PHP,Active Directory,用户帐户控制
First of appologies if this should be on server-fault, but it's to do with PHP as well, so I thought this the best site for it.
I'm creating a few methods to integrate our intranet with Active Directory. One of the methods will automatically search our database for new users, and create user accounts in AD if new users are found.
Likewise, if a user is marked as left in the database, it will automatically disable the account in active directory.
I've been looking at the attributes passed from active directory, and in particular the User Account Control field.
On the microsoft website it states this under its list of attributes:
The following table lists possible flags that you can assign. 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. The flags are cumulative. To disable a
user's account, set the UserAccountControl attribute to 0x0202 (0x002 + 0x0200). In
decimal, this is 514 (2 + 512).
Question My question is, if we use the example above, to mark a record as a user (512) and disabled (2), this ultimately makes the field value returned by AD as 514.
In PHP, how can I extract what flags have been marked on the record? For example, If given 514
, how can I use PHP to work out that its a normal user account, and also disabled (2 and 512)?
For example split the following:
Flag | Splits into | Flag Meaning
--------+------------------+---------------------------------------------------------
514 | 512 + 2 | Normal User Account + Disabled
522 | 512 + 2 + 8 | Normal User Account + Disabled + Home Directory Required
8389120 | 8388608 + 512 | Password Expired + Normal User Account
I hope you can understand my question, but feel free to ask for confirmation or more details.
Many thanks
如果这应该是服务器故障的第一个应用程序,但它也与PHP有关,所以我想 这是最好的网站。 p>
我正在创建一些方法来将我们的Intranet与Active Directory集成。 其中一种方法将自动在我们的数据库中搜索新用户,如果找到新用户,则在AD中创建用户帐户。 p>
同样,如果用户在数据库中被标记为左侧,它将自动禁用活动目录中的帐户。 p>
我一直在寻找 在从活动目录传递的属性,特别是用户帐户控制字段。 p>
在 microsoft website 它在其属性列表下声明: p>
下表列出了可以分配的可能标志。 您无法在用户或计算机对象上设置一些
值,因为这些值只能由目录服务设置或设置。 标志是累积的。 要禁用
user的帐户,请将UserAccountControl属性设置为0x0202(0x002 + 0x0200)。 在
decimal中,这是514(2 + 512)。
code> pre>
问题 strong>
我的问题是,如果我们使用上面的例子, 将记录标记为用户(512)和禁用(2),这最终使AD返回的字段值为514. p>
在PHP中,如何提取已标记的标记 记录在案吗? 例如,如果给出 514 code>,我如何使用PHP来计算其普通用户帐户,并且还禁用(2和512)? p>
For 示例拆分如下: p>
Flag | 分裂为| 标志含义
-------- + ------------------ + ------------------ ---------------------------------------
514 | 512 + 2 | 普通用户帐户+已禁用
522 | 512 + 2 + 8 | 普通用户帐户+已禁用+主页目录必需
8389120 | 8388608 + 512 | 密码已过期+普通用户帐户
code> pre>
我希望您能理解我的问题,但随时可以要求确认或更多详细信息。 p>
非常感谢 p>
div>
Came upon the same situation today and it is more concise with:
$flag_to_find = 530;
$flags = array();
for ($i=0; $i<=26; $i++){
if ($flag_to_find & (1 << $i)){
array_push($flags, 1 << $i);
}
}
print_r($flags);
Ok, so after a lot of trial and error, I've worked out how to do it!
$bits = array(
'27' => 1, '26' => 2, '25' => 4, '24' => 8, '23' => 16, '22' => 32,
'21' => 64, '20' => 128, '19' => 256, '18' => 512, '17' => 1024,
'16' => 2048, '15' => 4096, '14' => 8192, '13' => 16328,
'12' => 32768, '11' => 65536, '10' => 131072, '9' => 262144,
'8' => 524288, '7' => 1048576, '6' => 2097152, '5' => 4194304,
'4' => 8388608, '3' => 16777216, '2' => 33554432, '1' => 67108864
);
$flag_to_find = 530; // Indicates a normal user account, which is disabled, and locked out
$binary = str_pad(decbin($flag_to_find), count($bits), 0, STR_PAD_LEFT);
$flags = array();
for($i=0; $i<strlen($binary); $i++)
{
if($binary[$i]==1)
{
$flags[] = $bits[$i+1];
}
}
print_r($flags);
// Outputs: 512: Normal User Account
16: Locked Out Account
2: Disabled Accout
It works by getting the decimal values of ALL possible flags in the UAC. There are 27 - I've assigned all values to the $bits
array.
You then specify a flag to find.
Then convert the decimal value of the flag, to binary, and left pad it with 0
.
Loop through each value in the binary string. If the iteration value is 1
, get its associated flag decimal value from the $bits
array.
All possible flags are then stored in the $flags
array.
Hope this helps anyone in future with similar problems!
Adding to James Sloan's answer, here is the flag list :
public function findFlags($flag) {
$flags = array();
$flaglist = array(
1 => 'SCRIPT',
2 => 'ACCOUNTDISABLE',
8 => 'HOMEDIR_REQUIRED',
16 => 'LOCKOUT',
32 => 'PASSWD_NOTREQD',
64 => 'PASSWD_CANT_CHANGE',
128 => 'ENCRYPTED_TEXT_PWD_ALLOWED',
256 => 'TEMP_DUPLICATE_ACCOUNT',
512 => 'NORMAL_ACCOUNT',
2048 => 'INTERDOMAIN_TRUST_ACCOUNT',
4096 => 'WORKSTATION_TRUST_ACCOUNT',
8192 => 'SERVER_TRUST_ACCOUNT',
65536 => 'DONT_EXPIRE_PASSWORD',
131072 => 'MNS_LOGON_ACCOUNT',
262144 => 'SMARTCARD_REQUIRED',
524288 => 'TRUSTED_FOR_DELEGATION',
1048576 => 'NOT_DELEGATED',
2097152 => 'USE_DES_KEY_ONLY',
4194304 => 'DONT_REQ_PREAUTH',
8388608 => 'PASSWORD_EXPIRED',
16777216 => 'TRUSTED_TO_AUTH_FOR_DELEGATION',
67108864 => 'PARTIAL_SECRETS_ACCOUNT'
);
for ($i=0; $i<=26; $i++){
if ($flag & (1 << $i)){
array_push($flags, 1 << $i);
}
}
foreach($flags as $k=>&$v) {
$v = $v . ' ' . $flaglist[$v];
}
return $flags;
}
I think that even though the original post asks in a general way, the problem is specific to just certain flags that need to be checked. Using the very helpful list in Bill C's response:
$userAccountControl = 514; // Get this from AD
// using bitwise AND:
// this will be the right hand value if it's set, 0 if not
$isAccountDisabled = ($userAccountControl & 2) == 2;
$isNormalAccount = ($userAccountControl & 512) == 512;
And if the need is to update the value (which I think is the programmatic need of the original question, such as enabling the account):
$userAccountControl = 514; // Get this from AD
// using bitwise AND NOT:
// this will assure the right hand value is not set
$userAccountControl = $userAccountControl & ~2; // enable the account
// using bitwise OR:
// this will assure the right hand value is set
$userAccountControl = $userAccountControl | 512; // assure normal account
There is a nice abstract function example in the php bitwise operators docs that could be used to develop a generalized solution for AD flags: http://php.net/manual/en/language.operators.bitwise.php#108679.