diff options
| author | Simo Sorce <simo@redhat.com> | 2016-12-02 10:46:20 -0500 |
|---|---|---|
| committer | Simo Sorce <simo@redhat.com> | 2017-01-09 12:08:36 -0500 |
| commit | 4c5668b2b9d71bf3af674e9e093dd429ed1e962d (patch) | |
| tree | 786e9994a77ccbdb06144bab45714b132b186526 | |
| parent | 4bbf5dbe3e87ee883f85310e9d7f03e4883ccd79 (diff) | |
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 <simo@redhat.com>
Reviewed-by: Robbie Harwood <rharwood@redhat.com>
| -rw-r--r-- | proxy/src/mechglue/gpp_acquire_cred.c | 34 | ||||
| -rw-r--r-- | proxy/src/mechglue/gpp_creds.c | 14 | ||||
| -rw-r--r-- | proxy/src/mechglue/gss_plugin.h | 3 |
3 files changed, 46 insertions, 5 deletions
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, |
