summaryrefslogtreecommitdiffstats
path: root/proxy/src/mechglue
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-08-12 18:05:47 -0400
committerRobbie Harwood <rharwood@redhat.com>2015-12-01 17:45:53 -0500
commit7e71db8edc9694ed75110ddd9efa373250cc0545 (patch)
tree3534b077c88f6f710d0e7e4e5680620ccefb7216 /proxy/src/mechglue
parente155f81d84f7dd0b0b643a1228c2f9c503fc87e5 (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.c130
-rw-r--r--proxy/src/mechglue/gpp_creds.c4
-rw-r--r--proxy/src/mechglue/gss_plugin.h10
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,