2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2006 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 #include "rewrite-int.h"
29 #include "rewrite-map.h"
33 struct rewrite_info *info,
38 struct rewrite_map *map = NULL;
39 struct rewrite_subst *subst = NULL;
40 char *s, *begin = NULL, *end;
42 int l, cnt, mtx = 0, rc = 0;
44 assert( info != NULL );
45 assert( string != NULL );
46 assert( currpos != NULL );
51 * Go to the end of the map invocation (the right closing brace)
53 for ( p = string, cnt = 1; p[ 0 ] != '\0' && cnt > 0; p++ ) {
54 if ( IS_REWRITE_SUBMATCH_ESCAPE( p[ 0 ] ) ) {
56 * '%' marks the beginning of a new map
58 if ( p[ 1 ] == '{' ) {
61 * '%' followed by a digit may mark the beginning
64 } else if ( isdigit( (unsigned char) p[ 1 ] ) && p[ 2 ] == '{' ) {
69 if ( p[ 1 ] != '\0' ) {
73 } else if ( p[ 0 ] == '}' ) {
83 * Copy the map invocation
86 s = calloc( sizeof( char ), l + 1 );
87 AC_MEMCPY( s, string, l );
91 * Isolate the map name (except for variable deref)
94 case REWRITE_OPERATOR_VARIABLE_GET:
95 case REWRITE_OPERATOR_PARAM_GET:
99 begin = strchr( s, '(' );
100 if ( begin == NULL ) {
110 * Check for special map types
114 case REWRITE_OPERATOR_SUBCONTEXT:
115 case REWRITE_OPERATOR_COMMAND:
116 case REWRITE_OPERATOR_VARIABLE_SET:
117 case REWRITE_OPERATOR_VARIABLE_GET:
118 case REWRITE_OPERATOR_PARAM_GET:
124 * Variable set and get may be repeated to indicate session-wide
125 * instead of operation-wide variables
128 case REWRITE_OPERATOR_VARIABLE_SET:
129 case REWRITE_OPERATOR_VARIABLE_GET:
135 * Variable get token can be appended to variable set to mean store
138 if ( p[ 0 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
143 * Check the syntax of the variable name
145 if ( !isalpha( (unsigned char) p[ 0 ] ) ) {
149 for ( p++; p[ 0 ] != '\0'; p++ ) {
150 if ( !isalnum( (unsigned char) p[ 0 ] ) ) {
157 * Isolate the argument of the map (except for variable deref)
160 case REWRITE_OPERATOR_VARIABLE_GET:
161 case REWRITE_OPERATOR_PARAM_GET:
165 end = strrchr( begin, ')' );
173 * Compile the substitution pattern of the map argument
175 subst = rewrite_subst_compile( info, begin );
176 if ( subst == NULL ) {
186 map = calloc( sizeof( struct rewrite_map ), 1 );
191 memset( map, 0, sizeof( struct rewrite_map ) );
193 #ifdef USE_REWRITE_LDAP_PVT_THREADS
194 if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
199 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
202 * No subst for variable deref
205 case REWRITE_OPERATOR_VARIABLE_GET:
206 case REWRITE_OPERATOR_PARAM_GET:
210 map->lm_subst = subst;
215 * Parses special map types
222 case REWRITE_OPERATOR_SUBCONTEXT: /* '>' */
225 * Fetch the rewrite context
226 * it MUST have been defined previously
228 map->lm_type = REWRITE_MAP_SUBCONTEXT;
229 map->lm_name = strdup( s + 1 );
230 map->lm_data = rewrite_context_find( info, s + 1 );
231 if ( map->lm_data == NULL ) {
238 * External command (not implemented yet)
240 case REWRITE_OPERATOR_COMMAND: /* '|' */
247 case REWRITE_OPERATOR_VARIABLE_SET: /* '&' */
248 if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_SET ) {
249 if ( s[ 2 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
250 map->lm_type = REWRITE_MAP_SETW_SESN_VAR;
251 map->lm_name = strdup( s + 3 );
253 map->lm_type = REWRITE_MAP_SET_SESN_VAR;
254 map->lm_name = strdup( s + 2 );
257 if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
258 map->lm_type = REWRITE_MAP_SETW_OP_VAR;
259 map->lm_name = strdup( s + 2 );
261 map->lm_type = REWRITE_MAP_SET_OP_VAR;
262 map->lm_name = strdup( s + 1 );
268 * Variable dereference
270 case REWRITE_OPERATOR_VARIABLE_GET: /* '*' */
271 if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
272 map->lm_type = REWRITE_MAP_GET_SESN_VAR;
273 map->lm_name = strdup( s + 2 );
275 map->lm_type = REWRITE_MAP_GET_OP_VAR;
276 map->lm_name = strdup( s + 1 );
283 case REWRITE_OPERATOR_PARAM_GET: /* '$' */
284 map->lm_type = REWRITE_MAP_GET_PARAM;
285 map->lm_name = strdup( s + 1 );
292 map->lm_type = REWRITE_MAP_BUILTIN;
293 map->lm_name = strdup( s );
294 map->lm_data = rewrite_builtin_map_find( info, s );
295 if ( map->lm_data == NULL ) {
306 if ( subst != NULL ) {
310 #ifdef USE_REWRITE_LDAP_PVT_THREADS
312 ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
314 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
316 if ( map->lm_name ) {
317 free( map->lm_name );
329 * Applies the new map type
333 struct rewrite_info *info,
334 struct rewrite_op *op,
335 struct rewrite_map *map,
340 int rc = REWRITE_SUCCESS;
342 assert( info != NULL );
343 assert( op != NULL );
344 assert( map != NULL );
345 assert( key != NULL );
346 assert( val != NULL );
351 switch ( map->lm_type ) {
352 case REWRITE_MAP_SUBCONTEXT:
353 rc = rewrite_context_apply( info, op,
354 ( struct rewrite_context * )map->lm_data,
355 key->bv_val, &val->bv_val );
356 if ( val->bv_val != NULL ) {
357 if ( val->bv_val = key->bv_val ) {
358 val->bv_len = key->bv_len;
361 val->bv_len = strlen( val->bv_val );
366 case REWRITE_MAP_SET_OP_VAR:
367 case REWRITE_MAP_SETW_OP_VAR:
368 rc = rewrite_var_set( &op->lo_vars, map->lm_name,
370 ? REWRITE_SUCCESS : REWRITE_ERR;
371 if ( map->lm_type == REWRITE_MAP_SET_OP_VAR ) {
372 val->bv_val = strdup( "" );
374 val->bv_val = strdup( key->bv_val );
375 val->bv_len = key->bv_len;
379 case REWRITE_MAP_GET_OP_VAR: {
380 struct rewrite_var *var;
382 var = rewrite_var_find( op->lo_vars, map->lm_name );
386 val->bv_val = strdup( var->lv_value.bv_val );
387 val->bv_len = var->lv_value.bv_len;
392 case REWRITE_MAP_SET_SESN_VAR:
393 case REWRITE_MAP_SETW_SESN_VAR:
394 if ( op->lo_cookie == NULL ) {
398 rc = rewrite_session_var_set( info, op->lo_cookie,
399 map->lm_name, key->bv_val );
400 if ( map->lm_type == REWRITE_MAP_SET_SESN_VAR ) {
401 val->bv_val = strdup( "" );
403 val->bv_val = strdup( key->bv_val );
404 val->bv_len = key->bv_len;
408 case REWRITE_MAP_GET_SESN_VAR:
409 rc = rewrite_session_var_get( info, op->lo_cookie,
413 case REWRITE_MAP_GET_PARAM:
414 rc = rewrite_param_get( info, map->lm_name, val );
417 case REWRITE_MAP_BUILTIN: {
418 struct rewrite_builtin_map *bmap = map->lm_data;
420 switch ( bmap->lb_type ) {
421 case REWRITE_BUILTIN_MAP_LDAP:
422 rc = map_ldap_apply( bmap, key->bv_val, val );
440 rewrite_builtin_map_free(
444 struct rewrite_builtin_map *map = ( struct rewrite_builtin_map * )tmp;
446 assert( map != NULL );
448 switch ( map->lb_type ) {
449 case REWRITE_BUILTIN_MAP_LDAP:
450 map_ldap_destroy( &map );
458 free( map->lb_name );
464 struct rewrite_map **pmap
467 struct rewrite_map *map;
469 assert( pmap != NULL );
470 assert( *pmap != NULL );
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_name ) {
479 free( map->lm_name );
483 if ( map->lm_subst ) {
484 rewrite_subst_destroy( &map->lm_subst );
487 #ifdef USE_REWRITE_LDAP_PVT_THREADS
488 ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
489 ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
490 #endif /* USE_REWRITE_LDAP_PVT_THREADS */