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",
78 } else if ( argc > 2 ) {
79 Debug( LDAP_DEBUG_ANY,
80 "[%s:%d] extra fields in rewriteEngine"
81 " will be discarded\n%s",
85 if ( strcasecmp( argv[ 1 ], "on" ) == 0 ) {
86 info->li_state = REWRITE_ON;
87 } else if ( strcasecmp( argv[ 1 ], "off" ) == 0 ) {
88 info->li_state = REWRITE_OFF;
90 Debug( LDAP_DEBUG_ANY,
91 "[%s:%d] unknown 'state' in rewriteEngine;"
94 info->li_state = REWRITE_ON;
101 } else if ( strcasecmp( argv[ 0 ], "rewriteMaxPasses" ) == 0 ) {
103 Debug( LDAP_DEBUG_ANY,
104 "[%s:%d] rewriteMaxPasses needs 'value'\n%s",
108 info->li_max_passes = atoi( argv[ 1 ] );
109 rc = REWRITE_SUCCESS;
112 * Start a new rewrite context and set current context
114 } else if ( strcasecmp( argv[ 0 ], "rewriteContext" ) == 0 ) {
116 Debug( LDAP_DEBUG_ANY,
117 "[%s:%d] rewriteContext needs 'name'\n%s",
123 * Checks for existence (lots of contexts should be
124 * available by default ...)
126 __curr_context = rewrite_context_find( info, argv[ 1 ] );
127 if ( __curr_context == NULL ) {
128 __curr_context = rewrite_context_create( info,
131 if ( __curr_context == NULL ) {
138 * A context can alias another (e.g., the `builtin'
139 * contexts for backend operations, if not defined,
140 * alias the `default' rewrite context (with the
141 * notable exception of the searchResult context,
142 * which can be undefined)
144 if ( strcasecmp( argv[ 2 ], "alias" ) == 0 ) {
145 struct rewrite_context *aliased;
148 Debug( LDAP_DEBUG_ANY,
149 "[%s:%d] rewriteContext"
150 " needs 'name' after"
154 } else if ( argc > 4 ) {
155 Debug( LDAP_DEBUG_ANY,
156 "[%s:%d] extra fields in"
158 " after aliased name"
164 aliased = rewrite_context_find( info,
166 if ( aliased == NULL ) {
167 Debug( LDAP_DEBUG_ANY,
169 " rewriteContext '%s'"
170 " does not exists\n",
176 __curr_context->lc_alias = aliased;
177 __curr_context = aliased;
179 Debug( LDAP_DEBUG_ANY,
180 "[%s:%d] extra fields"
182 " will be discarded\n%s",
186 rc = REWRITE_SUCCESS;
189 * Compile a rule in current context
191 } else if ( strcasecmp( argv[ 0 ], "rewriteRule" ) == 0 ) {
193 Debug( LDAP_DEBUG_ANY,
194 "[%s:%d] rewriteRule needs 'pattern'"
195 " 'subst' ['flags']\n%s",
198 } else if ( argc > 4 ) {
199 Debug( LDAP_DEBUG_ANY,
200 "[%s:%d] extra fields in rewriteRule"
201 " will be discarded\n%s",
205 if ( __curr_context == NULL ) {
206 Debug( LDAP_DEBUG_ANY,
207 "[%s:%d] rewriteRule outside a"
208 " context; will add to default\n%s",
210 __curr_context = rewrite_context_find( info,
211 REWRITE_DEFAULT_CONTEXT );
214 * Default context MUST exist in a properly initialized
215 * struct rewrite_info
217 assert( __curr_context != NULL );
220 rc = rewrite_rule_compile( info, __curr_context, argv[ 1 ],
221 argv[ 2 ], ( argc == 4 ? argv[ 3 ] : "" ) );
224 * Add a plugin map to the map tree
226 } else if ( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 ) {
228 Debug( LDAP_DEBUG_ANY,
229 "[%s:%d] rewriteMap needs at least 'type'"
230 " and 'name' ['args']\n%s",
235 rc = rewrite_parse_builtin_map( info, fname, lineno,
239 * Set the value of a global scope parameter
241 } else if ( strcasecmp( argv[ 0 ], "rewriteParam" ) == 0 ) {
243 Debug( LDAP_DEBUG_ANY,
244 "[%s:%d] rewriteParam needs 'name'"
250 rc = rewrite_param_set( info, argv[ 1 ], argv[ 2 ] );
256 Debug( LDAP_DEBUG_ANY,
257 "[%s:%d] unknown command '%s'\n",
269 rewrite_builtin_map_cmp(
274 const struct rewrite_builtin_map *m1, *m2;
276 m1 = ( const struct rewrite_builtin_map * )c1;
277 m2 = ( const struct rewrite_builtin_map * )c2;
279 assert( m1 != NULL );
280 assert( m2 != NULL );
281 assert( m1->lb_name != NULL );
282 assert( m2->lb_name != NULL );
284 return strcasecmp( m1->lb_name, m2->lb_name );
291 rewrite_builtin_map_dup(
296 struct rewrite_builtin_map *m1, *m2;
298 m1 = ( struct rewrite_builtin_map * )c1;
299 m2 = ( struct rewrite_builtin_map * )c2;
301 assert( m1 != NULL );
302 assert( m2 != NULL );
303 assert( m1->lb_name != NULL );
304 assert( m2->lb_name != NULL );
306 return ( strcasecmp( m1->lb_name, m2->lb_name ) == 0 ? -1 : 0 );
310 * Adds a map to the info map tree
313 rewrite_builtin_map_insert(
314 struct rewrite_info *info,
315 struct rewrite_builtin_map *map
321 return avl_insert( &info->li_maps, ( caddr_t )map,
322 rewrite_builtin_map_cmp,
323 rewrite_builtin_map_dup );
329 struct rewrite_builtin_map *
330 rewrite_builtin_map_find(
331 struct rewrite_info *info,
335 struct rewrite_builtin_map tmp;
337 assert( info != NULL );
338 assert( name != NULL );
340 tmp.lb_name = ( char * )name;
342 return ( struct rewrite_builtin_map * )avl_find( info->li_maps,
343 ( caddr_t )&tmp, rewrite_builtin_map_cmp );
347 * Parses a plugin map
350 rewrite_parse_builtin_map(
351 struct rewrite_info *info,
358 struct rewrite_builtin_map *map;
363 assert( info != NULL );
364 assert( fname != NULL );
366 assert( argv != NULL );
367 assert( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 );
369 map = calloc( sizeof( struct rewrite_builtin_map ), 1 );
374 map->lb_name = strdup( argv[ MAP_NAME ] );
375 if ( map->lb_name == NULL ) {
383 if ( strcasecmp( argv[ MAP_TYPE ], "ldap" ) == 0 ) {
384 map->lb_type = REWRITE_BUILTIN_MAP_LDAP;
386 #ifdef USE_REWRITE_LDAP_PVT_THREADS
387 if ( ldap_pvt_thread_mutex_init( & map->lb_mutex ) ) {
388 free( map->lb_name );
392 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
394 map->lb_private = map_ldap_parse( info, fname, lineno,
395 argc - 3, argv + 3 );
401 Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown map type\n%s",
406 return rewrite_builtin_map_insert( info, map );