get_in_tkt.c (get_init_creds): Support ticket_lifetime libdefault. Made aware of...
authorAlexandra Ellwood <lxs@mit.edu>
Thu, 12 Aug 2004 19:10:54 +0000 (19:10 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Thu, 12 Aug 2004 19:10:54 +0000 (19:10 +0000)
ticket: 2654
ticket: 2655
ticket: 2656

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16656 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/get_in_tkt.c

index 9d508e8953ce92b66c93f4a62123c799e499f62e..1e284cce0d48a4ddf14a20a08b468346a3630a0f 100644 (file)
@@ -1,3 +1,10 @@
+2004-08-12  Alexandra Ellwood  <lxs@mit.edu>
+
+        * get_in_tkt.c (get_init_creds):
+        Support ticket_lifetime libdefault.
+        Made aware of 32 bit min and max for times.
+        Allow renew_until time < expiration time.
+        
 2004-08-03  Ken Raeburn  <raeburn@mit.edu>
 
        * srv_rcache.c (krb5_get_server_rcache): Call
index 7d70782e9e84bee52da64bad17ae8d760f366226..0ab3515ceaedaa9babcc461b3b5b46d074f97e99 100644 (file)
@@ -78,6 +78,24 @@ typedef krb5_error_code (*git_decrypt_proc) (krb5_context,
 static krb5_error_code make_preauth_list (krb5_context, 
                                                    krb5_preauthtype *,
                                                    int, krb5_pa_data ***);
+
+/*
+ * This function performs 32 bit bounded addition so we can generate
+ * lifetimes without overflowing krb5_int32
+ */
+static krb5_int32 krb5int_addint32 (krb5_int32 x, krb5_int32 y)
+{
+    if ((x > 0) && (y > (KRB5_INT32_MAX - x))) {
+        /* sum will be be greater than KRB5_INT32_MAX */
+        return KRB5_INT32_MAX;
+    } else if ((x < 0) && (y < (KRB5_INT32_MIN - x))) {
+        /* sum will be less than KRB5_INT32_MIN */
+        return KRB5_INT32_MIN;
+    }
+    
+    return x + y;
+}
+
 /*
  * This function sends a request to the KDC, and gets back a response;
  * the response is parsed into ret_err_reply or ret_as_reply if the
@@ -747,6 +765,7 @@ krb5_get_init_creds(krb5_context context,
     krb5_pa_data **padata;
     int tempint;
     char *tempstr;
+    krb5_deltat tkt_life;
     krb5_deltat renew_life;
     int loopcount;
     krb5_data salt;
@@ -806,8 +825,34 @@ krb5_get_init_creds(krb5_context context,
     if (tempint)
        request.kdc_options |= KDC_OPT_PROXIABLE;
 
-    /* renewable */
-
+    /* allow_postdate */
+    
+    if (start_time > 0)
+       request.kdc_options |= (KDC_OPT_ALLOW_POSTDATE|KDC_OPT_POSTDATED);
+    
+    /* ticket lifetime */
+    
+    if ((ret = krb5_timeofday(context, &request.from)))
+       goto cleanup;
+    request.from = krb5int_addint32(request.from, start_time);
+    
+    if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE)) {
+        tkt_life = options->tkt_life;
+    } else if ((ret = krb5_libdefault_string(context, &client->realm,
+                                            "ticket_lifetime", &tempstr))
+              == 0) {
+       if ((ret = krb5_string_to_deltat(tempstr, &tkt_life))) {
+           free(tempstr);
+           goto cleanup;
+       }
+    } else {
+       /* this used to be hardcoded in kinit.c */
+       tkt_life = 24*60*60;
+    }
+    request.till = krb5int_addint32(request.from, tkt_life);
+    
+    /* renewable lifetime */
+    
     if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE)) {
        renew_life = options->renew_life;
     } else if ((ret = krb5_libdefault_string(context, &client->realm,
@@ -822,16 +867,25 @@ krb5_get_init_creds(krb5_context context,
     }
     if (renew_life > 0)
        request.kdc_options |= KDC_OPT_RENEWABLE;
-
-    /* allow_postdate */
-
-    if (start_time > 0)
-       request.kdc_options |= (KDC_OPT_ALLOW_POSTDATE|KDC_OPT_POSTDATED);
-
+    
+    if (renew_life > 0) {
+       request.rtime = krb5int_addint32(request.from, renew_life);
+        if (request.rtime < request.till) {
+            /* don't ask for a smaller renewable time than the lifetime */
+            request.rtime = request.till;
+        }
+        /* we are already asking for renewable tickets so strip this option */
+       request.kdc_options &= ~(KDC_OPT_RENEWABLE_OK);
+    } else {
+       request.rtime = 0;
+    }
+    
     /* client */
 
     request.client = client;
 
+    /* service */
+    
     if (in_tkt_service) {
        /* this is ugly, because so are the data structures involved.  I'm
           in the library, so I'm going to manipulate the data structures
@@ -865,25 +919,6 @@ krb5_get_init_creds(krb5_context context,
            goto cleanup;
     }
 
-    if ((ret = krb5_timeofday(context, &request.from)))
-       goto cleanup;
-    request.from += start_time;
-
-    request.till = request.from;
-    if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE))
-       request.till += options->tkt_life;
-    else
-       request.till += 24*60*60; /* this used to be hardcoded in kinit.c */
-
-    if (renew_life > 0) {
-       request.rtime = request.from;
-       request.rtime += renew_life;
-       if (request.rtime >= request.till)
-           request.kdc_options &= ~(KDC_OPT_RENEWABLE_OK);
-    } else {
-       request.rtime = 0;
-    }
-
     /* nonce is filled in by send_as_request */
 
     if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST)) {