+ }
+
+ /**
+ * Add an entry to LDAP server.
+ *
+ * Warning: You must make sure that the arguments are correctly formated and
+ * sanitize use of special ldap keywords.
+ * @param string $dn the dn of the entry to be added
+ * @param array $data the values of the entry to be added
+ * @return boolean result (false on error)
+ * @since 1.5.2
+ */
+ function ldap_add($dn, $data) {
+ /* Make sure connection is there */
+ if(!$this->open()) {
+ return false;
+ }
+
+ if(!@ldap_add($this->linkid, $dn, $data)) {
+ $this->set_error(_("Write to address book failed"));
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove an entry from LDAP server.
+ *
+ * Warning: You must make sure that the argument is correctly formated and
+ * sanitize use of special ldap keywords.
+ * @param string $dn the dn of the entry to remove
+ * @return boolean result (false on error)
+ * @since 1.5.2
+ */
+ function ldap_remove($dn) {
+ /* Make sure connection is there */
+ if(!$this->open()) {
+ return false;
+ }
+
+ if(!@ldap_delete($this->linkid, $dn)) {
+ $this->set_error(_("Removing entry from address book failed"));
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Rename an entry on LDAP server.
+ *
+ * Warning: You must make sure that the arguments are correctly formated and
+ * sanitize use of special ldap keywords.
+ * @param string $sourcedn the dn of the entry to be renamed
+ * @param string $targetdn the dn which $sourcedn should be renamed to
+ * @param string $parent the dn of the parent entry
+ * @return boolean result (false on error)
+ * @since 1.5.2
+ */
+ function ldap_rename($sourcedn, $targetdn, $parent) {
+ /* Make sure connection is there */
+ if(!$this->open()) {
+ return false;
+ }
+
+ /* Make sure that the protocol version supports rename */
+ if($this->protocol < 3) {
+ $this->set_error(_("LDAP rename is not supported by used protocol version"));
+ return false;
+ }
+ /**
+ * Function is available only in OpenLDAP 2.x.x or Netscape Directory
+ * SDK x.x, and was added in PHP 4.0.5
+ * @todo maybe we can use copy + delete instead of ldap_rename()
+ */
+ if(!function_exists('ldap_rename')) {
+ $this->set_error(_("LDAP rename is not supported by used LDAP library. You can't change nickname"));
+ return false;
+ }
+
+ /* OK, go for it */
+ if(!@ldap_rename($this->linkid, $sourcedn, $targetdn, $parent, true)) {
+ $this->set_error(_("LDAP rename failed"));
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Modify the values of an entry on LDAP server.
+ *
+ * Warning: You must make sure that the arguments are correctly formated and
+ * sanitize use of special ldap keywords.
+ * @param string $dn the dn of the entry to be modified
+ * @param array $data the new values of the entry
+ * @param array $deleted_attribs attributes that should be deleted.
+ * @return bool result (false on error)
+ * @since 1.5.2
+ */
+ function ldap_modify($dn, $data, $deleted_attribs) {
+ /* Make sure connection is there */
+ if(!$this->open()) {
+ return false;
+ }
+
+ if(!@ldap_modify($this->linkid, $dn, $data)) {
+ $this->set_error(_("Write to address book failed"));
+ return false;
+ }
+
+ if (!@ldap_mod_del($this->linkid, $dn, $deleted_attribs)) {
+ $this->set_error(_("Unable to remove some field values"));
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Get error from LDAP resource if possible
+ *
+ * Should get error from server using the ldap_errno() and ldap_err2str() functions
+ * @param string $sError error message used when ldap error functions
+ * and connection resource are unavailable
+ * @return string error message
+ * @since 1.5.1
+ */
+ function ldap_error($sError) {
+ // it is possible that function_exists() tests are not needed
+ if(function_exists('ldap_err2str') &&
+ function_exists('ldap_errno') &&
+ is_resource($this->linkid)) {
+ return ldap_err2str(ldap_errno($this->linkid));
+ // return ldap_error($this->linkid);
+ } else {
+ return $sError;
+ }
+ }
+
+ /**
+ * 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 ======================== */
+
+ /**
+ * Search the LDAP server
+ * @param string $expr search expression
+ * @return array search results
+ */
+ function search($expr) {
+ /* To be replaced by advanded search expression parsing */
+ if(is_array($expr)) return false;
+
+ // don't allow wide search when listing is disabled.
+ if ($expr=='*' && ! $this->listing) {
+ return array();
+ } elseif ($expr=='*') {
+ // allow use of wildcard when listing is enabled.
+ $expression = '(cn=*)';
+ } else {
+ /* Convert search from user's charset to the one used in ldap and sanitize */
+ $expr = $this->quotevalue($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);