From 4c5668b2b9d71bf3af674e9e093dd429ed1e962d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 2 Dec 2016 10:46:20 -0500 Subject: In acquire_cred_from, probe for remote creds If the calling application is passing in a cred_store, it's either one of two cases: - The application previously stored credentials in a ccache and now wants to use them. - The application has access to specific keys and wants to acquire a local credential. In the first case we can only work with a remote call as a local mechanism wouldn't know what to do with remote creds. In the latter calling the remote code would make no sense as we have local credentials. Signed-off-by: Simo Sorce Reviewed-by: Robbie Harwood --- proxy/src/mechglue/gpp_acquire_cred.c | 34 +++++++++++++++++++++++++++++++++- proxy/src/mechglue/gpp_creds.c | 14 ++++++++++---- proxy/src/mechglue/gss_plugin.h | 3 +++ 3 files changed, 46 insertions(+), 5 deletions(-) (limited to 'proxy/src') diff --git a/proxy/src/mechglue/gpp_acquire_cred.c b/proxy/src/mechglue/gpp_acquire_cred.c index dade19c..1444728 100644 --- a/proxy/src/mechglue/gpp_acquire_cred.c +++ b/proxy/src/mechglue/gpp_acquire_cred.c @@ -87,6 +87,7 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status, enum gpp_behavior behavior; struct gpp_name_handle *name; struct gpp_cred_handle *out_cred_handle = NULL; + struct gssx_cred *in_cred_remote = NULL; OM_uint32 maj, min; OM_uint32 tmaj, tmin; @@ -110,6 +111,33 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status, name = (struct gpp_name_handle *)desired_name; behavior = gpp_get_behavior(); + /* if a cred_store option is passed in, check if it references + * valid credentials, if so switch behavior appropriately */ + if (cred_store) { + for (unsigned i = 0; i < cred_store->count; i++) { + if (strcmp(cred_store->elements[i].key, "ccache") == 0) { + gssx_cred remote = {0}; + maj = gppint_retrieve_remote_creds(&min, + cred_store->elements[i].value, NULL, &remote); + if (maj == GSS_S_COMPLETE) { + in_cred_remote = malloc(sizeof(gssx_cred)); + if (!in_cred_remote) { + maj = GSS_S_FAILURE; + min = ENOMEM; + goto done; + } + *in_cred_remote = remote; + break; + } + } + } + if (in_cred_remote) { + behavior = GPP_REMOTE_ONLY; + } else { + behavior = GPP_LOCAL_ONLY; + } + } + /* See if we should try local first */ if (behavior == GPP_LOCAL_ONLY || behavior == GPP_LOCAL_FIRST) { @@ -134,7 +162,7 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status, } } - maj = gpm_acquire_cred(&min, NULL, + maj = gpm_acquire_cred(&min, in_cred_remote, name ? name->remote : NULL, time_req, desired_mechs, @@ -160,6 +188,10 @@ done: maj = tmaj; min = tmin; } + if (in_cred_remote) { + xdr_free((xdrproc_t)xdr_gssx_cred, (char *)in_cred_remote); + free(in_cred_remote); + } if (maj == GSS_S_COMPLETE) { *output_cred_handle = (gss_cred_id_t)out_cred_handle; } else { diff --git a/proxy/src/mechglue/gpp_creds.c b/proxy/src/mechglue/gpp_creds.c index a0f28c2..c1241bb 100644 --- a/proxy/src/mechglue/gpp_creds.c +++ b/proxy/src/mechglue/gpp_creds.c @@ -79,8 +79,8 @@ done: return ret ? GSS_S_FAILURE : GSS_S_COMPLETE; } -static uint32_t retrieve_remote_creds(uint32_t *min, gssx_name *name, - gssx_cred *creds) +OM_uint32 gppint_retrieve_remote_creds(uint32_t *min, const char *ccache_name, + gssx_name *name, gssx_cred *creds) { krb5_context ctx = NULL; krb5_ccache ccache = NULL; @@ -96,7 +96,11 @@ static uint32_t retrieve_remote_creds(uint32_t *min, gssx_name *name, ret = krb5_init_context(&ctx); if (ret) goto done; - ret = krb5_cc_default(ctx, &ccache); + if (ccache_name) { + ret = krb5_cc_resolve(ctx, ccache_name, &ccache); + } else { + ret = krb5_cc_default(ctx, &ccache); + } if (ret) goto done; if (name) { @@ -203,7 +207,9 @@ OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status, memset(&remote, 0, sizeof(gssx_cred)); /* We intentionally ignore failures as finding creds is optional */ - maj = retrieve_remote_creds(&min, name ? name->remote : NULL, &remote); + maj = gppint_retrieve_remote_creds(&min, NULL, + name ? name->remote : NULL, + &remote); if (maj == GSS_S_COMPLETE) { premote = &remote; } diff --git a/proxy/src/mechglue/gss_plugin.h b/proxy/src/mechglue/gss_plugin.h index ac491e6..d32f2bc 100644 --- a/proxy/src/mechglue/gss_plugin.h +++ b/proxy/src/mechglue/gss_plugin.h @@ -136,6 +136,9 @@ OM_uint32 gssi_acquire_cred_impersonate_name(OM_uint32 *minor_status, gss_OID_set *actual_mechs, OM_uint32 *time_rec); +OM_uint32 gppint_retrieve_remote_creds(uint32_t *min, const char *ccache_name, + gssx_name *name, gssx_cred *creds); + OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status, enum gpp_behavior behavior, struct gpp_name_handle *name, -- cgit