Bonjour a tous.

Je développe actuellement une application d'archivage. Cette application est en fait une surcouche de pvcs (outil d'archivage).
Dans mon application j'ai développé un wrapper pour lancer des opérations via la ligne de commande de pvcs (ligne de dommande DOS).

Je souhaiterais faire en sorte que l'utilisateur se logue à mon application avec sont compte AD, mais toutes les opérations faites avec pvcs doivent etre faites avec un compte admin dont les caracteristiques sont stockées dans le code (pour l'instant).

Seulement j'utilise l'impersonation windows pour effectuer cela mais ca ne marche pas comme je le voudrai , je m'explique:
Lors du lancement d'une commande j'ai ce code la :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
using (new Impersonator(config.UidPcli, "cw01", config.PwdPcli))
                {
                    //Init
                    Process pcli = new Process();
 
                    pcli.StartInfo.UseShellExecute = false;
                    pcli.StartInfo.RedirectStandardOutput = true;
                    pcli.StartInfo.RedirectStandardError = true;
                    pcli.StartInfo.CreateNoWindow = true;
                    pcli.StartInfo.FileName = config.PcliPath;
                    foreach (AbstractCommand comm in LstCommand)
                    {
                        pcli.StartInfo.Arguments = comm.getArguments();
                        pcli.Start();
 
                        //Output
                        StreamReader streamOut = pcli.StandardOutput;
                        StreamReader streamError = pcli.StandardError;
                        output[0] = streamOut.ReadToEnd();
                        output[1] = streamError.ReadToEnd();
                        if (output[0].Contains("[Error]") || output[1].Contains("[Error]") ||
                            output[0].Contains("Warning:") || output[1].Contains("Warning:"))
                        {
                            throw new Exception("Erreur pcli\n" + output[0] + "\n" + output[1]);
                        }
                        output[3] = comm.getArguments();
                    }
                }
Donc dans le using, Environnement.UserName est bien celui du compte admin et pas celui de l'utilisateur.

Et voici le code de la classe Impersonator:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
 
namespace Configuration
{
	#region Using directives.
	// ----------------------------------------------------------------------
 
	using System;
	using System.Security.Principal;
	using System.Runtime.InteropServices;
	using System.ComponentModel;
    using System.Windows.Forms;
 
	// ----------------------------------------------------------------------
	#endregion
 
	/////////////////////////////////////////////////////////////////////////
 
	/// <summary>
	/// Impersonation of a user. Allows to execute code under another
	/// user context.
	/// Please note that the account that instantiates the Impersonator class
	/// needs to have the 'Act as part of operating system' privilege set.
	/// </summary>
	/// <remarks>	
	/// This class is based on the information in the Microsoft knowledge base
	/// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
	/// 
	/// Encapsulate an instance into a using-directive like e.g.:
	/// 
	///		...
	///		using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
	///		{
	///			...
	///			[code that executes under the new context]
	///			...
	///		}
	///		...
	/// 
	/// for questions regarding this class.
	/// </remarks>
	public class Impersonator :
		IDisposable
	{
		#region Public methods.
		// ------------------------------------------------------------------
 
		/// <summary>
		/// Constructor. Starts the impersonation with the given credentials.
		/// Please note that the account that instantiates the Impersonator class
		/// needs to have the 'Act as part of operating system' privilege set.
		/// </summary>
		/// <param name="userName">The name of the user to act as.</param>
		/// <param name="domainName">The domain name of the user to act as.</param>
		/// <param name="password">The password of the user to act as.</param>
		public Impersonator(
			string userName,
			string domainName,
			string password )
		{
			ImpersonateValidUser( userName, domainName, password );
		}
 
		// ------------------------------------------------------------------
		#endregion
 
		#region IDisposable member.
		// ------------------------------------------------------------------
 
		public void Dispose()
		{
			UndoImpersonation();
		}
 
		// ------------------------------------------------------------------
		#endregion
 
		#region P/Invoke.
		// ------------------------------------------------------------------
 
		[DllImport("advapi32.dll", SetLastError=true)]
		private static extern int LogonUser(
			string lpszUserName,
			string lpszDomain,
			string lpszPassword,
			int dwLogonType,
			int dwLogonProvider,
			ref IntPtr phToken);
 
		[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
		private static extern int DuplicateToken(
			IntPtr hToken,
			int impersonationLevel,
			ref IntPtr hNewToken);
 
		[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
		private static extern bool RevertToSelf();
 
		[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
		private static extern  bool CloseHandle(
			IntPtr handle);
 
		private const int LOGON32_LOGON_INTERACTIVE = 2;
		private const int LOGON32_PROVIDER_DEFAULT = 0;
 
		// ------------------------------------------------------------------
		#endregion
 
		#region Private member.
		// ------------------------------------------------------------------
 
		/// <summary>
		/// Does the actual impersonation.
		/// </summary>
		/// <param name="userName">The name of the user to act as.</param>
		/// <param name="domainName">The domain name of the user to act as.</param>
		/// <param name="password">The password of the user to act as.</param>
		private void ImpersonateValidUser(
			string userName, 
			string domain, 
			string password )
		{
			WindowsIdentity tempWindowsIdentity = null;
			IntPtr token = IntPtr.Zero;
			IntPtr tokenDuplicate = IntPtr.Zero;
 
			try
			{
				if ( RevertToSelf() )
				{
					if ( LogonUser(
						userName, 
						domain, 
						password, 
						LOGON32_LOGON_INTERACTIVE,
						LOGON32_PROVIDER_DEFAULT, 
						ref token ) != 0 )
					{
						if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
						{
							tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
                            MessageBox.Show(Environment.UserName);
							impersonationContext = tempWindowsIdentity.Impersonate();
                            MessageBox.Show(Environment.UserName);
						}
						else
						{
							throw new Win32Exception( Marshal.GetLastWin32Error() );
						}
					}
					else
					{
						throw new Win32Exception( Marshal.GetLastWin32Error() );
					}
				}
				else
				{
					throw new Win32Exception( Marshal.GetLastWin32Error() );
				}
			}
			finally
			{
				if ( token!= IntPtr.Zero )
				{
					CloseHandle( token );
				}
				if ( tokenDuplicate!=IntPtr.Zero )
				{
					CloseHandle( tokenDuplicate );
				}
			}
		}
 
		/// <summary>
		/// Reverts the impersonation.
		/// </summary>
		private void UndoImpersonation()
		{
			if ( impersonationContext!=null )
			{
				impersonationContext.Undo();
			}	
		}
 
		private WindowsImpersonationContext impersonationContext = null;
 
		// ------------------------------------------------------------------
		#endregion
	}
 
	/////////////////////////////////////////////////////////////////////////
}
Je précise que cette classe n'est pas de moi.

Donc lorsque j'utilise tout cela le contexte d'execution est bien changé car je verifie que Environnement.UserName à bien changé. Seulement tous les fichiers archivés par pvcs le sont sous le nom d'utilisateur et pas sous l'utilisateur admin.

Peut-etre n'est il pas possible d'executer un programme externe (via System.Diagnostic.Process.Start()) avec des droits d'utilisateurss différents. Ou bien peut-etre que j'ai fait des erreurs dans mon code.

Si quelqu'un peut m'aider !!
Merci d'avance.