1
/* $OpenLDAP: pkg/ldap/libraries/librewrite/map.c,v 1.21.2.6 2009/01/22 00:00:58 kurt Exp $ */
2
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
* Copyright 2000-2009 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"
31
static int num_mappers;
32
static const rewrite_mapper **mappers;
33
#define MAPPER_ALLOC 8
37
struct rewrite_info *info,
42
struct rewrite_map *map = NULL;
43
struct rewrite_subst *subst = NULL;
44
char *s, *begin = NULL, *end;
46
int l, cnt, mtx = 0, rc = 0;
48
assert( info != NULL );
49
assert( string != NULL );
50
assert( currpos != NULL );
55
* Go to the end of the map invocation (the right closing brace)
57
for ( p = string, cnt = 1; p[ 0 ] != '\0' && cnt > 0; p++ ) {
58
if ( IS_REWRITE_SUBMATCH_ESCAPE( p[ 0 ] ) ) {
60
* '%' marks the beginning of a new map
62
if ( p[ 1 ] == '{' ) {
65
* '%' followed by a digit may mark the beginning
68
} else if ( isdigit( (unsigned char) p[ 1 ] ) && p[ 2 ] == '{' ) {
73
if ( p[ 1 ] != '\0' ) {
77
} else if ( p[ 0 ] == '}' ) {
87
* Copy the map invocation
90
s = calloc( sizeof( char ), l + 1 );
94
AC_MEMCPY( s, string, l );
98
* Isolate the map name (except for variable deref)
101
case REWRITE_OPERATOR_VARIABLE_GET:
102
case REWRITE_OPERATOR_PARAM_GET:
106
begin = strchr( s, '(' );
107
if ( begin == NULL ) {
117
* Check for special map types
121
case REWRITE_OPERATOR_SUBCONTEXT:
122
case REWRITE_OPERATOR_COMMAND:
123
case REWRITE_OPERATOR_VARIABLE_SET:
124
case REWRITE_OPERATOR_VARIABLE_GET:
125
case REWRITE_OPERATOR_PARAM_GET:
131
* Variable set and get may be repeated to indicate session-wide
132
* instead of operation-wide variables
135
case REWRITE_OPERATOR_VARIABLE_SET:
136
case REWRITE_OPERATOR_VARIABLE_GET:
142
* Variable get token can be appended to variable set to mean store
145
if ( p[ 0 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
150
* Check the syntax of the variable name
152
if ( !isalpha( (unsigned char) p[ 0 ] ) ) {
156
for ( p++; p[ 0 ] != '\0'; p++ ) {
157
if ( !isalnum( (unsigned char) p[ 0 ] ) ) {
164
* Isolate the argument of the map (except for variable deref)
167
case REWRITE_OPERATOR_VARIABLE_GET:
168
case REWRITE_OPERATOR_PARAM_GET:
172
end = strrchr( begin, ')' );
180
* Compile the substitution pattern of the map argument
182
subst = rewrite_subst_compile( info, begin );
183
if ( subst == NULL ) {
193
map = calloc( sizeof( struct rewrite_map ), 1 );
198
memset( map, 0, sizeof( struct rewrite_map ) );
200
#ifdef USE_REWRITE_LDAP_PVT_THREADS
201
if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
206
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
209
* No subst for variable deref
212
case REWRITE_OPERATOR_VARIABLE_GET:
213
case REWRITE_OPERATOR_PARAM_GET:
217
map->lm_subst = subst;
222
* Parses special map types
229
case REWRITE_OPERATOR_SUBCONTEXT: /* '>' */
232
* Fetch the rewrite context
233
* it MUST have been defined previously
235
map->lm_type = REWRITE_MAP_SUBCONTEXT;
236
map->lm_name = strdup( s + 1 );
237
if ( map->lm_name == NULL ) {
241
map->lm_data = rewrite_context_find( info, s + 1 );
242
if ( map->lm_data == NULL ) {
249
* External command (not implemented yet)
251
case REWRITE_OPERATOR_COMMAND: /* '|' */
258
case REWRITE_OPERATOR_VARIABLE_SET: /* '&' */
259
if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_SET ) {
260
if ( s[ 2 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
261
map->lm_type = REWRITE_MAP_SETW_SESN_VAR;
262
map->lm_name = strdup( s + 3 );
264
map->lm_type = REWRITE_MAP_SET_SESN_VAR;
265
map->lm_name = strdup( s + 2 );
268
if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
269
map->lm_type = REWRITE_MAP_SETW_OP_VAR;
270
map->lm_name = strdup( s + 2 );
272
map->lm_type = REWRITE_MAP_SET_OP_VAR;
273
map->lm_name = strdup( s + 1 );
276
if ( map->lm_name == NULL ) {
283
* Variable dereference
285
case REWRITE_OPERATOR_VARIABLE_GET: /* '*' */
286
if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
287
map->lm_type = REWRITE_MAP_GET_SESN_VAR;
288
map->lm_name = strdup( s + 2 );
290
map->lm_type = REWRITE_MAP_GET_OP_VAR;
291
map->lm_name = strdup( s + 1 );
293
if ( map->lm_name == NULL ) {
302
case REWRITE_OPERATOR_PARAM_GET: /* '$' */
303
map->lm_type = REWRITE_MAP_GET_PARAM;
304
map->lm_name = strdup( s + 1 );
305
if ( map->lm_name == NULL ) {
315
map->lm_type = REWRITE_MAP_BUILTIN;
316
map->lm_name = strdup( s );
317
if ( map->lm_name == NULL ) {
321
map->lm_data = rewrite_builtin_map_find( info, s );
322
if ( map->lm_data == NULL ) {
333
if ( subst != NULL ) {
337
#ifdef USE_REWRITE_LDAP_PVT_THREADS
339
ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
341
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
343
if ( map->lm_name ) {
344
free( map->lm_name );
356
* Applies the new map type
360
struct rewrite_info *info,
361
struct rewrite_op *op,
362
struct rewrite_map *map,
367
int rc = REWRITE_SUCCESS;
369
assert( info != NULL );
370
assert( op != NULL );
371
assert( map != NULL );
372
assert( key != NULL );
373
assert( val != NULL );
378
switch ( map->lm_type ) {
379
case REWRITE_MAP_SUBCONTEXT:
380
rc = rewrite_context_apply( info, op,
381
( struct rewrite_context * )map->lm_data,
382
key->bv_val, &val->bv_val );
383
if ( val->bv_val != NULL ) {
384
if ( val->bv_val == key->bv_val ) {
385
val->bv_len = key->bv_len;
388
val->bv_len = strlen( val->bv_val );
393
case REWRITE_MAP_SET_OP_VAR:
394
case REWRITE_MAP_SETW_OP_VAR:
395
rc = rewrite_var_set( &op->lo_vars, map->lm_name,
397
? REWRITE_SUCCESS : REWRITE_ERR;
398
if ( rc == REWRITE_SUCCESS ) {
399
if ( map->lm_type == REWRITE_MAP_SET_OP_VAR ) {
400
val->bv_val = strdup( "" );
402
val->bv_val = strdup( key->bv_val );
403
val->bv_len = key->bv_len;
405
if ( val->bv_val == NULL ) {
411
case REWRITE_MAP_GET_OP_VAR: {
412
struct rewrite_var *var;
414
var = rewrite_var_find( op->lo_vars, map->lm_name );
418
val->bv_val = strdup( var->lv_value.bv_val );
419
val->bv_len = var->lv_value.bv_len;
420
if ( val->bv_val == NULL ) {
427
case REWRITE_MAP_SET_SESN_VAR:
428
case REWRITE_MAP_SETW_SESN_VAR:
429
if ( op->lo_cookie == NULL ) {
433
rc = rewrite_session_var_set( info, op->lo_cookie,
434
map->lm_name, key->bv_val );
435
if ( rc == REWRITE_SUCCESS ) {
436
if ( map->lm_type == REWRITE_MAP_SET_SESN_VAR ) {
437
val->bv_val = strdup( "" );
439
val->bv_val = strdup( key->bv_val );
440
val->bv_len = key->bv_len;
442
if ( val->bv_val == NULL ) {
448
case REWRITE_MAP_GET_SESN_VAR:
449
rc = rewrite_session_var_get( info, op->lo_cookie,
453
case REWRITE_MAP_GET_PARAM:
454
rc = rewrite_param_get( info, map->lm_name, val );
457
case REWRITE_MAP_BUILTIN: {
458
struct rewrite_builtin_map *bmap = map->lm_data;
460
if ( bmap->lb_mapper && bmap->lb_mapper->rm_apply )
461
rc = bmap->lb_mapper->rm_apply( bmap->lb_private, key->bv_val,
478
rewrite_builtin_map_free(
482
struct rewrite_builtin_map *map = ( struct rewrite_builtin_map * )tmp;
484
assert( map != NULL );
486
if ( map->lb_mapper && map->lb_mapper->rm_destroy )
487
map->lb_mapper->rm_destroy( map->lb_private );
489
free( map->lb_name );
495
struct rewrite_map **pmap
498
struct rewrite_map *map;
500
assert( pmap != NULL );
501
assert( *pmap != NULL );
505
#ifdef USE_REWRITE_LDAP_PVT_THREADS
506
ldap_pvt_thread_mutex_lock( &map->lm_mutex );
507
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
509
if ( map->lm_name ) {
510
free( map->lm_name );
514
if ( map->lm_subst ) {
515
rewrite_subst_destroy( &map->lm_subst );
518
#ifdef USE_REWRITE_LDAP_PVT_THREADS
519
ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
520
ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
521
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
530
extern const rewrite_mapper rewrite_ldap_mapper;
532
const rewrite_mapper *
539
if ( !strcasecmp( name, "ldap" ))
540
return &rewrite_ldap_mapper;
542
for (i=0; i<num_mappers; i++)
543
if ( !strcasecmp( name, mappers[i]->rm_name ))
549
rewrite_mapper_register(
550
const rewrite_mapper *map
553
if ( num_mappers % MAPPER_ALLOC == 0 ) {
554
const rewrite_mapper **mnew;
555
mnew = realloc( mappers, (num_mappers + MAPPER_ALLOC) *
556
sizeof( rewrite_mapper * ));
562
mappers[num_mappers++] = map;
567
rewrite_mapper_unregister(
568
const rewrite_mapper *map
573
for (i = 0; i<num_mappers; i++) {
574
if ( mappers[i] == map ) {
576
mappers[i] = mappers[num_mappers];
577
mappers[num_mappers] = NULL;