summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
authoralecpl <alec@alec.pl>2011-02-17 14:35:06 +0000
committeralecpl <alec@alec.pl>2011-02-17 14:35:06 +0000
commit4d982d38a85567491a163d2f1561ad938640dea2 (patch)
tree75ba9f085ca2e957ab23dd68b7ec4bc99af55a0c /program
parent261ea440ddf65c9152089faf9f66ca51629e28d0 (diff)
- Add LDAP SASL bind and proxy authentication (#1486692)
Diffstat (limited to 'program')
-rw-r--r--program/include/rcube_ldap.php84
1 files changed, 77 insertions, 7 deletions
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',
@@ -217,6 +234,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
*
* @param string Bind DN