2024 年 PHP 日本大会

ldap_bind

(PHP 4, PHP 5, PHP 7, PHP 8)

ldap_bind绑定到 LDAP 目录

描述

ldap_bind(LDAP\Connection $ldap, ?string $dn = null, #[\SensitiveParameter] ?string $password = null): bool

使用指定的 RDN 和密码绑定到 LDAP 目录。

参数

ldap

一个 LDAP\Connection 实例,由 ldap_connect() 返回。

dn

password

如果 password 未指定或为空,则尝试匿名绑定。对于匿名绑定,dn 也可以留空。这在 https://tools.ietf.org/html/rfc2251#section-4.2.2 中定义。

返回值

成功返回 true,失败返回 false

变更日志

版本 描述
8.1.0 ldap 参数现在期望一个 LDAP\Connection 实例;以前,期望一个有效的 ldap link 资源

示例

示例 #1 使用 LDAP 绑定

<?php

// 使用 ldap 绑定
$ldaprdn = 'uname'; // ldap rdn 或 dn
$ldappass = 'password'; // 关联密码

// 连接到 ldap 服务器
$ldapconn = ldap_connect("ldap://ldap.example.com")
or die(
"无法连接到 LDAP 服务器。");

if (
$ldapconn) {

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

// 验证绑定
if ($ldapbind) {
echo
"LDAP 绑定成功...";
} else {
echo
"LDAP 绑定失败...";
}

}

?>

示例 #2 匿名使用 LDAP 绑定

<?php

// 匿名使用 ldap 绑定

// 连接到 ldap 服务器
$ldapconn = ldap_connect("ldap://ldap.example.com")
or die(
"无法连接到 LDAP 服务器。");

if (
$ldapconn) {

// 匿名绑定
$ldapbind = ldap_bind($ldapconn);

if (
$ldapbind) {
echo
"LDAP 匿名绑定成功...";
} else {
echo
"LDAP 匿名绑定失败...";
}

}

?>

参见

添加备注

用户贡献的笔记 39 条笔记

gtkspert_SPAMMENOT_ at gmail dot com
13 年前
有趣的一点:

如果您无法使用错误“49:无效凭据”绑定到活动目录,您可以使用选项 LDAP_OPT_DIAGNOSTIC_MESSAGE 从 ldap_get_option 函数获取扩展错误输出。不幸的是,php 默认情况下没有定义它,但它的值为 0x0032。

如果用户必须在第一次登录时更改其密码(数据:773),或者如果他们的帐户在网络上已过期(数据:532),这将非常有用。

<?php

define
(LDAP_OPT_DIAGNOSTIC_MESSAGE, 0x0032)

$handle = ldap_connect('ldap://active.directory.server/');
$bind = ldap_bind($handle, 'user', 'expiredpass');

if (
$bind) {
if (
ldap_get_option($handle, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error)) {
echo
"LDAP 绑定错误: $extended_error";
} else {
echo
"LDAP 绑定错误:没有其他信息可用。";
}
}
?>

或者类似的东西。

我花了一段时间才解决这个问题,所以我想分享我的结果。
james at NOSPAM dot revillini dot com
16 年前
在按照一些关于创建 ldap.conf 文件的说明之前,我无法在 ldaps 连接上使用 ldap_bind。我在 php 网站上找不到这些说明。也许它们在 OpenLDAP 网站上,但我认为在这里也提供它们会很有用。感谢一位名为“LRM”的家伙,我在此处找到了我的解决方案:http://lists.horde.org/archives/sork/Week-of-Mon-20040503/001578.html

我的设置是 Win XP 上的 XAMPP。
###### ApacheFriends XAMPP(基本包)版本 1.6.3a ######

+ Apache 2.2.4
+ MySQL 5.0.45
+ PHP 5.2.3 + PHP 4.4.7 + PEAR
+ PHP-Switch win32 1.0(请使用“php-switch.bat”)
+ 来自 www.nat32.com 的 XAMPP Control 版本 2.5
+ XAMPP 安全 1.0
+ SQLite 2.8.15
+ OpenSSL 0.9.8e
+ phpMyAdmin 2.10.3
+ ADOdb 4.95
+ Mercury Mail Transport System v4.01b
+ FileZilla FTP Server 0.9.23
+ Webalizer 2.01-10
+ Zend Optimizer 3.3.0
+ 用于 PHP 5.2.3 的 eAccelerator 0.9.5.1(在 php.ini 中注释掉)

1. 创建 C:\OpenLDAP\sysconf\ldap.conf(是的,它必须是此路径,因为它在 dll 中是硬编码的)
2. 将此行放在顶部

TLS_REQCERT never

3. 保存,停止/启动 apache。

我认为原因是它不理解证书,因此此指令告诉它不要费心检查它。我猜在某些情况下这可能是不安全的,但在我的情况下,我对连接到的服务器充满信心。

我的连接代码如下所示(这里没有什么新东西,我认为)

<?php
$con
= @ldap_connect('ldaps://the.ldap.server', 636);
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($con, LDAP_OPT_REFERRALS, 0);
var_dump(@ldap_bind($con, '[email protected]', 'password'));
?>

祝你好运!LDAPS 真让人头疼。
[email protected]
17年前
许多使用 LDAP 简单绑定来验证用户的身份验证方案示例和实现未能正确清理用户提交的数据。这可能允许匿名用户以现有用户的身份验证到基于 Web 的应用程序。下面简要描述并举例说明此漏洞是如何产生的。有关更详细的信息,请访问此帖底部的链接。

如 RFC 4513 中所述,LDAP 的绑定操作提供了一种允许用户身份验证的方法。对于简单身份验证方法,用户可以使用匿名身份验证机制、未经身份验证的身份验证机制或名称/密码身份验证机制。当希望建立匿名授权状态的客户端传递非零长度的可分辨名称和零长度密码时,将使用未经身份验证的身份验证机制。大多数 LDAP 服务器可以配置为允许此机制,或者默认允许此机制。当建立匿名授权状态时,使用客户端凭据执行简单绑定操作的基于 Web 的应用程序处于危险之中。当基于 Web 的应用程序将可分辨名称和零长度密码传递到 LDAP 服务器时,就会发生这种情况。
当客户端未向基于 Web 的应用程序提供密码时,通常会遇到这种情况。这种情况在下面找到的一些帖子中有所描述。对于这种情况,其他帖子中的建议足以防止身份验证绕过。
但是,php.net 上以前的帖子没有描述客户端可能将非零长度的可分辨用户名和密码传递到基于 Web 的应用程序,从而导致匿名授权状态的情况。以下是这种情况的一个示例。

$dn="testuser";
$pass="\x00\x41";
if (empty($dn) or empty($pass)) { exit(); } //检查空字符串
//if (preg_match('/[^a-zA-Z]/',$dn) or preg_match('/[^a-zA-Z0-9\x20!@#$%^&*()]/',$pass)) { exit(); } //检查预期值(白名单)
//if (preg_match('/\x00/',$dn) or preg_match('/\x00/',$pass)) { exit(); } //检查空字节(黑名单)
$ldapconn=ldap_connect("192.0.2.2") or die("无法连接到 LDAP 服务器。");
if ($ldapconn) {
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
$ldapbind=ldap_bind($ldapconn, $dn, $pass);
if ($ldapbind) {
echo("成功");
} else {
echo("失败");
}
}

参考资料
http://security.okstate.edu
[email protected]
17年前
请注意,当服务器期望 LDAP 协议版本 3 时,您必须在调用 ldap_bind 之前指定协议版本。如果不这样做,您将收到警告并无法绑定,例如

ldap_bind(): 无法绑定到服务器:协议错误

为了避免这种情况,请进行此调用

<?php
ldap_set_option
($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
?>

其中 $ds 是 ldap_connect(...) 返回的结果;
[email protected]
15年前
当使用 LDAP 与 SSL 和使用自签名 SSL 证书的 LDAP 服务器时,通常不会建立连接。因此,您必须明确允许此类连接。
对于 Linux(例如 Debian、Ubuntu),您必须将“TLS_REQCERT never”添加到您的 /etc/ldap/ldap.conf 中。在其他发行版中,此配置文件可能位于其他位置。
[email protected]
13 年前
如果您在遵循网络上所有关于使 LDAPS 工作的说明后仍然遇到问题,以下方法对我有用

我试图通过运行以下命令来进行 LDAPS 连接(我们的 LDAP 服务器使用端口 40636)

ldap_connect("www.example.com",40636)

这几天都没用,直到我将其更改为以下格式

ldap_connect("ldaps://www.example.com:40636")

希望它能帮助一些人。

-Cagdas
匿名
19年前
使用 Active Directory 2003(可能还有 2000)时,您无法匿名搜索,因此您必须使用(已知的)用户名和密码绑定。否则,您将收到搜索操作错误。我还确认空密码绑定成功!因此,首先测试空密码!

此处找到一些优秀的信息
http://www.scit.wlv.ac.uk/~jphb/sst/php/extra/ldap.html
http://www.scit.wlv.ac.uk/~jphb/sst/basics/ldap.html
IanB
12年前
如果您使用 SSL(例如 ldaps)并且 ldap_bind 抛出“无法绑定到服务器:”错误,请检查 ldap_connect 中使用的主机名是否与 LDAP 服务器上的 SSL 证书中的“CN”匹配。例如

<?
ldap_connect('ldaps://ldap01');
// 'ldap01' 应该与 LDAP 服务器的 SSL 证书中的 CN 匹配,否则后续的 ldap_bind() 将抛出绑定错误

?>

您可以使用 Openssl 实用程序(Linux)检查 LDAP 服务器的 SSL 证书 - 查看“主题”行

$ openssl x509 -in /etc/pki/tls/certs/ldap01.crt -text -noout
...
主题:C=XY, ST=My State, L=My City, O=My Org, CN=ldap01/[email protected]
...

我最近在我的系统上应用了一些更新(现在是 Centos 5.7 和 PHP 5.3.6),并且开始在我的 PHP 脚本中遇到这个问题,这些脚本以前运行良好,我当时只是使用了服务器的 IP 地址。用主机名替换 IP 地址解决了我的问题。
[email protected]
12年前
我在针对 Active Directory 进行 SSL 上的 ldap_bind 时遇到问题。服务器不断告诉我:“无法绑定到服务器:”。要解决此问题(操作系统:CentOS 6),请确保 /etc/openldap/ldap.conf 包含此行

TLS_REQCERT allow
[email protected]
12年前
需要添加

<?php
ldap_set_option
($ds, LDAP_OPT_PROTOCOL_VERSION, 3)
?>

对于 ldap_bind 返回 true,当您尝试绑定到 openldap(至少版本 2.4.21)时。
RazmanAlias
7年前
我使用 PHP 7.1.*。在此版本中,如果 ldap_bind 无法绑定,它将抛出 RuntimeException。我已经尝试过错误的主机名、正确的主机和错误的密码、正确的主机和无效的 DN 语法。所有失败的条件似乎都抛出 RuntimeException。

因此,此函数可能不会返回 false。
[email protected]
19年前
这可能是一个安全问题,但在使用下面的 ldap 身份验证函数([email protected])进行数小时的调整后,我发现如果输入有效的用户名和 NULL 值,ldap_bind 函数将返回 true!

因此,如果该函数接收类似 $username = 'someuser' 和 $password = '' 的内容,它将返回 true。只要它不是空值,该函数就会按预期工作。最好检查它是否为空或为空。
[email protected]
19年前
完整的 ldap 身份验证脚本

function checkldapuser($username,$password,$ldap_server){
if($connect=@ldap_connect($ldap_server)){ //如果连接到 ldap 服务器

if (ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3)) {
echo "版本 3<br>\n";
} else {
echo "版本 2<br>\n";
}
echo "在'$ldap_server' 上验证:";

//绑定到 ldap 连接
if(($bind=@ldap_bind($connect)) == false){
print "绑定:__失败__<br>\n";
return false;
}

// 搜索用户
if (($res_id = ldap_search( $connect,
"dc=auto,dc=tuwien,dc=ac,dc=at",
"uid=$username")) == false) {
print "失败:LDAP 树搜索失败<br>";
return false;
}

if (ldap_count_entries($connect, $res_id) != 1) {
print "失败:用户名 $username 找到多次<br>\n";
return false;
}

if (( $entry_id = ldap_first_entry($connect, $res_id))== false) {
print "失败:无法获取搜索结果的条目<br>\n";
return false;
}

if (( $user_dn = ldap_get_dn($connect, $entry_id)) == false) {
print "失败:无法获取用户 dn<br>\n";
return false;
}

/* 用户身份验证 */
if (($link_id = ldap_bind($connect, $user_dn, $password)) == false) {
print "失败:用户名、密码不匹配:$user_dn<br>\n";
return false;
}

return true;
@ldap_close($connect);
} else { //没有连接到ldap服务器
echo "没有连接到'$ldap_server'<br>\n";
}

echo "失败:".ldap_error($connect)."<BR>\n";

@ldap_close($connect);
return(false);

}//end function checkldapuser

以下是使用此函数的示例

if (checkldapuser('myuser', 'secretpassword', 'ldap://link.to.ldap')) {
echo "访问已授予\n";
} else {
echo "访问被拒绝\n";
}
[email protected]
13 年前
经过大量的反复试验,我找到了验证 Apple 的 Opendirectory(Snow Leopard 服务器)的方法,并认为分享它可能会有用。

<?php
// 使用ldap绑定
$ldaprdn = 'uid=USERNAME,cn=users,dc=HOSTNAME,dc=DOMAIN,dc=com'; // ldap rdn 或 dn
$ldappass = 'PASSWORD'; // 关联密码

// 连接到ldap服务器
$ldapconn = ldap_connect("HOSTNAME.DOMAIN.com")
or die(
"无法连接到LDAP服务器。");

// 设置一些与...通信的ldap选项
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);

if (
$ldapconn) {

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

// 验证绑定
if ($ldapbind) {
echo
"LDAP绑定成功...\n";
} else {
echo
"LDAP绑定失败...\n";
}

}

?>
[email protected]
18年前
不得不为此做大量的研究,但一旦配置正确,它就能工作。

使用 Apache/2.2.3 (Win32) mod_ssl/2.2.3 OpenSSL/0.9.8b
PHP 版本 5.1.5-dev

ldap_bind 出现错误 "81 无法联系LDAP服务器",这非常烦人,因为在没有 "ldaps" 的情况下连接工作正常。
使用

$ldapconnect = @ldap_connect( $connection_string );

实际上,真正失败的是绑定...

$bind = ldap_bind($ldapconnect, $client, $this->objSecurityLogin->Password);

尝试了很多方法,直到我聪明起来,打开了跟踪级别

ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);

这必须在连接之前执行!

发现在 Windows 上,无法在 ldap.conf 中指定带引号的路径。
我使用了
TLS_REQCERT never
TLS_CACERT "C:\\Documents\\Tools\\Apache2\\conf\\ssl\\ad.pem"
这会抛出错误..
TLS: 无法加载验证位置 (文件:`"C:\Documents\Tools\Apache2\conf\ssl\ad.pem"', 目录:`).
TLS: 错误:0200107B:系统库:fopen:未知错误 .\crypto\bio\bss_file.c:122
TLS: 错误:2006D002:BIO例程:BIO_new_file:系统库 .\crypto\bio\bss_file.c:127
TLS: 错误:0B084002:x509证书例程:X509_load_cert_crl_file:系统库 .\crypto\x509\by_file.c:274
ldap_err2string

更改为
TLS_REQCERT never
TLS_CACERT C:\\Documents\\Tools\\Apache2\\conf\\ssl\\ad.pem
这将其清理为
TLS跟踪: SSL_connect:before/connect 初始化
TLS跟踪: SSL_connect:SSLv2/v3 写入客户端 hello A
TLS跟踪: SSL_connect:SSLv3 读取服务器 hello A
TLS证书验证: 深度: 1, 错误: 0, 主题: /DC=xxx/DC=yyy/CN=zzzz, 发行者: /DC=abab/DC=yyy/CN=zzzz
TLS证书验证: 深度: 0, 错误: 0, 主题: ......

所以故事的寓意是,即使 PHP 在某些 Windows 配置参数中需要引号,如果它在 ldap.conf 中,它也不会工作!
[email protected]
8年前
在 LDAPS 绑定期间(与 Microsoft Windows 2012R2 服务器绑定时),GnuTLS 和 SChannel(Microsoft)实现对于 TLS 1.2 协商(尚)不兼容。

诀窍是在使用 LDAP 函数之前禁用 TLS1.2

putenv(‘LDAPTLS_CIPHER_SUITE=NORMAL:!VERS-TLS1.2’);
[email protected]
10年前
在某些结构中,无法预先知道 dn 或 rdn。但是可以使用 $ldapuser= $samaccountname.'@'.domainname;
[email protected]
20年前
正如 "[email protected]" 正确写道的那样(这一点很重要,应该将其作为警告添加到文档中——尝试使用特定用户名和空密码进行绑定将返回 TRUE。
[email protected]
2年前
通过 SSH 端口转发进行 LDAPS。
在开发/调试过程中,您可能无法直接访问 LDAP 服务器。您可以使用 SSH 端口转发,但需要暂时禁用证书检查。以下是最简单的方法。

//启用调试,以便您可以查看失败的原因。
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL,7);

//禁用 TLS 证书检查(它将在域上不匹配)。或者
//编辑 /etc/ldap/ldap.conf 并设置 "TLS_REQCERT never",或者在您的脚本中
putenv('LDAPTLS_REQCERT=never');

//将您的 ldaps url 指向本地主机。例如
$ldap_url = "ldaps://127.0.0.1:63600";

//执行 SSH 端口转发(在另一个终端中)。例如
ssh -L 63600:your_real_ldap_server:636 your_proxy_server

//并继续正常操作...
ldap_connect($ldap_url);
[email protected]
9个月前
此函数可能导致在 ldap_connect 期间预期发生的错误。

由于 ldap_connect 与其名称相反——根本没有连接到任何服务器,通常 ldap_bind 是第一个实际访问服务器的命令,因此可能会导致此处无法预期的错误。
Christian Stoller
1年前
当使用 LDAP 与 SSL 和使用自签名 SSL 证书的 LDAP 服务器时,连接可能会因错误 "无法联系 LDAP 服务器" 而失败。要使连接工作,请使用选项指向公共证书文件(参见 https://php.net/manual/en/ldap.constants.php)。

或者,您可以禁用证书检查。但请记住,如果连接通过公共网络路由,这是一种安全风险!

这是通过以下方式实现的

<?php
$ds
= ldap_connect('ldaps://myhost:636');
ldap_bind($ds, '{your_ldap_dn}', '{your_ldap_password}')
ldap_set_option($ds, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_ALLOW);
?>
[email protected]
13 年前
此实现缺少 LDAP 控制支持。响应控制可能是 BIND 请求的响应的一部分,必须在代码中进行处理。
[email protected]
19年前
此代码示例演示了如何使用 LDAP for Netware 中的 LDAP 在 PHP 中连接到并绑定到 eDirectory。

<?php

$server
='137.65.138.159';
$admin='cn=admin,o=novell';
$passwd='novell';

$ds=ldap_connect($server); // 假设 LDAP 服务器在此主机上

if ($ds) {
// 使用适当的 dn 绑定以提供更新访问权限
$r=ldap_bind($ds, $admin, $passwd);
if(!
$r) die("ldap_bind 失败<br>");

echo
"ldap_bind 成功";
ldap_close($ds);
} else {
echo
"无法连接到 LDAP 服务器";
}
?>
[email protected]
16 年前
大家好,我只是想让大家意识到,在 slapd 和 Openldap 的 V3 协议版本中实现的错误或任何更改都没有被修复,或者不被认为是错误,或者无论如何……但仍然需要将隐式设置为 V3 才能使用 ldap_bind 函数。我正在使用 Apache 2 和 PHP 5.1 与 LDAP 2。默认设置为拒绝 V2 协议,即使重新配置 slapd 配置文件也无法解决此问题。

您仍然必须使用 ldap_set_option 函数。

示例

<?php
$ldapHost
= "ldap://server";
$ldapPort = "port";
$ldapUser ="cn=name,dc=domain";
$ldapPswd ="password";

$ldapLink =ldap_connect($ldapHost, $ldapPort)
or die(
"无法建立 LDAP 连接");

if (
ldap_set_option($ldapLink,LDAP_OPT_PROTOCOL_VERSION,3))
{
echo
"使用 LDAP v3";
}else{
echo
"无法将版本设置为协议 3";
}

ldap_bind($ldapLink,$ldapUser,$ldapPswd)
or die(
"无法绑定到服务器。");

?>

感谢下面 Ken 的指点。他选择的 link_id 存在轻微的代码错误,仅此而已。上面的代码运行良好,并证明我们仍在处理 2004 年的问题。我希望他们能够更新上面的代码。
[email protected]
19年前
我假设ldap_bind执行的是简单绑定,而对于其他
类型的绑定,应该使用ldap_sasl_bind。

此外,虽然允许绑定v2的解决方案可以与slapd一起使用,但是
如果可能的话,你真的应该使用ldap v3,因为它改进了安全性并
改进了协议定义。LDAP v2在此时已基本弃用。

希望PHP默认的LDAP版本很快就会升级到v3。
phredbroughton at yahoo dot com
19年前
正如之前关于密码所提到的,我发现如果用户名或密码的值为空,或者像我这种情况一样,由于未定义变量导致用户名出现错别字而为空,ldap_bind() 将只执行匿名绑定并返回true!
它不应该检测附加值的存在并返回错误吗?至少如果传递了用户名或密码。如果两者都为空,我不确定它应该做什么。
wkaiser at mpimf-heidelberg dot mpg dot de
20年前
如果你不想以unixadmin或*manager身份绑定(例如,对于web应用程序的身份验证),以下代码可能会有用
<?php

$ldaphost
= "ldap.yourdomain.com";

/*对于SSL安全的ldap_connect()

$ldaphost = "ldap.yourdomain.com"; */

$ldapport = 389;

$ds = ldap_connect($ldaphost, $ldapport)
or die(
"无法连接到 $ldaphost");

if (
$ds) {

$username = "some_user";
$upasswd = "secret";
$binddn = "uid=$username,ou=people,dc=yourdomain,dc=com";

$ldapbind = ldap_bind($ds, $binddn, $upasswd);

if (
$ldapbind) {

print
"恭喜!$some_user已通过身份验证.";}

else {

print
"尝试失败,小子。下次好运!" ;} }

?>
pete dot rowley at example dot com
20年前
你不应该尝试使用虚构的密码进行绑定。即使可能性很小,仍然存在你的代码生成有效密码的可能性。正确的做法是测试密码是否为空,如果你的应用程序只为已认证的用户提供服务,则不应代表用户执行任何其他LDAP操作——这也恰好更高效。
kokheng at jhs dot com dot sg
22年前
OpenLdap 2.1.x 库同时支持 LDAPv2 和 LDAPv3。问题在于 slapd,即 OpenLDAP 附带的 ldap 服务器。它默认支持的版本是 LDAPv3。可以在 slapd.conf 文件中设置“allow bind_v2”,配置完成后,就不需要 PHP ldap_set_option() 了。
elvisciousatrmci.net
22年前
我遇到一个问题,当我尝试绑定时出现协议错误。我可以正常连接,并且命令行可以正常使用 ldap 命令。

问题在于 openldap (v 2.1.5) 以版本 3 ldap 模式启动,而 php (4.2.3) 期望它以版本 2 模式启动。

要解决此问题,请使用 ldap_set_option 命令更改 php 预期的版本。
romerom at cox dot net
18年前
我尝试以“cn=manager,dc=example,dc=com”身份绑定时遇到了问题。我使用了 kenn 发布的示例,他为连接设置了 LDAP_OPT_PROTOCOL_VERSION 为“3”。设置之后,我就可以使用我的管理员 ID 进行绑定了。
dedlfix
18年前
如果发生错误,让脚本die()并没有多大意义,否则在继续执行脚本之前询问是否没有错误,就像官方示例那样。

更好的方法

<?php
ldap_bind
(...) or die(...);
do_something();
?>

或者更好(die() 很快但很粗糙)

<?php
if (!ldap_bind(...)) {
error();
} else {
do_something();
}
?>
kenn at pcintelligent dot com
20年前
我想指出,读取的行

"$ldaprdn = 'uname';"

有点令人困惑。你需要确保使用整个rootdn。例如,你的代码应该更像这样……

<?php

// 使用ldap绑定 *** 注意uname *****
$ldaprdn = 'cn=root,dc=testserver,dc=com'; // ldap rdn 或 dn
$ldappass = 'secret'; // 关联密码

// 连接到ldap服务器
$ldapconn = ldap_connect("ldap.testserver.com")
or die(
"无法连接到LDAP服务器.");

if (
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) {
echo
"使用LDAPv3";
} else {
echo
"设置协议版本为3失败";
}

if (
$ldapconn) {

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

// 验证绑定
if ($ldapbind) {
echo
"LDAP绑定成功...";
} else {
echo
"LDAP绑定失败...";
}

}

?>
get_your_gun at hotmail dot com
19年前


我整天都在尝试这个,最后注意到当你使用绑定和身份验证时。用户名需要如下所示才能工作。我使用的是 PHP V 4.03,所以现在可能有所不同,但这是我使用的内容,并且身份验证成功。

<?php
$ldaphost
= "ldap.what.at.greatnet.com";
$ldapport = 389;

$ds = ldap_connect($ldaphost, $ldapport)
or die(
"无法连接到 $ldaphost");

if (
$ds)
{
$username = "[email protected]";
$upasswd = "pass";

$ldapbind = ldap_bind($ds, $username, $upasswd);

if (
$ldapbind)
{print
"恭喜!$username已通过身份验证.";}
else
{print
"尝试失败,小子。下次好运!" ;}
}

?>
Victor
5年前
(更正)
如果密码过期或需要重置,ldap_bind 将返回 TRUE,如果 ldap_bind 返回 FALSE,请使用 ldap_get_option

<?php

define
("EXPIRED_PASSWORD", 532);
define("PASSWORD_RESET", 773);

$handle = ldap_connect('ldap://active.directory.server/');
$bind = ldap_bind($handle, 'user', 'expiredpass');

if (!
$bind) {
if (
ldap_get_option($handle, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error)) {
$errno = explode(',', $extended_error)[2];
$errno = explode(' ', $errno)[2];
$errno = intval($errno);

if (
$errno === EXPIRED_PASSWORD) {
$err = '登录失败:密码已过期';
} else if (
$errno === PASSWORD_RESET) {
$err = '登录失败:需要重置密码';
} else {
$err = $extended_error;
}
if (
$errno === EXPIRED_PASSWORD || $errno === PASSWORD_RESET) {
#更改密码
}
}
}
?>
juan[dot]pineda[at]resultstel.com
15年前
活动目录不再接受匿名请求。

在 Windows Server 2003 中,只有经过身份验证的用户才能启动针对基于 Windows Server 2003 的域控制器的 LDAP 请求。您可以通过更改以下 DN 路径上 dsHeuristics 属性的第七个字符来覆盖此新的默认行为:
CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,Root domain in forest

来自:http://support.microsoft.com/kb/326690
Josh A.
17年前
如果意外地留空密码字段,OpenLDAP 库在尝试重新绑定到非匿名帐户时将返回错误 53(服务器不愿执行)。如果要对不同于 dn 的字段进行身份验证,则必须两次绑定到服务器。您的代码可能如下所示:

<?
function ldapLogin($uname, $pass, $base_dn, $fname, $server, $port){
$ldc=@ldap_connect($server, $port);
if (!$ldc) return ERROR_CODE;

$bn='cn=anonymous-user,'.$base_dn;
$pw='anonymous-pass';
$lbind=@ldap_bind($ldc, $bn, $pw);
if (!$lbind) return ERROR_CODE;


$ureturn=@ldap_search($ldc, $base_dn, "($fname=$uname)", array('dn', 'givenName', 'sn', 'mail'));


$uent=@ldap_first_entry($ldc, $ureturn);
if (!$uent) return ERROR_CODE;

$bn=@ldap_get_dn($ldc, $uent);

//此行应使用 $pass 而不是 $password
$lbind=@ldap_bind($ldc, $bn, $password);
//现在您可以找到错误
echo ldap_error($ltc);

if ($lbind) return true; else return false;
?>

希望这对遇到相同错误的其他人有所帮助。
Teemu
17年前
连接和搜索 AD 的示例

$con = ldap_connect('ad.domain.com');
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($con, LDAP_OPT_REFERRALS, 0);
ldap_bind($con, '[email protected]', 'clear password');

ldap_search($con, 'DC=domain,DC=com', '(uniqueMember=user)');
[nie ten]archie
14年前
我在 Linux 上使用 OpenLDAP,并以艰难的方式找到了正确的绑定顺序……所以我要与您分享。

(如果一切正常,wkaiser 的解决方案是可以的,但对于开发,我建议使用 ldap_error 命令,如下所示)

<?php
$ldapconfig
['host'] = '10.10.10.10';
$ldapconfig['port'] = NULL;
$ldapconfig['basedn'] = 'dc=company,dc=com';

$ds=ldap_connect($ldapconfig['host'], $ldapconfig['port']);

$dn="uid=".$username.",ou=people,".$ldapconfig['basedn'];

if (
$bind=ldap_bind($ds, $dn, $password)) {
echo(
"登录成功");
} else {

echo(
"无法绑定到服务器</br>");

echo(
"消息:'".ldap_error($ds)."'</br>");#检查消息是否为:无法联系 LDAP 服务器 :)
#如果它说的是关于 cn 或用户的信息,那么您正在尝试使用错误的 $dn 模式,我通过查看 OpenLDAP 源代码找到了这一点 :)
#我们可以通过搜索用户树来确定正确的模式
#记住在 ldap 服务器上打开匿名搜索
if ($bind=ldap_bind($ds)) {

$filter = "(cn=*)";

if (!(
$search=@ldap_search($ds, $ldapconfig['basedn'], $filter))) {
echo(
"无法搜索 ldap 服务器<br>");
echo(
"消息:'".ldap_error($ds)."'</br>");#再次检查消息
} else {
$number_returned = ldap_count_entries($ds,$search);
$info = ldap_get_entries($ds, $search);
echo
"返回的条目数为 ". $number_returned."<p>";
for (
$i=0; $i<$info["count"]; $i++) {

var_dump($info[$i]);#在此一堆垃圾中查找您的用户帐户,并应用构建 $dn 的整个模式以完全匹配 ldap 树条目
}
}
} else {
echo(
"无法匿名绑定<br>");
echo(
"消息:".ldap_error($ds)."<br>");
}
}
?>

如您所见,大多数示例使用“cn=username”,而 OpenLDAP 使用“uid=username”,但谁知道将来版本中会使用什么,这段代码将帮助您检查它(我希望 :)
To Top