diff options
| author | alec <alec@208e9e7b-5314-0410-a742-e7e81cd9613c> | 2010-08-01 08:49:15 +0000 |
|---|---|---|
| committer | alec <alec@208e9e7b-5314-0410-a742-e7e81cd9613c> | 2010-08-01 08:49:15 +0000 |
| commit | a51420908555026339ec490fae346dfca4d9eb28 (patch) | |
| tree | e08f4e157932a5dd1f431a10006f780df6d766eb /plugins/password | |
| parent | 22f2a38247bf4b7032f126fb4a703049167e9e25 (diff) | |
- Added ldap_simple driver
git-svn-id: https://svn.roundcube.net/trunk@3850 208e9e7b-5314-0410-a742-e7e81cd9613c
Diffstat (limited to 'plugins/password')
| -rw-r--r-- | plugins/password/README | 16 | ||||
| -rw-r--r-- | plugins/password/config.inc.php.dist | 4 | ||||
| -rw-r--r-- | plugins/password/drivers/ldap_simple.php | 226 | ||||
| -rw-r--r-- | plugins/password/package.xml | 27 |
4 files changed, 266 insertions, 7 deletions
diff --git a/plugins/password/README b/plugins/password/README index 488d7f449..5312cbf46 100644 --- a/plugins/password/README +++ b/plugins/password/README @@ -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 ------------- diff --git a/plugins/password/config.inc.php.dist b/plugins/password/config.inc.php.dist index 4030c008a..9ac71aef7 100644 --- a/plugins/password/config.inc.php.dist +++ b/plugins/password/config.inc.php.dist @@ -79,8 +79,8 @@ $rcmail_config['password_pop_port'] = 106; $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'); diff --git a/plugins/password/drivers/ldap_simple.php b/plugins/password/drivers/ldap_simple.php new file mode 100644 index 000000000..fbe2edd97 --- /dev/null +++ b/plugins/password/drivers/ldap_simple.php @@ -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@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; +} diff --git a/plugins/password/package.xml b/plugins/password/package.xml index a280d3ed3..dfa57e88b 100644 --- a/plugins/password/package.xml +++ b/plugins/password/package.xml @@ -15,10 +15,10 @@ <email>alec@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> |
