Меню Рубрики

Php ldap windows 7

Подключение к AD из PHP по протоколу LDAPS

Прочитав пост Создаем пользователя AD через веб-интерфейс, вспомнил, что около года назад занимался с аналогичной задачей. Проблема была в том, что не удавалось создать пользователя при соединении по протоколу LDAP, а получилось только по протоколу LDAPS. Выкладываю свои записи, вдруг кому пригодится.

Все действия проделывались в RHEL 5.5 и Windows Server 2003 R2 EE.

Сертификаты

Потребуется пакет OpenSSL

Сертификаты для контроллеров домена

При запросе **Common Name (eg, your name or your server’s hostname) []:** нужно обязательно ввести FQDN DC для которого создаем сертификат.

PHP должен быть с поддержкой ldap
Файл /etc/openldap/ldap.conf

Установка сертификатов на DC

1. Копируем на сервер файлы
* cert.p12 — The certificate
* cacert.pem — The Root Certificate

2 .Start, Run, MMC, File, Add/Remove Snap-in, Add, Certificates, Computer Account, Local Computer, My User Account, Next, Finish, Close, Ok

3. Разворачиваем Certificates

4. Импортируем cacert.pem в Trusted Root Certificates Authorities (правой кнопкой на Trusted Root Certificates Authorities, All Tasks, Import, Next, Browse, All files, выбираем наш cacert.pem . )

5. Импортируем cert.p12 в Personal (правой кнопкой на Personal, All Tasks, Import, Next, Browse, All files, находим наш cert.p12, если нужно вводим пароль . )

6. Проверяем сертифика на DC
* Разворачиваем папки Personal и Certificates
* Двойной щклчок по установленному сертификару
* Убеждаемся, что есть строка «You have a private key that corresponds to this certificate»

Проверка сзязи

Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.

Источник

Функции LDAP

Содержание

  • ldap_8859_to_t61 — Переводит символы из кодировки ISO-8859 в t61
  • ldap_add_ext — Добавить записи в каталог LDAP
  • ldap_add — Добавить запись в LDAP директорию
  • ldap_bind_ext — Привязать к директории LDAP
  • ldap_bind — Привязать к LDAP директории
  • ldap_close — Псевдоним ldap_unbind
  • ldap_compare — Сравнить значение атрибута, найденного в записи определённой DN
  • ldap_connect — Подключиться к серверу LDAP
  • ldap_control_paged_result_response — Получить указатель на текущую страницу результирующего набора LDAP
  • ldap_control_paged_result — Послать серверу LDAP данные для использования постраничного извлечения результата
  • ldap_count_entries — Посчитать число записей в результатах поиска
  • ldap_delete_ext — Удалить запись из директории
  • ldap_delete — Удаляет запись из директории LDAP
  • ldap_dn2ufn — Преобразовать DN в удобный для пользователя формат именования
  • ldap_err2str — Преобразовать код ошибки LDAP в строковое сообщение об ошибке
  • ldap_errno — Возвратить номер ошибки LDAP последней команды
  • ldap_error — Возвратить сообщение об ошибке LDAP последней команды
  • ldap_escape — Экранирование строки для использования в фильтре LDAP или в DN
  • ldap_exop_passwd — Обертка для расширенной операции PASSWD
  • ldap_exop_refresh — Обертка для расширенной операции Refresh
  • ldap_exop_whoami — Обертка для расширенной операции WHOAMI
  • ldap_exop — Выполнить расширенную операцию
  • ldap_explode_dn — Разделить DN на его составные части
  • ldap_first_attribute — Вернуть первый атрибут
  • ldap_first_entry — Возвратить первый идентификатор результата
  • ldap_first_reference — Возвращает первую справку
  • ldap_free_result — Освободить память результата
  • ldap_get_attributes — Получает атрибуты из записи в результатах поиска
  • ldap_get_dn — Получить DN результирующей записи
  • ldap_get_entries — Получает все записи результата
  • ldap_get_option — Получить текущее значение данной опции
  • ldap_get_values_len — Получить все бинарные значения из записи результата
  • ldap_get_values — Получает все значения из записи результата
  • ldap_list — Одноуровневый поиск
  • ldap_mod_add_ext — Добавить значения атрибута к текущим атрибутам
  • ldap_mod_add — Добавить значения атрибута к текущим атрибутам
  • ldap_mod_del_ext — Удалить значения атрибутов из текущих атрибутов
  • ldap_mod_del — Удалить значения атрибута из текущих атрибутов
  • ldap_mod_replace_ext — Заменить значения атрибута на новые
  • ldap_mod_replace — Заменить значения атрибутов на новые
  • ldap_modify_batch — Формирования и запуск пакетного изменения записи LDAP
  • ldap_modify — Псевдоним ldap_mod_replace
  • ldap_next_attribute — Получить следующий атрибут из результата
  • ldap_next_entry — Получить следующую запись результата
  • ldap_next_reference — Возвращает следующую справку
  • ldap_parse_exop — Разбор результирующего объекта выполнения расширенной операции LDAP
  • ldap_parse_reference — Извлекает информацию из справочника
  • ldap_parse_result — Извлечь информацию из результата
  • ldap_read — Читает запись
  • ldap_rename_ext — Модифицировать название записи
  • ldap_rename — Изменить имя записи
  • ldap_sasl_bind — Привязать к LDAP директории, используя SASL
  • ldap_search — Поиск по LDAP дереву
  • ldap_set_option — Установить значение данной опции
  • ldap_set_rebind_proc — Установить функцию обратного вызова для повторного связывания при ссылочном поиске
  • ldap_sort — Сортирует записи LDAP
  • ldap_start_tls — Запускает TLS
  • ldap_t61_to_8859 — Переводит символы из кодировки t61 в ISO-8859
  • ldap_unbind — Разорвать привязку к директории LDAP

User Contributed Notes 34 notes

First of all, sorry for my English.
Here are two functions to check group membership and some others which can be useful for work with LDAP (Active Directory in this example).

= ‘bob’ ;
$password = ‘zhlob’ ;
$host = ‘myldap’ ;
$domain = ‘mydomain.ex’ ;
$basedn = ‘dc=mydomain,dc=ex’ ;
$group = ‘SomeGroup’ ;

$ad = ldap_connect ( «ldap:// < $host >. < $domain >» ) or die( ‘Could not connect to LDAP server.’ );
ldap_set_option ( $ad , LDAP_OPT_PROTOCOL_VERSION , 3 );
ldap_set_option ( $ad , LDAP_OPT_REFERRALS , 0 );
@ ldap_bind ( $ad , » < $user >@ < $domain >» , $password ) or die( ‘Could not bind to AD.’ );
$userdn = getDN ( $ad , $user , $basedn );
if ( checkGroupEx ( $ad , $userdn , getDN ( $ad , $group , $basedn ))) <
//if (checkGroup($ad, $userdn, getDN($ad, $group, $basedn))) <
echo «You’re authorized as » . getCN ( $userdn );
> else <
echo ‘Authorization failed’ ;
>
ldap_unbind ( $ad );

/*
* This function searchs in LDAP tree ($ad -LDAP link identifier)
* entry specified by samaccountname and returns its DN or epmty
* string on failure.
*/
function getDN ( $ad , $samaccountname , $basedn ) <
$attributes = array( ‘dn’ );
$result = ldap_search ( $ad , $basedn ,
«(samaccountname= < $samaccountname >)» , $attributes );
if ( $result === FALSE ) < return '' ; >
$entries = ldap_get_entries ( $ad , $result );
if ( $entries [ ‘count’ ]> 0 ) < return $entries [ 0 ][ 'dn' ]; >
else < return '' ; >;
>

/*
* This function retrieves and returns CN from given DN
*/
function getCN ( $dn ) <
preg_match ( ‘/[^,]*/’ , $dn , $matchs , PREG_OFFSET_CAPTURE , 3 );
return $matchs [ 0 ][ 0 ];
>

/*
* This function checks group membership of the user, searching only
* in specified group (not recursively).
*/
function checkGroup ( $ad , $userdn , $groupdn ) <
$attributes = array( ‘members’ );
$result = ldap_read ( $ad , $userdn , «(memberof= < $groupdn >)» , $attributes );
if ( $result === FALSE ) < return FALSE ; >;
$entries = ldap_get_entries ( $ad , $result );
return ( $entries [ ‘count’ ] > 0 );
>

/*
* This function checks group membership of the user, searching
* in specified group and groups which is its members (recursively).
*/
function checkGroupEx ( $ad , $userdn , $groupdn ) <
$attributes = array( ‘memberof’ );
$result = ldap_read ( $ad , $userdn , ‘(objectclass=*)’ , $attributes );
if ( $result === FALSE ) < return FALSE ; >;
$entries = ldap_get_entries ( $ad , $result );
if ( $entries [ ‘count’ ] 0 ) < return FALSE ; >;
if (empty( $entries [ 0 ][ ‘memberof’ ])) < return FALSE ; >else <
for ( $i = 0 ; $i $entries [ 0 ][ ‘memberof’ ][ ‘count’ ]; $i ++) <
if ( $entries [ 0 ][ ‘memberof’ ][ $i ] == $groupdn ) < return TRUE ; >
elseif ( checkGroupEx ( $ad , $entries [ 0 ][ ‘memberof’ ][ $i ], $groupdn )) < return TRUE ; >;
>;
>;
return FALSE ;
>

There is a lot of confusion about accountExpires, pwdLastSet, lastLogon and badPasswordTime active directory fields.

All of them are using «Interval» date/time format with a value that represents the number of 100-nanosecond intervals since January 1, 1601 (UTC, and a value of 0 or 0x7FFFFFFFFFFFFFFF, 9223372036854775807, indicates that the account never expires): https://msdn.microsoft.com/en-us/library/ms675098(v=vs.85).aspx

So if you need to translate it from/to UNIX timestamp you can easily calculate the difference with:

= new DateTime ( ‘1601-01-01’ );
$datetime2 = new DateTime ( ‘1970-01-01’ );
$interval = $datetime1 -> diff ( $datetime2 );
echo ( $interval -> days * 24 * 60 * 60 ) . » seconds\n» ;
?>

The difference between both dates is 11644473600 seconds. Don’t rely on floating point calculations nor other numbers that probably were calculated badly (including time zone or something similar).

Now you can convert from LDAP field:

= $info [ $i ][ ‘lastlogon’ ][ 0 ];
// divide by 10.000.000 to get seconds from 100-nanosecond intervals
$winInterval = round ( $lastlogon / 10000000 );
// substract seconds from 1601-01-01 -> 1970-01-01
$unixTimestamp = ( $winInterval — 11644473600 );
// show date/time in local time zone
echo date ( «Y-m-d H:i:s» , $unixTimestamp ) . «\n» ;
?>

Hope it helps.

Источник

ldap_connect

ldap_connect — Подключиться к серверу LDAP

Описание

Следующий синтаксис все еще поддерживается для обеспечения обратной совместимости, но он объявлен устаревшим и больше не должен использоваться!

Создает идентификатор соединения LDAP и проверяет правдоподобность заданных hostname и port .

Замечание: Эта функция НЕ открывает соединение. Она проверяет, правдоподобны ли заданные параметры и могут ли они использоваться для подключения, когда в нем возникнет нужна.

Список параметров

Полный LDAP URI вида ldap://hostname:port или ldaps://hostname:port .

Также вы можете указать несколько LDAP-URI, разделенных пробелом.

Обратите внимание, что hostname:port — это неподдерживаемый LDAP URI, так как отсутствует схема.

Имя сервера для соединения.

Порт для соединения.

Возвращаемые значения

Возвращает положительный идентификатор ссылки LDAP, если LDAP URI правдоподобен. Она производит синтаксический разбор и проверку переданных параметров, но соединения с сервером не происходит. Если проверка синтаксиса провалилась — возвращается FALSE . ldap_connect() будет всегда возвращать resource , поскольку она фактически не соединяется, а только инициализирует параметры соединения. Фактическое подключение происходит при последующих вызовах ldap_* функций, обычно при вызове ldap_bind() .

Если никакие параметры не будут определены, тогда будет возвращен идентификатор уже открытой ссылки.

Примеры

Пример #1 Пример подключения к серверу LDAP.

// LDAP переменные
$ldapuri = «ldap://ldap.example.com:389» ; // ldap-uri

// Соединение с LDAP
$ldapconn = ldap_connect ( $ldapuri )
or die( «LDAP-URI некорректен» );

Пример #2 Пример безопасного подключения к серверу LDAP.

// Убедитесь, что ваш хост корректный и
// что вы выдали ему сертификат безопасности
$ldaphost = «ldaps://ldap.example.com/» ;

// Соединение с LDAP
$ldapconn = ldap_connect ( $ldaphost )
or die( «LDAP-URI некорректен» );

Смотрите также

User Contributed Notes 28 notes

If you don’t want your PHP program to wait XXX seconds before giving up in a case when one of your corporate DC have failed, and since ldap_connect() does not have a mechanism to timeout on a user specified time, this is my workaround which shows excellent practical results.

===========================================================
function serviceping($host, $port=389, $timeout=1)
<
$op = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$op) return 0; //DC is N/A
else <
fclose($opanak); //explicitly close open socket connection
return 1; //DC is up & running, we can safely connect with ldap_connect
>
>

// ##### STATIC DC LIST, if your DNS round robin is not setup
//$dclist = array(‘10.111.222.111’, ‘10.111.222.100’, ‘10.111.222.200’);

// ##### DYNAMIC DC LIST, reverse DNS lookup sorted by round-robin result
$dclist = gethostbynamel(‘domain.name’);

foreach ($dclist as $k => $dc) if (serviceping($dc) == true) break; else $dc = 0;
//after this loop, either there will be at least one DC which is available at present, or $dc would return bool false while the next line stops program from further execution

if (!$dc) exit(«NO DOMAIN CONTROLLERS AVAILABLE AT PRESENT, PLEASE TRY AGAIN LATER!»); //user being notified

//now, ldap_connect would certainly connect succesfully to DC tested previously and no timeout will occur
$ldapconn = ldap_connect($dc) or die(«DC N/A, PLEASE TRY AGAIN LATER.»);
===========================================================

Also with this approach, you get a real nice failover functionality, take for an example a company with a dozen of DC-a distributed along distant places, this way your PHP program will always have high availability if at least one DC is active at present.

To be able to make modifications to Active Directory via the LDAP connector you must bind to the LDAP service over SSL. Otherwise Active Directory provides a mostly readonly connection. You cannot add objects or modify certain properties without LDAPS, e.g. passwords can only be changed using LDAPS connections to Active Directory.

Therefore, for those wishing to securely connect to Active Directory, from a Unix host using PHP+OpenLDAP+OpenSSL I spent some time getting this going myself, and came across a few gotcha’s. Hope this proves fruitfull for others like me when you couldn’t find answers out there.

Make sure you compile OpenLDAP with OpenSSL support, and that you compile PHP with OpenLDAP and OpenSSL.

This provides PHP with what it needs to make use of ldaps:// connections.

Extract your Root CA certificate from Active Directory, this is achived through the use of Certificate Services, a startard component of Windows 2000 Server, but may not be installed by default, (The usual Add/Remove Software method will work here). I extracted this in Base64 not DER format.

Place the extracted CAcert into the certs folder for openssl. (e.g. /usr/local/ssl/certs) and setup the hashed symlinks. This is easily done by simply running:

Once this is done you can test it is worked by running:

/usr/local/ssl/bin/openssl verify -verbose -CApath /usr/local/ssl/certs /tmp/exported_cacert.pem

Add the following to your ldap.conf file.
(found as /usr/local/openldap/etc/openldap/ldap.conf)

# Instruct client to NOT request a server’s cert.
TLS_REQCERT never

# Define location of CA Cert
TLS_CACERT /usr/local/ssl/certs/AD_CA_CERT.pem
TLS_CACERTDIR /usr/local/ssl/certs

You also need to place those same settings in a file within the Apache Web user homedir called .ldaprc

You can then test that you’re able to establish a LDAPS connection to Active Directory from the OpenLDAP command tools:

/usr/local/openldap/bin/ldapsearch -H «ldaps://adserver.ad.com»

This should return some output in extended LDIF format and will indicate no matching objects, but it proves the connection works.

The name of the server you’re connecting to is important. If they server name you specify in the «ldaps://» URI does not match the name of the server in it’s certificate, it will complain like so:

ldap_bind: Can’t contact LDAP server (81)
additional info: TLS: hostname does not match CN in peer certificate

Once you’ve gotten the ldapsearch tool working correctly PHP should work also.

One important gotcha however is that the Web user must be able to locate it’s HOME folder. You must check that Apache is providing a HOME variable set to the Web users home directory, so that php can locate the .ldaprc file and the settings contained within. This may well be different between Unix variants but it is such a simple and stupid thing if you miss it and it causes you grief. Simply use a SetEnv directive in Apache’s httpd.conf:

SetEnv HOME /usr/local/www

With all that done, you can now code up a simple connect function:

function connect_AD()
<
$ldap_server = «ldaps://adserver.ad.com» ;
$ldap_user = «CN=web service account,OU=Service Accounts,DC=ad,DC=com» ;
$ldap_pass = «password» ;

$ad = ldap_connect($ldap_server) ;
ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3) ;
$bound = ldap_bind($ad, $ldap_user, $ldap_pass);

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

  • Php json encode windows 1251
  • Php installer windows msi
  • Php installer windows installer
  • Php header charset windows 1251
  • Php exec без ожидания ответа windows