]> git.sur5r.net Git - openldap/blob - libraries/librewrite/rewrite-int.h
4b5a60bee262ecabf8ba0e82f2adff61088af4f7
[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 #ifdef USE_REWRITE_LDAP_PVT_THREADS
210         ldap_pvt_thread_mutex_t         lr_mutex;
211 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
212         regex_t                         lr_regex;
213
214         /*
215          * I was thinking about some kind of per-rule mutex, but there's
216          * probably no need, because rules after compilation are only read;
217          * however, I need to check whether regexec is reentrant ...
218          */
219
220         struct rewrite_subst           *lr_subst;
221         
222 #define REWRITE_REGEX_ICASE             REG_ICASE
223 #define REWRITE_REGEX_EXTENDED          REG_EXTENDED    
224         int                             lr_flags;
225
226 #define REWRITE_RECURSE                 0x0001
227 #define REWRITE_EXEC_ONCE               0x0002
228         int                             lr_mode;
229         int                             lr_max_passes;
230
231         struct rewrite_action          *lr_action;
232 };
233
234 /*
235  * Rewrite Context (set of rules)
236  */
237 struct rewrite_context {
238         char                           *lc_name;
239         struct rewrite_context         *lc_alias;
240         struct rewrite_rule            *lc_rule;
241 };
242
243 /*
244  * Session
245  */
246 struct rewrite_session {
247         void                           *ls_cookie;
248         Avlnode                        *ls_vars;
249 #ifdef USE_REWRITE_LDAP_PVT_THREADS
250         ldap_pvt_thread_rdwr_t          ls_vars_mutex;
251         ldap_pvt_thread_mutex_t         ls_mutex;
252 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
253         int                             ls_count;
254 };
255
256 /*
257  * Variable
258  */
259 struct rewrite_var {
260         char                           *lv_name;
261         int                             lv_flags;
262         struct berval                   lv_value;
263 };
264
265 /*
266  * Operation
267  */
268 struct rewrite_op {
269         int                             lo_num_passes;
270         int                             lo_depth;
271 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
272         char                           *lo_string;
273 #endif
274         char                           *lo_result;
275         Avlnode                        *lo_vars;
276         const void                     *lo_cookie;
277 };
278
279
280 /**********
281  * PUBLIC *
282  **********/
283
284 /*
285  * Rewrite info
286  */
287 struct rewrite_info {
288         Avlnode                        *li_context;
289         Avlnode                        *li_maps;
290         /*
291          * No global mutex because maps are read only at 
292          * config time
293          */
294         Avlnode                        *li_params;
295         Avlnode                        *li_cookies;
296         int                             li_num_cookies;
297
298 #ifdef USE_REWRITE_LDAP_PVT_THREADS
299         ldap_pvt_thread_rdwr_t          li_params_mutex;
300         ldap_pvt_thread_rdwr_t          li_cookies_mutex;
301 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
302
303         /*
304          * Default to `off';
305          * use `rewriteEngine {on|off}' directive to alter
306          */
307         int                             li_state;
308
309         /*
310          * Defaults to REWRITE_MAXPASSES;
311          * use `rewriteMaxPasses numPasses' directive to alter
312          */
313 #define REWRITE_MAXPASSES               100
314         int                             li_max_passes;
315         int                             li_max_passes_per_rule;
316
317         /*
318          * Behavior in case a NULL or non-existent context is required
319          */
320         int                             li_rewrite_mode;
321 };
322
323 /***********
324  * PRIVATE *
325  ***********/
326
327 LDAP_REWRITE_V (struct rewrite_context*) rewrite_int_curr_context;
328
329 /*
330  * Maps
331  */
332
333 /*
334  * Parses a map (also in legacy 'x' version)
335  */
336 LDAP_REWRITE_F (struct rewrite_map *)
337 rewrite_map_parse(
338                 struct rewrite_info *info,
339                 const char *s,
340                 const char **end
341 );
342
343 LDAP_REWRITE_F (struct rewrite_map *)
344 rewrite_xmap_parse(
345                 struct rewrite_info *info,
346                 const char *s,
347                 const char **end
348 );
349
350 /*
351  * Resolves key in val by means of map (also in legacy 'x' version)
352  */
353 LDAP_REWRITE_F (int)
354 rewrite_map_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_xmap_apply(
364                 struct rewrite_info *info,
365                 struct rewrite_op *op,
366                 struct rewrite_map *map,
367                 struct berval *key,
368                 struct berval *val
369 );
370
371 LDAP_REWRITE_F (int)
372 rewrite_map_destroy(
373                 struct rewrite_map **map
374 );
375
376 LDAP_REWRITE_F (int)
377 rewrite_xmap_destroy(
378                 struct rewrite_map **map
379 );
380
381 LDAP_REWRITE_F (void)
382 rewrite_builtin_map_free(
383                 void *map
384 );
385 /*
386  * Submatch substitution
387  */
388
389 /*
390  * Compiles a substitution pattern
391  */
392 LDAP_REWRITE_F (struct rewrite_subst *)
393 rewrite_subst_compile(
394                 struct rewrite_info *info,
395                 const char *result
396 );
397
398 /*
399  * Substitutes a portion of rewritten string according to substitution
400  * pattern using submatches
401  */
402 LDAP_REWRITE_F (int)
403 rewrite_subst_apply(
404                 struct rewrite_info *info,
405                 struct rewrite_op *op,
406                 struct rewrite_subst *subst,
407                 const char *string,
408                 const regmatch_t *match,
409                 struct berval *val
410 );
411
412 LDAP_REWRITE_F (int)
413 rewrite_subst_destroy(
414                 struct rewrite_subst **subst
415 );
416
417
418 /*
419  * Rules
420  */
421
422 /*
423  * Compiles the rule and appends it at the running context
424  */
425 LDAP_REWRITE_F (int)
426 rewrite_rule_compile(
427                 struct rewrite_info *info,
428                 struct rewrite_context *context,
429                 const char *pattern,
430                 const char *result,
431                 const char *flagstring
432 );
433
434 /*
435  * Rewrites string according to rule; may return:
436  *      REWRITE_REGEXEC_OK:     fine; if *result != NULL rule matched
437  *                              and rewrite succeeded.
438  *      REWRITE_REGEXEC_STOP:   fine, rule matched; stop processing
439  *                              following rules
440  *      REWRITE_REGEXEC_UNWILL: rule matched; force 'unwilling to perform'
441  *      REWRITE_REGEXEC_ERR:    an error occurred
442  */
443 LDAP_REWRITE_F (int)
444 rewrite_rule_apply(
445                 struct rewrite_info *info,
446                 struct rewrite_op *op,
447                 struct rewrite_rule *rule,
448                 const char *string,
449                 char **result
450 );
451
452 LDAP_REWRITE_F (int)
453 rewrite_rule_destroy(
454                 struct rewrite_rule **rule
455 );
456
457 /*
458  * Sessions
459  */
460
461 /*
462  * Fetches a struct rewrite_session
463  */
464 LDAP_REWRITE_F (struct rewrite_session *)
465 rewrite_session_find(
466                 struct rewrite_info *info,
467                 const void *cookie
468 );
469
470 /*
471  * Defines and inits a variable with session scope
472  */
473 LDAP_REWRITE_F (int)
474 rewrite_session_var_set_f(
475                 struct rewrite_info *info,
476                 const void *cookie,
477                 const char *name,
478                 const char *value,
479                 int flags
480 );
481
482 /*
483  * Gets a var with session scope
484  */
485 LDAP_REWRITE_F (int)
486 rewrite_session_var_get(
487                 struct rewrite_info *info,
488                 const void *cookie,
489                 const char *name,
490                 struct berval *val
491 );
492
493 /*
494  * Deletes a session
495  */
496 LDAP_REWRITE_F (int)
497 rewrite_session_delete(
498                 struct rewrite_info *info,
499                 const void *cookie
500 );
501
502 /*
503  * Destroys the cookie tree
504  */
505 LDAP_REWRITE_F (int)
506 rewrite_session_destroy(
507                 struct rewrite_info *info
508 );
509
510
511 /*
512  * Vars
513  */
514
515 /*
516  * Finds a var
517  */
518 LDAP_REWRITE_F (struct rewrite_var *)
519 rewrite_var_find(
520                 Avlnode *tree,
521                 const char *name
522 );
523
524 /*
525  * Replaces the value of a variable
526  */
527 LDAP_REWRITE_F (int)
528 rewrite_var_replace(
529                 struct rewrite_var *var,
530                 const char *value,
531                 int flags
532 );
533
534 /*
535  * Inserts a newly created var
536  */
537 LDAP_REWRITE_F (struct rewrite_var *)
538 rewrite_var_insert_f(
539                 Avlnode **tree,
540                 const char *name,
541                 const char *value,
542                 int flags
543 );
544
545 #define rewrite_var_insert(tree, name, value) \
546         rewrite_var_insert_f((tree), (name), (value), \
547                         REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE)
548
549 /*
550  * Sets/inserts a var
551  */
552 LDAP_REWRITE_F (struct rewrite_var *)
553 rewrite_var_set_f(
554                 Avlnode **tree,
555                 const char *name,
556                 const char *value,
557                 int flags
558 );
559
560 #define rewrite_var_set(tree, name, value, insert) \
561         rewrite_var_set_f((tree), (name), (value), \
562                         REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE|((insert)? REWRITE_VAR_INSERT : 0))
563
564 /*
565  * Deletes a var tree
566  */
567 LDAP_REWRITE_F (int)
568 rewrite_var_delete(
569                 Avlnode *tree
570 );
571
572
573 /*
574  * Contexts
575  */
576
577 /*
578  * Finds the context named rewriteContext in the context tree
579  */
580 LDAP_REWRITE_F (struct rewrite_context *)
581 rewrite_context_find(
582                 struct rewrite_info *info,
583                 const char *rewriteContext
584 );
585
586 /*
587  * Creates a new context called rewriteContext and stores in into the tree
588  */
589 LDAP_REWRITE_F (struct rewrite_context *)
590 rewrite_context_create(
591                 struct rewrite_info *info,
592                 const char *rewriteContext
593 );
594
595 /*
596  * Rewrites string according to context; may return:
597  *      OK:     fine; if *result != NULL rule matched and rewrite succeeded.
598  *      STOP:   fine, rule matched; stop processing following rules
599  *      UNWILL: rule matched; force 'unwilling to perform'
600  */
601 LDAP_REWRITE_F (int)
602 rewrite_context_apply(
603                 struct rewrite_info *info,
604                 struct rewrite_op *op,
605                 struct rewrite_context *context,
606                 const char *string,
607                 char **result
608 );
609
610 LDAP_REWRITE_F (int)
611 rewrite_context_destroy(
612                 struct rewrite_context **context
613 );
614
615 LDAP_REWRITE_F (void)
616 rewrite_context_free(
617                 void *tmp
618 );
619
620 #endif /* REWRITE_INT_H */
621