diff --git a/core/uwsgi.c b/core/uwsgi.c index 51c4255f..1d04788e 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -172,6 +172,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"emperor-required-heartbeat", required_argument, 0, "set the Emperor tolerance about heartbeats", uwsgi_opt_set_int, &uwsgi.emperor_heartbeat, 0}, {"emperor-pidfile", required_argument, 0, "write the Emperor pid in the specified file", uwsgi_opt_set_str, &uwsgi.emperor_pidfile, 0}, {"emperor-tyrant", no_argument, 0, "put the Emperor in Tyrant mode", uwsgi_opt_true, &uwsgi.emperor_tyrant, 0}, + {"emperor-tyrant-nofollow", no_argument, 0, "do not follow symlinks when checking for uid/gid in Tyrant mode", uwsgi_opt_true, &uwsgi.emperor_tyrant_nofollow, 0}, {"emperor-stats", required_argument, 0, "run the Emperor stats server", uwsgi_opt_set_str, &uwsgi.emperor_stats, 0}, {"emperor-stats-server", required_argument, 0, "run the Emperor stats server", uwsgi_opt_set_str, &uwsgi.emperor_stats, 0}, {"early-emperor", no_argument, 0, "spawn the emperor as soon as possibile", uwsgi_opt_true, &uwsgi.early_emperor, 0}, @@ -184,6 +185,8 @@ static struct uwsgi_option uwsgi_base_options[] = { {"emperor-on-demand-directory", required_argument, 0, "enable on demand mode binding to the unix socket in the specified directory named like the vassal + .socket", uwsgi_opt_set_str, &uwsgi.emperor_on_demand_directory, 0}, {"emperor-on-demand-dir", required_argument, 0, "enable on demand mode binding to the unix socket in the specified directory named like the vassal + .socket", uwsgi_opt_set_str, &uwsgi.emperor_on_demand_directory, 0}, {"emperor-on-demand-exec", required_argument, 0, "use the output of the specified command as on demand socket name (the vassal name is passed as the only argument)", uwsgi_opt_set_str, &uwsgi.emperor_on_demand_exec, 0}, + {"emperor-extra-extension", required_argument, 0, "allows the specified extension in the Emperor (vassal will be called with --config)", uwsgi_opt_add_string_list, &uwsgi.emperor_extra_extension, 0}, + {"emperor-extra-ext", required_argument, 0, "allows the specified extension in the Emperor (vassal will be called with --config)", uwsgi_opt_add_string_list, &uwsgi.emperor_extra_extension, 0}, {"imperial-monitor-list", no_argument, 0, "list enabled imperial monitors", uwsgi_opt_true, &uwsgi.imperial_monitor_list, 0}, {"imperial-monitors-list", no_argument, 0, "list enabled imperial monitors", uwsgi_opt_true, &uwsgi.imperial_monitor_list, 0}, {"vassals-inherit", required_argument, 0, "add config templates to vassals config", uwsgi_opt_add_string_list, &uwsgi.vassals_templates, 0}, @@ -264,6 +267,8 @@ static struct uwsgi_option uwsgi_base_options[] = { {"chroot", required_argument, 0, "chroot() to the specified directory", uwsgi_opt_set_str, &uwsgi.chroot, 0}, {"uid", required_argument, 0, "setuid to the specified user/uid", uwsgi_opt_set_uid, NULL, 0}, {"gid", required_argument, 0, "setgid to the specified group/gid", uwsgi_opt_set_gid, NULL, 0}, + {"immediate-uid", required_argument, 0, "setuid to the specified user/uid IMMEDIATELY", uwsgi_opt_set_immediate_uid, NULL, UWSGI_OPT_IMMEDIATE}, + {"immediate-gid", required_argument, 0, "setgid to the specified group/gid IMMEDIATELY", uwsgi_opt_set_immediate_gid, NULL, UWSGI_OPT_IMMEDIATE}, {"no-initgroups", no_argument, 0, "disable additional groups set via initgroups()", uwsgi_opt_true, &uwsgi.no_initgroups, 0}, #ifdef UWSGI_CAP {"cap", required_argument, 0, "set process capability", uwsgi_opt_set_cap, NULL, 0}, @@ -3186,6 +3191,59 @@ void uwsgi_opt_true(char *opt, char *value, void *key) { } } +void uwsgi_opt_set_immediate_gid(char *opt, char *value, void *none) { + gid_t gid = atoi(value); + if (gid == 0) { + struct group *ugroup = getgrnam(value); + if (ugroup) + gid = ugroup->gr_gid; + } + if (gid <= 0) { + uwsgi_log("uwsgi_opt_set_immediate_gid(): invalid gid %d\n", (int) gid); + exit(1); + } + if (setgid(gid)) { + uwsgi_error("uwsgi_opt_set_immediate_gid()/setgid()"); + exit(1); + } + + if (setgroups(0, NULL)) { + uwsgi_error("uwsgi_opt_set_immediate_gid()/setgroups()"); + exit(1); + } + + gid = getgid(); + if (!gid) { + exit(1); + } + uwsgi_log("immediate gid: %d\n", (int) gid); +} + + +void uwsgi_opt_set_immediate_uid(char *opt, char *value, void *none) { + uid_t uid = atoi(value); + if (uid == 0) { + struct passwd *upasswd = getpwnam(value); + if (upasswd) + uid = upasswd->pw_uid; + } + if (uid <= 0) { + uwsgi_log("uwsgi_opt_set_immediate_uid(): invalid uid %d\n", uid); + exit(1); + } + if (setuid(uid)) { + uwsgi_error("uwsgi_opt_set_immediate_uid()/setuid()"); + exit(1); + } + + uid = getuid(); + if (!uid) { + exit(1); + } + uwsgi_log("immediate uid: %d\n", (int) uid); +} + + void uwsgi_opt_set_int(char *opt, char *value, void *key) { int *ptr = (int *) key; if (value) { diff --git a/examples/config.lua b/examples/config.lua index 1c46a847..5afe46c3 100644 --- a/examples/config.lua +++ b/examples/config.lua @@ -1,5 +1,7 @@ config = {} +config['immediate-uid'] = 'roberto' +config['immediate-gid'] = 'roberto' config['http-socket'] = ':9090' config['env'] = { 'FOO=bar', 'TEST=topogigio' } config['module'] = 'werkzeug.testapp:test_app' diff --git a/examples/config2.lua b/examples/config2.lua new file mode 100644 index 00000000..6728ad66 --- /dev/null +++ b/examples/config2.lua @@ -0,0 +1,8 @@ +config = {} + +config[1] = { ['http-socket']=':9090' } +config[2] = { ['env']='FOO=bar' } +config[3] = { ['env']='TEST=topogigio' } +config[4] = { ['module']='werkzeug.testapp:test_app' } + +return config diff --git a/plugins/lua/lua_plugin.c b/plugins/lua/lua_plugin.c index 66802ed4..c65c943d 100644 --- a/plugins/lua/lua_plugin.c +++ b/plugins/lua/lua_plugin.c @@ -672,6 +672,26 @@ static uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t a } +static void uwsgi_lua_configurator_array(lua_State *L) { + + int i; + int n = luaL_getn(L, -3); + + for(i=1;i<=n;i++) { + lua_rawgeti(L, 1, i); + if (lua_istable(L, -1)) { + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + char *key = uwsgi_str((char *)lua_tostring(L, -2)); + char *value = uwsgi_str((char *)lua_tostring(L, -1)); + add_exported_option(key, value, 0); + lua_pop(L, 1); + } + } + } +} + + static void uwsgi_lua_configurator(char *filename, char *magic_table[]) { size_t len = 0; uwsgi_log_initial("[uWSGI] getting Lua configuration from %s\n", filename); @@ -696,18 +716,26 @@ static void uwsgi_lua_configurator(char *filename, char *magic_table[]) { // we always use uwsgi_str to avoid GC destroying our strings // and to be able to call lua_close at the end while (lua_next(L, -2) != 0) { - char *key = uwsgi_str((char *)lua_tostring(L, -2)); - if (lua_istable(L, -1)) { - lua_pushnil(L); - while (lua_next(L, -2) != 0) { + // array ? + if (lua_isnumber(L, -2)) { + uwsgi_lua_configurator_array(L); + break; + } + // dictionary + else { + char *key = uwsgi_str((char *)lua_tostring(L, -2)); + if (lua_istable(L, -1)) { + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + char *value = uwsgi_str((char *)lua_tostring(L, -1)); + add_exported_option(key, value, 0); + lua_pop(L, 1); + } + } + else { char *value = uwsgi_str((char *)lua_tostring(L, -1)); add_exported_option(key, value, 0); - lua_pop(L, 1); - } - } - else { - char *value = uwsgi_str((char *)lua_tostring(L, -1)); - add_exported_option(key, value, 0); + } } lua_pop(L, 1); } diff --git a/uwsgi.h b/uwsgi.h index eb296469..06ba2434 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1637,6 +1637,7 @@ struct uwsgi_server { int emperor_fd; int emperor_queue; int emperor_tyrant; + int emperor_tyrant_nofollow; int emperor_fd_config; int early_emperor; int emperor_throttle; @@ -1644,6 +1645,7 @@ struct uwsgi_server { int emperor_max_throttle; int emperor_magic_exec; int emperor_heartbeat; + struct uwsgi_string_list *emperor_extra_extension; // search for a file with the specified extension at the same level of the vassal file char *emperor_on_demand_extension; // bind to a unix socket on the specified directory named directory/vassal.socket @@ -3251,6 +3253,8 @@ void uwsgi_opt_add_spooler(char *, char *, void *); void uwsgi_opt_add_daemon(char *, char *, void *); void uwsgi_opt_set_uid(char *, char *, void *); void uwsgi_opt_set_gid(char *, char *, void *); +void uwsgi_opt_set_immediate_uid(char *, char *, void *); +void uwsgi_opt_set_immediate_gid(char *, char *, void *); void uwsgi_opt_set_env(char *, char *, void *); void uwsgi_opt_unset_env(char *, char *, void *); void uwsgi_opt_pidfile_signal(char *, char *, void *);