PHP,Active Directory,用户帐户控制

时间:2014-02-11 09:48:31

标签: php active-directory ldap

首先,如果这应该是服务器故障,但它也与PHP有关,所以我认为这是最好的网站。

我正在创建一些方法来将Intranet与Active Directory集成。其中一种方法将自动在我们的数据库中搜索新用户,如果找到新用户,则在AD中创建用户帐户。

同样,如果用户在数据库中标记为左侧,则会自动禁用活动目录中的帐户。

我一直在查看从活动目录传递的属​​性,特别是用户帐户控制字段。

microsoft website上,它在其属性列表中声明了这一点:

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).

问题 我的问题是,如果我们使用上面的例子,将记录标记为用户(512)和禁用(2),这最终会使AD返回的字段值为514.

在PHP中,如何提取记录中标记的标志?例如,如果给定514,我如何使用PHP来计算其普通用户帐户,并且还禁用(2和512)?

例如,拆分以下内容:

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

我希望你能理解我的问题,但随时可以要求确认或更多细节。

非常感谢

4 个答案:

答案 0 :(得分:4)

根据James Sloan的回答,这里是标志清单:

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;
}

答案 1 :(得分:1)

好的,经过大量的反复试验后,我已经知道如何做到这一点!

$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

通过获取UAC中所有可能标志的十进制值来工作。有27个 - 我已经为$bits数组分配了所有值。

然后指定要查找的标志。

然后将标志的十进制值转换为二进制,并用0左边填充它。

循环遍历二进制字符串中的每个值。如果迭代值为1,则从$bits数组中获取其关联的标志十进制值。

然后将所有可能的标志存储在$flags数组中。

希望这可以帮助将来遇到类似问题的人!

答案 2 :(得分:1)

今天遇到了同样的情况,它更简洁:

package dal

import javax.inject.Inject

import models.Music
import play.api.db.slick.DatabaseConfigProvider
import slick.driver.JdbcProfile

import scala.concurrent.{Future, ExecutionContext}

class MusicRepository @Inject()(dbConfigProvider: DatabaseConfigProvider)
                               (implicit ec: ExecutionContext) {

  /* Omitted for brevity */

  // Musics table
  private class Musics(tag: Tag) extends Table[Music](tag, "musics") {
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc)

    def albumId = column[Long]("album_id")

    def title = column[String]("title")

    def lyrics = column[String]("lyrics")

    def year = column[Int]("year")

    def * = (id, albumId, title, lyrics, year) <>((Music.apply _).tupled, Music.unapply)

    //
    // THIS IS WHERE I AM GETTING THE ERROR MESSAGE
    //
    def album = foreignKey("album_fk", albumId, AlbumRepository.albums)(_.id)
  }

}

答案 3 :(得分:0)

我认为,即使原始帖子以一般方式询问,问题也仅针对某些需要检查的标志。使用Bill C的回复中非常有用的列表:

$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;

如果需要更新值(我认为这是原始问题的编程需求,例如启用帐户):

$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

php按位运算符文档中有一个很好的抽象函数示例,可用于开发针对AD标志的通用解决方案:http://php.net/manual/en/language.operators.bitwise.php#108679