Postfix3.3.1
dict.h
[詳解]
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  */
37 typedef struct DICT_OWNER {
38  int status; /* see below */
39  uid_t uid; /* use only if status == UNTRUSTED */
40 } DICT_OWNER;
41 
42  /*
43  * Note that trust levels are not in numerical order.
44  */
45 #define DICT_OWNER_UNKNOWN (-1) /* ex: unauthenticated tcp, proxy */
46 #define DICT_OWNER_TRUSTED (!1) /* ex: root-owned config file */
47 #define DICT_OWNER_UNTRUSTED (!0) /* ex: non-root config file */
48 
49  /*
50  * When combining tables with different provenance, we initialize to the
51  * highest trust level, and remember the lowest trust level that we find
52  * during aggregation. If we combine tables that are owned by different
53  * untrusted users, the resulting provenance is "unknown".
54  */
55 #define DICT_OWNER_AGGREGATE_INIT(dst) { \
56  (dst).status = DICT_OWNER_TRUSTED; \
57  (dst).uid = 0; \
58  } while (0)
59 
60  /*
61  * The following is derived from the 3x3 transition matrix.
62  */
63 #define DICT_OWNER_AGGREGATE_UPDATE(dst, src) do { \
64  if ((dst).status == DICT_OWNER_TRUSTED \
65  || (src).status == DICT_OWNER_UNKNOWN) { \
66  (dst) = (src); \
67  } else if ((dst).status == (src).status \
68  && (dst).uid != (src).uid) { \
69  (dst).status = DICT_OWNER_UNKNOWN; \
70  (dst).uid = ~0; \
71  } \
72  } while (0)
73 
74  /*
75  * Generic dictionary interface - in reality, a dictionary extends this
76  * structure with private members to maintain internal state.
77  */
78 typedef struct DICT {
79  char *type; /* for diagnostics */
80  char *name; /* for diagnostics */
81  int flags; /* see below */
82  const char *(*lookup) (struct DICT *, const char *);
83  int (*update) (struct DICT *, const char *, const char *);
84  int (*delete) (struct DICT *, const char *);
85  int (*sequence) (struct DICT *, int, const char **, const char **);
86  int (*lock) (struct DICT *, int);
87  void (*close) (struct DICT *);
88  int lock_type; /* for read/write lock */
89  int lock_fd; /* for read/write lock */
90  int stat_fd; /* change detection */
91  time_t mtime; /* mod time at open */
92  VSTRING *fold_buf; /* key folding buffer */
93  DICT_OWNER owner; /* provenance */
94  int error; /* last operation only */
95  DICT_JMP_BUF *jbuf; /* exception handling */
96  struct DICT_UTF8_BACKUP *utf8_backup; /* see below */
97 } DICT;
98 
99 extern DICT *dict_alloc(const char *, const char *, ssize_t);
100 extern void dict_free(DICT *);
101 
102 extern DICT *dict_debug(DICT *);
103 
104 #define DICT_DEBUG(d) ((d)->flags & DICT_FLAG_DEBUG ? dict_debug(d) : (d))
105 
106  /*
107  * See dict_open.c embedded manpage for flag definitions.
108  */
109 #define DICT_FLAG_NONE (0)
110 #define DICT_FLAG_DUP_WARN (1<<0) /* warn about dups if not supported */
111 #define DICT_FLAG_DUP_IGNORE (1<<1) /* ignore dups if not supported */
112 #define DICT_FLAG_TRY0NULL (1<<2) /* do not append 0 to key/value */
113 #define DICT_FLAG_TRY1NULL (1<<3) /* append 0 to key/value */
114 #define DICT_FLAG_FIXED (1<<4) /* fixed key map */
115 #define DICT_FLAG_PATTERN (1<<5) /* keys are patterns */
116 #define DICT_FLAG_LOCK (1<<6) /* use temp lock before access */
117 #define DICT_FLAG_DUP_REPLACE (1<<7) /* replace dups if supported */
118 #define DICT_FLAG_SYNC_UPDATE (1<<8) /* sync updates if supported */
119 #define DICT_FLAG_DEBUG (1<<9) /* log access */
120 /*#define DICT_FLAG_FOLD_KEY (1<<10) /* lowercase the lookup key */
121 #define DICT_FLAG_NO_REGSUB (1<<11) /* disallow regexp substitution */
122 #define DICT_FLAG_NO_PROXY (1<<12) /* disallow proxy mapping */
123 #define DICT_FLAG_NO_UNAUTH (1<<13) /* disallow unauthenticated data */
124 #define DICT_FLAG_FOLD_FIX (1<<14) /* case-fold key with fixed-case map */
125 #define DICT_FLAG_FOLD_MUL (1<<15) /* case-fold key with multi-case map */
126 #define DICT_FLAG_FOLD_ANY (DICT_FLAG_FOLD_FIX | DICT_FLAG_FOLD_MUL)
127 #define DICT_FLAG_OPEN_LOCK (1<<16) /* perm lock if not multi-writer safe */
128 #define DICT_FLAG_BULK_UPDATE (1<<17) /* optimize for bulk updates */
129 #define DICT_FLAG_MULTI_WRITER (1<<18) /* multi-writer safe map */
130 #define DICT_FLAG_UTF8_REQUEST (1<<19) /* activate UTF-8 if possible */
131 #define DICT_FLAG_UTF8_ACTIVE (1<<20) /* UTF-8 proxy layer is present */
132 
133 #define DICT_FLAG_UTF8_MASK (DICT_FLAG_UTF8_REQUEST)
134 
135  /* IMPORTANT: Update the dict_mask[] table when the above changes */
136 
137  /*
138  * The subsets of flags that control how a map is used. These are relevant
139  * mainly for proxymap support. Note: some categories overlap.
140  *
141  * DICT_FLAG_IMPL_MASK - flags that are set by the map implementation itself.
142  *
143  * DICT_FLAG_PARANOID - requestor flags that forbid the use of insecure map
144  * types for security-sensitive operations. These flags are checked by the
145  * map implementation itself upon open, lookup etc. requests.
146  *
147  * DICT_FLAG_RQST_MASK - all requestor flags, including paranoid flags, that
148  * the requestor may change between open, lookup etc. requests. These
149  * specify requestor properties, not map properties.
150  *
151  * DICT_FLAG_INST_MASK - none of the above flags. The requestor may not change
152  * these flags between open, lookup, etc. requests (although a map may make
153  * changes to its copy of some of these flags). The proxymap server opens
154  * only one map instance for all client requests with the same values of
155  * these flags, and the proxymap client uses its own saved copy of these
156  * flags.
157  */
158 #define DICT_FLAG_PARANOID \
159  (DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY | DICT_FLAG_NO_UNAUTH)
160 #define DICT_FLAG_IMPL_MASK (DICT_FLAG_FIXED | DICT_FLAG_PATTERN | \
161  DICT_FLAG_MULTI_WRITER)
162 #define DICT_FLAG_RQST_MASK (DICT_FLAG_FOLD_ANY | DICT_FLAG_LOCK | \
163  DICT_FLAG_DUP_REPLACE | DICT_FLAG_DUP_WARN | \
164  DICT_FLAG_DUP_IGNORE | DICT_FLAG_SYNC_UPDATE | \
165  DICT_FLAG_PARANOID | DICT_FLAG_UTF8_MASK)
166 #define DICT_FLAG_INST_MASK ~(DICT_FLAG_IMPL_MASK | DICT_FLAG_RQST_MASK)
167 
168  /*
169  * Feature tests.
170  */
171 #define DICT_NEED_UTF8_ACTIVATION(enable, flags) \
172  ((enable) && ((flags) & DICT_FLAG_UTF8_MASK))
173 
174  /*
175  * dict->error values. Errors must be negative; smtpd_check depends on this.
176  */
177 #define DICT_ERR_NONE 0 /* no error */
178 #define DICT_ERR_RETRY (-1) /* soft error */
179 #define DICT_ERR_CONFIG (-2) /* configuration error */
180 
181  /*
182  * Result values for exposed functions except lookup. FAIL/ERROR are
183  * suggested values, not for use in comparisons for equality.
184  */
185 #define DICT_STAT_FAIL 1 /* any value > 0: notfound, conflict */
186 #define DICT_STAT_SUCCESS 0 /* request satisfied */
187 #define DICT_STAT_ERROR (-1) /* any value < 0: database error */
188 
189  /*
190  * Set an error code and return a result value.
191  */
192 #define DICT_ERR_VAL_RETURN(dict, err, val) do { \
193  (dict)->error = (err); \
194  return (val); \
195  } while (0)
196 
197  /*
198  * Sequence function types.
199  */
200 #define DICT_SEQ_FUN_FIRST 0 /* set cursor to first record */
201 #define DICT_SEQ_FUN_NEXT 1 /* set cursor to next record */
202 
203  /*
204  * Interface for dictionary types.
205  */
206 extern ARGV *dict_mapnames(void);
207 typedef void (*DICT_MAPNAMES_EXTEND_FN) (ARGV *);
209 
210 
211  /*
212  * High-level interface, with logical dictionary names.
213  */
214 extern void dict_register(const char *, DICT *);
215 extern DICT *dict_handle(const char *);
216 extern void dict_unregister(const char *);
217 extern int dict_update(const char *, const char *, const char *);
218 extern const char *dict_lookup(const char *, const char *);
219 extern int dict_delete(const char *, const char *);
220 extern int dict_sequence(const char *, const int, const char **, const char **);
221 extern int dict_load_file_xt(const char *, const char *);
222 extern void dict_load_fp(const char *, VSTREAM *);
223 extern const char *dict_eval(const char *, const char *, int);
224 extern int dict_error(const char *);
225 
226  /*
227  * Low-level interface, with physical dictionary handles.
228  */
229 typedef DICT *(*DICT_OPEN_FN) (const char *, int, int);
230 typedef DICT_OPEN_FN (*DICT_OPEN_EXTEND_FN) (const char *);
231 extern DICT *dict_open(const char *, int, int);
232 extern DICT *dict_open3(const char *, const char *, int, int);
233 extern void dict_open_register(const char *, DICT_OPEN_FN);
235 
236 #define dict_get(dp, key) ((const char *) (dp)->lookup((dp), (key)))
237 #define dict_put(dp, key, val) (dp)->update((dp), (key), (val))
238 #define dict_del(dp, key) (dp)->delete((dp), (key))
239 #define dict_seq(dp, f, key, val) (dp)->sequence((dp), (f), (key), (val))
240 #define dict_close(dp) (dp)->close(dp)
241 typedef void (*DICT_WALK_ACTION) (const char *, DICT *, void *);
242 extern void dict_walk(DICT_WALK_ACTION, void *);
243 extern int dict_changed(void);
244 extern const char *dict_changed_name(void);
245 extern const char *dict_flags_str(int);
246 extern int dict_flags_mask(const char *);
247 extern void dict_type_override(DICT *, const char *);
248 
249  /*
250  * Check and convert UTF-8 keys and values.
251  */
252 typedef struct DICT_UTF8_BACKUP {
253  const char *(*lookup) (struct DICT *, const char *);
254  int (*update) (struct DICT *, const char *, const char *);
255  int (*delete) (struct DICT *, const char *);
257 
258 extern DICT *dict_utf8_activate(DICT *);
259 
260  /*
261  * Driver for interactive or scripted tests.
262  */
263 void dict_test(int, char **);
264 
265  /*
266  * Behind-the-scenes support to continue execution with reduced
267  * functionality.
268  */
269 extern int dict_allow_surrogate;
270 extern DICT *PRINTFLIKE(5, 6) dict_surrogate(const char *, const char *, int, int, const char *,...);
271 
272  /*
273  * This name is reserved for matchlist error handling.
274  */
275 #define DICT_TYPE_NOFILE "non-existent"
276 #define DICT_TYPE_NOUTF8 "non-UTF-8"
277 
278  /*
279  * Duplicated from vstream(3). This should probably be abstracted out.
280  *
281  * Exception handling. We use pointer to jmp_buf to avoid a lot of unused
282  * baggage for streams that don't need this functionality.
283  *
284  * XXX sigsetjmp()/siglongjmp() save and restore the signal mask which can
285  * avoid surprises in code that manipulates signals, but unfortunately some
286  * systems have bugs in their implementation.
287  */
288 #ifdef NO_SIGSETJMP
289 #define dict_setjmp(dict) setjmp((dict)->jbuf[0])
290 #define dict_longjmp(dict, val) longjmp((dict)->jbuf[0], (val))
291 #else
292 #define dict_setjmp(dict) sigsetjmp((dict)->jbuf[0], 1)
293 #define dict_longjmp(dict, val) siglongjmp((dict)->jbuf[0], (val))
294 #endif
295 #define dict_isjmp(dict) ((dict)->jbuf != 0)
296 
297  /*
298  * Temporary API. If exception handling proves to be useful,
299  * dict_jmp_alloc() should be integrated into dict_alloc().
300  */
301 extern void dict_jmp_alloc(DICT *);
302 
303 /* LICENSE
304 /* .ad
305 /* .fi
306 /* The Secure Mailer license must be distributed with this software.
307 /* AUTHOR(S)
308 /* Wietse Venema
309 /* IBM T.J. Watson Research
310 /* P.O. Box 704
311 /* Yorktown Heights, NY 10598, USA
312 /*--*/
313 
314 #endif
DICT_JMP_BUF * jbuf
Definition: dict.h:95
uid_t uid
Definition: dict.h:39
time_t mtime
Definition: dict.h:91
void(* close)(struct DICT *)
Definition: dict.h:87
Definition: argv.h:17
int dict_delete(const char *, const char *)
Definition: dict.c:404
const char * dict_lookup(const char *, const char *)
Definition: dict.c:382
char * name
Definition: dict.h:80
int flags
Definition: dict.h:81
int(* update)(struct DICT *, const char *, const char *)
Definition: dict.h:254
const char * dict_flags_str(int)
Definition: dict.c:647
void dict_unregister(const char *)
Definition: dict.c:354
DICT * dict_open(const char *, int, int)
Definition: dict_open.c:421
DICT_OPEN_FN(* DICT_OPEN_EXTEND_FN)(const char *)
Definition: dict.h:230
DICT const char int
Definition: dict.h:270
int dict_flags_mask(const char *)
Definition: dict.c:660
int dict_changed(void)
Definition: dict.c:613
DICT * dict_open3(const char *, const char *, int, int)
Definition: dict_open.c:439
DICT * dict_handle(const char *)
Definition: dict.c:333
Definition: dict.h:78
int(* lock)(struct DICT *, int)
Definition: dict.h:86
DICT_MAPNAMES_EXTEND_FN dict_mapnames_extend(DICT_MAPNAMES_EXTEND_FN)
Definition: dict_open.c:552
char * type
Definition: dict.h:79
int(* update)(struct DICT *, const char *, const char *)
Definition: dict.h:83
void dict_jmp_alloc(DICT *)
Definition: dict_alloc.c:181
int dict_error(const char *)
Definition: dict.c:431
int stat_fd
Definition: dict.h:90
int lock_type
Definition: dict.h:88
int dict_sequence(const char *, const int, const char **, const char **)
Definition: dict.c:417
int dict_allow_surrogate
void dict_load_fp(const char *, VSTREAM *)
Definition: dict.c:472
DICT * dict_debug(DICT *)
Definition: dict_debug.c:136
int lock_fd
Definition: dict.h:89
void dict_type_override(DICT *, const char *)
Definition: dict_open.c:563
DICT_OPEN_EXTEND_FN dict_open_extend(DICT_OPEN_EXTEND_FN)
Definition: dict_open.c:509
struct DICT DICT
void dict_open_register(const char *, DICT_OPEN_FN)
Definition: dict_open.c:491
struct DICT_UTF8_BACKUP DICT_UTF8_BACKUP
#define DICT_JMP_BUF
Definition: dict.h:23
int error
Definition: dict.h:94
const char * dict_changed_name(void)
Definition: dict.c:583
void(* DICT_WALK_ACTION)(const char *, DICT *, void *)
Definition: dict.h:241
int status
Definition: dict.h:38
void dict_free(DICT *)
Definition: dict_alloc.c:163
void(* DICT_MAPNAMES_EXTEND_FN)(ARGV *)
Definition: dict.h:207
void dict_test(int, char **)
Definition: dict_test.c:36
ARGV * dict_mapnames(void)
Definition: dict_open.c:527
struct DICT_UTF8_BACKUP * utf8_backup
Definition: dict.h:96
DICT *(* DICT_OPEN_FN)(const char *, int, int)
Definition: dict.h:229
struct DICT_OWNER DICT_OWNER
int dict_load_file_xt(const char *, const char *)
Definition: dict.c:441
void dict_register(const char *, DICT *)
Definition: dict.c:312
int dict_update(const char *, const char *, const char *)
Definition: dict.c:369
void dict_walk(DICT_WALK_ACTION, void *)
Definition: dict.c:569
int(* sequence)(struct DICT *, int, const char **, const char **)
Definition: dict.h:85
DICT * dict_alloc(const char *, const char *, ssize_t)
Definition: dict_alloc.c:135
DICT * dict_utf8_activate(DICT *)
Definition: dict_utf8.c:248
VSTRING * fold_buf
Definition: dict.h:92
DICT * PRINTFLIKE(5, 6) dict_surrogate(const char *
const char * dict_eval(const char *, const char *, int)
Definition: dict.c:536
DICT_OWNER owner
Definition: dict.h:93
DICT * dict_surrogate(const char *dict_type, const char *dict_name, int open_flags, int dict_flags, const char *fmt,...)