如何检查特定用户是否以编程方式登录为服务权限

对于应用程序,我要检查特定用户是否已作为服务登录? 如何以编程方式执行此操作? 我在互联网上查了一下,找不到一些好的资源

谢谢

Upul

你有该帐户的令牌吗? 如果是这样,您可以使用TokenInformationClass == TokenPrivileges调用GetTokenInformation 。 这将返回与令牌关联的权限列表以及它们是否已被激活。

如果帐户未登录,因此您无法获得其令牌,则会变得更加困难。 您无法查询帐户允许的权限,更不用说任何帐户的组带来的权限。 您需要登录帐户才能检索令牌,然后按照之前的建议操作。

我检查了所有以前的答案以及相关post中的许多其他答案,花了3天时间深入研究Win32 API,但没有得到这个问题的可靠答案(一些抛出的exeptions,有些甚至没有编译,甚至尝试修复它们,一些仅适用于本地帐户)。 最后,我找到了可以接受的答案。 作为基础,我在technet论坛上使用了Wieger1983的答案。 我介绍了一些变化:

  • 略微适应纯C#(最初被宣布为powershell扩展)
  • 为它添加稳定性(如果用户没有权限,它现在不返回错误代码2。@D​​avid Woodwart在这篇文章中提供了解释: LsaEnumerateAccountRights总是返回“File not found” )。
  • 在任何不可预测的exception情况下防止内存泄漏。 现在在finally块中调用CloseHandle。

现在它适用于本地和Active Directory帐户,如果用户没有权限,它可以正常工作。 我希望它能为像我这样的人节省时间=)。

警告:如果您将在x64架构上使用此代码,请注意以下EricRRichards的评论。 我现在无法validation是否应该在每种情况下应用它。

 // // 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 ObjectAttributes, 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(string lpSystemName, string lpAccountName, IntPtr psid, ref int cbsid, StringBuilder 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 Attributes; 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(string accountName) { IList rights = new List(); string errorMessage = string.Empty; long winErrorCode = 0; 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 = ("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 objectAttributes = CreateLSAObject(); uint policyStatus = LsaOpenPolicy(ref systemName, ref objectAttributes, Access, out policyHandle); winErrorCode = LsaNtStatusToWinError(policyStatus); if (winErrorCode != 0) { errorMessage = string.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 = string.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(string accountName) { return new LocalSecurityAuthorityController().GetRights(accountName); } public static void SetRight(string accountName, string privilegeName) { new LocalSecurityAuthorityController().SetRight(accountName, privilegeName); } } } 

最后,检查权利很容易:

 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"); } 

看看使用

WindowsIdentity.GetCurrent方法和WindowsPrincipal类