How to PHP ldap_search() to get user OU if I don't know the OU for base DN

匿名 (未验证) 提交于 2019-12-03 01:30:01

问题:

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:

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 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 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 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(); 

回答1:

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 node can be under any node (a user is a node, an ou is a node).

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:



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!