2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2003-2007 Michael Rasmussen and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * Functions necessary to access LDAP servers.
31 #include <glib/gi18n.h>
37 #include "ldapupdate.h"
40 #include "addrcache.h"
42 #include "ldapquery.h"
43 #include "ldapserver.h"
46 #include "adbookbase.h"
49 * Structure to hold user defined attributes
52 typedef struct _AttrKeyValue AttrKeyValue;
53 struct _AttrKeyValue {
59 * Structure to hold contact information.
60 * Each addressbook will have 0..N contacts.
62 typedef struct _EmailKeyValue EmailKeyValue;
63 struct _EmailKeyValue {
70 * Structure to hold information about RDN.
72 typedef struct _Rdn Rdn;
80 * Retrieve address group item for update.
81 * \param group Group to print.
82 * \param array GHashTAble of item_group, or <i>NULL</i> if none created.
84 void ldapsvr_retrieve_item_group(ItemGroup *group, GHashTable *array) {
85 /* Not implemented in this release */
86 g_return_if_fail(group != NULL);
90 * Create an initial EmailKeyValue structure
91 * \return empty structure
93 EmailKeyValue *emailkeyvalue_create() {
96 buf = g_new0(EmailKeyValue, 1);
104 * Create an initial AttrKeyValue structure
105 * \return empty structure
107 AttrKeyValue *attrkeyvalue_create() {
110 buf = g_new0(AttrKeyValue, 1);
117 * Retrieve E-Mail address object for update.
118 * \param item ItemEmail to update.
119 * \return object, or <i>NULL</i> if none created.
121 EmailKeyValue *ldapsvr_retrieve_item_email(ItemEMail *item) {
122 EmailKeyValue *newItem;
123 g_return_val_if_fail(item != NULL, NULL);
124 newItem = emailkeyvalue_create();
125 newItem->alias = g_strdup(ADDRITEM_NAME(item));
126 newItem->mail = g_strdup(item->address);
127 newItem->remarks = g_strdup(item->remarks);
132 * Retrieve user attribute object for update.
133 * \param item UserAttribute to update.
134 * \return object, or <i>NULL</i> if none created.
136 AttrKeyValue *ldapsvr_retrieve_attribute(UserAttribute *item) {
137 AttrKeyValue *newItem;
138 g_return_val_if_fail(item != NULL, NULL);
139 newItem = attrkeyvalue_create();
140 newItem->key = g_strdup(item->name);
141 newItem->value = g_strdup(item->value);
146 * Retrieve person object for update.
147 * \param person ItemPerson to update.
148 * \param array GHashTable with user input.
149 * \return false if update is not needed, or true if update is needed.
151 gboolean ldapsvr_retrieve_item_person(ItemPerson *person, GHashTable *array) {
154 g_return_val_if_fail(person != NULL, FALSE);
155 switch (person->status) {
156 case NONE: return FALSE;
157 case ADD_ENTRY: g_hash_table_insert(array, "status", "new"); break;
158 case UPDATE_ENTRY: g_hash_table_insert(array, "status", "update"); break;
159 case DELETE_ENTRY: g_hash_table_insert(array, "status", "delete"); break;
160 default: g_critical(_("ldapsvr_retrieve_item_person->Unknown status: %d"), person->status);
162 g_hash_table_insert(array, "uid", ADDRITEM_ID(person));
163 g_hash_table_insert(array, "cn", ADDRITEM_NAME(person));
164 g_hash_table_insert(array, "givenName", person->firstName);
165 g_hash_table_insert(array, "sn", person->lastName);
166 g_hash_table_insert(array, "nickName", person->nickName);
167 g_hash_table_insert(array, "dn", person->externalID);
168 node = person->listEMail;
171 EmailKeyValue *newEmail = ldapsvr_retrieve_item_email(node->data);
173 attr = g_list_append(attr, newEmail);
174 node = g_list_next(node);
176 g_hash_table_insert(array, "mail", attr);
177 /* Not implemented in this release.
178 node = person->listAttrib;
181 AttrKeyValue *newAttr = ldapsvr_retrieve_attribute(node->data)
183 attr = g_list_append(attr, newAttr);
184 node = g_list_next(node);
186 g_hash_table_insert(array, "attribute", attr);
192 * Print contents of contacts hashtable for debug.
193 * This function must be called with g_hash_table_foreach.
194 * \param key Key to process.
195 * \param data Data to process.
196 * \param fd Output stream.
198 void ldapsvr_print_contacts_hashtable(gpointer key, gpointer data, gpointer fd) {
199 gchar *keyName = (gchar *) key;
202 if (g_ascii_strcasecmp("mail", keyName) == 0) {
203 node = (GList *) data;
205 EmailKeyValue *item = node->data;
206 if (debug_get_mode()) {
207 debug_print("\t\talias = %s\n", item->alias);
208 debug_print("\t\tmail = %s\n", item->mail);
209 debug_print("\t\tremarks = %s\n", item->remarks);
212 FILE *stream = (FILE *) fd;
213 fprintf(stream, "\t\talias = %s\n", item->alias);
214 fprintf(stream, "\t\tmail = %s\n", item->mail);
215 fprintf(stream, "\t\tremarks = %s\n", item->remarks);
217 node = g_list_next(node);
220 else if (g_ascii_strcasecmp("attribute", keyName) == 0) {
221 node = (GList *) data;
223 AttrKeyValue *item = node->data;
224 if (debug_get_mode()) {
225 debug_print("\t\t%s = %s\n", item->key, item->value);
228 FILE *stream = (FILE *) fd;
229 fprintf(stream, "\t\t%s = %s\n", item->key, item->value);
231 node = g_list_next(node);
235 if (debug_get_mode())
236 debug_print("\t\t%s = %s\n", keyName, (gchar *) data);
238 FILE *stream = (FILE *) fd;
239 fprintf(stream, "\t\t%s = %s\n", keyName, (gchar *) data);
245 * Free list of changed contacts
247 * \param list List of GHashTable
249 void ldapsvr_free_hashtable(GList *list) {
251 g_hash_table_destroy(list->data);
252 list = g_list_next(list);
258 * Get person object from cache
260 * \param server Resource to LDAP
261 * \param uid PersonID in cache
262 * \return person object, or <i>NULL</i> if fail
264 ItemPerson *ldapsvr_get_contact(LdapServer *server, gchar *uid) {
266 g_return_val_if_fail(server != NULL || uid != NULL, NULL);
267 aio = addrcache_get_object(server->addressCache, uid);
269 if(aio->type == ITEMTYPE_PERSON) {
270 return (ItemPerson *) aio;
277 * Connect to LDAP server.
278 * \param ctl Control object to process.
279 * \return LDAP Resource to LDAP.
281 LDAP *ldapsvr_connect(LdapControl *ctl) {
287 g_return_val_if_fail(ctl != NULL, NULL);
289 uri = g_strdup_printf("ldap%s://%s:%d",
290 ctl->enableSSL?"s":"",
291 ctl->hostName, ctl->port);
292 ldap_initialize(&ld, uri);
298 debug_print("connected to LDAP host %s on port %d\n", ctl->hostName, ctl->port);
302 version = LDAP_VERSION3;
303 rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
304 if (rc == LDAP_OPT_SUCCESS) {
305 ctl->version = LDAP_VERSION3;
308 if (ctl->version == LDAP_VERSION3) {
309 if (ctl->enableTLS && !ctl->enableSSL) {
310 rc = ldap_start_tls_s(ld, NULL, NULL);
312 if (rc != LDAP_SUCCESS) {
313 fprintf(stderr, "LDAP Error(tls): ldap_simple_bind_s: %s\n",
314 ldap_err2string(rc));
321 /* Bind to the server, if required */
323 if (* ctl->bindDN != '\0') {
324 rc = claws_ldap_simple_bind_s(ld, ctl->bindDN, ctl->bindPass);
325 if (rc != LDAP_SUCCESS) {
326 fprintf(stderr, "bindDN: %s, bindPass: %s\n", ctl->bindDN, ctl->bindPass);
327 fprintf(stderr, "LDAP Error(bind): ldap_simple_bind_s: %s\n",
328 ldap_err2string(rc));
337 * Disconnect to LDAP server.
338 * \param ld Resource to LDAP.
340 void ldapsvr_disconnect(LDAP *ld) {
342 g_return_if_fail(ld != NULL);
343 ldap_unbind_ext(ld, NULL, NULL);
347 * Create an initial Rdn structure
349 * \return empty structure
354 buf = g_new0(Rdn, 1);
355 buf->attribute = NULL;
362 * update Rdn structure
364 * \param rdn Rdn structure to update
365 * \param head Uniq part of dn
366 * \param tail Common part of dn
368 void update_rdn(Rdn *rdn, gchar *head, gchar *tail) {
369 rdn->value = g_strdup(head);
370 rdn->new_dn = g_strdup_printf("mail=%s%s", head, tail);
374 * Deside if dn needs to be changed
376 * \param hash GHashTable with user input.
377 * \param dn dn for current object
378 * \return Rdn structure
380 Rdn *ldapsvr_modify_dn(GHashTable *hash, gchar *dn) {
382 gchar *pos, *compare;
383 g_return_val_if_fail(hash != NULL || dn != NULL, NULL);
385 pos = g_strstr_len(dn, strlen(dn), "=");
386 compare = g_strndup(dn, pos - dn);
391 gchar *rest = g_strstr_len(pos, strlen(pos), ",");
392 gchar *val = g_strndup(pos, rest - pos);
399 rdn->value = g_strdup(val);
400 rdn->attribute = g_strdup(compare);
402 if (strcmp("mail", rdn->attribute) == 0) {
403 GList *list = g_hash_table_lookup(hash, rdn->attribute);
405 EmailKeyValue *item = list->data;
406 compare = g_strdup((gchar *) item->mail);
407 if (strcmp(compare, rdn->value) == 0) {
408 update_rdn(rdn, compare, rest);
412 list = g_list_next(list);
414 /* if compare and rdn->attribute are equal then last email removed/empty */
415 if (strcmp(compare, rdn->attribute) != 0) {
416 /* RDN changed. Find new */
417 update_rdn(rdn, compare, rest);
422 /* We cannot remove dn */
428 compare = g_hash_table_lookup(hash, rdn->attribute);
429 /* if compare and rdn->attribute are equal then dn removed/empty */
430 if (strcmp(compare, rdn->attribute) != 0) {
431 update_rdn(rdn, compare, rest);
435 /* We cannot remove dn */
443 * This macro is borrowed from the Balsa project
444 * Creates a LDAPMod structure
446 * \param mods Empty LDAPMod structure
447 * \param modarr Array with values to insert
448 * \param op Operation to perform on LDAP
449 * \param attr Attribute to insert
450 * \param strv Empty array which is NULL terminated
451 * \param val Value for attribute
453 #define SETMOD(mods,modarr,op,attr,strv,val) \
454 do { (mods) = &(modarr); (modarr).mod_type=attr; (modarr).mod_op=op;\
455 (strv)[0]=(val); (modarr).mod_values=strv; \
459 * Creates a LDAPMod structure
461 * \param mods Empty LDAPMod structure
462 * \param modarr Array with values to insert
463 * \param op Operation to perform on LDAP
464 * \param attr Attribute to insert
465 * \param strv Array with values to insert. Must be NULL terminated
467 #define SETMODS(mods,modarr,op,attr,strv) \
468 do { (mods) = &(modarr); (modarr).mod_type=attr; \
469 (modarr).mod_op=op; (modarr).mod_values=strv; \
474 * Clean up, close LDAP connection, and refresh cache
476 * \param ld Resource to LDAP
477 * \param server AddressBook resource
478 * \param contact GHashTable with current changed object
480 void clean_up(LDAP *ld, LdapServer *server, GHashTable *contact) {
482 ldapsvr_get_contact(server, g_hash_table_lookup(contact , "uid"));
485 person->status = NONE;
486 displayName = g_hash_table_lookup(contact, "displayName");
488 person->nickName = g_strdup(displayName);
491 ldapsvr_disconnect(ld);
492 ldapsvr_force_refresh(server);
493 /* ldapsvr_free_all_query(server);*/
497 * Get cn attribute from dn
499 * \param dn Distinguesh Name for current object
500 * \return AttrKeyValue, or <i>NULL</i> if none created
502 AttrKeyValue *get_cn(gchar *dn) {
508 g_return_val_if_fail(dn != NULL, NULL);
510 cn = attrkeyvalue_create();
511 start = g_strstr_len(dn, strlen(dn), "cn");
514 end = g_strstr_len(start, strlen(start), ",");
515 item = g_strndup(start, end - start);
518 key_value = g_strsplit(item, "=", 2);
519 cn->key = g_strdup(key_value[0]);
520 cn->value = g_strdup(key_value[1]);
521 g_strfreev(key_value);
527 * Get ou or o attribute from dn
529 * \param dn Distinguesh Name for current object
530 * \return AttrKeyValue, or <i>NULL</i> if none created
532 AttrKeyValue *get_ou(gchar *dn) {
539 g_return_val_if_fail(dn != NULL, NULL);
540 ou = attrkeyvalue_create();
541 start = g_strstr_len(dn, strlen(dn), ",o=");
543 start = g_strstr_len(dn, strlen(dn), ",ou=");
547 end = g_strstr_len(start, strlen(start), ",");
548 item = g_strndup(start, end - start);
551 key_value = g_strsplit(item, "=", 2);
552 ou->key = g_strdup(key_value[0]);
553 ou->value = g_strdup(key_value[1]);
554 g_strfreev(key_value);
560 * Print the contents of a LDAPMod structure for debuging purposes
562 * \param mods LDAPMod structure
564 void ldapsvr_print_ldapmod(LDAPMod *mods[]) {
568 fprintf( stderr, "Type\n");
569 for (i = 0; NULL != mods[i]; i++) {
570 LDAPMod *mod = (LDAPMod *) mods[i];
572 switch (mod->mod_op) {
573 case LDAP_MOD_ADD: mod_op = g_strdup("ADD"); break;
574 case LDAP_MOD_REPLACE: mod_op = g_strdup("MODIFY"); break;
575 case LDAP_MOD_DELETE: mod_op = g_strdup("DELETE"); break;
576 default: mod_op = g_strdup("UNKNOWN");
578 fprintf( stderr, "Operation: %s\tType:%s\nValues:\n", mod_op, mod->mod_type);
579 vals = mod->mod_vals.modv_strvals;
581 fprintf( stderr, "\t%s\n", *vals++);
587 * Add new contact to LDAP
589 * \param server AddressBook resource
590 * \param contact GHashTable with object to add
592 void ldapsvr_add_contact(LdapServer *server, GHashTable *contact) {
593 gchar *email = NULL, *param = NULL;
595 LDAPMod *mods[MODSIZE];
598 char *cn[] = {NULL, NULL};
599 char *displayName[] = {NULL, NULL};
600 char *givenName[] = {NULL, NULL};
602 char *sn[] = {NULL, NULL};
603 char *org[] = {NULL, NULL};
604 char *obj[] = {/*"top",*/ "person", "organizationalPerson", "inetOrgPerson", NULL};
607 AttrKeyValue *ou, *commonName;
612 g_return_if_fail(server != NULL || contact != NULL);
613 node = g_hash_table_lookup(contact , "mail");
615 EmailKeyValue *newEmail = node->data;
616 email = g_strdup(newEmail->mail);
619 server->retVal = LDAPRC_NODN;
622 base_dn = g_strdup_printf("mail=%s,%s", email, server->control->baseDN);
625 ldapsvr_get_contact(server, g_hash_table_lookup(contact , "uid"));
626 person->externalID = g_strdup(base_dn);
627 debug_print("dn: %s\n", base_dn);
628 ld = ldapsvr_connect(server->control);
630 clean_up(ld, server, contact);
631 debug_print("no ldap found\n");
634 SETMODS(mods[cnt], modarr[cnt], LDAP_MOD_ADD, "objectClass", obj);
636 ou = get_ou(base_dn);
638 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_ADD, ou->key, org, ou->value);
642 commonName = get_cn(base_dn);
643 if (commonName == NULL) {
644 param = g_hash_table_lookup(contact , "cn");
646 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_ADD, "cn", cn, param);
649 clean_up(ld, server, contact);
650 debug_print("no CN found\n");
655 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_ADD, commonName->key, cn, commonName->value);
657 param = g_hash_table_lookup(contact , "cn");
658 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_ADD, "displayName", displayName, param);
659 g_hash_table_insert(contact, "displayName", param);
662 param = g_hash_table_lookup(contact , "givenName");
664 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_ADD, "givenName", givenName, param);
667 mailList = g_hash_table_lookup(contact , "mail");
669 mail = g_malloc(sizeof(*mail));
670 char **tmp = g_malloc(sizeof(*tmp));
673 EmailKeyValue *item = mailList->data;
674 *tmp++ = g_strdup((gchar *) item->mail);
675 mailList = g_list_next(mailList);
678 SETMODS(mods[cnt], modarr[cnt], LDAP_MOD_ADD, "mail", mail);
681 param = g_hash_table_lookup(contact, "sn");
683 param = g_strdup(N_("Some SN"));
684 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_ADD, "sn", sn, param);
687 if (debug_get_mode()) {
688 ldapsvr_print_ldapmod(mods);
690 server->retVal = LDAPRC_SUCCESS;
691 rc = ldap_add_ext_s(ld, base_dn, mods, NULL, NULL);
694 case LDAP_ALREADY_EXISTS:
695 server->retVal = LDAPRC_ALREADY_EXIST;
698 fprintf(stderr, "ldap_modify for dn=%s\" failed[0x%x]: %s\n",base_dn, rc, ldap_err2string(rc));
700 server->retVal = LDAPRC_STRONG_AUTH;
702 server->retVal = LDAPRC_NAMING_VIOLATION;
706 clean_up(ld, server, contact);
710 * Update contact to LDAP
712 * \param server AddressBook resource
713 * \param contact GHashTable with object to update
715 void ldapsvr_update_contact(LdapServer *server, GHashTable *contact) {
717 LDAPMod *mods[MODSIZE];
721 Rdn *NoRemove = NULL;
722 char *cn[] = {NULL, NULL};
723 char *givenName[] = {NULL, NULL};
725 char *sn[] = {NULL, NULL};
728 g_return_if_fail(server != NULL || contact != NULL);
729 ld = ldapsvr_connect(server->control);
731 clean_up(ld, server, contact);
734 dn = g_hash_table_lookup(contact, "dn");
736 clean_up(ld, server, contact);
739 NoRemove = ldapsvr_modify_dn(contact, dn);
741 /* We are trying to change RDN */
742 gchar *newRdn = g_strdup_printf("%s=%s", NoRemove->attribute, NoRemove->value);
743 int rc = ldap_modrdn2_s(ld, dn, newRdn, 1);
744 if(rc != LDAP_SUCCESS) {
745 if (rc == LDAP_ALREADY_EXISTS) {
746 /* We are messing with a contact with more than one listed email
747 * address and the email we are changing is not the one used for dn
749 /* It needs to be able to handle renaming errors to an already defined
750 * dn. For now we just refuse the update. It will be caught later on as
751 * a LDAPRC_NAMING_VIOLATION error.
755 fprintf(stderr, "Current dn: %s\n", dn);
756 fprintf(stderr, "new dn: %s\n", newRdn);
757 fprintf(stderr, "LDAP Error(ldap_modrdn2_s) failed[0x%x]: %s\n", rc, ldap_err2string(rc));
764 dn = g_strdup(NoRemove->new_dn);
768 server->retVal = LDAPRC_NODN;
769 clean_up(ld, server, contact);
772 param = g_hash_table_lookup(contact , "cn");
773 if (param && (strcmp(param, NoRemove->value) != 0 && strcmp("cn", NoRemove->attribute) != 0)) {
774 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_REPLACE, "displayName", cn, param);
776 g_hash_table_insert(contact, "displayName", param);
778 param = g_hash_table_lookup(contact , "givenName");
779 if (param && (strcmp(param, NoRemove->value) != 0 && strcmp("givenName", NoRemove->attribute) != 0)) {
780 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_REPLACE, "givenName", givenName, param);
783 mailList = g_hash_table_lookup(contact , "mail");
785 if (!(strcmp("mail", NoRemove->attribute) == 0 && g_list_length(mailList) == 1)) {
786 mail = g_malloc(sizeof(*mail));
787 char **tmp = g_malloc(sizeof(*tmp));
790 EmailKeyValue *item = mailList->data;
791 *tmp++ = g_strdup((gchar *) item->mail);
792 mailList = g_list_next(mailList);
795 SETMODS(mods[cnt], modarr[cnt], LDAP_MOD_REPLACE, "mail", mail);
799 param = g_hash_table_lookup(contact , "sn");
800 if (param && (strcmp(param, NoRemove->value) != 0 && strcmp("sn", NoRemove->attribute) != 0)) {
801 SETMOD(mods[cnt], modarr[cnt], LDAP_MOD_REPLACE, "sn", sn, param);
804 debug_print("newDN: %s\n", dn);
807 server->retVal = LDAPRC_SUCCESS;
811 rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL);
813 fprintf(stderr, "ldap_modify for dn=%s\" failed[0x%x]: %s\n",
814 dn, rc, ldap_err2string(rc));
815 server->retVal = LDAPRC_NAMING_VIOLATION;
820 clean_up(ld, server, contact);
824 * Delete contact from LDAP
826 * \param server AddressBook resource
827 * \param contact GHashTable with object to delete
829 void ldapsvr_delete_contact(LdapServer *server, GHashTable *contact) {
834 g_return_if_fail(server != NULL || contact != NULL);
835 ld = ldapsvr_connect(server->control);
837 clean_up(ld, server, contact);
840 dn = g_hash_table_lookup(contact, "dn");
842 clean_up(ld, server, contact);
845 rc = ldap_delete_ext_s(ld, dn, NULL, NULL);
847 fprintf(stderr, "ldap_modify for dn=%s\" failed[0x%x]: %s\n",
848 dn, rc, ldap_err2string(rc));
849 server->retVal = LDAPRC_NODN;
851 clean_up(ld, server, contact);
855 * Update any changes to the server.
857 * \param server AddressBook resource.
858 * \param person ItemPerson holding user input.
860 void ldapsvr_update_book(LdapServer *server, ItemPerson *item) {
862 GHashTable *contact = NULL;
863 GList *contacts = NULL, *head = NULL;
865 g_return_if_fail(server != NULL);
866 debug_print("updating ldap addressbook\n");
868 contact = g_hash_table_new(g_str_hash, g_str_equal);
870 gboolean result = ldapsvr_retrieve_item_person(item, contact);
871 debug_print("Found contact to update: %s\n", result? "Yes" : "No");
873 if (debug_get_mode()) {
874 addritem_print_item_person(item, stdout);
876 contacts = g_list_append(contacts, contact);
880 ItemFolder *folder = server->addressCache->rootFolder;
881 node = folder->listFolder;
883 node = g_list_copy(node);
884 node = g_list_prepend(node, server->addressCache->rootFolder);
887 AddrItemObject *aio = node->data;
889 if (aio->type == ITEMTYPE_FOLDER) {
890 ItemFolder *folder = (ItemFolder *) aio;
891 GList *persons = folder->listPerson;
893 AddrItemObject *aio = persons->data;
895 if (aio->type == ITEMTYPE_PERSON) {
896 ItemPerson *item = (ItemPerson *) aio;
897 gboolean result = ldapsvr_retrieve_item_person(item, contact);
898 debug_print("Found contact to update: %s\n", result? "Yes" : "No");
900 if (debug_get_mode()) {
901 gchar *uid = g_hash_table_lookup(contact, "uid");
902 item = ldapsvr_get_contact(server, uid);
903 addritem_print_item_person(item, stdout);
905 contacts = g_list_append(contacts, contact);
909 persons = g_list_next(persons);
914 fprintf(stderr, "\t\tpid : ???\n");
916 node = g_list_next(node);
922 if (debug_get_mode()) {
924 debug_print("Contacts which must be updated in LDAP:\n");
926 debug_print("\tContact:\n");
927 g_hash_table_foreach(contacts->data,
928 ldapsvr_print_contacts_hashtable, stderr);
929 contacts = g_list_next(contacts);
932 if (contacts == NULL)
936 contact = (GHashTable *) contacts->data;
937 status = (gchar *) g_hash_table_lookup(contact, "status");
939 status = g_strdup("NULL");
940 if (g_ascii_strcasecmp(status, "new") == 0) {
941 ldapsvr_add_contact(server, contact);
943 else if (g_ascii_strcasecmp(status, "update") == 0) {
944 ldapsvr_update_contact(server, contact);
946 else if (g_ascii_strcasecmp(status, "delete") == 0) {
947 ldapsvr_delete_contact(server, contact);
950 g_critical(_("ldapsvr_update_book->Unknown status: %s\n"), status);
951 contacts = g_list_next(contacts);
953 ldapsvr_free_hashtable(head);
956 #endif /* USE_LDAP */