// Get groups of which p is a direct member internal override ResultSet GetGroupsMemberOf(Principal p) { // Enforced by the methods that call us Debug.Assert(p.unpersisted == false); if (!p.fakePrincipal) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "GetGroupsMemberOf: is real principal"); // No nested groups or computers as members of groups in SAM if (!(p is UserPrincipal)) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "GetGroupsMemberOf: not a user, returning empty set"); return new EmptySet(); } Debug.Assert(p.UnderlyingObject != null); DirectoryEntry userDE = (DirectoryEntry)p.UnderlyingObject; UnsafeNativeMethods.IADsMembers iadsMembers = (UnsafeNativeMethods.IADsMembers)userDE.Invoke("Groups"); ResultSet resultSet = new SAMGroupsSet(iadsMembers, this, _ctxBase); return resultSet; } else { // ADSI's IADsGroups doesn't work for fake principals like NT AUTHORITY\NETWORK SERVICE // We use the same SAMQuery set that we use for query-by-example, but with a different // SAMMatcher class to match groups which contain the specified principal as a member // Get the entries we'll iterate over. Write access to Children is controlled through the // ctxBaseLock, but we don't want to have to hold that lock while we're iterating over all // the child entries. So we have to clone the ctxBase --- not ideal, but it prevents // multithreading issues. DirectoryEntries entries = SDSUtils.BuildDirectoryEntry(_ctxBase.Path, _credentials, _authTypes).Children; Debug.Assert(entries != null); // The SAMQuerySet will use this to restrict the types of DirectoryEntry objects returned. List<string> schemaTypes = GetSchemaFilter(typeof(GroupPrincipal)); SecurityIdentifier principalSid = p.Sid; byte[] SidB = new byte[principalSid.BinaryLength]; principalSid.GetBinaryForm(SidB, 0); if (principalSid == null) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "SAMStoreCtx", "GetGroupsMemberOf: bad SID IC"); throw new InvalidOperationException(StringResources.StoreCtxNeedValueSecurityIdentityClaimToQuery); } // Create the ResultSet that will perform the client-side filtering SAMQuerySet resultSet = new SAMQuerySet( schemaTypes, entries, _ctxBase, -1, // no size limit this, new GroupMemberMatcher(SidB)); return resultSet; } }
// Get groups of which p is a direct member internal override ResultSet GetGroupsMemberOf(Principal p) { // Enforced by the methods that call us Debug.Assert(p.unpersisted == false); if (!p.fakePrincipal) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "GetGroupsMemberOf: is real principal"); // No nested groups or computers as members of groups in SAM if (!(p is UserPrincipal)) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "GetGroupsMemberOf: not a user, returning empty set"); return(new EmptySet()); } Debug.Assert(p.UnderlyingObject != null); DirectoryEntry userDE = (DirectoryEntry)p.UnderlyingObject; UnsafeNativeMethods.IADsMembers iadsMembers = (UnsafeNativeMethods.IADsMembers)userDE.Invoke("Groups"); ResultSet resultSet = new SAMGroupsSet(iadsMembers, this, _ctxBase); return(resultSet); } else { // ADSI's IADsGroups doesn't work for fake principals like NT AUTHORITY\NETWORK SERVICE // We use the same SAMQuery set that we use for query-by-example, but with a different // SAMMatcher class to match groups which contain the specified principal as a member // Get the entries we'll iterate over. Write access to Children is controlled through the // ctxBaseLock, but we don't want to have to hold that lock while we're iterating over all // the child entries. So we have to clone the ctxBase --- not ideal, but it prevents // multithreading issues. DirectoryEntries entries = SDSUtils.BuildDirectoryEntry(_ctxBase.Path, _credentials, _authTypes).Children; Debug.Assert(entries != null); // The SAMQuerySet will use this to restrict the types of DirectoryEntry objects returned. List <string> schemaTypes = GetSchemaFilter(typeof(GroupPrincipal)); SecurityIdentifier principalSid = p.Sid; byte[] SidB = new byte[principalSid.BinaryLength]; principalSid.GetBinaryForm(SidB, 0); if (principalSid == null) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "SAMStoreCtx", "GetGroupsMemberOf: bad SID IC"); throw new InvalidOperationException(SR.StoreCtxNeedValueSecurityIdentityClaimToQuery); } // Create the ResultSet that will perform the client-side filtering SAMQuerySet resultSet = new SAMQuerySet( schemaTypes, entries, _ctxBase, -1, // no size limit this, new GroupMemberMatcher(SidB)); return(resultSet); } }
internal override ResultSet GetGroupsMemberOf(Principal p) { if (p.fakePrincipal) { DirectoryEntries children = SDSUtils.BuildDirectoryEntry(this.ctxBase.Path, this.credentials, this.authTypes).Children; List<string> schemaFilter = this.GetSchemaFilter(typeof(GroupPrincipal)); SecurityIdentifier sid = p.Sid; byte[] numArray = new byte[sid.BinaryLength]; sid.GetBinaryForm(numArray, 0); if (sid != null) { SAMQuerySet sAMQuerySet = new SAMQuerySet(schemaFilter, children, this.ctxBase, -1, this, new GroupMemberMatcher(numArray)); return sAMQuerySet; } else { throw new InvalidOperationException(StringResources.StoreCtxNeedValueSecurityIdentityClaimToQuery); } } else { if (p as UserPrincipal != null) { DirectoryEntry underlyingObject = (DirectoryEntry)p.UnderlyingObject; UnsafeNativeMethods.IADsMembers aDsMember = (UnsafeNativeMethods.IADsMembers)underlyingObject.Invoke("Groups", new object[0]); ResultSet sAMGroupsSet = new SAMGroupsSet(aDsMember, this, this.ctxBase); return sAMGroupsSet; } else { return new EmptySet(); } } }