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.