PHP Conference Japan 2024

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 個註解

3
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。
}
?>
1
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');

?>
0
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
"重新連線失敗 - <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
"重新綁定失敗 - <br>";
return
1;
}
return
0;
}
?>

據我所知,返回值 0 表示成功,任何其他值表示失敗。缺乏完整的說明文件對此沒有幫助。

上述程式碼一路運作到對新伺服器進行身份驗證,但目前我似乎在嘗試將記錄寫入新伺服器之前收到取消綁定的請求,因此失敗了。

我也建議在綁定之前加入 ldap_start_tls。
0
pearcec at commnav dot com
21 年前
PHP 期望 ldap 函式 ldap_set_rebind_proc 具有三個參數。據我所知,這不在 OpenLDAP 的 2.0 版本中。但它進入了 2.1 版本。設定會告訴你:

checking for 3 arg ldap_set_rebind_proc... no
0
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 "無法綁定";
}
}
0
randy at kotmail dot com
22 年前
如果 rebind_proc 沒有編譯到 slapd 中,您的函式永遠無法運作。請查看 slapd 的新 alpha 版本和 rtfm。
-1
Anonymous
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