Ldap connect error

(PHP 4, PHP 5, PHP 7, PHP 8)

(PHP 4, PHP 5, PHP 7, PHP 8)

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

Описание

Внимание

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

ldap_connect(?string $host = null, int $port = 389): LDAPConnection|false

Замечание:

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

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

host

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

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

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

uri

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

port

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

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

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

Если никакие параметры не будут определены, тогда будет возвращён экземпляр LDAPConnection
открытого соединения.

Примеры

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


<?php// LDAP переменные
$ldapuri = "ldap://ldap.example.com:389"; // ldap-uri

// Соединение с LDAP

$ldapconn = ldap_connect($ldapuri)
or die(
"LDAP-URI некорректен");?>

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


<?php// Убедитесь, что ваш хост корректный и
// что вы выдали ему сертификат безопасности
$ldaphost = "ldaps://ldap.example.com/";// Соединение с LDAP
$ldapconn = ldap_connect($ldaphost)
or die(
"LDAP-URI некорректен");?>

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

  • ldap_bind() — Привязать к LDAP директории

nemanja at prolux-universal dot com

8 years ago


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.


Andrew (a.whyte at cqu.edu.au)

19 years ago


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.

Configure OpenSSL:

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:

  /usr/local/ssl/bin/c_rehash

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

(Should return: OK).

Configure OpenLDAP:

Add the following to your ldap.conf file.

(found as /usr/local/openldap/etc/openldap/ldap.conf)

  #--begin--

  # Instruct client to NOT request a server's cert.

  #

  # WARNING: This will open up the server vor Man-in-the-middle

  # attacs and should *not* be used on production systems or outside

  # of test-scenarios!

  #

  # If you use this setting you will not need any other settings as

  # no certificate is requested and therefore will not be validated

  #

  # For a proper solution check out https://andreas.heigl.org/2020/01/31/handle-self-signed-certificates-with-phps-ldap-extension/

  TLS_REQCERT never

  # Define location of CA Cert

  TLS_CACERT /usr/local/ssl/certs/AD_CA_CERT.pem

  TLS_CACERTDIR /usr/local/ssl/certs

  #--end--

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

  e.g.:

 
  cp /usr/local/openldap/etc/openldap/ldap.conf ~www/.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);

    return $ad ;

  }

Optionally you can avoid the URI style server string and use something like ldap_connect("adserver.ad.com", 636) ;  But work fine with Active Directory servers.

Hope this proves usefull.


peter dot burden at gmail dot com

14 years ago


The host name parameter can be a space separated list of host names. This means that the LDAP code will talk to a backup server if the main server is not operational. There will be a delay while the code times out trying to talk to the main server but things will still work. This is particularly useful with a typical Microsoft Active Directory setup of primary and backup domain controllers.
<?php
$ldaphost
= "192.168.0.100 192.168.0.101";
$ldapconn = ldap_connect($ldaphost);
?>

lee at lareck70 dot net

7 years ago


To use LDAPS on Windows whitout "c:openldapsysconfldap.conf":
Generate a file like ldap.conf, name it "ldaprc".
For PHP script running on command line put the file to the script.
For PHP script running on webserver put the file in home directory of PHP.

harrison at glsan dot com

7 years ago


To override the ssl ca file can be done by setting an environmental variable within php.

I found using saving the ca certificate (and intermediate ca's) to a file called ca.pem and then adding

putenv('LDAPTLS_CACERT=./ca.pem');

before ldap_connect works for me.  
Code example:
<?php
putenv
('LDAPTLS_CACERT=./ca.pem');
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
$l = ldap_connect("ldaps://ldap/");
ldap_set_option($l, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind($l, "cn=apache,dc=example", "xxxxxxx");
echo(
ldap_error($l)."n");
$s = ldap_search($l, "dc=example", "uid=test");
echo(
ldap_count_entries($l, $s)."n");
?>
in the file  ca.pem in the same directory we have our ca's:
-----BEGIN CERTIFICATE-----
<cert here>
-----END CERTIFICATE-----


blizzards at libero dot it

18 years ago


To complete questions about how to connect to a LDAP ACTIVE DIRECTORY 2000/2003 server with SASL on port 636, you can refer to prevous notes, and the following directives:

A)Create CA certificates from AD;
B)Export in .pem (DER) format;
C)Install OPENSSL,CYRUS SASL,OPENLDAP,KERBEROS 5;
D)Copy exported AD ca cert into openssl certs dir on your unix system;
E)Reash with c_reash command;
F)Get a kerberos ticket form AD for your user;
G)Compile PHP with SSL and LDAP support;
H)Test with ldapsearch -D <binddn> -W -H ldaps://ad.secure.com:636 -x

If all works right, create your php script.

Note: For writing parameters to AD you need to renew ticket each 10 hours or less (AD default lifetime ticket), for reading pourpose you can maintain expired ticket.
When querying a windows 2000/2003 AD you MUST use only SASL and not TLS (non supported).


nateshull at gmail dot com

2 years ago


Implementing LDAPS on a WISP stack - Win, IIS, SQL, PHP
PHP 7.0.19:

Had some issues with some of the instructions and I needed LDAPS for an upcoming Active Directory update that removes insecure LDAP connections.

Enable modules for ldap and openssl in php.ini

Also ensure the extensions are in the ext folder

Verify the modules are loaded: phpinfo()

Notes:
The ldap or openssl config file is not needed if the environment variables are set in the code. Also the ca path does not like double quotations around the path.

*** code sample:

<?php
$ldapuser
= "domain\user";
$ldappass = "Passsword";
$ldapserver = "ldaps://server.domain.com";//options are require, never, allow
//require is most secure, the others could allow for man in the middle attacks
putenv('LDAPTLS_REQCERT=require');//tell ldap where the root ca certificate is
//note that the space is allowed in the path without escape or quotes
//I have not tested the permissions, but I would assume the service should have read.
putenv('LDAPTLS_CACERT=C:\Program Files\php\certs\rootca.pem');//test to ensure the certificate is able to be read and path is right.
echo file_get_contents("LDAPTLS_CACERT=C:\Program Files\php\certs\rootca.pem");// Set debugging
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);// connect to ldap server
$ldapconn = ldap_connect($ldapserver) or die ("Couldn't connect"); // binding to ldap server
$ldapbind = false;
$ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass);//easy view of success or failure
if ($ldapbind) {
    print(
"n logged in! nn");
} else {
    print(
"n log on failure nn");
}
?>


mwilmes at avc dot edu

7 years ago


I support a LAMP stack with PHP-FPM on CentOS 7 that needs to connect to Active Directory over SSL.  We have a root certificate for the domain.  I was able to set this up in five steps.

1. Get the domain's root SSL certificate in base64. (Must be an Enterprise Administrator - talk with your admin if you are not one.)
Run mmc.exe
File -> Add/Remove Snap-in
Select Certification Authority, then the server that generates certificates for your domain.
Expand the tree until you find the entry for the root certificate, then right click->Properties.
Click the "View Certificate" button, The "Details" tab, then the "Copy to File..." button.
Use the wizard to export the root certificate to your computer. Ensure you use the Base-64 format.

2. Copy the root cert to the Linux server.  You can open the certificate in notepad and copy and paste the contents.

3. Convert the certificate to pem format.  Substitute the names of files as needed.
openssl x509 -in <copied certificate file> -out /etc/openldap/certs/<cert>.pem

4. Add a line in ldap.conf to use new root cert.
vi /etc/openldap/ldap.conf
TLS_CACERT      /etc/openldap/certs/<cert>.pem

5.Restart the PHP service.
systemctl restart php-fpm.service


Nixahnung

7 years ago


I have spent a lot of time to make an LDAPS connection to a MS AD Global Catalog port 3269

My five Cents:

ldap_connect("ldaps://example.com", 3269)
=> Connection to 636.... :(, DC only

ldap_connect("ldaps://example.com:3269")
=> Connection to 3269.... :), GC as expected

May it helps...


allie at lsu dot edu

15 years ago


I sure do wish there was some way I could get this information out to all programmers in the world about binding and searching MS AD.  This is the second time I was bit by the "I need to search the entire tree" problem.

For php (and apache auth_ldap ) you need to specify port 3268 when you want to search the entire tree.  Otherwise it will spit out the partial results error.

ldap_connect($server,3268);

I'm just fortunate enough to have won this same battle with apache searching the whole directory.  When I noticed our php application failing auth's for users, I was immediately able to fix the problem by adding this port specification (and the ldap_set_option($ldapserver, LDAP_OPT_REFERRALS, 0)  option).

I really hope this helps someone else before they pull all their hair out.  I know I miss mine.


avel at noc uoa gr

20 years ago


Note that hostname can be a space-separated list of LDAP host names. This is very useful for failover; if the first ldap host is down, ldap_connect will ask the second LDAP host. Of course, you _must_ have LDAP replicates before doing this. :) Read the LDAP API documentation for more information.

This can also be useful, apart from failover, for LDAP load balancing. Just use a random generator function that will return a different space-separated list every time. This is because the first host in the list is always tried first.

Be careful when doing LDAP writes; be sure to always connect to your master host when you are about to modify the database, so that the replicates will get the changes as expected.

Alexandros Vellis


titanrat at bk dot ru

6 years ago


I found some difference between php7.0 and php5.5 on this function

Php5 ldap_connect ('host', 0) try to connect default port - host:389
Php7 ldap_connect ('host', 0) try to connect host:0 and crashes.


ac dot russell at live dot com

10 years ago


In order to connect to an ldap server via ssl I needed to use a certificate. For this to work the ldap admin sent me a .der file which I put into /etc/openldap/cacerts.

    cp ldap-server.der /etc/openldap/cacerts

That directory must be chmod 755. Then the following entries had to be in /etc/openldap/ldap.conf

    # Make the connection vulnerable to MITM-Attacks

    # by not checking any certificates

    # For a better solution see https://andreas.heigl.org/2020/01/31/handle-self-signed-certificates-with-phps-ldap-extension/

    TLS_REQCERT   never 

    TLS_CACERTDIR /etc/openldap/cacerts

"TLS_REQCERT never" should only be required if there is a self-signed certificate in the certificate chain.


csnyder at fcny dot org

13 years ago


It bears repeating (and the examples should probably be updated) that ldap_connect() doesn't actually test the connection to the specified ldap server. This is important if you're trying to build failover into your ldap-based authentication routine.

The only way to test the connection is to actually call ldap_bind( $ds, $username, $password ). But if that fails, is it because you have the wrong username/password or is it because the connection is down? As far as I can see there isn't any way to tell.

It seems that if ldap_bind() fails against your primary server, you have no choice but to try ldap_bind() with the same credentials against the backup. And yet, if your organization limits failed login attempts, a single bad password counts as two failed login attempts. Not good.

One possible workaround is to try an anonymous bind first:

<?php

// connect to primary

$ds = ldap_connect( 'ldap://10.0.0.7/' );

// note: $ds is always a resource even if primary is down

// try anonymous login to test connection

$anon = @ldap_bind( $ds );

if ( !
$anon ) {

   
// test failed, connect to failover host

   
$ds = ldap_connect( 'ldap://10.0.0.8/' );

}

else {

   
// test passed, unbind anonymous and reconnect to primary

   
ldap_unbind( $ds );

   
$ds = ldap_connect( 'ldap://10.0.0.7/' );

}
// now try a real login

$login = @ldap_bind( $ds, $username, $password );

?>



Note that this workaround relies on anonymous login being enabled, which may not always be the case. It's a little sad that there is no other way to test the connection. Hopefully this can be remedied in some future implementation of ldap_connect().


geigers at binghamton dot edu

14 years ago


If you have oci8 and are trying to use openldap for ldap you *may* run into a problem.  I have an Oracle database that I connect to from apache.  Oracle also has ldap libs which were taking precedence over the openldap libs.  This would cause a seg fault when calling ldap_connect with a uri style connect string; e.g. ldap_connect("ldaps://myldapserver.host");

After using gdb to debug a core dump and a lot of googling I found that the solution was to add an env-var to apachectl startup.

I am using Apache 2.2.8 with PHP 5.2.5 on RHEL.  I added:

LD_PRELOAD=/path/to/libldap.so
export LD_PRELOAD

in /usr/sbin/envvars which is read when apachectl starts.  You can read more on this here: http://www.mail-archive.com/php-bugs@lists.php.net/msg02201.html

Scott Geiger


bleathem at gmail dot com

14 years ago


Everyone is posting about getting ldaps:// working in a WAMP/AD stack, I had a tough time finding how to get it going in RHEL 5.1 (w/ all stock rpms).  Good old strace did the trick and helped me find the problem...

Turns out php was looking for the CA file in /etc/pki/CA, and I didn't have the correct permissions on the folder.  chmod'ing it to 755 solved my "Can't contact LDAP server" message.


andreas dot a dot sandberg at gmail dot com

15 years ago


Be careful when using ldap_connect with the sun client libraries that come bundled with solaris.   When specifyng the host with the ldap protocol, my connection failed and it took me a good day to trouble shoot.  ie. ldap_connect("ldap://somwhere.com");  Just remove the 'ldap://' and specify the host.   This was on Solaris 10 sparc.

vandervoord at planet dot nl

15 years ago


The previous note concerning searching the whole AD tree works fully. Though you must be sure that the server you're authenticating/searching is a Global Catalog server. If not, connecting and binding will fail. Usually there is at least one Global Catalog server in your domain, so if the connect fails try another server it will work. The reason it works is that the Global Catalog server searches the whole domain as where the domain catalog only searches a given OU, offcourse this opposes a security threat as well :)...

elsint at yahoo dot com

16 years ago


Be careful about the certificate's permission if you are using Windows.

Set certificates' permissions for everyone to Read and Read&Execute or you may get binding errors because of this.


Srivathsa M

17 years ago


Using LDAP over SSL on NetWare:

1. Copy the server certificates to sys:/php5/cert directory. This location is configurable in php.ini file.

2. Use "ldaps://" prefix for host name argument or a value of 636 for port number argument in ldap_connect call.

For more details, visit, NetWare specific PHP documentation at http://developer.novell.com/ndk/doc/php/index.html


nigelf at esp dot co dot uk

17 years ago


As mentioned above, openLDAP will always return a resource, even if the server name isn't valid. 

If you then bind with errors suppressed (@ldap_bind) and it fails, it's not obvious what caused the failure (ie: connection or credentials).  As the bind doesn't return a resource you can't get the last error from ldap_error etc. either.

If you display just a message about login failure to the user they may get frustrated re-typing a valid username/password when it's the connection that's at fault.


Anonymous

20 years ago


A resource ID is always returned when using URLs for the host parameter
even if the host does not exist.

"When using an URI to describe the connection, the (open)ldap library
only parses the url and checks if it's valid, _no connection_ is
established in that case."
-mfischer@php.net
http://bugs.php.net/bug.php?id=15637


antoine dot php dot net at bonnefoy dot eu

7 years ago


Hello,

Little corrections to nemanja  post.
- There was a warning if connection is denied by firewall (adding @ before fsockopen)
- fclose parameter was incorrect.

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.
<?php
function serviceping($_host, $_port = 389, $_timeout = 1) {
   
$op = @fsockopen($_host, $_port, $errno, $errstr, $_timeout);
    if (!
$op) {
        echo
"KO!";
        return
0;

            }

//DC is N/A
   
else {
       
fclose($op); //explicitly close open socket connection
       
return 1; //DC is up & running, we can safely connect with ldap_connect
   
}
}

function

ldap_connect_failover($_domain) {
// ##### 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);

    foreach (

$dclist as $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 executionif (!$dc) {
        return
false;
    }
//user being notifiedreturn ldap_connect($dc);
}
?>


TheThinkingMan

8 years ago


I have spent hours and hours trying to get an LDAPS connection happening with my local AD LDS instance (running on Windows 8.1 64bit).

I tried certificate after certificate. OpenSSL, Thawte and Self-signed - all with no success.

I ended up deleting all of my certificates and created a Self-signed certificate using IIS 7 (running on Windows 8.1).

I then downloaded the Softerra LDAP browser and it was able to connect to my AD LDS instance via SSL with no problems.

Sure if it could PHP could.

I used the following code to connect:
<?php
$ldap_server
= "ldaps://delllappy:636";
$ldap_conn = ldap_connect($ldap_server)  or die("Failed to connect to LDAP server.");
?>
I added the following above the ldap_connect:
<?php
putenv
('LDAPTLS_REQCERT=allow');
putenv("LDAPCONF=C:OpenLDAPsysconfldap.conf");
?>

That did nothing.

The ldap_bind command I used was:
<?php
if (!ldap_bind($ldap_conn, $ldap_user, $ldap_pass)) {
    echo
"error";
}else{
    echo
"success";
}
?>
BTW: I added a heap of debug in the code too - which is referenced elsewhere - so I didn't add it in here.

The error that I kept on getting was:
Error Binding to LDAP: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

I then ran ProcMon (Process Monitor from Microsoft).

I monitored when I restarted my web server (Z-WAMP). At that point there was no attempt to read ldap.conf.

I then loaded up my web page with my test.php file.

At that point I noticed that it was ldap.conf that was being read but openldap.conf.

Of course as my file was called ldap.conf, openldap.conf failed. I renamed my ldap.conf to openldap.conf and everything worked.

On Z-WAMP running OpenLDAP don't used ldap.conf, use openldap.conf.

The openldap.conf file was placed in C:openldapsysconf.

As the PUTENV values did not do anything, I removed them.


baroque at citromail dot hu

17 years ago


This code sample shows how to connect and bind to eDirectory in PHP using LDAP for Netware.

<?php

$server

='137.65.138.159';
$admin='cn=admin,o=novell';
$passwd='novell';$ds=ldap_connect($server);  // assuming the LDAP server is on this hostif ($ds) {
   
// bind with appropriate dn to give update access
   
$r=ldap_bind($ds, $admin, $passwd);
    if(!
$r) die("ldap_bind failed<br>");

    echo

"ldap_bind success";
   
ldap_close($ds);
} else {
    echo
"Unable to connect to LDAP server";
}
?>


mharting at micahtek dot com

13 years ago


An addition to trying to setup failover. After doing the ldap_connect, do the ldap_bind.  If ldap_bind fails, use the command ldap_errno to get the error number.  If the error number is 81, that represents the server is down.  That is the only time we do a failover to our backup ldap server.

Another thing to consider is the error could be 49, then do
ldap_get_option($this->ds,LDAP_OPT_ERROR_NUMBER,$optErrorNumber);. This will return extended data and if the data code in that is 532 or 773, the bind failure will be caused by the password being expired and requiring a password update before the bind will succeed.


verikono

11 years ago


PHP:LDAP does not support persistent connections.

miki at qex dot cz

12 years ago


I had terrible problems with "Unable to bind to server: Invalid credentials" error - everything seemed to be OK (login/pwd used in other apps).

Solved by adding domain to login (instead "username" I used "username@example.com").

Название ошибки Номер Пояснения/причины LDAP_SUCCESS 0 (x’00) Успешное завершение запроса. LDAP_OPERATIONS_ERROR 1 (x’01) Произошла ошибка операции. LDAP_PROTOCOL_ERROR 2 (x’02) Обнаружено нарушение протокола. LDAP_TIMELIMIT_EXCEEDED 3 (x’03) Превышено ограничение по времени LDAP. LDAP_SIZELIMIT_EXCEEDED 4 (x’04) Превышено ограничение по размеру LDAP. LDAP_COMPARE_FALSE 5 (x’05) Операция сравнения вернула «ложь». LDAP_COMPARE_TRUE 6 (x’06) Операция сравнения вернула «истину». LDAP_STRONG_AUTH_NOT_SUPPORTED 7 (x’07) Сервер LDAP не поддерживает строгую аутентификацию. LDAP_STRONG_AUTH_REQUIRED 8 (x’08) Для данной операции требуется прохождение строгой аутентификации. LDAP_PARTIAL_RESULTS 9 (x’09) Возвращены только частичные результаты. LDAP_REFERRAL 10 (x’0A) Указывает, что в ответе присутствует отсылка LDAP. Данное сообщение будет содержать один или несколько LDAP URL, по которым клиент должен перенаправить последующие операции для получения данного DN. LDAP_ADMINLIMIT_EXCEEDED 11 (x’0B) Указывает на то, что какие-либо ограничения, установленные на стороне сервера на количество записей, возвращаемое при поиске, были превышены. LDAP_UNAVAILABLE_CRITICAL_EXTENSION 12 (x’0C) Указывает на то, что элемент управления или правило соответствия, запрашиваемые в операции, не поддерживаются данным сервером. LDAP_CONFIDENTIALITY_REQUIRED 13 (x’0D) Конфигурация данного сервера требует обеспечения какой-либо формы конфиденциальности (TLS/SSL или SASL) при выполнении подсоединения с предоставляемым DN, например, определённая на глобальном уровне или в разделе database директива security может требовать соблюдения некоторой формы SSF при выполнении simple_bind или операции обновления. LDAP_SASL_BIND_IN_PROGRESS 14 (x’0E) Данный сервер в настоящий момент выполняет SASL-подсоединение и в этом контексте запрашиваемая операция является неверной. 15 (x’0F) Не используется. LDAP_NO_SUCH_ATTRIBUTE 16 (x’10) Указанный в запросе атрибут не присутствует в записи. LDAP_UNDEFINED_TYPE 17 (x’11) Указанный в запросе тип атрибута был неверным. LDAP_INAPPROPRIATE_MATCHING 18 (x’12) Указывает на то, что правило соответствия с расширяемым фильтром соответствия не поддерживается для указываемого типа атрибута. LDAP_CONSTRAINT_VIOLATION 19 (x’13) Указываемое в операции значение атрибута нарушает некоторые ограничения.
Возможные причины:
1. Строка слишком большой длины.
2. Неверный тип — строка записывается в числовой атрибут.
3. Неправильное значение, например, атрибут может принимать только определённое значение, либо одно из набора значений. LDAP_TYPE_OR_VALUE_EXISTS 20 (x’14) Указываемый тип атрибута или значение атрибута уже присутствует в записи.
Возможные причины:
1. При добавлении записи — один или несколько атрибутов в LDIF (или операции добавления/замены) для записи в точности совпадают (дублируются). LDAP_INVALID_SYNTAX 21 (x’15) Было указано неверное значение атрибута. 22 — 31 (x’16 — x’1F). Не используются. LDAP_NO_SUCH_OBJECT 32 (x’20) Указанная запись не существует в каталоге (DIT). LDAP_ALIAS_PROBLEM 33 (x’21) Псевдоним в DIT указывает на несуществующую запись. LDAP_INVALID_DN_SYNTAX 34 (x’22) Был указан синтаксически неверный DN. Может также возникнуть, если Вы используете файл в формате LDIF (dn: cn=xxx и т.д.) с утилитой ldapdelete, которой требуется только указание простого DN. 35 (x’23) Зарезервировано и не используется в LDAPv3 (LDAPv2: LDAP_IS_LEAF — указанный объект является листовым, то есть у него нет дочерних объектов). LDAP_ALIAS_DEREF_PROBLEM 36 (x’24) Возникла проблема при разыменовании псевдонима. Смотрите также описание ошибки 33. 37 — 47 (x’25 — x’2F). Не используются. LDAP_INAPPROPRIATE_AUTH 48 (x’30) Была указана проверка подлинности, которую невозможно осуществить, например, была указана LDAP_AUTH_SIMPLE, а у записи нет атрибута userPassword. LDAP_INVALID_CREDENTIALS 49 (x’31) Были предоставлены неверные учётные данные, например, неправильный пароль.
Дополнительный текст: unable to get TLS Client DN (невозможно получить DN клиента TLS).
Возможные причины:
1. Не предоставлен сертификат клиента в случае, если директива TLSVerifyClient установлена в ‘demand’.
2. Не предоставлен сертификат клиента в случае, если директива TLSVerifyClient установлена в ‘never’. В этом случае данное сообщение об ошибке не является фатальным и обслуживание клиента продолжается. LDAP_INSUFFICIENT_ACCESS 50 (x’32) У данного пользователя недостаточно прав доступа на осуществление запрашиваемой операции. LDAP_BUSY 51 (x’33) Данный сервер (DSA) слишком занят, чтобы выполнить запрашиваемую операцию. LDAP_UNAVAILABLE 52 (x’34) DSA недоступен. Он может быть, например, остановлен, поставлен на паузу или находится в процессе инициализации. LDAP_UNWILLING_TO_PERFORM 53 (x’35) Данный сервер (DSA) не желает выполнять запрашиваемую операцию.
Дополнительный текст: no global superior knowledge (нет сведений о глобальном вышестоящем каталоге) — имя записи, которую собираются добавить или модифицировать, не находится ни в одном из контекстов именования и у сервера нет правильной отсылки на вышестоящий каталог.
Возможная причина: не задан атрибут olcSuffix (директива suffix в slapd.conf) для DIT, на которое идёт ссылка.
Дополнительный текст: Shadow context; no update referral (теневой контекст (реплика); отсылки для выполнения обновлений не указано) — DIT, в которое собираются вносить изменения, является репликой в режиме «только для чтения», и, из-за отсутствия директивы updateref, невозможно возвратить отсылку.
Возможные причины:
1. Была попытка произвести запись в реплику «только для чтения» (в конфигурации syncrepl потребитель всегда в режиме «только для чтения»).
2. В конфигурации syncrepl multi-master в файле slapd.conf возможно пропущена директива mirrormode true.
3. Если slapd при запуске использовал файл slapd.conf, а директория slapd.d (cn=config) также существует, то при последующих модификациях DIT могут возникать ошибки с выдачей этого сообщения. В частности, в FreeBSD требуется наличие явного указания в rc.conf (slapd_cn_config=»YES») для принудительного использования slapd.d. LDAP_LOOP_DETECT 54 (x’36) Выявлено зацикливание. 54 — 59 (x’37 — x’3B). Не используются. LDAP_SORT_CONTROL_MISSING 60 (x’3C) В стандартах не используется. Только для Sun LDAP Directory Server. Сервер не получил требуемый элемент управления сортировки на стороне сервера. LDAP_RANGE_INDEX_ERROR 61 (x’3D) В стандартах не используется. Только для Sun LDAP Directory Server. Результаты запроса превысили диапазон, указанный в запросе. 62 — 63 (x’3E — x’3F). Не используются. LDAP_NAMING_VIOLATION 64 (x’40) Указывает на то, что данный запрос содержит нарушение именования в отношении текущего DIT. LDAP_OBJECT_CLASS_VIOLATION 65 (x’41) Произошло нарушение объектного класса при использовании текущего набора схемы данных, например, при добавлении записи был пропущен обязательный (must) атрибут. LDAP_NOT_ALLOWED_ON_NONLEAF 66 (x’42) Операция на нелистовой записи (то есть той, у которой есть дочерние записи) не разрешается. LDAP_NOT_ALLOWED_ON_RDN 67 (x’43) Операция над RDN, например, удаление атрибута, использующегося в качестве RDN в DN, не разрешается. LDAP_ALREADY_EXISTS 68 (x’44) Данная запись уже существует в этом DIT. LDAP_NO_OBJECT_CLASS_MODS 69 (x’45) Не разрешена модификация объектного класса. LDAP_RESULTS_TOO_LARGE 70 (x’46) Только C API (черновой RFC). Результаты слишком велики и не могут содержаться в данном сообщении. LDAP_AFFECTS_MULTIPLE_DSAS 71 (x’47) Указывает на то, что операцию необходимо выполнить на нескольких серверах (DSA), а это не разрешено. 72 — 79 (x’48 — x’4F). Не используются. LDAP_OTHER 80 (x’50) Произошла неизвестная ошибка.
Возможная причина:
Попытка удаления атрибута (особенно в cn=config), удаление которого запрещено.
Дополнительный текст: olcDbDirectory: value #0: invalid path: No such file or directory
Возможная причина: перед инициализацией новой базы данных директория для её размещения должна существовать. LDAP_SERVER_DOWN 81 (x’51) Только C API (черновой RFC). Библиотека LDAP не может связаться с LDAP-сервером. LDAP_LOCAL_ERROR 82 (x’52) Только C API (черновой RFC). Произошла некоторая локальная ошибка. Обычно это неудачная попытка выделения динамической памяти. LDAP_ENCODING_ERROR 83 (x’53) Только C API (черновой RFC). Произошла ошибка при кодировании параметров, отправляемых на LDAP-сервер. LDAP_DECODING_ERROR 84 (x’54) Только C API (черновой RFC). Произошла ошибка при декодировании результатов, полученных от LDAP-сервера. LDAP_TIMEOUT 85 (x’55) Только C API (черновой RFC). При ожидании результатов было превышено ограничение по времени. LDAP_AUTH_UNKNOWN 86 (x’56) Только C API (черновой RFC). В ldap_bind() был указан неизвестный метод аутентификации. LDAP_FILTER_ERROR 87 (x’57) Только C API (черновой RFC). Операции ldap_search() был предоставлен неправильный фильтр (например, количество открывающихся и закрывающихся скобок в фильтре не совпадает). LDAP_USER_CANCELLED 88 (x’58) Только C API (черновой RFC). Указывает на то, что пользователь прервал запрошенную операцию. LDAP_PARAM_ERROR 89 (x’59) Только C API (черновой RFC). Процедура ldap была вызвана с неверными параметрами. LDAP_NO_MEMORY 90 (x’5A) Только C API (черновой RFC). Выделение памяти (например, с помощью malloc(3) или другого механизма динамического выделения памяти) вызвало сбой в процедуре из библиотеки ldap. LDAP_CONNECT_ERROR 91 (x’5B) Только C API (черновой RFC). Библиотека/клиент не может соединиться с LDAP-сервером, указанным в URL. LDAP_NOT_SUPPORTED 92 (x’5C) Только C API (черновой RFC). Указывает на то, что в запросе используется функция, не поддерживаемая данным сервером. LDAP_CONTROL_NOT_FOUND 93 (x’5D) Только C API (черновой RFC). Запрашиваемый элемент управления не найден на данном сервере. LDAP_NO_RESULTS_RETURNED 94 (x’5E) Только C API (черновой RFC). Запрашиваемая операция завершилась успешно, но никаких результатов возвращено (получено) не было. LDAP_MORE_RESULTS_TO_RETURN 95 (x’5F) Только C API (черновой RFC). Запрашиваемая операция завершилась успешно, но должны быть возвращены дополнительные результаты, которые можно уместить в текущее сообщение. LDAP_CLIENT_LOOP 96 (x’60) Только C API (черновой RFC). Клиент выявил зацикливание, например, при следовании по отсылкам. LDAP_REFERRAL_LIMIT_EXCEEDED 97 (x’61) Только C API (черновой RFC). Сервер или клиент превысил какое-либо установленное ограничение при следовании по отсылкам.

If you are experiencing issues with LDAP, you can review common issues setting up this event source to aid in diagnosing the problem. By default, the LDAP event source will only poll once per 24 hours, even if the source is stopped and restarted after editing configurations.

As such, it is easiest to troubleshoot LDAP by creating a new source for each connection attempt, which will poll LDAP immediately, resulting in success or an error message within about a minute.

LDAP issues fall into two categories:

  • Connection Errors
  • Low User Count

Connection Errors

The following are common codes for LDAP connection errors:

  • Result Code 8 Strong Auth Required
  • Result Code 12 Unavailable Critical Extension
  • Result Code 32 No Such Object
  • Result Code 49 Invalid Credentials
  • Result Code 91 Connect Error

Result Code from LDAP Server 8 Strong Auth Required

If you see this this error, please check that you are not using an expired certification.

Result Code from LDAP server 12 Unavailable Critical Extension

If you see “unavailable critical extension error,” or if you are seeing fewer users than expected under the “Users” metric on the InsightIDR homepage, your default Base DN may not be pointing to the right root node in the LDAP tree.

To find the appropriate root node for your Base DN, follow instructions here.

Result Code from LDAP server 32 No Such Object

If you see an error that states «no such object,” or if you are seeing fewer users than expected in the LDAP data, then your user profiles may be stored in organizational units (OUs) rather than containers. To fix this, see How to Find the Base DN of a Windows Domain.

Result Code from LDAP server 49 Invalid Credentials

If you receive an “Invalid Credentials error,” then the username and password provided in the event source configuration cannot properly authenticate to the LDAP server.

To resolve this error, try the following actions:

  • Confirm the account you attempted to authenticate with has the proper rights to perform an LDAP query.
  • Ensure the “User Domain” field contains the proper name in the short or “pre-2000” format. For example, if your login domain and name is ACMEJohnSmith, then ACME would be the User domain.
  • Verify that LDAP credential you used to configure the event source is in the down-level logon name format: DOMAINUserName. To verify or change this, go to Credential Settings and edit the specified credential.

Result Code from LDAP server 91 (connect error)

If you see an error that reads «Failed to create a connection on port 389 or 636,» then the Collector host cannot reach the LDAP server specified in the event source configuration.

To resolve this issue, try the following actions:

  • When configuring the LDAP event source, ensure the Collector can resolve the server host using the local DNS. If the host cannot be resolved, enter the LDAP server’s IP address in place of the host name.
  • If the Collector can resolve the host, but the error persists, there may be an issue with connectivity over LDAP (port 389) or secure LDAP (port 636). Adjust the firewall or routing rules to allow the Collector and the LDAP server to communicate over ports 389 or 636.

Low User Count

If you find InsightIDR is only showing a small user count on the main page, you are likely experiencing issues with your LDAP event source. When the Collector polls LDAP to pull in user account information, it may be unable to read all of the users in the domain.

To resolve this issue, try the following solutions:

  1. In your LDAP event source, verify that the value you specified as the domain is the correct Base DN. See How to find a Base DN for more information.
  2. If you verified that the Base DN is correct, but you are still seeing a low user account on the “User & Accounts” page, add one LDAP event source per each OU of your domain with the respective OU values in the Base DN field.
  3. Verify that the credential you used for the LDAP event source has permissions to access and read all of the field attributes on the user and group objects in the domain. If it does not have permission, InsightIDR cannot create corresponding user account records.
  4. Verify that the Collector can find the LDAP referral point for the Windows domain listed in the User Domain field. If it cannot, use the “short” or “pre-2000” name for the Windows domain in the User Domain field, instead of using the FQDN.
  5. Verify that the Collector can read all of the user objects from the domain controller specified. If it cannot, specify a different domain controller than the one that you used in the Server field of the event source.

Low active user count

If you find InsightIDR is only showing a small active user count on the main page, you are likely experiencing issues with your LDAP event source. Please check for proper permissions on the domain user you are using:

  1. In Active Directory Users and Computers (ADUC), in the console tree, browse to the organizational unit or object for which you want to view effective permissions.
  2. Right-click the LDAP user you are using for your LDAP event source, and click Properties.
  3. In the Properties dialog box, on the Security tab, click Advanced.
  4. In the Advanced Security Settings dialog box, on the Effective Permissions tab, click Select.
  5. In the Select User, Computer, or Group dialog box, find the LDAP user you’re using and select it.
  6. Ensure that «Read all properties» is checked off and enabled.

If you do not have the «Read all properties» permission (indicated by a green checkmark), you will need to delegate the permission. To do so, you must complete the following:

  1. In Active Directory Users and Computers (ADUC), click on View > Advanced Features.
  2. Right-click the Organizational units (OU) and select Properties.
  3. Select the Security tab, and click Advanced.
  4. Click Add, find the LDAP user you’re using, and click OK.
  5. Check the Allow option for «Read all properties», click OK on each subsequent window to close all property windows.

This section lists some of the result codes that can be returned by functions in the LDAP C SDK. For ease of use, they are first listed in numerical order, then in alphabetical order.

LDAP result codes are extensible; thus, LDAP v3 extensions may define their own error codes, and register them with the Internet Assigned Numbers Authority (IANA). The IANA maintains a list of registered LDAP parameters, including result codes. This list includes what LDAP C SDK currently knows in terms of result codes. More information can be found in RFC 4520, Internet Assigned Numbers Authority (IANA) Considerations for the Lightweight Directory Access Protocol (LDAP).

Contents

  • 1 Result Codes Summary in Numerical Order
  • 2 Result Codes Reference in Alphabetical Order
    • 2.1 LDAP_ADMINLIMIT_EXCEEDED
    • 2.2 LDAP_AFFECTS_MULTIPLE_DSAS
    • 2.3 LDAP_ALIAS_DEREF_PROBLEM
    • 2.4 LDAP_ALIAS_PROBLEM
    • 2.5 LDAP_ALREADY_EXISTS
    • 2.6 LDAP_AUTH_UNKNOWN
    • 2.7 LDAP_BUSY
    • 2.8 LDAP_CLIENT_LOOP
    • 2.9 LDAP_COMPARE_FALSE
    • 2.10 LDAP_COMPARE_TRUE
    • 2.11 LDAP_CONFIDENTIALITY_REQUIRED
    • 2.12 LDAP_CONNECT_ERROR
    • 2.13 LDAP_CONSTRAINT_VIOLATION
    • 2.14 LDAP_CONTROL_NOT_FOUND
    • 2.15 LDAP_DECODING_ERROR
    • 2.16 LDAP_ENCODING_ERROR
    • 2.17 LDAP_FILTER_ERROR
    • 2.18 LDAP_INAPPROPRIATE_AUTH
    • 2.19 LDAP_INAPPROPRIATE_MATCHING
    • 2.20 LDAP_INDEX_RANGE_ERROR
    • 2.21 LDAP_INSUFFICIENT_ACCESS
    • 2.22 LDAP_INVALID_CREDENTIALS
    • 2.23 LDAP_INVALID_DN_SYNTAX
    • 2.24 LDAP_INVALID_SYNTAX
    • 2.25 LDAP_IS_LEAF
    • 2.26 LDAP_LOCAL_ERROR
    • 2.27 LDAP_LOOP_DETECT
    • 2.28 LDAP_MORE_RESULTS_TO_RETURN
    • 2.29 LDAP_NAMING_VIOLATION
    • 2.30 LDAP_NO_MEMORY
    • 2.31 LDAP_NO_OBJECT_CLASS_MODS
    • 2.32 LDAP_NO_RESULTS_RETURNED
    • 2.33 LDAP_NO_SUCH_ATTRIBUTE
    • 2.34 LDAP_NO_SUCH_OBJECT
    • 2.35 LDAP_NOT_ALLOWED_ON_NONLEAF
    • 2.36 LDAP_NOT_ALLOWED_ON_RDN
    • 2.37 LDAP_NOT_SUPPORTED
    • 2.38 LDAP_OBJECT_CLASS_VIOLATION
    • 2.39 LDAP_OPERATIONS_ERROR
    • 2.40 LDAP_OTHER
    • 2.41 LDAP_PARAM_ERROR
    • 2.42 LDAP_PARTIAL_RESULTS
    • 2.43 LDAP_PROTOCOL_ERROR
    • 2.44 LDAP_REFERRAL
    • 2.45 LDAP_REFERRAL_LIMIT_EXCEEDED
    • 2.46 LDAP_RESULTS_TOO_LARGE
    • 2.47 LDAP_SASL_BIND_IN_PROGRESS
    • 2.48 LDAP_SERVER_DOWN
    • 2.49 LDAP_SIZELIMIT_EXCEEDED
    • 2.50 LDAP_SORT_CONTROL_MISSING
    • 2.51 LDAP_STRONG_AUTH_NOT_SUPPORTED
    • 2.52 LDAP_STRONG_AUTH_REQUIRED
    • 2.53 LDAP_SUCCESS
    • 2.54 LDAP_TIMELIMIT_EXCEEDED
    • 2.55 LDAP_TIMEOUT
    • 2.56 LDAP_TYPE_OR_VALUE_EXISTS
    • 2.57 LDAP_UNAVAILABLE
    • 2.58 LDAP_UNAVAILABLE_CRITICAL_EXTENSION
    • 2.59 LDAP_UNDEFINED_TYPE
    • 2.60 LDAP_UNWILLING_TO_PERFORM
    • 2.61 LDAP_USER_CANCELLED

Result Codes Summary in Numerical Order

The following table gives the decimal and hexadecimal value of all result codes. Values missing from the sequence are not assigned to a result code.

Numerical Listing of Result Codes

Decimal Hexadecimal Defined Name
0 0x00 LDAP_SUCCESS
1 0x01 LDAP_OPERATIONS_ERROR
2 0x02 LDAP_PROTOCOL_ERROR
3 0x03 LDAP_TIMELIMIT_EXCEEDED
4 0x04 LDAP_SIZELIMIT_EXCEEDED
5 0x05 LDAP_COMPARE_FALSE
6 0x06 LDAP_COMPARE_TRUE
7 0x07 LDAP_STRONG_AUTH_NOT_SUPPORTED
8 0x08 LDAP_STRONG_AUTH_REQUIRED
9 0x09 LDAP_PARTIAL_RESULTS
10 0x0a LDAP_REFERRAL
11 0x0b LDAP_ADMINLIMIT_EXCEEDED
12 0x0c LDAP_UNAVAILABLE_CRITICAL_EXTENSION
13 0x0d LDAP_CONFIDENTIALITY_REQUIRED
14 0x0e LDAP_SASL_BIND_IN_PROGRESS
     
16 0x10 LDAP_NO_SUCH_ATTRIBUTE
17 0x11 LDAP_UNDEFINED_TYPE
18 0x12 LDAP_INAPPROPRIATE_MATCHING
19 0x13 LDAP_CONSTRAINT_VIOLATION
20 0x14 LDAP_TYPE_OR_VALUE_EXISTS
21 0x15 LDAP_INVALID_SYNTAX
     
32 0x20 LDAP_NO_SUCH_OBJECT
33 0x21 LDAP_ALIAS_PROBLEM
34 0x22 LDAP_INVALID_DN_SYNTAX
35 0x23 LDAP_IS_LEAF
36 0x24 LDAP_ALIAS_DEREF_PROBLEM
     
48 0x30 LDAP_INAPPROPRIATE_AUTH
49 0x31 LDAP_INVALID_CREDENTIALS
50 0x32 LDAP_INSUFFICIENT_ACCESS
51 0x33 LDAP_BUSY
52 0x34 LDAP_UNAVAILABLE
53 0x35 LDAP_UNWILLING_TO_PERFORM
54 0x36 LDAP_LOOP_DETECT
     
60 0x3C LDAP_SORT_CONTROL_MISSING
61 0x3D LDAP_INDEX_RANGE_ERROR
     
64 0x40 LDAP_NAMING_VIOLATION
65 0x41 LDAP_OBJECT_CLASS_VIOLATION
66 0x42 LDAP_NOT_ALLOWED_ON_NONLEAF
67 0x43 LDAP_NOT_ALLOWED_ON_RDN
68 0x44 LDAP_ALREADY_EXISTS
69 0x45 LDAP_NO_OBJECT_CLASS_MODS
70 0x46 LDAP_RESULTS_TOO_LARGE
71 0x47 LDAP_AFFECTS_MULTIPLE_DSAS
     
80 0x50 LDAP_OTHER
81 0x51 LDAP_SERVER_DOWN
82 0x52 LDAP_LOCAL_ERROR
83 0x53 LDAP_ENCODING_ERROR
84 0x54 LDAP_DECODING_ERROR
85 0x55 LDAP_TIMEOUT
86 0x56 LDAP_AUTH_UNKNOWN
87 0x57 LDAP_FILTER_ERROR
88 0x58 LDAP_USER_CANCELLED
89 0x59 LDAP_PARAM_ERROR
90 0x5a LDAP_NO_MEMORY
91 0x5b LDAP_CONNECT_ERROR
92 0x5c LDAP_NOT_SUPPORTED
93 0x5d LDAP_CONTROL_NOT_FOUND
94 0x5e LDAP_NO_RESULTS_RETURNED
95 0x5f LDAP_MORE_RESULTS_TO_RETURN
96 0x60 LDAP_CLIENT_LOOP
97 0x61 LDAP_REFERRAL_LIMIT_EXCEEDED

Result Codes Reference in Alphabetical Order

The following section contains the detailed reference information for each result code listed in alphabetical order by code name.

LDAP_ADMINLIMIT_EXCEEDED

This result code indicates that the look-through limit on a search operation has been exceeded. The look-through limit is the maximum number of entries that the server will check when gathering a list of potential search result candidates.

Note: When working with Directory Server, keep in mind the following:

  • If you are bound as the root DN, the server sets an infinite look-through limit.
  • If you are not bound as the root DN, the server sets a time limit.

#define LDAP_ADMINLIMIT_EXCEEDED 0x0b /* 11 */

LDAP_AFFECTS_MULTIPLE_DSAS

This result code indicates that the requested operation needs to be performed on multiple servers, where this operation is not permitted.

#define LDAP_AFFECTS_MULTIPLE_DSAS 0x47 /* 71 */

LDAP_ALIAS_DEREF_PROBLEM

This result code indicates that a problem occurred when dereferencing an alias.

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_ALIAS_DEREF_PROBLEM 0x24 /* 36 */

LDAP_ALIAS_PROBLEM

This result code indicates that the alias is invalid.

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_ALIAS_PROBLEM 0x21 /* 33 */

LDAP_ALREADY_EXISTS

This result code indicates that the request is attempting to add an entry that already exists in the directory. Directory Server sends this result code back to the client in the following situations:

  • The request is an add request, and the entry already exists in the directory.
  • The request is a modify DN request, and the new DN of the entry already identifies another entry.
  • The request is adding an attribute to the schema, and an attribute with the specified name or object identifier (OID) already exists.

#define LDAP_ALREADY_EXISTS 0x44 /* 68 */

LDAP_AUTH_UNKNOWN

This result code indicates that an unknown authentication method was specified.

Note: LDAP C SDK library sets this result code if ldap_bind() or ldap_bind_s() are called and an authentication method other than LDAP_AUTH_SIMPLE is specified. These functions only allow you to use simple authentication.

#define LDAP_AUTH_UNKNOWN 0x56 /* 86 */

LDAP_BUSY

This result code indicates that the server is currently too busy to perform the requested operation.

#define LDAP_BUSY 0x33 /* 51 */

LDAP_CLIENT_LOOP

This result code indicates that the LDAP client detected a loop, for example, when following referrals.

#define LDAP_CLIENT_LOOP 0x60 /* 96 */

LDAP_COMPARE_FALSE

This result code is returned after an LDAP compare operation is completed. The result indicates that the specified attribute value is not present in the specified entry.

#define LDAP_COMPARE_FALSE 0x05 /* 5 */

LDAP_COMPARE_TRUE

This result code is returned after an LDAP compare operation is completed. The result indicates that the specified attribute value is present in the specified entry.

#define LDAP_COMPARE_TRUE 0x06 /* 6 */

LDAP_CONFIDENTIALITY_REQUIRED

This result code indicates that confidentiality is required for the operation.

#define LDAP_CONFIDENTIALITY_REQUIRED 0x0d /* 13 */

LDAP_CONNECT_ERROR

This result code indicates that the LDAP client cannot establish a connection, or has lost the connection, with the LDAP server. LDAP C SDK sets this result code. If you have not established an initial connection with the server, verify that you have specified the correct host name and port number and that the server is running.

#define LDAP_CONNECT_ERROR 0x5b /* 91 */

LDAP_CONSTRAINT_VIOLATION

This result code indicates that a value in the request does not comply with certain constraints. Directory Server sends this result code back to the client in the following situations:

  • The request adds or modifies the userpassword attribute, and one of the following is true:
    • The server is configured to check the password syntax, and the length of the new password is less than the minimum password length.
    • The server is configured to check the password syntax, and the new password is the same as one of the values of the uid, cn, sn, givenname, ou, or mail attributes.
    • The server is configured to keep a history of previous passwords, and the new password is the same as one of the previous passwords. The request is a bind request, and the user is locked out of the account. (For example, the server can be configured to lock a user out of the account after a given number of failed attempts to bind to the server.)

#define LDAP_CONSTRAINT_VIOLATION 0x13 /* 19 */

LDAP_CONTROL_NOT_FOUND

This result code indicates that a requested LDAP control was not found. LDAP C SDK sets this result code when parsing a server response for controls and not finding the requested controls. For example:

  • ldap_parse_entrychange_control() is called, but no entry change notification control is found in the server‚Äö√Ñ√¥s response.
  • ldap_parse_sort_control() is called, but no server-side sorting control is found in the server‚Äö√Ñ√¥s response.
  • ldap_parse_virtuallist_control() is called, but no virtual list view response control is found in the server‚Äö√Ñ√¥s response.

#define LDAP_CONTROL_NOT_FOUND 0x5d /* 93 */

LDAP_DECODING_ERROR

This result code indicates that the LDAP client encountered an error when decoding the LDAP response received from the server.

#define LDAP_DECODING_ERROR 0x54 /* 84 */

LDAP_ENCODING_ERROR

This result code indicates that the LDAP client encountered an error when encoding the LDAP request to be sent to the server.

#define LDAP_ENCODING_ERROR 0x53 /* 83 */

LDAP_FILTER_ERROR

This result code indicates that an error occurred when specifying the search filter. LDAP C SDK sets this result code if it cannot encode the specified search filter in an LDAP search request.

#define LDAP_FILTER_ERROR 0x57 /* 87 */

LDAP_INAPPROPRIATE_AUTH

This result code indicates that the type of credentials are not appropriate for the method of authentication used. Directory Server sends this result code back to the client if simple authentication is used in a bind request, but the entry has no userpassword attribute; also, if LDAP_SASL_EXTERNAL is attempted on a non-SSL connection.

#define LDAP_INAPPROPRIATE_AUTH 0x30 /* 48 */

LDAP_INAPPROPRIATE_MATCHING

This result code indicates that an extensible match filter in a search request contained a matching rule that does not apply to the specified attribute type.

#define LDAP_INAPPROPRIATE_MATCHING 0x12 /* 18 */

LDAP_INDEX_RANGE_ERROR

This result code indicates that the search results exceeded the range specified by the requested offsets. This result code applies to search requests that contain virtual list view controls.

#define LDAP_INDEX_RANGE_ERROR 0x3D /* 61 */

LDAP_INSUFFICIENT_ACCESS

This result code indicates that the client has insufficient access to perform the operation. Check that the user you are authenticating as has the appropriate permissions.

#define LDAP_INSUFFICIENT_ACCESS 0x32 /* 50 */

LDAP_INVALID_CREDENTIALS

This result code indicates that the credentials provided in the request are invalid. Directory Server sends this result code back to the client if a bind request contains the incorrect credentials for a user or if a user’s password has already expired.

#define LDAP_INVALID_CREDENTIALS 0x31 /* 49 */

LDAP_INVALID_DN_SYNTAX

This result code indicates than an invalid DN has been specified. Directory Server sends this result code back to the client if an add request or a modify DN request specifies an invalid DN. It also sends this code when an LDAP_SASL_EXTERNAL bind is attempted but certification to DN mapping fails.

#define LDAP_INVALID_DN_SYNTAX 0x22 /* 34 */

LDAP_INVALID_SYNTAX

This result code indicates that the request contains invalid syntax. Directory Server sends this result code back to the client in the following situations:

  • The server encounters an access control instruction (ACI) with invalid syntax.
  • The request attempts to add or modify an aci attribute, and the value of the attribute is an ACI with invalid syntax.
  • The request is a search request with a substring filter, and the syntax of the filter is invalid.
  • The request is a modify request that is attempting to modify the schema, but no values are provided (for example, the request might be attempting to delete all values of the objectclass attribute).

#define LDAP_INVALID_SYNTAX 0x15 /* 21 */

LDAP_IS_LEAF

This result code indicates that the specified entry is a leaf entry.

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_IS_LEAF 0x23 /* 35 */

LDAP_LOCAL_ERROR

This result code indicates that an error occurred in the LDAP client, though it may also be returned by Directory Server.

#define LDAP_LOCAL_ERROR 0x52 /* 82 */

LDAP_LOOP_DETECT

This result code indicates that the server was unable to perform the requested operation because of an internal loop.

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_LOOP_DETECT 0x36 /* 54 */

LDAP_MORE_RESULTS_TO_RETURN

This result code indicates that there are more results in the chain of results. The LDAP C SDK sets this result code when the ldap_parse_sasl_bind_result() function is called to retrieve the result code of an operation, and additional result codes from the server are available in the LDAP structure.

#define LDAP_MORE_RESULTS_TO_RETURN 0x5f /* 95 */

LDAP_NAMING_VIOLATION

This result code indicates that the request violates the structure of the DIT.

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_NAMING_VIOLATION 0x40 /* 64 */

LDAP_NO_MEMORY

This result code indicates that no memory is available. LDAP C SDK sets this result code if a function cannot allocate memory (for example, when creating an LDAP request or an LDAP control).

#define LDAP_NO_MEMORY 0x5a /* 90 */

LDAP_NO_OBJECT_CLASS_MODS

This result code indicates that the request is attempting to modify an object class that should not be modified (for example, a structural object class).

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_NO_OBJECT_CLASS_MODS 0x45 /* 69 */

LDAP_NO_RESULTS_RETURNED

This result code indicates that no results were returned from the server. The LDAP C SDK sets this result code when the ldap_parse_result() function is called but no result code is included in the server’s response.

#define LDAP_NO_RESULTS_RETURNED 0x5E /* 94 */

LDAP_NO_SUCH_ATTRIBUTE

This result code indicates that the specified attribute does not exist in the entry. Directory Server might send this result code back to the client if, for example, a modify request specifies the modification or removal of a non-existent attribute or if a compare request specifies a non-existent attribute.

#define LDAP_NO_SUCH_ATTRIBUTE 0x10 /* 16 */

LDAP_NO_SUCH_OBJECT

This result code indicates that the server cannot find an entry specified in the request. Directory Server sends this result code back to the client if it cannot find a requested entry and it cannot refer your client to another LDAP server.

#define LDAP_NO_SUCH_OBJECT 0x20 /* 32 */

LDAP_NOT_ALLOWED_ON_NONLEAF

This result code indicates that the requested operation is allowed only on entries that do not have child entries (leaf entries as opposed to branch entries). Directory Server sends this result code back to the client if the request is a delete request or a modify DN request and the entry is a parent entry. You cannot delete or move a branch of entries in a single operation.

#define LDAP_NOT_ALLOWED_ON_NONLEAF 0x42 /* 66 */

LDAP_NOT_ALLOWED_ON_RDN

This result code indicates that the requested operation will affect the RDN of the entry. Directory Server sends this result code back to the client if the request is a modify request that deletes attribute values from the entry that are used in the RDN of the entry. (For example, the request removes the attribute value uid=bjensen from the entry uid=bjensen,ou=People,dc=example,dc=com.)

#define LDAP_NOT_ALLOWED_ON_RDN 0x43 /* 67 */

LDAP_NOT_SUPPORTED

This result code indicates that the LDAP client is attempting to use functionality that is not supported. LDAP C SDK sets this result code if the client identifies itself as an LDAP v2 client, and the client is attempting to use functionality available in LDAP v3. For example:

  • You are passing LDAP controls to a function.
  • You are calling ldap_extended_operation() , ldap_extended_operation_s(), or ldap_parse_extended_result() to request an extended operation or to parse an extended response.
  • You are calling ldap_rename() or ldap_rename_s(), and you are specifying a new superior DN as an argument.
  • You are calling ldap_sasl_bind(), ldap_sasl_bind_s(), or ldap_parse_sasl_bind_result() to request Simple Authentication and Security Layer (SASL) authentication or to parse a SASL bind response.
  • You are calling ldap_parse_virtuallist_control() to parse a virtual list control from the server‚Äö√Ñ√¥s response.

If you want to use these features, make sure to specify that your LDAP client is an LDAP v3 client.

#define LDAP_NOT_SUPPORTED 0x5c /* 92 */

LDAP_OBJECT_CLASS_VIOLATION

This result code indicates that the request specifies a new entry or a change to an existing entry that does not comply with the server’s schema. Directory Server sends this result code back to the client in the following situations:

  • The request is an add request, and the new entry does not comply with the schema. For example, the new entry does not have all the required attributes, or the entry has attributes that are not allowed in the entry.
  • The request is a modify request, and the change will make the entry non compliant with the schema. For example, the change removes a required attribute or adds an attribute that is not allowed.

Check the server error logs for more information, and the schema for the type of entry that you are adding or modifying.

#define LDAP_OBJECT_CLASS_VIOLATION 0x41 /* 65 */

LDAP_OPERATIONS_ERROR

This is a general result code indicating that an error has occurred. Directory Server might send this code if, for example, memory cannot be allocated on the server. To troubleshoot this type of error, check the server’s error logs. You may need to increase the log level of the server to get additional information.

#define LDAP_OPERATIONS_ERROR 0x01 /* 1 */

LDAP_OTHER

This result code indicates than an unknown error has occurred. This error may be returned by Directory Server when an error occurs that is not better described using another LDAP error code. When this error occurs, check the server’s error logs. You may need to increase the log level of the server to get additional information.

#define LDAP_OTHER 0x50 /* 80 */

LDAP_PARAM_ERROR

This result code indicates that an invalid parameter was specified. LDAP C SDK sets this result code if a function was called and invalid parameters were specified, for example, if the LDAP structure is NULL.

#define LDAP_PARAM_ERROR 0x59 /* 89 */

LDAP_PARTIAL_RESULTS

Directory Server sends this result code to LDAP v2 clients to refer them to another LDAP server. When sending this code to a client, the server includes a new line-delimited list of LDAP URLs that identifies another LDAP server. If the client identifies itself as an LDAP v3 client in the request, an LDAP_REFERRAL result code is sent instead of this result code.

#define LDAP_PARTIAL_RESULTS 0x09 /* 9 */

LDAP_PROTOCOL_ERROR

This result code indicates that the LDAP client’s request does not comply with the LDAP. Directory Server sends this result code back to the client in the following situations:

  • The server cannot parse the incoming request.
  • The request specifies an attribute type that uses a syntax not supported by the server.
  • The request is a SASL bind request, but your client identifies itself as an LDAP v2 client.
  • The request is a bind request that specifies an unsupported version of the LDAP. Make sure to specify whether your LDAP client is an LDAP v2 client or an LDAP v3 client.
  • The request is an add or a modify request that specifies the addition of an attribute type to an entry, but no values are specified.
  • The request is a modify request, and one of the following is true:
    • An unknown modify operation is specified (an operation other than LDAP_MOD_ADD, LDAP_MOD_DELETE, and LDAP_MOD_REPLACE).
    • No modifications are specified.
  • The request is a modify DN request, and one of the following is true:
    • The new RDN is not a valid RDN.
    • A new superior DN is specified, but your client identifies itself as an LDAP v2 client.
  • The request is a search request, and one of the following is true:
    • An unknown scope is specified, meaning a scope other than LDAP_SCOPE_BASE , LDAP_SCOPE_ONELEVEL, or LDAP_SCOPE_SUBTREE .
    • An unknown filter type is specified.
    • The filter type LDAP_FILTER_GE or LDAP_FILTER_LE is specified, but the type of attribute contains values that cannot be ordered. (For example, if the attribute type uses a binary syntax, the values of the attribute contain binary data, which cannot be sorted.)
    • The request contains an extensible filter (a filter using matching rules), but your client identifies itself as an LDAP v2 client.
    • The request contains an extensible filter (a filter using matching rules), but the matching rule is not supported by the server.
  • The request is a search request with a server-side sorting control, and one of the following is true:
    • The server does not have a syntax plug-in that supports the attribute used for sorting.
    • The syntax plug-in does not have a function for comparing values of the attribute. (This compare function is used for sorting.)
    • The type of attribute specified for sorting contains values that cannot be sorted in any order. For example, if the attribute type uses a binary syntax, the values of the attribute contain binary data, which cannot be sorted.
    • The server encounters an error when creating the sorting response control (the control to be sent back to the client).
    • When sorting the results, the time limit or the look-through limit is exceeded. The look-through limit is the maximum number of entries that the server will check when gathering a list of potential search result candidates.
  • The request is an extended operation request, and the server does not support the extended operation. In Directory Server, extended operations are supported through extended operation server plug-ins. Make sure that the server is loading a plug-in that supports the extended operation. Check the OID of the extended operation in your LDAP client to make sure that it matches the OID of the extended operation registered in the server plug-in.
  • An authentication method other than LDAP_AUTH_SIMPLE or LDAP_AUTH_SASL is specified.

To troubleshoot this type of error, check the server’s error logs. You may need to increase the log level of the server to get additional information.

#define LDAP_PROTOCOL_ERROR 0x02 /* 2 */

LDAP_REFERRAL

This result code indicates that the server is referring the client to another LDAP server. When sending this code to a client, the server includes a list of LDAP URLs that identify another LDAP server. This result code is part of the LDAP v3. For LDAP v2 clients, Directory Server sends an LDAP_PARTIAL_RESULTS result code instead.

#define LDAP_REFERRAL 0x0a /* 10 */

LDAP_REFERRAL_LIMIT_EXCEEDED

This result code indicates that the referral hop limitwas exceeded. LDAP C SDK sets this result code, when following referrals, if the client is referred to other servers more times than allowed by the referral hop limit.

#define LDAP_REFERRAL_LIMIT_EXCEEDED 0x61 /* 97 */

LDAP_RESULTS_TOO_LARGE

This result code indicates that the results of the request are too large.

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_RESULTS_TOO_LARGE 0x46 /* 70 */

LDAP_SASL_BIND_IN_PROGRESS

This result code is used in multi stage SASL bind operations. The server sends this result code back to the client to indicate that the authentication process has not yet completed.

#define LDAP_SASL_BIND_IN_PROGRESS 0x0E /* 14 */

LDAP_SERVER_DOWN

This result code indicates that LDAP C SDK cannot establish a connection with, or lost the connection to, the LDAP server. If you have not established an initial connection with the server, verify that you have specified the correct host name and port number and that the server is running.

#define LDAP_SERVER_DOWN 0x51 /* 81 */

LDAP_SIZELIMIT_EXCEEDED

This result code indicates that the maximum number of search results to return has been exceeded. This limit is specified in the search request. If you specify no size limit, the server will set one. When working with Directory Server, keep in mind the following:

  • If you are bound as the root DN and specify no size limit, the server enforces no size limit at all.
  • If you are not bound as the root DN and specify no size limit, the server sets the size limit to the value specified by the sizelimit directive in the server‚Äö√Ñ√¥s slapd.conf configuration file.
  • If the size limit that you specify exceeds the value specified by the sizelimit directive in the server‚Äö√Ñ√¥s slapd.conf configuration file, the server uses the size limit specified in the configuration file.

#define LDAP_SIZELIMIT_EXCEEDED 0x04 /* 4 */

LDAP_SORT_CONTROL_MISSING

This result code indicates that server did not receive a required server-side sorting control. Directory Server sends this result code back to the client if the server receives a search request with a virtual list view control but no server-side sorting control as the virtual list view control requires a server-side sorting control.

#define LDAP_SORT_CONTROL_MISSING 0x3C /* 60 */

LDAP_STRONG_AUTH_NOT_SUPPORTED

This result code is returned as the result of a bind operation. It indicates that the server does not recognize or support the specified authentication method.

#define LDAP_STRONG_AUTH_NOT_SUPPORTED 0x07 /* 7 */

LDAP_STRONG_AUTH_REQUIRED

This result code indicates that a stronger method of authentication is required to perform the operation.

#define LDAP_STRONG_AUTH_REQUIRED 0x08 /* 8 */

LDAP_SUCCESS

This result code indicates that the LDAP operation was successful.

#define LDAP_SUCCESS 0x00 /* 0 */

LDAP_TIMELIMIT_EXCEEDED

This result code indicates that the time limit on a search operation has been exceeded. The time limit is specified in the search request. If you specify no time limit, the server will set one. When working with Directory Server, keep in mind the following:

  • If you are bound as the root DN and specify no time limit, the server enforces no limit at all.
  • If you are not bound as the root DN and specify no time limit, the server sets the time limit.
  • If the time limit that you specify exceeds the time limit specified for the server configuration, the server uses the time limit specified in its configuration.

#define LDAP_TIMELIMIT_EXCEEDED 0x03 /* 3 */

LDAP_TIMEOUT

This result code indicates that the LDAP client timed out while waiting for a response from the server. LDAP C SDK sets this result code in the LDAP structure if the time-out period (for example, in a search request) has been exceeded and the server has not responded.

#define LDAP_TIMEOUT 0x55 /* 85 */

LDAP_TYPE_OR_VALUE_EXISTS

This result code indicates that the request attempted to add an attribute type or value that already exists. Directory Server sends this result code back to the client in the following situations:

  • The request attempts to add values that already exist in the attribute.
  • The request is adding an attribute to the schema of the server, but the OID of the attribute is already used by an object class in the schema.
  • The request is adding an object class to the schema of the server, and one of the following occurs:
    • The object class already exists.
    • The OID of the object class is already used by another object class or an attribute in the schema.
    • The superior object class for this new object class does not exist.

#define LDAP_TYPE_OR_VALUE_EXISTS 0x14 /* 20 */

LDAP_UNAVAILABLE

This result code indicates that the server is unavailable to perform the requested operation.

Note: At this point, neither LDAP C SDK nor Directory Server return this result code.

#define LDAP_UNAVAILABLE 0x34 /* 52 */

LDAP_UNAVAILABLE_CRITICAL_EXTENSION

This result code indicates that the specified control or matching rule is not supported by the server. Directory Server might send back this result code if the request includes an unsupported control or if the filter in the search request specifies an unsupported matching rule.

#define LDAP_UNAVAILABLE_CRITICAL_EXTENSION 0x0c /* 12 */

LDAP_UNDEFINED_TYPE

This result code indicates that the request specifies an undefined attribute type.

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_UNDEFINED_TYPE 0x11 /* 17 */

LDAP_UNWILLING_TO_PERFORM

This result code indicates that the server is unwilling to perform the requested operation. Directory Server sends this result code back to the client in the following situations:

  • The client has logged in for the first time and needs to change its password, but the client is requesting to perform other LDAP operations. In this situation, the result code is accompanied by an expired password control.
  • The request is a modify DN request, and a superior DN is specified.
  • The database is in read-only mode, and the request attempts to write to the directory.
  • The request is a delete request that attempts to delete the root DSE.
  • The request is a modify DN request that attempts to modify the DN of the root DSE.
  • The request is a modify request to modify the schema entry, and one of the following occurs:
    • The operation is LDAP_MOD_REPLACE. (The server does not allow you to replace schema entry attributes.)
    • The request attempts to delete an object class that is the parent of another object class.
    • The request attempts to delete a read-only object class or attribute.
  • The server uses a database plug-in that does not implement the operation specified in the request. For example, if the database plug-in does not implement the add operation, sending an add request will return this result code.

#define LDAP_UNWILLING_TO_PERFORM 0x35 /* 53 */

LDAP_USER_CANCELLED

This result code indicates that the user cancelled the LDAP operation.

Note: Directory Server does not currently send this result code back to LDAP clients.

#define LDAP_USER_CANCELLED 0x58 /* 88 */

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Ldap acceptsecuritycontext error data 52e
  • Ld player 9 ошибка запуска виртуальной машины
  • Ld lld error undefined symbol
  • Ld cannot find collect2 error ld returned 1 exit status
  • Lcpdfr encountered a critical error

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии