Php 如果我没有';我不知道基本DN的OU
我有一个Active Directory结构,其中用户对象驻留在OU中,例如,IT、技术、HR、帐户等。。我想编写一个PHP脚本,用AD对用户进行身份验证,并根据用户组提供适当的web服务 ldap_search()需要基本DN。 我试着用Php 如果我没有';我不知道基本DN的OU,php,active-directory,ldap,Php,Active Directory,Ldap,我有一个Active Directory结构,其中用户对象驻留在OU中,例如,IT、技术、HR、帐户等。。我想编写一个PHP脚本,用AD对用户进行身份验证,并根据用户组提供适当的web服务 ldap_search()需要基本DN。 我试着用 ldap_search($ldap, "dc=country,dc=company,dc=co,dc=uk", "(samaccountname=$username)", array("memberof")); 但是PHP给出了“操作错误”。如果我指定了O
ldap_search($ldap, "dc=country,dc=company,dc=co,dc=uk", "(samaccountname=$username)", array("memberof"));
但是PHP给出了“操作错误”。如果我指定了OU
ldap_search($ldap, "ou=sales,dc=country,dc=company,dc=co,dc=uk", "(samaccountname=jake)", array("memberof"));
那么搜索就可以了
我可以使用通配符吗
另一方面,用户对象是否应该在OU中?因为我是第一个把他们搬进去的人
编辑:
感谢JPBlanc为我指引了正确的方向
解决方案是在connect和bind之间添加两行
ldap_connect(..)
ldap_set_option ($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind(..)
谢谢=)
编辑2-完整代码:
<?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;
}
}
?>
如果您尝试在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);
如果不这样做,如果您尝试搜索整个广告(使用域的根作为$base\u dn),您将得到“Operations error”
在LDAP目录中,通常任何节点都可以位于任何节点下(用户是节点,ou是节点) 但Active Directory的行为方式与模式不同,模式定义对象可以存在于哪个容器中。因此,如果您查找用户,允许的上级是:
内置域名
、域名域名
和组织单元
,您可以在下面看到:
谢谢,但我收到了一个不同的警告:ldap_search():搜索:部分结果和转介接收编辑答案。请尝试。我能够解决问题,因此我已将您的帖子标记为答案。此外,我还编辑了我的问题。谢谢你的帮助!非常完美,这就是我想要的。@LarryG.Wapnitsky我已经发布了我在PHP5.3.x上的代码。希望你能用上。我发邮件后两个小时就可以用了。谢谢
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);