我想使用C#来确定为我的进程/线程令牌分配了哪些权限,并根据需要进行调整.例如,为了让我的程序重新启动计算机,它必须首先启用SeShutdownPrivilege权限.
如何从托管代码安全地完成?
解决方法
事实证明这并不重要,因为它没有内置机制.不仅需要P / Invoke,而且您必须仔细编码以确保您不会通过启用它们来“泄漏”权限,然后不会很快禁用它们(如果您重新启动计算机则不会出现问题).
有关描述的完整代码示例,请阅读Mark Novak 2005年3月“Manipulate Privileges in Managed Code Reliably,Securely,and Efficiently”中的MSDN杂志文章.
这是P / Invoke声明:
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.ConstrainedExecution;
- namespace PrivilegeClass
- {
- [Flags]
- internal enum TokenAccessLevels
- {
- AssignPrimary = 0x00000001,Duplicate = 0x00000002,Impersonate = 0x00000004,Query = 0x00000008,QuerySource = 0x00000010,AdjustPrivileges = 0x00000020,AdjustGroups = 0x00000040,AdjustDefault = 0x00000080,AdjustSessionId = 0x00000100,Read = 0x00020000 | Query,Write = 0x00020000 | AdjustPrivileges | AdjustGroups | AdjustDefault,AllAccess = 0x000F0000 |
- AssignPrimary |
- Duplicate |
- Impersonate |
- Query |
- QuerySource |
- AdjustPrivileges |
- AdjustGroups |
- AdjustDefault |
- AdjustSessionId,MaximumAllowed = 0x02000000
- }
- internal enum SecurityImpersonationLevel
- {
- Anonymous = 0,Identification = 1,Impersonation = 2,Delegation = 3,}
- internal enum TokenType
- {
- Primary = 1,}
- internal sealed class NativeMethods
- {
- internal const uint SE_PRIVILEGE_DISABLED = 0x00000000;
- internal const uint SE_PRIVILEGE_ENABLED = 0x00000002;
- [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
- internal struct LUID
- {
- internal uint LowPart;
- internal uint HighPart;
- }
- [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
- internal struct LUID_AND_ATTRIBUTES
- {
- internal LUID Luid;
- internal uint Attributes;
- }
- [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
- internal struct TOKEN_PRIVILEGE
- {
- internal uint PrivilegeCount;
- internal LUID_AND_ATTRIBUTES Privilege;
- }
- internal const string ADVAPI32 = "advapi32.dll";
- internal const string KERNEL32 = "kernel32.dll";
- internal const int ERROR_SUCCESS = 0x0;
- internal const int ERROR_ACCESS_DENIED = 0x5;
- internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8;
- internal const int ERROR_NO_TOKEN = 0x3f0;
- internal const int ERROR_NOT_ALL_ASSIGNED = 0x514;
- internal const int ERROR_NO_SUCH_PRIVILEGE = 0x521;
- internal const int ERROR_CANT_OPEN_ANONYMOUS = 0x543;
- [DllImport(
- KERNEL32,SetLastError=true)]
- [ReliabilityContract(Consistency.WillNotCorruptState,Cer.MayFail)]
- internal static extern bool CloseHandle(IntPtr handle);
- [DllImport(
- ADVAPI32,CharSet=CharSet.Unicode,Cer.MayFail)]
- internal static extern bool AdjustTokenPrivileges (
- [In] SafeTokenHandle TokenHandle,[In] bool DisableAllPrivileges,[In] ref TOKEN_PRIVILEGE NewState,[In] uint BufferLength,[In,Out] ref TOKEN_PRIVILEGE PrevIoUsState,Out] ref uint ReturnLength);
- [DllImport(
- ADVAPI32,CharSet=CharSet.Auto,Cer.MayFail)]
- internal static extern
- bool RevertToSelf();
- [DllImport(
- ADVAPI32,EntryPoint="LookupPrivilegeValueW",Cer.MayFail)]
- internal static extern
- bool LookupPrivilegeValue (
- [In] string lpSystemName,[In] string lpName,Out] ref LUID Luid);
- [DllImport(
- KERNEL32,Cer.MayFail)]
- internal static extern
- IntPtr GetCurrentProcess();
- [DllImport(
- KERNEL32,Cer.MayFail)]
- internal static extern
- IntPtr GetCurrentThread ();
- [DllImport(
- ADVAPI32,Cer.MayFail)]
- internal static extern
- bool OpenProcessToken (
- [In] IntPtr ProcessToken,[In] TokenAccessLevels DesiredAccess,Out] ref SafeTokenHandle TokenHandle);
- [DllImport
- (ADVAPI32,Cer.MayFail)]
- internal static extern
- bool OpenThreadToken(
- [In] IntPtr ThreadToken,[In] bool OpenAsSelf,Out] ref SafeTokenHandle TokenHandle);
- [DllImport
- (ADVAPI32,Cer.MayFail)]
- internal static extern
- bool DuplicateTokenEx(
- [In] SafeTokenHandle ExistingToken,[In] TokenAccessLevels DesiredAccess,[In] IntPtr TokenAttributes,[In] SecurityImpersonationLevel ImpersonationLevel,[In] TokenType TokenType,Out] ref SafeTokenHandle NewToken);
- [DllImport
- (ADVAPI32,Cer.MayFail)]
- internal static extern
- bool SetThreadToken(
- [In] IntPtr Thread,[In] SafeTokenHandle Token);
- static NativeMethods()
- {
- }
- }
- }