Source for file API.php
Documentation is available at API.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
require_once 'ActiveDirectory/Common.php';
* ActiveDirectory_API :: Active Directory Internal API
* @package ActiveDirectory
private $pagesize = 1000;
private $unix_attr = array (
'uid', 'uidnumber', 'gidnumber', 'loginshell', 'mssfu30name',
'mssfu30nisdomain', 'unixhomedirectory', 'unixuserpassword'
// {{{ (boolean) ActiveDirectory_API::auth ($rdn, $pass)
function auth ($rdn, $pass, $link = null) {
$link = $link ? $link : $this->link;
return @ldap_bind ($link, $rdn, $pass);
// {{{ (mixed) ActiveDirectory_API::search_api ($rdn, $filter = null, $attr = null)
* 기본적으로 Active Directory는 검색 결과를 1000개로 제한을 한다. 1000개
* 이상의 검색 결과를 가져야 한다면 PHP 5.4 이상을 사용하거나 또는 5.3 이하
* 버전에서는 ldap extnesion에 pagenation page를 해 줘야한다.
* 이 API를 PHP 5.3 이하 버전에서 pagenation 패치가 되지 않은 상태에서
* 실행하면 최대 1000개의 결과를 반환한다.
* @return object|array|false
function search_api ($rdn, $filter = null, $attr = null, $link = null) {
$filter = $filter ? $filter : '(objectclass=*)';
$attr = is_array ($attr) ? $attr : array ();
$link = $link ? $link : $this->link;
$rdn = $rdn ? $rdn : $this->rdn;
# filter에 euc-kr(또는 cp949)가 있으면 utf8로 변환한다
# Need KSC5601 pear package
# If you use local character set except euc-kr,
# this code changes to iconv
if ( $this->ksc->is_utf8 ($filter) === false )
$filter = $this->ksc->utf8 ($filter);
# Support from PHP 5.4 or ldap pagenation patch
ldap_control_paged_results ($link, $this->pagesize, true, $cookie);
if ( ($entries = @ldap_search ($link, $rdn, $filter, $attr, 0, 0, 30)) === false ) {
#ldap_sort ($link, $entries, 'sn');
$ent = ldap_get_entries ($link, $entries);
if ( is_array ($ent) && $ent['count'] != 0 ) {
$this->search_merge ($r, $ent);
ldap_control_paged_results_response ($link, $entries, $cookie);
} while ( $cookie !== null && $cookie != '' );
if ( ($entries = @ldap_search ($link, $rdn, $filter, $attr, 0, 0, 30)) === false ) {
ldap_sort ($link, $entries, 'sn');
$ent = ldap_get_entries ($link, $entries);
if ( ! is_array ($ent) || $ent['count'] == 0 ) {
$this->search_merge ($r, $ent);
// {{{ (void) ActiveDirectory_API::search_merge (&$r, $ent)
* @param array 결과값을 저장할 배열
function search_merge (&$r, $ent) {
if ( $ent['count'] == 0 )
$ignore_pattern = '/^(object|msexchmailboxguid|msexchmailboxsecuritydescriptor|count|usercerti|logonhours|userparameters|replicationsignature|msmqsigncertifi|msmqdigests)/i';
foreach ( $ent as $key => $value ) {
foreach ($value as $k => $v) {
if ( $v['count'] == 1 ) {
if ( $r[$key]->member['count'] )
$member = $r[$key]->member;
$member = $r[$key]->memberof;
for ( $i = 0; $i< $member['count']; $i++ )
$r[$key]->members[$i] = preg_replace ('/(CN=|,.*)/i', '', $member[$i]);
// {{{ (string) ActiveDirectory_API::make_nt_password ($pass)
* UTF-16 기반의 Active Directory 암호를 생성
for ( $i= 0; $i< $passlen; $i++ )
$newpass .= $pass[$i] . "\000";
// {{{ (boolean) ActiveDirectory_API::set_unix_attributes ($account, $type = 'add') {
* Unix attributte를 활성/수정/비활성 한다.
* 제어하는 Unix attribute는 다음과 같다.
* <li>mssfu30nisdomain</li>
* <li>unixhomedirectory</li>
* <li>unixuserpassword</li>
* 삭제시, uid, unixuserpassword, mssfu30name 은 남아 있는다.
* @param object|string계정 속성 또는 계정 이름
* @param array Unix Attribute 값
* @param string 활성/비활성/수정 (add/replace/remove)
$account = $this->user ($account);
if ( $account === false || ! is_object ($account) )
$is_unix = $this->is_unix_attribute ($account);
$attr->unixuserpassword = 'ABCD!efgh12345$67890';
if ( ! preg_match ('/^\$1\$/', $attr->unixuserpassword) )
$attr->unixuserpassword = crypt ($attr->unixuserpassword);
if ( ! $attr->loginshell )
$attr->loginshell = '/bin/bash';
if ( ! $attr->mssfu30name )
$attr->mssfu30name = $account->cn;
if ( ! $attr->mssfu30nisdomain )
$attr->mssfu30nisdomain = $this->domain;
if ( ! $attr->unixhomedirectory )
$attr->unixhomedirectory = '/home/AD/' . $account->cn;
'uidnumber' => ++ $uidnumber,
'gidnumber' => $gidnumber,
'loginshell' => $attr->shell,
'mssfu30name' => $attr->mssfu30name,
'mssfu30nisdomain' => $attr->mssfu30nisdomain,
'unixhomedirectory' => $attr->unixhomedirectory,
'unixuserpassword' => $attr->unixuserpassword,
foreach ( $value as $k => $v ) {
if ( ! isset ($account->$k) )
$addvar[$k] = $value[$k];
$r = $this->exec ($account->distinguishedname, $addvar, 'add');
return $this->set_unix_attirbutes ($account, $attr);
if ( $attr->unixuserpassword ) {
if ( ! preg_match ('/^\$1\$/', $attr->unixuserpassword) )
$attr->unixuserpassword = crypt ($attr->unixuserpassword);
$attrkey = array ('unixuserpassword', 'loginshell', 'unixhomedirectory');
foreach ( $attrkey as $key ) {
$act = $account->$key ? 'replace' : 'add';
$account->distinguishedname,
array ($key => $attr->$key),
'uid', 'uidnumber', 'gidnumber', 'loginshell', 'mssfu30name',
'mssfu30nisdomain', 'unixhomedirectory', 'unixuserpassword'
foreach ( $entryies as $key ) {
$value[$key] = $account->$ey;
$r = $this->exec ($account->distinguishedname, $value, 'del');
' (' . $account->cn . ' - ' . $account->distinguishedname . ')';
* 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
|