add TGS key caching
authorJohn Kohl <jtkohl@mit.edu>
Wed, 13 Feb 1991 13:42:07 +0000 (13:42 +0000)
committerJohn Kohl <jtkohl@mit.edu>
Wed, 13 Feb 1991 13:42:07 +0000 (13:42 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@1680 dc483132-0cff-0310-8789-dd5450dbe970

src/kdc/extern.c
src/kdc/extern.h
src/kdc/kdc_util.c
src/kdc/main.c

index 3df65372449415eb399d1e7fce83c01a813fa616..1fc591e76e1badb391fa30f8c02458d3c58888d1 100644 (file)
@@ -36,3 +36,8 @@ volatile int signal_requests_exit = 0;        /* gets set when signal hits */
 
 char *dbm_db_name = DEFAULT_DBM_FILE;
 
+krb5_keyblock tgs_key;
+krb5_kvno tgs_kvno;
+
+static krb5_data tgs_name = {sizeof(TGTNAME)-1, TGTNAME};
+krb5_data *tgs_server[4] = {0, &tgs_name, 0, 0};
index 7d1c0e57f24e1698baafc4d5cb89cabfc567cceb..d85b66e683df5516b1bcfeb2f107edd185f2322f 100644 (file)
@@ -30,4 +30,8 @@ extern krb5_principal master_princ;
 extern volatile int signal_requests_exit;
 extern char *dbm_db_name;
 
+extern krb5_keyblock tgs_key;
+extern krb5_kvno tgs_kvno;
+extern krb5_data *tgs_server[4];
+
 #endif /* __KRB5_KDC_EXTERN__ */
index 63e91e3b5d0bfede34c72e249762d5cca57a027a..ada2d5406931ea9ee778fb7ce024697327ca5ad5 100644 (file)
@@ -2,7 +2,7 @@
  * $Source$
  * $Author$
  *
- * Copyright 1990 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991 by the Massachusetts Institute of Technology.
  *
  * For copying and distribution information, please see the file
  * <krb5/copyright.h>.
@@ -127,6 +127,7 @@ krb5_ticket **ticket;
     krb5_checksum our_cksum;
     krb5_data *scratch, scratch2;
     krb5_pa_data **tmppa;
+    krb5_boolean freeprinc = FALSE;
 
     if (!request->padata)
        return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
@@ -169,31 +170,35 @@ krb5_ticket **ticket;
        return KRB5KDC_ERR_POLICY;
     }
 
-    /* XXX perhaps we should optimize the case of the TGS, by having
-       the key always hanging around? */
-
-    nprincs = 1;
-    if (retval = krb5_db_get_principal(apreq->ticket->server,
-                                      &server, &nprincs,
-                                      &more)) {
-       cleanup_apreq();
-       return(retval);
-    }
-    if (more) {
-       krb5_db_free_principal(&server, nprincs);
-       cleanup_apreq();
-       return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
-    } else if (nprincs != 1) {
-       krb5_db_free_principal(&server, nprincs);
-       cleanup_apreq();
-       return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
-    }
-    /* convert server.key into a real key (it may be encrypted
-       in the database) */
-    if (retval = KDB_CONVERT_KEY_OUTOF_DB(&server.key, &encrypting_key)) {
-       krb5_db_free_principal(&server, nprincs);
-       cleanup_apreq();
-       return retval;
+    if (krb5_principal_compare(tgs_server, apreq->ticket->server)) {
+       encrypting_key = tgs_key;
+       server.kvno = tgs_kvno;
+       server.principal = tgs_server;
+    } else {
+       nprincs = 1;
+       if (retval = krb5_db_get_principal(apreq->ticket->server,
+                                          &server, &nprincs,
+                                          &more)) {
+           cleanup_apreq();
+           return(retval);
+       }
+       if (more) {
+           krb5_db_free_principal(&server, nprincs);
+           cleanup_apreq();
+           return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
+       } else if (nprincs != 1) {
+           krb5_db_free_principal(&server, nprincs);
+           cleanup_apreq();
+           return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
+       }
+       /* convert server.key into a real key (it may be encrypted
+          in the database) */
+       if (retval = KDB_CONVERT_KEY_OUTOF_DB(&server.key, &encrypting_key)) {
+           krb5_db_free_principal(&server, nprincs);
+           cleanup_apreq();
+           return retval;
+       }
+       freeprinc = TRUE;
     }
     who.dbentry = &server;
     who.key = &encrypting_key;
@@ -204,9 +209,11 @@ krb5_ticket **ticket;
                                 (krb5_pointer)&who,
                                 0,     /* no replay cache */
                                 &authdat);
-    krb5_db_free_principal(&server, nprincs);
-    memset((char *)encrypting_key.contents, 0, encrypting_key.length);
-    free((char *)encrypting_key.contents);
+    if (freeprinc) {
+       krb5_db_free_principal(&server, nprincs);
+       memset((char *)encrypting_key.contents, 0, encrypting_key.length);
+       free((char *)encrypting_key.contents);
+    }
     if (retval) {
        cleanup_apreq();
        return(retval);
index 512f65d65a935dea3fede146228b19f231519b89..6f49e17e4fa5368bde65bfd725b3d59731dbfc78 100644 (file)
@@ -237,6 +237,9 @@ krb5_principal masterkeyname;
 krb5_keyblock *masterkeyblock;
 {
     krb5_error_code retval;
+    int nprincs;
+    krb5_boolean more;
+    krb5_db_entry server;
 
     /* set db name if appropriate */
     if (dbname && (retval = krb5_db_set_name(dbname)))
@@ -259,6 +262,46 @@ krb5_keyblock *masterkeyblock;
        return(retval);
     }
 
+    /* fetch the TGS key, and hold onto it; this is an efficiency hack */
+
+    /* the master key name here is from the master_princ global,
+       so we can safely share its substructure */
+
+    tgs_server[0] = krb5_princ_realm(masterkeyname);
+    /* tgs_server[1] is init data */
+    tgs_server[2] = krb5_princ_realm(masterkeyname);
+    /* tgs_server[3] is init data (0) */
+
+    nprincs = 1;
+    if (retval = krb5_db_get_principal(tgs_server,
+                                      &server, &nprincs,
+                                      &more)) {
+       return(retval);
+    }
+    if (more) {
+       krb5_db_free_principal(&server, nprincs);
+       (void) krb5_finish_key(&master_encblock);
+       memset((char *)&master_encblock, 0, sizeof(master_encblock));
+       (void) krb5_db_fini();
+       return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
+    } else if (nprincs != 1) {
+       krb5_db_free_principal(&server, nprincs);
+       (void) krb5_finish_key(&master_encblock);
+       memset((char *)&master_encblock, 0, sizeof(master_encblock));
+       (void) krb5_db_fini();
+       return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
+    }
+    /* convert server.key into a real key (it may be encrypted
+       in the database) */
+    if (retval = KDB_CONVERT_KEY_OUTOF_DB(&server.key, &tgs_key)) {
+       krb5_db_free_principal(&server, nprincs);
+       (void) krb5_finish_key(&master_encblock);
+       memset((char *)&master_encblock, 0, sizeof(master_encblock));
+       (void) krb5_db_fini();
+       return retval;
+    }
+    tgs_kvno = server.kvno;
+    krb5_db_free_principal(&server, nprincs);
     return 0;
 }
 
@@ -272,6 +315,8 @@ closedown_db()
 
     memset((char *)&master_encblock, 0, sizeof(master_encblock));
 
+    memset((char *)tgs_key.contents, 0, tgs_key.length);
+
     /* close database */
     if (retval) {
        (void) krb5_db_fini();