I think this would be the way to go.
On Wed, Aug 21, 2013 at 9:14 AM, Todd C. Miller
<todd.mil...@courtesan.com> wrote:
> Speaking of spamd, I've been running the following diff for five
> months or so. It removes the use of time_t in the greylist db file
> and provides backwards compat for 32-bit times.
>
> - todd
>
> Index: usr.sbin/spamdb/Makefile
> ===================================================================
> RCS file: /home/cvs/openbsd/src/usr.sbin/spamdb/Makefile,v
> retrieving revision 1.3
> diff -u -p -u -r1.3 Makefile
> --- usr.sbin/spamdb/Makefile 24 May 2005 22:23:05 -0000 1.3
> +++ usr.sbin/spamdb/Makefile 22 Apr 2013 20:03:45 -0000
> @@ -1,9 +1,11 @@
> # $OpenBSD: Makefile,v 1.3 2005/05/24 22:23:05 millert Exp $
>
> PROG= spamdb
> -SRCS= spamdb.c
> +SRCS= spamdb.c gdcopy.c
> MAN= spamdb.8
>
> CFLAGS+= -Wall -Wstrict-prototypes -I${.CURDIR}/../../libexec/spamd
> +
> +.PATH: ${.CURDIR}/../../libexec/spamd
>
> .include <bsd.prog.mk>
> Index: usr.sbin/spamdb/spamdb.c
> ===================================================================
> RCS file: /home/cvs/openbsd/src/usr.sbin/spamdb/spamdb.c,v
> retrieving revision 1.26
> diff -u -p -u -r1.26 spamdb.c
> --- usr.sbin/spamdb/spamdb.c 22 Apr 2013 19:49:36 -0000 1.26
> +++ usr.sbin/spamdb/spamdb.c 22 Apr 2013 20:03:45 -0000
> @@ -129,12 +129,11 @@ dbupdate(DB *db, char *ip, int add, int
> goto bad;
> }
> } else {
> - if (dbd.size != sizeof(gd)) {
> + if (gdcopyin(&dbd, &gd) == -1) {
> /* whatever this is, it doesn't belong */
> db->del(db, &dbk, 0);
> goto bad;
> }
> - memcpy(&gd, dbd.data, sizeof(gd));
> gd.pcount++;
> switch (type) {
> case WHITE:
> @@ -185,11 +184,10 @@ dblist(DB *db)
> r = db->seq(db, &dbk, &dbd, R_NEXT)) {
> char *a, *cp;
>
> - if ((dbk.size < 1) || dbd.size != sizeof(struct gdata)) {
> + if ((dbk.size < 1) || gdcopyin(&dbd, &gd) == -1) {
> db->close(db);
> errx(1, "bogus size db entry - bad db file?");
> }
> - memcpy(&gd, dbd.data, sizeof(gd));
> a = malloc(dbk.size + 1);
> if (a == NULL)
> err(1, "malloc");
> Index: libexec/spamd/Makefile
> ===================================================================
> RCS file: /home/cvs/openbsd/src/libexec/spamd/Makefile,v
> retrieving revision 1.9
> diff -u -p -u -r1.9 Makefile
> --- libexec/spamd/Makefile 4 Mar 2007 03:19:41 -0000 1.9
> +++ libexec/spamd/Makefile 22 Apr 2013 20:03:45 -0000
> @@ -1,7 +1,7 @@
> # $OpenBSD: Makefile,v 1.9 2007/03/04 03:19:41 beck Exp $
>
> PROG= spamd
> -SRCS= spamd.c sdl.c grey.c sync.c
> +SRCS= spamd.c sdl.c gdcopy.c grey.c sync.c
> MAN= spamd.8
>
> CFLAGS+= -Wall -Wstrict-prototypes
> Index: libexec/spamd/gdcopy.c
> ===================================================================
> RCS file: libexec/spamd/gdcopy.c
> diff -N libexec/spamd/gdcopy.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ libexec/spamd/gdcopy.c 22 Apr 2013 20:03:45 -0000
> @@ -0,0 +1,50 @@
> +/*
> + * Copyright (c) 2013 Todd C. Miller <todd.mil...@courtesan.com>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include <sys/types.h>
> +#include <db.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <time.h>
> +
> +#include "grey.h"
> +
> +/* Fill in struct gdata from DBT, converting from obsolete format as needed.
> */
> +int
> +gdcopyin(const void *v, struct gdata *gd)
> +{
> + const DBT *dbd = v;
> + int rc = 0;
> +
> + if (dbd->size == sizeof(struct gdata)) {
> + /* Current grey data format. */
> + memcpy(gd, dbd->data, sizeof(struct gdata));
> + } else if (dbd->size == sizeof(struct ogdata)) {
> + /* Backwards compat for obsolete grey data format. */
> + struct ogdata ogd;
> + memcpy(&ogd, dbd->data, sizeof(struct ogdata));
> + gd->first = ogd.first;
> + gd->pass = ogd.pass;
> + gd->expire = ogd.expire;
> + gd->bcount = ogd.bcount;
> + gd->pcount = ogd.pcount;
> + } else {
> + /* Unsupported grey data format. */
> + rc = -1;
> + }
> + return (rc);
> +}
> Index: libexec/spamd/grey.c
> ===================================================================
> RCS file: /home/cvs/openbsd/src/libexec/spamd/grey.c,v
> retrieving revision 1.52
> diff -u -p -u -r1.52 grey.c
> --- libexec/spamd/grey.c 2 Oct 2012 15:26:17 -0000 1.52
> +++ libexec/spamd/grey.c 22 Apr 2013 20:03:45 -0000
> @@ -540,7 +540,6 @@ do_changes(DB *db)
> int
> db_addrstate(DB *db, char *key)
> {
> - int i;
> DBT dbk, dbd;
> struct gdata gd;
>
> @@ -548,14 +547,18 @@ db_addrstate(DB *db, char *key)
> dbk.size = strlen(key);
> dbk.data = key;
> memset(&dbd, 0, sizeof(dbd));
> - i = db->get(db, &dbk, &dbd, 0);
> - if (i == -1)
> - return (-1);
> - if (i)
> - /* not in the database */
> + switch (db->get(db, &dbk, &dbd, 0)) {
> + case 1:
> + /* not found */
> return (0);
> - memcpy(&gd, dbd.data, sizeof(gd));
> - return gd.pcount == -1 ? 1 : 2;
> + case 0:
> + if (gdcopyin(&dbd, &gd) != -1)
> + return (gd.pcount == -1 ? 1 : 2);
> + /* FALLTHROUGH */
> + default:
> + /* error */
> + return (-1);
> + }
> }
>
>
> @@ -582,7 +585,7 @@ greyscan(char *dbname)
> memset(&dbd, 0, sizeof(dbd));
> for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r;
> r = db->seq(db, &dbk, &dbd, R_NEXT)) {
> - if ((dbk.size < 1) || dbd.size != sizeof(struct gdata)) {
> + if ((dbk.size < 1) || gdcopyin(&dbd, &gd) == -1) {
> syslog_r(LOG_ERR, &sdata, "bogus entry in spamd
> database");
> goto bad;
> }
> @@ -597,7 +600,6 @@ greyscan(char *dbname)
> }
> memset(a, 0, asiz);
> memcpy(a, dbk.data, dbk.size);
> - memcpy(&gd, dbd.data, sizeof(gd));
> if (gd.expire <= now && gd.pcount != -2) {
> /* get rid of entry */
> if (queue_change(a, NULL, 0, DBC_DEL) == -1)
> @@ -719,7 +721,7 @@ twupdate(char *dbname, char *what, char
>
> now = time(NULL);
> /* expiry times have to be in the future */
> - expire = strtonum(expires, now, INT_MAX, NULL);
> + expire = strtonum(expires, now, sizeof(time_t) == sizeof(int) ?
> INT_MAX : LLONG_MAX, NULL);
> if (expire == 0)
> return(-1);
>
> @@ -766,13 +768,12 @@ twupdate(char *dbname, char *what, char
> expires);
> } else {
> /* existing entry */
> - if (dbd.size != sizeof(gd)) {
> + if (gdcopyin(&dbd, &gd) == -1) {
> /* whatever this is, it doesn't belong */
> db->del(db, &dbk, 0);
> db->sync(db, 0);
> goto bad;
> }
> - memcpy(&gd, dbd.data, sizeof(gd));
> if (spamtrap) {
> gd.pcount = -1;
> gd.bcount++;
> @@ -889,13 +890,12 @@ greyupdate(char *dbname, char *helo, cha
> spamtrap ? "greytrap " : "", ip, from, to, helo);
> } else {
> /* existing entry */
> - if (dbd.size != sizeof(gd)) {
> + if (gdcopyin(&dbd, &gd) == -1) {
> /* whatever this is, it doesn't belong */
> db->del(db, &dbk, 0);
> db->sync(db, 0);
> goto bad;
> }
> - memcpy(&gd, dbd.data, sizeof(gd));
> gd.bcount++;
> gd.pcount = spamtrap ? -1 : 0;
> if (gd.first + passtime < now)
> @@ -979,7 +979,7 @@ greyreader(void)
> sync = 1;
> if (grey == NULL) {
> syslog_r(LOG_ERR, &sdata, "No greylist pipe stream!\n");
> - exit(1);
> + return (-1);
> }
>
> /* grab trap suffixes */
> @@ -1140,10 +1140,11 @@ greywatcher(void)
> */
> close(pfdev);
> setproctitle("(%s update)", PATH_SPAMD_DB);
> - greyreader();
> - syslog_r(LOG_ERR, &sdata, "greyreader failed (%m)");
> - /* NOTREACHED */
> - _exit(1);
> + if (greyreader() == -1) {
> + syslog_r(LOG_ERR, &sdata, "greyreader failed (%m)");
> + _exit(1);
> + }
> + _exit(0);
> }
>
>
> Index: libexec/spamd/grey.h
> ===================================================================
> RCS file: /home/cvs/openbsd/src/libexec/spamd/grey.h,v
> retrieving revision 1.9
> diff -u -p -u -r1.9 grey.h
> --- libexec/spamd/grey.h 6 Mar 2007 23:38:36 -0000 1.9
> +++ libexec/spamd/grey.h 22 Apr 2013 20:03:45 -0000
> @@ -27,13 +27,23 @@
> #define DB_TRAP_INTERVAL 60 * 10
> #define PATH_SPAMD_DB "/var/db/spamd"
>
> +/* Obsolete grey data format. */
> +struct ogdata {
> + int32_t first; /* when did we see it first */
> + int32_t pass; /* when was it whitelisted */
> + int32_t expire; /* when will we get rid of this entry */
> + int bcount; /* how many times have we blocked it */
> + int pcount; /* how many times passed, or -1 for spamtrap */
> +};
> +
> struct gdata {
> - time_t first; /* when did we see it first */
> - time_t pass; /* when was it whitelisted */
> - time_t expire; /* when will we get rid of this entry */
> - int bcount; /* how many times have we blocked it */
> - int pcount; /* how many times passed, or -1 for spamtrap */
> + int64_t first; /* when did we see it first */
> + int64_t pass; /* when was it whitelisted */
> + int64_t expire; /* when will we get rid of this entry */
> + int bcount; /* how many times have we blocked it */
> + int pcount; /* how many times passed, or -1 for spamtrap */
> };
>
> extern int greywatcher(void);
> extern int greyupdate(char *, char *, char *, char *, char *, int, char *);
> +extern int gdcopyin(const void *, struct gdata *);
> Index: libexec/spamlogd/Makefile
> ===================================================================
> RCS file: /home/cvs/openbsd/src/libexec/spamlogd/Makefile,v
> retrieving revision 1.6
> diff -u -p -u -r1.6 Makefile
> --- libexec/spamlogd/Makefile 4 Mar 2007 03:19:41 -0000 1.6
> +++ libexec/spamlogd/Makefile 22 Apr 2013 20:03:45 -0000
> @@ -1,7 +1,7 @@
> # $OpenBSD: Makefile,v 1.6 2007/03/04 03:19:41 beck Exp $
>
> PROG= spamlogd
> -SRCS= spamlogd.c sync.c
> +SRCS= spamlogd.c sync.c gdcopy.c
> MAN= spamlogd.8
>
> CFLAGS+= -Wall -Wstrict-prototypes -I${.CURDIR}/../spamd
> Index: libexec/spamlogd/spamlogd.c
> ===================================================================
> RCS file: /home/cvs/openbsd/src/libexec/spamlogd/spamlogd.c,v
> retrieving revision 1.21
> diff -u -p -u -r1.21 spamlogd.c
> --- libexec/spamlogd/spamlogd.c 18 Mar 2011 22:37:06 -0000 1.21
> +++ libexec/spamlogd/spamlogd.c 22 Apr 2013 20:03:45 -0000
> @@ -250,12 +250,12 @@ dbupdate(char *dbname, char *ip)
> goto bad;
> }
> } else {
> - if (dbd.size != sizeof(gd)) {
> + /* XXX - backwards compat */
> + if (gdcopyin(&dbd, &gd) == -1) {
> /* whatever this is, it doesn't belong */
> db->del(db, &dbk, 0);
> goto bad;
> }
> - memcpy(&gd, dbd.data, sizeof(gd));
> gd.pcount++;
> gd.expire = now + whiteexp;
> memset(&dbk, 0, sizeof(dbk));
>