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 mutex;
49 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
54 struct ldap_map_data *data
57 assert( data != NULL );
59 if ( data->url != NULL ) {
63 if ( data->lud != NULL ) {
64 ldap_free_urldesc( data->lud );
67 if ( data->binddn != NULL ) {
71 if ( data->bindpw != NULL ) {
75 if ( data->when != MAP_LDAP_EVERYTIME && data->ld != NULL ) {
76 ldap_unbind_s( data->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->url = strdup( argv[ 0 ] );
112 if ( data->url == NULL ) {
113 map_ldap_free( data );
117 if ( ldap_url_parse( argv[ 0 ], &data->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->url, '/' );
126 assert( p[ 1 ] == '/' );
127 if ( ( p = strchr( p + 2, '/' ) ) != NULL ) {
131 if ( strcasecmp( data->lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
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->binddn = strdup( p );
152 if ( data->binddn == NULL ) {
153 map_ldap_free( data );
157 if ( data->binddn[ l ] == '\"'
158 || data->binddn[ l ] == '\'' ) {
159 data->binddn[ l ] = '\0';
161 } else if ( strncasecmp( argv[ 0 ], "bindpw=", 7 ) == 0 ) {
162 data->bindpw = strdup( argv[ 2 ] + 7 );
163 if ( data->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->when = MAP_LDAP_NOW;
176 * Init LDAP handler ...
178 rc = ldap_initialize( &data->ld, data->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->mutex );
186 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
188 } else if ( strcasecmp( p, "later" ) == 0 ) {
189 data->when = MAP_LDAP_LATER;
191 #ifdef USE_REWRITE_LDAP_PVT_THREADS
192 ldap_pvt_thread_mutex_init( &data->mutex );
193 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
195 } else if ( strcasecmp( p, "everytime" ) == 0 ) {
196 data->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->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->when == MAP_LDAP_EVERYTIME ) {
233 rc = ldap_initialize( &ld, data->url );
235 #ifdef USE_REWRITE_LDAP_PVT_THREADS
236 ldap_pvt_thread_mutex_lock( &data->mutex );
237 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
241 if ( data->when == MAP_LDAP_LATER && data->ld == NULL ) {
242 rc = ldap_initialize( &data->ld, data->url );
248 if ( rc != LDAP_SUCCESS ) {
254 if ( data->binddn != NULL ) {
255 rc = ldap_simple_bind_s( ld, data->binddn, data->bindpw );
256 if ( rc == LDAP_SERVER_DOWN && first_try ) {
258 if ( ldap_initialize( &ld, data->url ) != LDAP_SUCCESS ) {
263 } else if ( rc != REWRITE_SUCCESS ) {
269 rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, ( char * )filter,
270 lud->lud_attrs, data->attrsonly, &res );
271 if ( rc == LDAP_SERVER_DOWN && first_try ) {
273 if ( ldap_initialize( &ld, data->url ) != LDAP_SUCCESS ) {
278 } else if ( rc != REWRITE_SUCCESS ) {
283 if ( ldap_count_entries( ld, res ) != 1 ) {
289 entry = ldap_first_entry( ld, res );
290 assert( entry != NULL );
292 if ( data->attrsonly == 1 ) {
294 * dn is newly allocated, so there's no need to strdup it
296 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->when == MAP_LDAP_EVERYTIME ) {
326 #ifdef USE_REWRITE_LDAP_PVT_THREADS
327 ldap_pvt_thread_mutex_unlock( &data->mutex );
328 #endif /* USE_REWRITE_LDAP_PVT_THREADS */