diff options
| author | Simo Sorce <simo@redhat.com> | 2014-08-12 18:05:47 -0400 |
|---|---|---|
| committer | Robbie Harwood <rharwood@redhat.com> | 2015-12-01 17:45:53 -0500 |
| commit | 7e71db8edc9694ed75110ddd9efa373250cc0545 (patch) | |
| tree | 3534b077c88f6f710d0e7e4e5680620ccefb7216 /proxy/src/mechglue | |
| parent | e155f81d84f7dd0b0b643a1228c2f9c503fc87e5 (diff) | |
Add gss_acquire_cred_impersonate_name support
This is used by a client that wants to peform a s4u2self operation
using its server credentials.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Robbie Harwoood <rharwood@redhat.com>
Diffstat (limited to 'proxy/src/mechglue')
| -rw-r--r-- | proxy/src/mechglue/gpp_acquire_cred.c | 130 | ||||
| -rw-r--r-- | proxy/src/mechglue/gpp_creds.c | 4 | ||||
| -rw-r--r-- | proxy/src/mechglue/gss_plugin.h | 10 |
3 files changed, 138 insertions, 6 deletions
diff --git a/proxy/src/mechglue/gpp_acquire_cred.c b/proxy/src/mechglue/gpp_acquire_cred.c index 3591e8a..faf5914 100644 --- a/proxy/src/mechglue/gpp_acquire_cred.c +++ b/proxy/src/mechglue/gpp_acquire_cred.c @@ -3,6 +3,7 @@ #include "gss_plugin.h" static OM_uint32 acquire_local(OM_uint32 *minor_status, + struct gpp_cred_handle *imp_cred_handle, struct gpp_name_handle *name, OM_uint32 time_req, const gss_OID_set desired_mechs, @@ -29,6 +30,19 @@ static OM_uint32 acquire_local(OM_uint32 *minor_status, } } + if (imp_cred_handle) { + maj = gss_acquire_cred_impersonate_name(&min, + imp_cred_handle->local, + name ? name->local : NULL, + time_req, + special_mechs, + cred_usage, + &out_cred_handle->local, + actual_mechs, + time_rec); + goto done; + } + maj = gss_acquire_cred(&min, name ? name->local : NULL, time_req, @@ -82,7 +96,8 @@ OM_uint32 gssi_acquire_cred(OM_uint32 *minor_status, /* See if we should try local first */ if (behavior == GPP_LOCAL_ONLY || behavior == GPP_LOCAL_FIRST) { - maj = acquire_local(&min, name, time_req, desired_mechs, cred_usage, + maj = acquire_local(&min, NULL, name, + time_req, desired_mechs, cred_usage, out_cred_handle, actual_mechs, time_rec); if (maj == GSS_S_COMPLETE || behavior == GPP_LOCAL_ONLY) { @@ -102,11 +117,11 @@ OM_uint32 gssi_acquire_cred(OM_uint32 *minor_status, } } - maj = gpm_acquire_cred(&min, + maj = gpm_acquire_cred(&min, NULL, name ? name->remote : NULL, time_req, desired_mechs, - cred_usage, + cred_usage, false, &out_cred_handle->remote, actual_mechs, time_rec); @@ -116,7 +131,8 @@ OM_uint32 gssi_acquire_cred(OM_uint32 *minor_status, if (behavior == GPP_REMOTE_FIRST) { /* So remote failed, but we can fallback to local, try that */ - maj = acquire_local(&min, name, time_req, desired_mechs, cred_usage, + maj = acquire_local(&min, NULL, name, + time_req, desired_mechs, cred_usage, out_cred_handle, actual_mechs, time_rec); } @@ -310,3 +326,109 @@ done: (void)gss_release_oid_set(&min, &special_mechs); return maj; } + +OM_uint32 gssi_acquire_cred_impersonate_name(OM_uint32 *minor_status, + gss_cred_id_t *imp_cred_handle, + const gss_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + enum gpp_behavior behavior; + struct gpp_name_handle *name; + struct gpp_cred_handle *impersonator_cred_handle = NULL; + struct gpp_cred_handle *out_cred_handle = NULL; + OM_uint32 maj, min; + OM_uint32 tmaj, tmin; + + GSSI_TRACE(); + + if (!imp_cred_handle) { + *minor_status = gpp_map_error(EINVAL); + return GSS_S_NO_CRED; + } + + impersonator_cred_handle = (struct gpp_cred_handle *)imp_cred_handle; + + if (!output_cred_handle) { + *minor_status = gpp_map_error(EINVAL); + return GSS_S_FAILURE; + } + + tmaj = GSS_S_COMPLETE; + tmin = 0; + + out_cred_handle = calloc(1, sizeof(struct gpp_cred_handle)); + if (!out_cred_handle) { + maj = GSS_S_FAILURE; + min = ENOMEM; + goto done; + } + + name = (struct gpp_name_handle *)desired_name; + behavior = gpp_get_behavior(); + + /* See if we should try local first */ + if (behavior == GPP_LOCAL_ONLY || behavior == GPP_LOCAL_FIRST) { + + maj = acquire_local(&min, impersonator_cred_handle, name, + time_req, desired_mechs, cred_usage, + out_cred_handle, actual_mechs, time_rec); + + if (maj == GSS_S_COMPLETE || behavior == GPP_LOCAL_ONLY) { + goto done; + } + + /* not successful, save actual local error if remote fallback fails */ + tmaj = maj; + tmin = min; + } + + /* Then try with remote */ + if (name && name->local && !name->remote) { + maj = gpp_local_to_name(&min, name->local, &name->remote); + if (maj) { + goto done; + } + } + + maj = gpm_acquire_cred(&min, + impersonator_cred_handle->remote, + name ? name->remote : NULL, + time_req, + desired_mechs, + cred_usage, + true, + &out_cred_handle->remote, + actual_mechs, + time_rec); + if (maj == GSS_S_COMPLETE || behavior == GPP_REMOTE_ONLY) { + goto done; + } + + if (behavior == GPP_REMOTE_FIRST) { + /* So remote failed, but we can fallback to local, try that */ + maj = acquire_local(&min, impersonator_cred_handle, name, + time_req, desired_mechs, cred_usage, + out_cred_handle, actual_mechs, time_rec); + } + +done: + if (maj != GSS_S_COMPLETE && + maj != GSS_S_CONTINUE_NEEDED && + tmaj != GSS_S_COMPLETE) { + maj = tmaj; + min = tmin; + } + if (maj == GSS_S_COMPLETE) { + *output_cred_handle = (gss_cred_id_t)out_cred_handle; + } else { + free(out_cred_handle); + } + *minor_status = gpp_map_error(min); + return maj; +} + diff --git a/proxy/src/mechglue/gpp_creds.c b/proxy/src/mechglue/gpp_creds.c index fab987a..dcfc896 100644 --- a/proxy/src/mechglue/gpp_creds.c +++ b/proxy/src/mechglue/gpp_creds.c @@ -67,8 +67,8 @@ OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status, /* Then try with remote */ if (behavior == GPP_REMOTE_ONLY || behavior == GPP_REMOTE_FIRST) { - maj = gpm_acquire_cred(&min, - NULL, 0, NULL, cred_usage, + maj = gpm_acquire_cred(&min, NULL, + NULL, 0, NULL, cred_usage, false, &cred->remote, NULL, NULL); if (maj == GSS_S_COMPLETE || behavior == GPP_REMOTE_ONLY) { diff --git a/proxy/src/mechglue/gss_plugin.h b/proxy/src/mechglue/gss_plugin.h index cc5f01b..6df4c6a 100644 --- a/proxy/src/mechglue/gss_plugin.h +++ b/proxy/src/mechglue/gss_plugin.h @@ -102,6 +102,16 @@ OM_uint32 gssi_acquire_cred_with_password(OM_uint32 *minor_status, gss_OID_set *actual_mechs, OM_uint32 *time_rec); +OM_uint32 gssi_acquire_cred_impersonate_name(OM_uint32 *minor_status, + gss_cred_id_t *imp_cred_handle, + const gss_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec); + OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status, enum gpp_behavior behavior, struct gpp_name_handle *name, |
