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_connect() が返す LDAP\Connection クラスのインスタンス。
dn
-
password
-
password
を省略または空にした場合は匿名バインドを試みます。
匿名バインドのため、dn
も空のままにできます。
これは、https://tools.ietf.org/html/rfc2251#section-4.2.2 で定義されています。
変更履歴
バージョン | 説明 |
---|---|
8.1.0 |
引数 ldap は、LDAP\Connection
クラスのインスタンスを期待するようになりました。
これより前のバージョンでは、有効な ldap link リソース を期待していました。
|
例
例1 LDAP バインドの使用
<?php
// ldap バインドを使用する
$ldaprdn = 'uname'; // ldap rdn あるいは dn
$ldappass = 'password'; // パスワード
// ldap サーバーに接続する
$ldapconn = ldap_connect("ldap.example.com")
or die("Could not connect to LDAP server.");
if ($ldapconn) {
// ldap サーバーにバインドする
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
// バインド結果を検証する
if ($ldapbind) {
echo "LDAP bind successful...";
} else {
echo "LDAP bind failed...";
}
}
?>
例2 LDAP 匿名バインドの使用
<?php
// ldap 匿名バインドを使用する
// ldap サーバーに接続する
$ldapconn = ldap_connect("ldap.example.com")
or die("Could not connect to LDAP server.");
if ($ldapconn) {
// 匿名でバインドする
$ldapbind = ldap_bind($ldapconn);
if ($ldapbind) {
echo "LDAP bind anonymous successful...";
} else {
echo "LDAP bind anonymous failed...";
}
}
?>
+add a note
User Contributed Notes 39 notes
gtkspert_SPAMMENOT_ at gmail dot com ¶
13 years ago
Interesting point,
if you can't bind to active directory with the error "49: Invalid Credentials", you can get the extended error output from the ldap_get_option function, using the option: LDAP_OPT_DIAGNOSTIC_MESSAGE. Unfortunately php hasn't defined this by default, but it's value is 0x0032.
This is useful if a user must change their password at first login (Data: 773), or if their account has expired on the network (Data: 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 "Error Binding to LDAP: $extended_error";
} else {
echo "Error Binding to LDAP: No additional information is available.";
}
}
?>
Or something to that effect..
It took me a while to work this one out, so i figured i'd share my results..
james at NOSPAM dot revillini dot com ¶
16 years ago
I couldn't get ldap_bind to work on an ldaps connection until I followed some instructions about creating an ldap.conf file. I don't see these instructions anywhere on the php site. Maybe they're on the OpenLDAP site, but I thought it would be useful to have here as well. Credit goes to a dude known as 'LRM', and I found my solution here: http://lists.horde.org/archives/sork/Week-of-Mon-20040503/001578.html
My setup is XAMPP on Win XP.
###### ApacheFriends XAMPP (basic package) version 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 (please use the "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 (comment out in the php.ini)
1. create C:\OpenLDAP\sysconf\ldap.conf (Yes, it MUST be this path because it's hard-coded in the dll)
2. put this line at the top:
TLS_REQCERT never
3. Save, stop/start apache.
The reason is, I think, because it doesn't understand the certificate, so this directive tells it to not bother checking it. I guess that could be unsafe in some cases, but in my case I'm confident with the server I'm connecting to.
My connection code was as follows (nothing new here, I don't think):
<?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'));
?>
Good luck! LDAPS can be a real bitch.
alex dot everett at okstate dot edu ¶
17 years ago
A number of examples and implementations of authentication schemes which use LDAP simple binds to authenticate users fail to properly sanitize user-submitted data. This can allow for an anonymous user to authenticate to a web-based application as an existing user. Provided below is a brief description and example of how this vulnerability can arise. For more detailed information please visit the links at the bottom of this posting.
The bind operation of LDAP, as described in RFC 4513, provides a method which allows for authentication of users. For the Simple Authentication Method a user may use the anonymous authentication mechanism, the unauthenticated authentication mechanism, or the name/password authentication mechanism. The unauthenticated authentication mechanism is used when a client who desires to establish an anonymous authorization state passes a non-zero length distinguished name and a zero length password. Most LDAP servers either can be configured to allow this mechanism or allow it by default. Web-based applications which perform the simple bind operation with the client's credentials are at risk when an anonymous authorization state is established. This can occur when the web-based application passes a distinguished name and a zero length password to the LDAP server.
This is commonly encountered when no password is provided from the client to the web-based application. This situation is described in some of the postings found below. For this situation, the recommendations found in other postings is sufficient to prevent authentication bypass.
However, no prior postings at php.net describe a situation in which a client may pass a distinguished username and a password of non-zero length to the web-based application which results in an anonymous authorization state. Below is an example of this situation.
$dn="testuser";
$pass="\x00\x41";
if (empty($dn) or empty($pass)) { exit(); } //check for empty strings
//if (preg_match('/[^a-zA-Z]/',$dn) or preg_match('/[^a-zA-Z0-9\x20!@#$%^&*()]/',$pass)) { exit(); } //check for expected values (whitelisting)
//if (preg_match('/\x00/',$dn) or preg_match('/\x00/',$pass)) { exit(); } //check for null byte (blacklisting)
$ldapconn=ldap_connect("192.0.2.2") or die("Could not connect to LDAP server.");
if ($ldapconn) {
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
$ldapbind=ldap_bind($ldapconn, $dn, $pass);
if ($ldapbind) {
echo("success");
} else {
echo("fail");
}
}
References:
http://security.okstate.edu
john dot hargrove at sellingsource dot com ¶
17 years ago
Note that you have to specify the protocol version prior to making a call to ldap_bind, when the server is expecting LDAP protocol version 3. If you do not, you will receive a warning and fail to bind, such as:
ldap_bind(): Unable to bind to server: Protocol error
In order to avoid this, make this call:
<?php
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
?>
Where $ds is the result returned by ldap_connect(...);
spam[AT]it-blog[DOT]net ¶
15 years ago
When using LDAP with SSL and a LDAP server which uses a self-signed SSL certificate normally no connection will be established. Therefor you have to allow such connections explicitly.
With Linux (e.g. Debian, Ubuntu) you have to add "TLS_REQCERT never" to your /etc/ldap/ldap.conf. On other distributions this config file may be located somewhere else.
elsint at yahoo dot com ¶
14 years ago
If you are still having trouble after following all the instructions on the Web to get LDAPS to work, here's what worked for me:
I was trying to do LDAPS connection (our LDAP server was using port 40636) by running following command:
ldap_connect("www.example.com",40636)
This didn't work for days till I changed it to the following format:
ldap_connect("ldaps://www.example.com:40636")
Hope it'll help some out there.
-Cagdas
Anonymous ¶
19 years ago
When using Active Directory 2003 (possibly also 2000) you can't search anonymously so you have to bind with a (known) user and password. Or else you will get an Search operations error. I also can confirm that an empty password bind succeeds! So test for an empty password first!
Some excellent information is found here:
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 years ago
If you're using SSL (e.g. ldaps) and ldap_bind is throwing 'Unable to bind to server:' errors, check that the hostname used in the ldap_connect matches the 'CN' in the SSL certificate on the LDAP server. For example:
<?
ldap_connect('ldaps://ldap01');
// 'ldap01' should match the CN in your LDAP server's SSL cert, otherwise the subsequent ldap_bind() will throw a bind error
?>
You can check your LDAP server's SSL cert using Openssl utility (Linux) - look for the 'Subject' line:
$ openssl x509 -in /etc/pki/tls/certs/ldap01.crt -text -noout
...
Subject: C=XY, ST=My State, L=My City, O=My Org, CN=ldap01/emailAddress=me@domain.com
...
I recently applied some updates to my system (now Centos 5.7 and PHP 5.3.6) and started having this issue with PHP scripts that had been fine previously where I was simply using the IP address of the server. Replacing the IP address with the hostname fixed my issue.
peter dot schlaf at web dot de ¶
12 years ago
I had a problem doing a ldap_bind over SSL against Active Directory. The server kept telling me: 'Unable to bind to server:'. To solve this (OS: CentOS 6) make sure that /etc/openldap/ldap.conf has this line:
TLS_REQCERT allow
deniskutin at gmail dot com ¶
12 years ago
It's nessesary to add:
<?php
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)
?>
for ldap_bind returned true, while you try to bind for openldap (at least version 2.4.21)
RazmanAlias ¶
7 years ago
I use PHP 7.1.*. In this version ldap_bind will throw a RuntimeException if it fails to bind. I've tried with wrong host name, correct host and wrong password, correct host and invalid DN syntax. All fail conditions seems to throw RuntimeException.
So this function probably doesn't return false.
darkstar_ae at hotmail dot com ¶
19 years ago
This may be a security issue but after tinkering for hours with the below ldap auth function (edi01 at gmx dot at), I discovered that the ldap_bind function will return true if you enter a valid username AND a NULL value!
so if that function were to receive something like $username = 'someuser' and $password = '', it would return true. As long as it isn't a null value the function will work as expected. Might as well check if it is null or empty then.
edi01 at gmx dot at ¶
19 years ago
complete ldap authentication script:
function checkldapuser($username,$password,$ldap_server){
if($connect=@ldap_connect($ldap_server)){ // if connected to ldap server
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': ";
// bind to ldap connection
if(($bind=@ldap_bind($connect)) == false){
print "bind:__FAILED__<br>\n";
return false;
}
// search for user
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;
}
/* Authentifizierung des User */
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 { // no conection to ldap server
echo "no connection to '$ldap_server'<br>\n";
}
echo "failed: ".ldap_error($connect)."<BR>\n";
@ldap_close($connect);
return(false);
}//end function checkldapuser
Here a sample for using this function:
if (checkldapuser('myuser', 'secretpassword', 'ldap://link.to.ldap')) {
echo "ACCESS GRANTED\n";
} else {
echo "ACCESS DENIED\n";
}
marnijt at LIKEHAM dot gmail dot com ¶
13 years ago
After a lot of trail and error i've found the way to authenticate to apple's Opendirectory (snow leopard server) and thought it maybe useful to share.
<?php
// using ldap bind
$ldaprdn = 'uid=USERNAME,cn=users,dc=HOSTNAME,dc=DOMAIN,dc=com'; // ldap rdn or dn
$ldappass = 'PASSWORD'; // associated password
// connect to ldap server
$ldapconn = ldap_connect("HOSTNAME.DOMAIN.com")
or die("Could not connect to LDAP server.");
// Set some ldap options for talking to
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
if ($ldapconn) {
// binding to ldap server
$ldapbind = @ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...\n";
} else {
echo "LDAP bind failed...\n";
}
}
?>
david dot marsh at hartfordlife dot com ¶
18 years ago
had to do a bunch of research on this, but it does work, once config'd correctly.
using Apache/2.2.3 (Win32) mod_ssl/2.2.3 OpenSSL/0.9.8b
PHP PHP Version 5.1.5-dev
ldap_bind was getting "81 Can't contact LDAP server" which was really annoying, since the connection worked fine without "ldaps"
using:
$ldapconnect = @ldap_connect( $connection_string );
well, actually the bind was really the one failing...
$bind = ldap_bind($ldapconnect, $client, $this->objSecurityLogin->Password);
many attempts to determine until i smartened up and turned on the trace level:
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
which must go before the connect!
found that on windows, you can't specifiy a quote in the ldap.conf:
i had:
TLS_REQCERT never
TLS_CACERT "C:\\Documents\\Tools\\Apache2\\conf\\ssl\\ad.pem"
which throws the error..
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
changed to:
TLS_REQCERT never
TLS_CACERT C:\\Documents\\Tools\\Apache2\\conf\\ssl\\ad.pem
which cleans it up as:
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: ......
so the moral to the story is even though PHP wants quotes in some windows config parms, it won't work if its in ldap.conf!
info at multiotp dot net ¶
8 years ago
GnuTLS and SChannel (Microsoft) implementations are not (yet) compatible for TLS 1.2 negotiation during LDAPS binding (when binding with Microsoft Windows 2012R2 server).
The trick is to disable TLS1.2 before using LDAP functions:
putenv(‘LDAPTLS_CIPHER_SUITE=NORMAL:!VERS-TLS1.2’);
john dot doe at somewhere dot org ¶
10 years ago
In some structures its not possible to know the dn or rdn up front. However one can use $ldapuser= $samaccountname.'@'.domainname;