Source for file ActiveDirectory.php
Documentation is available at ActiveDirectory.php
* Project: ActiveDirectory :: Control Active Directory with ldap or ldaps
* File: ActiveDirectory.php
* Copyright (c) 2018, JoungKyun.Kim <http://oops.org>
* ActiveDirectory pear package support to control Microsoft Active Directory
* with ldap or ldaps protocol.
* @package ActiveDirectory
* @author JoungKyun.Kim <http://oops.org>
* @copyright (c) 2018 JoungKyun.Kim
* @link http://pear.oops.org/package/ActiveDirectory
* http://pear.oops.org/docs/li_KSC5601.html
* http://pear.oops.org/package/KSC5601
require_once 'KSC5601.php';
* import ActiveDirectory_API class
require_once 'ActiveDirectory/API.php';
* Main Class that control Active Directory
* @package ActiveDirectory
* Set default Active Directory Domain name
* Set default distinguished name
* 출력 문자열. 이 값은 iconv 변경을 위해 지정한다.
* ActiveDirectory의 local character set 을 지정한다.
* Set Ldap error messages
// {{{ (boolean) ActiveDirectory::__construct (void)
putenv ('LDAPTLS_REQCERT=never');
$this->charset = 'cp949'; // euc-kr
// {{{ (object) ActiveDirectory::connect ($account, $pass, $host, $port = null, $certi = null)
* Active Directory 에 접속을 하고, 접속한 계정의 정보를 반환한다.
* @return object|false {status, error, info}
* @param string Active Directory account 이름
* @param string Account 암호
* @param string Ldaps 연결에 필요한 서버 인증서
function connect ($account, $pass, $host, $port = null, $certi = null) {
$port = $certi ? 636 : 389;
$proto = $certi ? 'ldaps' : 'ldap';
$host = sprintf ('%s://%s', $proto, $host);
putenv ('LDAPTLS_CACERT=' . $certi);
$this->link = ldap_connect ($host, $port);
ldap_set_option($this->link, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($this->link, LDAP_OPT_REFERRALS, 0);
if ( ($r->status = $this->auth ($dn, $pass, $this->link)) === false ) {
$r->error = ldap_error ($this->link);
$r->info = $this->user ($account, $this->rdn);
if ( $r->info === false ) {
$r->error = self::$error;
@ldap_unbind ($this->link);
// {{{ (object) ActiveDirectory::user ($user, $rdn = null, $full = false)
* @param string Account 이름
* @param bool true로 지정을 하면 전체 속성을 반환 (기본값 false)
function user ($user, $rdn = null, $full = false) {
$rdn = $rdn ? $rdn : $this->rdn;
$r->error = self::$error = null;
$filter = sprintf ('(samaccountname=%s)', $user);
return $this->search ($rdn, $filter);
// {{{ (array) ActiveDirectory::userlist ($rdn = null)
* Active Directory에 있는 전체 사용자 계정 리스트를 반환
$rdn = $rdn ? $rdn : $this->rdn;
$filter = '(&(objectCategory=person)(objectClass=user))';
$entries = $this->search ($rdn, $filter);
if ( $entries === false )
foreach ( $entries as $v )
// {{{ (array) ActiveDirectory::grouplist ($rdn = null)
* Active Directory에 있는 전체 그룹 리스트를 반환
$rdn = $rdn ? $rdn : $this->rdn;
#$filter = '(grouptype=*)';
$filter = '(objectCategory=group)';
$entries = $this->search ($rdn, $filter);
if ( $entries === false )
foreach ( $entries as $v )
// {{{ (boolean) ActiveDirectory::is_account_lock ($obj)
* 주어진 계정이 lock이 걸려있는지 여부를 확인
* lockout account (lockouttime>=1)
* disabled account (userAccountControl:1.2.840.113556.1.4.803:=2)
* -> userAccountControl value is 512 or 66048 enabled account
* -> userAccountControl value is 514 or 66050 disabled account
* @param object ActiveDirectory::user mehtod의 결과값
if ( $obj->lockouttime && $obj->lockouttime != 0 )
if ( $obj->useraccountcontrol == 514 || $obj->useraccountcontrol == 66050 )
// {{{ (object) ActiveDirectory::maxid ($rdn = null)
* 현재 Active Directory의 UID/GID 최대값을 가져온다.
* Unix Attribute가 활성화 되어 있지 않으면 0을 반환한다.
function maxid ($rdn = null) {
$rdn = $rdn ? $rdn : $this->rdn;
$r = $this->search_api ($rdn, null, array ('uid', 'uidnumber', 'gidnumber'));
$ret->uid = ( isset ($v->uidnumber) && $v->uidnumber > $ret->uid ) ? $v->uidnumber : $ret->uid;
$ret->gid = ( isset ($v->gidnumber) && $v->gidnumber > $ret->gid ) ? $v->gidnumber : $ret->gid;
// {{{ (object) ActiveDirectory::search ($rdn, $filter = null)
* 결과 값이 1 entry일 경우에는 object로 반환을 하며, 1개 이상일 경우에는
* @return object|array|false
function search ($rdn = null, $filter = null) {
$rdn = $rdn ? $rdn : $this->rdn;
// {{{ (object) ActiveDirectory::search_ex ($rdn, $filter = null, $attr = null)
* ActiveDirectory::search 와의 차이점은 4번째 인자로 반환할 속성을
* 지정할 수 있다. 지정하지 않을 경우 다음의 속성을 반환한다.
* 'cn', 'sn', 'givenname', 'displayname', 'distinguishedname',
* 'department', 'title', 'description', 'company',
* 'mail', 'ipphone', 'mobile', 'memberof', 'member',
* 'mssfu30name', 'uidnumber', 'gidnumber', 'unixhomedirectory', 'loginshell',
* 'whencreated', 'whenchanged', 'lastlogontimestamp', 'lastlogon',
* 'pwdlastset', 'badpasswordtime', 'accountexpires', 'lockouttime',
* 'useraccountcontrol', 'samaccountname'
* @return object|array|false
function search_ex ($rdn = null, $filter = null, $attr = null) {
$rdn = $rdn ? $rdn : $this->rdn;
'cn', 'sn', 'givenname', 'displayname', 'distinguishedname',
'department', 'title', 'description', 'company',
'mail', 'ipphone', 'mobile', 'memberof', 'member',
'mssfu30name', 'uidnumber', 'gidnumber', 'unixhomedirectory', 'loginshell',
'whencreated', 'whenchanged', 'lastlogontimestamp', 'lastlogon',
'pwdlastset', 'badpasswordtime', 'accountexpires', 'lockouttime',
'useraccountcontrol', 'samaccountname'
// {{{ (boolean) ActiveDirectory::change_password ($account, $new_pass)
* Active Directory 계정의 암호를 변경한다. 이 method는 ldaps 프로토콜로
* @param string|object 계정 이름 또는 ActiveDirectory::user method의 결과
if ( ! trim ($new_pass) ) {
"The given password is '%s'. " .
"The password is only ascii character.",
"The given account name is '%s'. " .
"The account name is only ascii character without white space.",
$entry = $this->user ($entry);
#$entry = $this->search_ex ($this->rdn, "samaccountname={$account}");
$data['unicodePwd'] = $this->make_nt_passwd ($new_pass);
* 패스워드 변경은.. UTF8 로 보내면.. 또 안된다..
* 2012 에서도 그런지는 확인 필요! (2008 R2 까지는 확인)
* LDAP protocol 3 에서는 어떤지 확인 안됨. protocol3은 무조건
if ( $this->ksc->is_utf8 ($entry->distinguishedname, true) )
$entry->distinguishedname = $this->ksc->utf8 ($entry->distinguishednamem, UHC);
$r = $this->exec ($entry->distinguishedname, $data, 'replace');
#if ( ($r = @ldap_mod_replace ($this->link, $entry->distinguishedname, $data)) === false )
# self::$error = ldap_error ($this->link);
if ( $this->is_unix_attribute )
// {{{ (boolean) ActiveDirectory::is_unix_attribute (&$r)
* 해당 유저의 UNIX attribute가 활성화 되어 있는지 여부를 확인
* @param string|object 계정 또는 계정 속성
if ( ($res = $this->user ($r, $this->rdn)) === false )
if ( is_object ($res) || ! isset ($res->samaccountname) )
if ( $r->uid && $r->mssfu30name && $r->loginshell )
// {{{ (boolean) ActiveDirectory::enable_unix_attribute ($account, $attr)
* 계정의 unix attribyte를 활성화 한다.
* ActiveDirectory::user method의 결과값을 파라미터로 넘긴다.
* @param array unix attribute 값<br>
* 설정 가능한 배열 멤버는 다음과 같다. (괄호안은 지정하지 않았을 경우의
* <li>mssfu30name (CN attribute)</li>
* <li>mssfu30nisdomain (ActiveDirectory::$domain)</li>
* <li>loginshell (/bin/bash)</li>
* <li>unixhomedirectory (/home/AD/USERNAME)</li>
* <li>unixuserpassword (Gabage data)</li>
return $this->set_unix_attribute ($account, $attr, 'add');
// {{{ (boolean) ActiveDirectory::disable_unix_attribute ($account)
* 계정의 unix attribyte를 비활성화 한다.
* @param object 계정 속성 또는 계정 이름
return $this->set_unix_attribute ($account, null, 'remove');
// {{{ (boolean) ActiveDirectory::change_unix_password ($account, $pass = null)
* Unix Attribute 속성의 암호를 변경한다.
$attr['unixuserpassword'] = $pass;
return $this->set_unix_attribute ($account, $attr, 'replace');
// {{{ (void) ActiveDirectory::close ($link = null)
* Disconnect Active Directory
* @param resource (optional) ldap link
// {{{ (boolean) ActiveDirectory::exec ($link, $dn, $attrs, $mode='add')
function exec ($dn, $attrs, $mode = 'add', $link = null) {
$link = $link ? $link : $this->link;
if ( ! count ($attrs) ) {
if ( ! preg_match ('/^(add|del|replace)$/', $mode) ) {
$funcname = 'ldap_mod_' . $mode;
if ( ($r = @$funcname ($link, $dn, $attrs)) === false )
// {{{ (boolean) ActiveDirectory::__construct (void)
ldap_unbind ($this->link);
* vim: set filetype=php noet sw=4 ts=4 fdm=marker:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
|