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