kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 15fd95450123e9940eb82174213ac988b148b4bc
parent ee59eb3f77e36a30c6096d6dec5b61d237d88798
Author: Joris Vink <joris@coders.se>
Date:   Wed, 20 May 2015 11:34:07 +0200

Merge pull request #61 from thorduri/runas

Make runas behave similarly to chroot.
Diffstat:
includes/kore.h | 2+-
src/cli.c | 4++--
src/config.c | 25++++++++++---------------
src/kore.c | 14++++++++------
src/worker.c | 18++++++++++++++----
5 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/includes/kore.h b/includes/kore.h @@ -362,6 +362,7 @@ extern int foreground; extern int kore_debug; extern int skip_chroot; extern char *chroot_path; +extern int skip_runas; extern char *runas_user; extern char *kore_pidfile; extern char *config_file; @@ -386,7 +387,6 @@ extern struct listener_head listeners; extern struct kore_worker *worker; extern struct kore_domain_h domains; extern struct kore_domain *primary_dom; -extern struct passwd *pw; extern struct kore_pool nb_pool; void kore_cli_usage(int); diff --git a/src/cli.c b/src/cli.c @@ -119,7 +119,7 @@ static void file_create_gitignore(void); static struct cmd cmds[] = { { "help", "this help text", cli_help }, - { "run", "run an application (-fn implied)", cli_run }, + { "run", "run an application (-fnr implied)", cli_run }, { "build", "build an application", cli_build }, { "clean", "cleanup the build files", cli_clean }, { "create", "create a new application skeleton", cli_create }, @@ -990,7 +990,7 @@ cli_run_kore(void *arg) (void)cli_vasprintf(&cpath, "conf/%s.conf", appl); args[0] = "kore"; - args[1] = "-fnc"; + args[1] = "-fnrc"; args[2] = cpath; args[3] = NULL; diff --git a/src/config.c b/src/config.c @@ -132,8 +132,6 @@ static struct kore_module_handle *current_handler = NULL; void kore_parse_config(void) { - char *p; - kore_parse_config_file(config_file); if (!kore_module_loaded()) @@ -142,22 +140,19 @@ kore_parse_config(void) if (LIST_EMPTY(&listeners)) fatal("no listeners defined"); - if (skip_chroot != 1 && chroot_path == NULL) + if (skip_chroot != 1 && chroot_path == NULL) { fatal("missing a chroot path"); - - if (runas_user == NULL) { - if ((p = getlogin()) == NULL) - fatal("missing a username to run as"); - - /* runas_user is free'd later down the line. */ - runas_user = kore_strdup(p); + } + if (getuid() != 0 && skip_chroot == 0) { + fatal("cannot chroot, use -n to skip it"); } - if ((pw = getpwnam(runas_user)) == NULL) - fatal("user '%s' does not exist", runas_user); - - if (getuid() != 0 && skip_chroot == 0) - fatal("Cannot chroot(), use -n to skip it"); + if (skip_runas != 1 && runas_user == NULL) { + fatal("missing runas user"); + } + if (getuid() != 0 && skip_runas == 0) { + fatal("cannot drop privileges, use -p to skip it"); + } } static void diff --git a/src/kore.c b/src/kore.c @@ -25,15 +25,15 @@ volatile sig_atomic_t sig_recv; struct listener_head listeners; u_int8_t nlisteners; -struct passwd *pw = NULL; pid_t kore_pid = -1; u_int16_t cpu_count = 1; int foreground = 0; int kore_debug = 0; -int skip_chroot = 0; u_int8_t worker_count = 0; -char *runas_user = NULL; +int skip_chroot = 0; char *chroot_path = NULL; +int skip_runas = 0; +char *runas_user = NULL; u_int32_t kore_socket_backlog = 5000; char *kore_pidfile = KORE_PIDFILE_DEFAULT; char *kore_tls_cipher_list = KORE_DEFAULT_CIPHER_LIST; @@ -55,6 +55,7 @@ usage(void) fprintf(stderr, "\t-f\tstart kore in foreground mode\n"); fprintf(stderr, "\t-h\tthis help text\n"); fprintf(stderr, "\t-n\tdo not chroot (if not starting kore as root)\n"); + fprintf(stderr, "\t-r\tdo not runas (uid drop) (if not starting kore as root)\n"); fprintf(stderr, "\t-v\tdisplay kore's version information\n"); kore_cli_usage(0); @@ -84,7 +85,7 @@ main(int argc, char *argv[]) flags = 0; - while ((ch = getopt(argc, argv, "c:dfhnv")) != -1) { + while ((ch = getopt(argc, argv, "c:dfhnrv")) != -1) { flags++; switch (ch) { case 'c': @@ -106,6 +107,9 @@ main(int argc, char *argv[]) case 'n': skip_chroot = 1; break; + case 'r': + skip_runas = 1; + break; case 'v': version(); break; @@ -302,8 +306,6 @@ kore_server_start(void) { int quit; - kore_mem_free(runas_user); - if (foreground == 0 && daemon(1, 1) == -1) fatal("cannot daemon(): %s", errno_s); diff --git a/src/worker.c b/src/worker.c @@ -186,14 +186,24 @@ kore_worker_entry(struct kore_worker *kw) struct connection *c, *cnext; int quit, had_lock, r; u_int64_t now, idle_check, next_lock, netwait; + struct passwd *pw = NULL; worker = kw; + /* Must happen before chroot. */ + if (skip_runas == 0) { + pw = getpwnam(runas_user); + if (pw == NULL) { + fatal("cannot getpwnam(\"%s\") runas user: %s", + runas_user, errno_s); + } + } + if (skip_chroot == 0) { if (chroot(chroot_path) == -1) - fatal("cannot chroot(): %s", errno_s); + fatal("cannot chroot(\"%s\"): %s", chroot_path, errno_s); if (chdir("/") == -1) - fatal("cannot chdir(): %s", errno_s); + fatal("cannot chdir(\"/\"): %s", errno_s); } if (getrlimit(RLIMIT_NOFILE, &rl) == -1) { @@ -213,7 +223,7 @@ kore_worker_entry(struct kore_worker *kw) worker_rlimit_nofiles, errno_s); } - if (getuid() != pw->pw_uid) { + if (skip_runas == 0) { if (setgroups(1, &pw->pw_gid) || #ifdef __MACH__ setgid(pw->pw_gid) || setegid(pw->pw_gid) || @@ -222,7 +232,7 @@ kore_worker_entry(struct kore_worker *kw) setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) #endif - fatal("unable to drop privileges"); + fatal("cannot drop privileges"); } (void)snprintf(buf, sizeof(buf), "kore [wrk %d]", kw->id);