4 * A module which implements the LDAP connector for Citadel.
16 #include <sys/types.h>
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
23 # include <sys/time.h>
34 #include "sysdep_decls.h"
35 #include "citserver.h"
38 #include "serv_extensions.h"
43 #include "serv_ldap.h"
50 LDAP *dirserver = NULL;
53 * LDAP connector cleanup function
55 void serv_ldap_cleanup(void)
57 if (!dirserver) return;
59 lprintf(7, "Unbinding from directory server\n");
60 ldap_unbind(dirserver);
64 #endif /* HAVE_LDAP */
67 void CtdlConnectToLdap(void) {
71 lprintf(7, "Connecting to LDAP server %s:%d...\n",
72 config.c_ldap_host, config.c_ldap_port);
74 dirserver = ldap_init(config.c_ldap_host, config.c_ldap_port);
75 if (dirserver == NULL) {
76 lprintf(3, "Could not connect to %s:%d : %s\n",
83 ldap_set_option(dirserver, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
85 lprintf(7, "Binding to %s\n", config.c_ldap_bind_dn);
87 i = ldap_simple_bind_s(dirserver,
88 config.c_ldap_bind_dn,
91 if (i != LDAP_SUCCESS) {
92 lprintf(3, "Cannot bind: %s (%d)\n", ldap_err2string(i), i);
93 dirserver = NULL; /* FIXME disconnect from ldap */
100 * Write (add, or change if already exists) a directory entry to the
101 * LDAP server, based on the information supplied in a vCard.
103 void ctdl_vcard_to_ldap(struct CtdlMessage *msg) {
104 struct vCard *v = NULL;
107 LDAPMod **attrs = NULL;
110 if (dirserver == NULL) return;
111 if (msg == NULL) return;
112 if (msg->cm_fields['M'] == NULL) return;
113 if (msg->cm_fields['A'] == NULL) return;
114 if (msg->cm_fields['N'] == NULL) return;
116 sprintf(this_dn, "cn=%s,ou=%s,%s",
119 config.c_ldap_base_dn
122 /* The first LDAP attribute will be an 'objectclass' list. Citadel
123 * doesn't do anything with this. It's just there for compatibility
127 attrs = mallok( (sizeof(LDAPMod *) * num_attrs) );
128 attrs[0] = mallok(sizeof(LDAPMod));
129 memset(attrs[0], 0, sizeof(LDAPMod));
130 attrs[0]->mod_op = LDAP_MOD_ADD;
131 attrs[0]->mod_type = "objectclass";
132 attrs[0]->mod_values = mallok(5 * sizeof(char *));
133 attrs[0]->mod_values[0] = strdoop("inetOrgPerson");
134 attrs[0]->mod_values[1] = strdoop("organizationalPerson");
135 attrs[0]->mod_values[2] = strdoop("person");
136 attrs[0]->mod_values[3] = strdoop("Top");
137 attrs[0]->mod_values[4] = NULL;
139 /* Convert the vCard fields to LDAP properties */
140 v = vcard_load(msg->cm_fields['M']);
141 if (v->numprops) for (i=0; i<(v->numprops); ++i) {
147 vcard_free(v); /* Don't need this anymore. */
149 /* The last attribute must be a NULL one. */
150 attrs = realloc(attrs, (sizeof(LDAPMod *) * ++num_attrs) );
151 attrs[num_attrs - 1] = NULL;
153 lprintf(9, "this_dn: <%s>\n", this_dn);
155 begin_critical_section(S_LDAP);
156 i = ldap_add_s(dirserver, this_dn, attrs);
157 end_critical_section(S_LDAP);
158 if (i != LDAP_SUCCESS) {
159 lprintf(3, "ldap_add_s() failed: %s (%d)\n",
160 ldap_err2string(i), i);
163 /* Free the attributes */
164 for (i=0; i<num_attrs; ++i) {
165 if (attrs[i] != NULL) {
167 /* First, free the value strings */
168 if (attrs[i]->mod_values != NULL) {
169 for (j=0; attrs[i]->mod_values[j] != NULL; ++j) {
170 phree(attrs[i]->mod_values[j]);
174 /* Free the value strings pointer list */
175 if (attrs[i]->mod_values != NULL) {
176 phree(attrs[i]->mod_values);
179 /* Now free the LDAPMod struct itself. */
190 * Initialize the LDAP connector module ... or don't, if we don't have LDAP.
192 char *serv_ldap_init(void)
195 CtdlRegisterCleanupHook(serv_ldap_cleanup);
197 if (strlen(config.c_ldap_host) > 0) {
201 #endif /* HAVE_LDAP */