#include <limits.h>
#include "citadel.h"
#include "server.h"
-#include "sysdep_decls.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
-#include "serv_extensions.h"
#include "room_ops.h"
#include "policy.h"
#include "database.h"
#include "vcard.h"
#include "tools.h"
+
+#include "ctdl_module.h"
+
+
+
#ifdef HAVE_LDAP
#include <ldap.h>
{
if (!dirserver) return;
- lprintf(7, "Unbinding from directory server\n");
+ lprintf(CTDL_INFO, "Unbinding from directory server\n");
ldap_unbind(dirserver);
dirserver = NULL;
}
mods[2] = NULL;
/* Perform the transaction */
- lprintf(9, "Setting up Base DN node...\n");
+ lprintf(CTDL_DEBUG, "Setting up Base DN node...\n");
begin_critical_section(S_LDAP);
i = ldap_add_s(dirserver, config.c_ldap_base_dn, mods);
end_critical_section(S_LDAP);
- if (i != LDAP_SUCCESS) {
- lprintf(3, "ldap_add_s() failed: %s (%d)\n",
+ if (i == LDAP_ALREADY_EXISTS) {
+ lprintf(CTDL_INFO, "Base DN is already present in the directory; no need to add it again.\n");
+ }
+ else if (i != LDAP_SUCCESS) {
+ lprintf(CTDL_CRIT, "ldap_add_s() failed: %s (%d)\n",
ldap_err2string(i), i);
}
}
mods[2] = NULL;
/* Perform the transaction */
- lprintf(9, "Setting up Host OU node...\n");
+ lprintf(CTDL_DEBUG, "Setting up Host OU node...\n");
begin_critical_section(S_LDAP);
i = ldap_add_s(dirserver, dn, mods);
end_critical_section(S_LDAP);
- /* ignore the error -- it's ok if it already exists
- if (i != LDAP_SUCCESS) {
- lprintf(3, "ldap_add_s() failed: %s (%d)\n",
+ if (i == LDAP_ALREADY_EXISTS) {
+ lprintf(CTDL_INFO, "Host OU is already present in the directory; no need to add it again.\n");
+ }
+ else if (i != LDAP_SUCCESS) {
+ lprintf(CTDL_CRIT, "ldap_add_s() failed: %s (%d)\n",
ldap_err2string(i), i);
}
- */
}
int i;
int ldap_version = 3;
- lprintf(7, "Connecting to LDAP server %s:%d...\n",
+ lprintf(CTDL_INFO, "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(3, "Could not connect to %s:%d : %s\n",
+ lprintf(CTDL_CRIT, "Could not connect to %s:%d : %s\n",
config.c_ldap_host,
config.c_ldap_port,
strerror(errno));
ldap_set_option(dirserver, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
- lprintf(7, "Binding to %s\n", config.c_ldap_bind_dn);
+ lprintf(CTDL_INFO, "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(3, "Cannot bind: %s (%d)\n", ldap_err2string(i), i);
+ lprintf(CTDL_CRIT, "Cannot bind: %s (%d)\n", ldap_err2string(i), i);
dirserver = NULL; /* FIXME disconnect from ldap */
return;
}
}
-
-/*
- * Write (add, or change if already exists) a directory entry to the
+/*
+ * vCard-to-LDAP conversions.
+ *
+ * If 'op' is set to V2L_WRITE, then write
+ * (add, or change if already exists) a directory entry to the
* LDAP server, based on the information supplied in a vCard.
+ *
+ * If 'op' is set to V2L_DELETE, then delete the entry from LDAP.
*/
-void ctdl_vcard_to_ldap(struct CtdlMessage *msg) {
+void ctdl_vcard_to_ldap(struct CtdlMessage *msg, int op) {
struct vCard *v = NULL;
int i, j;
char this_dn[SIZ];
LDAPMod **attrs = NULL;
int num_attrs = 0;
-
- char givenname[SIZ];
- char sn[SIZ];
+ int num_emails = 0;
+ int alias_attr = (-1);
+ int num_phones = 0;
+ int phone_attr = (-1);
+ int have_addr = 0;
+ int have_cn = 0;
+
+ char givenname[128];
+ char sn[128];
+ char uid[256];
+ char street[256];
+ char city[128];
+ char state[3];
+ char zipcode[10];
+ char calFBURL[256];
if (dirserver == NULL) return;
if (msg == NULL) return;
if (msg->cm_fields['A'] == NULL) return;
if (msg->cm_fields['N'] == NULL) return;
- /* First make sure the OU for the user's home Citadel host is created */
- CtdlCreateHostOU(msg->cm_fields['N']);
-
/* Initialize variables */
- strcpy(givenname, "_");
- strcpy(sn, "_");
+ strcpy(givenname, "");
+ strcpy(sn, "");
+ strcpy(calFBURL, "");
sprintf(this_dn, "cn=%s,ou=%s,%s",
msg->cm_fields['A'],
msg->cm_fields['N'],
config.c_ldap_base_dn
);
+
+ sprintf(uid, "%s@%s",
+ msg->cm_fields['A'],
+ msg->cm_fields['N']
+ );
+
+ /* Are we just deleting? If so, it's simple... */
+ if (op == V2L_DELETE) {
+ lprintf(CTDL_DEBUG, "Calling ldap_delete_s()\n");
+ begin_critical_section(S_LDAP);
+ i = ldap_delete_s(dirserver, this_dn);
+ end_critical_section(S_LDAP);
+ if (i != LDAP_SUCCESS) {
+ lprintf(CTDL_ERR, "ldap_delete_s() failed: %s (%d)\n",
+ ldap_err2string(i), i);
+ }
+ return;
+ }
+
+ /*
+ * If we get to this point then it must be a V2L_WRITE operation.
+ */
+
+ /* First make sure the OU for the user's home Citadel host is created */
+ CtdlCreateHostOU(msg->cm_fields['N']);
/* The first LDAP attribute will be an 'objectclass' list. Citadel
* doesn't do anything with this. It's just there for compatibility
* with Kolab.
*/
num_attrs = 1;
- attrs = mallok( (sizeof(LDAPMod *) * num_attrs) );
- attrs[0] = mallok(sizeof(LDAPMod));
+ attrs = malloc( (sizeof(LDAPMod *) * num_attrs) );
+ attrs[0] = malloc(sizeof(LDAPMod));
memset(attrs[0], 0, sizeof(LDAPMod));
attrs[0]->mod_op = LDAP_MOD_ADD;
attrs[0]->mod_type = "objectclass";
- attrs[0]->mod_values = mallok(5 * sizeof(char *));
- attrs[0]->mod_values[0] = strdoop("inetOrgPerson");
- attrs[0]->mod_values[1] = strdoop("organizationalPerson");
- attrs[0]->mod_values[2] = strdoop("person");
- attrs[0]->mod_values[3] = strdoop("Top");
- attrs[0]->mod_values[4] = NULL;
-
- /* Add a "cn" (Common Name) attribute based on the user's screen name */
- attrs = reallok(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
- attrs[num_attrs-1] = mallok(sizeof(LDAPMod));
- memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
- attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
- attrs[num_attrs-1]->mod_type = "cn";
- attrs[num_attrs-1]->mod_values = mallok(2 * sizeof(char *));
- attrs[num_attrs-1]->mod_values[0] = strdoop(msg->cm_fields['A']);
- attrs[num_attrs-1]->mod_values[1] = NULL;
-
+ attrs[0]->mod_values = malloc(3 * sizeof(char *));
+ attrs[0]->mod_values[0] = strdup("citadelInetOrgPerson");
+ attrs[0]->mod_values[1] = NULL;
+
/* Convert the vCard fields to LDAP properties */
v = vcard_load(msg->cm_fields['M']);
- if (v->numprops) for (i=0; i<(v->numprops); ++i) {
+ if (v->numprops) for (i=0; i<(v->numprops); ++i) if (striplt(v->prop[i].value), strlen(v->prop[i].value) > 0) {
if (!strcasecmp(v->prop[i].name, "n")) {
- extract_token(sn, v->prop[i].value, 0, ';');
- extract_token(givenname, v->prop[i].value, 1, ';');
+ extract_token(sn, v->prop[i].value, 0, ';', sizeof sn);
+ extract_token(givenname, v->prop[i].value, 1, ';', sizeof givenname);
+ }
+
+ if (!strcasecmp(v->prop[i].name, "fn")) {
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "cn";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(v->prop[i].value);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+ have_cn = 1;
+ }
+
+ if (!strcasecmp(v->prop[i].name, "title")) {
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "title";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(v->prop[i].value);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+ }
+
+ if (!strcasecmp(v->prop[i].name, "org")) {
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "o";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(v->prop[i].value);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+ }
+
+ if ( (!strcasecmp(v->prop[i].name, "adr"))
+ ||(!strncasecmp(v->prop[i].name, "adr;", 4)) ) {
+ /* Unfortunately, we can only do a single address */
+ if (!have_addr) {
+ have_addr = 1;
+ strcpy(street, "");
+ extract_token(&street[strlen(street)],
+ v->prop[i].value, 0, ';', (sizeof street - strlen(street))); /* po box */
+ strcat(street, " ");
+ extract_token(&street[strlen(street)],
+ v->prop[i].value, 1, ';', (sizeof street - strlen(street))); /* extend addr */
+ strcat(street, " ");
+ extract_token(&street[strlen(street)],
+ v->prop[i].value, 2, ';', (sizeof street - strlen(street))); /* street */
+ striplt(street);
+ extract_token(city, v->prop[i].value, 3, ';', sizeof city);
+ extract_token(state, v->prop[i].value, 4, ';', sizeof state);
+ extract_token(zipcode, v->prop[i].value, 5, ';', sizeof zipcode);
+
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "street";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(street);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "l";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(city);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "st";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(state);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "postalcode";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(zipcode);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+ }
+ }
+
+ if ( (!strcasecmp(v->prop[i].name, "tel"))
+ ||(!strncasecmp(v->prop[i].name, "tel;", 4)) ) {
+ ++num_phones;
+ /* The first 'tel' property creates the 'telephoneNumber' attribute */
+ if (num_phones == 1) {
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ phone_attr = num_attrs-1;
+ attrs[phone_attr] = malloc(sizeof(LDAPMod));
+ memset(attrs[phone_attr], 0, sizeof(LDAPMod));
+ attrs[phone_attr]->mod_op = LDAP_MOD_ADD;
+ attrs[phone_attr]->mod_type = "telephoneNumber";
+ attrs[phone_attr]->mod_values = malloc(2 * sizeof(char *));
+ attrs[phone_attr]->mod_values[0] = strdup(v->prop[i].value);
+ attrs[phone_attr]->mod_values[1] = NULL;
+ }
+ /* Subsequent 'tel' properties *add to* the 'telephoneNumber' attribute */
+ else {
+ attrs[phone_attr]->mod_values = realloc(attrs[phone_attr]->mod_values,
+ num_phones * sizeof(char *));
+ attrs[phone_attr]->mod_values[num_phones-1]
+ = strdup(v->prop[i].value);
+ attrs[phone_attr]->mod_values[num_phones]
+ = NULL;
+ }
+ }
+
+
+ if ( (!strcasecmp(v->prop[i].name, "email"))
+ ||(!strcasecmp(v->prop[i].name, "email;internet")) ) {
+
+ ++num_emails;
+ lprintf(CTDL_DEBUG, "email addr %d\n", num_emails);
+
+ /* The first email address creates the 'mail' attribute */
+ if (num_emails == 1) {
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "mail";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(v->prop[i].value);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+ }
+ /* The second email address creates the 'alias' attribute */
+ else if (num_emails == 2) {
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ alias_attr = num_attrs-1;
+ attrs[alias_attr] = malloc(sizeof(LDAPMod));
+ memset(attrs[alias_attr], 0, sizeof(LDAPMod));
+ attrs[alias_attr]->mod_op = LDAP_MOD_ADD;
+ attrs[alias_attr]->mod_type = "alias";
+ attrs[alias_attr]->mod_values = malloc(2 * sizeof(char *));
+ attrs[alias_attr]->mod_values[0] = strdup(v->prop[i].value);
+ attrs[alias_attr]->mod_values[1] = NULL;
+ }
+ /* Subsequent email addresses *add to* the 'alias' attribute */
+ else if (num_emails > 2) {
+ attrs[alias_attr]->mod_values = realloc(attrs[alias_attr]->mod_values,
+ num_emails * sizeof(char *));
+ attrs[alias_attr]->mod_values[num_emails-2]
+ = strdup(v->prop[i].value);
+ attrs[alias_attr]->mod_values[num_emails-1]
+ = NULL;
+ }
+
+
+ }
+
+ /* Calendar free/busy URL (take the first one we find, but if a subsequent
+ * one contains the "pref" designation then we go with that instead.)
+ */
+ if ( (!strcasecmp(v->prop[i].name, "fburl"))
+ ||(!strncasecmp(v->prop[i].name, "fburl;", 6)) ) {
+ if ( (strlen(calFBURL) == 0)
+ || (!strncasecmp(v->prop[i].name, "fburl;pref", 10)) ) {
+ safestrncpy(calFBURL, v->prop[i].value, sizeof calFBURL);
+ }
}
}
vcard_free(v); /* Don't need this anymore. */
/* "sn" (surname) based on info in vCard */
- attrs = reallok(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
- attrs[num_attrs-1] = mallok(sizeof(LDAPMod));
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
attrs[num_attrs-1]->mod_type = "sn";
- attrs[num_attrs-1]->mod_values = mallok(2 * sizeof(char *));
- attrs[num_attrs-1]->mod_values[0] = strdoop(sn);
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(sn);
attrs[num_attrs-1]->mod_values[1] = NULL;
-
+
/* "givenname" (first name) based on info in vCard */
- attrs = reallok(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
- attrs[num_attrs-1] = mallok(sizeof(LDAPMod));
+ if (strlen(givenname) == 0) strcpy(givenname, "_");
+ if (strlen(sn) == 0) strcpy(sn, "_");
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
attrs[num_attrs-1]->mod_type = "givenname";
- attrs[num_attrs-1]->mod_values = mallok(2 * sizeof(char *));
- attrs[num_attrs-1]->mod_values[0] = strdoop(givenname);
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(givenname);
attrs[num_attrs-1]->mod_values[1] = NULL;
+ /* "uid" is a Kolab compatibility thing. We just do cituser@citnode */
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "uid";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(uid);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+
+ /* Add a "cn" (Common Name) attribute based on the user's screen name,
+ * but only there was no 'fn' (full name) property in the vCard
+ */
+ if (!have_cn) {
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "cn";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(msg->cm_fields['A']);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+ }
+
+ /* Add a "calFBURL" attribute if a calendar free/busy URL exists */
+ if (strlen(calFBURL) > 0) {
+ attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
+ attrs[num_attrs-1] = malloc(sizeof(LDAPMod));
+ memset(attrs[num_attrs-1], 0, sizeof(LDAPMod));
+ attrs[num_attrs-1]->mod_op = LDAP_MOD_ADD;
+ attrs[num_attrs-1]->mod_type = "calFBURL";
+ attrs[num_attrs-1]->mod_values = malloc(2 * sizeof(char *));
+ attrs[num_attrs-1]->mod_values[0] = strdup(calFBURL);
+ attrs[num_attrs-1]->mod_values[1] = NULL;
+ }
+
/* The last attribute must be a NULL one. */
attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
attrs[num_attrs - 1] = NULL;
- lprintf(9, "this_dn: <%s>\n", this_dn);
-
- lprintf(9, "Calling ldap_add_s()\n");
+ lprintf(CTDL_DEBUG, "Calling ldap_add_s() for '%s'\n", this_dn);
begin_critical_section(S_LDAP);
i = ldap_add_s(dirserver, this_dn, attrs);
end_critical_section(S_LDAP);
for (j=0; j<(num_attrs-1); ++j) {
attrs[j]->mod_op = LDAP_MOD_REPLACE;
}
- lprintf(9, "Calling ldap_modify_s()\n");
+ lprintf(CTDL_DEBUG, "Calling ldap_modify_s() for '%s'\n", this_dn);
begin_critical_section(S_LDAP);
i = ldap_modify_s(dirserver, this_dn, attrs);
end_critical_section(S_LDAP);
}
if (i != LDAP_SUCCESS) {
- lprintf(3, "ldap_add_s() failed: %s (%d)\n",
+ lprintf(CTDL_ERR, "ldap_add_s() failed: %s (%d)\n",
ldap_err2string(i), i);
}
- lprintf(9, "Freeing attributes\n");
+ lprintf(CTDL_DEBUG, "Freeing attributes\n");
/* Free the attributes */
for (i=0; i<num_attrs; ++i) {
if (attrs[i] != NULL) {
/* First, free the value strings */
if (attrs[i]->mod_values != NULL) {
for (j=0; attrs[i]->mod_values[j] != NULL; ++j) {
- phree(attrs[i]->mod_values[j]);
+ free(attrs[i]->mod_values[j]);
}
}
/* Free the value strings pointer list */
if (attrs[i]->mod_values != NULL) {
- phree(attrs[i]->mod_values);
+ free(attrs[i]->mod_values);
}
/* Now free the LDAPMod struct itself. */
- phree(attrs[i]);
+ free(attrs[i]);
}
}
- phree(attrs);
- lprintf(9, "LDAP operation complete.\n");
+ free(attrs);
+ lprintf(CTDL_DEBUG, "LDAP write operation complete.\n");
}
/*
* Initialize the LDAP connector module ... or don't, if we don't have LDAP.
*/
-char *serv_ldap_init(void)
+CTDL_MODULE_INIT(ldap)
{
#ifdef HAVE_LDAP
CtdlRegisterCleanupHook(serv_ldap_cleanup);
}
#endif /* HAVE_LDAP */
+
+ /* return our Subversion id for the Log */
return "$Id$";
}