8ebf6f6e40e875234865473cc1f05eba497eabd8
[exim.git] / src / src / dbstuff.h
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* Copyright (c) The Exim Maintainers 2020 - 2022 */
7 /* See the file NOTICE for conditions of use and distribution. */
8
9 /* This header file contains macro definitions so that a variety of DBM
10 libraries can be used by Exim. Nigel Metheringham provided the original set for
11 Berkeley DB 1.x in native mode and ndbm. Subsequently, versions for Berkeley DB
12 2.x and 3.x were added. Later still, support for tdb was added, courtesy of
13 James Antill. Most recently, support for native mode gdbm was added, with code
14 from Pierre A. Humblet, so Exim could be made to work with Cygwin.
15
16 For convenience, the definitions of the structures used in the various hints
17 databases are also kept in this file, which is used by the maintenance
18 utilities as well as the main Exim binary. */
19
20
21 #ifdef USE_TDB
22
23 /* ************************* tdb interface ************************ */
24
25 # include <tdb.h>
26
27 /* Basic DB type */
28 # define EXIM_DB TDB_CONTEXT
29
30 /* Cursor type: tdb uses the previous "key" in _nextkey() (really it wants
31 tdb_traverse to be called) */
32 # define EXIM_CURSOR TDB_DATA
33
34 /* The datum type used for queries */
35 # define EXIM_DATUM TDB_DATA
36
37 /* Some text for messages */
38 # define EXIM_DBTYPE "tdb"
39
40 /* Access functions */
41
42 /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */
43 # define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
44        *(dbpp) = tdb_open(CS name, 0, TDB_DEFAULT, flags, mode)
45
46 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
47 # define EXIM_DBGET(db, key, data)      \
48        (data = tdb_fetch(db, key), data.dptr != NULL)
49
50 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
51 # define EXIM_DBPUT(db, key, data)      \
52        tdb_store(db, key, data, TDB_REPLACE)
53
54 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
55 # define EXIM_DBPUTB(db, key, data)      \
56        tdb_store(db, key, data, TDB_INSERT)
57
58 /* Returns from EXIM_DBPUTB */
59
60 # define EXIM_DBPUTB_OK  0
61 # define EXIM_DBPUTB_DUP (-1)
62
63 /* EXIM_DBDEL */
64 # define EXIM_DBDEL(db, key) tdb_delete(db, key)
65
66 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
67 # define EXIM_DBCREATE_CURSOR(db, cursor) { \
68    *(cursor) = store_malloc(sizeof(TDB_DATA)); (*(cursor))->dptr = NULL; }
69
70 /* EXIM_DBSCAN - This is complicated because we have to free the last datum
71 free() must not die when passed NULL */
72 # define EXIM_DBSCAN(db, key, data, first, cursor)      \
73        (key = (first ? tdb_firstkey(db) : tdb_nextkey(db, *(cursor))), \
74         free((cursor)->dptr), *(cursor) = key, \
75         key.dptr != NULL)
76
77 /* EXIM_DBDELETE_CURSOR - terminate scanning operation. */
78 # define EXIM_DBDELETE_CURSOR(cursor) store_free(cursor)
79
80 /* EXIM_DBCLOSE */
81 # define EXIM_DBCLOSE__(db)        tdb_close(db)
82
83 /* Datum access types - these are intended to be assignable */
84
85 # define EXIM_DATUM_SIZE(datum)  (datum).dsize
86 # define EXIM_DATUM_DATA(datum)  (datum).dptr
87
88 /* Free the stuff inside the datum. */
89
90 # define EXIM_DATUM_FREE(datum)  (free((datum).dptr), (datum).dptr = NULL)
91
92 /* No initialization is needed. */
93
94 # define EXIM_DATUM_INIT(datum)
95
96 /* size limit */
97
98 # define EXIM_DB_RLIMIT 150
99
100
101
102
103
104
105 /********************* Berkeley db native definitions **********************/
106
107 #elif defined USE_DB
108
109 # include <db.h>
110
111
112 /* We can distinguish between versions 1.x and 2.x/3.x by looking for a
113 definition of DB_VERSION_STRING, which is present in versions 2.x onwards. */
114
115 # ifdef DB_VERSION_STRING
116
117 #  if DB_VERSION_MAJOR >= 6
118 #   error Version 6 and later BDB API is not supported
119 #  endif
120
121 /* The API changed (again!) between the 2.x and 3.x versions */
122
123 #  if DB_VERSION_MAJOR >= 3
124
125 /***************** Berkeley db 3.x/4.x native definitions ******************/
126
127 /* Basic DB type */
128 #   if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
129 #    define EXIM_DB       DB_ENV
130 /* Cursor type, for scanning */
131 #    define EXIM_CURSOR   DBC
132
133 /* The datum type used for queries */
134 #    define EXIM_DATUM    DBT
135
136 /* Some text for messages */
137 #    define EXIM_DBTYPE   "db (v4.1+)"
138
139 /* Only more-recent versions.  5+ ? */
140 #    ifndef DB_FORCESYNC
141 #     define DB_FORCESYNC 0
142 #    endif
143
144
145 /* Access functions */
146
147 /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed. The
148 API changed for DB 4.1. - and we also starting using the "env" with a
149 specified working dir, to avoid the DBCONFIG file trap. */
150
151 #    define ENV_TO_DB(env) ((DB *)((env)->app_private))
152
153 #    define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
154   if (  db_env_create(dbpp, 0) != 0                                             \
155      || ((*dbpp)->set_errcall(*dbpp, dbfn_bdb_error_callback), 0)               \
156      || (*dbpp)->open(*dbpp, CS dirname, DB_CREATE|DB_INIT_MPOOL|DB_PRIVATE, 0) != 0\
157      )                                                                          \
158     *dbpp = NULL;                                       \
159   else if (db_create((DB **) &((*dbpp)->app_private), *dbpp, 0) != 0)           \
160     {                                                   \
161     ((DB_ENV *)(*dbpp))->close((DB_ENV *)(*dbpp), 0);   \
162     *dbpp = NULL;                                       \
163     }                                                   \
164   else if (ENV_TO_DB(*dbpp)->open(ENV_TO_DB(*dbpp), NULL, CS name, NULL,        \
165               (flags) == O_RDONLY ? DB_UNKNOWN : DB_HASH,                       \
166               (flags) == O_RDONLY ? DB_RDONLY : DB_CREATE,                      \
167               mode) != 0                                                        \
168           )                                                                     \
169     {                                                   \
170     ENV_TO_DB(*dbpp)->close(ENV_TO_DB(*dbpp), 0);       \
171     ((DB_ENV *)(*dbpp))->close((DB_ENV *)(*dbpp), 0);   \
172     *dbpp = NULL;                                       \
173     }
174
175 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
176 #    define EXIM_DBGET(db, key, data)      \
177        (ENV_TO_DB(db)->get(ENV_TO_DB(db), NULL, &key, &data, 0) == 0)
178
179 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
180 #    define EXIM_DBPUT(db, key, data)      \
181        ENV_TO_DB(db)->put(ENV_TO_DB(db), NULL, &key, &data, 0)
182
183 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
184 #    define EXIM_DBPUTB(db, key, data)      \
185        ENV_TO_DB(db)->put(ENV_TO_DB(db), NULL, &key, &data, DB_NOOVERWRITE)
186
187 /* Return values from EXIM_DBPUTB */
188
189 #    define EXIM_DBPUTB_OK  0
190 #    define EXIM_DBPUTB_DUP DB_KEYEXIST
191
192 /* EXIM_DBDEL */
193 #    define EXIM_DBDEL(db, key)     ENV_TO_DB(db)->del(ENV_TO_DB(db), NULL, &key, 0)
194
195 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
196
197 #    define EXIM_DBCREATE_CURSOR(db, cursor) \
198        ENV_TO_DB(db)->cursor(ENV_TO_DB(db), NULL, cursor, 0)
199
200 /* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */
201 #    define EXIM_DBSCAN(db, key, data, first, cursor)      \
202        ((cursor)->c_get(cursor, &key, &data,         \
203          (first? DB_FIRST : DB_NEXT)) == 0)
204
205 /* EXIM_DBDELETE_CURSOR - terminate scanning operation */
206 #    define EXIM_DBDELETE_CURSOR(cursor) \
207        (cursor)->c_close(cursor)
208
209 /* EXIM_DBCLOSE */
210 #    define EXIM_DBCLOSE__(db) \
211         (ENV_TO_DB(db)->close(ENV_TO_DB(db), 0) , ((DB_ENV *)(db))->close((DB_ENV *)(db), DB_FORCESYNC))
212
213 /* Datum access types - these are intended to be assignable. */
214
215 #    define EXIM_DATUM_SIZE(datum)  (datum).size
216 #    define EXIM_DATUM_DATA(datum)  (datum).data
217
218 /* The whole datum structure contains other fields that must be cleared
219 before use, but we don't have to free anything after reading data. */
220
221 #    define EXIM_DATUM_INIT(datum)   memset(&datum, 0, sizeof(datum))
222 #    define EXIM_DATUM_FREE(datum)
223
224 #   else        /* pre- 4.1 */
225
226 #    define EXIM_DB       DB
227
228 /* Cursor type, for scanning */
229 #    define EXIM_CURSOR   DBC
230
231 /* The datum type used for queries */
232 #    define EXIM_DATUM    DBT
233
234 /* Some text for messages */
235 #    define EXIM_DBTYPE   "db (v3/4)"
236
237 /* Access functions */
238
239 /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed. */
240
241 #    define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
242        if (db_create(dbpp, NULL, 0) != 0 || \
243          ((*dbpp)->set_errcall(*dbpp, dbfn_bdb_error_callback), \
244          ((*dbpp)->open)(*dbpp, CS name, NULL, \
245          ((flags) == O_RDONLY)? DB_UNKNOWN : DB_HASH, \
246          ((flags) == O_RDONLY)? DB_RDONLY : DB_CREATE, \
247          mode)) != 0) *(dbpp) = NULL
248
249 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
250 #    define EXIM_DBGET(db, key, data)      \
251        ((db)->get(db, NULL, &key, &data, 0) == 0)
252
253 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
254 #    define EXIM_DBPUT(db, key, data)      \
255        (db)->put(db, NULL, &key, &data, 0)
256
257 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
258 #    define EXIM_DBPUTB(db, key, data)      \
259        (db)->put(db, NULL, &key, &data, DB_NOOVERWRITE)
260
261 /* Return values from EXIM_DBPUTB */
262
263 #    define EXIM_DBPUTB_OK  0
264 #    define EXIM_DBPUTB_DUP DB_KEYEXIST
265
266 /* EXIM_DBDEL */
267 #    define EXIM_DBDEL(db, key)     (db)->del(db, NULL, &key, 0)
268
269 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
270
271 #    define EXIM_DBCREATE_CURSOR(db, cursor) \
272        (db)->cursor(db, NULL, cursor, 0)
273
274 /* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */
275 #    define EXIM_DBSCAN(db, key, data, first, cursor)      \
276        ((cursor)->c_get(cursor, &key, &data,         \
277          (first? DB_FIRST : DB_NEXT)) == 0)
278
279 /* EXIM_DBDELETE_CURSOR - terminate scanning operation */
280 #    define EXIM_DBDELETE_CURSOR(cursor) \
281        (cursor)->c_close(cursor)
282
283 /* EXIM_DBCLOSE */
284 #    define EXIM_DBCLOSE__(db)        (db)->close(db, 0)
285
286 /* Datum access types - these are intended to be assignable. */
287
288 #    define EXIM_DATUM_SIZE(datum)  (datum).size
289 #    define EXIM_DATUM_DATA(datum)  (datum).data
290
291 /* The whole datum structure contains other fields that must be cleared
292 before use, but we don't have to free anything after reading data. */
293
294 #    define EXIM_DATUM_INIT(datum)   memset(&datum, 0, sizeof(datum))
295 #    define EXIM_DATUM_FREE(datum)
296
297 #   endif
298
299
300 #  else /* DB_VERSION_MAJOR >= 3 */
301 #   error Berkeley DB versions earlier than 3 are not supported */
302 #  endif /* DB_VERSION_MAJOR */
303 # else
304 #  error Berkeley DB version 1 is no longer supported
305 # endif /* DB_VERSION_STRING */
306
307
308 /* all BDB versions */
309 /* size limit */
310
311 # define EXIM_DB_RLIMIT 150
312
313
314
315
316
317
318 /********************* gdbm interface definitions **********************/
319
320 #elif defined USE_GDBM
321
322 # include <gdbm.h>
323
324 /* Basic DB type */
325 typedef struct {
326        GDBM_FILE gdbm;  /* Database */
327        datum lkey;      /* Last key, for scans */
328 } gdbm_db;
329
330 #define EXIM_DB gdbm_db
331
332 /* Cursor type, not used with gdbm: just set up a dummy */
333 # define EXIM_CURSOR int
334
335 /* The datum type used for queries */
336 # define EXIM_DATUM datum
337
338 /* Some text for messages */
339
340 # define EXIM_DBTYPE "gdbm"
341
342 /* Access functions */
343
344 /* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
345 # define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
346      { EXIM_DB * dbp = malloc(sizeof(EXIM_DB));\
347        if (dbp) { \
348          dbp->lkey.dptr = NULL;\
349          dbp->gdbm = gdbm_open(CS name, 0, (((flags) & O_CREAT))?GDBM_WRCREAT:(((flags) & (O_RDWR|O_WRONLY))?GDBM_WRITER:GDBM_READER), (mode), 0);\
350           if (!dbp->gdbm) {\
351               free(dbp);\
352               dbp = NULL;\
353           }\
354        }\
355        *(dbpp) = dbp;\
356      }
357
358 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
359 # define EXIM_DBGET(db, key, data)      \
360        (data = gdbm_fetch(db->gdbm, key), data.dptr != NULL)
361
362 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
363 # define EXIM_DBPUT(db, key, data)      \
364        gdbm_store(db->gdbm, key, data, GDBM_REPLACE)
365
366 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
367 # define EXIM_DBPUTB(db, key, data)      \
368        gdbm_store(db->gdbm, key, data, GDBM_INSERT)
369
370 /* Returns from EXIM_DBPUTB */
371
372 # define EXIM_DBPUTB_OK  0
373 # define EXIM_DBPUTB_DUP 1
374
375 /* EXIM_DBDEL */
376 # define EXIM_DBDEL(db, key) gdbm_delete(db->gdbm, key)
377
378 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */
379 # define EXIM_DBCREATE_CURSOR(db, cursor) {}
380
381 /* EXIM_DBSCAN */
382 # define EXIM_DBSCAN(db, key, data, first, cursor)      \
383   ( key = ((first)? gdbm_firstkey(db->gdbm) : gdbm_nextkey(db->gdbm, db->lkey)), \
384     (((db)->lkey.dptr != NULL)? (free((db)->lkey.dptr),1) : 1),\
385     db->lkey = key, key.dptr != NULL)
386
387 /* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). */
388 # define EXIM_DBDELETE_CURSOR(cursor) { }
389
390 /* EXIM_DBCLOSE */
391 # define EXIM_DBCLOSE__(db) \
392 { gdbm_close((db)->gdbm);\
393   if ((db)->lkey.dptr != NULL) free((db)->lkey.dptr);\
394   free(db); }
395
396 /* Datum access types - these are intended to be assignable */
397
398 # define EXIM_DATUM_SIZE(datum) (datum).dsize
399 # define EXIM_DATUM_DATA(datum) (datum).dptr
400
401 /* There's no clearing required before use, but we have to free the dptr
402 after reading data. */
403
404 # define EXIM_DATUM_INIT(datum)
405 # define EXIM_DATUM_FREE(datum) free(datum.dptr)
406
407 /* size limit */
408
409 # define EXIM_DB_RLIMIT 150
410
411 #else  /* USE_GDBM */
412
413
414
415
416
417
418 /* If none of USE_DB, USG_GDBM, or USE_TDB are set, the default is the NDBM
419 interface */
420
421
422 /********************* ndbm interface definitions **********************/
423
424 # include <ndbm.h>
425
426 /* Basic DB type */
427 # define EXIM_DB DBM
428
429 /* Cursor type, not used with ndbm: just set up a dummy */
430 # define EXIM_CURSOR int
431
432 /* The datum type used for queries */
433 # define EXIM_DATUM datum
434
435 /* Some text for messages */
436
437 # define EXIM_DBTYPE "ndbm"
438
439 /* Access functions */
440
441 /* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
442 /* Check that the name given is not present. This catches
443 a directory name; otherwise we would create the name.pag and
444 name.dir files in the directory's parent. */
445
446 # define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp)                \
447        {                                                                \
448        struct stat st;                                                  \
449        *(dbpp) =    !(flags & O_CREAT)                                  \
450                  || lstat(CCS (name), &st) != 0 && errno == ENOENT      \
451          ? dbm_open(CS (name), (flags), (mode))                         \
452          : (errno = (st.st_mode & S_IFMT) == S_IFDIR ? EISDIR : EEXIST, \
453            NULL);                                                       \
454        }
455
456 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
457 # define EXIM_DBGET(db, key, data)      \
458        (data = dbm_fetch(db, key), data.dptr != NULL)
459
460 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
461 # define EXIM_DBPUT(db, key, data)      \
462        dbm_store(db, key, data, DBM_REPLACE)
463
464 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
465 # define EXIM_DBPUTB(db, key, data)      \
466        dbm_store(db, key, data, DBM_INSERT)
467
468 /* Returns from EXIM_DBPUTB */
469
470 # define EXIM_DBPUTB_OK  0
471 # define EXIM_DBPUTB_DUP 1
472
473 /* EXIM_DBDEL */
474 # define EXIM_DBDEL(db, key) dbm_delete(db, key)
475
476 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */
477 # define EXIM_DBCREATE_CURSOR(db, cursor) {}
478
479 /* EXIM_DBSCAN */
480 # define EXIM_DBSCAN(db, key, data, first, cursor)      \
481        (key = (first? dbm_firstkey(db) : dbm_nextkey(db)), key.dptr != NULL)
482
483 /* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). */
484 # define EXIM_DBDELETE_CURSOR(cursor) { }
485
486 /* EXIM_DBCLOSE */
487 # define EXIM_DBCLOSE__(db) dbm_close(db)
488
489 /* Datum access types - these are intended to be assignable */
490
491 # define EXIM_DATUM_SIZE(datum) (datum).dsize
492 # define EXIM_DATUM_DATA(datum) (datum).dptr
493
494 /* There's no clearing required before use, and we don't have to free anything
495 after reading data. */
496
497 # define EXIM_DATUM_INIT(datum)
498 # define EXIM_DATUM_FREE(datum)
499
500 /* size limit */
501
502 # define EXIM_DB_RLIMIT 150
503
504 #endif /* USE_GDBM */
505
506
507
508
509
510 #ifdef COMPILE_UTILITY
511
512 # define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \
513   EXIM_DBOPEN__(name, dirname, flags, mode, dbpp)
514 # define EXIM_DBCLOSE(db) EXIM_DBCLOSE__(db)
515
516 #else
517
518 # define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \
519   do { \
520   DEBUG(D_hints_lookup) \
521     debug_printf_indent("EXIM_DBOPEN: file <%s> dir <%s> flags=%s\n", \
522       (name), (dirname),                \
523       (flags) == O_RDONLY ? "O_RDONLY"  \
524       : (flags) == O_RDWR ? "O_RDWR"    \
525       : (flags) == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT"  \
526       : "??");  \
527   if (is_tainted(name) || is_tainted(dirname)) \
528     { \
529     log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted"); \
530     *dbpp = NULL; \
531     } \
532   else \
533     { EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); } \
534   DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", *dbpp); \
535   } while(0)
536 # define EXIM_DBCLOSE(db) \
537   do { \
538   DEBUG(D_hints_lookup) debug_printf_indent("EXIM_DBCLOSE(%p)\n", db); \
539   EXIM_DBCLOSE__(db); \
540   } while(0)
541
542 # endif
543
544 #ifndef EXIM_DB
545 # define EXIM_DB void           /* dummy */
546 #endif
547 #ifndef EXIM_CURSOR
548 # define EXIM_CURSOR void       /* dummy */
549 #endif
550 /********************* End of dbm library definitions **********************/
551
552
553 /* Structure for carrying around an open DBM file, and an open locking file
554 that relates to it. */
555
556 typedef struct {
557   EXIM_DB *dbptr;
558   int lockfd;
559 } open_db;
560
561
562 /* Structures for records stored in exim database dbm files. They all
563 start with the same fields, described in the generic type. */
564
565
566 typedef struct {
567   time_t time_stamp;      /* Timestamp of writing */
568 } dbdata_generic;
569
570
571 /* This structure keeps track of retry information for a host or a local
572 address. */
573
574 typedef struct {
575   time_t time_stamp;
576   /*************/
577   time_t first_failed;    /* Time of first failure */
578   time_t last_try;        /* Time of last try */
579   time_t next_try;        /* Time of next try */
580   BOOL   expired;         /* Retry time has expired */
581   int    basic_errno;     /* Errno of last failure */
582   int    more_errno;      /* Additional information */
583   uschar text[1];         /* Text message for last failure */
584 } dbdata_retry;
585
586 /* These structures keep track of addresses that have had callout verification
587 performed on them. There are two groups of records:
588
589 1. keyed by localpart@domain -
590      Full address was tested and record holds result
591
592 2. keyed by domain -
593      Domain response upto MAIL FROM:<>, postmaster, random local part;
594
595 If a record exists, the result field is either ccache_accept or ccache_reject,
596 or, for a domain record only, ccache_reject_mfnull when MAIL FROM:<> was
597 rejected. The other fields, however, (which are only relevant to domain
598 records) may also contain ccache_unknown if that particular test has not been
599 done.
600
601 Originally, there was only one structure, used for both types. However, it got
602 expanded for domain records, so it got split. To make it possible for Exim to
603 handle the old type of record, we retain the old definition. The different
604 kinds of record can be distinguished by their different lengths. */
605
606 typedef struct {
607   time_t time_stamp;
608   /*************/
609   int   result;
610   int   postmaster_result; /* Postmaster is accepted */
611   int   random_result;     /* Random local part was accepted */
612 } dbdata_callout_cache_obs;
613
614 typedef struct {
615   time_t time_stamp;       /* Timestamp of last address check */
616   /*************/
617   int   result;            /* accept or reject */
618 } dbdata_callout_cache_address;
619
620 /* For this new layout, we put the additional fields (the timestamps)
621 last so that if somebody reverts to an older Exim, the new records will
622 still make sense because they match the old layout. */
623
624 typedef struct {
625   time_t time_stamp;       /* Time stamp of last connection */
626   /*************/
627   int   result;            /* Domain reject or accept */
628   int   postmaster_result; /* Postmaster result */
629   int   random_result;     /* Random result */
630   time_t postmaster_stamp; /* Timestamp of postmaster check */
631   time_t random_stamp;     /* Timestamp of random check */
632 } dbdata_callout_cache;
633
634 /* This structure keeps track of messages that are waiting for a particular
635 host for a particular transport. */
636
637 typedef struct {
638   time_t time_stamp;
639   /*************/
640   int    count;           /* Count of message ids */
641   int    sequence;        /* Sequence for continued records */
642   uschar text[1];         /* One long character string */
643 } dbdata_wait;
644
645
646 /* The contents of the "misc" database are a mixture of different kinds of
647 record, as defined below. The keys used for a specific type all start with a
648 given string such as "etrn-" or "host-serialize-". */
649
650
651 /* This structure records a connection to a particular host, for the
652 purpose of serializing access to certain hosts. For possible future extension,
653 a field is defined for holding the count of connections, but it is not
654 at present in use. The same structure is used for recording a running ETRN
655 process. */
656
657 typedef struct {
658   time_t time_stamp;
659   /*************/
660   int    count;           /* Reserved for possible connection count */
661 } dbdata_serialize;
662
663
664 /* This structure records the information required for the ratelimit
665 ACL condition. */
666
667 typedef struct {
668   time_t time_stamp;
669   /*************/
670   int    time_usec;       /* Fractional part of time, from gettimeofday() */
671   double rate;            /* Smoothed sending rate at that time */
672 } dbdata_ratelimit;
673
674 /* Same as above, plus a Bloom filter for uniquifying events. */
675
676 typedef struct {
677   dbdata_ratelimit dbd;
678   time_t   bloom_epoch;   /* When the Bloom filter was last reset */
679   unsigned bloom_size;    /* Number of bytes in the Bloom filter */
680   uschar   bloom[40];     /* Bloom filter which may be larger than this */
681 } dbdata_ratelimit_unique;
682
683
684 /* For "seen" ACL condition */
685 typedef struct {
686   time_t time_stamp;
687 } dbdata_seen;
688
689 #ifndef DISABLE_PIPE_CONNECT
690 /* This structure records the EHLO responses, cleartext and crypted,
691 for an IP, as bitmasks (cf. OPTION_TLS).  For LIMITS, also values
692 advertised for MAILMAX, RCPTMAX and RCPTDOMAINMAX; zero meaning no
693 value advertised. */
694
695 typedef struct {
696   unsigned short cleartext_features;
697   unsigned short crypted_features;
698   unsigned short cleartext_auths;
699   unsigned short crypted_auths;
700
701 # ifdef EXPERIMENTAL_ESMTP_LIMITS
702   unsigned int limit_mail;
703   unsigned int limit_rcpt;
704   unsigned int limit_rcptdom;
705 # endif
706 } ehlo_resp_precis;
707
708 typedef struct {
709   time_t time_stamp;
710   /*************/
711   ehlo_resp_precis data;
712 } dbdata_ehlo_resp;
713 #endif
714
715 typedef struct {
716   time_t time_stamp;
717   /*************/
718   uschar verify_override:1;
719   uschar ocsp:3;
720   uschar session[1];
721 } dbdata_tls_session;
722
723
724 /* End of dbstuff.h */