IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Windows impersonation + process.start


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 25
    Par défaut Windows impersonation + process.start
    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.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Radec Voir le message
    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.
    Ben si :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pcli.StartInfo.UserName = "admin";
    pcli.StartInfo.Password = "lemotdepasse";
    Pas besoin de se casser la tête avec l'impersonation

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Echec appel Process Start sous IIS 7.5 windows 2008 server
    Par ouadie99 dans le forum Windows Communication Foundation
    Réponses: 6
    Dernier message: 25/10/2012, 17h45
  2. [Débutant] Runas et Process.Start(explorer) sous windows 7
    Par gnoupix dans le forum VB.NET
    Réponses: 0
    Dernier message: 27/12/2011, 09h59
  3. service windows et process.start()
    Par isoman dans le forum C#
    Réponses: 4
    Dernier message: 11/03/2009, 11h51
  4. Réponses: 2
    Dernier message: 12/02/2008, 11h59
  5. [DELPHI6][API Windows] Fenêtre - Process
    Par Desraux dans le forum API, COM et SDKs
    Réponses: 1
    Dernier message: 02/06/2005, 17h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo