internal static void InsertPrincipal(Principal p, StoreCtx storeCtx, SDSUtils.GroupMembershipUpdater updateGroupMembership, NetCred credentials, AuthenticationTypes authTypes, bool needToSetPassword) { if (p as UserPrincipal != null || p as GroupPrincipal != null || p as AuthenticablePrincipal != null || p as ComputerPrincipal != null) { SDSUtils.ApplyChangesToDirectory(p, storeCtx, updateGroupMembership, credentials, authTypes); if (needToSetPassword && p.GetChangeStatusForProperty("AuthenticablePrincipal.PasswordInfo.Password")) { string valueForProperty = (string)p.GetValueForProperty("AuthenticablePrincipal.PasswordInfo.Password"); storeCtx.SetPassword((AuthenticablePrincipal)p, valueForProperty); } if (p.GetChangeStatusForProperty("AuthenticablePrincipal.PasswordInfo.ExpireImmediately")) { bool flag = (bool)p.GetValueForProperty("AuthenticablePrincipal.PasswordInfo.ExpireImmediately"); if (flag) { storeCtx.ExpirePassword((AuthenticablePrincipal)p); } } return; } else { object[] str = new object[1]; str[0] = p.GetType().ToString(); throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.StoreCtxUnsupportedPrincipalTypeForSave, str)); } }
internal override bool IsValidProperty(Principal p, string propertyName) { ObjectMask value = ObjectMask.None; if (s_validPropertyMap.TryGetValue(propertyName, out value)) { return((s_maskMap[p.GetType()] & value) > 0 ? true : false); } else { Debug.Fail("Property not found"); return(false); } }
private bool HasReferentialPropertiesSet() { // If using a null query filter, nothing to validate, as it can't have any referential // properties set. if (_qbeFilter == null) { return(false); } // Since the QBE filter must be in the "unpersisted" state, any set properties have their changed // flag still set (qbeFilter.GetChangeStatusForProperty() == true). Therefore, checking which properties // have been set == checking which properties have their change flag set to true. Debug.Assert(_qbeFilter.unpersisted == true); // Retrieve the list of referential properties for this type of Principal. // If this type of Principal doesn't have any, the Properties hashtable will return null. Type t = _qbeFilter.GetType(); GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalSearcher", "HasReferentialPropertiesSet: using type " + t.ToString()); ArrayList referentialProperties = (ArrayList)ReferentialProperties.Properties[t]; if (referentialProperties != null) { foreach (string propertyName in referentialProperties) { if (_qbeFilter.GetChangeStatusForProperty(propertyName) == true) { // Property was set. GlobalDebug.WriteLineIf(GlobalDebug.Warn, "PrincipalSearcher", "HasReferentialPropertiesSet: found ref property " + propertyName); return(true); } } } return(false); }
static internal 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( String.Format(CultureInfo.CurrentCulture, SR.StoreCtxUnsupportedPrincipalTypeForSave, p.GetType().ToString())); } // 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); } } }
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); } } } }
// 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); }