ldap_set_rebind_proc

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

ldap_set_rebind_proc设置一个回调函数来在转发跟踪时进行重新绑定

描述

ldap_set_rebind_proc(LDAP\Connection $ldap, ?callable $callback): bool
警告

此函数目前没有文档;只有它的参数列表可用。

变更日志

版本 描述
8.1.0 ldap 参数现在期望一个 LDAP\Connection 实例;以前,期望一个有效的 ldap link 资源
8.0.0 callback 现在可以为 null。
添加注释

用户贡献的注释 7 个注释

mvanbeek at forgetaboutit dot net
11 年前
在回调函数中使用的 $referral 不是绑定 dn,而是正在访问的记录的 dn(或者更确切地说,是它在主服务器上的位置,如果两者有区别的话),所以你需要用你现有的凭据重新绑定。连接 ($ldap) 似乎已经连接到新服务器,所以它只是一个重新绑定过程,没有比这更复杂的事情。底层库中一定有一个循环,它会重新提交导致转发的请求,直到返回成功或失败。

我想如果你最初使用的绑定 dn 无法让你在主服务器上编辑记录,那么那就是一个 ldap 问题而不是 php 问题。但是,至少通过重新绑定过程,你可以先修改绑定 dn。

所以,重新绑定过程实际上非常简单,现在我理解它是如何工作的!我以为它会复杂得多。以最简单的方式,这是你所需要的,假设你的绑定 $dn 和 $pass 是全局的

<?php
function rebind($ldap, $referral) {
// 设置 ldap 选项
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, True);
ldap_set_rebind_proc($ldap, 'rebind');
// 重新绑定
if (!ldap_bind($ldap, $dn, $pass)) {
echo
'无法绑定到转发服务器';
return
1; // 是的,1 表示失败。
}
return
0; // 是的,成功时返回 0。
}
?>
leon at leonux dot co dot za
13 年前
我终于使用 ldap_set_rebind_proc 函数让转发工作了。不要在你的回调函数中连接到转发服务器。这将为你完成。你只需要绑定。回调函数必须在绑定成功时返回 0,失败时返回 1。

考虑一个主 - 从 LDAP 设置,其中从服务器是只读的,并将写入转发到主服务器。对于从服务器上的 PHP,你需要类似以下内容

<?php

// 回调函数
function rebind($ldap, $referral) {
// ldap 选项
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, True);
ldap_set_rebind_proc($ldap, 'rebind');
// 转发形式如下:
// ldaps://newhost/cn=user,ou=people,dc=example,dc=com
$refparts = explode('/', $referral);
if (
count($refparts) > 2) {
// 从转发中获取绑定 dn
$dn = $refparts[3];
// 绑定到新主机
if (!ldap_bind($ldap, $dn, $pass)) {
echo
'无法绑定到转发服务器';
return
1;
}
} else {
// 尝试匿名绑定
if (!ldap_bind($ldap)) {
echo
'无法匿名绑定到转发服务器';
return
1;
}
}
return
0;
}

// 初始化与从服务器的 ldap 连接
$ldap_host = 'localhost'
$ds = ldap_connect($ldap_host);
// ldap 选项
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)
ldap_set_option($ds, LDAP_OPT_REFERRALS, True)
// 设置回调函数
ldap_set_rebind_proc($ds, 'rebind'))
// 绑定
ldap_bind($ds, $dn, $pass)
// ldap 写入
ldap_modify($ds, $dn, $attr);

?>

如果你使用类方法作为回调函数,从你的回调函数中访问密码和其他数据会更容易。回调函数将像这样初始化

<?php

ldap_set_rebind_proc
($ldap, 'MyClass::rebind');

?>
mvanbeek at forgetaboutit dot net
14 年前
我一直在寻找有关跟踪转发的良好信息,但一直很困难,所以我在此添加我的意见。我的测试代码还没有完全运行,所以请查看页面下方以获取更新。

这种方法似乎必须这样工作:你使用此函数来设置你自己的回调函数,以连接并绑定到转发服务器。你需要设置它,并强制使用 v3 ldap 并将转发跟踪设置为开启作为初始连接设置的一部分,所以在连接之后但在绑定之前,你需要类似以下内容

<?php
$ds
= ldap_connect($server);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 1);
ldap_set_rebind_proc($ds, "rebind");
ldap_bind($ds,$dn,$pass);
?>

这个回调函数(在上面的例子中称为 rebind)需要两个参数。这些参数是预设的,并在调用回调函数时提供。第一个是 ldap 链接标识符。我假设这是提供的,因为该函数可以被连续的多个引用连续使用。第二个是初始服务器提供的 ldap 引用 URL。我看到一些注释说这个函数必须在被 ldap_set_rebind_proc 设置之前定义,但我还没有确认这一点。

我的设置基于主从 LDAP 服务器配置,PHP 应用程序驻留在从服务器上,它在那里进行本地主机查找。当您尝试写入从 LDAP 服务器时,服务器返回一个引用 URL,然后内部 PHP 函数调用回调函数。

尽管此页面上已经存在代码,它似乎也被用来测试 PHP 代码,但我认为它是错误的。我认为它只是重新连接到初始服务器。我认为回调函数应该做的是连接到新服务器,并绑定到它。我的测试代码目前看起来像这样

<?php
function rebind($ldap, $referral) {
global
$dn;
global
$pass;
$server= preg_replace('!^(ldap://[^/]+)/.*$!', '\\1', $referral);
if (!(
$ldap = ldap_connect($server))){
echo
"reconnect failed - <br>";
return
1;
}
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 1);
ldap_set_rebind_proc($ldap, "rebind");
if (!
ldap_bind($ldap,$dn,$pass)){
echo
"rebind failed - <br>";
return
1;
}
return
0;
}
?>

据我所知,返回值 0 表示成功,任何其他值表示失败。完全缺乏文档并没有帮助。

上面的代码一直工作到对新服务器进行身份验证,但在目前,在我尝试将记录写入新服务器之前,我似乎收到了一个解绑请求,因此它失败了。

我还建议在绑定之前添加一个 ldap_start_tls。
pearcec at commnav dot com
21 年前
PHP 期望 ldap 函数 ldap_set_rebind_proc 是具有三个参数的函数。据我所知,这在 OpenLDAP 的 2.0 版本中不存在。但在 2.1 中做到了。配置会告诉你

检查 3 参数 ldap_set_rebind_proc... 不存在
night0wl at frost dot ath dot cx
21 年前
当然,这个函数没有示例代码,我花了很长时间才让它正常工作。

所以,这里有一个工作示例

function rebind_on_ref ($ds, $ldap_url) {
global $binddn; // 用于绑定的 DN
global $bindpw; // 用于绑定的密码

// 大多数现代 LDAP 服务器都需要,使用 LDAPv3
ldap_set_option($a, LDAP_OPT_PROTOCOL_VERSION, 3);

if (!ldap_bind($a,$binddn,$bindpw)) {
print "无法绑定";
}
}
randy at kotmail dot com
22 年前
如果 rebind_proc 没有编译到 slapd 中,你永远无法让它工作。查看 slapd 的新 alpha 版本并阅读手册。
匿名
13 年前
我已经花了足够的时间来查看这个问题了,我可以说,ldap 引用,至少在尝试添加、修改或删除从服务器上的记录时,该从服务器会正确地将引用传递给主服务器,在 php 中不起作用。我的建议是关闭 ldap 引用,并使用内置引用处理编写你自己的添加、修改和删除函数。类似于这样

<?php
function ldap_referral_add($connection,$add_dn,$Add_entry,$bind_dn,$bind_pw)
{
$rconnection = $connection;
$loop = 10; # 最大引用跳转次数。
# 关闭正常引用
ldap_get_option($connection,LDAP_OPT_REFERRALS,$old_referral_setting)
do
{
$response = ldap_add($rconnection,$dn,$entry);
# 我们收到一个成功消息:
if ( $response )
{
ldap_unbind($rconnection);
$loop = 0; # 可能不需要
ldap_set_option($connection,LDAP_OPT_REFERRALS,$old_referral_setting);
return
true;
}
# 我们收到一个引用消息:
elseif ( !$response && ldap_errno($rconnection) == 0x0a )
{
$new_server_url = $server= preg_replace('!^(ldap://[^/]+)/.*$!', '\\1', $ldap_error($rconnection)); # 可能需要在这里进行一些健全性检查
$rconnection = ldap_connect($new_server_url);
ldap_set_option($rconnection,LDAP_OPT_REFERRALS,0)
ldap_set_option($rconnection,LDAP_OPT_PROTOCOL_VERSION, 3)
ldap_bind($rconnection,$bind_dn,$bind_pw);
$loop = $loop - 1;
}
else
{
ldap_unbind($rconnection);
$loop = 0; # 可能不需要
ldap_set_option($connection,LDAP_OPT_REFERRALS,$old_referral_setting);
return
false;
}
} while (
$loop > 0);
}
?>
To Top