config.c revision 1.1.1.2 1 1.1.1.2 lukem /* $NetBSD: config.c,v 1.1.1.2 2010/03/08 02:14:20 lukem Exp $ */
2 1.1.1.2 lukem
3 1.1.1.2 lukem /* OpenLDAP: pkg/ldap/libraries/librewrite/config.c,v 1.14.2.4 2009/01/22 00:00:58 kurt Exp */
4 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 1.1 lukem *
6 1.1.1.2 lukem * Copyright 2000-2009 The OpenLDAP Foundation.
7 1.1 lukem * All rights reserved.
8 1.1 lukem *
9 1.1 lukem * Redistribution and use in source and binary forms, with or without
10 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP
11 1.1 lukem * Public License.
12 1.1 lukem *
13 1.1 lukem * A copy of this license is available in the file LICENSE in the
14 1.1 lukem * top-level directory of the distribution or, alternatively, at
15 1.1 lukem * <http://www.OpenLDAP.org/license.html>.
16 1.1 lukem */
17 1.1 lukem /* ACKNOWLEDGEMENT:
18 1.1 lukem * This work was initially developed by Pierangelo Masarati for
19 1.1 lukem * inclusion in OpenLDAP Software.
20 1.1 lukem */
21 1.1 lukem
22 1.1 lukem #include <portable.h>
23 1.1 lukem
24 1.1 lukem #include "rewrite-int.h"
25 1.1 lukem #include "rewrite-map.h"
26 1.1 lukem
27 1.1 lukem /*
28 1.1 lukem * Parses a plugin map
29 1.1 lukem */
30 1.1 lukem static int
31 1.1 lukem rewrite_parse_builtin_map(
32 1.1 lukem struct rewrite_info *info,
33 1.1 lukem const char *fname,
34 1.1 lukem int lineno,
35 1.1 lukem int argc,
36 1.1 lukem char **argv
37 1.1 lukem );
38 1.1 lukem
39 1.1 lukem /*
40 1.1 lukem * Parses a config line and takes actions to fit content in rewrite structure;
41 1.1 lukem * lines handled are of the form:
42 1.1 lukem *
43 1.1 lukem * rewriteEngine {on|off}
44 1.1 lukem * rewriteMaxPasses numPasses [numPassesPerRule]
45 1.1 lukem * rewriteContext contextName [alias aliasedContextName]
46 1.1 lukem * rewriteRule pattern substPattern [ruleFlags]
47 1.1 lukem * rewriteMap mapType mapName [mapArgs]
48 1.1 lukem * rewriteParam paramName paramValue
49 1.1 lukem */
50 1.1 lukem int
51 1.1 lukem rewrite_parse(
52 1.1 lukem struct rewrite_info *info,
53 1.1 lukem const char *fname,
54 1.1 lukem int lineno,
55 1.1 lukem int argc,
56 1.1 lukem char **argv
57 1.1 lukem )
58 1.1 lukem {
59 1.1 lukem int rc = -1;
60 1.1 lukem
61 1.1 lukem assert( info != NULL );
62 1.1 lukem assert( fname != NULL );
63 1.1 lukem assert( argv != NULL );
64 1.1 lukem assert( argc > 0 );
65 1.1 lukem
66 1.1 lukem /*
67 1.1 lukem * Switch on the rewrite engine
68 1.1 lukem */
69 1.1 lukem if ( strcasecmp( argv[ 0 ], "rewriteEngine" ) == 0 ) {
70 1.1 lukem if ( argc < 2 ) {
71 1.1 lukem Debug( LDAP_DEBUG_ANY,
72 1.1 lukem "[%s:%d] rewriteEngine needs 'state'\n%s",
73 1.1 lukem fname, lineno, "" );
74 1.1 lukem return -1;
75 1.1 lukem
76 1.1 lukem } else if ( argc > 2 ) {
77 1.1 lukem Debug( LDAP_DEBUG_ANY,
78 1.1 lukem "[%s:%d] extra fields in rewriteEngine"
79 1.1 lukem " will be discarded\n%s",
80 1.1 lukem fname, lineno, "" );
81 1.1 lukem }
82 1.1 lukem
83 1.1 lukem if ( strcasecmp( argv[ 1 ], "on" ) == 0 ) {
84 1.1 lukem info->li_state = REWRITE_ON;
85 1.1 lukem
86 1.1 lukem } else if ( strcasecmp( argv[ 1 ], "off" ) == 0 ) {
87 1.1 lukem info->li_state = REWRITE_OFF;
88 1.1 lukem
89 1.1 lukem } else {
90 1.1 lukem Debug( LDAP_DEBUG_ANY,
91 1.1 lukem "[%s:%d] unknown 'state' in rewriteEngine;"
92 1.1 lukem " assuming 'on'\n%s",
93 1.1 lukem fname, lineno, "" );
94 1.1 lukem info->li_state = REWRITE_ON;
95 1.1 lukem }
96 1.1 lukem rc = REWRITE_SUCCESS;
97 1.1 lukem
98 1.1 lukem /*
99 1.1 lukem * Alter max passes
100 1.1 lukem */
101 1.1 lukem } else if ( strcasecmp( argv[ 0 ], "rewriteMaxPasses" ) == 0 ) {
102 1.1 lukem if ( argc < 2 ) {
103 1.1 lukem Debug( LDAP_DEBUG_ANY,
104 1.1 lukem "[%s:%d] rewriteMaxPasses needs 'value'\n%s",
105 1.1 lukem fname, lineno, "" );
106 1.1 lukem return -1;
107 1.1 lukem }
108 1.1 lukem
109 1.1 lukem if ( lutil_atoi( &info->li_max_passes, argv[ 1 ] ) != 0 ) {
110 1.1 lukem Debug( LDAP_DEBUG_ANY,
111 1.1 lukem "[%s:%d] unable to parse rewriteMaxPasses=\"%s\"\n",
112 1.1 lukem fname, lineno, argv[ 1 ] );
113 1.1 lukem return -1;
114 1.1 lukem }
115 1.1 lukem
116 1.1 lukem if ( info->li_max_passes <= 0 ) {
117 1.1 lukem Debug( LDAP_DEBUG_ANY,
118 1.1 lukem "[%s:%d] negative or null rewriteMaxPasses\n",
119 1.1 lukem fname, lineno, 0 );
120 1.1 lukem return -1;
121 1.1 lukem }
122 1.1 lukem
123 1.1 lukem if ( argc > 2 ) {
124 1.1 lukem if ( lutil_atoi( &info->li_max_passes_per_rule, argv[ 2 ] ) != 0 ) {
125 1.1 lukem Debug( LDAP_DEBUG_ANY,
126 1.1 lukem "[%s:%d] unable to parse rewriteMaxPassesPerRule=\"%s\"\n",
127 1.1 lukem fname, lineno, argv[ 2 ] );
128 1.1 lukem return -1;
129 1.1 lukem }
130 1.1 lukem
131 1.1 lukem if ( info->li_max_passes_per_rule <= 0 ) {
132 1.1 lukem Debug( LDAP_DEBUG_ANY,
133 1.1 lukem "[%s:%d] negative or null rewriteMaxPassesPerRule\n",
134 1.1 lukem fname, lineno, 0 );
135 1.1 lukem return -1;
136 1.1 lukem }
137 1.1 lukem
138 1.1 lukem } else {
139 1.1 lukem info->li_max_passes_per_rule = info->li_max_passes;
140 1.1 lukem }
141 1.1 lukem rc = REWRITE_SUCCESS;
142 1.1 lukem
143 1.1 lukem /*
144 1.1 lukem * Start a new rewrite context and set current context
145 1.1 lukem */
146 1.1 lukem } else if ( strcasecmp( argv[ 0 ], "rewriteContext" ) == 0 ) {
147 1.1 lukem if ( argc < 2 ) {
148 1.1 lukem Debug( LDAP_DEBUG_ANY,
149 1.1 lukem "[%s:%d] rewriteContext needs 'name'\n%s",
150 1.1 lukem fname, lineno, "" );
151 1.1 lukem return -1;
152 1.1 lukem }
153 1.1 lukem
154 1.1 lukem /*
155 1.1 lukem * Checks for existence (lots of contexts should be
156 1.1 lukem * available by default ...)
157 1.1 lukem */
158 1.1 lukem rewrite_int_curr_context = rewrite_context_find( info, argv[ 1 ] );
159 1.1 lukem if ( rewrite_int_curr_context == NULL ) {
160 1.1 lukem rewrite_int_curr_context = rewrite_context_create( info,
161 1.1 lukem argv[ 1 ] );
162 1.1 lukem }
163 1.1 lukem if ( rewrite_int_curr_context == NULL ) {
164 1.1 lukem return -1;
165 1.1 lukem }
166 1.1 lukem
167 1.1 lukem if ( argc > 2 ) {
168 1.1 lukem
169 1.1 lukem /*
170 1.1 lukem * A context can alias another (e.g., the `builtin'
171 1.1 lukem * contexts for backend operations, if not defined,
172 1.1 lukem * alias the `default' rewrite context (with the
173 1.1 lukem * notable exception of the searchResult context,
174 1.1 lukem * which can be undefined)
175 1.1 lukem */
176 1.1 lukem if ( strcasecmp( argv[ 2 ], "alias" ) == 0 ) {
177 1.1 lukem struct rewrite_context *aliased;
178 1.1 lukem
179 1.1 lukem if ( argc == 3 ) {
180 1.1 lukem Debug( LDAP_DEBUG_ANY,
181 1.1 lukem "[%s:%d] rewriteContext"
182 1.1 lukem " needs 'name' after"
183 1.1 lukem " 'alias'\n%s",
184 1.1 lukem fname, lineno, "" );
185 1.1 lukem return -1;
186 1.1 lukem
187 1.1 lukem } else if ( argc > 4 ) {
188 1.1 lukem Debug( LDAP_DEBUG_ANY,
189 1.1 lukem "[%s:%d] extra fields in"
190 1.1 lukem " rewriteContext"
191 1.1 lukem " after aliased name"
192 1.1 lukem " will be"
193 1.1 lukem " discarded\n%s",
194 1.1 lukem fname, lineno, "" );
195 1.1 lukem }
196 1.1 lukem
197 1.1 lukem aliased = rewrite_context_find( info,
198 1.1 lukem argv[ 3 ] );
199 1.1 lukem if ( aliased == NULL ) {
200 1.1 lukem Debug( LDAP_DEBUG_ANY,
201 1.1 lukem "[%s:%d] aliased"
202 1.1 lukem " rewriteContext '%s'"
203 1.1 lukem " does not exists\n",
204 1.1 lukem fname, lineno,
205 1.1 lukem argv[ 3 ] );
206 1.1 lukem return -1;
207 1.1 lukem }
208 1.1 lukem
209 1.1 lukem rewrite_int_curr_context->lc_alias = aliased;
210 1.1 lukem rewrite_int_curr_context = aliased;
211 1.1 lukem
212 1.1 lukem } else {
213 1.1 lukem Debug( LDAP_DEBUG_ANY,
214 1.1 lukem "[%s:%d] extra fields"
215 1.1 lukem " in rewriteContext"
216 1.1 lukem " will be discarded\n%s",
217 1.1 lukem fname, lineno, "" );
218 1.1 lukem }
219 1.1 lukem }
220 1.1 lukem rc = REWRITE_SUCCESS;
221 1.1 lukem
222 1.1 lukem /*
223 1.1 lukem * Compile a rule in current context
224 1.1 lukem */
225 1.1 lukem } else if ( strcasecmp( argv[ 0 ], "rewriteRule" ) == 0 ) {
226 1.1 lukem if ( argc < 3 ) {
227 1.1 lukem Debug( LDAP_DEBUG_ANY,
228 1.1 lukem "[%s:%d] rewriteRule needs 'pattern'"
229 1.1 lukem " 'subst' ['flags']\n%s",
230 1.1 lukem fname, lineno, "" );
231 1.1 lukem return -1;
232 1.1 lukem
233 1.1 lukem } else if ( argc > 4 ) {
234 1.1 lukem Debug( LDAP_DEBUG_ANY,
235 1.1 lukem "[%s:%d] extra fields in rewriteRule"
236 1.1 lukem " will be discarded\n%s",
237 1.1 lukem fname, lineno, "" );
238 1.1 lukem }
239 1.1 lukem
240 1.1 lukem if ( rewrite_int_curr_context == NULL ) {
241 1.1 lukem Debug( LDAP_DEBUG_ANY,
242 1.1 lukem "[%s:%d] rewriteRule outside a"
243 1.1 lukem " context; will add to default\n%s",
244 1.1 lukem fname, lineno, "" );
245 1.1 lukem rewrite_int_curr_context = rewrite_context_find( info,
246 1.1 lukem REWRITE_DEFAULT_CONTEXT );
247 1.1 lukem
248 1.1 lukem /*
249 1.1 lukem * Default context MUST exist in a properly initialized
250 1.1 lukem * struct rewrite_info
251 1.1 lukem */
252 1.1 lukem assert( rewrite_int_curr_context != NULL );
253 1.1 lukem }
254 1.1 lukem
255 1.1 lukem rc = rewrite_rule_compile( info, rewrite_int_curr_context, argv[ 1 ],
256 1.1 lukem argv[ 2 ], ( argc == 4 ? argv[ 3 ] : "" ) );
257 1.1 lukem
258 1.1 lukem /*
259 1.1 lukem * Add a plugin map to the map tree
260 1.1 lukem */
261 1.1 lukem } else if ( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 ) {
262 1.1 lukem if ( argc < 3 ) {
263 1.1 lukem Debug( LDAP_DEBUG_ANY,
264 1.1 lukem "[%s:%d] rewriteMap needs at least 'type'"
265 1.1 lukem " and 'name' ['args']\n%s",
266 1.1 lukem fname, lineno, "" );
267 1.1 lukem return -1;
268 1.1 lukem }
269 1.1 lukem
270 1.1 lukem rc = rewrite_parse_builtin_map( info, fname, lineno,
271 1.1 lukem argc, argv );
272 1.1 lukem
273 1.1 lukem /*
274 1.1 lukem * Set the value of a global scope parameter
275 1.1 lukem */
276 1.1 lukem } else if ( strcasecmp( argv[ 0 ], "rewriteParam" ) == 0 ) {
277 1.1 lukem if ( argc < 3 ) {
278 1.1 lukem Debug( LDAP_DEBUG_ANY,
279 1.1 lukem "[%s:%d] rewriteParam needs 'name'"
280 1.1 lukem " and 'value'\n%s",
281 1.1 lukem fname, lineno, "" );
282 1.1 lukem return -1;
283 1.1 lukem }
284 1.1 lukem
285 1.1 lukem rc = rewrite_param_set( info, argv[ 1 ], argv[ 2 ] );
286 1.1 lukem
287 1.1 lukem /*
288 1.1 lukem * Error
289 1.1 lukem */
290 1.1 lukem } else {
291 1.1 lukem Debug( LDAP_DEBUG_ANY,
292 1.1 lukem "[%s:%d] unknown command '%s'\n",
293 1.1 lukem fname, lineno, "" );
294 1.1 lukem return -1;
295 1.1 lukem }
296 1.1 lukem
297 1.1 lukem return rc;
298 1.1 lukem }
299 1.1 lukem
300 1.1 lukem /*
301 1.1 lukem * Compares two maps
302 1.1 lukem */
303 1.1 lukem static int
304 1.1 lukem rewrite_builtin_map_cmp(
305 1.1 lukem const void *c1,
306 1.1 lukem const void *c2
307 1.1 lukem )
308 1.1 lukem {
309 1.1 lukem const struct rewrite_builtin_map *m1, *m2;
310 1.1 lukem
311 1.1 lukem m1 = ( const struct rewrite_builtin_map * )c1;
312 1.1 lukem m2 = ( const struct rewrite_builtin_map * )c2;
313 1.1 lukem
314 1.1 lukem assert( m1 != NULL );
315 1.1 lukem assert( m2 != NULL );
316 1.1 lukem assert( m1->lb_name != NULL );
317 1.1 lukem assert( m2->lb_name != NULL );
318 1.1 lukem
319 1.1 lukem return strcasecmp( m1->lb_name, m2->lb_name );
320 1.1 lukem }
321 1.1 lukem
322 1.1 lukem /*
323 1.1 lukem * Duplicate map ?
324 1.1 lukem */
325 1.1 lukem static int
326 1.1 lukem rewrite_builtin_map_dup(
327 1.1 lukem void *c1,
328 1.1 lukem void *c2
329 1.1 lukem )
330 1.1 lukem {
331 1.1 lukem struct rewrite_builtin_map *m1, *m2;
332 1.1 lukem
333 1.1 lukem m1 = ( struct rewrite_builtin_map * )c1;
334 1.1 lukem m2 = ( struct rewrite_builtin_map * )c2;
335 1.1 lukem
336 1.1 lukem assert( m1 != NULL );
337 1.1 lukem assert( m2 != NULL );
338 1.1 lukem assert( m1->lb_name != NULL );
339 1.1 lukem assert( m2->lb_name != NULL );
340 1.1 lukem
341 1.1 lukem return ( strcasecmp( m1->lb_name, m2->lb_name ) == 0 ? -1 : 0 );
342 1.1 lukem }
343 1.1 lukem
344 1.1 lukem /*
345 1.1 lukem * Adds a map to the info map tree
346 1.1 lukem */
347 1.1 lukem static int
348 1.1 lukem rewrite_builtin_map_insert(
349 1.1 lukem struct rewrite_info *info,
350 1.1 lukem struct rewrite_builtin_map *map
351 1.1 lukem )
352 1.1 lukem {
353 1.1 lukem /*
354 1.1 lukem * May need a mutex?
355 1.1 lukem */
356 1.1 lukem return avl_insert( &info->li_maps, ( caddr_t )map,
357 1.1 lukem rewrite_builtin_map_cmp,
358 1.1 lukem rewrite_builtin_map_dup );
359 1.1 lukem }
360 1.1 lukem
361 1.1 lukem /*
362 1.1 lukem * Retrieves a map
363 1.1 lukem */
364 1.1 lukem struct rewrite_builtin_map *
365 1.1 lukem rewrite_builtin_map_find(
366 1.1 lukem struct rewrite_info *info,
367 1.1 lukem const char *name
368 1.1 lukem )
369 1.1 lukem {
370 1.1 lukem struct rewrite_builtin_map tmp;
371 1.1 lukem
372 1.1 lukem assert( info != NULL );
373 1.1 lukem assert( name != NULL );
374 1.1 lukem
375 1.1 lukem tmp.lb_name = ( char * )name;
376 1.1 lukem
377 1.1 lukem return ( struct rewrite_builtin_map * )avl_find( info->li_maps,
378 1.1 lukem ( caddr_t )&tmp, rewrite_builtin_map_cmp );
379 1.1 lukem }
380 1.1 lukem
381 1.1 lukem /*
382 1.1 lukem * Parses a plugin map
383 1.1 lukem */
384 1.1 lukem static int
385 1.1 lukem rewrite_parse_builtin_map(
386 1.1 lukem struct rewrite_info *info,
387 1.1 lukem const char *fname,
388 1.1 lukem int lineno,
389 1.1 lukem int argc,
390 1.1 lukem char **argv
391 1.1 lukem )
392 1.1 lukem {
393 1.1 lukem struct rewrite_builtin_map *map;
394 1.1 lukem
395 1.1 lukem #define MAP_TYPE 1
396 1.1 lukem #define MAP_NAME 2
397 1.1 lukem
398 1.1 lukem assert( info != NULL );
399 1.1 lukem assert( fname != NULL );
400 1.1 lukem assert( argc > 2 );
401 1.1 lukem assert( argv != NULL );
402 1.1 lukem assert( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 );
403 1.1 lukem
404 1.1 lukem map = calloc( sizeof( struct rewrite_builtin_map ), 1 );
405 1.1 lukem if ( map == NULL ) {
406 1.1 lukem return REWRITE_ERR;
407 1.1 lukem }
408 1.1 lukem
409 1.1 lukem map->lb_name = strdup( argv[ MAP_NAME ] );
410 1.1 lukem if ( map->lb_name == NULL ) {
411 1.1 lukem free( map );
412 1.1 lukem return REWRITE_ERR;
413 1.1 lukem }
414 1.1 lukem
415 1.1 lukem /*
416 1.1 lukem * Built-in ldap map
417 1.1 lukem */
418 1.1 lukem if (( map->lb_mapper = rewrite_mapper_find( argv[ MAP_TYPE ] ))) {
419 1.1 lukem map->lb_type = REWRITE_BUILTIN_MAP;
420 1.1 lukem
421 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
422 1.1 lukem if ( ldap_pvt_thread_mutex_init( & map->lb_mutex ) ) {
423 1.1 lukem free( map->lb_name );
424 1.1 lukem free( map );
425 1.1 lukem return REWRITE_ERR;
426 1.1 lukem }
427 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
428 1.1 lukem
429 1.1 lukem map->lb_private = map->lb_mapper->rm_config( fname, lineno,
430 1.1 lukem argc - 3, argv + 3 );
431 1.1 lukem
432 1.1 lukem /*
433 1.1 lukem * Error
434 1.1 lukem */
435 1.1 lukem } else {
436 1.1 lukem free( map );
437 1.1 lukem Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown map type\n%s",
438 1.1 lukem fname, lineno, "" );
439 1.1 lukem return -1;
440 1.1 lukem }
441 1.1 lukem
442 1.1 lukem return rewrite_builtin_map_insert( info, map );
443 1.1 lukem }
444