summaryrefslogtreecommitdiffstats
path: root/libraries/librewrite/rewrite-int.h
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/librewrite/rewrite-int.h')
-rw-r--r--libraries/librewrite/rewrite-int.h628
1 files changed, 628 insertions, 0 deletions
diff --git a/libraries/librewrite/rewrite-int.h b/libraries/librewrite/rewrite-int.h
new file mode 100644
index 0000000..441db51
--- /dev/null
+++ b/libraries/librewrite/rewrite-int.h
@@ -0,0 +1,628 @@
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2000-2022 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENT:
+ * This work was initially developed by Pierangelo Masarati for
+ * inclusion in OpenLDAP Software.
+ */
+
+#ifndef REWRITE_INT_H
+#define REWRITE_INT_H
+
+/*
+ * These are required by every file of the library, so they're included here
+ */
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/syslog.h>
+#include <ac/regex.h>
+#include <ac/socket.h>
+#include <ac/unistd.h>
+#include <ac/ctype.h>
+
+#include <lber.h>
+#include <ldap.h>
+#define LDAP_DEFINE_LDAP_DEBUG
+#include <ldap_log.h>
+#include <lutil.h>
+#include <ldap_avl.h>
+
+#include <rewrite.h>
+
+#ifndef NO_THREADS
+#define USE_REWRITE_LDAP_PVT_THREADS
+#include <ldap_pvt_thread.h>
+#endif
+
+#define malloc(x) ber_memalloc(x)
+#define calloc(x,y) ber_memcalloc(x,y)
+#define realloc(x,y) ber_memrealloc(x,y)
+#define free(x) ber_memfree(x)
+#undef strdup
+#define strdup(x) ber_strdup(x)
+
+/*
+ * For details, see RATIONALE.
+ */
+
+#define REWRITE_MAX_MATCH 11 /* 0: overall string; 1-9: submatches */
+#define REWRITE_MAX_PASSES 100
+
+/*
+ * Submatch escape char
+ */
+/* the '\' conflicts with slapd.conf parsing */
+/* #define REWRITE_SUBMATCH_ESCAPE '\\' */
+#define REWRITE_SUBMATCH_ESCAPE_ORIG '%'
+#define REWRITE_SUBMATCH_ESCAPE '$'
+#define IS_REWRITE_SUBMATCH_ESCAPE(c) \
+ ((c) == REWRITE_SUBMATCH_ESCAPE || (c) == REWRITE_SUBMATCH_ESCAPE_ORIG)
+
+/*
+ * REGEX flags
+ */
+
+#define REWRITE_FLAG_HONORCASE 'C'
+#define REWRITE_FLAG_BASICREGEX 'R'
+
+/*
+ * Action flags
+ */
+#define REWRITE_FLAG_EXECONCE ':'
+#define REWRITE_FLAG_STOP '@'
+#define REWRITE_FLAG_UNWILLING '#'
+#define REWRITE_FLAG_GOTO 'G' /* requires an arg */
+#define REWRITE_FLAG_USER 'U' /* requires an arg */
+#define REWRITE_FLAG_MAX_PASSES 'M' /* requires an arg */
+#define REWRITE_FLAG_IGNORE_ERR 'I'
+
+/*
+ * Map operators
+ */
+#define REWRITE_OPERATOR_SUBCONTEXT '>'
+#define REWRITE_OPERATOR_COMMAND '|'
+#define REWRITE_OPERATOR_VARIABLE_SET '&'
+#define REWRITE_OPERATOR_VARIABLE_GET '*'
+#define REWRITE_OPERATOR_PARAM_GET '$'
+
+
+/***********
+ * PRIVATE *
+ ***********/
+
+/*
+ * Action
+ */
+struct rewrite_action {
+ struct rewrite_action *la_next;
+
+#define REWRITE_ACTION_STOP 0x0001
+#define REWRITE_ACTION_UNWILLING 0x0002
+#define REWRITE_ACTION_GOTO 0x0003
+#define REWRITE_ACTION_IGNORE_ERR 0x0004
+#define REWRITE_ACTION_USER 0x0005
+ int la_type;
+ void *la_args;
+};
+
+/*
+ * Map
+ */
+struct rewrite_map {
+
+ /*
+ * Legacy stuff
+ */
+#define REWRITE_MAP_XFILEMAP 0x0001 /* Rough implementation! */
+#define REWRITE_MAP_XPWDMAP 0x0002 /* uid -> gecos */
+#define REWRITE_MAP_XLDAPMAP 0x0003 /* Not implemented yet! */
+
+ /*
+ * Maps with args
+ */
+#define REWRITE_MAP_SUBCONTEXT 0x0101
+
+#define REWRITE_MAP_SET_OP_VAR 0x0102
+#define REWRITE_MAP_SETW_OP_VAR 0x0103
+#define REWRITE_MAP_GET_OP_VAR 0x0104
+#define REWRITE_MAP_SET_SESN_VAR 0x0105
+#define REWRITE_MAP_SETW_SESN_VAR 0x0106
+#define REWRITE_MAP_GET_SESN_VAR 0x0107
+#define REWRITE_MAP_GET_PARAM 0x0108
+#define REWRITE_MAP_BUILTIN 0x0109
+ int lm_type;
+
+ char *lm_name;
+ void *lm_data;
+
+ /*
+ * Old maps store private data in _lm_args;
+ * new maps store the substitution pattern in _lm_subst
+ */
+ union {
+ void *_lm_args;
+ struct rewrite_subst *_lm_subst;
+ } lm_union;
+#define lm_args lm_union._lm_args
+#define lm_subst lm_union._lm_subst
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+ ldap_pvt_thread_mutex_t lm_mutex;
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+};
+
+/*
+ * Builtin maps
+ */
+struct rewrite_builtin_map {
+#define REWRITE_BUILTIN_MAP 0x0200
+ int lb_type;
+ char *lb_name;
+ void *lb_private;
+ const rewrite_mapper *lb_mapper;
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+ ldap_pvt_thread_mutex_t lb_mutex;
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+};
+
+/*
+ * Submatch substitution
+ */
+struct rewrite_submatch {
+#define REWRITE_SUBMATCH_ASIS 0x0000
+#define REWRITE_SUBMATCH_XMAP 0x0001
+#define REWRITE_SUBMATCH_MAP_W_ARG 0x0002
+ int ls_type;
+ struct rewrite_map *ls_map;
+ int ls_submatch;
+ /*
+ * The first one represents the index of the submatch in case
+ * the map has single submatch as argument;
+ * the latter represents the map argument scheme in case
+ * the map has substitution string argument form
+ */
+};
+
+/*
+ * Pattern substitution
+ */
+struct rewrite_subst {
+ size_t lt_subs_len;
+ struct berval *lt_subs;
+
+ int lt_num_submatch;
+ struct rewrite_submatch *lt_submatch;
+};
+
+/*
+ * Rule
+ */
+struct rewrite_rule {
+ struct rewrite_rule *lr_next;
+ struct rewrite_rule *lr_prev;
+
+ char *lr_pattern;
+ char *lr_subststring;
+ char *lr_flagstring;
+ regex_t lr_regex;
+
+ /*
+ * I was thinking about some kind of per-rule mutex, but there's
+ * probably no need, because rules after compilation are only read;
+ * however, I need to check whether regexec is reentrant ...
+ */
+
+ struct rewrite_subst *lr_subst;
+
+#define REWRITE_REGEX_ICASE REG_ICASE
+#define REWRITE_REGEX_EXTENDED REG_EXTENDED
+ int lr_flags;
+
+#define REWRITE_RECURSE 0x0001
+#define REWRITE_EXEC_ONCE 0x0002
+ int lr_mode;
+ int lr_max_passes;
+
+ struct rewrite_action *lr_action;
+};
+
+/*
+ * Rewrite Context (set of rules)
+ */
+struct rewrite_context {
+ char *lc_name;
+ struct rewrite_context *lc_alias;
+ struct rewrite_rule *lc_rule;
+};
+
+/*
+ * Session
+ */
+struct rewrite_session {
+ void *ls_cookie;
+ Avlnode *ls_vars;
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+ ldap_pvt_thread_rdwr_t ls_vars_mutex;
+ ldap_pvt_thread_mutex_t ls_mutex;
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+ int ls_count;
+};
+
+/*
+ * Variable
+ */
+struct rewrite_var {
+ char *lv_name;
+ int lv_flags;
+ struct berval lv_value;
+};
+
+/*
+ * Operation
+ */
+struct rewrite_op {
+ int lo_num_passes;
+ int lo_depth;
+#if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
+ char *lo_string;
+#endif
+ char *lo_result;
+ Avlnode *lo_vars;
+ const void *lo_cookie;
+};
+
+
+/**********
+ * PUBLIC *
+ **********/
+
+/*
+ * Rewrite info
+ */
+struct rewrite_info {
+ Avlnode *li_context;
+ Avlnode *li_maps;
+ /*
+ * No global mutex because maps are read only at
+ * config time
+ */
+ Avlnode *li_params;
+ Avlnode *li_cookies;
+ int li_num_cookies;
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+ ldap_pvt_thread_rdwr_t li_params_mutex;
+ ldap_pvt_thread_rdwr_t li_cookies_mutex;
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+
+ /*
+ * Default to `off';
+ * use `rewriteEngine {on|off}' directive to alter
+ */
+ int li_state;
+
+ /*
+ * Defaults to REWRITE_MAXPASSES;
+ * use `rewriteMaxPasses numPasses' directive to alter
+ */
+#define REWRITE_MAXPASSES 100
+ int li_max_passes;
+ int li_max_passes_per_rule;
+
+ /*
+ * Behavior in case a NULL or non-existent context is required
+ */
+ int li_rewrite_mode;
+};
+
+/***********
+ * PRIVATE *
+ ***********/
+
+LDAP_REWRITE_V (struct rewrite_context*) rewrite_int_curr_context;
+
+/*
+ * Maps
+ */
+
+/*
+ * Parses a map (also in legacy 'x' version)
+ */
+LDAP_REWRITE_F (struct rewrite_map *)
+rewrite_map_parse(
+ struct rewrite_info *info,
+ const char *s,
+ const char **end
+);
+
+LDAP_REWRITE_F (struct rewrite_map *)
+rewrite_xmap_parse(
+ struct rewrite_info *info,
+ const char *s,
+ const char **end
+);
+
+/*
+ * Resolves key in val by means of map (also in legacy 'x' version)
+ */
+LDAP_REWRITE_F (int)
+rewrite_map_apply(
+ struct rewrite_info *info,
+ struct rewrite_op *op,
+ struct rewrite_map *map,
+ struct berval *key,
+ struct berval *val
+);
+
+LDAP_REWRITE_F (int)
+rewrite_xmap_apply(
+ struct rewrite_info *info,
+ struct rewrite_op *op,
+ struct rewrite_map *map,
+ struct berval *key,
+ struct berval *val
+);
+
+LDAP_REWRITE_F (int)
+rewrite_map_destroy(
+ struct rewrite_map **map
+);
+
+LDAP_REWRITE_F (int)
+rewrite_xmap_destroy(
+ struct rewrite_map **map
+);
+
+LDAP_REWRITE_F (void)
+rewrite_builtin_map_free(
+ void *map
+);
+/*
+ * Submatch substitution
+ */
+
+/*
+ * Compiles a substitution pattern
+ */
+LDAP_REWRITE_F (struct rewrite_subst *)
+rewrite_subst_compile(
+ struct rewrite_info *info,
+ const char *result
+);
+
+/*
+ * Substitutes a portion of rewritten string according to substitution
+ * pattern using submatches
+ */
+LDAP_REWRITE_F (int)
+rewrite_subst_apply(
+ struct rewrite_info *info,
+ struct rewrite_op *op,
+ struct rewrite_subst *subst,
+ const char *string,
+ const regmatch_t *match,
+ struct berval *val
+);
+
+LDAP_REWRITE_F (int)
+rewrite_subst_destroy(
+ struct rewrite_subst **subst
+);
+
+
+/*
+ * Rules
+ */
+
+/*
+ * Compiles the rule and appends it at the running context
+ */
+LDAP_REWRITE_F (int)
+rewrite_rule_compile(
+ struct rewrite_info *info,
+ struct rewrite_context *context,
+ const char *pattern,
+ const char *result,
+ const char *flagstring
+);
+
+/*
+ * Rewrites string according to rule; may return:
+ * REWRITE_REGEXEC_OK: fine; if *result != NULL rule matched
+ * and rewrite succeeded.
+ * REWRITE_REGEXEC_STOP: fine, rule matched; stop processing
+ * following rules
+ * REWRITE_REGEXEC_UNWILL: rule matched; force 'unwilling to perform'
+ * REWRITE_REGEXEC_ERR: an error occurred
+ */
+LDAP_REWRITE_F (int)
+rewrite_rule_apply(
+ struct rewrite_info *info,
+ struct rewrite_op *op,
+ struct rewrite_rule *rule,
+ const char *string,
+ char **result
+);
+
+LDAP_REWRITE_F (int)
+rewrite_rule_destroy(
+ struct rewrite_rule **rule
+);
+
+/*
+ * Sessions
+ */
+
+/*
+ * Fetches a struct rewrite_session
+ */
+LDAP_REWRITE_F (struct rewrite_session *)
+rewrite_session_find(
+ struct rewrite_info *info,
+ const void *cookie
+);
+
+/*
+ * Defines and inits a variable with session scope
+ */
+LDAP_REWRITE_F (int)
+rewrite_session_var_set_f(
+ struct rewrite_info *info,
+ const void *cookie,
+ const char *name,
+ const char *value,
+ int flags
+);
+
+/*
+ * Gets a var with session scope
+ */
+LDAP_REWRITE_F (int)
+rewrite_session_var_get(
+ struct rewrite_info *info,
+ const void *cookie,
+ const char *name,
+ struct berval *val
+);
+
+/*
+ * Deletes a session
+ */
+LDAP_REWRITE_F (int)
+rewrite_session_delete(
+ struct rewrite_info *info,
+ const void *cookie
+);
+
+/*
+ * Destroys the cookie tree
+ */
+LDAP_REWRITE_F (int)
+rewrite_session_destroy(
+ struct rewrite_info *info
+);
+
+
+/*
+ * Vars
+ */
+
+/*
+ * Finds a var
+ */
+LDAP_REWRITE_F (struct rewrite_var *)
+rewrite_var_find(
+ Avlnode *tree,
+ const char *name
+);
+
+/*
+ * Replaces the value of a variable
+ */
+LDAP_REWRITE_F (int)
+rewrite_var_replace(
+ struct rewrite_var *var,
+ const char *value,
+ int flags
+);
+
+/*
+ * Inserts a newly created var
+ */
+LDAP_REWRITE_F (struct rewrite_var *)
+rewrite_var_insert_f(
+ Avlnode **tree,
+ const char *name,
+ const char *value,
+ int flags
+);
+
+#define rewrite_var_insert(tree, name, value) \
+ rewrite_var_insert_f((tree), (name), (value), \
+ REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE)
+
+/*
+ * Sets/inserts a var
+ */
+LDAP_REWRITE_F (struct rewrite_var *)
+rewrite_var_set_f(
+ Avlnode **tree,
+ const char *name,
+ const char *value,
+ int flags
+);
+
+#define rewrite_var_set(tree, name, value, insert) \
+ rewrite_var_set_f((tree), (name), (value), \
+ REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE|((insert)? REWRITE_VAR_INSERT : 0))
+
+/*
+ * Deletes a var tree
+ */
+LDAP_REWRITE_F (int)
+rewrite_var_delete(
+ Avlnode *tree
+);
+
+
+/*
+ * Contexts
+ */
+
+/*
+ * Finds the context named rewriteContext in the context tree
+ */
+LDAP_REWRITE_F (struct rewrite_context *)
+rewrite_context_find(
+ struct rewrite_info *info,
+ const char *rewriteContext
+);
+
+/*
+ * Creates a new context called rewriteContext and stores in into the tree
+ */
+LDAP_REWRITE_F (struct rewrite_context *)
+rewrite_context_create(
+ struct rewrite_info *info,
+ const char *rewriteContext
+);
+
+/*
+ * Rewrites string according to context; may return:
+ * OK: fine; if *result != NULL rule matched and rewrite succeeded.
+ * STOP: fine, rule matched; stop processing following rules
+ * UNWILL: rule matched; force 'unwilling to perform'
+ */
+LDAP_REWRITE_F (int)
+rewrite_context_apply(
+ struct rewrite_info *info,
+ struct rewrite_op *op,
+ struct rewrite_context *context,
+ const char *string,
+ char **result
+);
+
+LDAP_REWRITE_F (int)
+rewrite_context_destroy(
+ struct rewrite_context **context
+);
+
+LDAP_REWRITE_F (void)
+rewrite_context_free(
+ void *tmp
+);
+
+#endif /* REWRITE_INT_H */
+