From e3e31af4f09c8e1932040d6f151075369559f2bb Mon Sep 17 00:00:00 2001
From: Damien Regad <damien.regad@merckserono.net>
Date: Thu, 4 Nov 2010 16:05:15 +0100
Subject: [PATCH 2/2] Fix #12167: Improve LDAP logging and comments in config_defaults.php

Document the fact that LDAP port parameter is not used by ldap_connect when the provided hostname is a URI, and modify the logging in ldap_api.php to correctly reflect what is actually happening to avoid creating confusion.

Implemented also additional improvements to LDAP logging, allowing to fully trace what is happening throughout the LDAP authentication process.
---
 config_defaults_inc.php |   11 +++++++++--
 core/ldap_api.php       |   38 +++++++++++++++++++++++++++++++-------
 2 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/config_defaults_inc.php b/config_defaults_inc.php
index b3f8bd8..276a55a 100644
--- a/config_defaults_inc.php
+++ b/config_defaults_inc.php
@@ -1641,13 +1641,20 @@
 	 **************************/
 
 	/**
+	 * The LDAP server can be provided either as
+	 * - a simple hostname (in that case, g_ldap_port must be defined)
+	 * - a complete URI (then g_ldap_port is ignored, and the port number
+	 *   has to be specified as part of the URI itself, e.g.
+	 *   ldaps://ldap.example.com:636/)
 	 *
 	 * @global string $g_ldap_server
 	 */
-	$g_ldap_server			= 'ldaps://ldap.example.com.au/';
+	$g_ldap_server			= 'ldap.example.com';
 
 	/**
-	 * LDAP port (default 389).  If this doesn't work, try 636.
+	 * LDAP port (default 389).  If this doesn't work, try 636 (ldaps)
+	 * or for Active Directory Global Catalog forest-wide search,
+	 * default port 3268 (ldap) or 3269 (ldaps)
 	 *
 	 * @global integer $g_ldap_port
 	 */
diff --git a/core/ldap_api.php b/core/ldap_api.php
index d962afc..d5bb248 100644
--- a/core/ldap_api.php
+++ b/core/ldap_api.php
@@ -38,10 +38,27 @@ function ldap_connect_bind( $p_binddn = '', $p_password = '' ) {
 	$t_ldap_server = config_get( 'ldap_server' );
 	$t_ldap_port = config_get( 'ldap_port' );
 
-	log_event( LOG_LDAP, "Attempting connection to LDAP server '{$t_ldap_server}' port '{$t_ldap_port}'." );
-	$t_ds = @ldap_connect( $t_ldap_server, $t_ldap_port );
+    # Verify if LDAP server provided is a URI or just a host name
+    # Connect and log accordingly
+    $t_message = "Attempting connection to LDAP ";
+    $t_ldap_uri = parse_url( $t_ldap_server );
+    if ( count( $t_ldap_uri ) > 1 ) {
+        $t_message .= "URI '{$t_ldap_server}'.";
+        $t_ds = @ldap_connect( $t_ldap_server );
+    } else {
+        $t_message .= "server '{$t_ldap_server}' port '{$t_ldap_port}'.";
+        if (is_numeric( $t_ldap_port ) ) {
+            $t_ds = @ldap_connect( $t_ldap_server, $t_ldap_port );
+        } else {
+            log_event( LOG_LDAP, "ERROR - LDAP port '$t_ldap_port' is not numeric" );
+            trigger_error( ERROR_LDAP_SERVER_CONNECT_FAILED, ERROR );
+            return false;
+        }
+    }
+    log_event( LOG_LDAP, $t_message );
+    
 	if ( $t_ds !== false && $t_ds > 0 ) {
-		log_event( LOG_LDAP, "Connection accepted to LDAP server" );
+		log_event( LOG_LDAP, "Connection accepted by LDAP server" );
 		$t_protocol_version = config_get( 'ldap_protocol_version' );
 
 		if( $t_protocol_version > 0 ) {
@@ -70,10 +87,10 @@ function ldap_connect_bind( $p_binddn = '', $p_password = '' ) {
 		}
 
 		if ( !$t_br ) {
-			log_event( LOG_LDAP, "bind to ldap server  failed - authentication error?" );
+			log_event( LOG_LDAP, "Bind to ldap server failed - authentication error?" );
 			trigger_error( ERROR_LDAP_AUTH_FAILED, ERROR );
 		} else {
-			log_event( LOG_LDAP, "bind to ldap server successful" );
+			log_event( LOG_LDAP, "Bind to ldap server successful" );
 		}
 	} else {
 		log_event( LOG_LDAP, "Connection to ldap server failed" );
@@ -332,10 +349,11 @@ function ldap_authenticate_by_username( $p_username, $p_password ) {
 
 		$t_authenticated = false;
 
-		if ( $t_info ) {
+		if ( $t_info['count'] > 0 ) {
 			# Try to authenticate to each until we get a match
 			for ( $i = 0; $i < $t_info['count']; $i++ ) {
 				$t_dn = $t_info[$i]['dn'];
+                log_event( LOG_LDAP, "Checking {$t_info[$i]['dn']}" );
 
 				# Attempt to bind with the DN and password
 				if ( @ldap_bind( $t_ds, $t_dn, $p_password ) ) {
@@ -343,8 +361,11 @@ function ldap_authenticate_by_username( $p_username, $p_password ) {
 					break;
 				}
 			}
+		} else {
+		    log_event( LOG_LDAP, "No matching entries found" );
 		}
-
+		
+		log_event( LOG_LDAP, "Unbinding from LDAP server" );
 		ldap_free_result( $t_sr );
 		ldap_unbind( $t_ds );
 	}
@@ -368,6 +389,9 @@ function ldap_authenticate_by_username( $p_username, $p_password ) {
 				user_set_field( $t_user_id, 'email', $t_email );
 			}
 		}
+        log_event( LOG_LDAP, "User '$p_username' authenticated" );
+	} else {
+        log_event( LOG_LDAP, "Authentication failed" );
 	}
 
 	return $t_authenticated;
-- 
1.7.1

