* StartTLS code by John Lane
* <starfry at users.sourceforge.net> (#1197703)
* Code for remove, add, modify, lookup by David Härdeman
- * <david at 2gen.com> (#1495763)
+ * <david at hardeman.nu> (#1495763)
*
* This backend uses LDAP person (RFC2256), organizationalPerson (RFC2256)
* and inetOrgPerson (RFC2798) objects and dn, description, sn, givenname,
* cn, mail attributes. Other attributes are ignored.
*
- * @copyright © 1999-2006 The SquirrelMail Project Team
+ * @copyright 1999-2014 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id$
* @package squirrelmail
* </pre>
* Advanced settings:
* <pre>
- * ? filter => Filter expression to limit ldap searches
+ * ? filter => Filter expression to limit ldap search results.
+ * You can use this to *limit* the result set, based on specific
+ * requirements. The filter must be enclosed in parentheses, e.g.:
+ * '(objectclass=mailRecipient)'
+ * or '(&(objectclass=mailRecipient)(obectclass=myCustomClass))'
+ * The default value is empty.
+ *
+ * ? search_expression => Custom expression to expand ldap searches.
+ * This can help *expand* the result set, because of hits in more
+ * LDAP attributes. It must be a printf()-style string with either
+ * one placeholder '%s', or, if you want to repeat the expression
+ * many times, '%1$s'. The default value is:
+ * '(|(cn=*%1$s*)(mail=*%1$s*)(sn=*%1$s*))'
+ * that is, the search expression is search in the fields cn (common
+ * name), sn (surname) and mail.
+ *
* ? limit_scope => Limits scope to base DN (Specific to Win2k3 ADS).
* ? listing => Controls listing of LDAP directory.
* ? writeable => Controls write access to address book
* @since 1.5.1
*/
var $filter = '';
+ /**
+ * @var string printf()-style ldap search expression.
+ * The default is to search for same string in cn, mail and sn.
+ * @since 1.5.2
+ */
+ var $search_expression = '(|(cn=*%1$s*)(mail=*%1$s*)(sn=*%1$s*))';
/**
* @var integer timeout of LDAP operations (in seconds)
*/
* @var boolean true if removing/adding/modifying entries is allowed
* @since 1.5.2
*/
- var $writeable = true;
+ var $writeable = false;
/**
* @var boolean controls ldap search type.
* only first level entries are displayed if set to false
if(isset($param['filter']))
$this->filter = trim($param['filter']);
+
+ if(isset($param['search_expression']) &&
+ (strstr($param['search_expression'], '%s') || strstr($param['search_expression'], '%1$s'))) {
+ $this->search_expression = trim($param['search_expression']);
+ }
if(isset($param['limit_scope']))
$this->limit_scope = (bool) $param['limit_scope'];
return false;
}
- $attributes = array('dn', 'description', 'sn', 'givenname', 'cn', 'mail');
+ $attributes = array('dn', 'description', 'sn', 'givenName', 'cn', 'mail');
if ($singleentry) {
// ldap_read - search for one single entry
$surname = trim($this->charset_decode($row['sn'][0]));
}
- // FIXME: Write generic function to handle name order
- $fullname = trim($firstname . " " . $surname);
+ $fullname = $this->fullname($firstname,$surname);
/* Add one row to result for each e-mail address */
if(isset($row['mail']['count'])) {
}
}
+ /**
+ * Determine internal attribute name given one of
+ * the SquirrelMail SM_ABOOK_FIELD_* constants
+ *
+ * @param integer $attr The SM_ABOOK_FIELD_* contant to look up
+ *
+ * @return string The desired attribute name, or the string "ERROR"
+ * if the $field is not understood (the caller
+ * is responsible for handing errors)
+ *
+ */
+ function get_attr_name($attr) {
+ switch ($attr) {
+ case SM_ABOOK_FIELD_NICKNAME:
+ return 'cn';
+ case SM_ABOOK_FIELD_FIRSTNAME:
+ return 'givenName';
+ case SM_ABOOK_FIELD_LASTNAME:
+ return 'sn';
+ case SM_ABOOK_FIELD_EMAIL:
+ return 'mail';
+ case SM_ABOOK_FIELD_LABEL:
+ return 'description';
+ default:
+ return 'ERROR';
+ }
+ }
+
/* ========================== Public ======================== */
/**
/* Convert search from user's charset to the one used in ldap and sanitize */
$expr = $this->quotevalue($expr);
- /* Search for same string in cn, main and sn */
- $expression = '(|(cn=*'.$expr.'*)(mail=*'.$expr.'*)(sn=*'.$expr.'*))';
+ /* If search expr contains %s or %1$s, replace them with escaped values,
+ * so that a wrong printf()-style string is not created by mistake.
+ * (Probably overkill but who knows...) */
+ $expr = str_replace('%s', '\\25s', $expr);
+ $expr = str_replace('%1$s', '\\251$s', $expr);
+
+ /* Substitute %s or %1$s in printf()-formatted search_expresison with
+ * the value that the user searches for. */
+ $expression = sprintf($this->search_expression, $expr);
/* Undo sanitizing of * symbol */
$expression = str_replace('\2a','*',$expression);
+
+ /* Replace '**', '***' etc. with '*' in case it occurs in final
+ * search expression */
+ while(strstr($expression, '**')) {
+ $expression = str_replace('**', '*', $expression);
+ }
}
/* Add search filtering */
}
/**
- * Lookup an alias
- * @param string $alias alias
- * @return array search results
+ * Lookup an address by the indicated field.
+ *
+ * @param string $value The value to look up
+ * @param integer $field The field to look in, should be one
+ * of the SM_ABOOK_FIELD_* constants
+ * defined in include/constants.php
+ * (OPTIONAL; defaults to nickname field)
+ * NOTE: uniqueness is only guaranteed
+ * when the nickname field is used here;
+ * otherwise, the first matching address
+ * is returned.
+ *
+ * @return array Array with lookup results when the value
+ * was found, an empty array if the value was
+ * not found.
+ *
* @since 1.5.2
+ *
*/
- function lookup($alias) {
- /* Generate the dn and try to retrieve that single entry */
- $cn = $this->quotevalue($alias);
- $dn = 'cn=' . $cn . ',' . $this->basedn;
+ function lookup($value, $field=SM_ABOOK_FIELD_NICKNAME) {
+
+
+ $attr = get_attr_name($field);
+ if ($attr == 'ERROR') {
+ return $this->set_error(sprintf(_("Unknown field name: %s"), $field));
+ }
+
+ // Generate the dn
+ $dn = $attr . '=' . $this->quotevalue($value) . ',' . $this->basedn;
- /* Do the search */
+ // Do the search
$result = $this->ldap_search($dn, true);
if (!is_array($result) || count($result) < 1)
return array();