1 /* $OpenLDAP: pkg/ldap/libraries/librewrite/xmap.c,v 1.12.2.3 2008/02/11 23:26:43 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2008 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" );
78 assert( s
[7] == '}' );
81 #ifdef USE_REWRITE_LDAP_PVT_THREADS
82 if ( !xpasswd_mutex_init
) {
83 if ( ldap_pvt_thread_mutex_init( &xpasswd_mutex
) ) {
89 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
91 /* Don't really care if fails */
95 * Experimental file map:
96 * looks up key in a `key value' ascii file
98 } else if ( strncasecmp( s
, "xfile", 5 ) == 0 ) {
104 map
->lm_type
= REWRITE_MAP_XFILEMAP
;
106 if ( s
[ c
] != '(' ) {
111 /* Must start with '/' for security concerns */
113 if ( s
[ c
] != '/' ) {
118 for ( p
= s
+ c
; p
[ 0 ] != '\0' && p
[ 0 ] != ')'; p
++ );
119 if ( p
[ 0 ] != ')' ) {
125 filename
= calloc( sizeof( char ), l
+ 1 );
126 AC_MEMCPY( filename
, s
+ c
, l
);
127 filename
[ l
] = '\0';
129 map
->lm_args
= ( void * )fopen( filename
, "r" );
132 if ( map
->lm_args
== NULL
) {
139 #ifdef USE_REWRITE_LDAP_PVT_THREADS
140 if ( ldap_pvt_thread_mutex_init( &map
->lm_mutex
) ) {
141 fclose( ( FILE * )map
->lm_args
);
145 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
150 * Experimental ldap map:
151 * looks up key on the fly (not implemented!)
153 } else if ( strncasecmp(s
, "xldap", 5 ) == 0 ) {
160 if ( s
[ c
] != '(' ) {
166 p
= strchr( s
, '}' );
176 * Add two bytes for urlencoding of '%s'
179 url
= calloc( sizeof( char ), l
+ 3 );
180 AC_MEMCPY( url
, s
+ c
, l
);
184 * Urlencodes the '%s' for ldap_url_parse
186 p
= strchr( url
, '%' );
188 AC_MEMCPY( p
+ 3, p
+ 1, strlen( p
+ 1 ) + 1 );
193 rc
= ldap_url_parse( url
, &lud
);
196 if ( rc
!= LDAP_SUCCESS
) {
200 assert( lud
!= NULL
);
202 map
->lm_args
= ( void * )lud
;
203 map
->lm_type
= REWRITE_MAP_XLDAPMAP
;
205 #ifdef USE_REWRITE_LDAP_PVT_THREADS
206 if ( ldap_pvt_thread_mutex_init( &map
->lm_mutex
) ) {
207 ldap_free_urldesc( lud
);
211 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
223 * Map key -> value resolution
224 * NOTE: these are old-fashion maps; new maps will be parsed on separate
225 * config lines, and referred by name.
229 struct rewrite_info
*info
,
230 struct rewrite_op
*op
,
231 struct rewrite_map
*map
,
236 int rc
= REWRITE_SUCCESS
;
238 assert( info
!= NULL
);
239 assert( op
!= NULL
);
240 assert( map
!= NULL
);
241 assert( key
!= NULL
);
242 assert( val
!= NULL
);
247 switch ( map
->lm_type
) {
249 case REWRITE_MAP_XPWDMAP
: {
252 #ifdef USE_REWRITE_LDAP_PVT_THREADS
253 ldap_pvt_thread_mutex_lock( &xpasswd_mutex
);
254 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
256 pwd
= getpwnam( key
->bv_val
);
259 #ifdef USE_REWRITE_LDAP_PVT_THREADS
260 ldap_pvt_thread_mutex_unlock( &xpasswd_mutex
);
261 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
263 rc
= LDAP_NO_SUCH_OBJECT
;
267 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
268 if ( pwd
->pw_gecos
!= NULL
&& pwd
->pw_gecos
[0] != '\0' ) {
269 int l
= strlen( pwd
->pw_gecos
);
271 val
->bv_val
= strdup( pwd
->pw_gecos
);
272 if ( val
->bv_val
== NULL
) {
274 #ifdef USE_REWRITE_LDAP_PVT_THREADS
275 ldap_pvt_thread_mutex_unlock( &xpasswd_mutex
);
276 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
283 #endif /* HAVE_STRUCT_PASSWD_PW_GECOS */
285 val
->bv_val
= strdup( key
->bv_val
);
286 val
->bv_len
= key
->bv_len
;
289 #ifdef USE_REWRITE_LDAP_PVT_THREADS
290 ldap_pvt_thread_mutex_unlock( &xpasswd_mutex
);
291 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
295 #endif /* HAVE_GETPWNAM*/
297 case REWRITE_MAP_XFILEMAP
: {
300 if ( map
->lm_args
== NULL
) {
305 #ifdef USE_REWRITE_LDAP_PVT_THREADS
306 ldap_pvt_thread_mutex_lock( &map
->lm_mutex
);
307 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
309 rewind( ( FILE * )map
->lm_args
);
311 while ( fgets( buf
, sizeof( buf
), ( FILE * )map
->lm_args
) ) {
315 blen
= strlen( buf
);
316 if ( buf
[ blen
- 1 ] == '\n' ) {
317 buf
[ blen
- 1 ] = '\0';
320 p
= strtok( buf
, " " );
322 #ifdef USE_REWRITE_LDAP_PVT_THREADS
323 ldap_pvt_thread_mutex_unlock( &map
->lm_mutex
);
324 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
328 if ( strcasecmp( p
, key
->bv_val
) == 0
329 && ( p
= strtok( NULL
, "" ) ) ) {
330 val
->bv_val
= strdup( p
);
331 if ( val
->bv_val
== NULL
) {
335 val
->bv_len
= strlen( p
);
337 #ifdef USE_REWRITE_LDAP_PVT_THREADS
338 ldap_pvt_thread_mutex_unlock( &map
->lm_mutex
);
339 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
345 #ifdef USE_REWRITE_LDAP_PVT_THREADS
346 ldap_pvt_thread_mutex_unlock( &map
->lm_mutex
);
347 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
354 case REWRITE_MAP_XLDAPMAP
: {
357 LDAPMessage
*res
= NULL
, *entry
;
358 LDAPURLDesc
*lud
= ( LDAPURLDesc
* )map
->lm_args
;
362 assert( lud
!= NULL
);
365 * No mutex because there is no write on the map data
368 ld
= ldap_init( lud
->lud_host
, lud
->lud_port
);
374 snprintf( filter
, sizeof( filter
), lud
->lud_filter
,
377 if ( strcasecmp( lud
->lud_attrs
[ 0 ], "dn" ) == 0 ) {
380 rc
= ldap_search_s( ld
, lud
->lud_dn
, lud
->lud_scope
,
381 filter
, lud
->lud_attrs
, attrsonly
, &res
);
382 if ( rc
!= LDAP_SUCCESS
) {
388 if ( ldap_count_entries( ld
, res
) != 1 ) {
394 entry
= ldap_first_entry( ld
, res
);
395 if ( entry
== NULL
) {
401 if ( attrsonly
== 1 ) {
402 val
->bv_val
= ldap_get_dn( ld
, entry
);
403 if ( val
->bv_val
== NULL
) {
410 values
= ldap_get_values( ld
, entry
,
412 if ( values
== NULL
) {
418 val
->bv_val
= strdup( values
[ 0 ] );
419 ldap_value_free( values
);
421 val
->bv_len
= strlen( val
->bv_val
);
426 rc
= REWRITE_SUCCESS
;
435 rewrite_xmap_destroy(
436 struct rewrite_map
**pmap
439 struct rewrite_map
*map
;
441 assert( pmap
!= NULL
);
442 assert( *pmap
!= NULL
);
446 switch ( map
->lm_type
) {
447 case REWRITE_MAP_XPWDMAP
:
448 #ifdef USE_REWRITE_LDAP_PVT_THREADS
449 --xpasswd_mutex_init
;
450 if ( !xpasswd_mutex_init
) {
451 ldap_pvt_thread_mutex_destroy( &xpasswd_mutex
);
453 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
457 case REWRITE_MAP_XFILEMAP
:
458 #ifdef USE_REWRITE_LDAP_PVT_THREADS
459 ldap_pvt_thread_mutex_lock( &map
->lm_mutex
);
460 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
462 if ( map
->lm_args
) {
463 fclose( ( FILE * )map
->lm_args
);
467 #ifdef USE_REWRITE_LDAP_PVT_THREADS
468 ldap_pvt_thread_mutex_unlock( &map
->lm_mutex
);
469 ldap_pvt_thread_mutex_destroy( &map
->lm_mutex
);
470 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
473 case REWRITE_MAP_XLDAPMAP
:
474 #ifdef USE_REWRITE_LDAP_PVT_THREADS
475 ldap_pvt_thread_mutex_lock( &map
->lm_mutex
);
476 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
478 if ( map
->lm_args
) {
479 ldap_free_urldesc( ( LDAPURLDesc
* )map
->lm_args
);
483 #ifdef USE_REWRITE_LDAP_PVT_THREADS
484 ldap_pvt_thread_mutex_unlock( &map
->lm_mutex
);
485 ldap_pvt_thread_mutex_destroy( &map
->lm_mutex
);
486 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
494 free( map
->lm_name
);