Comment vérifier qu’un utilisateur particulier a ouvert une session en tant que service par programme

Pour une application je vérifie si un utilisateur particulier a ouvert une session en tant que droit de service Comment faire cela par programmation? J’ai vérifié sur Internet et n’ai pas pu trouver une bonne ressource

Merci

Upul

Avez-vous un jeton pour ce compte? Si c’est le cas, vous pouvez appeler GetTokenInformation avec TokenInformationClass == TokenPrivileges . Cela renverra la liste des privilèges associés au jeton et s’ils ont été activés ou non.

Si le compte n’est pas connecté et que vous ne pouvez donc pas obtenir son jeton, cela devient beaucoup plus difficile. Vous ne pouvez pas rechercher les privilèges autorisés pour le compte, sans parler des privilèges que n’importe quel groupe du compte apporte dans le jeton. Vous devez vous connecter au compte pour récupérer un jeton, puis suivre les conseils précédents.

J’ai vérifié toutes les réponses précédentes et de nombreuses autres dans les publications correspondantes, passé 3 jours à creuser dans l’API Win32, mais je n’ai pas obtenu de réponse fiable à cette question (certaines exceptions ont été levées, certaines n’ont pas été compilées, même avec des tentatives de correction, certaines travaillé uniquement avec des comptes locaux). Enfin, j’ai trouvé une réponse acceptable pour moi. En guise de base, j’ai utilisé la réponse de Wieger1983 sur le forum technique . J’y ai apporté quelques modifications:

  • légère adaptation au C # pur (à l’origine, il a été déclaré extension PowerShell)
  • en lui ajoutant de la stabilité (il ne renvoie pas le code d’erreur 2 au cas où l’utilisateur n’aurait aucun droit. L’explication a été fournie par @David Woodwart dans ce message: LsaEnumerateAccountRights renvoie toujours “Fichier non trouvé” ).
  • éviter les memory leaks en cas d’exception imprévisible. CloseHandle est appelé maintenant dans le bloc finally.

Maintenant, cela fonctionne à la fois avec les comptes locaux et Active Directory et fonctionne bien si l’utilisateur n’a aucun droit. J’espère que cela fera gagner du temps à quelqu’un comme moi =).

AVERTISSEMENT: Si vous utilisez ce code sur une architecture x64, veuillez prendre note des commentaires d’EricRRichards ci-dessous. Je ne peux pas vérifier maintenant si cela devrait être appliqué dans tous les cas.

 // // This code has been adapted from http://www.codeproject.com/KB/cs/lsadotnet.aspx // The rights enumeration code came from http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.interop/2004-11/0394.html // // Windows Security via .NET is covered on by Pluralsight:http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/HomePage.html // using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Text; namespace LSA { // // Provides methods the local security authority which controls user rights. Managed via secpol.msc normally. // public class LocalSecurityAuthorityController { private const int Access = (int)( LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN | LSA_AccessPolicy.POLICY_CREATE_ACCOUNT | LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE | LSA_AccessPolicy.POLICY_CREATE_SECRET | LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION | LSA_AccessPolicy.POLICY_LOOKUP_NAMES | LSA_AccessPolicy.POLICY_NOTIFICATION | LSA_AccessPolicy.POLICY_SERVER_ADMIN | LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS | LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS | LSA_AccessPolicy.POLICY_TRUST_ADMIN | LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION | LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION ); [DllImport("advapi32.dll", PreserveSig = true)] private static extern UInt32 LsaOpenPolicy(ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAtsortingbutes, Int32 DesiredAccess, out IntPtr PolicyHandle); [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] private static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, int CountOfRights); [DllImport("advapi32")] public static extern void FreeSid(IntPtr pSid); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, PreserveSig = true)] private static extern bool LookupAccountName(ssortingng lpSystemName, ssortingng lpAccountName, IntPtr psid, ref int cbsid, SsortingngBuilder domainName, ref int cbdomainLength, ref int use); [DllImport("advapi32.dll")] private static extern bool IsValidSid(IntPtr pSid); [DllImport("advapi32.dll")] private static extern int LsaClose(IntPtr ObjectHandle); [DllImport("kernel32.dll")] private static extern int GetLastError(); [DllImport("advapi32.dll")] private static extern int LsaNtStatusToWinError(uint status); [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] private static extern uint LsaEnumerateAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, out IntPtr UserRightsPtr, out int CountOfRights); [StructLayout(LayoutKind.Sequential)] private struct LSA_UNICODE_STRING { public UInt16 Length; public UInt16 MaximumLength; public IntPtr Buffer; } [StructLayout(LayoutKind.Sequential)] private struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public LSA_UNICODE_STRING ObjectName; public UInt32 Atsortingbutes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } [Flags] private enum LSA_AccessPolicy : long { POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L, POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L, POLICY_GET_PRIVATE_INFORMATION = 0x00000004L, POLICY_TRUST_ADMIN = 0x00000008L, POLICY_CREATE_ACCOUNT = 0x00000010L, POLICY_CREATE_SECRET = 0x00000020L, POLICY_CREATE_PRIVILEGE = 0x00000040L, POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L, POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L, POLICY_AUDIT_LOG_ADMIN = 0x00000200L, POLICY_SERVER_ADMIN = 0x00000400L, POLICY_LOOKUP_NAMES = 0x00000800L, POLICY_NOTIFICATION = 0x00001000L } // Returns the Local Security Authority rights granted to the account public IList GetRights(ssortingng accountName) { IList rights = new List(); ssortingng errorMessage = ssortingng.Empty; long winErrorCode = 0; IntPtr sid = IntPtr.Zero; int sidSize = 0; SsortingngBuilder domainName = new SsortingngBuilder(); int nameSize = 0; int accountType = 0; LookupAccountName(ssortingng.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); domainName = new SsortingngBuilder(nameSize); sid = Marshal.AllocHGlobal(sidSize); if (!LookupAccountName(ssortingng.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType)) { winErrorCode = GetLastError(); errorMessage = ("LookupAccountName failed: " + winErrorCode); throw new Win32Exception((int)winErrorCode, errorMessage); } else { LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING(); IntPtr policyHandle = IntPtr.Zero; IntPtr userRightsPtr = IntPtr.Zero; int countOfRights = 0; LSA_OBJECT_ATTRIBUTES objectAtsortingbutes = CreateLSAObject(); uint policyStatus = LsaOpenPolicy(ref systemName, ref objectAtsortingbutes, Access, out policyHandle); winErrorCode = LsaNtStatusToWinError(policyStatus); if (winErrorCode != 0) { errorMessage = ssortingng.Format("OpenPolicy failed: {0}.", winErrorCode); throw new Win32Exception((int)winErrorCode, errorMessage); } else { try { uint result = LsaEnumerateAccountRights(policyHandle, sid, out userRightsPtr, out countOfRights); winErrorCode = LsaNtStatusToWinError(result); if (winErrorCode != 0) { if (winErrorCode == 2) { return new List(); } errorMessage = ssortingng.Format("LsaEnumerateAccountRights failed: {0}", winErrorCode); throw new Win32Exception((int)winErrorCode, errorMessage); } Int32 ptr = userRightsPtr.ToInt32(); LSA_UNICODE_STRING userRight; for (int i = 0; i < countOfRights; i++) { userRight = (LSA_UNICODE_STRING)Marshal.PtrToStructure(new IntPtr(ptr), typeof(LSA_UNICODE_STRING)); string userRightStr = Marshal.PtrToStringAuto(userRight.Buffer); rights.Add(userRightStr); ptr += Marshal.SizeOf(userRight); } } finally { LsaClose(policyHandle); } } FreeSid(sid); } return rights; } // Adds a privilege to an account public void SetRight(string accountName, string privilegeName) { long winErrorCode = 0; string errorMessage = string.Empty; IntPtr sid = IntPtr.Zero; int sidSize = 0; StringBuilder domainName = new StringBuilder(); int nameSize = 0; int accountType = 0; LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); domainName = new StringBuilder(nameSize); sid = Marshal.AllocHGlobal(sidSize); if (!LookupAccountName(string.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType)) { winErrorCode = GetLastError(); errorMessage = string.Format("LookupAccountName failed: {0}", winErrorCode); throw new Win32Exception((int)winErrorCode, errorMessage); } else { LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING(); IntPtr policyHandle = IntPtr.Zero; LSA_OBJECT_ATTRIBUTES objectAttributes = CreateLSAObject(); uint resultPolicy = LsaOpenPolicy(ref systemName, ref objectAttributes, Access, out policyHandle); winErrorCode = LsaNtStatusToWinError(resultPolicy); if (winErrorCode != 0) { errorMessage = string.Format("OpenPolicy failed: {0} ", winErrorCode); throw new Win32Exception((int)winErrorCode, errorMessage); } else { try { LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[1]; userRights[0] = new LSA_UNICODE_STRING(); userRights[0].Buffer = Marshal.StringToHGlobalUni(privilegeName); userRights[0].Length = (UInt16)(privilegeName.Length * UnicodeEncoding.CharSize); userRights[0].MaximumLength = (UInt16)((privilegeName.Length + 1) * UnicodeEncoding.CharSize); uint res = LsaAddAccountRights(policyHandle, sid, userRights, 1); winErrorCode = LsaNtStatusToWinError(res); if (winErrorCode != 0) { errorMessage = string.Format("LsaAddAccountRights failed: {0}", winErrorCode); throw new Win32Exception((int)winErrorCode, errorMessage); } } finally { LsaClose(policyHandle); } } FreeSid(sid); } } private static LSA_OBJECT_ATTRIBUTES CreateLSAObject() { LSA_OBJECT_ATTRIBUTES newInstance = new LSA_OBJECT_ATTRIBUTES(); newInstance.Length = 0; newInstance.RootDirectory = IntPtr.Zero; newInstance.Attributes = 0; newInstance.SecurityDescriptor = IntPtr.Zero; newInstance.SecurityQualityOfService = IntPtr.Zero; return newInstance; } } // Local security rights managed by the Local Security Authority public class LocalSecurityAuthorityRights { // Log on as a service right public const string LogonAsService = "SeServiceLogonRight"; // Log on as a batch job right public const string LogonAsBatchJob = "SeBatchLogonRight"; // Interactive log on right public const string InteractiveLogon = "SeInteractiveLogonRight"; // Network log on right public const string NetworkLogon = "SeNetworkLogonRight"; // Generate security audit logs right public const string GenerateSecurityAudits = "SeAuditPrivilege"; } /* added wrapper for PowerShell */ public class LSAWrapper { public static IList GetRights(ssortingng accountName) { return new LocalSecurityAuthorityController().GetRights(accountName); } public static void SetRight(ssortingng accountName, ssortingng privilegeName) { new LocalSecurityAuthorityController().SetRight(accountName, privilegeName); } } } 

Enfin, il est assez facile de vérifier les droits:

 var rights = LSAWrapper.GetRights("myMachineName\\TestUser"); if (rights.Contains(LocalSecurityAuthorityRights.LogonAsService)) { Console.WriteLine("User has right to logon as a service"); } else { Console.WriteLine("User doesn't have right to logon as a service"); } 

Regardez comment utiliser

Méthode WindowsIdentity.GetCurrent et classe WindowsPrincipal