如何将PHP ldap_search()来获取用户的OU,如果我不知道该OU的基本DN [英] How to PHP ldap_search() to get user OU if I don't know the OU for base DN

查看:2617
本文介绍了如何将PHP ldap_search()来获取用户的OU,如果我不知道该OU的基本DN的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在那里的用户对象驻留在OU例如一个活动目录架构,IT,技术,人力资源,会计等。我希望写出与AD认证用户PHP脚本,并根据他们的集团提供aproperiate Web服务。

ldap_search()需要基本DN。 我试着用

搜索

  ldap_search($ LDAP,DC =国,DC =公司,DC =合作,直流=英国,(SAM帐户名= $的用户名),阵列(成员​​) );
 

但是PHP提供了操作错误。相反,如果我指定的OU

  ldap_search($ LDAP,OU =销售额,DC =国,DC =公司,DC =合作,直流=英国,(SAM帐户=杰克),阵列(成员));
 

那么搜索就可以了。

有一个通配符可以使用吗?

在一个侧面说明,应用户对象在OU呢?因为我是谁摆在首位!

感动他们里面的小白

编辑: 随着学分JPBlanc在正确的方向引导我, http://blog.redbranch.net/?p=76

该解决方案是增加连接和绑定的2行。

  ldap_connect(..)
ldap_set_option($ LDAP,LDAP_OPT_REFERRALS,0);
ldap_set_option($ LDAP,LDAP_OPT_PROTOCOL_VERSION,3);
的ldap_bind(..)
 

感谢=)

编辑2 - 全code:

 < PHP

命名空间的LDAP;

抽象类AuthStatus
{
    常量FAIL =验证失败;
    常量OK =认证OK;
    常量SERVER_FAIL =无法连接到LDAP服务器;
    常量匿名=匿名登录;
}

// LDAP服务器
一流的LDAP
{
    私人$服务器=127.0.0.1;
    私人$域=localhost的;
    私人$管理=管理;
    私人$密码=;

    公共职能__construct($服务器,$领域,$管理=,$密码=)
    {
        $这个 - >服务器= $服务器;
        $这个 - >域= $域;
        $这个 - >管理= $管理;
        $这个 - >密码= $密码;
    }

    //验证了对服务器的域\用户名和密码组合。
    公共功能验证($用户)
    {
        $用户可>的auth_status = AuthStatus ::失败;

        $ LDAP = ldap_connect($这个 - >服务器)或$用户自>的auth_status = AuthStatus :: SERVER_FAIL;
        ldap_set_option($ LDAP,LDAP_OPT_REFERRALS,0);
        ldap_set_option($ LDAP,LDAP_OPT_PROTOCOL_VERSION,3);
        $ ldapbind =的ldap_bind($ LDAP,$用户可>用户名@$这 - >域名,用户可$>密码);

        如果($ ldapbind)
        {
            如果(空($用户自>密码))
            {
                $用户可>的auth_status = AuthStatus ::匿名的;
            }
            其他
            {
                $结果= $用户自>的auth_status = AuthStatus ::确定;

                $这个 - > _get_user_info($ LDAP,$用户);
            }
        }
        其他
        {
            $结果= $用户自>的auth_status = AuthStatus ::失败;
        }

        ldap_close($ LDAP);
    }

    //获取用户的数组或返回错误的错误
    公共职能get_users()
    {
        如果(($ LDAP = ldap_connect($这个 - >!服务器)))返回false;

        ldap_set_option($ LDAP,LDAP_OPT_REFERRALS,0);
        ldap_set_option($ LDAP,LDAP_OPT_PROTOCOL_VERSION,3);
        $ ldapbind =的ldap_bind($ LDAP,$这个 - >联系@$这 - >域名,$这个 - >密码);

        $ DC =爆炸(,$这个 - &GT。域名);
        $ base_dn =;
        的foreach($直流如$ _dc)$ base_dn =直流=$ _直流,。;
        $ base_dn = SUBSTR($ base_dn,0,-1);
        $ SR = ldap_search($ LDAP,$ base_dn, "(&(objectClass=user)(objectCategory=person)(|(mail=*)(telephonenumber=*))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))",阵列(CN,DN,成员,邮件,telephonenumber,othertelephone,手机,IPPHONE,部,标题));
        $信息= ldap_get_entries($ LDAP,$ SR);

        为($ i = 0; $ I< $信息[伯爵]; $ I ++)
        {
            $用户[$ i] [名称] = $信息[$ i] [CN] [0];
            $用户[$ i] [电子邮件] = $信息[$ i] [电子邮件] [0];
            $用户[$ i] [手机] = $信息[$ i] [手机] [0];
            $用户[$ i] [Skype的] = $信息[$ i] [IPPHONE] [0];
            $用户[$ i] [电话] = $信息[$ i] [telephonenumber] [0];
            $用户[$ i] [部门] = $信息[$ i] [部门] [0];
            $用户[$ i] [标题] = $信息[$ i] [标题] [0];

            为($ T = 0; $ T< $信息[$ i] [othertelephone] [数量]; $ T ++)
                $用户[$ i] [othertelephone] [$ T] = $信息[$ i] [othertelephone] [$ T]

            //设置为空数组
            如果(!is_array($用户[$ i] [othertelephone]))$用户[$ i] [othertelephone] =阵列();
        }

        返回$用户;
    }

    私有函数_get_user_info($ LDAP,$用户)
    {
        $ DC =爆炸(,$这个 - &GT。域名);

        $ base_dn =;
        的foreach($直流如$ _dc)$ base_dn =直流=$ _直流,。;

        $ base_dn = SUBSTR($ base_dn,0,-1);

        $ SR = ldap_search($ LDAP,$ base_dn,(及(objectClass的=用户)(objectCategory属性=人)(Sam帐户=$用户可与GT;用户名)),阵列(CN,DN ,成员,邮件,telephonenumber,othertelephone,手机,IPPHONE,部,标题));
        $信息= ldap_get_entries($ LDAP,$ SR);

        $用户可基团取代=阵列();
        为($ i = 0; $ I< $信息[0] [成员] [伯爵]; $ I ++)
            array_push($用户可基团取代,$信息[0] [成员] [$ i]于);

        $用户可>名称= $信息[0] [CN] [0];
        $用户可>的dn = $信息[0] [DN];
        $用户可>邮件= $信息[0] [电子邮件] [0];
        $用户可>电话= $信息[0] [telephonenumber] [0];
        $用户可>移动= $信息[0] [手机] [0];
        $用户可> Skype的= $信息[0] [IPPHONE] [0];
        $用户可>部门= $信息[0] [部门] [0];
        $用户可>标题= $信息[0] [标题] [0];

        为($ T = 0; $ T< $信息[$ i] [othertelephone] [数量]; $ T ++)
                $用户可> other_telephone [$ T] = $信息[$ i] [othertelephone] [$ T]

        如果(is_array($用户自>!other_telephone [$ T]))$用户可> other_telephone [$ T] =阵列();
    }
}

类用户
{
    变量$的auth_status = AuthStatus ::失败;
    变量$用户名=无名氏;
    变量$密码=;

    变量$组=阵列();
    变量$ DN =;
    变量$ NAME =;
    变量$电子邮件=;
    变量$电话=;
    变量$ other_telephone =阵列();
    变量$手机=;
    变量$ Skype的=;
    变量$部门=;
    变量$标题=;

    公共职能__construct($的用户名,密码$)
    {
        $这个 - >的auth_status = AuthStatus ::失败;
        $这个 - >用户名= $的用户名;
        $这个 - >密码= $密码;
    }

    公共职能get_auth_status()
    {
        返回$这个 - >的auth_status;
    }
 }
?>
 

用法:

  $ LDAP =新的LDAP \ LDAP(192.168.1.123,company.com,管理,输入mypassword);
$用户= $ LDAP-> get_users();
 

解决方案

如果您尝试在Windows 2003 Server的Active Directory或以上进行搜索,似乎你的LDAP_OPT_REFERRALS选项设置为0:

  ldap_set_option($ LDAP,LDAP_OPT_REFERRALS,0);
ldap_set_option($ LDAP,LDAP_OPT_PROTOCOL_VERSION,3);
 

如果没有这个,你会得到操作错误如果您尝试到整个AD(领域中使用根作为$ base_dn)进行搜索。


在LDAP目录一般任何点头可以在任何点头(用户是一个点头,一个OU是点头)。

但是主动 - 指南的行为以不同的方式的模式中定义,其中容器中的对象可存在。所以,如果你找一个用户,允许上级是: builtinDomain domainDNS 组织单位,你可以在这里看到:

I have an Active-Directory structure where User objects reside in OU for example, IT, Technical, HR, Accounts etc.. I want to write a PHP script that authenticates the user with AD and depending on their Group to provide the aproperiate web services.

ldap_search() requires base DN. I tried to search with

ldap_search($ldap, "dc=country,dc=company,dc=co,dc=uk", "(samaccountname=$username)", array("memberof"));

but PHP gives "Operation Error". If instead i specify the OU

ldap_search($ldap, "ou=sales,dc=country,dc=company,dc=co,dc=uk", "(samaccountname=jake)", array("memberof"));

then the search is ok.

Is there a wildcard I can use?

On a side note, should user objects be in OU at all? Because I am the noob who moved them inside in the first place!

EDIT: With credits to JPBlanc for guiding me in the right direction and http://blog.redbranch.net/?p=76

The solution is to add 2 lines between connect and bind.

ldap_connect(..)
ldap_set_option ($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind(..)

Thanks =)

EDIT 2 - Fullcode:

<?php

namespace ldap;

abstract class AuthStatus
{
    const FAIL = "Authentication failed";
    const OK = "Authentication OK";
    const SERVER_FAIL = "Unable to connect to LDAP server";
    const ANONYMOUS = "Anonymous log on";
}

// The LDAP server
class LDAP
{
    private $server = "127.0.0.1";
    private $domain = "localhost";
    private $admin = "admin";
    private $password = "";

    public function __construct($server, $domain, $admin = "", $password = "")
    {
        $this->server = $server;
        $this->domain = $domain;
        $this->admin = $admin;
        $this->password = $password;
    }

    // Authenticate the against server the domain\username and password combination.
    public function authenticate($user)
    {
        $user->auth_status = AuthStatus::FAIL;

        $ldap = ldap_connect($this->server) or $user->auth_status = AuthStatus::SERVER_FAIL;
        ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
        ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
        $ldapbind = ldap_bind($ldap, $user->username."@".$this->domain, $user->password);

        if($ldapbind)
        {
            if(empty($user->password))
            {
                $user->auth_status = AuthStatus::ANONYMOUS;
            }
            else
            {
                $result = $user->auth_status = AuthStatus::OK;

                $this->_get_user_info($ldap, $user);
            }
        }
        else
        {
            $result = $user->auth_status = AuthStatus::FAIL;
        }

        ldap_close($ldap);
    }

    // Get an array of users or return false on error
    public function get_users()
    {       
        if(!($ldap = ldap_connect($this->server))) return false;

        ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
        ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
        $ldapbind = ldap_bind($ldap, $this->admin."@".$this->domain, $this->password);

        $dc = explode(".", $this->domain);
        $base_dn = "";
        foreach($dc as $_dc) $base_dn .= "dc=".$_dc.",";
        $base_dn = substr($base_dn, 0, -1);
        $sr=ldap_search($ldap, $base_dn, "(&(objectClass=user)(objectCategory=person)(|(mail=*)(telephonenumber=*))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))", array("cn", "dn", "memberof", "mail", "telephonenumber", "othertelephone", "mobile", "ipphone", "department", "title"));
        $info = ldap_get_entries($ldap, $sr);

        for($i = 0; $i < $info["count"]; $i++)
        {
            $users[$i]["name"] = $info[$i]["cn"][0];
            $users[$i]["mail"] = $info[$i]["mail"][0];
            $users[$i]["mobile"] = $info[$i]["mobile"][0];
            $users[$i]["skype"] = $info[$i]["ipphone"][0];
            $users[$i]["telephone"] = $info[$i]["telephonenumber"][0];
            $users[$i]["department"] = $info[$i]["department"][0];
            $users[$i]["title"] = $info[$i]["title"][0];

            for($t = 0; $t < $info[$i]["othertelephone"]["count"]; $t++)
                $users[$i]["othertelephone"][$t] = $info[$i]["othertelephone"][$t];

            // set to empty array
            if(!is_array($users[$i]["othertelephone"])) $users[$i]["othertelephone"] = Array();
        }

        return $users;
    }

    private function _get_user_info($ldap, $user)
    {
        $dc = explode(".", $this->domain);

        $base_dn = "";
        foreach($dc as $_dc) $base_dn .= "dc=".$_dc.",";

        $base_dn = substr($base_dn, 0, -1);

        $sr=ldap_search($ldap, $base_dn, "(&(objectClass=user)(objectCategory=person)(samaccountname=".$user->username."))", array("cn", "dn", "memberof", "mail", "telephonenumber", "othertelephone", "mobile", "ipphone", "department", "title"));
        $info = ldap_get_entries($ldap, $sr);

        $user->groups = Array();
        for($i = 0; $i < $info[0]["memberof"]["count"]; $i++)
            array_push($user->groups, $info[0]["memberof"][$i]);

        $user->name = $info[0]["cn"][0];
        $user->dn = $info[0]["dn"];
        $user->mail = $info[0]["mail"][0];
        $user->telephone = $info[0]["telephonenumber"][0];
        $user->mobile = $info[0]["mobile"][0];
        $user->skype = $info[0]["ipphone"][0];
        $user->department = $info[0]["department"][0];
        $user->title = $info[0]["title"][0];

        for($t = 0; $t < $info[$i]["othertelephone"]["count"]; $t++)
                $user->other_telephone[$t] = $info[$i]["othertelephone"][$t];

        if(!is_array($user->other_telephone[$t])) $user->other_telephone[$t] = Array();
    }
}

class User
{
    var $auth_status = AuthStatus::FAIL;
    var $username = "Anonymous";
    var $password = "";

    var $groups = Array();
    var $dn = "";
    var $name = "";
    var $mail = "";
    var $telephone = "";
    var $other_telephone = Array();
    var $mobile = "";
    var $skype = "";
    var $department = "";
    var $title = "";

    public function __construct($username, $password)
    {       
        $this->auth_status = AuthStatus::FAIL;
        $this->username = $username;
        $this->password = $password;
    }

    public function get_auth_status()
    {
        return $this->auth_status;
    }
 }
?>

Usage:

$ldap = new ldap\LDAP("192.168.1.123", "company.com", "admin", "mypassword");
$users = $ldap->get_users();

解决方案

If you try to perform the searches on Windows 2003 Server Active Directory or above, it seems that you have to set the LDAP_OPT_REFERRALS option to 0:

ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);

Without this, you will get "Operations error" if you try to search the whole AD (using root of the domain as a $base_dn).


In LDAP Directories in general any nod can be under any nod (a user is a nod, an ou is a nod).

But Active-Directory behave in a different way the SCHEMA define in which container an object can exist. So, if you look for a user, superiors allowed are : builtinDomain, domainDNS and organizationalUnit as you can see here under :

这篇关于如何将PHP ldap_search()来获取用户的OU,如果我不知道该OU的基本DN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆