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 :

retrouver le WindowsIdentity du desktop user


Sujet :

C#

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut retrouver le WindowsIdentity du desktop user
    Bonjour
    Voila une question souvant posée mais toujours sans réponse:

    Dans un programme lancé "en tant que", comment retrouver la session du bureau?

    Concretement, dans ce programme, WindowsIdentity.GetCurrent(); retournera "Machine\Administrateur", moi je veux récupérer "Machine\Giova" qui est ma session actuelle.

    Souvant, il n'y a pas de réponse car les gens répondent : "il peut y avoir plusieurs sessions ouvertes". Ok, mais pourtant windows sait laquelle de ces sessions est celle en cours (je peux en faire la démonstration).

    La seule solution que j'ai trouvé est ici :
    impersonate desktop user from elevated application

    Malheureusement, elle ne fonctionne pas chez moi, elle me dit que je n'ai pas les droits nécessaires, alors que pourtant le programme est lancé en tant qu'admin.

    Merci

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Je crois avoir trouvé.

    Le temps de tester et je vous posterai la solution

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Voila la solution.

    Pour les tests, j'ai ouvert 2 sessions windows, la premiere avec l'utilisateur Toto, la deuxieme avec l'utilisateur Titi (les 2 sont des utilisateurs standards). Je reste dans la session de Titi.

    Je lance mon programme en tant qu'admin :

    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
     static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main(string[] args)
            {
                //Depuis une session utilisateur standard, nous venons de lancer ce programme 'en tant qu'administrateur'
     
                //Voir code plus bas dans le post
                WinLogin switcher = new WinLogin();
                //Va afficher le chemin vers 'Mes documents' de l'administrateur.
                MessageBox.Show(String.Format("avant : {0}", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)));
                //On bascule sur la session de l'utilisateur standard, celui dont le bureau est affiché.
                switcher.EnterSessionUser();
                //Va afficher le chemin vers 'Mes documents' de l'utilisateur TOTO.
                MessageBox.Show(String.Format("pendant : {0}", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)));
                //Retourne sur la session administrateur
                switcher.LeaveSessionUser();
                //Va afficher de nouveau le chemin vers 'Mes documents' de l'administrateur.
                MessageBox.Show(String.Format("apres : {0}", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)));
     
            }
        }
    celui ci m'affiche
    c:\Utilisateurs\administrateur\Documents\
    puis
    c:\Utilisateurs\titi\Documents\
    puis
    c:\Utilisateurs\administrateur\Documents\

    il a donc pu faire une impersonalisation sur l'utilisateur actuel titi.

    L'astuce (je n'ai rien inventé, juste arrangé ce qui se trouve dans le liens que je vous avais donné), consiste à retrouver le processus du shell (explorer.exe)
    Récupérer son token, puis faire une impersonalisation grace à ce token.

    Voici la classe Winlogin qui permet de le faire :

    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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    using System.Security.Principal;
     
    namespace impersonate
    {
        public class WinLogin
        {
            WindowsImpersonationContext _ImpersonationCtx;
            int _lastError;
     
            #region Invokes
     
            [Flags()]
            enum TokenAccessFlags : int
            {
                STANDARD_RIGHTS_REQUIRED = 0x000F0000,
                STANDARD_RIGHTS_READ = 0x00020000,
                TOKEN_ASSIGN_PRIMARY = 0x0001,
                TOKEN_DUPLICATE = 0x0002,
                TOKEN_IMPERSONATE = 0x0004,
                TOKEN_QUERY = 0x0008,
                TOKEN_QUERY_SOURCE = 0x0010,
                TOKEN_ADJUST_PRIVILEGES = 0x0020,
                TOKEN_ADJUST_GROUPS = 0x0040,
                TOKEN_ADJUST_DEFAULT = 0x0080,
                TOKEN_ADJUST_SESSIONID = 0x0100,
                TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY),
                TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
                    TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
                    TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
                    TOKEN_ADJUST_SESSIONID)
            }
     
     
            [Flags()]
            enum ProcessAccessFlags : int
            {
                /// <summary>Specifies all possible access flags for the process object.</summary>
                AllAccess = CreateThread | DuplicateHandle | QueryInformation | SetInformation
                    | Terminate | VMOperation | VMRead | VMWrite | Synchronize,
                /// <summary>Enables usage of the process handle in the CreateRemoteThread 
                /// function to create a thread in the process.</summary>
                CreateThread = 0x2,
                /// <summary>Enables usage of the process handle as either the source or target process 
                /// in the DuplicateHandle function to duplicate a handle.</summary>
                DuplicateHandle = 0x40,
                /// <summary>Enables usage of the process handle in the GetExitCodeProcess and 
                /// GetPriorityClass functions to read information from the process object.</summary>
                QueryInformation = 0x400,
                /// <summary>Enables usage of the process handle in the SetPriorityClass function to 
                /// set the priority class of the process.</summary>
                SetInformation = 0x200,
                /// <summary>Enables usage of the process handle in the TerminateProcess function to 
                /// terminate the process.</summary>
                Terminate = 0x1,
                /// <summary>Enables usage of the process handle in the VirtualProtectEx and 
                /// WriteProcessMemory functions to modify the virtual memory of the process.</summary>
                VMOperation = 0x8,
                /// <summary>Enables usage of the process handle in the ReadProcessMemory function to' 
                /// read from the virtual memory of the process.</summary>
                VMRead = 0x10,
                /// <summary>Enables usage of the process handle in the WriteProcessMemory function to 
                /// write to the virtual memory of the process.</summary>
                VMWrite = 0x20,
                /// <summary>Enables usage of the process handle in any of the wait functions to wait 
                /// for the process to terminate.</summary>
                Synchronize = 0x100000
            }
     
            [DllImport("advapi32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            static extern bool OpenProcessToken(IntPtr ProcessHandle,
                TokenAccessFlags DesiredAccess, out IntPtr TokenHandle);
     
            [DllImport("user32.dll")]
            static extern IntPtr GetShellWindow();
     
            [DllImport("user32.dll", SetLastError = true)]
            static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
     
     
            [DllImport("kernel32.dll")]
            static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] 
                bool bInheritHandle, uint dwProcessId);
     
            #endregion
     
            public void EnterSessionUser()
            {
     
     
                IntPtr shellWindow = GetShellWindow();
     
                if (shellWindow == IntPtr.Zero)
                {
                    throw new InvalidOperationException("Unable to get shell window.");
                }
     
                uint processID = 0;
                GetWindowThreadProcessId(shellWindow, out processID);
                if (processID == 0)
                {
                    _lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Win32Exception(_lastError);
                }
     
                IntPtr processHandle = OpenProcess(ProcessAccessFlags.QueryInformation, true, processID);
     
                if (processHandle == IntPtr.Zero)
                {
                    _lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Win32Exception(_lastError);
                }
     
                IntPtr shellProcessToken;
     
                TokenAccessFlags tokenAccess = TokenAccessFlags.TOKEN_QUERY | TokenAccessFlags.TOKEN_DUPLICATE | TokenAccessFlags.TOKEN_IMPERSONATE;
     
     
                if (!OpenProcessToken(processHandle, tokenAccess, out shellProcessToken))
                {
                    _lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Win32Exception(_lastError);
                }
     
                WindowsIdentity alle = new WindowsIdentity(shellProcessToken);
                _ImpersonationCtx = alle.Impersonate();
            }
     
            public void LeaveSessionUser()
            {
                if (_ImpersonationCtx != null)
                {
                    _ImpersonationCtx.Undo();
                    _ImpersonationCtx = null;
                }
            }
        }
    }

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

Discussions similaires

  1. [2.x] Retrouver l'objet User dans un form de FosUserBundle
    Par DanaKil dans le forum Symfony
    Réponses: 0
    Dernier message: 18/05/2015, 13h30
  2. Réponses: 3
    Dernier message: 04/02/2015, 16h44
  3. Retrouver un mot de passe d'un user en mode root
    Par Thordax dans le forum Administration
    Réponses: 0
    Dernier message: 06/01/2010, 14h49
  4. [reseaux] Comment creer un compte user à partir d'un formul avec perl
    Par oulai_evado dans le forum Programmation et administration système
    Réponses: 4
    Dernier message: 01/10/2002, 19h54

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