Fix NULL pointer dereference in LDAP lookup code.
[claws.git] / src / ldapupdate.c
index ff121a7a3a08f3c4e92299060fc25cb04e270747..e8ea64ae2779012888f1c841ba1a8ba7b2a3c0f5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2003-2009 Michael Rasmussen and the Claws Mail team
+ * Copyright (C) 2003-2012 Michael Rasmussen and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,6 +35,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
+#include "claws-features.h"
 #endif
 
 #ifdef USE_LDAP
@@ -43,8 +44,6 @@
 #include <glib/gi18n.h>
 #include <sys/time.h>
 #include <string.h>
-#include <ldap.h>
-#include <lber.h>
 
 #include "ldapupdate.h"
 #include "mgutils.h"
@@ -187,7 +186,7 @@ gboolean ldapsvr_retrieve_item_person(ItemPerson *person, GHashTable *array) {
                case ADD_ENTRY: g_hash_table_insert(array, "status", "new"); break;
                case UPDATE_ENTRY: g_hash_table_insert(array, "status", "update"); break;
                case DELETE_ENTRY: g_hash_table_insert(array, "status", "delete"); break;
-               default: g_critical(_("ldapsvr_retrieve_item_person->Unknown status: %d"), person->status);
+               default: g_critical("ldapsvr_retrieve_item_person->Unknown status: %d", person->status);
        }
        g_hash_table_insert(array, "uid", ADDRITEM_ID(person));
        g_hash_table_insert(array, "cn", ADDRITEM_NAME(person));
@@ -307,78 +306,6 @@ ItemPerson *ldapsvr_get_contact(LdapServer *server, gchar *uid) {
        return NULL;
 }
 
-/**
- * Connect to LDAP server.
- * \param  ctl Control object to process.
- * \return LDAP Resource to LDAP.
- */
-LDAP *ldapsvr_connect(LdapControl *ctl) {
-       LDAP *ld = NULL;
-       gint rc;
-       gint version;
-       gchar *uri = NULL;
-
-       cm_return_val_if_fail(ctl != NULL, NULL);
-
-       ldapsrv_set_options (ctl->timeOut, NULL);
-       uri = g_strdup_printf("ldap%s://%s:%d",
-                               ctl->enableSSL?"s":"",
-                               ctl->hostName, ctl->port);
-       ldap_initialize(&ld, uri);
-       g_free(uri);
-
-       if (ld == NULL)
-               return NULL;
-
-
-       debug_print("connected to LDAP host %s on port %d\n", ctl->hostName, ctl->port);
-
-#ifdef USE_LDAP_TLS
-       /* Handle TLS */
-       version = LDAP_VERSION3;
-       rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
-       if (rc == LDAP_OPT_SUCCESS) {
-               ctl->version = LDAP_VERSION3;
-       }
-
-       if (ctl->version == LDAP_VERSION3) {
-               if (ctl->enableTLS && !ctl->enableSSL) {
-                       rc = ldap_start_tls_s(ld, NULL, NULL);
-                       
-                       if (rc != LDAP_SUCCESS) {
-                               g_printerr("LDAP Error(tls): ldap_simple_bind_s: %s\n",
-                                       ldap_err2string(rc));
-                               return NULL;
-                       }
-               }
-       }
-#endif
-
-       /* Bind to the server, if required */
-       if (ctl->bindDN) {
-               if (* ctl->bindDN != '\0') {
-                       rc = claws_ldap_simple_bind_s(ld, ctl->bindDN, ctl->bindPass);
-                       if (rc != LDAP_SUCCESS) {
-                               g_printerr("bindDN: %s, bindPass: %s\n", ctl->bindDN, ctl->bindPass);
-                               g_printerr("LDAP Error(bind): ldap_simple_bind_s: %s\n",
-                                       ldap_err2string(rc));
-                               return NULL;
-                       }
-               }
-       }
-       return ld;
-}
-
-/**
- * Disconnect to LDAP server.
- * \param ld Resource to LDAP.
- */
-void ldapsvr_disconnect(LDAP *ld) {
-       /* Disconnect */
-       cm_return_if_fail(ld != NULL);
-       ldap_unbind_ext(ld, NULL, NULL);
-}
-
 /**
  * Create an initial Rdn structure
  *
@@ -442,10 +369,11 @@ Rdn *ldapsvr_modify_dn(GHashTable *hash, gchar *dn) {
        cm_return_val_if_fail(hash != NULL || dn != NULL, NULL);
        
        pos = g_strstr_len(dn, strlen(dn), "=");
-       compare = g_strndup(dn, pos - dn);
-
        if (!pos)
                return NULL;
+
+       compare = g_strndup(dn, pos - dn);
+
        pos++;
        rest = g_strstr_len(pos, strlen(pos), ",");
        val = g_strndup(pos, rest - pos);
@@ -455,17 +383,16 @@ Rdn *ldapsvr_modify_dn(GHashTable *hash, gchar *dn) {
                return NULL;
        }
        rdn = rdn_create();
-       rdn->value = g_strdup(val);
-       rdn->attribute = g_strdup(compare);
-       g_free(val);
+       rdn->value = val;
+       rdn->attribute = compare;
+
        if (strcmp("mail", rdn->attribute) == 0) {
                GList *list = g_hash_table_lookup(hash, rdn->attribute);
                while (list) {
                        EmailKeyValue *item = list->data;
-                       compare = g_strdup((gchar *) item->mail);
+                       compare = (gchar *) item->mail;
                        if (strcmp(compare, rdn->value) == 0) {
                                update_rdn(rdn, compare, rest);
-                               g_free(compare);
                                return rdn;
                        }
                        list = g_list_next(list);
@@ -474,28 +401,16 @@ Rdn *ldapsvr_modify_dn(GHashTable *hash, gchar *dn) {
                if (strcmp(compare, rdn->attribute) != 0) {
                        /* RDN changed. Find new */
                        update_rdn(rdn, compare, rest);
-                       g_free(compare);
                        return rdn;
                }
-               else {
-                       /* We cannot remove dn */
-                       g_free(compare);
-                       rdn_free(rdn);
-                       return NULL;
-               }
        }
        else {
                compare = g_hash_table_lookup(hash, rdn->attribute);
                /* if compare and rdn->attribute are equal then dn removed/empty */
-               if (strcmp(compare, rdn->attribute) != 0) {
+               if (compare != NULL && strcmp(compare, rdn->attribute) != 0) {
                        update_rdn(rdn, compare, rest);
                        return rdn;
                }
-               else {
-                       /* We cannot remove dn */
-                       rdn_free(rdn);
-                       return NULL;
-               }
        }
        rdn_free(rdn);
        return NULL;
@@ -554,7 +469,7 @@ void clean_up(LDAP *ld, LdapServer *server, GHashTable *contact) {
                        ItemPerson *res = 
                                addrcache_remove_person(server->addressCache, person);
                        if (!res)
-                               g_critical(N_("ldapsvr_update_book: Could not clean cache\n"));
+                               g_critical("ldapsvr_update_book: Could not clean cache\n");
                        else
                                addritem_free_item_person(res);
                }
@@ -736,7 +651,7 @@ void ldapsvr_compare_attr(LDAP *ld, gchar *dn, gint cnt, LDAPMod *mods[]) {
 #endif
 
                g_printerr("ldap_compare for (%s:%s)\" failed[0x%x]: %s\n",
-               mods[i]->mod_type, value, rc, ldap_err2string(rc));
+               mods[i]->mod_type, value, rc, ldaputil_get_error(ld));
                g_free(value);
        }
 }
@@ -771,19 +686,10 @@ int ldapsvr_compare_manual_attr(LDAP *ld, LdapServer *server, gchar *dn, char *a
        attrkeyvalue_free(mail);
        if (ctl) {
 
-#ifdef OPEN_LDAP_API_AT_LEAST_3000
-
                rc = ldap_search_ext_s(ld, ctl->baseDN, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, NULL, NULL, NULL, 0, &res);
 
-#else
-
-               /* This is deprecated as of OpenLDAP-2.3.0 */
-               rc = ldap_search_s(ld, ctl->baseDN, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &res);
-
-#endif
-
                if (rc) {
-                       g_printerr("ldap_search for attr=%s\" failed[0x%x]: %s\n",attr, rc, ldap_err2string(rc));
+                       g_printerr("ldap_search for attr=%s\" failed[0x%x]: %s\n",attr, rc, ldaputil_get_error(ld));
                        retVal = -2;
                }
                else {
@@ -878,7 +784,7 @@ int ldapsvr_deside_operation(LDAP *ld, LdapServer *server, char *dn, char *attr,
 #endif
 
        debug_print("ldap_compare for (%s:%s)\" error_code[0x%x]: %s\n",
-               attr, value, rc, ldap_err2string(rc));
+               attr, value, rc, ldaputil_get_error(ld));
        switch (rc) {
                case LDAP_COMPARE_FALSE: 
                        if (dummy)
@@ -1020,7 +926,7 @@ void ldapsvr_handle_other_attributes(LDAP *ld, LdapServer *server, char *dn, GHa
                                server->retVal = LDAPRC_ALREADY_EXIST;
                                break;
                        default:
-                               g_printerr("ldap_modify for dn=%s\" failed[0x%x]: %s\n", dn, rc, ldap_err2string(rc));
+                               g_printerr("ldap_modify for dn=%s\" failed[0x%x]: %s\n", dn, rc, ldaputil_get_error(ld));
                                if (rc == 0x8)
                                        server->retVal = LDAPRC_STRONG_AUTH;
                                else
@@ -1163,7 +1069,7 @@ void ldapsvr_add_contact(LdapServer *server, GHashTable *contact) {
                                break;
                        default:
                                g_printerr("ldap_modify for dn=%s\" failed[0x%x]: %s\n",
-                                               base_dn, rc, ldap_err2string(rc));
+                                               base_dn, rc, ldaputil_get_error(ld));
                                if (rc == 0x8)
                                        server->retVal = LDAPRC_STRONG_AUTH;
                                else
@@ -1236,7 +1142,7 @@ void ldapsvr_update_contact(LdapServer *server, GHashTable *contact) {
                        else {
                                g_printerr("Current dn: %s\n", dn);
                                g_printerr("new dn: %s\n", newRdn);
-                               g_printerr("LDAP Error(ldap_modrdn2_s) failed[0x%x]: %s\n", rc, ldap_err2string(rc));
+                               g_printerr("LDAP Error(ldap_modrdn2_s) failed[0x%x]: %s\n", rc, ldaputil_get_error(ld));
                                g_free(newRdn);
                                clean_up(ld, server, contact);
                                return;
@@ -1392,7 +1298,7 @@ void ldapsvr_update_contact(LdapServer *server, GHashTable *contact) {
                rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL);
                if (rc) {
                        g_printerr("ldap_modify for dn=%s\" failed[0x%x]: %s\n",
-                    dn, rc, ldap_err2string(rc));
+                    dn, rc, ldaputil_get_error(ld));
                        server->retVal = LDAPRC_NAMING_VIOLATION;
                }
                if (mail)
@@ -1433,7 +1339,7 @@ void ldapsvr_delete_contact(LdapServer *server, GHashTable *contact) {
        rc = ldap_delete_ext_s(ld, dn, NULL, NULL);
        if (rc) {
                g_printerr("ldap_modify for dn=%s\" failed[0x%x]: %s\n",
-                               dn, rc, ldap_err2string(rc));
+                               dn, rc, ldaputil_get_error(ld));
                server->retVal = LDAPRC_NODN;
        }
        clean_up(ld, server, contact);
@@ -1531,7 +1437,7 @@ void ldapsvr_update_book(LdapServer *server, ItemPerson *item) {
                        ldapsvr_delete_contact(server, contact);
                }
                else
-                       g_critical(_("ldapsvr_update_book->Unknown status: %s\n"), status);
+                       g_critical("ldapsvr_update_book->Unknown status: %s\n", status);
                contacts = g_list_next(contacts);
        }
        ldapsvr_free_hashtable(head);