2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2003 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
16 * This work was initially developed by Pierangelo Masarati for
17 * inclusion in OpenLDAP Software.
22 #include "rewrite-int.h"
23 #include "rewrite-map.h"
26 * LDAP map data structure
28 struct ldap_map_data {
35 #define MAP_LDAP_EVERYTIME 0x00
36 #define MAP_LDAP_NOW 0x01
37 #define MAP_LDAP_LATER 0x02
42 #ifdef USE_REWRITE_LDAP_PVT_THREADS
43 ldap_pvt_thread_mutex_t lm_mutex;
44 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
49 struct ldap_map_data *data
52 assert( data != NULL );
54 if ( data->lm_url != NULL ) {
58 if ( data->lm_lud != NULL ) {
59 ldap_free_urldesc( data->lm_lud );
62 if ( data->lm_binddn != NULL ) {
63 free( data->lm_binddn );
66 if ( data->lm_bindpw != NULL ) {
67 free( data->lm_bindpw );
70 if ( data->lm_when != MAP_LDAP_EVERYTIME && data->lm_ld != NULL ) {
71 ldap_unbind_s( data->lm_ld );
79 struct rewrite_info *info,
86 struct ldap_map_data *data;
89 assert( info != NULL );
90 assert( fname != NULL );
91 assert( argv != NULL );
93 data = calloc( sizeof( struct ldap_map_data ), 1 );
99 Debug( LDAP_DEBUG_ANY,
100 "[%s:%d] ldap map needs URI\n%s",
106 data->lm_url = strdup( argv[ 0 ] );
107 if ( data->lm_url == NULL ) {
108 map_ldap_free( data );
112 if ( ldap_url_parse( argv[ 0 ], &data->lm_lud ) != REWRITE_SUCCESS ) {
113 Debug( LDAP_DEBUG_ANY,
114 "[%s:%d] illegal URI '%s'\n",
115 fname, lineno, argv[ 0 ] );
116 map_ldap_free( data );
120 p = strchr( data->lm_url, '/' );
121 assert( p[ 1 ] == '/' );
122 if ( ( p = strchr( p + 2, '/' ) ) != NULL ) {
126 if ( strcasecmp( data->lm_lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
127 data->lm_attrsonly = 1;
130 for ( argc--, argv++; argc > 0; argc--, argv++ ) {
131 if ( strncasecmp( argv[ 0 ], "binddn=", 7 ) == 0 ) {
132 char *p = argv[ 0 ] + 7;
135 if ( p[ 0 ] == '\"' || p [ 0 ] == '\'' ) {
138 if ( p[ l ] != p[ 0 ] ) {
139 map_ldap_free( data );
146 data->lm_binddn = strdup( p );
147 if ( data->lm_binddn == NULL ) {
148 map_ldap_free( data );
152 if ( data->lm_binddn[ l ] == '\"'
153 || data->lm_binddn[ l ] == '\'' ) {
154 data->lm_binddn[ l ] = '\0';
156 } else if ( strncasecmp( argv[ 0 ], "bindpw=", 7 ) == 0 ) {
157 data->lm_bindpw = strdup( argv[ 2 ] + 7 );
158 if ( data->lm_bindpw == NULL ) {
159 map_ldap_free( data );
162 } else if ( strncasecmp( argv[ 0 ], "bindwhen=", 9 ) == 0 ) {
163 char *p = argv[ 0 ] + 9;
165 if ( strcasecmp( p, "now" ) == 0 ) {
168 data->lm_when = MAP_LDAP_NOW;
171 * Init LDAP handler ...
173 rc = ldap_initialize( &data->lm_ld, data->lm_url );
174 if ( rc != LDAP_SUCCESS ) {
175 map_ldap_free( data );
179 #ifdef USE_REWRITE_LDAP_PVT_THREADS
180 ldap_pvt_thread_mutex_init( &data->lm_mutex );
181 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
183 } else if ( strcasecmp( p, "later" ) == 0 ) {
184 data->lm_when = MAP_LDAP_LATER;
186 #ifdef USE_REWRITE_LDAP_PVT_THREADS
187 ldap_pvt_thread_mutex_init( &data->lm_mutex );
188 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
190 } else if ( strcasecmp( p, "everytime" ) == 0 ) {
191 data->lm_when = MAP_LDAP_EVERYTIME;
198 return ( void * )data;
203 struct rewrite_builtin_map *map,
210 LDAPMessage *res = NULL, *entry;
213 struct ldap_map_data *data = ( struct ldap_map_data * )map->lb_private;
214 LDAPURLDesc *lud = data->lm_lud;
218 assert( map != NULL );
219 assert( map->lb_type == REWRITE_BUILTIN_MAP_LDAP );
220 assert( map->lb_private != NULL );
221 assert( filter != NULL );
222 assert( val != NULL );
227 if ( data->lm_when == MAP_LDAP_EVERYTIME ) {
228 rc = ldap_initialize( &ld, data->lm_url );
231 #ifdef USE_REWRITE_LDAP_PVT_THREADS
232 ldap_pvt_thread_mutex_lock( &data->lm_mutex );
233 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
237 if ( data->lm_when == MAP_LDAP_LATER && data->lm_ld == NULL ) {
238 rc = ldap_initialize( &data->lm_ld, data->lm_url );
244 if ( rc != LDAP_SUCCESS ) {
250 if ( data->lm_binddn != NULL ) {
251 rc = ldap_simple_bind_s( ld, data->lm_binddn, data->lm_bindpw );
252 if ( rc == LDAP_SERVER_DOWN && first_try ) {
254 if ( ldap_initialize( &ld, data->lm_url ) != LDAP_SUCCESS ) {
260 } else if ( rc != REWRITE_SUCCESS ) {
266 rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, ( char * )filter,
267 lud->lud_attrs, data->lm_attrsonly, &res );
268 if ( rc == LDAP_SERVER_DOWN && first_try ) {
270 if ( ldap_initialize( &ld, data->lm_url ) != LDAP_SUCCESS ) {
276 } else if ( rc != REWRITE_SUCCESS ) {
281 if ( ldap_count_entries( ld, res ) != 1 ) {
287 entry = ldap_first_entry( ld, res );
288 assert( entry != NULL );
290 if ( data->lm_attrsonly == 1 ) {
292 * dn is newly allocated, so there's no need to strdup it
294 val->bv_val = ldap_get_dn( ld, entry );
297 values = ldap_get_values( ld, entry, lud->lud_attrs[ 0 ] );
298 if ( values == NULL || values[ 0 ] == NULL ) {
299 if ( values != NULL ) {
300 ldap_value_free( values );
306 val->bv_val = strdup( values[ 0 ] );
307 ldap_value_free( values );
312 if ( val->bv_val == NULL ) {
316 val->bv_len = strlen( val->bv_val );
319 if ( data->lm_when == MAP_LDAP_EVERYTIME ) {
326 #ifdef USE_REWRITE_LDAP_PVT_THREADS
327 ldap_pvt_thread_mutex_unlock( &data->lm_mutex );
328 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
336 struct rewrite_builtin_map **pmap
339 struct ldap_map_data *data;
344 data = ( struct ldap_map_data * )(*pmap)->lb_private;
346 if ( data->lm_when != MAP_LDAP_EVERYTIME && data->lm_ld != NULL ) {
347 ldap_unbind_s( data->lm_ld );
351 if ( data->lm_lud ) {
352 ldap_free_urldesc( data->lm_lud );
356 if ( data->lm_url ) {
357 free( data->lm_url );
361 if ( data->lm_binddn ) {
362 free( data->lm_binddn );
363 data->lm_binddn = NULL;
366 if (data->lm_bindpw ) {
367 memset( data->lm_bindpw, 0, strlen( data->lm_bindpw ) );
368 free( data->lm_bindpw );
369 data->lm_bindpw = NULL;
373 (*pmap)->lb_private = NULL;