X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;ds=sidebyside;f=secnet.c;h=c7ce2b8a459b6707431b11e2bd182e637035a6c1;hb=7138d0c54cd2212439434d27cb2d6ea775c3039b;hp=ab562f1e8e6f0891c16ea84d68910d2a96917d6e;hpb=9d3a4132788b198345116624761c12ed7bc936b6;p=secnet.git diff --git a/secnet.c b/secnet.c index ab562f1..c7ce2b8 100644 --- a/secnet.c +++ b/secnet.c @@ -18,17 +18,28 @@ extern char version[]; #include "util.h" #include "conffile.h" +#include "process.h" -/* Command-line options (possibly config-file options too) */ +/* XXX should be from autoconf */ static char *configfile="/etc/secnet/secnet.conf"; bool_t just_check_config=False; static char *userid=NULL; static uid_t uid=0; -static bool_t background=True; +bool_t background=True; static char *pidfile=NULL; bool_t require_root_privileges=False; string_t require_root_privileges_explanation=NULL; +static pid_t secnet_pid; + +/* from log.c */ +extern uint32_t message_level; +extern bool_t secnet_is_daemon; +extern struct log_if *system_log; + +/* from process.c */ +extern void start_signal_handling(void); + /* Structures dealing with poll() call */ struct poll_interest { beforepoll_fn *before; @@ -95,21 +106,26 @@ static void parse_options(int argc, char **argv) break; case 'v': - message_level|=M_INFO|M_WARNING|M_ERROR|M_FATAL; + message_level|=M_INFO|M_NOTICE|M_WARNING|M_ERROR|M_SECURITY| + M_FATAL; break; - case 'n': - background=False; + case 'w': + message_level&=(~M_WARNING); break; case 'd': - message_level|=M_DEBUG_CONFIG|M_DEBUG_PHASE; + message_level|=M_DEBUG_CONFIG|M_DEBUG_PHASE|M_DEBUG; break; case 'f': message_level=M_FATAL; break; + case 'n': + background=False; + break; + case 'c': if (optarg) configfile=safe_strdup(optarg,"config_filename"); @@ -125,12 +141,12 @@ static void parse_options(int argc, char **argv) break; default: - Message(M_WARNING,"secnet: Unknown getopt code %c\n",c); + Message(M_ERROR,"secnet: Unknown getopt code %c\n",c); } } if (argc-optind != 0) { - Message(M_WARNING,"secnet: You gave extra command line parameters, " + Message(M_ERROR,"secnet: You gave extra command line parameters, " "which were ignored.\n"); } } @@ -140,7 +156,6 @@ static void setup(dict_t *config) list_t *l; item_t *site; dict_t *system; - struct log_if *log; struct passwd *pw; struct cloc loc; int i; @@ -158,8 +173,7 @@ static void setup(dict_t *config) if (!l) { fatal("configuration does not include a system/log facility\n"); } - log=init_log(l); - log->log(log->st,LOG_DEBUG,"%s: logging started",version); + system_log=init_log(l); /* Who are we supposed to run as? */ userid=dict_read_string(system,"userid",False,"system",loc); @@ -248,7 +262,9 @@ static void run(void) fatal("run: couldn't alloca\n"); } - while (!finished) { + Message(M_NOTICE,"%s [%d]: starting\n",version,secnet_pid); + + do { if (gettimeofday(&tv_now, NULL)!=0) { fatal_perror("main loop: gettimeofday"); } @@ -277,6 +293,7 @@ static void run(void) i->nfds=nfds; } do { + if (finished) break; rv=poll(fds, idx, timeout); if (rv<0) { if (errno!=EINTR) { @@ -284,7 +301,7 @@ static void run(void) } } } while (rv<0); - } + } while (!finished); } static void droppriv(void) @@ -294,20 +311,26 @@ static void droppriv(void) add_hook(PHASE_SHUTDOWN,system_phase_hook,NULL); - /* Background now, if we're supposed to: we may be unable to write the - pidfile if we don't. */ - if (background) { - /* Open the pidfile before forking - that way the parent can tell - whether it succeeds */ - if (pidfile) { - pf=fopen(pidfile,"w"); - if (!pf) { - fatal_perror("cannot open pidfile \"%s\"",pidfile); - } - } else { - Message(M_WARNING,"secnet: no pidfile configured, but " - "backgrounding anyway\n"); + /* Open the pidfile for writing now: we may be unable to do so + once we drop privileges. */ + if (pidfile) { + pf=fopen(pidfile,"w"); + if (!pf) { + fatal_perror("cannot open pidfile \"%s\"",pidfile); } + } + if (!background && pf) { + fprintf(pf,"%d\n",getpid()); + fclose(pf); + } + + /* Now drop privileges */ + if (uid!=0) { + if (setuid(uid)!=0) { + fatal_perror("can't set uid to \"%s\"",userid); + } + } + if (background) { p=fork(); if (p>0) { if (pf) { @@ -319,28 +342,26 @@ static void droppriv(void) } else if (p==0) { /* Child process - all done, just carry on */ if (pf) fclose(pf); + secnet_is_daemon=True; } else { /* Error */ fatal_perror("cannot fork"); exit(1); } - } else { - if (pidfile) { - pf=fopen(pidfile,"w"); - if (!pf) { - fatal_perror("cannot open pidfile \"%s\"",pidfile); - } - fprintf(pf,"%d\n",getpid()); - fclose(pf); - } } + secnet_pid=getpid(); +} - /* Drop privilege now, if configured to do so */ - if (uid!=0) { - if (setuid(uid)!=0) { - fatal_perror("can't set uid to \"%s\"",userid); - } - } +static signal_notify_fn finish,ignore_hup; +static void finish(void *st, int signum) +{ + finished=True; + Message(M_NOTICE,"%s [%d]: received %s\n",version,secnet_pid,(string_t)st); +} +static void ignore_hup(void *st, int signum) +{ + Message(M_INFO,"%s [%d]: received SIGHUP\n",version,secnet_pid); + return; } int main(int argc, char **argv) @@ -368,10 +389,14 @@ int main(int argc, char **argv) droppriv(); enter_phase(PHASE_RUN); + start_signal_handling(); + request_signal_notification(SIGTERM,finish,"SIGTERM"); + if (!background) request_signal_notification(SIGINT,finish,"SIGINT"); + request_signal_notification(SIGHUP,ignore_hup,NULL); run(); enter_phase(PHASE_SHUTDOWN); + Message(M_NOTICE,"%s [%d]: finished\n",version,secnet_pid); return 0; } -