Statistics
| Revision:

root / src / syldap.c @ 123

History | View | Annotate | Download (31.9 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 1 hiro
 * Copyright (C) 2001 Match Grun
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
/*
21 1 hiro
 * Functions necessary to access LDAP servers.
22 1 hiro
 */
23 1 hiro
24 1 hiro
#ifdef HAVE_CONFIG_H
25 1 hiro
#  include "config.h"
26 1 hiro
#endif
27 1 hiro
28 1 hiro
#ifdef USE_LDAP
29 1 hiro
30 1 hiro
#include <glib.h>
31 1 hiro
#include <gdk/gdk.h>
32 1 hiro
#include <gtk/gtkmain.h>
33 1 hiro
#include <sys/time.h>
34 1 hiro
#include <string.h>
35 1 hiro
#include <ldap.h>
36 1 hiro
#include <lber.h>
37 1 hiro
#include <pthread.h>
38 1 hiro
/* #include <dlfcn.h> */
39 1 hiro
40 1 hiro
#include "mgutils.h"
41 1 hiro
#include "addritem.h"
42 1 hiro
#include "addrcache.h"
43 1 hiro
#include "syldap.h"
44 1 hiro
#include "utils.h"
45 1 hiro
46 1 hiro
/*
47 1 hiro
* Create new LDAP server interface object.
48 1 hiro
*/
49 1 hiro
SyldapServer *syldap_create() {
50 1 hiro
        SyldapServer *ldapServer;
51 1 hiro
52 1 hiro
        debug_print("Creating LDAP server interface object\n");
53 1 hiro
54 1 hiro
        ldapServer = g_new0( SyldapServer, 1 );
55 1 hiro
        ldapServer->name = NULL;
56 1 hiro
        ldapServer->hostName = NULL;
57 1 hiro
        ldapServer->port = SYLDAP_DFL_PORT;
58 1 hiro
        ldapServer->baseDN = NULL;
59 1 hiro
        ldapServer->bindDN = NULL;
60 1 hiro
        ldapServer->bindPass = NULL;
61 1 hiro
        ldapServer->searchCriteria = NULL;
62 1 hiro
        ldapServer->searchValue = NULL;
63 1 hiro
        ldapServer->entriesRead = 0;
64 1 hiro
        ldapServer->maxEntries = SYLDAP_MAX_ENTRIES;
65 1 hiro
        ldapServer->timeOut = SYLDAP_DFL_TIMEOUT;
66 1 hiro
        ldapServer->newSearch = TRUE;
67 1 hiro
        ldapServer->addressCache = addrcache_create();
68 1 hiro
        ldapServer->thread = NULL;
69 1 hiro
        ldapServer->busyFlag = FALSE;
70 1 hiro
        ldapServer->retVal = MGU_SUCCESS;
71 1 hiro
        ldapServer->callBack = NULL;
72 1 hiro
        ldapServer->accessFlag = FALSE;
73 1 hiro
        ldapServer->idleId = 0;
74 1 hiro
        return ldapServer;
75 1 hiro
}
76 1 hiro
77 1 hiro
/*
78 1 hiro
* Specify name to be used.
79 1 hiro
*/
80 1 hiro
void syldap_set_name( SyldapServer* ldapServer, const gchar *value ) {
81 1 hiro
        ldapServer->name = mgu_replace_string( ldapServer->name, value );
82 1 hiro
        g_strstrip( ldapServer->name );
83 1 hiro
}
84 1 hiro
85 1 hiro
/*
86 1 hiro
* Specify hostname to be used.
87 1 hiro
*/
88 1 hiro
void syldap_set_host( SyldapServer* ldapServer, const gchar *value ) {
89 1 hiro
        addrcache_refresh( ldapServer->addressCache );
90 1 hiro
        ldapServer->hostName = mgu_replace_string( ldapServer->hostName, value );
91 1 hiro
        g_strstrip( ldapServer->hostName );
92 1 hiro
}
93 1 hiro
94 1 hiro
/*
95 1 hiro
* Specify port to be used.
96 1 hiro
*/
97 1 hiro
void syldap_set_port( SyldapServer* ldapServer, const gint value ) {
98 1 hiro
        addrcache_refresh( ldapServer->addressCache );
99 1 hiro
        if( value > 0 ) {
100 1 hiro
                ldapServer->port = value;
101 1 hiro
        }
102 1 hiro
        else {
103 1 hiro
                ldapServer->port = SYLDAP_DFL_PORT;
104 1 hiro
        }
105 1 hiro
}
106 1 hiro
107 1 hiro
/*
108 1 hiro
* Specify base DN to be used.
109 1 hiro
*/
110 1 hiro
void syldap_set_base_dn( SyldapServer* ldapServer, const gchar *value ) {
111 1 hiro
        addrcache_refresh( ldapServer->addressCache );
112 1 hiro
        ldapServer->baseDN = mgu_replace_string( ldapServer->baseDN, value );
113 1 hiro
        g_strstrip( ldapServer->baseDN );
114 1 hiro
}
115 1 hiro
116 1 hiro
/*
117 1 hiro
* Specify bind DN to be used.
118 1 hiro
*/
119 1 hiro
void syldap_set_bind_dn( SyldapServer* ldapServer, const gchar *value ) {
120 1 hiro
        addrcache_refresh( ldapServer->addressCache );
121 1 hiro
        ldapServer->bindDN = mgu_replace_string( ldapServer->bindDN, value );
122 1 hiro
        g_strstrip( ldapServer->bindDN );
123 1 hiro
}
124 1 hiro
125 1 hiro
/*
126 1 hiro
* Specify bind password to be used.
127 1 hiro
*/
128 1 hiro
void syldap_set_bind_password( SyldapServer* ldapServer, const gchar *value ) {
129 1 hiro
        addrcache_refresh( ldapServer->addressCache );
130 1 hiro
        ldapServer->bindPass = mgu_replace_string( ldapServer->bindPass, value );
131 1 hiro
        g_strstrip( ldapServer->bindPass );
132 1 hiro
}
133 1 hiro
134 1 hiro
/*
135 1 hiro
* Specify search criteria to be used.
136 1 hiro
*/
137 1 hiro
void syldap_set_search_criteria( SyldapServer* ldapServer, const gchar *value ) {
138 1 hiro
        addrcache_refresh( ldapServer->addressCache );
139 1 hiro
        ldapServer->searchCriteria = mgu_replace_string( ldapServer->searchCriteria, value );
140 1 hiro
        g_strstrip( ldapServer->searchCriteria );
141 1 hiro
        ldapServer->newSearch = TRUE;
142 1 hiro
}
143 1 hiro
144 1 hiro
/*
145 1 hiro
* Specify search value to be searched for.
146 1 hiro
*/
147 1 hiro
void syldap_set_search_value( SyldapServer* ldapServer, const gchar *value ) {
148 1 hiro
        addrcache_refresh( ldapServer->addressCache );
149 1 hiro
        ldapServer->searchValue = mgu_replace_string( ldapServer->searchValue, value );
150 1 hiro
        g_strstrip( ldapServer->searchValue );
151 1 hiro
        ldapServer->newSearch = TRUE;
152 1 hiro
}
153 1 hiro
154 1 hiro
/*
155 1 hiro
* Specify maximum number of entries to retrieve.
156 1 hiro
*/
157 1 hiro
void syldap_set_max_entries( SyldapServer* ldapServer, const gint value ) {
158 1 hiro
        addrcache_refresh( ldapServer->addressCache );
159 1 hiro
        if( value > 0 ) {
160 1 hiro
                ldapServer->maxEntries = value;
161 1 hiro
        }
162 1 hiro
        else {
163 1 hiro
                ldapServer->maxEntries = SYLDAP_MAX_ENTRIES;
164 1 hiro
        }
165 1 hiro
}
166 1 hiro
167 1 hiro
/*
168 1 hiro
* Specify timeout value for LDAP operation (in seconds).
169 1 hiro
*/
170 1 hiro
void syldap_set_timeout( SyldapServer* ldapServer, const gint value ) {
171 1 hiro
        addrcache_refresh( ldapServer->addressCache );
172 1 hiro
        if( value > 0 ) {
173 1 hiro
                ldapServer->timeOut = value;
174 1 hiro
        }
175 1 hiro
        else {
176 1 hiro
                ldapServer->timeOut = SYLDAP_DFL_TIMEOUT;
177 1 hiro
        }
178 1 hiro
}
179 1 hiro
180 1 hiro
/*
181 1 hiro
* Register a callback function. When called, the function will be passed
182 1 hiro
* this object as an argument.
183 1 hiro
*/
184 1 hiro
void syldap_set_callback( SyldapServer *ldapServer, void *func ) {
185 1 hiro
        ldapServer->callBack = func;
186 1 hiro
}
187 1 hiro
188 1 hiro
void syldap_set_accessed( SyldapServer *ldapServer, const gboolean value ) {
189 1 hiro
        g_return_if_fail( ldapServer != NULL );
190 1 hiro
        ldapServer->accessFlag = value;
191 1 hiro
}
192 1 hiro
193 1 hiro
/*
194 1 hiro
* Refresh internal variables to force a file read.
195 1 hiro
*/
196 1 hiro
void syldap_force_refresh( SyldapServer *ldapServer ) {
197 1 hiro
        addrcache_refresh( ldapServer->addressCache );
198 1 hiro
        ldapServer->newSearch = TRUE;
199 1 hiro
}
200 1 hiro
201 1 hiro
gint syldap_get_status( SyldapServer *ldapServer ) {
202 1 hiro
        g_return_val_if_fail( ldapServer != NULL, -1 );
203 1 hiro
        return ldapServer->retVal;
204 1 hiro
}
205 1 hiro
206 1 hiro
ItemFolder *syldap_get_root_folder( SyldapServer *ldapServer ) {
207 1 hiro
        g_return_val_if_fail( ldapServer != NULL, NULL );
208 1 hiro
        return addrcache_get_root_folder( ldapServer->addressCache );
209 1 hiro
}
210 1 hiro
211 1 hiro
gchar *syldap_get_name( SyldapServer *ldapServer ) {
212 1 hiro
        g_return_val_if_fail( ldapServer != NULL, NULL );
213 1 hiro
        return ldapServer->name;
214 1 hiro
}
215 1 hiro
216 1 hiro
gboolean syldap_get_accessed( SyldapServer *ldapServer ) {
217 1 hiro
        g_return_val_if_fail( ldapServer != NULL, FALSE );
218 1 hiro
        return ldapServer->accessFlag;
219 1 hiro
}
220 1 hiro
221 1 hiro
/*
222 1 hiro
* Free up LDAP server interface object by releasing internal memory.
223 1 hiro
*/
224 1 hiro
void syldap_free( SyldapServer *ldapServer ) {
225 1 hiro
        g_return_if_fail( ldapServer != NULL );
226 1 hiro
227 1 hiro
        debug_print("Freeing LDAP server interface object\n");
228 1 hiro
229 1 hiro
        ldapServer->callBack = NULL;
230 1 hiro
231 1 hiro
        /* Free internal stuff */
232 1 hiro
        g_free( ldapServer->name );
233 1 hiro
        g_free( ldapServer->hostName );
234 1 hiro
        g_free( ldapServer->baseDN );
235 1 hiro
        g_free( ldapServer->bindDN );
236 1 hiro
        g_free( ldapServer->bindPass );
237 1 hiro
        g_free( ldapServer->searchCriteria );
238 1 hiro
        g_free( ldapServer->searchValue );
239 1 hiro
        g_free( ldapServer->thread );
240 1 hiro
241 1 hiro
        ldapServer->port = 0;
242 1 hiro
        ldapServer->entriesRead = 0;
243 1 hiro
        ldapServer->maxEntries = 0;
244 1 hiro
        ldapServer->newSearch = FALSE;
245 1 hiro
246 1 hiro
        /* Clear cache */
247 1 hiro
        addrcache_clear( ldapServer->addressCache );
248 1 hiro
        addrcache_free( ldapServer->addressCache );
249 1 hiro
250 1 hiro
        /* Clear pointers */
251 1 hiro
        ldapServer->name = NULL;
252 1 hiro
        ldapServer->hostName = NULL;
253 1 hiro
        ldapServer->baseDN = NULL;
254 1 hiro
        ldapServer->bindDN = NULL;
255 1 hiro
        ldapServer->bindPass = NULL;
256 1 hiro
        ldapServer->searchCriteria = NULL;
257 1 hiro
        ldapServer->searchValue = NULL;
258 1 hiro
        ldapServer->addressCache = NULL;
259 1 hiro
        ldapServer->thread = NULL;
260 1 hiro
        ldapServer->busyFlag = FALSE;
261 1 hiro
        ldapServer->retVal = MGU_SUCCESS;
262 1 hiro
        ldapServer->accessFlag = FALSE;
263 1 hiro
264 1 hiro
        /* Now release LDAP object */
265 1 hiro
        g_free( ldapServer );
266 1 hiro
267 1 hiro
}
268 1 hiro
269 1 hiro
/*
270 1 hiro
* Display object to specified stream.
271 1 hiro
*/
272 1 hiro
void syldap_print_data( SyldapServer *ldapServer, FILE *stream ) {
273 1 hiro
        g_return_if_fail( ldapServer != NULL );
274 1 hiro
275 1 hiro
        fprintf( stream, "SyldapServer:\n" );
276 1 hiro
        fprintf( stream, "     name: '%s'\n", ldapServer->name );
277 1 hiro
        fprintf( stream, "host name: '%s'\n", ldapServer->hostName );
278 1 hiro
        fprintf( stream, "     port: %d\n",   ldapServer->port );
279 1 hiro
        fprintf( stream, "  base dn: '%s'\n", ldapServer->baseDN );
280 1 hiro
        fprintf( stream, "  bind dn: '%s'\n", ldapServer->bindDN );
281 1 hiro
        fprintf( stream, "bind pass: '%s'\n", ldapServer->bindPass );
282 1 hiro
        fprintf( stream, " criteria: '%s'\n", ldapServer->searchCriteria );
283 1 hiro
        fprintf( stream, "searchval: '%s'\n", ldapServer->searchValue );
284 1 hiro
        fprintf( stream, "max entry: %d\n",   ldapServer->maxEntries );
285 1 hiro
        fprintf( stream, " num read: %d\n",   ldapServer->entriesRead );
286 1 hiro
        fprintf( stream, "  ret val: %d\n",   ldapServer->retVal );
287 1 hiro
        addrcache_print( ldapServer->addressCache, stream );
288 1 hiro
        addritem_print_item_folder( ldapServer->addressCache->rootFolder, stream );
289 1 hiro
}
290 1 hiro
291 1 hiro
/*
292 1 hiro
* Display object to specified stream.
293 1 hiro
*/
294 1 hiro
void syldap_print_short( SyldapServer *ldapServer, FILE *stream ) {
295 1 hiro
        g_return_if_fail( ldapServer != NULL );
296 1 hiro
297 1 hiro
        fprintf( stream, "SyldapServer:\n" );
298 1 hiro
        fprintf( stream, "     name: '%s'\n", ldapServer->name );
299 1 hiro
        fprintf( stream, "host name: '%s'\n", ldapServer->hostName );
300 1 hiro
        fprintf( stream, "     port: %d\n",   ldapServer->port );
301 1 hiro
        fprintf( stream, "  base dn: '%s'\n", ldapServer->baseDN );
302 1 hiro
        fprintf( stream, "  bind dn: '%s'\n", ldapServer->bindDN );
303 1 hiro
        fprintf( stream, "bind pass: '%s'\n", ldapServer->bindPass );
304 1 hiro
        fprintf( stream, " criteria: '%s'\n", ldapServer->searchCriteria );
305 1 hiro
        fprintf( stream, "searchval: '%s'\n", ldapServer->searchValue );
306 1 hiro
        fprintf( stream, "max entry: %d\n",   ldapServer->maxEntries );
307 1 hiro
        fprintf( stream, " num read: %d\n",   ldapServer->entriesRead );
308 1 hiro
        fprintf( stream, "  ret val: %d\n",   ldapServer->retVal );
309 1 hiro
}
310 1 hiro
311 1 hiro
#if 0
312 1 hiro
/*
313 1 hiro
* Build an address list entry and append to list of address items. Name is formatted
314 1 hiro
* as it appears in the common name (cn) attribute.
315 1 hiro
*/
316 1 hiro
static void syldap_build_items_cn( SyldapServer *ldapServer, GSList *listName, GSList *listAddr ) {
317 1 hiro
        ItemPerson *person;
318 1 hiro
        ItemEMail *email;
319 1 hiro
        GSList *nodeName = listName;
320 1 hiro
321 1 hiro
        while( nodeName ) {
322 1 hiro
                GSList *nodeAddress = listAddr;
323 1 hiro
                person = addritem_create_item_person();
324 1 hiro
                addritem_person_set_common_name( person, nodeName->data );
325 1 hiro
                addrcache_id_person( ldapServer->addressCache, person );
326 1 hiro
                addrcache_add_person( ldapServer->addressCache, person );
327 1 hiro
328 1 hiro
                while( nodeAddress ) {
329 1 hiro
                        email = addritem_create_item_email();
330 1 hiro
                        addritem_email_set_address( email, nodeAddress->data );
331 1 hiro
                        addrcache_id_email( ldapServer->addressCache, email );
332 1 hiro
                        addrcache_person_add_email( ldapServer->addressCache, person, email );
333 1 hiro
                        nodeAddress = g_slist_next( nodeAddress );
334 1 hiro
                        ldapServer->entriesRead++;
335 1 hiro
                }
336 1 hiro
                nodeName = g_slist_next( nodeName );
337 1 hiro
        }
338 1 hiro
}
339 1 hiro
#endif
340 1 hiro
341 1 hiro
/*
342 1 hiro
* Build an address list entry and append to list of address items. Name is formatted
343 1 hiro
* as "<first-name> <last-name>".
344 1 hiro
*/
345 1 hiro
static void syldap_build_items_fl( SyldapServer *ldapServer, GSList *listAddr, GSList *listFirst, GSList *listLast  ) {
346 1 hiro
        GSList *nodeFirst = listFirst;
347 1 hiro
        GSList *nodeAddress = listAddr;
348 1 hiro
        gchar *firstName = NULL, *lastName = NULL, *fullName = NULL;
349 1 hiro
        gint iLen = 0, iLenT = 0;
350 1 hiro
        ItemPerson *person;
351 1 hiro
        ItemEMail *email;
352 1 hiro
353 1 hiro
        /* Find longest first name in list */
354 1 hiro
        while( nodeFirst ) {
355 1 hiro
                if( firstName == NULL ) {
356 1 hiro
                        firstName = nodeFirst->data;
357 1 hiro
                        iLen = strlen( firstName );
358 1 hiro
                }
359 1 hiro
                else {
360 1 hiro
                        if( ( iLenT = strlen( nodeFirst->data ) ) > iLen ) {
361 1 hiro
                                firstName = nodeFirst->data;
362 1 hiro
                                iLen = iLenT;
363 1 hiro
                        }
364 1 hiro
                }
365 1 hiro
                nodeFirst = g_slist_next( nodeFirst );
366 1 hiro
        }
367 1 hiro
368 1 hiro
        /* Format name */
369 1 hiro
        if( listLast ) {
370 1 hiro
                lastName = listLast->data;
371 1 hiro
        }
372 1 hiro
373 1 hiro
        if( firstName ) {
374 1 hiro
                if( lastName ) {
375 1 hiro
                        fullName = g_strdup_printf( "%s %s", firstName, lastName );
376 1 hiro
                }
377 1 hiro
                else {
378 1 hiro
                        fullName = g_strdup_printf( "%s", firstName );
379 1 hiro
                }
380 1 hiro
        }
381 1 hiro
        else {
382 1 hiro
                if( lastName ) {
383 1 hiro
                        fullName = g_strdup_printf( "%s", lastName );
384 1 hiro
                }
385 1 hiro
        }
386 1 hiro
        if( fullName ) {
387 1 hiro
                g_strchug( fullName ); g_strchomp( fullName );
388 1 hiro
        }
389 1 hiro
390 1 hiro
        if( nodeAddress ) {
391 1 hiro
                person = addritem_create_item_person();
392 1 hiro
                addritem_person_set_common_name( person, fullName );
393 1 hiro
                addritem_person_set_first_name( person, firstName );
394 1 hiro
                addritem_person_set_last_name( person, lastName );
395 1 hiro
                addrcache_id_person( ldapServer->addressCache, person );
396 1 hiro
                addrcache_add_person( ldapServer->addressCache, person );
397 1 hiro
        }
398 1 hiro
399 1 hiro
        /* Add address item */
400 1 hiro
        while( nodeAddress ) {
401 1 hiro
                email = addritem_create_item_email();
402 1 hiro
                addritem_email_set_address( email, nodeAddress->data );
403 1 hiro
                addrcache_id_email( ldapServer->addressCache, email );
404 1 hiro
                addrcache_person_add_email( ldapServer->addressCache, person, email );
405 1 hiro
                nodeAddress = g_slist_next( nodeAddress );
406 1 hiro
                ldapServer->entriesRead++;
407 1 hiro
        }
408 1 hiro
        g_free( fullName );
409 1 hiro
        fullName = firstName = lastName = NULL;
410 1 hiro
411 1 hiro
}
412 1 hiro
413 1 hiro
/*
414 1 hiro
* Add all attribute values to a list.
415 1 hiro
*/
416 1 hiro
static GSList *syldap_add_list_values( LDAP *ld, LDAPMessage *entry, char *attr ) {
417 1 hiro
        GSList *list = NULL;
418 1 hiro
        gint i;
419 1 hiro
        gchar **vals;
420 1 hiro
421 1 hiro
        if( ( vals = ldap_get_values( ld, entry, attr ) ) != NULL ) {
422 1 hiro
                for( i = 0; vals[i] != NULL; i++ ) {
423 1 hiro
                        /* printf( "lv\t%s: %s\n", attr, vals[i] ); */
424 1 hiro
                        list = g_slist_append( list, g_strdup( vals[i] ) );
425 1 hiro
                }
426 1 hiro
        }
427 1 hiro
        ldap_value_free( vals );
428 1 hiro
        return list;
429 1 hiro
}
430 1 hiro
431 1 hiro
/*
432 1 hiro
* Add a single attribute value to a list.
433 1 hiro
*/
434 1 hiro
static GSList *syldap_add_single_value( LDAP *ld, LDAPMessage *entry, char *attr ) {
435 1 hiro
        GSList *list = NULL;
436 1 hiro
        gchar **vals;
437 1 hiro
438 1 hiro
        if( ( vals = ldap_get_values( ld, entry, attr ) ) != NULL ) {
439 1 hiro
                if( vals[0] != NULL ) {
440 1 hiro
                        /* printf( "sv\t%s: %s\n", attr, vals[0] ); */
441 1 hiro
                        list = g_slist_append( list, g_strdup( vals[0] ) );
442 1 hiro
                }
443 1 hiro
        }
444 1 hiro
        ldap_value_free( vals );
445 1 hiro
        return list;
446 1 hiro
}
447 1 hiro
448 1 hiro
/*
449 1 hiro
* Free linked lists of character strings.
450 1 hiro
*/
451 1 hiro
static void syldap_free_lists( GSList *listName, GSList *listAddr, GSList *listID, GSList *listDN, GSList *listFirst, GSList *listLast ) {
452 1 hiro
        mgu_free_list( listName );
453 1 hiro
        mgu_free_list( listAddr );
454 1 hiro
        mgu_free_list( listID );
455 1 hiro
        mgu_free_list( listDN );
456 1 hiro
        mgu_free_list( listFirst );
457 1 hiro
        mgu_free_list( listLast );
458 1 hiro
}
459 1 hiro
460 1 hiro
/*
461 1 hiro
* Check parameters that are required for a search. This should
462 1 hiro
* be called before performing a search.
463 1 hiro
* Return: TRUE if search criteria appear OK.
464 1 hiro
*/
465 1 hiro
gboolean syldap_check_search( SyldapServer *ldapServer ) {
466 1 hiro
        g_return_val_if_fail( ldapServer != NULL, FALSE );
467 1 hiro
468 1 hiro
        ldapServer->retVal = MGU_LDAP_CRITERIA;
469 1 hiro
470 1 hiro
        /* Test search criteria */
471 1 hiro
        if( ldapServer->searchCriteria == NULL ) {
472 1 hiro
                return FALSE;
473 1 hiro
        }
474 1 hiro
        if( strlen( ldapServer->searchCriteria ) < 1 ) {
475 1 hiro
                return FALSE;
476 1 hiro
        }
477 1 hiro
478 1 hiro
        if( ldapServer->searchValue == NULL ) {
479 1 hiro
                return FALSE;
480 1 hiro
        }
481 1 hiro
        if( strlen( ldapServer->searchValue ) < 1 ) {
482 1 hiro
                return FALSE;
483 1 hiro
        }
484 1 hiro
485 1 hiro
        ldapServer->retVal = MGU_SUCCESS;
486 1 hiro
        return TRUE;
487 1 hiro
}
488 1 hiro
489 1 hiro
/*
490 1 hiro
* Perform the LDAP search, reading LDAP entries into cache.
491 1 hiro
* Note that one LDAP entry can have multiple values for many of its
492 1 hiro
* attributes. If these attributes are E-Mail addresses; these are
493 1 hiro
* broken out into separate address items. For any other attribute,
494 1 hiro
* only the first occurrence is read.
495 1 hiro
*/
496 1 hiro
gint syldap_search( SyldapServer *ldapServer ) {
497 1 hiro
        LDAP *ld;
498 1 hiro
        LDAPMessage *result, *e;
499 1 hiro
        char *attribs[10];
500 1 hiro
        char *attribute;
501 1 hiro
        gchar *criteria;
502 1 hiro
        BerElement *ber;
503 1 hiro
        gint rc;
504 1 hiro
        GSList *listName = NULL, *listAddress = NULL, *listID = NULL;
505 1 hiro
        GSList *listFirst = NULL, *listLast = NULL, *listDN = NULL;
506 1 hiro
        struct timeval timeout;
507 1 hiro
        gboolean entriesFound = FALSE;
508 1 hiro
509 1 hiro
        g_return_val_if_fail( ldapServer != NULL, -1 );
510 1 hiro
511 1 hiro
        ldapServer->retVal = MGU_SUCCESS;
512 1 hiro
        if( ! syldap_check_search( ldapServer ) ) {
513 1 hiro
                return ldapServer->retVal;
514 1 hiro
        }
515 1 hiro
516 1 hiro
        /* Set timeout */
517 1 hiro
        timeout.tv_sec = ldapServer->timeOut;
518 1 hiro
        timeout.tv_usec = 0L;
519 1 hiro
520 1 hiro
        ldapServer->entriesRead = 0;
521 1 hiro
        if( ( ld = ldap_init( ldapServer->hostName, ldapServer->port ) ) == NULL ) {
522 1 hiro
                ldapServer->retVal = MGU_LDAP_INIT;
523 1 hiro
                return ldapServer->retVal;
524 1 hiro
        }
525 1 hiro
526 1 hiro
        /* printf( "connected to LDAP host %s on port %d\n", ldapServer->hostName, ldapServer->port ); */
527 1 hiro
528 1 hiro
        /* Bind to the server, if required */
529 1 hiro
        if( ldapServer->bindDN ) {
530 1 hiro
                if( * ldapServer->bindDN != '\0' ) {
531 1 hiro
                        /* printf( "binding...\n" ); */
532 1 hiro
                        rc = ldap_simple_bind_s( ld, ldapServer->bindDN, ldapServer->bindPass );
533 1 hiro
                        /* printf( "rc=%d\n", rc ); */
534 1 hiro
                        if( rc != LDAP_SUCCESS ) {
535 1 hiro
                                /* printf( "LDAP Error: ldap_simple_bind_s: %s\n", ldap_err2string( rc ) ); */
536 1 hiro
                                ldap_unbind( ld );
537 1 hiro
                                ldapServer->retVal = MGU_LDAP_BIND;
538 1 hiro
                                return ldapServer->retVal;
539 1 hiro
                        }
540 1 hiro
                }
541 1 hiro
        }
542 1 hiro
543 1 hiro
        /* Define all attributes we are interested in. */
544 1 hiro
        attribs[0] = SYLDAP_ATTR_DN;
545 1 hiro
        attribs[1] = SYLDAP_ATTR_COMMONNAME;
546 1 hiro
        attribs[2] = SYLDAP_ATTR_GIVENNAME;
547 1 hiro
        attribs[3] = SYLDAP_ATTR_SURNAME;
548 1 hiro
        attribs[4] = SYLDAP_ATTR_EMAIL;
549 1 hiro
        attribs[5] = SYLDAP_ATTR_UID;
550 1 hiro
        attribs[6] = NULL;
551 1 hiro
552 1 hiro
        /* Create LDAP search string and apply search criteria */
553 1 hiro
        criteria = g_strdup_printf( ldapServer->searchCriteria, ldapServer->searchValue );
554 1 hiro
        rc = ldap_search_ext_s( ld, ldapServer->baseDN, LDAP_SCOPE_SUBTREE, criteria, attribs, 0, NULL, NULL,
555 1 hiro
                       &timeout, 0, &result );
556 1 hiro
        g_free( criteria );
557 1 hiro
        criteria = NULL;
558 1 hiro
        if( rc == LDAP_TIMEOUT ) {
559 1 hiro
                ldap_unbind( ld );
560 1 hiro
                ldapServer->retVal = MGU_LDAP_TIMEOUT;
561 1 hiro
                return ldapServer->retVal;
562 1 hiro
        }
563 1 hiro
        if( rc != LDAP_SUCCESS ) {
564 1 hiro
                /* printf( "LDAP Error: ldap_search_st: %s\n", ldap_err2string( rc ) ); */
565 1 hiro
                ldap_unbind( ld );
566 1 hiro
                ldapServer->retVal = MGU_LDAP_SEARCH;
567 1 hiro
                return ldapServer->retVal;
568 1 hiro
        }
569 1 hiro
570 1 hiro
        /* printf( "Total results are: %d\n", ldap_count_entries( ld, result ) ); */
571 1 hiro
572 1 hiro
        /* Clear the cache if we have new entries, otherwise leave untouched. */
573 1 hiro
        if( ldap_count_entries( ld, result ) > 0 ) {
574 1 hiro
                addrcache_clear( ldapServer->addressCache );
575 1 hiro
        }
576 1 hiro
577 1 hiro
        /* Process results */
578 1 hiro
        ldapServer->entriesRead = 0;
579 1 hiro
        for( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) {
580 1 hiro
                entriesFound = TRUE;
581 1 hiro
                if( ldapServer->entriesRead >= ldapServer->maxEntries ) break;
582 1 hiro
                /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
583 1 hiro
584 1 hiro
                /* Process all attributes */
585 1 hiro
                for( attribute = ldap_first_attribute( ld, e, &ber ); attribute != NULL;
586 1 hiro
                               attribute = ldap_next_attribute( ld, e, ber ) ) {
587 1 hiro
                        if( strcasecmp( attribute, SYLDAP_ATTR_COMMONNAME ) == 0 ) {
588 1 hiro
                                listName = syldap_add_list_values( ld, e, attribute );
589 1 hiro
                        }
590 1 hiro
                        if( strcasecmp( attribute, SYLDAP_ATTR_EMAIL ) == 0 ) {
591 1 hiro
                                listAddress = syldap_add_list_values( ld, e, attribute );
592 1 hiro
                        }
593 1 hiro
                        if( strcasecmp( attribute, SYLDAP_ATTR_UID ) == 0 ) {
594 1 hiro
                                listID = syldap_add_single_value( ld, e, attribute );
595 1 hiro
                        }
596 1 hiro
                        if( strcasecmp( attribute, SYLDAP_ATTR_GIVENNAME ) == 0 ) {
597 1 hiro
                                listFirst = syldap_add_list_values( ld, e, attribute );
598 1 hiro
                        }
599 1 hiro
                        if( strcasecmp( attribute, SYLDAP_ATTR_SURNAME ) == 0 ) {
600 1 hiro
                                listLast = syldap_add_single_value( ld, e, attribute );
601 1 hiro
                        }
602 1 hiro
                        if( strcasecmp( attribute, SYLDAP_ATTR_DN ) == 0 ) {
603 1 hiro
                                listDN = syldap_add_single_value( ld, e, attribute );
604 1 hiro
                        }
605 1 hiro
                }
606 1 hiro
607 1 hiro
                /* Free memory used to store attribute */
608 1 hiro
                ldap_memfree( attribute );
609 1 hiro
610 1 hiro
                /* Format and add items to cache */
611 1 hiro
                syldap_build_items_fl( ldapServer, listAddress, listFirst, listLast );
612 1 hiro
613 1 hiro
                /* Free up */
614 1 hiro
                syldap_free_lists( listName, listAddress, listID, listDN, listFirst, listLast );
615 1 hiro
                listName = listAddress = listID = listFirst = listLast = listDN = NULL;
616 1 hiro
617 1 hiro
                if( ber != NULL ) {
618 1 hiro
                        ber_free( ber, 0 );
619 1 hiro
                }
620 1 hiro
        }
621 1 hiro
622 1 hiro
        syldap_free_lists( listName, listAddress, listID, listDN, listFirst, listLast );
623 1 hiro
        listName = listAddress = listID = listFirst = listLast = listDN = NULL;
624 1 hiro
625 1 hiro
        /* Free up and disconnect */
626 1 hiro
        ldap_msgfree( result );
627 1 hiro
        ldap_unbind( ld );
628 1 hiro
        ldapServer->newSearch = FALSE;
629 1 hiro
        if( entriesFound ) {
630 1 hiro
                ldapServer->retVal = MGU_SUCCESS;
631 1 hiro
        }
632 1 hiro
        else {
633 1 hiro
                ldapServer->retVal = MGU_LDAP_NOENTRIES;
634 1 hiro
        }
635 1 hiro
        return ldapServer->retVal;
636 1 hiro
}
637 1 hiro
638 1 hiro
/* syldap_display_search_results() - updates the ui. this function is called from the
639 1 hiro
 * main thread (the thread running the GTK event loop). */
640 1 hiro
static gint syldap_display_search_results(SyldapServer *ldapServer)
641 1 hiro
{
642 1 hiro
        /* NOTE: when this function is called the accompanying thread should
643 1 hiro
         * already be terminated. */
644 1 hiro
        gtk_idle_remove(ldapServer->idleId);
645 1 hiro
        ldapServer->callBack(ldapServer);
646 1 hiro
        /* FIXME:  match should know whether to free this SyldapServer stuff. */
647 1 hiro
        g_free(ldapServer->thread);
648 1 hiro
        ldapServer->thread = NULL;
649 1 hiro
        return TRUE;
650 1 hiro
}
651 1 hiro
652 1 hiro
/* ============================================================================================ */
653 1 hiro
/*
654 1 hiro
* Read data into list. Main entry point
655 1 hiro
* Return: TRUE if file read successfully.
656 1 hiro
*/
657 1 hiro
/* ============================================================================================ */
658 1 hiro
gint syldap_read_data( SyldapServer *ldapServer ) {
659 1 hiro
        g_return_val_if_fail( ldapServer != NULL, -1 );
660 1 hiro
661 1 hiro
        ldapServer->accessFlag = FALSE;
662 1 hiro
        pthread_detach( pthread_self() );
663 1 hiro
        if( ldapServer->newSearch ) {
664 1 hiro
                /* Read data into the list */
665 1 hiro
                syldap_search( ldapServer );
666 1 hiro
667 1 hiro
                /* Mark cache */
668 1 hiro
                ldapServer->addressCache->modified = FALSE;
669 1 hiro
                ldapServer->addressCache->dataRead = TRUE;
670 1 hiro
                ldapServer->accessFlag = FALSE;
671 1 hiro
        }
672 1 hiro
673 1 hiro
        /* Callback */
674 1 hiro
        ldapServer->busyFlag = FALSE;
675 1 hiro
        if( ldapServer->callBack ) {
676 1 hiro
                /* make the ui thread update the search results */
677 1 hiro
                /* TODO: really necessary to call gdk_threads_XXX()??? gtk_idle_add()
678 1 hiro
                 * should do this - could someone check the GTK sources please? */
679 1 hiro
                gdk_threads_enter();
680 1 hiro
                ldapServer->idleId = gtk_idle_add((GtkFunction)syldap_display_search_results, ldapServer);
681 1 hiro
                gdk_threads_leave();
682 1 hiro
        }
683 1 hiro
684 1 hiro
        return ldapServer->retVal;
685 1 hiro
}
686 1 hiro
687 1 hiro
/* ============================================================================================ */
688 1 hiro
/*
689 1 hiro
* Cancel read with thread.
690 1 hiro
*/
691 1 hiro
/* ============================================================================================ */
692 1 hiro
void syldap_cancel_read( SyldapServer *ldapServer ) {
693 1 hiro
        g_return_if_fail( ldapServer != NULL );
694 1 hiro
695 1 hiro
        /* DELETEME: this is called from inside UI thread so it's OK, Christoph! */
696 1 hiro
        if( ldapServer->thread ) {
697 1 hiro
                /* printf( "thread cancelled\n" ); */
698 1 hiro
                pthread_cancel( *ldapServer->thread );
699 1 hiro
        }
700 1 hiro
        g_free(ldapServer->thread);
701 1 hiro
        ldapServer->thread = NULL;
702 1 hiro
        ldapServer->busyFlag = FALSE;
703 1 hiro
}
704 1 hiro
705 1 hiro
/* ============================================================================================ */
706 1 hiro
/*
707 1 hiro
* Read data into list using a background thread.
708 1 hiro
* Return: TRUE if file read successfully. Callback function will be
709 1 hiro
* notified when search is complete.
710 1 hiro
*/
711 1 hiro
/* ============================================================================================ */
712 1 hiro
gint syldap_read_data_th( SyldapServer *ldapServer ) {
713 1 hiro
        g_return_val_if_fail( ldapServer != NULL, -1 );
714 1 hiro
715 1 hiro
        ldapServer->busyFlag = FALSE;
716 1 hiro
        syldap_check_search( ldapServer );
717 1 hiro
        if( ldapServer->retVal == MGU_SUCCESS ) {
718 1 hiro
                /* debug_print("Staring LDAP read thread\n"); */
719 1 hiro
720 1 hiro
                ldapServer->busyFlag = TRUE;
721 1 hiro
                ldapServer->thread = g_new0(pthread_t, 1);
722 1 hiro
                pthread_create( ldapServer->thread, NULL, (void *) syldap_read_data, (void *) ldapServer );
723 1 hiro
        }
724 1 hiro
        return ldapServer->retVal;
725 1 hiro
}
726 1 hiro
727 1 hiro
/*
728 1 hiro
* Return link list of persons.
729 1 hiro
*/
730 1 hiro
GList *syldap_get_list_person( SyldapServer *ldapServer ) {
731 1 hiro
        g_return_val_if_fail( ldapServer != NULL, NULL );
732 1 hiro
        return addrcache_get_list_person( ldapServer->addressCache );
733 1 hiro
}
734 1 hiro
735 1 hiro
/*
736 1 hiro
* Return link list of folders. This is always NULL since there are
737 1 hiro
* no folders in GnomeCard.
738 1 hiro
* Return: NULL.
739 1 hiro
*/
740 1 hiro
GList *syldap_get_list_folder( SyldapServer *ldapServer ) {
741 1 hiro
        g_return_val_if_fail( ldapServer != NULL, NULL );
742 1 hiro
        return NULL;
743 1 hiro
}
744 1 hiro
745 1 hiro
#define SYLDAP_TEST_FILTER   "(objectclass=*)"
746 1 hiro
#define SYLDAP_SEARCHBASE_V2 "cn=config"
747 1 hiro
#define SYLDAP_SEARCHBASE_V3 ""
748 1 hiro
#define SYLDAP_V2_TEST_ATTR  "database"
749 1 hiro
#define SYLDAP_V3_TEST_ATTR  "namingcontexts"
750 1 hiro
751 1 hiro
/*
752 1 hiro
* Attempt to discover the base DN for the server.
753 1 hiro
* Enter:
754 1 hiro
*        host        Host name
755 1 hiro
*        port        Port number
756 1 hiro
*        bindDN        Bind DN (optional).
757 1 hiro
*        bindPW        Bind PW (optional).
758 1 hiro
*        tov        Timeout value (seconds), or 0 for none, default 30 secs.
759 1 hiro
* Return: List of Base DN's, or NULL if could not read. Base DN should
760 1 hiro
* be g_free() when done.
761 1 hiro
*/
762 1 hiro
GList *syldap_read_basedn_s( const gchar *host, const gint port, const gchar *bindDN, const gchar *bindPW, const gint tov ) {
763 1 hiro
        GList *baseDN = NULL;
764 1 hiro
        LDAP *ld;
765 1 hiro
        gint rc, i;
766 1 hiro
        LDAPMessage *result, *e;
767 1 hiro
        gchar *attribs[10];
768 1 hiro
        BerElement *ber;
769 1 hiro
        gchar *attribute;
770 1 hiro
        gchar **vals;
771 1 hiro
        struct timeval timeout;
772 1 hiro
773 1 hiro
        if( host == NULL ) return baseDN;
774 1 hiro
        if( port < 1 ) return baseDN;
775 1 hiro
776 1 hiro
        /* Set timeout */
777 1 hiro
        timeout.tv_usec = 0L;
778 1 hiro
        if( tov > 0 ) {
779 1 hiro
                timeout.tv_sec = tov;
780 1 hiro
        }
781 1 hiro
        else {
782 1 hiro
                timeout.tv_sec = 30L;
783 1 hiro
        }
784 1 hiro
785 1 hiro
        /* Connect to server. */
786 1 hiro
        if( ( ld = ldap_init( host, port ) ) == NULL ) {
787 1 hiro
                return baseDN;
788 1 hiro
        }
789 1 hiro
790 1 hiro
        /* Bind to the server, if required */
791 1 hiro
        if( bindDN ) {
792 1 hiro
                if( *bindDN != '\0' ) {
793 1 hiro
                        rc = ldap_simple_bind_s( ld, bindDN, bindPW );
794 1 hiro
                        if( rc != LDAP_SUCCESS ) {
795 1 hiro
                                /* printf( "LDAP Error: ldap_simple_bind_s: %s\n", ldap_err2string( rc ) ); */
796 1 hiro
                                ldap_unbind( ld );
797 1 hiro
                                return baseDN;
798 1 hiro
                        }
799 1 hiro
                }
800 1 hiro
        }
801 1 hiro
802 1 hiro
        /* Test for LDAP version 3 */
803 1 hiro
        attribs[0] = SYLDAP_V3_TEST_ATTR;
804 1 hiro
        attribs[1] = NULL;
805 1 hiro
        rc = ldap_search_ext_s( ld, SYLDAP_SEARCHBASE_V3, LDAP_SCOPE_BASE, SYLDAP_TEST_FILTER, attribs,
806 1 hiro
                       0, NULL, NULL, &timeout, 0, &result );
807 1 hiro
        if( rc == LDAP_SUCCESS ) {
808 1 hiro
                /* Process entries */
809 1 hiro
                for( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) {
810 1 hiro
                        /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
811 1 hiro
812 1 hiro
                        /* Process attributes */
813 1 hiro
                        for( attribute = ldap_first_attribute( ld, e, &ber ); attribute != NULL;
814 1 hiro
                                        attribute = ldap_next_attribute( ld, e, ber ) ) {
815 1 hiro
                                if( strcasecmp( attribute, SYLDAP_V3_TEST_ATTR ) == 0 ) {
816 1 hiro
                                        if( ( vals = ldap_get_values( ld, e, attribute ) ) != NULL ) {
817 1 hiro
                                                for( i = 0; vals[i] != NULL; i++ ) {
818 1 hiro
                                                        /* printf( "\t%s: %s\n", attribute, vals[i] ); */
819 1 hiro
                                                        baseDN = g_list_append( baseDN, g_strdup( vals[i] ) );
820 1 hiro
                                                }
821 1 hiro
                                        }
822 1 hiro
                                        ldap_value_free( vals );
823 1 hiro
                                }
824 1 hiro
                        }
825 1 hiro
                        ldap_memfree( attribute );
826 1 hiro
                        if( ber != NULL ) {
827 1 hiro
                                ber_free( ber, 0 );
828 1 hiro
                        }
829 1 hiro
                }
830 1 hiro
                ldap_msgfree( result );
831 1 hiro
        }
832 1 hiro
        else {
833 1 hiro
        }
834 1 hiro
835 1 hiro
        if( baseDN == NULL ) {
836 1 hiro
                /* Test for LDAP version 2 */
837 1 hiro
                attribs[0] = NULL;
838 1 hiro
                rc = ldap_search_ext_s( ld, SYLDAP_SEARCHBASE_V2, LDAP_SCOPE_BASE, SYLDAP_TEST_FILTER, attribs,
839 1 hiro
                               0, NULL, NULL, &timeout, 0, &result );
840 1 hiro
                if( rc == LDAP_SUCCESS ) {
841 1 hiro
                        /* Process entries */
842 1 hiro
                        for( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) {
843 1 hiro
                                /* if( baseDN ) break;                         */
844 1 hiro
                                /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
845 1 hiro
846 1 hiro
                                /* Process attributes */
847 1 hiro
                                for( attribute = ldap_first_attribute( ld, e, &ber ); attribute != NULL;
848 1 hiro
                                               attribute = ldap_next_attribute( ld, e, ber ) ) {
849 1 hiro
                                        /* if( baseDN ) break;                         */
850 1 hiro
                                        if( strcasecmp( attribute, SYLDAP_V2_TEST_ATTR ) == 0 ) {
851 1 hiro
                                                if( ( vals = ldap_get_values( ld, e, attribute ) ) != NULL ) {
852 1 hiro
                                                        for( i = 0; vals[i] != NULL; i++ ) {
853 1 hiro
                                                                char *ch;
854 1 hiro
                                                                /* Strip the 'ldb:' from the front of the value */
855 1 hiro
                                                                ch = ( char * ) strchr( vals[i], ':' );
856 1 hiro
                                                                if( ch ) {
857 1 hiro
                                                                        gchar *bn = g_strdup( ++ch );
858 1 hiro
                                                                        g_strchomp( bn );
859 1 hiro
                                                                        g_strchug( bn );
860 1 hiro
                                                                        baseDN = g_list_append( baseDN, g_strdup( bn ) );
861 1 hiro
                                                                }
862 1 hiro
                                                        }
863 1 hiro
                                                }
864 1 hiro
                                                ldap_value_free( vals );
865 1 hiro
                                        }
866 1 hiro
                                }
867 1 hiro
                                ldap_memfree( attribute );
868 1 hiro
                                if( ber != NULL ) {
869 1 hiro
                                        ber_free( ber, 0 );
870 1 hiro
                                }
871 1 hiro
                        }
872 1 hiro
                        ldap_msgfree( result );
873 1 hiro
                }
874 1 hiro
        }
875 1 hiro
        ldap_unbind( ld );
876 1 hiro
        return baseDN;
877 1 hiro
}
878 1 hiro
879 1 hiro
/*
880 1 hiro
* Attempt to discover the base DN for the server.
881 1 hiro
* Enter:  ldapServer Server to test.
882 1 hiro
* Return: List of Base DN's, or NULL if could not read. Base DN should
883 1 hiro
* be g_free() when done. Return code set in ldapServer.
884 1 hiro
*/
885 1 hiro
GList *syldap_read_basedn( SyldapServer *ldapServer ) {
886 1 hiro
        GList *baseDN = NULL;
887 1 hiro
        LDAP *ld;
888 1 hiro
        gint rc, i;
889 1 hiro
        LDAPMessage *result, *e;
890 1 hiro
        gchar *attribs[10];
891 1 hiro
        BerElement *ber;
892 1 hiro
        gchar *attribute;
893 1 hiro
        gchar **vals;
894 1 hiro
        struct timeval timeout;
895 1 hiro
896 1 hiro
        ldapServer->retVal = MGU_BAD_ARGS;
897 1 hiro
        if( ldapServer == NULL ) return baseDN;
898 1 hiro
        if( ldapServer->hostName == NULL ) return baseDN;
899 1 hiro
        if( ldapServer->port < 1 ) return baseDN;
900 1 hiro
901 1 hiro
        /* Set timeout */
902 1 hiro
        timeout.tv_usec = 0L;
903 1 hiro
        if( ldapServer->timeOut > 0 ) {
904 1 hiro
                timeout.tv_sec = ldapServer->timeOut;
905 1 hiro
        }
906 1 hiro
        else {
907 1 hiro
                timeout.tv_sec = 30L;
908 1 hiro
        }
909 1 hiro
910 1 hiro
        /* Connect to server. */
911 1 hiro
        if( ( ld = ldap_init( ldapServer->hostName, ldapServer->port ) ) == NULL ) {
912 1 hiro
                ldapServer->retVal = MGU_LDAP_INIT;
913 1 hiro
                return baseDN;
914 1 hiro
        }
915 1 hiro
916 1 hiro
        /* Bind to the server, if required */
917 1 hiro
        if( ldapServer->bindDN ) {
918 1 hiro
                if( *ldapServer->bindDN != '\0' ) {
919 1 hiro
                        rc = ldap_simple_bind_s( ld, ldapServer->bindDN, ldapServer->bindPass );
920 1 hiro
                        if( rc != LDAP_SUCCESS ) {
921 1 hiro
                                /* printf( "LDAP Error: ldap_simple_bind_s: %s\n", ldap_err2string( rc ) ); */
922 1 hiro
                                ldap_unbind( ld );
923 1 hiro
                                ldapServer->retVal = MGU_LDAP_BIND;
924 1 hiro
                                return baseDN;
925 1 hiro
                        }
926 1 hiro
                }
927 1 hiro
        }
928 1 hiro
929 1 hiro
        ldapServer->retVal = MGU_LDAP_SEARCH;
930 1 hiro
931 1 hiro
        /* Test for LDAP version 3 */
932 1 hiro
        attribs[0] = SYLDAP_V3_TEST_ATTR;
933 1 hiro
        attribs[1] = NULL;
934 1 hiro
        rc = ldap_search_ext_s( ld, SYLDAP_SEARCHBASE_V3, LDAP_SCOPE_BASE, SYLDAP_TEST_FILTER, attribs,
935 1 hiro
                       0, NULL, NULL, &timeout, 0, &result );
936 1 hiro
        if( rc == LDAP_SUCCESS ) {
937 1 hiro
                /* Process entries */
938 1 hiro
                for( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) {
939 1 hiro
                        /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
940 1 hiro
941 1 hiro
                        /* Process attributes */
942 1 hiro
                        for( attribute = ldap_first_attribute( ld, e, &ber ); attribute != NULL;
943 1 hiro
                                        attribute = ldap_next_attribute( ld, e, ber ) ) {
944 1 hiro
                                if( strcasecmp( attribute, SYLDAP_V3_TEST_ATTR ) == 0 ) {
945 1 hiro
                                        if( ( vals = ldap_get_values( ld, e, attribute ) ) != NULL ) {
946 1 hiro
                                                for( i = 0; vals[i] != NULL; i++ ) {
947 1 hiro
                                                        /* printf( "\t%s: %s\n", attribute, vals[i] ); */
948 1 hiro
                                                        baseDN = g_list_append( baseDN, g_strdup( vals[i] ) );
949 1 hiro
                                                }
950 1 hiro
                                        }
951 1 hiro
                                        ldap_value_free( vals );
952 1 hiro
                                }
953 1 hiro
                        }
954 1 hiro
                        ldap_memfree( attribute );
955 1 hiro
                        if( ber != NULL ) {
956 1 hiro
                                ber_free( ber, 0 );
957 1 hiro
                        }
958 1 hiro
                }
959 1 hiro
                ldap_msgfree( result );
960 1 hiro
                ldapServer->retVal = MGU_SUCCESS;
961 1 hiro
        }
962 1 hiro
        else if( rc == LDAP_TIMEOUT ) {
963 1 hiro
                ldapServer->retVal = MGU_LDAP_TIMEOUT;
964 1 hiro
        }
965 1 hiro
966 1 hiro
        if( baseDN == NULL ) {
967 1 hiro
                /* Test for LDAP version 2 */
968 1 hiro
                attribs[0] = NULL;
969 1 hiro
                rc = ldap_search_ext_s( ld, SYLDAP_SEARCHBASE_V2, LDAP_SCOPE_BASE, SYLDAP_TEST_FILTER, attribs,
970 1 hiro
                               0, NULL, NULL, &timeout, 0, &result );
971 1 hiro
                if( rc == LDAP_SUCCESS ) {
972 1 hiro
                        /* Process entries */
973 1 hiro
                        for( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) {
974 1 hiro
                                /* if( baseDN ) break;                         */
975 1 hiro
                                /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
976 1 hiro
977 1 hiro
                                /* Process attributes */
978 1 hiro
                                for( attribute = ldap_first_attribute( ld, e, &ber ); attribute != NULL;
979 1 hiro
                                               attribute = ldap_next_attribute( ld, e, ber ) ) {
980 1 hiro
                                        /* if( baseDN ) break;                         */
981 1 hiro
                                        if( strcasecmp( attribute, SYLDAP_V2_TEST_ATTR ) == 0 ) {
982 1 hiro
                                                if( ( vals = ldap_get_values( ld, e, attribute ) ) != NULL ) {
983 1 hiro
                                                        for( i = 0; vals[i] != NULL; i++ ) {
984 1 hiro
                                                                char *ch;
985 1 hiro
                                                                /* Strip the 'ldb:' from the front of the value */
986 1 hiro
                                                                ch = ( char * ) strchr( vals[i], ':' );
987 1 hiro
                                                                if( ch ) {
988 1 hiro
                                                                        gchar *bn = g_strdup( ++ch );
989 1 hiro
                                                                        g_strchomp( bn );
990 1 hiro
                                                                        g_strchug( bn );
991 1 hiro
                                                                        baseDN = g_list_append( baseDN, g_strdup( bn ) );
992 1 hiro
                                                                }
993 1 hiro
                                                        }
994 1 hiro
                                                }
995 1 hiro
                                                ldap_value_free( vals );
996 1 hiro
                                        }
997 1 hiro
                                }
998 1 hiro
                                ldap_memfree( attribute );
999 1 hiro
                                if( ber != NULL ) {
1000 1 hiro
                                        ber_free( ber, 0 );
1001 1 hiro
                                }
1002 1 hiro
                        }
1003 1 hiro
                        ldap_msgfree( result );
1004 1 hiro
                        ldapServer->retVal = MGU_SUCCESS;
1005 1 hiro
                }
1006 1 hiro
                else if( rc == LDAP_TIMEOUT ) {
1007 1 hiro
                        ldapServer->retVal = MGU_LDAP_TIMEOUT;
1008 1 hiro
                }
1009 1 hiro
        }
1010 1 hiro
        ldap_unbind( ld );
1011 1 hiro
1012 1 hiro
        return baseDN;
1013 1 hiro
}
1014 1 hiro
1015 1 hiro
/*
1016 1 hiro
* Attempt to connect to the server.
1017 1 hiro
* Enter:
1018 1 hiro
*        host        Host name
1019 1 hiro
*        port        Port number
1020 1 hiro
* Return: TRUE if connected successfully.
1021 1 hiro
*/
1022 1 hiro
gboolean syldap_test_connect_s( const gchar *host, const gint port ) {
1023 1 hiro
        gboolean retVal = FALSE;
1024 1 hiro
        LDAP *ld;
1025 1 hiro
1026 1 hiro
        if( host == NULL ) return retVal;
1027 1 hiro
        if( port < 1 ) return retVal;
1028 1 hiro
        if( ( ld = ldap_open( host, port ) ) != NULL ) {
1029 1 hiro
                retVal = TRUE;
1030 1 hiro
        }
1031 1 hiro
        if( ld != NULL ) {
1032 1 hiro
                ldap_unbind( ld );
1033 1 hiro
        }
1034 1 hiro
        return retVal;
1035 1 hiro
}
1036 1 hiro
1037 1 hiro
/*
1038 1 hiro
* Attempt to connect to the server.
1039 1 hiro
* Enter:  ldapServer Server to test.
1040 1 hiro
* Return: TRUE if connected successfully. Return code set in ldapServer.
1041 1 hiro
*/
1042 1 hiro
gboolean syldap_test_connect( SyldapServer *ldapServer ) {
1043 1 hiro
        gboolean retVal = FALSE;
1044 1 hiro
        LDAP *ld;
1045 1 hiro
1046 1 hiro
        ldapServer->retVal = MGU_BAD_ARGS;
1047 1 hiro
        if( ldapServer == NULL ) return retVal;
1048 1 hiro
        if( ldapServer->hostName == NULL ) return retVal;
1049 1 hiro
        if( ldapServer->port < 1 ) return retVal;
1050 1 hiro
        ldapServer->retVal = MGU_LDAP_INIT;
1051 1 hiro
        if( ( ld = ldap_open( ldapServer->hostName, ldapServer->port ) ) != NULL ) {
1052 1 hiro
                ldapServer->retVal = MGU_SUCCESS;
1053 1 hiro
                retVal = TRUE;
1054 1 hiro
        }
1055 1 hiro
        if( ld != NULL ) {
1056 1 hiro
                ldap_unbind( ld );
1057 1 hiro
        }
1058 1 hiro
        return retVal;
1059 1 hiro
}
1060 1 hiro
1061 1 hiro
#define LDAP_LINK_LIB_NAME_1 "libldap.so"
1062 1 hiro
#define LDAP_LINK_LIB_NAME_2 "liblber.so"
1063 1 hiro
#define LDAP_LINK_LIB_NAME_3 "libresolv.so"
1064 1 hiro
#define LDAP_LINK_LIB_NAME_4 "libpthread.so"
1065 1 hiro
1066 1 hiro
/*
1067 1 hiro
* Test whether LDAP libraries installed.
1068 1 hiro
* Return: TRUE if library available.
1069 1 hiro
*/
1070 1 hiro
#if 0
1071 1 hiro
gboolean syldap_test_ldap_lib() {
1072 1 hiro
        void *handle, *fun;
1073 1 hiro
1074 1 hiro
        /* Get library */
1075 1 hiro
        handle = dlopen( LDAP_LINK_LIB_NAME_1, RTLD_LAZY );
1076 1 hiro
        if( ! handle ) {
1077 1 hiro
                return FALSE;
1078 1 hiro
        }
1079 1 hiro
1080 1 hiro
        /* Test for symbols we need */
1081 1 hiro
        fun = dlsym( handle, "ldap_init" );
1082 1 hiro
        if( ! fun ) {
1083 1 hiro
                dlclose( handle );
1084 1 hiro
                return FALSE;
1085 1 hiro
        }
1086 1 hiro
        dlclose( handle ); handle = NULL; fun = NULL;
1087 1 hiro
1088 1 hiro
        handle = dlopen( LDAP_LINK_LIB_NAME_2, RTLD_LAZY );
1089 1 hiro
        if( ! handle ) {
1090 1 hiro
                return FALSE;
1091 1 hiro
        }
1092 1 hiro
        fun = dlsym( handle, "ber_init" );
1093 1 hiro
        if( ! fun ) {
1094 1 hiro
                dlclose( handle );
1095 1 hiro
                return FALSE;
1096 1 hiro
        }
1097 1 hiro
        dlclose( handle ); handle = NULL; fun = NULL;
1098 1 hiro
1099 1 hiro
        handle = dlopen( LDAP_LINK_LIB_NAME_3, RTLD_LAZY );
1100 1 hiro
        if( ! handle ) {
1101 1 hiro
                return FALSE;
1102 1 hiro
        }
1103 1 hiro
        fun = dlsym( handle, "res_query" );
1104 1 hiro
        if( ! fun ) {
1105 1 hiro
                dlclose( handle );
1106 1 hiro
                return FALSE;
1107 1 hiro
        }
1108 1 hiro
        dlclose( handle ); handle = NULL; fun = NULL;
1109 1 hiro
1110 1 hiro
        handle = dlopen( LDAP_LINK_LIB_NAME_4, RTLD_LAZY );
1111 1 hiro
        if( ! handle ) {
1112 1 hiro
                return FALSE;
1113 1 hiro
        }
1114 1 hiro
        fun = dlsym( handle, "pthread_create" );
1115 1 hiro
        if( ! fun ) {
1116 1 hiro
                dlclose( handle );
1117 1 hiro
                return FALSE;
1118 1 hiro
        }
1119 1 hiro
        dlclose( handle ); handle = NULL; fun = NULL;
1120 1 hiro
1121 1 hiro
        return TRUE;
1122 1 hiro
}
1123 1 hiro
#endif /* 0 */
1124 1 hiro
1125 1 hiro
#endif        /* USE_LDAP */
1126 1 hiro
1127 1 hiro
/*
1128 1 hiro
* End of Source.
1129 1 hiro
*/