/// <summary>
        ///		Adds the specified access rule to the Discretionary Access Control List (DACL) associated with this
        ///		<see cref="CommonObjectSecurity"/> object.
        /// </summary>
        /// <param name="rule">The access rule to add.</param>
        /// <returns><strong>True</strong> if the access rule was added, otherwise <strong>False</strong>.</returns>
        /// <remarks>
        ///		The method does nothing if current DACL already contains identity specified in the <strong>rule</strong>
        ///		parameter. DACL merging is not supported.
        /// </remarks>
        public Boolean AddAccessRule(CertTemplateAccessRule rule)
        {
            AuthorizationRuleCollection rules = GetAccessRules(true, false, typeof(NTAccount));
            CertTemplateRights          effectiveRuleRights = rule.Rights;

            if (_schemaVersion == 1 && (rule.Rights & CertTemplateRights.Autoenroll) > 0)
            {
                effectiveRuleRights &= ~CertTemplateRights.Autoenroll;
            }

            var existingRule = rules
                               .Cast <CertTemplateAccessRule>()
                               .FirstOrDefault(x => x.IdentityReference.Value == rule.IdentityReference.Value && x.AccessControlType == rule.AccessControlType);

            if (existingRule != null)
            {
                RemoveAccessRule(existingRule);
                var ace = new CertTemplateAccessRule(
                    rule.IdentityReference,
                    effectiveRuleRights | existingRule.Rights,
                    rule.AccessControlType);
                base.AddAccessRule(ace);
                return(true);
            }
            base.AddAccessRule(rule);
            return(true);
        }
        void fromActiveDirectorySecurity()
        {
            ActiveDirectorySecurity dsSecurity;

            using (var entry = new DirectoryEntry("LDAP://" + _x500Name)) {
                dsSecurity = entry.ObjectSecurity;
            }

            try {
                SetOwner(dsSecurity.GetOwner(typeof(NTAccount)));
            } catch {
                SetOwner(dsSecurity.GetOwner(typeof(SecurityIdentifier)));
            }

            IEnumerable <IdentityReference> users = dsSecurity
                                                    .GetAccessRules(true, true, typeof(NTAccount))
                                                    .Cast <ActiveDirectoryAccessRule>()
                                                    .Select(x => x.IdentityReference)
                                                    .Distinct();

            foreach (IdentityReference user in users)
            {
                foreach (AccessControlType accessType in Enum.GetValues(typeof(AccessControlType)))
                {
                    CertTemplateRights rights = 0;
                    IEnumerable <ActiveDirectoryAccessRule> aceList = dsSecurity.GetAccessRules(true, true, typeof(NTAccount))
                                                                      .Cast <ActiveDirectoryAccessRule>()
                                                                      .Where(x => x.IdentityReference == user && x.AccessControlType == accessType);
                    foreach (ActiveDirectoryAccessRule ace in aceList)
                    {
                        ActiveDirectoryRights aceRights = ace.ActiveDirectoryRights;
                        if (aceRights.HasFlag(ActiveDirectoryRights.GenericRead) || aceRights.HasFlag(ActiveDirectoryRights.GenericExecute))
                        {
                            rights |= CertTemplateRights.Read;
                        }
                        if (aceRights.HasFlag(ActiveDirectoryRights.WriteDacl))
                        {
                            rights |= CertTemplateRights.Write;
                        }
                        if (aceRights.HasFlag(ActiveDirectoryRights.GenericAll))
                        {
                            rights |= CertTemplateRights.FullControl;
                        }
                        if (aceRights.HasFlag(ActiveDirectoryRights.ExtendedRight))
                        {
                            switch (ace.ObjectType.ToString())
                            {
                            case GUID_ENROLL:
                                rights |= CertTemplateRights.Enroll;
                                break;

                            case GUID_AUTOENROLL:
                                rights |= CertTemplateRights.Autoenroll;
                                break;
                            }
                        }
                    }
                    if (rights > 0)
                    {
                        AddAccessRule(new CertTemplateAccessRule(user, rights, accessType));
                    }
                }
            }
        }
        ActiveDirectorySecurity toAdSecurity(DirectoryEntry entry)
        {
            ActiveDirectorySecurity dsSecurity = entry.ObjectSecurity;

            // clear all existing ACEs
            dsSecurity
            .GetAccessRules(true, true, typeof(NTAccount))
            .Cast <ActiveDirectoryAccessRule>()
            .Select(x => x.IdentityReference)
            .Distinct()
            .ToList()
            .ForEach(x => dsSecurity.PurgeAccessRules(x));
            // iterate over local ACEs and translate to DS ACL
            foreach (CertTemplateAccessRule localAce in GetAccessRules(true, false, typeof(NTAccount)))
            {
                CertTemplateRights localRights = localAce.Rights;
                if ((localRights & CertTemplateRights.FullControl) > 0)
                {
                    var ace = new ActiveDirectoryAccessRule(
                        localAce.IdentityReference,
                        ActiveDirectoryRights.GenericAll,
                        localAce.AccessControlType);
                    dsSecurity.AddAccessRule(ace);
                    continue;
                }
                CertTemplateRights rw = localRights & (CertTemplateRights.Read | CertTemplateRights.Write);
                if (rw > 0)
                {
                    ActiveDirectoryRights tempRights;
                    if (rw == (CertTemplateRights.Read | CertTemplateRights.Write))
                    {
                        tempRights = ActiveDirectoryRights.CreateChild
                                     | ActiveDirectoryRights.DeleteChild
                                     | ActiveDirectoryRights.Self
                                     | ActiveDirectoryRights.WriteProperty
                                     | ActiveDirectoryRights.DeleteTree
                                     | ActiveDirectoryRights.Delete
                                     | ActiveDirectoryRights.GenericRead
                                     | ActiveDirectoryRights.WriteDacl
                                     | ActiveDirectoryRights.WriteOwner;
                    }
                    else if (rw == CertTemplateRights.Read)
                    {
                        tempRights = ActiveDirectoryRights.GenericRead;
                    }
                    else
                    {
                        tempRights = ActiveDirectoryRights.Self
                                     | ActiveDirectoryRights.WriteProperty
                                     | ActiveDirectoryRights.WriteDacl
                                     | ActiveDirectoryRights.WriteOwner;
                    }
                    var ace = new ActiveDirectoryAccessRule(
                        localAce.IdentityReference,
                        tempRights,
                        localAce.AccessControlType);
                    dsSecurity.AddAccessRule(ace);
                }
                if ((localRights & CertTemplateRights.Enroll) > 0)
                {
                    var ace = new ActiveDirectoryAccessRule(
                        localAce.IdentityReference,
                        ActiveDirectoryRights.ReadProperty | ActiveDirectoryRights.WriteProperty | ActiveDirectoryRights.ExtendedRight,
                        localAce.AccessControlType,
                        new Guid(GUID_ENROLL));
                    dsSecurity.AddAccessRule(ace);
                }
                if ((localRights & CertTemplateRights.Autoenroll) > 0)
                {
                    var ace = new ActiveDirectoryAccessRule(
                        localAce.IdentityReference,
                        ActiveDirectoryRights.ExtendedRight,
                        localAce.AccessControlType,
                        new Guid(GUID_AUTOENROLL));
                    dsSecurity.AddAccessRule(ace);
                }
            }
            return(dsSecurity);
        }