This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master
in repository gssproxy.
commit 620223ef2314dd6b0f17f4ce69c20675a916a5f4
Author: Simo Sorce <simo(a)redhat.com>
Date: Wed Jan 4 18:01:30 2017 -0500
Control access to constrained delegation
A client must be tusted or must be explicitly allowed to perform
impersonation or constrained delegation to be able to use evidence
tickets for s4u2proxy operations.
Signed-off-by: Simo Sorce <simo(a)redhat.com>
Reviewed-by: Robbie Harwood <rharwood(a)redhat.com>
---
proxy/man/gssproxy.conf.5.xml | 12 +++++
proxy/src/gp_config.c | 8 +++
proxy/src/gp_creds.c | 105 ++++++++++++++++++++++++++++++++++++
proxy/src/gp_proxy.h | 1 +
proxy/src/gp_rpc_creds.h | 4 ++
proxy/src/gp_rpc_init_sec_context.c | 6 +++
6 files changed, 136 insertions(+)
diff --git a/proxy/man/gssproxy.conf.5.xml b/proxy/man/gssproxy.conf.5.xml
index 6d44e8a..7c724d6 100644
--- a/proxy/man/gssproxy.conf.5.xml
+++ b/proxy/man/gssproxy.conf.5.xml
@@ -114,6 +114,18 @@
</varlistentry>
<varlistentry>
+ <term>allow_constrained_delegation (boolean)</term>
+ <listitem>
+ <para>Allow clients to request a ticket to another service
using an
+ evidence ticket.</para>
+ <para>This option controls whether s4u2proxy requests are
allowed for
+ the requesting client. The KDC still needs to allow the
operation
+ for it to succeed.</para>
+ <para>Default: false</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>cred_usage (string)</term>
<listitem>
<para>Allow to restrict the kind of operations permitted
for this service.</para>
diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c
index 8a449c7..cf1c08b 100644
--- a/proxy/src/gp_config.c
+++ b/proxy/src/gp_config.c
@@ -379,6 +379,14 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context
*ctx)
}
}
+ ret = gp_config_get_string(ctx, secname,
+ "allow_constrained_delegation",
&value);
+ if (ret == 0) {
+ if (gp_boolean_is_true(value)) {
+ cfg->svcs[n]->allow_const_deleg = true;
+ }
+ }
+
ret = gp_config_get_string(ctx, secname, "trusted", &value);
if (ret == 0) {
if (gp_boolean_is_true(value)) {
diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c
index 8fafa66..7236ee1 100644
--- a/proxy/src/gp_creds.c
+++ b/proxy/src/gp_creds.c
@@ -3,6 +3,7 @@
#include "config.h"
#include <stdio.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <pwd.h>
@@ -681,3 +682,107 @@ void gp_filter_flags(struct gp_call_ctx *gpcall, uint32_t *flags)
*flags |= gpcall->service->enforce_flags;
*flags &= ~gpcall->service->filter_flags;
}
+
+uint32_t gp_cred_allowed(uint32_t *min,
+ struct gp_call_ctx *gpcall,
+ gss_cred_id_t cred)
+{
+ uint32_t ret_maj = 0;
+ uint32_t ret_min = 0;
+ char *memcache = NULL;
+ krb5_context context = NULL;
+ krb5_ccache ccache = NULL;
+ krb5_data config;
+ int err;
+
+ if (cred == GSS_C_NO_CREDENTIAL) {
+ return GSS_S_CRED_UNAVAIL;
+ }
+
+ if (gpcall->service->trusted ||
+ gpcall->service->impersonate ||
+ gpcall->service->allow_const_deleg) {
+
+ GPDEBUGN(2, "Credentials allowed by configuration\n");
+ *min = 0;
+ return GSS_S_COMPLETE;
+ }
+
+ /* FIXME: krb5 specific code, should get an oid registerd to query the
+ * cred with gss_inquire_cred_by_oid() or similar instead */
+
+ err = krb5_init_context(&context);
+ if (err) {
+ ret_min = err;
+ ret_maj = GSS_S_FAILURE;
+ goto done;
+ }
+
+ /* Create a memory ccache we can iterate with libkrb5 functions */
+ gss_key_value_element_desc ccelement = { "ccache", NULL };
+ gss_key_value_set_desc cred_store = { 1, &ccelement };
+
+ err = asprintf(&memcache, "MEMORY:cred_allowed_%p", &memcache);
+ if (err == -1) {
+ memcache = NULL;
+ ret_min = ENOMEM;
+ ret_maj = GSS_S_FAILURE;
+ goto done;
+ }
+ cred_store.elements[0].value = memcache;
+
+ ret_maj = gss_store_cred_into(&ret_min, cred, GSS_C_INITIATE,
+ discard_const(gss_mech_krb5), 1, 0,
+ &cred_store, NULL, NULL);
+ if (ret_maj != GSS_S_COMPLETE) {
+ goto done;
+ }
+
+ err = krb5_cc_resolve(context, memcache, &ccache);
+ if (err) {
+ ret_min = err;
+ ret_maj = GSS_S_FAILURE;
+ goto done;
+ }
+
+ /* if we find an impersonator entry we bail as that is not authorized,
+ * if it were then gpcall->service->allow_const_deleg would have caused
+ * the ealier check to return GSS_S_COMPLETE already */
+ err = krb5_cc_get_config(context, ccache, NULL, "proxy_impersonator",
+ &config);
+ if (!err) {
+ krb5_free_data_contents(context, &config);
+ ret_min = 0;
+ ret_maj = GSS_S_UNAUTHORIZED;
+ } else if (err != KRB5_CC_NOTFOUND) {
+ ret_min = err;
+ ret_maj = GSS_S_FAILURE;
+ } else {
+ ret_min = 0;
+ ret_maj = GSS_S_COMPLETE;
+ }
+
+done:
+ switch (ret_maj) {
+ case GSS_S_UNAUTHORIZED:
+ GPDEBUGN(2, "Unauthorized impersonator credentials detected\n");
+ break;
+ case GSS_S_COMPLETE:
+ GPDEBUGN(2, "No impersonator credentials detected\n");
+ break;
+ default:
+ GPDEBUG("Failure while checking credentials\n");
+ break;
+ }
+ if (context) {
+ /* NOTE: destroy only if we created a MEMORY ccache */
+ if (ccache) {
+ if (memcache) krb5_cc_destroy(context, ccache);
+ else krb5_cc_close(context, ccache);
+ }
+ krb5_free_context(context);
+ }
+ free(memcache);
+ *min = ret_min;
+ return ret_maj;
+}
diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h
index 4216b72..ad6806a 100644
--- a/proxy/src/gp_proxy.h
+++ b/proxy/src/gp_proxy.h
@@ -31,6 +31,7 @@ struct gp_service {
uid_t euid;
bool any_uid;
bool allow_proto_trans;
+ bool allow_const_deleg;
bool trusted;
bool kernel_nfsd;
bool impersonate;
diff --git a/proxy/src/gp_rpc_creds.h b/proxy/src/gp_rpc_creds.h
index ead6afc..93df7e1 100644
--- a/proxy/src/gp_rpc_creds.h
+++ b/proxy/src/gp_rpc_creds.h
@@ -32,6 +32,10 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
uint32_t *initiator_time_rec,
uint32_t *acceptor_time_rec);
+uint32_t gp_cred_allowed(uint32_t *min,
+ struct gp_call_ctx *gpcall,
+ gss_cred_id_t cred);
+
void gp_filter_flags(struct gp_call_ctx *gpcall, uint32_t *flags);
#endif /* _GP_RPC_CREDS_H_ */
diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c
index d607b07..f3dc11d 100644
--- a/proxy/src/gp_rpc_init_sec_context.c
+++ b/proxy/src/gp_rpc_init_sec_context.c
@@ -55,6 +55,7 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
goto done;
}
}
+
ret_maj = gp_conv_gssx_to_name(&ret_min, isca->target_name,
&target_name);
if (ret_maj) {
goto done;
@@ -98,6 +99,11 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
}
}
+ ret_maj = gp_cred_allowed(&ret_min, gpcall, ich);
+ if (ret_maj) {
+ goto done;
+ }
+
gp_filter_flags(gpcall, &req_flags);
ret_maj = gss_init_sec_context(&ret_min,
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.