Back to index

openldap  2.4.31
rewrite-int.h
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 2000-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 /* ACKNOWLEDGEMENT:
00016  * This work was initially developed by Pierangelo Masarati for
00017  * inclusion in OpenLDAP Software.
00018  */
00019 
00020 #ifndef REWRITE_INT_H
00021 #define REWRITE_INT_H
00022 
00023 /*
00024  * These are required by every file of the library, so they're included here
00025  */
00026 #include <ac/stdlib.h>
00027 #include <ac/string.h>
00028 #include <ac/syslog.h>
00029 #include <ac/regex.h>
00030 #include <ac/socket.h>
00031 #include <ac/unistd.h>
00032 #include <ac/ctype.h>
00033 
00034 #include <lber.h>
00035 #include <ldap.h>
00036 #define LDAP_DEFINE_LDAP_DEBUG
00037 #include <ldap_log.h>
00038 #include <lutil.h>
00039 #include <avl.h>
00040 
00041 #include <rewrite.h>
00042 
00043 #define malloc(x)    ber_memalloc(x)
00044 #define calloc(x,y)  ber_memcalloc(x,y)
00045 #define realloc(x,y) ber_memrealloc(x,y)
00046 #define free(x)      ber_memfree(x)
00047 #undef strdup
00048 #define       strdup(x)     ber_strdup(x)
00049 
00050 /* Uncomment to use ldap pvt threads */
00051 #define USE_REWRITE_LDAP_PVT_THREADS
00052 #include <ldap_pvt_thread.h>
00053 
00054 /*
00055  * For details, see RATIONALE.
00056  */
00057 
00058 #define REWRITE_MAX_MATCH   11     /* 0: overall string; 1-9: submatches */
00059 #define REWRITE_MAX_PASSES  100
00060 
00061 /*
00062  * Submatch escape char
00063  */
00064 /* the '\' conflicts with slapd.conf parsing */
00065 /* #define REWRITE_SUBMATCH_ESCAPE               '\\' */
00066 #define REWRITE_SUBMATCH_ESCAPE_ORIG             '%'
00067 #define REWRITE_SUBMATCH_ESCAPE                  '$'
00068 #define IS_REWRITE_SUBMATCH_ESCAPE(c) \
00069        ((c) == REWRITE_SUBMATCH_ESCAPE || (c) == REWRITE_SUBMATCH_ESCAPE_ORIG)
00070 
00071 /*
00072  * REGEX flags
00073  */
00074 
00075 #define REWRITE_FLAG_HONORCASE                   'C'
00076 #define REWRITE_FLAG_BASICREGEX                  'R'
00077 
00078 /*
00079  * Action flags
00080  */
00081 #define REWRITE_FLAG_EXECONCE                    ':'
00082 #define REWRITE_FLAG_STOP                 '@'
00083 #define REWRITE_FLAG_UNWILLING                   '#'
00084 #define REWRITE_FLAG_GOTO                 'G'    /* requires an arg */
00085 #define REWRITE_FLAG_USER                 'U'    /* requires an arg */
00086 #define REWRITE_FLAG_MAX_PASSES                  'M'    /* requires an arg */
00087 #define REWRITE_FLAG_IGNORE_ERR                  'I'
00088 
00089 /*
00090  * Map operators
00091  */
00092 #define REWRITE_OPERATOR_SUBCONTEXT              '>'
00093 #define REWRITE_OPERATOR_COMMAND          '|'
00094 #define REWRITE_OPERATOR_VARIABLE_SET            '&'
00095 #define REWRITE_OPERATOR_VARIABLE_GET            '*'
00096 #define REWRITE_OPERATOR_PARAM_GET        '$'
00097 
00098 
00099 /***********
00100  * PRIVATE *
00101  ***********/
00102 
00103 /*
00104  * Action
00105  */
00106 struct rewrite_action {
00107        struct rewrite_action          *la_next;
00108        
00109 #define REWRITE_ACTION_STOP        0x0001
00110 #define REWRITE_ACTION_UNWILLING   0x0002
00111 #define REWRITE_ACTION_GOTO        0x0003
00112 #define REWRITE_ACTION_IGNORE_ERR  0x0004
00113 #define REWRITE_ACTION_USER        0x0005
00114        int                             la_type;
00115        void                           *la_args;
00116 };
00117 
00118 /*
00119  * Map
00120  */
00121 struct rewrite_map {
00122 
00123        /*
00124         * Legacy stuff
00125         */
00126 #define REWRITE_MAP_XFILEMAP              0x0001 /* Rough implementation! */
00127 #define REWRITE_MAP_XPWDMAP        0x0002  /* uid -> gecos */
00128 #define REWRITE_MAP_XLDAPMAP              0x0003 /* Not implemented yet! */
00129 
00130        /*
00131         * Maps with args
00132         */
00133 #define REWRITE_MAP_SUBCONTEXT            0x0101
00134        
00135 #define REWRITE_MAP_SET_OP_VAR            0x0102
00136 #define REWRITE_MAP_SETW_OP_VAR           0x0103
00137 #define REWRITE_MAP_GET_OP_VAR            0x0104
00138 #define       REWRITE_MAP_SET_SESN_VAR    0x0105
00139 #define REWRITE_MAP_SETW_SESN_VAR  0x0106
00140 #define       REWRITE_MAP_GET_SESN_VAR    0x0107
00141 #define REWRITE_MAP_GET_PARAM             0x0108
00142 #define REWRITE_MAP_BUILTIN        0x0109
00143        int                             lm_type;
00144 
00145        char                           *lm_name;
00146        void                           *lm_data;
00147 
00148        /*
00149         * Old maps store private data in _lm_args;
00150         * new maps store the substitution pattern in _lm_subst
00151         */
00152        union {              
00153                void                   *_lm_args;
00154               struct rewrite_subst   *_lm_subst;
00155        } lm_union;
00156 #define       lm_args lm_union._lm_args
00157 #define       lm_subst lm_union._lm_subst
00158 
00159 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00160        ldap_pvt_thread_mutex_t         lm_mutex;
00161 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00162 };
00163 
00164 /*
00165  * Builtin maps
00166  */
00167 struct rewrite_builtin_map {
00168 #define REWRITE_BUILTIN_MAP 0x0200
00169        int                             lb_type;
00170        char                           *lb_name;
00171        void                           *lb_private;
00172        const rewrite_mapper           *lb_mapper;
00173 
00174 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00175        ldap_pvt_thread_mutex_t         lb_mutex;
00176 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00177 };
00178 
00179 /*
00180  * Submatch substitution
00181  */
00182 struct rewrite_submatch {
00183 #define REWRITE_SUBMATCH_ASIS             0x0000
00184 #define REWRITE_SUBMATCH_XMAP             0x0001
00185 #define REWRITE_SUBMATCH_MAP_W_ARG 0x0002
00186        int                             ls_type;
00187        struct rewrite_map             *ls_map;
00188        int                             ls_submatch;
00189        /*
00190         * The first one represents the index of the submatch in case
00191         * the map has single submatch as argument;
00192         * the latter represents the map argument scheme in case
00193         * the map has substitution string argument form
00194         */
00195 };
00196 
00197 /*
00198  * Pattern substitution
00199  */
00200 struct rewrite_subst {
00201        size_t                          lt_subs_len;
00202        struct berval                  *lt_subs;
00203        
00204        int                             lt_num_submatch;
00205        struct rewrite_submatch        *lt_submatch;
00206 };
00207 
00208 /*
00209  * Rule
00210  */
00211 struct rewrite_rule {
00212        struct rewrite_rule            *lr_next;
00213        struct rewrite_rule            *lr_prev;
00214 
00215        char                           *lr_pattern;
00216        char                           *lr_subststring;
00217        char                           *lr_flagstring;
00218        regex_t                            lr_regex;
00219 
00220        /*
00221         * I was thinking about some kind of per-rule mutex, but there's
00222         * probably no need, because rules after compilation are only read;
00223         * however, I need to check whether regexec is reentrant ...
00224         */
00225 
00226        struct rewrite_subst           *lr_subst;
00227        
00228 #define REWRITE_REGEX_ICASE        REG_ICASE
00229 #define REWRITE_REGEX_EXTENDED            REG_EXTENDED  
00230        int                             lr_flags;
00231 
00232 #define REWRITE_RECURSE                   0x0001
00233 #define REWRITE_EXEC_ONCE                 0x0002
00234        int                         lr_mode;
00235        int                         lr_max_passes;
00236 
00237        struct rewrite_action          *lr_action;
00238 };
00239 
00240 /*
00241  * Rewrite Context (set of rules)
00242  */
00243 struct rewrite_context {
00244        char                           *lc_name;
00245        struct rewrite_context         *lc_alias;
00246        struct rewrite_rule            *lc_rule;
00247 };
00248 
00249 /*
00250  * Session
00251  */
00252 struct rewrite_session {
00253        void                           *ls_cookie;
00254        Avlnode                        *ls_vars;
00255 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00256        ldap_pvt_thread_rdwr_t          ls_vars_mutex;
00257        ldap_pvt_thread_mutex_t            ls_mutex;
00258 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00259        int                         ls_count;
00260 };
00261 
00262 /*
00263  * Variable
00264  */
00265 struct rewrite_var {
00266        char                           *lv_name;
00267        int                         lv_flags;
00268        struct berval                   lv_value;
00269 };
00270 
00271 /*
00272  * Operation
00273  */
00274 struct rewrite_op {
00275        int                             lo_num_passes;
00276        int                             lo_depth;
00277 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
00278        char                           *lo_string;
00279 #endif
00280        char                           *lo_result;
00281        Avlnode                        *lo_vars;
00282        const void                     *lo_cookie;
00283 };
00284 
00285 
00286 /**********
00287  * PUBLIC *
00288  **********/
00289 
00290 /*
00291  * Rewrite info
00292  */
00293 struct rewrite_info {
00294        Avlnode                        *li_context;
00295        Avlnode                        *li_maps;
00296        /*
00297         * No global mutex because maps are read only at 
00298         * config time
00299         */
00300        Avlnode                        *li_params;
00301        Avlnode                        *li_cookies;
00302        int                             li_num_cookies;
00303 
00304 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00305        ldap_pvt_thread_rdwr_t          li_params_mutex;
00306         ldap_pvt_thread_rdwr_t          li_cookies_mutex;
00307 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00308 
00309        /*
00310         * Default to `off';
00311         * use `rewriteEngine {on|off}' directive to alter
00312         */
00313        int                         li_state;
00314 
00315        /*
00316         * Defaults to REWRITE_MAXPASSES;
00317         * use `rewriteMaxPasses numPasses' directive to alter
00318         */
00319 #define REWRITE_MAXPASSES          100
00320        int                             li_max_passes;
00321        int                             li_max_passes_per_rule;
00322 
00323        /*
00324         * Behavior in case a NULL or non-existent context is required
00325         */
00326        int                             li_rewrite_mode;
00327 };
00328 
00329 /***********
00330  * PRIVATE *
00331  ***********/
00332 
00333 LDAP_REWRITE_V (struct rewrite_context*) rewrite_int_curr_context;
00334 
00335 /*
00336  * Maps
00337  */
00338 
00339 /*
00340  * Parses a map (also in legacy 'x' version)
00341  */
00342 LDAP_REWRITE_F (struct rewrite_map *)
00343 rewrite_map_parse(
00344               struct rewrite_info *info,
00345               const char *s,
00346               const char **end
00347 );
00348 
00349 LDAP_REWRITE_F (struct rewrite_map *)
00350 rewrite_xmap_parse(
00351               struct rewrite_info *info,
00352               const char *s,
00353               const char **end
00354 );
00355 
00356 /*
00357  * Resolves key in val by means of map (also in legacy 'x' version)
00358  */
00359 LDAP_REWRITE_F (int)
00360 rewrite_map_apply(
00361               struct rewrite_info *info,
00362               struct rewrite_op *op,
00363               struct rewrite_map *map,
00364               struct berval *key,
00365               struct berval *val
00366 );
00367 
00368 LDAP_REWRITE_F (int)
00369 rewrite_xmap_apply(
00370               struct rewrite_info *info,
00371               struct rewrite_op *op,
00372               struct rewrite_map *map,
00373               struct berval *key,
00374               struct berval *val
00375 );
00376 
00377 LDAP_REWRITE_F (int)
00378 rewrite_map_destroy(
00379               struct rewrite_map **map
00380 );
00381 
00382 LDAP_REWRITE_F (int)
00383 rewrite_xmap_destroy(
00384               struct rewrite_map **map
00385 );
00386 
00387 LDAP_REWRITE_F (void)
00388 rewrite_builtin_map_free(
00389               void *map
00390 );
00391 /*
00392  * Submatch substitution
00393  */
00394 
00395 /*
00396  * Compiles a substitution pattern
00397  */
00398 LDAP_REWRITE_F (struct rewrite_subst *)
00399 rewrite_subst_compile(
00400               struct rewrite_info *info,
00401               const char *result
00402 );
00403 
00404 /*
00405  * Substitutes a portion of rewritten string according to substitution
00406  * pattern using submatches
00407  */
00408 LDAP_REWRITE_F (int)
00409 rewrite_subst_apply(
00410               struct rewrite_info *info,
00411               struct rewrite_op *op,
00412               struct rewrite_subst *subst,
00413               const char *string,
00414               const regmatch_t *match,
00415               struct berval *val
00416 );
00417 
00418 LDAP_REWRITE_F (int)
00419 rewrite_subst_destroy(
00420               struct rewrite_subst **subst
00421 );
00422 
00423 
00424 /*
00425  * Rules
00426  */
00427 
00428 /*
00429  * Compiles the rule and appends it at the running context
00430  */
00431 LDAP_REWRITE_F (int)
00432 rewrite_rule_compile(
00433               struct rewrite_info *info,
00434               struct rewrite_context *context,
00435               const char *pattern,
00436               const char *result,
00437               const char *flagstring
00438 );
00439 
00440 /*
00441  * Rewrites string according to rule; may return:
00442  *      REWRITE_REGEXEC_OK: fine; if *result != NULL rule matched
00443  *                          and rewrite succeeded.
00444  *      REWRITE_REGEXEC_STOP:   fine, rule matched; stop processing
00445  *                          following rules
00446  *      REWRITE_REGEXEC_UNWILL: rule matched; force 'unwilling to perform'
00447  *      REWRITE_REGEXEC_ERR:       an error occurred
00448  */
00449 LDAP_REWRITE_F (int)
00450 rewrite_rule_apply(
00451               struct rewrite_info *info,
00452               struct rewrite_op *op,
00453               struct rewrite_rule *rule,
00454               const char *string,
00455               char **result
00456 );
00457 
00458 LDAP_REWRITE_F (int)
00459 rewrite_rule_destroy(
00460               struct rewrite_rule **rule
00461 );
00462 
00463 /*
00464  * Sessions
00465  */
00466 
00467 /*
00468  * Fetches a struct rewrite_session
00469  */
00470 LDAP_REWRITE_F (struct rewrite_session *)
00471 rewrite_session_find(
00472                 struct rewrite_info *info,
00473                 const void *cookie
00474 );
00475 
00476 /*
00477  * Defines and inits a variable with session scope
00478  */
00479 LDAP_REWRITE_F (int)
00480 rewrite_session_var_set_f(
00481                 struct rewrite_info *info,
00482                 const void *cookie,
00483                 const char *name,
00484                 const char *value,
00485               int flags
00486 );
00487 
00488 /*
00489  * Gets a var with session scope
00490  */
00491 LDAP_REWRITE_F (int)
00492 rewrite_session_var_get(
00493                 struct rewrite_info *info,
00494                 const void *cookie,
00495                 const char *name,
00496                 struct berval *val
00497 );
00498 
00499 /*
00500  * Deletes a session
00501  */
00502 LDAP_REWRITE_F (int)
00503 rewrite_session_delete(
00504                 struct rewrite_info *info,
00505                 const void *cookie
00506 );
00507 
00508 /*
00509  * Destroys the cookie tree
00510  */
00511 LDAP_REWRITE_F (int)
00512 rewrite_session_destroy(
00513                 struct rewrite_info *info
00514 );
00515 
00516 
00517 /*
00518  * Vars
00519  */
00520 
00521 /*
00522  * Finds a var
00523  */
00524 LDAP_REWRITE_F (struct rewrite_var *)
00525 rewrite_var_find(
00526                 Avlnode *tree,
00527                 const char *name
00528 );
00529 
00530 /*
00531  * Replaces the value of a variable
00532  */
00533 LDAP_REWRITE_F (int)
00534 rewrite_var_replace(
00535               struct rewrite_var *var,
00536               const char *value,
00537               int flags
00538 );
00539 
00540 /*
00541  * Inserts a newly created var
00542  */
00543 LDAP_REWRITE_F (struct rewrite_var *)
00544 rewrite_var_insert_f(
00545                 Avlnode **tree,
00546                 const char *name,
00547                 const char *value,
00548               int flags
00549 );
00550 
00551 #define rewrite_var_insert(tree, name, value) \
00552        rewrite_var_insert_f((tree), (name), (value), \
00553                      REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE)
00554 
00555 /*
00556  * Sets/inserts a var
00557  */
00558 LDAP_REWRITE_F (struct rewrite_var *)
00559 rewrite_var_set_f(
00560                 Avlnode **tree,
00561                 const char *name,
00562                 const char *value,
00563                 int flags
00564 );
00565 
00566 #define rewrite_var_set(tree, name, value, insert) \
00567        rewrite_var_set_f((tree), (name), (value), \
00568                      REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE|((insert)? REWRITE_VAR_INSERT : 0))
00569 
00570 /*
00571  * Deletes a var tree
00572  */
00573 LDAP_REWRITE_F (int)
00574 rewrite_var_delete(
00575                 Avlnode *tree
00576 );
00577 
00578 
00579 /*
00580  * Contexts
00581  */
00582 
00583 /*
00584  * Finds the context named rewriteContext in the context tree
00585  */
00586 LDAP_REWRITE_F (struct rewrite_context *)
00587 rewrite_context_find(
00588               struct rewrite_info *info,
00589               const char *rewriteContext
00590 );
00591 
00592 /*
00593  * Creates a new context called rewriteContext and stores in into the tree
00594  */
00595 LDAP_REWRITE_F (struct rewrite_context *)
00596 rewrite_context_create(
00597               struct rewrite_info *info,
00598               const char *rewriteContext
00599 );
00600 
00601 /*
00602  * Rewrites string according to context; may return:
00603  *      OK:     fine; if *result != NULL rule matched and rewrite succeeded.
00604  *      STOP:   fine, rule matched; stop processing following rules
00605  *      UNWILL: rule matched; force 'unwilling to perform'
00606  */
00607 LDAP_REWRITE_F (int)
00608 rewrite_context_apply(
00609               struct rewrite_info *info,
00610               struct rewrite_op *op,
00611               struct rewrite_context *context,
00612               const char *string,
00613               char **result
00614 );
00615 
00616 LDAP_REWRITE_F (int)
00617 rewrite_context_destroy(
00618               struct rewrite_context **context
00619 );
00620 
00621 LDAP_REWRITE_F (void)
00622 rewrite_context_free(
00623               void *tmp
00624 );
00625 
00626 #endif /* REWRITE_INT_H */
00627