Connect an active directory or LDAP with PHP - php

I am trying to connect the active directory or LDAP of window with an application (GLPI) made in PHP.
Connection parameters:
Connecting with the server:
$ds = ldap_connect($host, $port) // return true
#ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
#ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
#ldap_set_option($ds, LDAP_OPT_DEREF, $deref_options);
Relate connection to server and user and password
ldap_bind ($ds, $ login, $ password)
returns me:
"Can not contact LDAP server"
I want to know what can happen with that error message, since in the first method it returns true to me, which means that if it connects to the server.
RootDN This is fine and has all the permissions the user I am using.
The default server is fine and I did ping andtelnet.
Note: I already downloaded LDAPExplorer and established connection without problem.

Does the missing : $ds = ldap_connect ... like how it is in your code?
It should be something like :
$ds = ldap_connect($host, $port);
#ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
#ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
#ldap_set_option($ds, LDAP_OPT_DEREF, $deref_options);
ldap_bind ($ds, $login, $password)

ldap_connect does not connect to the server as is clearly stated in the docs. It merely creates a resource and checks whether the given values are plausible. The actual connection is established with the first command that requires a connection to the server. In this case the ldap_bind.
BTW: The "first method" does not return true but a resource-handle. Only when you pass something absolutely not parseable it will return false. But never true
I'd recommend using an LDAP-URI instead of the $host, $port variation as the PHP-library has to do that otherwise internaly. And it's the only way to f.e. establish an LDAPS-connection.

Ok, the solution to my problem is to upgrade from GLPI version 9.3.0 to 9.3.3.
Suggestions:
For users, what could happen to this, verify the messages that GLPI has informs about pending installation packages. So I opted for the update and the connection worked without problem.
For users who can not update version, verify that apache packages are pending to install or update, also in the installation process in the setup, be very careful installing the entire list that seems pending.
To fix some errors by installing version 9.3.3:
chown -R apache: apache glpi / files
chmod -R 755 glpi / files
chown -R apache: apache config
chmod -R 755 glpi / config
also:
setsebool -P httpd_can_network_connect_db 1
Thank you.

Related

"Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] Connection refused" after updating a PHP file [duplicate]

I am trying to use a PHP connection to connect MySQL Database which is on phpmyadmin. Nothing fancy about the connection just trying to see whether the connection is successful or not. I am using MAMP to host the database, the connection I am trying to use is this:
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "root";
try {
$conn = new PDO("mysql:host=$servername;dbname=AppDatabase", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
?>
I have been using postman to test to see if the connection is working, but I keep receiving this error message:
Connection failed: SQLSTATE[HY000] [2002] Connection refused
Before I was receiving an error message of:
Connection failed: SQLSTATE[HY000] [2002] No such file or directory
This was because I had set the servername to localhost, through changing this to the IP address it has given me connection refused and I have no idea what is wrong.
Any help regarding this would be appreciated.
I found the reason why the connection was not working, it was because the connection was trying to connect to port 8888, when it needed to connect to port 8889.
$conn = new PDO("mysql:host=$servername;port=8889;dbname=AppDatabase", $username, $password);
This fixed the problem, although changing the server name to localhost still gives the error.
Connection failed: SQLSTATE[HY000] [2002] No such file or directory
But it connects successfully when the IP address is entered for the server name.
In my case MySQL sever was not running. I restarted the MySQL server and issue was resolved.
//on ubuntu server
sudo /etc/init.d/mysql start
To avoid MySQL stop problem, you can use the "initctl" utility in Ubuntu 14.04 LTS Linux to make sure the service restarts in case of a failure or reboot. Please consider talking a snapshot of root volume (with mysql stopped) before performing this operations for data retention purpose[8]. You can use the following commands to manage the mysql service with "initctl" utility with stop and start operations.
$ sudo initctl stop mysql
$ sudo initctl start mysql
To verify the working, you can check the status of the service and get
the process id (pid), simulate a failure by killing the "mysql"
process and verify its status as running with new process id after
sometime (typically within 1 minute) using the following commands.
$ sudo initctl status mysql # get pid
$ sudo kill -9 <pid> # kill mysql process
$ sudo initctl status mysql # verify status as running after sometime
Note : In latest Ubuntu version now initctl is replaced by systemctl
I spent quite a few hours in a docker environment where all my containers are docker containers and I was using Phinx for migrations. Just to share different responses with different configurations.
Working solutions
"host" => "db", // {docker container's name} Worked
"host" => "172.22.112.1", // {some docker IP through ipconfig - may change on every instance - usually something like 172.x.x.x} Worked
Non-working solutions
"host" => "127.0.0.1", // SQLSTATE[HY000] [2002] Connection refused
"host" => "docker.host.internal", // SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name does not resolve
"host" => "localhost", // SQLSTATE[HY000] [2002] No such file or directory
I was running Phinx in following way.
docker compose --env-file .env run --rm phinx status -e development
Using MAMP I changed the host=localhost to host=127.0.0.1. But a new issue came "connection refused"
Solved this by putting 'port' => '8889', in 'Datasources' => [
Using MAMP ON Mac, I solve my problem by renaming
/Applications/MAMP/tmp/mysql/mysql.sock.lock
to
/Applications/MAMP/tmp/mysql/mysql.sock
1. server cert verify flag
I was required to use SSL to connect, and needed to set PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT to false in the new PDO options array, besides the entry PDO::MYSQL_ATTR_SSL_CA for the CA file.
Without it, the mysql log on the server helpfully mentions
2021-07-27 17:02:51 597605 [Warning] Aborted connection 597605 to db: 'unconnected' user: 'unauthenticated' host: '192.168.10.123' (This connection closed normally without authentication)
where I was definitely passing the right db and username and such in the DSN. An empty options array will show the db and user in the error log, at least. I am sure there is a valid, technical reason for these things.
I am adding this information so I can more easily find it, the next time I end up on this page..
2. host in connection string
In the context of SSL, I've also seen the error when using the IP address instead of the hostname to connect, if the hostname was used as CN (Common Name) in the certificate.
For me was php version from mac instead of MAMP, PATH variable on .bash_profile was wrong. I just prepend the MAMP PHP bin folder to the $PATH env variable. For me was:
/Applications/mampstack-7.1.21-0/php/bin
In terminal run vim ~/.bash_profile to open ~/.bash_profile
Type i to be able to edit the file, add the bin directory as PATH variable on the top to the file:
export PATH="/Applications/mampstack-7.1.21-0/php/bin/:$PATH"
Hit ESC, Type :wq, and hit Enter
In Terminal run source ~/.bash_profile
In Terminal type which php, output should be the path to MAMP PHP install.
I had the same issue on a docker container from php:8.0-fpm-alpine image. I just added the following line in the Dockerfile and it fixed the issue:
RUN apk add mysql-client
I had a similar problem once, turned out the User in the database was created with something like:
CREATE USER 'webpage'#'localhost' IDENTIFIED BY 'password';
worked fine when the connection details php script had localhost, but not when the IP address was there. A quick swap (ip address when creating user and localhost in connection details) revealed those two things have to match.
For everyone if you still strugle with Refusing connection, here is my advice. Download XAMPP or other similar sw and just start MySQL. You dont have to run apache or other things just the MySQL.

Docker php8.1 cant connect to MySQL [duplicate]

I am trying to use a PHP connection to connect MySQL Database which is on phpmyadmin. Nothing fancy about the connection just trying to see whether the connection is successful or not. I am using MAMP to host the database, the connection I am trying to use is this:
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "root";
try {
$conn = new PDO("mysql:host=$servername;dbname=AppDatabase", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
?>
I have been using postman to test to see if the connection is working, but I keep receiving this error message:
Connection failed: SQLSTATE[HY000] [2002] Connection refused
Before I was receiving an error message of:
Connection failed: SQLSTATE[HY000] [2002] No such file or directory
This was because I had set the servername to localhost, through changing this to the IP address it has given me connection refused and I have no idea what is wrong.
Any help regarding this would be appreciated.
I found the reason why the connection was not working, it was because the connection was trying to connect to port 8888, when it needed to connect to port 8889.
$conn = new PDO("mysql:host=$servername;port=8889;dbname=AppDatabase", $username, $password);
This fixed the problem, although changing the server name to localhost still gives the error.
Connection failed: SQLSTATE[HY000] [2002] No such file or directory
But it connects successfully when the IP address is entered for the server name.
In my case MySQL sever was not running. I restarted the MySQL server and issue was resolved.
//on ubuntu server
sudo /etc/init.d/mysql start
To avoid MySQL stop problem, you can use the "initctl" utility in Ubuntu 14.04 LTS Linux to make sure the service restarts in case of a failure or reboot. Please consider talking a snapshot of root volume (with mysql stopped) before performing this operations for data retention purpose[8]. You can use the following commands to manage the mysql service with "initctl" utility with stop and start operations.
$ sudo initctl stop mysql
$ sudo initctl start mysql
To verify the working, you can check the status of the service and get
the process id (pid), simulate a failure by killing the "mysql"
process and verify its status as running with new process id after
sometime (typically within 1 minute) using the following commands.
$ sudo initctl status mysql # get pid
$ sudo kill -9 <pid> # kill mysql process
$ sudo initctl status mysql # verify status as running after sometime
Note : In latest Ubuntu version now initctl is replaced by systemctl
I spent quite a few hours in a docker environment where all my containers are docker containers and I was using Phinx for migrations. Just to share different responses with different configurations.
Working solutions
"host" => "db", // {docker container's name} Worked
"host" => "172.22.112.1", // {some docker IP through ipconfig - may change on every instance - usually something like 172.x.x.x} Worked
Non-working solutions
"host" => "127.0.0.1", // SQLSTATE[HY000] [2002] Connection refused
"host" => "docker.host.internal", // SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name does not resolve
"host" => "localhost", // SQLSTATE[HY000] [2002] No such file or directory
I was running Phinx in following way.
docker compose --env-file .env run --rm phinx status -e development
Using MAMP I changed the host=localhost to host=127.0.0.1. But a new issue came "connection refused"
Solved this by putting 'port' => '8889', in 'Datasources' => [
Using MAMP ON Mac, I solve my problem by renaming
/Applications/MAMP/tmp/mysql/mysql.sock.lock
to
/Applications/MAMP/tmp/mysql/mysql.sock
1. server cert verify flag
I was required to use SSL to connect, and needed to set PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT to false in the new PDO options array, besides the entry PDO::MYSQL_ATTR_SSL_CA for the CA file.
Without it, the mysql log on the server helpfully mentions
2021-07-27 17:02:51 597605 [Warning] Aborted connection 597605 to db: 'unconnected' user: 'unauthenticated' host: '192.168.10.123' (This connection closed normally without authentication)
where I was definitely passing the right db and username and such in the DSN. An empty options array will show the db and user in the error log, at least. I am sure there is a valid, technical reason for these things.
I am adding this information so I can more easily find it, the next time I end up on this page..
2. host in connection string
In the context of SSL, I've also seen the error when using the IP address instead of the hostname to connect, if the hostname was used as CN (Common Name) in the certificate.
For me was php version from mac instead of MAMP, PATH variable on .bash_profile was wrong. I just prepend the MAMP PHP bin folder to the $PATH env variable. For me was:
/Applications/mampstack-7.1.21-0/php/bin
In terminal run vim ~/.bash_profile to open ~/.bash_profile
Type i to be able to edit the file, add the bin directory as PATH variable on the top to the file:
export PATH="/Applications/mampstack-7.1.21-0/php/bin/:$PATH"
Hit ESC, Type :wq, and hit Enter
In Terminal run source ~/.bash_profile
In Terminal type which php, output should be the path to MAMP PHP install.
I had the same issue on a docker container from php:8.0-fpm-alpine image. I just added the following line in the Dockerfile and it fixed the issue:
RUN apk add mysql-client
I had a similar problem once, turned out the User in the database was created with something like:
CREATE USER 'webpage'#'localhost' IDENTIFIED BY 'password';
worked fine when the connection details php script had localhost, but not when the IP address was there. A quick swap (ip address when creating user and localhost in connection details) revealed those two things have to match.
For everyone if you still strugle with Refusing connection, here is my advice. Download XAMPP or other similar sw and just start MySQL. You dont have to run apache or other things just the MySQL.

SNI issues connecting to Google LDAP server

I'm trying to connect to Google's LDAP server with a cert, the basic code is
ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
$ldap = ldap_connect('ldaps://ldap.google.com', 636);
putenv('LDAPTLS_REQCERT=demand');
putenv("LDAPTLS_CACERT=/etc/ssl/certs/ca-certificates.crt");
putenv("LDAPTLS_CERT=" . path('Google_2024_01_22_49615.crt'));
putenv("LDAPTLS_KEY=" . path('Google_2024_01_22_49615.key'));
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_start_tls($ldap);
ldap_sasl_bind($ldap, null, '', 'EXTERNAL');
$resuts = ldap_search($ldap, 'dc=foo,dc=com', 'uid=*');
print_r(ldap_get_entries($ldap, $searchResults));
It fails on ldap_start_tls with Unable to start TLS: Can't contact LDAP serer, looking into this further I can see the real error is TLS: peer cert untrusted or revoked (0x42) which is caused by hostname (ldap.google.com) does not match common name in certificate (invalid2.invalid). Google returns this cert to indicate that SNI isn't supported (https://support.google.com/a/answer/9190869)
But my PHP version is 7.1.33 compiled in Dec 2020 on Ubuntu 20.04, with OpenLDAP 20449 (SASL Support enabled) and OpenSSL 1.1.1i. So why would I not have SNI supported? Elsewhere I see people using LDAPTLS_REQCERT=never to bypass this problem, but as Google requires a TLS cert & SASL I need to use LDAPTLS_REQCERT=demand or PHP won't let me use the SASL EXTERNAL auth mechanism (https://gist.github.com/heiglandreas/8a299a6f47a13ba463c3f2da41c679f7) and I won't be able to authenticate
It's worth noting on the same machine the following command works perfectly, authenticates with SASL EXTERNAL and lists users LDAPTLS_CERT=Google_2024_01_22_49615.crt LDAPTLS_KEY=Google_2024_01_22_49615.key ldapsearch -X -W -D uid=MyUUID,ou=Users,dc=foo,dc=com -H ldaps://ldap.google.com:636 -b dc=foo,dc=com
I have also tried using the PHP options LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_CACERTDIR, LDAP_OPT_X_TLS_CACERTFILE, LDAP_OPT_X_TLS_KEYFILE and LDAP_OPT_X_TLS_CERTFILE but they don't make a difference
My problem here was using ldap_start_tls and ldap_sasl_bind (or ldap_bind) at the same time when you only need one to open the connection, as-well as using ldap_set_option with the resource like ldap_set_option($ldap, LDAP_OPT_X_TLS_KEYFILE, $keyFilePath); when it should be used on null like ldap_set_option(null, LDAP_OPT_X_TLS_KEYFILE, $keyFilePath); since it's overriding a /etc/ldap/ldap.conf variable.
Following https://www.php.net/manual/en/function.ldap-get-option.php#124601 was useful to figuring this out

PHP on CentOS 7: LDAP could not bind to the server

I have the following code
public function openConnection()
{
$this->ldapServerHandle = ldap_connect(ConfigH::getConfig()->ldap->host);
$bindDN = ConfigH::getConfig()->ldap->serviceAccount->bindDN;
if ($this->ldapServerHandle) {
$this->ldapBindHandle = ldap_bind(
$this->ldapServerHandle,
$bindDN,
ConfigH::getConfig()->ldap->serviceAccount->password
);
if (!$this->ldapBindHandle) {
$errorMsg = "LDAP::__construct(): Could not bind the service account ".$bindDN;
LoggerH::emergency($errorMsg);
throw new LDAPException($errorMsg);
}
} else {
$errorMsg = "LDAP::__construct(): Could not connect to the LDAP server ".ConfigH::getConfig()->ldap->host;
LoggerH::emergency($errorMsg);
throw new LDAPException($errorMsg);
}
}
The issue
I have this error causing me headaches since this morning:
Warning: ldap_bind(): Unable to bind to server: Can't contact LDAP server [...]
Everything worked fine on Windows, when I executed the code on our CentOS production server, it stopped working.
What I have already checked
OpenLDAP is installed and enabled
The LDAP server is reachable from the CentOS server (Kerberos is experiencing no issues on the same machine)
What I have already tried
Re-installed the php-ldap extension
Checked the credentials and the address a milion times
Additional information
ConfigH::getConfig()->ldap->host returns something like "adserver.ourcompany.com", which is the address of our LDAP server
ConfigH::getConfig()->ldap->serviceAccount->bindDN returns a valid bind DN
ConfigH::getConfig()->ldap->serviceAccount->password returns the password of the service account
The solution
Who uses CentOS gets SELinux, yay.
After digging even deeper in Google (such as page 4 of results) and Stackoverflow, I found the issue to be caused by SELinux restricting httpd to communicate over some ports despite the firewall being configured to allow it, including the LDAP one(s).
To allow httpd to communicate over these ports, run the following command
setsebool -P httpd_can_network_connect 1
(Original solution here (WhoIsRich's answer))

PHP ldap_bind is not working on azure with a message can't contact Ldap server

I have a laravel 5 app. With the code below, I am able to successfully authenticate with active directory when on localhost and having the company network cabled plugged to my computer.
public static function connect_ldap($username, $password)
{
$ldapServer = DirectorySetting::where('config_key', 'LdapServerAddress')->value('config_value');
$conn = ldap_connect($ldapServer, 389);
if(!$conn) return false;
ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3);
$bindServerLDAP = #ldap_bind($conn, $username, $password);
if(!$bindServerLDAP) return false;
return $conn;
}
How ever, our test and production server is on Microsoft Azure. When I try to authenticate. I get the error below:
Warning: ldap_bind(): Unable to bind to server: Can't contact LDAP server in /var/www/html/test_ldap.php on line 70
Error Binding to LDAP: No additional information is available
Observation
ldap_connect is successful
I can successfully ping the ldap server address
ldap_bind is unsuccessful. Enabling verbose here doesn't help either. It just tells me that No additional information is available
The system teams says they have created a link between the on premise and azure active dir
My server is CentOS 7, I have enabled the variables httpd_can_network_connect and httpd_can_connect_ldap like below:
sudo setsebool -P httpd_can_network_connect on
sudo setsebool -P httpd_can_connect_ldap on
I have equally added in /etc/openldap/ldap.conf, the variable below:
TLS_REQCERT never
Even with this, it doesn't work.
What could be wrong?

Categories