]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Resolve krb5 GSS creds if time_rec is requested
authorSimo Sorce <simo@redhat.com>
Mon, 17 Aug 2015 17:21:42 +0000 (13:21 -0400)
committerGreg Hudson <ghudson@mit.edu>
Wed, 19 Aug 2015 15:28:27 +0000 (11:28 -0400)
The code normally tries to defer credential acquisition to a later
time.  However, if the application requests the lifetime, the code
needs to resolve the credential and return the actual expiration time.
Returning 0 would cause the application to think credentials are
expired.

In the mechglue, pass through null time_rec pointers to the mech so
that the mech knows whether it was requested.  In SPNEGO, pass through
time_rec to the mech when acquiring creds, via a new parameter to
get_available_mechs().

[ghudson@mit.edu: minor style changes; edit and expand commit message]

ticket: 8235 (new)

src/lib/gssapi/krb5/acquire_cred.c
src/lib/gssapi/mechglue/g_acquire_cred.c
src/lib/gssapi/spnego/spnego_mech.c

index 5bcfec9e56bde4b7be9fc6c02230c829d7a2a91c..6e83fb9ea1b9409369a54005b77b132bbb17ef27 100644 (file)
@@ -825,8 +825,15 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
         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;
index ff250deca463a96612efceeb6d40b3c9c52f6366..d29856c2c4181d196732a7962b3ba356e6d384c2 100644 (file)
@@ -190,8 +190,9 @@ OM_uint32 *                 time_rec;
        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) {
@@ -356,7 +357,7 @@ gss_add_cred_from(minor_status, input_cred_handle,
     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;
@@ -447,15 +448,18 @@ gss_add_cred_from(minor_status, input_cred_handle,
     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;
     }
index 8ade2454edb813f790ffcab302fb1d9abed3ed97..f3d5f092e4c945a4c04893471b9020691de0f2b8 100644 (file)
@@ -96,7 +96,8 @@ static gss_OID_set get_mech_set(OM_uint32 *, unsigned char **, unsigned int);
 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 *);
@@ -399,7 +400,7 @@ spnego_gss_acquire_cred_from(OM_uint32 *minor_status,
         */
        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);
@@ -2009,7 +2010,7 @@ spnego_gss_inquire_cred(
                        GSS_C_BOTH,
                        GSS_C_NO_CRED_STORE,
                        &creds,
-                       mechanisms);
+                       mechanisms, NULL);
                if (status != GSS_S_COMPLETE) {
                        dsyslog("Leaving inquire_cred\n");
                        return (status);
@@ -2637,7 +2638,7 @@ spnego_gss_acquire_cred_with_password(OM_uint32 *minor_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;
 
@@ -3006,7 +3007,7 @@ static OM_uint32
 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;
@@ -3060,7 +3061,7 @@ get_available_mechs(OM_uint32 *minor_status,
                                                     GSS_C_INDEFINITE,
                                                     *rmechs, usage,
                                                     cred_store, creds,
-                                                    &goodmechs, NULL);
+                                                    &goodmechs, time_rec);
 
                /*
                 * Drop the old list in favor of the new
@@ -3110,7 +3111,7 @@ get_negotiable_mechs(OM_uint32 *minor_status, spnego_gss_cred_id_t spcred,
                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);
        }