From 66114ee754049dd2238b29c5f09e6f75e81b4bdd Mon Sep 17 00:00:00 2001 From: Christian Kier Date: Wed, 13 Feb 2008 09:08:45 +1300 Subject: [PATCH 1/7] Allow LDAP drviver to use TLS (closes 1873513) --- config/example-config.php | 8 +++++++- inc/drivers_ldap.php | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/config/example-config.php b/config/example-config.php index 4b076568..0799d7d1 100644 --- a/config/example-config.php +++ b/config/example-config.php @@ -191,7 +191,13 @@ $c->admin_email ='calendar-admin@example.com'; // 'default_value' => array("date_format_type" => "E","locale" => "fr_FR"), /** foreach key set start and length in the string provided by ldap example for openLDAP timestamp : 20070503162215Z **/ -// 'format_updated'=> array('Y' => array(0,4),'m' => array(4,2),'d'=> array(6,2),'H' => array(8,2),'M'=>array(10,2),'S' => array(12,2)) +// 'format_updated'=> array('Y' => array(0,4),'m' => array(4,2),'d'=> array(6,2),'H' => array(8,2),'M'=>array(10,2),'S' => array(12,2)), + +// 'starttls' => 'yes', // If ldap_start_tls is not working, it is probably + // because php wants to validate the server's + // certificate. Try adding "TLS_REQCERT never" to the + // ldap configuration file that php uses (e.g. /etc/ldap.conf + // or /etc/ldap/ldap.conf). Of course, this lessens security! // // ); // diff --git a/inc/drivers_ldap.php b/inc/drivers_ldap.php index ba7be4cc..ae23f765 100644 --- a/inc/drivers_ldap.php +++ b/inc/drivers_ldap.php @@ -66,6 +66,20 @@ class ldapDrivers //Set LDAP protocol version if (isset($config['protocolVersion'])) ldap_set_option($this->connect,LDAP_OPT_PROTOCOL_VERSION, $config['protocolVersion']); + // Start TLS if desired + if (isset($config['starttls'])) { + if (!ldap_set_option($this->connect, LDAP_OPT_PROTOCOL_VERSION, 3)) { + $c->messages[] = sprintf(i18n("Failed to set LDAP Protocol version to 3, TLS not supported.")); + $this->valid=false; + return; + } + if (!ldap_start_tls($this->connect)) { + $c->messages[] = sprintf(i18n("Could not start TLS. Ldap_start_tls() failed.")); + $this->valid=false; + return; + } + } + //connect as root if (!ldap_bind($this->connect,$config['bindDN'],$config['passDN'])){ $bindDN = isset($config['bindDN']) ? $config['bindDN'] : 'anonymous'; From 280e78a461adcac1b3fabcd81ce1e73afc3de602 Mon Sep 17 00:00:00 2001 From: Andrew Ruthven Date: Wed, 13 Feb 2008 09:17:01 +1300 Subject: [PATCH 2/7] Tidy up the TLS bits a little bit. --- config/example-config.php | 14 ++++++++------ inc/drivers_ldap.php | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/config/example-config.php b/config/example-config.php index 0799d7d1..37099f79 100644 --- a/config/example-config.php +++ b/config/example-config.php @@ -169,14 +169,16 @@ $c->admin_email ='calendar-admin@example.com'; //$c->authenticate_hook['call'] = 'LDAP_check'; //$c->authenticate_hook['config'] = array( // 'host' => 'www.tennaxia.net', //host name of your LDAP Server -// 'port' => '389', //port +// 'port' => '389', //port /* For the initial bind to be anonymous leave bindDN and passDN commented out */ -// 'bindDN'=> 'cn=manager,cn=internal,dc=tennaxia,dc=net', //DN to bind to this server enabling to perform request -// 'passDN'=> 'xxxxxxxx', //Password of the previous bindDN to bind to this server enabling to perform request +// DN to bind to this server enabling to perform request +// 'bindDN'=> 'cn=manager,cn=internal,dc=tennaxia,dc=net', +// Password of the previous bindDN to bind to this server enabling to perform request +// 'passDN'=> 'xxxxxxxx', -// 'protocolVersion' => '3', //Version of LDAP protocol to use +// 'protocolVersion' => '3', //Version of LDAP protocol to use // 'baseDNUsers'=> 'dc=tennaxia,dc=net', //where to look at valid user // 'filterUsers' => 'objectClass=kolabInetOrgPerson', //filter which must validate a user according to RFC4515, i.e. surrounded by brackets // 'baseDNGroups' => 'ou=divisions,dc=tennaxia,dc=net', //not used ATM @@ -192,8 +194,8 @@ $c->admin_email ='calendar-admin@example.com'; /** foreach key set start and length in the string provided by ldap example for openLDAP timestamp : 20070503162215Z **/ // 'format_updated'=> array('Y' => array(0,4),'m' => array(4,2),'d'=> array(6,2),'H' => array(8,2),'M'=>array(10,2),'S' => array(12,2)), - -// 'starttls' => 'yes', // If ldap_start_tls is not working, it is probably +// 'startTLS' => 'yes', // Require that TLS is used for LDAP? + // If ldap_start_tls is not working, it is probably // because php wants to validate the server's // certificate. Try adding "TLS_REQCERT never" to the // ldap configuration file that php uses (e.g. /etc/ldap.conf diff --git a/inc/drivers_ldap.php b/inc/drivers_ldap.php index ae23f765..d1b2a127 100644 --- a/inc/drivers_ldap.php +++ b/inc/drivers_ldap.php @@ -66,15 +66,15 @@ class ldapDrivers //Set LDAP protocol version if (isset($config['protocolVersion'])) ldap_set_option($this->connect,LDAP_OPT_PROTOCOL_VERSION, $config['protocolVersion']); - // Start TLS if desired - if (isset($config['starttls'])) { + // Start TLS if desired (requires protocol version 3) + if (isset($config['startTLS'])) { if (!ldap_set_option($this->connect, LDAP_OPT_PROTOCOL_VERSION, 3)) { - $c->messages[] = sprintf(i18n("Failed to set LDAP Protocol version to 3, TLS not supported.")); + $c->messages[] = sprintf(i18n( "drivers_ldap : Failed to set LDAP to use protocol version 3, TLS not supported") ); $this->valid=false; return; } if (!ldap_start_tls($this->connect)) { - $c->messages[] = sprintf(i18n("Could not start TLS. Ldap_start_tls() failed.")); + $c->messages[] = sprintf(i18n( "drivers_ldap : Could not start TLS: ldap_start_tls() failed") ); $this->valid=false; return; } From c4200203ca28e01811052f514e697081895483a2 Mon Sep 17 00:00:00 2001 From: Andrew Ruthven Date: Wed, 13 Feb 2008 10:35:16 +1300 Subject: [PATCH 3/7] Allow specifying the search scope to use. --- config/example-config.php | 2 ++ inc/drivers_ldap.php | 20 ++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/config/example-config.php b/config/example-config.php index 37099f79..d69537e8 100644 --- a/config/example-config.php +++ b/config/example-config.php @@ -200,6 +200,8 @@ $c->admin_email ='calendar-admin@example.com'; // certificate. Try adding "TLS_REQCERT never" to the // ldap configuration file that php uses (e.g. /etc/ldap.conf // or /etc/ldap/ldap.conf). Of course, this lessens security! +// 'scope' => 'subtree', // Search scope to use, defaults to subtree. +// // Allowed values: base, onelevel, subtree. // // ); // diff --git a/inc/drivers_ldap.php b/inc/drivers_ldap.php index d1b2a127..3dd79a7d 100644 --- a/inc/drivers_ldap.php +++ b/inc/drivers_ldap.php @@ -80,6 +80,22 @@ class ldapDrivers } } + //Set the search scope to be used + switch (strtolower($config['scope'])) { + case "base": + $this->ldap_query_one = ldap_read; + $this->ldap_query_all = ldap_read; + break; + case "onelevel": + $this->ldap_query_one = ldap_list; + $this->ldap_query_all = ldap_list; + break; + default: + $this->ldap_query_one = ldap_search; + $this->ldap_query_all = ldap_list; + break; + } + //connect as root if (!ldap_bind($this->connect,$config['bindDN'],$config['passDN'])){ $bindDN = isset($config['bindDN']) ? $config['bindDN'] : 'anonymous'; @@ -102,7 +118,7 @@ class ldapDrivers */ function getAllUsers($attributes){ global $c; - $entry = ldap_list($this->connect,$this->baseDNUsers,$this->filterUsers,$attributes); + $entry = $this->ldap_query_all($this->connect,$this->baseDNUsers,$this->filterUsers,$attributes); if (!ldap_first_entry($this->connect,$entry)) $c->messages[] = sprintf(i18n("Error NoUserFound with filter >%s<, attributes >%s< , dn >%s<"),$this->filterUsers,join(', ',$attributes), $this->baseDNUsers); for($i=ldap_first_entry($this->connect,$entry); @@ -130,7 +146,7 @@ class ldapDrivers $entry=NULL; // We get the DN of the USER - $entry = ldap_search($this->connect, $this->baseDNUsers, $filter,$attributes); + $entry = this->ldap_query($this->connect, $this->baseDNUsers, $filter,$attributes); if ( !ldap_first_entry($this->connect, $entry) ){ dbg_error_log( "ERROR", "drivers_ldap : Unable to find the user with filter %s",$filter ); return false; From 7147b5a0540b7e932e1d4ff398534ae35fdcb135 Mon Sep 17 00:00:00 2001 From: Andrew Ruthven Date: Wed, 13 Feb 2008 11:01:50 +1300 Subject: [PATCH 4/7] Make sure that the scope config variable is set. --- inc/drivers_ldap.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inc/drivers_ldap.php b/inc/drivers_ldap.php index 3dd79a7d..9b084234 100644 --- a/inc/drivers_ldap.php +++ b/inc/drivers_ldap.php @@ -80,7 +80,8 @@ class ldapDrivers } } - //Set the search scope to be used + //Set the search scope to be used, default to subtree. + if (!isset($config['scope'])) $config['scope'] = 'subtree'; switch (strtolower($config['scope'])) { case "base": $this->ldap_query_one = ldap_read; From de50126b6e65f94897e4d873e571fee8e379f346 Mon Sep 17 00:00:00 2001 From: Andrew Ruthven Date: Wed, 13 Feb 2008 11:28:40 +1300 Subject: [PATCH 5/7] Fix the deferencing of the query variables for LDAP scope to work. --- inc/drivers_ldap.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/inc/drivers_ldap.php b/inc/drivers_ldap.php index 9b084234..648d1043 100644 --- a/inc/drivers_ldap.php +++ b/inc/drivers_ldap.php @@ -119,7 +119,9 @@ class ldapDrivers */ function getAllUsers($attributes){ global $c; - $entry = $this->ldap_query_all($this->connect,$this->baseDNUsers,$this->filterUsers,$attributes); + + $query = $this->ldap_query_all; + $entry = $query($this->connect,$this->baseDNUsers,$this->filterUsers,$attributes); if (!ldap_first_entry($this->connect,$entry)) $c->messages[] = sprintf(i18n("Error NoUserFound with filter >%s<, attributes >%s< , dn >%s<"),$this->filterUsers,join(', ',$attributes), $this->baseDNUsers); for($i=ldap_first_entry($this->connect,$entry); @@ -147,7 +149,8 @@ class ldapDrivers $entry=NULL; // We get the DN of the USER - $entry = this->ldap_query($this->connect, $this->baseDNUsers, $filter,$attributes); + $query = $this->ldap_query_one; + $entry = $query($this->connect, $this->baseDNUsers, $filter,$attributes); if ( !ldap_first_entry($this->connect, $entry) ){ dbg_error_log( "ERROR", "drivers_ldap : Unable to find the user with filter %s",$filter ); return false; From 0bc51a9e3914eb4128160ee78f1ab1cf15267580 Mon Sep 17 00:00:00 2001 From: Andrew Ruthven Date: Wed, 13 Feb 2008 12:33:27 +1300 Subject: [PATCH 6/7] Work on "Sync LDAP with RSCDS" feature. * Use an ugly hack so that users that are updated using the Sync LDAP feature retain their user_no. Otherwise a new user_no was selected, and the insert failed since the username already existed. * Tidy up the output messages to be more consistent. * Only display "updating user records" if users were updated. --- inc/drivers_ldap.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/inc/drivers_ldap.php b/inc/drivers_ldap.php index 648d1043..8d312e6e 100644 --- a/inc/drivers_ldap.php +++ b/inc/drivers_ldap.php @@ -349,7 +349,7 @@ function sync_LDAP(){ $usr_in .= ', ' . qpg($v); } $usr_in = substr($usr_in,1); - $c->messages[] = sprintf(i18n('- deactivating users : %s'),$usr_in); + $c->messages[] = sprintf(i18n('- deactivating users : %s'),join(', ',$users_to_deactivate)); $qry = new PgQuery( "UPDATE usr SET active = FALSE WHERE lower(username) IN ($usr_in)"); $qry->Exec('sync_LDAP',__LINE__,__FILE__); } @@ -360,6 +360,9 @@ function sync_LDAP(){ $valid=$ldap_users_info[$username]; $ldap_timestamp = $valid[$mapping["updated"]]; + $valid["user_no"] = $db_users_info[$username]["user_no"]; + $mapping["user_no"] = "user_no"; + /** * This splits the LDAP timestamp apart and assigns values to $Y $m $d $H $M and $S */ @@ -377,9 +380,10 @@ function sync_LDAP(){ $users_nothing_done[] = $username; } } - $c->messages[] = sprintf(i18n('- updating user record %s'),join(', ',$users_to_update)); + if ( sizeof($users_to_update) ) + $c->messages[] = sprintf(i18n('- updating user records : %s'),join(', ',$users_to_update)); if ( sizeof($users_nothing_done) ) - $c->messages[] = sprintf(i18n('- nothing done on %s'),join(', ', $users_nothing_done)); + $c->messages[] = sprintf(i18n('- nothing done on : %s'),join(', ', $users_nothing_done)); } } } From 256bf9d32857cf74e207f0c46f1c2eca09d49759 Mon Sep 17 00:00:00 2001 From: Andrew Ruthven Date: Wed, 13 Feb 2008 12:46:20 +1300 Subject: [PATCH 7/7] Handle the case where sync_LDAP doesn't find any users in LDAP. --- inc/drivers_ldap.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inc/drivers_ldap.php b/inc/drivers_ldap.php index 8d312e6e..451fd0d1 100644 --- a/inc/drivers_ldap.php +++ b/inc/drivers_ldap.php @@ -302,6 +302,10 @@ function sync_LDAP(){ $mapping = $c->authenticate_hook['config']['mapping_field']; $attributes = array_values($mapping); $ldap_users_tmp = $ldapDriver->getAllUsers($attributes); + + if ( sizeof($ldap_users_tmp) == 0 ) + return; + foreach($ldap_users_tmp as $key => $ldap_user){ $ldap_users_info[$ldap_user[$mapping["username"]]] = $ldap_user; unset($ldap_users_tmp[$key]);