diff options
-rw-r--r-- | proxy/man/gssproxy.conf.5.xml | 9 | ||||
-rw-r--r-- | proxy/src/gp_config.c | 12 | ||||
-rw-r--r-- | proxy/src/gp_init.c | 46 | ||||
-rw-r--r-- | proxy/src/gp_proxy.h | 3 | ||||
-rw-r--r-- | proxy/src/gssproxy.c | 5 |
5 files changed, 75 insertions, 0 deletions
diff --git a/proxy/man/gssproxy.conf.5.xml b/proxy/man/gssproxy.conf.5.xml index b4d5add..95fdb65 100644 --- a/proxy/man/gssproxy.conf.5.xml +++ b/proxy/man/gssproxy.conf.5.xml @@ -254,6 +254,15 @@ </varlistentry> <varlistentry> + <term>run_as_user (string)</term> + <listitem> + <para>The name of the user gssproxy will drop privileges to.</para> + <para>This option is only available in the global section.</para> + <para>Default: run_as_user = </para> + </listitem> + </varlistentry> + + <varlistentry> <term>selinux_context (string)</term> <listitem> <para>This parameter instructs the proxy to allow map a diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c index ee96975..b102546 100644 --- a/proxy/src/gp_config.c +++ b/proxy/src/gp_config.c @@ -453,6 +453,17 @@ int load_config(struct gp_config *cfg) goto done; } + ret = gp_config_get_string(ctx, "gssproxy", "run_as_user", &tmpstr); + if (ret == 0) { + cfg->proxy_user = strdup(tmpstr); + if (!cfg->proxy_user) { + ret = ENOMEM; + goto done; + } + } else if (ret != ENOENT) { + goto done; + } + ret = gp_config_get_int(ctx, "gssproxy", "worker threads", &cfg->num_workers); if (ret != 0 && ret != ENOENT) { @@ -540,6 +551,7 @@ void free_config(struct gp_config **cfg) free(config->config_file); free(config->socket_name); + free(config->proxy_user); for (i=0; i < config->num_svcs; i++) { gp_service_free(config->svcs[i]); diff --git a/proxy/src/gp_init.c b/proxy/src/gp_init.c index 7e29c59..830ae16 100644 --- a/proxy/src/gp_init.c +++ b/proxy/src/gp_init.c @@ -33,6 +33,8 @@ #include <string.h> #include <unistd.h> #include <stdio.h> +#include <pwd.h> +#include <grp.h> #include "gp_proxy.h" void init_server(bool daemonize) @@ -207,3 +209,47 @@ void write_pid(void) GP_PID_FILE, ret, gp_strerror(ret)); } } + +int drop_privs(struct gp_config *cfg) +{ + char buf[2048]; + struct passwd *pw, pws; + int ret; + + if (cfg->proxy_user == NULL) { + /* not dropping privs */ + return 0; + } + + ret = getpwnam_r(cfg->proxy_user, &pws, buf, 2048, &pw); + if (ret) { + GPDEBUG("Failed to look up proxy user: '%s'! [%d:%s]\n", + cfg->proxy_user, ret, gp_strerror(ret)); + return ret; + } + + ret = initgroups(pw->pw_name, pw->pw_gid); + if (ret) { + GPDEBUG("Failed to set access credentials: [%d:%s]\n", + ret, gp_strerror(ret)); + return ret; + } + + ret = setgid(pw->pw_gid); + if (ret == -1) { + ret = errno; + GPDEBUG("Failed to set group id to %d: [%d:%s]\n", + pw->pw_gid, ret, gp_strerror(ret)); + return ret; + } + + ret = setuid(pw->pw_uid); + if (ret == -1) { + ret = errno; + GPDEBUG("Failed to set user id to %d: [%d:%s]\n", + pw->pw_uid, ret, gp_strerror(ret)); + return ret; + } + + return 0; +} diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h index b6c64ae..733fec5 100644 --- a/proxy/src/gp_proxy.h +++ b/proxy/src/gp_proxy.h @@ -74,6 +74,8 @@ struct gp_config { struct gp_service **svcs; int num_svcs; + + char *proxy_user; /* user to drop privs to if not NULL */ }; struct gp_workers; @@ -109,6 +111,7 @@ void fini_server(void); verto_ctx *init_event_loop(void); void init_proc_nfsd(struct gp_config *cfg); void write_pid(void); +int drop_privs(struct gp_config *cfg); /* from gp_socket.c */ struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx, diff --git a/proxy/src/gssproxy.c b/proxy/src/gssproxy.c index 1fca922..1bf0a0b 100644 --- a/proxy/src/gssproxy.c +++ b/proxy/src/gssproxy.c @@ -142,6 +142,11 @@ int main(int argc, const char *argv[]) /* special call to tell the Linux kernel gss-proxy is available */ init_proc_nfsd(gpctx->config); + ret = drop_privs(gpctx->config); + if (ret) { + exit(EXIT_FAILURE); + } + ret = gp_workers_init(gpctx); if (ret) { exit(EXIT_FAILURE); |