1#ifndef _DICT_H_INCLUDED_ 2#define _DICT_H_INCLUDED_ 3 4/*++ 5/* NAME 6/* dict 3h 7/* SUMMARY 8/* dictionary manager 9/* SYNOPSIS 10/* #include <dict.h> 11/* DESCRIPTION 12/* .nf 13 14 /* 15 * System library. 16 */ 17#include <fcntl.h> 18#include <setjmp.h> 19 20#ifdef NO_SIGSETJMP 21#define DICT_JMP_BUF jmp_buf 22#else 23#define DICT_JMP_BUF sigjmp_buf 24#endif 25 26 /* 27 * Utility library. 28 */ 29#include <vstream.h> 30#include <argv.h> 31#include <vstring.h> 32#include <myflock.h> 33 34 /* 35 * Provenance information. 36 */ 37typedef struct DICT_OWNER { 38 int status; /* see below */ 39 uid_t uid; /* use only if status == UNTRUSTED */ 40} DICT_OWNER; 41 42#define DICT_OWNER_UNKNOWN (-1) /* ex: unauthenticated tcp, proxy */ 43#define DICT_OWNER_TRUSTED (!1) /* ex: root-owned config file */ 44#define DICT_OWNER_UNTRUSTED (!0) /* ex: non-root config file */ 45 46 /* 47 * Generic dictionary interface - in reality, a dictionary extends this 48 * structure with private members to maintain internal state. 49 */ 50typedef struct DICT { 51 char *type; /* for diagnostics */ 52 char *name; /* for diagnostics */ 53 int flags; /* see below */ 54 const char *(*lookup) (struct DICT *, const char *); 55 int (*update) (struct DICT *, const char *, const char *); 56 int (*delete) (struct DICT *, const char *); 57 int (*sequence) (struct DICT *, int, const char **, const char **); 58 int (*lock) (struct DICT *, int); 59 void (*close) (struct DICT *); 60 int lock_type; /* for read/write lock */ 61 int lock_fd; /* for read/write lock */ 62 int stat_fd; /* change detection */ 63 time_t mtime; /* mod time at open */ 64 VSTRING *fold_buf; /* key folding buffer */ 65 DICT_OWNER owner; /* provenance */ 66 int error; /* last operation only */ 67 DICT_JMP_BUF *jbuf; /* exception handling */ 68} DICT; 69 70extern DICT *dict_alloc(const char *, const char *, ssize_t); 71extern void dict_free(DICT *); 72 73extern DICT *dict_debug(DICT *); 74 75#define DICT_DEBUG(d) ((d)->flags & DICT_FLAG_DEBUG ? dict_debug(d) : (d)) 76 77 /* 78 * See dict_open.c embedded manpage for flag definitions. 79 */ 80#define DICT_FLAG_NONE (0) 81#define DICT_FLAG_DUP_WARN (1<<0) /* warn about dups if not supported */ 82#define DICT_FLAG_DUP_IGNORE (1<<1) /* ignore dups if not supported */ 83#define DICT_FLAG_TRY0NULL (1<<2) /* do not append 0 to key/value */ 84#define DICT_FLAG_TRY1NULL (1<<3) /* append 0 to key/value */ 85#define DICT_FLAG_FIXED (1<<4) /* fixed key map */ 86#define DICT_FLAG_PATTERN (1<<5) /* keys are patterns */ 87#define DICT_FLAG_LOCK (1<<6) /* use temp lock before access */ 88#define DICT_FLAG_DUP_REPLACE (1<<7) /* replace dups if supported */ 89#define DICT_FLAG_SYNC_UPDATE (1<<8) /* sync updates if supported */ 90#define DICT_FLAG_DEBUG (1<<9) /* log access */ 91/*#define DICT_FLAG_FOLD_KEY (1<<10) /* lowercase the lookup key */ 92#define DICT_FLAG_NO_REGSUB (1<<11) /* disallow regexp substitution */ 93#define DICT_FLAG_NO_PROXY (1<<12) /* disallow proxy mapping */ 94#define DICT_FLAG_NO_UNAUTH (1<<13) /* disallow unauthenticated data */ 95#define DICT_FLAG_FOLD_FIX (1<<14) /* case-fold key with fixed-case map */ 96#define DICT_FLAG_FOLD_MUL (1<<15) /* case-fold key with multi-case map */ 97#define DICT_FLAG_FOLD_ANY (DICT_FLAG_FOLD_FIX | DICT_FLAG_FOLD_MUL) 98#define DICT_FLAG_OPEN_LOCK (1<<16) /* perm lock if not multi-writer safe */ 99#define DICT_FLAG_BULK_UPDATE (1<<17) /* optimize for bulk updates */ 100#define DICT_FLAG_MULTI_WRITER (1<<18) /* multi-writer safe map */ 101 102 /* IMPORTANT: Update the dict_mask[] table when the above changes */ 103 104 /* 105 * The subsets of flags that control how a map is used. These are relevant 106 * mainly for proxymap support. Note: some categories overlap. 107 * 108 * DICT_FLAG_IMPL_MASK - flags that are set by the map implementation itself. 109 * 110 * DICT_FLAG_PARANOID - requestor flags that forbid the use of insecure map 111 * types for security-sensitive operations. These flags are checked by the 112 * map implementation itself upon open, lookup etc. requests. 113 * 114 * DICT_FLAG_RQST_MASK - all requestor flags, including paranoid flags, that 115 * the requestor may change between open, lookup etc. requests. These 116 * specify requestor properties, not map properties. 117 * 118 * DICT_FLAG_INST_MASK - none of the above flags. The requestor may not change 119 * these flags between open, lookup, etc. requests (although a map may make 120 * changes to its copy of some of these flags). The proxymap server opens 121 * only one map instance for all client requests with the same values of 122 * these flags, and the proxymap client uses its own saved copy of these 123 * flags. 124 */ 125#define DICT_FLAG_PARANOID \ 126 (DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY | DICT_FLAG_NO_UNAUTH) 127#define DICT_FLAG_IMPL_MASK (DICT_FLAG_FIXED | DICT_FLAG_PATTERN | \ 128 DICT_FLAG_MULTI_WRITER) 129#define DICT_FLAG_RQST_MASK (DICT_FLAG_FOLD_ANY | DICT_FLAG_LOCK | \ 130 DICT_FLAG_DUP_REPLACE | DICT_FLAG_DUP_WARN | \ 131 DICT_FLAG_DUP_IGNORE | DICT_FLAG_SYNC_UPDATE | \ 132 DICT_FLAG_PARANOID) 133#define DICT_FLAG_INST_MASK ~(DICT_FLAG_IMPL_MASK | DICT_FLAG_RQST_MASK) 134 135 /* 136 * dict->error values. Errors must be negative; smtpd_check depends on this. 137 */ 138#define DICT_ERR_NONE 0 /* no error */ 139#define DICT_ERR_RETRY (-1) /* soft error */ 140#define DICT_ERR_CONFIG (-2) /* configuration error */ 141 142 /* 143 * Result values for exposed functions except lookup. FAIL/ERROR are 144 * suggested values, not for use in comparisons for equality. 145 */ 146#define DICT_STAT_FAIL 1 /* any value > 0: notfound, conflict */ 147#define DICT_STAT_SUCCESS 0 /* request satisfied */ 148#define DICT_STAT_ERROR (-1) /* any value < 0: database error */ 149 150 /* 151 * Set an error code and return a result value. 152 */ 153#define DICT_ERR_VAL_RETURN(dict, err, val) do { \ 154 (dict)->error = (err); \ 155 return (val); \ 156 } while (0) 157 158 /* 159 * Sequence function types. 160 */ 161#define DICT_SEQ_FUN_FIRST 0 /* set cursor to first record */ 162#define DICT_SEQ_FUN_NEXT 1 /* set cursor to next record */ 163 164 /* 165 * Interface for dictionary types. 166 */ 167extern ARGV *dict_mapnames(void); 168 169 /* 170 * High-level interface, with logical dictionary names. 171 */ 172extern void dict_register(const char *, DICT *); 173extern DICT *dict_handle(const char *); 174extern void dict_unregister(const char *); 175extern int dict_update(const char *, const char *, const char *); 176extern const char *dict_lookup(const char *, const char *); 177extern int dict_delete(const char *, const char *); 178extern int dict_sequence(const char *, const int, const char **, const char **); 179extern int dict_load_file_xt(const char *, const char *); 180extern void dict_load_fp(const char *, VSTREAM *); 181extern const char *dict_eval(const char *, const char *, int); 182extern int dict_error(const char *); 183 184 /* 185 * Low-level interface, with physical dictionary handles. 186 */ 187extern DICT *dict_open(const char *, int, int); 188extern DICT *dict_open3(const char *, const char *, int, int); 189extern void dict_open_register(const char *, DICT *(*) (const char *, int, int)); 190 191#define dict_get(dp, key) ((const char *) (dp)->lookup((dp), (key))) 192#define dict_put(dp, key, val) (dp)->update((dp), (key), (val)) 193#define dict_del(dp, key) (dp)->delete((dp), (key)) 194#define dict_seq(dp, f, key, val) (dp)->sequence((dp), (f), (key), (val)) 195#define dict_close(dp) (dp)->close(dp) 196typedef void (*DICT_WALK_ACTION) (const char *, DICT *, char *); 197extern void dict_walk(DICT_WALK_ACTION, char *); 198extern int dict_changed(void); 199extern const char *dict_changed_name(void); 200extern const char *dict_flags_str(int); 201extern int dict_flags_mask(const char *); 202 203 /* 204 * Driver for interactive or scripted tests. 205 */ 206void dict_test(int, char **); 207 208 /* 209 * Behind-the-scenes support to continue execution with reduced 210 * functionality. 211 */ 212extern int dict_allow_surrogate; 213extern DICT *dict_surrogate(const char *, const char *, int, int, const char *,...); 214 215 /* 216 * This name is reserved for matchlist error handling. 217 */ 218#define DICT_TYPE_NOFILE "non-existent" 219 220 /* 221 * Duplicated from vstream(3). This should probably be abstracted out. 222 * 223 * Exception handling. We use pointer to jmp_buf to avoid a lot of unused 224 * baggage for streams that don't need this functionality. 225 * 226 * XXX sigsetjmp()/siglongjmp() save and restore the signal mask which can 227 * avoid surprises in code that manipulates signals, but unfortunately some 228 * systems have bugs in their implementation. 229 */ 230#ifdef NO_SIGSETJMP 231#define dict_setjmp(stream) setjmp((stream)->jbuf[0]) 232#define dict_longjmp(stream, val) longjmp((stream)->jbuf[0], (val)) 233#else 234#define dict_setjmp(stream) sigsetjmp((stream)->jbuf[0], 1) 235#define dict_longjmp(stream, val) siglongjmp((stream)->jbuf[0], (val)) 236#endif 237#define dict_isjmp(stream) ((stream)->jbuf != 0) 238 239 /* 240 * Temporary API. If exception handling proves to be useful, 241 * dict_jmp_alloc() should be integrated into dict_alloc(). 242 */ 243extern void dict_jmp_alloc(DICT *); 244 245/* LICENSE 246/* .ad 247/* .fi 248/* The Secure Mailer license must be distributed with this software. 249/* AUTHOR(S) 250/* Wietse Venema 251/* IBM T.J. Watson Research 252/* P.O. Box 704 253/* Yorktown Heights, NY 10598, USA 254/*--*/ 255 256#endif 257