From 4d982d38a85567491a163d2f1561ad938640dea2 Mon Sep 17 00:00:00 2001 From: alecpl Date: Thu, 17 Feb 2011 14:35:06 +0000 Subject: - Add LDAP SASL bind and proxy authentication (#1486692) --- program/include/rcube_ldap.php | 84 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 7 deletions(-) (limited to 'program') diff --git a/program/include/rcube_ldap.php b/program/include/rcube_ldap.php index 308c4f238..c8253713b 100644 --- a/program/include/rcube_ldap.php +++ b/program/include/rcube_ldap.php @@ -162,11 +162,16 @@ class rcube_ldap extends rcube_addressbook { $this->ready = true; + $bind_pass = $this->prop['bind_pass']; + $bind_user = $this->prop['bind_user']; + $bind_dn = $this->prop['bind_dn']; + $base_dn = $this->prop['base_dn']; + // User specific access, generate the proper values to use. if ($this->prop['user_specific']) { // No password set, use the session password - if (empty($this->prop['bind_pass'])) { - $this->prop['bind_pass'] = $RCMAIL->decrypt($_SESSION['password']); + if (empty($bind_pass)) { + $bind_pass = $RCMAIL->decrypt($_SESSION['password']); } // Get the pieces needed for variable replacement. @@ -190,19 +195,31 @@ class rcube_ldap extends rcube_addressbook $this->_debug("S: search returned dn: $bind_dn"); if ($bind_dn) { - $this->prop['bind_dn'] = $bind_dn; $dn = ldap_explode_dn($bind_dn, 1); $replaces['%dn'] = $dn[0]; } } } // Replace the bind_dn and base_dn variables. - $this->prop['bind_dn'] = strtr($this->prop['bind_dn'], $replaces); - $this->prop['base_dn'] = strtr($this->prop['base_dn'], $replaces); + $bind_dn = strtr($bind_dn, $replaces); + $base_dn = strtr($base_dn, $replaces); + + if (empty($bind_user)) { + $bind_user = $u; + } } - if (!empty($this->prop['bind_dn']) && !empty($this->prop['bind_pass'])) - $this->ready = $this->_bind($this->prop['bind_dn'], $this->prop['bind_pass']); + if (!empty($bind_pass)) { + if (!empty($bind_dn)) { + $this->ready = $this->_bind($bind_dn, $bind_pass); + } + else if (!empty($this->prop['auth_cid'])) { + $this->ready = $this->_sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user); + } + else { + $this->ready = $this->_sasl_bind($bind_user, $bind_pass); + } + } } else raise_error(array('code' => 100, 'type' => 'ldap', @@ -216,6 +233,59 @@ class rcube_ldap extends rcube_addressbook } + /** + * Bind connection with (SASL-) user and password + * + * @param string $authc Authentication user + * @param string $pass Bind password + * @param string $authz Autorization user + * + * @return boolean True on success, False on error + */ + private function _sasl_bind($authc, $pass, $authz=null) + { + if (!$this->conn) { + return false; + } + + if (!function_exists('ldap_sasl_bind')) { + raise_error(array( + 'code' => 100, 'type' => 'ldap', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Unable to bind: ldap_sasl_bind() not exists"), + true, true); + } + + if (!empty($authz)) { + $authz = 'u:' . $authz; + } + + if (!empty($this->prop['auth_method'])) { + $method = $this->prop['auth_method']; + } + else { + $method = 'DIGEST-MD5'; + } + + $this->_debug("C: Bind [mech: $method, authc: $authc, authz: $authz] [pass: $pass]"); + + if (ldap_sasl_bind($this->conn, NULL, $pass, $method, NULL, $authc, $authz)) { + $this->_debug("S: OK"); + return true; + } + + $this->_debug("S: ".ldap_error($this->conn)); + + raise_error(array( + 'code' => ldap_errno($this->conn), 'type' => 'ldap', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Bind failed for authcid=$authc ".ldap_error($this->conn)), + true); + + return false; + } + + /** * Bind connection with DN and password * -- cgit v1.2.3