Pull up r25723 from trunk
authorTom Yu <tlyu@mit.edu>
Wed, 7 Mar 2012 23:44:32 +0000 (23:44 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 7 Mar 2012 23:44:32 +0000 (23:44 +0000)
 ------------------------------------------------------------------------
 r25723 | ghudson | 2012-03-01 15:49:17 -0500 (Thu, 01 Mar 2012) | 16 lines

 ticket: 7096
 subject: Fix KDB iteration when callback does write calls
 target_version: 1.10.1
 tags: pullup

 kdb_db2's ctx_iterate makes an convenience alias to dbc->db in order
 to call more invoke call the DB's seq method.  This alias may become
 invalidated if the callback writes to the DB, since ctx_lock() may
 re-open the DB in order to acquire a write lock.  Fix the bug by
 getting rid of the convenience alias.

 Most KDB iteration operations in the code base do not write to the DB,
 but kdb5_util update_princ_encryption does.

 Bug discovered and diagnosed by will.fiveash@oracle.com.

ticket: 7096
version_fixed: 1.10.1
status: resolved

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-10@25740 dc483132-0cff-0310-8789-dd5450dbe970

src/plugins/kdb/db2/kdb_db2.c

index f63b12e057534899804a906d5aa981d035adec1d..e85ce4be152ae11e16b49fe11bd4c2fd15e34a0a 100644 (file)
@@ -940,7 +940,6 @@ ctx_iterate(krb5_context context, krb5_db2_context *dbc,
             krb5_error_code (*func)(krb5_pointer, krb5_db_entry *),
             krb5_pointer func_arg)
 {
-    DB *db;
     DBT key, contents;
     krb5_data contdata;
     krb5_db_entry *entry;
@@ -951,8 +950,7 @@ ctx_iterate(krb5_context context, krb5_db2_context *dbc,
     if (retval)
         return retval;
 
-    db = dbc->db;
-    dbret = db->seq(db, &key, &contents, R_FIRST);
+    dbret = dbc->db->seq(dbc->db, &key, &contents, R_FIRST);
     while (dbret == 0) {
         contdata.data = contents.data;
         contdata.length = contents.size;
@@ -974,7 +972,7 @@ ctx_iterate(krb5_context context, krb5_db2_context *dbc,
             retval = retval2;
             break;
         }
-        dbret = db->seq(db, &key, &contents, R_NEXT);
+        dbret = dbc->db->seq(dbc->db, &key, &contents, R_NEXT);
     }
     switch (dbret) {
     case 1: