summaryrefslogtreecommitdiffstats
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
parente155f81d84f7dd0b0b643a1228c2f9c503fc87e5 (diff)
downloadgss-proxy-7e71db8edc9694ed75110ddd9efa373250cc0545.tar.gz
gss-proxy-7e71db8edc9694ed75110ddd9efa373250cc0545.tar.xz
gss-proxy-7e71db8edc9694ed75110ddd9efa373250cc0545.zip
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>
-rw-r--r--proxy/src/client/gpm_acquire_cred.c33
-rw-r--r--proxy/src/client/gssapi_gpm.h2
-rw-r--r--proxy/src/gp_common.h3
-rw-r--r--proxy/src/gp_creds.c84
-rw-r--r--proxy/src/gp_rpc_accept_sec_context.c2
-rw-r--r--proxy/src/gp_rpc_acquire_cred.c9
-rw-r--r--proxy/src/gp_rpc_creds.h8
-rw-r--r--proxy/src/gp_rpc_init_sec_context.c2
-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
-rw-r--r--proxy/tests/cli_srv_comm.c3
12 files changed, 263 insertions, 27 deletions
diff --git a/proxy/src/client/gpm_acquire_cred.c b/proxy/src/client/gpm_acquire_cred.c
index c0b16cb..a2ac068 100644
--- a/proxy/src/client/gpm_acquire_cred.c
+++ b/proxy/src/client/gpm_acquire_cred.c
@@ -45,10 +45,12 @@ static int gpmint_cred_to_actual_mechs(gssx_cred *c, gss_OID_set *a)
}
OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status,
+ gssx_cred *in_cred_handle,
gssx_name *desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
+ bool impersonate,
gssx_cred **output_cred_handle,
gss_OID_set *actual_mechs,
OM_uint32 *time_rec)
@@ -72,6 +74,7 @@ OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status,
/* ignore call_ctx for now */
+ arg->input_cred_handle = in_cred_handle;
arg->desired_name = desired_name;
if (desired_mechs) {
@@ -85,6 +88,33 @@ OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status,
arg->time_req = time_req;
arg->cred_usage = gp_conv_cred_usage_to_gssx(cred_usage);
+ /* impersonate calls use input cred and a special option */
+ if (impersonate) {
+ gssx_option *opt;
+ arg->options.options_val = calloc(1, sizeof(gssx_option));
+ if (!arg->options.options_val) {
+ ret_maj = GSS_S_FAILURE;
+ ret_min = ENOMEM;
+ goto done;
+ }
+ arg->options.options_len = 1;
+ opt = &arg->options.options_val[0];
+ opt->option.octet_string_val = strdup(ACQUIRE_TYPE_OPTION);
+ if (!opt->option.octet_string_val) {
+ ret_maj = GSS_S_FAILURE;
+ ret_min = ENOMEM;
+ goto done;
+ }
+ opt->option.octet_string_len = sizeof(ACQUIRE_TYPE_OPTION);
+ opt->value.octet_string_val = strdup(ACQUIRE_IMPERSONATE_NAME);
+ if (!opt->value.octet_string_val) {
+ ret_maj = GSS_S_FAILURE;
+ ret_min = ENOMEM;
+ goto done;
+ }
+ opt->value.octet_string_len = sizeof(ACQUIRE_IMPERSONATE_NAME);
+ }
+
/* execute proxy request */
ret = gpm_make_call(GSSX_ACQUIRE_CRED, &uarg, &ures);
if (ret) {
@@ -133,8 +163,9 @@ OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status,
ret_min = 0;
done:
- /* desired_name is passed in, don't let gpm_free_xdrs free it */
+ /* don't let gpm_free_xdrs free variables passed in */
arg->desired_name = NULL;
+ arg->input_cred_handle = NULL;
gpm_free_xdrs(GSSX_ACQUIRE_CRED, &uarg, &ures);
*minor_status = ret_min;
return ret_maj;
diff --git a/proxy/src/client/gssapi_gpm.h b/proxy/src/client/gssapi_gpm.h
index b0a75d0..667b0e0 100644
--- a/proxy/src/client/gssapi_gpm.h
+++ b/proxy/src/client/gssapi_gpm.h
@@ -53,10 +53,12 @@ OM_uint32 gpm_delete_sec_context(OM_uint32 *minor_status,
gss_buffer_t output_token);
OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status,
+ gssx_cred *imp_cred_handle,
gssx_name *desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
+ bool impersonate,
gssx_cred **output_cred_handle,
gss_OID_set *actual_mechs,
OM_uint32 *time_rec);
diff --git a/proxy/src/gp_common.h b/proxy/src/gp_common.h
index 25a89b7..5b9b9b2 100644
--- a/proxy/src/gp_common.h
+++ b/proxy/src/gp_common.h
@@ -114,4 +114,7 @@ do { \
} \
} while(0)
+#define ACQUIRE_TYPE_OPTION "acquire_type"
+#define ACQUIRE_IMPERSONATE_NAME "impersonate_name"
+
#endif /* _GP_COMMON_H_ */
diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c
index 2a747a6..c28c10a 100644
--- a/proxy/src/gp_creds.c
+++ b/proxy/src/gp_creds.c
@@ -192,9 +192,31 @@ static void free_cred_store_elements(gss_key_value_set_desc *cs)
safefree(cs->elements);
}
+int gp_get_acquire_type(struct gssx_arg_acquire_cred *arg)
+{
+ struct gssx_option *val = NULL;
+
+ gp_options_find(val, arg->options,
+ ACQUIRE_TYPE_OPTION, sizeof(ACQUIRE_TYPE_OPTION));
+ if (val) {
+ if (gp_option_value_match(val, ACQUIRE_IMPERSONATE_NAME,
+ sizeof(ACQUIRE_IMPERSONATE_NAME))) {
+ return ACQ_IMPNAME;
+ } else {
+ return -1;
+ }
+ }
+
+ return ACQ_NORMAL;
+}
+
static bool try_impersonate(struct gp_service *svc,
- gss_cred_usage_t cred_usage)
+ gss_cred_usage_t cred_usage,
+ enum gp_aqcuire_cred_type acquire_type)
{
+ if (acquire_type == ACQ_IMPNAME) {
+ return true;
+ }
if (!svc->impersonate) {
return false;
}
@@ -276,7 +298,7 @@ static int gp_get_cred_environment(struct gp_call_ctx *gpcall,
/* impersonation case (only for initiation) */
if (user_requested) {
- if (try_impersonate(svc, *cred_usage)) {
+ if (try_impersonate(svc, *cred_usage, ACQ_NORMAL)) {
/* When impersonating we want to use the service keytab to
* acquire initial credential ... */
use_service_keytab = true;
@@ -394,6 +416,7 @@ done:
uint32_t gp_add_krb5_creds(uint32_t *min,
struct gp_call_ctx *gpcall,
+ enum gp_aqcuire_cred_type acquire_type,
gss_cred_id_t in_cred,
gssx_name *desired_name,
gss_cred_usage_t cred_usage,
@@ -409,7 +432,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
uint32_t discard;
gss_name_t req_name = GSS_C_NO_NAME;
gss_OID_set_desc desired_mechs = { 1, &gp_mech_krb5 };
- gss_key_value_set_desc cred_store;
+ gss_key_value_set_desc cred_store = { 0 };
gss_cred_id_t impersonator_cred = GSS_C_NO_CREDENTIAL;
gss_cred_id_t user_cred = GSS_C_NO_CREDENTIAL;
gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT;
@@ -417,6 +440,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
gss_name_t target_name = GSS_C_NO_NAME;
gss_buffer_desc init_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc accept_token = GSS_C_EMPTY_BUFFER;
+ gss_cred_id_t input_cred;
if (!min || !output_cred_handle) {
return GSS_S_CALL_INACCESSIBLE_WRITE;
@@ -428,7 +452,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
*actual_mechs = GSS_C_NO_OID_SET;
}
- if (in_cred != GSS_C_NO_CREDENTIAL) {
+ if (in_cred != GSS_C_NO_CREDENTIAL && acquire_type != ACQ_IMPNAME) {
/* we can't yet handle adding to an existing credential due to
* the way gss_krb5_import_cred works. This limitation should
* be removed by adding a gssapi extension that superceedes this
@@ -436,14 +460,18 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
return GSS_S_CRED_UNAVAIL;
}
- ret_min = gp_get_cred_environment(gpcall, desired_name, &req_name,
- &cred_usage, &cred_store);
+ if (acquire_type == ACQ_NORMAL) {
+ ret_min = gp_get_cred_environment(gpcall, desired_name, &req_name,
+ &cred_usage, &cred_store);
+ } else if (desired_name) {
+ ret_maj = gp_conv_gssx_to_name(&ret_min, desired_name, &req_name);
+ }
if (ret_min) {
ret_maj = GSS_S_CRED_UNAVAIL;
goto done;
}
- if (!try_impersonate(gpcall->service, cred_usage)) {
+ if (!try_impersonate(gpcall->service, cred_usage, acquire_type)) {
ret_maj = gss_acquire_cred_from(&ret_min, req_name, GSS_C_INDEFINITE,
&desired_mechs, cred_usage,
&cred_store, output_cred_handle,
@@ -452,22 +480,35 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
goto done;
}
} else { /* impersonation */
- ret_maj = gss_acquire_cred_from(&ret_min, GSS_C_NO_NAME,
- GSS_C_INDEFINITE,
- &desired_mechs, GSS_C_BOTH,
- &cred_store, &impersonator_cred,
- NULL, NULL);
- if (ret_maj) {
+ switch (acquire_type) {
+ case ACQ_NORMAL:
+ ret_maj = gss_acquire_cred_from(&ret_min, GSS_C_NO_NAME,
+ GSS_C_INDEFINITE,
+ &desired_mechs, GSS_C_BOTH,
+ &cred_store, &impersonator_cred,
+ NULL, NULL);
+ if (ret_maj) {
+ goto done;
+ }
+ input_cred = impersonator_cred;
+ break;
+ case ACQ_IMPNAME:
+ input_cred = in_cred;
+ break;
+ default:
+ ret_maj = GSS_S_FAILURE;
+ ret_min = EFAULT;
goto done;
}
- ret_maj = gss_inquire_cred(&ret_min, impersonator_cred,
+
+ ret_maj = gss_inquire_cred(&ret_min, input_cred,
&target_name, NULL, NULL, NULL);
if (ret_maj) {
goto done;
}
ret_maj = gss_acquire_cred_impersonate_name(&ret_min,
- impersonator_cred,
+ input_cred,
req_name,
GSS_C_INDEFINITE,
&desired_mechs,
@@ -477,6 +518,14 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
if (ret_maj) {
goto done;
}
+
+ if (acquire_type == ACQ_IMPNAME) {
+ /* we are done here */
+ *output_cred_handle = user_cred;
+ user_cred = GSS_C_NO_CREDENTIAL;
+ goto done;
+ }
+
/* now acquire credentials for impersonated user to self */
ret_maj = gss_init_sec_context(&ret_min, user_cred, &initiator_context,
target_name, &gp_mech_krb5,
@@ -488,9 +537,9 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
if (ret_maj) {
goto done;
}
- /* accept context to be able to store delgated credentials */
+ /* accept context to be able to store delegated credentials */
ret_maj = gss_accept_sec_context(&ret_min, &acceptor_context,
- impersonator_cred, &init_token,
+ input_cred, &init_token,
GSS_C_NO_CHANNEL_BINDINGS,
NULL, NULL, &accept_token,
NULL, NULL, output_cred_handle);
@@ -530,6 +579,7 @@ done:
gss_delete_sec_context(&discard, &initiator_context, NULL);
gss_release_buffer(&discard, &init_token);
gss_release_buffer(&discard, &accept_token);
+ gss_release_name(&discard, &req_name);
*min = ret_min;
return ret_maj;
diff --git a/proxy/src/gp_rpc_accept_sec_context.c b/proxy/src/gp_rpc_accept_sec_context.c
index 7b9d5df..4bb892b 100644
--- a/proxy/src/gp_rpc_accept_sec_context.c
+++ b/proxy/src/gp_rpc_accept_sec_context.c
@@ -56,7 +56,7 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
if (ach == GSS_C_NO_CREDENTIAL) {
ret_maj = gp_add_krb5_creds(&ret_min, gpcall,
- NULL, NULL,
+ ACQ_NORMAL, NULL, NULL,
GSS_C_ACCEPT,
0, 0,
&ach,
diff --git a/proxy/src/gp_rpc_acquire_cred.c b/proxy/src/gp_rpc_acquire_cred.c
index e9deabf..7f40c64 100644
--- a/proxy/src/gp_rpc_acquire_cred.c
+++ b/proxy/src/gp_rpc_acquire_cred.c
@@ -18,6 +18,7 @@ int gp_acquire_cred(struct gp_call_ctx *gpcall,
gss_cred_usage_t cred_usage;
gss_cred_id_t out_cred = GSS_C_NO_CREDENTIAL;
gss_cred_id_t *add_out_cred = NULL;
+ int acquire_type = ACQ_NORMAL;
int ret;
int i;
@@ -32,6 +33,13 @@ int gp_acquire_cred(struct gp_call_ctx *gpcall,
if (ret_maj) {
goto done;
}
+
+ acquire_type = gp_get_acquire_type(aca);
+ if (acquire_type == -1) {
+ ret_maj = GSS_S_FAILURE;
+ ret_min = EINVAL;
+ goto done;
+ }
}
if (aca->add_cred_to_input_handle) {
@@ -93,6 +101,7 @@ int gp_acquire_cred(struct gp_call_ctx *gpcall,
if (gss_oid_equal(desired_mech, gss_mech_krb5)) {
ret_maj = gp_add_krb5_creds(&ret_min,
gpcall,
+ acquire_type,
in_cred,
aca->desired_name,
cred_usage,
diff --git a/proxy/src/gp_rpc_creds.h b/proxy/src/gp_rpc_creds.h
index 98f2eaf..ead6afc 100644
--- a/proxy/src/gp_rpc_creds.h
+++ b/proxy/src/gp_rpc_creds.h
@@ -12,8 +12,16 @@ struct gp_call_ctx;
bool gp_creds_allowed_mech(struct gp_call_ctx *gpcall, gss_OID desired_mech);
uint32_t gp_get_supported_mechs(uint32_t *min, gss_OID_set *set);
+struct gssx_arg_acquire_cred;
+enum gp_aqcuire_cred_type {
+ ACQ_NORMAL = 0,
+ ACQ_IMPNAME = 1,
+};
+int gp_get_acquire_type(struct gssx_arg_acquire_cred *arg);
+
uint32_t gp_add_krb5_creds(uint32_t *min,
struct gp_call_ctx *gpcall,
+ enum gp_aqcuire_cred_type acquire_type,
gss_cred_id_t in_cred,
gssx_name *desired_name,
gss_cred_usage_t cred_usage,
diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c
index 563275d..d607b07 100644
--- a/proxy/src/gp_rpc_init_sec_context.c
+++ b/proxy/src/gp_rpc_init_sec_context.c
@@ -84,7 +84,7 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
if (!isca->cred_handle) {
if (gss_oid_equal(mech_type, gss_mech_krb5)) {
ret_maj = gp_add_krb5_creds(&ret_min, gpcall,
- NULL, NULL,
+ ACQ_NORMAL, NULL, NULL,
GSS_C_INITIATE,
time_req, 0, &ich,
NULL, NULL, NULL);
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,
diff --git a/proxy/tests/cli_srv_comm.c b/proxy/tests/cli_srv_comm.c
index 8a18b4e..77fe338 100644
--- a/proxy/tests/cli_srv_comm.c
+++ b/proxy/tests/cli_srv_comm.c
@@ -457,10 +457,11 @@ void *server_thread(void *pvt)
}
ret_maj = gpm_acquire_cred(&ret_min,
- NULL,
+ NULL, NULL,
GSS_C_INDEFINITE,
mech_set,
GSS_C_ACCEPT,
+ false,
&cred_handle,
NULL,
NULL);