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