summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2004-03-13 17:46:16 +0000
committerBob Beck <beck@cvs.openbsd.org>2004-03-13 17:46:16 +0000
commit4d052fa31b15731d9e172f7f1873b02a329d8cc5 (patch)
treec7a84ee27ec01dcde4614e23ca14fb732e6777cc
parentf554452c3e4eb6b4a6e9cf535ffe18d7b804d420 (diff)
Add signal handler to parent, so that when greylisting we don't need to
kill all three processes to make it go away. Adjust daemon() call and logging appropriately. ok henning@, millert@
-rw-r--r--libexec/spamd/grey.c65
-rw-r--r--libexec/spamd/spamd.c38
2 files changed, 69 insertions, 34 deletions
diff --git a/libexec/spamd/grey.c b/libexec/spamd/grey.c
index 62fcccb6017..426da9bcbc9 100644
--- a/libexec/spamd/grey.c
+++ b/libexec/spamd/grey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: grey.c,v 1.11 2004/03/11 17:48:59 millert Exp $ */
+/* $OpenBSD: grey.c,v 1.12 2004/03/13 17:46:15 beck Exp $ */
/*
* Copyright (c) 2004 Bob Beck. All rights reserved.
@@ -30,6 +30,7 @@
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -42,11 +43,13 @@
extern time_t passtime, greyexp, whiteexp;
extern struct syslog_data sdata;
extern struct passwd *pw;
+extern pid_t jail_pid;
extern FILE * grey;
extern int debug;
size_t whitecount, whitealloc;
char **whitelist;
+pid_t db_pid = -1;
int pfdev;
static char *pargv[11]= {
@@ -54,6 +57,18 @@ static char *pargv[11]= {
"spamd-white", "-T", "replace", "-f" "-", NULL
};
+
+/* If the parent gets a signal, kill off the children and exit */
+static void
+sig_term_chld(int sig)
+{
+ if (db_pid != -1)
+ kill(db_pid, SIGTERM);
+ if (jail_pid != -1)
+ kill(jail_pid, SIGTERM);
+ _exit(1);
+}
+
int
configure_pf(char **addrs, int count)
{
@@ -75,6 +90,7 @@ configure_pf(char **addrs, int count)
fdpath = NULL;
return(-1);
}
+ signal(SIGCHLD, SIG_DFL);
switch (pid = fork()) {
case -1:
syslog_r(LOG_INFO, &sdata, "fork failed (%m)");
@@ -82,6 +98,7 @@ configure_pf(char **addrs, int count)
fdpath = NULL;
close(pdes[0]);
close(pdes[1]);
+ signal(SIGCHLD, sig_term_chld);
return(-1);
case 0:
/* child */
@@ -103,6 +120,7 @@ configure_pf(char **addrs, int count)
if (pf == NULL) {
syslog_r(LOG_INFO, &sdata, "fdopen failed (%m)");
close(pdes[1]);
+ signal(SIGCHLD, sig_term_chld);
return(-1);
}
for (i = 0; i < count; i++)
@@ -110,6 +128,7 @@ configure_pf(char **addrs, int count)
fprintf(pf, "%s/32\n", addrs[i]);
fclose(pf);
waitpid(pid, NULL, 0);
+ signal(SIGCHLD, sig_term_chld);
return(0);
}
@@ -352,8 +371,10 @@ greyreader(void)
struct in_addr ia;
state = 0;
- if (grey == NULL)
- errx(-1, "No greylist pipe stream!\n");
+ if (grey == NULL) {
+ syslog_r(LOG_ERR, &sdata, "No greylist pipe stream!\n");
+ exit(1);
+ }
while ((buf = fgetln(grey, &len))) {
if (buf[len - 1] == '\n')
buf[len - 1] = '\0';
@@ -417,21 +438,28 @@ greyscanner(void)
int
greywatcher(void)
{
- pid_t pid;
int i;
pfdev = open("/dev/pf", O_RDWR);
- if (pfdev == -1)
- err(1, "open of /dev/pf failed");
+ if (pfdev == -1) {
+ syslog_r(LOG_ERR, &sdata, "open of /dev/pf failed (%m)");
+ exit(1);
+ }
/* check to see if /var/db/spamd exists, if not, create it */
if ((i = open(PATH_SPAMD_DB, O_RDWR, 0)) == -1 && errno == ENOENT) {
i = open(PATH_SPAMD_DB, O_RDWR|O_CREAT, 0644);
- if (i == -1)
- err(1, "can't create %s", PATH_SPAMD_DB);
+ if (i == -1) {
+ syslog_r(LOG_ERR, &sdata, "create %s failed (%m)",
+ PATH_SPAMD_DB);
+ exit(1);
+ }
/* if we are dropping privs, chown to that user */
- if (pw && (fchown(i, pw->pw_uid, pw->pw_gid) == -1))
- err(1, "can't chown %s", PATH_SPAMD_DB);
+ if (pw && (fchown(i, pw->pw_uid, pw->pw_gid) == -1)) {
+ syslog_r(LOG_ERR, &sdata, "chown %s failed (%m)",
+ PATH_SPAMD_DB);
+ exit(1);
+ }
}
if (i != -1)
close(i);
@@ -448,15 +476,11 @@ greywatcher(void)
setuid(pw->pw_uid);
}
- if (!debug) {
- if (daemon(1, 1) == -1)
- err(1, "daemon");
- }
-
- pid = fork();
- switch(pid) {
+ db_pid = fork();
+ switch(db_pid) {
case -1:
- err(1, "fork");
+ syslog_r(LOG_ERR, &sdata, "fork failed (%m)");
+ exit(1);
case 0:
/*
* child, talks to jailed spamd over greypipe,
@@ -473,6 +497,11 @@ greywatcher(void)
* pf whitelist table accordingly.
*/
fclose(grey);
+ signal(SIGTERM, sig_term_chld);
+ signal(SIGHUP, sig_term_chld);
+ signal(SIGCHLD, sig_term_chld);
+ signal(SIGINT, sig_term_chld);
+
setproctitle("(pf <spamd-white> update)");
greyscanner();
/* NOTREACHED */
diff --git a/libexec/spamd/spamd.c b/libexec/spamd/spamd.c
index 62223c2d69b..d136d5608ca 100644
--- a/libexec/spamd/spamd.c
+++ b/libexec/spamd/spamd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spamd.c,v 1.59 2004/03/12 21:02:58 beck Exp $ */
+/* $OpenBSD: spamd.c,v 1.60 2004/03/13 17:46:15 beck Exp $ */
/*
* Copyright (c) 2002 Theo de Raadt. All rights reserved.
@@ -112,6 +112,7 @@ time_t passtime = PASSTIME;
time_t greyexp = GREYEXP;
time_t whiteexp = WHITEEXP;
struct passwd *pw;
+pid_t jail_pid = -1;
extern struct sdlist *blacklists;
@@ -854,7 +855,6 @@ main(int argc, char *argv[])
u_short port, cfg_port;
struct servent *ent;
struct rlimit rlp;
- pid_t pid;
char *bind_address = NULL;
tzset();
@@ -1001,21 +1001,28 @@ main(int argc, char *argv[])
if (!pw)
pw = getpwnam("nobody");
+ if (debug == 0) {
+ if (daemon(1, 1) == -1)
+ err(1, "daemon");
+ }
+
if (greylist) {
/* open pipe to talk to greylister */
- if (pipe(greypipe) == -1)
- err(1, "pipe");
-
- pid = fork();
- switch(pid) {
- case -1:
- err(1, "fork");
+ if (pipe(greypipe) == -1) {
+ syslog(LOG_ERR, "pipe (%m)");
+ exit(1);
+ }
+ jail_pid = fork();
+ switch(jail_pid) {
+ case -1:
+ syslog(LOG_ERR, "fork (%m)");
+ exit(1);
case 0:
/* child - continue */
close(greypipe[0]);
grey = fdopen(greypipe[1], "w");
if (grey == NULL) {
- warn("fdopen");
+ syslog(LOG_ERR, "fdopen (%m)");
_exit(1);
}
goto jail;
@@ -1023,8 +1030,10 @@ main(int argc, char *argv[])
/* parent - run greylister */
close(greypipe[1]);
grey = fdopen(greypipe[0], "r");
- if (grey == NULL)
- err(1, "fdopen");
+ if (grey == NULL) {
+ syslog(LOG_ERR, "fdopen (%m)");
+ exit(1);
+ }
return(greywatcher());
/* NOTREACHED */
}
@@ -1049,10 +1058,7 @@ jail:
if (listen(conflisten, 10) == -1)
err(1, "listen");
- if (debug == 0) {
- if (daemon(1, 1) == -1)
- err(1, "daemon");
- } else
+ if (debug != 0)
printf("listening for incoming connections.\n");
syslog_r(LOG_WARNING, &sdata, "listening for incoming connections.");