Plugin API: Added 'ldap_connected' hook

pull/6540/head
Aleksander Machniak 6 years ago
parent 394dacc1ae
commit c1aa2169f6

@ -12,6 +12,7 @@ CHANGELOG Roundcube Webmail
- Update to TinyMCE 4.8.2 - Update to TinyMCE 4.8.2
- Plugin API: Added 'raise_error' hook (#6199) - Plugin API: Added 'raise_error' hook (#6199)
- Plugin API: Added 'common_headers' hook (#6385) - Plugin API: Added 'common_headers' hook (#6385)
- Plugin API: Added 'ldap_connected' hook
- Enigma: Update to OpenPGPjs 4.2.1 - fixes user name encoding issues in key generation (#6524) - Enigma: Update to OpenPGPjs 4.2.1 - fixes user name encoding issues in key generation (#6524)
- Managesieve: Added support for 'editheader' extension - RFC5293 (#5954) - Managesieve: Added support for 'editheader' extension - RFC5293 (#5954)
- Markasjunk: Integrate markasjunk2 features into markasjunk - marking as non-junk + learning engine (#6504) - Markasjunk: Integrate markasjunk2 features into markasjunk - marking as non-junk + learning engine (#6504)

@ -284,23 +284,27 @@ class rcube_ldap extends rcube_addressbook
$this->readonly = false; $this->readonly = false;
} }
$bind_pass = $this->prop['bind_pass']; // trigger post-connect hook
$bind_user = $this->prop['bind_user']; $rcube = rcube::get_instance();
$bind_dn = $this->prop['bind_dn']; $conf = $rcube->plugins->exec_hook('ldap_connected', $this->prop + array('host' => $host));
$auth_method = $this->prop['auth_method'];
$this->base_dn = $this->prop['base_dn']; $bind_pass = $conf['bind_pass'];
$this->groups_base_dn = $this->prop['groups']['base_dn'] ?: $this->base_dn; $bind_user = $conf['bind_user'];
$bind_dn = $conf['bind_dn'];
$auth_method = $conf['auth_method'];
$this->base_dn = $conf['base_dn'];
$this->groups_base_dn = $conf['groups']['base_dn'] ?: $this->base_dn;
// User specific access, generate the proper values to use. // User specific access, generate the proper values to use.
if ($this->prop['user_specific']) { if ($conf['user_specific']) {
// No password set, use the session password // No password set, use the session password
if (empty($bind_pass)) { if (empty($bind_pass)) {
$bind_pass = $rcube->get_user_password(); $bind_pass = $rcube->get_user_password();
} }
// Get the pieces needed for variable replacement. // Get the pieces needed for variable replacement.
if ($fu = ($rcube->get_user_email() ?: $this->prop['username'])) { if ($fu = ($rcube->get_user_email() ?: $conf['username'])) {
list($u, $d) = explode('@', $fu); list($u, $d) = explode('@', $fu);
} }
else { else {
@ -310,50 +314,49 @@ class rcube_ldap extends rcube_addressbook
$dc = 'dc='.strtr($d, array('.' => ',dc=')); // hierarchal domain string $dc = 'dc='.strtr($d, array('.' => ',dc=')); // hierarchal domain string
// resolve $dc through LDAP // resolve $dc through LDAP
if (!empty($this->prop['domain_filter']) && !empty($this->prop['search_bind_dn']) && if (!empty($conf['domain_filter']) && !empty($conf['search_bind_dn']) &&
method_exists($this->ldap, 'domain_root_dn')) { method_exists($this->ldap, 'domain_root_dn')) {
$this->ldap->bind($this->prop['search_bind_dn'], $this->prop['search_bind_pw']); $this->ldap->bind($conf['search_bind_dn'], $conf['search_bind_pw']);
$dc = $this->ldap->domain_root_dn($d); $dc = $this->ldap->domain_root_dn($d);
} }
$replaces = array('%dn' => '', '%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u); $replaces = array('%dn' => '', '%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u);
// Search for the dn to use to authenticate // Search for the dn to use to authenticate
if ($this->prop['search_base_dn'] && $this->prop['search_filter'] if ($conf['search_base_dn'] && $conf['search_filter']
&& (strstr($bind_dn, '%dn') || strstr($this->base_dn, '%dn') || strstr($this->groups_base_dn, '%dn')) && (strstr($bind_dn, '%dn') || strstr($this->base_dn, '%dn') || strstr($this->groups_base_dn, '%dn'))
) { ) {
$search_attribs = array('uid'); $search_attribs = array('uid');
if ($search_bind_attrib = (array)$this->prop['search_bind_attrib']) { if ($search_bind_attrib = (array) $conf['search_bind_attrib']) {
foreach ($search_bind_attrib as $r => $attr) { foreach ($search_bind_attrib as $r => $attr) {
$search_attribs[] = $attr; $search_attribs[] = $attr;
$replaces[$r] = ''; $replaces[$r] = '';
} }
} }
$search_bind_dn = strtr($this->prop['search_bind_dn'], $replaces); $search_bind_dn = strtr($conf['search_bind_dn'], $replaces);
$search_base_dn = strtr($this->prop['search_base_dn'], $replaces); $search_base_dn = strtr($conf['search_base_dn'], $replaces);
$search_filter = strtr($this->prop['search_filter'], $replaces); $search_filter = strtr($conf['search_filter'], $replaces);
$cache_key = 'DN.' . md5("$host:$search_bind_dn:$search_base_dn:$search_filter:" $cache_key = 'DN.' . md5("$host:$search_bind_dn:$search_base_dn:$search_filter:" . $conf['search_bind_pw']);
.$this->prop['search_bind_pw']);
if ($this->cache && ($dn = $this->cache->get($cache_key))) { if ($this->cache && ($dn = $this->cache->get($cache_key))) {
$replaces['%dn'] = $dn; $replaces['%dn'] = $dn;
} }
else { else {
$ldap = $this->ldap; $ldap = $this->ldap;
if (!empty($search_bind_dn) && !empty($this->prop['search_bind_pw'])) { if (!empty($search_bind_dn) && !empty($conf['search_bind_pw'])) {
// To protect from "Critical extension is unavailable" error // To protect from "Critical extension is unavailable" error
// we need to use a separate LDAP connection // we need to use a separate LDAP connection
if (!empty($this->prop['vlv'])) { if (!empty($conf['vlv'])) {
$ldap = new rcube_ldap_generic($this->prop); $ldap = new rcube_ldap_generic($conf);
$ldap->config_set(array('cache' => $this->cache, 'debug' => $this->debug)); $ldap->config_set(array('cache' => $this->cache, 'debug' => $this->debug));
if (!$ldap->connect($host)) { if (!$ldap->connect($host)) {
continue; continue;
} }
} }
if (!$ldap->bind($search_bind_dn, $this->prop['search_bind_pw'])) { if (!$ldap->bind($search_bind_dn, $conf['search_bind_pw'])) {
continue; // bind failed, try next host continue; // bind failed, try next host
} }
} }
@ -379,8 +382,8 @@ class rcube_ldap extends rcube_addressbook
// DN not found // DN not found
if (empty($replaces['%dn'])) { if (empty($replaces['%dn'])) {
if (!empty($this->prop['search_dn_default'])) if (!empty($conf['search_dn_default']))
$replaces['%dn'] = $this->prop['search_dn_default']; $replaces['%dn'] = $conf['search_dn_default'];
else { else {
rcube::raise_error(array( rcube::raise_error(array(
'code' => 100, 'type' => 'ldap', 'code' => 100, 'type' => 'ldap',
@ -401,20 +404,24 @@ class rcube_ldap extends rcube_addressbook
$this->groups_base_dn = strtr($this->groups_base_dn, $replaces); $this->groups_base_dn = strtr($this->groups_base_dn, $replaces);
// replace placeholders in filter settings // replace placeholders in filter settings
if (!empty($this->prop['filter'])) if (!empty($conf['filter'])) {
$this->prop['filter'] = strtr($this->prop['filter'], $replaces); $this->prop['filter'] = strtr($conf['filter'], $replaces);
}
foreach (array('base_dn','filter','member_filter') as $k) { foreach (array('base_dn','filter','member_filter') as $k) {
if (!empty($this->prop['groups'][$k])) if (!empty($conf['groups'][$k])) {
$this->prop['groups'][$k] = strtr($this->prop['groups'][$k], $replaces); $this->prop['groups'][$k] = strtr($conf['groups'][$k], $replaces);
}
} }
if (is_array($this->prop['group_filters'])) { if (is_array($conf['group_filters'])) {
foreach ($this->prop['group_filters'] as $i => $gf) { foreach ($conf['group_filters'] as $i => $gf) {
if (!empty($gf['base_dn'])) if (!empty($gf['base_dn'])) {
$this->prop['group_filters'][$i]['base_dn'] = strtr($gf['base_dn'], $replaces); $this->prop['group_filters'][$i]['base_dn'] = strtr($gf['base_dn'], $replaces);
if (!empty($gf['filter'])) }
if (!empty($gf['filter'])) {
$this->prop['group_filters'][$i]['filter'] = strtr($gf['filter'], $replaces); $this->prop['group_filters'][$i]['filter'] = strtr($gf['filter'], $replaces);
}
} }
} }
@ -427,11 +434,11 @@ class rcube_ldap extends rcube_addressbook
$this->ready = true; $this->ready = true;
} }
else { else {
if (!empty($bind_dn)) { if (!empty($conf['auth_cid'])) {
$this->ready = $this->ldap->bind($bind_dn, $bind_pass); $this->ready = $this->ldap->sasl_bind($conf['auth_cid'], $bind_pass, $bind_dn);
} }
else if (!empty($this->prop['auth_cid'])) { else if (!empty($bind_dn)) {
$this->ready = $this->ldap->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user); $this->ready = $this->ldap->bind($bind_dn, $bind_pass);
} }
else { else {
$this->ready = $this->ldap->sasl_bind($bind_user, $bind_pass); $this->ready = $this->ldap->sasl_bind($bind_user, $bind_pass);

Loading…
Cancel
Save