summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/password/README16
-rw-r--r--plugins/password/config.inc.php.dist4
-rw-r--r--plugins/password/drivers/ldap_simple.php226
-rw-r--r--plugins/password/package.xml27
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>