Example #1
0
        protected QbeFilterDescription BuildQbeFilterDescription(Principal p)
        {
            QbeFilterDescription qbeFilterDescription = new QbeFilterDescription();

            if (p != null)
            {
                this.BuildFilterSet(p, StoreCtx.principalProperties, qbeFilterDescription);
            }
            if (p as AuthenticablePrincipal != null)
            {
                this.BuildFilterSet(p, StoreCtx.authenticablePrincipalProperties, qbeFilterDescription);
            }
            if (p as UserPrincipal != null)
            {
                if (!p.GetChangeStatusForProperty("AuthenticablePrincipal.AccountInfo.AccountExpirationDate") || !p.GetChangeStatusForProperty("AuthenticablePrincipal.AccountInfoExpired"))
                {
                    this.BuildFilterSet(p, StoreCtx.userProperties, qbeFilterDescription);
                }
                else
                {
                    object[] externalForm = new object[1];
                    externalForm[0] = PropertyNamesExternal.GetExternalForm("AuthenticablePrincipal.AccountInfo.AccountExpirationDate");
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.StoreCtxMultipleFiltersForPropertyUnsupported, externalForm));
                }
            }
            if (p as GroupPrincipal != null)
            {
                this.BuildFilterSet(p, StoreCtx.groupProperties, qbeFilterDescription);
            }
            if (p as ComputerPrincipal != null)
            {
                this.BuildFilterSet(p, StoreCtx.computerProperties, qbeFilterDescription);
            }
            return(qbeFilterDescription);
        }
Example #2
0
        protected QbeFilterDescription BuildQbeFilterDescription(Principal p)
        {
            QbeFilterDescription qbeFilterDescription = new QbeFilterDescription();

            // We don't have to check to make sure the application didn't try to set any
            // disallowed properties (i..e, referential properties, such as Group.Members),
            // because that check was enforced by the PrincipalSearcher in its
            // FindAll() and GetUnderlyingSearcher() methods, by calling
            // PrincipalSearcher.HasReferentialPropertiesSet().

            if (p is Principal)
            {
                BuildFilterSet(p, principalProperties, qbeFilterDescription);
            }

            if (p is AuthenticablePrincipal)
            {
                BuildFilterSet(p, authenticablePrincipalProperties, qbeFilterDescription);
            }

            if (p is UserPrincipal)  // includes AccountInfo and PasswordInfo
            {
                // AcctInfoExpirationDate and AcctInfoExpiredAccount represent filters on the same property
                // check that only one is specified
                if (p.GetChangeStatusForProperty(PropertyNames.AcctInfoExpirationDate) &&
                    p.GetChangeStatusForProperty(PropertyNames.AcctInfoExpiredAccount))
                {
                    throw new InvalidOperationException(
                              String.Format(
                                  CultureInfo.CurrentCulture,
                                  StringResources.StoreCtxMultipleFiltersForPropertyUnsupported,
                                  PropertyNamesExternal.GetExternalForm(ExpirationDateFilter.PropertyNameStatic)));
                }

                BuildFilterSet(p, userProperties, qbeFilterDescription);
            }

            if (p is GroupPrincipal)
            {
                BuildFilterSet(p, groupProperties, qbeFilterDescription);
            }

            if (p is ComputerPrincipal)
            {
                BuildFilterSet(p, computerProperties, qbeFilterDescription);
            }

            return(qbeFilterDescription);
        }
        // The core query operation.
        // Given a PrincipalSearcher containg a query filter, transforms it into the store schema
        // and performs the query to get a collection of matching native objects (up to a maximum of sizeLimit,
        // or uses the sizelimit already set on the DirectorySearcher if sizeLimit == -1).
        // If the PrincipalSearcher does not have a query filter (PrincipalSearcher.QueryFilter == null),
        // matches all principals in the store.
        //
        // The collection may not be complete, i.e., paging - the returned ResultSet will automatically
        // page in additional results as needed.
        internal override ResultSet Query(PrincipalSearcher ps, int sizeLimit)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "Query");

            Debug.Assert(sizeLimit >= -1);

            // Build the description of the properties we'll filter by.  In SAMStoreCtx, the "native" searcher
            // is simply the QbeFilterDescription, which will be passed to the SAMQuerySet to use to
            // manually filter out non-matching results.
            QbeFilterDescription propertiesToMatch = (QbeFilterDescription)PushFilterToNativeSearcher(ps);

            // 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);

            // Determine the principal types of interest.  The SAMQuerySet will use this to restrict
            // the types of DirectoryEntry objects returned.
            Type qbeFilterType = typeof(Principal);

            if (ps.QueryFilter != null)
            {
                qbeFilterType = ps.QueryFilter.GetType();
            }

            List <string> schemaTypes = GetSchemaFilter(qbeFilterType);

            // Create the ResultSet that will perform the client-side filtering
            SAMQuerySet resultSet = new SAMQuerySet(
                schemaTypes,
                entries,
                _ctxBase,
                sizeLimit,
                this,
                new QbeMatcher(propertiesToMatch));

            return(resultSet);
        }
        // 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)
        {
            // There's no underlying searcher for SAM
            Debug.Assert(ps.UnderlyingSearcher == null);

            Principal            qbeFilter = ps.QueryFilter;
            QbeFilterDescription filters;

            // If they specified a filter object, extract the set properties from it.
            // Otherwise, use an empty set.  Note that we don't worry about filtering by
            // the type of the qbeFilter object (e.g., restricting the returned principals
            // to only Users, or only Groups) --- that's handled in Query().
            if (qbeFilter != null)
            {
                filters = BuildQbeFilterDescription(qbeFilter);
            }
            else
            {
                filters = new QbeFilterDescription();
            }

            return(filters);
        }
Example #5
0
		protected QbeFilterDescription BuildQbeFilterDescription(Principal p)
		{
			QbeFilterDescription qbeFilterDescription = new QbeFilterDescription();
			if (p != null)
			{
				this.BuildFilterSet(p, StoreCtx.principalProperties, qbeFilterDescription);
			}
			if (p as AuthenticablePrincipal != null)
			{
				this.BuildFilterSet(p, StoreCtx.authenticablePrincipalProperties, qbeFilterDescription);
			}
			if (p as UserPrincipal != null)
			{
				if (!p.GetChangeStatusForProperty("AuthenticablePrincipal.AccountInfo.AccountExpirationDate") || !p.GetChangeStatusForProperty("AuthenticablePrincipal.AccountInfoExpired"))
				{
					this.BuildFilterSet(p, StoreCtx.userProperties, qbeFilterDescription);
				}
				else
				{
					object[] externalForm = new object[1];
					externalForm[0] = PropertyNamesExternal.GetExternalForm("AuthenticablePrincipal.AccountInfo.AccountExpirationDate");
					throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.StoreCtxMultipleFiltersForPropertyUnsupported, externalForm));
				}
			}
			if (p as GroupPrincipal != null)
			{
				this.BuildFilterSet(p, StoreCtx.groupProperties, qbeFilterDescription);
			}
			if (p as ComputerPrincipal != null)
			{
				this.BuildFilterSet(p, StoreCtx.computerProperties, qbeFilterDescription);
			}
			return qbeFilterDescription;
		}
Example #6
0
		private void BuildFilterSet(Principal p, string[] propertySet, QbeFilterDescription qbeFilterDescription)
		{
			string[] strArrays = propertySet;
			for (int i = 0; i < (int)strArrays.Length; i++)
			{
				string str = strArrays[i];
				if (p.GetChangeStatusForProperty(str))
				{
					object valueForProperty = p.GetValueForProperty(str);
					if (valueForProperty as PrincipalValueCollection<string> == null)
					{
						if (valueForProperty as X509Certificate2Collection == null)
						{
							object obj = FilterFactory.CreateFilter(str);
							if (valueForProperty != null)
							{
								if (!valueForProperty as bool)
								{
									if (valueForProperty as string == null)
									{
										if (valueForProperty as GroupScope == GroupScope.Local)
										{
											if (valueForProperty as byte[] == null)
											{
												if (valueForProperty as DateTime? == null)
												{
													if (valueForProperty as ExtensionCache == null)
													{
														if (valueForProperty as QbeMatchType != null)
														{
															((FilterBase)obj).Value = (QbeMatchType)valueForProperty;
														}
													}
													else
													{
														((FilterBase)obj).Value = (ExtensionCache)valueForProperty;
													}
												}
												else
												{
													((FilterBase)obj).Value = (DateTime?)valueForProperty;
												}
											}
											else
											{
												((FilterBase)obj).Value = (byte[])valueForProperty;
											}
										}
										else
										{
											((FilterBase)obj).Value = (GroupScope)valueForProperty;
										}
									}
									else
									{
										((FilterBase)obj).Value = (string)valueForProperty;
									}
								}
								else
								{
									((FilterBase)obj).Value = (bool)valueForProperty;
								}
							}
							else
							{
								((FilterBase)obj).Value = null;
							}
							qbeFilterDescription.FiltersToApply.Add(obj);
						}
						else
						{
							X509Certificate2Collection x509Certificate2Collection = (X509Certificate2Collection)valueForProperty;
							X509Certificate2Enumerator enumerator = x509Certificate2Collection.GetEnumerator();
							while (enumerator.MoveNext())
							{
								X509Certificate2 current = enumerator.Current;
								object obj1 = FilterFactory.CreateFilter(str);
								((FilterBase)obj1).Value = current;
								qbeFilterDescription.FiltersToApply.Add(obj1);
							}
						}
					}
					else
					{
						PrincipalValueCollection<string> strs = (PrincipalValueCollection<string>)valueForProperty;
						foreach (string inserted in strs.Inserted)
						{
							object obj2 = FilterFactory.CreateFilter(str);
							((FilterBase)obj2).Value = inserted;
							qbeFilterDescription.FiltersToApply.Add(obj2);
						}
					}
				}
			}
		}
Example #7
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);
                    }
                }
            }
        }
Example #8
0
 internal QbeMatcher(QbeFilterDescription propertiesToMatch)
 {
     _propertiesToMatch = propertiesToMatch;
 }
Example #9
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);
        }
Example #10
0
		internal QbeMatcher(QbeFilterDescription propertiesToMatch)
		{
			this.propertiesToMatch = propertiesToMatch;
		}
Example #11
0
		internal override object PushFilterToNativeSearcher(PrincipalSearcher ps)
		{
			QbeFilterDescription qbeFilterDescription;
			Principal queryFilter = ps.QueryFilter;
			if (queryFilter == null)
			{
				qbeFilterDescription = new QbeFilterDescription();
			}
			else
			{
				qbeFilterDescription = base.BuildQbeFilterDescription(queryFilter);
			}
			return qbeFilterDescription;
		}
Example #12
0
 private void BuildFilterSet(Principal p, string[] propertySet, QbeFilterDescription qbeFilterDescription)
 {
     string[] strArrays = propertySet;
     for (int i = 0; i < (int)strArrays.Length; i++)
     {
         string str = strArrays[i];
         if (p.GetChangeStatusForProperty(str))
         {
             object valueForProperty = p.GetValueForProperty(str);
             if (valueForProperty as PrincipalValueCollection <string> == null)
             {
                 if (valueForProperty as X509Certificate2Collection == null)
                 {
                     object obj = FilterFactory.CreateFilter(str);
                     if (valueForProperty != null)
                     {
                         if (!valueForProperty as bool)
                         {
                             if (valueForProperty as string == null)
                             {
                                 if (valueForProperty as GroupScope == GroupScope.Local)
                                 {
                                     if (valueForProperty as byte[] == null)
                                     {
                                         if (valueForProperty as DateTime? == null)
                                         {
                                             if (valueForProperty as ExtensionCache == null)
                                             {
                                                 if (valueForProperty as QbeMatchType != null)
                                                 {
                                                     ((FilterBase)obj).Value = (QbeMatchType)valueForProperty;
                                                 }
                                             }
                                             else
                                             {
                                                 ((FilterBase)obj).Value = (ExtensionCache)valueForProperty;
                                             }
                                         }
                                         else
                                         {
                                             ((FilterBase)obj).Value = (DateTime?)valueForProperty;
                                         }
                                     }
                                     else
                                     {
                                         ((FilterBase)obj).Value = (byte[])valueForProperty;
                                     }
                                 }
                                 else
                                 {
                                     ((FilterBase)obj).Value = (GroupScope)valueForProperty;
                                 }
                             }
                             else
                             {
                                 ((FilterBase)obj).Value = (string)valueForProperty;
                             }
                         }
                         else
                         {
                             ((FilterBase)obj).Value = (bool)valueForProperty;
                         }
                     }
                     else
                     {
                         ((FilterBase)obj).Value = null;
                     }
                     qbeFilterDescription.FiltersToApply.Add(obj);
                 }
                 else
                 {
                     X509Certificate2Collection x509Certificate2Collection = (X509Certificate2Collection)valueForProperty;
                     X509Certificate2Enumerator enumerator = x509Certificate2Collection.GetEnumerator();
                     while (enumerator.MoveNext())
                     {
                         X509Certificate2 current = enumerator.Current;
                         object           obj1    = FilterFactory.CreateFilter(str);
                         ((FilterBase)obj1).Value = current;
                         qbeFilterDescription.FiltersToApply.Add(obj1);
                     }
                 }
             }
             else
             {
                 PrincipalValueCollection <string> strs = (PrincipalValueCollection <string>)valueForProperty;
                 foreach (string inserted in strs.Inserted)
                 {
                     object obj2 = FilterFactory.CreateFilter(str);
                     ((FilterBase)obj2).Value = inserted;
                     qbeFilterDescription.FiltersToApply.Add(obj2);
                 }
             }
         }
     }
 }