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