xref: /netbsd-src/external/bsd/openldap/dist/libraries/librewrite/rewrite-int.h (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1 /*	$NetBSD: rewrite-int.h,v 1.1.1.3 2010/12/12 15:22:13 adam Exp $	*/
2 
3 /* OpenLDAP: pkg/ldap/libraries/librewrite/rewrite-int.h,v 1.20.2.6 2010/04/13 20:23:08 kurt Exp */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 2000-2010 The OpenLDAP Foundation.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in the file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* ACKNOWLEDGEMENT:
18  * This work was initially developed by Pierangelo Masarati for
19  * inclusion in OpenLDAP Software.
20  */
21 
22 #ifndef REWRITE_INT_H
23 #define REWRITE_INT_H
24 
25 /*
26  * These are required by every file of the library, so they're included here
27  */
28 #include <ac/stdlib.h>
29 #include <ac/string.h>
30 #include <ac/syslog.h>
31 #include <ac/regex.h>
32 #include <ac/socket.h>
33 #include <ac/unistd.h>
34 #include <ac/ctype.h>
35 
36 #include <lber.h>
37 #include <ldap.h>
38 #include "../libldap/ldap-int.h"
39 #include <lutil.h>
40 #include <avl.h>
41 
42 #include <rewrite.h>
43 
44 #define malloc(x)	ber_memalloc(x)
45 #define calloc(x,y)	ber_memcalloc(x,y)
46 #define realloc(x,y)	ber_memrealloc(x,y)
47 #define free(x)	ber_memfree(x)
48 #undef strdup
49 #define	strdup(x)	ber_strdup(x)
50 
51 /* Uncomment to use ldap pvt threads */
52 #define USE_REWRITE_LDAP_PVT_THREADS
53 #include <ldap_pvt_thread.h>
54 
55 /*
56  * For details, see RATIONALE.
57  */
58 
59 #define REWRITE_MAX_MATCH	11	/* 0: overall string; 1-9: submatches */
60 #define REWRITE_MAX_PASSES	100
61 
62 /*
63  * Submatch escape char
64  */
65 /* the '\' conflicts with slapd.conf parsing */
66 /* #define REWRITE_SUBMATCH_ESCAPE			'\\' */
67 #define REWRITE_SUBMATCH_ESCAPE_ORIG		'%'
68 #define REWRITE_SUBMATCH_ESCAPE			'$'
69 #define IS_REWRITE_SUBMATCH_ESCAPE(c) \
70 	((c) == REWRITE_SUBMATCH_ESCAPE || (c) == REWRITE_SUBMATCH_ESCAPE_ORIG)
71 
72 /*
73  * REGEX flags
74  */
75 
76 #define REWRITE_FLAG_HONORCASE			'C'
77 #define REWRITE_FLAG_BASICREGEX			'R'
78 
79 /*
80  * Action flags
81  */
82 #define REWRITE_FLAG_EXECONCE			':'
83 #define REWRITE_FLAG_STOP			'@'
84 #define REWRITE_FLAG_UNWILLING			'#'
85 #define REWRITE_FLAG_GOTO			'G'	/* requires an arg */
86 #define REWRITE_FLAG_USER			'U'	/* requires an arg */
87 #define REWRITE_FLAG_MAX_PASSES			'M'	/* requires an arg */
88 #define REWRITE_FLAG_IGNORE_ERR			'I'
89 
90 /*
91  * Map operators
92  */
93 #define REWRITE_OPERATOR_SUBCONTEXT		'>'
94 #define REWRITE_OPERATOR_COMMAND		'|'
95 #define REWRITE_OPERATOR_VARIABLE_SET		'&'
96 #define REWRITE_OPERATOR_VARIABLE_GET		'*'
97 #define REWRITE_OPERATOR_PARAM_GET		'$'
98 
99 
100 /***********
101  * PRIVATE *
102  ***********/
103 
104 /*
105  * Action
106  */
107 struct rewrite_action {
108 	struct rewrite_action          *la_next;
109 
110 #define REWRITE_ACTION_STOP		0x0001
111 #define REWRITE_ACTION_UNWILLING	0x0002
112 #define REWRITE_ACTION_GOTO		0x0003
113 #define REWRITE_ACTION_IGNORE_ERR	0x0004
114 #define REWRITE_ACTION_USER		0x0005
115 	int                             la_type;
116 	void                           *la_args;
117 };
118 
119 /*
120  * Map
121  */
122 struct rewrite_map {
123 
124 	/*
125 	 * Legacy stuff
126 	 */
127 #define REWRITE_MAP_XFILEMAP		0x0001	/* Rough implementation! */
128 #define REWRITE_MAP_XPWDMAP		0x0002  /* uid -> gecos */
129 #define REWRITE_MAP_XLDAPMAP		0x0003	/* Not implemented yet! */
130 
131 	/*
132 	 * Maps with args
133 	 */
134 #define REWRITE_MAP_SUBCONTEXT		0x0101
135 
136 #define REWRITE_MAP_SET_OP_VAR		0x0102
137 #define REWRITE_MAP_SETW_OP_VAR		0x0103
138 #define REWRITE_MAP_GET_OP_VAR		0x0104
139 #define	REWRITE_MAP_SET_SESN_VAR	0x0105
140 #define REWRITE_MAP_SETW_SESN_VAR	0x0106
141 #define	REWRITE_MAP_GET_SESN_VAR	0x0107
142 #define REWRITE_MAP_GET_PARAM		0x0108
143 #define REWRITE_MAP_BUILTIN		0x0109
144 	int                             lm_type;
145 
146 	char                           *lm_name;
147 	void                           *lm_data;
148 
149 	/*
150 	 * Old maps store private data in _lm_args;
151 	 * new maps store the substitution pattern in _lm_subst
152 	 */
153 	union {
154 	        void                   *_lm_args;
155 		struct rewrite_subst   *_lm_subst;
156 	} lm_union;
157 #define	lm_args lm_union._lm_args
158 #define	lm_subst lm_union._lm_subst
159 
160 #ifdef USE_REWRITE_LDAP_PVT_THREADS
161 	ldap_pvt_thread_mutex_t         lm_mutex;
162 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
163 };
164 
165 /*
166  * Builtin maps
167  */
168 struct rewrite_builtin_map {
169 #define REWRITE_BUILTIN_MAP	0x0200
170 	int                             lb_type;
171 	char                           *lb_name;
172 	void                           *lb_private;
173 	const rewrite_mapper		   *lb_mapper;
174 
175 #ifdef USE_REWRITE_LDAP_PVT_THREADS
176 	ldap_pvt_thread_mutex_t         lb_mutex;
177 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
178 };
179 
180 /*
181  * Submatch substitution
182  */
183 struct rewrite_submatch {
184 #define REWRITE_SUBMATCH_ASIS		0x0000
185 #define REWRITE_SUBMATCH_XMAP		0x0001
186 #define REWRITE_SUBMATCH_MAP_W_ARG	0x0002
187 	int                             ls_type;
188 	struct rewrite_map             *ls_map;
189 	int                             ls_submatch;
190 	/*
191 	 * The first one represents the index of the submatch in case
192 	 * the map has single submatch as argument;
193 	 * the latter represents the map argument scheme in case
194 	 * the map has substitution string argument form
195 	 */
196 };
197 
198 /*
199  * Pattern substitution
200  */
201 struct rewrite_subst {
202 	size_t                          lt_subs_len;
203 	struct berval                  *lt_subs;
204 
205 	int                             lt_num_submatch;
206 	struct rewrite_submatch        *lt_submatch;
207 };
208 
209 /*
210  * Rule
211  */
212 struct rewrite_rule {
213 	struct rewrite_rule            *lr_next;
214 	struct rewrite_rule            *lr_prev;
215 
216 	char                           *lr_pattern;
217 	char                           *lr_subststring;
218 	char                           *lr_flagstring;
219 	regex_t				lr_regex;
220 
221 	/*
222 	 * I was thinking about some kind of per-rule mutex, but there's
223 	 * probably no need, because rules after compilation are only read;
224 	 * however, I need to check whether regexec is reentrant ...
225 	 */
226 
227 	struct rewrite_subst           *lr_subst;
228 
229 #define REWRITE_REGEX_ICASE		REG_ICASE
230 #define REWRITE_REGEX_EXTENDED		REG_EXTENDED
231 	int                             lr_flags;
232 
233 #define REWRITE_RECURSE			0x0001
234 #define REWRITE_EXEC_ONCE          	0x0002
235 	int				lr_mode;
236 	int				lr_max_passes;
237 
238 	struct rewrite_action          *lr_action;
239 };
240 
241 /*
242  * Rewrite Context (set of rules)
243  */
244 struct rewrite_context {
245 	char                           *lc_name;
246 	struct rewrite_context         *lc_alias;
247 	struct rewrite_rule            *lc_rule;
248 };
249 
250 /*
251  * Session
252  */
253 struct rewrite_session {
254 	void                           *ls_cookie;
255 	Avlnode                        *ls_vars;
256 #ifdef USE_REWRITE_LDAP_PVT_THREADS
257 	ldap_pvt_thread_rdwr_t          ls_vars_mutex;
258 	ldap_pvt_thread_mutex_t		ls_mutex;
259 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
260 	int				ls_count;
261 };
262 
263 /*
264  * Variable
265  */
266 struct rewrite_var {
267 	char                           *lv_name;
268 	int				lv_flags;
269 	struct berval                   lv_value;
270 };
271 
272 /*
273  * Operation
274  */
275 struct rewrite_op {
276 	int                             lo_num_passes;
277 	int                             lo_depth;
278 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
279 	char                           *lo_string;
280 #endif
281 	char                           *lo_result;
282 	Avlnode                        *lo_vars;
283 	const void                     *lo_cookie;
284 };
285 
286 
287 /**********
288  * PUBLIC *
289  **********/
290 
291 /*
292  * Rewrite info
293  */
294 struct rewrite_info {
295 	Avlnode                        *li_context;
296 	Avlnode                        *li_maps;
297 	/*
298 	 * No global mutex because maps are read only at
299 	 * config time
300 	 */
301 	Avlnode                        *li_params;
302 	Avlnode                        *li_cookies;
303 	int                             li_num_cookies;
304 
305 #ifdef USE_REWRITE_LDAP_PVT_THREADS
306 	ldap_pvt_thread_rdwr_t          li_params_mutex;
307         ldap_pvt_thread_rdwr_t          li_cookies_mutex;
308 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
309 
310 	/*
311 	 * Default to `off';
312 	 * use `rewriteEngine {on|off}' directive to alter
313 	 */
314 	int				li_state;
315 
316 	/*
317 	 * Defaults to REWRITE_MAXPASSES;
318 	 * use `rewriteMaxPasses numPasses' directive to alter
319 	 */
320 #define REWRITE_MAXPASSES		100
321 	int                             li_max_passes;
322 	int                             li_max_passes_per_rule;
323 
324 	/*
325 	 * Behavior in case a NULL or non-existent context is required
326 	 */
327 	int                             li_rewrite_mode;
328 };
329 
330 /***********
331  * PRIVATE *
332  ***********/
333 
334 LDAP_REWRITE_V (struct rewrite_context*) rewrite_int_curr_context;
335 
336 /*
337  * Maps
338  */
339 
340 /*
341  * Parses a map (also in legacy 'x' version)
342  */
343 LDAP_REWRITE_F (struct rewrite_map *)
344 rewrite_map_parse(
345 		struct rewrite_info *info,
346 		const char *s,
347 		const char **end
348 );
349 
350 LDAP_REWRITE_F (struct rewrite_map *)
351 rewrite_xmap_parse(
352 		struct rewrite_info *info,
353 		const char *s,
354 		const char **end
355 );
356 
357 /*
358  * Resolves key in val by means of map (also in legacy 'x' version)
359  */
360 LDAP_REWRITE_F (int)
361 rewrite_map_apply(
362 		struct rewrite_info *info,
363 		struct rewrite_op *op,
364 		struct rewrite_map *map,
365 		struct berval *key,
366 		struct berval *val
367 );
368 
369 LDAP_REWRITE_F (int)
370 rewrite_xmap_apply(
371 		struct rewrite_info *info,
372 		struct rewrite_op *op,
373 		struct rewrite_map *map,
374 		struct berval *key,
375 		struct berval *val
376 );
377 
378 LDAP_REWRITE_F (int)
379 rewrite_map_destroy(
380 		struct rewrite_map **map
381 );
382 
383 LDAP_REWRITE_F (int)
384 rewrite_xmap_destroy(
385 		struct rewrite_map **map
386 );
387 
388 LDAP_REWRITE_F (void)
389 rewrite_builtin_map_free(
390 		void *map
391 );
392 /*
393  * Submatch substitution
394  */
395 
396 /*
397  * Compiles a substitution pattern
398  */
399 LDAP_REWRITE_F (struct rewrite_subst *)
400 rewrite_subst_compile(
401 		struct rewrite_info *info,
402 		const char *result
403 );
404 
405 /*
406  * Substitutes a portion of rewritten string according to substitution
407  * pattern using submatches
408  */
409 LDAP_REWRITE_F (int)
410 rewrite_subst_apply(
411 		struct rewrite_info *info,
412 		struct rewrite_op *op,
413 		struct rewrite_subst *subst,
414 		const char *string,
415 		const regmatch_t *match,
416 		struct berval *val
417 );
418 
419 LDAP_REWRITE_F (int)
420 rewrite_subst_destroy(
421 		struct rewrite_subst **subst
422 );
423 
424 
425 /*
426  * Rules
427  */
428 
429 /*
430  * Compiles the rule and appends it at the running context
431  */
432 LDAP_REWRITE_F (int)
433 rewrite_rule_compile(
434 		struct rewrite_info *info,
435 		struct rewrite_context *context,
436 		const char *pattern,
437 		const char *result,
438 		const char *flagstring
439 );
440 
441 /*
442  * Rewrites string according to rule; may return:
443  *      REWRITE_REGEXEC_OK:	fine; if *result != NULL rule matched
444  *      			and rewrite succeeded.
445  *      REWRITE_REGEXEC_STOP:   fine, rule matched; stop processing
446  *      			following rules
447  *      REWRITE_REGEXEC_UNWILL: rule matched; force 'unwilling to perform'
448  *      REWRITE_REGEXEC_ERR:	an error occurred
449  */
450 LDAP_REWRITE_F (int)
451 rewrite_rule_apply(
452 		struct rewrite_info *info,
453 		struct rewrite_op *op,
454 		struct rewrite_rule *rule,
455 		const char *string,
456 		char **result
457 );
458 
459 LDAP_REWRITE_F (int)
460 rewrite_rule_destroy(
461 		struct rewrite_rule **rule
462 );
463 
464 /*
465  * Sessions
466  */
467 
468 /*
469  * Fetches a struct rewrite_session
470  */
471 LDAP_REWRITE_F (struct rewrite_session *)
472 rewrite_session_find(
473                 struct rewrite_info *info,
474                 const void *cookie
475 );
476 
477 /*
478  * Defines and inits a variable with session scope
479  */
480 LDAP_REWRITE_F (int)
481 rewrite_session_var_set_f(
482                 struct rewrite_info *info,
483                 const void *cookie,
484                 const char *name,
485                 const char *value,
486 		int flags
487 );
488 
489 /*
490  * Gets a var with session scope
491  */
492 LDAP_REWRITE_F (int)
493 rewrite_session_var_get(
494                 struct rewrite_info *info,
495                 const void *cookie,
496                 const char *name,
497                 struct berval *val
498 );
499 
500 /*
501  * Deletes a session
502  */
503 LDAP_REWRITE_F (int)
504 rewrite_session_delete(
505                 struct rewrite_info *info,
506                 const void *cookie
507 );
508 
509 /*
510  * Destroys the cookie tree
511  */
512 LDAP_REWRITE_F (int)
513 rewrite_session_destroy(
514                 struct rewrite_info *info
515 );
516 
517 
518 /*
519  * Vars
520  */
521 
522 /*
523  * Finds a var
524  */
525 LDAP_REWRITE_F (struct rewrite_var *)
526 rewrite_var_find(
527                 Avlnode *tree,
528                 const char *name
529 );
530 
531 /*
532  * Replaces the value of a variable
533  */
534 LDAP_REWRITE_F (int)
535 rewrite_var_replace(
536 		struct rewrite_var *var,
537 		const char *value,
538 		int flags
539 );
540 
541 /*
542  * Inserts a newly created var
543  */
544 LDAP_REWRITE_F (struct rewrite_var *)
545 rewrite_var_insert_f(
546                 Avlnode **tree,
547                 const char *name,
548                 const char *value,
549 		int flags
550 );
551 
552 #define rewrite_var_insert(tree, name, value) \
553 	rewrite_var_insert_f((tree), (name), (value), \
554 			REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE)
555 
556 /*
557  * Sets/inserts a var
558  */
559 LDAP_REWRITE_F (struct rewrite_var *)
560 rewrite_var_set_f(
561                 Avlnode **tree,
562                 const char *name,
563                 const char *value,
564                 int flags
565 );
566 
567 #define rewrite_var_set(tree, name, value, insert) \
568 	rewrite_var_set_f((tree), (name), (value), \
569 			REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE|((insert)? REWRITE_VAR_INSERT : 0))
570 
571 /*
572  * Deletes a var tree
573  */
574 LDAP_REWRITE_F (int)
575 rewrite_var_delete(
576                 Avlnode *tree
577 );
578 
579 
580 /*
581  * Contexts
582  */
583 
584 /*
585  * Finds the context named rewriteContext in the context tree
586  */
587 LDAP_REWRITE_F (struct rewrite_context *)
588 rewrite_context_find(
589 		struct rewrite_info *info,
590 		const char *rewriteContext
591 );
592 
593 /*
594  * Creates a new context called rewriteContext and stores in into the tree
595  */
596 LDAP_REWRITE_F (struct rewrite_context *)
597 rewrite_context_create(
598 		struct rewrite_info *info,
599 		const char *rewriteContext
600 );
601 
602 /*
603  * Rewrites string according to context; may return:
604  *      OK:     fine; if *result != NULL rule matched and rewrite succeeded.
605  *      STOP:   fine, rule matched; stop processing following rules
606  *      UNWILL: rule matched; force 'unwilling to perform'
607  */
608 LDAP_REWRITE_F (int)
609 rewrite_context_apply(
610 		struct rewrite_info *info,
611 		struct rewrite_op *op,
612 		struct rewrite_context *context,
613 		const char *string,
614 		char **result
615 );
616 
617 LDAP_REWRITE_F (int)
618 rewrite_context_destroy(
619 		struct rewrite_context **context
620 );
621 
622 LDAP_REWRITE_F (void)
623 rewrite_context_free(
624 		void *tmp
625 );
626 
627 #endif /* REWRITE_INT_H */
628 
629