2010-03-26 [pawel] 3.7.5cvs40
[claws.git] / src / editldap.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2001-2009 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_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         GtkObject *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         CLAWS_TIP_DECL();
408         gint top;
409
410         vbox = gtk_vbox_new( FALSE, 8 );
411         gtk_widget_show( vbox );
412         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
413
414         label = gtk_label_new( pageLbl );
415         gtk_widget_show( label );
416         gtk_notebook_set_tab_label(
417                 GTK_NOTEBOOK( ldapedit.notebook ),
418                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
419
420         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
421         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
422         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
423         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
424         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
425
426         /* First row */
427         top = 0;
428         label = gtk_label_new(_("Name"));
429         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
430         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
431
432         entry_name = gtk_entry_new();
433         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1),
434                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
435
436         CLAWS_SET_TIP(entry_name, _( 
437                 "A name that you wish to call the server." ));
438
439         /* Next row */
440         ++top;
441         label = gtk_label_new(_("Hostname"));
442         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
443         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
444
445         entry_server = gtk_entry_new();
446         gtk_table_attach(GTK_TABLE(table), entry_server, 1, 2, top, (top + 1),
447                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
448
449         CLAWS_SET_TIP(entry_server, _( 
450                 "This is the hostname of the server. For example, " \
451                 "\"ldap.mydomain.com\" may be appropriate for the " \
452                 "\"mydomain.com\" organization. An IP address may also be " \
453                 "used. You may specify \"localhost\" if running an LDAP " \
454                 "server on the same computer as Claws Mail." ));
455
456         /* Next row */
457         ++top;
458         label = gtk_label_new(_("Port"));
459         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
460         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
461
462         hbox_spin = gtk_hbox_new (FALSE, 8);
463         spinbtn_port_adj = gtk_adjustment_new (389, 1, 65535, 1, 1000, 0);
464         spinbtn_port = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_port_adj), 1, 0);
465         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_port, TRUE, FALSE, 0);
466         gtk_widget_set_size_request (spinbtn_port, 64, -1);
467         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_port), TRUE);
468         
469 #ifdef USE_LDAP_TLS
470         enable_tls_checkbtn = gtk_check_button_new_with_label(_("TLS"));
471         enable_ssl_checkbtn = gtk_check_button_new_with_label(_("SSL"));
472         SET_TOGGLE_SENSITIVITY_REVERSE(enable_tls_checkbtn, enable_ssl_checkbtn);
473         SET_TOGGLE_SENSITIVITY_REVERSE(enable_ssl_checkbtn, enable_tls_checkbtn);
474         CLAWS_SET_TIP(enable_tls_checkbtn, _( 
475                 "Enable secure connection to the LDAP server via TLS."
476                 "If connection fails, be sure to check the correct "
477                 "configuration in ldap.conf (TLS_CACERTDIR and TLS_REQCERT fields)." ));
478         CLAWS_SET_TIP(enable_ssl_checkbtn, _( 
479                 "Enable secure connection to the LDAP server via SSL."
480                 "If connection fails, be sure to check the correct "
481                 "configuration in ldap.conf (TLS_CACERTDIR and TLS_REQCERT fields)." ));
482
483         gtk_box_pack_start (GTK_BOX (hbox_spin), enable_tls_checkbtn, TRUE, FALSE, 0);
484         gtk_box_pack_start (GTK_BOX (hbox_spin), enable_ssl_checkbtn, TRUE, FALSE, 0);
485 #endif
486
487         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
488                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
489
490         CLAWS_SET_TIP(spinbtn_port, _( 
491                 "The port number that the server listens on. Port 389 is " \
492                 "the default." ));
493
494         check_btn = gtk_button_new_with_label( _(" Check Server "));
495         gtk_table_attach(GTK_TABLE(table), check_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
496
497         CLAWS_SET_TIP(check_btn, _( 
498                 "Press this button to test the connection to the server." ));
499
500         /* Next row */
501         ++top;
502         label = gtk_label_new(_("Search Base"));
503         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
504         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
505
506         entry_baseDN = gtk_entry_new();
507         gtk_table_attach(GTK_TABLE(table), entry_baseDN, 1, 2, top, (top + 1),
508                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
509
510         CLAWS_SET_TIP(entry_baseDN, _( 
511                 "This specifies the name of the directory to be searched " \
512                 "on the server. Examples include:\n" \
513                 "  dc=claws-mail,dc=org\n" \
514                 "  ou=people,dc=domainname,dc=com\n" \
515                 "  o=Organization Name,c=Country\n"
516                 ));
517
518         lookdn_btn = gtkut_get_browse_file_btn(_("_Browse"));
519         gtk_table_attach(GTK_TABLE(table), lookdn_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
520
521         CLAWS_SET_TIP(lookdn_btn, _( 
522                 "Press this button to lookup the name of available " \
523                 "directory names on the server." ));
524
525         /* Signal handlers */
526         g_signal_connect(G_OBJECT(check_btn), "clicked",
527                          G_CALLBACK(edit_ldap_server_check), NULL);
528         g_signal_connect(G_OBJECT(lookdn_btn), "clicked",
529                          G_CALLBACK(edit_ldap_basedn_select), NULL);
530
531         /* Done */
532         gtk_widget_show_all(vbox);
533
534         ldapedit.entry_name   = entry_name;
535         ldapedit.entry_server = entry_server;
536         ldapedit.spinbtn_port = spinbtn_port;
537         ldapedit.entry_baseDN = entry_baseDN;
538 #ifdef USE_LDAP_TLS
539         ldapedit.enable_ssl = enable_ssl_checkbtn;
540         ldapedit.enable_tls = enable_tls_checkbtn;
541
542         g_signal_connect(G_OBJECT(enable_ssl_checkbtn), "toggled", \
543                          G_CALLBACK(editldap_update_port), NULL); 
544 #endif                   
545 }
546
547 static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
548         GtkWidget *vbox;
549         GtkWidget *table;
550         GtkWidget *label;
551         GtkWidget *entry_criteria;
552         GtkWidget *hbox_spin;
553         GtkObject *spinbtn_queryage_adj;
554         GtkWidget *spinbtn_queryage;
555         GtkWidget *check_dynsearch;
556         GtkWidget *check_matchoption;
557         GtkWidget *reset_btn;
558         CLAWS_TIP_DECL();
559         gint top;
560
561         vbox = gtk_vbox_new( FALSE, 8 );
562         gtk_widget_show( vbox );
563         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
564
565         label = gtk_label_new( pageLbl );
566         gtk_widget_show( label );
567         gtk_notebook_set_tab_label(
568                 GTK_NOTEBOOK( ldapedit.notebook ),
569                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
570
571         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
572         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
573         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
574         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
575         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
576
577         /* First row */
578         top = 0;
579         label = gtk_label_new(_("Search Attributes"));
580         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
581         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
582
583         entry_criteria = gtk_entry_new();
584         gtk_table_attach(GTK_TABLE(table), entry_criteria, 1, 2, top, (top + 1),
585                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
586
587         CLAWS_SET_TIP(entry_criteria, _( 
588                 "A list of LDAP attribute names that should be searched " \
589                 "when attempting to find a name or address." ));
590
591         reset_btn = gtk_button_new_with_label( _(" Defaults "));
592         gtk_table_attach(GTK_TABLE(table), reset_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
593
594         CLAWS_SET_TIP(reset_btn, _( 
595                 "This resets the attribute names to a default value " \
596                 "that should find most names and addresses during a " \
597                 "name or address search process." ));
598
599         /* Next row */
600         ++top;
601         label = gtk_label_new(_("Max Query Age (secs)"));
602         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
603         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
604
605         hbox_spin = gtk_hbox_new (FALSE, 8);
606         spinbtn_queryage_adj = gtk_adjustment_new(
607                 LDAPCTL_DFL_QUERY_AGE, 1, LDAPCTL_MAX_QUERY_AGE, 10, 1000, 0 );
608         spinbtn_queryage = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_queryage_adj), 1, 0);
609         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_queryage, FALSE, FALSE, 0);
610         gtk_widget_set_size_request (spinbtn_queryage, 64, -1);
611         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_queryage), TRUE);
612         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
613                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
614
615         CLAWS_SET_TIP(spinbtn_queryage, _( 
616                 "This defines the maximum period of time (in seconds) that " \
617                 "an address search result is valid for address completion " \
618                 "purposes. Search results are stored in a cache until this " \
619                 "period of time has passed and then retired. This will " \
620                 "improve the response time when attempting to search for " \
621                 "the same name or address on subsequent address completion " \
622                 "requests. The cache will be searched in preference to " \
623                 "performing a new server search request. The default value " \
624                 "of 600 seconds (10 minutes), should be sufficient for most " \
625                 "servers. A larger value will reduce the search time for " \
626                 "subsequent searches. This is useful for servers that have " \
627                 "slow response times at the expense of more memory to cache " \
628                 "results." ));
629
630         /* Next row */
631         ++top;
632         check_dynsearch = gtk_check_button_new_with_label(
633                                 _("Include server in dynamic search") );
634         gtk_table_attach(GTK_TABLE(table), check_dynsearch, 1, 3, top, (top + 1),
635                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
636
637         CLAWS_SET_TIP(check_dynsearch, _( 
638                 "Check this option to include this server for dynamic " \
639                 "searches when using address completion." ));
640
641         /* Next row */
642         ++top;
643         check_matchoption = gtk_check_button_new_with_label(
644                                 _("Match names 'containing' search term") );
645         gtk_table_attach(GTK_TABLE(table), check_matchoption, 1, 3, top, (top + 1),
646                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
647
648         CLAWS_SET_TIP(check_matchoption, _( 
649                 "Searches for names and addresses can be performed either " \
650                 "using \"begins-with\" or \"contains\" search term. Check " \
651                 "this option to perform a \"contains\" search; this type of " \
652                 "search usually takes longer to complete. Note that for " \
653                 "performance reasons, address completion uses " \
654                 "\"begins-with\" for all searches against other address " \
655                 "interfaces." \
656                 ));
657
658         /* Signal handlers */
659         g_signal_connect(G_OBJECT(reset_btn), "clicked",
660                          G_CALLBACK(edit_ldap_search_reset), NULL);
661
662         /* Done */
663         gtk_widget_show_all(vbox);
664
665         ldapedit.entry_criteria    = entry_criteria;
666         ldapedit.spinbtn_queryage  = spinbtn_queryage;
667         ldapedit.check_dynsearch   = check_dynsearch;
668         ldapedit.check_matchoption = check_matchoption;
669 }
670
671 static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl ) {
672         GtkWidget *vbox;
673         GtkWidget *table;
674         GtkWidget *label;
675         GtkWidget *entry_bindDN;
676         GtkWidget *entry_bindPW;
677         GtkWidget *hbox_spin;
678         GtkObject *spinbtn_timeout_adj;
679         GtkWidget *spinbtn_timeout;
680         GtkObject *spinbtn_maxentry_adj;
681         GtkWidget *spinbtn_maxentry;
682         CLAWS_TIP_DECL();
683         gint top;
684
685         vbox = gtk_vbox_new( FALSE, 8 );
686         gtk_widget_show( vbox );
687         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
688
689         label = gtk_label_new( pageLbl );
690         gtk_widget_show( label );
691         gtk_notebook_set_tab_label(
692                 GTK_NOTEBOOK( ldapedit.notebook ),
693                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
694
695         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
696         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
697         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
698         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
699         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
700
701         /* Next row */
702         top = 0;
703         label = gtk_label_new(_("Bind DN"));
704         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
705         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
706
707         entry_bindDN = gtk_entry_new();
708         gtk_table_attach(GTK_TABLE(table), entry_bindDN, 1, 2, top, (top + 1),
709                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
710
711         CLAWS_SET_TIP(entry_bindDN, _( 
712                 "The LDAP user account name to be used to connect to the server. " \
713                 "This is usually only used for protected servers. This name " \
714                 "is typically formatted as: \"cn=user,dc=claws-mail,dc=org\". " \
715                 "This is usually left empty when performing a search." ));
716
717         /* Next row */
718         ++top;
719         label = gtk_label_new(_("Bind Password"));
720         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
721         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
722
723         entry_bindPW = gtk_entry_new();
724         gtk_table_attach(GTK_TABLE(table), entry_bindPW, 1, 2, top, (top + 1),
725                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
726         gtk_entry_set_visibility(GTK_ENTRY(entry_bindPW), FALSE);
727 #ifdef MAEMO
728         hildon_gtk_entry_set_input_mode(GTK_ENTRY(entry_bindPW), 
729                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
730 #endif
731
732         CLAWS_SET_TIP(entry_bindPW, _( 
733                 "The password to be used when connecting as the \"Bind DN\" " \
734                 "user." ));
735
736         /* Next row */
737         ++top;
738         label = gtk_label_new(_("Timeout (secs)"));
739         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
740         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
741
742         hbox_spin = gtk_hbox_new (FALSE, 8);
743         spinbtn_timeout_adj = gtk_adjustment_new (0, 0, 300, 1, 10, 0);
744         spinbtn_timeout = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_timeout_adj), 1, 0);
745         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_timeout, FALSE, FALSE, 0);
746         gtk_widget_set_size_request (spinbtn_timeout, 64, -1);
747         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_timeout), TRUE);
748         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
749                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
750
751         CLAWS_SET_TIP(spinbtn_timeout, _( 
752                 "The timeout period in seconds." ));
753
754         /* Next row */
755         ++top;
756         label = gtk_label_new(_("Maximum Entries"));
757         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
758         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
759
760         hbox_spin = gtk_hbox_new (FALSE, 8);
761         spinbtn_maxentry_adj = gtk_adjustment_new (0, 0, 500, 1, 10, 0);
762         spinbtn_maxentry = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_maxentry_adj), 1, 0);
763         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_maxentry, FALSE, FALSE, 0);
764         gtk_widget_set_size_request (spinbtn_maxentry, 64, -1);
765         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_maxentry), TRUE);
766         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
767                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
768
769         CLAWS_SET_TIP(spinbtn_maxentry, _( 
770                 "The maximum number of entries that should be returned " \
771                 "in the search result." ));
772
773         /* Done */
774         gtk_widget_show_all(vbox);
775
776         ldapedit.entry_bindDN     = entry_bindDN;
777         ldapedit.entry_bindPW     = entry_bindPW;
778         ldapedit.spinbtn_timeout  = spinbtn_timeout;
779         ldapedit.spinbtn_maxentry = spinbtn_maxentry;
780 }
781
782 static void addressbook_edit_ldap_create( gboolean *cancelled ) {
783         gint page = 0;
784         addressbook_edit_ldap_dialog_create( cancelled );
785         addressbook_edit_ldap_page_basic( page++, _( "Basic" ) );
786         addressbook_edit_ldap_page_search( page++, _( "Search" ) );
787         addressbook_edit_ldap_page_extended( page++, _( "Extended" ) );
788         gtk_widget_show_all( ldapedit.window );
789 }
790
791 /**
792  * Format criteria list for display.
793  * \param ctl Control object.
794  * \return Formatted string, or <i>NULL</i> if no attributes found.
795  */
796 static gchar *editldap_build_criteria_list( const LdapControl *ctl ) {
797         gchar *str = NULL;
798         gchar *tmp = NULL;
799         GList *node;
800
801         node = ldapctl_get_criteria_list( ctl );
802         while( node ) {
803                 gchar *attr = node->data;
804                 if( str ) {
805                         tmp = g_strdup_printf( "%s, %s", str, attr );
806                         g_free( str );
807                         str = tmp;
808                         tmp = NULL;
809                 }
810                 else {
811                         str = g_strdup( attr );
812                 }
813                 node = g_list_next( node );
814         }
815
816         return str;
817 }
818
819 /**
820  * Parse out individual attribute names from criteria string.
821  * \param criteria Criteria string.
822  * \ctl   Control object.
823  */
824 static void editldap_parse_criteria( gchar *criteria, LdapControl *ctl ) {
825         gchar *ptr;
826         gchar **splitStr;
827         gint i;
828
829         /* Replace delimiters with spaces */
830         ptr = criteria;
831         while( *ptr ) {
832                 if( *ptr == ',' || *ptr == ';' || *ptr == '|' )
833                         *ptr = ' ';
834                 ptr++;
835         }
836
837         /* Parse string */
838         ldapctl_criteria_list_clear( ctl );
839         splitStr = g_strsplit( criteria, " ", 0 );
840         i = 0;
841         while( TRUE ) {
842                 if( splitStr[i] ) {
843                         if( *splitStr[i] ) {
844                                 ldapctl_criteria_list_add( ctl, splitStr[i] );
845                         }
846                 }
847                 else {
848                         break;
849                 }
850                 i++;
851         }
852         g_strfreev( splitStr );
853 }
854
855 /**
856  * Clear entry fields to reasonable defaults (for a new server entry).
857  */
858 static void edit_ldap_clear_fields(void) {
859         gtk_entry_set_text(
860                 GTK_ENTRY(ldapedit.entry_name), ADDRESSBOOK_GUESS_LDAP_NAME );
861         gtk_entry_set_text(
862                 GTK_ENTRY(ldapedit.entry_server), ADDRESSBOOK_GUESS_LDAP_SERVER );
863         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), "");
864         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindDN), "");
865         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindPW), "");
866         gtk_spin_button_set_value(
867                 GTK_SPIN_BUTTON( ldapedit.spinbtn_port ), LDAPCTL_DFL_PORT );
868         gtk_spin_button_set_value(
869                 GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ), LDAPCTL_DFL_TIMEOUT );
870         gtk_spin_button_set_value(
871                 GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ), LDAPCTL_DFL_TIMEOUT );
872         gtk_entry_set_text(
873                 GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST);
874         gtk_spin_button_set_value(
875                 GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), LDAPCTL_DFL_QUERY_AGE );
876         gtk_toggle_button_set_active(
877                 GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), TRUE );
878         gtk_toggle_button_set_active(
879                 GTK_TOGGLE_BUTTON( ldapedit.check_matchoption), FALSE );
880 #ifdef USE_LDAP_TLS
881         gtk_toggle_button_set_active(
882                 GTK_TOGGLE_BUTTON( ldapedit.enable_ssl), FALSE );
883         gtk_toggle_button_set_active(
884                 GTK_TOGGLE_BUTTON( ldapedit.enable_tls), FALSE );
885 #endif
886 }
887
888 /**
889  * Load entry fields from server control data.
890  * \param server Server object.
891  */
892 static void edit_ldap_set_fields( LdapServer *server ) {
893         LdapControl *ctl;
894         gchar *crit;
895         gchar *pwd;
896
897         if( ldapsvr_get_name( server ) )
898                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_name),
899                 ldapsvr_get_name( server ) );
900
901         ctl = server->control;
902         if( ctl->hostName )
903                 gtk_entry_set_text(
904                         GTK_ENTRY(ldapedit.entry_server), ctl->hostName);
905         if( ctl->baseDN )
906                 gtk_entry_set_text(
907                         GTK_ENTRY(ldapedit.entry_baseDN), ctl->baseDN );
908         if( ctl->bindDN )
909                 gtk_entry_set_text(
910                         GTK_ENTRY(ldapedit.entry_bindDN), ctl->bindDN );
911         if( ctl->bindPass ) {
912                 pwd = ldapctl_get_bind_password( ctl );
913                 gtk_entry_set_text(     GTK_ENTRY(ldapedit.entry_bindPW),  pwd );
914                 g_free(pwd);
915         }
916         gtk_spin_button_set_value(
917                 GTK_SPIN_BUTTON(ldapedit.spinbtn_timeout), ctl->timeOut );
918         gtk_spin_button_set_value(
919                 GTK_SPIN_BUTTON(ldapedit.spinbtn_maxentry), ctl->maxEntries );
920 #ifdef USE_LDAP_TLS
921         gtk_toggle_button_set_active(
922                 GTK_TOGGLE_BUTTON(ldapedit.enable_tls), ctl->enableTLS );
923         gtk_toggle_button_set_active(
924                 GTK_TOGGLE_BUTTON(ldapedit.enable_ssl), ctl->enableSSL );
925 #endif
926         gtk_spin_button_set_value(
927                 GTK_SPIN_BUTTON(ldapedit.spinbtn_port), ctl->port );
928         /* Format criteria */
929         crit = editldap_build_criteria_list( ctl );
930         if( crit ) {
931                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), crit );
932                 g_free( crit );
933         }
934         else {
935                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), "" );
936         }
937         gtk_spin_button_set_value(
938                 GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), ctl->maxQueryAge );
939         gtk_toggle_button_set_active(
940                 GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), server->searchFlag );
941         gtk_toggle_button_set_active(
942                 GTK_TOGGLE_BUTTON( ldapedit.check_matchoption),
943                 ( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) );
944 }
945
946 /**
947  * Edit LDAP server datasource that appears addressbook.
948  * \param addrIndex Address index object.
949  * \param ads       Data source adapter.
950  * \return Update data source adapter, or <code>NULL</code> if user cancelled
951  *         edit with dialog.
952  */
953 AdapterDSource *addressbook_edit_ldap(
954         AddressIndex *addrIndex, AdapterDSource *ads )
955 {
956         static gboolean cancelled;
957         gchar *sName, *sHost, *sBase, *sBind, *sPass, *sCrit;
958         gint iPort, iMaxE, iTime, iAge;
959         gboolean bSrch, bMatch;
960         AddressDataSource *ds = NULL;
961         LdapServer *server = NULL;
962         LdapControl *ctl = NULL;
963         gboolean fin, ssl = FALSE, tls = FALSE;
964
965         if (!ldapedit.window)
966                 addressbook_edit_ldap_create(&cancelled);
967         gtk_notebook_set_current_page( GTK_NOTEBOOK(ldapedit.notebook), PAGE_BASIC );
968         gtk_widget_grab_focus(ldapedit.ok_btn);
969         gtk_widget_grab_focus(ldapedit.entry_name);
970         gtk_widget_show(ldapedit.window);
971         manage_window_set_transient(GTK_WINDOW(ldapedit.window));
972         gtk_window_set_modal(GTK_WINDOW(ldapedit.window), TRUE);
973
974         edit_ldap_status_show( "" );
975         if( ads ) {
976                 ds = ads->dataSource;
977                 server = ds->rawDataSource;
978                 edit_ldap_set_fields( server );
979                 gtk_window_set_title(
980                         GTK_WINDOW(ldapedit.window), _("Edit LDAP Server"));
981         }
982         else {
983                 edit_ldap_clear_fields();
984                 gtk_window_set_title(
985                         GTK_WINDOW(ldapedit.window), _("Add New LDAP Server"));
986         }
987
988         gtk_main();
989         gtk_widget_hide(ldapedit.window);
990         gtk_window_set_modal(GTK_WINDOW(ldapedit.window), FALSE);
991         if (cancelled == TRUE) return NULL;
992
993         sName = gtk_editable_get_chars(
994                         GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
995         sHost = gtk_editable_get_chars(
996                         GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
997         sBase = gtk_editable_get_chars(
998                         GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
999         sCrit = gtk_editable_get_chars(
1000                         GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
1001         sBind = gtk_editable_get_chars(
1002                         GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
1003         sPass = gtk_editable_get_chars(
1004                         GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
1005         iPort = gtk_spin_button_get_value_as_int(
1006                         GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
1007         iTime = gtk_spin_button_get_value_as_int(
1008                         GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
1009         iMaxE = gtk_spin_button_get_value_as_int(
1010                         GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ) );
1011         iAge  = gtk_spin_button_get_value_as_int(
1012                         GTK_SPIN_BUTTON( ldapedit.spinbtn_queryage ) );
1013         bSrch = gtk_toggle_button_get_active(
1014                         GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ) );
1015         bMatch = gtk_toggle_button_get_active(
1016                         GTK_TOGGLE_BUTTON( ldapedit.check_matchoption ) );
1017 #ifdef USE_LDAP_TLS
1018         ssl = gtk_toggle_button_get_active(
1019                         GTK_TOGGLE_BUTTON( ldapedit.enable_ssl ) );
1020         tls = gtk_toggle_button_get_active(
1021                         GTK_TOGGLE_BUTTON( ldapedit.enable_tls ) );
1022 #endif
1023         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",
1024                         sName, sHost, sBase, sCrit, sBind, iPort, iTime, iMaxE, iAge, bSrch, bMatch);
1025         fin = FALSE;
1026         if( *sName == '\0' ) fin = TRUE;
1027         if( *sHost == '\0' ) fin = TRUE;
1028
1029         if( ! fin ) {
1030                 /* Save changes */
1031                 if( ! ads ) {
1032                         /* New server */
1033                         server = ldapsvr_create();
1034                         ds = addrindex_index_add_datasource(
1035                                 addrIndex, ADDR_IF_LDAP, server );
1036                         ads = addressbook_create_ds_adapter(
1037                                 ds, ADDR_LDAP, NULL );
1038                 }
1039                 ctl = server->control;
1040                 addressbook_ads_set_name( ads, sName );
1041                 ldapsvr_set_name( server, sName );
1042                 ldapsvr_set_search_flag( server, bSrch );
1043                 ldapctl_set_host( ctl, sHost );
1044                 ldapctl_set_base_dn( ctl, sBase );
1045                 ldapctl_set_bind_dn( ctl, sBind );
1046                 ldapctl_set_bind_password( ctl, sPass, TRUE, TRUE );
1047                 ldapctl_set_port( ctl, iPort );
1048                 ldapctl_set_max_entries( ctl, iMaxE );
1049                 ldapctl_set_timeout( ctl, iTime );
1050                 ldapctl_set_max_query_age( ctl, iAge );
1051 #ifdef USE_LDAP_TLS
1052                 ldapctl_set_tls( ctl, tls );
1053                 ldapctl_set_ssl( ctl, ssl );
1054 #endif
1055                 ldapctl_set_matching_option(
1056                         ctl, bMatch ?
1057                         LDAPCTL_MATCH_CONTAINS : LDAPCTL_MATCH_BEGINWITH );
1058
1059                 addrindex_save_data(addrIndex);
1060
1061                 /* Save attributes */
1062                 editldap_parse_criteria( sCrit, ctl );
1063
1064         }
1065         g_free( sName );
1066         g_free( sHost );
1067         g_free( sBase );
1068         g_free( sBind );
1069         g_free( sPass );
1070         g_free( sCrit );
1071
1072         return ads;
1073 }
1074
1075 #endif /* USE_LDAP */
1076
1077 /*
1078 * End of Source.
1079 */