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 <ac/string.h>
29 #include "rewrite-int.h"
30 #include "rewrite-map.h"
33 * LDAP map data structure
35 struct ldap_map_data {
42 #define MAP_LDAP_EVERYTIME 0x00
43 #define MAP_LDAP_NOW 0x01
44 #define MAP_LDAP_LATER 0x02
49 #ifdef USE_REWRITE_LDAP_PVT_THREADS
50 ldap_pvt_thread_mutex_t mutex;
51 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
56 struct ldap_map_data *data
59 assert( data != NULL );
61 if ( data->url != NULL ) {
65 if ( data->lud != NULL ) {
66 ldap_free_urldesc( data->lud );
69 if ( data->binddn != NULL ) {
73 if ( data->bindpw != NULL ) {
77 if ( data->when != MAP_LDAP_EVERYTIME && data->ld != NULL ) {
78 ldap_unbind_s( data->ld );
86 struct rewrite_info *info,
93 struct ldap_map_data *data;
96 assert( info != NULL );
97 assert( fname != NULL );
98 assert( argv != NULL );
100 data = calloc( sizeof( struct ldap_map_data ), 1 );
101 if ( data == NULL ) {
106 Debug( LDAP_DEBUG_ANY,
107 "[%s:%d] ldap map needs URI\n%s",
113 data->url = strdup( argv[ 0 ] );
114 if ( data->url == NULL ) {
115 map_ldap_free( data );
119 if ( ldap_url_parse( argv[ 0 ], &data->lud ) != REWRITE_SUCCESS ) {
120 Debug( LDAP_DEBUG_ANY,
121 "[%s:%d] illegal URI '%s'\n",
122 fname, lineno, argv[ 0 ] );
123 map_ldap_free( data );
127 p = strchr( data->url, '/' );
128 assert( p[ 1 ] == '/' );
129 if ( ( p = strchr( p + 2, '/' ) ) != NULL ) {
133 if ( strcasecmp( data->lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
137 for ( argc--, argv++; argc > 0; argc--, argv++ ) {
138 if ( strncasecmp( argv[ 0 ], "binddn=", 7 ) == 0 ) {
139 char *p = argv[ 0 ] + 7;
142 if ( p[ 0 ] == '\"' || p [ 0 ] == '\'' ) {
145 if ( p[ l ] != p[ 0 ] ) {
146 map_ldap_free( data );
153 data->binddn = strdup( p );
154 if ( data->binddn == NULL ) {
155 map_ldap_free( data );
159 if ( data->binddn[ l ] == '\"'
160 || data->binddn[ l ] == '\'' ) {
161 data->binddn[ l ] = '\0';
163 } else if ( strncasecmp( argv[ 0 ], "bindpw=", 7 ) == 0 ) {
164 data->bindpw = strdup( argv[ 2 ] + 7 );
165 if ( data->bindpw == NULL ) {
166 map_ldap_free( data );
169 } else if ( strncasecmp( argv[ 0 ], "bindwhen=", 9 ) == 0 ) {
170 char *p = argv[ 0 ] + 9;
172 if ( strcasecmp( p, "now" ) == 0 ) {
175 data->when = MAP_LDAP_NOW;
178 * Init LDAP handler ...
180 rc = ldap_initialize( &data->ld, data->url );
181 if ( rc != LDAP_SUCCESS ) {
182 map_ldap_free( data );
186 #ifdef USE_REWRITE_LDAP_PVT_THREADS
187 ldap_pvt_thread_mutex_init( &data->mutex );
188 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
190 } else if ( strcasecmp( p, "later" ) == 0 ) {
191 data->when = MAP_LDAP_LATER;
193 #ifdef USE_REWRITE_LDAP_PVT_THREADS
194 ldap_pvt_thread_mutex_init( &data->mutex );
195 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
197 } else if ( strcasecmp( p, "everytime" ) == 0 ) {
198 data->when = MAP_LDAP_EVERYTIME;
205 return ( void * )data;
210 struct rewrite_builtin_map *map,
217 LDAPMessage *res = NULL, *entry;
220 struct ldap_map_data *data = ( struct ldap_map_data * )map->lb_private;
221 LDAPURLDesc *lud = data->lud;
225 assert( map != NULL );
226 assert( map->lb_type == REWRITE_BUILTIN_MAP_LDAP );
227 assert( map->lb_private != NULL );
228 assert( filter != NULL );
229 assert( val != NULL );
234 if ( data->when == MAP_LDAP_EVERYTIME ) {
235 rc = ldap_initialize( &ld, data->url );
237 #ifdef USE_REWRITE_LDAP_PVT_THREADS
238 ldap_pvt_thread_mutex_lock( &data->mutex );
239 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
243 if ( data->when == MAP_LDAP_LATER && data->ld == NULL ) {
244 rc = ldap_initialize( &data->ld, data->url );
250 if ( rc != LDAP_SUCCESS ) {
256 if ( data->binddn != NULL ) {
257 rc = ldap_simple_bind_s( ld, data->binddn, data->bindpw );
258 if ( rc == LDAP_SERVER_DOWN && first_try ) {
260 if ( ldap_initialize( &ld, data->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->attrsonly, &res );
273 if ( rc == LDAP_SERVER_DOWN && first_try ) {
275 if ( ldap_initialize( &ld, data->url ) != LDAP_SUCCESS ) {
280 } else if ( rc != REWRITE_SUCCESS ) {
285 if ( ldap_count_entries( ld, res ) != 1 ) {
291 entry = ldap_first_entry( ld, res );
292 assert( entry != NULL );
294 if ( data->attrsonly == 1 ) {
296 * dn is newly allocated, so there's no need to strdup it
298 val->bv_val = ldap_get_dn( ld, entry );
300 values = ldap_get_values( ld, entry, lud->lud_attrs[ 0 ] );
301 if ( values == NULL || values[ 0 ] == NULL ) {
302 if ( values != NULL ) {
303 ldap_value_free( values );
309 val->bv_val = strdup( values[ 0 ] );
310 ldap_value_free( values );
315 if ( val->bv_val == NULL ) {
319 val->bv_len = strlen( val->bv_val );
322 if ( data->when == MAP_LDAP_EVERYTIME ) {
328 #ifdef USE_REWRITE_LDAP_PVT_THREADS
329 ldap_pvt_thread_mutex_unlock( &data->mutex );
330 #endif /* USE_REWRITE_LDAP_PVT_THREADS */