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