]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/ldap/serv_ldap.c
* serv_ldap.c: upon successful connect to an LDAP server, post an aide message warnin...
[citadel.git] / citadel / modules / ldap / serv_ldap.c
index fdde84df4b238535d0dbf01413525f19b3dfe7d5..a7551dcbfecd1efcdb4c785ffc5980e13c6b1a6f 100644 (file)
@@ -29,6 +29,7 @@
 #include <sys/wait.h>
 #include <string.h>
 #include <limits.h>
+#include <libcitadel.h>
 #include "citadel.h"
 #include "server.h"
 #include "citserver.h"
@@ -37,9 +38,7 @@
 #include "room_ops.h"
 #include "policy.h"
 #include "database.h"
-#include "msgbase.h"
 #include "serv_ldap.h"
-#include "tools.h"
 
 
 #include "ctdl_module.h"
@@ -56,13 +55,18 @@ LDAP *dirserver = NULL;
 int ldap_time_disconnect = 0;
 
 
+
+/* There is a forward referance so.... */
+int delete_from_ldap(char *cn, char *ou, void **object);
+
+
 /*
  * LDAP connector cleanup function
  */
 void serv_ldap_cleanup(void)
 {
        if (dirserver) {
-               lprintf(CTDL_INFO,
+               CtdlLogPrintf(CTDL_INFO,
                        "LDAP: Unbinding from directory server\n");
                ldap_unbind(dirserver);
        }
@@ -71,7 +75,13 @@ void serv_ldap_cleanup(void)
 }
 
 
-
+/*
+ * connect_to_ldap
+ *
+ * BIG FAT WARNING
+ * Make sure this function is only called from within a begin_critical_section(S_LDAP)
+ * If you don't things will break!!!!!.
+ */
 
 
 int connect_to_ldap(void)
@@ -79,42 +89,52 @@ int connect_to_ldap(void)
        int i;
        int ldap_version = 3;
 
-       if (ldap_time_disconnect && dirserver) {        // Already connected
-               ldap_time_disconnect = 5;       // reset the timer.
+       if (dirserver) {        // Already connected
+               ldap_time_disconnect = 1 ;      // reset the timer.
                return 0;
        }
 
-       lprintf(CTDL_INFO, "LDAP: Connecting to LDAP server %s:%d...\n",
+       CtdlLogPrintf(CTDL_INFO, "LDAP: Connecting to LDAP server %s:%d...\n",
                config.c_ldap_host, config.c_ldap_port);
 
        dirserver = ldap_init(config.c_ldap_host, config.c_ldap_port);
        if (dirserver == NULL) {
-               lprintf(CTDL_CRIT,
+               CtdlLogPrintf(CTDL_CRIT,
                        "LDAP: Could not connect to %s:%d : %s\n",
                        config.c_ldap_host, config.c_ldap_port,
                        strerror(errno));
-               aide_message(strerror(errno),
+               CtdlAideMessage(strerror(errno),
                             "LDAP: Could not connect to server.");
                return -1;
        }
+       else {
+               CtdlAideMessage(
+                       "WARNING: populating an external LDAP address book is deprecated.\n"
+                       "This function will be discontinued in a future release.\n"
+                       "Please migrate to vCard-based address books as soon as possible.\n"
+                       "Visit the Citadel support forum if you need further assistance.\n"
+                       ,
+                       "Warning: LDAP address book is deprecated"
+               );
+       }
 
        ldap_set_option(dirserver, LDAP_OPT_PROTOCOL_VERSION,
                        &ldap_version);
 
-       lprintf(CTDL_INFO, "LDAP: Binding to %s\n", config.c_ldap_bind_dn);
+       CtdlLogPrintf(CTDL_INFO, "LDAP: Binding to %s\n", config.c_ldap_bind_dn);
 
        i = ldap_simple_bind_s(dirserver,
                               config.c_ldap_bind_dn,
                               config.c_ldap_bind_pw);
        if (i != LDAP_SUCCESS) {
-               lprintf(CTDL_CRIT, "LDAP: Cannot bind: %s (%d)\n",
+               CtdlLogPrintf(CTDL_CRIT, "LDAP: Cannot bind: %s (%d)\n",
                        ldap_err2string(i), i);
                dirserver = NULL;       /* FIXME disconnect from ldap */
-               aide_message(ldap_err2string(i),
+               CtdlAideMessage(ldap_err2string(i),
                             "LDAP: Cannot bind to server");
                return -1;
        }
-       ldap_time_disconnect = 5;
+       ldap_time_disconnect = 1;
        return 0;
 }
 
@@ -162,7 +182,7 @@ void create_ldap_root(void)
        mods[2] = NULL;
 
        /* Perform the transaction */
-       lprintf(CTDL_DEBUG, "LDAP: Setting up Base DN node...\n");
+       CtdlLogPrintf(CTDL_DEBUG, "LDAP: Setting up Base DN node...\n");
 
        begin_critical_section(S_LDAP);
        if (connect_to_ldap()) {
@@ -173,10 +193,10 @@ void create_ldap_root(void)
        end_critical_section(S_LDAP);
 
        if (i == LDAP_ALREADY_EXISTS) {
-               lprintf(CTDL_INFO,
+               CtdlLogPrintf(CTDL_INFO,
                        "LDAP: Base DN is already present in the directory; no need to add it again.\n");
        } else if (i != LDAP_SUCCESS) {
-               lprintf(CTDL_CRIT, "LDAP: ldap_add_s() failed: %s (%d)\n",
+               CtdlLogPrintf(CTDL_CRIT, "LDAP: ldap_add_s() failed: %s (%d)\n",
                        ldap_err2string(i), i);
        }
 }
@@ -216,7 +236,7 @@ int create_ldap_host_OU(char *cn, char *host, void **object)
        mods[2] = NULL;
 
        /* Perform the transaction */
-       lprintf(CTDL_DEBUG, "LDAP: Setting up Host OU node...\n");
+       CtdlLogPrintf(CTDL_DEBUG, "LDAP: Setting up Host OU node...\n");
 
        begin_critical_section(S_LDAP);
        if (connect_to_ldap()) {
@@ -227,10 +247,10 @@ int create_ldap_host_OU(char *cn, char *host, void **object)
        end_critical_section(S_LDAP);
 
        if (i == LDAP_ALREADY_EXISTS) {
-               lprintf(CTDL_INFO,
+               CtdlLogPrintf(CTDL_INFO,
                        "LDAP: Host OU is already present in the directory; no need to add it again.\n");
        } else if (i != LDAP_SUCCESS) {
-               lprintf(CTDL_CRIT, "LDAP: ldap_add_s() failed: %s (%d)\n",
+               CtdlLogPrintf(CTDL_CRIT, "LDAP: ldap_add_s() failed: %s (%d)\n",
                        ldap_err2string(i), i);
                return -1;
        }
@@ -249,7 +269,7 @@ int create_ldap_host_OU(char *cn, char *host, void **object)
 int create_ldap_object(char *cn, char *ou, void **object)
 {
        // We do nothing here, this just gets the base structure created by the interface.
-       lprintf(CTDL_DEBUG, "LDAP: Created ldap object\n");
+       CtdlLogPrintf(CTDL_DEBUG, "LDAP: Created ldap object\n");
        return 0;
 }
 
@@ -266,7 +286,7 @@ int add_ldap_object(char *cn, char *ou, void **object)
        int cur_attr;
 
 
-       lprintf(CTDL_DEBUG,
+       CtdlLogPrintf(CTDL_DEBUG,
                "LDAP: Adding ldap attribute name:\"%s\" value:\"%s\"\n",
                cn, ou);
 
@@ -285,7 +305,7 @@ int add_ldap_object(char *cn, char *ou, void **object)
                                            (ou,
                                             attrs[cur_attr]->
                                             mod_values[num_values])) {
-                                               lprintf(CTDL_DEBUG,
+                                               CtdlLogPrintf(CTDL_DEBUG,
                                                        "LDAP: Ignoring duplicate attribute/value pair\n");
                                                return 0;
                                        }
@@ -324,7 +344,7 @@ int add_ldap_object(char *cn, char *ou, void **object)
  */
 int save_ldap_object(char *cn, char *ou, void **object)
 {
-       int i, j;
+       int i;
 
        char this_dn[SIZ];
        LDAPMod **attrs;
@@ -338,7 +358,7 @@ int save_ldap_object(char *cn, char *ou, void **object)
 
        sprintf(this_dn, "%s,%s", cn, config.c_ldap_base_dn);
 
-       lprintf(CTDL_INFO, "LDAP: Calling ldap_add_s() for dn of '%s'\n",
+       CtdlLogPrintf(CTDL_INFO, "LDAP: Calling ldap_add_s() for dn of '%s'\n",
                this_dn);
 
        /* The last attribute must be a NULL one. */
@@ -347,7 +367,7 @@ int save_ldap_object(char *cn, char *ou, void **object)
                while (attrs[num_attrs]) {
                        count = 0;
                        while (attrs[num_attrs]->mod_values[count]) {
-                               lprintf(CTDL_DEBUG,
+                               CtdlLogPrintf(CTDL_DEBUG,
                                        "LDAP: attribute %d, value %d = \'%s=%s\'\n",
                                        num_attrs, count,
                                        attrs[num_attrs]->mod_type,
@@ -358,7 +378,7 @@ int save_ldap_object(char *cn, char *ou, void **object)
                        num_attrs++;
                }
        } else {
-               lprintf(CTDL_ERR,
+               CtdlLogPrintf(CTDL_ERR,
                        "LDAP: no attributes in save_ldap_object\n");
                return -1;
        }
@@ -372,7 +392,7 @@ int save_ldap_object(char *cn, char *ou, void **object)
        i = ldap_add_s(dirserver, this_dn, attrs);
 
        if (i == LDAP_SERVER_DOWN) {
-               aide_message
+               CtdlAideMessage
                    ("The LDAP server appears to be down.\nThe save to LDAP did not occurr.\n",
                     "LDAP: save failed");
                end_critical_section(S_LDAP);
@@ -380,20 +400,27 @@ int save_ldap_object(char *cn, char *ou, void **object)
        }
 
        /* If the entry already exists, repopulate it instead */
+       /* repopulating doesn't work as Citadel may want some attributes to be deleted.
+        * we have no way of knowing which attributes to delete and LDAP won't work it out for us
+        * so now we delete the old entry and create a new one.
+        */
        if (i == LDAP_ALREADY_EXISTS) {
-               for (j = 0; j < (num_attrs); ++j) {
-                       attrs[j]->mod_op = LDAP_MOD_REPLACE;
-               }
-               lprintf(CTDL_INFO,
-                       "LDAP: Calling ldap_modify_s() for dn of '%s'\n",
+               end_critical_section(S_LDAP);
+               CtdlLogPrintf(CTDL_INFO,
+                       "LDAP: Create, already exists, deleteing first.\n");
+               if (delete_from_ldap(cn, ou, NULL))
+                       return -1;
+               begin_critical_section(S_LDAP);
+               CtdlLogPrintf(CTDL_INFO,
+                       "LDAP: Calling ldap_add_s() to recreate for dn of '%s'\n",
                        this_dn);
-               i = ldap_modify_s(dirserver, this_dn, attrs);
+               i = ldap_add_s(dirserver, this_dn, attrs);
        }
 
        if (i != LDAP_SUCCESS) {
-               lprintf(CTDL_ERR, "LDAP: ldap_add_s() failed: %s (%d)\n",
+               CtdlLogPrintf(CTDL_ERR, "LDAP: ldap_add_s() failed: %s (%d)\n",
                        ldap_err2string(i), i);
-               aide_message
+               CtdlAideMessage
                    ("The LDAP server refused the save command.\nDid you update the schema?\n",
                     "LDAP: save failed (schema?)");
                end_critical_section(S_LDAP);
@@ -420,7 +447,7 @@ int free_ldap_object(char *cn, char *ou, void **object)
                        num_attrs++;
        }
 
-       lprintf(CTDL_DEBUG, "LDAP: Freeing attributes\n");
+       CtdlLogPrintf(CTDL_DEBUG, "LDAP: Freeing attributes\n");
        /* Free the attributes */
        for (i = 0; i < num_attrs; ++i) {
                if (attrs[i] != NULL) {
@@ -463,14 +490,12 @@ int delete_from_ldap(char *cn, char *ou, void **object)
 
        if (dirserver == NULL)
                return -1;
-       if (ou == NULL)
-               return -1;
        if (cn == NULL)
                return -1;
 
        sprintf(this_dn, "%s,%s", cn, config.c_ldap_base_dn);
 
-       lprintf(CTDL_DEBUG, "LDAP: Calling ldap_delete_s()\n");
+       CtdlLogPrintf(CTDL_DEBUG, "LDAP: Calling ldap_delete_s()\n");
 
        begin_critical_section(S_LDAP);
        if (connect_to_ldap()) {
@@ -482,18 +507,18 @@ int delete_from_ldap(char *cn, char *ou, void **object)
 
        if (i == LDAP_SERVER_DOWN) {
                end_critical_section(S_LDAP);
-               aide_message
+               CtdlAideMessage
                    ("The LDAP server appears to be down.\nThe delete from LDAP did not occurr.\n",
                     "LDAP: delete failed");
                return -1;
        }
 
        if (i != LDAP_SUCCESS) {
-               lprintf(CTDL_ERR,
+               CtdlLogPrintf(CTDL_ERR,
                        "LDAP: ldap_delete_s() failed: %s (%d)\n",
                        ldap_err2string(i), i);
                end_critical_section(S_LDAP);
-               aide_message(ldap_err2string(i), "LDAP: delete failed");
+               CtdlAideMessage(ldap_err2string(i), "LDAP: delete failed");
                return -1;
        }
        end_critical_section(S_LDAP);
@@ -524,32 +549,35 @@ void ldap_disconnect_timer(void)
  */
 CTDL_MODULE_INIT(ldap)
 {
+       if (!threading)
+       {
 #ifdef HAVE_LDAP
-       if (!IsEmptyStr(config.c_ldap_base_dn)) {
-               CtdlRegisterCleanupHook(serv_ldap_cleanup);
-               CtdlRegisterSessionHook(ldap_disconnect_timer, EVT_TIMER);
-               CtdlRegisterDirectoryServiceFunc(delete_from_ldap,
-                                                DIRECTORY_USER_DEL,
-                                                "ldap");
-               CtdlRegisterDirectoryServiceFunc(create_ldap_host_OU,
-                                                DIRECTORY_CREATE_HOST,
-                                                "ldap");
-               CtdlRegisterDirectoryServiceFunc(create_ldap_object,
-                                                DIRECTORY_CREATE_OBJECT,
-                                                "ldap");
-               CtdlRegisterDirectoryServiceFunc(add_ldap_object,
-                                                DIRECTORY_ATTRIB_ADD,
-                                                "ldap");
-               CtdlRegisterDirectoryServiceFunc(save_ldap_object,
-                                                DIRECTORY_SAVE_OBJECT,
-                                                "ldap");
-               CtdlRegisterDirectoryServiceFunc(free_ldap_object,
-                                                DIRECTORY_FREE_OBJECT,
-                                                "ldap");
-               create_ldap_root();
-       }
+               if (!IsEmptyStr(config.c_ldap_base_dn)) {
+                       CtdlRegisterCleanupHook(serv_ldap_cleanup);
+                       CtdlRegisterSessionHook(ldap_disconnect_timer, EVT_TIMER);
+                       CtdlRegisterDirectoryServiceFunc(delete_from_ldap,
+                                                        DIRECTORY_USER_DEL,
+                                                        "ldap");
+                       CtdlRegisterDirectoryServiceFunc(create_ldap_host_OU,
+                                                        DIRECTORY_CREATE_HOST,
+                                                        "ldap");
+                       CtdlRegisterDirectoryServiceFunc(create_ldap_object,
+                                                        DIRECTORY_CREATE_OBJECT,
+                                                        "ldap");
+                       CtdlRegisterDirectoryServiceFunc(add_ldap_object,
+                                                        DIRECTORY_ATTRIB_ADD,
+                                                        "ldap");
+                       CtdlRegisterDirectoryServiceFunc(save_ldap_object,
+                                                        DIRECTORY_SAVE_OBJECT,
+                                                        "ldap");
+                       CtdlRegisterDirectoryServiceFunc(free_ldap_object,
+                                                        DIRECTORY_FREE_OBJECT,
+                                                        "ldap");
+                       create_ldap_root();
+               }
 #endif                         /* HAVE_LDAP */
-
+       }
+       
        /* return our Subversion id for the Log */
        return "$Id$";
 }