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 匿名绑定失败...";
}

}

?>

参见

添加注释

用户贡献的注释 40 条注释

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

如果你无法使用错误“49:无效凭据”绑定到活动目录,你可以使用选项从 ldap_get_option 函数获取扩展错误输出:LDAP_OPT_DIAGNOSTIC_MESSAGE。 不幸的是,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
15 年前
我无法在 ldaps 连接上使 ldap_bind 工作,直到我遵循了一些关于创建 ldap.conf 文件的说明。 我没有在 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”)
+ XAMPP 控制版本 2.5 来自 www.nat32.com
+ XAMPP 安全 1.0
+ SQLite 2.8.15
+ OpenSSL 0.9.8e
+ phpMyAdmin 2.10.3
+ ADOdb 4.95
+ Mercury 邮件传输系统 v4.01b
+ FileZilla FTP 服务器 0.9.23
+ Webalizer 2.01-10
+ Zend Optimizer 3.3.0
+ eAccelerator 0.9.5.1 for PHP 5.2.3(在 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 真的很烦人。
alex dot everett at okstate dot edu
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
john dot hargrove at sellingsource dot com
17 年前
请注意,当服务器期望 LDAP 协议版本 3 时,您必须在调用 ldap_bind 之前指定协议版本。如果您没有这样做,您将收到警告并无法绑定,例如

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

为了避免这种情况,请执行以下调用

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

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

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

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

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

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

希望这对其他人有所帮助。

-Cagdas
Anonymous
18 年前
当使用 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 地址替换为主机名解决了我的问题。
peter dot schlaf at web dot de
12 年前
我在针对 Active Directory 的 SSL 上执行 ldap_bind 时遇到了问题。服务器一直告诉我:“无法绑定到服务器:”。要解决此问题(操作系统:CentOS 6),请确保 /etc/openldap/ldap.conf 包含此行

TLS_REQCERT allow
marnijt at LIKEHAM dot gmail dot com
12 年前
经过多次尝试和错误,我找到了验证 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";
}

}

?>
RazmanAlias
7 年前
我使用 PHP 7.1.*。在此版本中,如果 ldap_bind 无法绑定,它将抛出 RuntimeException。我已经尝试了错误的主机名、正确的主机名和错误的密码、正确的主机名和无效的 DN 语法。所有失败条件似乎都抛出 RuntimeException。

因此,此函数可能不会返回 false。
david dot marsh at hartfordlife dot com
18 年前
我不得不对此进行大量研究,但它确实有效,只要配置正确。

使用 Apache/2.2.3 (Win32) mod_ssl/2.2.3 OpenSSL/0.9.8b
PHP 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:连接初始化之前/连接
TLS 跟踪:SSL_connect:SSLv2/v3 写入客户端问候 A
TLS 跟踪:SSL_connect:SSLv3 读取服务器问候 A
TLS 证书验证:深度:1,错误:0,主题:/DC=xxx/DC=yyy/CN=zzzz,颁发者:/DC=abab/DC=yyy/CN=zzzz
TLS 证书验证:深度:0,错误:0,主题:......

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

技巧是在使用 LDAP 函数之前禁用 TLS1.2

putenv(‘LDAPTLS_CIPHER_SUITE=NORMAL:!VERS-TLS1.2’);
john dot doe at somewhere dot org
10 年前
在某些结构中,无法预先知道 dn 或 rdn。但是,可以使用 $ldapuser= $samaccountname.'@'.domainname;
php at richardneill dot org
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://localhost:63600";

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

// 然后继续正常操作...
ldap_connect($ldap_url);
jakob at grimstveit dot no
19 年前
正如 "john dot lewis at waldenweb dot com" 正确写道(这一点很重要,应该在文档中作为警告包含进来 - 尝试用特定用户名和空密码绑定将返回 TRUE。
andreas at heigl dot org
5 个月前
此函数可能会导致在 ldap_connect 期间预计会发生的错误。

由于 ldap_connect 与其名称相反,根本没有连接到任何服务器,因此通常 ldap_bind 是第一个实际命中服务器的命令,因此可能会导致人们不希望在这里发生的错误。
Christian Stoller
10 个月前
当使用 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);
?>
deniskutin at gmail dot com
12 年前
需要添加

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

以便 ldap_bind 返回 true,而您尝试为 openldap 绑定(至少版本 2.4.21)
bydand1959 at yahoo dot com
13 年前
此实现缺少 LDAP 控制支持。响应控制可能是 BIND 请求的响应的一部分,必须在代码中处理。
baroque at citromail dot hu
18 年前
此代码示例演示了如何使用 LDAP 为 Netware 通过 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 failed<br>");

echo
"ldap_bind success";
ldap_close($ds);
} else {
echo
"Unable to connect to LDAP server";
}
?>
Devia dot Fan at gmail dot com
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(
"Can't establish LDAP connection");

if (
ldap_set_option($ldapLink,LDAP_OPT_PROTOCOL_VERSION,3))
{
echo
"Using LDAP v3";
}else{
echo
"Failed to set version to protocol 3";
}

ldap_bind($ldapLink,$ldapUser,$ldapPswd)
or die(
"Can't bind to server.");

?>

感谢下面的 Ken 指明了方向。他在链接 ID 中选择的内容存在一个轻微的代码错误,但这只是全部。上面的代码运行良好,并且表明我们仍在处理 2004 年的问题。我希望他们在上面的代码中更新此问题。
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)');
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();
}
?>
darkstar_ae at hotmail dot com
18 年前
这可能是一个安全问题,但在对下面的 ldap 身份验证函数(edi01 at gmx dot at)进行数小时的调整后,我发现,如果您输入有效的用户名和 NULL 值,ldap_bind 函数将返回 true!

因此,如果该函数接收类似于 $username = 'someuser' 和 $password = '' 的内容,它将返回 true。只要它不是 NULL 值,该函数将按预期工作。最好检查它是否为 NULL 或为空。
edi01 at gmx dot at
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 "version 3<br>\n";
} else {
echo "version 2<br>\n";
}
echo "verification on '$ldap_server': ";

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

// 搜索用户
if (($res_id = ldap_search( $connect,
"dc=auto,dc=tuwien,dc=ac,dc=at",
"uid=$username")) == false) {
print "failure: search in LDAP-tree failed<br>";
return false;
}

if (ldap_count_entries($connect, $res_id) != 1) {
print "failure: username $username found more than once<br>\n";
return false;
}

if (( $entry_id = ldap_first_entry($connect, $res_id))== false) {
print "failur: entry of searchresult couln't be fetched<br>\n";
return false;
}

if (( $user_dn = ldap_get_dn($connect, $entry_id)) == false) {
print "failure: user-dn coulnd't be fetched<br>\n";
return false;
}

/* 用户身份验证 */
if (($link_id = ldap_bind($connect, $user_dn, $password)) == false) {
print "failure: username, password didn't match: $user_dn<br>\n";
return false;
}

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

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

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

}//end function checkldapuser

以下是使用此函数的示例

if (checkldapuser('myuser', 'secretpassword', 'ldap://link.to.ldap')) {
echo "ACCESS GRANTED\n";
} else {
echo "ACCESS DENIED\n";
}
owen at delong dot com
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
19 年前
如果您不想以 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
21 年前
OpenLdap 2.1.x 库支持 LDAPv2 和 LDAPv3。问题在于 slapd,OpenLDAP 附带的 ldap 服务器。它的默认支持版本是 LDAPv3。可以在 slapd.conf 文件中设置“allow bind_v2”,配置完成后,不需要 PHP ldap_set_option()。
elvisciousatrmci.net
21 年前
我遇到一个问题,当我尝试绑定时出现协议错误。我能够正常连接,并且 ldap 命令可以在命令行上正常工作。

问题原来是 openldap(v 2.1.5)在版本 3 ldap 模式下启动,而 php(4.2.3)预期它在版本 2 模式下。

要解决此问题,请使用 ldap_set_option 命令更改 php 预期的版本。
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
18 年前


我整天都在尝试这个,最后注意到,当您使用 bind 和身份验证时。用户名需要如下所示才能正常工作。我使用的是 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
4 年前
(更正)
如果密码已过期或需要重置,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 年前
Active Directory 不再接受匿名请求。

使用 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;
?>

希望这对遇到相同错误的其他人有所帮助。
[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”,但谁知道未来的版本会使用什么,这段代码将帮助您检查(希望如此)。
nelson777 at gmail dot com
6 年前
我尝试了 user_o at hbt dot com 关于超时问题的解决方案,但无法使其正常工作。最初我尝试了以下方法:

$this->conn = @ldap_connect($ip, $port);
ldap_set_option($this->conn, LDAP_OPT_NETWORK_TIMEOUT, 10);
ldap_set_option($this->conn, LDAP_OPT_TIMELIMIT, 10);
@ldap_bind($this->conn, $ldapUser, $ldapPwd);

但如果服务器没有响应,请求就会卡在这个点。
然后使用代码完成,我发现有一个隐藏的 LDAP 选项:LDAP_OPT_TIMEOUT

因此将代码更改为

$this->conn = @ldap_connect($ip, $port);
ldap_set_option($this->conn, LDAP_OPT_NETWORK_TIMEOUT, 10);
ldap_set_option($this->conn, LDAP_OPT_TIMELIMIT, 10);
ldap_set_option($this->conn, LDAP_OPT_TIMEOUT, 10);
@ldap_bind($this->conn, $ldapUser, $ldapPwd);

最后使 LDAP 绑定超时正确地工作。
To Top