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.

Accounts that are demoted from a protected group should be deleted as a security precaution to ensure that any back doors created using the account can’t be exploited once it has been demoted. If you must keep the account, you should review the ACLs on the object, and manually change the adminCount attribute to zero using ADSI Edit:

1.   Log in to a Server 2008 R2 domain controller (DC) as a Domain Administrator, and find the ADUC console by searching for the phrase active directory in the Start menu's programs and files box.

2.   In the ADUC console, click the View menu, and make sure that Advanced Features is selected.

3.   In the left pane, expand your AD hierarchy to find the container or OU with the user object you want to reset.

4.   Right-click the object in the right pane and select Properties from the menu.

5.   On the Attribute Editor tab, you’ll see the adminCount attribute listed, which you can edit if required. 

When a user account is removed from a protected group, resetting the adminCount attribute isn’t enough to enable the object’s inheritance flag, which is the default setting for users not protected by AdminSDHolder (see Figure 1). You’ll need to change it manually as follows:

1.   Continuing from where we finished in the previous set of instructions, switch to the Security tab and click Advanced.

2.   Select Include inheritable permissions from this object’s parent and click OK.

3.   Click OK in the user’s Properties dialog box to complete the procedure.

You can also reset the Include inheritable permissions flag and restore permissions that were assigned to the object when it was first created, as defined in the AD schema, by clicking Restore defaults in the Advanced Security Settings dialog box. Be aware that Restore defaults is not the same as restoring ACLs from a known point in time.

You can modify security on the AdminSDHolder object in AD (see Figure 2), so that the inheritance flag is enabled, or to apply different ACLs to all protected objects. Changes made to ACLs or the inheritance flag on the AdminSDHolder object itself are applied to the objects it protects. To change permissions on the AdminSDHolder object in a lab:

1.   Log in to a Server 2008 R2 DC as a Domain Administrator, and find the ADSI Edit console by searching for it in the Start menu's programs and files box.

2.   In the ADSI Edit console, right-click ADSI Edit in the left pane and select Connect to from the menu.

3.   In the Connection Settings dialog box, leave all the default settings in place and click OK.

4.   In the left pane, double-click Default naming context to expand the directory, and drill down to CN=System.

 5.  Select CN=System in the left pane, right click CN=AdminSDHolder in the right pane and select Properties from the menu.

6.   In the CN=AdminSDHolder Properties dialog box, switch to the Security tab and click Advanced.

7.   In the Advanced Security Settings for AdminSDHolder dialog box, check Include inheritable permissions from this object’s parent and click Apply.

8.   Click Add and browse for an AD group that you want to permanently assign change and reset password permissions to on protected objects. In this example, I have a group called On Duty Security Team. After you’ve successfully selected a group, click OK.

9.   In the Permission Entry for AdminSDHolder dialog box (see Figure 3), select Descendant User objects from the Apply to menu.

10.  In the Permissions list, check Change and Reset password, then click OK.

11.  In the Advanced Security Settings for the AdminSDHolder dialog box, click OK.

12.  Click OK in the CN=AdminSDHolder Properties dialog box to complete the procedure.

The next time the SDProp code runs, any user objects protected by AdminSDHolder will have additional ACL entries so that my example group, the On Duty Security Team group, can change and reset passwords. The inheritance flag will also be enabled so ACLs are propagated from the parent OU.

Forcing SDProp to Run

The SDProp code runs hourly, by default, on DCs that hold the PDC Emulator role, to enforce ACLs on groups protected by AdminSDHolder. If you need to apply these settings immediately, the SDProp code can be forced to run by using the following LDAP operation:

1.   Log in to a Server 2008 R2 DC as a Domain Administrator, and find the LDP console by searching for it in the Start menu's programs and files box.

2.   In the LDP console, select Bind from the Connection menu.

3.   In the Bind dialog box, leave the default settings, and click OK.

4.   Select Modify from the Browse menu. Type RunProtectAdminGroupsTask in the Edit Entry Attribute field, 1 into the Values field and click Enter (see Figure 4). For Windows Server versions prior to Server 2008 R2, replace the RunProtectAdminGroupsTask with FixUpInheritance and 1 with Yes.

5.   Click Run, then Close. The update process may take some time depending on the size of your AD database.


Excluding Account, Server, Print, or Backup Operators from AdminSDHolder

As of Windows Server 2003 SP2, it’s possible to exclude Account, Server, Print, and Backup Operators from AdminSDHolder protection. These operator groups are protected because they have privileges, such as log on locally and shutdown, which can have a serious impact on server security. If you must remove any of these groups from AdminSDHolder protection, you should consider removing their user rights:

1.   Log in to a Server 2008 R2 DC as a Domain Administrator and open the ADSI Edit console.

2.   In the left pane of ADSI, right-click ADSI Edit and select Connect to from the menu.

3.   Select Configuration from the Select a well known Naming Context menu and click OK.

4.   In the left pane, expand Configuration, CN=Services, CN=Windows NT. In the right pane, right-click CN=Directory Service, and select Properties from the menu.

5.   In the CN=Directory Service Properties dialog box, select dsHeuristics on the Attribute Editor tab and click Edit.

6.   In the String Attribute Editor dialog box, type 000000000100000f to exclude all four operator groups, and click OK.

7.   Click OK in the CN=Directory Service Properties dialog box and close ADSI Edit.

Each ‘operator’ group has a binary value as follows: Account Operators (0001), Server Operators (0010), Print Operators (0100), Backup Operators (1000). The binary value must be converted to hexadecimal and added to the last position in the string (f in step 6 above).

If you want to exclude more than one group, add the binary values of the groups together, then convert the result to hex. For example, to exclude Print Operators and Backup Operators only, the dsHeuristics string would be 000000000100000c. You can use Windows calculator in Programmer mode to add binary numbers and convert them to hex.

Best Practices

Though as we’ve seen in this article, it's possible to modify the default ACLs for objects protected by AdminSDHolder, I wouldn’t recommend changing AD default settings unless you have a very good reason to do so. Modifications made to ACLs by AdminSDHolder can impact standard functionality for applications such as Exchange, AD delegation, and any other AD function or application that relies on permission inheritance, such as BlackBerry servers.

Changing default AdminSDHolder behavior should be restricted to situations where political reasons dictate a specific solution. If you follow best practices, changing AdminSDHolder functionality shouldn’t be necessary. If you need to delegate permissions to objects protected by AdminSDHolder, it might be time to rethink your AD design to separate privileged tasks to dedicated user accounts.

Firecall accounts—special-purpose accounts used for server maintenance when elevated privileges are required—should be created for support purposes, added to a protected group—or assigned the required privileges—and be disabled when not in use.

If accounts must be reused after they’ve been removed from a protected group, be sure to implement a procedure so that inheritance is re-enabled, ACLs are checked, and the adminCount attribute is set back to zero.

The most common reason to add a user account to one of AD’s protected groups is so that a user can perform maintenance tasks on a DC. If you can't escape the need for permanent access to servers hosting AD, Read-only domain controllers (RODCs) allow administrative rights to be separated from access to AD. For more information on server access for support staff, see "Managing Privileged Access to Servers," InstantDoc ID 104709.