From d9f9b3be036747c9f55060aed47896f951bfb853 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 12 Feb 2016 10:10:33 +0900 Subject: [PATCH] g10: Make sure to have the directory for trustdb. * g10/tdbio.c (tdbio_set_dbname): Return earlier if !CREATE. Check the directory and create it if none before calling take_write_lock. -- Thanks to Marc Deslauriers for the bug report and his patch. GnuPG-bug-id: 2246 Signed-off-by: NIIBE Yutaka --- g10/tdbio.c | 118 +++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/g10/tdbio.c b/g10/tdbio.c index 3cc8bd3ff..79e1e8323 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -603,9 +603,10 @@ create_version_record (void) int tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) { - char *fname; + char *fname, *p; struct stat statbuf; static int initialized = 0; + int save_slash; if (!initialized) { @@ -643,11 +644,48 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) /* OK, we have the valid trustdb.gpg already. */ return 0; } + else if (!create) + { + *r_nofile = 1; + return 0; + } + + /* Here comes: No valid trustdb.gpg AND CREATE==1 */ + + /* + * Make sure the directory exists. This should be done before + * acquiring the lock, which assumes the existence of the directory. + */ + p = strrchr (fname, DIRSEP_C); +#if HAVE_W32_SYSTEM + { + /* Windows may either have a slash or a backslash. Take + care of it. */ + char *pp = strrchr (fname, '/'); + if (!p || pp > p) + p = pp; + } +#endif /*HAVE_W32_SYSTEM*/ + assert (p); + save_slash = *p; + *p = 0; + if (access (fname, F_OK)) + { + try_make_homedir (fname); + if (access (fname, F_OK)) + log_fatal (_("%s: directory does not exist!\n"), fname); + } + *p = save_slash; take_write_lock (); if (access (fname, R_OK)) { + FILE *fp; + TRUSTREC rec; + int rc; + mode_t oldmask; + #ifdef HAVE_W32CE_SYSTEM /* We know how the cegcc implementation of access works ;-). */ if (GetLastError () == ERROR_FILE_NOT_FOUND) @@ -658,66 +696,34 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) if (errno != ENOENT) log_fatal ( _("can't access '%s': %s\n"), fname, strerror (errno)); - if (!create) - *r_nofile = 1; - else + oldmask = umask (077); + if (is_secured_filename (fname)) { - FILE *fp; - TRUSTREC rec; - int rc; - char *p = strrchr (fname, DIRSEP_C); - mode_t oldmask; - int save_slash; + fp = NULL; + gpg_err_set_errno (EPERM); + } + else + fp = fopen (fname, "wb"); + umask(oldmask); + if (!fp) + log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno)); + fclose (fp); -#if HAVE_W32_SYSTEM - { - /* Windows may either have a slash or a backslash. Take - care of it. */ - char *pp = strrchr (fname, '/'); - if (!p || pp > p) - p = pp; - } -#endif /*HAVE_W32_SYSTEM*/ - assert (p); - save_slash = *p; - *p = 0; - if (access (fname, F_OK)) - { - try_make_homedir (fname); - if (access (fname, F_OK)) - log_fatal (_("%s: directory does not exist!\n"), fname); - } - *p = save_slash; + db_fd = open (db_name, O_RDWR | MY_O_BINARY); + if (db_fd == -1) + log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno)); - oldmask = umask (077); - if (is_secured_filename (fname)) - { - fp = NULL; - gpg_err_set_errno (EPERM); - } - else - fp = fopen (fname, "wb"); - umask(oldmask); - if (!fp) - log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno)); - fclose (fp); + rc = create_version_record (); + if (rc) + log_fatal (_("%s: failed to create version record: %s"), + fname, gpg_strerror (rc)); - db_fd = open (db_name, O_RDWR | MY_O_BINARY); - if (db_fd == -1) - log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno)); + /* Read again to check that we are okay. */ + if (tdbio_read_record (0, &rec, RECTYPE_VER)) + log_fatal (_("%s: invalid trustdb created\n"), db_name); - rc = create_version_record (); - if (rc) - log_fatal (_("%s: failed to create version record: %s"), - fname, gpg_strerror (rc)); - - /* Read again to check that we are okay. */ - if (tdbio_read_record (0, &rec, RECTYPE_VER)) - log_fatal (_("%s: invalid trustdb created\n"), db_name); - - if (!opt.quiet) - log_info (_("%s: trustdb created\n"), db_name); - } + if (!opt.quiet) + log_info (_("%s: trustdb created\n"), db_name); } release_write_lock ();