[Svn] r3850 - in trunk/plugins/password: . drivers

trac at roundcube.net trac at roundcube.net
Sun Aug 1 10:49:15 CEST 2010


Author: alec
Date: 2010-08-01 03:49:15 -0500 (Sun, 01 Aug 2010)
New Revision: 3850

Added:
   trunk/plugins/password/drivers/ldap_simple.php
Modified:
   trunk/plugins/password/README
   trunk/plugins/password/config.inc.php.dist
   trunk/plugins/password/package.xml
Log:
- Added ldap_simple driver


Modified: trunk/plugins/password/README
===================================================================
--- trunk/plugins/password/README	2010-07-31 11:36:34 UTC (rev 3849)
+++ trunk/plugins/password/README	2010-08-01 08:49:15 UTC (rev 3850)
@@ -37,6 +37,7 @@
  2.9.   hMailServer (hmail)
  2.10.  PAM (pam)
  2.11.  Chpasswd (chpasswd)
+ 2.12.  LDAP - no PEAR (ldap_simple)
  3.	Driver API
 
 
@@ -222,6 +223,21 @@
  the 'chpasswd' command. See config.inc.php file.
 
 
+ 2.12.  LDAP - no PEAR (ldap_simple)
+ -----------------------------------
+
+ It's rewritten ldap driver that doesn't require the Net_LDAP2 PEAR extension.
+ It uses directly PHP's ldap module functions instead (as Roundcube does).
+
+ This driver is fully compatible with the ldap driver, but
+ does not require (or uses) the
+    $rcmail_config['password_ldap_force_replace'] variable.
+ Other advantages:
+    * Connects only once with the LDAP server when using the search user.
+    * Does not read the DN, but only replaces the password within (that is
+      why the 'force replace' is always used).
+
+
  3. Driver API
  -------------
 

Modified: trunk/plugins/password/config.inc.php.dist
===================================================================
--- trunk/plugins/password/config.inc.php.dist	2010-07-31 11:36:34 UTC (rev 3849)
+++ trunk/plugins/password/config.inc.php.dist	2010-08-01 08:49:15 UTC (rev 3850)
@@ -79,8 +79,8 @@
 $rcmail_config['password_saslpasswd_args'] = '';
 
 
-// LDAP Driver options
-// -------------------
+// LDAP and LDAP_SIMPLE Driver options
+// -----------------------------------
 // LDAP server name to connect to. 
 // You can provide one or several hosts in an array in which case the hosts are tried from left to right.
 // Exemple: array('ldap1.exemple.com', 'ldap2.exemple.com');

Added: trunk/plugins/password/drivers/ldap_simple.php
===================================================================
--- trunk/plugins/password/drivers/ldap_simple.php	                        (rev 0)
+++ trunk/plugins/password/drivers/ldap_simple.php	2010-08-01 08:49:15 UTC (rev 3850)
@@ -0,0 +1,226 @@
+<?php
+/**
+ * Simple LDAP Password Driver
+ *
+ * Driver for passwords stored in LDAP
+ * This driver is based on Edouard's LDAP Password Driver, but does not
+ * require PEAR's Net_LDAP2 to be installed
+ * 
+ * @version 1.0 (2010-07-31)
+ * @author Wout Decre <wout at canodus.be>
+ */
+function password_save($curpass, $passwd)
+{
+	$rcmail = rcmail::get_instance();
+	
+	/* Connect */
+	if (!$ds = ldap_connect($rcmail->config->get('password_ldap_host'), $rcmail->config->get('password_ldap_port'))) {
+		ldap_unbind($ds);
+		return PASSWORD_CONNECT_ERROR;
+	}
+
+	/* Set protocol version */	
+	if (!ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $rcmail->config->get('password_ldap_version'))) {
+		ldap_unbind($ds);
+		return PASSWORD_CONNECT_ERROR;
+	}
+	
+	/* Start TLS */
+	if ($rcmail->config->get('password_ldap_starttls')) {
+		if (!ldap_start_tls($ds)) {
+			ldap_unbind($ds);
+			return PASSWORD_CONNECT_ERROR;
+		}
+	}
+
+	/* Build user DN */
+	if ($user_dn = $rcmail->config->get('password_ldap_userDN_mask')) {
+		$user_dn = ldap_simple_substitute_vars($user_dn);
+	} else {
+		$user_dn = ldap_simple_search_userdn($rcmail, $ds);
+	}
+	
+	if (empty($user_dn)) {
+		ldap_unbind($ds);
+		return PASSWORD_CONNECT_ERROR;
+	}
+	
+	/* Connection method */
+	switch ($rcmail->config->get('password_ldap_method')) {
+		case 'admin':
+			$binddn = $rcmail->config->get('password_ldap_adminDN');
+			$bindpw = $rcmail->config->get('password_ldap_adminPW');
+			break;
+		case 'user':
+		default:
+			$binddn = $user_dn;
+			$bindpw = $curpass;
+			break;
+	}
+
+	/* Bind */
+	if (!ldap_bind($ds, $binddn, $bindpw)) {
+		ldap_unbind($ds);
+		return PASSWORD_CONNECT_ERROR;
+	}
+	
+	/* Crypting new password */
+	$passwd = ldap_simple_hash_password($passwd, $rcmail->config->get('password_ldap_encodage'));
+	if (!$passwd) {
+		ldap_unbind($ds);
+		return PASSWORD_CRYPT_ERROR;
+	}
+	
+	$entree[$rcmail->config->get('password_ldap_pwattr')] = $passwd;
+	
+	if (!ldap_modify($ds, $user_dn, $entree)) {
+		ldap_unbind($ds);
+		return PASSWORD_CONNECT_ERROR;
+	}
+	
+	/* All done, no error */
+	ldap_unbind($ds);
+	return PASSWORD_SUCCESS;
+}
+
+/**
+ * Bind with searchDN and searchPW and search for the user's DN
+ * Use search_base and search_filter defined in config file
+ * Return the found DN
+ */
+function ldap_simple_search_userdn($rcmail, $ds)
+{
+	/* Bind */
+	if (!ldap_bind($ds, $rcmail->config->get('password_ldap_searchDN'), $rcmail->config->get('password_ldap_searchPW'))) {
+		return false;
+	}
+	
+	/* Search for the DN */
+	if (!$sr = ldap_search($ds, $rcmail->config->get('password_ldap_search_base'), ldap_simple_substitute_vars($rcmail->config->get('password_ldap_search_filter')))) {
+		return false;
+	}
+	
+	/* If no or more entries were found, return false */
+	if (ldap_count_entries($ds, $sr) != 1) {
+		return false;
+	}
+	
+	return ldap_get_dn($ds, ldap_first_entry($ds, $sr));
+}
+
+/**
+ * Substitute %login, %name and %domain in $str
+ * See plugin config for details
+ */
+function ldap_simple_substitute_vars($str)
+{
+	$str = str_replace('%login', $_SESSION['username'], $str);
+	$str = str_replace('%l', $_SESSION['username'], $str);
+	
+	$parts = explode('@', $_SESSION['username']);
+	if (count($parts) == 2) {
+		$str = str_replace('%name', $parts[0], $str);
+		$str = str_replace('%n', $parts[0], $str);
+		
+		$str = str_replace('%domain', $parts[1], $str);
+		$str = str_replace('%d', $parts[1], $str);
+	}
+
+	return $str;
+}
+
+/**
+ * Code originaly from the phpLDAPadmin development team
+ * http://phpldapadmin.sourceforge.net/
+ *
+ * Hashes a password and returns the hash based on the specified enc_type
+ */
+function ldap_simple_hash_password($password_clear, $encodage_type)
+{
+	$encodage_type = strtolower($encodage_type);
+	switch ($encodage_type) {
+		case 'crypt':
+			$crypted_password = '{CRYPT}' . crypt($password_clear, ldap_simple_random_salt(2));
+			break;
+		case 'ext_des':
+			/* Extended DES crypt. see OpenBSD crypt man page */
+			if (!defined('CRYPT_EXT_DES') || CRYPT_EXT_DES == 0) {
+				/* Your system crypt library does not support extended DES encryption */
+				return false;
+			}
+			$crypted_password = '{CRYPT}' . crypt($password_clear, '_' . ldap_simple_random_salt(8));
+			break;
+		case 'md5crypt':
+			if (!defined('CRYPT_MD5') || CRYPT_MD5 == 0) {
+				/* Your system crypt library does not support md5crypt encryption */
+				return false;
+			}
+			$crypted_password = '{CRYPT}' . crypt($password_clear, '$1$' . ldap_simple_random_salt(9));
+			break;
+		case 'blowfish':
+			if (!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH == 0) {
+				/* Your system crypt library does not support blowfish encryption */
+				return false;
+			}
+			/* Hardcoded to second blowfish version and set number of rounds */
+			$crypted_password = '{CRYPT}' . crypt($password_clear, '$2a$12$' . ldap_simple_random_salt(13));
+			break;
+		case 'md5':
+			$crypted_password = '{MD5}' . base64_encode(pack('H*', md5($password_clear)));
+			break;
+		case 'sha':
+			if (function_exists('sha1')) {
+				/* Use PHP 4.3.0+ sha1 function, if it is available */
+				$crypted_password = '{SHA}' . base64_encode(pack('H*', sha1($password_clear)));
+			} else if (function_exists('mhash')) {
+				$crypted_password = '{SHA}' . base64_encode(mhash(MHASH_SHA1, $password_clear));
+			} else {
+				/* Your PHP install does not have the mhash() function */
+				return false;
+			}
+			break;
+		case 'ssha':
+			if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) {
+				mt_srand((double) microtime() * 1000000 );
+				$salt = mhash_keygen_s2k(MHASH_SHA1, $password_clear, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
+				$crypted_password = '{SSHA}' . base64_encode(mhash(MHASH_SHA1, $password_clear . $salt) . $salt);
+			} else {
+				/* Your PHP install does not have the mhash() function */
+				return false;
+			}
+			break;
+		case 'smd5':
+			if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) {
+				mt_srand((double) microtime() * 1000000 );
+				$salt = mhash_keygen_s2k(MHASH_MD5, $password_clear, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
+				$crypted_password = '{SMD5}' . base64_encode(mhash(MHASH_MD5, $password_clear . $salt) . $salt);
+			} else {
+				/* Your PHP install does not have the mhash() function */
+				return false;
+			}
+			break;
+		case 'clear':
+		default:
+			$crypted_password = $password_clear;
+	}
+
+	return $crypted_password;
+}
+
+/**
+ * Code originaly from the phpLDAPadmin development team
+ * http://phpldapadmin.sourceforge.net/
+ *
+ * Used to generate a random salt for crypt-style passwords
+ */
+function ldap_simple_random_salt($length)
+{
+	$possible = '0123456789' . 'abcdefghijklmnopqrstuvwxyz' . 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . './';
+	$str = '';
+	// mt_srand((double)microtime() * 1000000);
+	while (strlen($str) < $length) {
+		$str .= substr($possible, (rand() % strlen($possible)), 1);
+	}
+	
+	return $str;
+}

Modified: trunk/plugins/password/package.xml
===================================================================
--- trunk/plugins/password/package.xml	2010-07-31 11:36:34 UTC (rev 3849)
+++ trunk/plugins/password/package.xml	2010-08-01 08:49:15 UTC (rev 3850)
@@ -15,10 +15,10 @@
 		<email>alec at alec.pl</email>
 		<active>yes</active>
 	</lead>
-	<date>2010-06-20</date>
-	<time>12:00:00</time>
+	<date>2010-08-01</date>
+	<time>09:00:00</time>
 	<version>
-		<release>1.5</release>
+		<release>1.6</release>
 		<api>1.5</api>
 	</version>
 	<stability>
@@ -27,8 +27,7 @@
 	</stability>
 	<license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
 	<notes>
-- Removed user_login/username_local/username_domain methods,
-  use rcube_user::get_username instead (#1486707)
+- Added ldap_simple driver
     </notes>
 	<contents>
 		<dir baseinstalldir="/" name="/">
@@ -72,6 +71,7 @@
             <file name="drivers/chpasswd.php" role="php"></file>
             <file name="drivers/directadmin.php" role="php"></file>
             <file name="drivers/ldap.php" role="php"></file>
+            <file name="drivers/ldap_simple.php" role="php"></file>
             <file name="drivers/poppassd.php" role="php"></file>
             <file name="drivers/sql.php" role="php"></file>
             <file name="drivers/vpopmaild.php" role="php"></file>
@@ -116,5 +116,22 @@
 - Created package.xml
             </notes>
 	    </release>
+        <release>
+	        <date>2010-06-20</date>
+	        <time>12:00:00</time>
+	        <version>
+		        <release>1.5</release>
+		        <api>1.5</api>
+	        </version>
+	        <stability>
+		        <release>stable</release>
+		        <api>stable</api>
+	        </stability>
+	        <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+	        <notes>
+- Removed user_login/username_local/username_domain methods,
+  use rcube_user::get_username instead (#1486707)
+            </notes>
+        </release>
 	</changelog>
 </package>

_______________________________________________
http://lists.roundcube.net/mailman/listinfo/svn



More information about the Svn mailing list