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