1 /******************************************************************************
3 * Copyright (C) 2000 Pierangelo Masarati, <ando@sys-net.it>
6 * Permission is granted to anyone to use this software for any purpose
7 * on any computer system, and to alter it and redistribute it, subject
8 * to the following restrictions:
10 * 1. The author is not responsible for the consequences of use of this
11 * software, no matter how awful, even if they arise from flaws in it.
13 * 2. The origin of this software must not be misrepresented, either by
14 * explicit claim or by omission. Since few users ever read sources,
15 * credits should appear in the documentation.
17 * 3. Altered versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software. Since few users
19 * ever read sources, credits should appear in the documentation.
21 * 4. This notice may not be removed or altered.
23 ******************************************************************************/
27 #include <ac/string.h>
29 #include "rewrite-int.h"
30 #include "rewrite-map.h"
35 extern struct rewrite_context *__curr_context;
41 rewrite_parse_builtin_map(
42 struct rewrite_info *info,
50 * Parses a config line and takes actions to fit content in rewrite structure;
51 * lines handled are of the form:
53 * rewriteEngine {on|off}
54 * rewriteMaxPasses numPasses
55 * rewriteContext contextName [alias aliasedContextName]
56 * rewriteRule pattern substPattern [ruleFlags]
57 * rewriteMap mapType mapName [mapArgs]
58 * rewriteParam paramName paramValue
62 struct rewrite_info *info,
71 assert( info != NULL );
72 assert( fname != NULL );
73 assert( argv != NULL );
77 * Switch on the rewrite engine
79 if ( strcasecmp( argv[ 0 ], "rewriteEngine" ) == 0 ) {
81 Debug( LDAP_DEBUG_ANY,
82 "[%s:%d] rewriteEngine needs 'state'\n%s",
85 } else if ( argc > 2 ) {
86 Debug( LDAP_DEBUG_ANY,
87 "[%s:%d] extra fields in rewriteEngine"
88 " will be discarded\n%s",
92 if ( strcasecmp( argv[ 1 ], "on" ) == 0 ) {
93 info->li_state = REWRITE_ON;
94 } else if ( strcasecmp( argv[ 1 ], "off" ) == 0 ) {
95 info->li_state = REWRITE_OFF;
97 Debug( LDAP_DEBUG_ANY,
98 "[%s:%d] unknown 'state' in rewriteEngine;"
101 info->li_state = REWRITE_ON;
103 rc = REWRITE_SUCCESS;
108 } else if ( strcasecmp( argv[ 0 ], "rewriteMaxPasses" ) == 0 ) {
110 Debug( LDAP_DEBUG_ANY,
111 "[%s:%d] rewriteMaxPasses needs 'value'\n%s",
115 info->li_max_passes = atoi( argv[ 1 ] );
116 rc = REWRITE_SUCCESS;
119 * Start a new rewrite context and set current context
121 } else if ( strcasecmp( argv[ 0 ], "rewriteContext" ) == 0 ) {
123 Debug( LDAP_DEBUG_ANY,
124 "[%s:%d] rewriteContext needs 'name'\n%s",
130 * Checks for existence (lots of contexts should be
131 * available by default ...)
133 __curr_context = rewrite_context_find( info, argv[ 1 ] );
134 if ( __curr_context == NULL ) {
135 __curr_context = rewrite_context_create( info,
138 if ( __curr_context == NULL ) {
145 * A context can alias another (e.g., the `builtin'
146 * contexts for backend operations, if not defined,
147 * alias the `default' rewrite context (with the
148 * notable exception of the searchResult context,
149 * which can be undefined)
151 if ( strcasecmp( argv[ 2 ], "alias" ) == 0 ) {
152 struct rewrite_context *aliased;
155 Debug( LDAP_DEBUG_ANY,
156 "[%s:%d] rewriteContext"
157 " needs 'name' after"
161 } else if ( argc > 4 ) {
162 Debug( LDAP_DEBUG_ANY,
163 "[%s:%d] extra fields in"
165 " after aliased name"
171 aliased = rewrite_context_find( info,
173 if ( aliased == NULL ) {
174 Debug( LDAP_DEBUG_ANY,
176 " rewriteContext '%s'"
177 " does not exists\n",
183 __curr_context->lc_alias = aliased;
184 __curr_context = aliased;
186 Debug( LDAP_DEBUG_ANY,
187 "[%s:%d] extra fields"
189 " will be discarded\n%s",
193 rc = REWRITE_SUCCESS;
196 * Compile a rule in current context
198 } else if ( strcasecmp( argv[ 0 ], "rewriteRule" ) == 0 ) {
200 Debug( LDAP_DEBUG_ANY,
201 "[%s:%d] rewriteRule needs 'pattern'"
202 " 'subst' ['flags']\n%s",
205 } else if ( argc > 4 ) {
206 Debug( LDAP_DEBUG_ANY,
207 "[%s:%d] extra fields in rewriteRule"
208 " will be discarded\n%s",
212 if ( __curr_context == NULL ) {
213 Debug( LDAP_DEBUG_ANY,
214 "[%s:%d] rewriteRule outside a"
215 " context; will add to default\n%s",
217 __curr_context = rewrite_context_find( info,
218 REWRITE_DEFAULT_CONTEXT );
221 * Default context MUST exist in a properly initialized
222 * struct rewrite_info
224 assert( __curr_context != NULL );
227 rc = rewrite_rule_compile( info, __curr_context, argv[ 1 ],
228 argv[ 2 ], ( argc == 4 ? argv[ 3 ] : "" ) );
231 * Add a plugin map to the map tree
233 } else if ( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 ) {
235 Debug( LDAP_DEBUG_ANY,
236 "[%s:%d] rewriteMap needs at least 'type'"
237 " and 'name' ['args']\n%s",
242 rc = rewrite_parse_builtin_map( info, fname, lineno,
246 * Set the value of a global scope parameter
248 } else if ( strcasecmp( argv[ 0 ], "rewriteParam" ) == 0 ) {
250 Debug( LDAP_DEBUG_ANY,
251 "[%s:%d] rewriteParam needs 'name'"
257 rc = rewrite_param_set( info, argv[ 1 ], argv[ 2 ] );
263 Debug( LDAP_DEBUG_ANY,
264 "[%s:%d] unknown command '%s'\n",
276 rewrite_builtin_map_cmp(
281 const struct rewrite_builtin_map *m1, *m2;
283 m1 = ( struct rewrite_builtin_map * )c1;
284 m2 = ( struct rewrite_builtin_map * )c2;
286 assert( m1 != NULL );
287 assert( m2 != NULL );
288 assert( m1->lb_name != NULL );
289 assert( m2->lb_name != NULL );
291 return strcasecmp( m1->lb_name, m2->lb_name );
298 rewrite_builtin_map_dup(
303 struct rewrite_builtin_map *m1, *m2;
305 m1 = ( struct rewrite_builtin_map * )c1;
306 m2 = ( struct rewrite_builtin_map * )c2;
308 assert( m1 != NULL );
309 assert( m2 != NULL );
310 assert( m1->lb_name != NULL );
311 assert( m2->lb_name != NULL );
313 return ( strcasecmp( m1->lb_name, m2->lb_name ) == 0 ? -1 : 0 );
317 * Adds a map to the info map tree
320 rewrite_builtin_map_insert(
321 struct rewrite_info *info,
322 struct rewrite_builtin_map *map
328 return avl_insert( &info->li_maps, ( caddr_t )map,
329 rewrite_builtin_map_cmp,
330 rewrite_builtin_map_dup );
336 struct rewrite_builtin_map *
337 rewrite_builtin_map_find(
338 struct rewrite_info *info,
342 struct rewrite_builtin_map tmp;
344 assert( info != NULL );
345 assert( name != NULL );
347 tmp.lb_name = ( char * )name;
349 return ( struct rewrite_builtin_map * )avl_find( info->li_maps,
350 ( caddr_t )&tmp, rewrite_builtin_map_cmp );
354 * Parses a plugin map
357 rewrite_parse_builtin_map(
358 struct rewrite_info *info,
365 struct rewrite_builtin_map *map;
370 assert( info != NULL );
371 assert( fname != NULL );
373 assert( argv != NULL );
374 assert( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 );
376 map = calloc( sizeof( struct rewrite_builtin_map ), 1 );
381 map->lb_name = strdup( argv[ MAP_NAME ] );
382 if ( map->lb_name == NULL ) {
390 if ( strcasecmp( argv[ MAP_TYPE ], "ldap" ) == 0 ) {
391 map->lb_type = REWRITE_BUILTIN_MAP_LDAP;
393 #ifdef USE_REWRITE_LDAP_PVT_THREADS
394 if ( ldap_pvt_thread_mutex_init( & map->lb_mutex ) ) {
395 free( map->lb_name );
399 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
401 map->lb_private = map_ldap_parse( info, fname, lineno,
402 argc - 3, argv + 3 );
408 Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown map type\n%s",
413 return rewrite_builtin_map_insert( info, map );