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.

495 lines
24 KiB

  1. /* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. * THE SOFTWARE.
  20. */
  21. using System;
  22. using System.ComponentModel;
  23. using System.Diagnostics.CodeAnalysis;
  24. using System.Runtime.InteropServices;
  25. using System.Security;
  26. using System.Text;
  27. namespace Alphaleonis.Win32.Security
  28. {
  29. /// <summary>Represents a privilege for an access token. The privileges available on the local machine are available as
  30. /// static instances from this class. To create a <see cref="Privilege"/> representing a privilege on another system,
  31. /// use the constructor specifying a system name together with one of these static instances.
  32. /// </summary>
  33. /// <seealso cref="PrivilegeEnabler"/>
  34. [ImmutableObject(true)]
  35. public class Privilege : IEquatable<Privilege>
  36. {
  37. #region System Privileges
  38. #region AssignPrimaryToken
  39. /// <summary>Required to assign the primary token of a process. User Right: Replace a process-level token.</summary>
  40. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  41. public static readonly Privilege AssignPrimaryToken = new Privilege("SeAssignPrimaryTokenPrivilege");
  42. #endregion // AssignPrimaryToken
  43. #region Audit
  44. /// <summary>Required to generate audit-log entries. Give this privilege to secure servers. User Right: Generate security audits.</summary>
  45. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  46. public static readonly Privilege Audit = new Privilege("SeAuditPrivilege");
  47. #endregion // Audit
  48. #region Backup
  49. /// <summary>Required to perform backup operations. This privilege causes the system to grant all read access control to any file, regardless of the access control list (ACL) specified for the file. Any access request other than read is still evaluated with the ACL. User Right: Back up files and directories.</summary>
  50. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  51. public static readonly Privilege Backup = new Privilege("SeBackupPrivilege");
  52. #endregion // Backup
  53. #region ChangeNotify
  54. /// <summary>Required to receive notifications of changes to files or directories. This privilege also causes the system to skip all traversal access checks. It is enabled by default for all users. User Right: Bypass traverse checking.</summary>
  55. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  56. public static readonly Privilege ChangeNotify = new Privilege("SeChangeNotifyPrivilege");
  57. #endregion // ChangeNotify
  58. #region CreateGlobal
  59. /// <summary>Required to create named file mapping objects in the global namespace during Terminal Services sessions. This privilege is enabled by default for administrators, services, and the local system account. User Right: Create global objects.</summary>
  60. /// <remarks>Windows XP/2000: This privilege is not supported. Note that this value is supported starting with Windows Server 2003, Windows XP SP2, and Windows 2000 SP4.</remarks>
  61. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  62. public static readonly Privilege CreateGlobal = new Privilege("SeCreateGlobalPrivilege");
  63. #endregion // CreateGlobal
  64. #region CreatePagefile
  65. /// <summary>Required to create a paging file. User Right: Create a pagefile.</summary>
  66. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pagefile")]
  67. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  68. public static readonly Privilege CreatePagefile = new Privilege("SeCreatePagefilePrivilege");
  69. #endregion // CreatePagefile
  70. #region CreatePermanent
  71. /// <summary>Required to create a permanent object. User Right: Create permanent shared objects.</summary>
  72. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  73. public static readonly Privilege CreatePermanent = new Privilege("SeCreatePermanentPrivilege");
  74. #endregion // CreatePermanent
  75. #region CreateSymbolicLink
  76. /// <summary>Required to create a symbolic link. User Right: Create symbolic links.</summary>
  77. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  78. public static readonly Privilege CreateSymbolicLink = new Privilege("SeCreateSymbolicLinkPrivilege");
  79. #endregion // CreateSymbolicLink
  80. #region CreateToken
  81. /// <summary>Required to create a primary token. User Right: Create a token object.</summary>
  82. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  83. public static readonly Privilege CreateToken = new Privilege("SeCreateTokenPrivilege");
  84. #endregion // CreateToken
  85. #region Debug
  86. /// <summary>Required to debug and adjust the memory of a process owned by another account. User Right: Debug programs.</summary>
  87. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  88. public static readonly Privilege Debug = new Privilege("SeDebugPrivilege");
  89. #endregion // Debug
  90. #region EnableDelegation
  91. /// <summary>Required to mark user and computer accounts as trusted for delegation. User Right: Enable computer and user accounts to be trusted for delegation.</summary>
  92. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  93. public static readonly Privilege EnableDelegation = new Privilege("SeEnableDelegationPrivilege");
  94. #endregion // EnableDelegation
  95. #region Impersonate
  96. /// <summary>Required to impersonate. User Right: Impersonate a client after authentication.</summary>
  97. /// <remarks>Windows XP/2000: This privilege is not supported. Note that this value is supported starting with Windows Server 2003, Windows XP SP2, and Windows 2000 SP4.</remarks>
  98. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  99. public static readonly Privilege Impersonate = new Privilege("SeImpersonatePrivilege");
  100. #endregion // Impersonate
  101. #region IncreaseBasePriority
  102. /// <summary>Required to increase the base priority of a process. User Right: Increase scheduling priority.</summary>
  103. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  104. public static readonly Privilege IncreaseBasePriority = new Privilege("SeIncreaseBasePriorityPrivilege");
  105. #endregion // IncreaseBasePriority
  106. #region IncreaseQuota
  107. /// <summary>Required to increase the quota assigned to a process. User Right: Adjust memory quotas for a process.</summary>
  108. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  109. public static readonly Privilege IncreaseQuota = new Privilege("SeIncreaseQuotaPrivilege");
  110. #endregion // IncreaseQuota
  111. #region IncreaseWorkingSet
  112. /// <summary>Required to allocate more memory for applications that run in the context of users. User Right: Increase a process working set.</summary>
  113. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  114. public static readonly Privilege IncreaseWorkingSet = new Privilege("SeIncreaseWorkingSetPrivilege");
  115. #endregion // IncreaseWorkingSet
  116. #region LoadDriver
  117. /// <summary>Required to load or unload a device driver. User Right: Load and unload device drivers.</summary>
  118. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  119. public static readonly Privilege LoadDriver = new Privilege("SeLoadDriverPrivilege");
  120. #endregion // LoadDriver
  121. #region LockMemory
  122. /// <summary>Required to lock physical pages in memory. User Right: Lock pages in memory.</summary>
  123. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  124. public static readonly Privilege LockMemory = new Privilege("SeLockMemoryPrivilege");
  125. #endregion // LockMemory
  126. #region MachineAccount
  127. /// <summary>Required to create a computer account. User Right: Add workstations to domain.</summary>
  128. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  129. public static readonly Privilege MachineAccount = new Privilege("SeMachineAccountPrivilege");
  130. #endregion // MachineAccount
  131. #region ManageVolume
  132. /// <summary>Required to enable volume management privileges. User Right: Manage the files on a volume.</summary>
  133. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  134. public static readonly Privilege ManageVolume = new Privilege("SeManageVolumePrivilege");
  135. #endregion // ManageVolume
  136. #region ProfileSingleProcess
  137. /// <summary>Required to gather profiling information for a single process. User Right: Profile single process.</summary>
  138. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  139. public static readonly Privilege ProfileSingleProcess = new Privilege("SeProfileSingleProcessPrivilege");
  140. #endregion // ProfileSingleProcess
  141. #region Relabel
  142. /// <summary>Required to modify the mandatory integrity level of an object. User Right: Modify an object label.</summary>
  143. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  144. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Relabel")]
  145. public static readonly Privilege Relabel = new Privilege("SeRelabelPrivilege");
  146. #endregion // Relabel
  147. #region RemoteShutdown
  148. /// <summary>Required to shut down a system using a network request. User Right: Force shutdown from a remote system.</summary>
  149. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  150. public static readonly Privilege RemoteShutdown = new Privilege("SeRemoteShutdownPrivilege");
  151. #endregion // RemoteShutdown
  152. #region Restore
  153. /// <summary>Required to perform restore operations. This privilege causes the system to grant all write access control to any file, regardless of the ACL specified for the file. Any access request other than write is still evaluated with the ACL. Additionally, this privilege enables you to set any valid user or group SID as the owner of a file. User Right: Restore files and directories.</summary>
  154. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  155. public static readonly Privilege Restore = new Privilege("SeRestorePrivilege");
  156. #endregion // Restore
  157. #region Security
  158. /// <summary>Required to perform a number of security-related functions, such as controlling and viewing audit messages. This privilege identifies its holder as a security operator. User Right: Manage auditing and security log.</summary>
  159. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  160. public static readonly Privilege Security = new Privilege("SeSecurityPrivilege");
  161. #endregion // Security
  162. #region Shutdown
  163. /// <summary>Required to shut down a local system. User Right: Shut down the system.</summary>
  164. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  165. public static readonly Privilege Shutdown = new Privilege("SeShutdownPrivilege");
  166. #endregion // Shutdown
  167. #region SyncAgent
  168. /// <summary>Required for a domain controller to use the LDAP directory synchronization services. This privilege enables the holder to read all objects and properties in the directory, regardless of the protection on the objects and properties. By default, it is assigned to the Administrator and LocalSystem accounts on domain controllers. User Right: Synchronize directory service data.</summary>
  169. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  170. public static readonly Privilege SyncAgent = new Privilege("SeSyncAgentPrivilege");
  171. #endregion // SyncAgent
  172. #region SystemEnvironment
  173. /// <summary>Required to modify the nonvolatile RAM of systems that use this type of memory to store configuration information. User Right: Modify firmware environment values.</summary>
  174. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  175. public static readonly Privilege SystemEnvironment = new Privilege("SeSystemEnvironmentPrivilege");
  176. #endregion // SystemEnvironment
  177. #region SystemProfile
  178. /// <summary>Required to gather profiling information for the entire system. User Right: Profile system performance.</summary>
  179. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  180. public static readonly Privilege SystemProfile = new Privilege("SeSystemProfilePrivilege");
  181. #endregion // SystemProfile
  182. #region SystemTime
  183. /// <summary>Required to modify the system time. User Right: Change the system time.</summary>
  184. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  185. public static readonly Privilege SystemTime = new Privilege("SeSystemtimePrivilege");
  186. #endregion // SystemTime
  187. #region TakeOwnership
  188. /// <summary>Required to take ownership of an object without being granted discretionary access. This privilege allows the owner value to be set only to those values that the holder may legitimately assign as the owner of an object. User Right: Take ownership of files or other objects.</summary>
  189. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  190. public static readonly Privilege TakeOwnership = new Privilege("SeTakeOwnershipPrivilege");
  191. #endregion // TakeOwnership
  192. #region Tcb
  193. /// <summary>This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege. User Right: Act as part of the operating system.</summary>
  194. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  195. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tcb")]
  196. public static readonly Privilege Tcb = new Privilege("SeTcbPrivilege");
  197. #endregion // Tcb
  198. #region TimeZone
  199. /// <summary>Required to adjust the time zone associated with the computer's internal clock. User Right: Change the time zone.</summary>
  200. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  201. public static readonly Privilege TimeZone = new Privilege("SeTimeZonePrivilege");
  202. #endregion // TimeZone
  203. #region TrustedCredManAccess
  204. /// <summary>Required to access Credential Manager as a trusted caller. User Right: Access Credential Manager as a trusted caller.</summary>
  205. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]
  206. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  207. public static readonly Privilege TrustedCredManAccess = new Privilege("SeTrustedCredManAccessPrivilege");
  208. #endregion // TrustedCredManAccess
  209. #region Undock
  210. /// <summary>Required to undock a laptop. User Right: Remove computer from docking station.</summary>
  211. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  212. public static readonly Privilege Undock = new Privilege("SeUndockPrivilege");
  213. #endregion // Undock
  214. #region UnsolicitedInput
  215. /// <summary>Required to read unsolicited input from a terminal device. User Right: Not applicable.</summary>
  216. [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  217. public static readonly Privilege UnsolicitedInput = new Privilege("SeUnsolicitedInputPrivilege");
  218. #endregion // UnsolicitedInput
  219. #endregion // System Privileges
  220. #region Privilege
  221. private readonly string _systemName;
  222. /// <summary>Create a new <see cref="Privilege"/> representing the specified privilege on the specified system.</summary>
  223. /// <param name="systemName">Name of the system.</param>
  224. /// <param name="privilege">The privilege to copy the privilege name from.</param>
  225. public Privilege(string systemName, Privilege privilege)
  226. {
  227. if (Utils.IsNullOrWhiteSpace(systemName))
  228. throw new ArgumentException(Resources.Privilege_Name_Cannot_Be_Empty, "systemName");
  229. _systemName = systemName;
  230. if (privilege != null)
  231. _name = privilege._name;
  232. }
  233. #endregion // Privilege
  234. #region Name
  235. private readonly string _name;
  236. /// <summary>Gets the system name identifying this privilege.</summary>
  237. /// <value>The system name identifying this privilege.</value>
  238. public string Name
  239. {
  240. get { return _name; }
  241. }
  242. #endregion // Name
  243. #region LookupDisplayName
  244. /// <summary>Retrieves the display name that represents this privilege.</summary>
  245. /// <returns>The display name that represents this privilege.</returns>
  246. [SecurityCritical]
  247. public string LookupDisplayName()
  248. {
  249. const uint initialCapacity = 10;
  250. uint displayNameCapacity = initialCapacity;
  251. StringBuilder displayName = new StringBuilder((int) displayNameCapacity);
  252. uint languageId;
  253. if (!NativeMethods.LookupPrivilegeDisplayName(_systemName, _name, ref displayName, ref displayNameCapacity, out languageId))
  254. {
  255. int lastError = Marshal.GetLastWin32Error();
  256. if (lastError == Win32Errors.ERROR_INSUFFICIENT_BUFFER)
  257. {
  258. displayName = new StringBuilder((int) displayNameCapacity + 1);
  259. if (!NativeMethods.LookupPrivilegeDisplayName(_systemName, _name, ref displayName, ref displayNameCapacity, out languageId))
  260. NativeError.ThrowException(Marshal.GetLastWin32Error());
  261. }
  262. else
  263. NativeError.ThrowException(lastError);
  264. }
  265. return displayName.ToString();
  266. }
  267. #endregion // LookupDisplayName
  268. #region LookupLuid
  269. /// <summary>Retrieves the locally unique identifier (LUID) used on to represent this privilege (on the system from which it originates).</summary>
  270. /// <returns>the locally unique identifier (LUID) used on to represent this privilege (on the system from which it originates).</returns>
  271. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Luid")]
  272. [SecurityCritical]
  273. public long LookupLuid()
  274. {
  275. Luid luid;
  276. if (!NativeMethods.LookupPrivilegeValue(_systemName, _name, out luid))
  277. NativeError.ThrowException(Marshal.GetLastWin32Error());
  278. return Filesystem.NativeMethods.LuidToLong(luid);
  279. }
  280. #endregion // LookupLuid
  281. #region Equals
  282. /// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
  283. /// <param name="other">An object to compare with this object.</param>
  284. /// <returns><see langword="true"/> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <see langword="false"/>.</returns>
  285. public bool Equals(Privilege other)
  286. {
  287. if (other == null)
  288. return false;
  289. return _name.Equals(other._name, StringComparison.OrdinalIgnoreCase) &&
  290. ((_systemName == null && other._systemName == null) ||
  291. (_systemName != null && _systemName.Equals(other._systemName, StringComparison.OrdinalIgnoreCase)));
  292. }
  293. /// <summary>Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="System.Object"/>.</summary>
  294. /// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="System.Object"/>.</param>
  295. /// <returns><see langword="true"/> if the specified <see cref="System.Object"/> is equal to the current <see cref="System.Object"/>; otherwise, <see langword="false"/>.</returns>
  296. /// <exception cref="NullReferenceException"/>
  297. public override bool Equals(object obj)
  298. {
  299. Privilege other = obj as Privilege;
  300. if (other == null)
  301. return false;
  302. return _name.Equals(other._name, StringComparison.OrdinalIgnoreCase) &&
  303. ((_systemName == null && other._systemName == null) ||
  304. (_systemName != null && _systemName.Equals(other._systemName, StringComparison.OrdinalIgnoreCase)));
  305. }
  306. #endregion // Equals
  307. #region GetHashCode
  308. // A random prime number will be picked and added to the HashCode, each time an instance is created.
  309. [NonSerialized] private readonly int _random = new Random().Next(0, 19);
  310. [NonSerialized] private static readonly int[] Primes = { 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919 };
  311. /// <summary>Serves as a hash function for a particular type.</summary>
  312. /// <returns>A hash code for the current Object.</returns>
  313. public override int GetHashCode()
  314. {
  315. unchecked
  316. {
  317. int hash = Primes[_random];
  318. if (!Utils.IsNullOrWhiteSpace(_name))
  319. hash = hash * Primes[1] + _name.GetHashCode();
  320. if (!Utils.IsNullOrWhiteSpace(_systemName))
  321. hash = hash * Primes[1] + _systemName.GetHashCode();
  322. return hash;
  323. }
  324. }
  325. #endregion // GetHashCode
  326. #region ToString
  327. /// <summary>Returns the system name for this privilege.</summary>
  328. /// <remarks>This is equivalent to <see cref="Privilege.Name"/>.</remarks>
  329. /// <returns>A <see cref="System.String"/> that represents the current <see cref="System.Object"/>.</returns>
  330. public override string ToString()
  331. {
  332. return _name;
  333. }
  334. #endregion // ToString
  335. #region Privilege
  336. /// <summary>Initializes a new instance of the <see cref="Privilege"/> class, representing a privilege with the specified name on the local system.</summary>
  337. /// <param name="name">The name.</param>
  338. private Privilege(string name)
  339. {
  340. if (Utils.IsNullOrWhiteSpace(name))
  341. throw new ArgumentException(Resources.Privilege_Name_Cannot_Be_Empty, "name");
  342. _name = name;
  343. }
  344. #endregion // Privilege
  345. }
  346. }