添加注释

用户贡献注释 34 个注释

14
nick dot veitch at futurenet dot co dot
21 年前
在此处列出有效的运算符可能会有用

= - 匹配精确值
=*xxx - 匹配以 xxx 结尾的值
=xxx* - 匹配以 xxx 开头的值
=*xxx* - 匹配包含 xxx 的值
=* - 匹配所有值(如果已设置 - 不会返回 NULL)

>=xxx - 匹配从 xxx 到目录末尾的所有内容
<=xxx - 匹配目录中所有直到 xxx 的内容

~=xxx - 匹配类似的条目(并非所有系统都支持)

用于构建复杂搜索的布尔运算符

&(term1)(term2) - 匹配 term1 且 term2
| (term1)(term2) - 匹配 term1 或 term2
!(term1) - 匹配非 term1
&(|(term1)(term2))(!(&(term1)(term2)) - 匹配 term1 和 term2 的异或

一些更复杂的构造似乎以不同的效率工作 - 有时,用搜索过滤一些结果并在 PHP 中进行进一步过滤会更好。
17
jayleno at yahoo dot com
11 年前
<?php
set_time_limit
(30);
error_reporting(E_ALL);
ini_set('error_reporting', E_ALL);
ini_set('display_errors',1);

// 配置
$ldapserver = 'svr.domain.com';
$ldapuser = 'administrator';
$ldappass = 'PASSWORD_HERE';
$ldaptree = "OU=SBSUsers,OU=Users,OU=MyBusiness,DC=myDomain,DC=local";

// 连接
$ldapconn = ldap_connect($ldapserver) or die("无法连接到 LDAP 服务器。");

if(
$ldapconn) {
// 绑定到 LDAP 服务器
$ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass) or die ("绑定错误: ".ldap_error($ldapconn));
// 验证绑定
if ($ldapbind) {
echo
"LDAP 绑定成功...<br /><br />";


$result = ldap_search($ldapconn,$ldaptree, "(cn=*)") or die ("搜索查询错误: ".ldap_error($ldapconn));
$data = ldap_get_entries($ldapconn, $result);

// 显示所有数据
echo '<h1>转储所有数据</h1><pre>';
print_r($data);
echo
'</pre>';


// 遍历数组并打印每个条目的数据
echo '<h1>显示用户</h1>';
for (
$i=0; $i<$data["count"]; $i++) {
//echo "dn is: ". $data[$i]["dn"] ."<br />";
echo "用户: ". $data[$i]["cn"][0] ."<br />";
if(isset(
$data[$i]["mail"][0])) {
echo
"邮箱: ". $data[$i]["mail"][0] ."<br /><br />";
} else {
echo
"邮箱: 无<br /><br />";
}
}
// 打印找到的条目数
echo "找到的条目数: " . ldap_count_entries($ldapconn, $result);
} else {
echo
"LDAP 绑定失败...";
}

}

// 全部完成了吗?清理
ldap_close($ldapconn);
?>
6
aa529 at nospamchebucto dot ns dot ca
24 年前
从用户输入生成过滤器时,请注意特殊字符。

*, (, ), \ 和 NUL 应该用反斜杠转义。请参见 RFC 2254 的第 4 节(我在这里找到了它
http://www.cis.ohio-state.edu/htbin/rfc/rfc2254.html)
2
steven_bauman at outlook dot com
4 年前
请添加一个使用新的 $serverctrls 参数的示例。我不知道如何使用它。
6
Arnold
13 年前
我一直在编写一个脚本,需要获取所有属于特定 MS AD 组的用户。由于 PHP 错误 #42060(http://bugs.php.net/bug.php?id=42060)我无法获取属于该组的所有用户。
在谷歌搜索了一天后,我找到了一篇文章和一个补丁,但它需要我下载 php 5.1.6 或 5.2.10 的源代码,运行补丁,然后重新编译代码才能解决问题。
问题是
1) 我不是 Linux 专家,所以我不太习惯这样做......
2) 我在使用 PHP 的其他代码的生产机器上运行该脚本,我不知道这会对那些代码造成什么后果。
3) 我无法再更新 PHP,因为在更新版本中,这个补丁可能不再有效。

但昨天我看到了希望,写了一些代码来解决这个问题,也许其他遇到同样问题的人也可以使用它。

<?PHP
$startFilter
= "(&(memberOf=" .$ADGroup. "))";
$startResults = ldap_search($ldapconnect, $userBase, $startFilter, $attr);
$countResult = ldap_count_entries($ldapconnect,$startResults);

IF(
$countResult == 1000 OR $countResult == 1500)
{
// 循环遍历 97-122(字符 a-z 的 ASCII 码)
For($a=97;$a<=122;$a++)
{
// 将数字转换为字符
$character = chr($a);
// 新的搜索过滤器返回所有姓氏以 $character 开头的用户
$filter = "(&(sn=$character*)(memberOf=$ADGroup))";
$results = ldap_search($ldapconnect, $userBase, $filter, $attr);
$countResult2 = ldap_count_entries($ldapconnect,$results);

// 查看以特定字符开头的所有用户的搜索是否仍然达到搜索限制
// 如果是这样,则执行新的搜索以查找所有姓氏以“aa”开头的用户
// 然后以“ab”,“ac”等开头。
// 在最佳情况下,现在每个组可以找到 675.324 个用户,当搜索限制为 1000 时
// ((26 * 999 for the first character) * 26 for the second character)
// 以及 1.013.324 当搜索限制为 1500 时
If($countResult2 == 1000 or $countResult2 == 1500)
{
For(
$b=97;$b<=122;$b++)
{
$character2 = chr($b);
$filter2 = "(&(sn=$character$character2*)(memberOf=$ADGroup))";
$results2 = ldap_search($ldapconnect, $userBase, $filter2, $attr);
$count2 = ldap_count_entries($ldapconnect,$results2);
$entries2 = ldap_get_entries($ldapconnect,$results2);

// 做你的事
}
}
Else
{
$entries = ldap_get_entries($ldapconnect,$results);
// 做你的事
}
}
}
else
{
$entries = ldap_get_entries($ldapconnect,$startResults);
// 做你的事
}
?>
4
cruzfern at chuchuwa dot com dot ar
18 年前
内部属性(如 createTimestamp、modifyTimestamp 等)不会默认出现(当可选参数属性未设置时)。您必须指定它

<?
$r=ldap_search($ds,$base,$filter,array("createTimestamp"));
?>
8
chrisbloom7 at gmail dot com
17 年前
以下是一些关于如何正确构建过滤器的资源。

http://msdn2.microsoft.com/En-US/library/aa746475.aspx

http://technet.microsoft.com/en-us/library/aa996205.aspx

在找到这些之前,我一直苦苦思索如何做类似“所有以“a”开头的用户,除了来自 OU 'foo' 的用户”这样的操作。
3
sembiance at cosmicrealms dot com
20 年前
当搜索二进制数据(如 Active Directory 对象 GUID)时,需要使用反斜杠转义每个十六进制字符。

以下ldapsearch命令行运行显示
ldapsearch -b "dc=blahblah,dc=com" "(objectGUID=\AE\C3\23\35\F7)"

在PHP中,需要为反斜杠转义转义
ldap_search($ds,"dc=blahblah,dc=com", "(objectGUID=\\AE\\C3\\23\\35\\F7)");
3
francis dot tyers at hp dot com
20 年前
似乎所有字段都必须使用小写,即使它们在ldapsearch输出中是混合大小写的。

例如

gidNumber: 1010
homeDirectory: /home/dnt

必须是

echo "gid: " . $info[$i]["gidnumber"][0] . "<br>";
echo "home directory: ". $info[$i]["homedirectory"][0] ."<br>";

而不是 ( $info[$i]["homeDirectory"][0] ) 等等。
1
cdaveb at csua dot berkeley dot edu
23 年前
仅供参考,对于那些在 Exchange 服务器上执行 LDAP 搜索的人,Exchange 似乎有一些偏好,不允许进行非初始搜索(即,只有 x* 可以工作,而不是 * 或 *x)。我一直很困惑,试图弄清楚为什么我不断地遇到执行 * 搜索时的错误。

更多信息请访问
http://www.microsoft.com/Exchange/en/55/help/documents/server/XOG16007.HTM
4
Jean-Loup
12 年前
并行搜索示例

<?php
$basedn
=array('dmdName=users,dc=foo,dc=fr','dmdName=users,dc=bar,dc=com'); // 两个 basedn
$filter='(&(objectClass=inetOrgPerson)(uid=*))'; // 单个过滤器
$attributes=array('dn','uid','sn');

$cnx = ldap_connect('localhost',389); // 单个连接
ldap_set_option($cnx, LDAP_OPT_PROTOCOL_VERSION, 3);

ldap_bind($cnx,'uid=root,dc=foo,dc=fr','password'); // 在两个 BDB 上进行身份验证
ldap_bind($cnx,'uid=root,dc=bar,dc=com','password');

$search = ldap_search(array($cnx,$cnx),$basedn,$filter,$attributes); // 搜索

// 结果
for($i=0;$i<count($search);$i++){
print_r(ldap_get_entries($cnx,$search[$i]));
print
"\n";
}
?>
2
nicolas at atanis dot net
20 年前
以下是一个进行完整子树搜索的小脚本(我知道上面的脚本似乎可以做到,但它不能正常工作)。
这是我的版本。

Voila ce que j'ai fait aujourd'hui ...

$ldap_host = "192.168.0.50";
$ldap_port = "389";
$base_dn = "dc=fr";
$filter = "(cn=*)";
$ldap_user ="cn=admin,dc=fr";
$ldap_pass = "hellodelu";
$connect = ldap_connect( $ldap_host, $ldap_port);
ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);

$bind = ldap_bind($connect, $ldap_user, $ldap_pass);
$read = ldap_search($connect, $base_dn, $filter);

$info = ldap_get_entries($connect, $read);
echo $info["count"]." entrees retournees<BR><BR>";
for($ligne = 0; $ligne<$info["count"]; $ligne++)
{
for($colonne = 0; $colonne<$info[$ligne]["count"]; $colonne++)
{
$data = $info[$ligne][$colonne];
echo $data.":".$info[$ligne][$data][0]."<BR>";
}
echo "<BR>";
}
ldap_close($connect);

--------
nicolas
3
sema at technion dot ac dot il
19 年前
为了在 Windows 2003 Server Active Directory 上执行搜索,您必须将 LDAP_OPT_REFERRALS 选项设置为 0。

ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);

如果没有这样做,如果您尝试搜索整个 AD 架构(使用域根目录作为 $base_dn),您将收到“操作错误”。

与 Windows 2000 Server 相反,该选项是可选的,并且只会提高性能。
2
john_taylor_1973 at yahoo dot com
22 年前
如果可能,请尝试使用 ldap_list()。它要快得多。ldap_search 搜索 LDAP_SCOPE_SUBTREE 范围,但 ldap_list 搜索的范围仅为 LDAP_SCOPE_ONELEVEL。这在 Novell eDirectory 8.6.1 上有很大的区别,即使对于只返回 130 个对象的查询也是如此。使用属性列表(即,两个函数的第四个参数),也可以使查询速度更快。
1
jpdalbec at ysu dot edu
21 年前
我发现至少在使用 Red Hat PHP 4.1.2 软件包时,搜索过滤器中的空格需要转义("\20")。否则将不会返回任何结果。
1
chester at the dot underground dot com dot au
20 年前
如果您正在搜索活动目录,并且遇到延迟或超时,可能是您从 LDAP 服务器收到了 LDAP 转发。以下代码将禁用此功能。

<?
ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
?>
2
mike at remi-designs dot net
8 年前
我遇到了这样的问题,即我搜索的属性具有“exactMatch”的匹配规则。

例子
电子邮件地址存储为混合大小写:[email protected]

当用户输入:[email protected] 时,LDAP 搜索将不会检索任何值。

解决方案:不要通过以下方式比较用户输入和属性值

<?php
if($data[$i]['mail'][0] == $username) {
// 这将一无所获
}
?>

而是使用 strcasecmp

<?php
if(strcasecmp($data[$i]['mail'][0], $username) == 0) {
// 工作
}
1
me at gavinadams dot org
20 年前
关于 AD LDAP 搜索的轻微说明。前面的示例中有一个小错误,并且不会显示每个属性的多个值。这是用于枚举所有条目、属性和值的 for 循环。

$bind = ldap_bind($connect) // 假设匿名连接或添加用户/密码
or exit(">>Could not bind to $ldap_host<<");
$read = ldap_search($connect, $base_dn, $filter)
or exit(">>Unable to search ldap server<<");
$info = ldap_get_entries($connect, $read);
echo $info["count"]." entries returned<br>";
// $i = 条目
// $ii = 每个条目的属性
// $iii = 每个属性的值
for ($i = 0; $i<$info["count"]; $i++) {
for ($ii=0; $ii<$info[$i]["count"]; $ii++){
$data = $info[$i][$ii];
for ($iii=0; $iii<$info[$i][$data]["count"]; $iii++) {
echo $data.":&nbsp;&nbsp;".$info[$i][$data][$iii]."<br>";
}
}
echo "<p>"; // 分隔条目
0
peter dot mlich at volny dot cz
4 年前
来自我的 LDAP 类的示例代码。

public function query($_filter, $_att, $_ref=2, $count_bool=true)
{
$fn = 'query';
$config = $this->config;
$conn = $this->conn;
if (!$conn)
{return $this->errorConnection($fn);}
ldap_set_option($conn, LDAP_OPT_DEREF, $_ref);
$result = ldap_search($conn, $config['baseDn'], $_filter, $_att); // or die(ldap_error($conn))
if ($result===false)
{
$this->error("Search error, neexistuje!");
return false;
}
$count = ldap_count_entries($conn, $result);
if ($count_bool && $count!=1)
{
$this->error("Search error, neni unikatni! count=".$count);
ldap_free_result($result);
return false;
}
$data = ldap_get_entries($conn, $result);
ldap_free_result($result);
return $data;
}

// ---

$filter = "(&(objectclass=person)(cn=" . $user_name . "))";
$att = array(
'uid',
'workforceID',
'employeeID',
'givenName',
'sn',
'mail'
);
$data = $this->query($filter, $att, 2, true);
0
anze dot pratnemer at fe dot uni-lj dot si
5 年前
在开发插件时,我不得不使用 ldap_search() 命令在 LDAP 服务器上搜索用户,但它没有找到它们,而 unix shell(ubuntu)中的 ldapsearch 命令则找到了。

问题出在我代码中的几行代码之上,大约在 ldap_connect() 附近。我输入的服务器地址是 ldap://server.hostname,事实证明这就是罪魁祸首。

一旦我只使用 server.hostname,不带协议(ldap://),用户就会被找到并正确显示。
0
Allie
17 年前
我刚刚在 ldap_bind 上发布了帖子,但我认为在这里发布不会有什么坏处,因为这是我尝试解决问题时首先停止的地方。我的错误指向 ldap_search,但指定 ldap_connect 端口是解决方法。

当您想要在整个目录中搜索 MS AD 时,您必须在绑定中指定端口 3268。这对于 apache auth_ldap 也是如此。

$ldapserver = ldap_connect($server,3268);
0
php @ fccfurn dot com
21 年前
要从活动目录中的顶层 DN 进行子树搜索,请确保执行了 ldap_set_option()。

<?php
$ldap_host
= "pdc.php.net";
$base_dn = "DC=php,DC=net";
$filter = "(cn=Joe User)";
$ldap_user = "CN=Joe User,OU=Sales,DC=php,DC=net";
$ldap_pass = "pass";
$connect = ldap_connect( $ldap_host, $ldap_port)
or exit(
">>无法连接到 LDAP 服务器<<");
ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
$bind = ldap_bind($connect, $ldap_user, $ldap_pass)
or exit(
">>无法绑定到 $ldap_host<<");
$read = ldap_search($connect, $base_dn, $filter)
or exit(
">>无法搜索 ldap 服务器<<");
$info = ldap_get_entries($connect, $read);
echo
$info["count"]." 条条目返回<p>";
$ii=0;
for (
$i=0; $ii<$info[$i]["count"]; $ii++){
$data = $info[$i][$ii];
echo
$data.":&nbsp;&nbsp;".$info[$i][$data][0]."<br>";
}
ldap_close($connect);
?>
0
匿名
22 年前
我使用以下代码从 ILS(Netmeeting)服务器检索所有条目:<p> $sr=ldap_search($ds, "objectclass=rtperson","(&(cn=%)(objectclass=rtperson))");
<p>玩得开心!
<p>Kees
-1
ben _at_ onshop_co_uk
14 年前
示例说明搜索多个 DN(多个 DN)

<?php
$ds
=ldap_connect($ldapserver);

$dn[]='OU=ABC,DC=xyz,DC=ac,DC=uk';
$dn[]='OU=DEF,DC=xyz,DC=ac,DC=uk';

$id[] = $ds;
$id[] = $ds;

$filter = 'samaccountname='.$_POST['username'];

$result = ldap_search($id,$dn,$filter);

$search = false;

foreach (
$result as $value) {
if(
ldap_count_entries($ds,$value)>0){
$search = $value;
break;
}
}

if(
$search){
$info = ldap_get_entries($ds, $search);
}else{
$info = '未找到结果';
}
?>
-1
ben _at_ onshop.co.uk
14 年前
继我 2009 年 11 月 11 日 06:56 关于使用 LDAP 查询 AD 时 DN 问题,进一步调查表明,虽然结果在数据包中,但我却收到了一个错误

'搜索:无法联系 LDAP 服务器' 又名错误 81。

使用更详细的分析

ldap_get_option($ds,LDAP_OPT_ERROR_STRING,$error);

echo $error

显示

转介:ldap://DomainDnsZones.defg.de.bc.ac.uk/ DC=DomainDnsZonesDC=defg,DC=de,DC=abc,DC=ac,DC=uk

通过反复试验,使用以下方法消除了错误并返回了结果

ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
-1
Kamil Kukura <kamk at nexen dot cz>
21 年前
当我尝试在具有 "" namingContext 的 OpenLDAP 服务器上使用空基 DN 进行搜索时,我得到了结果 "no such object"。在日志文件中,查询了 dn:dc=example,dc=com(!)。
作为解决方法,似乎可以使用空格 (' ') 作为基 DN 就可以了 - ldap_search($ds, ' ', '(...filter...)', ...
-1
neumeyed at city dot bloomington dot in dot us
21 年前
先前的一条评论指出:"我还注意到,departmentNumber、employeeNumber(以及 inetorgperson.schema 中的其它属性)不会从搜索中返回。"

这是错误的。这些属性会被返回,但你必须使用小写名称引用它们。也就是说,不要这样

$entries[0]["departmentNumber"][0]

而应该这样

$entries[0]["departmentnumber"][0]

在我看来,这并不是 "正确" 的行为,但我对 LDAP 的了解还不够,无法确定。
-3
info at acpower dot biz
12 年前
我是一个新手,所以我希望这能帮助其他遇到相同问题的新手...

这段代码返回了 "No Such Object" 的错误

<?php

$search
= ldap_search ($ldapcon, "cn=admin,dc=acpower,dc=biz", "(filters)");

?>

我删除了 cn,然后奇迹发生了!它成功了

<?php

$search
= ldap_search ($ldapcon, "dc=acpower,dc=biz", "(filters)");

?>
-2
openldap at mail dot doris dot cc
19 年前
PHP 4.3.10

我试图在没有 basedn 的情况下进行 ldapsearch。首先,我尝试使用 ' ',正如上面所建议的那样,但它给了我一个无效的 dn 语法错误。

例如
$sr=ldap_search($ds, ' ', $filter);
警告:ldap_search(): 搜索:... 中的 DN 语法无效

然后我将其更改为
$sr=ldap_search($ds, "", $filter);

这给了我以下错误
警告:ldap_search(): 搜索:... 中没有这样的对象

然后我修改了我的 ldap.conf 文件,并注释掉了 BASE 字段
#BASE dc=example, dc=com

然后它就成功了!

因此,看起来如果你提供一个空白的 basedn,它将使用 ldap.conf 中的默认 basedn。
-1
emrecio at netscape dot net
21 年前
implode(", ",$uentry[0]["rfc822mailalias"]);

不能按预期工作,因为 "count" 在里面... 必须使用 "for" 循环遍历结果(丢弃 "count" 元素)。
-2
fmouse at fmp dot com
19 年前
看起来,用于 LDAP 筛选器信息的 Netscape 目录 SDK(developer.netscape.com)不再接受连接。RFC 2254 的副本定义了 LDAP 筛选器的字符串表示标准,可以在 http://www.ietf.org/rfc/rfc2254.txt 找到。
-4
nick
12 年前
来自 ActiveDirectory 的结果可能按 objectSid 排序。
我们可以通过修改筛选器来获取每个页面大小的所有用户。

<?php
// ... 连接到 LDAP
$lastsid='';
while (
1) {
$filter = '(objectClass=user)';
if (
strlen($lastsid)) {
list(
$v)=array_values(unpack('V',substr($lastsid,24))); // 用户的 ID。
$s = substr($lastsid,0,24).pack('V',1+$v); // 下一个 SID。
$s = preg_replace('/../','\\\\$0',bin2hex($s)); // 为了过滤而转义
$filter = '(&'.$filter.'(objectSid>='.$s.'))'; // 下一个条目的过滤条件。
}
$res = ldap_search($ldap,$basedn,$filter,array('objectSid','cn'));
if (!
ldap_count_entries($ldap,$res)) {
break;
}
for (
$ent=ldap_first_entry($ldap,$res); $ent; $ent=ldap_next_entry($ldap,$ent)) {
list(
$lastsid) = ldap_get_values_len($ldap,$ent,'objectSid');
}
}
?>
-8
匿名
18 年前
如何列出 LDAP 用户。

这段代码列出了 LDAP 树中的一个用户,但我想要列出 LDAP 中某个 ou=Organization 下的所有用户。

<?php

$ldaprdn
= 'cn=user,dc=domain,dc=org';
$ldappass = 'password';
$sdn = 'cn=user,ou=group,dc=domain,dc=org';

$ldapconn = ldap_connect("ldap://localhost", 389)
or die(
"无法连接: $ldaphost ");

if (
$ldapconn) {

// 绑定到 LDAP 服务器
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);

// 验证绑定
if ($ldapbind) {
$filter="uid=*";
$justthese = array("uid");

$sr=ldap_read($ldapconn, $srdn, $filter, $justthese);
$entry = ldap_get_entries($ldapconn, $sr);

} else {
echo
"LDAP 连接成功...";
}

}

ldap_close($ldapconn);

?>
<?php
echo $entry[0]["mail"][0] . " 邮件地址 ";
echo
$entry[0]["sn"][0] . " 姓名 ";
?>
-7
rsu_friend at yahoo dot com
19 年前
我正在使用 ldap_search,代码如下:
$searchbasedn = "miDomainName=" . $_SESSION['selectDomain'] ."," . LDAP_DOMAINBASE;
$filter = "(&(mpsAccountNumber=". $acctNumber .")(objectclass=mpsAccountDetails))";
$attributes = array("mpsparentchild");

$sr = ldap_search($ldapconn, $searchbasedn, $filter,$attributes);

由于某种原因,这个搜索失败了。
但当我将搜索过滤器改为以下代码时,搜索成功了:
$filter = "(&(mpsAccountNumber= $acctNumber )(objectclass=mpsAccountDetails))";

我不明白为什么第一种情况下的 ldap_search 无法进行搜索。
To Top