Enumerate accounts protected by AdminSDHolder and fix resulting ACL problems
Back in the days of Windows 2000, I was asked to design a delegation model for an Active Directory (AD) project that required a small set of trusted users to be granted the right to reset passwords on accounts in an organizational unit (OU), which also belonged to the Domain Admins group.
At the time this didn’t appear to be a particularly difficult task, but I was surprised to find that ACLs that had been applied to the accounts, for the purposes of delegating appropriate permissions, had disappeared.
My initial reaction was that there must be something wrong with AD in the lab or that someone had changed the permissions back to their defaults. So we reset the ACLs in the hope that they’d stick, only to find that they’d disappeared again.
A little more investigation into the problem revealed that this behavior is by design.
A security mechanism called AdminSDHolder defines the ACLs applied to a list of protected users and groups and by default prevents them from inheriting permissions from their parent object in AD. A process called SDProp (Security Descriptor Propagator) runs hourly to enforce ACLs on objects protected by AdminSDHolder.
So, using the wizard in the Active Directory Users and Computers (ADUC) management console to delegate the reset password rights for accounts in an OU might not be effective if any of the child objects are members of a group protected by AdminSDHolder.
Users and Groups Protected by AdminSDHolder
In Win2K, AdminSDHolder protected just four key groups: Administrators, Domain Admins, Enterprise Admins, and Schema Admins.
Over the years, that number has been expanded, and in Windows Server 2008 and Server 2008 R2, AdminSDHolder protects the following users and groups: Account Operators, Administrator, Administrators, Backup Operators, Domain Admins, Domain Controllers, Enterprise Admins, Krbgt, Print Operators, Read-only Domain Controllers, Replicator, Schema Admins, and Server Operators.
Accounts that belong to a protected group should be treated as special purpose. For instance, a user account that is a member of the Backup Operators group should be used only for performing backup and restore operations.
When a user becomes a member of a protected group, not only does the user no longer inherit permissions from its parent object in AD, but some default ACLs are also removed and others added.
So accounts added to protected groups have different ACLs than standard user accounts in AD. This can impact functionality, such as the ability to upload a user’s certificate to the Global Address List (GAL) in Exchange due to missing SELF permissions on the user’s AD account.
Working with the adminCount Attribute
AdminSDHolder determines whether a user object should be protected by enumerating the user’s group membership, including nested groups. If a user is deemed to belong to a protected group, it’s stamped with the ACLs as set on the AdminSDHolder object in AD. The user’s adminCount attribute is also set to 1.
You can run an LDAP query against AD to determine which user accounts or groups are protected. However, the only surefire way to determine if an account is protected by AdminSDHolder is to expand its transitive group membership, as the adminCount attribute isn't set back to zero when an account is removed from a protected group.
In Server 2008 R2, you can run an LDAP query using Windows PowerShell’s new AD administration commands. Start by importing the AD module into PowerShell so that you can use the AD commandlets. The get-aduser command below will list all user objects where the adminCount attribute is set to 1:
import-module activedirectory
get-aduser -ldapfilter "(objectcategory=person)
(admincount=1)"
And the get-adgroup command does the same but for AD groups:
get-adgroup -ldapfilter "(objectcategory=group)
(admincount=1)"
If you're not using Server 2008 R2, you can use LDIFDE to achieve similar output, where -f specifies a filename for recording the results of the query and -r specifies the LDAP filter:
ldifde -f ldifdeoutput.txt -r "(&(objectcategory=
person)(objectclass=user)(admincount=1))"
You should also bear in mind that the adminCount attribute might be set to 1 even if a user isn't a direct member of a group protected by AdminSDHolder, as AD also sets the adminCount attribute to 1 if a user has indirect membership of a protected group through nested groups.
Clearing the adminCount Attribute
When a user is removed from a protected group, the adminCount attribute on their user object remains set to 1. The account remains in a strange state of limbo in that it no longer receives ACLs from the AdminSDHolder object but also doesn’t inherit permissions from its parent container. Any ACLs previously applied from AdminSDHolder remain in place.
Setting the adminCount attribute to 1 isn’t enough to protect a group or account with AdminSDHolder, so resetting the value to zero might not be strictly necessary. However, you should set the attribute back to zero for consistency.





