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 "rewrite-int.h"
28 #include "rewrite-map.h"
34 rewrite_parse_builtin_map(
35 struct rewrite_info *info,
43 * Parses a config line and takes actions to fit content in rewrite structure;
44 * lines handled are of the form:
46 * rewriteEngine {on|off}
47 * rewriteMaxPasses numPasses
48 * rewriteContext contextName [alias aliasedContextName]
49 * rewriteRule pattern substPattern [ruleFlags]
50 * rewriteMap mapType mapName [mapArgs]
51 * rewriteParam paramName paramValue
55 struct rewrite_info *info,
64 assert( info != NULL );
65 assert( fname != NULL );
66 assert( argv != NULL );
70 * Switch on the rewrite engine
72 if ( strcasecmp( argv[ 0 ], "rewriteEngine" ) == 0 ) {
74 Debug( LDAP_DEBUG_ANY,
75 "[%s:%d] rewriteEngine needs 'state'\n%s",
79 } else if ( argc > 2 ) {
80 Debug( LDAP_DEBUG_ANY,
81 "[%s:%d] extra fields in rewriteEngine"
82 " will be discarded\n%s",
86 if ( strcasecmp( argv[ 1 ], "on" ) == 0 ) {
87 info->li_state = REWRITE_ON;
89 } else if ( strcasecmp( argv[ 1 ], "off" ) == 0 ) {
90 info->li_state = REWRITE_OFF;
93 Debug( LDAP_DEBUG_ANY,
94 "[%s:%d] unknown 'state' in rewriteEngine;"
97 info->li_state = REWRITE_ON;
104 } else if ( strcasecmp( argv[ 0 ], "rewriteMaxPasses" ) == 0 ) {
106 Debug( LDAP_DEBUG_ANY,
107 "[%s:%d] rewriteMaxPasses needs 'value'\n%s",
111 info->li_max_passes = atoi( argv[ 1 ] );
112 rc = REWRITE_SUCCESS;
115 * Start a new rewrite context and set current context
117 } else if ( strcasecmp( argv[ 0 ], "rewriteContext" ) == 0 ) {
119 Debug( LDAP_DEBUG_ANY,
120 "[%s:%d] rewriteContext needs 'name'\n%s",
126 * Checks for existence (lots of contexts should be
127 * available by default ...)
129 rewrite_int_curr_context = rewrite_context_find( info, argv[ 1 ] );
130 if ( rewrite_int_curr_context == NULL ) {
131 rewrite_int_curr_context = rewrite_context_create( info,
134 if ( rewrite_int_curr_context == NULL ) {
141 * A context can alias another (e.g., the `builtin'
142 * contexts for backend operations, if not defined,
143 * alias the `default' rewrite context (with the
144 * notable exception of the searchResult context,
145 * which can be undefined)
147 if ( strcasecmp( argv[ 2 ], "alias" ) == 0 ) {
148 struct rewrite_context *aliased;
151 Debug( LDAP_DEBUG_ANY,
152 "[%s:%d] rewriteContext"
153 " needs 'name' after"
158 } else if ( argc > 4 ) {
159 Debug( LDAP_DEBUG_ANY,
160 "[%s:%d] extra fields in"
162 " after aliased name"
168 aliased = rewrite_context_find( info,
170 if ( aliased == NULL ) {
171 Debug( LDAP_DEBUG_ANY,
173 " rewriteContext '%s'"
174 " does not exists\n",
180 rewrite_int_curr_context->lc_alias = aliased;
181 rewrite_int_curr_context = aliased;
184 Debug( LDAP_DEBUG_ANY,
185 "[%s:%d] extra fields"
187 " will be discarded\n%s",
191 rc = REWRITE_SUCCESS;
194 * Compile a rule in current context
196 } else if ( strcasecmp( argv[ 0 ], "rewriteRule" ) == 0 ) {
198 Debug( LDAP_DEBUG_ANY,
199 "[%s:%d] rewriteRule needs 'pattern'"
200 " 'subst' ['flags']\n%s",
204 } else if ( argc > 4 ) {
205 Debug( LDAP_DEBUG_ANY,
206 "[%s:%d] extra fields in rewriteRule"
207 " will be discarded\n%s",
211 if ( rewrite_int_curr_context == NULL ) {
212 Debug( LDAP_DEBUG_ANY,
213 "[%s:%d] rewriteRule outside a"
214 " context; will add to default\n%s",
216 rewrite_int_curr_context = rewrite_context_find( info,
217 REWRITE_DEFAULT_CONTEXT );
220 * Default context MUST exist in a properly initialized
221 * struct rewrite_info
223 assert( rewrite_int_curr_context != NULL );
226 rc = rewrite_rule_compile( info, rewrite_int_curr_context, argv[ 1 ],
227 argv[ 2 ], ( argc == 4 ? argv[ 3 ] : "" ) );
230 * Add a plugin map to the map tree
232 } else if ( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 ) {
234 Debug( LDAP_DEBUG_ANY,
235 "[%s:%d] rewriteMap needs at least 'type'"
236 " and 'name' ['args']\n%s",
241 rc = rewrite_parse_builtin_map( info, fname, lineno,
245 * Set the value of a global scope parameter
247 } else if ( strcasecmp( argv[ 0 ], "rewriteParam" ) == 0 ) {
249 Debug( LDAP_DEBUG_ANY,
250 "[%s:%d] rewriteParam needs 'name'"
256 rc = rewrite_param_set( info, argv[ 1 ], argv[ 2 ] );
262 Debug( LDAP_DEBUG_ANY,
263 "[%s:%d] unknown command '%s'\n",
275 rewrite_builtin_map_cmp(
280 const struct rewrite_builtin_map *m1, *m2;
282 m1 = ( const struct rewrite_builtin_map * )c1;
283 m2 = ( const struct rewrite_builtin_map * )c2;
285 assert( m1 != NULL );
286 assert( m2 != NULL );
287 assert( m1->lb_name != NULL );
288 assert( m2->lb_name != NULL );
290 return strcasecmp( m1->lb_name, m2->lb_name );
297 rewrite_builtin_map_dup(
302 struct rewrite_builtin_map *m1, *m2;
304 m1 = ( struct rewrite_builtin_map * )c1;
305 m2 = ( struct rewrite_builtin_map * )c2;
307 assert( m1 != NULL );
308 assert( m2 != NULL );
309 assert( m1->lb_name != NULL );
310 assert( m2->lb_name != NULL );
312 return ( strcasecmp( m1->lb_name, m2->lb_name ) == 0 ? -1 : 0 );
316 * Adds a map to the info map tree
319 rewrite_builtin_map_insert(
320 struct rewrite_info *info,
321 struct rewrite_builtin_map *map
327 return avl_insert( &info->li_maps, ( caddr_t )map,
328 rewrite_builtin_map_cmp,
329 rewrite_builtin_map_dup );
335 struct rewrite_builtin_map *
336 rewrite_builtin_map_find(
337 struct rewrite_info *info,
341 struct rewrite_builtin_map tmp;
343 assert( info != NULL );
344 assert( name != NULL );
346 tmp.lb_name = ( char * )name;
348 return ( struct rewrite_builtin_map * )avl_find( info->li_maps,
349 ( caddr_t )&tmp, rewrite_builtin_map_cmp );
353 * Parses a plugin map
356 rewrite_parse_builtin_map(
357 struct rewrite_info *info,
364 struct rewrite_builtin_map *map;
369 assert( info != NULL );
370 assert( fname != NULL );
372 assert( argv != NULL );
373 assert( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 );
375 map = calloc( sizeof( struct rewrite_builtin_map ), 1 );
380 map->lb_name = strdup( argv[ MAP_NAME ] );
381 if ( map->lb_name == NULL ) {
389 if ( strcasecmp( argv[ MAP_TYPE ], "ldap" ) == 0 ) {
390 map->lb_type = REWRITE_BUILTIN_MAP_LDAP;
392 #ifdef USE_REWRITE_LDAP_PVT_THREADS
393 if ( ldap_pvt_thread_mutex_init( & map->lb_mutex ) ) {
394 free( map->lb_name );
398 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
400 map->lb_private = map_ldap_parse( info, fname, lineno,
401 argc - 3, argv + 3 );
407 Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown map type\n%s",
412 return rewrite_builtin_map_insert( info, map );