public static void SetRights(string accountName, string privilegeName, bool enable) { if (accountName.StartsWith(".\\")) accountName = accountName.Substring(2); c_LSA_OBJECT_ATTRIBUTES lsaObjAttrs = new c_LSA_OBJECT_ATTRIBUTES(); lsaObjAttrs.Length = Marshal.SizeOf(lsaObjAttrs); IntPtr lsaPolicy = IntPtr.Zero, pAccSid = IntPtr.Zero, privilegeHandle = IntPtr.Zero; try { int status = LsaOpenPolicy(null, lsaObjAttrs, POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, out lsaPolicy); if (status != STATUS_SUCCESS) throw new Win32Exception(LsaNtStatusToWinError(status)); int cbSid = 128, cchRefDomain = 16; pAccSid = Marshal.AllocHGlobal(cbSid); StringBuilder refDomain = new StringBuilder(cchRefDomain); int sidNameUse, cbNextSid = cbSid, cchNextRefDomain = cchRefDomain; while (!LookupAccountName(null, accountName, pAccSid, ref cbNextSid, refDomain, ref cchNextRefDomain, out sidNameUse)) { if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) throw new Win32Exception(); if (cbSid < cbNextSid) { Marshal.ReAllocHGlobal(pAccSid, (IntPtr)cbNextSid); cbSid = cbNextSid; } if (cchRefDomain < cchNextRefDomain) { refDomain.EnsureCapacity(cchNextRefDomain); cchRefDomain = cchNextRefDomain; } } if (privilegeName.Length > 0x7FFE) throw new ArgumentOutOfRangeException(); privilegeHandle = Marshal.StringToHGlobalUni(privilegeName); s_LSA_UNICODE_STRING[] lsaPrivilege = new s_LSA_UNICODE_STRING[1]; lsaPrivilege[0] = new s_LSA_UNICODE_STRING(); lsaPrivilege[0].Buffer = privilegeHandle; lsaPrivilege[0].Length = (ushort)(privilegeName.Length * UnicodeEncoding.CharSize); lsaPrivilege[0].MaximumLength = (ushort)((privilegeName.Length + 1) * UnicodeEncoding.CharSize); if (enable) status = LsaAddAccountRights(lsaPolicy, pAccSid, lsaPrivilege, lsaPrivilege.Length); else status = LsaRemoveAccountRights(lsaPolicy, pAccSid, 0, lsaPrivilege, lsaPrivilege.Length); if (status != STATUS_SUCCESS) throw new Win32Exception(LsaNtStatusToWinError(status)); } finally { if (privilegeHandle != IntPtr.Zero) Marshal.FreeHGlobal(privilegeHandle); if (pAccSid != IntPtr.Zero) Marshal.FreeHGlobal(pAccSid); if (lsaPolicy != IntPtr.Zero) LsaClose(lsaPolicy); } }
private static extern int LsaOpenPolicy([In] c_LSA_UNICODE_STRING SystemName, [In] c_LSA_OBJECT_ATTRIBUTES ObjectAttributes, [In] uint DesiredAccess, [Out] out IntPtr PolicyHandle);