2011-10-22 [colin] 3.7.10cvs41
[claws.git] / src / editldap.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2001-2011 Match Grun and the Claws Mail team
4  *
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 3 of the License, or
8  * (at your option) any later version.
9  *
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.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  * 
18  */
19
20 /*
21  * Edit LDAP address book data.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #ifdef USE_LDAP
29
30 #include "defs.h"
31
32 #include <glib.h>
33 #include <glib/gi18n.h>
34 #include <gdk/gdkkeysyms.h>
35 #include <gtk/gtk.h>
36
37 #include "addressbook.h"
38 #include "prefs_common.h"
39 #include "addressitem.h"
40 #include "mgutils.h"
41 #include "ldapserver.h"
42 #include "ldapctrl.h"
43 #include "ldaputil.h"
44 #include "editldap_basedn.h"
45 #include "manage_window.h"
46 #include "gtkutils.h"
47 #include "prefs_gtk.h"
48
49 #define PAGE_BASIC      0
50 #define PAGE_SEARCH     1
51 #define PAGE_EXTENDED   2
52
53 #define ADDRESSBOOK_GUESS_LDAP_NAME     "MyServer"
54 #define ADDRESSBOOK_GUESS_LDAP_SERVER   "localhost"
55
56 #define LDAPEDIT_TABLE_ROWS     6
57 #define LDAPEDIT_TABLE_COLS     3
58
59 static struct _LDAPEdit {
60         GtkWidget *window;
61         GtkWidget *notebook;
62         GtkWidget *ok_btn;
63         GtkWidget *cancel_btn;
64         GtkWidget *statusbar;
65         gint status_cid;
66         GtkWidget *entry_name;
67         GtkWidget *entry_server;
68         GtkWidget *spinbtn_port;
69         GtkWidget *entry_baseDN;
70         GtkWidget *spinbtn_timeout;
71         GtkWidget *entry_bindDN;
72         GtkWidget *entry_bindPW;
73         GtkWidget *spinbtn_maxentry;
74         GtkWidget *entry_criteria;
75         GtkWidget *spinbtn_queryage;
76         GtkWidget *check_dynsearch;
77         GtkWidget *check_matchoption;
78 #ifdef USE_LDAP_TLS
79         GtkWidget *enable_ssl;
80         GtkWidget *enable_tls;
81 #endif
82 } ldapedit;
83
84 /**
85  * Parse out individual attribute names from criteria string.
86  * \param criteria Criteria string.
87  * \ctl   Control object.
88  */
89 static gboolean editldap_validate_criteria( gchar *criteria ) {
90         gchar *ptr;
91         gchar **splitStr;
92         gint i;
93         gboolean errorFlag;
94
95         cm_return_val_if_fail(criteria != NULL, TRUE);
96
97         errorFlag = TRUE;
98
99         /* Replace delimiters with spaces */
100         ptr = criteria;
101         while( *ptr ) {
102                 if( *ptr == ',' || *ptr == ';' || *ptr == '|' )
103                         *ptr = ' ';
104                 ptr++;
105         }
106         debug_print("cleaned criteria list: %s\n", criteria);
107
108         /* Parse string */
109         splitStr = g_strsplit( criteria, " ", 0 );
110         i = 0;
111         while( TRUE ) {
112                 if( splitStr[i] ) {
113                         if( *splitStr[i] ) {
114                                 errorFlag = FALSE;
115                                 break;
116                         }
117                 }
118                 else {
119                         break;
120                 }
121                 i++;
122         }
123         g_strfreev( splitStr );
124         return errorFlag;
125 }
126
127 /*
128 * Edit functions.
129 */
130 static void edit_ldap_status_show( gchar *msg ) {
131         if( ldapedit.statusbar != NULL ) {
132                 gtk_statusbar_pop( GTK_STATUSBAR(ldapedit.statusbar), ldapedit.status_cid );
133                 if( msg ) {
134                         gtk_statusbar_push( GTK_STATUSBAR(ldapedit.statusbar),
135                                 ldapedit.status_cid, msg );
136                 }
137         }
138 }
139
140 static gboolean edit_ldap_validate( void ) {
141         gchar *str;
142         gboolean errorFlag;
143         gint page = 0;
144
145         errorFlag = FALSE;
146         str = gtk_editable_get_chars(
147                         GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
148         if( *str == '\0' ) {
149                 page = PAGE_BASIC;
150                 gtk_widget_grab_focus( ldapedit.entry_name );
151                 edit_ldap_status_show( _( "A Name must be supplied." ) );
152                 errorFlag = TRUE;
153         }
154         g_free( str );
155
156         if( ! errorFlag ) {
157                 str = gtk_editable_get_chars(
158                                 GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
159                 if( *str == '\0' ) {
160                         page = PAGE_BASIC;
161                         gtk_widget_grab_focus( ldapedit.entry_server );
162                         edit_ldap_status_show(
163                                 _( "A Hostname must be supplied for the server." ) );
164                         errorFlag = TRUE;
165                 }
166                 g_free( str );
167         }
168
169         if( ! errorFlag ) {
170                 str = gtk_editable_get_chars(
171                                 GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
172                 if( editldap_validate_criteria( str ) ) {
173                         page = PAGE_SEARCH;
174                         gtk_widget_grab_focus( ldapedit.entry_criteria );
175                         edit_ldap_status_show(
176                                 _( "At least one LDAP search attribute should be supplied." ) );
177                         errorFlag = TRUE;
178                 }
179                 g_free( str );
180         }
181
182         /* Switch to page with error */
183         if( errorFlag ) {
184                 gtk_notebook_set_current_page( GTK_NOTEBOOK(ldapedit.notebook), page );
185         }
186
187         return errorFlag;
188 }
189
190 static void edit_ldap_ok( GtkWidget *widget, gboolean *cancelled ) {
191         if( ! edit_ldap_validate() ) {
192                 *cancelled = FALSE;
193                 gtk_main_quit();
194         }
195 }
196
197 static void edit_ldap_cancel( GtkWidget *widget, gboolean *cancelled ) {
198         *cancelled = TRUE;
199         gtk_main_quit();
200 }
201
202 static gint edit_ldap_delete_event( GtkWidget *widget, GdkEventAny *event, gboolean *cancelled ) {
203         *cancelled = TRUE;
204         gtk_main_quit();
205         return TRUE;
206 }
207
208 static gboolean edit_ldap_key_pressed( GtkWidget *widget, GdkEventKey *event, gboolean *cancelled ) {
209         if (event && event->keyval == GDK_KEY_Escape) {
210                 *cancelled = TRUE;
211                 gtk_main_quit();
212         }
213         return FALSE;
214 }
215
216 static void edit_ldap_server_check( void ) {
217         gchar *sHost, *sBind, *sPass;
218         gint iPort, iTime;
219         gchar *sMsg;
220         gchar *sBaseDN = NULL;
221         gint iBaseDN = 0;
222         gboolean flg;
223         gboolean tls = FALSE, ssl = FALSE;
224         GList *baseDN = NULL;
225
226         edit_ldap_status_show( "" );
227         flg = FALSE;
228         sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
229         sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
230         sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
231         iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
232         iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
233 #ifdef USE_LDAP_TLS
234         tls = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ldapedit.enable_tls));
235         ssl = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ldapedit.enable_ssl));
236 #endif
237
238         g_strchomp( sHost ); g_strchug( sHost );
239         g_strchomp( sBind ); g_strchug( sBind );
240         g_strchomp( sPass ); g_strchug( sPass );
241         if( *sHost != '\0' ) {
242                 /* Test connection to server */
243                 debug_print("ldap server: %s\nport: %d\nssl: %d\ntls: %d\nbindDN: %s\n", sHost, iPort, ssl, tls, sBind);
244                 if( ldaputil_test_connect( sHost, iPort, ssl, tls, iTime ) ) {
245                         /* Attempt to read base DN */
246                         baseDN = ldaputil_read_basedn(sHost, iPort, sBind, sPass, iTime, ssl, tls);
247                         if( baseDN ) {
248                                 GList *node = baseDN;
249                                 while( node ) {
250                                         ++iBaseDN;
251                                         if( ! sBaseDN ) {
252                                                 sBaseDN = g_strdup( node->data );
253                                         }
254                                         node = g_list_next( node );
255                                 }
256                                 mgu_free_dlist( baseDN );
257                                 baseDN = node = NULL;
258                                 flg = TRUE;
259                         } else {
260                                 flg = FALSE;
261                         }
262                 }
263         }
264         g_free( sHost );
265         g_free( sBind );
266         g_free( sPass );
267
268         if( sBaseDN ) {
269                 /* Load search DN */
270                 debug_print("baseDN: %s\n", sBaseDN);
271                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), sBaseDN);
272                 g_free( sBaseDN );
273         }
274
275         /* Display appropriate message */
276         if( flg ) {
277                 sMsg = _( "Connected successfully to server" );
278         }
279         else {
280                 sMsg = _( "Could not connect to server" );
281         }
282         edit_ldap_status_show( sMsg );
283 }
284
285 static void edit_ldap_basedn_select( void ) {
286         gchar *sHost, *sBind, *sPass, *sBase;
287         gint iPort, iTime, tls = 0, ssl = 0;
288         gchar *selectDN;
289
290         sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
291         sBase = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
292         sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
293         sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
294         iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
295         iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
296 #ifdef USE_LDAP_TLS
297         tls = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ldapedit.enable_tls));
298         ssl = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ldapedit.enable_ssl));
299 #endif
300
301         g_strchomp( sHost ); g_strchug( sHost );
302         g_strchomp( sBind ); g_strchug( sBind );
303         g_strchomp( sPass ); g_strchug( sPass );
304         debug_print("ldap server: %s\nport: %d\nssl: %d\ntls: %d\nbindDN: %s\n", sHost, iPort, ssl, tls, sBind);
305         selectDN = edit_ldap_basedn_selection( sHost, iPort, sBase, iTime, sBind, sPass, ssl, tls );
306         if( selectDN ) {
307                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), selectDN);
308                 g_free( selectDN );
309                 selectDN = NULL;
310         }
311         g_free( sHost );
312         g_free( sBase );
313         g_free( sBind );
314         g_free( sPass );
315 }
316
317 static void edit_ldap_search_reset(void) {
318         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST);
319 }
320
321 static void addressbook_edit_ldap_dialog_create( gboolean *cancelled ) {
322         GtkWidget *window;
323         GtkWidget *vbox;
324         GtkWidget *notebook;
325         GtkWidget *hbbox;
326         GtkWidget *ok_btn;
327         GtkWidget *cancel_btn;
328         GtkWidget *hsbox;
329         GtkWidget *statusbar;
330
331         debug_print("creating edit_ldap_dialog\n");
332         window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "editldap");
333         gtk_widget_set_size_request(window, 450, -1);
334         gtk_container_set_border_width(GTK_CONTAINER(window), 0);
335         gtk_window_set_title(GTK_WINDOW(window), _("Edit LDAP Server"));
336         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
337         g_signal_connect(G_OBJECT(window), "delete_event",
338                          G_CALLBACK(edit_ldap_delete_event),
339                          cancelled);
340         g_signal_connect(G_OBJECT(window), "key_press_event",
341                          G_CALLBACK(edit_ldap_key_pressed),
342                          cancelled);
343
344         vbox = gtk_vbox_new( FALSE, 6 );
345         gtk_widget_show( vbox );
346         gtk_container_add( GTK_CONTAINER( window ), vbox );
347
348         /* Notebook */
349         notebook = gtk_notebook_new();
350         gtk_widget_show( notebook );
351         gtk_box_pack_start( GTK_BOX( vbox ), notebook, TRUE, TRUE, 0 );
352         gtk_container_set_border_width( GTK_CONTAINER( notebook ), 6 );
353
354         /* Status line */
355         hsbox = gtk_hbox_new(FALSE, 0);
356         gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
357         statusbar = gtk_statusbar_new();
358         gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
359
360         /* Button panel */
361         gtkut_stock_button_set_create(&hbbox, &cancel_btn, GTK_STOCK_CANCEL,
362                                       &ok_btn, GTK_STOCK_OK,
363                                       NULL, NULL);
364         gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
365         gtk_widget_grab_default(ok_btn);
366
367         g_signal_connect(G_OBJECT(ok_btn), "clicked",
368                          G_CALLBACK(edit_ldap_ok), cancelled);
369         g_signal_connect(G_OBJECT(cancel_btn), "clicked",
370                          G_CALLBACK(edit_ldap_cancel), cancelled);
371
372         gtk_widget_show_all(vbox);
373
374         ldapedit.window     = window;
375         ldapedit.notebook   = notebook;
376         ldapedit.ok_btn     = ok_btn;
377         ldapedit.cancel_btn = cancel_btn;
378         ldapedit.statusbar  = statusbar;
379         ldapedit.status_cid =
380                 gtk_statusbar_get_context_id(
381                         GTK_STATUSBAR(statusbar), "Edit LDAP Server Dialog" );
382 }
383
384 static void editldap_update_port (GtkToggleButton *ssl_btn, gpointer data) {
385         gboolean val = gtk_toggle_button_get_active(ssl_btn);
386         gtk_spin_button_set_value(
387                 GTK_SPIN_BUTTON( ldapedit.spinbtn_port ), 
388                         val ? LDAPCTL_DFL_SSL_PORT:LDAPCTL_DFL_PORT );
389         debug_print("Setting port: %d\n", val ? LDAPCTL_DFL_SSL_PORT:LDAPCTL_DFL_PORT);
390 }
391
392 static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
393         GtkWidget *vbox;
394         GtkWidget *table;
395         GtkWidget *label;
396         GtkWidget *entry_name;
397         GtkWidget *entry_server;
398         GtkWidget *hbox_spin;
399         GtkAdjustment *spinbtn_port_adj;
400         GtkWidget *spinbtn_port;
401 #ifdef USE_LDAP_TLS
402         GtkWidget *enable_ssl_checkbtn, *enable_tls_checkbtn;
403 #endif
404         GtkWidget *entry_baseDN;
405         GtkWidget *check_btn;
406         GtkWidget *lookdn_btn;
407         gint top;
408
409         vbox = gtk_vbox_new( FALSE, 8 );
410         gtk_widget_show( vbox );
411         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
412
413         label = gtk_label_new( pageLbl );
414         gtk_widget_show( label );
415         gtk_notebook_set_tab_label(
416                 GTK_NOTEBOOK( ldapedit.notebook ),
417                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
418
419         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
420         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
421         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
422         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
423         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
424
425         /* First row */
426         top = 0;
427         label = gtk_label_new(_("Name"));
428         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
429         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
430
431         entry_name = gtk_entry_new();
432         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1),
433                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
434
435         CLAWS_SET_TIP(entry_name, _( 
436                 "A name that you wish to call the server." ));
437
438         /* Next row */
439         ++top;
440         label = gtk_label_new(_("Hostname"));
441         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
442         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
443
444         entry_server = gtk_entry_new();
445         gtk_table_attach(GTK_TABLE(table), entry_server, 1, 2, top, (top + 1),
446                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
447
448         CLAWS_SET_TIP(entry_server, _( 
449                 "This is the hostname of the server. For example, " \
450                 "\"ldap.mydomain.com\" may be appropriate for the " \
451                 "\"mydomain.com\" organization. An IP address may also be " \
452                 "used. You may specify \"localhost\" if running an LDAP " \
453                 "server on the same computer as Claws Mail." ));
454
455         /* Next row */
456         ++top;
457         label = gtk_label_new(_("Port"));
458         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
459         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
460
461         hbox_spin = gtk_hbox_new (FALSE, 8);
462         spinbtn_port_adj = gtk_adjustment_new (389, 1, 65535, 1, 1000, 0);
463         spinbtn_port = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_port_adj), 1, 0);
464         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_port, TRUE, FALSE, 0);
465         gtk_widget_set_size_request (spinbtn_port, 64, -1);
466         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_port), TRUE);
467         
468 #ifdef USE_LDAP_TLS
469         enable_tls_checkbtn = gtk_check_button_new_with_label(_("TLS"));
470         enable_ssl_checkbtn = gtk_check_button_new_with_label(_("SSL"));
471         SET_TOGGLE_SENSITIVITY_REVERSE(enable_tls_checkbtn, enable_ssl_checkbtn);
472         SET_TOGGLE_SENSITIVITY_REVERSE(enable_ssl_checkbtn, enable_tls_checkbtn);
473         CLAWS_SET_TIP(enable_tls_checkbtn, _( 
474                 "Enable secure connection to the LDAP server via TLS."
475                 "If connection fails, be sure to check the correct "
476                 "configuration in ldap.conf (TLS_CACERTDIR and TLS_REQCERT fields)." ));
477         CLAWS_SET_TIP(enable_ssl_checkbtn, _( 
478                 "Enable secure connection to the LDAP server via SSL."
479                 "If connection fails, be sure to check the correct "
480                 "configuration in ldap.conf (TLS_CACERTDIR and TLS_REQCERT fields)." ));
481
482         gtk_box_pack_start (GTK_BOX (hbox_spin), enable_tls_checkbtn, TRUE, FALSE, 0);
483         gtk_box_pack_start (GTK_BOX (hbox_spin), enable_ssl_checkbtn, TRUE, FALSE, 0);
484 #endif
485
486         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
487                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
488
489         CLAWS_SET_TIP(spinbtn_port, _( 
490                 "The port number that the server listens on. Port 389 is " \
491                 "the default." ));
492
493         check_btn = gtk_button_new_with_label( _(" Check Server "));
494         gtk_table_attach(GTK_TABLE(table), check_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
495
496         CLAWS_SET_TIP(check_btn, _( 
497                 "Press this button to test the connection to the server." ));
498
499         /* Next row */
500         ++top;
501         label = gtk_label_new(_("Search Base"));
502         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
503         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
504
505         entry_baseDN = gtk_entry_new();
506         gtk_table_attach(GTK_TABLE(table), entry_baseDN, 1, 2, top, (top + 1),
507                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
508
509         CLAWS_SET_TIP(entry_baseDN, _( 
510                 "This specifies the name of the directory to be searched " \
511                 "on the server. Examples include:\n" \
512                 "  dc=claws-mail,dc=org\n" \
513                 "  ou=people,dc=domainname,dc=com\n" \
514                 "  o=Organization Name,c=Country\n"
515                 ));
516
517         lookdn_btn = gtkut_get_browse_file_btn(_("_Browse"));
518         gtk_table_attach(GTK_TABLE(table), lookdn_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
519
520         CLAWS_SET_TIP(lookdn_btn, _( 
521                 "Press this button to lookup the name of available " \
522                 "directory names on the server." ));
523
524         /* Signal handlers */
525         g_signal_connect(G_OBJECT(check_btn), "clicked",
526                          G_CALLBACK(edit_ldap_server_check), NULL);
527         g_signal_connect(G_OBJECT(lookdn_btn), "clicked",
528                          G_CALLBACK(edit_ldap_basedn_select), NULL);
529
530         /* Done */
531         gtk_widget_show_all(vbox);
532
533         ldapedit.entry_name   = entry_name;
534         ldapedit.entry_server = entry_server;
535         ldapedit.spinbtn_port = spinbtn_port;
536         ldapedit.entry_baseDN = entry_baseDN;
537 #ifdef USE_LDAP_TLS
538         ldapedit.enable_ssl = enable_ssl_checkbtn;
539         ldapedit.enable_tls = enable_tls_checkbtn;
540
541         g_signal_connect(G_OBJECT(enable_ssl_checkbtn), "toggled", \
542                          G_CALLBACK(editldap_update_port), NULL); 
543 #endif                   
544 }
545
546 static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
547         GtkWidget *vbox;
548         GtkWidget *table;
549         GtkWidget *label;
550         GtkWidget *entry_criteria;
551         GtkWidget *hbox_spin;
552         GtkAdjustment *spinbtn_queryage_adj;
553         GtkWidget *spinbtn_queryage;
554         GtkWidget *check_dynsearch;
555         GtkWidget *check_matchoption;
556         GtkWidget *reset_btn;
557         gint top;
558
559         vbox = gtk_vbox_new( FALSE, 8 );
560         gtk_widget_show( vbox );
561         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
562
563         label = gtk_label_new( pageLbl );
564         gtk_widget_show( label );
565         gtk_notebook_set_tab_label(
566                 GTK_NOTEBOOK( ldapedit.notebook ),
567                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
568
569         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
570         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
571         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
572         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
573         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
574
575         /* First row */
576         top = 0;
577         label = gtk_label_new(_("Search Attributes"));
578         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
579         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
580
581         entry_criteria = gtk_entry_new();
582         gtk_table_attach(GTK_TABLE(table), entry_criteria, 1, 2, top, (top + 1),
583                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
584
585         CLAWS_SET_TIP(entry_criteria, _( 
586                 "A list of LDAP attribute names that should be searched " \
587                 "when attempting to find a name or address." ));
588
589         reset_btn = gtk_button_new_with_label( _(" Defaults "));
590         gtk_table_attach(GTK_TABLE(table), reset_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
591
592         CLAWS_SET_TIP(reset_btn, _( 
593                 "This resets the attribute names to a default value " \
594                 "that should find most names and addresses during a " \
595                 "name or address search process." ));
596
597         /* Next row */
598         ++top;
599         label = gtk_label_new(_("Max Query Age (secs)"));
600         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
601         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
602
603         hbox_spin = gtk_hbox_new (FALSE, 8);
604         spinbtn_queryage_adj = gtk_adjustment_new(
605                 LDAPCTL_DFL_QUERY_AGE, 1, LDAPCTL_MAX_QUERY_AGE, 10, 1000, 0 );
606         spinbtn_queryage = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_queryage_adj), 1, 0);
607         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_queryage, FALSE, FALSE, 0);
608         gtk_widget_set_size_request (spinbtn_queryage, 64, -1);
609         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_queryage), TRUE);
610         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
611                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
612
613         CLAWS_SET_TIP(spinbtn_queryage, _( 
614                 "This defines the maximum period of time (in seconds) that " \
615                 "an address search result is valid for address completion " \
616                 "purposes. Search results are stored in a cache until this " \
617                 "period of time has passed and then retired. This will " \
618                 "improve the response time when attempting to search for " \
619                 "the same name or address on subsequent address completion " \
620                 "requests. The cache will be searched in preference to " \
621                 "performing a new server search request. The default value " \
622                 "of 600 seconds (10 minutes), should be sufficient for most " \
623                 "servers. A larger value will reduce the search time for " \
624                 "subsequent searches. This is useful for servers that have " \
625                 "slow response times at the expense of more memory to cache " \
626                 "results." ));
627
628         /* Next row */
629         ++top;
630         check_dynsearch = gtk_check_button_new_with_label(
631                                 _("Include server in dynamic search") );
632         gtk_table_attach(GTK_TABLE(table), check_dynsearch, 1, 3, top, (top + 1),
633                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
634
635         CLAWS_SET_TIP(check_dynsearch, _( 
636                 "Check this option to include this server for dynamic " \
637                 "searches when using address completion." ));
638
639         /* Next row */
640         ++top;
641         check_matchoption = gtk_check_button_new_with_label(
642                                 _("Match names 'containing' search term") );
643         gtk_table_attach(GTK_TABLE(table), check_matchoption, 1, 3, top, (top + 1),
644                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
645
646         CLAWS_SET_TIP(check_matchoption, _( 
647                 "Searches for names and addresses can be performed either " \
648                 "using \"begins-with\" or \"contains\" search term. Check " \
649                 "this option to perform a \"contains\" search; this type of " \
650                 "search usually takes longer to complete. Note that for " \
651                 "performance reasons, address completion uses " \
652                 "\"begins-with\" for all searches against other address " \
653                 "interfaces." \
654                 ));
655
656         /* Signal handlers */
657         g_signal_connect(G_OBJECT(reset_btn), "clicked",
658                          G_CALLBACK(edit_ldap_search_reset), NULL);
659
660         /* Done */
661         gtk_widget_show_all(vbox);
662
663         ldapedit.entry_criteria    = entry_criteria;
664         ldapedit.spinbtn_queryage  = spinbtn_queryage;
665         ldapedit.check_dynsearch   = check_dynsearch;
666         ldapedit.check_matchoption = check_matchoption;
667 }
668
669 static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl ) {
670         GtkWidget *vbox;
671         GtkWidget *table;
672         GtkWidget *label;
673         GtkWidget *entry_bindDN;
674         GtkWidget *entry_bindPW;
675         GtkWidget *hbox_spin;
676         GtkAdjustment *spinbtn_timeout_adj;
677         GtkWidget *spinbtn_timeout;
678         GtkAdjustment *spinbtn_maxentry_adj;
679         GtkWidget *spinbtn_maxentry;
680         gint top;
681
682         vbox = gtk_vbox_new( FALSE, 8 );
683         gtk_widget_show( vbox );
684         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
685
686         label = gtk_label_new( pageLbl );
687         gtk_widget_show( label );
688         gtk_notebook_set_tab_label(
689                 GTK_NOTEBOOK( ldapedit.notebook ),
690                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
691
692         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
693         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
694         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
695         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
696         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
697
698         /* Next row */
699         top = 0;
700         label = gtk_label_new(_("Bind DN"));
701         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
702         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
703
704         entry_bindDN = gtk_entry_new();
705         gtk_table_attach(GTK_TABLE(table), entry_bindDN, 1, 2, top, (top + 1),
706                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
707
708         CLAWS_SET_TIP(entry_bindDN, _( 
709                 "The LDAP user account name to be used to connect to the server. " \
710                 "This is usually only used for protected servers. This name " \
711                 "is typically formatted as: \"cn=user,dc=claws-mail,dc=org\". " \
712                 "This is usually left empty when performing a search." ));
713
714         /* Next row */
715         ++top;
716         label = gtk_label_new(_("Bind Password"));
717         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
718         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
719
720         entry_bindPW = gtk_entry_new();
721         gtk_table_attach(GTK_TABLE(table), entry_bindPW, 1, 2, top, (top + 1),
722                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
723         gtk_entry_set_visibility(GTK_ENTRY(entry_bindPW), FALSE);
724 #ifdef MAEMO
725         hildon_gtk_entry_set_input_mode(GTK_ENTRY(entry_bindPW), 
726                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
727 #endif
728
729         CLAWS_SET_TIP(entry_bindPW, _( 
730                 "The password to be used when connecting as the \"Bind DN\" " \
731                 "user." ));
732
733         /* Next row */
734         ++top;
735         label = gtk_label_new(_("Timeout (secs)"));
736         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
737         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
738
739         hbox_spin = gtk_hbox_new (FALSE, 8);
740         spinbtn_timeout_adj = gtk_adjustment_new (0, 0, 300, 1, 10, 0);
741         spinbtn_timeout = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_timeout_adj), 1, 0);
742         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_timeout, FALSE, FALSE, 0);
743         gtk_widget_set_size_request (spinbtn_timeout, 64, -1);
744         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_timeout), TRUE);
745         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
746                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
747
748         CLAWS_SET_TIP(spinbtn_timeout, _( 
749                 "The timeout period in seconds." ));
750
751         /* Next row */
752         ++top;
753         label = gtk_label_new(_("Maximum Entries"));
754         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
755         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
756
757         hbox_spin = gtk_hbox_new (FALSE, 8);
758         spinbtn_maxentry_adj = gtk_adjustment_new (0, 0, 500, 1, 10, 0);
759         spinbtn_maxentry = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_maxentry_adj), 1, 0);
760         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_maxentry, FALSE, FALSE, 0);
761         gtk_widget_set_size_request (spinbtn_maxentry, 64, -1);
762         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_maxentry), TRUE);
763         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
764                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
765
766         CLAWS_SET_TIP(spinbtn_maxentry, _( 
767                 "The maximum number of entries that should be returned " \
768                 "in the search result." ));
769
770         /* Done */
771         gtk_widget_show_all(vbox);
772
773         ldapedit.entry_bindDN     = entry_bindDN;
774         ldapedit.entry_bindPW     = entry_bindPW;
775         ldapedit.spinbtn_timeout  = spinbtn_timeout;
776         ldapedit.spinbtn_maxentry = spinbtn_maxentry;
777 }
778
779 static void addressbook_edit_ldap_create( gboolean *cancelled ) {
780         gint page = 0;
781         addressbook_edit_ldap_dialog_create( cancelled );
782         addressbook_edit_ldap_page_basic( page++, _( "Basic" ) );
783         addressbook_edit_ldap_page_search( page++, _( "Search" ) );
784         addressbook_edit_ldap_page_extended( page++, _( "Extended" ) );
785         gtk_widget_show_all( ldapedit.window );
786 }
787
788 /**
789  * Format criteria list for display.
790  * \param ctl Control object.
791  * \return Formatted string, or <i>NULL</i> if no attributes found.
792  */
793 static gchar *editldap_build_criteria_list( const LdapControl *ctl ) {
794         gchar *str = NULL;
795         gchar *tmp = NULL;
796         GList *node;
797
798         node = ldapctl_get_criteria_list( ctl );
799         while( node ) {
800                 gchar *attr = node->data;
801                 if( str ) {
802                         tmp = g_strdup_printf( "%s, %s", str, attr );
803                         g_free( str );
804                         str = tmp;
805                         tmp = NULL;
806                 }
807                 else {
808                         str = g_strdup( attr );
809                 }
810                 node = g_list_next( node );
811         }
812
813         return str;
814 }
815
816 /**
817  * Parse out individual attribute names from criteria string.
818  * \param criteria Criteria string.
819  * \ctl   Control object.
820  */
821 static void editldap_parse_criteria( gchar *criteria, LdapControl *ctl ) {
822         gchar *ptr;
823         gchar **splitStr;
824         gint i;
825
826         /* Replace delimiters with spaces */
827         ptr = criteria;
828         while( *ptr ) {
829                 if( *ptr == ',' || *ptr == ';' || *ptr == '|' )
830                         *ptr = ' ';
831                 ptr++;
832         }
833
834         /* Parse string */
835         ldapctl_criteria_list_clear( ctl );
836         splitStr = g_strsplit( criteria, " ", 0 );
837         i = 0;
838         while( TRUE ) {
839                 if( splitStr[i] ) {
840                         if( *splitStr[i] ) {
841                                 ldapctl_criteria_list_add( ctl, splitStr[i] );
842                         }
843                 }
844                 else {
845                         break;
846                 }
847                 i++;
848         }
849         g_strfreev( splitStr );
850 }
851
852 /**
853  * Clear entry fields to reasonable defaults (for a new server entry).
854  */
855 static void edit_ldap_clear_fields(void) {
856         gtk_entry_set_text(
857                 GTK_ENTRY(ldapedit.entry_name), ADDRESSBOOK_GUESS_LDAP_NAME );
858         gtk_entry_set_text(
859                 GTK_ENTRY(ldapedit.entry_server), ADDRESSBOOK_GUESS_LDAP_SERVER );
860         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), "");
861         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindDN), "");
862         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindPW), "");
863         gtk_spin_button_set_value(
864                 GTK_SPIN_BUTTON( ldapedit.spinbtn_port ), LDAPCTL_DFL_PORT );
865         gtk_spin_button_set_value(
866                 GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ), LDAPCTL_DFL_TIMEOUT );
867         gtk_spin_button_set_value(
868                 GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ), LDAPCTL_DFL_TIMEOUT );
869         gtk_entry_set_text(
870                 GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST);
871         gtk_spin_button_set_value(
872                 GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), LDAPCTL_DFL_QUERY_AGE );
873         gtk_toggle_button_set_active(
874                 GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), TRUE );
875         gtk_toggle_button_set_active(
876                 GTK_TOGGLE_BUTTON( ldapedit.check_matchoption), FALSE );
877 #ifdef USE_LDAP_TLS
878         gtk_toggle_button_set_active(
879                 GTK_TOGGLE_BUTTON( ldapedit.enable_ssl), FALSE );
880         gtk_toggle_button_set_active(
881                 GTK_TOGGLE_BUTTON( ldapedit.enable_tls), FALSE );
882 #endif
883 }
884
885 /**
886  * Load entry fields from server control data.
887  * \param server Server object.
888  */
889 static void edit_ldap_set_fields( LdapServer *server ) {
890         LdapControl *ctl;
891         gchar *crit;
892         gchar *pwd;
893
894         if( ldapsvr_get_name( server ) )
895                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_name),
896                 ldapsvr_get_name( server ) );
897
898         ctl = server->control;
899         if( ctl->hostName )
900                 gtk_entry_set_text(
901                         GTK_ENTRY(ldapedit.entry_server), ctl->hostName);
902         if( ctl->baseDN )
903                 gtk_entry_set_text(
904                         GTK_ENTRY(ldapedit.entry_baseDN), ctl->baseDN );
905         if( ctl->bindDN )
906                 gtk_entry_set_text(
907                         GTK_ENTRY(ldapedit.entry_bindDN), ctl->bindDN );
908         if( ctl->bindPass ) {
909                 pwd = ldapctl_get_bind_password( ctl );
910                 gtk_entry_set_text(     GTK_ENTRY(ldapedit.entry_bindPW),  pwd );
911                 g_free(pwd);
912         }
913         gtk_spin_button_set_value(
914                 GTK_SPIN_BUTTON(ldapedit.spinbtn_timeout), ctl->timeOut );
915         gtk_spin_button_set_value(
916                 GTK_SPIN_BUTTON(ldapedit.spinbtn_maxentry), ctl->maxEntries );
917 #ifdef USE_LDAP_TLS
918         gtk_toggle_button_set_active(
919                 GTK_TOGGLE_BUTTON(ldapedit.enable_tls), ctl->enableTLS );
920         gtk_toggle_button_set_active(
921                 GTK_TOGGLE_BUTTON(ldapedit.enable_ssl), ctl->enableSSL );
922 #endif
923         gtk_spin_button_set_value(
924                 GTK_SPIN_BUTTON(ldapedit.spinbtn_port), ctl->port );
925         /* Format criteria */
926         crit = editldap_build_criteria_list( ctl );
927         if( crit ) {
928                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), crit );
929                 g_free( crit );
930         }
931         else {
932                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), "" );
933         }
934         gtk_spin_button_set_value(
935                 GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), ctl->maxQueryAge );
936         gtk_toggle_button_set_active(
937                 GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), server->searchFlag );
938         gtk_toggle_button_set_active(
939                 GTK_TOGGLE_BUTTON( ldapedit.check_matchoption),
940                 ( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) );
941 }
942
943 /**
944  * Edit LDAP server datasource that appears addressbook.
945  * \param addrIndex Address index object.
946  * \param ads       Data source adapter.
947  * \return Update data source adapter, or <code>NULL</code> if user cancelled
948  *         edit with dialog.
949  */
950 AdapterDSource *addressbook_edit_ldap(
951         AddressIndex *addrIndex, AdapterDSource *ads )
952 {
953         static gboolean cancelled;
954         gchar *sName, *sHost, *sBase, *sBind, *sPass, *sCrit;
955         gint iPort, iMaxE, iTime, iAge;
956         gboolean bSrch, bMatch;
957         AddressDataSource *ds = NULL;
958         LdapServer *server = NULL;
959         LdapControl *ctl = NULL;
960         gboolean fin, ssl = FALSE, tls = FALSE;
961
962         if (!ldapedit.window)
963                 addressbook_edit_ldap_create(&cancelled);
964         gtk_notebook_set_current_page( GTK_NOTEBOOK(ldapedit.notebook), PAGE_BASIC );
965         gtk_widget_grab_focus(ldapedit.ok_btn);
966         gtk_widget_grab_focus(ldapedit.entry_name);
967         gtk_widget_show(ldapedit.window);
968         manage_window_set_transient(GTK_WINDOW(ldapedit.window));
969         gtk_window_set_modal(GTK_WINDOW(ldapedit.window), TRUE);
970
971         edit_ldap_status_show( "" );
972         if( ads ) {
973                 ds = ads->dataSource;
974                 server = ds->rawDataSource;
975                 edit_ldap_set_fields( server );
976                 gtk_window_set_title(
977                         GTK_WINDOW(ldapedit.window), _("Edit LDAP Server"));
978         }
979         else {
980                 edit_ldap_clear_fields();
981                 gtk_window_set_title(
982                         GTK_WINDOW(ldapedit.window), _("Add New LDAP Server"));
983         }
984
985         gtk_main();
986         gtk_widget_hide(ldapedit.window);
987         gtk_window_set_modal(GTK_WINDOW(ldapedit.window), FALSE);
988         if (cancelled == TRUE) return NULL;
989
990         sName = gtk_editable_get_chars(
991                         GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
992         sHost = gtk_editable_get_chars(
993                         GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
994         sBase = gtk_editable_get_chars(
995                         GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
996         sCrit = gtk_editable_get_chars(
997                         GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
998         sBind = gtk_editable_get_chars(
999                         GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
1000         sPass = gtk_editable_get_chars(
1001                         GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
1002         iPort = gtk_spin_button_get_value_as_int(
1003                         GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
1004         iTime = gtk_spin_button_get_value_as_int(
1005                         GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
1006         iMaxE = gtk_spin_button_get_value_as_int(
1007                         GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ) );
1008         iAge  = gtk_spin_button_get_value_as_int(
1009                         GTK_SPIN_BUTTON( ldapedit.spinbtn_queryage ) );
1010         bSrch = gtk_toggle_button_get_active(
1011                         GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ) );
1012         bMatch = gtk_toggle_button_get_active(
1013                         GTK_TOGGLE_BUTTON( ldapedit.check_matchoption ) );
1014 #ifdef USE_LDAP_TLS
1015         ssl = gtk_toggle_button_get_active(
1016                         GTK_TOGGLE_BUTTON( ldapedit.enable_ssl ) );
1017         tls = gtk_toggle_button_get_active(
1018                         GTK_TOGGLE_BUTTON( ldapedit.enable_tls ) );
1019 #endif
1020         debug_print("saving server config:\nname: %s\nhost: %s\nbase: %s\ncriteria: %s\nbind: %s\nport: %d\ntime: %d\nmax_entries: %d\ntimeout: %d\ndynamic: %d\ncheck_match: %d\n",
1021                         sName, sHost, sBase, sCrit, sBind, iPort, iTime, iMaxE, iAge, bSrch, bMatch);
1022         fin = FALSE;
1023         if( *sName == '\0' ) fin = TRUE;
1024         if( *sHost == '\0' ) fin = TRUE;
1025
1026         if( ! fin ) {
1027                 /* Save changes */
1028                 if( ! ads ) {
1029                         /* New server */
1030                         server = ldapsvr_create();
1031                         ds = addrindex_index_add_datasource(
1032                                 addrIndex, ADDR_IF_LDAP, server );
1033                         ads = addressbook_create_ds_adapter(
1034                                 ds, ADDR_LDAP, NULL );
1035                 }
1036                 ctl = server->control;
1037                 addressbook_ads_set_name( ads, sName );
1038                 ldapsvr_set_name( server, sName );
1039                 ldapsvr_set_search_flag( server, bSrch );
1040                 ldapctl_set_host( ctl, sHost );
1041                 ldapctl_set_base_dn( ctl, sBase );
1042                 ldapctl_set_bind_dn( ctl, sBind );
1043                 ldapctl_set_bind_password( ctl, sPass, TRUE, TRUE );
1044                 ldapctl_set_port( ctl, iPort );
1045                 ldapctl_set_max_entries( ctl, iMaxE );
1046                 ldapctl_set_timeout( ctl, iTime );
1047                 ldapctl_set_max_query_age( ctl, iAge );
1048                 ldapctl_set_tls( ctl, tls );
1049                 ldapctl_set_ssl( ctl, ssl );
1050                 ldapctl_set_matching_option(
1051                         ctl, bMatch ?
1052                         LDAPCTL_MATCH_CONTAINS : LDAPCTL_MATCH_BEGINWITH );
1053
1054                 addrindex_save_data(addrIndex);
1055
1056                 /* Save attributes */
1057                 editldap_parse_criteria( sCrit, ctl );
1058
1059         }
1060         g_free( sName );
1061         g_free( sHost );
1062         g_free( sBase );
1063         g_free( sBind );
1064         g_free( sPass );
1065         g_free( sCrit );
1066
1067         return ads;
1068 }
1069
1070 #endif /* USE_LDAP */
1071
1072 /*
1073 * End of Source.
1074 */