X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fmain.c;h=36c5f88db63232928ba607e91518c4292a21aacc;hb=454ad122eb158b4391e2690fe6a7e127d24c525b;hp=d6342f1d728cb4e387625b1014737029ff0ace64;hpb=5191e1cb38d24ebf5c180ac7911893ca8bc4031f;p=umurmur.git diff --git a/src/main.c b/src/main.c index d6342f1..36c5f88 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010, Martin Johansson +/* Copyright (C) 2009-2010, Martin Johansson Copyright (C) 2005-2010, Thorvald Natvig All rights reserved. @@ -34,11 +34,17 @@ #include #include #include +#include #include +#include +#include #include -#include #include - +#include +#include +#ifdef _POSIX_PRIORITY_SCHEDULING +#include +#endif #include "server.h" #include "ssl.h" #include "channel.h" @@ -47,20 +53,78 @@ #include "conf.h" #include "version.h" +char system_string[64], version_string[64]; +int bindport; +char *bindaddr; + void lockfile(const char *pidfile) { int lfp; char str[16]; - lfp = open(pidfile, O_RDWR|O_CREAT, 0640); + lfp = open(pidfile, O_RDWR|O_CREAT|O_EXCL, 0640); if (lfp < 0) Log_fatal("Cannot open PID-file %s for writing", pidfile); - sprintf(str,"%d\n", getpid()); + snprintf(str,16,"%d\n", getpid()); write(lfp, str, strlen(str)); /* record pid to lockfile */ + close(lfp); Log_info("PID-file: %s", pidfile); } +/* Drops privileges (if configured to do so). */ +static void switch_user(void) +{ + struct passwd *pwd; + struct group *grp = NULL; + const char *username, *groupname; + gid_t gid; + + username = getStrConf(USERNAME); + groupname = getStrConf(GROUPNAME); + + if (!*username) { + /* It's an error to specify groupname + * but leave username empty. + */ + if (*groupname) + Log_fatal("username missing"); + + /* Nothing to do. */ + return; + } + + pwd = getpwnam(username); + if (!pwd) + Log_fatal("Unknown user '%s'", username); + + if (!*groupname) + gid = pwd->pw_gid; + else { + grp = getgrnam(groupname); + + if (!grp) + Log_fatal("Unknown group '%s'", groupname); + + gid = grp->gr_gid; + } + + if (initgroups(pwd->pw_name, gid)) + Log_fatal("initgroups() failed: %s", strerror(errno)); + + if (setgid(gid)) + Log_fatal("setgid() failed: %s", strerror(errno)); + + if (setuid(pwd->pw_uid)) + Log_fatal("setuid() failed: %s", strerror(errno)); + + if (!grp) + grp = getgrgid(gid); + if (!grp) + Log_fatal("getgrgid() failed: %s", strerror(errno)); + + Log_info("Switch to user '%s' group '%s'", pwd->pw_name, grp->gr_name); +} void signal_handler(int sig) { @@ -104,6 +168,7 @@ void daemonize() } +#ifdef _POSIX_PRIORITY_SCHEDULING void setscheduler() { int rc; @@ -115,15 +180,20 @@ void setscheduler() if (rc < 0) Log_warn("Failed to set scheduler: %s", strerror(errno)); } +#endif void printhelp() { printf("uMurmur version %s. Mumble protocol %d.%d.%d\n", UMURMUR_VERSION, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH); printf("Usage: umurmurd [-d] [-p ] [-c ] [-h]\n"); - printf(" -d - Do not deamonize\n"); + printf(" -d - Do not daemonize\n"); printf(" -p - Write PID to this file\n"); printf(" -c - Specify configuration file\n"); +#ifdef _POSIX_PRIORITY_SCHEDULING printf(" -r - Run with realtime priority\n"); +#endif + printf(" -a
- Bind to IP address\n"); + printf(" -b - Bind to port\n"); printf(" -h - Print this help\n"); exit(0); } @@ -131,12 +201,19 @@ void printhelp() int main(int argc, char **argv) { bool_t nodaemon = false; +#ifdef _POSIX_PRIORITY_SCHEDULING bool_t realtime = false; +#endif char *conffile = NULL, *pidfile = NULL; int c; + struct utsname utsbuf; /* Arguments */ - while ((c = getopt(argc, argv, "drp:c:h")) != EOF) { +#ifdef _POSIX_PRIORITY_SCHEDULING + while ((c = getopt(argc, argv, "drp:c:a:b:h")) != EOF) { +#else + while ((c = getopt(argc, argv, "dp:c:a:b:h")) != EOF) { +#endif switch(c) { case 'c': conffile = optarg; @@ -144,54 +221,82 @@ int main(int argc, char **argv) case 'p': pidfile = optarg; break; + case 'a': + bindaddr = optarg; + break; + case 'b': + bindport = atoi(optarg); + break; case 'd': nodaemon = true; break; case 'h': printhelp(); break; +#ifdef _POSIX_PRIORITY_SCHEDULING case 'r': realtime = true; break; +#endif default: fprintf(stderr, "Unrecognized option\n"); printhelp(); break; } } + + /* Logging to terminal if not daemonizing, otherwise to syslog. + * Need to initialize logging before calling Conf_init() + */ + if (!nodaemon) + Log_init(false); + else + Log_init(true); - if (Conf_init(conffile) != 0) { - fprintf(stderr, "Configuration error\n"); - exit(1); - } - + /* Initialize the config subsystem early; + * switch_user() will need to read some config variables. + */ + Conf_init(conffile); + if (!nodaemon) { - Log_init(false); daemonize(); if (pidfile != NULL) lockfile(pidfile); + + switch_user(); } - else - Log_init(true); - + signal(SIGCHLD, SIG_IGN); /* ignore child */ signal(SIGTSTP, SIG_IGN); /* ignore tty signals */ signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); + signal(SIGPIPE, SIG_IGN); signal(SIGHUP, signal_handler); /* catch hangup signal */ signal(SIGTERM, signal_handler); /* catch kill signal */ - + + /* Build system string */ + if (uname(&utsbuf) == 0) { + snprintf(system_string, 64, "%s %s", utsbuf.sysname, utsbuf.machine); + snprintf(version_string, 64, "%s", utsbuf.release); + } + else { + snprintf(system_string, 64, "unknown unknown"); + snprintf(version_string, 64, "unknown"); + } + /* Initializing */ - SSL_init(); + SSLi_init(); Chan_init(); Client_init(); +#ifdef _POSIX_PRIORITY_SCHEDULING if (realtime) setscheduler(); +#endif Server_run(); - SSL_deinit(); + SSLi_deinit(); Chan_free(); Log_free(); Conf_deinit();