You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

319 lines
15 KiB

  1. // <copyright file="Privileges.cs" company="Nick Lowe">
  2. // Copyright © Nick Lowe 2009
  3. // </copyright>
  4. // <author>Nick Lowe</author>
  5. // <email>nick@int-r.net</email>
  6. // <url>http://processprivileges.codeplex.com/</url>
  7. namespace ProcessPrivileges
  8. {
  9. using System;
  10. using System.Collections.Generic;
  11. using System.ComponentModel;
  12. using System.Runtime.InteropServices;
  13. using System.Text;
  14. internal static class Privileges
  15. {
  16. private const int PrivilegesCount = 35;
  17. private const string SeAssignPrimaryTokenPrivilege = "SeAssignPrimaryTokenPrivilege";
  18. private const string SeAuditPrivilege = "SeAuditPrivilege";
  19. private const string SeBackupPrivilege = "SeBackupPrivilege";
  20. private const string SeChangeNotifyPrivilege = "SeChangeNotifyPrivilege";
  21. private const string SeCreateGlobalPrivilege = "SeCreateGlobalPrivilege";
  22. private const string SeCreatePagefilePrivilege = "SeCreatePagefilePrivilege";
  23. private const string SeCreatePermanentPrivilege = "SeCreatePermanentPrivilege";
  24. private const string SeCreateSymbolicLinkPrivilege = "SeCreateSymbolicLinkPrivilege";
  25. private const string SeCreateTokenPrivilege = "SeCreateTokenPrivilege";
  26. private const string SeDebugPrivilege = "SeDebugPrivilege";
  27. private const string SeEnableDelegationPrivilege = "SeEnableDelegationPrivilege";
  28. private const string SeImpersonatePrivilege = "SeImpersonatePrivilege";
  29. private const string SeIncreaseBasePriorityPrivilege = "SeIncreaseBasePriorityPrivilege";
  30. private const string SeIncreaseQuotaPrivilege = "SeIncreaseQuotaPrivilege";
  31. private const string SeIncreaseWorkingSetPrivilege = "SeIncreaseWorkingSetPrivilege";
  32. private const string SeLoadDriverPrivilege = "SeLoadDriverPrivilege";
  33. private const string SeLockMemoryPrivilege = "SeLockMemoryPrivilege";
  34. private const string SeMachineAccountPrivilege = "SeMachineAccountPrivilege";
  35. private const string SeManageVolumePrivilege = "SeManageVolumePrivilege";
  36. private const string SeProfileSingleProcessPrivilege = "SeProfileSingleProcessPrivilege";
  37. private const string SeRelabelPrivilege = "SeRelabelPrivilege";
  38. private const string SeRemoteShutdownPrivilege = "SeRemoteShutdownPrivilege";
  39. private const string SeRestorePrivilege = "SeRestorePrivilege";
  40. private const string SeSecurityPrivilege = "SeSecurityPrivilege";
  41. private const string SeShutdownPrivilege = "SeShutdownPrivilege";
  42. private const string SeSyncAgentPrivilege = "SeSyncAgentPrivilege";
  43. private const string SeSystemEnvironmentPrivilege = "SeSystemEnvironmentPrivilege";
  44. private const string SeSystemProfilePrivilege = "SeSystemProfilePrivilege";
  45. private const string SeSystemTimePrivilege = "SeSystemtimePrivilege";
  46. private const string SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege";
  47. private const string SeTcbPrivilege = "SeTcbPrivilege";
  48. private const string SeTimeZonePrivilege = "SeTimeZonePrivilege";
  49. private const string SeTrustedCredManAccessPrivilege = "SeTrustedCredManAccessPrivilege";
  50. private const string SeUndockPrivilege = "SeUndockPrivilege";
  51. private const string SeUnsolicitedInputPrivilege = "SeUnsolicitedInputPrivilege";
  52. private static readonly Dictionary<Privilege, Luid> luidDictionary =
  53. new Dictionary<Privilege, Luid>(PrivilegesCount);
  54. private static readonly Dictionary<Privilege, string> privilegeConstantsDictionary =
  55. new Dictionary<Privilege, string>(PrivilegesCount)
  56. {
  57. { Privilege.AssignPrimaryToken, SeAssignPrimaryTokenPrivilege },
  58. { Privilege.Audit, SeAuditPrivilege },
  59. { Privilege.Backup, SeBackupPrivilege },
  60. { Privilege.ChangeNotify, SeChangeNotifyPrivilege },
  61. { Privilege.CreateGlobal, SeCreateGlobalPrivilege },
  62. { Privilege.CreatePageFile, SeCreatePagefilePrivilege },
  63. { Privilege.CreatePermanent, SeCreatePermanentPrivilege },
  64. { Privilege.CreateSymbolicLink, SeCreateSymbolicLinkPrivilege },
  65. { Privilege.CreateToken, SeCreateTokenPrivilege },
  66. { Privilege.Debug, SeDebugPrivilege },
  67. { Privilege.EnableDelegation, SeEnableDelegationPrivilege },
  68. { Privilege.Impersonate, SeImpersonatePrivilege },
  69. { Privilege.IncreaseBasePriority, SeIncreaseBasePriorityPrivilege },
  70. { Privilege.IncreaseQuota, SeIncreaseQuotaPrivilege },
  71. { Privilege.IncreaseWorkingSet, SeIncreaseWorkingSetPrivilege },
  72. { Privilege.LoadDriver, SeLoadDriverPrivilege },
  73. { Privilege.LockMemory, SeLockMemoryPrivilege },
  74. { Privilege.MachineAccount, SeMachineAccountPrivilege },
  75. { Privilege.ManageVolume, SeManageVolumePrivilege },
  76. { Privilege.ProfileSingleProcess, SeProfileSingleProcessPrivilege },
  77. { Privilege.Relabel, SeRelabelPrivilege },
  78. { Privilege.RemoteShutdown, SeRemoteShutdownPrivilege },
  79. { Privilege.Restore, SeRestorePrivilege },
  80. { Privilege.Security, SeSecurityPrivilege },
  81. { Privilege.Shutdown, SeShutdownPrivilege },
  82. { Privilege.SyncAgent, SeSyncAgentPrivilege },
  83. { Privilege.SystemEnvironment, SeSystemEnvironmentPrivilege },
  84. { Privilege.SystemProfile, SeSystemProfilePrivilege },
  85. { Privilege.SystemTime, SeSystemTimePrivilege },
  86. { Privilege.TakeOwnership, SeTakeOwnershipPrivilege },
  87. { Privilege.TrustedComputerBase, SeTcbPrivilege },
  88. { Privilege.TimeZone, SeTimeZonePrivilege },
  89. { Privilege.TrustedCredentialManagerAccess, SeTrustedCredManAccessPrivilege },
  90. { Privilege.Undock, SeUndockPrivilege },
  91. { Privilege.UnsolicitedInput, SeUnsolicitedInputPrivilege }
  92. };
  93. private static readonly Dictionary<string, Privilege> privilegesDictionary =
  94. new Dictionary<string, Privilege>(PrivilegesCount)
  95. {
  96. { SeAssignPrimaryTokenPrivilege, Privilege.AssignPrimaryToken },
  97. { SeAuditPrivilege, Privilege.Audit },
  98. { SeBackupPrivilege, Privilege.Backup },
  99. { SeChangeNotifyPrivilege, Privilege.ChangeNotify },
  100. { SeCreateGlobalPrivilege, Privilege.CreateGlobal },
  101. { SeCreatePagefilePrivilege, Privilege.CreatePageFile },
  102. { SeCreatePermanentPrivilege, Privilege.CreatePermanent },
  103. { SeCreateSymbolicLinkPrivilege, Privilege.CreateSymbolicLink },
  104. { SeCreateTokenPrivilege, Privilege.CreateToken },
  105. { SeDebugPrivilege, Privilege.Debug },
  106. { SeEnableDelegationPrivilege, Privilege.EnableDelegation },
  107. { SeImpersonatePrivilege, Privilege.Impersonate },
  108. { SeIncreaseBasePriorityPrivilege, Privilege.IncreaseBasePriority },
  109. { SeIncreaseQuotaPrivilege, Privilege.IncreaseQuota },
  110. { SeIncreaseWorkingSetPrivilege, Privilege.IncreaseWorkingSet },
  111. { SeLoadDriverPrivilege, Privilege.LoadDriver },
  112. { SeLockMemoryPrivilege, Privilege.LockMemory },
  113. { SeMachineAccountPrivilege, Privilege.MachineAccount },
  114. { SeManageVolumePrivilege, Privilege.ManageVolume },
  115. { SeProfileSingleProcessPrivilege, Privilege.ProfileSingleProcess },
  116. { SeRelabelPrivilege, Privilege.Relabel },
  117. { SeRemoteShutdownPrivilege, Privilege.RemoteShutdown },
  118. { SeRestorePrivilege, Privilege.Restore },
  119. { SeSecurityPrivilege, Privilege.Security },
  120. { SeShutdownPrivilege, Privilege.Shutdown },
  121. { SeSyncAgentPrivilege, Privilege.SyncAgent },
  122. { SeSystemEnvironmentPrivilege, Privilege.SystemEnvironment },
  123. { SeSystemProfilePrivilege, Privilege.SystemProfile },
  124. { SeSystemTimePrivilege, Privilege.SystemTime },
  125. { SeTakeOwnershipPrivilege, Privilege.TakeOwnership },
  126. { SeTcbPrivilege, Privilege.TrustedComputerBase },
  127. { SeTimeZonePrivilege, Privilege.TimeZone },
  128. { SeTrustedCredManAccessPrivilege, Privilege.TrustedCredentialManagerAccess },
  129. { SeUndockPrivilege, Privilege.Undock },
  130. { SeUnsolicitedInputPrivilege, Privilege.UnsolicitedInput }
  131. };
  132. internal static AdjustPrivilegeResult DisablePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege)
  133. {
  134. return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Disabled);
  135. }
  136. internal static AdjustPrivilegeResult EnablePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege)
  137. {
  138. return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Enabled);
  139. }
  140. internal static AdjustPrivilegeResult RemovePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege)
  141. {
  142. return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Removed);
  143. }
  144. internal static PrivilegeAttributes GetPrivilegeAttributes(Privilege privilege, PrivilegeAndAttributesCollection privileges)
  145. {
  146. foreach (PrivilegeAndAttributes privilegeAndAttributes in privileges)
  147. {
  148. if (privilegeAndAttributes.Privilege == privilege)
  149. {
  150. return privilegeAndAttributes.PrivilegeAttributes;
  151. }
  152. }
  153. GetLuid(privilege);
  154. return PrivilegeAttributes.Removed;
  155. }
  156. internal static PrivilegeAndAttributesCollection GetPrivileges(AccessTokenHandle accessTokenHandle)
  157. {
  158. LuidAndAttributes[] luidAndAttributesArray = GetTokenPrivileges(accessTokenHandle);
  159. int length = luidAndAttributesArray.Length;
  160. List<PrivilegeAndAttributes> privilegeAndAttributes = new List<PrivilegeAndAttributes>(length);
  161. for (int i = 0; i < length; i++)
  162. {
  163. LuidAndAttributes luidAndAttributes = luidAndAttributesArray[i];
  164. string name = GetPrivilegeName(luidAndAttributes.Luid);
  165. if (privilegesDictionary.ContainsKey(name))
  166. {
  167. privilegeAndAttributes.Add(new PrivilegeAndAttributes(
  168. privilegesDictionary[name],
  169. luidAndAttributes.Attributes));
  170. }
  171. }
  172. return new PrivilegeAndAttributesCollection(privilegeAndAttributes);
  173. }
  174. private static AdjustPrivilegeResult AdjustPrivilege(
  175. AccessTokenHandle accessTokenHandle,
  176. Luid luid,
  177. PrivilegeAttributes privilegeAttributes)
  178. {
  179. TokenPrivilege newState = new TokenPrivilege
  180. {
  181. PrivilegeCount = 1,
  182. Privilege = new LuidAndAttributes
  183. {
  184. Attributes = privilegeAttributes,
  185. Luid = luid
  186. }
  187. };
  188. TokenPrivilege previousState = new TokenPrivilege();
  189. int returnLength = 0;
  190. if (!NativeMethods.AdjustTokenPrivileges(
  191. accessTokenHandle,
  192. false,
  193. ref newState,
  194. Marshal.SizeOf(previousState),
  195. ref previousState,
  196. ref returnLength))
  197. {
  198. throw new Win32Exception(Marshal.GetLastWin32Error());
  199. }
  200. return (AdjustPrivilegeResult)previousState.PrivilegeCount;
  201. }
  202. private static AdjustPrivilegeResult AdjustPrivilege(
  203. AccessTokenHandle accessTokenHandle,
  204. Privilege privilege,
  205. PrivilegeAttributes privilegeAttributes)
  206. {
  207. return AdjustPrivilege(accessTokenHandle, GetLuid(privilege), privilegeAttributes);
  208. }
  209. private static Luid GetLuid(Privilege privilege)
  210. {
  211. if (luidDictionary.ContainsKey(privilege))
  212. {
  213. return luidDictionary[privilege];
  214. }
  215. Luid luid = new Luid();
  216. if (!NativeMethods.LookupPrivilegeValue(String.Empty, privilegeConstantsDictionary[privilege], ref luid))
  217. {
  218. throw new Win32Exception(Marshal.GetLastWin32Error());
  219. }
  220. luidDictionary.Add(privilege, luid);
  221. return luid;
  222. }
  223. private static string GetPrivilegeName(Luid luid)
  224. {
  225. StringBuilder nameBuilder = new StringBuilder();
  226. int nameLength = 0;
  227. if (NativeMethods.LookupPrivilegeName(String.Empty, ref luid, nameBuilder, ref nameLength))
  228. {
  229. return String.Empty;
  230. }
  231. int lastWin32Error = Marshal.GetLastWin32Error();
  232. if (lastWin32Error != NativeMethods.ErrorInsufficientBuffer)
  233. {
  234. throw new Win32Exception(lastWin32Error);
  235. }
  236. nameBuilder.EnsureCapacity(nameLength);
  237. if (!NativeMethods.LookupPrivilegeName(String.Empty, ref luid, nameBuilder, ref nameLength))
  238. {
  239. throw new Win32Exception(Marshal.GetLastWin32Error());
  240. }
  241. return nameBuilder.ToString();
  242. }
  243. private static LuidAndAttributes[] GetTokenPrivileges(AccessTokenHandle accessTokenHandle)
  244. {
  245. int tokenInformationLength = 0;
  246. int returnLength = 0;
  247. if (NativeMethods.GetTokenInformation(
  248. accessTokenHandle,
  249. TokenInformationClass.TokenPrivileges,
  250. IntPtr.Zero,
  251. tokenInformationLength,
  252. ref returnLength))
  253. {
  254. return new LuidAndAttributes[0];
  255. }
  256. int lastWin32Error = Marshal.GetLastWin32Error();
  257. if (lastWin32Error != NativeMethods.ErrorInsufficientBuffer)
  258. {
  259. throw new Win32Exception(lastWin32Error);
  260. }
  261. tokenInformationLength = returnLength;
  262. returnLength = 0;
  263. using (AllocatedMemory allocatedMemory = new AllocatedMemory(tokenInformationLength))
  264. {
  265. if (!NativeMethods.GetTokenInformation(
  266. accessTokenHandle,
  267. TokenInformationClass.TokenPrivileges,
  268. allocatedMemory.Pointer,
  269. tokenInformationLength,
  270. ref returnLength))
  271. {
  272. throw new Win32Exception(Marshal.GetLastWin32Error());
  273. }
  274. int privilegeCount = Marshal.ReadInt32(allocatedMemory.Pointer);
  275. LuidAndAttributes[] luidAndAttributes = new LuidAndAttributes[privilegeCount];
  276. long pointer = allocatedMemory.Pointer.ToInt64() + Marshal.SizeOf(privilegeCount);
  277. Type type = typeof(LuidAndAttributes);
  278. long size = Marshal.SizeOf(type);
  279. for (int i = 0; i < privilegeCount; i++)
  280. {
  281. luidAndAttributes[i] = (LuidAndAttributes)Marshal.PtrToStructure(new IntPtr(pointer), type);
  282. pointer += size;
  283. }
  284. return luidAndAttributes;
  285. }
  286. }
  287. }
  288. }