Example #1
0
        internal SidList(List <byte[]> sidListByteFormat, string target, NetCred credentials)
        {
            this.entries = new List <SidListEntry>();
            IntPtr zero  = IntPtr.Zero;
            int    count = sidListByteFormat.Count;

            IntPtr[] intPtr = new IntPtr[count];
            for (int i = 0; i < count; i++)
            {
                intPtr[i] = Utils.ConvertByteArrayToIntPtr(sidListByteFormat[i]);
            }
            try
            {
                if (credentials != null)
                {
                    Utils.BeginImpersonation(credentials, out zero);
                }
                this.TranslateSids(target, intPtr);
            }
            finally
            {
                if (zero != IntPtr.Zero)
                {
                    Utils.EndImpersonation(zero);
                }
            }
        }
Example #2
0
        internal static DirectoryEntry BuildDirectoryEntry(NetCred credentials, AuthenticationTypes authTypes)
        {
            string         userName;
            string         password;
            DirectoryEntry directoryEntry  = new DirectoryEntry();
            DirectoryEntry directoryEntry1 = directoryEntry;

            if (credentials != null)
            {
                userName = credentials.UserName;
            }
            else
            {
                userName = null;
            }
            directoryEntry1.Username = userName;
            DirectoryEntry directoryEntry2 = directoryEntry;

            if (credentials != null)
            {
                password = credentials.Password;
            }
            else
            {
                password = null;
            }
            directoryEntry2.Password          = password;
            directoryEntry.AuthenticationType = authTypes;
            return(directoryEntry);
        }
Example #3
0
        internal SidList(List<Byte[]> sidListByteFormat, string target, NetCred credentials)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: processing {0} ByteFormat SIDs", sidListByteFormat.Count);
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: Targetting {0} ", (target != null) ? target : "local store");

            // Build the list of SIDs to resolve
            IntPtr hUser = IntPtr.Zero;

            int sidCount = sidListByteFormat.Count;
            IntPtr[] pSids = new IntPtr[sidCount];

            for (int i = 0; i < sidCount; i++)
            {
                pSids[i] = Utils.ConvertByteArrayToIntPtr(sidListByteFormat[i]);
            }

            try
            {
                if (credentials != null)
                {
                    Utils.BeginImpersonation(credentials, out hUser);
                }

                TranslateSids(target, pSids);
            }
            finally
            {
                if (hUser != IntPtr.Zero)
                    Utils.EndImpersonation(hUser);
            }
        }
Example #4
0
        internal SidList(List <Byte[]> sidListByteFormat, string target, NetCred credentials)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: processing {0} ByteFormat SIDs", sidListByteFormat.Count);
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: Targetting {0} ", (target != null) ? target : "local store");

            // Build the list of SIDs to resolve
            IntPtr hUser = IntPtr.Zero;

            int sidCount = sidListByteFormat.Count;

            IntPtr[] pSids = new IntPtr[sidCount];

            for (int i = 0; i < sidCount; i++)
            {
                pSids[i] = Utils.ConvertByteArrayToIntPtr(sidListByteFormat[i]);
            }

            try
            {
                if (credentials != null)
                {
                    Utils.BeginImpersonation(credentials, out hUser);
                }

                TranslateSids(target, pSids);
            }
            finally
            {
                if (hUser != IntPtr.Zero)
                {
                    Utils.EndImpersonation(hUser);
                }
            }
        }
Example #5
0
        internal static DirectoryEntry BuildDirectoryEntry(string path, NetCred credentials, AuthenticationTypes authTypes)
        {
            string userName;
            string password;
            string str = path;

            if (credentials != null)
            {
                userName = credentials.UserName;
            }
            else
            {
                userName = null;
            }
            if (credentials != null)
            {
                password = credentials.Password;
            }
            else
            {
                password = null;
            }
            DirectoryEntry directoryEntry = new DirectoryEntry(str, userName, password, authTypes);

            return(directoryEntry);
        }
Example #6
0
		internal SidList(List<byte[]> sidListByteFormat, string target, NetCred credentials)
		{
			this.entries = new List<SidListEntry>();
			IntPtr zero = IntPtr.Zero;
			int count = sidListByteFormat.Count;
			IntPtr[] intPtr = new IntPtr[count];
			for (int i = 0; i < count; i++)
			{
				intPtr[i] = Utils.ConvertByteArrayToIntPtr(sidListByteFormat[i]);
			}
			try
			{
				if (credentials != null)
				{
					Utils.BeginImpersonation(credentials, out zero);
				}
				this.TranslateSids(target, intPtr);
			}
			finally
			{
				if (zero != IntPtr.Zero)
				{
					Utils.EndImpersonation(zero);
				}
			}
		}
Example #7
0
        static internal DirectoryEntry BuildDirectoryEntry(string path, NetCred credentials, AuthenticationTypes authTypes)
        {
            DirectoryEntry de = new DirectoryEntry(path,
                                                   credentials != null ? credentials.UserName : null,
                                                   credentials != null ? credentials.Password : null,
                                                   authTypes);

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSUtils", "BuildDirectoryEntry (1): built DE for  " + de.Path);

            return(de);
        }
Example #8
0
        internal static int LookupSid(string serverName, NetCred credentials, byte[] sid, out string name, out string domainName, out int accountUsage)
        {
            int    num;
            IntPtr zero = IntPtr.Zero;
            int    num1 = 0;
            int    num2 = 0;

            accountUsage = 0;
            name         = null;
            domainName   = null;
            IntPtr intPtr = IntPtr.Zero;

            try
            {
                zero = Utils.ConvertByteArrayToIntPtr(sid);
                Utils.BeginImpersonation(credentials, out intPtr);
                bool flag           = UnsafeNativeMethods.LookupAccountSid(serverName, zero, null, ref num1, null, ref num2, ref accountUsage);
                int  lastWin32Error = Marshal.GetLastWin32Error();
                if (lastWin32Error == 122)
                {
                    StringBuilder stringBuilder  = new StringBuilder(num1);
                    StringBuilder stringBuilder1 = new StringBuilder(num2);
                    flag = UnsafeNativeMethods.LookupAccountSid(serverName, zero, stringBuilder, ref num1, stringBuilder1, ref num2, ref accountUsage);
                    if (flag)
                    {
                        name       = stringBuilder.ToString();
                        domainName = stringBuilder1.ToString();
                        num        = 0;
                    }
                    else
                    {
                        lastWin32Error = Marshal.GetLastWin32Error();
                        num            = lastWin32Error;
                    }
                }
                else
                {
                    num = lastWin32Error;
                }
            }
            finally
            {
                if (zero != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(zero);
                }
                if (intPtr != IntPtr.Zero)
                {
                    Utils.EndImpersonation(intPtr);
                }
            }
            return(num);
        }
Example #9
0
        static internal DirectoryEntry BuildDirectoryEntry(NetCred credentials, AuthenticationTypes authTypes)
        {
            DirectoryEntry de = new DirectoryEntry();

            de.Username           = credentials != null ? credentials.UserName : null;
            de.Password           = credentials != null ? credentials.Password : null;
            de.AuthenticationType = authTypes;

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSUtils", "BuildDirectoryEntry (2): built DE");

            return(de);
        }
Example #10
0
        internal static bool BeginImpersonation(NetCred credential, out IntPtr hUserToken)
        {
            hUserToken = IntPtr.Zero;
            IntPtr zero = IntPtr.Zero;

            if (credential != null)
            {
                string parsedUserName = credential.ParsedUserName;
                string password       = credential.Password;
                string domain         = credential.Domain;
                if (parsedUserName != null || password != null)
                {
                    int num = UnsafeNativeMethods.LogonUser(parsedUserName, domain, password, 9, 3, ref zero);
                    if (num != 0)
                    {
                        num = UnsafeNativeMethods.ImpersonateLoggedOnUser(zero);
                        if (num != 0)
                        {
                            hUserToken = zero;
                            return(true);
                        }
                        else
                        {
                            int lastWin32Error = Marshal.GetLastWin32Error();
                            UnsafeNativeMethods.CloseHandle(zero);
                            object[] objArray = new object[1];
                            objArray[0] = lastWin32Error;
                            throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.UnableToImpersonateCredentials, objArray));
                        }
                    }
                    else
                    {
                        int      lastWin32Error1 = Marshal.GetLastWin32Error();
                        object[] objArray1       = new object[1];
                        objArray1[0] = lastWin32Error1;
                        throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.UnableToImpersonateCredentials, objArray1));
                    }
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Example #11
0
		internal static bool BeginImpersonation(NetCred credential, out IntPtr hUserToken)
		{
			hUserToken = IntPtr.Zero;
			IntPtr zero = IntPtr.Zero;
			if (credential != null)
			{
				string parsedUserName = credential.ParsedUserName;
				string password = credential.Password;
				string domain = credential.Domain;
				if (parsedUserName != null || password != null)
				{
					int num = UnsafeNativeMethods.LogonUser(parsedUserName, domain, password, 9, 3, ref zero);
					if (num != 0)
					{
						num = UnsafeNativeMethods.ImpersonateLoggedOnUser(zero);
						if (num != 0)
						{
							hUserToken = zero;
							return true;
						}
						else
						{
							int lastWin32Error = Marshal.GetLastWin32Error();
							UnsafeNativeMethods.CloseHandle(zero);
							object[] objArray = new object[1];
							objArray[0] = lastWin32Error;
							throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.UnableToImpersonateCredentials, objArray));
						}
					}
					else
					{
						int lastWin32Error1 = Marshal.GetLastWin32Error();
						object[] objArray1 = new object[1];
						objArray1[0] = lastWin32Error1;
						throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.UnableToImpersonateCredentials, objArray1));
					}
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}
Example #12
0
        // Throws exception if ctxBase is not a computer object
        public SAMStoreCtx(DirectoryEntry ctxBase, bool ownCtxBase, string username, string password, ContextOptions options)
        {
            Debug.Assert(ctxBase != null);
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "Constructing SAMStoreCtx for {0}", ctxBase.Path);

            Debug.Assert(SAMUtils.IsOfObjectClass(ctxBase, "Computer"));

            _ctxBase    = ctxBase;
            _ownCtxBase = ownCtxBase;

            if (username != null && password != null)
            {
                _credentials = new NetCred(username, password);
            }

            _contextOptions = options;
            _authTypes      = SDSUtils.MapOptionsToAuthTypes(options);
        }
Example #13
0
        static internal void ApplyChangesToDirectory(
            Principal p,
            StoreCtx storeCtx,
            GroupMembershipUpdater updateGroupMembership,
            NetCred credentials,
            AuthenticationTypes authTypes)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSUtils", "Entering ApplyChangesToDirectory");
            Debug.Assert(storeCtx != null);
            Debug.Assert(storeCtx is ADStoreCtx || storeCtx is SAMStoreCtx || storeCtx is ADAMStoreCtx);
            Debug.Assert(p != null);
            Debug.Assert(updateGroupMembership != null);

            // Update the properties in the DirectoryEntry.  Note that this does NOT
            // update group membership.
            DirectoryEntry de = (DirectoryEntry)storeCtx.PushChangesToNative(p);

            Debug.Assert(de == p.UnderlyingObject);

            // Commit the property update
            try
            {
                de.CommitChanges();
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "SDSUtils", "ApplyChangesToDirectory: caught COMException with message " + e.Message);

                throw (ExceptionHelper.GetExceptionFromCOMException(e));
            }

            if ((p is GroupPrincipal) && (p.GetChangeStatusForProperty(PropertyNames.GroupMembers)))
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSUtils", "ApplyChangesToDirectory: Updating group membership");

                // It's a group, and it's membership has changed.  Commit those membership changes.
                // Note that this is an immediate operation, because it goes through IADsGroup,
                // and does not require a call to de.CommitChanges().
                updateGroupMembership(p, de, credentials, authTypes);
            }
        }
Example #14
0
		public SAMStoreCtx(DirectoryEntry ctxBase, bool ownCtxBase, string username, string password, ContextOptions options)
		{
			this.ctxBaseLock = new object();
			this.computerInfoLock = new object();
			this.isLSAM = null;
			this.ctxBase = ctxBase;
			this.ownCtxBase = ownCtxBase;
			if (username != null && password != null)
			{
				this.credentials = new NetCred(username, password);
			}
			this.contextOptions = options;
			this.authTypes = SDSUtils.MapOptionsToAuthTypes(options);
		}
Example #15
0
        // Throws exception if ctxBase is not a computer object
        public SAMStoreCtx(DirectoryEntry ctxBase, bool ownCtxBase, string username, string password, ContextOptions options)
        {
            Debug.Assert(ctxBase != null);
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "Constructing SAMStoreCtx for {0}", ctxBase.Path);

            Debug.Assert(SAMUtils.IsOfObjectClass(ctxBase, "Computer"));

            _ctxBase = ctxBase;
            _ownCtxBase = ownCtxBase;

            if (username != null && password != null)
                _credentials = new NetCred(username, password);

            _contextOptions = options;
            _authTypes = SDSUtils.MapOptionsToAuthTypes(options);
        }
Example #16
0
        internal AuthZSet(
                    byte[] userSid,
                    NetCred credentials,
                    ContextOptions contextOptions,
                    string flatUserAuthority,
                    StoreCtx userStoreCtx,
                    object userCtxBase)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                    "AuthZSet",
                                    "AuthZSet: SID={0}, authority={1}, storeCtx={2}",
                                    Utils.ByteArrayToString(userSid),
                                    flatUserAuthority,
                                    userStoreCtx.GetType());

            _userType = userStoreCtx.OwningContext.ContextType;
            _userCtxBase = userCtxBase;
            _userStoreCtx = userStoreCtx;
            _credentials = credentials;
            _contextOptions = contextOptions;

            // flatUserAuthority is flat domain name if userType == Domain,
            // flat host name if userType == LocalMachine
            _flatUserAuthority = flatUserAuthority;

            // Preload the PrincipalContext cache with the user's PrincipalContext
            _contexts[flatUserAuthority] = userStoreCtx.OwningContext;

            IntPtr hUser = IntPtr.Zero;

            //
            // Get the SIDs of the groups to which the user belongs
            //

            IntPtr pClientContext = IntPtr.Zero;
            IntPtr pResManager = IntPtr.Zero;
            IntPtr pBuffer = IntPtr.Zero;

            try
            {
                UnsafeNativeMethods.LUID luid = new UnsafeNativeMethods.LUID();
                luid.low = 0;
                luid.high = 0;

                _psMachineSid = new SafeMemoryPtr(Utils.GetMachineDomainSid());
                _psUserSid = new SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid));

                bool f;
                int lastError = 0;

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Initializing resource manager");

                // Create a resource manager
                f = UnsafeNativeMethods.AuthzInitializeResourceManager(
                                            UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT,
                                            IntPtr.Zero,
                                            IntPtr.Zero,
                                            IntPtr.Zero,
                                            null,
                                            out pResManager
                                            );

                if (f)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting ctx from SID");

                    // Construct a context for the user based on the user's SID
                    f = UnsafeNativeMethods.AuthzInitializeContextFromSid(
                                                0,                  // default flags
                                                _psUserSid.DangerousGetHandle(),
                                                pResManager,
                                                IntPtr.Zero,
                                                luid,
                                                IntPtr.Zero,
                                                out pClientContext
                                                );

                    if (f)
                    {
                        int bufferSize = 0;

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx");

                        // Extract the group SIDs from the user's context.  Determine the size of the buffer we need.
                        f = UnsafeNativeMethods.AuthzGetInformationFromContext(
                                                    pClientContext,
                                                    2,	                // AuthzContextInfoGroupsSids 
                                                    0,
                                                    out bufferSize,
                                                    IntPtr.Zero
                                                    );
                        if (!f && (bufferSize > 0) && (Marshal.GetLastWin32Error() == 122) /*ERROR_INSUFFICIENT_BUFFER*/)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx (size={0})", bufferSize);

                            Debug.Assert(bufferSize > 0);

                            // Set up the needed buffer
                            pBuffer = Marshal.AllocHGlobal(bufferSize);

                            // Extract the group SIDs from the user's context, into our buffer.0
                            f = UnsafeNativeMethods.AuthzGetInformationFromContext(
                                                        pClientContext,
                                                        2,	                // AuthzContextInfoGroupsSids 
                                                        bufferSize,
                                                        out bufferSize,
                                                        pBuffer
                                                        );

                            if (f)
                            {
                                // Marshall the native buffer into managed SID_AND_ATTR structures.
                                // The native buffer holds a TOKEN_GROUPS structure:
                                //
                                //        struct TOKEN_GROUPS {
                                //                DWORD GroupCount;
                                //                SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
                                //        };
                                //

                                // Extract TOKEN_GROUPS.GroupCount                

                                UnsafeNativeMethods.TOKEN_GROUPS tokenGroups = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(pBuffer, typeof(UnsafeNativeMethods.TOKEN_GROUPS));

                                int groupCount = tokenGroups.groupCount;

                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Found {0} groups", groupCount);

                                // Extract TOKEN_GROUPS.Groups, by iterating over the array and marshalling
                                // each native SID_AND_ATTRIBUTES into a managed SID_AND_ATTR.
                                UnsafeNativeMethods.SID_AND_ATTR[] groups = new UnsafeNativeMethods.SID_AND_ATTR[groupCount];

                                IntPtr currentItem = new IntPtr(pBuffer.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - Marshal.SizeOf(typeof(IntPtr)));

                                for (int i = 0; i < groupCount; i++)
                                {
                                    groups[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(currentItem, typeof(UnsafeNativeMethods.SID_AND_ATTR));

                                    currentItem = new IntPtr(currentItem.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR)));
                                }

                                _groupSidList = new SidList(groups);
                            }
                            else
                            {
                                lastError = Marshal.GetLastWin32Error();
                            }
                        }
                        else
                        {
                            lastError = Marshal.GetLastWin32Error();
                            // With a zero-length buffer, this should have never succeeded
                            Debug.Assert(false);
                        }
                    }
                    else
                    {
                        lastError = Marshal.GetLastWin32Error();
                    }
                }
                else
                {
                    lastError = Marshal.GetLastWin32Error();
                }

                if (!f)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "Failed to retrieve group list, {0}", lastError);

                    throw new PrincipalOperationException(
                                    String.Format(
                                            CultureInfo.CurrentCulture,
                                            StringResources.AuthZFailedToRetrieveGroupList,
                                            lastError));
                }

                // Save off the buffer since it still holds the native SIDs referenced by SidList
                _psBuffer = new SafeMemoryPtr(pBuffer);
                pBuffer = IntPtr.Zero;
            }
            catch (Exception e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "AuthZSet", "Caught exception {0} with message {1}", e.GetType(), e.Message);

                if (_psBuffer != null && !_psBuffer.IsInvalid)
                    _psBuffer.Close();

                if (_psUserSid != null && !_psUserSid.IsInvalid)
                    _psUserSid.Close();

                if (_psMachineSid != null && !_psMachineSid.IsInvalid)
                    _psMachineSid.Close();

                // We're on a platform that doesn't have the AuthZ library
                if (e is DllNotFoundException)
                    throw new NotSupportedException(StringResources.AuthZNotSupported, e);

                if (e is EntryPointNotFoundException)
                    throw new NotSupportedException(StringResources.AuthZNotSupported, e);

                throw;
            }
            finally
            {
                if (pClientContext != IntPtr.Zero)
                    UnsafeNativeMethods.AuthzFreeContext(pClientContext);

                if (pResManager != IntPtr.Zero)
                    UnsafeNativeMethods.AuthzFreeResourceManager(pResManager);

                if (pBuffer != IntPtr.Zero)
                    Marshal.FreeHGlobal(pBuffer);
            }
        }
Example #17
0
		public PrincipalContext GetContext(string name, NetCred credentials, ContextOptions contextOptions)
		{
			string nT4UserName;
			PrincipalContext target;
			PrincipalContext principalContext;
			ContextType contextType;
			string userName;
			string password;
			Hashtable hashtables;
			Hashtable hashtables1;
			string domainName = name;
			bool flag = false;
			if (credentials == null || credentials.UserName == null)
			{
				nT4UserName = Utils.GetNT4UserName();
			}
			else
			{
				if (credentials.Domain == null)
				{
					nT4UserName = credentials.UserName;
				}
				else
				{
					nT4UserName = string.Concat(credentials.Domain, "\\", credentials.UserName);
				}
				flag = true;
			}
			if (!this.isSAM)
			{
				int num = 0x40000110;
				UnsafeNativeMethods.DomainControllerInfo dcName = Utils.GetDcName(null, domainName, null, num);
				domainName = dcName.DomainName;
			}
			ManualResetEvent manualResetEvent = null;
			while (true)
			{
				Hashtable hashtables2 = null;
				if (manualResetEvent != null)
				{
					manualResetEvent.WaitOne();
				}
				manualResetEvent = null;
				lock (this.tableLock)
				{
					SDSCache.CredHolder item = (SDSCache.CredHolder)this.table[domainName];
					if (item != null)
					{
						if (flag)
						{
							hashtables1 = item.explicitCreds;
						}
						else
						{
							hashtables1 = item.defaultCreds;
						}
						hashtables2 = hashtables1;
						object obj = hashtables2[nT4UserName];
						if (obj as SDSCache.Placeholder == null)
						{
							WeakReference weakReference = obj as WeakReference;
							if (weakReference != null)
							{
								target = (PrincipalContext)weakReference.Target;
								if (target == null || target.Disposed)
								{
									hashtables2.Remove(nT4UserName);
								}
								else
								{
									principalContext = target;
									break;
								}
							}
						}
						else
						{
							manualResetEvent = ((SDSCache.Placeholder)obj).contextReadyEvent;
							continue;
						}
					}
					if (item == null)
					{
						item = new SDSCache.CredHolder();
						this.table[domainName] = item;
						if (flag)
						{
							hashtables = item.explicitCreds;
						}
						else
						{
							hashtables = item.defaultCreds;
						}
						hashtables2 = hashtables;
					}
					hashtables2[nT4UserName] = new SDSCache.Placeholder();
					if (this.isSAM)
					{
						contextType = ContextType.Machine;
					}
					else
					{
						contextType = ContextType.Domain;
					}
					string str = domainName;
					object obj1 = null;
					ContextOptions contextOption = contextOptions;
					if (credentials != null)
					{
						userName = credentials.UserName;
					}
					else
					{
						userName = null;
					}
					if (credentials != null)
					{
						password = credentials.Password;
					}
					else
					{
						password = null;
					}
					target = new PrincipalContext(contextType, str, obj1, contextOption, userName, password);
					lock (this.tableLock)
					{
						SDSCache.Placeholder placeholder = (SDSCache.Placeholder)hashtables2[nT4UserName];
						hashtables2[nT4UserName] = new WeakReference(target);
						placeholder.contextReadyEvent.Set();
					}
					return target;
				}
			}
			return principalContext;
		}
Example #18
0
        internal static bool BeginImpersonation(NetCred credential, out IntPtr hUserToken)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "Utils", "Entering BeginImpersonation");

            hUserToken = IntPtr.Zero;
            IntPtr hToken = IntPtr.Zero;

            // default credential is specified, no need to do impersonation
            if (credential == null)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "Utils", "BeginImpersonation: nothing to impersonate");
                return false;
            }

            // Retrive the parsed username which has had the domain removed because LogonUser
            // expects creds this way.
            string userName = credential.ParsedUserName;
            string password = credential.Password;
            string domainName = credential.Domain;

            // no need to do impersonation as username and password are both null
            if (userName == null && password == null)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "Utils", "BeginImpersonation: nothing to impersonate (2)");
                return false;
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "Utils", "BeginImpersonation: trying to impersonate " + userName);

            int result = UnsafeNativeMethods.LogonUser(
                                            userName,
                                            domainName,
                                            password,
                                            9, /* LOGON32_LOGON_NEW_CREDENTIALS */
                                            3, /* LOGON32_PROVIDER_WINNT50 */
                                            ref hToken);
            // check the result
            if (result == 0)
            {
                int lastError = Marshal.GetLastWin32Error();
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "BeginImpersonation: LogonUser failed, gle=" + lastError);

                throw new PrincipalOperationException(
                    String.Format(CultureInfo.CurrentCulture,
                                  StringResources.UnableToImpersonateCredentials,
                                  lastError));
            }

            result = UnsafeNativeMethods.ImpersonateLoggedOnUser(hToken);
            if (result == 0)
            {
                int lastError = Marshal.GetLastWin32Error();
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "BeginImpersonation: ImpersonateLoggedOnUser failed, gle=" + lastError);

                // Close the token the was created above....
                UnsafeNativeMethods.CloseHandle(hToken);

                throw new PrincipalOperationException(
                    String.Format(CultureInfo.CurrentCulture,
                                  StringResources.UnableToImpersonateCredentials,
                                  lastError));
            }

            hUserToken = hToken;
            return true;
        }
Example #19
0
        internal static int LookupSid(string serverName, NetCred credentials, byte[] sid, out string name, out string domainName, out int accountUsage)
        {
            IntPtr pSid = IntPtr.Zero;

            int nameLength = 0;
            int domainNameLength = 0;

            StringBuilder sbName;
            StringBuilder sbDomainName;

            accountUsage = 0;
            name = null;
            domainName = null;

            IntPtr hUser = IntPtr.Zero;

            try
            {
                pSid = ConvertByteArrayToIntPtr(sid);

                Utils.BeginImpersonation(credentials, out hUser);

                // hUser could be null if no credentials were specified
                Debug.Assert(hUser != IntPtr.Zero ||
                                (credentials == null || (credentials.UserName == null && credentials.Password == null)));

                bool f = UnsafeNativeMethods.LookupAccountSid(serverName, pSid, null, ref nameLength, null, ref domainNameLength, ref accountUsage);

                int lastErr = Marshal.GetLastWin32Error();
                if (lastErr != 122) // ERROR_INSUFFICIENT_BUFFER
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "LookupSid: LookupAccountSid (1st try) failed, gle=" + lastErr);
                    return lastErr;
                }

                Debug.Assert(f == false);   // should never succeed, with a 0 buffer size                

                Debug.Assert(nameLength > 0);
                Debug.Assert(domainNameLength > 0);

                sbName = new StringBuilder(nameLength);
                sbDomainName = new StringBuilder(domainNameLength);

                f = UnsafeNativeMethods.LookupAccountSid(serverName, pSid, sbName, ref nameLength, sbDomainName, ref domainNameLength, ref accountUsage);

                if (f == false)
                {
                    lastErr = Marshal.GetLastWin32Error();
                    Debug.Assert(lastErr != 0);

                    GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "LookupSid: LookupAccountSid (2nd try) failed, gle=" + lastErr);
                    return lastErr;
                }

                name = sbName.ToString();
                domainName = sbDomainName.ToString();

                return 0;
            }
            finally
            {
                if (pSid != IntPtr.Zero)
                    Marshal.FreeHGlobal(pSid);

                if (hUser != IntPtr.Zero)
                    Utils.EndImpersonation(hUser);
            }
        }
Example #20
0
        public PrincipalContext GetContext(string name, NetCred credentials, ContextOptions contextOptions)
        {
            string           nT4UserName;
            PrincipalContext target;
            PrincipalContext principalContext;
            ContextType      contextType;
            string           userName;
            string           password;
            Hashtable        hashtables;
            Hashtable        hashtables1;
            string           domainName = name;
            bool             flag       = false;

            if (credentials == null || credentials.UserName == null)
            {
                nT4UserName = Utils.GetNT4UserName();
            }
            else
            {
                if (credentials.Domain == null)
                {
                    nT4UserName = credentials.UserName;
                }
                else
                {
                    nT4UserName = string.Concat(credentials.Domain, "\\", credentials.UserName);
                }
                flag = true;
            }
            if (!this.isSAM)
            {
                int num = 0x40000110;
                UnsafeNativeMethods.DomainControllerInfo dcName = Utils.GetDcName(null, domainName, null, num);
                domainName = dcName.DomainName;
            }
            ManualResetEvent manualResetEvent = null;

            while (true)
            {
                Hashtable hashtables2 = null;
                if (manualResetEvent != null)
                {
                    manualResetEvent.WaitOne();
                }
                manualResetEvent = null;
                lock (this.tableLock)
                {
                    SDSCache.CredHolder item = (SDSCache.CredHolder) this.table[domainName];
                    if (item != null)
                    {
                        if (flag)
                        {
                            hashtables1 = item.explicitCreds;
                        }
                        else
                        {
                            hashtables1 = item.defaultCreds;
                        }
                        hashtables2 = hashtables1;
                        object obj = hashtables2[nT4UserName];
                        if (obj as SDSCache.Placeholder == null)
                        {
                            WeakReference weakReference = obj as WeakReference;
                            if (weakReference != null)
                            {
                                target = (PrincipalContext)weakReference.Target;
                                if (target == null || target.Disposed)
                                {
                                    hashtables2.Remove(nT4UserName);
                                }
                                else
                                {
                                    principalContext = target;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            manualResetEvent = ((SDSCache.Placeholder)obj).contextReadyEvent;
                            continue;
                        }
                    }
                    if (item == null)
                    {
                        item = new SDSCache.CredHolder();
                        this.table[domainName] = item;
                        if (flag)
                        {
                            hashtables = item.explicitCreds;
                        }
                        else
                        {
                            hashtables = item.defaultCreds;
                        }
                        hashtables2 = hashtables;
                    }
                    hashtables2[nT4UserName] = new SDSCache.Placeholder();
                    if (this.isSAM)
                    {
                        contextType = ContextType.Machine;
                    }
                    else
                    {
                        contextType = ContextType.Domain;
                    }
                    string         str           = domainName;
                    object         obj1          = null;
                    ContextOptions contextOption = contextOptions;
                    if (credentials != null)
                    {
                        userName = credentials.UserName;
                    }
                    else
                    {
                        userName = null;
                    }
                    if (credentials != null)
                    {
                        password = credentials.Password;
                    }
                    else
                    {
                        password = null;
                    }
                    target = new PrincipalContext(contextType, str, obj1, contextOption, userName, password);
                    lock (this.tableLock)
                    {
                        SDSCache.Placeholder placeholder = (SDSCache.Placeholder)hashtables2[nT4UserName];
                        hashtables2[nT4UserName] = new WeakReference(target);
                        placeholder.contextReadyEvent.Set();
                    }
                    return(target);
                }
            }
            return(principalContext);
        }
Example #21
0
        internal AuthZSet(byte[] userSid, NetCred credentials, ContextOptions contextOptions, string flatUserAuthority, StoreCtx userStoreCtx, object userCtxBase)
        {
            this.currentGroup                = -1;
            this.contexts                    = new Hashtable();
            this.localMachineIsDC            = null;
            this.userType                    = userStoreCtx.OwningContext.ContextType;
            this.userCtxBase                 = userCtxBase;
            this.userStoreCtx                = userStoreCtx;
            this.credentials                 = credentials;
            this.contextOptions              = contextOptions;
            this.flatUserAuthority           = flatUserAuthority;
            this.contexts[flatUserAuthority] = userStoreCtx.OwningContext;
            IntPtr zero   = IntPtr.Zero;
            IntPtr intPtr = IntPtr.Zero;
            IntPtr zero1  = IntPtr.Zero;

            try
            {
                try
                {
                    UnsafeNativeMethods.LUID lUID = new UnsafeNativeMethods.LUID();
                    lUID.low          = 0;
                    lUID.high         = 0;
                    this.psMachineSid = new AuthZSet.SafeMemoryPtr(Utils.GetMachineDomainSid());
                    this.psUserSid    = new AuthZSet.SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid));
                    int  lastWin32Error = 0;
                    bool flag           = UnsafeNativeMethods.AuthzInitializeResourceManager(UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out intPtr);
                    if (!flag)
                    {
                        lastWin32Error = Marshal.GetLastWin32Error();
                    }
                    else
                    {
                        flag = UnsafeNativeMethods.AuthzInitializeContextFromSid(0, this.psUserSid.DangerousGetHandle(), intPtr, IntPtr.Zero, lUID, IntPtr.Zero, out zero);
                        if (!flag)
                        {
                            lastWin32Error = Marshal.GetLastWin32Error();
                        }
                        else
                        {
                            int num = 0;
                            flag = UnsafeNativeMethods.AuthzGetInformationFromContext(zero, 2, 0, out num, IntPtr.Zero);
                            if (flag || num <= 0 || Marshal.GetLastWin32Error() != 122)
                            {
                                lastWin32Error = Marshal.GetLastWin32Error();
                            }
                            else
                            {
                                zero1 = Marshal.AllocHGlobal(num);
                                flag  = UnsafeNativeMethods.AuthzGetInformationFromContext(zero, 2, num, out num, zero1);
                                if (!flag)
                                {
                                    lastWin32Error = Marshal.GetLastWin32Error();
                                }
                                else
                                {
                                    UnsafeNativeMethods.TOKEN_GROUPS structure = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(zero1, typeof(UnsafeNativeMethods.TOKEN_GROUPS));
                                    int num1 = structure.groupCount;
                                    UnsafeNativeMethods.SID_AND_ATTR[] sIDANDATTRArray = new UnsafeNativeMethods.SID_AND_ATTR[num1];
                                    IntPtr intPtr1 = new IntPtr(zero1.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - (long)Marshal.SizeOf(typeof(IntPtr)));
                                    for (int i = 0; i < num1; i++)
                                    {
                                        sIDANDATTRArray[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(intPtr1, typeof(UnsafeNativeMethods.SID_AND_ATTR));
                                        intPtr1            = new IntPtr(intPtr1.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR)));
                                    }
                                    this.groupSidList = new SidList(sIDANDATTRArray);
                                }
                            }
                        }
                    }
                    if (flag)
                    {
                        this.psBuffer = new AuthZSet.SafeMemoryPtr(zero1);
                        zero1         = IntPtr.Zero;
                    }
                    else
                    {
                        object[] objArray = new object[1];
                        objArray[0] = lastWin32Error;
                        throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.AuthZFailedToRetrieveGroupList, objArray));
                    }
                }
                catch (Exception exception1)
                {
                    Exception exception = exception1;
                    if (this.psBuffer != null && !this.psBuffer.IsInvalid)
                    {
                        this.psBuffer.Close();
                    }
                    if (this.psUserSid != null && !this.psUserSid.IsInvalid)
                    {
                        this.psUserSid.Close();
                    }
                    if (this.psMachineSid != null && !this.psMachineSid.IsInvalid)
                    {
                        this.psMachineSid.Close();
                    }
                    if (exception as DllNotFoundException == null)
                    {
                        if (exception as EntryPointNotFoundException == null)
                        {
                            throw;
                        }
                        else
                        {
                            throw new NotSupportedException(StringResources.AuthZNotSupported, exception);
                        }
                    }
                    else
                    {
                        throw new NotSupportedException(StringResources.AuthZNotSupported, exception);
                    }
                }
            }
            finally
            {
                if (zero != IntPtr.Zero)
                {
                    UnsafeNativeMethods.AuthzFreeContext(zero);
                }
                if (intPtr != IntPtr.Zero)
                {
                    UnsafeNativeMethods.AuthzFreeResourceManager(intPtr);
                }
                if (zero1 != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(zero1);
                }
            }
        }
Example #22
0
        public PrincipalContext GetContext(string name, NetCred credentials, ContextOptions contextOptions)
        {
            string contextName = name;
            string userName = null;
            bool explicitCreds = false;
            if (credentials != null && credentials.UserName != null)
            {
                if (credentials.Domain != null)
                    userName = credentials.Domain + "\\" + credentials.UserName;
                else
                    userName = credentials.UserName;

                explicitCreds = true;
            }
            else
            {
                userName = Utils.GetNT4UserName();
            }

            GlobalDebug.WriteLineIf(
                        GlobalDebug.Info,
                        "SDSCache",
                        "GetContext: looking for context for server {0}, user {1}, explicitCreds={2}, options={3}",
                        name,
                        userName,
                        explicitCreds.ToString(),
                        contextOptions.ToString());

            if (!_isSAM)
            {
                // Determine the domain DNS name

                // DS_RETURN_DNS_NAME | DS_DIRECTORY_SERVICE_REQUIRED | DS_BACKGROUND_ONLY
                int flags = unchecked((int)(0x40000000 | 0x00000010 | 0x00000100));
                UnsafeNativeMethods.DomainControllerInfo info = Utils.GetDcName(null, contextName, null, flags);
                contextName = info.DomainName;
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: final contextName is " + contextName);

            ManualResetEvent contextReadyEvent = null;

            while (true)
            {
                Hashtable credTable = null;
                PrincipalContext ctx = null;

                // Wait for the PrincipalContext to be ready
                if (contextReadyEvent != null)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: waiting");

                    contextReadyEvent.WaitOne();
                }

                contextReadyEvent = null;

                lock (_tableLock)
                {
                    CredHolder credHolder = (CredHolder)_table[contextName];

                    if (credHolder != null)
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: found a credHolder for " + contextName);

                        credTable = (explicitCreds ? credHolder.explicitCreds : credHolder.defaultCreds);
                        Debug.Assert(credTable != null);

                        object o = credTable[userName];

                        if (o is Placeholder)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: credHolder for " + contextName + " has a Placeholder");

                            // A PrincipalContext is currently being constructed by another thread.
                            // Wait for it.
                            contextReadyEvent = ((Placeholder)o).contextReadyEvent;
                            continue;
                        }

                        WeakReference refToContext = o as WeakReference;
                        if (refToContext != null)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: refToContext is non-null");

                            ctx = (PrincipalContext)refToContext.Target;  // null if GC'ed

                            // If the PrincipalContext hasn't been GCed or disposed, use it.
                            // Otherwise, we'll need to create a new one
                            if (ctx != null && ctx.Disposed == false)
                            {
                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: using found refToContext");
                                return ctx;
                            }
                            else
                            {
                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: refToContext is GCed/disposed, removing");
                                credTable.Remove(userName);
                            }
                        }
                    }

                    // Either credHolder/credTable are null (no contexts exist for the contextName), or credHolder/credTable
                    // are non-null (contexts exist, but none for the userName).  Either way, we need to create a PrincipalContext.

                    if (credHolder == null)
                    {
                        GlobalDebug.WriteLineIf(
                                GlobalDebug.Info,
                                "SDSCache",
                                "GetContext: null credHolder for " + contextName + ", explicitCreds=" + explicitCreds.ToString());

                        // No contexts exist for the contextName.  Create a CredHolder for the contextName so we have a place
                        // to store the PrincipalContext we'll be creating.
                        credHolder = new CredHolder();
                        _table[contextName] = credHolder;

                        credTable = (explicitCreds ? credHolder.explicitCreds : credHolder.defaultCreds);
                    }

                    // Put a placeholder on the contextName/userName slot, so that other threads that come along after
                    // we release the tableLock know we're in the process of creating the needed PrincipalContext and will wait for us
                    credTable[userName] = new Placeholder();
                }

                // Now we just need to create a PrincipalContext for the contextName and credentials
                GlobalDebug.WriteLineIf(
                        GlobalDebug.Info,
                        "SDSCache",
                        "GetContext: creating context, contextName=" + contextName + ", options=" + contextOptions.ToString());

                ctx = new PrincipalContext(
                                (_isSAM ? ContextType.Machine : ContextType.Domain),
                                contextName,
                                null,
                                contextOptions,
                                (credentials != null ? credentials.UserName : null),
                                (credentials != null ? credentials.Password : null)
                                );

                lock (_tableLock)
                {
                    Placeholder placeHolder = (Placeholder)credTable[userName];

                    // Replace the placeholder with the newly-created PrincipalContext
                    credTable[userName] = new WeakReference(ctx);

                    // Signal waiting threads to continue.  We do this after inserting the PrincipalContext
                    // into the table, so that the PrincipalContext is ready as soon as the other threads wake up.
                    // (Actually, the order probably doesn't matter, since even if we did it in the
                    // opposite order and the other thread woke up before we inserted the PrincipalContext, it would
                    // just block as soon as it tries to acquire the tableLock that we're currently holding.)
                    bool f = placeHolder.contextReadyEvent.Set();
                    Debug.Assert(f == true);
                }

                return ctx;
            }
        }
Example #23
0
        internal static void WriteAttribute(string dePath, string attribute, int value, NetCred credentials, AuthenticationTypes authTypes)
        {
            DirectoryEntry directoryEntry = null;

            using (directoryEntry)
            {
                try
                {
                    directoryEntry = SDSUtils.BuildDirectoryEntry(dePath, credentials, authTypes);
                    string[] strArrays = new string[1];
                    strArrays[0] = attribute;
                    directoryEntry.RefreshCache(strArrays);
                    directoryEntry.Properties[attribute].Value = value;
                    directoryEntry.CommitChanges();
                }
                catch (COMException cOMException1)
                {
                    COMException cOMException = cOMException1;
                    throw ExceptionHelper.GetExceptionFromCOMException(cOMException);
                }
            }
        }
Example #24
0
 internal static void InsertPrincipal(Principal p, StoreCtx storeCtx, SDSUtils.GroupMembershipUpdater updateGroupMembership, NetCred credentials, AuthenticationTypes authTypes, bool needToSetPassword)
 {
     if (p as UserPrincipal != null || p as GroupPrincipal != null || p as AuthenticablePrincipal != null || p as ComputerPrincipal != null)
     {
         SDSUtils.ApplyChangesToDirectory(p, storeCtx, updateGroupMembership, credentials, authTypes);
         if (needToSetPassword && p.GetChangeStatusForProperty("AuthenticablePrincipal.PasswordInfo.Password"))
         {
             string valueForProperty = (string)p.GetValueForProperty("AuthenticablePrincipal.PasswordInfo.Password");
             storeCtx.SetPassword((AuthenticablePrincipal)p, valueForProperty);
         }
         if (p.GetChangeStatusForProperty("AuthenticablePrincipal.PasswordInfo.ExpireImmediately"))
         {
             bool flag = (bool)p.GetValueForProperty("AuthenticablePrincipal.PasswordInfo.ExpireImmediately");
             if (flag)
             {
                 storeCtx.ExpirePassword((AuthenticablePrincipal)p);
             }
         }
         return;
     }
     else
     {
         object[] str = new object[1];
         str[0] = p.GetType().ToString();
         throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.StoreCtxUnsupportedPrincipalTypeForSave, str));
     }
 }
Example #25
0
        internal static Principal ConstructFakePrincipalFromSID(byte[] sid, PrincipalContext ctx, string serverName, NetCred credentials, string authorityName)
        {
            string str  = null;
            string str1 = null;
            string str2;
            string str3 = "";
            int    num  = 0;
            int    num1 = Utils.LookupSid(serverName, credentials, sid, out str, out str1, out num);

            if (num1 == 0)
            {
                if (!string.IsNullOrEmpty(str1))
                {
                    str2 = string.Concat(str1, "\\");
                }
                else
                {
                    str2 = "";
                }
                str3 = string.Concat(str2, str);
            }
            GroupPrincipal groupPrincipal = GroupPrincipal.MakeGroup(ctx);

            groupPrincipal.fakePrincipal = true;
            groupPrincipal.unpersisted   = false;
            groupPrincipal.LoadValueIntoProperty("Principal.DisplayName", str3);
            groupPrincipal.LoadValueIntoProperty("Principal.Name", str);
            groupPrincipal.LoadValueIntoProperty("Principal.SamAccountName", str);
            SecurityIdentifier securityIdentifier = new SecurityIdentifier(Utils.ConvertSidToSDDL(sid));

            groupPrincipal.LoadValueIntoProperty("Principal.Sid", securityIdentifier);
            groupPrincipal.LoadValueIntoProperty("GroupPrincipal.IsSecurityGroup", (bool)1);
            return(groupPrincipal);
        }
Example #26
0
        public PrincipalContext GetContext(string name, NetCred credentials, ContextOptions contextOptions)
        {
            string contextName   = name;
            string userName      = null;
            bool   explicitCreds = false;

            if (credentials != null && credentials.UserName != null)
            {
                if (credentials.Domain != null)
                {
                    userName = credentials.Domain + "\\" + credentials.UserName;
                }
                else
                {
                    userName = credentials.UserName;
                }

                explicitCreds = true;
            }
            else
            {
                userName = Utils.GetNT4UserName();
            }

            GlobalDebug.WriteLineIf(
                GlobalDebug.Info,
                "SDSCache",
                "GetContext: looking for context for server {0}, user {1}, explicitCreds={2}, options={3}",
                name,
                userName,
                explicitCreds.ToString(),
                contextOptions.ToString());

            if (!_isSAM)
            {
                // Determine the domain DNS name

                // DS_RETURN_DNS_NAME | DS_DIRECTORY_SERVICE_REQUIRED | DS_BACKGROUND_ONLY
                int flags = unchecked ((int)(0x40000000 | 0x00000010 | 0x00000100));
                UnsafeNativeMethods.DomainControllerInfo info = Utils.GetDcName(null, contextName, null, flags);
                contextName = info.DomainName;
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: final contextName is " + contextName);

            ManualResetEvent contextReadyEvent = null;

            while (true)
            {
                Hashtable        credTable = null;
                PrincipalContext ctx       = null;

                // Wait for the PrincipalContext to be ready
                if (contextReadyEvent != null)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: waiting");

                    contextReadyEvent.WaitOne();
                }

                contextReadyEvent = null;

                lock (_tableLock)
                {
                    CredHolder credHolder = (CredHolder)_table[contextName];

                    if (credHolder != null)
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: found a credHolder for " + contextName);

                        credTable = (explicitCreds ? credHolder.explicitCreds : credHolder.defaultCreds);
                        Debug.Assert(credTable != null);

                        object o = credTable[userName];

                        if (o is Placeholder)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: credHolder for " + contextName + " has a Placeholder");

                            // A PrincipalContext is currently being constructed by another thread.
                            // Wait for it.
                            contextReadyEvent = ((Placeholder)o).contextReadyEvent;
                            continue;
                        }

                        WeakReference refToContext = o as WeakReference;
                        if (refToContext != null)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: refToContext is non-null");

                            ctx = (PrincipalContext)refToContext.Target;  // null if GC'ed

                            // If the PrincipalContext hasn't been GCed or disposed, use it.
                            // Otherwise, we'll need to create a new one
                            if (ctx != null && ctx.Disposed == false)
                            {
                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: using found refToContext");
                                return(ctx);
                            }
                            else
                            {
                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: refToContext is GCed/disposed, removing");
                                credTable.Remove(userName);
                            }
                        }
                    }

                    // Either credHolder/credTable are null (no contexts exist for the contextName), or credHolder/credTable
                    // are non-null (contexts exist, but none for the userName).  Either way, we need to create a PrincipalContext.

                    if (credHolder == null)
                    {
                        GlobalDebug.WriteLineIf(
                            GlobalDebug.Info,
                            "SDSCache",
                            "GetContext: null credHolder for " + contextName + ", explicitCreds=" + explicitCreds.ToString());

                        // No contexts exist for the contextName.  Create a CredHolder for the contextName so we have a place
                        // to store the PrincipalContext we'll be creating.
                        credHolder          = new CredHolder();
                        _table[contextName] = credHolder;

                        credTable = (explicitCreds ? credHolder.explicitCreds : credHolder.defaultCreds);
                    }

                    // Put a placeholder on the contextName/userName slot, so that other threads that come along after
                    // we release the tableLock know we're in the process of creating the needed PrincipalContext and will wait for us
                    credTable[userName] = new Placeholder();
                }

                // Now we just need to create a PrincipalContext for the contextName and credentials
                GlobalDebug.WriteLineIf(
                    GlobalDebug.Info,
                    "SDSCache",
                    "GetContext: creating context, contextName=" + contextName + ", options=" + contextOptions.ToString());

                ctx = new PrincipalContext(
                    (_isSAM ? ContextType.Machine : ContextType.Domain),
                    contextName,
                    null,
                    contextOptions,
                    credentials?.UserName,
                    credentials?.Password
                    );

                lock (_tableLock)
                {
                    Placeholder placeHolder = (Placeholder)credTable[userName];

                    // Replace the placeholder with the newly-created PrincipalContext
                    credTable[userName] = new WeakReference(ctx);

                    // Signal waiting threads to continue.  We do this after inserting the PrincipalContext
                    // into the table, so that the PrincipalContext is ready as soon as the other threads wake up.
                    // (Actually, the order probably doesn't matter, since even if we did it in the
                    // opposite order and the other thread woke up before we inserted the PrincipalContext, it would
                    // just block as soon as it tries to acquire the tableLock that we're currently holding.)
                    bool f = placeHolder.contextReadyEvent.Set();
                    Debug.Assert(f);
                }

                return(ctx);
            }
        }
Example #27
0
        internal static unsafe int LookupSid(string serverName, NetCred credentials, byte[] sid, out string name, out string domainName, out int accountUsage)
        {
            int nameLength       = 0;
            int domainNameLength = 0;

            accountUsage = 0;
            name         = null;
            domainName   = null;

            IntPtr hUser = IntPtr.Zero;

            try
            {
                Utils.BeginImpersonation(credentials, out hUser);

                // hUser could be null if no credentials were specified
                Debug.Assert(hUser != IntPtr.Zero ||
                             (credentials == null || (credentials.UserName == null && credentials.Password == null)));

                int f = Interop.Advapi32.LookupAccountSid(serverName, sid, null, ref nameLength, null, ref domainNameLength, out accountUsage);

                int lastErr = Marshal.GetLastWin32Error();
                if (lastErr != 122) // ERROR_INSUFFICIENT_BUFFER
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "LookupSid: LookupAccountSid (1st try) failed, gle=" + lastErr);
                    return(lastErr);
                }

                Debug.Assert(f == 0);   // should never succeed, with a 0 buffer size

                Debug.Assert(nameLength > 0);
                Debug.Assert(domainNameLength > 0);

                fixed(char *sbName = new char[nameLength])
                fixed(char *sbDomainName = new char[domainNameLength])
                {
                    f = Interop.Advapi32.LookupAccountSid(serverName, sid, sbName, ref nameLength, sbDomainName, ref domainNameLength, out accountUsage);

                    if (f == 0)
                    {
                        lastErr = Marshal.GetLastWin32Error();
                        Debug.Assert(lastErr != 0);

                        GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "LookupSid: LookupAccountSid (2nd try) failed, gle=" + lastErr);
                        return(lastErr);
                    }

                    name       = new string(sbName);
                    domainName = new string(sbDomainName);
                }

                return(0);
            }
            finally
            {
                if (hUser != IntPtr.Zero)
                {
                    Utils.EndImpersonation(hUser);
                }
            }
        }
Example #28
0
        static internal void WriteAttribute(string dePath, string attribute, int value, NetCred credentials, AuthenticationTypes authTypes)
        {
            GlobalDebug.WriteLineIf(
                GlobalDebug.Info,
                "SDSUtils",
                "WriteAttribute: writing {0} to {1} on {2}",
                value.ToString(CultureInfo.InvariantCulture),
                attribute,
                dePath);

            Debug.Assert(attribute != null && attribute.Length > 0);

            // Ideally, we'd just like to set the property in the principal's DirectoryEntry and write
            // the changes to the store.  However, there might be other changes in the DirectoryEntry,
            // and we don't want to write all of them to the store.  So we must make
            // a fresh DirectoryEntry and write using that.

            DirectoryEntry copyOfDe = null;

            try
            {
                copyOfDe = SDSUtils.BuildDirectoryEntry(dePath, credentials, authTypes);

                Debug.Assert(copyOfDe != null);

                // So we don't do a implicit GetInfo() and retrieve every attribute
                copyOfDe.RefreshCache(new string[] { attribute });

                copyOfDe.Properties[attribute].Value = value;
                copyOfDe.CommitChanges();
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                GlobalDebug.WriteLineIf(
                    GlobalDebug.Error,
                    "SDSUtils",
                    "WriteAttribute: caught exception with message '{0}' writing {1} to {2} on {3}",
                    e.Message,
                    value.ToString(CultureInfo.InvariantCulture),
                    attribute,
                    dePath);

                // ADSI threw an exception trying to write the change
                throw ExceptionHelper.GetExceptionFromCOMException(e);
            }
            finally
            {
                if (copyOfDe != null)
                {
                    copyOfDe.Dispose();
                }
            }
        }
Example #29
0
        static internal Principal ConstructFakePrincipalFromSID(
                                                            byte[] sid,
                                                            PrincipalContext ctx,
                                                            string serverName,
                                                            NetCred credentials,
                                                            string authorityName)
        {
            GlobalDebug.WriteLineIf(
                        GlobalDebug.Info,
                        "Utils",
                        "ConstructFakePrincipalFromSID: Build principal for SID={0}, server={1}, authority={2}",
                        Utils.ByteArrayToString(sid),
                        (serverName != null ? serverName : "NULL"),
                        (authorityName != null ? authorityName : "NULL"));

            Debug.Assert(ClassifySID(sid) == SidType.FakeObject);

            // Get the name for it
            string nt4Name = "";

            int accountUsage = 0;
            string name;
            string domainName;

            int err = Utils.LookupSid(serverName, credentials, sid, out name, out domainName, out accountUsage);
            if (err == 0)
            {
                // If it failed, we'll just live without a name
                //Debug.Assert(accountUsage == 5 /*WellKnownGroup*/);
                nt4Name = (!String.IsNullOrEmpty(domainName) ? domainName + "\\" : "") + name;
            }
            else
            {
                GlobalDebug.WriteLineIf(
                            GlobalDebug.Warn,
                            "Utils",
                            "ConstructFakePrincipalFromSID: LookupSid failed (ignoring), serverName=" + serverName + ", err=" + err);
            }

            // Since LookupAccountSid indicates all of the NT AUTHORITY, etc., SIDs are WellKnownGroups,
            // we'll map them all to Group.

            // Create a Principal object to represent it
            GroupPrincipal g = GroupPrincipal.MakeGroup(ctx);

            g.fakePrincipal = true;
            g.unpersisted = false;

            // Set the display name on the object
            g.LoadValueIntoProperty(PropertyNames.PrincipalDisplayName, nt4Name);

            // Set the display name on the object
            g.LoadValueIntoProperty(PropertyNames.PrincipalName, name);

            // Set the display name on the object
            g.LoadValueIntoProperty(PropertyNames.PrincipalSamAccountName, name);

            // SID IdentityClaim
            SecurityIdentifier sidObj = new SecurityIdentifier(Utils.ConvertSidToSDDL(sid));

            // Set the display name on the object
            g.LoadValueIntoProperty(PropertyNames.PrincipalSid, sidObj);

            g.LoadValueIntoProperty(PropertyNames.GroupIsSecurityGroup, true);
            return g;
        }
Example #30
0
        static internal Principal ConstructFakePrincipalFromSID(
            byte[] sid,
            PrincipalContext ctx,
            string serverName,
            NetCred credentials,
            string authorityName)
        {
            GlobalDebug.WriteLineIf(
                GlobalDebug.Info,
                "Utils",
                "ConstructFakePrincipalFromSID: Build principal for SID={0}, server={1}, authority={2}",
                Utils.ByteArrayToString(sid),
                (serverName != null ? serverName : "NULL"),
                (authorityName != null ? authorityName : "NULL"));

            Debug.Assert(ClassifySID(sid) == SidType.FakeObject);

            // Get the name for it
            string nt4Name = "";

            int    accountUsage = 0;
            string name;
            string domainName;

            int err = Utils.LookupSid(serverName, credentials, sid, out name, out domainName, out accountUsage);

            if (err == 0)
            {
                // If it failed, we'll just live without a name
                //Debug.Assert(accountUsage == 5 /*WellKnownGroup*/);
                nt4Name = (!String.IsNullOrEmpty(domainName) ? domainName + "\\" : "") + name;
            }
            else
            {
                GlobalDebug.WriteLineIf(
                    GlobalDebug.Warn,
                    "Utils",
                    "ConstructFakePrincipalFromSID: LookupSid failed (ignoring), serverName=" + serverName + ", err=" + err);
            }

            // Since LookupAccountSid indicates all of the NT AUTHORITY, etc., SIDs are WellKnownGroups,
            // we'll map them all to Group.

            // Create a Principal object to represent it
            GroupPrincipal g = GroupPrincipal.MakeGroup(ctx);

            g.fakePrincipal = true;
            g.unpersisted   = false;

            // Set the display name on the object
            g.LoadValueIntoProperty(PropertyNames.PrincipalDisplayName, nt4Name);

            // Set the display name on the object
            g.LoadValueIntoProperty(PropertyNames.PrincipalName, name);

            // Set the display name on the object
            g.LoadValueIntoProperty(PropertyNames.PrincipalSamAccountName, name);

            // SID IdentityClaim
            SecurityIdentifier sidObj = new SecurityIdentifier(Utils.ConvertSidToSDDL(sid));

            // Set the display name on the object
            g.LoadValueIntoProperty(PropertyNames.PrincipalSid, sidObj);

            g.LoadValueIntoProperty(PropertyNames.GroupIsSecurityGroup, true);
            return(g);
        }
Example #31
0
        private static void UpdateGroupMembership(Principal group, DirectoryEntry de, NetCred credentials, AuthenticationTypes authTypes)
        {
            Debug.Assert(group.fakePrincipal == false);

            PrincipalCollection members = (PrincipalCollection)group.GetValueForProperty(PropertyNames.GroupMembers);

            UnsafeNativeMethods.IADsGroup iADsGroup = (UnsafeNativeMethods.IADsGroup)de.NativeObject;

            try
            {
                //
                // Process clear
                //
                if (members.Cleared)
                {
                    // Unfortunately, there's no quick way to clear a group's membership in SAM.
                    // So we remove each member in turn, by enumerating over the group membership
                    // and calling remove on each.

                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "UpdateGroupMembership: clearing {0}", de.Path);

                    // Prepare the COM Interopt enumeration
                    UnsafeNativeMethods.IADsMembers iADsMembers = iADsGroup.Members();
                    IEnumVARIANT enumerator = (IEnumVARIANT)iADsMembers._NewEnum;

                    object[] nativeMembers = new object[1];
                    int hr;

                    do
                    {
                        hr = enumerator.Next(1, nativeMembers, IntPtr.Zero);

                        if (hr == 0) // S_OK
                        {
                            // Found a member, remove it.
                            UnsafeNativeMethods.IADs iADs = (UnsafeNativeMethods.IADs)nativeMembers[0];
                            iADsGroup.Remove(iADs.ADsPath);
                        }
                    }
                    while (hr == 0);

                    // Either hr == S_FALSE (1), which means we completed the enumerator,
                    // or we encountered an error
                    if (hr != 1)
                    {
                        // Error occurred.
                        GlobalDebug.WriteLineIf(GlobalDebug.Warn, "SAMStoreCtx", "UpdateGroupMembership: error while clearing, hr={0}", hr);

                        throw new PrincipalOperationException(
                                        String.Format(
                                                CultureInfo.CurrentCulture,
                                                StringResources.SAMStoreCtxFailedToClearGroup,
                                                hr.ToString(CultureInfo.InvariantCulture)));
                    }
                }

                //
                // Process inserted members
                //
                List<Principal> insertedMembers = members.Inserted;

                // First, validate the members to be added
                foreach (Principal member in insertedMembers)
                {
                    Type memberType = member.GetType();

                    if ((memberType != typeof(UserPrincipal)) && (!memberType.IsSubclassOf(typeof(UserPrincipal))) &&
                         (memberType != typeof(ComputerPrincipal)) && (!memberType.IsSubclassOf(typeof(ComputerPrincipal))) &&
                         (memberType != typeof(GroupPrincipal)) && (!memberType.IsSubclassOf(typeof(GroupPrincipal))))
                    {
                        throw new InvalidOperationException(
                                        String.Format(CultureInfo.CurrentCulture, StringResources.StoreCtxUnsupportedPrincipalTypeForGroupInsert, memberType.ToString()));
                    }

                    // Can't inserted unpersisted principal
                    if (member.unpersisted)
                        throw new InvalidOperationException(StringResources.StoreCtxGroupHasUnpersistedInsertedPrincipal);

                    Debug.Assert(member.Context != null);

                    // There's no restriction on the type of principal to be inserted (AD/reg-SAM/MSAM), but it needs
                    // to have a SID IdentityClaim.  We'll check that as we go.
                }

                // Now add each member to the group
                foreach (Principal member in insertedMembers)
                {
                    // We'll add the member via its SID.  This works for both MSAM members and AD members.

                    // Build a SID ADsPath
                    string memberSidPath = GetSidADsPathFromPrincipal(member);

                    if (memberSidPath == null)
                        throw new InvalidOperationException(StringResources.SAMStoreCtxCouldntGetSIDForGroupMember);

                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "UpdateGroupMembership: inserting {0}", memberSidPath);

                    // Add the member to the group
                    iADsGroup.Add(memberSidPath);
                }

                //
                // Process removed members
                //
                List<Principal> removedMembers = members.Removed;

                foreach (Principal member in removedMembers)
                {
                    // Since we don't allow any of these to be inserted, none of them should ever
                    // show up in the removal list
                    Debug.Assert(member.unpersisted == false);

                    // If the collection was cleared, there should be no original members to remove
                    Debug.Assert(members.Cleared == false);

                    // Like insertion, we'll remove by SID.

                    // Build a SID ADsPath
                    string memberSidPath = GetSidADsPathFromPrincipal(member);

                    if (memberSidPath == null)
                        throw new InvalidOperationException(StringResources.SAMStoreCtxCouldntGetSIDForGroupMember);

                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "UpdateGroupMembership: removing {0}", memberSidPath);

                    // Remove the member from the group
                    iADsGroup.Remove(memberSidPath);
                }
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error,
                                        "SAMStoreCtx",
                                        "UpdateGroupMembership: caught COMException, message={0}, code={1}",
                                        e.Message,
                                        e.ErrorCode);

                // ADSI threw an exception trying to update the group membership
                throw ExceptionHelper.GetExceptionFromCOMException(e);
            }
        }
Example #32
0
        // {PropertyNames.GroupMembers,  "members",   null,                                                      new ToLdapConverterDelegate(GroupMembersToLdapConverter)},

        protected static void UpdateGroupMembership(Principal group, DirectoryEntry de, NetCred credentials, AuthenticationTypes authTypes)
        {
            Debug.Assert(group.fakePrincipal == false);

            PrincipalCollection members = (PrincipalCollection)group.GetValueForProperty(PropertyNames.GroupMembers);

            DirectoryEntry groupDe = null;

            try
            {
                //
                // Process clear
                //
                if (members.Cleared)
                {
                    DirectoryEntry copyOfDe = null;

                    try
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "UpdateGroupMembership: clearing {0}", de.Path);

                        copyOfDe = SDSUtils.BuildDirectoryEntry(
                                                de.Path,
                                                credentials,
                                                authTypes);

                        Debug.Assert(copyOfDe != null);
                        copyOfDe.Properties["member"].Clear();
                        copyOfDe.CommitChanges();
                    }
                    finally
                    {
                        if (copyOfDe != null)
                            copyOfDe.Dispose();
                    }
                }

                //
                // Process inserted members
                //

                List<Principal> insertedMembers = members.Inserted;
                List<Principal> removedMembers = members.Removed;

                if (insertedMembers.Count > 0 || removedMembers.Count > 0)
                {
                    groupDe = SDSUtils.BuildDirectoryEntry(
                                            de.Path,
                                            credentials,
                                            authTypes);
                }

                // First, validate the members to be added
                foreach (Principal member in insertedMembers)
                {
                    Type memberType = member.GetType();
                    if ((memberType != typeof(UserPrincipal)) && (!memberType.IsSubclassOf(typeof(UserPrincipal))) &&
                        (memberType != typeof(ComputerPrincipal)) && (!memberType.IsSubclassOf(typeof(ComputerPrincipal))) &&
                        (memberType != typeof(GroupPrincipal)) && (!memberType.IsSubclassOf(typeof(GroupPrincipal))) &&
                        (!memberType.IsSubclassOf(typeof(AuthenticablePrincipal))))
                    {
                        throw new InvalidOperationException(
                                        String.Format(CultureInfo.CurrentCulture, StringResources.StoreCtxUnsupportedPrincipalTypeForGroupInsert, memberType.ToString()));
                    }
                    // Can't inserted unpersisted principal
                    if (member.unpersisted)
                        throw new InvalidOperationException(StringResources.StoreCtxGroupHasUnpersistedInsertedPrincipal);

                    Debug.Assert(member.Context != null);

                    // Can only insert AD principals (no reg-SAM/MSAM principals)
                    if (member.ContextType == ContextType.Machine)
                        throw new InvalidOperationException(StringResources.ADStoreCtxUnsupportedPrincipalContextForGroupInsert);
                }

                // Now add each member to the group
                foreach (Principal member in insertedMembers)
                {
                    // For objects in the current domain or any other domains in the forest we need to use the objects DN
                    // SID path would work for current domain but would not work for child or parent domains.
                    // For foreign objects we must use SID path e.g.  "<SID=...>" so that the necessary FPO gets autocreated by AD.
                    // It also works in the "fake principal" case (which are always represented as FPOs).
                    if (!member.fakePrincipal && ADUtils.ArePrincipalsInSameForest(group, member))
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "UpdateGroupMembership: add {0}", member.DistinguishedName);

                        groupDe.Properties["member"].Add(member.DistinguishedName);
                    }
                    else
                    {
                        // Build a SID DN.  This needs to be a DN path not an ADSI sid path with the LDAP prefix.
                        string memberSidDN = GetSidPathFromPrincipal(member);

                        if (memberSidDN == null)
                            throw new PrincipalOperationException(StringResources.ADStoreCtxCouldntGetSIDForGroupMember);

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "UpdateGroupMembership: add {0}", memberSidDN);

                        // Add the member to the group
                        groupDe.Properties["member"].Add(memberSidDN);
                    }
                }

                // If we had any members then commit them.
                if (insertedMembers.Count > 0)
                    groupDe.CommitChanges();

                //
                // Process removed members
                //

                foreach (Principal member in removedMembers)
                {
                    // Since we don't allow any of these to be inserted, none of them should ever
                    // show up in the removal list
                    Debug.Assert(member.unpersisted == false);
                    Debug.Assert(member.ContextType == ContextType.Domain || member.ContextType == ContextType.ApplicationDirectory);

                    // If the collection was cleared, there should be no original members to remove
                    Debug.Assert(members.Cleared == false);

                    // Since we are using PropertyValueCollection to do the item removal we are constrainted to items that are in the collection
                    // For principals that are in the same forest just use their DN to do the removal.  This is how they are represented in the member attr.
                    // For foreign principals we must represent them with their SID binding string since they are locally represented by an FSP object.
                    if (!member.fakePrincipal && ADUtils.ArePrincipalsInSameForest(group, member))
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "UpdateGroupMembership: remove via DN {0}", member.DistinguishedName);

                        // Remove the member from the group

                        groupDe.Properties["member"].Remove(member.DistinguishedName);
                    }
                    else
                    {
                        // SID DN case

                        // Build a SID DN.
                        string memberSidDN = GetSidPathFromPrincipal(member);

                        if (memberSidDN == null)
                            throw new PrincipalOperationException(StringResources.ADStoreCtxCouldntGetSIDForGroupMember);

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "UpdateGroupMembership: remove via SID {0}", memberSidDN);

                        // Remove the member from the group
                        groupDe.Properties["member"].Remove(memberSidDN);
                    }
                }

                // If we used the collection to do a modification then commit it.
                if (removedMembers.Count > 0)
                    groupDe.CommitChanges();
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                throw ExceptionHelper.GetExceptionFromCOMException(e);
            }
            finally
            {
                if (null != groupDe)
                    groupDe.Dispose();
            }
        }
Example #33
0
        static internal void InsertPrincipal(
            Principal p,
            StoreCtx storeCtx,
            GroupMembershipUpdater updateGroupMembership,
            NetCred credentials,
            AuthenticationTypes authTypes,
            bool needToSetPassword)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSUtils", "Entering InsertPrincipal");

            Debug.Assert(storeCtx != null);
            Debug.Assert(storeCtx is ADStoreCtx || storeCtx is SAMStoreCtx);
            Debug.Assert(p != null);

            if ((!(p is UserPrincipal)) &&
                (!(p is GroupPrincipal)) &&
                (!(p is AuthenticablePrincipal)) &&
                (!(p is ComputerPrincipal)))
            {
                // It's not a type of Principal that we support
                GlobalDebug.WriteLineIf(GlobalDebug.Warn, "SDSUtils", "InsertPrincipal: Bad principal type:" + p.GetType().ToString());

                throw new InvalidOperationException(
                          String.Format(CultureInfo.CurrentCulture, SR.StoreCtxUnsupportedPrincipalTypeForSave, p.GetType().ToString()));
            }

            // Commit the properties
            SDSUtils.ApplyChangesToDirectory(
                p,
                storeCtx,
                updateGroupMembership,
                credentials,
                authTypes
                );

            // Handle any saved-off operations

            // For SAM, we set password elsewhere prior to creating the principal, so needToSetPassword == false
            // For AD, we have to set the password after creating the principal, so needToSetPassword == true
            if (needToSetPassword && p.GetChangeStatusForProperty(PropertyNames.PwdInfoPassword))
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSUtils", "InsertPrincipal: Setting password");

                // Only AuthenticablePrincipals can have PasswordInfo
                Debug.Assert(p is AuthenticablePrincipal);

                string password = (string)p.GetValueForProperty(PropertyNames.PwdInfoPassword);
                Debug.Assert(password != null); // if null, PasswordInfo should not have indicated it was changed

                storeCtx.SetPassword((AuthenticablePrincipal)p, password);
            }

            if (p.GetChangeStatusForProperty(PropertyNames.PwdInfoExpireImmediately))
            {
                // Only AuthenticablePrincipals can have PasswordInfo
                Debug.Assert(p is AuthenticablePrincipal);

                bool expireImmediately = (bool)p.GetValueForProperty(PropertyNames.PwdInfoExpireImmediately);

                if (expireImmediately)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSUtils", "InsertPrincipal: Setting pwd expired");

                    storeCtx.ExpirePassword((AuthenticablePrincipal)p);
                }
            }
        }
Example #34
0
		internal static int LookupSid(string serverName, NetCred credentials, byte[] sid, out string name, out string domainName, out int accountUsage)
		{
			int num;
			IntPtr zero = IntPtr.Zero;
			int num1 = 0;
			int num2 = 0;
			accountUsage = 0;
			name = null;
			domainName = null;
			IntPtr intPtr = IntPtr.Zero;
			try
			{
				zero = Utils.ConvertByteArrayToIntPtr(sid);
				Utils.BeginImpersonation(credentials, out intPtr);
				bool flag = UnsafeNativeMethods.LookupAccountSid(serverName, zero, null, ref num1, null, ref num2, ref accountUsage);
				int lastWin32Error = Marshal.GetLastWin32Error();
				if (lastWin32Error == 122)
				{
					StringBuilder stringBuilder = new StringBuilder(num1);
					StringBuilder stringBuilder1 = new StringBuilder(num2);
					flag = UnsafeNativeMethods.LookupAccountSid(serverName, zero, stringBuilder, ref num1, stringBuilder1, ref num2, ref accountUsage);
					if (flag)
					{
						name = stringBuilder.ToString();
						domainName = stringBuilder1.ToString();
						num = 0;
					}
					else
					{
						lastWin32Error = Marshal.GetLastWin32Error();
						num = lastWin32Error;
					}
				}
				else
				{
					num = lastWin32Error;
				}
			}
			finally
			{
				if (zero != IntPtr.Zero)
				{
					Marshal.FreeHGlobal(zero);
				}
				if (intPtr != IntPtr.Zero)
				{
					Utils.EndImpersonation(intPtr);
				}
			}
			return num;
		}
Example #35
0
		private static void UpdateGroupMembership(Principal group, DirectoryEntry de, NetCred credentials, AuthenticationTypes authTypes)
		{
			int num;
			PrincipalCollection valueForProperty = (PrincipalCollection)group.GetValueForProperty("GroupPrincipal.Members");
			UnsafeNativeMethods.IADsGroup nativeObject = (UnsafeNativeMethods.IADsGroup)de.NativeObject;
			try
			{
				if (valueForProperty.Cleared)
				{
					UnsafeNativeMethods.IADsMembers aDsMember = nativeObject.Members();
					IEnumVARIANT enumVARIANT = (IEnumVARIANT)aDsMember._NewEnum;
					object[] objArray = new object[1];
					do
					{
						num = enumVARIANT.Next(1, objArray, IntPtr.Zero);
						if (num != 0)
						{
							continue;
						}
						UnsafeNativeMethods.IADs aD = (UnsafeNativeMethods.IADs)objArray[0];
						nativeObject.Remove(aD.ADsPath);
					}
					while (num == 0);
					if (num != 1)
					{
						object[] str = new object[1];
						str[0] = num.ToString(CultureInfo.InvariantCulture);
						throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.SAMStoreCtxFailedToClearGroup, str));
					}
				}
				List<Principal> inserted = valueForProperty.Inserted;
				foreach (Principal principal in inserted)
				{
					Type type = principal.GetType();
					if (!(type != typeof(UserPrincipal)) || type.IsSubclassOf(typeof(UserPrincipal)) || !(type != typeof(ComputerPrincipal)) || type.IsSubclassOf(typeof(ComputerPrincipal)) || !(type != typeof(GroupPrincipal)) || type.IsSubclassOf(typeof(GroupPrincipal)))
					{
						if (!principal.unpersisted)
						{
							continue;
						}
						throw new InvalidOperationException(StringResources.StoreCtxGroupHasUnpersistedInsertedPrincipal);
					}
					else
					{
						object[] str1 = new object[1];
						str1[0] = type.ToString();
						throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.StoreCtxUnsupportedPrincipalTypeForGroupInsert, str1));
					}
				}
				foreach (Principal principal1 in inserted)
				{
					string sidADsPathFromPrincipal = SAMStoreCtx.GetSidADsPathFromPrincipal(principal1);
					if (sidADsPathFromPrincipal != null)
					{
						nativeObject.Add(sidADsPathFromPrincipal);
					}
					else
					{
						throw new InvalidOperationException(StringResources.SAMStoreCtxCouldntGetSIDForGroupMember);
					}
				}
				List<Principal> removed = valueForProperty.Removed;
				foreach (Principal principal2 in removed)
				{
					string sidADsPathFromPrincipal1 = SAMStoreCtx.GetSidADsPathFromPrincipal(principal2);
					if (sidADsPathFromPrincipal1 != null)
					{
						nativeObject.Remove(sidADsPathFromPrincipal1);
					}
					else
					{
						throw new InvalidOperationException(StringResources.SAMStoreCtxCouldntGetSIDForGroupMember);
					}
				}
			}
			catch (COMException cOMException1)
			{
				COMException cOMException = cOMException1;
				throw ExceptionHelper.GetExceptionFromCOMException(cOMException);
			}
		}
Example #36
0
        internal AuthZSet(
            byte[] userSid,
            NetCred credentials,
            ContextOptions contextOptions,
            string flatUserAuthority,
            StoreCtx userStoreCtx,
            object userCtxBase)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                    "AuthZSet",
                                    "AuthZSet: SID={0}, authority={1}, storeCtx={2}",
                                    Utils.ByteArrayToString(userSid),
                                    flatUserAuthority,
                                    userStoreCtx.GetType());

            _userType       = userStoreCtx.OwningContext.ContextType;
            _userCtxBase    = userCtxBase;
            _userStoreCtx   = userStoreCtx;
            _credentials    = credentials;
            _contextOptions = contextOptions;

            // flatUserAuthority is flat domain name if userType == Domain,
            // flat host name if userType == LocalMachine
            _flatUserAuthority = flatUserAuthority;

            // Preload the PrincipalContext cache with the user's PrincipalContext
            _contexts[flatUserAuthority] = userStoreCtx.OwningContext;

            IntPtr hUser = IntPtr.Zero;

            //
            // Get the SIDs of the groups to which the user belongs
            //

            IntPtr pClientContext = IntPtr.Zero;
            IntPtr pResManager    = IntPtr.Zero;
            IntPtr pBuffer        = IntPtr.Zero;

            try
            {
                UnsafeNativeMethods.LUID luid = new UnsafeNativeMethods.LUID();
                luid.low  = 0;
                luid.high = 0;

                _psMachineSid = new SafeMemoryPtr(Utils.GetMachineDomainSid());
                _psUserSid    = new SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid));

                bool f;
                int  lastError = 0;

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Initializing resource manager");

                // Create a resource manager
                f = UnsafeNativeMethods.AuthzInitializeResourceManager(
                    UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    null,
                    out pResManager
                    );

                if (f)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting ctx from SID");

                    // Construct a context for the user based on the user's SID
                    f = UnsafeNativeMethods.AuthzInitializeContextFromSid(
                        0,                                          // default flags
                        _psUserSid.DangerousGetHandle(),
                        pResManager,
                        IntPtr.Zero,
                        luid,
                        IntPtr.Zero,
                        out pClientContext
                        );

                    if (f)
                    {
                        int bufferSize = 0;

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx");

                        // Extract the group SIDs from the user's context.  Determine the size of the buffer we need.
                        f = UnsafeNativeMethods.AuthzGetInformationFromContext(
                            pClientContext,
                            2,                                            // AuthzContextInfoGroupsSids
                            0,
                            out bufferSize,
                            IntPtr.Zero
                            );
                        if (!f && (bufferSize > 0) && (Marshal.GetLastWin32Error() == 122) /*ERROR_INSUFFICIENT_BUFFER*/)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx (size={0})", bufferSize);

                            Debug.Assert(bufferSize > 0);

                            // Set up the needed buffer
                            pBuffer = Marshal.AllocHGlobal(bufferSize);

                            // Extract the group SIDs from the user's context, into our buffer.0
                            f = UnsafeNativeMethods.AuthzGetInformationFromContext(
                                pClientContext,
                                2,                                            // AuthzContextInfoGroupsSids
                                bufferSize,
                                out bufferSize,
                                pBuffer
                                );

                            if (f)
                            {
                                // Marshall the native buffer into managed SID_AND_ATTR structures.
                                // The native buffer holds a TOKEN_GROUPS structure:
                                //
                                //        struct TOKEN_GROUPS {
                                //                DWORD GroupCount;
                                //                SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
                                //        };
                                //

                                // Extract TOKEN_GROUPS.GroupCount

                                UnsafeNativeMethods.TOKEN_GROUPS tokenGroups = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(pBuffer, typeof(UnsafeNativeMethods.TOKEN_GROUPS));

                                int groupCount = tokenGroups.groupCount;

                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Found {0} groups", groupCount);

                                // Extract TOKEN_GROUPS.Groups, by iterating over the array and marshalling
                                // each native SID_AND_ATTRIBUTES into a managed SID_AND_ATTR.
                                UnsafeNativeMethods.SID_AND_ATTR[] groups = new UnsafeNativeMethods.SID_AND_ATTR[groupCount];

                                IntPtr currentItem = new IntPtr(pBuffer.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - IntPtr.Size);

                                for (int i = 0; i < groupCount; i++)
                                {
                                    groups[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(currentItem, typeof(UnsafeNativeMethods.SID_AND_ATTR));

                                    currentItem = new IntPtr(currentItem.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR)));
                                }

                                _groupSidList = new SidList(groups);
                            }
                            else
                            {
                                lastError = Marshal.GetLastWin32Error();
                            }
                        }
                        else
                        {
                            lastError = Marshal.GetLastWin32Error();
                            Debug.Fail("With a zero-length buffer, this should have never succeeded");
                        }
                    }
                    else
                    {
                        lastError = Marshal.GetLastWin32Error();
                    }
                }
                else
                {
                    lastError = Marshal.GetLastWin32Error();
                }

                if (!f)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "Failed to retrieve group list, {0}", lastError);

                    throw new PrincipalOperationException(
                              SR.Format(
                                  SR.AuthZFailedToRetrieveGroupList,
                                  lastError));
                }

                // Save off the buffer since it still holds the native SIDs referenced by SidList
                _psBuffer = new SafeMemoryPtr(pBuffer);
                pBuffer   = IntPtr.Zero;
            }
            catch (Exception e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "AuthZSet", "Caught exception {0} with message {1}", e.GetType(), e.Message);

                if (_psBuffer != null && !_psBuffer.IsInvalid)
                {
                    _psBuffer.Close();
                }

                if (_psUserSid != null && !_psUserSid.IsInvalid)
                {
                    _psUserSid.Close();
                }

                if (_psMachineSid != null && !_psMachineSid.IsInvalid)
                {
                    _psMachineSid.Close();
                }

                // We're on a platform that doesn't have the AuthZ library
                if (e is DllNotFoundException)
                {
                    throw new NotSupportedException(SR.AuthZNotSupported, e);
                }

                if (e is EntryPointNotFoundException)
                {
                    throw new NotSupportedException(SR.AuthZNotSupported, e);
                }

                throw;
            }
            finally
            {
                if (pClientContext != IntPtr.Zero)
                {
                    UnsafeNativeMethods.AuthzFreeContext(pClientContext);
                }

                if (pResManager != IntPtr.Zero)
                {
                    UnsafeNativeMethods.AuthzFreeResourceManager(pResManager);
                }

                if (pBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pBuffer);
                }
            }
        }
Example #37
0
        static internal void WriteAttribute <T>(string dePath, string attribute, T value, NetCred credentials, AuthenticationTypes authTypes)
        {
            Debug.Assert(attribute != null && attribute.Length > 0);

            // Ideally, we'd just like to set the property in the principal's DirectoryEntry and write
            // the changes to the store.  However, there might be other changes in the DirectoryEntry,
            // and we don't want to write all of them to the store.  So we must make
            // a fresh DirectoryEntry and write using that.

            DirectoryEntry copyOfDe = null;

            try
            {
                copyOfDe = SDSUtils.BuildDirectoryEntry(dePath, credentials, authTypes);

                Debug.Assert(copyOfDe != null);

                // So we don't do a implicit GetInfo() and retrieve every attribute
                copyOfDe.RefreshCache(new string[] { attribute });

                copyOfDe.Properties[attribute].Value = value;
                copyOfDe.CommitChanges();
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                // ADSI threw an exception trying to write the change
                throw ExceptionHelper.GetExceptionFromCOMException(e);
            }
            finally
            {
                if (copyOfDe != null)
                {
                    copyOfDe.Dispose();
                }
            }
        }
Example #38
0
        internal static void ApplyChangesToDirectory(Principal p, StoreCtx storeCtx, SDSUtils.GroupMembershipUpdater updateGroupMembership, NetCred credentials, AuthenticationTypes authTypes)
        {
            DirectoryEntry native = (DirectoryEntry)storeCtx.PushChangesToNative(p);

            try
            {
                native.CommitChanges();
            }
            catch (COMException cOMException1)
            {
                COMException cOMException = cOMException1;
                throw ExceptionHelper.GetExceptionFromCOMException(cOMException);
            }
            if (p as GroupPrincipal != null && p.GetChangeStatusForProperty("GroupPrincipal.Members"))
            {
                updateGroupMembership(p, native, credentials, authTypes);
            }
        }
Example #39
0
        internal static int LookupSid(string serverName, NetCred credentials, byte[] sid, out string name, out string domainName, out int accountUsage)
        {
            IntPtr pSid = IntPtr.Zero;

            int nameLength       = 0;
            int domainNameLength = 0;

            StringBuilder sbName;
            StringBuilder sbDomainName;

            accountUsage = 0;
            name         = null;
            domainName   = null;

            IntPtr hUser = IntPtr.Zero;

            try
            {
                pSid = ConvertByteArrayToIntPtr(sid);

                Utils.BeginImpersonation(credentials, out hUser);

                // hUser could be null if no credentials were specified
                Debug.Assert(hUser != IntPtr.Zero ||
                             (credentials == null || (credentials.UserName == null && credentials.Password == null)));

                bool f = UnsafeNativeMethods.LookupAccountSid(serverName, pSid, null, ref nameLength, null, ref domainNameLength, ref accountUsage);

                int lastErr = Marshal.GetLastWin32Error();
                if (lastErr != 122) // ERROR_INSUFFICIENT_BUFFER
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "LookupSid: LookupAccountSid (1st try) failed, gle=" + lastErr);
                    return(lastErr);
                }

                Debug.Assert(f == false);   // should never succeed, with a 0 buffer size

                Debug.Assert(nameLength > 0);
                Debug.Assert(domainNameLength > 0);

                sbName       = new StringBuilder(nameLength);
                sbDomainName = new StringBuilder(domainNameLength);

                f = UnsafeNativeMethods.LookupAccountSid(serverName, pSid, sbName, ref nameLength, sbDomainName, ref domainNameLength, ref accountUsage);

                if (f == false)
                {
                    lastErr = Marshal.GetLastWin32Error();
                    Debug.Assert(lastErr != 0);

                    GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "LookupSid: LookupAccountSid (2nd try) failed, gle=" + lastErr);
                    return(lastErr);
                }

                name       = sbName.ToString();
                domainName = sbDomainName.ToString();

                return(0);
            }
            finally
            {
                if (pSid != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pSid);
                }

                if (hUser != IntPtr.Zero)
                {
                    Utils.EndImpersonation(hUser);
                }
            }
        }
Example #40
0
		internal static Principal ConstructFakePrincipalFromSID(byte[] sid, PrincipalContext ctx, string serverName, NetCred credentials, string authorityName)
		{
			string str = null;
			string str1 = null;
			string str2;
			string str3 = "";
			int num = 0;
			int num1 = Utils.LookupSid(serverName, credentials, sid, out str, out str1, out num);
			if (num1 == 0)
			{
				if (!string.IsNullOrEmpty(str1))
				{
					str2 = string.Concat(str1, "\\");
				}
				else
				{
					str2 = "";
				}
				str3 = string.Concat(str2, str);
			}
			GroupPrincipal groupPrincipal = GroupPrincipal.MakeGroup(ctx);
			groupPrincipal.fakePrincipal = true;
			groupPrincipal.unpersisted = false;
			groupPrincipal.LoadValueIntoProperty("Principal.DisplayName", str3);
			groupPrincipal.LoadValueIntoProperty("Principal.Name", str);
			groupPrincipal.LoadValueIntoProperty("Principal.SamAccountName", str);
			SecurityIdentifier securityIdentifier = new SecurityIdentifier(Utils.ConvertSidToSDDL(sid));
			groupPrincipal.LoadValueIntoProperty("Principal.Sid", securityIdentifier);
			groupPrincipal.LoadValueIntoProperty("GroupPrincipal.IsSecurityGroup", (bool)1);
			return groupPrincipal;
		}
Example #41
0
        internal static bool BeginImpersonation(NetCred credential, out IntPtr hUserToken)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "Utils", "Entering BeginImpersonation");

            hUserToken = IntPtr.Zero;
            IntPtr hToken = IntPtr.Zero;

            // default credential is specified, no need to do impersonation
            if (credential == null)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "Utils", "BeginImpersonation: nothing to impersonate");
                return(false);
            }

            // Retrive the parsed username which has had the domain removed because LogonUser
            // expects creds this way.
            string userName   = credential.ParsedUserName;
            string password   = credential.Password;
            string domainName = credential.Domain;

            // no need to do impersonation as username and password are both null
            if (userName == null && password == null)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "Utils", "BeginImpersonation: nothing to impersonate (2)");
                return(false);
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "Utils", "BeginImpersonation: trying to impersonate " + userName);

            int result = UnsafeNativeMethods.LogonUser(
                userName,
                domainName,
                password,
                9,                             /* LOGON32_LOGON_NEW_CREDENTIALS */
                3,                             /* LOGON32_PROVIDER_WINNT50 */
                ref hToken);

            // check the result
            if (result == 0)
            {
                int lastError = Marshal.GetLastWin32Error();
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "BeginImpersonation: LogonUser failed, gle=" + lastError);

                throw new PrincipalOperationException(
                          String.Format(CultureInfo.CurrentCulture,
                                        StringResources.UnableToImpersonateCredentials,
                                        lastError));
            }

            result = UnsafeNativeMethods.ImpersonateLoggedOnUser(hToken);
            if (result == 0)
            {
                int lastError = Marshal.GetLastWin32Error();
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "BeginImpersonation: ImpersonateLoggedOnUser failed, gle=" + lastError);

                // Close the token the was created above....
                UnsafeNativeMethods.CloseHandle(hToken);

                throw new PrincipalOperationException(
                          String.Format(CultureInfo.CurrentCulture,
                                        StringResources.UnableToImpersonateCredentials,
                                        lastError));
            }

            hUserToken = hToken;
            return(true);
        }
Example #42
0
		internal AuthZSet(byte[] userSid, NetCred credentials, ContextOptions contextOptions, string flatUserAuthority, StoreCtx userStoreCtx, object userCtxBase)
		{
			this.currentGroup = -1;
			this.contexts = new Hashtable();
			this.localMachineIsDC = null;
			this.userType = userStoreCtx.OwningContext.ContextType;
			this.userCtxBase = userCtxBase;
			this.userStoreCtx = userStoreCtx;
			this.credentials = credentials;
			this.contextOptions = contextOptions;
			this.flatUserAuthority = flatUserAuthority;
			this.contexts[flatUserAuthority] = userStoreCtx.OwningContext;
			IntPtr zero = IntPtr.Zero;
			IntPtr intPtr = IntPtr.Zero;
			IntPtr zero1 = IntPtr.Zero;
			try
			{
				try
				{
					UnsafeNativeMethods.LUID lUID = new UnsafeNativeMethods.LUID();
					lUID.low = 0;
					lUID.high = 0;
					this.psMachineSid = new AuthZSet.SafeMemoryPtr(Utils.GetMachineDomainSid());
					this.psUserSid = new AuthZSet.SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid));
					int lastWin32Error = 0;
					bool flag = UnsafeNativeMethods.AuthzInitializeResourceManager(UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out intPtr);
					if (!flag)
					{
						lastWin32Error = Marshal.GetLastWin32Error();
					}
					else
					{
						flag = UnsafeNativeMethods.AuthzInitializeContextFromSid(0, this.psUserSid.DangerousGetHandle(), intPtr, IntPtr.Zero, lUID, IntPtr.Zero, out zero);
						if (!flag)
						{
							lastWin32Error = Marshal.GetLastWin32Error();
						}
						else
						{
							int num = 0;
							flag = UnsafeNativeMethods.AuthzGetInformationFromContext(zero, 2, 0, out num, IntPtr.Zero);
							if (flag || num <= 0 || Marshal.GetLastWin32Error() != 122)
							{
								lastWin32Error = Marshal.GetLastWin32Error();
							}
							else
							{
								zero1 = Marshal.AllocHGlobal(num);
								flag = UnsafeNativeMethods.AuthzGetInformationFromContext(zero, 2, num, out num, zero1);
								if (!flag)
								{
									lastWin32Error = Marshal.GetLastWin32Error();
								}
								else
								{
									UnsafeNativeMethods.TOKEN_GROUPS structure = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(zero1, typeof(UnsafeNativeMethods.TOKEN_GROUPS));
									int num1 = structure.groupCount;
									UnsafeNativeMethods.SID_AND_ATTR[] sIDANDATTRArray = new UnsafeNativeMethods.SID_AND_ATTR[num1];
									IntPtr intPtr1 = new IntPtr(zero1.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - (long)Marshal.SizeOf(typeof(IntPtr)));
									for (int i = 0; i < num1; i++)
									{
										sIDANDATTRArray[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(intPtr1, typeof(UnsafeNativeMethods.SID_AND_ATTR));
										intPtr1 = new IntPtr(intPtr1.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR)));
									}
									this.groupSidList = new SidList(sIDANDATTRArray);
								}
							}
						}
					}
					if (flag)
					{
						this.psBuffer = new AuthZSet.SafeMemoryPtr(zero1);
						zero1 = IntPtr.Zero;
					}
					else
					{
						object[] objArray = new object[1];
						objArray[0] = lastWin32Error;
						throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.AuthZFailedToRetrieveGroupList, objArray));
					}
				}
				catch (Exception exception1)
				{
					Exception exception = exception1;
					if (this.psBuffer != null && !this.psBuffer.IsInvalid)
					{
						this.psBuffer.Close();
					}
					if (this.psUserSid != null && !this.psUserSid.IsInvalid)
					{
						this.psUserSid.Close();
					}
					if (this.psMachineSid != null && !this.psMachineSid.IsInvalid)
					{
						this.psMachineSid.Close();
					}
					if (exception as DllNotFoundException == null)
					{
						if (exception as EntryPointNotFoundException == null)
						{
							throw;
						}
						else
						{
							throw new NotSupportedException(StringResources.AuthZNotSupported, exception);
						}
					}
					else
					{
						throw new NotSupportedException(StringResources.AuthZNotSupported, exception);
					}
				}
			}
			finally
			{
				if (zero != IntPtr.Zero)
				{
					UnsafeNativeMethods.AuthzFreeContext(zero);
				}
				if (intPtr != IntPtr.Zero)
				{
					UnsafeNativeMethods.AuthzFreeResourceManager(intPtr);
				}
				if (zero1 != IntPtr.Zero)
				{
					Marshal.FreeHGlobal(zero1);
				}
			}
		}