gss_const_OID /* second_oid */
);
+/* Credential store extensions */
+
+struct gss_key_value_element_struct {
+ const char *key;
+ const char *value;
+};
+typedef struct gss_key_value_element_struct gss_key_value_element_desc;
+
+struct gss_key_value_set_struct {
+ OM_uint32 count;
+ gss_key_value_element_desc *elements;
+};
+typedef struct gss_key_value_set_struct gss_key_value_set_desc;
+typedef const gss_key_value_set_desc *gss_const_key_value_set_t;
+
+#define GSS_C_NO_CRED_STORE ((gss_const_key_value_set_t) 0)
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_from(
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *); /* time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_from(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ gss_name_t, /* desired_name */
+ gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 *); /* acceptor_time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred_into(
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ gss_cred_usage_t, /* input_usage */
+ gss_OID, /* desired_mech */
+ OM_uint32, /* overwrite_cred */
+ OM_uint32, /* default_cred */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_OID_set *, /* elements_stored */
+ gss_cred_usage_t *); /* cred_usage_stored */
+
#ifdef __cplusplus
}
#endif
krb5_gss_register_acceptor_identity
krb5_gss_use_kdc_context
gss_inquire_name
+gss_acquire_cred_from
+gss_add_cred_from
+gss_store_cred_into
OM_uint32 time_req,
gss_OID_set desired_mechs,
int cred_usage,
+ gss_const_key_value_set_t cred_store,
gss_cred_id_t *output_cred_handle,
gss_OID_set *actual_mechs,
OM_uint32 *time_rec)
return GSS_S_FAILURE;
}
+ if (cred_store != NULL && cred_store->count == 0) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ return GSS_S_FAILURE;
+ }
+
return (GSS_S_COMPLETE);
}
gss_OID_set * actual_mechs;
OM_uint32 * time_rec;
+{
+ return gss_acquire_cred_from(minor_status, desired_name, time_req,
+ desired_mechs, cred_usage, NULL,
+ output_cred_handle, actual_mechs, time_rec);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_from(minor_status,
+ desired_name,
+ time_req,
+ desired_mechs,
+ cred_usage,
+ cred_store,
+ output_cred_handle,
+ actual_mechs,
+ time_rec)
+
+OM_uint32 * minor_status;
+gss_name_t desired_name;
+OM_uint32 time_req;
+gss_OID_set desired_mechs;
+int cred_usage;
+gss_const_key_value_set_t cred_store;
+gss_cred_id_t * output_cred_handle;
+gss_OID_set * actual_mechs;
+OM_uint32 * time_rec;
+
{
OM_uint32 major = GSS_S_FAILURE, tmpMinor;
OM_uint32 first_major = GSS_S_COMPLETE, first_minor = 0;
time_req,
desired_mechs,
cred_usage,
+ cred_store,
output_cred_handle,
actual_mechs,
time_rec);
/* for each requested mech attempt to obtain a credential */
for (i = 0, major = GSS_S_UNAVAILABLE; i < mechs->count; i++) {
- major = gss_add_cred(&tmpMinor, (gss_cred_id_t)creds,
- desired_name,
- &mechs->elements[i],
- cred_usage, time_req, time_req, NULL,
- NULL, &initTimeOut, &acceptTimeOut);
+ major = gss_add_cred_from(&tmpMinor, (gss_cred_id_t)creds,
+ desired_name, &mechs->elements[i],
+ cred_usage, time_req, time_req,
+ cred_store, NULL, NULL, &initTimeOut,
+ &acceptTimeOut);
if (major == GSS_S_COMPLETE) {
/* update the credential's time */
if (cred_usage == GSS_C_ACCEPT) {
gss_name_t desired_name,
gss_OID desired_mech,
gss_cred_usage_t cred_usage,
+ gss_const_key_value_set_t cred_store,
OM_uint32 initiator_time_req,
OM_uint32 acceptor_time_req,
gss_cred_id_t *output_cred_handle,
return GSS_S_FAILURE;
}
+ if (cred_store != NULL && cred_store->count == 0) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ return GSS_S_FAILURE;
+ }
+
return (GSS_S_COMPLETE);
}
gss_OID_set *actual_mechs;
OM_uint32 *initiator_time_rec;
OM_uint32 *acceptor_time_rec;
+{
+ return gss_add_cred_from(minor_status, input_cred_handle, desired_name,
+ desired_mech, cred_usage, initiator_time_req,
+ acceptor_time_req, NULL, output_cred_handle,
+ actual_mechs, initiator_time_rec,
+ acceptor_time_rec);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_from(minor_status, input_cred_handle,
+ desired_name, desired_mech,
+ cred_usage,
+ initiator_time_req, acceptor_time_req,
+ cred_store,
+ output_cred_handle, actual_mechs,
+ initiator_time_rec, acceptor_time_rec)
+ OM_uint32 *minor_status;
+ gss_cred_id_t input_cred_handle;
+ gss_name_t desired_name;
+ gss_OID desired_mech;
+ gss_cred_usage_t cred_usage;
+ OM_uint32 initiator_time_req;
+ OM_uint32 acceptor_time_req;
+ gss_const_key_value_set_t cred_store;
+ gss_cred_id_t *output_cred_handle;
+ gss_OID_set *actual_mechs;
+ OM_uint32 *initiator_time_rec;
+ OM_uint32 *acceptor_time_rec;
{
OM_uint32 status, temp_minor_status;
OM_uint32 time_req, time_rec;
desired_name,
desired_mech,
cred_usage,
+ cred_store,
initiator_time_req,
acceptor_time_req,
output_cred_handle,
return (GSS_S_FAILURE);
(void) memset(union_cred, 0, sizeof (gss_union_cred_desc));
-
- /* for default credentials we will use GSS_C_NO_NAME */
- internal_name = GSS_C_NO_NAME;
} else {
union_cred = (gss_union_cred_t)input_cred_handle;
if (gssint_get_mechanism_cred(union_cred, desired_mech) !=
GSS_C_NO_CREDENTIAL)
return (GSS_S_DUPLICATE_ELEMENT);
+ }
+ /* for default credentials we will use GSS_C_NO_NAME */
+ if (input_cred_handle != GSS_C_NO_CREDENTIAL ||
+ cred_store != GSS_C_NO_CRED_STORE) {
/* may need to create a mechanism specific name */
if (desired_name) {
union_name = (gss_union_name_t)desired_name;
else
time_req = 0;
- status = mech->gss_acquire_cred(minor_status,
- internal_name, time_req,
- GSS_C_NULL_OID_SET, cred_usage,
- &cred, NULL, &time_rec);
+ if (mech->gss_acquire_cred_from) {
+ status = mech->gss_acquire_cred_from(minor_status, internal_name,
+ time_req, GSS_C_NULL_OID_SET,
+ cred_usage, cred_store, &cred,
+ NULL, &time_rec);
+ } else if (cred_store == GSS_C_NO_CRED_STORE) {
+ status = mech->gss_acquire_cred(minor_status, internal_name, time_req,
+ GSS_C_NULL_OID_SET, cred_usage, &cred,
+ NULL, &time_rec);
+ } else {
+ return GSS_S_UNAVAILABLE;
+ }
if (status != GSS_S_COMPLETE) {
map_error(minor_status, mech);
#include <mglueP.h>
+static OM_uint32
+store_cred_fallback(
+ OM_uint32 *minor_status,
+ gss_mechanism mech,
+ gss_cred_id_t mech_cred,
+ gss_cred_usage_t cred_usage,
+ gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_const_key_value_set_t cred_store,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored)
+{
+ if (mech->gss_store_cred_into != NULL) {
+ return mech->gss_store_cred_into(minor_status, mech_cred,
+ cred_usage, desired_mech,
+ overwrite_cred, default_cred,
+ cred_store, elements_stored,
+ cred_usage_stored);
+ } else if (cred_store == GSS_C_NO_CRED_STORE) {
+ return mech->gss_store_cred(minor_status, mech_cred,
+ cred_usage, desired_mech,
+ overwrite_cred, default_cred,
+ elements_stored,
+ cred_usage_stored);
+ } else {
+ return GSS_S_UNAVAILABLE;
+ }
+}
+
static OM_uint32
val_store_cred_args(
OM_uint32 *minor_status,
const gss_OID desired_mech,
OM_uint32 overwrite_cred,
OM_uint32 default_cred,
+ gss_const_key_value_set_t cred_store,
gss_OID_set *elements_stored,
gss_cred_usage_t *cred_usage_stored)
{
return GSS_S_FAILURE;
}
+ if (cred_store != NULL && cred_store->count == 0) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ return GSS_S_FAILURE;
+ }
+
return (GSS_S_COMPLETE);
}
gss_OID_set *elements_stored;
gss_cred_usage_t *cred_usage_stored;
+{
+ return gss_store_cred_into(minor_status, input_cred_handle, cred_usage,
+ desired_mech, overwrite_cred, default_cred,
+ GSS_C_NO_CRED_STORE, elements_stored,
+ cred_usage_stored);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred_into(minor_status,
+ input_cred_handle,
+ cred_usage,
+ desired_mech,
+ overwrite_cred,
+ default_cred,
+ cred_store,
+ elements_stored,
+ cred_usage_stored)
+
+OM_uint32 *minor_status;
+gss_cred_id_t input_cred_handle;
+gss_cred_usage_t cred_usage;
+gss_OID desired_mech;
+OM_uint32 overwrite_cred;
+OM_uint32 default_cred;
+gss_const_key_value_set_t cred_store;
+gss_OID_set *elements_stored;
+gss_cred_usage_t *cred_usage_stored;
+
{
OM_uint32 major_status = GSS_S_FAILURE;
gss_union_cred_t union_cred;
desired_mech,
overwrite_cred,
default_cred,
+ cred_store,
elements_stored,
cred_usage_stored);
if (major_status != GSS_S_COMPLETE)
if (mech == NULL)
return (GSS_S_BAD_MECH);
- if (mech->gss_store_cred == NULL)
+ if (mech->gss_store_cred_into == NULL &&
+ cred_store != GSS_C_NO_CRED_STORE)
+ return (major_status);
+
+ if (mech->gss_store_cred == NULL &&
+ mech->gss_store_cred_into == NULL)
return (major_status);
mech_cred = gssint_get_mechanism_cred(union_cred, desired_mech);
if (mech_cred == GSS_C_NO_CREDENTIAL)
return (GSS_S_NO_CRED);
- major_status = mech->gss_store_cred(
- minor_status,
- (gss_cred_id_t)mech_cred,
- cred_usage,
- desired_mech,
- overwrite_cred,
- default_cred,
- elements_stored,
- cred_usage_stored);
+ major_status = store_cred_fallback(minor_status, mech,
+ mech_cred, cred_usage,
+ desired_mech,
+ overwrite_cred,
+ default_cred, cred_store,
+ elements_stored,
+ cred_usage_stored);
if (major_status != GSS_S_COMPLETE)
map_error(minor_status, mech);
return major_status;
if (mech == NULL)
continue;
- if (mech->gss_store_cred == NULL)
+ if (mech->gss_store_cred_into == NULL &&
+ cred_store != GSS_C_NO_CRED_STORE)
+ continue;
+
+ if (mech->gss_store_cred == NULL &&
+ mech->gss_store_cred_into == NULL)
continue;
mech_cred = gssint_get_mechanism_cred(union_cred, dmech);
if (mech_cred == GSS_C_NO_CREDENTIAL)
continue; /* can't happen, but safe to ignore */
- major_status = mech->gss_store_cred(
- minor_status,
- (gss_cred_id_t)mech_cred,
- cred_usage,
- dmech,
- overwrite_cred,
- default_cred,
- NULL,
- cred_usage_stored);
+ major_status = store_cred_fallback(minor_status, mech,
+ mech_cred, cred_usage,
+ dmech, overwrite_cred,
+ default_cred, cred_store,
+ NULL, cred_usage_stored);
if (major_status != GSS_S_COMPLETE) {
map_error(minor_status, mech);
continue;
gss_OID_set * /* known_mech_attrs */
/* */);
+ /* Credential store extensions */
+
+ OM_uint32 (KRB5_CALLCONV *gss_acquire_cred_from)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 * /* time_rec */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_store_cred_into)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ gss_cred_usage_t, /* input_usage */
+ gss_OID, /* desired_mech */
+ OM_uint32, /* overwrite_cred */
+ OM_uint32, /* default_cred */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_OID_set *, /* elements_stored */
+ gss_cred_usage_t * /* cred_usage_stored */
+ /* */);
+
} *gss_mechanism;
/* This structure MUST NOT be used by any code outside libgss */