]> git.sur5r.net Git - openldap/blob - libraries/librewrite/rewrite-int.h
Fix stupid bug
[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         char                           *lo_string;
266         char                           *lo_result;
267         Avlnode                        *lo_vars;
268         const void                     *lo_cookie;
269 };
270
271
272 /**********
273  * PUBLIC *
274  **********/
275
276 /*
277  * Rewrite info
278  */
279 struct rewrite_info {
280         Avlnode                        *li_context;
281         Avlnode                        *li_maps;
282         /*
283          * No global mutex because maps are read only at 
284          * config time
285          */
286         Avlnode                        *li_params;
287         Avlnode                        *li_cookies;
288         int                             li_num_cookies;
289
290 #ifdef USE_REWRITE_LDAP_PVT_THREADS
291         ldap_pvt_thread_rdwr_t          li_params_mutex;
292         ldap_pvt_thread_rdwr_t          li_cookies_mutex;
293 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
294
295         /*
296          * Default to `off';
297          * use `rewriteEngine {on|off}' directive to alter
298          */
299         int                             li_state;
300
301         /*
302          * Defaults to REWRITE_MAXPASSES;
303          * use `rewriteMaxPasses numPasses' directive to alter
304          */
305 #define REWRITE_MAXPASSES               100
306         int                             li_max_passes;
307
308         /*
309          * Behavior in case a NULL or non-existent context is required
310          */
311         int                             li_rewrite_mode;
312 };
313
314 /***********
315  * PRIVATE *
316  ***********/
317
318 LDAP_REWRITE_V (struct rewrite_context*) __curr_context;
319
320 /*
321  * Maps
322  */
323
324 /*
325  * Parses a map (also in legacy 'x' version)
326  */
327 LDAP_REWRITE_F (struct rewrite_map *)
328 rewrite_map_parse(
329                 struct rewrite_info *info,
330                 const char *s,
331                 const char **end
332 );
333
334 LDAP_REWRITE_F (struct rewrite_map *)
335 rewrite_xmap_parse(
336                 struct rewrite_info *info,
337                 const char *s,
338                 const char **end
339 );
340
341 /*
342  * Resolves key in val by means of map (also in legacy 'x' version)
343  */
344 LDAP_REWRITE_F (int)
345 rewrite_map_apply(
346                 struct rewrite_info *info,
347                 struct rewrite_op *op,
348                 struct rewrite_map *map,
349                 struct berval *key,
350                 struct berval *val
351 );
352
353 LDAP_REWRITE_F (int)
354 rewrite_xmap_apply(
355                 struct rewrite_info *info,
356                 struct rewrite_op *op,
357                 struct rewrite_map *map,
358                 struct berval *key,
359                 struct berval *val
360 );
361
362
363 /*
364  * Submatch substitution
365  */
366
367 /*
368  * Compiles a substitution pattern
369  */
370 LDAP_REWRITE_F (struct rewrite_subst *)
371 rewrite_subst_compile(
372                 struct rewrite_info *info,
373                 const char *result
374 );
375
376 /*
377  * Substitutes a portion of rewritten string according to substitution
378  * pattern using submatches
379  */
380 LDAP_REWRITE_F (int)
381 rewrite_subst_apply(
382                 struct rewrite_info *info,
383                 struct rewrite_op *op,
384                 struct rewrite_subst *subst,
385                 const char *string,
386                 const regmatch_t *match,
387                 struct berval *val
388 );
389
390
391 /*
392  * Rules
393  */
394
395 /*
396  * Compiles the rule and appends it at the running context
397  */
398 LDAP_REWRITE_F (int)
399 rewrite_rule_compile(
400                 struct rewrite_info *info,
401                 struct rewrite_context *context,
402                 const char *pattern,
403                 const char *result,
404                 const char *flagstring
405 );
406
407 /*
408  * Rewrites string according to rule; may return:
409  *      REWRITE_REGEXEC_OK:     fine; if *result != NULL rule matched
410  *                              and rewrite succeeded.
411  *      REWRITE_REGEXEC_STOP:   fine, rule matched; stop processing
412  *                              following rules
413  *      REWRITE_REGEXEC_UNWILL: rule matched; force 'unwilling to perform'
414  *      REWRITE_REGEXEC_ERR:    an error occurred
415  */
416 LDAP_REWRITE_F (int)
417 rewrite_rule_apply(
418                 struct rewrite_info *info,
419                 struct rewrite_op *op,
420                 struct rewrite_rule *rule,
421                 const char *string,
422                 char **result
423 );
424
425 /*
426  * Sessions
427  */
428
429 /*
430  * Fetches a struct rewrite_session
431  */
432 LDAP_REWRITE_F (struct rewrite_session *)
433 rewrite_session_find(
434                 struct rewrite_info *info,
435                 const void *cookie
436 );
437
438 /*
439  * Defines and inits a variable with session scope
440  */
441 LDAP_REWRITE_F (int)
442 rewrite_session_var_set(
443                 struct rewrite_info *info,
444                 const void *cookie,
445                 const char *name,
446                 const char *value
447 );
448
449 /*
450  * Gets a var with session scope
451  */
452 LDAP_REWRITE_F (int)
453 rewrite_session_var_get(
454                 struct rewrite_info *info,
455                 const void *cookie,
456                 const char *name,
457                 struct berval *val
458 );
459
460 /*
461  * Deletes a session
462  */
463 LDAP_REWRITE_F (int)
464 rewrite_session_delete(
465                 struct rewrite_info *info,
466                 const void *cookie
467 );
468
469 /*
470  * Destroys the cookie tree
471  */
472 LDAP_REWRITE_F (int)
473 rewrite_session_destroy(
474                 struct rewrite_info *info
475 );
476
477
478 /*
479  * Vars
480  */
481
482 /*
483  * Finds a var
484  */
485 LDAP_REWRITE_F (struct rewrite_var *)
486 rewrite_var_find(
487                 Avlnode *tree,
488                 const char *name
489 );
490
491 /*
492  * Inserts a newly created var
493  */
494 LDAP_REWRITE_F (struct rewrite_var *)
495 rewrite_var_insert(
496                 Avlnode **tree,
497                 const char *name,
498                 const char *value
499 );
500
501 /*
502  * Sets/inserts a var
503  */
504 LDAP_REWRITE_F (struct rewrite_var *)
505 rewrite_var_set(
506                 Avlnode **tree,
507                 const char *name,
508                 const char *value,
509                 int insert
510 );
511
512 /*
513  * Deletes a var tree
514  */
515 LDAP_REWRITE_F (int)
516 rewrite_var_delete(
517                 Avlnode *tree
518 );
519
520
521 /*
522  * Contexts
523  */
524
525 /*
526  * Finds the context named rewriteContext in the context tree
527  */
528 LDAP_REWRITE_F (struct rewrite_context *)
529 rewrite_context_find(
530                 struct rewrite_info *info,
531                 const char *rewriteContext
532 );
533
534 /*
535  * Creates a new context called rewriteContext and stores in into the tree
536  */
537 LDAP_REWRITE_F (struct rewrite_context *)
538 rewrite_context_create(
539                 struct rewrite_info *info,
540                 const char *rewriteContext
541 );
542
543 /*
544  * Rewrites string according to context; may return:
545  *      OK:     fine; if *result != NULL rule matched and rewrite succeeded.
546  *      STOP:   fine, rule matched; stop processing following rules
547  *      UNWILL: rule matched; force 'unwilling to perform'
548  */
549 LDAP_REWRITE_F (int)
550 rewrite_context_apply(
551                 struct rewrite_info *info,
552                 struct rewrite_op *op,
553                 struct rewrite_context *context,
554                 const char *string,
555                 char **result
556 );
557
558 #endif /* REWRITE_INT_H */
559