summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proxy/man/gssproxy.conf.5.xml9
-rw-r--r--proxy/src/gp_config.c12
-rw-r--r--proxy/src/gp_init.c46
-rw-r--r--proxy/src/gp_proxy.h3
-rw-r--r--proxy/src/gssproxy.c5
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);