PHP Conference Japan 2024

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 連線 資源

範例

範例 #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: 無效憑證" 綁定到 Active Directory,您可以使用選項 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_bind 在 ldaps 連線上運作,直到我按照一些關於建立 ldap.conf 檔案的說明進行操作。我在 php 網站上沒有看到這些說明。也許它們在 OpenLDAP 網站上,但我認為在這裡也有它們會很有用。功勞歸於一位名為 'LRM' 的人,我在此處找到了我的解決方案:http://lists.horde.org/archives/sork/Week-of-Mon-20040503/001578.html

我的設定是 Windows 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 Control Version 2.5 from www.nat32.com
+ XAMPP Security 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
+ 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, 'user@sub.domain.com', '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
15 年前
當搭配 SSL 使用 LDAP 時,且 LDAP 伺服器使用自我簽署的 SSL 憑證時,通常不會建立連線。因此,您必須明確允許此類連線。
使用 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
匿名
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
...
Subject: C=XY, ST=我的州, L=我的城市, O=我的組織, CN=ldap01/emailAddress=me@domain.com
...

我最近對我的系統套用了一些更新(現在是 Centos 5.7 和 PHP 5.3.6),並且開始在先前運作正常的 PHP 腳本中遇到此問題,而我先前只是使用伺服器的 IP 位址。將 IP 位址替換為主機名稱修正了我的問題。
peter dot schlaf at web dot de
12 年前
我在透過 SSL 對 Active Directory 執行 ldap_bind 時遇到問題。伺服器一直告訴我:「無法綁定到伺服器:」。為了修正這個問題(作業系統:CentOS 6),請確保 /etc/openldap/ldap.conf 具有此行

TLS_REQCERT allow
deniskutin at gmail dot com
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。
darkstar_ae at hotmail dot com
19 年前
這可能是一個安全性問題,但在使用以下 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 "版本 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);

}//結束函式 checkldapuser

這是使用此函式的範例

if (checkldapuser('myuser', 'secretpassword', 'ldap://link.to.ldap')) {
echo "已授權存取\n";
} else {
echo "存取遭拒\n";
}
marnijt at LIKEHAM dot gmail dot com
13 年前
經過多次試驗後,我找到了驗證 Apple 的 Opendirectory(雪豹伺服器)的方法,並認為分享出來可能會有所幫助。

<?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";
}

}

?>
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 Can't contact LDAP server" 錯誤,這真的很惱人,因為在沒有 "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: could not load verify locations (file:`"C:\Documents\Tools\Apache2\conf\ssl\ad.pem"',dir:`').
TLS: error:0200107B:system library:fopen:Unknown error .\crypto\bio\bss_file.c:122
TLS: error:2006D002:BIO routines:BIO_new_file:system lib .\crypto\bio\bss_file.c:127
TLS: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib .\crypto\x509\by_file.c:274
ldap_err2string

改為
TLS_REQCERT never
TLS_CACERT C:\\Documents\\Tools\\Apache2\\conf\\ssl\\ad.pem
這樣就清理乾淨了
TLS trace: SSL_connect:before/connect initialization
TLS trace: SSL_connect:SSLv2/v3 write client hello A
TLS trace: SSL_connect:SSLv3 read server hello A
TLS certificate verification: depth: 1, err: 0, subject: /DC=xxx/DC=yyy/CN=zzzz, issuer: /DC=abab/DC=yyy/CN=zzzz
TLS certificate verification: depth: 0, err: 0, subject: ......

所以這個故事的寓意是,即使 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;
jakob at grimstveit dot no
20 年前
正如 "john dot lewis at waldenweb dot com" 正確寫的 (這點很重要,應該作為警告納入文件中 - 嘗試使用特定使用者名稱和空密碼綁定將返回 TRUE)。
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 指向 localhost。例如。
$ldap_url = "ldaps://127.0.0.1:63600";

//執行 SSH 通道轉發 (在另一個終端機中)。例如。
ssh -L 63600:your_real_ldap_server:636 your_proxy_server

//並像平常一樣繼續...
ldap_connect($ldap_url);
andreas at heigl dot org
9 個月前
此函數可能會導致預期在 ldap_connect 期間發生的錯誤。

由於 ldap_connect 與其名稱相反 - 根本沒有連接到任何伺服器,通常 ldap_bind 是第一個實際連線伺服器的命令,因此可能會導致在此處不預期發生的問題。
Christian Stoller
1 年前
當使用帶有 SSL 的 LDAP 和使用自我簽署 SSL 憑證的 LDAP 伺服器時,連線可能會失敗,並出現「無法連線到 LDAP 伺服器」錯誤。 若要使連線運作,請使用選項指向公用憑證檔案(請參閱 https://php.dev.org.tw/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);
?>
bydand1959 at yahoo dot com
13 年前
此實作缺少 LDAP 控制項支援。 回應控制項可能是對 BIND 請求的回應的一部分,並且必須在程式碼中處理。
baroque at citromail dot hu
19 年前
此程式碼範例顯示如何使用 LDAP for 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 失敗<br>");

echo
"ldap_bind 成功";
ldap_close($ds);
} else {
echo
"無法連接到 LDAP 伺服器";
}
?>
Devia dot Fan at gmail dot com
16 年前
大家好,我只是想讓大家知道,使用 slapd 和 Openldap 的 V3 版本協定所實作的錯誤或任何變更,不是尚未修復,就是不認為是錯誤或其他什麼... 但仍然需要針對 ldap_bind 函數的使用進行隱式設定為 V3。 我使用 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 年的問題。我希望他們能在上面的程式碼中更新這個。
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
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 = "johndoe@what.at.greatnet.com";
$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 年前
Active Directory 不再接受匿名請求。

在 Windows Server 2003 中,只有通過身份驗證的使用者才能對基於 Windows Server 2003 的網域控制站發起 LDAP 請求。您可以通過更改 DN 路徑上的 dsHeuristics 屬性的第七個字元來覆蓋這個新的預設行為,如下所示:
CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,森林中的根網域

來源: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, 'user@DOMAIN.COM', '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(
"msg:'".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(
"msg:'".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(
"msg:".ldap_error($ds)."<br>");
}
}
?>

正如您所見,大多數範例都使用「cn=username」,而 OpenLDAP 使用「uid=username」,但誰知道未來版本會使用什麼,此程式碼將協助您檢查出來(我希望:)
To Top