2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2006 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 #define LDAP_DEPRECATED 1
23 #include "rewrite-int.h"
24 #include "rewrite-map.h"
27 * LDAP map data structure
29 struct ldap_map_data {
36 #define MAP_LDAP_EVERYTIME 0x00
37 #define MAP_LDAP_NOW 0x01
38 #define MAP_LDAP_LATER 0x02
43 #ifdef USE_REWRITE_LDAP_PVT_THREADS
44 ldap_pvt_thread_mutex_t lm_mutex;
45 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
50 struct ldap_map_data *data
53 assert( data != NULL );
55 if ( data->lm_url != NULL ) {
59 if ( data->lm_lud != NULL ) {
60 ldap_free_urldesc( data->lm_lud );
63 if ( data->lm_binddn != NULL ) {
64 free( data->lm_binddn );
67 if ( data->lm_bindpw != NULL ) {
68 free( data->lm_bindpw );
71 if ( data->lm_when != MAP_LDAP_EVERYTIME && data->lm_ld != NULL ) {
72 ldap_unbind_s( data->lm_ld );
80 struct rewrite_info *info,
87 struct ldap_map_data *data;
90 assert( info != NULL );
91 assert( fname != NULL );
92 assert( argv != NULL );
94 data = calloc( sizeof( struct ldap_map_data ), 1 );
100 Debug( LDAP_DEBUG_ANY,
101 "[%s:%d] ldap map needs URI\n%s",
107 data->lm_url = strdup( argv[ 0 ] );
108 if ( data->lm_url == NULL ) {
109 map_ldap_free( data );
113 if ( ldap_url_parse( argv[ 0 ], &data->lm_lud ) != REWRITE_SUCCESS ) {
114 Debug( LDAP_DEBUG_ANY,
115 "[%s:%d] illegal URI '%s'\n",
116 fname, lineno, argv[ 0 ] );
117 map_ldap_free( data );
121 p = strchr( data->lm_url, '/' );
122 assert( p[ 1 ] == '/' );
123 if ( ( p = strchr( p + 2, '/' ) ) != NULL ) {
127 if ( strcasecmp( data->lm_lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
128 data->lm_attrsonly = 1;
131 for ( argc--, argv++; argc > 0; argc--, argv++ ) {
132 if ( strncasecmp( argv[ 0 ], "binddn=", 7 ) == 0 ) {
133 char *p = argv[ 0 ] + 7;
136 if ( p[ 0 ] == '\"' || p [ 0 ] == '\'' ) {
139 if ( p[ l ] != p[ 0 ] ) {
140 map_ldap_free( data );
147 data->lm_binddn = strdup( p );
148 if ( data->lm_binddn == NULL ) {
149 map_ldap_free( data );
153 if ( data->lm_binddn[ l ] == '\"'
154 || data->lm_binddn[ l ] == '\'' ) {
155 data->lm_binddn[ l ] = '\0';
157 } else if ( strncasecmp( argv[ 0 ], "bindpw=", 7 ) == 0 ) {
158 data->lm_bindpw = strdup( argv[ 2 ] + 7 );
159 if ( data->lm_bindpw == NULL ) {
160 map_ldap_free( data );
163 } else if ( strncasecmp( argv[ 0 ], "bindwhen=", 9 ) == 0 ) {
164 char *p = argv[ 0 ] + 9;
166 if ( strcasecmp( p, "now" ) == 0 ) {
169 data->lm_when = MAP_LDAP_NOW;
172 * Init LDAP handler ...
174 rc = ldap_initialize( &data->lm_ld, data->lm_url );
175 if ( rc != LDAP_SUCCESS ) {
176 map_ldap_free( data );
180 #ifdef USE_REWRITE_LDAP_PVT_THREADS
181 ldap_pvt_thread_mutex_init( &data->lm_mutex );
182 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
184 } else if ( strcasecmp( p, "later" ) == 0 ) {
185 data->lm_when = MAP_LDAP_LATER;
187 #ifdef USE_REWRITE_LDAP_PVT_THREADS
188 ldap_pvt_thread_mutex_init( &data->lm_mutex );
189 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
191 } else if ( strcasecmp( p, "everytime" ) == 0 ) {
192 data->lm_when = MAP_LDAP_EVERYTIME;
199 return ( void * )data;
204 struct rewrite_builtin_map *map,
211 LDAPMessage *res = NULL, *entry;
214 struct ldap_map_data *data = ( struct ldap_map_data * )map->lb_private;
215 LDAPURLDesc *lud = data->lm_lud;
219 assert( map != NULL );
220 assert( map->lb_type == REWRITE_BUILTIN_MAP_LDAP );
221 assert( map->lb_private != NULL );
222 assert( filter != NULL );
223 assert( val != NULL );
228 if ( data->lm_when == MAP_LDAP_EVERYTIME ) {
229 rc = ldap_initialize( &ld, data->lm_url );
232 #ifdef USE_REWRITE_LDAP_PVT_THREADS
233 ldap_pvt_thread_mutex_lock( &data->lm_mutex );
234 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
238 if ( data->lm_when == MAP_LDAP_LATER && data->lm_ld == NULL ) {
239 rc = ldap_initialize( &data->lm_ld, data->lm_url );
245 if ( rc != LDAP_SUCCESS ) {
251 if ( data->lm_binddn != NULL ) {
252 rc = ldap_simple_bind_s( ld, data->lm_binddn, data->lm_bindpw );
253 if ( rc == LDAP_SERVER_DOWN && first_try ) {
255 if ( ldap_initialize( &ld, data->lm_url ) != LDAP_SUCCESS ) {
261 } else if ( rc != REWRITE_SUCCESS ) {
267 rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, ( char * )filter,
268 lud->lud_attrs, data->lm_attrsonly, &res );
269 if ( rc == LDAP_SERVER_DOWN && first_try ) {
271 if ( ldap_initialize( &ld, data->lm_url ) != LDAP_SUCCESS ) {
277 } else if ( rc != REWRITE_SUCCESS ) {
282 if ( ldap_count_entries( ld, res ) != 1 ) {
288 entry = ldap_first_entry( ld, res );
289 assert( entry != NULL );
291 if ( data->lm_attrsonly == 1 ) {
293 * dn is newly allocated, so there's no need to strdup it
295 val->bv_val = ldap_get_dn( ld, entry );
298 values = ldap_get_values( ld, entry, lud->lud_attrs[ 0 ] );
299 if ( values == NULL || values[ 0 ] == NULL ) {
300 if ( values != NULL ) {
301 ldap_value_free( values );
307 val->bv_val = strdup( values[ 0 ] );
308 ldap_value_free( values );
313 if ( val->bv_val == NULL ) {
317 val->bv_len = strlen( val->bv_val );
320 if ( data->lm_when == MAP_LDAP_EVERYTIME ) {
327 #ifdef USE_REWRITE_LDAP_PVT_THREADS
328 ldap_pvt_thread_mutex_unlock( &data->lm_mutex );
329 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
337 struct rewrite_builtin_map **pmap
340 struct ldap_map_data *data;
342 assert( pmap != NULL );
343 assert( *pmap != NULL );
345 data = ( struct ldap_map_data * )(*pmap)->lb_private;
347 if ( data->lm_when != MAP_LDAP_EVERYTIME && data->lm_ld != NULL ) {
348 ldap_unbind_s( data->lm_ld );
352 if ( data->lm_lud ) {
353 ldap_free_urldesc( data->lm_lud );
357 if ( data->lm_url ) {
358 free( data->lm_url );
362 if ( data->lm_binddn ) {
363 free( data->lm_binddn );
364 data->lm_binddn = NULL;
367 if (data->lm_bindpw ) {
368 memset( data->lm_bindpw, 0, strlen( data->lm_bindpw ) );
369 free( data->lm_bindpw );
370 data->lm_bindpw = NULL;
374 (*pmap)->lb_private = NULL;