2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2011 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.
28 #define LDAP_DEPRECATED 1
29 #include "rewrite-int.h"
30 #include "rewrite-map.h"
35 #ifdef USE_REWRITE_LDAP_PVT_THREADS
36 ldap_pvt_thread_mutex_t xpasswd_mutex;
37 static int xpasswd_mutex_init = 0;
38 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
42 * NOTE: these are old-fashion maps; new maps will be parsed on separate
43 * config lines, and referred by name.
47 struct rewrite_info *info,
52 struct rewrite_map *map;
54 assert( info != NULL );
56 assert( currpos != NULL );
58 Debug( LDAP_DEBUG_ARGS, "rewrite_xmap_parse: %s\n%s%s",
63 map = calloc( sizeof( struct rewrite_map ), 1 );
65 Debug( LDAP_DEBUG_ANY, "rewrite_xmap_parse:"
66 " calloc failed\n%s%s%s", "", "", "" );
71 * Experimental passwd map:
72 * replaces the uid with the matching gecos from /etc/passwd file
74 if ( strncasecmp(s, "xpasswd", 7 ) == 0 ) {
75 map->lm_type = REWRITE_MAP_XPWDMAP;
76 map->lm_name = strdup( "xpasswd" );
77 if ( map->lm_name == NULL ) {
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 if ( filename == NULL ) {
134 AC_MEMCPY( filename, s + c, l );
135 filename[ l ] = '\0';
137 map->lm_args = ( void * )fopen( filename, "r" );
140 if ( map->lm_args == NULL ) {
147 #ifdef USE_REWRITE_LDAP_PVT_THREADS
148 if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
149 fclose( ( FILE * )map->lm_args );
153 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
158 * Experimental ldap map:
159 * looks up key on the fly (not implemented!)
161 } else if ( strncasecmp(s, "xldap", 5 ) == 0 ) {
168 if ( s[ c ] != '(' ) {
174 p = strchr( s, '}' );
184 * Add two bytes for urlencoding of '%s'
187 url = calloc( sizeof( char ), l + 3 );
192 AC_MEMCPY( url, s + c, l );
196 * Urlencodes the '%s' for ldap_url_parse
198 p = strchr( url, '%' );
200 AC_MEMCPY( p + 3, p + 1, strlen( p + 1 ) + 1 );
205 rc = ldap_url_parse( url, &lud );
208 if ( rc != LDAP_SUCCESS ) {
212 assert( lud != NULL );
214 map->lm_args = ( void * )lud;
215 map->lm_type = REWRITE_MAP_XLDAPMAP;
217 #ifdef USE_REWRITE_LDAP_PVT_THREADS
218 if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
219 ldap_free_urldesc( lud );
223 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
235 * Map key -> value resolution
236 * NOTE: these are old-fashion maps; new maps will be parsed on separate
237 * config lines, and referred by name.
241 struct rewrite_info *info,
242 struct rewrite_op *op,
243 struct rewrite_map *map,
248 int rc = REWRITE_SUCCESS;
250 assert( info != NULL );
251 assert( op != NULL );
252 assert( map != NULL );
253 assert( key != NULL );
254 assert( val != NULL );
259 switch ( map->lm_type ) {
261 case REWRITE_MAP_XPWDMAP: {
264 #ifdef USE_REWRITE_LDAP_PVT_THREADS
265 ldap_pvt_thread_mutex_lock( &xpasswd_mutex );
266 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
268 pwd = getpwnam( key->bv_val );
271 #ifdef USE_REWRITE_LDAP_PVT_THREADS
272 ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
273 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
275 rc = LDAP_NO_SUCH_OBJECT;
279 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
280 if ( pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0' ) {
281 int l = strlen( pwd->pw_gecos );
283 val->bv_val = strdup( pwd->pw_gecos );
286 #endif /* HAVE_STRUCT_PASSWD_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 */
296 if ( val->bv_val == NULL ) {
301 #endif /* HAVE_GETPWNAM*/
303 case REWRITE_MAP_XFILEMAP: {
306 if ( map->lm_args == NULL ) {
311 #ifdef USE_REWRITE_LDAP_PVT_THREADS
312 ldap_pvt_thread_mutex_lock( &map->lm_mutex );
313 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
315 rewind( ( FILE * )map->lm_args );
317 while ( fgets( buf, sizeof( buf ), ( FILE * )map->lm_args ) ) {
321 blen = strlen( buf );
322 if ( buf[ blen - 1 ] == '\n' ) {
323 buf[ blen - 1 ] = '\0';
326 p = strtok( buf, " " );
328 #ifdef USE_REWRITE_LDAP_PVT_THREADS
329 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
330 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
334 if ( strcasecmp( p, key->bv_val ) == 0
335 && ( p = strtok( NULL, "" ) ) ) {
336 val->bv_val = strdup( p );
337 if ( val->bv_val == NULL ) {
341 val->bv_len = strlen( p );
343 #ifdef USE_REWRITE_LDAP_PVT_THREADS
344 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
345 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
351 #ifdef USE_REWRITE_LDAP_PVT_THREADS
352 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
353 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
360 case REWRITE_MAP_XLDAPMAP: {
363 LDAPMessage *res = NULL, *entry;
364 LDAPURLDesc *lud = ( LDAPURLDesc * )map->lm_args;
368 assert( lud != NULL );
371 * No mutex because there is no write on the map data
374 ld = ldap_init( lud->lud_host, lud->lud_port );
380 snprintf( filter, sizeof( filter ), lud->lud_filter,
383 if ( strcasecmp( lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
386 rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope,
387 filter, lud->lud_attrs, attrsonly, &res );
388 if ( rc != LDAP_SUCCESS ) {
394 if ( ldap_count_entries( ld, res ) != 1 ) {
400 entry = ldap_first_entry( ld, res );
401 if ( entry == NULL ) {
407 if ( attrsonly == 1 ) {
408 val->bv_val = ldap_get_dn( ld, entry );
411 values = ldap_get_values( ld, entry,
413 if ( values != NULL ) {
414 val->bv_val = strdup( values[ 0 ] );
415 ldap_value_free( values );
422 if ( val->bv_val == NULL ) {
426 val->bv_len = strlen( val->bv_val );
428 rc = REWRITE_SUCCESS;
437 rewrite_xmap_destroy(
438 struct rewrite_map **pmap
441 struct rewrite_map *map;
443 assert( pmap != NULL );
444 assert( *pmap != NULL );
448 switch ( map->lm_type ) {
449 case REWRITE_MAP_XPWDMAP:
450 #ifdef USE_REWRITE_LDAP_PVT_THREADS
451 --xpasswd_mutex_init;
452 if ( !xpasswd_mutex_init ) {
453 ldap_pvt_thread_mutex_destroy( &xpasswd_mutex );
455 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
459 case REWRITE_MAP_XFILEMAP:
460 #ifdef USE_REWRITE_LDAP_PVT_THREADS
461 ldap_pvt_thread_mutex_lock( &map->lm_mutex );
462 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
464 if ( map->lm_args ) {
465 fclose( ( FILE * )map->lm_args );
469 #ifdef USE_REWRITE_LDAP_PVT_THREADS
470 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
471 ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
472 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
475 case REWRITE_MAP_XLDAPMAP:
476 #ifdef USE_REWRITE_LDAP_PVT_THREADS
477 ldap_pvt_thread_mutex_lock( &map->lm_mutex );
478 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
480 if ( map->lm_args ) {
481 ldap_free_urldesc( ( LDAPURLDesc * )map->lm_args );
485 #ifdef USE_REWRITE_LDAP_PVT_THREADS
486 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
487 ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
488 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
496 free( map->lm_name );