예제 #1
0
        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);
            }
        }
예제 #2
0
    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);
            }
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
 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}");
                }
            }
        }
예제 #8
0
            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);
            }
예제 #9
0
        // 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
     );
예제 #12
0
        /// <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;
        }
예제 #13
0
 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);
 }
예제 #14
0
 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);
 }
예제 #15
0
        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);
        }
예제 #16
0
        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
     );
예제 #18
0
            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);
            }
예제 #19
0
            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());
            }
예제 #20
0
            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);
        }
예제 #22
0
파일: Win32Sec.cs 프로젝트: ndubul/Chillas
    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);
    }
예제 #23
0
        /// <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));
        }
예제 #24
0
파일: Win32Sec.cs 프로젝트: ndubul/Chillas
    /// <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);
    }
예제 #25
0
        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);
        }
예제 #26
0
            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);
        }
예제 #28
0
        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);
        }
예제 #29
0
        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));
                }
            }
        }
예제 #32
0
 private static extern UInt32 LsaOpenPolicy(
     ref LSA_UNICODE_STRING SystemName,
     ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
     Int32 DesiredAccess,
     out IntPtr PolicyHandle
 );
예제 #33
0
        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;
        }
예제 #34
0
    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;
    }
예제 #35
0
 /// <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);
 }
예제 #36
0
 internal static extern uint LsaOpenPolicy(
    ref LSA_UNICODE_STRING systemName,
    ref LSA_OBJECT_ATTRIBUTES objectAttributes,
    uint desiredAccess,
    out IntPtr policyHandle);
예제 #37
0
 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);
예제 #39
0
 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);
 }
예제 #40
0
 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);
예제 #42
0
 internal static extern uint LsaEnumerateAccountsWithUserRight(
     LSA_HANDLE PolicyHandle,
     LSA_UNICODE_STRING[] UserRights,
     out IntPtr EnumerationBuffer,
     out ulong CountReturned
     );
예제 #43
0
 internal static extern uint LsaOpenPolicy(
     LSA_UNICODE_STRING[] SystemName,
     ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
     int AccessMask,
     out LSA_HANDLE PolicyHandle
     );
예제 #44
0
 /// <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;
 }
예제 #45
0
 private static extern long LsaAddAccountRights(
     IntPtr PolicyHandle,
     IntPtr AccountSid,
     LSA_UNICODE_STRING[] UserRights,
     long CountOfRights);
예제 #46
0
            // 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));
            }
예제 #47
0
 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
     );
예제 #49
0
 internal static extern uint LsaOpenSecret(
     IntPtr policyHandle,
     ref LSA_UNICODE_STRING secretName,
     uint accessMask,
     out IntPtr secretHandle);
예제 #50
0
    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;
    }
예제 #51
0
 internal static extern uint LsaSetSecret(
     IntPtr secretHandle,
     ref LSA_UNICODE_STRING currentValue,
     ref LSA_UNICODE_STRING oldValue);
예제 #52
0
            // 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;
            }
예제 #53
0
        /// <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;
        }
예제 #54
0
 /// <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));
     }
 }
예제 #55
0
 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);
 }
예제 #56
0
 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);
예제 #58
0
 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;
 }
예제 #59
0
    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;
    }
예제 #60
0
        /// <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;
        }