openldap/libraries/librewrite/rewrite-int.h
2001-10-31 09:28:03 +00:00

557 lines
12 KiB
C

/******************************************************************************
*
* Copyright (C) 2000 Pierangelo Masarati, <ando@sys-net.it>
* All rights reserved.
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to alter it and redistribute it, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits should appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits should appear in the documentation.
*
* 4. This notice may not be removed or altered.
*
******************************************************************************/
#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>
#include "../libldap/ldap-int.h"
#include <avl.h>
#include <rewrite.h>
/* Uncomment to use ldap pvt threads */
#define USE_REWRITE_LDAP_PVT_THREADS
#include <ldap_pvt_thread.h>
/*
* 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 '%'
/*
* 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_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
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_LDAP 0x0201
int lb_type;
char *lb_name;
void *lb_private;
#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;
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;
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
};
/*
* Variable
*/
struct rewrite_var {
char *lv_name;
struct berval lv_value;
};
/*
* Operation
*/
struct rewrite_op {
int lo_num_passes;
int lo_depth;
char *lo_string;
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;
/*
* Behavior in case a NULL or non-existent context is required
*/
int li_rewrite_mode;
};
/***********
* PRIVATE *
***********/
/*
* Maps
*/
/*
* Parses a map (also in legacy 'x' version)
*/
extern struct rewrite_map *
rewrite_map_parse(
struct rewrite_info *info,
const char *s,
const char **end
);
extern 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)
*/
extern int
rewrite_map_apply(
struct rewrite_info *info,
struct rewrite_op *op,
struct rewrite_map *map,
struct berval *key,
struct berval *val
);
extern int
rewrite_xmap_apply(
struct rewrite_info *info,
struct rewrite_op *op,
struct rewrite_map *map,
struct berval *key,
struct berval *val
);
/*
* Submatch substitution
*/
/*
* Compiles a substitution pattern
*/
extern 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
*/
extern 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
);
/*
* Rules
*/
/*
* Compiles the rule and appends it at the running context
*/
extern 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
*/
extern int
rewrite_rule_apply(
struct rewrite_info *info,
struct rewrite_op *op,
struct rewrite_rule *rule,
const char *string,
char **result
);
/*
* Sessions
*/
/*
* Fetches a struct rewrite_session
*/
extern struct rewrite_session *
rewrite_session_find(
struct rewrite_info *info,
const void *cookie
);
/*
* Defines and inits a variable with session scope
*/
extern int
rewrite_session_var_set(
struct rewrite_info *info,
const void *cookie,
const char *name,
const char *value
);
/*
* Gets a var with session scope
*/
extern int
rewrite_session_var_get(
struct rewrite_info *info,
const void *cookie,
const char *name,
struct berval *val
);
/*
* Deletes a session
*/
extern int
rewrite_session_delete(
struct rewrite_info *info,
const void *cookie
);
/*
* Destroys the cookie tree
*/
extern int
rewrite_session_destroy(
struct rewrite_info *info
);
/*
* Vars
*/
/*
* Finds a var
*/
extern struct rewrite_var *
rewrite_var_find(
Avlnode *tree,
const char *name
);
/*
* Inserts a newly created var
*/
extern struct rewrite_var *
rewrite_var_insert(
Avlnode **tree,
const char *name,
const char *value
);
/*
* Sets/inserts a var
*/
extern struct rewrite_var *
rewrite_var_set(
Avlnode **tree,
const char *name,
const char *value,
int insert
);
/*
* Deletes a var tree
*/
extern int
rewrite_var_delete(
Avlnode *tree
);
/*
* Contexts
*/
/*
* Finds the context named rewriteContext in the context tree
*/
extern 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
*/
extern 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'
*/
extern int
rewrite_context_apply(
struct rewrite_info *info,
struct rewrite_op *op,
struct rewrite_context *context,
const char *string,
char **result
);
#endif /* REWRITE_INT_H */