#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "room_ops.h"
#include "policy.h"
#include "database.h"
-#include "msgbase.h"
#include "serv_ldap.h"
-#include "tools.h"
#include "ctdl_module.h"
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);
}
}
-
+/*
+ * 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)
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;
}
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()) {
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);
}
}
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()) {
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;
}
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;
}
int cur_attr;
- lprintf(CTDL_DEBUG,
+ CtdlLogPrintf(CTDL_DEBUG,
"LDAP: Adding ldap attribute name:\"%s\" value:\"%s\"\n",
cn, ou);
(ou,
attrs[cur_attr]->
mod_values[num_values])) {
- lprintf(CTDL_DEBUG,
+ CtdlLogPrintf(CTDL_DEBUG,
"LDAP: Ignoring duplicate attribute/value pair\n");
return 0;
}
*/
int save_ldap_object(char *cn, char *ou, void **object)
{
- int i, j;
+ int i;
char this_dn[SIZ];
LDAPMod **attrs;
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. */
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,
num_attrs++;
}
} else {
- lprintf(CTDL_ERR,
+ CtdlLogPrintf(CTDL_ERR,
"LDAP: no attributes in save_ldap_object\n");
return -1;
}
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);
}
/* 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);
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) {
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()) {
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);
*/
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$";
}