private static extern int LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, out IntPtr PolicyHandle);
/// <summary> /// Creates a Security Identity from an object name (e.g. DOMAIN\AccountName) /// </summary> /// <param name="name">A security object name (i.e. a Computer, Account, or Group)</param> /// <returns>A populated Security Identity</returns> public static SecurityIdentity SecurityIdentityFromName(string name) { if (name == null) { throw new ArgumentNullException("name"); } if (name == "") { throw new ArgumentException("Argument 'name' cannot be the empty string.", "name"); } LSA_OBJECT_ATTRIBUTES attribs = new LSA_OBJECT_ATTRIBUTES(); attribs.Attributes = 0; attribs.ObjectName = IntPtr.Zero; attribs.RootDirectory = IntPtr.Zero; attribs.SecurityDescriptor = IntPtr.Zero; attribs.SecurityQualityOfService = IntPtr.Zero; attribs.Length = (uint)Marshal.SizeOf(attribs); IntPtr handle; int status = LsaOpenPolicy(IntPtr.Zero, ref attribs, ACCESS_MASK.POLICY_LOOKUP_NAMES, out handle); if (status != 0) { throw new ExternalException("Unable to Find Object: " + GetErrorMessage(LsaNtStatusToWinError(status))); } try { LSA_UNICODE_STRING nameString = new LSA_UNICODE_STRING(); nameString.Buffer = name; nameString.Length = (ushort)(name.Length * UnicodeEncoding.CharSize); nameString.MaxLength = (ushort)((name.Length * UnicodeEncoding.CharSize) + UnicodeEncoding.CharSize); IntPtr domains; IntPtr sids; status = LsaLookupNames2(handle, 0, 1, new[] { nameString }, out domains, out sids); if (status != 0) { throw new ExternalException("Unable to Find Object: " + GetErrorMessage(LsaNtStatusToWinError(status))); } try { SecurityIdentity secId = new SecurityIdentity(); LSA_TRANSLATED_SID2 lsaSid = (LSA_TRANSLATED_SID2)Marshal.PtrToStructure(sids, typeof(LSA_TRANSLATED_SID2)); IntPtr sidStruct = lsaSid.Sid; IntPtr sidString; // Get the SID string if (!ConvertSidToStringSid(sidStruct, out sidString)) { throw new ExternalException("Unable to Find Object: " + GetErrorMessage(GetLastError())); } try { // Marshal and store the SID string secId.sid = Marshal.PtrToStringAnsi(sidString); } finally { if (sidString != IntPtr.Zero) { LocalFree(sidString); } } // Check if the SID is a well known SID secId.wellKnownSidType = (WELL_KNOWN_SID_TYPE)Array.IndexOf(WellKnownSids, secId.sid); SID_NAME_USE nameUse; uint nameLen = 0; uint domainLen = 0; // Get the lengths for the object and domain names LookupAccountSid(null, sidStruct, IntPtr.Zero, ref nameLen, IntPtr.Zero, ref domainLen, out nameUse); if (nameLen == 0) { throw new ExternalException("Unable to Find SID: " + GetErrorMessage(GetLastError())); } IntPtr accountName = Marshal.AllocHGlobal((IntPtr)nameLen); IntPtr domainName = domainLen > 0 ? Marshal.AllocHGlobal((IntPtr)domainLen) : IntPtr.Zero; try { // Get the object and domain names if (!LookupAccountSid(null, sidStruct, accountName, ref nameLen, domainName, ref domainLen, out nameUse)) { throw new ExternalException("Unable to Find SID: " + GetErrorMessage(GetLastError())); } // Marshal and store the object name secId.name = string.Format("{0}{1}{2}", domainLen > 1 ? Marshal.PtrToStringAnsi(domainName) : "", domainLen > 1 ? "\\" : "", Marshal.PtrToStringAnsi(accountName)); return(secId); } finally { if (accountName != IntPtr.Zero) { Marshal.FreeHGlobal(accountName); } if (domainName != IntPtr.Zero) { Marshal.FreeHGlobal(domainName); } } } finally { if (domains != IntPtr.Zero) { LsaFreeMemory(domains); } if (sids != IntPtr.Zero) { LsaFreeMemory(sids); } } } finally { if (handle != IntPtr.Zero) { LsaClose(handle); } } }