ldap_bind function (winldap.h)
The ldap_bind function asynchronously authenticates a client with the LDAP server. The bind operation identifies a client to the directory server by providing a distinguished name and some type of authentication credential, such as a password. The authentication method used determines the type of required credential.
Syntax
Parameters
The session handle.
A pointer to a null-terminated string that contains the distinguished name of the entry used to bind.
A pointer to a null-terminated string that contains the credentials to use for authentication. Arbitrary credentials can be passed using this parameter. The format and content of the credentials depend on the setting of the method parameter. For more information, see the Remarks section.
The authentication method to use.
Return value
If the function succeeds, the return value is the message ID of the initiated operation.
If the function fails, it returns –1 and sets the session error parameters in the LDAP structure.
Remarks
This implementation of ldap_bind supports the following authentication method.
| Authentication method | Description | Credential |
|---|---|---|
| LDAP_AUTH_SIMPLE | Authentication with a plaintext password. | A string that contains the user password. |
В
LDAP_AUTH_SIMPLE is the only authentication method compatible with the asynchronous version of binding; ldap_bind. Using any other authentication method with ldap_bind will fail and return LDAP_PARAM_ERROR. Calling ldap_bind with the LDAP_AUTH_SIMPLE method is equivalent to calling ldap_simple_bind. All other authentication methods require synchronous binding as provided by ldap_bind_s.
Be aware that LDAP 2 servers require an application to bind before attempting any other operations that require authentication.
Multithreading: Bind calls are not safe because they apply to the connection as a whole. Use caution if threads share connections and, when possible, thread the bind operations with other operations.
LDAP-«аутентификация» — это антипаттерн
Сегодня в любой организации есть LDAP-каталог, наполненный пользователями этой организации. Если присмотреться, вы найдете одно или несколько приложений, которые используют этот же каталог для «аутентификации». И кавычки здесь неспроста, ведь LDAP — это протокол доступа к каталогам, спроектированный для чтения, записи и поиска в службе каталогов. Это не протокол аутентификации. Термин «LDAP-аутентификация», скорее, относится к той части протокола (операции bind), где определяется, кто вы такой, и какие права доступа имеете к информации каталога.
Со временем LDAP стал службой аутентификации де-факто. Широко распространенные и доступные службы LDAP, такие, как Active Directory, стали лакомым кусочком для разработчиков программного обеспечения, которые хотят встроить аутентификацию в свои продукты. Клиентские библиотеки LDAP доступны практически для любого фреймворка, а реализовать интеграцию относительно легко.
Но несмотря на то, что применение LDAP может помочь решить задачу внедрения аутентификации пользователей в различных приложениях компании, оно создает множество проблем. В отличие от специально предназначенных протоколов аутентификации, при использовании LDAP возникают различные уязвимости информационной безопасности.
Чтобы разобраться в том, что это за уязвимости, сперва нужно понять, как работает LDAP-аутентификация.
Как работает LDAP-аутентификация
Представьте себе следующую ситуацию (она далека от реальности, но отлично передает суть).
Предположим, я делаю заказ в интернет-магазине так, чтобы его доставили мне домой в мое отсутствие. Курьер приезжает и оставляет под дверью записку с текстом «извините, мы вас не застали» и просит меня забрать заказ в ближайшем пункте выдачи в удобное время. В пункте выдачи сотрудник спрашивает мое имя, адрес и просит ключи от дома, чтобы подтвердить мою личность. Затем сотрудник службы доставки приезжает ко мне домой и открывает дверь моим ключом. Он заходит внутрь, чтобы убедиться, что я там живу, например, по фотографиям на стене или по имени адресата на корреспонденции. После этого сотрудник возвращается в пункт выдачи и сообщает мне, что успешно подтвердил мою личность, и я могу получить свою посылку! Ура!
Помимо проблем с логистикой, данная ситуация полна других вопросов. Что, если недобросовестный проверяющий сделал копию моего ключа? Или он оставил ключ надолго без присмотра, и это сделал кто-либо еще? Что, если на проверяющего напали и забрали мой ключ? Когда я отдаю ключ от своей квартиры незнакомцу, я не могу быть уверен в его порядочности и своей безопасности.
В мире LDAP мы все еще должны передавать наши ключи, чтобы открыть дверь от нашего имени. Мы передаем наш пароль стороннему лицу, и он пытается с его помощью проникнуть на сервер LDAP. Если ему удается получить доступ, мы не можем быть уверены, что наши учетные данные не скомпрометированы. При этом злоумышленник получит не только возможность разблокировать дверь LDAP, но и доступ к любому приложению, использующему те же учетные данные.
К счастью, в более полном мире аутентификации у нас также есть паспорта и водительские права! Протоколы аутентификации, такие как Kerberos, SAML и OpenID Connect, выпускают токены третьим лицам. Токены подтверждают, что вы являетесь тем, за кого себя выдаете, и нет необходимости передавать кому-либо свои ключи. Поскольку LDAP никогда не разрабатывался как протокол аутентификации, соответствующие механизмы у него отсутствуют.
Недостатки LDAP как системы аутентификации
В 2007 году Шумон Хак выпустил фантастическую статью (LDAP Weaknesses as a Central Authentication System), в которой он описывает три конкретные проблемы при использовании LDAP в качестве системы аутентификации.
1. Приложение, вероятно, недостаточно защищено, чтобы оперировать учетными данными
Автор подчеркивает, что защитить от атаки небольшой набор серверов аутентификации гораздо проще, чем защитить большое количество серверов приложений.
В своем большинстве серверы аутентификации, как правило, находятся под тщательным присмотром специалистов, обладающих значительным опытом в области информационной безопасности.
С другой стороны, серверы приложений имеют совершенно иной уровень безопасности и более подвержены риску компрометации. Они менее защищены, работают с более сложными программными стеками и с большей вероятностью имеют уязвимости. И чаще они находятся под управлением людей, которые не имеют глубоких знаний о безопасности. Построение правильной системы безопасности — сложнейший процесс, в котором очень легко допустить ошибку.
Проблема заключается в том, что если один сервер приложений скомпрометирован, то все учетные данные, которыми пользовались их владельцы во время атаки, также скомпрометированы. Под угрозой находится и любая другая система, которая использует тот же каталог LDAP для аутентификации.
2. Сервер LDAP не может обеспечить безопасность механизма аутентификации, используемого для получения учетных данных
LDAP-сервер не может гарантировать безопасность транзакции. Несмотря на то, что LDAP-сервер, например, может обеспечить принудительное выполнение операции bind по TLS, чтобы гарантировать, что учетные данные не передаются в открытом виде, сам сервер никогда не принимал никакой роли в получении учетных данных от пользователя. Существует риск, что приложение будет получать пароль по небезопасному каналу.
3. Пользователь вынужден делиться своим секретом аутентификации с третьей стороной
Пароль пользователя или секрет аутентификации должен оставаться секретом. Он должен быть известен только самому пользователю и системе аутентификации. При использовании LDAP-аутентификации пользователь вынужден поделиться своим секретом с третьей стороной, чтобы она затем смогла использовать данный секрет для взаимодействия с LDAP-каталогом от имени пользователя.
Важно упомянуть, что при использовании специально предназначенных протоколов аутентификации, таких как Kerberos, и даже с более раннего — NTLM, секрет пользователя никогда не передается по сети. Клиентское устройство и сервер используют криптографические операции, чтобы доказать друг другу, что у них один и тот же секрет и при этом даже не обмениваются самим секретом.
К пунктам Шумона Хука добавлю описание нескольких нюансов LDAP-аутентификации, основываясь на собственном опыте. Прежде всего, тема касается использования Active Directory.
4. Многие разработчики знают о механизмах работы LDAP недостаточно, чтобы правильно его использовать
В одном из моих прошлых постов блога описывается, как анонимные и неаутентифицированные bind’ы позволяли обхитрить разработчиков приложений и заставляли пропускать неавторизованных пользователей. Возможность выполнения операции bind без проверки подлинности — одна из тонкостей протокола, о которой не знают даже самые опытные специалисты по LDAP.
Каталоги устроены непросто и способны хранить огромное количество организационной информации и предоставляют множество настраиваемых способов ее хранения. Я видел очень много случаев, когда разработчик приложения предполагал, что существует определенный класс объекта или атрибут, а когда их не обнаруживалось, приложение падало. Для аутентификации пользователя не должны требоваться и применяться знания о структуре данных, хранящихся в каталоге. Протокол аутентификации должен абстрагироваться от деталей хранилища объектов, расположенного уровнем ниже.
5. Администраторы приложений зачастую не настраивают LDAP-клиенты корректным образом
При управлении Active Directory в большой распределенной среде есть один неприятный нюанс: трудно определить, какие конкретно приложения используют Active Directory в качестве LDAP-каталога, и как именно администраторы приложений настроили LDAP-клиент.
Ниже представлены примеры ужасов некорректной настройки.
6. LDAP-аутентификация и современные сервисы аутентификации взаимоисключают друг друга
Приложение, использующее LDAP для аутентификации, всегда будет вынуждено опираться на имена пользователей и пароли. Попытка реализовать современные технологии, такие как многофакторная аутентификация и единый вход, практически невозможна (если только вы не собираетесь внедрять свои собственные технологии, что само по себе является плохой идеей). Альянс FIDO стремится сделать пароли пережитком прошлого, а каждое приложение, использующее аутентификацию LDAP, будет помехой на пути к беспарольной политике.
Какие есть варианты?
Сегодня веб-приложения действительно могут обойтись без LDAP-аутентификации. Существует множество прекрасных веб-протоколов аутентификации, таких как SAML, WS-Federation и OpenID Connect, которые не требуют учетных данных пользователя для работы со сторонними приложениями. Бесчисленное количество продуктов предоставляют эти услуги, включая Active Directory Federation Service (встроенные в Windows Server) или сторонние сервисы, такие как Microsoft Azure AD, Okta, Ping и другие. Если в организации нет федеративного IdP, первое, что нужно сделать — внедрить его.
Главное, на что стоит обратить внимание при выборе нового ПО — поддержка современных протоколов аутентификации. Даже если приложение требуется бизнесу здесь и сейчас, не стоит спешить с выбором решения, особенно, если этот выбор ограничен только продуктами с LDAP-аутентификацией. Стоит попробовать донести до выбранного вендора необходимость доработки продукта с использованием более современных протоколов аутентификации. Возможно он прислушается и пересмотрит свой план разработки.
Число десктоп-приложений с «толстым клиентом», поддерживающих современные протоколы аутентификации, растет, и это действительно радостная тенденция. Эти приложения обычно были оплотом LDAP-аутентификации. Растет число SDK, таких, как Microsoft Authentication Library (MSAL), которые позволяют разработчикам легко добавлять поддержку современных сервисов аутентификации в свои мобильные и десктоп-приложения.
В конечном счете, стоит признать, что в сегодняшней реальности не все приложения поддерживают современные протоколы аутентификации, и, возможно, никогда и не будут. Внедрение полного запрета LDAP-аутентификации, вероятно, невозможно ни в одной организации. Однако ни в коей мере не стоит поощрять применение LDAP-аутентификации внутри организации. Использование LDAP следует рассматривать только при отсутствии других вариантов.
ldap_bind
(PHP 4, PHP 5, PHP 7, PHP 8)
ldap_bind — Привязать к LDAP директории
Описание
Связывает LDAP-директорию с указанным RDN и паролем.
Список параметров
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Список изменений
| Версия | Описание |
|---|---|
| 8.1.0 | Параметр ldap теперь ожидает экземпляр LDAP\Connection ; ранее ожидался ресурс (resource). |
Примеры
Пример #1 Пример использования привязки LDAP
// используется ldap-привязка
$ldaprdn = ‘uname’ ; // ldap rdn или dn
$ldappass = ‘password’ ; // ассоциированный пароль
// соединение с сервером
$ldapconn = ldap_connect ( «ldap://ldap.example.com» )
or die( «Не могу соединиться с сервером LDAP.» );
Пример #2 Использование анонимной привязки LDAP
//анонимное использование ldap-привязки
// соединение с сервером ldap
$ldapconn = ldap_connect ( «ldap://ldap.example.com» )
or die( «Не могу соединиться с сервером LDAP.» );
Смотрите также
User Contributed Notes 40 notes
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).
It took me a while to work this one out, so i figured i’d share my results..
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:
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):
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:
This didn’t work for days till I changed it to the following format:
Hope it’ll help some out there.
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.
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:
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/
Due to a bug in PHP 5.3 you may have to place the ldap.conf in the root of all your drives (I had to place it on D:).
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:
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.
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.
// 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.» );
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.
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:
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:
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:
well, actually the bind was really the one failing.
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!
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!
It’s nessesary to add:
Example code from my ldap class.
this->query i send notes under ldap_search function documentation.
Just a quick and easy function to authenticate against an AD domain controller:
Active Directory doesn’t accept anonymous requests anymore.
With Windows Server 2003, only authenticated users may initiate an LDAP request against Windows Server 2003-based domain controllers. You can override this new default behavior by changing the seventh character of the dsHeuristics attribute on the DN path as follows:
CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,Root domain in forest
Hi All, I just thought people should realize that the bug, or whatever change that was implemented with slapd and Openldap for the version V3 protocol has either not been repaired, or isn;t believed to be a bug or whatever. but still requires an implicit setting to V3 for use of the ldap_bind function. I am using Apache 2 and PHP 5.1 with LDAP 2. The default is set to deny V2 protocol, and even reconfiguring the slapd config file will not fix the problem.
You must still use the ldap_set_option function.
= «ldap://server» ;
$ldapPort = «port» ;
$ldapUser = «cn=name,dc=domain» ;
$ldapPswd = «password» ;
?>
Thanks to Ken on below for showing the way. There was a slight code error in what he chose as his link_id, but thats all. This code above worked nice and shinny, and demonstrates we are still working with 2004 problems. I wish they would update this in the code above.
The OpenLDAP libraries will return error 53 (Server unwilling to perform) when trying to re-bind to a non-anonymous account if you accidentally leave the password field blank. If you want to authenticate against a different field than the dn, you have to bind to the server twice. Your code may look like the following:
Hope this helps someone else running in to the same error.
Example of connecting and searching 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)’);
Linux.yaroslavl.ru
Введение в LDAP
Эта концепция аналогична структуре каталога на вашем жестком диске, за исключением того что в данном контексте корневой каталог рассматривается как «весь мир» а подкаталоги первого уровня как «страны». Более низкие уровни структуры директории содержат входы для компаний, организаций или мест, на уровне еще ниже находятся входы каталога для людей, и возможно для оборудования или документов.
Для ссылки на файл в подкаталоге на жестком диске используется нечто подобное
Прямая косая черта отмечает каждый раздел в ссылке, а вся последовательность символов ссылки читается слева направо.
Эквивалентом полностью определенной ссылки в LDAP является «distinguished name» (различаемое имя), обозначаемое просто как «dn». Примером dn может быть:
cn=John Smith,ou=Accounts,o=My Company,c=US
country = US
organization = My Company
organizationalUnit = Accounts
commonName = John Smith
Так же как и при организации структуры каталога на жестком диске, в данном способе нет жестких правил по организации структуры, и менеджер сервера директории LDAP допускает любую структуру, подходящую для выбранной цели. Однако имеется ряд соглашений. Суть их в том, что вы не можете написать код доступа к серверу директории, не зная его структуры, так же как вы не можете использовать базу данных без представления о ее предназначении. Пример полной программы
Поиск информации для всех записей, где фамилия начинается с «S», в сервере директории, вывод на дисплей и извлечение с именем и email-адресом.



