1 /* $OpenLDAP: pkg/ldap/libraries/librewrite/config.c,v 1.14.2.3 2008/02/11 23:26:42 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.
22 #include "rewrite-int.h"
23 #include "rewrite-map.h"
29 rewrite_parse_builtin_map(
30 struct rewrite_info
*info
,
38 * Parses a config line and takes actions to fit content in rewrite structure;
39 * lines handled are of the form:
41 * rewriteEngine {on|off}
42 * rewriteMaxPasses numPasses [numPassesPerRule]
43 * rewriteContext contextName [alias aliasedContextName]
44 * rewriteRule pattern substPattern [ruleFlags]
45 * rewriteMap mapType mapName [mapArgs]
46 * rewriteParam paramName paramValue
50 struct rewrite_info
*info
,
59 assert( info
!= NULL
);
60 assert( fname
!= NULL
);
61 assert( argv
!= NULL
);
65 * Switch on the rewrite engine
67 if ( strcasecmp( argv
[ 0 ], "rewriteEngine" ) == 0 ) {
69 Debug( LDAP_DEBUG_ANY
,
70 "[%s:%d] rewriteEngine needs 'state'\n%s",
74 } else if ( argc
> 2 ) {
75 Debug( LDAP_DEBUG_ANY
,
76 "[%s:%d] extra fields in rewriteEngine"
77 " will be discarded\n%s",
81 if ( strcasecmp( argv
[ 1 ], "on" ) == 0 ) {
82 info
->li_state
= REWRITE_ON
;
84 } else if ( strcasecmp( argv
[ 1 ], "off" ) == 0 ) {
85 info
->li_state
= REWRITE_OFF
;
88 Debug( LDAP_DEBUG_ANY
,
89 "[%s:%d] unknown 'state' in rewriteEngine;"
92 info
->li_state
= REWRITE_ON
;
99 } else if ( strcasecmp( argv
[ 0 ], "rewriteMaxPasses" ) == 0 ) {
101 Debug( LDAP_DEBUG_ANY
,
102 "[%s:%d] rewriteMaxPasses needs 'value'\n%s",
107 if ( lutil_atoi( &info
->li_max_passes
, argv
[ 1 ] ) != 0 ) {
108 Debug( LDAP_DEBUG_ANY
,
109 "[%s:%d] unable to parse rewriteMaxPasses=\"%s\"\n",
110 fname
, lineno
, argv
[ 1 ] );
114 if ( info
->li_max_passes
<= 0 ) {
115 Debug( LDAP_DEBUG_ANY
,
116 "[%s:%d] negative or null rewriteMaxPasses\n",
122 if ( lutil_atoi( &info
->li_max_passes_per_rule
, argv
[ 2 ] ) != 0 ) {
123 Debug( LDAP_DEBUG_ANY
,
124 "[%s:%d] unable to parse rewriteMaxPassesPerRule=\"%s\"\n",
125 fname
, lineno
, argv
[ 2 ] );
129 if ( info
->li_max_passes_per_rule
<= 0 ) {
130 Debug( LDAP_DEBUG_ANY
,
131 "[%s:%d] negative or null rewriteMaxPassesPerRule\n",
137 info
->li_max_passes_per_rule
= info
->li_max_passes
;
139 rc
= REWRITE_SUCCESS
;
142 * Start a new rewrite context and set current context
144 } else if ( strcasecmp( argv
[ 0 ], "rewriteContext" ) == 0 ) {
146 Debug( LDAP_DEBUG_ANY
,
147 "[%s:%d] rewriteContext needs 'name'\n%s",
153 * Checks for existence (lots of contexts should be
154 * available by default ...)
156 rewrite_int_curr_context
= rewrite_context_find( info
, argv
[ 1 ] );
157 if ( rewrite_int_curr_context
== NULL
) {
158 rewrite_int_curr_context
= rewrite_context_create( info
,
161 if ( rewrite_int_curr_context
== NULL
) {
168 * A context can alias another (e.g., the `builtin'
169 * contexts for backend operations, if not defined,
170 * alias the `default' rewrite context (with the
171 * notable exception of the searchResult context,
172 * which can be undefined)
174 if ( strcasecmp( argv
[ 2 ], "alias" ) == 0 ) {
175 struct rewrite_context
*aliased
;
178 Debug( LDAP_DEBUG_ANY
,
179 "[%s:%d] rewriteContext"
180 " needs 'name' after"
185 } else if ( argc
> 4 ) {
186 Debug( LDAP_DEBUG_ANY
,
187 "[%s:%d] extra fields in"
189 " after aliased name"
195 aliased
= rewrite_context_find( info
,
197 if ( aliased
== NULL
) {
198 Debug( LDAP_DEBUG_ANY
,
200 " rewriteContext '%s'"
201 " does not exists\n",
207 rewrite_int_curr_context
->lc_alias
= aliased
;
208 rewrite_int_curr_context
= aliased
;
211 Debug( LDAP_DEBUG_ANY
,
212 "[%s:%d] extra fields"
214 " will be discarded\n%s",
218 rc
= REWRITE_SUCCESS
;
221 * Compile a rule in current context
223 } else if ( strcasecmp( argv
[ 0 ], "rewriteRule" ) == 0 ) {
225 Debug( LDAP_DEBUG_ANY
,
226 "[%s:%d] rewriteRule needs 'pattern'"
227 " 'subst' ['flags']\n%s",
231 } else if ( argc
> 4 ) {
232 Debug( LDAP_DEBUG_ANY
,
233 "[%s:%d] extra fields in rewriteRule"
234 " will be discarded\n%s",
238 if ( rewrite_int_curr_context
== NULL
) {
239 Debug( LDAP_DEBUG_ANY
,
240 "[%s:%d] rewriteRule outside a"
241 " context; will add to default\n%s",
243 rewrite_int_curr_context
= rewrite_context_find( info
,
244 REWRITE_DEFAULT_CONTEXT
);
247 * Default context MUST exist in a properly initialized
248 * struct rewrite_info
250 assert( rewrite_int_curr_context
!= NULL
);
253 rc
= rewrite_rule_compile( info
, rewrite_int_curr_context
, argv
[ 1 ],
254 argv
[ 2 ], ( argc
== 4 ? argv
[ 3 ] : "" ) );
257 * Add a plugin map to the map tree
259 } else if ( strcasecmp( argv
[ 0 ], "rewriteMap" ) == 0 ) {
261 Debug( LDAP_DEBUG_ANY
,
262 "[%s:%d] rewriteMap needs at least 'type'"
263 " and 'name' ['args']\n%s",
268 rc
= rewrite_parse_builtin_map( info
, fname
, lineno
,
272 * Set the value of a global scope parameter
274 } else if ( strcasecmp( argv
[ 0 ], "rewriteParam" ) == 0 ) {
276 Debug( LDAP_DEBUG_ANY
,
277 "[%s:%d] rewriteParam needs 'name'"
283 rc
= rewrite_param_set( info
, argv
[ 1 ], argv
[ 2 ] );
289 Debug( LDAP_DEBUG_ANY
,
290 "[%s:%d] unknown command '%s'\n",
302 rewrite_builtin_map_cmp(
307 const struct rewrite_builtin_map
*m1
, *m2
;
309 m1
= ( const struct rewrite_builtin_map
* )c1
;
310 m2
= ( const struct rewrite_builtin_map
* )c2
;
312 assert( m1
!= NULL
);
313 assert( m2
!= NULL
);
314 assert( m1
->lb_name
!= NULL
);
315 assert( m2
->lb_name
!= NULL
);
317 return strcasecmp( m1
->lb_name
, m2
->lb_name
);
324 rewrite_builtin_map_dup(
329 struct rewrite_builtin_map
*m1
, *m2
;
331 m1
= ( struct rewrite_builtin_map
* )c1
;
332 m2
= ( struct rewrite_builtin_map
* )c2
;
334 assert( m1
!= NULL
);
335 assert( m2
!= NULL
);
336 assert( m1
->lb_name
!= NULL
);
337 assert( m2
->lb_name
!= NULL
);
339 return ( strcasecmp( m1
->lb_name
, m2
->lb_name
) == 0 ? -1 : 0 );
343 * Adds a map to the info map tree
346 rewrite_builtin_map_insert(
347 struct rewrite_info
*info
,
348 struct rewrite_builtin_map
*map
354 return avl_insert( &info
->li_maps
, ( caddr_t
)map
,
355 rewrite_builtin_map_cmp
,
356 rewrite_builtin_map_dup
);
362 struct rewrite_builtin_map
*
363 rewrite_builtin_map_find(
364 struct rewrite_info
*info
,
368 struct rewrite_builtin_map tmp
;
370 assert( info
!= NULL
);
371 assert( name
!= NULL
);
373 tmp
.lb_name
= ( char * )name
;
375 return ( struct rewrite_builtin_map
* )avl_find( info
->li_maps
,
376 ( caddr_t
)&tmp
, rewrite_builtin_map_cmp
);
380 * Parses a plugin map
383 rewrite_parse_builtin_map(
384 struct rewrite_info
*info
,
391 struct rewrite_builtin_map
*map
;
396 assert( info
!= NULL
);
397 assert( fname
!= NULL
);
399 assert( argv
!= NULL
);
400 assert( strcasecmp( argv
[ 0 ], "rewriteMap" ) == 0 );
402 map
= calloc( sizeof( struct rewrite_builtin_map
), 1 );
407 map
->lb_name
= strdup( argv
[ MAP_NAME
] );
408 if ( map
->lb_name
== NULL
) {
416 if (( map
->lb_mapper
= rewrite_mapper_find( argv
[ MAP_TYPE
] ))) {
417 map
->lb_type
= REWRITE_BUILTIN_MAP
;
419 #ifdef USE_REWRITE_LDAP_PVT_THREADS
420 if ( ldap_pvt_thread_mutex_init( & map
->lb_mutex
) ) {
421 free( map
->lb_name
);
425 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
427 map
->lb_private
= map
->lb_mapper
->rm_config( fname
, lineno
,
428 argc
- 3, argv
+ 3 );
435 Debug( LDAP_DEBUG_ANY
, "[%s:%d] unknown map type\n%s",
440 return rewrite_builtin_map_insert( info
, map
);