]> git.sur5r.net Git - openldap/blob - libraries/librewrite/rewrite-int.h
1886227f4cb4efddd8b0133447d48fc45183f2f3
[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 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
247 };
248
249 /*
250  * Variable
251  */
252 struct rewrite_var {
253         char                           *lv_name;
254         struct berval                   lv_value;
255 };
256
257 /*
258  * Operation
259  */
260 struct rewrite_op {
261         int                             lo_num_passes;
262         int                             lo_depth;
263         char                           *lo_string;
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_V (struct rewrite_context*) __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
361 /*
362  * Submatch substitution
363  */
364
365 /*
366  * Compiles a substitution pattern
367  */
368 LDAP_REWRITE_F (struct rewrite_subst *)
369 rewrite_subst_compile(
370                 struct rewrite_info *info,
371                 const char *result
372 );
373
374 /*
375  * Substitutes a portion of rewritten string according to substitution
376  * pattern using submatches
377  */
378 LDAP_REWRITE_F (int)
379 rewrite_subst_apply(
380                 struct rewrite_info *info,
381                 struct rewrite_op *op,
382                 struct rewrite_subst *subst,
383                 const char *string,
384                 const regmatch_t *match,
385                 struct berval *val
386 );
387
388
389 /*
390  * Rules
391  */
392
393 /*
394  * Compiles the rule and appends it at the running context
395  */
396 LDAP_REWRITE_F (int)
397 rewrite_rule_compile(
398                 struct rewrite_info *info,
399                 struct rewrite_context *context,
400                 const char *pattern,
401                 const char *result,
402                 const char *flagstring
403 );
404
405 /*
406  * Rewrites string according to rule; may return:
407  *      REWRITE_REGEXEC_OK:     fine; if *result != NULL rule matched
408  *                              and rewrite succeeded.
409  *      REWRITE_REGEXEC_STOP:   fine, rule matched; stop processing
410  *                              following rules
411  *      REWRITE_REGEXEC_UNWILL: rule matched; force 'unwilling to perform'
412  *      REWRITE_REGEXEC_ERR:    an error occurred
413  */
414 LDAP_REWRITE_F (int)
415 rewrite_rule_apply(
416                 struct rewrite_info *info,
417                 struct rewrite_op *op,
418                 struct rewrite_rule *rule,
419                 const char *string,
420                 char **result
421 );
422
423 /*
424  * Sessions
425  */
426
427 /*
428  * Fetches a struct rewrite_session
429  */
430 LDAP_REWRITE_F (struct rewrite_session *)
431 rewrite_session_find(
432                 struct rewrite_info *info,
433                 const void *cookie
434 );
435
436 /*
437  * Defines and inits a variable with session scope
438  */
439 LDAP_REWRITE_F (int)
440 rewrite_session_var_set(
441                 struct rewrite_info *info,
442                 const void *cookie,
443                 const char *name,
444                 const char *value
445 );
446
447 /*
448  * Gets a var with session scope
449  */
450 LDAP_REWRITE_F (int)
451 rewrite_session_var_get(
452                 struct rewrite_info *info,
453                 const void *cookie,
454                 const char *name,
455                 struct berval *val
456 );
457
458 /*
459  * Deletes a session
460  */
461 LDAP_REWRITE_F (int)
462 rewrite_session_delete(
463                 struct rewrite_info *info,
464                 const void *cookie
465 );
466
467 /*
468  * Destroys the cookie tree
469  */
470 LDAP_REWRITE_F (int)
471 rewrite_session_destroy(
472                 struct rewrite_info *info
473 );
474
475
476 /*
477  * Vars
478  */
479
480 /*
481  * Finds a var
482  */
483 LDAP_REWRITE_F (struct rewrite_var *)
484 rewrite_var_find(
485                 Avlnode *tree,
486                 const char *name
487 );
488
489 /*
490  * Inserts a newly created var
491  */
492 LDAP_REWRITE_F (struct rewrite_var *)
493 rewrite_var_insert(
494                 Avlnode **tree,
495                 const char *name,
496                 const char *value
497 );
498
499 /*
500  * Sets/inserts a var
501  */
502 LDAP_REWRITE_F (struct rewrite_var *)
503 rewrite_var_set(
504                 Avlnode **tree,
505                 const char *name,
506                 const char *value,
507                 int insert
508 );
509
510 /*
511  * Deletes a var tree
512  */
513 LDAP_REWRITE_F (int)
514 rewrite_var_delete(
515                 Avlnode *tree
516 );
517
518
519 /*
520  * Contexts
521  */
522
523 /*
524  * Finds the context named rewriteContext in the context tree
525  */
526 LDAP_REWRITE_F (struct rewrite_context *)
527 rewrite_context_find(
528                 struct rewrite_info *info,
529                 const char *rewriteContext
530 );
531
532 /*
533  * Creates a new context called rewriteContext and stores in into the tree
534  */
535 LDAP_REWRITE_F (struct rewrite_context *)
536 rewrite_context_create(
537                 struct rewrite_info *info,
538                 const char *rewriteContext
539 );
540
541 /*
542  * Rewrites string according to context; may return:
543  *      OK:     fine; if *result != NULL rule matched and rewrite succeeded.
544  *      STOP:   fine, rule matched; stop processing following rules
545  *      UNWILL: rule matched; force 'unwilling to perform'
546  */
547 LDAP_REWRITE_F (int)
548 rewrite_context_apply(
549                 struct rewrite_info *info,
550                 struct rewrite_op *op,
551                 struct rewrite_context *context,
552                 const char *string,
553                 char **result
554 );
555
556 #endif /* REWRITE_INT_H */
557