]> git.sur5r.net Git - openldap/blob - libraries/librewrite/rewrite-int.h
This is the commit of:
[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/syslog.h>
33 #include <ac/regex.h>
34 #include <ac/socket.h>
35 #include <ac/unistd.h>
36 #include <ac/ctype.h>
37
38 #include <lber.h>
39 #include <ldap.h>
40 #include "../libldap/ldap-int.h"
41
42 #include <avl.h>
43
44 #include <rewrite.h>
45
46 /* Uncomment to use ldap pvt threads */
47 #define USE_REWRITE_LDAP_PVT_THREADS
48 #include <ldap_pvt_thread.h>
49
50 /*
51  * For details, see RATIONALE.
52  */
53
54 #define REWRITE_MAX_MATCH       11      /* 0: overall string; 1-9: submatches */
55 #define REWRITE_MAX_PASSES      100
56
57 /*
58  * Submatch escape char
59  */
60 //#define REWRITE_SUBMATCH_ESCAPE                       '\\'
61 #define REWRITE_SUBMATCH_ESCAPE                 '%'
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_IGNORE_ERR                 'I'
78
79 /*
80  * Map operators
81  */
82 #define REWRITE_OPERATOR_SUBCONTEXT             '>'
83 #define REWRITE_OPERATOR_COMMAND                '|'
84 #define REWRITE_OPERATOR_VARIABLE_SET           '&'
85 #define REWRITE_OPERATOR_VARIABLE_GET           '*'
86 #define REWRITE_OPERATOR_PARAM_GET              '$'
87
88
89 /***********
90  * PRIVATE *
91  ***********/
92
93 /*
94  * Action
95  */
96 struct rewrite_action {
97         struct rewrite_action          *la_next;
98         
99 #define REWRITE_ACTION_STOP             0x0001
100 #define REWRITE_ACTION_UNWILLING        0x0002
101 #define REWRITE_ACTION_GOTO             0x0003
102 #define REWRITE_ACTION_IGNORE_ERR       0x0004
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
224         struct rewrite_action          *lr_action;
225 };
226
227 /*
228  * Rewrite Context (set of rules)
229  */
230 struct rewrite_context {
231         char                           *lc_name;
232         struct rewrite_context         *lc_alias;
233         struct rewrite_rule            *lc_rule;
234 };
235
236 /*
237  * Session
238  */
239 struct rewrite_session {
240         void                           *ls_cookie;
241         Avlnode                        *ls_vars;
242 #ifdef USE_REWRITE_LDAP_PVT_THREADS
243         ldap_pvt_thread_rdwr_t          ls_vars_mutex;
244 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
245 };
246
247 /*
248  * Variable
249  */
250 struct rewrite_var {
251         char                           *lv_name;
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         char                           *lo_string;
262         char                           *lo_result;
263         Avlnode                        *lo_vars;
264         const void                     *lo_cookie;
265 };
266
267
268 /**********
269  * PUBLIC *
270  **********/
271
272 /*
273  * Rewrite info
274  */
275 struct rewrite_info {
276         Avlnode                        *li_context;
277         Avlnode                        *li_maps;
278         /*
279          * No global mutex because maps are read only at 
280          * config time
281          */
282         Avlnode                        *li_params;
283         Avlnode                        *li_cookies;
284         int                             li_num_cookies;
285
286 #ifdef USE_REWRITE_LDAP_PVT_THREADS
287         ldap_pvt_thread_rdwr_t          li_params_mutex;
288         ldap_pvt_thread_rdwr_t          li_cookies_mutex;
289 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
290
291         /*
292          * Default to `off';
293          * use `rewriteEngine {on|off}' directive to alter
294          */
295         int                             li_state;
296
297         /*
298          * Defaults to REWRITE_MAXPASSES;
299          * use `rewriteMaxPasses numPasses' directive to alter
300          */
301 #define REWRITE_MAXPASSES               100
302         int                             li_max_passes;
303
304         /*
305          * Behavior in case a NULL or non-existent context is required
306          */
307         int                             li_rewrite_mode;
308 };
309
310 /***********
311  * PRIVATE *
312  ***********/
313
314
315 /*
316  * Maps
317  */
318
319 /*
320  * Parses a map (also in legacy 'x' version)
321  */
322 extern struct rewrite_map *
323 rewrite_map_parse(
324                 struct rewrite_info *info,
325                 const char *s,
326                 const char **end
327 );
328
329 extern struct rewrite_map *
330 rewrite_xmap_parse(
331                 struct rewrite_info *info,
332                 const char *s,
333                 const char **end
334 );
335
336 /*
337  * Resolves key in val by means of map (also in legacy 'x' version)
338  */
339 extern int
340 rewrite_map_apply(
341                 struct rewrite_info *info,
342                 struct rewrite_op *op,
343                 struct rewrite_map *map,
344                 struct berval *key,
345                 struct berval *val
346 );
347
348 extern int
349 rewrite_xmap_apply(
350                 struct rewrite_info *info,
351                 struct rewrite_op *op,
352                 struct rewrite_map *map,
353                 struct berval *key,
354                 struct berval *val
355 );
356
357
358 /*
359  * Submatch substitution
360  */
361
362 /*
363  * Compiles a substitution pattern
364  */
365 extern struct rewrite_subst *
366 rewrite_subst_compile(
367                 struct rewrite_info *info,
368                 const char *result
369 );
370
371 /*
372  * Substitutes a portion of rewritten string according to substitution
373  * pattern using submatches
374  */
375 extern int
376 rewrite_subst_apply(
377                 struct rewrite_info *info,
378                 struct rewrite_op *op,
379                 struct rewrite_subst *subst,
380                 const char *string,
381                 const regmatch_t *match,
382                 struct berval *val
383 );
384
385
386 /*
387  * Rules
388  */
389
390 /*
391  * Compiles the rule and appends it at the running context
392  */
393 extern int
394 rewrite_rule_compile(
395                 struct rewrite_info *info,
396                 struct rewrite_context *context,
397                 const char *pattern,
398                 const char *result,
399                 const char *flagstring
400 );
401
402 /*
403  * Rewrites string according to rule; may return:
404  *      REWRITE_REGEXEC_OK:     fine; if *result != NULL rule matched
405  *                              and rewrite succeeded.
406  *      REWRITE_REGEXEC_STOP:   fine, rule matched; stop processing
407  *                              following rules
408  *      REWRITE_REGEXEC_UNWILL: rule matched; force 'unwilling to perform'
409  *      REWRITE_REGEXEC_ERR:    an error occurred
410  */
411 extern int
412 rewrite_rule_apply(
413                 struct rewrite_info *info,
414                 struct rewrite_op *op,
415                 struct rewrite_rule *rule,
416                 const char *string,
417                 char **result
418 );
419
420 /*
421  * Sessions
422  */
423
424 /*
425  * Fetches a struct rewrite_session
426  */
427 extern struct rewrite_session *
428 rewrite_session_find(
429                 struct rewrite_info *info,
430                 const void *cookie
431 );
432
433 /*
434  * Defines and inits a variable with session scope
435  */
436 extern int
437 rewrite_session_var_set(
438                 struct rewrite_info *info,
439                 const void *cookie,
440                 const char *name,
441                 const char *value
442 );
443
444 /*
445  * Gets a var with session scope
446  */
447 extern int
448 rewrite_session_var_get(
449                 struct rewrite_info *info,
450                 const void *cookie,
451                 const char *name,
452                 struct berval *val
453 );
454
455 /*
456  * Deletes a session
457  */
458 extern int
459 rewrite_session_delete(
460                 struct rewrite_info *info,
461                 const void *cookie
462 );
463
464 /*
465  * Destroys the cookie tree
466  */
467 extern int
468 rewrite_session_destroy(
469                 struct rewrite_info *info
470 );
471
472
473 /*
474  * Vars
475  */
476
477 /*
478  * Finds a var
479  */
480 extern struct rewrite_var *
481 rewrite_var_find(
482                 Avlnode *tree,
483                 const char *name
484 );
485
486 /*
487  * Inserts a newly created var
488  */
489 extern struct rewrite_var *
490 rewrite_var_insert(
491                 Avlnode **tree,
492                 const char *name,
493                 const char *value
494 );
495
496 /*
497  * Sets/inserts a var
498  */
499 extern struct rewrite_var *
500 rewrite_var_set(
501                 Avlnode **tree,
502                 const char *name,
503                 const char *value,
504                 int insert
505 );
506
507 /*
508  * Deletes a var tree
509  */
510 extern int
511 rewrite_var_delete(
512                 Avlnode *tree
513 );
514
515
516 /*
517  * Contexts
518  */
519
520 /*
521  * Finds the context named rewriteContext in the context tree
522  */
523 extern struct rewrite_context *
524 rewrite_context_find(
525                 struct rewrite_info *info,
526                 const char *rewriteContext
527 );
528
529 /*
530  * Creates a new context called rewriteContext and stores in into the tree
531  */
532 extern struct rewrite_context *
533 rewrite_context_create(
534                 struct rewrite_info *info,
535                 const char *rewriteContext
536 );
537
538 /*
539  * Rewrites string according to context; may return:
540  *      OK:     fine; if *result != NULL rule matched and rewrite succeeded.
541  *      STOP:   fine, rule matched; stop processing following rules
542  *      UNWILL: rule matched; force 'unwilling to perform'
543  */
544 extern int
545 rewrite_context_apply(
546                 struct rewrite_info *info,
547                 struct rewrite_op *op,
548                 struct rewrite_context *context,
549                 const char *string,
550                 char **result
551 );
552
553 #endif /* REWRITE_INT_H */
554