Esempio n. 1
0
        //
        // PAPI --> S.DS (LDAP or WinNT) conversion routines
        //

        static internal void MultiStringToDirectoryEntryConverter(Principal p, string propertyName, DirectoryEntry de, string suggestedProperty)
        {
            PrincipalValueCollection <string> trackingList = (PrincipalValueCollection <string>)p.GetValueForProperty(propertyName);

            if (p.unpersisted && trackingList == null)
            {
                return;
            }

            List <string> insertedValues = trackingList.Inserted;
            List <string> removedValues  = trackingList.Removed;
            List <Pair <string, string> > changedValues = trackingList.ChangedValues;

            PropertyValueCollection properties = de.Properties[suggestedProperty];

            // We test to make sure the change hasn't already been applied to the PropertyValueCollection,
            // because PushChangesToNative can be called multiple times prior to committing the changes and
            // we want to maintain idempotency
            foreach (string value in removedValues)
            {
                if (value != null && properties.Contains(value))
                {
                    properties.Remove(value);
                }
            }

            foreach (Pair <string, string> changedValue in changedValues)
            {
                // Remove the original value and add in the new value
                Debug.Assert(changedValue.Left != null);    // since it came from the system
                properties.Remove(changedValue.Left);

                if (changedValue.Right != null && !properties.Contains(changedValue.Right))
                {
                    properties.Add(changedValue.Right);
                }
            }

            foreach (string value in insertedValues)
            {
                if (value != null && !properties.Contains(value))
                {
                    properties.Add(value);
                }
            }
        }
Esempio n. 2
0
        internal const int SAM_DefaultUAC        = (int)(0x200 | 0x1);         // UF_NORMAL_ACCOUNT | UF_SCRIPT

        static internal void AccountControlToDirectoryEntry(
            Principal p,
            string propertyName,
            DirectoryEntry de,
            string suggestedProperty,
            bool isSAM,
            bool isUnpersisted)
        {
            Debug.Assert(
                (!isSAM && (String.Equals(suggestedProperty, "userAccountControl", StringComparison.OrdinalIgnoreCase))) ||
                (isSAM && (String.Equals(suggestedProperty, "UserFlags", StringComparison.OrdinalIgnoreCase)))
                );

            bool flag = (bool)p.GetValueForProperty(propertyName);

            int uacValue = 0;

            // We want to get the current value, so we can flip the appropriate bit while leaving the other bits as-is.
            // If this is a to-be-inserted Principal, we should have already initialized the userAccountControl property
            if (de.Properties[suggestedProperty].Count > 0)
            {
                Debug.Assert(de.Properties[suggestedProperty].Count == 1);

                uacValue = (int)de.Properties[suggestedProperty][0];

                // When we write to userAccountControl, we must OR the new value with the value of msDS-User-Account-Control-Computed.
                // Otherwise we might mistakenly clear computed bits like UF_LOCKOUT.
                if (!isSAM && de.Properties["msDS-User-Account-Control-Computed"].Count > 0)
                {
                    Debug.Assert(de.Properties["msDS-User-Account-Control-Computed"].Count == 1);
                    uacValue = uacValue | (int)de.Properties["msDS-User-Account-Control-Computed"][0];
                }
            }
            else
            {
                // We don't have the userAccountControl property, this must be a persisted principal.  Perhaps we don't have access
                // to it.  In that case, we don't want to blindly overwrite whatever other bits might be there.
                Debug.Assert(p.unpersisted == false);
                throw new PrincipalOperationException(
                          SR.ADStoreCtxUnableToReadExistingAccountControlFlagsForUpdate);
            }

            uint bitmask;

            // Get the right bitmask for the property
            switch (propertyName)
            {
            case PropertyNames.AuthenticablePrincipalEnabled:
                if (!isUnpersisted || isSAM)
                {
                    // UF_ACCOUNTDISABLE
                    // Note that the logic is inverted on this one.  We expose "Enabled",
                    // but AD/SAM store it as "Disabled".
                    bitmask = 0x2;
                    flag    = !flag;
                }
                else
                {
                    // We're writing to an unpersisted AD principal
                    Debug.Assert(!isSAM && isUnpersisted);

                    // Nothing to do here.  The ADStoreCtx will take care of enabling the
                    // principal after it's persisted.
                    bitmask = 0;
                }
                break;

            case PropertyNames.AcctInfoSmartcardRequired:
                // UF_SMARTCARD_REQUIRED
                bitmask = 0x40000;
                break;

            case PropertyNames.AcctInfoDelegationPermitted:
                // UF_NOT_DELEGATED
                // Note that the logic is inverted on this one.  That's because we expose
                // "delegation allowed", but AD represents it as the inverse, "delegation NOT allowed"
                bitmask = 0x100000;
                flag    = !flag;
                break;

            case PropertyNames.PwdInfoPasswordNotRequired:
                // UF_PASSWD_NOTREQD
                bitmask = 0x0020;
                break;

            case PropertyNames.PwdInfoPasswordNeverExpires:
                // UF_DONT_EXPIRE_PASSWD
                bitmask = 0x10000;
                break;

            case PropertyNames.PwdInfoAllowReversiblePasswordEncryption:
                // UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED
                bitmask = 0x0080;
                break;

            // This bit doesn't work in userAccountControl
            case PropertyNames.PwdInfoCannotChangePassword:
                if (isSAM)
                {
                    // UF_PASSWD_CANT_CHANGE
                    bitmask = 0x0040;
                    break;
                }
                else
                {
                    Debug.Fail(
                        "SDSUtils.AccountControlToDirectoryEntry: At PwdInfoCannotChangePassword but isSAM==false, path=" + de.Path
                        );

                    goto default;
                }

            default:
                Debug.Fail("SDSUtils.AccountControlToDirectoryEntry: Fell off end looking for " + propertyName);
                bitmask = 0;
                break;
            }

            // Set/clear the "bitmask" bit in "uacValue", based on the value of "flag"
            if (flag)
            {
                Utils.SetBit(ref uacValue, bitmask);
            }
            else
            {
                Utils.ClearBit(ref uacValue, bitmask);
            }

            de.Properties[suggestedProperty].Value = uacValue;
        }
Esempio n. 3
0
        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);
                }
            }
        }
Esempio n. 4
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);
                    }
                }
            }
        }
Esempio n. 5
0
        internal static void MultiStringToDirectoryEntryConverter(Principal p, string propertyName, DirectoryEntry de, string suggestedProperty)
        {
            PrincipalValueCollection <string> valueForProperty = (PrincipalValueCollection <string>)p.GetValueForProperty(propertyName);

            if (!p.unpersisted || valueForProperty != null)
            {
                List <string> inserted = valueForProperty.Inserted;
                List <string> removed  = valueForProperty.Removed;
                List <Pair <string, string> > changedValues = valueForProperty.ChangedValues;
                PropertyValueCollection       item          = de.Properties[suggestedProperty];
                foreach (string str in removed)
                {
                    if (str == null || !item.Contains(str))
                    {
                        continue;
                    }
                    item.Remove(str);
                }
                foreach (Pair <string, string> changedValue in changedValues)
                {
                    item.Remove(changedValue.Left);
                    if (changedValue.Right == null || item.Contains(changedValue.Right))
                    {
                        continue;
                    }
                    item.Add(changedValue.Right);
                }
                foreach (string str1 in inserted)
                {
                    if (str1 == null || item.Contains(str1))
                    {
                        continue;
                    }
                    item.Add(str1);
                }
                return;
            }
            else
            {
                return;
            }
        }
Esempio n. 6
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;
            }
        }
Esempio n. 7
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);
                 }
             }
         }
     }
 }