summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-10-14 16:41:13 -0400
committerGünther Deschner <gdeschner@redhat.com>2013-10-18 15:46:24 +0200
commit3f587569f2fdd9ec4db05748c5ed5ebbfc1ab5c9 (patch)
treec0d10556b81aa7b585138c1a4641643fafdda220
parenta324853818fd75d7ec11c68de9d499f37228b26a (diff)
downloadgss-proxy-3f587569f2fdd9ec4db05748c5ed5ebbfc1ab5c9.tar.gz
gss-proxy-3f587569f2fdd9ec4db05748c5ed5ebbfc1ab5c9.tar.xz
gss-proxy-3f587569f2fdd9ec4db05748c5ed5ebbfc1ab5c9.zip
Add option to specify allowed usage.
Credentials can often be used both to accept and to initiate contexts. With this option admins can allow a specific usage only. This is to avoid allowing an unprivileged process to fool a remote client by allowing it to impersonate a server, when we only want to allow this service to use credentials to initiate contexts. Reviewed-by: Günther Deschner <gdeschner@redhat.com
-rw-r--r--proxy/examples/gssproxy.conf.in1
-rw-r--r--proxy/src/gp_config.c19
-rw-r--r--proxy/src/gp_creds.c14
-rw-r--r--proxy/src/gp_proxy.h1
4 files changed, 33 insertions, 2 deletions
diff --git a/proxy/examples/gssproxy.conf.in b/proxy/examples/gssproxy.conf.in
index 262125a..f121199 100644
--- a/proxy/examples/gssproxy.conf.in
+++ b/proxy/examples/gssproxy.conf.in
@@ -13,6 +13,7 @@
cred_store = keytab:/etc/krb5.keytab
cred_store = ccache:FILE:@gpstatedir@/clients/krb5cc_%U
cred_store = client_keytab:@gpstatedir@/clients/%U.keytab
+ cred_usage = initiate
allow_any_uid = yes
trusted = yes
euid = 0
diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c
index 943906a..2aeaaa9 100644
--- a/proxy/src/gp_config.c
+++ b/proxy/src/gp_config.c
@@ -163,6 +163,9 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx)
}
cfg->num_svcs++;
+ /* by default allow both */
+ cfg->svcs[n]->cred_usage = GSS_C_BOTH;
+
cfg->svcs[n]->name = strdup(secname + 8);
if (!cfg->svcs[n]->name) {
ret = ENOMEM;
@@ -271,6 +274,22 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx)
goto done;
}
}
+
+ ret = gp_config_get_string(ctx, secname, "cred_usage", &value);
+ if (ret == 0) {
+ if (strcasecmp(value, "initiate") == 0) {
+ cfg->svcs[n]->cred_usage = GSS_C_INITIATE;
+ } else if (strcasecmp(value, "accept") == 0) {
+ cfg->svcs[n]->cred_usage = GSS_C_ACCEPT;
+ } else if (strcasecmp(value, "both") == 0) {
+ cfg->svcs[n]->cred_usage = GSS_C_BOTH;
+ } else {
+ GPDEBUG("Invalid value '%s' for cred_usage in [%s].\n",
+ value, secname);
+ ret = EINVAL;
+ goto done;
+ }
+ }
}
safefree(secname);
}
diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c
index b047d8f..28a3d45 100644
--- a/proxy/src/gp_creds.c
+++ b/proxy/src/gp_creds.c
@@ -205,7 +205,7 @@ static void free_cred_store_elements(gss_key_value_set_desc *cs)
static int gp_get_cred_environment(struct gp_call_ctx *gpcall,
gssx_name *desired_name,
gss_name_t *requested_name,
- gss_cred_usage_t cred_usage,
+ gss_cred_usage_t *cred_usage,
gss_key_value_set_desc *cs)
{
struct gp_service *svc;
@@ -226,6 +226,16 @@ static int gp_get_cred_environment(struct gp_call_ctx *gpcall,
target_uid = gp_conn_get_uid(gpcall->connection);
svc = gpcall->service;
+ /* filter based on cred_usage */
+ if (svc->cred_usage != GSS_C_BOTH) {
+ if (*cred_usage == GSS_C_BOTH) {
+ *cred_usage = svc->cred_usage;
+ } else if (svc->cred_usage != *cred_usage) {
+ ret = EACCES;
+ goto done;
+ }
+ }
+
if (desired_name) {
gp_conv_gssx_to_oid(&desired_name->name_type, &name_type);
@@ -379,7 +389,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
}
ret_min = gp_get_cred_environment(gpcall, desired_name, &req_name,
- cred_usage, &cred_store);
+ &cred_usage, &cred_store);
if (ret_min) {
ret_maj = GSS_S_CRED_UNAVAIL;
goto done;
diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h
index a5b3a28..5f42ffa 100644
--- a/proxy/src/gp_proxy.h
+++ b/proxy/src/gp_proxy.h
@@ -55,6 +55,7 @@ struct gp_service {
bool kernel_nfsd;
char *socket;
SELINUX_CTX selinux_ctx;
+ gss_cred_usage_t cred_usage;
uint32_t mechs;
struct gp_cred_krb5 krb5;