1 /******************************************************************************
3 * Copyright (C) 2000 Pierangelo Masarati, <ando@sys-net.it>
6 * Permission is granted to anyone to use this software for any purpose
7 * on any computer system, and to alter it and redistribute it, subject
8 * to the following restrictions:
10 * 1. The author is not responsible for the consequences of use of this
11 * software, no matter how awful, even if they arise from flaws in it.
13 * 2. The origin of this software must not be misrepresented, either by
14 * explicit claim or by omission. Since few users ever read sources,
15 * credits should appear in the documentation.
17 * 3. Altered versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software. Since few users
19 * ever read sources, credits should appear in the documentation.
21 * 4. This notice may not be removed or altered.
23 ******************************************************************************/
27 #include "rewrite-int.h"
28 #include "rewrite-map.h"
31 * LDAP map data structure
33 struct ldap_map_data {
40 #define MAP_LDAP_EVERYTIME 0x00
41 #define MAP_LDAP_NOW 0x01
42 #define MAP_LDAP_LATER 0x02
47 #ifdef USE_REWRITE_LDAP_PVT_THREADS
48 ldap_pvt_thread_mutex_t lm_mutex;
49 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
54 struct ldap_map_data *data
57 assert( data != NULL );
59 if ( data->lm_url != NULL ) {
63 if ( data->lm_lud != NULL ) {
64 ldap_free_urldesc( data->lm_lud );
67 if ( data->lm_binddn != NULL ) {
68 free( data->lm_binddn );
71 if ( data->lm_bindpw != NULL ) {
72 free( data->lm_bindpw );
75 if ( data->lm_when != MAP_LDAP_EVERYTIME && data->lm_ld != NULL ) {
76 ldap_unbind_s( data->lm_ld );
84 struct rewrite_info *info,
91 struct ldap_map_data *data;
94 assert( info != NULL );
95 assert( fname != NULL );
96 assert( argv != NULL );
98 data = calloc( sizeof( struct ldap_map_data ), 1 );
104 Debug( LDAP_DEBUG_ANY,
105 "[%s:%d] ldap map needs URI\n%s",
111 data->lm_url = strdup( argv[ 0 ] );
112 if ( data->lm_url == NULL ) {
113 map_ldap_free( data );
117 if ( ldap_url_parse( argv[ 0 ], &data->lm_lud ) != REWRITE_SUCCESS ) {
118 Debug( LDAP_DEBUG_ANY,
119 "[%s:%d] illegal URI '%s'\n",
120 fname, lineno, argv[ 0 ] );
121 map_ldap_free( data );
125 p = strchr( data->lm_url, '/' );
126 assert( p[ 1 ] == '/' );
127 if ( ( p = strchr( p + 2, '/' ) ) != NULL ) {
131 if ( strcasecmp( data->lm_lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
132 data->lm_attrsonly = 1;
135 for ( argc--, argv++; argc > 0; argc--, argv++ ) {
136 if ( strncasecmp( argv[ 0 ], "binddn=", 7 ) == 0 ) {
137 char *p = argv[ 0 ] + 7;
140 if ( p[ 0 ] == '\"' || p [ 0 ] == '\'' ) {
143 if ( p[ l ] != p[ 0 ] ) {
144 map_ldap_free( data );
151 data->lm_binddn = strdup( p );
152 if ( data->lm_binddn == NULL ) {
153 map_ldap_free( data );
157 if ( data->lm_binddn[ l ] == '\"'
158 || data->lm_binddn[ l ] == '\'' ) {
159 data->lm_binddn[ l ] = '\0';
161 } else if ( strncasecmp( argv[ 0 ], "bindpw=", 7 ) == 0 ) {
162 data->lm_bindpw = strdup( argv[ 2 ] + 7 );
163 if ( data->lm_bindpw == NULL ) {
164 map_ldap_free( data );
167 } else if ( strncasecmp( argv[ 0 ], "bindwhen=", 9 ) == 0 ) {
168 char *p = argv[ 0 ] + 9;
170 if ( strcasecmp( p, "now" ) == 0 ) {
173 data->lm_when = MAP_LDAP_NOW;
176 * Init LDAP handler ...
178 rc = ldap_initialize( &data->lm_ld, data->lm_url );
179 if ( rc != LDAP_SUCCESS ) {
180 map_ldap_free( data );
184 #ifdef USE_REWRITE_LDAP_PVT_THREADS
185 ldap_pvt_thread_mutex_init( &data->lm_mutex );
186 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
188 } else if ( strcasecmp( p, "later" ) == 0 ) {
189 data->lm_when = MAP_LDAP_LATER;
191 #ifdef USE_REWRITE_LDAP_PVT_THREADS
192 ldap_pvt_thread_mutex_init( &data->lm_mutex );
193 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
195 } else if ( strcasecmp( p, "everytime" ) == 0 ) {
196 data->lm_when = MAP_LDAP_EVERYTIME;
203 return ( void * )data;
208 struct rewrite_builtin_map *map,
215 LDAPMessage *res = NULL, *entry;
218 struct ldap_map_data *data = ( struct ldap_map_data * )map->lb_private;
219 LDAPURLDesc *lud = data->lm_lud;
223 assert( map != NULL );
224 assert( map->lb_type == REWRITE_BUILTIN_MAP_LDAP );
225 assert( map->lb_private != NULL );
226 assert( filter != NULL );
227 assert( val != NULL );
232 if ( data->lm_when == MAP_LDAP_EVERYTIME ) {
233 rc = ldap_initialize( &ld, data->lm_url );
236 #ifdef USE_REWRITE_LDAP_PVT_THREADS
237 ldap_pvt_thread_mutex_lock( &data->lm_mutex );
238 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
242 if ( data->lm_when == MAP_LDAP_LATER && data->lm_ld == NULL ) {
243 rc = ldap_initialize( &data->lm_ld, data->lm_url );
249 if ( rc != LDAP_SUCCESS ) {
255 if ( data->lm_binddn != NULL ) {
256 rc = ldap_simple_bind_s( ld, data->lm_binddn, data->lm_bindpw );
257 if ( rc == LDAP_SERVER_DOWN && first_try ) {
259 if ( ldap_initialize( &ld, data->lm_url ) != LDAP_SUCCESS ) {
265 } else if ( rc != REWRITE_SUCCESS ) {
271 rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, ( char * )filter,
272 lud->lud_attrs, data->lm_attrsonly, &res );
273 if ( rc == LDAP_SERVER_DOWN && first_try ) {
275 if ( ldap_initialize( &ld, data->lm_url ) != LDAP_SUCCESS ) {
281 } else if ( rc != REWRITE_SUCCESS ) {
286 if ( ldap_count_entries( ld, res ) != 1 ) {
292 entry = ldap_first_entry( ld, res );
293 assert( entry != NULL );
295 if ( data->lm_attrsonly == 1 ) {
297 * dn is newly allocated, so there's no need to strdup it
299 val->bv_val = ldap_get_dn( ld, entry );
302 values = ldap_get_values( ld, entry, lud->lud_attrs[ 0 ] );
303 if ( values == NULL || values[ 0 ] == NULL ) {
304 if ( values != NULL ) {
305 ldap_value_free( values );
311 val->bv_val = strdup( values[ 0 ] );
312 ldap_value_free( values );
317 if ( val->bv_val == NULL ) {
321 val->bv_len = strlen( val->bv_val );
324 if ( data->lm_when == MAP_LDAP_EVERYTIME ) {
331 #ifdef USE_REWRITE_LDAP_PVT_THREADS
332 ldap_pvt_thread_mutex_unlock( &data->lm_mutex );
333 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
341 struct rewrite_builtin_map **pmap
344 struct ldap_map_data *data;
349 data = ( struct ldap_map_data * )(*pmap)->lb_private;
351 if ( data->lm_when != MAP_LDAP_EVERYTIME && data->lm_ld != NULL ) {
352 ldap_unbind_s( data->lm_ld );
356 if ( data->lm_lud ) {
357 ldap_free_urldesc( data->lm_lud );
361 if ( data->lm_url ) {
362 free( data->lm_url );
366 if ( data->lm_binddn ) {
367 free( data->lm_binddn );
368 data->lm_binddn = NULL;
371 if (data->lm_bindpw ) {
372 memset( data->lm_bindpw, 0, strlen( data->lm_bindpw ) );
373 free( data->lm_bindpw );
374 data->lm_bindpw = NULL;
378 (*pmap)->lb_private = NULL;