krb5 commit: Fix kdb5_util dump race

Greg Hudson ghudson at MIT.EDU
Fri Oct 5 14:37:12 EDT 2012


https://github.com/krb5/krb5/commit/464e61f63d023a16f6aecd2798860323cbf84c91
commit 464e61f63d023a16f6aecd2798860323cbf84c91
Author: Nicolas Williams <nico at cryptonector.com>
Date:   Wed Sep 26 17:32:56 2012 -0500

    Fix kdb5_util dump race
    
    ticket: 7377

 src/kadmin/dbutil/dump.c      |   64 ++++++++++++++++++++--------------------
 src/kadmin/dbutil/kdb5_util.h |    2 -
 2 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index c5c0034..c1478b6 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -490,41 +490,45 @@ current_dump_sno_in_ulog(char *ifile, kdb_hlog_t *ulog)
     return 1;
 }
 
-/*
- * Update the "ok" file.
- */
-void update_ok_file (file_name)
-    char *file_name;
+
+/* Create the .dump_ok file. */
+static int
+prep_ok_file(krb5_context context, char *file_name, int *fd)
 {
-    /* handle slave locking/failure stuff */
-    char *file_ok;
-    int fd;
     static char ok[]=".dump_ok";
+    krb5_error_code retval;
+    char *file_ok;
 
     if (asprintf(&file_ok, "%s%s", file_name, ok) < 0) {
-        com_err(progname, ENOMEM,
-                _("while allocating filename for update_ok_file"));
+        com_err(progname, ENOMEM, _("while allocating dump_ok filename"));
         exit_status++;
-        return;
+        return 0;
     }
-    if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
-        com_err(progname, errno, _("while creating 'ok' file, '%s'"),
-                file_ok);
+
+    *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+    if (*fd == -1) {
+        com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
         exit_status++;
         free(file_ok);
-        return;
+        return 0;
     }
-    if (write(fd, "", 1) != 1) {
-        com_err(progname, errno, _("while writing to 'ok' file, '%s'"),
-                file_ok);
-        exit_status++;
-        free(file_ok);
-        return;
+    retval = krb5_lock_file(context, *fd, KRB5_LOCKMODE_EXCLUSIVE);
+    if (retval) {
+        com_err(progname, retval, _("while locking 'ok' file, '%s'"), file_ok);
+        return 0;
     }
+    return 1;
+}
 
-    free(file_ok);
+/*
+ * Update the "ok" file.
+ */
+static void
+update_ok_file(krb5_context context, int fd)
+{
+    write(fd, "", 1);
+    krb5_lock_file(context, fd, KRB5_LOCKMODE_UNLOCK);
     close(fd);
-    return;
 }
 
 /*
@@ -1274,6 +1278,7 @@ dump_db(argc, argv)
     dump_version        *dump;
     int                 aindex;
     int                 conditional = 0;
+    int                 ok_fd = -1;
     char                *new_mkey_file = 0;
     bool_t              dump_sno = FALSE;
     kdb_log_context     *log_ctx;
@@ -1454,11 +1459,13 @@ dump_db(argc, argv)
          */
         if (ofile[0] == '-')
             usage();
+        if (!prep_ok_file(util_context, ofile, &ok_fd))
+            return;            /* prep_ok_file() bumps exit_status */
         f = create_ofile(ofile, &tmpofile);
         if (f == NULL) {
             fprintf(stderr, ofopen_error,
                     progname, ofile, error_message(errno));
-            return;
+            goto error;
         }
     } else {
         f = stdout;
@@ -1508,7 +1515,7 @@ dump_db(argc, argv)
         if (ofile && f != stdout) {
             fclose(f);
             finish_ofile(ofile, &tmpofile);
-            update_ok_file(ofile);
+            update_ok_file(util_context, ok_fd);
         }
         return;
     }
@@ -2732,13 +2739,6 @@ load_db(argc, argv)
             exit_status++;
             return;
         }
-        if ((kret = krb5_lock_file(kcontext, fileno(f),
-                                   KRB5_LOCKMODE_SHARED))) {
-            fprintf(stderr, _("%s: Cannot lock %s: %s\n"), progname,
-                    dumpfile, error_message(errno));
-            exit_status++;
-            return;
-        }
     } else
         f = stdin;
 
diff --git a/src/kadmin/dbutil/kdb5_util.h b/src/kadmin/dbutil/kdb5_util.h
index b606b8d..9517ea7 100644
--- a/src/kadmin/dbutil/kdb5_util.h
+++ b/src/kadmin/dbutil/kdb5_util.h
@@ -87,8 +87,6 @@ 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);
-
 extern int kadm5_create (kadm5_config_params *params);
 
 extern krb5_error_code add_new_mkey(krb5_context, krb5_db_entry *,


More information about the cvs-krb5 mailing list