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 <[email protected]>
+ *
+ * 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));