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