downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

ldap_8859_to_t61> <kadm5_modify_principal
[edit] Last updated: Mon, 01 Nov 2010

view this page in

LXVI. Funciones LDAP

Introducción

LDAP es el protocolo simple de acceso a directorios (Lightweight Directory Access Protocol), un protocolo usado para acceder a "Servidores de Directorio". El directorio es una clase especial de base de datos que contiene información estructurada en forma de árbol.

El concepto es similar a la estructura de directorios de los discos duros, pero en este caso, el directorio raiz es "El Mundo" y los subdirectorios de primer nivel son los "países". Niveles inferiores de la estructura de directorio contienen entradas para compañías, organizaciones o lugares, y en niveles aún más inferiores se encuentran las entradas para la gente, y en algunos casos equipos informáticos y documentos.

Para referirse a un archivo en un subdirectorio del disco duro se usa algo como:


    /usr/local/misapps/docs
   

Las barras marcan cada división en la referencia al archivo, y la secuencia es leida de izquierda a derecha.

El equivalente a la referencia a un archivo en LDAP es el "distinguished name" (nombre distinguible), abreviado como "dn". Un ejemplo de dn podría ser.


    cn=Pedro Pérez,ou=Contabilidad,o=Mi Compañía,c=ES
   

Las comas marcan cada división en la referencia, y la secuencia se lee de derecha a izquierda. Este dn se leería como:


    country = ES
    organization = Mi Compañía
    organizationalUnit = Contabilidad
    commonName = Pedro Pérez
   

De la misma manera que no hay reglas estrictas sobre como organizar la estructura de directorios de un disco duro, un administrador de un servidor de directorio puede establecer cualquier estructura que sea útil para sus propósitos. Sin embargo hay algunos acuerdos tácitos que siempre deben seguirse. La conclusión es que no se pueden escribir programas para acceder a un directorio si no se conoce algo de su estructura, igual que no se puede usar una base de datos sin algún conocimiento sobre lo que está disponible en ella.

Información sobre LDAP se puede encontrar en:

Netscape SDK tiene una Guia de programación muy buena en HTML.

Requisitos

Se necesita obtener y compilar las bibliotecas LDAP cliente de la dirección de OpenLDAP o de Bind9.net para poder compilar PHP con soporte LDAP.

Instalación

Para incluir el soporte de LDAP en PHP, es necesario añadir el parámetro --with-ldap[=DIR] a las opciones de configuración de la compilación de PHP, donde DIR apunta al directorio base de instalación de LDAP. Para incluir soporte de SASL, también se debe añadir la siguiente opción de compilación --with-ldap-sasl[=DIR], y además el archivo sasl.h debe existir en el sistema.

Nota para los usuarios de Windows: Para habilitar este módulo en entornos Windows, se deben copiar varios archivos de la carpeta DLL del directorio PHP/Win32 a la carpeta SYSTEM del sistema (que normalmente se encuentra en C:\WINNT\SYSTEM32 o C:\WINDOWS\SYSTEM). Para las versiones de PHP <= 4.2.0 se tiene que copiar el archivo libsasl.dll, para las versiones de PHP >= 4.3.0 se deben copiar los archivos libeay32.dll y ssleay32.dll.

Configuración en tiempo de ejecución

El comportamiento de estas funciones está afectado por los valores definidos en php.ini.

Tabla 1. Opciones de configuración de LDAP

NombreValor por defectoDonde se cambiaRegistro de cambios
ldap.max_links"-1"PHP_INI_SYSTEM 
For further details and definitions of the PHP_INI_* constants, see the Apéndice G.

Tipos de recursos

Esta extensión no tiene ningún tipo de recurso definido.

Constantes predefinidas

Estas constantes están definidas por esta extensión y estarán disponibles solamente cuando la extensión ha sido o bien compilada dentro de PHP o grabada dinámicamente en tiempo de ejecución.

LDAP_DEREF_NEVER (integer)

LDAP_DEREF_SEARCHING (integer)

LDAP_DEREF_FINDING (integer)

LDAP_DEREF_ALWAYS (integer)

LDAP_OPT_DEREF (integer)

LDAP_OPT_SIZELIMIT (integer)

LDAP_OPT_TIMELIMIT (integer)

LDAP_OPT_PROTOCOL_VERSION (integer)

LDAP_OPT_ERROR_NUMBER (integer)

LDAP_OPT_REFERRALS (integer)

LDAP_OPT_RESTART (integer)

LDAP_OPT_HOST_NAME (integer)

LDAP_OPT_ERROR_STRING (integer)

LDAP_OPT_MATCHED_DN (integer)

LDAP_OPT_SERVER_CONTROLS (integer)

LDAP_OPT_CLIENT_CONTROLS (integer)

LDAP_OPT_DEBUG_LEVEL (integer)

GSLC_SSL_NO_AUTH (integer)

GSLC_SSL_ONEWAY_AUTH (integer)

GSLC_SSL_TWOWAY_AUTH (integer)

Ejemplos

Recuperar informacion para todas las entradas donde el apellido empiece por "P" de un servidor de directorio, mostrando un listado con el nombre y dirección de correo electrónico.

Ejemplo 1. Ejemplo de búsqueda LDAP

<?php
// La secuencia básica para trabajar con LDAP es conectar, autentificarse,
// buscar, interpretar el resultado de la búsqueda y cerrar la conexión.

echo "<h3>Prueba de consulta LDAP</h3>";
echo
"Conectando ...";
$ds=ldap_connect("localhost");  // Debe ser un servidor LDAP valido!
echo "El resultado de la conexion es ".$ds."<br />";

if (
$ds) {
    echo
"Autentificandose  ...";
   
$r=ldap_bind($ds);     // Autentificacion anonima, habitual de los
                           // accesos de solo lectura
   
echo "El resultado de la autentificacion es ".$r."<br />";

    echo
"Buscando (sn=P*) ...";
   
// Busqueda de entradas por apellidos
   
$sr=ldap_search($ds,"o=Mi Compania, c=ES", "sn=P*"); 
    echo
"El resultado de la busqueda es ".$sr."<br />";

    echo
"El numero de entradas devueltas es ".ldap_count_entries($ds,$sr)."<br />";

    echo
"Recuperando entradas ...<p>";
   
$info = ldap_get_entries($ds, $sr);
    echo
"Se han encontrado ".$info["count"]." entradas:<p>";

    for (
$i=0; $i<$info["count"]; $i++) {
        echo
"dn es: ". $info[$i]["dn"] ."<br />";
        echo
"La primera entrada cn es: ". $info[$i]["cn"][0] ."<br />";
        echo
"La primera entrada email es: ". $info[$i]["mail"][0] ."<br /><hr />";
    }

    echo
"Cerrando conexion";
   
ldap_close($ds);

} else {
    echo
"<h4>No ha sido posible conectarse al servidor LDAP</h4>";
}
?>

Usando las funciones LDAP de PHP

Antes de usar las funciones LDAP deben conocerse los siguientes datos...

  • El nombre o dirección del servidor de directorio que se va a usar

  • El "dn base" del servidor (la parte del directorio global que maneja ese servidor, que puede ser por ejemplo "o=Mi Compañía,c=ES")

  • Si es necesaria contraseña para acceder al servidor (muchos servidores ofrecen acceso de lectura para usuarios anónimos pero requieren una contraseña para cualquier otro acceso)

La secuencia típica de llamadas a funciones LDAP que realizan las aplicaciones suele seguir el siguiente patrón:


  ldap_connect()    // establecer la conexión con el servidor
     |
  ldap_bind()       // acceso anónimo o autentificado
     |
  Hacer búsquedas o actualizaciones en el directorio
  y mostrar los resultados
     |
  ldap_close()      // cerrar la conexión
    

Tabla de contenidos
ldap_8859_to_t61 --  Transforma caracteres en formato 8859 a caracteres en formato t61
ldap_add -- Añade entradas a un directorio LDAP
ldap_bind -- Autenticación en un directorio LDAP
ldap_close -- Alias of ldap_unbind()
ldap_compare -- Compara un valor indicado con el valor de un atributo especificado mediante su DN
ldap_connect -- Conecta con un servidor LDAP
ldap_count_entries -- Cuenta el número de entradas de una búsqueda
ldap_delete -- Borra una entrada de un directorio
ldap_dn2ufn -- Convierte un DN a un formato más legible
ldap_err2str --  Convertir el número de error LDAP a un mensaje de error tipo cadena
ldap_errno --  Devuelve el número de error LDAP del último comando LDAP
ldap_error --  Devuelve el mensaje de error LDAP del último comando LDAP
ldap_explode_dn -- Divide un DN en las partes que lo componen
ldap_first_attribute -- Devuelte el primer atributo
ldap_first_entry -- Devuelve el identificador del primer resultado
ldap_first_reference --  Devuelve la primera referencia
ldap_free_result -- Libera la memoria que almacena los resultados
ldap_get_attributes -- Obtiene los atributos de una entrada de un resultado de búsqueda
ldap_get_dn -- Obtiene el DN de una entrada de un resultado
ldap_get_entries -- Obtiene todas las entradas de un resultado
ldap_get_option -- Obtiene el valor de la opción indicada
ldap_get_values_len -- Obtiene todos los valores binarios de un atributo de una entrada de un resultado
ldap_get_values -- Obtiene todos los valores de una entrada de un resultado
ldap_list -- Búsqueda de nivel único
ldap_mod_add -- Añade valores a los atributos
ldap_mod_del -- Borra valores de atributos
ldap_mod_replace -- Reemplaza valores de atributos
ldap_modify -- Modifica una entrada LDAP
ldap_next_attribute -- Obtiene el siguiente atributo de una entrada de un resultado
ldap_next_entry -- Obtiene la siguiente entrada de un resultado
ldap_next_reference --  Obtiene la siguiente referencia
ldap_parse_reference --  Obtiene información de la entrada de referencia
ldap_parse_result --  Obtiene información de un resultado
ldap_read -- Lee una entrada
ldap_rename -- Modifica el nombre de una entrada
ldap_sasl_bind --  Autenticarse en un directorio LDAP empleando SASL
ldap_search -- Busca en un arbol LDAP
ldap_set_option -- Establece el valor de la opción indicada
ldap_set_rebind_proc --  Indica la funció de callback a utilizar en caso de tener que volver a realizar la autenticación con el servidor.
ldap_sort --  Ordena las entradas de un resultado de búsqueda LDAP
ldap_start_tls --  Inicia TLS
ldap_t61_to_8859 --  Transforma caracteres en formato t61 a caracteres en formato 8859
ldap_unbind -- Desconectarse de un directorio LDAP


ldap_8859_to_t61> <kadm5_modify_principal
[edit] Last updated: Mon, 01 Nov 2010
 
add a note add a note User Contributed Notes Funciones LDAP
vito dot robar at mors dot si 16-May-2012 12:21
If you have problems with national characters or UTF8 encoding/decoding, set protocol to version 3:

<?php
$ds
= ldap_connect(...);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind($ds,...);
?>
Andrew Sharpe 23-Apr-2012 06:04
To compile PHP 5.1.6 on RHEL 6.2 x86_64, add the following to your configure command:

--with-libdir=lib64
--with-ldap=/usr
idbobby at rambler dot ru 12-Aug-2010 02:26
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).

index.php
---------

<?php

$user
= '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;
}

?>
ben_demott at hotmail dot com 01-Apr-2008 06:54
For anyone that is a programmer and not extremely familiar with naming conventions in Microsoft Active Directory or how to find objects within the directory, or more importantly how to reference the objects.
Running "adsiedit.msc" from the command line will display all of your objects in the directory in an easy to read and copyable naming format.
Hope this is helpful!

Note:
You must Run this command from an AD Domain Controller
You Must have the Windows Resource Kit Tools installed
(wouldn't let me make a link that long so I had to make a link break - Sorry!)
a http://www.microsoft.com/downloads/details.aspx
?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en

Installing this tool should modify your system path so you can just type the command from the run dialogue, otherwise the absolute path is:
C:\Program Files\Windows Resource Kits\Tools\adsiedit.msc
tuliogs at pgt dot mpt dot gov dot br 14-Jan-2008 12:53
This may be related to bug #28150, but as it´s marked "Won´t fix", I thought it´d be good to post this here, ´cause it´s a real bugger. :)

When compiling on AMD64 RedHat (and so possibly on CentOS), the configure script fails to find LDAP libraries under /usr/lib64, because it only searches under /usr/lib.

It´s hardcoded, so LDFLAGS, CPPFLAGS and --libdir are of no use, and neither is editing ext/ldap/config.m4 and running buildconf; you´ll need to manually edit configure and alter all occurrences of LDAP_LIBDIR to "lib64". Else, you´ll get a "cannot find ldap libs under /usr/lib" or "cannot find ldap.h" error upon configure.
alex at netflex dot nl 03-Sep-2007 06:49
If you want to use ldaps on windows but you don't want to validate the tls certificate try the following line before the ldap_connect call:

putenv('LDAPTLS_REQCERT=never') or die('Failed to setup the env');
Tod 03-Jul-2007 05:10
Notes for people running PHP 4 with Apache 2.2 on Win2k3.
The Apache Service needs to be running under the local administrators account in order for the ldap_connect to return a result. As apposed to the Domain Administrators account as may happen on servers in an Active Directory Domain.

It will 'appear' to work ok but will return no results otherwise.

so use (server name)\administrator for the username in the service logon properties.

Tod
jector at inbox dot ru 18-Mar-2007 09:01
Spent some time on fixing "Unable to load dynamic library 'php_ldap.dll'. Copied libeay32.dll and ssleay32.dll  everywhere, but error still stands.

After digging all this dlls I found, that both libeay32.dll and ssleay32.dll need msvcr70.dll (or msvcr71.dll, it depends on the compiler version). Then just copy that dll to system32\ dir and it works perfectly.
maykelsb at yahoo dot com dot br 12-Feb-2007 11:27
Problems with ldap_search in W2k3, can be solved adding

// -- $conn is a valid ldap connection.

ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION,3);
ldap_set_option($conn, LDAP_OPT_REFERRALS,0);

before ldap_bind, as sad in http://bugs.php.net/bug.php?id=30670.
unroar at gmail dot com 11-Dec-2006 05:33
In Solaris 9 the libnet library is a prerequisite for building  PHP with LDAP, SASL and SSL (libnet is available on Sunfreeware). 

I didn't see this mentioned anywhere and I'm not sure if it is required by ldap or sasl or ssl.  I just spent an hour on Google with no luck before I figured it out, maybe this comment will help the next googler.

The error is,
ld: fatal: library -lnet: not found
ld: fatal: File processing errors. No output written to sapi/cli/php
collect2: ld returned 1 exit status
make: *** [sapi/cli/php] Error 1
nigelf at esp dot co dot uk 16-Nov-2006 06:34
Chasing referrals in Active Directory (ie: searching across domains), can be slow.  You can look up the object instead in the GC (Global Catalog) as follows:

Remove any reference to ldap:// when you use ldap_connect, ie: use "serv1.mydom.com" NOT "ldap://serv1.mydom.com"

Connect to port 3268 (not 389, the default)

Set the Base DN for the search to null ie: "" (empty quotes). 

AD will then run the search against the GC which holds a copy of all objects in the Forest.  You can also retrieve a subset of attributes (including group membership, except local groups).

You will still need to follow referals for a full set of attributes.
gcathell at thetdgroup dot com 07-Jul-2006 09:05
I recently had to access a Microsoft Active Directory server as an LDAP service over SSL using PHP.  It took me a long time to get all the information I needed to get it to work.

I attempted to post a note here with the details but it ended it being too long.  I've placed the details at the following URL in hopes that someone else will benefit and will be able to solve the problem much more quickly than I did.

http://greg.cathell.net/php_ldap_ssl.html

Good luck!
brudinie at yahoo dot co dot uk 26-Jan-2006 08:43
LDAP Active Directory Last Logon (lastlogon).

This took me an entire day to work out. If you want to get the last logon date from an active directory account, you have to convert it from AD time stamp to unix time stamp.
Once you've got a unix time stamp, PHP can format it as a date.

Here is the code to do it:

        $dateLargeInt=$info[$i]["lastlogon"][0]; // nano seconds (yes, nano seconds) since jan 1st 1601
        $secsAfterADEpoch = $dateLargeInt / (10000000); // seconds since jan 1st 1601
        $ADToUnixConvertor=((1970-1601) * 365.242190) * 86400; // unix epoch - AD epoch * number of tropical days * seconds in a day
        $unixTsLastLogon=intval($secsAfterADEpoch-$ADToUnixConvertor); // unix Timestamp version of AD timestamp
        $lastlogon=date("d-m-Y", $unixTsLastLogon); // formatted date
nacenroe at remove dot this dot nystec dot com 19-Dec-2005 12:28
If you're looking to use PHP to integrate LDAP with AD (I'm working with Win2K3), you may want to tinker with the LDP.exe tool included (no resource kit needed!!) with Win2k and Win2K3.  You can run this app right from the command line.

The Win2K3 Help function was a good start point, and then pointed me to an article in the M$ KB: http://support.microsoft.com/default.aspx?scid=kb;en-us;255602 (XADM: Browsing and Querying Using the LDP Utility).

So ... if your connect/bindings are working but your queries are not, you may want to start here.  I'm finding it very useful when I run it on the local AD to see the attributes, etc.
ooja at roceindhoven dot nl 24-Oct-2005 11:52
If you bind anonymousely to a Windows 2003 Server (Active Directory) and you perform a ldap_search you will get an search operations error. You have to use a login and a password when binding!

I personally found alot of good information here:
http://www.scit.wlv.ac.uk/~jphb/sst/php/extra/ldap.html
christopherbyrne at hotmail dot com 16-Oct-2005 08:53
Just an ammendment to my previous post: my calculations were using east coast Australian time (GMT+10) whereas the Unix timestamp is in GMT. Therefore Active Directoy's "accountexpires" integer value does start from 1-Jan-1601 00:00:00 GMT and the number of seconds between this date and 1-Jan-1970 00:00:00 GMT is 11644524000.

The increments are still definately in 100 nanoseconds though!
christopherbyrne at hotmail dot com 16-Oct-2005 04:32
For anyone who's been having trouble working with the "accountexpires" attribute in Active Directory after having read the following article

www.microsoft.com/technet/scriptcenter/
resources/qanda/sept05/hey0902.mspx

or something similar, this may save you some frustration. In the article is is mentioned that this attribute is an integer representing the number of nanoseconds since 01-Jan-1601 00:00:00.

However the "accountexpires" attribute actually seems to be the number of 100 nanosecond increments since 31-Dec-1600 14:00:00. As a result if you divide the integer by 10,000,000 and subtract 11644560000 you will get a Unix timestamp that will match the dates in AD.

To set the "accountexpires" date just reverse the procedure, that is, get the timestamp for the new date you want, add 11644560000 and multiply by 10,000,000. You will also need to format the resultant number to make sure it is not outputted in scientific notation for AD to be happy with it.

Hope this helps!
hijinio at comcast dot net 28-Jul-2005 11:28
In case anybody has trouble configuring PHP with LDAP support on a Solaris 10 box, here is the configure line I used:

./configure --with-nsapi=/opt/SUNWwbsvr --enable-libgcc --disable-libxml --with-ldap=/usr/local --prefix=/opt/php/php-5.0.4

The important part to note is the location used for --with-ldap= ; which for most S10 people, will be "--with-ldap=/usr/local".
jpmens at gmail dot com 11-Mar-2005 02:04
Further to jabba at zeelandnet dot nl's note. If you are trying to connect to an LDAPS URI with OpenLDAP, you can either create the configuration file as described by jabba, or alternatively, use the environment settings to set LDAPTLS_REQCERT=never as described in ldap.conf(5).
Richie Bartlett(at)ITsystems-Online com 20-Dec-2004 12:44
This is an update to <i>wtfo at technocraft dot com</i> (23-May-2002 03:40)... This function allows additional (optional) parameters. The prev function listed, failed to close the ldap connection after successful authenication.

<?php
function checkNTuser($username,$password,$DomainName="myDomain",
                     
$ldap_server="ldap://PDC.example.net"){//v0.9
// returns true when user/pass enable bind to LDAP (Windows 2k).
   
$auth_user=$username."@".$DomainName;
   
#echo $auth_user."->";
   
if($connect=@ldap_connect($ldap_server)){
       
#echo "connection ($ldap_server): ";
       
if($bind=@ldap_bind($connect, $auth_user, $password)){
           
#echo "true <BR>";
           
@ldap_close($connect);
            return(
true);
        }
//if bound to ldap
   
}//if connected to ldap
    #echo "failed <BR>";
   
@ldap_close($connect);
    return(
false);
}
//end function checkNTuser
?>
xxoes at gmx dot de 08-Dec-2004 06:24
Yes you musst use LDAP with SSL!

$newPassword = "\"" . $new_password . "\"";
$len = strlen($newPassword);
$newPassw = "";
for($i=0;$i<$len;$i++)
   $newPassw .= "{$newPassword{$i}}\000";
$userdata["unicodepwd"] = $newPassw;
ldap_mod_replace($dn, $userdata);

My Windows php binary "PHP Version 4.3.9" dos not support LDAP with SSL, i have use stunnel to create a ssl connection.
jabba at zeelandnet dot nl 15-Nov-2004 11:51
When using PHP on windows, and you are trying to connect (bind) to a Netware (6) LDAP server that requires secure connections (LDAPS), PHP will return a message stating that the server cannot be found.
 
A network traffic capture of the traffic taking place on connection attempt reveals that the server supplies a certificate for use in the SSL connection, but this is rejected (***bad certificate SSLv3 packet) by the client.

The reason for this is probably that the PHP LDAP implementation tries to verify the received certificate with the CA that issued the certificate. There may be a way to make it possible that this verification succeeds, but it is also possible to disable this verification by the client (which is, in this case, PHP) by creating an openldap (surprise!!) configuration file.

The location of this configuration file seems to be hardcoded in the LDAP support module for windows, and you may need to manually create the following directory structure:

C:\openldap\sysconf\

In the sysconf folder, create a text file named 'ldap.conf' (you can use notepad for this) and, to disable certificate verification, place the following line in the ldap.conf file:

TLS_REQCERT never

After this, all the normal ldap_bind calls will work, provided your supplied user id and password are correct.
spam2004 at turniton dot dk 29-Oct-2004 05:36
Here are two small functions that enables you to convert a binary objectSID from Microsoft AD into a more usefull text version (formatted (S-1-5.....)).

// Converts a little-endian hex-number to one, that 'hexdec' can convert
function littleEndian($hex) {
    for ($x=strlen($hex)-2; $x >= 0; $x=$x-2) {
        $result .= substr($hex,$x,2);
    }
    return $result;
}

// Returns the textual SID
function binSIDtoText($binsid) {
    $hex_sid=bin2hex($binsid);
    $rev = hexdec(substr($hex_sid,0,2));          // Get revision-part of SID
    $subcount = hexdec(substr($hex_sid,2,2));    // Get count of sub-auth entries
    $auth = hexdec(substr($hex_sid,4,12));      // SECURITY_NT_AUTHORITY
    $result = "$rev-$auth";
    for ($x=0;$x < $subcount; $x++) {
        $subauth[$x] = hexdec(littleEndian(substr($hex_sid,16+($x*8),8)));  // get all SECURITY_NT_AUTHORITY
        $result .= "-".$subauth[$x];
    }
    return $result;
}

echo binSIDtoText($bin_sid);
Jimmy Wimenta Oei 23-Sep-2004 12:32
If you want to disable/enable chase referral option, you need to first set the protocol version to version 3, otherwise the LDAP_OPT_REFERRALS option will not have any effect. This is especially true for querying MS Active Directory.

<?php
ldap_set_option
($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
?>

And as always, these should be called after connect but before binding.
dmeehan at flcancer dot com 12-Aug-2004 01:26
If your having problems running LDAP searches on the base DC against Active Directory 2k3, you need to set dsHeuristics to 0000002 in Active Directory. This allows searches to function similar to how they did in Active Directory 2k2. You can update dsHeuristics by launching ldp.exe goto 'connection' and create a new connection. Then goto bind and bind to your ldap server. Next select the 'Browse' menu and choose 'modify'. The DN *might* look like this:

CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=mycompany,DC=com

Attribute is: dsHeuristics
Value is: 0000002

Set the operation to replace and you should be set.
This solves the 'Operations error' error that happens when attempting to search without specifying an OU.

-d
Sami Oksanen 16-May-2004 06:27
I edited Jon Caplinger's code which is located below (date: 09-Nov-2002 05:44).

 - I corrected line
   "if (!($connect=@ldap_connect($ldap))) {" with
   "if (!($connect=@ldap_connect($ldap_server))) {"

 - Removed $name-attribute

 - "Name is:"-field was always an Array, so I changed printing line to:
   " echo "Name is: ". $info[$i]["name"][0]."<br>";"

I also added some alternative search filters to try out.

Here is the code:

<?php

$ldap_server
= "ldap://foo.bar.net";
$auth_user = "user@bar.net";
$auth_pass = "mypassword";

// Set the base dn to search the entire directory.

$base_dn = "DC=bar, DC=net";

// Show only user persons
$filter = "(&(objectClass=user)(objectCategory=person)(cn=*))";

// Enable to show only users
// $filter = "(&(objectClass=user)(cn=$*))";

// Enable to show everything
// $filter = "(cn=*)";

// connect to server

if (!($connect=@ldap_connect($ldap_server))) {
     die(
"Could not connect to ldap server");
}

// bind to server

if (!($bind=@ldap_bind($connect, $auth_user, $auth_pass))) {
     die(
"Unable to bind to server");
}

//if (!($bind=@ldap_bind($connect))) {
//     die("Unable to bind to server");
//}

// search active directory

if (!($search=@ldap_search($connect, $base_dn, $filter))) {
     die(
"Unable to search ldap server");
}

$number_returned = ldap_count_entries($connect,$search);
$info = ldap_get_entries($connect, $search);

echo
"The number of entries returned is ". $number_returned."<p>";

for (
$i=0; $i<$info["count"]; $i++) {
   echo
"Name is: ". $info[$i]["name"][0]."<br>";
   echo
"Display name is: ". $info[$i]["displayname"][0]."<br>";
   echo
"Email is: ". $info[$i]["mail"][0]."<br>";
   echo
"Telephone number is: ". $info[$i]["telephonenumber"][0]."<p>";
}
?>
ant at solace dot mh dot se 26-Feb-2004 08:23
When working with LDAP, its worth remembering that the majority
of LDAP servers encode their strings as UTF-8. What this means
for non ascii strings is that you will need to use the utf8_encode and
utf8_decode functions when creating filters for the LDAP server.

Of course, if you can its simpler to just avoid using non-ascii characters
but for most sites the users like to see their strange native character
sets including umlauts etc..

If you just get ? characters where you are expecting non-ascii, then
you might just need to upgrade your PHP version.
pookey at pookey dot co dot uk 07-Oct-2003 01:57
This is an example of how to query an LDAP server, and print all entries out.

<?php

$ldapServer
= '127.0.0.1';
$ldapBase = 'DC=anlx,DC=net';

/*
 * try to connect to the server
 */
$ldapConn = ldap_connect($ldapServer);
if (!
$ldapConn)
{
  die(
'Cannot Connect to LDAP server');
}

/*
 * bind anonymously
 */
$ldapBind = ldap_bind($ldapConn);
if (!
$ldapBind)
{
  die(
'Cannot Bind to LDAP server');
}

/*
 * set the ldap options
 */
ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);

/*
 * search the LDAP server
 */
$ldapSearch = ldap_search($ldapConn, $ldapBase, "(cn=*)");
$ldapResults = ldap_get_entries($ldapConn, $ldapSearch);

for (
$item = 0; $item < $ldapResults['count']; $item++)
{
  for (
$attribute = 0; $attribute < $ldapResults[$item]['count']; $attribute++)
  {
   
$data = $ldapResults[$item][$attribute];
    echo
$data.":&nbsp;&nbsp;".$ldapResults[$item][$data][0]."<br>";
  }
  echo
'<hr />';
}

?>
paul at datacom dot bg 15-Aug-2003 02:40
This note is for people trying to load extensions which require additional dlls on W2k/XP.
As stated in the installation notes one has to copy those libraries to %SystemRoot%\system32 directory.
Generally it's not a good idea to copy files from left to right and back especially for the system folder.
The result is always a mess. I hope you'll find my way to get things working for more elegant than just copying files.
Leave those dlls where they are in dlls folder under PHP's installation path. Then edit environment variables so that the system variable PATH to include the dlls' folder. You may need to reboot the system. That's all, nice and clean.
One who doesn't know what I'm talking about should go this way:
My Computer - > Control Panel -> System -> Advanced -> Environment Variables ... -> System variables.
mrowe at pointsystems dot com 06-Aug-2003 11:58
FWIW,

Before anyone else wastes a day scratching their head wondering why they can't search Active Directory...

I wasn't able to search on Active Directory until I did this (immediately after the ldap_connect):

ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);

I was able to ldap_bind if I didn't set this option, but I kept receiving errors.  Also note, I had to set the option BEFORE binding.
hkemale at hkem dot com 16-Jul-2003 10:49
For IIS+PHP+NTFS file system user
After copied <php_dir>/dlls/*.dll to <windows>/systems32/ remember to add read and exexcute premission to "everyone" and the extensions *.dll. this can prevent warning of Access is denied of php_ldap.dll
greatsafari at hotmail dot com 26-May-2003 11:01
Having seen so many variations of methods for connecting and query the Active Directory server, it really makes me suspect that the whole thing is dependent of the Active Directory configurations. Looking at this post at:

http://www.phpbuilder.com/mail/php-general/2003022/1459.php

Some methods proven to be working in one instance failed at another instance.
nliu99 at nospam dot yahoo dot com 29-Apr-2003 03:09
libsasl.dll is NOT required for ldap functionalities. Go check out the posting at: http://bugs.php.net/bug.php?id=9485

On win2k I followed these easy steps and got ldap to work:
1. copy php_ldap.dll from the extension folder to winnt/system32
2. edit winnt/php.ini so that ldap is enabled (uncomment the line).
3. restart IIS.
That's it and have fun with ldap.

A note for Microsoft Active Directory
1. You can login with the user email, i.e. user@company.com
2. It's easiest to search for user info with ldap_search by filtering: (userprincipalname=[user])
egeczi at nospamplease dot dist113 dot org 01-Apr-2003 09:05
On Win2k Server running IIS, it is not enough to just restart IIS after enabling the php_ldap extension. You have to restart the server itself.
yorch at correo dot ath dot cx 03-Mar-2003 09:12
Some notes about running LDAP extension on a Win2k box:

After copying php_ldap.php and libsasl.dll in every single directory possible (c:\WinNT\System32, c:\php ...) I decided to read the installation.txt file.
The instructions to install php extensions say: "Some extra DLLs are required for some PHP extensions. Please copy the bundled dlls from the 'dlls/' directory in distribution package to your windows/system (Win9.x) or winnt/system32 (WinNT, Win2000, XP) directory. If you already have these DLLs installed on your system, overwrite them only if something is not working correctly."

So I did exactly that: copy ALL the dll files from "c:\php\dlls" to "c:\WinNT\System32".
Now they load beautifully ;-)

I hope this helps someone.
jon dot caplinger at broadwing dot com 08-Nov-2002 10:44
Here is an example of searching active directory in w2k. Active directory requires a user account that has permissions to search the tree.

/* The following values are used for the example:
  1.  Domain =  microsoft.com
  2.  Server =  unstable
  3.  User = bgates
  4.  Password = iloveopensource
*/

// Get name value to search for from submitted form.

if (isset($HTTP_GET_VARS["name"])) {
     $name = $HTTP_GET_VARS["name"];
}

$ldap_server = "ldap://unstable.microsoft.com";
$auth_user = "bgates@microsoft.com";
$auth_pass = "iloveopensource";

// Set the base dn to search the entire microsoft.com directory.

$base_dn = "DC=microsoft, DC=com";

/* filter the search for all people in the microsoft.com tree that have a name that matches any one of the following attributes name, displayname, or cn. */
 
$filter = "(&(objectClass=user)(objectCategory=person)
(|(name=$name*)(displayname=$name*)(cn=$name*)))";

// connect to server

if (!($connect=@ldap_connect($ldap))) {
     die("Could not connect to ldap server");
}

// bind to server

if (!($bind=@ldap_bind($connect, $auth_user, $auth_pass))) {
     die("Unable to bind to server"); 
}

// search active directory

if (!($search=@ldap_search($connect, $base_dn, $filter))) {
     die("Unable to search ldap server");
}

$number_returned = ldap_count_entries($connect,$search);
$info = ldap_get_entries($connect, $search);

echo "The number of entries returned is ". $number_returned;

for ($i=0; $i<$info["count"]; $i++) {
   echo "Name is: ". $info[$i]["name"];
   echo "Display name is: ". $info[$i]["displayname"][0];
   echo "Email is: ". $info[$i]["mail"][0];
   echo "Telephone number is: ". $info[$i]["telephonenumber"][0];
}
gerbille at free dot fr 10-Oct-2002 06:26
The MD5 of PHP returns a result encoded in base16. But the LDAP MD5 returns a string encoded in base64.
$pwd="toto";
$pwd_md5=base64_encode(mhash(MHASH_MD5,$pwd));
Just add "{MD5}" front $pwd_md5 to obtain the same format as LDAP directory.

Bye
Aurélia
mike at whisperedlies dot org 09-Sep-2002 09:41
In addition to the netBIOS suggestion above, when binding to a Windows2k AD server, you can use the UPN of the intended user. For instance, if your SAM account name is firstname.lastname and your domain is domainname.com, your UPN might be firstname.lastname@domainname.com

This can be used to bind to AD. I've not seen any difference in any of the methods.
rusko dot marton at gibzone dot hu 10-Jul-2002 05:06
You can authenticate to a Windows 2000 domain's ldap server easily by using the simplified netbios form of the username.

Somebody written:
When authenticating to a Win2k LDAP server, the name of the person must be
the FULL NAME in the dn

NO. You can use this form:

$user = "DOMAINNAME\\username"
$password = "Password_of_user";

if (!$connect = ldap_connect("<server>", <port>)) {
  //error
  exit;
}
if (!$res = @ldap_bind($ldap, $user, $password)) {
  //error
  exit;
}

It works fine with Active Directory, we use it.
knitterb at blandsite dot org 19-Jun-2002 08:48
When using PHP 4.2.1 with OpenLDAP 2.1.2 I was having problems with binding to the ldap server.  I found that php was using an older protocol and added the following to the slapd.conf:

allow bind_v2

See ``man slapd.conf'' for more info about the allow item in the slapd.conf file, this is all I know! :)
wtfo at technocraft dot com 23-May-2002 03:40
This worked for me:

function checkNTUser ($username,$password) {
    $ldapserver = 'Your Server';
    $ds=ldap_connect($ldapserver);
    if ($ds) {
        $dn="cn=$username,cn=Users, DC=[sitename], DC=[sitesuffix]";
        $r=@ldap_bind($ds,$dn,$password);  
        if ($r) { return true;
        } else {
            return false;
        }
    }
}
sukhruprai at yahoo dot com 04-May-2002 06:56
There is an article about how to compile openldap on windows. Openldap binaries are also available for download (for windows).
http://www.fivesight.com/downloads/openldap.asp
php ^ pixelcop , com 23-Apr-2002 01:33
For those trying to do LDAP authentication with Lotus Domino NAB, the following has worked for me (based on the win2k example by webmaster@autourdupc.com) :

$ip = "localhost";
$dn="CN=Joe Blo, O=myOrganization";
$password = "password";

if (!($ldap = ldap_connect($ip))) {
    die ("Could not connect to LDAP server");
}

print "connected to <b>$ip</b><br/>";

if (!($res = @ldap_bind($ldap, $dn, $password))) {
    die ("Could not bind to $dn");
}

print "user <b>$dn</b> authenticated.<br/>";

$sdn = "O=myOrganization";
$filter = "(objectclass=*)";

print "executing search...<b>DN: $sdn; Filter: $filter</b><br/>";
$sr=ldap_search($ldap, $sdn, $filter);

$info = ldap_get_entries($ldap, $sr);

print $info["count"]." entries returned<hr>";
print "<PRE>";
print_r($info);
print "</PRE>";
webmaster at autourdupc dot com 31-Dec-2001 04:36
When authenticating to a Win2k LDAP server, the name of the person must be the FULL NAME in the dn

NB : nothing is case sensitive !

$dn="cn=DUPOND John, cn=Users, dc=autourdupc, dc=com"
$password = "Password_of_DUPOND";

Then when you bind to the LDAP database you use:

if (!($ldap = ldap_connect("<server>", <port>))) {
die ("Could not connect to LDAP server");
}
if (!($res = @ldap_bind($ldap, $dn, $password))) {
die ("Could not bind to $dn");
}

Hope this will usefull for everyone !
bounty_arz at hotmail dot com 26-Nov-2001 09:46
Hi,

There is a way to Access Active Directory :
- You will have to bind as admin :
eg: administrator@yourdomain.com
or as a user :
eg: fschultz@yourdomain.com
(because you can't search the Subtree as anonymous).

Then you can query, add, delete and modify entries if you respect the syntax of the MS schema.

F.B
http://www.imphar.com
mleaver at scis dot ecu dot edu dot au 08-Mar-2001 01:32
When authenticating to a Win2k LDAP server you must include the name of the person authenticating to the server in the dn

i.e. cn=administrator, cn=users, dc=server, dc=domain, dc=country

Then when you bind to the LDAP database you use:

<?php $res = ldap_bind($ldap, $dn, $password); ?>

So a full example would be:

<?php
if (!($ldap = ldap_connect("<server>", <port>))) {
       die (
"Could not connect to LDAP server");
}
$dn = "cn=administrator, cn=users, dc=myserver, dc=com, dc=au";
$password = "MyPassword";
if (!(
$res = @ldap_bind($ldap, $dn, $password))) {
       die (
"Could not bind to $dn");
}
?>

Then you do your list or search functions on the ldap database.

 
show source | credits | sitemap | contact | advertising | mirror sites