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