PHP Active Directory Integration: get userAccountControl attributes

While trying to integrate an Active Directory based login in my PHP application, I came across the problem of checking which user accounts were not disabled.

After going through some forums I did the following to see accounts which were not disabled:

$result = ldap_search($ad, "OU=Users,OU=Office1,DC=country,DC=company,DC=com", "(&(objectCategory=user)(!(userAccountControl=514)))");

Microsoft returns the flags set for any user in the userAccountControl attribute in a cumulative manner. The flag values used by Active Directory are mentioned here.

So e.g.
John has a Normal Account [Flag 512]
Alex had a Normal Account [Flag 512] but now has been disabled [Flag 2] so the status on his account now is [512+2 = 514].

This works fine in most cases but as the flags can be summed up in any order, ldap_search returned 66050 for some users.  Seeing the table what that means is:

[Flag 65536 ]+ [Flag 512] + [Flag 2] which translates to

[Password Doesn't Expire] + [was a Normal Account] + [but has been disabled now.]

So checking for 66050 was the next dirty fix to exclude such people, like so:

$result = ldap_search($ad, "OU=Users,OU=Office1,DC=country,DC=company,DC=com", "(&(objectCategory=user)(!(userAccountControl=514))(!(userAccountControl=66050)))");

While making the admin section to manage these users I had to show the users in our different offices (located across different countries) along with the properties of the users.
To solve this problem I made the following function to breakdown the codes (returned in the useraccountcontrol field) into their corresponding flags values.

function getUserAccountControlAttributes($inputCode)
{
/**
* http://support.microsoft.com/kb/305144
*
* You cannot set some of the values on a user or computer object because
* these values can be set or reset only by the directory service.
*
*/
$userAccountControlFlags = array(16777216 => "TRUSTED_TO_AUTH_FOR_DELEGATION",
8388608 => "PASSWORD_EXPIRED",
4194304 => "DONT_REQ_PREAUTH",
2097152 => "USE_DES_KEY_ONLY",
1048576 => "NOT_DELEGATED",
524288 => "TRUSTED_FOR_DELEGATION",
262144 => "SMARTCARD_REQUIRED",
131072 => "MNS_LOGON_ACCOUNT",
65536 => "DONT_EXPIRE_PASSWORD",
8192 => "SERVER_TRUST_ACCOUNT",
4096 => "WORKSTATION_TRUST_ACCOUNT",
2048 => "INTERDOMAIN_TRUST_ACCOUNT",
512 => "NORMAL_ACCOUNT",
256 => "TEMP_DUPLICATE_ACCOUNT",
128 => "ENCRYPTED_TEXT_PWD_ALLOWED",
64 => "PASSWD_CANT_CHANGE",
32 => "PASSWD_NOTREQD",
16 => "LOCKOUT",
8 => "HOMEDIR_REQUIRED",
2 => "ACCOUNTDISABLE",
1 => "SCRIPT");

$attributes = NULL;
while($inputCode > 0) {
    foreach($userAccountControlFlags as $flag => $flagName) {
        $temp = $inputCode-$flag;
        if($temp>0) {
            $attributes[$userAccountControlFlags[$flag]] = $flag;
            $inputCode = $temp;
        }
        if($temp==0) {
            if(isset($userAccountControlFlags[$inputCode])) {
                $attributes[$userAccountControlFlags[$inputCode]] = $inputCode;
            }
            $inputCode = $temp;
        }
    }
}
return $attributes;
}

// so for example
$userAccountControlAttributes = getUserAccountControlAttributes(66048);
var_dump($userAccountControlAttributes);

var_dump shows all the flags set in the $userAccountControlAttributes variable:

array(2) { ["DONT_EXPIRE_PASSWORD"]=> int(65536) ["NORMAL_ACCOUNT"]=> int(512) }

This made it easier for me to display the attributes set on each user and to filter out users whose accounts had been disabled, I just made sure the ACCOUNTDISABLE flag was not set in the return values.


// example usage
$result = ldap_search($ad, "OU=Users,OU=Office1,DC=country,DC=company,DC=com", "(&(objectCategory=user))");
//Create result set
$entries = ldap_get_entries($ad, $result);

for ($i=0; $i < $entries["count"]; $i++) {
    $userAccountControlAttributes = getUserAccountControlAttributes($entries[$i]["useraccountcontrol"][0]);
    if (!isset($userAccountControlAttributes["ACCOUNTDISABLE"])) {
        // do something
    }
}

Hope this helps someone trying to show account attributes using PHP.

comments powered by Disqus