summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-12-22 16:13:56 -0500
committerGünther Deschner <gdeschner@redhat.com>2014-01-14 16:07:27 +0100
commita14cb37d199fec9227f668fe107bf38f99b8b842 (patch)
tree87846966a6820a6c109e856d7185f490f81ffd01
parent8b147c9196d9068d0fc5e5a8919b84e8cbb97ef4 (diff)
downloadgss-proxy-a14cb37d199fec9227f668fe107bf38f99b8b842.tar.gz
gss-proxy-a14cb37d199fec9227f668fe107bf38f99b8b842.tar.xz
gss-proxy-a14cb37d199fec9227f668fe107bf38f99b8b842.zip
Add support for dropping privileges
If the 'proxy user' configuation option is set in the [gssproxy] section then GSS Proxy will drop privileges to the specified after setting up all the sockets. Care must be taken to make sure all the resources the daemon need access to (keytabs, ccache directories, etc..) are accessible as the proxy user. Implements: https://fedorahosted.org/gss-proxy/ticket/102 Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Günther Deschner <gdeschner@redhat.com>
-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);