php如何使用ldap_search搜索目标用户的条目的字段数据?
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
本文讨论ldap
的数据搜索函数ldap_search()
,这个函数的功用其实就是个数据匹配外加个分页的功能,就像是传统网站的文章分类页面。本文的ldap_search()
和上文的ldap_bind()
函数,虽然经常在一起使用,但是两者之间并没有必须的联系。也就是说,这个ldap_search()
的使用方式,并不需要必须执行ldap_bind()
函数。两者都需要一个ldap_connection
对象。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验文章。本文测试环境:win10
,nginx@1.15.11
,php@8.2.9nts
,php_ldap.so
,openldap@2.4.32
。
函数原型
官网文档,参考链接:
ldap_search(
LDAP\Connection|array $ldap,
array|string $base,
array|string $filter,
array $attributes = [],
int $attributes_only = 0,
int $sizelimit = -1,
int $timelimit = -1,
int $deref = LDAP_DEREF_NEVER,
?array $controls = null
): LDAP\Result|array|false
参数比较多,本文仅仅涉及前几个参数,后续参数待后续文章讨论。所以原型简化为:
ldap_search(
LDAP\Connection|array $ldap,
array|string $base,
array|string $filter,
array $attributes = []
): LDAP\Result|false
这几个参数的时候,返回值就两种情况。
- 第一种情况是返回一个
result
对象(实际效果上类似一个指针),无法直接读取到有用数据。 - 第二种情况就是返回值
false
,表明确实没有数据。(实践表面:返回的是result
的时候,也可能是count
为0
)。
龙套数据
可以通过下面的两个方式,来制造本文的龙套数据,用户条目。参考文章:
代码框架
这里先放一下代码的框架,代码如下:
$con = @ldap_connect('ldap://127.0.0.1', 389);
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($con, LDAP_OPT_REFERRALS, 0);
if ($con) {
// 本文主体代码在这里
}
搜索之精准匹配
$basedn = "ou=People,dc=my-domain,dc=com";
// $basedn = "dc=my-domain,dc=com";
// $basedn = "dc=com"; // 没有数据
$filter = "uid=hacker";
$filter = "cn=Sergio";
$filter = "sn=Hacker";
$filter = "mail=info@matear.eu";
$filter = "uidNumber=1561";
$filter = "objectClass=top"; // 返回多个
$result = @ldap_search($con, $basedn, $filter);
if ($result) {
$info = ldap_get_entries($con, $result);
var_dump($result);
var_dump($info["count"]);
var_dump($info);
} else {
echo "没有数据";
}
这个里面要设定basedn
,这个就类似一个作用域的设置。值得注意的是:
dn
里面的作用域里面有两个dc=
。如果仅仅在basedn
里面仅仅写一个dc=
,是查询不到任何数据的。- 对于
objectClass=top
这个条件,实际上所有的节点都符合,所以是返回多个节点数据。 ldap_search()
的结果LDAP\Result
只是个指针,并不是现实的数据,因此需要再次解析。
大范围模糊匹配
除了精准的条件匹配外,filter
还支持模糊匹配。下面的例子中,filter
是另外的写法。
$basedn = "ou=People,dc=my-domain,dc=com";
$filter = "(|(sn=hack*)(cn=hack*))";
$filter = "(&(sn=hack*)(uid=hack*))";
$result = ldap_search($con, $basedn, $filter);
if ($result) {
$info = ldap_get_entries($con, $result);
var_dump($result);
var_dump($info["count"]);
var_dump($info);
} else {
echo "没有数据";
}
控制匹配结果的字段
默认返回所有的条目字段,事实上可以通过参数$attributes
来控制返回的字段范围。例子:
$basedn = "ou=People,dc=my-domain,dc=com";
$filter = "objectClass=top";
$attributes = ["cn", "mail"];
$result = ldap_search($con, $basedn, $filter, $attributes);
if ($result) {
$info = ldap_get_entries($con, $result);
var_dump($result);
var_dump($info["count"]);
var_dump($info);
} else {
echo "没有数据";
}
这个拿到了四个返回值,即使某个节点没有mail
属性,也是没有问题的。
重大误解
并不是返回了LDAP\Result
,就一定找到了数据,也有可能查到的数据count
为0
,实际效果上就等同于返回值false
。
例如下面的这个例子:
$basedn = "ou=People,dc=my-domain,dc=com";
$filter="(&(sn=hack*)(cn=hack*))";
$result = ldap_search($con, $basedn, $filter);
if ($result) {
$info = ldap_get_entries($con, $result);
var_dump($result);
var_dump($info["count"]);
var_dump($info);
} else {
echo "没有数据";
}
返回值是:
object(LDAP\Result)#2 (0) {
}
int(0)
array(1) {
["count"]=>
int(0)
}
ldap_get_entries()
对LDAP\Result
进行具体数据解析的函数是:
- ldap_get_entries($con, $result)
- ldap_first_entry($con, $result)
- ldap_get_attributes($con, $entry)
- ldap_get_dn($con, $entry)
参考代码:
$basedn = "ou=People,dc=my-domain,dc=com";
$filter="(|(sn=hack*)(cn=hack*))";
$result = ldap_search($con, $basedn, $filter); // object(LDAP\Result)#2 (0) {}
if ($result) {
// ## 获取所有条目 ##
// $info = ldap_get_entries($con, $result);
// var_dump($result);
// var_dump($info["count"]);
// var_dump($info);
// if($info["count"]<=0){
// echo "没有数据2";
// }
// ## 仅获取第一条条目数据 ##
$entry = ldap_first_entry($con, $result);
// object(LDAP\ResultEntry)#3 (0) {}
if($entry){
$attrs = ldap_get_attributes($con, $entry);
var_dump($attrs);
$user_dn = ldap_get_dn($con, $entry);
var_dump($user_dn);
// string(40) "uid=hacker,ou=People,dc=my-domain,dc=com"
}
} else {
echo "没有数据";
}
参考文章
- https://newsn.net/say/openldap.html
- https://newsn.net/say/phpldapadmin.html
- https://newsn.net/say/openldap-init.html
- https://newsn.net/say/openldap-user.html
- https://newsn.net/say/php-ldap_bind.html
- https://www.php.net/manual/en/ldap.examples-basic.php
结语
更多ldap
的经验文章,可以参考苏南大叔的文章链接:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。