From 93c7bd21702e9cc392c6d7abfc7f49ab840503b3 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Sun, 18 Feb 2018 19:52:55 +1000 Subject: [PATCH] Run as user --- dist/config/bbs.ini | 1 + docs/docs/guide/ini/bbs.md | 1 + setup.sh | 2 ++ src/bbs.h | 2 ++ src/main.c | 71 +++++++++++++++++++++++++++++--------- 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/dist/config/bbs.ini b/dist/config/bbs.ini index 1e0c3e0..0da2382 100644 --- a/dist/config/bbs.ini +++ b/dist/config/bbs.ini @@ -14,6 +14,7 @@ External Editor stdio = true External Editor Codepage = CP437 Automessage Write Level = 10 Fork = false +Run As User = USERNAME Enable WWW = false WWW Port = 8080 WWW URL = http://127.0.0.1:8080/ diff --git a/docs/docs/guide/ini/bbs.md b/docs/docs/guide/ini/bbs.md index 94daea5..6489357 100644 --- a/docs/docs/guide/ini/bbs.md +++ b/docs/docs/guide/ini/bbs.md @@ -18,6 +18,7 @@ This is the main bbs INI file and contains the following sections * **External Editor Codepage** The codepage the external editor uses (CP437 for magiedit) (Only required if External Editor CMD is set) * **Automessage Write Level** The security level a user needs to change the automessage (Required) * **Fork** True if you want the BBS to run in daemon mode false if not. (Required) + * **Run as User** Which user to run at if invoked as root. (Required if running as root) * **Enable WWW** True to enable the WWW server, false if not. (Required) * **WWW Port** Port to listen for HTTP connections (Required if WWW is enabled) * **WWW URL** Public facing url of the BBS (Required if WWW is enabled) diff --git a/setup.sh b/setup.sh index 298a02e..49da63b 100755 --- a/setup.sh +++ b/setup.sh @@ -69,9 +69,11 @@ else SED=sed fi + $SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/bbs.ini $SED -i "s/BBS Name = Magicka BBS/BBS Name = ${bbsname}/g" config/bbs.ini $SED -i "s/Sysop Name = sysop/Sysop Name = ${handle}/g" config/bbs.ini +$SED -i "s/USERNAME/${USERNAME}/g" config/bbs.ini $SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/localmail.ini $SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/filesgen.ini $SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/happynet.ini diff --git a/src/bbs.h b/src/bbs.h index bc650b2..84d96d0 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -125,6 +125,8 @@ struct ip_address_guard { }; struct bbs_config { + uid_t uid; + gid_t gid; int codepage; int ipv6; char *bbs_name; diff --git a/src/main.c b/src/main.c index d1de661..6bd2c8a 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ extern struct user_record *gUser; int ssh_pid = -1; int bbs_pid = 0; int server_socket = -1; +int ipv6_pid = -1; int bbs_stdin; int bbs_stdout; @@ -62,6 +64,10 @@ void sigterm_handler(int s) MHD_stop_daemon(www_daemon); } #endif + if (ipv6_pid != -1) { + printf("ipv6_pid %d\n", ipv6_pid); + kill(ipv6_pid, SIGTERM); + } remove(conf.pid_file); exit(0); } @@ -407,6 +413,7 @@ static int handler(void* user, const char* section, const char* name, const char* value) { struct bbs_config *conf = (struct bbs_config *)user; + struct passwd *pwd; if (strcasecmp(section, "main") == 0) { if (strcasecmp(name, "bbs name") == 0) { @@ -521,6 +528,12 @@ static int handler(void* user, const char* section, const char* name, } else { conf->date_style = 0; } + } else if (strcasecmp(name, "run as user") == 0) { + pwd = getpwnam(value); + if (pwd != NULL) { + conf->uid = pwd->pw_uid; + conf->gid = pwd->pw_gid; + } } } else if (strcasecmp(section, "paths") == 0){ if (strcasecmp(name, "ansi path") == 0) { @@ -794,6 +807,14 @@ void serverssh(int port, int ipv6) { } c = sizeof(struct sockaddr_in); } + + if (conf.uid != getuid()) { + if (setgid(conf.gid) != 0 || setuid(conf.uid) != 0) { + perror("SetUID Failed: "); + remove(conf.pid_file); + exit(1); + } + } listen(ssh_sock, 3); @@ -1070,6 +1091,7 @@ void server(int port, int ipv6) { ssh_pid = fork(); if (ssh_pid == 0) { + ipv6_pid = -1; ssh_pid = -1; serverssh(conf.ssh_port, ipv6); exit(0); @@ -1079,20 +1101,6 @@ void server(int port, int ipv6) { } } -#if defined(ENABLE_WWW) - if (conf.www_server && conf.www_path != NULL && conf.www_url != NULL) { - if (!conf.fork) { - printf(" - HTTP Starting on Port %d (IPv%d)\n", conf.www_port, (ipv6 ? 6 : 4)); - } - www_init(); - if (ipv6) { - www_daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION|MHD_USE_IPv6, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &www_request_completed, NULL, MHD_OPTION_URI_LOG_CALLBACK, &www_logger, NULL, MHD_OPTION_END); - } else { - www_daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &www_request_completed, NULL, MHD_OPTION_URI_LOG_CALLBACK, &www_logger, NULL, MHD_OPTION_END); - } - } -#endif - if (ipv6) { server_socket = socket(AF_INET6, SOCK_STREAM, 0); } else { @@ -1152,6 +1160,28 @@ void server(int port, int ipv6) { client_p = &client4; } + if (conf.uid != getuid()) { + if (setgid(conf.gid) != 0 || setuid(conf.uid) != 0) { + perror("SetUID Failed: "); + remove(conf.pid_file); + exit(1); + } + } + +#if defined(ENABLE_WWW) + if (conf.www_server && conf.www_path != NULL && conf.www_url != NULL) { + if (!conf.fork) { + printf(" - HTTP Starting on Port %d (IPv%d)\n", conf.www_port, (ipv6 ? 6 : 4)); + } + www_init(); + if (ipv6) { + www_daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION|MHD_USE_IPv6, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &www_request_completed, NULL, MHD_OPTION_URI_LOG_CALLBACK, &www_logger, NULL, MHD_OPTION_END); + } else { + www_daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &www_request_completed, NULL, MHD_OPTION_URI_LOG_CALLBACK, &www_logger, NULL, MHD_OPTION_END); + } + } +#endif + listen(server_socket, 3); @@ -1229,7 +1259,7 @@ void server(int port, int ipv6) { int main(int argc, char **argv) { int i; - int main_pid, ipv6_pid; + int main_pid; FILE *fptr; struct stat s; char buffer[1024]; @@ -1269,7 +1299,8 @@ int main(int argc, char **argv) { conf.codepage = 0; conf.date_style = 0; conf.ipv6 = 0; - + conf.uid = getuid(); + conf.gid = getgid(); // Load BBS data if (ini_parse(argv[1], handler, &conf) <0) { fprintf(stderr, "Unable to load configuration ini (%s)!\n", argv[1]); @@ -1336,6 +1367,12 @@ int main(int argc, char **argv) { exit(-1); } else if (main_pid > 0) { + if (conf.uid != getuid()) { + if (setgid(conf.gid) != 0 || setuid(conf.uid) != 0) { + perror("Setuid Error: "); + exit(1); + } + } fptr = fopen(conf.pid_file, "w"); if (!fptr) { fprintf(stderr, "Unable to open pid file for writing.\n"); @@ -1358,6 +1395,7 @@ int main(int argc, char **argv) { } else if (ipv6_pid > 0) { server(conf.telnet_port, 0); } else { + ipv6_pid = -1; server(conf.telnet_port, 1); } } else { @@ -1382,6 +1420,7 @@ int main(int argc, char **argv) { } else if (ipv6_pid > 0) { server(conf.telnet_port, 0); } else { + ipv6_pid = -1; server(conf.telnet_port, 1); } } else {