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