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