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 ******************************************************************************/
33 #include "rewrite-int.h"
34 #include "rewrite-map.h"
39 #ifdef USE_REWRITE_LDAP_PVT_THREADS
40 ldap_pvt_thread_mutex_t xpasswd_mutex;
41 static int xpasswd_mutex_init = 0;
42 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
46 * NOTE: these are old-fashion maps; new maps will be parsed on separate
47 * config lines, and referred by name.
51 struct rewrite_info *info,
56 struct rewrite_map *map;
58 assert( info != NULL );
60 assert( currpos != NULL );
62 Debug( LDAP_DEBUG_ARGS, "rewrite_xmap_parse: %s\n%s%s",
67 map = calloc( sizeof( struct rewrite_map ), 1 );
69 Debug( LDAP_DEBUG_ANY, "rewrite_xmap_parse:"
70 " calloc failed\n%s%s%s", "", "", "" );
75 * Experimental passwd map:
76 * replaces the uid with the matching gecos from /etc/passwd file
78 if ( strncasecmp(s, "xpasswd", 7 ) == 0 ) {
79 map->lm_type = REWRITE_MAP_XPWDMAP;
80 map->lm_name = strdup( "xpasswd" );
82 assert( s[7] == '}' );
85 #ifdef USE_REWRITE_LDAP_PVT_THREADS
86 if ( !xpasswd_mutex_init ) {
87 if ( ldap_pvt_thread_mutex_init( &xpasswd_mutex ) ) {
93 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
95 /* Don't really care if fails */
99 * Experimental file map:
100 * looks up key in a `key value' ascii file
102 } else if ( strncasecmp(s, "xfile", 5 ) == 0 ) {
108 map->lm_type = REWRITE_MAP_XFILEMAP;
110 if ( s[ c ] != '(' ) {
115 /* Must start with '/' for security concerns */
117 if ( s[ c ] != '/' ) {
122 for ( p = s + c; p[ 0 ] != '\0' && p[ 0 ] != ')'; p++ );
123 if ( p[ 0 ] != ')' ) {
129 filename = calloc( sizeof( char ), l + 1 );
130 AC_MEMCPY( filename, s + c, l );
131 filename[ l ] = '\0';
133 map->lm_args = ( void * )fopen( filename, "r" );
136 if ( map->lm_args == NULL ) {
143 #ifdef USE_REWRITE_LDAP_PVT_THREADS
144 if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
145 fclose( ( FILE * )map->lm_args );
149 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
154 * Experimental ldap map:
155 * looks up key on the fly (not implemented!)
157 } else if ( strncasecmp(s, "xldap", 5 ) == 0 ) {
164 if ( s[ c ] != '(' ) {
170 p = strchr( s, '}' );
180 * Add two bytes for urlencoding of '%s'
183 url = calloc( sizeof( char ), l + 3 );
184 AC_MEMCPY( url, s + c, l );
188 * Urlencodes the '%s' for ldap_url_parse
190 p = strchr( url, '%' );
192 AC_MEMCPY( p + 3, p + 1, strlen( p + 1 ) + 1 );
197 rc = ldap_url_parse( url, &lud );
200 if ( rc != LDAP_SUCCESS ) {
204 assert( lud != NULL );
206 map->lm_args = ( void * )lud;
207 map->lm_type = REWRITE_MAP_XLDAPMAP;
209 #ifdef USE_REWRITE_LDAP_PVT_THREADS
210 if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
211 ldap_free_urldesc( lud );
215 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
226 * Map key -> value resolution
227 * NOTE: these are old-fashion maps; new maps will be parsed on separate
228 * config lines, and referred by name.
232 struct rewrite_info *info,
233 struct rewrite_op *op,
234 struct rewrite_map *map,
239 int rc = REWRITE_SUCCESS;
241 assert( info != NULL );
242 assert( op != NULL );
243 assert( map != NULL );
244 assert( key != NULL );
245 assert( val != NULL );
250 switch ( map->lm_type ) {
252 case REWRITE_MAP_XPWDMAP: {
255 #ifdef USE_REWRITE_LDAP_PVT_THREADS
256 ldap_pvt_thread_mutex_lock( &xpasswd_mutex );
257 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
259 pwd = getpwnam( key->bv_val );
262 #ifdef USE_REWRITE_LDAP_PVT_THREADS
263 ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
264 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
266 rc = REWRITE_NO_SUCH_OBJECT;
271 if ( pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0' ) {
272 int l = strlen( pwd->pw_gecos );
274 val->bv_val = strdup( pwd->pw_gecos );
275 if ( val->bv_val == NULL ) {
277 #ifdef USE_REWRITE_LDAP_PVT_THREADS
278 ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
279 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
286 #endif /* HAVE_PW_GECOS */
288 val->bv_val = strdup( key->bv_val );
289 val->bv_len = key->bv_len;
292 #ifdef USE_REWRITE_LDAP_PVT_THREADS
293 ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
294 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
298 #endif /* HAVE_GETPWNAM*/
300 case REWRITE_MAP_XFILEMAP: {
303 if ( map->lm_args == NULL ) {
308 #ifdef USE_REWRITE_LDAP_PVT_THREADS
309 ldap_pvt_thread_mutex_lock( &map->lm_mutex );
310 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
312 rewind( ( FILE * )map->lm_args );
314 while ( fgets( buf, sizeof( buf ), ( FILE * )map->lm_args ) ) {
318 blen = strlen( buf );
319 if ( buf[ blen - 1 ] == '\n' ) {
320 buf[ blen - 1 ] = '\0';
323 p = strtok( buf, " " );
325 #ifdef USE_REWRITE_LDAP_PVT_THREADS
326 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
327 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
331 if ( strcasecmp( p, key->bv_val ) == 0
332 && ( p = strtok( NULL, "" ) ) ) {
333 val->bv_val = strdup( p );
334 if ( val->bv_val == NULL ) {
338 val->bv_len = strlen( p );
340 #ifdef USE_REWRITE_LDAP_PVT_THREADS
341 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
342 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
348 #ifdef USE_REWRITE_LDAP_PVT_THREADS
349 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
350 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
357 case REWRITE_MAP_XLDAPMAP: {
360 LDAPMessage *res = NULL, *entry;
361 LDAPURLDesc *lud = ( LDAPURLDesc * )map->lm_args;
365 assert( lud != NULL );
368 * No mutex because there is no write on the map data
371 ld = ldap_init( lud->lud_host, lud->lud_port );
377 snprintf( filter, sizeof( filter ), lud->lud_filter,
380 if ( strcasecmp( lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
383 rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope,
384 filter, lud->lud_attrs, attrsonly, &res );
385 if ( rc != LDAP_SUCCESS ) {
391 if ( ldap_count_entries( ld, res ) != 1 ) {
397 entry = ldap_first_entry( ld, res );
398 if ( entry == NULL ) {
404 if ( attrsonly == 1 ) {
405 val->bv_val = ldap_get_dn( ld, entry );
406 if ( val->bv_val == NULL ) {
413 values = ldap_get_values( ld, entry,
415 if ( values == NULL ) {
421 val->bv_val = strdup( values[ 0 ] );
422 ldap_value_free( values );
424 val->bv_len = strlen( val->bv_val );
429 rc = REWRITE_SUCCESS;
438 rewrite_xmap_destroy(
439 struct rewrite_map **pmap
442 struct rewrite_map *map;
449 switch ( map->lm_type ) {
450 case REWRITE_MAP_XPWDMAP:
451 #ifdef USE_REWRITE_LDAP_PVT_THREADS
452 --xpasswd_mutex_init;
453 if ( !xpasswd_mutex_init ) {
454 ldap_pvt_thread_mutex_destroy( &xpasswd_mutex );
456 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
460 case REWRITE_MAP_XFILEMAP:
461 #ifdef USE_REWRITE_LDAP_PVT_THREADS
462 ldap_pvt_thread_mutex_lock( &map->lm_mutex );
463 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
465 if ( map->lm_args ) {
466 fclose( ( FILE * )map->lm_args );
470 #ifdef USE_REWRITE_LDAP_PVT_THREADS
471 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
472 ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
473 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
476 case REWRITE_MAP_XLDAPMAP:
477 #ifdef USE_REWRITE_LDAP_PVT_THREADS
478 ldap_pvt_thread_mutex_lock( &map->lm_mutex );
479 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
481 if ( map->lm_args ) {
482 ldap_free_urldesc( ( LDAPURLDesc * )map->lm_args );
486 #ifdef USE_REWRITE_LDAP_PVT_THREADS
487 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
488 ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
489 #endif /* USE_REWRITE_LDAP_PVT_THREADS */