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"
33 extern struct rewrite_context *__curr_context;
39 rewrite_parse_builtin_map(
40 struct rewrite_info *info,
48 * Parses a config line and takes actions to fit content in rewrite structure;
49 * lines handled are of the form:
51 * rewriteEngine {on|off}
52 * rewriteMaxPasses numPasses
53 * rewriteContext contextName [alias aliasedContextName]
54 * rewriteRule pattern substPattern [ruleFlags]
55 * rewriteMap mapType mapName [mapArgs]
56 * rewriteParam paramName paramValue
60 struct rewrite_info *info,
69 assert( info != NULL );
70 assert( fname != NULL );
71 assert( argv != NULL );
75 * Switch on the rewrite engine
77 if ( strcasecmp( argv[ 0 ], "rewriteEngine" ) == 0 ) {
79 Debug( LDAP_DEBUG_ANY,
80 "[%s:%d] rewriteEngine needs 'state'\n%s",
83 } else if ( argc > 2 ) {
84 Debug( LDAP_DEBUG_ANY,
85 "[%s:%d] extra fields in rewriteEngine"
86 " will be discarded\n%s",
90 if ( strcasecmp( argv[ 1 ], "on" ) == 0 ) {
91 info->li_state = REWRITE_ON;
92 } else if ( strcasecmp( argv[ 1 ], "off" ) == 0 ) {
93 info->li_state = REWRITE_OFF;
95 Debug( LDAP_DEBUG_ANY,
96 "[%s:%d] unknown 'state' in rewriteEngine;"
99 info->li_state = REWRITE_ON;
101 rc = REWRITE_SUCCESS;
106 } else if ( strcasecmp( argv[ 0 ], "rewriteMaxPasses" ) == 0 ) {
108 Debug( LDAP_DEBUG_ANY,
109 "[%s:%d] rewriteMaxPasses needs 'value'\n%s",
113 info->li_max_passes = atoi( argv[ 1 ] );
114 rc = REWRITE_SUCCESS;
117 * Start a new rewrite context and set current context
119 } else if ( strcasecmp( argv[ 0 ], "rewriteContext" ) == 0 ) {
121 Debug( LDAP_DEBUG_ANY,
122 "[%s:%d] rewriteContext needs 'name'\n%s",
128 * Checks for existence (lots of contexts should be
129 * available by default ...)
131 __curr_context = rewrite_context_find( info, argv[ 1 ] );
132 if ( __curr_context == NULL ) {
133 __curr_context = rewrite_context_create( info,
136 if ( __curr_context == NULL ) {
143 * A context can alias another (e.g., the `builtin'
144 * contexts for backend operations, if not defined,
145 * alias the `default' rewrite context (with the
146 * notable exception of the searchResult context,
147 * which can be undefined)
149 if ( strcasecmp( argv[ 2 ], "alias" ) == 0 ) {
150 struct rewrite_context *aliased;
153 Debug( LDAP_DEBUG_ANY,
154 "[%s:%d] rewriteContext"
155 " needs 'name' after"
159 } else if ( argc > 4 ) {
160 Debug( LDAP_DEBUG_ANY,
161 "[%s:%d] extra fields in"
163 " after aliased name"
169 aliased = rewrite_context_find( info,
171 if ( aliased == NULL ) {
172 Debug( LDAP_DEBUG_ANY,
174 " rewriteContext '%s'"
175 " does not exists\n",
181 __curr_context->lc_alias = aliased;
182 __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",
203 } else if ( argc > 4 ) {
204 Debug( LDAP_DEBUG_ANY,
205 "[%s:%d] extra fields in rewriteRule"
206 " will be discarded\n%s",
210 if ( __curr_context == NULL ) {
211 Debug( LDAP_DEBUG_ANY,
212 "[%s:%d] rewriteRule outside a"
213 " context; will add to default\n%s",
215 __curr_context = rewrite_context_find( info,
216 REWRITE_DEFAULT_CONTEXT );
219 * Default context MUST exist in a properly initialized
220 * struct rewrite_info
222 assert( __curr_context != NULL );
225 rc = rewrite_rule_compile( info, __curr_context, argv[ 1 ],
226 argv[ 2 ], ( argc == 4 ? argv[ 3 ] : "" ) );
229 * Add a plugin map to the map tree
231 } else if ( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 ) {
233 Debug( LDAP_DEBUG_ANY,
234 "[%s:%d] rewriteMap needs at least 'type'"
235 " and 'name' ['args']\n%s",
240 rc = rewrite_parse_builtin_map( info, fname, lineno,
244 * Set the value of a global scope parameter
246 } else if ( strcasecmp( argv[ 0 ], "rewriteParam" ) == 0 ) {
248 Debug( LDAP_DEBUG_ANY,
249 "[%s:%d] rewriteParam needs 'name'"
255 rc = rewrite_param_set( info, argv[ 1 ], argv[ 2 ] );
261 Debug( LDAP_DEBUG_ANY,
262 "[%s:%d] unknown command '%s'\n",
274 rewrite_builtin_map_cmp(
279 const struct rewrite_builtin_map *m1, *m2;
281 m1 = ( struct rewrite_builtin_map * )c1;
282 m2 = ( struct rewrite_builtin_map * )c2;
284 assert( m1 != NULL );
285 assert( m2 != NULL );
286 assert( m1->lb_name != NULL );
287 assert( m2->lb_name != NULL );
289 return strcasecmp( m1->lb_name, m2->lb_name );
296 rewrite_builtin_map_dup(
301 struct rewrite_builtin_map *m1, *m2;
303 m1 = ( struct rewrite_builtin_map * )c1;
304 m2 = ( struct rewrite_builtin_map * )c2;
306 assert( m1 != NULL );
307 assert( m2 != NULL );
308 assert( m1->lb_name != NULL );
309 assert( m2->lb_name != NULL );
311 return ( strcasecmp( m1->lb_name, m2->lb_name ) == 0 ? -1 : 0 );
315 * Adds a map to the info map tree
318 rewrite_builtin_map_insert(
319 struct rewrite_info *info,
320 struct rewrite_builtin_map *map
326 return avl_insert( &info->li_maps, ( caddr_t )map,
327 rewrite_builtin_map_cmp,
328 rewrite_builtin_map_dup );
334 struct rewrite_builtin_map *
335 rewrite_builtin_map_find(
336 struct rewrite_info *info,
340 struct rewrite_builtin_map tmp;
342 assert( info != NULL );
343 assert( name != NULL );
345 tmp.lb_name = ( char * )name;
347 return ( struct rewrite_builtin_map * )avl_find( info->li_maps,
348 ( caddr_t )&tmp, rewrite_builtin_map_cmp );
352 * Parses a plugin map
355 rewrite_parse_builtin_map(
356 struct rewrite_info *info,
363 struct rewrite_builtin_map *map;
368 assert( info != NULL );
369 assert( fname != NULL );
371 assert( argv != NULL );
372 assert( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 );
374 map = calloc( sizeof( struct rewrite_builtin_map ), 1 );
379 map->lb_name = strdup( argv[ MAP_NAME ] );
380 if ( map->lb_name == NULL ) {
388 if ( strcasecmp( argv[ MAP_TYPE ], "ldap" ) == 0 ) {
389 map->lb_type = REWRITE_BUILTIN_MAP_LDAP;
391 #ifdef USE_REWRITE_LDAP_PVT_THREADS
392 if ( ldap_pvt_thread_mutex_init( & map->lb_mutex ) ) {
393 free( map->lb_name );
397 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
399 map->lb_private = map_ldap_parse( info, fname, lineno,
400 argc - 3, argv + 3 );
406 Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown map type\n%s",
411 return rewrite_builtin_map_insert( info, map );