diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2004-03-13 17:46:16 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2004-03-13 17:46:16 +0000 |
commit | 4d052fa31b15731d9e172f7f1873b02a329d8cc5 (patch) | |
tree | c7a84ee27ec01dcde4614e23ca14fb732e6777cc | |
parent | f554452c3e4eb6b4a6e9cf535ffe18d7b804d420 (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.c | 65 | ||||
-rw-r--r-- | libexec/spamd/spamd.c | 38 |
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."); |