// // Static constructor: used for initializing static tables // static QbeMatcher() { // // Load the filterPropertiesTable // s_filterPropertiesTable = new Hashtable(); for (int i = 0; i < s_filterPropertiesTableRaw.GetLength(0); i++) { Type qbeType = s_filterPropertiesTableRaw[i, 0] as Type; string winNTPropertyName = s_filterPropertiesTableRaw[i, 1] as string; MatcherDelegate f = s_filterPropertiesTableRaw[i, 2] as MatcherDelegate; Debug.Assert(qbeType != null); Debug.Assert(winNTPropertyName != null); Debug.Assert(f != null); // There should only be one entry per QBE type Debug.Assert(s_filterPropertiesTable[qbeType] == null); FilterPropertyTableEntry entry = new FilterPropertyTableEntry(); entry.winNTPropertyName = winNTPropertyName; entry.matcher = f; s_filterPropertiesTable[qbeType] = entry; } }
internal override bool Matches(DirectoryEntry de) { // If it has no SID, it's not a security principal, and we're not interested in it. // (In reg-SAM, computers don't have accounts and therefore don't have SIDs, but ADSI // creates fake Computer objects for them. In LSAM, computers CAN have accounts, and thus // SIDs). if (de.Properties["objectSid"] == null || de.Properties["objectSid"].Count == 0) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMQuerySet", "SamMatcher: Matches: skipping no-SID {0}", de.Path); return(false); } // Try to match each specified property in turn foreach (FilterBase filter in _propertiesToMatch.FiltersToApply) { FilterPropertyTableEntry entry = (FilterPropertyTableEntry)s_filterPropertiesTable[filter.GetType()]; if (entry == null) { // Must be a property we don't support throw new NotSupportedException( String.Format( CultureInfo.CurrentCulture, SR.StoreCtxUnsupportedPropertyForQuery, PropertyNamesExternal.GetExternalForm(filter.PropertyName))); } if (!entry.matcher(filter, entry.winNTPropertyName, de)) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMQuerySet", "SamMatcher: Matches: no match {0}", de.Path); return(false); } } // All tests pass --- it's a match GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMQuerySet", "SamMatcher: Matches: match {0}", de.Path); return(true); }
// 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); }
// // Static constructor: used for initializing static tables // static QbeMatcher() { // // Load the filterPropertiesTable // s_filterPropertiesTable = new Hashtable(); for (int i = 0; i < s_filterPropertiesTableRaw.GetLength(0); i++) { Type qbeType = s_filterPropertiesTableRaw[i, 0] as Type; string winNTPropertyName = s_filterPropertiesTableRaw[i, 1] as string; MatcherDelegate f = s_filterPropertiesTableRaw[i, 2] as MatcherDelegate; Debug.Assert(qbeType != null); Debug.Assert(winNTPropertyName != null); Debug.Assert(f != null); // There should only be one entry per QBE type Debug.Assert(s_filterPropertiesTable[qbeType] == null); FilterPropertyTableEntry entry = new FilterPropertyTableEntry(); entry.winNTPropertyName = winNTPropertyName; entry.matcher = f; s_filterPropertiesTable[qbeType] = entry; } }