public LSASecret(string key) { secretName = new LSA_UNICODE_STRING() { Buffer = Marshal.StringToHGlobalUni(key), Length = (ushort)(key.Length * 2), MaximumLength = (ushort)((key.Length + 1) * 2) }; var localsystem = default(LSA_UNICODE_STRING); var objectAttributes = default(LSA_OBJECT_ATTRIBUTES); var winErrorCode = LsaNtStatusToWinError( LsaOpenPolicy( ref localsystem, ref objectAttributes, POLICY_GET_PRIVATE_INFORMATION, out lsaPolicyHandle ) ); if (winErrorCode != 0) { throw new Win32Exception(winErrorCode); } }
private IEnumerable <string> FetchSchedulerGroups() { var privileges = new LSA_UNICODE_STRING[1]; privileges[0] = InitLsaString("SeBatchLogonRight"); IntPtr buffer; int count; uint ret = Win32Sec.LsaEnumerateAccountsWithUserRight(lsaHandle, privileges, out buffer, out count); var accounts = new List <String>(); if (ret == 0) { var LsaInfo = new LSA_ENUMERATION_INFORMATION[count]; for (int i = 0, elemOffs = (int)buffer; i < count; i++) { LsaInfo[i] = (LSA_ENUMERATION_INFORMATION) Marshal.PtrToStructure((IntPtr)elemOffs, typeof(LSA_ENUMERATION_INFORMATION)); elemOffs += Marshal.SizeOf(typeof(LSA_ENUMERATION_INFORMATION)); var SID = new SecurityIdentifier(LsaInfo[i].PSid); accounts.Add(ResolveAccountName(SID)); } } return(accounts); }
public LsaPolicy() { LSA_UNICODE_STRING system = new LSA_UNICODE_STRING(); LSA_OBJECT_ATTRIBUTES attrib = new LSA_OBJECT_ATTRIBUTES() { Length = 0, RootDirectory = IntPtr.Zero, Attributes = 0, SecurityDescriptor = IntPtr.Zero, SecurityQualityOfService = IntPtr.Zero, }; IntPtr handle = IntPtr.Zero; uint result = LsaOpenPolicy(ref system, ref attrib, LSA_POLICY_ALL_ACCESS, out handle); if (result != 0 || handle == IntPtr.Zero) { if (result == ReturnCode.STATUS_ACCESS_DENIED) { throw new Exception(StringUtil.Loc("ShouldBeAdmin")); } throw new Exception(StringUtil.Loc("OperationFailed", nameof(LsaOpenPolicy), result)); } Handle = handle; }
public static void SetValue(string key, string?value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (key.Length == 0) { throw new ArgumentException($"{nameof(key)} must not be empty", nameof(key)); } var objectAttributes = new LSA_OBJECT_ATTRIBUTES(); var localsystem = new LSA_UNICODE_STRING(); var secretName = new LSA_UNICODE_STRING(key); var lusSecretData = !string.IsNullOrEmpty(value) ? new LSA_UNICODE_STRING(value) : default; var lsaPolicyHandle = GetLsaPolicy(ref objectAttributes, ref localsystem); var result = LsaStorePrivateData(lsaPolicyHandle, ref secretName, ref lusSecretData); ReleaseLsaPolicy(lsaPolicyHandle); var winErrorCode = LsaNtStatusToWinError(result); if (winErrorCode != 0) { throw new Win32Exception(winErrorCode, "StorePrivateData failed: " + winErrorCode); } }
public void SetSecret(string value) { LSA_UNICODE_STRING lusSecretData = new LSA_UNICODE_STRING(); if (value.Length > 0) { //Create data and key lusSecretData.Buffer = Marshal.StringToHGlobalUni(value); lusSecretData.Length = (UInt16)(value.Length * UnicodeEncoding.CharSize); lusSecretData.MaximumLength = (UInt16)((value.Length + 1) * UnicodeEncoding.CharSize); } else { //Delete data and key lusSecretData.Buffer = IntPtr.Zero; lusSecretData.Length = 0; lusSecretData.MaximumLength = 0; } IntPtr LsaPolicyHandle = GetLsaPolicy(LSA_AccessPolicy.POLICY_CREATE_SECRET); uint result = LsaStorePrivateData(LsaPolicyHandle, ref secretName, ref lusSecretData); ReleaseLsaPolicy(LsaPolicyHandle); uint winErrorCode = LsaNtStatusToWinError(result); if (winErrorCode != 0) { throw new Exception("StorePrivateData failed: " + winErrorCode); } }
private static extern uint LsaRemoveAccountRights( IntPtr PolicyHandle, IntPtr AccountSid, [MarshalAs(UnmanagedType.U1)] bool AllRights, LSA_UNICODE_STRING[] UserRights, uint CountOfRights);
private void LookupAccount(string accountName, ref IntPtr sid, ref IntPtr policyHandle) { int sidSize = 0; var domainName = new StringBuilder(); int nameSize = 0; int accountType = 0; LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); domainName = new StringBuilder(nameSize); sid = Marshal.AllocHGlobal(sidSize); if (!LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType)) { var winErrorCode = (int)GetLastError(); throw new Win32Exception(winErrorCode, $"LookupAccountName failed: {winErrorCode}"); } else { var systemName = new LSA_UNICODE_STRING(); var objectAttributes = CreateLSAObject(); uint resultPolicy = LsaOpenPolicy(ref systemName, ref objectAttributes, Access, out policyHandle); var winErrorCode = LsaNtStatusToWinError(resultPolicy); if (winErrorCode != 0) { throw new Win32Exception((int)winErrorCode, $"OpenPolicy failed: {winErrorCode}"); } } }
public static List <String> getAccessTokens(String sidString) { List <String> tokens = new List <String>(); IntPtr sid = IntPtr.Zero; if (!ConvertStringSidToSid(sidString, out sid)) { int errorCode = GetLastError(); switch (errorCode) { case ERROR_FILE_NOT_FOUND: // no such user? return(tokens); default: throw new System.ComponentModel.Win32Exception(errorCode); } } IntPtr policyHandle = IntPtr.Zero; LSA_OBJECT_ATTRIBUTES objAttrs = new LSA_OBJECT_ATTRIBUTES(); int mode = POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION; uint result = LsaNtStatusToWinError(LsaOpenPolicy(null, ref objAttrs, mode, out policyHandle)); if (result != 0) { Marshal.FreeHGlobal(sid); throw new System.ComponentModel.Win32Exception((int)result); } IntPtr rightsArray = IntPtr.Zero; UInt32 rightsLen = 0; result = LsaNtStatusToWinError(LsaEnumerateAccountRights(policyHandle, sid, out rightsArray, out rightsLen)); Marshal.FreeHGlobal(sid); switch ((int)result) { case ERROR_SUCCESS: LSA_UNICODE_STRING myLsaus = new LSA_UNICODE_STRING(); for (ulong i = 0; i < rightsLen; i++) { IntPtr itemAddr = new IntPtr(rightsArray.ToInt64() + (long)(i * (ulong)Marshal.SizeOf(myLsaus))); myLsaus = (LSA_UNICODE_STRING)Marshal.PtrToStructure(itemAddr, myLsaus.GetType()); String thisRight = LSAUS2string(myLsaus); tokens.Add(thisRight); } break; case ERROR_FILE_NOT_FOUND: // no account rights were found for the user break; default: LsaClose(policyHandle); throw new System.ComponentModel.Win32Exception((int)result); } LsaClose(policyHandle); return(tokens); }
// Adds a privilege to an account public void SetRight(string accountName, string privilegeName) { long winErrorCode = 0; string errorMessage = string.Empty; IntPtr sid = IntPtr.Zero; int sidSize = 0; StringBuilder domainName = new StringBuilder(); int nameSize = 0; int accountType = 0; LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); domainName = new StringBuilder(nameSize); sid = Marshal.AllocHGlobal(sidSize); if (!LookupAccountName(string.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType)) { winErrorCode = GetLastError(); errorMessage = string.Format("LookupAccountName failed: {0}", winErrorCode); } else { LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING(); IntPtr policyHandle = IntPtr.Zero; LSA_OBJECT_ATTRIBUTES objectAttributes = CreateLSAObject(); uint resultPolicy = LsaOpenPolicy(ref systemName, ref objectAttributes, Access, out policyHandle); winErrorCode = LsaNtStatusToWinError(Convert.ToInt32(resultPolicy)); if (winErrorCode != 0) { errorMessage = string.Format("OpenPolicy failed: {0} ", winErrorCode); } else { LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[1]; userRights[0] = new LSA_UNICODE_STRING(); userRights[0].Buffer = Marshal.StringToHGlobalUni(privilegeName); userRights[0].Length = (UInt16)(privilegeName.Length * UnicodeEncoding.CharSize); userRights[0].MaximumLength = (UInt16)((privilegeName.Length + 1) * UnicodeEncoding.CharSize); int res = LsaAddAccountRights(policyHandle, sid, userRights, 1); winErrorCode = LsaNtStatusToWinError(Convert.ToInt32(res)); if (winErrorCode != 0) { errorMessage = string.Format("LsaAddAccountRights failed: {0}", winErrorCode); } LsaClose(policyHandle); } FreeSid(sid); } if (winErrorCode > 0) { throw new ApplicationException(string.Format("Failed to add right {0} to {1}. Error detail:{2}", accountName, privilegeName, errorMessage)); } }
private unsafe static extern int LsaStorePrivateData( [In] System.IntPtr PolicyHandle, [In] ref LSA_UNICODE_STRING KeyName, [In] ref LSA_UNICODE_STRING PrivateData );
private unsafe static extern int LsaRetrievePrivateData( [In] System.IntPtr PolicyHandle, [In] ref LSA_UNICODE_STRING KeyName, [Out] out void *PrivateData );
/// <summary>Initializes a new instance of the <see cref="LocalSecurity"/> class.</summary> /// <param name="server">The server. Use <c>null</c> for the local server.</param> /// <param name="accessRights">The access rights mask for the actions to be taken.</param> /// <exception cref="System.ComponentModel.Win32Exception"></exception> public LocalSecurity(string server = null, LsaPolicyAccessRights accessRights = LsaPolicyAccessRights.AllAccess) { LSA_UNICODE_STRING systemName = server; LSA_OBJECT_ATTRIBUTES objectAttributes = LSA_OBJECT_ATTRIBUTES.Empty; ThrowIfLsaError(LsaOpenPolicy(systemName, ref objectAttributes, 0x000F0000 | (int)accessRights, out handle)); // Add in STANDARD_RIGHTS_REQUIRED svr = server; }
private static LSA_UNICODE_STRING[] StringsToLsaStrings(string[] privileges) { LSA_UNICODE_STRING[] lsaPrivileges = new LSA_UNICODE_STRING[privileges.Length]; for (int idx = 0; idx < privileges.Length; ++idx) { lsaPrivileges[idx] = new LSA_UNICODE_STRING(privileges[idx]); } return(lsaPrivileges); }
public object MarshalNativeToManaged(System.IntPtr pNativeData) { if (pNativeData != IntPtr.Zero) { LSA_UNICODE_STRING lus = (LSA_UNICODE_STRING)Marshal.PtrToStructure(pNativeData, typeof(LSA_UNICODE_STRING)); return(lus.ToString()); } return(null); }
public static LSA_UNICODE_STRING string2LSAUS(string myString) { LSA_UNICODE_STRING retStr = new LSA_UNICODE_STRING(); retStr.Buffer = Marshal.StringToHGlobalUni(myString); retStr.Length = (UInt16)((myString.Length + 1) * UnicodeEncoding.CharSize); retStr.MaximumLength = retStr.Length; return(retStr); }
private static System.Collections.Specialized.StringCollection GetRights(System.Security.Principal.WindowsIdentity identity) { System.Collections.Specialized.StringCollection rights = new System.Collections.Specialized.StringCollection(); LSA_OBJECT_ATTRIBUTES objectAttributes = CreateLSAObjectAttributes(); IntPtr policyHandle = IntPtr.Zero; LSA_UNICODE_STRING SystemName = new LSA_UNICODE_STRING(); /* * SystemName.Length = (ushort)(System.Environment.MachineName.Length * System.Text.UnicodeEncoding.CharSize); * SystemName.MaximumLength = (ushort)((System.Environment.MachineName.Length + 1) * System.Text.UnicodeEncoding.CharSize); * SystemName.Buffer = System.Environment.MachineName; // Marshal.StringToHGlobalUni(System.Environment.MachineName); */ // Open a policy handle on the remote PC. uint ret = LsaOpenPolicy(ref SystemName, ref objectAttributes, (int)POLICY_ALL_ACCESS, out policyHandle); if (ret == 0) { //long winErrorCode = 0; //IntPtr sid = IntPtr.Zero; //int sidSize = 0; //System.Text.StringBuilder domainName = new System.Text.StringBuilder(); //int nameSize = 0; //int accountType = 0; long winErrorCode = 0; IntPtr userRightsPtr = IntPtr.Zero; int countOfRights = 0; byte[] accountSidBytes = new byte[identity.User.BinaryLength]; identity.User.GetBinaryForm(accountSidBytes, 0); int result = LsaEnumerateAccountRights(policyHandle, accountSidBytes, out userRightsPtr, out countOfRights); winErrorCode = LsaNtStatusToWinError(result); if (winErrorCode == 0) { long current = userRightsPtr.ToInt64(); LSA_UNICODE_STRING userRight; for (int i = 0; i < countOfRights; i++) { userRight = (LSA_UNICODE_STRING)Marshal.PtrToStructure(new IntPtr(current), typeof(LSA_UNICODE_STRING)); string userRightStr = Marshal.PtrToStringAuto(userRight.Buffer); rights.Add(userRightStr); current += Marshal.SizeOf(userRight); } } LsaClose(policyHandle); } return(rights); }
private unsafe static extern int LsaOpenPolicy( [In] ref LSA_UNICODE_STRING SystemName, [In, MarshalAs(UnmanagedType.LPStruct)] LSA_OBJECT_ATTRIBUTES Attributes, [In] System.UInt32 DesiredAccess, [Out] out System.IntPtr PolicyHandle );
public System.IntPtr MarshalManagedToNative(object ManagedObj) { LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING(); IntPtr memory = Marshal.AllocHGlobal(nativeSize); myAllocated[memory] = memory; //Console.WriteLine("MarshalManagedToNative"); lus.SetTo((string)ManagedObj); Marshal.StructureToPtr(lus, memory, true); return(memory); }
public IntPtr MarshalManagedToNative(object ManagedObj) { var s = ManagedObj as string; if (s == null) { return(IntPtr.Zero); } var str = new LSA_UNICODE_STRING(s); return(str.StructureToPtr()); }
public void CleanUpNativeData(System.IntPtr pNativeData) { //Console.WriteLine("CCC Cleanup Native Data"); if (myAllocated.ContainsKey(pNativeData)) { myAllocated.Remove(pNativeData); LSA_UNICODE_STRING lus = (LSA_UNICODE_STRING)Marshal.PtrToStructure(pNativeData, typeof(LSA_UNICODE_STRING)); lus.Clean(); Marshal.FreeHGlobal(pNativeData); } }
internal unsafe string RetrieveEncryptedString() { System.IntPtr PolicyHandle; LSA_UNICODE_STRING PrivateKeyName = new LSA_UNICODE_STRING(); LSA_UNICODE_STRING NullString = new LSA_UNICODE_STRING(); int ReturnValue = 0; void * Secret = null; ushort *Data = null; string Result = String.Empty; NullString.Buffer = String.Empty; NullString.Length = NullString.MaximumLength = 0; ReturnValue = LsaOpenPolicy(ref NullString, new LSA_OBJECT_ATTRIBUTES(), POLICY_READ, out PolicyHandle); if (ReturnValue != 0) { ulong error = LsaNtStatusToWinError(ReturnValue); throw new System.Security.SecurityException("Unable to open the local LSA policy. " + error.ToString()); } PrivateKeyName.Buffer = PrivateKeyString; PrivateKeyName.Length = (ushort)(PrivateKeyName.Buffer.Length * 2); PrivateKeyName.MaximumLength = (ushort)((PrivateKeyName.Buffer.Length + 1) * 2); ReturnValue = LsaRetrievePrivateData(PolicyHandle, ref PrivateKeyName, out Secret); LsaClose(PolicyHandle); if (ReturnValue != 0) { ulong error = LsaNtStatusToWinError(ReturnValue); throw new System.Security.SecurityException("Unable to retrieve private data. " + error.ToString()); } Data = (ushort *)Secret; if (Data != null) { // The first ushort is the length; the second is the maxlength (buffer size). The // third is the pointer to the unicode string data. ushort *StringData = *((ushort **)(&(Data[2]))); int Length = (Data[0] / 2) - 1; // Length is in bytes, not unicode characters for (int i = 0; i <= Length; i++) { Result += Convert.ToChar(StringData[i]).ToString(); } } LsaFreeMemory(Secret); return(Result); }
public bool IsWindowsAuthorised(string privilege, string userName) { bool windowsAuthorised = false; userName = CleanUser(userName); var privileges = new LSA_UNICODE_STRING[1]; privileges[0] = InitLsaString(privilege); IntPtr buffer; ulong count; uint ret = Win32Sec.LsaEnumerateAccountsWithUserRight(lsaHandle, privileges, out buffer, out count); var Accounts = new List <String>(); if (ret == 0) { var LsaInfo = new LSA_ENUMERATION_INFORMATION[count]; LSA_ENUMERATION_INFORMATION myLsaus = new LSA_ENUMERATION_INFORMATION(); for (ulong i = 0; i < count; i++) { IntPtr itemAddr = new IntPtr(buffer.ToInt64() + (long)(i * (ulong)Marshal.SizeOf(myLsaus))); LsaInfo[i] = (LSA_ENUMERATION_INFORMATION)Marshal.PtrToStructure(itemAddr, myLsaus.GetType()); var SID = new SecurityIdentifier(LsaInfo[i].PSid); Accounts.Add(ResolveAccountName(SID)); } try { var wp = new WindowsPrincipal(new WindowsIdentity(userName)); foreach (string account in Accounts) { if (wp.IsInRole(account)) { windowsAuthorised = true; } } return(windowsAuthorised); } catch (Exception) { var localGroups = GetLocalUserGroupsForTaskSchedule(userName); var intersection = localGroups.Intersect(Accounts); return(intersection.Any()); } } return(false); }
/// <summary> /// Constructor for <see cref="LocalSecurityPolicy"/> /// </summary> /// <param name="systemName">local system if systemName is null</param> public LocalSecurityPolicy(string systemName) { lsaHandle = IntPtr.Zero; LSA_UNICODE_STRING system = InitLsaString(systemName); //combine all policies int access = (int)( LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN | LSA_AccessPolicy.POLICY_CREATE_ACCOUNT | LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE | LSA_AccessPolicy.POLICY_CREATE_SECRET | LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION | LSA_AccessPolicy.POLICY_LOOKUP_NAMES | LSA_AccessPolicy.POLICY_NOTIFICATION | LSA_AccessPolicy.POLICY_SERVER_ADMIN | LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS | LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS | LSA_AccessPolicy.POLICY_TRUST_ADMIN | LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION | LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION ); //initialize a pointer for the policy handle IntPtr policyHandle = IntPtr.Zero; //these attributes are not used, but LsaOpenPolicy wants them to exists LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES(); ObjectAttributes.Length = 0; ObjectAttributes.RootDirectory = IntPtr.Zero; ObjectAttributes.Attributes = 0; ObjectAttributes.SecurityDescriptor = IntPtr.Zero; ObjectAttributes.SecurityQualityOfService = IntPtr.Zero; //get a policy handle uint ret = LsaOpenPolicy(ref system, ref ObjectAttributes, access, out lsaHandle); if (ret == 0) { return; } if (ret == STATUS_ACCESS_DENIED) { throw new UnauthorizedAccessException(); } if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY)) { throw new OutOfMemoryException(); } throw new Win32Exception((int)LsaNtStatusToWinError(ret)); }
/// <summary> /// Converts the specified string to an LSA string value /// </summary> /// <param name="Value"></param> private static LSA_UNICODE_STRING InitLsaString(string Value) { if (Value.Length > 0x7ffe) { throw new ArgumentException("String too long"); } var lus = new LSA_UNICODE_STRING { Buffer = Value, Length = (ushort)(Value.Length * sizeof(char)) }; lus.MaximumLength = (ushort)(lus.Length + sizeof(char)); return(lus); }
static LSA_UNICODE_STRING InitLsaString(string lsaString) { // Unicode strings max. 32KB if (lsaString.Length > 0x7ffe) { throw new ArgumentException("String too long"); } LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING(); lus.Buffer = Marshal.StringToHGlobalUni(lsaString); lus.Length = (ushort)(lsaString.Length * sizeof(char)); lus.MaximumLength = (ushort)(lus.Length + sizeof(char)); return(lus); }
public IntPtr MarshalManagedToNative(object ManagedObj) { var s = ManagedObj as string; if (s == null) { return(IntPtr.Zero); } var str = new LSA_UNICODE_STRING(s); var ret = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(LSA_UNICODE_STRING))); Marshal.StructureToPtr(str, ret, false); return(ret); }
public static string GetValue(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (key.Length == 0) { throw new ArgumentException($"{nameof(key)} must not be empty", nameof(key)); } var objectAttributes = new LSA_OBJECT_ATTRIBUTES(); var localsystem = new LSA_UNICODE_STRING(); var secretName = new LSA_UNICODE_STRING(key); // Get LSA policy var lsaPolicyHandle = GetLsaPolicy(ref objectAttributes, ref localsystem); var result = LsaRetrievePrivateData(lsaPolicyHandle, ref secretName, out var privateData); ReleaseLsaPolicy(lsaPolicyHandle); if (result == STATUS_OBJECT_NAME_NOT_FOUND) { return(null); } var winErrorCode = LsaNtStatusToWinError(result); if (winErrorCode != 0) { throw new Win32Exception(winErrorCode, "LsaRetrievePrivateData failed: " + winErrorCode); } if (privateData == IntPtr.Zero) { return(null); } var lusSecretData = Marshal.PtrToStructure <LSA_UNICODE_STRING>(privateData); var value = Marshal.PtrToStringAuto(lusSecretData.Buffer).Substring(0, lusSecretData.Length / UnicodeEncoding.CharSize); FreeMemory(privateData); return(value); }
public bool IsUserHasLogonAsServicePrivilege(string domain, string userName) { Trace.Entering(); ArgUtil.NotNullOrEmpty(userName, nameof(userName)); bool userHasPermission = false; using (LsaPolicy lsaPolicy = new LsaPolicy()) { IntPtr rightsPtr; uint count; uint result = LsaEnumerateAccountRights(lsaPolicy.Handle, GetSidBinaryFromWindows(domain, userName), out rightsPtr, out count); try { if (result == 0) { IntPtr incrementPtr = rightsPtr; for (int i = 0; i < count; i++) { LSA_UNICODE_STRING nativeRightString = Marshal.PtrToStructure <LSA_UNICODE_STRING>(incrementPtr); string rightString = Marshal.PtrToStringUni(nativeRightString.Buffer); Trace.Verbose($"Account {userName} has '{rightString}' right."); if (string.Equals(rightString, s_logonAsServiceName, StringComparison.OrdinalIgnoreCase)) { userHasPermission = true; } incrementPtr += Marshal.SizeOf(nativeRightString); } } else { Trace.Error($"Can't enumerate account rights, return code {result}."); } } finally { result = LsaFreeMemory(rightsPtr); if (result != 0) { Trace.Error(StringUtil.Format("Failed to free memory from LsaEnumerateAccountRights. Return code : {0} ", result)); } } } return(userHasPermission); }
static void Main(string[] args) { // LsaOpenPolicy function opens a handle to the Policy object on a local or remote system. //initialize an empty unicode-string LSA_UNICODE_STRING aSystemName = new LSA_UNICODE_STRING(); //these attributes are not used, but LsaOpenPolicy wants them to exists LSA_OBJECT_ATTRIBUTES aObjectAttributes = new LSA_OBJECT_ATTRIBUTES(); //these attributes are not used, but LsaOpenPolicy wants them to exist // (MSDN: "the structure members are not used, initalize them to NULL or zero") LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES(); ObjectAttributes.Length = 0; ObjectAttributes.RootDirectory = IntPtr.Zero; ObjectAttributes.Attributes = 0; ObjectAttributes.SecurityDescriptor = IntPtr.Zero; ObjectAttributes.SecurityQualityOfService = IntPtr.Zero; // This was hard coded in keithga's binary - https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask uint access = 1; // A pointer to an LSA_HANDLE variable that receives a handle to the Policy object. IntPtr policy = IntPtr.Zero; //get a policy handle UInt32 resultPolicy = LsaOpenPolicy(ref aSystemName, ref ObjectAttributes, access, out policy); UInt32 winErrorCode = LsaNtStatusToWinError(resultPolicy); if (resultPolicy != 0) { Console.WriteLine("OpenPolicy failed: " + resultPolicy); } if (winErrorCode != 0) { Console.WriteLine("OpenPolicy Error: " + winErrorCode); } string result = RetrievePrivateData("DefaultPassword", policy); Console.WriteLine("AutoLogon Password: " + result); }
private static LSA_UNICODE_STRING InitLsaString(string s) { if (string.IsNullOrEmpty(s)) { return(new LSA_UNICODE_STRING()); } // Unicode strings max. 32KB if (s.Length > 0x7ffe) { throw new ArgumentException("String too long"); } LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING(); lus.Buffer = Marshal.StringToHGlobalUni(s); lus.Length = (UInt16)(s.Length * sizeof(char)); lus.MaximumLength = (UInt16)((s.Length + 1) * sizeof(char)); return(lus); }
public bool GrantUserLogonAsServicePrivilage(string domain, string userName) { Trace.Entering(); IntPtr lsaPolicyHandle = IntPtr.Zero; ArgUtil.NotNullOrEmpty(userName, nameof(userName)); try { LSA_UNICODE_STRING system = new LSA_UNICODE_STRING(); LSA_OBJECT_ATTRIBUTES attrib = new LSA_OBJECT_ATTRIBUTES() { Length = 0, RootDirectory = IntPtr.Zero, Attributes = 0, SecurityDescriptor = IntPtr.Zero, SecurityQualityOfService = IntPtr.Zero, }; uint result = LsaOpenPolicy(ref system, ref attrib, LSA_POLICY_ALL_ACCESS, out lsaPolicyHandle); if (result != 0 || lsaPolicyHandle == IntPtr.Zero) { if (result == ReturnCode.STATUS_ACCESS_DENIED) { throw new Exception(StringUtil.Loc("ShouldBeAdmin")); } throw new Exception(StringUtil.Loc("OperationFailed", nameof(LsaOpenPolicy), result)); } result = LsaAddAccountRights(lsaPolicyHandle, GetSidBinaryFromWindows(domain, userName), LogonAsServiceRights, 1); Trace.Info("LsaAddAccountRights return with error code {0} ", result); return(result == 0); } finally { int result = LsaClose(lsaPolicyHandle); if (result != 0) { Trace.Error(StringUtil.Format("Can not close LasPolicy handler. LsaClose failed with error code {0}", result)); } } }
private static extern UInt32 LsaOpenPolicy( ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, Int32 DesiredAccess, out IntPtr PolicyHandle );
private static LSA_UNICODE_STRING InitLsaString(string s) { if (string.IsNullOrEmpty(s)) return new LSA_UNICODE_STRING(); // Unicode strings max. 32KB if (s.Length > 0x7ffe) throw new ArgumentException("String too long"); LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING(); lus.Buffer = Marshal.StringToHGlobalUni(s); lus.Length = (UInt16)(s.Length * UnicodeEncoding.CharSize); lus.MaximumLength = (UInt16)((s.Length + 1) * UnicodeEncoding.CharSize); return lus; }
private IEnumerable<string> FetchSchedulerGroups() { var privileges = new LSA_UNICODE_STRING[1]; privileges[0] = InitLsaString("SeBatchLogonRight"); IntPtr buffer; ulong count; uint ret = Win32Sec.LsaEnumerateAccountsWithUserRight(lsaHandle, privileges, out buffer, out count); var accounts = new List<String>(); if (ret == 0) { var LsaInfo = new LSA_ENUMERATION_INFORMATION[count]; LSA_ENUMERATION_INFORMATION myLsaus = new LSA_ENUMERATION_INFORMATION(); for (ulong i = 0; i < count; i++) { IntPtr itemAddr = new IntPtr(buffer.ToInt64() + (long)(i * (ulong)Marshal.SizeOf(myLsaus))); LsaInfo[i] = (LSA_ENUMERATION_INFORMATION)Marshal.PtrToStructure(itemAddr, myLsaus.GetType()); var SID = new SecurityIdentifier(LsaInfo[i].PSid); accounts.Add(ResolveAccountName(SID)); } } return accounts; }
/// <summary> /// Initialize a LSA_UNICODE_STRING /// </summary> /// <param name="s"></param> /// <param name="lus"></param> /// <returns></returns> internal static void InitLsaString(string s, ref LSA_UNICODE_STRING lus) { // Unicode strings max 32KB. The max value for MaximumLength should be ushort.MaxValue-1 // because UnicodeEncoding.CharSize is 2. So the length of the string s should not be larger // than (ushort.MaxValue - 1)/UnicodeEncoding.CharSize - 1, which is 0x7ffe (32766) ushort maxLength = (ushort.MaxValue - 1) / UnicodeEncoding.CharSize - 1; if (s.Length > maxLength) throw new ArgumentException("String too long"); lus.Buffer = Marshal.StringToHGlobalUni(s); lus.Length = (ushort)(s.Length * UnicodeEncoding.CharSize); lus.MaximumLength = (ushort)((s.Length + 1) * UnicodeEncoding.CharSize); }
internal static extern uint LsaOpenPolicy( ref LSA_UNICODE_STRING systemName, ref LSA_OBJECT_ATTRIBUTES objectAttributes, uint desiredAccess, out IntPtr policyHandle);
internal static extern uint LsaCreateSecret( IntPtr policyHandle, ref LSA_UNICODE_STRING secretName, uint desiredAccess, out IntPtr secretHandle);
public static extern int LsaRemoveAccountRights(IntPtr policyHandle, byte[] accountSid, bool allRights, LSA_UNICODE_STRING userRights, int countOfRights);
public SecurityWrapper(string MachineName) { LSA_OBJECT_ATTRIBUTES lsaAttr; lsaAttr.RootDirectory = IntPtr.Zero; lsaAttr.ObjectName = IntPtr.Zero; lsaAttr.Attributes = 0; lsaAttr.SecurityDescriptor = IntPtr.Zero; lsaAttr.SecurityQualityOfService = IntPtr.Zero; lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES)); lsaHandle = IntPtr.Zero; LSA_UNICODE_STRING[] system = null; if (MachineName != null) { system = new LSA_UNICODE_STRING[1]; system[0] = InitLsaString(MachineName); } uint ret = Win32Sec.LsaOpenPolicy(system, ref lsaAttr, (int)Access.POLICY_ALL_ACCESS, out lsaHandle); TestReturnValue(ret); }
public static extern int LsaAddAccountRights(int PolicyHandle, int AccountSid, LSA_UNICODE_STRING[] UserRights, uint CountOfRights);
public static extern int LsaOpenPolicy(LSA_UNICODE_STRING systemName, IntPtr pointerObjectAttributes, int desiredAccess, out IntPtr pointerPolicyHandle);
internal static extern uint LsaEnumerateAccountsWithUserRight( LSA_HANDLE PolicyHandle, LSA_UNICODE_STRING[] UserRights, out IntPtr EnumerationBuffer, out ulong CountReturned );
internal static extern uint LsaOpenPolicy( LSA_UNICODE_STRING[] SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, int AccessMask, out LSA_HANDLE PolicyHandle );
/// <summary> /// Converts the specified string to an LSA string value /// </summary> /// <param name="Value"></param> private static LSA_UNICODE_STRING InitLsaString(string Value) { if (Value.Length > 0x7ffe) throw new ArgumentException("String too long"); var lus = new LSA_UNICODE_STRING { Buffer = Value, Length = (ushort)(Value.Length * sizeof(char)) }; lus.MaximumLength = (ushort)(lus.Length + sizeof(char)); return lus; }
private static extern long LsaAddAccountRights( IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights);
// local system if systemName is null public LsaWrapper(string systemName) { LSA_OBJECT_ATTRIBUTES lsaAttr; lsaAttr.RootDirectory = IntPtr.Zero; lsaAttr.ObjectName = IntPtr.Zero; lsaAttr.Attributes = 0; lsaAttr.SecurityDescriptor = IntPtr.Zero; lsaAttr.SecurityQualityOfService = IntPtr.Zero; lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES)); lsaHandle = IntPtr.Zero; LSA_UNICODE_STRING[] system = null; if (!ComputerManager.IsLocal(systemName)) { system = new LSA_UNICODE_STRING[1]; system[0] = InitLsaString(systemName); } uint ret = Win32Sec.LsaOpenPolicy(system, ref lsaAttr, (int)Access.POLICY_ALL_ACCESS, out lsaHandle); if (ret == 0) return; if (ret == STATUS_ACCESS_DENIED) { throw new UnauthorizedAccessException(); } if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY)) { throw new OutOfMemoryException(); } throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret)); }
public void AddPrivileges(string account, string privilege) { uint ret; using (Sid sid = new Sid(account)) { LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1]; privileges[0] = InitLsaString(privilege); ret = Win32Sec.LsaAddAccountRights(lsaHandle, sid.pSid, privileges, 1); } if (ret == 0) return; if (ret == STATUS_ACCESS_DENIED) { throw new UnauthorizedAccessException(); } if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY)) { throw new OutOfMemoryException(); } throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret)); }
public static extern int LsaGetAppliedCAPIDs( ref LSA_UNICODE_STRING systemName, ref IntPtr CAPIDs, out ULONG CAPIDCount );
internal static extern uint LsaOpenSecret( IntPtr policyHandle, ref LSA_UNICODE_STRING secretName, uint accessMask, out IntPtr secretHandle);
private IEnumerable<string> FetchSchedulerGroups() { var privileges = new LSA_UNICODE_STRING[1]; privileges[0] = InitLsaString("SeBatchLogonRight"); IntPtr buffer; int count; uint ret = Win32Sec.LsaEnumerateAccountsWithUserRight(lsaHandle, privileges, out buffer, out count); var accounts = new List<String>(); if (ret == 0) { var LsaInfo = new LSA_ENUMERATION_INFORMATION[count]; for (int i = 0, elemOffs = (int)buffer; i < count; i++) { LsaInfo[i] = (LSA_ENUMERATION_INFORMATION) Marshal.PtrToStructure((IntPtr)elemOffs, typeof(LSA_ENUMERATION_INFORMATION)); elemOffs += Marshal.SizeOf(typeof(LSA_ENUMERATION_INFORMATION)); var SID = new SecurityIdentifier(LsaInfo[i].PSid); accounts.Add(ResolveAccountName(SID)); } } return accounts; }
internal static extern uint LsaSetSecret( IntPtr secretHandle, ref LSA_UNICODE_STRING currentValue, ref LSA_UNICODE_STRING oldValue);
// helper functions static LSA_UNICODE_STRING InitLsaString(string s) { // Unicode strings max. 32KB if (s.Length > 0x7ffe) throw new ArgumentException("String too long"); LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING(); lus.Buffer = s; lus.Length = (ushort)(s.Length * sizeof(char)); lus.MaximumLength = (ushort)(lus.Length + sizeof(char)); return lus; }
/// <summary> /// Free the LSA_UNICODE_STRING /// </summary> /// <param name="s"></param> internal static void FreeLsaString(ref LSA_UNICODE_STRING s) { if (s.Buffer == IntPtr.Zero) return; Marshal.FreeHGlobal(s.Buffer); s.Buffer = IntPtr.Zero; }
/// <summary> /// Add privileges for the given account /// </summary> /// <param name="account">The account name (domain\userName)</param> /// <param name="privilege">The name of the privilege to add</param> public void AddPrivilege(string account, string privilege) { IntPtr pSid = GetSIDInformation(account); LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1]; privileges[0] = InitLsaString(privilege); long ret = LsaAddAccountRights(lsaHandle, pSid, privileges, 1); if (ret != 0)//ret = 0 Success { if (ret == STATUS_ACCESS_DENIED) throw new UnauthorizedAccessException(); if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY)) throw new OutOfMemoryException(); throw new Win32Exception((int)LsaNtStatusToWinError((int)ret)); } }
public static string LSAUS2string(LSA_UNICODE_STRING lsaus) { char[] cvt = new char[lsaus.Length / UnicodeEncoding.CharSize]; Marshal.Copy(lsaus.Buffer, cvt, 0, lsaus.Length / UnicodeEncoding.CharSize); return new string(cvt); }
internal static extern uint LsaAddAccountRights( LSA_HANDLE PolicyHandle, IntPtr pSID, LSA_UNICODE_STRING[] UserRights, int CountOfRights );
static extern uint LsaAddAccountRights( IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, uint CountOfRights);
public static LSA_UNICODE_STRING string2LSAUS(string myString) { LSA_UNICODE_STRING retStr = new LSA_UNICODE_STRING(); retStr.Buffer = Marshal.StringToHGlobalUni(myString); retStr.Length = (UInt16)((myString.Length + 1) * UnicodeEncoding.CharSize); retStr.MaximumLength = retStr.Length; return retStr; }
public bool IsWindowsAuthorised(string privilege, string userName) { bool windowsAuthorised = false; userName = CleanUser(userName); var privileges = new LSA_UNICODE_STRING[1]; privileges[0] = InitLsaString(privilege); IntPtr buffer; ulong count; uint ret = Win32Sec.LsaEnumerateAccountsWithUserRight(lsaHandle, privileges, out buffer, out count); var Accounts = new List<String>(); if (ret == 0) { var LsaInfo = new LSA_ENUMERATION_INFORMATION[count]; LSA_ENUMERATION_INFORMATION myLsaus = new LSA_ENUMERATION_INFORMATION(); for (ulong i = 0; i < count; i++) { IntPtr itemAddr = new IntPtr(buffer.ToInt64() + (long)(i * (ulong)Marshal.SizeOf(myLsaus))); LsaInfo[i] = (LSA_ENUMERATION_INFORMATION)Marshal.PtrToStructure(itemAddr, myLsaus.GetType()); var SID = new SecurityIdentifier(LsaInfo[i].PSid); Accounts.Add(ResolveAccountName(SID)); } try { var wp = new WindowsPrincipal(new WindowsIdentity(userName)); foreach (string account in Accounts) { if (wp.IsInRole(account)) { windowsAuthorised = true; } } return windowsAuthorised; } catch (Exception) { var localGroups = GetLocalUserGroupsForTaskSchedule(userName); var intersection = localGroups.Intersect(Accounts); return intersection.Any(); } } return false; }
/// <summary>Adds a privilege to an account</summary> /// <param name="accountName">Name of an account - "domain\account" or only "account"</param> /// <param name="privilegeName">Name ofthe privilege</param> /// <returns>The windows error code returned by LsaAddAccountRights</returns> public static long SetRight(String accountName, String privilegeName) { long winErrorCode = 0; //contains the last error //pointer an size for the SID IntPtr sid = IntPtr.Zero; int sidSize = 0; //StringBuilder and size for the domain name StringBuilder domainName = new StringBuilder(); int nameSize = 0; //account-type variable for lookup int accountType = 0; //get required buffer size LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); //allocate buffers domainName = new StringBuilder(nameSize); sid = Marshal.AllocHGlobal(sidSize); //lookup the SID for the account bool result = LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); //say what you're doing Console.WriteLine("LookupAccountName result = "+result); Console.WriteLine("IsValidSid: "+IsValidSid(sid)); Console.WriteLine("LookupAccountName domainName: "+domainName.ToString()); if( ! result ){ winErrorCode = GetLastError(); Console.WriteLine("LookupAccountName failed: "+ winErrorCode); }else{ //initialize an empty unicode-string LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING(); //combine all policies int access = (int)( LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN | LSA_AccessPolicy.POLICY_CREATE_ACCOUNT | LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE | LSA_AccessPolicy.POLICY_CREATE_SECRET | LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION | LSA_AccessPolicy.POLICY_LOOKUP_NAMES | LSA_AccessPolicy.POLICY_NOTIFICATION | LSA_AccessPolicy.POLICY_SERVER_ADMIN | LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS | LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS | LSA_AccessPolicy.POLICY_TRUST_ADMIN | LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION | LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION ); //initialize a pointer for the policy handle IntPtr policyHandle = IntPtr.Zero; //these attributes are not used, but LsaOpenPolicy wants them to exists LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES(); ObjectAttributes.Length = 0; ObjectAttributes.RootDirectory = IntPtr.Zero; ObjectAttributes.Attributes = 0; ObjectAttributes.SecurityDescriptor = IntPtr.Zero; ObjectAttributes.SecurityQualityOfService = IntPtr.Zero; //get a policy handle uint resultPolicy = LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle); winErrorCode = LsaNtStatusToWinError(resultPolicy); if(winErrorCode != 0){ Console.WriteLine("OpenPolicy failed: "+ winErrorCode); }else{ //Now that we have the SID an the policy, //we can add rights to the account. //initialize an unicode-string for the privilege name LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[1]; userRights[0] = new LSA_UNICODE_STRING(); userRights[0].Buffer = Marshal.StringToHGlobalUni(privilegeName); userRights[0].Length = (UInt16)( privilegeName.Length * UnicodeEncoding.CharSize ); userRights[0].MaximumLength = (UInt16)( (privilegeName.Length+1) * UnicodeEncoding.CharSize ); //add the right to the account long res = LsaAddAccountRights(policyHandle, sid, userRights, 1); winErrorCode = LsaNtStatusToWinError(res); if(winErrorCode != 0){ Console.WriteLine("LsaAddAccountRights failed: "+ winErrorCode); } LsaClose(policyHandle); } FreeSid(sid); } return winErrorCode; }