From 4462ad8df344895eec89a5670a4a83b9afde047d Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <machniak@kolabsys.com>
Date: Wed, 31 May 2023 13:28:49 +0200
Subject: [PATCH] Improve host/port handling

---
 lib/Net/LDAP3.php | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/lib/Net/LDAP3.php b/lib/Net/LDAP3.php
index d4c88ce..e0ee15c 100644
--- a/lib/Net/LDAP3.php
+++ b/lib/Net/LDAP3.php
@@ -609,9 +609,10 @@ class Net_LDAP3
         $port  = $this->config_get('port', 389);
 
         foreach ((array) $hosts as $host) {
-            $this->_debug("C: Connect [" . $host . (strpos($host, ':') ? '' : ":$port") . "]");
+            $ldap_uri = $this->_host2uri($host, $port);
+            $this->_debug("C: Connect [{$ldap_uri}]");
 
-            if ($lc = @ldap_connect($host, $port)) {
+            if ($lc = @ldap_connect($ldap_uri)) {
                 if ($this->config_get('use_tls', false) === true) {
                     if (!ldap_start_tls($lc)) {
                         $this->_debug("S: Could not start TLS. " . ldap_error($lc));
@@ -635,7 +636,7 @@ class Net_LDAP3
                     ldap_set_option($lc, LDAP_OPT_REFERRALS, (bool) $referrals);
                 }
 
-                $this->_current_host = $host . (strpos($host, ':') ? '' : ":$port");
+                $this->_current_host = $ldap_uri;
                 $this->conn          = $lc;
 
                 break;
@@ -789,7 +790,7 @@ class Net_LDAP3
             $moz_ldapsearch,
             '-x',
             '-h',
-            preg_replace('|^[a-z]+://|i', '', $this->_current_host),
+            parse_url($this->_current_host, PHP_URL_HOST),
             '-b',
             escapeshellarg($entry_dn),
             '-s',
@@ -802,9 +803,11 @@ class Net_LDAP3
 
         if ($moz_ldapsearch != "/usr/bin/ldapsearch") {
             $command[] = '-p';
-            $command[] = $this->config_get('port', 389);
+            $command[] = parse_url($this->_current_host, PHP_URL_PORT);
         }
 
+        // TODO: Can we use -H instead of -h and -p?
+
         if ($this->vendor_name() == "Oracle Corporation") {
             // For Oracle DSEE
             $command[] = "-J";
@@ -2961,6 +2964,26 @@ class Net_LDAP3
         return implode(unpack("H*", $str));
     }
 
+    /**
+     * Convert LDAP host/port into URI
+     */
+    private static function _host2uri($host, $port = null)
+    {
+        if (stripos($host, 'ldapi://') === 0) {
+            return $host;
+        }
+
+        if (strpos($host, '://') === false) {
+            $host = ($port == 636 ? 'ldaps' : 'ldap') . '://' . $host;
+        }
+
+        if ($port && !preg_match('/:[0-9]+$/', $host)) {
+            $host .= ':' . $port;
+        }
+
+        return $host;
+    }
+
     /**
      * Get global handle for cache access
      *
-- 
GitLab