Пример #1
0
 internal protected AdvancedFilters(Principal p)
 {
     _p = p;
 }
 internal override bool IsMemberOfInStore(GroupPrincipal g, Principal p)
 {
     Debug.Fail("SAMStoreCtx.IsMemberOfInStore: Shouldn't be here.");
     return(false);
 }
        //
        // Cross-store support
        //

        // Given a native store object that represents a "foreign" principal (e.g., a FPO object in this store that
        // represents a pointer to another store), maps that representation to the other store's StoreCtx and returns
        // a Principal from that other StoreCtx.  The implementation of this method is highly dependent on the
        // details of the particular store, and must have knowledge not only of this StoreCtx, but also of how to
        // interact with other StoreCtxs to fulfill the request.
        //
        // This method is typically used by ResultSet implementations, when they're iterating over a collection
        // (e.g., of group membership) and encounter an entry that represents a foreign principal.
        internal override Principal ResolveCrossStoreRefToPrincipal(object o)
        {
            Debug.Assert(o is DirectoryEntry);

            // Get the SID of the foreign principal
            DirectoryEntry foreignDE = (DirectoryEntry)o;

            if (foreignDE.Properties["objectSid"].Count == 0)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Warn, "SAMStoreCtx", "ResolveCrossStoreRefToPrincipal: no objectSid found");
                throw new PrincipalOperationException(SR.SAMStoreCtxCantRetrieveObjectSidForCrossStore);
            }

            Debug.Assert(foreignDE.Properties["objectSid"].Count == 1);

            byte[] sid = (byte[])foreignDE.Properties["objectSid"].Value;

            // Ask the OS to resolve the SID to its target.
            int    accountUsage = 0;
            string name;
            string domainName;

            int err = Utils.LookupSid(this.MachineUserSuppliedName, _credentials, sid, out name, out domainName, out accountUsage);

            if (err != 0)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Warn,
                                        "SAMStoreCtx",
                                        "ResolveCrossStoreRefToPrincipal: LookupSid failed, err={0}, server={1}",
                                        err,
                                        this.MachineUserSuppliedName);

                throw new PrincipalOperationException(
                          SR.Format(SR.SAMStoreCtxCantResolveSidForCrossStore, err));
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                    "SAMStoreCtx",
                                    "ResolveCrossStoreRefToPrincipal: LookupSid found {0} in {1}",
                                    name,
                                    domainName);

            // Since this is SAM, the remote principal must be an AD principal.
            // Build a PrincipalContext for the store which owns the principal
            // Use the ad default options so we turn sign and seal back on.
#if USE_CTX_CACHE
            PrincipalContext remoteCtx = SDSCache.Domain.GetContext(domainName, _credentials, DefaultContextOptions.ADDefaultContextOption);
#else
            PrincipalContext remoteCtx = new PrincipalContext(
                ContextType.Domain,
                domainName,
                null,
                (this.credentials != null ? credentials.UserName : null),
                (this.credentials != null ? credentials.Password : null),
                DefaultContextOptions.ADDefaultContextOption);
#endif

            SecurityIdentifier sidObj = new SecurityIdentifier(sid, 0);

            Principal p = remoteCtx.QueryCtx.FindPrincipalByIdentRef(
                typeof(Principal),
                UrnScheme.SidScheme,
                sidObj.ToString(),
                DateTime.UtcNow);

            if (p != null)
            {
                return(p);
            }
            else
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Warn, "SAMStoreCtx", "ResolveCrossStoreRefToPrincipal: no matching principal");
                throw new PrincipalOperationException(SR.SAMStoreCtxFailedFindCrossStoreTarget);
            }
        }
Пример #4
0
 internal static void SingleScalarFromDirectoryEntry <T>(dSPropertyCollection properties, string suggestedProperty, Principal p, string propertyName)
 {
     if (properties[suggestedProperty].Count != 0 && properties[suggestedProperty][0] != null)
     {
         p.LoadValueIntoProperty(propertyName, (T)properties[suggestedProperty][0]);
     }
 }
 internal override void Move(StoreCtx originalStore, Principal p)
 {
     GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "Move");
 }
Пример #6
0
 protected internal AdvancedFilters(Principal p)
 {
     this.p = p;
 }
Пример #7
0
        internal static void AccountControlToDirectoryEntry(Principal p, string propertyName, DirectoryEntry de, string suggestedProperty, bool isSAM, bool isUnpersisted)
        {
            uint num;
            bool valueForProperty = (bool)p.GetValueForProperty(propertyName);

            if (de.Properties[suggestedProperty].Count <= 0)
            {
                throw new PrincipalOperationException(StringResources.ADStoreCtxUnableToReadExistingAccountControlFlagsForUpdate);
            }
            else
            {
                int item = (int)de.Properties[suggestedProperty][0];
                if (!isSAM && de.Properties["msDS-User-Account-Control-Computed"].Count > 0)
                {
                    item = item | (int)de.Properties["msDS-User-Account-Control-Computed"][0];
                }
                string str  = propertyName;
                string str1 = str;
                if (str != null)
                {
                    if (str1 == "AuthenticablePrincipal.Enabled")
                    {
                        if (!isUnpersisted || isSAM)
                        {
                            num = 2;
                            valueForProperty = !valueForProperty;
                            if (!valueForProperty)
                            {
                                Utils.ClearBit(ref item, num);
                            }
                            else
                            {
                                Utils.SetBit(ref item, num);
                            }
                            de.Properties[suggestedProperty].Value = (object)item;
                            return;
                        }
                        else
                        {
                            num = 0;
                            if (!valueForProperty)
                            {
                                Utils.ClearBit(ref item, num);
                            }
                            else
                            {
                                Utils.SetBit(ref item, num);
                            }
                            de.Properties[suggestedProperty].Value = (object)item;
                            return;
                        }
                    }
                    else if (str1 == "AuthenticablePrincipal.AccountInfo.SmartcardLogonRequired")
                    {
                        num = 0x40000;
                        if (!valueForProperty)
                        {
                            Utils.ClearBit(ref item, num);
                        }
                        else
                        {
                            Utils.SetBit(ref item, num);
                        }
                        de.Properties[suggestedProperty].Value = (object)item;
                        return;
                    }
                    else if (str1 == "AuthenticablePrincipal.AccountInfo.DelegationPermitted")
                    {
                        num = 0x100000;
                        valueForProperty = !valueForProperty;
                        if (!valueForProperty)
                        {
                            Utils.ClearBit(ref item, num);
                        }
                        else
                        {
                            Utils.SetBit(ref item, num);
                        }
                        de.Properties[suggestedProperty].Value = (object)item;
                        return;
                    }
                    else if (str1 == "AuthenticablePrincipal.PasswordInfo.PasswordNotRequired")
                    {
                        num = 32;
                        if (!valueForProperty)
                        {
                            Utils.ClearBit(ref item, num);
                        }
                        else
                        {
                            Utils.SetBit(ref item, num);
                        }
                        de.Properties[suggestedProperty].Value = (object)item;
                        return;
                    }
                    else if (str1 == "AuthenticablePrincipal.PasswordInfo.PasswordNeverExpires")
                    {
                        num = 0x10000;
                        if (!valueForProperty)
                        {
                            Utils.ClearBit(ref item, num);
                        }
                        else
                        {
                            Utils.SetBit(ref item, num);
                        }
                        de.Properties[suggestedProperty].Value = (object)item;
                        return;
                    }
                    else if (str1 == "AuthenticablePrincipal.PasswordInfo.AllowReversiblePasswordEncryption")
                    {
                        num = 128;
                        if (!valueForProperty)
                        {
                            Utils.ClearBit(ref item, num);
                        }
                        else
                        {
                            Utils.SetBit(ref item, num);
                        }
                        de.Properties[suggestedProperty].Value = (object)item;
                        return;
                    }
                    else if (str1 == "AuthenticablePrincipal.PasswordInfo.UserCannotChangePassword")
                    {
                        if (!isSAM)
                        {
                            num = 0;
                            if (!valueForProperty)
                            {
                                Utils.ClearBit(ref item, num);
                            }
                            else
                            {
                                Utils.SetBit(ref item, num);
                            }
                            de.Properties[suggestedProperty].Value = (object)item;
                            return;
                        }
                        num = 64;
                        if (!valueForProperty)
                        {
                            Utils.ClearBit(ref item, num);
                        }
                        else
                        {
                            Utils.SetBit(ref item, num);
                        }
                        de.Properties[suggestedProperty].Value = (object)item;
                        return;
                    }
                    num = 0;
                    if (!valueForProperty)
                    {
                        Utils.ClearBit(ref item, num);
                    }
                    else
                    {
                        Utils.SetBit(ref item, num);
                    }
                    de.Properties[suggestedProperty].Value = (object)item;
                    return;
                }
                else
                {
                    num = 0;
                    if (!valueForProperty)
                    {
                        Utils.ClearBit(ref item, num);
                    }
                    else
                    {
                        Utils.SetBit(ref item, num);
                    }
                    de.Properties[suggestedProperty].Value = (object)item;
                    return;
                }
                if (!valueForProperty)
                {
                    Utils.ClearBit(ref item, num);
                }
                else
                {
                    Utils.SetBit(ref item, num);
                }
                de.Properties[suggestedProperty].Value = item;
                return;
            }
        }
Пример #8
0
 // Can the given member be removed from the specified group?  If not, also returns
 // a string containing a human-readable explanation of why not, suitable for use in an exception.
 internal abstract bool CanGroupMemberBeRemoved(GroupPrincipal g, Principal member, out string explanationForFailure);
Пример #9
0
        //
        // Data Validation
        //

        // Validiate the passed property name to determine if it is valid for the store and Principal type.
        // used by the principal objects to determine if a property is valid in the property before
        // save is called.
        internal abstract bool IsValidProperty(Principal p, string propertyName);
Пример #10
0
 // Get groups of which p is a member, using AuthZ S4U APIs for recursive membership
 internal abstract ResultSet GetGroupsMemberOfAZ(Principal p);
Пример #11
0
 internal abstract bool IsMemberOfInStore(GroupPrincipal g, Principal p);
Пример #12
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);
Пример #13
0
 internal abstract bool AccessCheck(Principal p, PrincipalAccessMask targetPermission);
Пример #14
0
 // Returns a type indicating the type of object that would be returned as the wormhole for the specified
 // Principal.  For some StoreCtxs, this method may always return a constant (e.g., typeof(DirectoryEntry)
 // for ADStoreCtx).  For others, it may vary depending on the Principal passed in.
 internal abstract Type NativeType(Principal p);
Пример #15
0
 // Loads only the psecified property into the principal object.  The object should have already been persisted or searched for this to happen.
 internal abstract void Load(Principal p, string principalPropertyName);
Пример #16
0
        private void BuildFilterSet(Principal p, string[] propertySet, QbeFilterDescription qbeFilterDescription)
        {
            foreach (string propertyName in propertySet)
            {
                if (p.GetChangeStatusForProperty(propertyName))
                {
                    // Property has changed.  Add it to the filter set.
                    object value = p.GetValueForProperty(propertyName);

                    GlobalDebug.WriteLineIf(
                        GlobalDebug.Info,
                        "StoreCtx",
                        "BuildFilterSet: type={0}, property name={1}, property value={2} of type {3}",
                        p.GetType().ToString(),
                        propertyName,
                        value.ToString(),
                        value.GetType().ToString());

                    // Build the right filter based on type of the property value
                    if (value is PrincipalValueCollection <string> )
                    {
                        PrincipalValueCollection <string> trackingList = (PrincipalValueCollection <string>)value;
                        foreach (string s in trackingList.Inserted)
                        {
                            object filter = FilterFactory.CreateFilter(propertyName);
                            ((FilterBase)filter).Value = (string)s;
                            qbeFilterDescription.FiltersToApply.Add(filter);
                        }
                    }
                    else if (value is X509Certificate2Collection)
                    {
                        // Since QBE filter objects are always unpersisted, any certs in the collection
                        // must have been inserted by the application.
                        X509Certificate2Collection certCollection = (X509Certificate2Collection)value;
                        foreach (X509Certificate2 cert in certCollection)
                        {
                            object filter = FilterFactory.CreateFilter(propertyName);
                            ((FilterBase)filter).Value = (X509Certificate2)cert;
                            qbeFilterDescription.FiltersToApply.Add(filter);
                        }
                    }
                    else
                    {
                        // It's not one of the multivalued cases.  Try the scalar cases.

                        object filter = FilterFactory.CreateFilter(propertyName);

                        if (value == null)
                        {
                            ((FilterBase)filter).Value = null;
                        }
                        else if (value is bool)
                        {
                            ((FilterBase)filter).Value = (bool)value;
                        }
                        else if (value is string)
                        {
                            ((FilterBase)filter).Value = (string)value;
                        }
                        else if (value is GroupScope)
                        {
                            ((FilterBase)filter).Value = (GroupScope)value;
                        }
                        else if (value is byte[])
                        {
                            ((FilterBase)filter).Value = (byte[])value;
                        }
                        else if (value is Nullable <DateTime> )
                        {
                            ((FilterBase)filter).Value = (Nullable <DateTime>)value;
                        }
                        else if (value is ExtensionCache)
                        {
                            ((FilterBase)filter).Value = (ExtensionCache)value;
                        }
                        else if (value is QbeMatchType)
                        {
                            ((FilterBase)filter).Value = (QbeMatchType)value;
                        }
                        else
                        {
                            // Internal error.  Didn't match either the known multivalued or scalar cases.
                            Debug.Fail(String.Format(
                                           CultureInfo.CurrentCulture,
                                           "StoreCtx.BuildFilterSet: fell off end looking for {0} of type {1}",
                                           propertyName,
                                           value.GetType().ToString()
                                           ));
                        }

                        qbeFilterDescription.FiltersToApply.Add(filter);
                    }
                }
            }
        }
Пример #17
0
        // Pushes the query represented by the QBE filter into the PrincipalSearcher's underlying native
        // searcher object (creating a fresh native searcher and assigning it to the PrincipalSearcher if one
        // doesn't already exist) and returns the native searcher.
        // If the PrincipalSearcher does not have a query filter set (PrincipalSearcher.QueryFilter == null),
        // produces a query that will match all principals in the store.
        //
        // For stores which don't have a native searcher (SAM), the StoreCtx
        // is free to create any type of object it chooses to use as its internal representation of the query.
        //
        // Also adds in any clauses to the searcher to ensure that only principals, not mere
        // contacts, are retrieved from the store.
        internal override object PushFilterToNativeSearcher(PrincipalSearcher ps)
        {
            // This is the first time we're being called on this principal.  Create a fresh searcher.
            if (ps.UnderlyingSearcher == null)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "PushFilterToNativeSearcher: creating fresh DirectorySearcher");

                ps.UnderlyingSearcher = new DirectorySearcher(this.ctxBase);
                ((DirectorySearcher)ps.UnderlyingSearcher).PageSize        = ps.PageSize;
                ((DirectorySearcher)ps.UnderlyingSearcher).ServerTimeLimit = new TimeSpan(0, 0, 30);  // 30 seconds
            }

            DirectorySearcher ds = (DirectorySearcher)ps.UnderlyingSearcher;

            Principal qbeFilter = ps.QueryFilter;

            StringBuilder ldapFilter = new StringBuilder();

            if (qbeFilter == null)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "PushFilterToNativeSearcher: no qbeFilter specified");

                // No filter specified.  Search for all principals (all users, computers, groups).
                ldapFilter.Append("(|(objectClass=user)(objectClass=computer)(objectClass=group))");
            }
            else
            {
                //
                // Start by appending the appropriate objectClass given the Principal type
                //
                ldapFilter.Append(GetObjectClassPortion(qbeFilter.GetType()));

                //
                // Next, fill in the properties (if any)
                //
                QbeFilterDescription filters = BuildQbeFilterDescription(qbeFilter);

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "PushFilterToNativeSearcher: using {0} filters", filters.FiltersToApply.Count);

                Hashtable filterTable = (Hashtable)s_filterPropertiesTable[this.MappingTableIndex];

                foreach (FilterBase filter in filters.FiltersToApply)
                {
                    FilterPropertyTableEntry entry = (FilterPropertyTableEntry)filterTable[filter.GetType()];

                    if (entry == null)
                    {
                        // Must be a property we don't support
                        throw new InvalidOperationException(
                                  SR.Format(
                                      SR.StoreCtxUnsupportedPropertyForQuery,
                                      PropertyNamesExternal.GetExternalForm(filter.PropertyName)));
                    }

                    ldapFilter.Append(entry.converter(filter, entry.suggestedADPropertyName));
                }

                //
                // Wrap off the filter
                //
                ldapFilter.Append(')');
            }

            // We don't need any attributes returned, since we're just going to get a DirectoryEntry
            // for the result.  Per RFC 2251, OID 1.1 == no attributes.
            //ds.PropertiesToLoad.Add("1.1");
            BuildPropertySet(qbeFilter.GetType(), ds.PropertiesToLoad);

            ds.Filter = ldapFilter.ToString();
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "PushFilterToNativeSearcher: using LDAP filter {0}", ds.Filter);

            return(ds);
        }
Пример #18
0
        //
        // CRUD
        //

        // Used to perform the specified operation on the Principal.  They also make any needed security subsystem
        // calls to obtain digitial signatures (e..g, to sign the Principal Extension/GroupMember Relationship for
        // WinFS).
        //
        // Insert() and Update() must check to make sure no properties not supported by this StoreCtx
        // have been set, prior to persisting the Principal.
        internal abstract void Insert(Principal p);
Пример #19
0
        internal static void AccountControlFromDirectoryEntry(dSPropertyCollection properties, string suggestedProperty, Principal p, string propertyName, bool testCantChangePassword)
        {
            dSPropertyValueCollection item = properties[suggestedProperty];

            if (item.Count != 0)
            {
                int  num  = (int)item[0];
                bool flag = SDSUtils.StatusFromAccountControl(num, propertyName);
                p.LoadValueIntoProperty(propertyName, flag);
            }
        }
Пример #20
0
 internal abstract void Update(Principal p);
Пример #21
0
        internal static void MultiScalarFromDirectoryEntry <T>(dSPropertyCollection properties, string suggestedProperty, Principal p, string propertyName)
        {
            dSPropertyValueCollection item = properties[suggestedProperty];
            List <T> ts = new List <T>();

            foreach (object obj in item)
            {
                ts.Add((T)obj);
            }
            p.LoadValueIntoProperty(propertyName, ts);
        }
Пример #22
0
 internal abstract void Delete(Principal p);
Пример #23
0
        private bool MoveNextForeign()
        {
            bool needToRetry;

            do
            {
                needToRetry = false;

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextForeign: foreignMembers count={0}", _foreignMembers.Count);

                if (_foreignMembers.Count > 0)
                {
                    // foreignDE is a DirectoryEntry in _this_ store representing a principal in another store
                    DirectoryEntry foreignDE = _foreignMembers[0];
                    _foreignMembers.RemoveAt(0);

                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextForeign: foreignDE={0}", foreignDE.Path);

                    // foreignPrincipal is a principal from _another_ store (e.g., it's backed by an ADStoreCtx)
                    Principal foreignPrincipal = _storeCtx.ResolveCrossStoreRefToPrincipal(foreignDE);

                    // If we're not enumerating recursively, return the principal.
                    // If we are enumerating recursively, and it's a group, save it off for later.
                    if (!_recursive || !(foreignPrincipal is GroupPrincipal))
                    {
                        // Return the principal.
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextForeign: setting currentForeign to {0}", foreignDE.Path);

                        _current = null;
                        _currentFakePrincipal = null;
                        _currentForeign       = foreignPrincipal;

                        if (_foreignResultSet != null)
                        {
                            _foreignResultSet.Dispose();
                        }
                        _foreignResultSet = null;
                        return(true);
                    }
                    else
                    {
                        // Save off the group for recursive expansion, and go on to the next principal.
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextForeign: adding {0} to foreignGroups", foreignDE.Path);

                        _foreignGroups.Add((GroupPrincipal)foreignPrincipal);
                        needToRetry = true;
                        continue;
                    }
                }

                if (_foreignResultSet == null && _foreignGroups.Count > 0)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                            "SAMMembersSet",
                                            "MoveNextForeign: getting foreignResultSet (foreignGroups count={0})",
                                            _foreignGroups.Count);

                    // We're expanding recursively, and either (1) we're immediately before
                    // the recursive expansion of the first foreign group, or (2) we just completed
                    // the recursive expansion of a foreign group, and now are moving on to the next.
                    Debug.Assert(_recursive == true);

                    // Pull off a foreign group to expand.
                    GroupPrincipal foreignGroup = _foreignGroups[0];
                    _foreignGroups.RemoveAt(0);

                    // Since it's a foreign group, we don't know how to enumerate its members.  So we'll
                    // ask the group, through its StoreCtx, to do it for us.  Effectively, we'll end up acting
                    // as a proxy to the foreign group's ResultSet.
                    _foreignResultSet = foreignGroup.GetStoreCtxToUse().GetGroupMembership(foreignGroup, true);
                }

                // We're either just beginning the recursive expansion of a foreign group, or we're continuing the expansion
                // that we started on a previous call to MoveNext().
                if (_foreignResultSet != null)
                {
                    Debug.Assert(_recursive == true);

                    bool f = _foreignResultSet.MoveNext();

                    if (f)
                    {
                        // By setting current, currentFakePrincipal, and currentForeign to null,
                        // CurrentAsPrincipal/CurrentAsIdentityReference will know to proxy out to foreignResultSet.
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextForeign: using foreignResultSet");

                        _current = null;
                        _currentFakePrincipal = null;
                        _currentForeign       = null;
                        return(true);
                    }

                    // Ran out of members in the foreign group, is there another foreign group remaining that we need
                    // to expand?
                    if (_foreignGroups.Count > 0)
                    {
                        // Yes, there is.  Null out the foreignResultSet so we'll pull out the next foreign group
                        // the next time around the loop.
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextForeign: ran out of members, using next foreignResultSet");

                        _foreignResultSet.Dispose();
                        _foreignResultSet = null;
                        Debug.Assert(_foreignMembers.Count == 0);
                        needToRetry = true;
                    }
                    else
                    {
                        // No, there isn't.  Nothing left to do.  We set foreignResultSet to null here just
                        // to leave things in a clean state --- it shouldn't really be necessary.
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextForeign: ran out of members, nothing more to do");

                        _foreignResultSet.Dispose();
                        _foreignResultSet = null;
                    }
                }
            }while (needToRetry);

            return(false);
        }
Пример #24
0
 internal abstract void Move(StoreCtx originalStore, Principal p);
        // 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);
            }
        }
Пример #26
0
        //
        // Native <--> Principal
        //

        // For modified object, pushes any changes (including IdentityClaim changes)
        // into the underlying store-specific object (e.g., DirectoryEntry) and returns the underlying object.
        // For unpersisted object, creates a  underlying object if one doesn't already exist (in
        // Principal.UnderlyingObject), then pushes any changes into the underlying object.
        internal abstract object PushChangesToNative(Principal p);
 // Can the given member be removed from the specified group?  If not, also returns
 // a string containing a human-readable explanation of why not, suitable for use in an exception.
 internal override bool CanGroupMemberBeRemoved(GroupPrincipal g, Principal member, out string explanationForFailure)
 {
     // Always true for this type of StoreCtx
     explanationForFailure = null;
     return(true);
 }
Пример #28
0
 // Loads the store values from p.UnderlyingObject into p, performing schema mapping as needed.
 internal abstract void Load(Principal p);
Пример #29
0
 public static IObservable <DirectoryEntry> GetAllGroups(this Principal source, IScheduler scheduler = null) => Locator.Current.GetService <ADFacade>().GetParents(source.GetGroups().Select(principal => principal.Name), scheduler);
Пример #30
0
 internal ExtensionHelper(Principal p)
 {
     _p = p;
 }