if (code != 0)
goto krb_error_out;
- if (time_rec)
+ if (time_rec) {
+ /* Resolve cred now to determine the expiration time. */
+ ret = kg_cred_resolve(minor_status, context, (gss_cred_id_t)cred,
+ GSS_C_NO_NAME);
+ if (GSS_ERROR(ret))
+ goto error_out;
*time_rec = (cred->expire > now) ? (cred->expire - now) : 0;
+ k5_mutex_unlock(&cred->lock);
+ }
}
*minor_status = 0;
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);
+ cred_store, NULL, NULL,
+ time_rec ? &initTimeOut : NULL,
+ time_rec ? &acceptTimeOut : NULL);
if (major == GSS_S_COMPLETE) {
/* update the credential's time */
if (cred_usage == GSS_C_ACCEPT) {
OM_uint32 *acceptor_time_rec;
{
OM_uint32 status, temp_minor_status;
- OM_uint32 time_req, time_rec;
+ OM_uint32 time_req, time_rec = 0, *time_recp = NULL;
gss_union_name_t union_name;
gss_union_cred_t new_union_cred, union_cred;
gss_name_t internal_name = GSS_C_NO_NAME;
if (status != GSS_S_COMPLETE)
goto errout;
+ if (initiator_time_rec != NULL || acceptor_time_rec != NULL)
+ time_recp = &time_rec;
+
if (mech->gss_acquire_cred_from) {
status = mech->gss_acquire_cred_from(minor_status, internal_name,
time_req, target_mechs,
cred_usage, cred_store, &cred,
- NULL, &time_rec);
+ NULL, time_recp);
} else if (cred_store == GSS_C_NO_CRED_STORE) {
status = mech->gss_acquire_cred(minor_status, internal_name, time_req,
target_mechs, cred_usage, &cred, NULL,
- &time_rec);
+ time_recp);
} else {
return GSS_S_UNAVAILABLE;
}
static OM_uint32 get_req_flags(unsigned char **, OM_uint32, OM_uint32 *);
static OM_uint32 get_available_mechs(OM_uint32 *, gss_name_t, gss_cred_usage_t,
gss_const_key_value_set_t,
- gss_cred_id_t *, gss_OID_set *);
+ gss_cred_id_t *, gss_OID_set *,
+ OM_uint32 *);
static OM_uint32 get_negotiable_mechs(OM_uint32 *, spnego_gss_cred_id_t,
gss_cred_usage_t, gss_OID_set *);
static void release_spnego_ctx(spnego_gss_ctx_id_t *);
*/
status = get_available_mechs(minor_status, desired_name,
cred_usage, cred_store, &mcred,
- &amechs);
+ &amechs, time_rec);
if (actual_mechs && amechs != GSS_C_NULL_OID_SET) {
(void) gssint_copy_oid_set(&tmpmin, amechs, actual_mechs);
GSS_C_BOTH,
GSS_C_NO_CRED_STORE,
&creds,
- mechanisms);
+ mechanisms, NULL);
if (status != GSS_S_COMPLETE) {
dsyslog("Leaving inquire_cred\n");
return (status);
status = get_available_mechs(minor_status, desired_name,
cred_usage, GSS_C_NO_CRED_STORE,
- NULL, &amechs);
+ NULL, &amechs, NULL);
if (status != GSS_S_COMPLETE)
goto cleanup;
get_available_mechs(OM_uint32 *minor_status,
gss_name_t name, gss_cred_usage_t usage,
gss_const_key_value_set_t cred_store,
- gss_cred_id_t *creds, gss_OID_set *rmechs)
+ gss_cred_id_t *creds, gss_OID_set *rmechs, OM_uint32 *time_rec)
{
unsigned int i;
int found = 0;
GSS_C_INDEFINITE,
*rmechs, usage,
cred_store, creds,
- &goodmechs, NULL);
+ &goodmechs, time_rec);
/*
* Drop the old list in favor of the new
credptr = (usage == GSS_C_INITIATE) ? &creds : NULL;
ret = get_available_mechs(minor_status, GSS_C_NO_NAME, usage,
GSS_C_NO_CRED_STORE, credptr,
- rmechs);
+ rmechs, NULL);
gss_release_cred(&tmpmin, &creds);
return (ret);
}