svn rev #21836: branches/mkey_migrate/src/ include/ kadmin/dbutil/ kdc/ lib/kadm5/srv/ ...

wfiveash@MIT.EDU wfiveash at MIT.EDU
Fri Jan 30 15:07:40 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=21836
Commit By: wfiveash
Log Message:
Implemented kdb5_util purge_meys.

Fixed a number of memleaks where the master key list was refetched.

Modified the initial actkvno TL entry to set the act_time to 0 in case
the kdc's clock is moved back after the initial entry is created.  This
way the initial mkey will always be active.



Changed Files:
U   branches/mkey_migrate/src/include/kdb.h
U   branches/mkey_migrate/src/kadmin/dbutil/kdb5_create.c
U   branches/mkey_migrate/src/kadmin/dbutil/kdb5_mkey.c
U   branches/mkey_migrate/src/kadmin/dbutil/kdb5_util.c
U   branches/mkey_migrate/src/kadmin/dbutil/kdb5_util.h
U   branches/mkey_migrate/src/kdc/do_as_req.c
U   branches/mkey_migrate/src/kdc/do_tgs_req.c
U   branches/mkey_migrate/src/kdc/kdc_preauth.c
U   branches/mkey_migrate/src/kdc/kdc_util.c
U   branches/mkey_migrate/src/lib/kadm5/srv/svr_principal.c
U   branches/mkey_migrate/src/lib/kdb/kdb5.c
U   branches/mkey_migrate/src/lib/krb5/error_tables/kdb5_err.et
U   branches/mkey_migrate/src/plugins/kdb/db2/db2_exp.c
U   branches/mkey_migrate/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
Modified: branches/mkey_migrate/src/include/kdb.h
===================================================================
--- branches/mkey_migrate/src/include/kdb.h	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/include/kdb.h	2009-01-30 20:07:37 UTC (rev 21836)
@@ -484,6 +484,11 @@
 				 krb5_timestamp      * stamp);
 
 krb5_error_code
+krb5_dbe_delete_tl_data( krb5_context    context,
+                         krb5_db_entry * entry,
+                         krb5_int16      tl_data_type);
+
+krb5_error_code
 krb5_dbe_update_tl_data( krb5_context          context,
 			 krb5_db_entry       * entry,
 			 krb5_tl_data        * new_tl_data);
@@ -682,6 +687,9 @@
 void
 krb5_dbe_free_mkey_aux_list(krb5_context, krb5_mkey_aux_node *);
 
+void
+krb5_dbe_free_tl_data(krb5_context, krb5_tl_data *);
+
 #define KRB5_KDB_DEF_FLAGS	0
 
 #define KDB_MAX_DB_NAME			128

Modified: branches/mkey_migrate/src/kadmin/dbutil/kdb5_create.c
===================================================================
--- branches/mkey_migrate/src/kadmin/dbutil/kdb5_create.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/kadmin/dbutil/kdb5_create.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -467,7 +467,8 @@
          */
         actkvno.next = NULL;
         actkvno.act_kvno = mkey_kvno;
-        actkvno.act_time = now;
+        /* earliest possible time in case system clock is set back */
+        actkvno.act_time = 0;
         if ((retval = krb5_dbe_update_actkvno(context, &entry, &actkvno)))
             return retval;
 

Modified: branches/mkey_migrate/src/kadmin/dbutil/kdb5_mkey.c
===================================================================
--- branches/mkey_migrate/src/kadmin/dbutil/kdb5_mkey.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/kadmin/dbutil/kdb5_mkey.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -30,6 +30,7 @@
 #endif
 
 extern krb5_keyblock master_keyblock; /* current mkey */
+extern krb5_kvno   master_kvno;
 extern krb5_principal master_princ;
 extern krb5_keylist_node *master_keylist;
 extern krb5_data master_salt;
@@ -110,7 +111,7 @@
                                               &master_entry->key_data[0]))) {
         return (retval);
     }
-    /* so getprinc will show the new mkvno */
+    /* the mvkno should be that of the newest mkey */
     if ((retval = krb5_dbe_update_mkvno(context, master_entry, new_mkey_kvno))) {
         krb5_free_key_data_contents(context, &master_entry->key_data[0]);
         return (retval);
@@ -501,7 +502,7 @@
 
             if (cur_actkvno->act_kvno == use_kvno) {
                 cur_actkvno->act_time = start_time;
-                inserted = 1;   /* fake it */
+                inserted = TRUE;   /* fake it */
             }
             if (!inserted) {
                 if (new_actkvno->act_time < cur_actkvno->act_time) {
@@ -941,7 +942,8 @@
     krb5_error_code retval;
     krb5_actkvno_node *actkvno_list;
     krb5_db_entry master_entry;
-    int nentries = 1, more = 0;
+    int nentries = 1;
+    krb5_boolean more = FALSE;
     char *mkey_fullname = 0;
 #ifdef BSD_REGEXPS
     char *msg;
@@ -1092,3 +1094,327 @@
     krb5_free_keyblock(util_context, tmp_keyblock);
     krb5_free_unparsed_name(util_context, mkey_fullname);
 }
+
+struct kvnos_in_use {
+    krb5_kvno               kvno;
+    unsigned int            use_count;
+};
+
+struct purge_args {
+    krb5_context         kcontext;
+    struct kvnos_in_use  *kvnos;
+    unsigned int         num_kvnos;
+};
+
+static krb5_error_code
+find_mkvnos_in_use(krb5_pointer   ptr,
+                   krb5_db_entry *entry)
+{
+    krb5_error_code retval;
+    struct purge_args * args;
+    unsigned int i;
+    krb5_kvno mkvno;
+
+    args = (struct purge_args *) ptr;
+
+    retval = krb5_dbe_lookup_mkvno(args->kcontext, entry, &mkvno);
+    if (retval)
+        return (retval);
+
+    for (i = 0; i < args->num_kvnos; i++) {
+        if (args->kvnos[i].kvno == mkvno) {
+            /* XXX do I need to worry about use_count wrapping? */
+            args->kvnos[i].use_count++;
+            break;
+        }
+    }
+    return 0;
+}
+
+void
+kdb5_purge_mkeys(int argc, char *argv[])
+{
+    int optchar;
+    krb5_error_code retval;
+    char  *mkey_fullname;
+    krb5_timestamp now;
+    krb5_db_entry master_entry;
+    int   nentries = 0;
+    krb5_boolean more = FALSE;
+    krb5_boolean force = FALSE, dry_run = FALSE, verbose = FALSE;
+    struct purge_args args;
+    char buf[5];
+    unsigned int i, j, k, num_kvnos_inuse, num_kvnos_purged;
+    unsigned int old_key_data_count;
+    krb5_actkvno_node *cur_actkvno_list, *actkvno_entry, *prev_actkvno_entry;
+    krb5_mkey_aux_node *cur_mkey_aux_list, *mkey_aux_entry, *prev_mkey_aux_entry;
+    krb5_key_data *old_key_data;
+
+    optind = 1;
+    while ((optchar = getopt(argc, argv, "fnv")) != -1) {
+        switch(optchar) {
+        case 'f':
+            force = TRUE;
+            break;
+        case 'n':
+            dry_run = TRUE; /* mkey princ will not be modified */
+            force = TRUE; /* implied */
+            break;
+        case 'v':
+            verbose = TRUE;
+            break;
+        case '?':
+        default:
+            usage();
+            return;
+        }
+    }
+
+    /* assemble & parse the master key name */
+    if ((retval = krb5_db_setup_mkey_name(util_context,
+                                          global_params.mkey_name,
+                                          global_params.realm,  
+                                          &mkey_fullname, &master_princ))) {
+        com_err(progname, retval, "while setting up master key name");
+        exit_status++;
+        return;
+    }
+
+    retval = krb5_db_get_principal(util_context, master_princ, &master_entry,
+                                   &nentries, &more);
+    if (retval != 0) {
+        com_err(progname, retval,
+                "while getting master key principal %s",
+                mkey_fullname);
+        exit_status++;
+        return;
+    } else if (nentries == 0) {
+        com_err(progname, KRB5_KDB_NOENTRY,
+                "principal %s not found in Kerberos database",
+                mkey_fullname);
+        exit_status++;
+        return;
+    } else if (nentries > 1) {
+        com_err(progname, KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE,
+                "principal %s has multiple entries in Kerberos database",
+                mkey_fullname);
+        exit_status++;
+        return;
+    }
+
+    if (!force) {
+        printf("Will purge/delete all unused master keys stored in the '%s' principal, are you sure?\n",
+               mkey_fullname);
+        printf("(type 'yes' to confirm)? ");
+        if (fgets(buf, sizeof(buf), stdin) == NULL) {
+            exit_status++;
+            return;
+        }
+        if (strcmp(buf, "yes\n")) {
+            exit_status++;
+            return;
+        }
+        printf("OK, purging unused master keys from '%s'...\n", mkey_fullname);
+    }
+
+    /* save the old keydata */
+    old_key_data_count = master_entry.n_key_data;
+    if (old_key_data_count == 1) {
+        if (verbose)
+            printf("There is only one master key which can not be purged.\n");
+        return;
+    }
+    old_key_data = master_entry.key_data;
+
+    args.kvnos = (struct kvnos_in_use *) malloc(sizeof(struct kvnos_in_use) * old_key_data_count);
+    if (args.kvnos == NULL) {
+        retval = ENOMEM;
+        com_err(progname, ENOMEM, "while allocating args.kvnos");
+        exit_status++;
+        return;
+    }
+    memset(args.kvnos, 0, sizeof(struct kvnos_in_use) * old_key_data_count);
+    args.num_kvnos = old_key_data_count;
+    args.kcontext = util_context;
+
+    /* populate the kvnos array with all the current mkvnos */
+    for (i = 0; i < old_key_data_count; i++)
+        args.kvnos[i].kvno =  master_entry.key_data[i].key_data_kvno;
+
+    if ((retval = krb5_db_iterate(util_context,
+                                  NULL,
+                                  find_mkvnos_in_use,
+                                  (krb5_pointer) &args))) {
+        com_err(progname, retval, "while finding master keys in use");
+        exit_status++;
+        return;
+    }
+    /*
+     * args.kvnos has been marked with the mkvno's that are currently protecting
+     * princ entries
+     */
+    if (verbose) {
+        if (dry_run)
+            printf("Would purge the follwing master key(s) from %s:\n", mkey_fullname);
+        else
+            printf("Will purge the follwing master key(s) from %s:\n", mkey_fullname);
+    }
+
+    /* find # of keys still in use or print out verbose info */
+    for (i = num_kvnos_inuse = num_kvnos_purged = 0; i < args.num_kvnos; i++) {
+        if (args.kvnos[i].use_count > 0) {
+            num_kvnos_inuse++;
+        } else {
+            /* this key would be deleted */
+            if (args.kvnos[i].kvno == master_kvno) {
+                com_err(progname, KRB5_KDB_STORED_MKEY_NOTCURRENT,
+                        "master key stash file needs updating");
+                exit_status++;
+                return;
+            }
+            num_kvnos_purged++;
+            if (verbose)
+                printf("KNVO: %d\n", args.kvnos[i].kvno);
+        }
+    }
+    /* didn't find any keys to purge */
+    if (num_kvnos_inuse == args.num_kvnos) {
+        if (verbose)
+            printf("No keys will be purged\n");
+        goto clean_and_exit;
+    }
+    if (dry_run) {
+        /* bail before doing anything else */
+        printf("%d key(s) would be purged\n", num_kvnos_purged);
+        goto clean_and_exit;
+    }
+
+    retval = krb5_dbe_lookup_actkvno(util_context, &master_entry, &cur_actkvno_list);
+    if (retval != 0) {
+        com_err(progname, retval, "while looking up active kvno list");
+        exit_status++;
+        return;
+    }
+
+    retval = krb5_dbe_lookup_mkey_aux(util_context, &master_entry, &cur_mkey_aux_list);
+    if (retval != 0) {
+        com_err(progname, retval, "while looking up mkey aux data list");
+        exit_status++;
+        return;
+    }
+
+    master_entry.key_data = (krb5_key_data *) malloc(sizeof(krb5_key_data) * num_kvnos_inuse);
+    if (master_entry.key_data == NULL) {
+        retval = ENOMEM;
+        com_err(progname, ENOMEM, "while allocating key_data");
+        exit_status++;
+        return;
+    }
+    memset((char *) master_entry.key_data, 0, sizeof(krb5_key_data) * num_kvnos_inuse);
+    master_entry.n_key_data = num_kvnos_inuse; /* there's only 1 mkey per kvno */
+
+    /*
+     * Assuming that the latest mkey will not be purged because it will always
+     * be "in use" so this code will not bother with encrypting keys again.
+     */
+    for (i = k = 0; i < old_key_data_count; i++) {
+        for (j = 0; j < args.num_kvnos; j++) {
+            if (args.kvnos[j].kvno == (krb5_kvno) old_key_data[i].key_data_kvno) {
+                if (args.kvnos[j].use_count != 0) {
+                    master_entry.key_data[k++] = old_key_data[i];
+                    break;
+                } else {
+                    /* remove unused mkey */
+                    /* adjust the actkno data */
+                    for (prev_actkvno_entry = actkvno_entry = cur_actkvno_list;
+                         actkvno_entry != NULL;
+                         actkvno_entry = actkvno_entry->next) {
+
+                        if (actkvno_entry->act_kvno == args.kvnos[j].kvno) {
+                            if (actkvno_entry == cur_actkvno_list) {
+                                /* remove from head */
+                                cur_actkvno_list = actkvno_entry->next;
+                                prev_actkvno_entry = cur_actkvno_list;
+                            } else if (actkvno_entry->next == NULL) {
+                                /* remove from tail */
+                                prev_actkvno_entry->next = NULL;
+                            } else {
+                                /* remove in between */
+                                prev_actkvno_entry->next = actkvno_entry->next;
+                            }
+                            /* XXX WAF: free actkvno_entry */
+                            break; /* deleted entry, no need to loop further */
+                        } else {
+                            prev_actkvno_entry = actkvno_entry;
+                        }
+                    }
+                    /* adjust the mkey aux data */
+                    for (prev_mkey_aux_entry = mkey_aux_entry = cur_mkey_aux_list;
+                         mkey_aux_entry != NULL;
+                         mkey_aux_entry = mkey_aux_entry->next) {
+
+                        if (mkey_aux_entry->mkey_kvno == args.kvnos[j].kvno) {
+                            if (mkey_aux_entry == cur_mkey_aux_list) {
+                                cur_mkey_aux_list = mkey_aux_entry->next;
+                                prev_mkey_aux_entry = cur_mkey_aux_list;
+                            } else if (mkey_aux_entry->next == NULL) {
+                                prev_mkey_aux_entry->next = NULL;
+                            } else {
+                                prev_mkey_aux_entry->next = mkey_aux_entry->next;
+                            }
+                            /* XXX WAF: free mkey_aux_entry */
+                            break; /* deleted entry, no need to loop further */
+                        } else {
+                            prev_mkey_aux_entry = mkey_aux_entry;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    assert(k == num_kvnos_inuse);
+
+    if ((retval = krb5_dbe_update_actkvno(util_context, &master_entry,
+                                          cur_actkvno_list))) {
+        com_err(progname, retval,
+                "while updating actkvno data for master principal entry");
+        exit_status++;
+        return;
+    }
+
+    if ((retval = krb5_dbe_update_mkey_aux(util_context, &master_entry,
+                                           cur_mkey_aux_list))) {
+        com_err(progname, retval,
+                "while updating mkey_aux data for master principal entry");
+        exit_status++;
+        return;
+    }
+
+    if ((retval = krb5_timeofday(util_context, &now))) {
+        com_err(progname, retval, "while getting current time");
+        exit_status++;
+        return;
+    }
+
+    if ((retval = krb5_dbe_update_mod_princ_data(util_context, &master_entry,
+                                                 now, master_princ))) {
+        com_err(progname, retval,
+                "while updating the master key principal modification time");
+        exit_status++;
+        return;
+    }
+
+    if ((retval = krb5_db_put_principal(util_context, &master_entry, &nentries))) {
+        (void) krb5_db_fini(util_context);
+        com_err(progname, retval, "while adding master key entry to the database");
+        exit_status++;
+        return;
+    }
+
+clean_and_exit:
+    /* clean up */
+    (void) krb5_db_fini(util_context);
+    free(args.kvnos);
+    free(mkey_fullname);
+    return;
+}

Modified: branches/mkey_migrate/src/kadmin/dbutil/kdb5_util.c
===================================================================
--- branches/mkey_migrate/src/kadmin/dbutil/kdb5_util.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/kadmin/dbutil/kdb5_util.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -98,16 +98,18 @@
 	     "\tadd_mkey [-e etype] [-s]\n"
 	     "\tuse_mkey kvno [time]\n"
 	     "\tlist_mkeys\n"
-	     "\tupdate_princ_encryption [-f] [-n] [-v] [princ-pattern]\n"
              );
      /* avoid a string length compiler warning */
      fprintf(stderr,
+	     "\tupdate_princ_encryption [-f] [-n] [-v] [princ-pattern]\n"
+	     "\tpurge_mkeys [-f] [-n] [-v]\n"
 	     "\nwhere,\n\t[-x db_args]* - any number of database specific arguments.\n"
 	     "\t\t\tLook at each database documentation for supported arguments\n");
      exit(1);
 }
 
 extern krb5_keyblock master_keyblock;
+krb5_kvno   master_kvno; /* fetched */
 extern krb5_keylist_node *master_keylist;
 extern krb5_principal master_princ;
 krb5_db_entry master_entry;
@@ -129,15 +131,16 @@
      int opendb;
 } cmd_table[] = {
      {"create", kdb5_create, 0},
-     {"destroy", kdb5_destroy, 1},
+     {"destroy", kdb5_destroy, 1}, /* 1 opens the kdb */
      {"stash", kdb5_stash, 1},
      {"dump", dump_db, 1},
      {"load", load_db, 0},
      {"ark", add_random_key, 1},
-     {"add_mkey", kdb5_add_mkey, 1}, /* 1 is opendb */
-     {"use_mkey", kdb5_use_mkey, 1}, /* 1 is opendb */
-     {"list_mkeys", kdb5_list_mkeys, 1}, /* 1 is opendb */
+     {"add_mkey", kdb5_add_mkey, 1},
+     {"use_mkey", kdb5_use_mkey, 1},
+     {"list_mkeys", kdb5_list_mkeys, 1},
      {"update_princ_encryption", kdb5_update_princ_encryption, 1},
+     {"purge_mkeys", kdb5_purge_mkeys, 1},
      {NULL, NULL, 0},
 };
 
@@ -399,7 +402,6 @@
     int nentries;
     krb5_boolean more;
     krb5_data scratch, pwd, seed;
-    krb5_kvno kvno;
 
     dbactive = FALSE;
     valid_master_key = 0;
@@ -442,9 +444,9 @@
     }
 
     if (global_params.mask & KADM5_CONFIG_KVNO)
-        kvno = global_params.kvno; /* user specified */
+        master_kvno = global_params.kvno; /* user specified */
     else
-        kvno = IGNORE_VNO;
+        master_kvno = IGNORE_VNO;
 
     /* the databases are now open, and the master principal exists */
     dbactive = TRUE;
@@ -483,7 +485,7 @@
 					    master_keyblock.enctype,
 					    manual_mkey, FALSE,
 					    global_params.stash_file,
-					    &kvno,
+					    &master_kvno,
                                             0, &master_keyblock))) {
             com_err(progname, retval, "while reading master key");
             com_err(progname, 0, "Warning: proceeding without master key");
@@ -494,7 +496,7 @@
 #if 0 /************** Begin IFDEF'ed OUT *******************************/
     /* krb5_db_fetch_mkey_list will verify the mkey */
     if ((retval = krb5_db_verify_master_key(util_context, master_princ, 
-					    kvno, &master_keyblock))) {
+					    master_kvno, &master_keyblock))) {
 	com_err(progname, retval, "while verifying master key");
 	exit_status++;
 	krb5_free_keyblock_contents(util_context, &master_keyblock);
@@ -503,7 +505,8 @@
 #endif /**************** END IFDEF'ed OUT *******************************/
 
     if ((retval = krb5_db_fetch_mkey_list(util_context, master_princ,
-				          &master_keyblock, kvno, &master_keylist))) {
+				          &master_keyblock, master_kvno,
+                                          &master_keylist))) {
 	com_err(progname, retval, "while getting master key list");
 	com_err(progname, 0, "Warning: proceeding without master key list");
 	exit_status++;

Modified: branches/mkey_migrate/src/kadmin/dbutil/kdb5_util.h
===================================================================
--- branches/mkey_migrate/src/kadmin/dbutil/kdb5_util.h	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/kadmin/dbutil/kdb5_util.h	2009-01-30 20:07:37 UTC (rev 21836)
@@ -89,6 +89,7 @@
 extern void kdb5_update_princ_encryption (int argc, char **argv);
 extern krb5_error_code master_key_convert(krb5_context context,
 					  krb5_db_entry *db_entry);
+extern void kdb5_purge_mkeys (int argc, char **argv);
 
 extern void update_ok_file (char *file_name);
 

Modified: branches/mkey_migrate/src/kdc/do_as_req.c
===================================================================
--- branches/mkey_migrate/src/kdc/do_as_req.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/kdc/do_as_req.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -116,6 +116,7 @@
     void *pa_context = NULL;
     int did_log = 0;
     const char *emsg = 0;
+    krb5_keylist_node *tmp_mkey_list;
 
 #if APPLE_PKINIT
     asReqDebug("process_as_req top realm %s name %s\n", 
@@ -431,7 +432,9 @@
         /* try refreshing master key list */
         /* XXX it would nice if we had the mkvno here for optimization */
         if (krb5_db_fetch_mkey_list(kdc_context, master_princ,
-                                    &master_keyblock, 0, &master_keylist) == 0) {
+                                    &master_keyblock, 0, &tmp_mkey_list) == 0) {
+            krb5_dbe_free_key_list(kdc_context, master_keylist);
+            master_keylist = tmp_mkey_list;
             if ((errcode = krb5_dbe_find_mkey(kdc_context, master_keylist,
                                               &server, &mkey_ptr))) {
                 status = "FINDING_MASTER_KEY";
@@ -479,7 +482,9 @@
         /* try refreshing master key list */
         /* XXX it would nice if we had the mkvno here for optimization */
         if (krb5_db_fetch_mkey_list(kdc_context, master_princ,
-                                    &master_keyblock, 0, &master_keylist) == 0) {
+                                    &master_keyblock, 0, &tmp_mkey_list) == 0) {
+            krb5_dbe_free_key_list(kdc_context, master_keylist);
+            master_keylist = tmp_mkey_list;
             if ((errcode = krb5_dbe_find_mkey(kdc_context, master_keylist,
                                               &client, &mkey_ptr))) {
                 status = "FINDING_MASTER_KEY";

Modified: branches/mkey_migrate/src/kdc/do_tgs_req.c
===================================================================
--- branches/mkey_migrate/src/kdc/do_tgs_req.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/kdc/do_tgs_req.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -576,10 +576,13 @@
 
         if ((errcode = krb5_dbe_find_mkey(kdc_context, master_keylist, &server,
                                           &mkey_ptr))) {
+            krb5_keylist_node *tmp_mkey_list;
             /* try refreshing master key list */
             /* XXX it would nice if we had the mkvno here for optimization */
             if (krb5_db_fetch_mkey_list(kdc_context, master_princ,
-                                        &master_keyblock, 0, &master_keylist) == 0) {
+                                        &master_keyblock, 0, &tmp_mkey_list) == 0) {
+                krb5_dbe_free_key_list(kdc_context, master_keylist);
+                master_keylist = tmp_mkey_list;
                 if ((errcode = krb5_dbe_find_mkey(kdc_context, master_keylist,
                                                   &server, &mkey_ptr))) {
                     status = "FINDING_MASTER_KEY";

Modified: branches/mkey_migrate/src/kdc/kdc_preauth.c
===================================================================
--- branches/mkey_migrate/src/kdc/kdc_preauth.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/kdc/kdc_preauth.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -703,10 +703,13 @@
 	memset(ret->data, 0, ret->length);
 	if ((error = krb5_dbe_find_mkey(context, master_keylist, entry,
                                         &mkey_ptr))) {
+            krb5_keylist_node *tmp_mkey_list;
             /* try refreshing the mkey list in case it's been updated */
             if (krb5_db_fetch_mkey_list(context, master_princ,
                                         &master_keyblock, 0,
-                                        &master_keylist) == 0) {
+                                        &tmp_mkey_list) == 0) {
+                krb5_dbe_free_key_list(context, master_keylist);
+                master_keylist = tmp_mkey_list;
                 if ((error = krb5_dbe_find_mkey(context, master_keylist, entry,
                                                 &mkey_ptr))) {
                     free(ret);
@@ -1374,10 +1377,13 @@
 
     if ((retval = krb5_dbe_find_mkey(context, master_keylist, client,
                                      &mkey_ptr))) {
+        krb5_keylist_node *tmp_mkey_list;
         /* try refreshing the mkey list in case it's been updated */
         if (krb5_db_fetch_mkey_list(context, master_princ,
                                     &master_keyblock, 0,
-                                    &master_keylist) == 0) {
+                                    &tmp_mkey_list) == 0) {
+            krb5_dbe_free_key_list(context, master_keylist);
+            master_keylist = tmp_mkey_list;
             if ((retval = krb5_dbe_find_mkey(context, master_keylist, client,
                                              &mkey_ptr))) {
                 goto cleanup;
@@ -2044,10 +2050,13 @@
 	{
           if ((retval = krb5_dbe_find_mkey(context, master_keylist, &assoc,
                                            &mkey_ptr))) {
-               /* try refreshing the mkey list in case it's been updated */
+              krb5_keylist_node *tmp_mkey_list;
+              /* try refreshing the mkey list in case it's been updated */
               if (krb5_db_fetch_mkey_list(context, master_princ,
                                           &master_keyblock, 0,
-                                          &master_keylist) == 0) {
+                                          &tmp_mkey_list) == 0) {
+                  krb5_dbe_free_key_list(context, master_keylist);
+                  master_keylist = tmp_mkey_list;
                   if ((retval = krb5_dbe_find_mkey(context, master_keylist, &assoc,
                                                    &mkey_ptr))) {
                       return (retval);
@@ -2705,10 +2714,13 @@
     }
     cert_hash_len = strlen(cert_hash);
     if ((krtn = krb5_dbe_find_mkey(context, master_keylist, &entry, &mkey_ptr))) {
+        krb5_keylist_node *tmp_mkey_list;
         /* try refreshing the mkey list in case it's been updated */
         if (krb5_db_fetch_mkey_list(context, master_princ,
                                     &master_keyblock, 0,
-                                    &master_keylist) == 0) {
+                                    &tmp_mkey_list) == 0) {
+            krb5_dbe_free_key_list(context, master_keylist);
+            master_keylist = tmp_mkey_list;
             if ((krtn = krb5_dbe_find_mkey(context, master_keylist, &entry,
                                            &mkey_ptr))) {
                 goto cleanup;

Modified: branches/mkey_migrate/src/kdc/kdc_util.c
===================================================================
--- branches/mkey_migrate/src/kdc/kdc_util.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/kdc/kdc_util.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -449,10 +449,13 @@
 
     if ((retval = krb5_dbe_find_mkey(kdc_context, master_keylist, server,
                                      &mkey_ptr))) {
+        krb5_keylist_node *tmp_mkey_list;
         /* try refreshing master key list */
         /* XXX it would nice if we had the mkvno here for optimization */
         if (krb5_db_fetch_mkey_list(kdc_context, master_princ,
-                                    &master_keyblock, 0, &master_keylist) == 0) {
+                                    &master_keyblock, 0, &tmp_mkey_list) == 0) {
+            krb5_dbe_free_key_list(kdc_context, master_keylist);
+            master_keylist = tmp_mkey_list;
             if ((retval = krb5_dbe_find_mkey(kdc_context, master_keylist,
                                              server, &mkey_ptr))) {
                 goto errout;

Modified: branches/mkey_migrate/src/lib/kadm5/srv/svr_principal.c
===================================================================
--- branches/mkey_migrate/src/lib/kadm5/srv/svr_principal.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/lib/kadm5/srv/svr_principal.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -2096,11 +2096,14 @@
     if (keyblocks) {
 	if ((ret = krb5_dbe_find_mkey(handle->context, master_keylist, &kdb,
                                       &mkey_ptr))) {
+            krb5_keylist_node *tmp_mkey_list;
             /* try refreshing master key list */
             /* XXX it would nice if we had the mkvno here for optimization */
             if (krb5_db_fetch_mkey_list(handle->context, master_princ,
                                         &master_keyblock, 0,
-                                        &master_keylist) == 0) {
+                                        &tmp_mkey_list) == 0) {
+                krb5_dbe_free_key_list(handle->context, master_keylist);
+                master_keylist = tmp_mkey_list;
                 if ((ret = krb5_dbe_find_mkey(handle->context, master_keylist,
                                               &kdb, &mkey_ptr))) {
                     goto done;
@@ -2238,10 +2241,13 @@
     dbent.tl_data = entry->tl_data;
     if ((ret = krb5_dbe_find_mkey(handle->context, master_keylist, &dbent,
                                   &mkey_ptr))) {
+        krb5_keylist_node *tmp_mkey_list;
         /* try refreshing master key list */
         /* XXX it would nice if we had the mkvno here for optimization */
         if (krb5_db_fetch_mkey_list(handle->context, master_princ,
-                                    &master_keyblock, 0, &master_keylist) == 0) {
+                                    &master_keyblock, 0, &tmp_mkey_list) == 0) {
+            krb5_dbe_free_key_list(handle->context, master_keylist);
+            master_keylist = tmp_mkey_list;
             if ((ret = krb5_dbe_find_mkey(handle->context, master_keylist,
                                           &dbent, &mkey_ptr))) {
                 return ret;

Modified: branches/mkey_migrate/src/lib/kdb/kdb5.c
===================================================================
--- branches/mkey_migrate/src/lib/kdb/kdb5.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/lib/kdb/kdb5.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -163,6 +163,16 @@
     }
 }
 
+void
+krb5_dbe_free_tl_data(krb5_context context, krb5_tl_data *tl_data)
+{
+    if (tl_data) {
+        if (tl_data->tl_data_contents)
+            free(tl_data->tl_data_contents);
+        free(tl_data);
+    }
+}
+
 #define kdb_init_lib_lock(a) 0
 #define kdb_destroy_lib_lock(a) (void)0
 #define kdb_lock_lib_lock(a, b) 0
@@ -2404,6 +2414,12 @@
     unsigned char *nextloc;
     krb5_mkey_aux_node *aux_data_entry;
 
+    if (!mkey_aux_data_list) {
+        /* delete the KRB5_TL_MKEY_AUX from the entry */
+        krb5_dbe_delete_tl_data(context, entry, KRB5_TL_MKEY_AUX);
+        return (0);
+    }
+
     memset(&tl_data, 0, sizeof(tl_data));
     tl_data.tl_data_type = KRB5_TL_MKEY_AUX;
     /*
@@ -2623,6 +2639,44 @@
 }
 
 krb5_error_code
+krb5_dbe_delete_tl_data(krb5_context context,
+                        krb5_db_entry *entry,
+                        krb5_int16 tl_data_type) 
+{
+    krb5_tl_data *tl_data, *prev_tl_data, *free_tl_data;
+
+    /*
+     * Find existing entries of the specified type and remove them from the
+     * entry's tl_data list.
+     */
+
+    for (prev_tl_data = tl_data = entry->tl_data; tl_data != NULL;) {
+        if (tl_data->tl_data_type == tl_data_type) {
+            if (tl_data == entry->tl_data) {
+                /* remove from head */
+                entry->tl_data = tl_data->tl_data_next;
+                prev_tl_data = entry->tl_data;
+            } else if (tl_data->tl_data_next == NULL) {
+                /* remove from tail */
+                prev_tl_data->tl_data_next = NULL;
+            } else {
+                /* remove in between */
+                prev_tl_data->tl_data_next = tl_data->tl_data_next;
+            }
+            free_tl_data = tl_data;
+            tl_data = tl_data->tl_data_next;
+            krb5_dbe_free_tl_data(context, free_tl_data);
+            entry->n_tl_data--;
+        } else {
+            tl_data = tl_data->tl_data_next;
+            prev_tl_data = tl_data;
+        }
+    }
+
+    return (0);
+}
+
+krb5_error_code
 krb5_dbe_update_tl_data(context, entry, new_tl_data)
     krb5_context context;
     krb5_db_entry *entry;

Modified: branches/mkey_migrate/src/lib/krb5/error_tables/kdb5_err.et
===================================================================
--- branches/mkey_migrate/src/lib/krb5/error_tables/kdb5_err.et	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/lib/krb5/error_tables/kdb5_err.et	2009-01-30 20:07:37 UTC (rev 21836)
@@ -59,6 +59,7 @@
 ec KRB5_KDB_BADSTORED_MKEY,	"Stored master key is corrupted"
 ec KRB5_KDB_NOACTMASTERKEY,	"Cannot find active master key"
 ec KRB5_KDB_KVNONOMATCH,	"KVNO of new master key does not match expected value"
+ec KRB5_KDB_STORED_MKEY_NOTCURRENT,	"Stored master key is not current"
 
 ec KRB5_KDB_CANTLOCK_DB,	"Insufficient access to lock database"
 

Modified: branches/mkey_migrate/src/plugins/kdb/db2/db2_exp.c
===================================================================
--- branches/mkey_migrate/src/plugins/kdb/db2/db2_exp.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/plugins/kdb/db2/db2_exp.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -178,15 +178,6 @@
 	   ( krb5_context kcontext, osa_policy_ent_t entry ),
 	   (kcontext, entry));
 
-WRAP (krb5_db2_alloc, void *,
-      ( krb5_context kcontext,  
-	void *ptr, 
-	size_t size ),
-      (kcontext, ptr, size), NULL);
-WRAP_VOID (krb5_db2_free,
-	   ( krb5_context kcontext, void *ptr ),
-	   (kcontext, ptr));
-
 WRAP_K (krb5_db2_set_master_key_ext,
 	( krb5_context kcontext, char *pwd, krb5_keyblock *key),
 	(kcontext, pwd, key));

Modified: branches/mkey_migrate/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
===================================================================
--- branches/mkey_migrate/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c	2009-01-30 16:45:10 UTC (rev 21835)
+++ branches/mkey_migrate/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c	2009-01-30 20:07:37 UTC (rev 21836)
@@ -345,7 +345,7 @@
 
 static krb5_error_code
 asn1_decode_sequence_of_keys (krb5_data *in, krb5_key_data **out,
-			      krb5_int16 *n_key_data, int *mkvno)
+			      krb5_int16 *n_key_data, krb5_kvno *mkvno)
 {
     krb5_error_code err;
     ldap_seqof_key_data *p;




More information about the cvs-krb5 mailing list