Example #1
0
		internal static Principal DirectoryEntryAsPrincipal(DirectoryEntry de, StoreCtx storeCtx)
		{
			if (SAMUtils.IsOfObjectClass(de, "Computer") || SAMUtils.IsOfObjectClass(de, "User") || SAMUtils.IsOfObjectClass(de, "Group"))
			{
				return storeCtx.GetAsPrincipal(de, null);
			}
			else
			{
				return null;
			}
		}
Example #2
0
 internal override void Move(StoreCtx originalStore, Principal p)
 {
     GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "Move");
 }
Example #3
0
        public void Save(PrincipalContext context)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "Principal", "Entering Save(Context)");

            // Make sure we're not disposed or deleted.
            CheckDisposedOrDeleted();

            // Make sure we're not a fake principal
            CheckFakePrincipal();

            // We must have a PrincipalContext to save into.  This should always be the case, unless we're unpersisted
            // and they never set a PrincipalContext.
            if (context == null)
            {
                Debug.Assert(this.unpersisted == true);
                throw new InvalidOperationException(SR.NullArguments);
            }

            if (context.ContextType == ContextType.Machine || _ctx.ContextType == ContextType.Machine)
            {
                throw new InvalidOperationException(SR.SaveToNotSupportedAgainstMachineStore);
            }

            // If the user is trying to save to the same context we are already set to then just save the changes
            if (context == _ctx)
            {
                Save();
                return;
            }

            // If we already have a context set on this object then make sure the new
            // context is of the same type.
            if (context.ContextType != _ctx.ContextType)
            {
                Debug.Assert(this.unpersisted == true);
                throw new InvalidOperationException(SR.SaveToMustHaveSamecontextType);
            }

            StoreCtx originalStoreCtx = GetStoreCtxToUse();

            _ctx = context;

            // Call the appropriate operation depending on whether this is an insert or update
            StoreCtx newStoreCtx = GetStoreCtxToUse();

            Debug.Assert(newStoreCtx != null);      // since we know this.ctx isn't null
            Debug.Assert(originalStoreCtx != null); // since we know this.ctx isn't null

            if (this.unpersisted)
            {
                // We have an unpersisted principal so we just want to create a principal in the new store.
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "Principal", "Save(context): inserting new principal of type {0} using {1}", this.GetType(), newStoreCtx.GetType());
                Debug.Assert(newStoreCtx == _ctx.ContextForType(this.GetType()));
                newStoreCtx.Insert(this);
                this.unpersisted = false;  // once we persist, we're no longer in the unpersisted state
            }
            else
            {
                // We have a principal that already exists.  We need to move it to the new store.
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "Principal", "Save(context): Moving principal of type {0} using {1}", this.GetType(), newStoreCtx.GetType());

                // we are now saving to a new store so this principal is unpersisted.
                this.unpersisted = true;

                // If the user has modified the name save away the current name so
                // if the move succeeds and the update fails we will move the item back to the original
                // store with the original name.
                bool   nameModified = _nameChanged == LoadState.Changed;
                string previousName = null;

                if (nameModified)
                {
                    string newName = _name;
                    _ctx.QueryCtx.Load(this, PropertyNames.PrincipalName);
                    previousName = _name;
                    this.Name    = newName;
                }

                newStoreCtx.Move(originalStoreCtx, this);

                try
                {
                    this.unpersisted = false;  // once we persist, we're no longer in the unpersisted state

                    newStoreCtx.Update(this);
                }
                catch (System.SystemException e)
                {
                    try
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Error, "Principal", "Save(context):,  Update Failed (attempting to move back) Exception {0} ", e.Message);

                        if (nameModified)
                        {
                            this.Name = previousName;
                        }

                        originalStoreCtx.Move(newStoreCtx, this);

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "Principal", "Move back succeeded");
                    }
                    catch (System.SystemException deleteFail)
                    {
                        // The move back failed.  Just continue we will throw the original exception below.
                        GlobalDebug.WriteLineIf(GlobalDebug.Error, "Principal", "Save(context):,  Move back Failed {0} ", deleteFail.Message);
                    }

                    if (e is System.Runtime.InteropServices.COMException)
                    {
                        throw ExceptionHelper.GetExceptionFromCOMException((System.Runtime.InteropServices.COMException)e);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            _ctx.QueryCtx = newStoreCtx;  // so Updates go to the right StoreCtx
        }
Example #4
0
 public void Save(PrincipalContext context)
 {
     this.CheckDisposedOrDeleted();
     this.CheckFakePrincipal();
     if (context.ContextType == ContextType.Machine || this.ctx.ContextType == ContextType.Machine)
     {
         throw new InvalidOperationException(StringResources.SaveToNotSupportedAgainstMachineStore);
     }
     else
     {
         if (context != null)
         {
             if (context != this.ctx)
             {
                 if (context.ContextType == this.ctx.ContextType)
                 {
                     StoreCtx storeCtxToUse = this.GetStoreCtxToUse();
                     this.ctx = context;
                     StoreCtx storeCtx = this.GetStoreCtxToUse();
                     if (!this.unpersisted)
                     {
                         this.unpersisted = true;
                         bool   flag = this.nameChanged == LoadState.Changed;
                         string str  = null;
                         if (flag)
                         {
                             string str1 = this.name;
                             this.ctx.QueryCtx.Load(this, "Principal.Name");
                             str       = this.name;
                             this.Name = str1;
                         }
                         storeCtx.Move(storeCtxToUse, this);
                         try
                         {
                             this.unpersisted = false;
                             storeCtx.Update(this);
                         }
                         catch (SystemException systemException2)
                         {
                             SystemException systemException = systemException2;
                             try
                             {
                                 if (flag)
                                 {
                                     this.Name = str;
                                 }
                                 storeCtxToUse.Move(storeCtx, this);
                             }
                             catch (SystemException systemException1)
                             {
                             }
                             if (systemException as COMException == null)
                             {
                                 throw systemException;
                             }
                             else
                             {
                                 throw ExceptionHelper.GetExceptionFromCOMException((COMException)systemException);
                             }
                         }
                     }
                     else
                     {
                         storeCtx.Insert(this);
                         this.unpersisted = false;
                     }
                     this.ctx.QueryCtx = storeCtx;
                     return;
                 }
                 else
                 {
                     throw new InvalidOperationException(StringResources.SaveToMustHaveSamecontextType);
                 }
             }
             else
             {
                 this.Save();
                 return;
             }
         }
         else
         {
             throw new InvalidOperationException(StringResources.NullArguments);
         }
     }
 }
Example #5
0
        internal static 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(SR.Format(SR.StoreCtxUnsupportedPrincipalTypeForSave, p.GetType()));
            }

            // 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 #6
0
		private void DoLDAPDirectoryInitNoContainer()
		{
			string str = null;
			string str1 = null;
			byte[] numArray = new byte[] { 169, 209, 202, 21, 118, 136, 17, 209, 173, 237, 0, 192, 79, 216, 213, 205 };
			byte[] numArray1 = numArray;
			byte[] numArray2 = new byte[] { 170, 49, 40, 37, 118, 136, 17, 209, 173, 237, 0, 192, 79, 216, 213, 205 };
			byte[] numArray3 = numArray2;
			DirectoryEntry directoryEntry = null;
			DirectoryEntry directoryEntry1 = null;
			DirectoryEntry directoryEntry2 = null;
			ADStoreCtx aDStoreCtx = null;
			ADStoreCtx aDStoreCtx1 = null;
			ADStoreCtx aDStoreCtx2 = null;
			DirectoryEntry directoryEntry3 = null;
			string str2 = "";
			if (this.name != null)
			{
				str2 = string.Concat(this.name, "/");
			}
			AuthenticationTypes authTypes = SDSUtils.MapOptionsToAuthTypes(this.options);
			using (directoryEntry3)
			{
				directoryEntry3 = new DirectoryEntry(string.Concat("LDAP://", str2, "rootDse"), this.username, this.password, authTypes);
				string item = (string)directoryEntry3.Properties["defaultNamingContext"][0];
				str = string.Concat("LDAP://", str2, item);
			}
			try
			{
				directoryEntry2 = new DirectoryEntry(str, this.username, this.password, authTypes);
				if (this.serverProperties.portSSL > 0)
				{
					directoryEntry2.Options.PasswordPort = this.serverProperties.portSSL;
				}
				string str3 = null;
				PropertyValueCollection propertyValueCollection = directoryEntry2.Properties["wellKnownObjects"];
				foreach (UnsafeNativeMethods.IADsDNWithBinary aDsDNWithBinary in propertyValueCollection)
				{
					if (Utils.AreBytesEqual(numArray1, (byte[])aDsDNWithBinary.BinaryValue))
					{
						str3 = string.Concat("LDAP://", str2, aDsDNWithBinary.DNString);
					}
					if (!Utils.AreBytesEqual(numArray3, (byte[])aDsDNWithBinary.BinaryValue))
					{
						continue;
					}
					str1 = string.Concat("LDAP://", str2, aDsDNWithBinary.DNString);
				}
				if (str3 == null || str1 == null)
				{
					throw new PrincipalOperationException(StringResources.ContextNoWellKnownObjects);
				}
				else
				{
					directoryEntry = new DirectoryEntry(str3, this.username, this.password, authTypes);
					directoryEntry1 = new DirectoryEntry(str1, this.username, this.password, authTypes);
					StoreCtx storeCtx = this.CreateContextFromDirectoryEntry(directoryEntry);
					this.userCtx = storeCtx;
					this.groupCtx = storeCtx;
					directoryEntry = null;
					this.computerCtx = this.CreateContextFromDirectoryEntry(directoryEntry1);
					directoryEntry1 = null;
					this.queryCtx = this.CreateContextFromDirectoryEntry(directoryEntry2);
					this.connectedServer = ADUtils.GetServerName(directoryEntry2);
					directoryEntry2 = null;
				}
			}
			catch (Exception exception)
			{
				if (directoryEntry != null)
				{
					directoryEntry.Dispose();
				}
				if (directoryEntry1 != null)
				{
					directoryEntry1.Dispose();
				}
				if (directoryEntry2 != null)
				{
					directoryEntry2.Dispose();
				}
				if (aDStoreCtx != null)
				{
					aDStoreCtx.Dispose();
				}
				if (aDStoreCtx1 != null)
				{
					aDStoreCtx1.Dispose();
				}
				if (aDStoreCtx2 != null)
				{
					aDStoreCtx2.Dispose();
				}
				throw;
			}
		}
Example #7
0
		internal abstract ResultSet GetGroupsMemberOf(Principal foreignPrincipal, StoreCtx foreignContext);
        private void DoLDAPDirectoryInit()
        {
            // use the servername if they gave us one, else let ADSI figure it out
            string serverName = "";

            if (_name != null)
            {
                if (_contextType == ContextType.ApplicationDirectory)
                {
                    serverName = _serverProperties.dnsHostName + ":" +
                                 ((ContextOptions.SecureSocketLayer & _options) > 0 ? _serverProperties.portSSL : _serverProperties.portLDAP);
                }
                else
                {
                    serverName = _name;
                }

                serverName += "/";
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "DoLDAPDirectoryInit: serverName is " + serverName);

            // use the options they specified
            AuthenticationTypes authTypes = SDSUtils.MapOptionsToAuthTypes(_options);

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "DoLDAPDirectoryInit: authTypes is " + authTypes.ToString());

            DirectoryEntry de = new DirectoryEntry("LDAP://" + serverName + _container, _username, _password, authTypes);

            try
            {
                // Set the password port to the ssl port read off of the rootDSE.  Without this
                // password change/set won't work when we connect without SSL and ADAM is running
                // on non-standard port numbers.  We have already verified directory connectivity at this point
                // so this should always succeed.
                if (_serverProperties.portSSL > 0)
                {
                    de.Options.PasswordPort = _serverProperties.portSSL;
                }

                StoreCtx storeCtx = CreateContextFromDirectoryEntry(de);

                _queryCtx    = storeCtx;
                _userCtx     = storeCtx;
                _groupCtx    = storeCtx;
                _computerCtx = storeCtx;

                _connectedServer = ADUtils.GetServerName(de);
                de = null;
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                throw ExceptionHelper.GetExceptionFromCOMException(e);
            }
            catch (Exception e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "PrincipalContext",
                                        "DoLDAPDirectoryInit: caught exception of type "
                                        + e.GetType().ToString() +
                                        " and message " + e.Message);

                throw;
            }
            finally
            {
                // Cleanup the DE on failure
                if (de != null)
                {
                    de.Dispose();
                }
            }
        }
        private void DoLDAPDirectoryInitNoContainer()
        {
            byte[] USERS_CONTAINER_GUID     = new byte[] { 0xa9, 0xd1, 0xca, 0x15, 0x76, 0x88, 0x11, 0xd1, 0xad, 0xed, 0x00, 0xc0, 0x4f, 0xd8, 0xd5, 0xcd };
            byte[] COMPUTERS_CONTAINER_GUID = new byte[] { 0xaa, 0x31, 0x28, 0x25, 0x76, 0x88, 0x11, 0xd1, 0xad, 0xed, 0x00, 0xc0, 0x4f, 0xd8, 0xd5, 0xcd };

            // The StoreCtxs that will be used in the PrincipalContext, and their associated DirectoryEntry objects.
            DirectoryEntry deUserGroupOrg = null;
            DirectoryEntry deComputer     = null;
            DirectoryEntry deBase         = null;

            ADStoreCtx storeCtxUserGroupOrg = null;
            ADStoreCtx storeCtxComputer     = null;
            ADStoreCtx storeCtxBase         = null;

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "Entering DoLDAPDirectoryInitNoContainer");

            //
            // Build a DirectoryEntry that represents the root of the domain.
            //

            // Use the RootDSE to find the default naming context
            DirectoryEntry deRootDse = null;
            string         adsPathBase;

            // use the servername if they gave us one, else let ADSI figure it out
            string serverName = "";

            if (_name != null)
            {
                serverName = _name + "/";
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "DoLDAPDirectoryInitNoContainer: serverName is " + serverName);

            // use the options they specified
            AuthenticationTypes authTypes = SDSUtils.MapOptionsToAuthTypes(_options);

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "DoLDAPDirectoryInitNoContainer: authTypes is " + authTypes.ToString());

            try
            {
                deRootDse = new DirectoryEntry("LDAP://" + serverName + "rootDse", _username, _password, authTypes);

                // This will also detect if the server is down or nonexistent
                string domainNC = (string)deRootDse.Properties["defaultNamingContext"][0];
                adsPathBase = "LDAP://" + serverName + domainNC;

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "DoLDAPDirectoryInitNoContainer: domainNC is " + domainNC);
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "DoLDAPDirectoryInitNoContainer: adsPathBase is " + adsPathBase);
            }
            finally
            {
                // Don't allow the DE to leak
                if (deRootDse != null)
                {
                    deRootDse.Dispose();
                }
            }

            try
            {
                // Build a DE for the root of the domain using the retrieved naming context
                deBase = new DirectoryEntry(adsPathBase, _username, _password, authTypes);

                // Set the password port to the ssl port read off of the rootDSE.  Without this
                // password change/set won't work when we connect without SSL and ADAM is running
                // on non-standard port numbers.  We have already verified directory connectivity at this point
                // so this should always succeed.
                if (_serverProperties.portSSL > 0)
                {
                    deBase.Options.PasswordPort = _serverProperties.portSSL;
                }

                //
                // Use the wellKnownObjects attribute to determine the default location
                // for users and computers.
                //
                string adsPathUserGroupOrg = null;
                string adsPathComputer     = null;

                PropertyValueCollection wellKnownObjectValues = deBase.Properties["wellKnownObjects"];

                foreach (UnsafeNativeMethods.IADsDNWithBinary value in wellKnownObjectValues)
                {
                    if (Utils.AreBytesEqual(USERS_CONTAINER_GUID, (byte[])value.BinaryValue))
                    {
                        Debug.Assert(adsPathUserGroupOrg == null);
                        adsPathUserGroupOrg = "LDAP://" + serverName + value.DNString;

                        GlobalDebug.WriteLineIf(
                            GlobalDebug.Info,
                            "PrincipalContext",
                            "DoLDAPDirectoryInitNoContainer: found USER, adsPathUserGroupOrg is " + adsPathUserGroupOrg);
                    }

                    // Is it the computer container?
                    if (Utils.AreBytesEqual(COMPUTERS_CONTAINER_GUID, (byte[])value.BinaryValue))
                    {
                        Debug.Assert(adsPathComputer == null);
                        adsPathComputer = "LDAP://" + serverName + value.DNString;

                        GlobalDebug.WriteLineIf(
                            GlobalDebug.Info,
                            "PrincipalContext",
                            "DoLDAPDirectoryInitNoContainer: found COMPUTER, adsPathComputer is " + adsPathComputer);
                    }
                }

                if ((adsPathUserGroupOrg == null) || (adsPathComputer == null))
                {
                    // Something's wrong with the domain, it's not exposing the proper
                    // well-known object fields.
                    throw new PrincipalOperationException(SR.ContextNoWellKnownObjects);
                }

                //
                // Build DEs for the Users and Computers containers.
                // The Users container will also be used as the default for Groups.
                // The reason there are different contexts for groups, users and computers is so that
                // when a principal is created it will go into the appropriate default container.  This is so users don't
                // be default create principals in the root of their directory.  When a search happens the base context is used so that
                // the whole directory will be covered.
                //
                deUserGroupOrg = new DirectoryEntry(adsPathUserGroupOrg, _username, _password, authTypes);
                deComputer     = new DirectoryEntry(adsPathComputer, _username, _password, authTypes);

                StoreCtx userStore = CreateContextFromDirectoryEntry(deUserGroupOrg);

                _userCtx       = userStore;
                _groupCtx      = userStore;
                deUserGroupOrg = null;  // since we handed off ownership to the StoreCtx

                _computerCtx = CreateContextFromDirectoryEntry(deComputer);

                deComputer = null;

                _queryCtx = CreateContextFromDirectoryEntry(deBase);

                _connectedServer = ADUtils.GetServerName(deBase);

                deBase = null;
            }
            catch (Exception e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error,
                                        "PrincipalContext",
                                        "DoLDAPDirectoryInitNoContainer: caught exception of type "
                                        + e.GetType().ToString() +
                                        " and message " + e.Message);

                // Cleanup on failure.  Once a DE has been successfully handed off to a ADStoreCtx,
                // that ADStoreCtx will handle Dispose()'ing it
                if (deUserGroupOrg != null)
                {
                    deUserGroupOrg.Dispose();
                }

                if (deComputer != null)
                {
                    deComputer.Dispose();
                }

                if (deBase != null)
                {
                    deBase.Dispose();
                }

                if (storeCtxUserGroupOrg != null)
                {
                    storeCtxUserGroupOrg.Dispose();
                }

                if (storeCtxComputer != null)
                {
                    storeCtxComputer.Dispose();
                }

                if (storeCtxBase != null)
                {
                    storeCtxBase.Dispose();
                }

                throw;
            }
        }
Example #10
0
 // Get groups from this ctx which contain a principal corresponding to foreignPrincipal
 // (which is a principal from foreignContext)
 internal abstract ResultSet GetGroupsMemberOf(Principal foreignPrincipal, StoreCtx foreignContext);
Example #11
0
 internal abstract void Move(StoreCtx originalStore, Principal p);
Example #12
0
		internal override void Move(StoreCtx originalStore, Principal p)
		{
		}
Example #13
0
		internal override ResultSet GetGroupsMemberOf(Principal foreignPrincipal, StoreCtx foreignContext)
		{
			if (!foreignPrincipal.fakePrincipal)
			{
				SecurityIdentifier sid = foreignPrincipal.Sid;
				if (sid != null)
				{
					UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(base.OwningContext, IdentityType.Sid, sid.ToString());
					if (userPrincipal != null)
					{
						return this.GetGroupsMemberOf(userPrincipal);
					}
					else
					{
						return new EmptySet();
					}
				}
				else
				{
					throw new InvalidOperationException(StringResources.StoreCtxNeedValueSecurityIdentityClaimToQuery);
				}
			}
			else
			{
				return this.GetGroupsMemberOf(foreignPrincipal);
			}
		}
Example #14
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 #15
0
        // Get groups from this ctx which contain a principal corresponding to foreignPrincipal
        // (which is a principal from foreignContext)
        internal override ResultSet GetGroupsMemberOf(Principal foreignPrincipal, StoreCtx foreignContext)
        {
            // If it's a fake principal, we don't need to do any of the lookup to find a local representation.
            // We'll skip straight to GetGroupsMemberOf(Principal), which will lookup the groups to which it belongs via its SID.
            if (foreignPrincipal.fakePrincipal)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "GetGroupsMemberOf(ctx): is fake principal");
                return GetGroupsMemberOf(foreignPrincipal);
            }

            // Get the Principal's SID, so we can look it up by SID in our store
            SecurityIdentifier Sid = foreignPrincipal.Sid;

            if (Sid == null)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Warn, "SAMStoreCtx", "GetGroupsMemberOf(ctx): no SID IC");
                throw new InvalidOperationException(StringResources.StoreCtxNeedValueSecurityIdentityClaimToQuery);
            }

            // In SAM, only users can be member of SAM groups (no nested groups)
            UserPrincipal u = UserPrincipal.FindByIdentity(this.OwningContext, IdentityType.Sid, Sid.ToString());

            // If no corresponding principal exists in this store, then by definition the principal isn't
            // a member of any groups in this store.
            if (u == null)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "GetGroupsMemberOf(ctx): no corresponding user, returning empty set");
                return new EmptySet();
            }

            // Now that we got the principal in our store, enumerating its group membership can be handled the
            // usual way.
            return GetGroupsMemberOf(u);
        }
Example #16
0
        public bool Remove(Principal principal)
        {
            CheckDisposed();

            if (principal == null)
            {
                throw new ArgumentNullException(nameof(principal));
            }

            // Ask the StoreCtx to verify that this member can be removed.  Right now, the only
            // reason it couldn't is if it's actually a member by virtue of its primaryGroupId
            // pointing to this group.
            //
            // If storeCtxToUse == null, then we must be unpersisted, in which case there clearly
            // can't be any such primary group members pointing to this group on the store.
            StoreCtx storeCtxToUse = _owningGroup.GetStoreCtxToUse();
            string   explanation;

            Debug.Assert(storeCtxToUse != null || _owningGroup.unpersisted == true);

            if ((storeCtxToUse != null) && (!storeCtxToUse.CanGroupMemberBeRemoved(_owningGroup, principal, out explanation)))
            {
                throw new InvalidOperationException(explanation);
            }

            bool removed = false;

            // If the value was previously inserted, we just remove it from insertedValuesPending.
            if (_insertedValuesPending.Contains(principal))
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalCollection", "Remove: removing from insertedValuesPending");

                MarkChange();
                _insertedValuesPending.Remove(principal);
                removed = true;

                // If they did a Remove(x) --> Save() --> Add(x) --> Remove(x), we'll end up with x in neither
                // the ResultSet or the removedValuesCompleted list.  This is bad.  Avoid that by adding x
                // back to the removedValuesCompleted list here.
                //
                // At worst, we end up with x on the removedValuesCompleted list even though it's not even in
                // resultSet.  That's not a problem.  The only thing we use the removedValuesCompleted list for
                // is deciding which values in resultSet to skip, anyway.
                if (!_removedValuesCompleted.Contains(principal))
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalCollection", "Remove: adding to removedValuesCompleted");
                    _removedValuesCompleted.Add(principal);
                }
            }
            else
            {
                // They're trying to remove an already-persisted value.  We add it to the
                // removedValues list.  Then, if it's already been loaded into insertedValuesCompleted,
                // we remove it from insertedValuesCompleted.

                removed = Contains(principal);
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalCollection", "Remove: making it a pending remove, removed={0}", removed);

                if (removed)
                {
                    MarkChange();

                    _removedValuesPending.Add(principal);

                    // in case it's the result of a previous-but-already-committed insert
                    _insertedValuesCompleted.Remove(principal);
                }
            }

            return(removed);
        }
Example #17
0
		private void DoLDAPDirectoryInit()
		{
			int num;
			string str = "";
			if (this.name != null)
			{
				if (this.contextType != ContextType.ApplicationDirectory)
				{
					str = this.name;
				}
				else
				{
					string str1 = this.serverProperties.dnsHostName;
					string str2 = ":";
					if ((ContextOptions.SecureSocketLayer & this.options) > 0)
					{
						num = this.serverProperties.portSSL;
					}
					else
					{
						num = this.serverProperties.portLDAP;
					}
					str = string.Concat(str1, str2, num);
				}
				str = string.Concat(str, "/");
			}
			AuthenticationTypes authTypes = SDSUtils.MapOptionsToAuthTypes(this.options);
			using (DirectoryEntry directoryEntry = new DirectoryEntry(string.Concat("LDAP://", str, this.container), this.username, this.password, authTypes))
			{
				try
				{
					if (this.serverProperties.portSSL > 0)
					{
						directoryEntry.Options.PasswordPort = this.serverProperties.portSSL;
					}
					StoreCtx storeCtx = this.CreateContextFromDirectoryEntry(directoryEntry);
					this.queryCtx = storeCtx;
					this.userCtx = storeCtx;
					this.groupCtx = storeCtx;
					this.computerCtx = storeCtx;
					this.connectedServer = ADUtils.GetServerName(directoryEntry);
				}
				catch (COMException cOMException1)
				{
					COMException cOMException = cOMException1;
					throw ExceptionHelper.GetExceptionFromCOMException(cOMException);
				}
				catch (Exception exception)
				{
					throw;
				}
			}
		}
Example #18
0
 internal override void Move(StoreCtx originalStore, Principal p)
 {
     GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "Move");
 }
Example #19
0
		private void DoMachineInit()
		{
			DirectoryEntry directoryEntry = null;
			try
			{
				string computerFlatName = this.name;
				if (computerFlatName == null)
				{
					computerFlatName = Utils.GetComputerFlatName();
				}
				AuthenticationTypes authTypes = SDSUtils.MapOptionsToAuthTypes(this.options);
				directoryEntry = new DirectoryEntry(string.Concat("WinNT://", computerFlatName, ",computer"), this.username, this.password, authTypes);
				directoryEntry.RefreshCache();
				StoreCtx storeCtx = this.CreateContextFromDirectoryEntry(directoryEntry);
				this.queryCtx = storeCtx;
				this.userCtx = storeCtx;
				this.groupCtx = storeCtx;
				this.computerCtx = storeCtx;
				this.connectedServer = computerFlatName;
				directoryEntry = null;
			}
			catch (Exception exception)
			{
				if (directoryEntry != null)
				{
					directoryEntry.Dispose();
				}
				throw;
			}
		}
Example #20
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 #21
0
		internal abstract void Move(StoreCtx originalStore, Principal p);
Example #22
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);
				}
			}
		}