2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2005 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 info->li_max_passes = atoi( argv[ 1 ] );
108 if ( info->li_max_passes <= 0 ) {
109 Debug( LDAP_DEBUG_ANY,
110 "[%s:%d] negative or null rewriteMaxPasses'\n",
115 info->li_max_passes_per_rule = atoi( argv[ 2 ] );
116 if ( info->li_max_passes_per_rule <= 0 ) {
117 Debug( LDAP_DEBUG_ANY,
118 "[%s:%d] negative or null rewriteMaxPassesPerRule'\n",
123 info->li_max_passes_per_rule = info->li_max_passes;
125 rc = REWRITE_SUCCESS;
128 * Start a new rewrite context and set current context
130 } else if ( strcasecmp( argv[ 0 ], "rewriteContext" ) == 0 ) {
132 Debug( LDAP_DEBUG_ANY,
133 "[%s:%d] rewriteContext needs 'name'\n%s",
139 * Checks for existence (lots of contexts should be
140 * available by default ...)
142 rewrite_int_curr_context = rewrite_context_find( info, argv[ 1 ] );
143 if ( rewrite_int_curr_context == NULL ) {
144 rewrite_int_curr_context = rewrite_context_create( info,
147 if ( rewrite_int_curr_context == NULL ) {
154 * A context can alias another (e.g., the `builtin'
155 * contexts for backend operations, if not defined,
156 * alias the `default' rewrite context (with the
157 * notable exception of the searchResult context,
158 * which can be undefined)
160 if ( strcasecmp( argv[ 2 ], "alias" ) == 0 ) {
161 struct rewrite_context *aliased;
164 Debug( LDAP_DEBUG_ANY,
165 "[%s:%d] rewriteContext"
166 " needs 'name' after"
171 } else if ( argc > 4 ) {
172 Debug( LDAP_DEBUG_ANY,
173 "[%s:%d] extra fields in"
175 " after aliased name"
181 aliased = rewrite_context_find( info,
183 if ( aliased == NULL ) {
184 Debug( LDAP_DEBUG_ANY,
186 " rewriteContext '%s'"
187 " does not exists\n",
193 rewrite_int_curr_context->lc_alias = aliased;
194 rewrite_int_curr_context = aliased;
197 Debug( LDAP_DEBUG_ANY,
198 "[%s:%d] extra fields"
200 " will be discarded\n%s",
204 rc = REWRITE_SUCCESS;
207 * Compile a rule in current context
209 } else if ( strcasecmp( argv[ 0 ], "rewriteRule" ) == 0 ) {
211 Debug( LDAP_DEBUG_ANY,
212 "[%s:%d] rewriteRule needs 'pattern'"
213 " 'subst' ['flags']\n%s",
217 } else if ( argc > 4 ) {
218 Debug( LDAP_DEBUG_ANY,
219 "[%s:%d] extra fields in rewriteRule"
220 " will be discarded\n%s",
224 if ( rewrite_int_curr_context == NULL ) {
225 Debug( LDAP_DEBUG_ANY,
226 "[%s:%d] rewriteRule outside a"
227 " context; will add to default\n%s",
229 rewrite_int_curr_context = rewrite_context_find( info,
230 REWRITE_DEFAULT_CONTEXT );
233 * Default context MUST exist in a properly initialized
234 * struct rewrite_info
236 assert( rewrite_int_curr_context != NULL );
239 rc = rewrite_rule_compile( info, rewrite_int_curr_context, argv[ 1 ],
240 argv[ 2 ], ( argc == 4 ? argv[ 3 ] : "" ) );
243 * Add a plugin map to the map tree
245 } else if ( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 ) {
247 Debug( LDAP_DEBUG_ANY,
248 "[%s:%d] rewriteMap needs at least 'type'"
249 " and 'name' ['args']\n%s",
254 rc = rewrite_parse_builtin_map( info, fname, lineno,
258 * Set the value of a global scope parameter
260 } else if ( strcasecmp( argv[ 0 ], "rewriteParam" ) == 0 ) {
262 Debug( LDAP_DEBUG_ANY,
263 "[%s:%d] rewriteParam needs 'name'"
269 rc = rewrite_param_set( info, argv[ 1 ], argv[ 2 ] );
275 Debug( LDAP_DEBUG_ANY,
276 "[%s:%d] unknown command '%s'\n",
288 rewrite_builtin_map_cmp(
293 const struct rewrite_builtin_map *m1, *m2;
295 m1 = ( const struct rewrite_builtin_map * )c1;
296 m2 = ( const struct rewrite_builtin_map * )c2;
298 assert( m1 != NULL );
299 assert( m2 != NULL );
300 assert( m1->lb_name != NULL );
301 assert( m2->lb_name != NULL );
303 return strcasecmp( m1->lb_name, m2->lb_name );
310 rewrite_builtin_map_dup(
315 struct rewrite_builtin_map *m1, *m2;
317 m1 = ( struct rewrite_builtin_map * )c1;
318 m2 = ( struct rewrite_builtin_map * )c2;
320 assert( m1 != NULL );
321 assert( m2 != NULL );
322 assert( m1->lb_name != NULL );
323 assert( m2->lb_name != NULL );
325 return ( strcasecmp( m1->lb_name, m2->lb_name ) == 0 ? -1 : 0 );
329 * Adds a map to the info map tree
332 rewrite_builtin_map_insert(
333 struct rewrite_info *info,
334 struct rewrite_builtin_map *map
340 return avl_insert( &info->li_maps, ( caddr_t )map,
341 rewrite_builtin_map_cmp,
342 rewrite_builtin_map_dup );
348 struct rewrite_builtin_map *
349 rewrite_builtin_map_find(
350 struct rewrite_info *info,
354 struct rewrite_builtin_map tmp;
356 assert( info != NULL );
357 assert( name != NULL );
359 tmp.lb_name = ( char * )name;
361 return ( struct rewrite_builtin_map * )avl_find( info->li_maps,
362 ( caddr_t )&tmp, rewrite_builtin_map_cmp );
366 * Parses a plugin map
369 rewrite_parse_builtin_map(
370 struct rewrite_info *info,
377 struct rewrite_builtin_map *map;
382 assert( info != NULL );
383 assert( fname != NULL );
385 assert( argv != NULL );
386 assert( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 );
388 map = calloc( sizeof( struct rewrite_builtin_map ), 1 );
393 map->lb_name = strdup( argv[ MAP_NAME ] );
394 if ( map->lb_name == NULL ) {
402 if ( strcasecmp( argv[ MAP_TYPE ], "ldap" ) == 0 ) {
403 map->lb_type = REWRITE_BUILTIN_MAP_LDAP;
405 #ifdef USE_REWRITE_LDAP_PVT_THREADS
406 if ( ldap_pvt_thread_mutex_init( & map->lb_mutex ) ) {
407 free( map->lb_name );
411 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
413 map->lb_private = map_ldap_parse( info, fname, lineno,
414 argc - 3, argv + 3 );
420 Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown map type\n%s",
425 return rewrite_builtin_map_insert( info, map );