void lwan_straitjacket_enforce(config_t *c, config_line_t *l) { char *user_name = NULL; char *chroot_path = NULL; uid_t uid; gid_t gid; if (geteuid() != 0) { config_error(c, "Straitjacket requires root privileges"); return; } while (config_read_line(c, l)) { switch (l->type) { case CONFIG_LINE_TYPE_LINE: /* TODO: limit_syscalls */ if (!strcmp(l->line.key, "user")) { user_name = strdupa(l->line.value); } else if (!strcmp(l->line.key, "chroot")) { chroot_path = strdupa(l->line.value); } else { config_error(c, "Invalid key: %s", l->line.key); return; } break; case CONFIG_LINE_TYPE_SECTION: config_error(c, "Straitjacket accepts no sections"); return; case CONFIG_LINE_TYPE_SECTION_END: if (!get_user_uid_gid(user_name, &uid, &gid)) { config_error(c, "Unknown user: %s", user_name); return; } if (chroot_path) { if (chroot(chroot_path) < 0) { lwan_status_critical_perror("Could not chroot() to %s", chroot_path); } lwan_status_debug("Jailed to %s", chroot_path); } if (!switch_to_user(uid, gid, user_name)) { lwan_status_critical("Could not drop privileges to %s, aborting", user_name); } return; } } config_error(c, "Expecting section end while parsing straitjacket"); }
void bsp_finish_booting(void) { int i; #if SPROFILE sprofiling = 0; /* we're not profiling until instructed to */ #endif /* SPROFILE */ cprof_procs_no = 0; /* init nr of hash table slots used */ cpu_identify(); vm_running = 0; krandom.random_sources = RANDOM_SOURCES; krandom.random_elements = RANDOM_ELEMENTS; /* MINIX is now ready. All boot image processes are on the ready queue. * Return to the assembly code to start running the current process. */ /* it should point somewhere */ get_cpulocal_var(bill_ptr) = get_cpulocal_var_ptr(idle_proc); get_cpulocal_var(proc_ptr) = get_cpulocal_var_ptr(idle_proc); announce(); /* print MINIX startup banner */ /* * we have access to the cpu local run queue, only now schedule the processes. * We ignore the slots for the former kernel tasks */ for (i=0; i < NR_BOOT_PROCS - NR_TASKS; i++) { RTS_UNSET(proc_addr(i), RTS_PROC_STOP); } /* * enable timer interrupts and clock task on the boot CPU */ if (boot_cpu_init_timer(system_hz)) { panic("FATAL : failed to initialize timer interrupts, " "cannot continue without any clock source!"); } fpu_init(); /* Warnings for sanity checks that take time. These warnings are printed * so it's a clear warning no full release should be done with them * enabled. */ #if DEBUG_SCHED_CHECK FIXME("DEBUG_SCHED_CHECK enabled"); #endif #if DEBUG_VMASSERT FIXME("DEBUG_VMASSERT enabled"); #endif #if DEBUG_PROC_CHECK FIXME("PROC check enabled"); #endif DEBUGEXTRA(("cycles_accounting_init()... ")); cycles_accounting_init(); DEBUGEXTRA(("done\n")); #ifdef CONFIG_SMP cpu_set_flag(bsp_cpu_id, CPU_IS_READY); machine.processors_count = ncpus; machine.bsp_id = bsp_cpu_id; #else machine.processors_count = 1; machine.bsp_id = 0; #endif /* Kernel may no longer use bits of memory as VM will be running soon */ kernel_may_alloc = 0; switch_to_user(); NOT_REACHABLE; }
void execv_in_app(const char* username, const char* appname, const char* arg0, char** argv) { if(username) switch_to_user(username); const char* kinko_root = getenv("KINKO_ROOT"); if(!kinko_root) { kinko_root = Cwd(); fprintf(stderr, "KINKO_ROOT environment setting missing; falling back to current dir: %s\n", kinko_root); } /* * Fetch system settings to build environment for new process. */ const char* pw_shell = "/bin/false"; /* * The homedir is the root dir of the requested app. * If the username is "kinko-<name>", then the homedir is "<kinko_root>/apps/<name>" */ const char* homedir = vstrcat(kinko_root, "/apps/", appname, 0); /* * Clear environment. This implements a simple variant of sudo's env_reset * function. * * Note: while sudo falls back to setting TERM, PATH, HOME, MAIL, SHELL, * LOGNAME, USER, USERNAME we skp TERM and MAIL. */ static const int MAX_ENV_ENTRIES = 128; char* env[MAX_ENV_ENTRIES]; char** envp = env; /* * get initial path. * * Note that /usr/local/bin is in the path, because that allows for a * system-wide installation of various interpreters even when they are * not packaged by the system's package manager. */ const char* path = "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin"; /* * set ruby environment. * * The following code should make --no-print-directory sure that the new user will have gems * installed in a private location. Note that a proper ruby installation * must be installed system-wide; if nothing else works then in * /usr/local/bin. */ path = vstrcat(homedir, "/bin" ":", path, 0); path = vstrcat(homedir, "/var/bin" ":", path, 0); path = vstrcat(homedir, "/var/gems/bin" ":", path, 0); *envp++ = vstrcat("GEM_HOME=", homedir, "/var/gems", 0); *envp++ = vstrcat("GEM_PATH=", homedir, "/var/gems", 0); /* * If there is a Gemfile in $homedir/Gemfile, we remember that in the * environment. This make --no-print-directorys sure that bundler finds its Gemfile even * when in the wrong directory; but it also prevents to run multiple * ruby-based apps with different gemsets. */ /* { const char* gemfile = vstrcat(homedir, "/Gemfile", 0); struct stat stat_buf; if(!stat(gemfile, &stat_buf)) { (void)0; *envp++ = vstrcat("BUNDLE_GEMFILE=", gemfile, 0); } } */ *envp = 0; /* * set KINKO environment entries */ *envp++ = vstrcat("KINKO_ROOT=", kinko_root, 0); path = vstrcat(kinko_root, "/sbin:", path, 0); path = vstrcat(kinko_root, "/bin:", path, 0); *envp++ = vstrcat("JIT_HOME=", kinko_root, "/var/jit", 0); /* * set base entries */ *envp++ = "TMPDIR=/tmp"; *envp++ = vstrcat("PATH=", path, 0); *envp++ = vstrcat("HOME=", homedir, 0); *envp++ = vstrcat("SHELL=", pw_shell, 0); #if STRICT_MODE *envp++ = vstrcat("LOGNAME=", username, 0); *envp++ = vstrcat("USER="******"USERNAME="******"Cannot chdir into homedir %s\n", homedir); perror(homedir); } /* * set umask. By default an application should not create files writeable * by others. */ umask(S_IWGRP | S_IWOTH); /* * start program. */ execve(arg0, argv, env); die(arg0); }