/* Handle the creation of a keyring or a keybox if it does not yet exist. Take into acount that other processes might have the keyring/keybox already locked. This lock check does not work if the directory itself is not yet available. */ static int maybe_create_keyring_or_box (char *filename, int is_box, int force) { dotlock_t lockhd = NULL; IOBUF iobuf; int rc; mode_t oldmask; char *last_slash_in_filename; int save_slash; /* A quick test whether the filename already exists. */ if (!access (filename, F_OK)) return 0; /* If we don't want to create a new file at all, there is no need to go any further - bail out right here. */ if (!force) return gpg_error (GPG_ERR_ENOENT); /* First of all we try to create the home directory. Note, that we don't do any locking here because any sane application of gpg would create the home directory by itself and not rely on gpg's tricky auto-creation which is anyway only done for some home directory name patterns. */ last_slash_in_filename = strrchr (filename, DIRSEP_C); #if HAVE_W32_SYSTEM { /* Windows may either have a slash or a backslash. Take care of it. */ char *p = strrchr (filename, '/'); if (!last_slash_in_filename || p > last_slash_in_filename) last_slash_in_filename = p; } #endif /*HAVE_W32_SYSTEM*/ if (!last_slash_in_filename) return gpg_error (GPG_ERR_ENOENT); /* No slash at all - should not happen though. */ save_slash = *last_slash_in_filename; *last_slash_in_filename = 0; if (access(filename, F_OK)) { static int tried; if (!tried) { tried = 1; try_make_homedir (filename); } if (access (filename, F_OK)) { rc = gpg_error_from_syserror (); *last_slash_in_filename = save_slash; goto leave; } } *last_slash_in_filename = save_slash; /* To avoid races with other instances of gpg trying to create or update the keyring (it is removed during an update for a short time), we do the next stuff in a locked state. */ lockhd = dotlock_create (filename, 0); if (!lockhd) { rc = gpg_error_from_syserror (); /* A reason for this to fail is that the directory is not writable. However, this whole locking stuff does not make sense if this is the case. An empty non-writable directory with no keyring is not really useful at all. */ if (opt.verbose) log_info ("can't allocate lock for '%s': %s\n", filename, gpg_strerror (rc)); if (!force) return gpg_error (GPG_ERR_ENOENT); else return rc; } if ( dotlock_take (lockhd, -1) ) { rc = gpg_error_from_syserror (); /* This is something bad. Probably a stale lockfile. */ log_info ("can't lock '%s': %s\n", filename, gpg_strerror (rc)); goto leave; } /* Now the real test while we are locked. */ if (!access (filename, F_OK)) { rc = 0; /* Okay, we may access the file now. */ goto leave; } /* The file does not yet exist, create it now. */ oldmask = umask (077); if (is_secured_filename (filename)) { iobuf = NULL; gpg_err_set_errno (EPERM); } else iobuf = iobuf_create (filename); umask (oldmask); if (!iobuf) { rc = gpg_error_from_syserror (); if (is_box) log_error (_("error creating keybox '%s': %s\n"), filename, gpg_strerror (rc)); else log_error (_("error creating keyring '%s': %s\n"), filename, gpg_strerror (rc)); goto leave; } iobuf_close (iobuf); /* Must invalidate that ugly cache */ iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename); /* Make sure that at least one record is in a new keybox file, so that the detection magic will work the next time it is used. */ if (is_box) { FILE *fp = fopen (filename, "w"); if (!fp) rc = gpg_error_from_syserror (); else { rc = _keybox_write_header_blob (fp); fclose (fp); } if (rc) { if (is_box) log_error (_("error creating keybox '%s': %s\n"), filename, gpg_strerror (rc)); else log_error (_("error creating keyring '%s': %s\n"), filename, gpg_strerror (rc)); goto leave; } } if (!opt.quiet) { if (is_box) log_info (_("keybox '%s' created\n"), filename); else log_info (_("keyring '%s' created\n"), filename); } rc = 0; leave: if (lockhd) { dotlock_release (lockhd); dotlock_destroy (lockhd); } return rc; }
/* Handle the creation of a keyring if it does not yet exist. Take into acount that other processes might have the keyring already locked. This lock check does not work if the directory itself is not yet available. */ static int maybe_create_keyring (char *filename, int force) { DOTLOCK lockhd = NULL; IOBUF iobuf; int rc; mode_t oldmask; char *last_slash_in_filename; /* A quick test whether the filename already exists. */ if (!access (filename, F_OK)) return 0; /* If we don't want to create a new file at all, there is no need to go any further - bail out right here. */ if (!force) return G10ERR_OPEN_FILE; /* First of all we try to create the home directory. Note, that we don't do any locking here because any sane application of gpg would create the home directory by itself and not rely on gpg's tricky auto-creation which is anyway only done for some home directory name patterns. */ last_slash_in_filename = strrchr (filename, DIRSEP_C); *last_slash_in_filename = 0; if (access(filename, F_OK)) { static int tried; if (!tried) { tried = 1; try_make_homedir (filename); } if (access (filename, F_OK)) { rc = G10ERR_OPEN_FILE; *last_slash_in_filename = DIRSEP_C; goto leave; } } *last_slash_in_filename = DIRSEP_C; /* To avoid races with other instances of gpg trying to create or update the keyring (it is removed during an update for a short time), we do the next stuff in a locked state. */ lockhd = create_dotlock (filename); if (!lockhd) { /* A reason for this to fail is that the directory is not writable. However, this whole locking stuff does not make sense if this is the case. An empty non-writable directory with no keyring is not really useful at all. */ if (opt.verbose) log_info ("can't allocate lock for `%s'\n", filename ); if (!force) return G10ERR_OPEN_FILE; else return G10ERR_GENERAL; } if ( make_dotlock (lockhd, -1) ) { /* This is something bad. Probably a stale lockfile. */ log_info ("can't lock `%s'\n", filename ); rc = G10ERR_GENERAL; goto leave; } /* Now the real test while we are locked. */ if (!access(filename, F_OK)) { rc = 0; /* Okay, we may access the file now. */ goto leave; } /* The file does not yet exist, create it now. */ oldmask = umask (077); if (is_secured_filename (filename)) { iobuf = NULL; errno = EPERM; } else iobuf = iobuf_create (filename); umask (oldmask); if (!iobuf) { log_error ( _("error creating keyring `%s': %s\n"), filename, strerror(errno)); rc = G10ERR_OPEN_FILE; goto leave; } if (!opt.quiet) log_info (_("keyring `%s' created\n"), filename); iobuf_close (iobuf); /* Must invalidate that ugly cache */ iobuf_ioctl (NULL, 2, 0, filename); rc = 0; leave: if (lockhd) { release_dotlock (lockhd); destroy_dotlock (lockhd); } return rc; }
int tdbio_set_dbname( const char *new_dbname, int create ) { char *fname; static int initialized = 0; if( !initialized ) { atexit( cleanup ); initialized = 1; } if(new_dbname==NULL) fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL); else if (*new_dbname != DIRSEP_C ) { if (strchr(new_dbname, DIRSEP_C) ) fname = make_filename (new_dbname, NULL); else fname = make_filename (opt.homedir, new_dbname, NULL); } else fname = xstrdup (new_dbname); if( access( fname, R_OK ) ) { if( errno != ENOENT ) { log_error( _("can't access `%s': %s\n"), fname, strerror(errno) ); xfree(fname); return G10ERR_TRUSTDB; } if( create ) { FILE *fp; TRUSTREC rec; int rc; char *p = strrchr( fname, DIRSEP_C ); mode_t oldmask; assert(p); *p = 0; if( access( fname, F_OK ) ) { try_make_homedir( fname ); log_fatal( _("%s: directory does not exist!\n"), fname ); } *p = DIRSEP_C; xfree(db_name); db_name = fname; #ifdef __riscos__ if( !lockhandle ) lockhandle = create_dotlock( db_name ); if( !lockhandle ) log_fatal( _("can't create lock for `%s'\n"), db_name ); if( make_dotlock( lockhandle, -1 ) ) log_fatal( _("can't lock `%s'\n"), db_name ); #endif /* __riscos__ */ oldmask=umask(077); if (is_secured_filename (fname)) { fp = NULL; errno = EPERM; } else fp =fopen( fname, "wb" ); umask(oldmask); if( !fp ) log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) ); fclose(fp); 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) ); #ifndef __riscos__ if( !lockhandle ) lockhandle = create_dotlock( db_name ); if( !lockhandle ) log_fatal( _("can't create lock for `%s'\n"), db_name ); #endif /* !__riscos__ */ rc = create_version_record (); if( rc ) log_fatal( _("%s: failed to create version record: %s"), fname, g10_errstr(rc)); /* and 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); return 0; } } xfree(db_name); db_name = fname; return 0; }
int tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile) { char *fname; struct stat statbuf; static int initialized = 0; if( !initialized ) { atexit( cleanup ); initialized = 1; } *r_nofile = 0; if(new_dbname==NULL) fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL); else if (*new_dbname != DIRSEP_C ) { if (strchr(new_dbname, DIRSEP_C) ) fname = make_filename (new_dbname, NULL); else fname = make_filename (opt.homedir, new_dbname, NULL); } else fname = xstrdup (new_dbname); xfree (db_name); db_name = fname; /* * Quick check for (likely) case where there is trustdb.gpg * already. This check is not required in theory, but it helps in * practice, avoiding costly operations of preparing and taking * the lock. */ if (stat (fname, &statbuf) == 0 && statbuf.st_size > 0) /* OK, we have the valid trustdb.gpg already. */ return 0; take_write_lock (); if( access( fname, R_OK ) ) { if( errno != ENOENT ) log_fatal( _("can't access `%s': %s\n"), fname, strerror(errno) ); if (!create) *r_nofile = 1; else { FILE *fp; TRUSTREC rec; int rc; char *p = strrchr( fname, DIRSEP_C ); mode_t oldmask; int save_slash; #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; oldmask=umask(077); if (is_secured_filename (fname)) { fp = NULL; errno = EPERM; } else fp =fopen( fname, "wb" ); umask(oldmask); if( !fp ) log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) ); fclose(fp); 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) ); rc = create_version_record (); if( rc ) log_fatal( _("%s: failed to create version record: %s"), fname, g10_errstr(rc)); /* and 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); } } release_write_lock (); return 0; }
int exec_write(struct exec_info **info,const char *program, const char *args_in,const char *name,int writeonly,int binary) { int ret=G10ERR_GENERAL; if(opt.exec_disable && !opt.no_perm_warn) { log_info(_("external program calls are disabled due to unsafe " "options file permissions\n")); return ret; } #if defined(HAVE_GETUID) && defined(HAVE_GETEUID) /* There should be no way to get to this spot while still carrying setuid privs. Just in case, bomb out if we are. */ if ( getuid () != geteuid ()) BUG (); #endif if(program==NULL && args_in==NULL) BUG(); *info=xmalloc_clear(sizeof(struct exec_info)); if(name) (*info)->name=xstrdup(name); (*info)->flags.binary=binary; (*info)->flags.writeonly=writeonly; /* Expand the args, if any */ if(args_in && expand_args(*info,args_in)) goto fail; #ifdef EXEC_TEMPFILE_ONLY if(!(*info)->flags.use_temp_files) { log_error(_("this platform requires temporary files when calling" " external programs\n")); goto fail; } #else /* !EXEC_TEMPFILE_ONLY */ /* If there are no args, or there are args, but no temp files, we can use fork/exec/pipe */ if(args_in==NULL || (*info)->flags.use_temp_files==0) { int to[2],from[2]; if(pipe(to)==-1) goto fail; if(pipe(from)==-1) { close(to[0]); close(to[1]); goto fail; } if(((*info)->child=fork())==-1) { close(to[0]); close(to[1]); close(from[0]); close(from[1]); goto fail; } if((*info)->child==0) { char *shell=getenv("SHELL"); if(shell==NULL) shell="/bin/sh"; /* I'm the child */ /* If the program isn't going to respond back, they get to keep their stdout/stderr */ if(!(*info)->flags.writeonly) { /* implied close of STDERR */ if(dup2(STDOUT_FILENO,STDERR_FILENO)==-1) _exit(1); /* implied close of STDOUT */ close(from[0]); if(dup2(from[1],STDOUT_FILENO)==-1) _exit(1); } /* implied close of STDIN */ close(to[1]); if(dup2(to[0],STDIN_FILENO)==-1) _exit(1); if(args_in==NULL) { if(DBG_EXTPROG) log_debug("execlp: %s\n",program); execlp(program,program,(void *)NULL); } else { if(DBG_EXTPROG) log_debug("execlp: %s -c %s\n",shell,(*info)->command); execlp(shell,shell,"-c",(*info)->command,(void *)NULL); } /* If we get this far the exec failed. Clean up and return. */ if(args_in==NULL) log_error(_("unable to execute program `%s': %s\n"), program,strerror(errno)); else log_error(_("unable to execute shell `%s': %s\n"), shell,strerror(errno)); /* This mimics the POSIX sh behavior - 127 means "not found" from the shell. */ if(errno==ENOENT) _exit(127); _exit(1); } /* I'm the parent */ close(to[0]); (*info)->tochild=fdopen(to[1],binary?"wb":"w"); if((*info)->tochild==NULL) { ret = gpg_error_from_syserror (); close(to[1]); goto fail; } close(from[1]); (*info)->fromchild=iobuf_fdopen(from[0],"r"); if((*info)->fromchild==NULL) { ret = gpg_error_from_syserror (); close(from[0]); goto fail; } /* fd iobufs are cached?! */ iobuf_ioctl((*info)->fromchild,3,1,NULL); return 0; } #endif /* !EXEC_TEMPFILE_ONLY */ if(DBG_EXTPROG) log_debug("using temp file `%s'\n",(*info)->tempfile_in); /* It's not fork/exec/pipe, so create a temp file */ if( is_secured_filename ((*info)->tempfile_in) ) { (*info)->tochild = NULL; errno = EPERM; } else (*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w"); if((*info)->tochild==NULL) { ret = gpg_error_from_syserror (); log_error(_("can't create `%s': %s\n"), (*info)->tempfile_in,strerror(errno)); goto fail; } ret=0; fail: if (ret) { xfree (*info); *info = NULL; } return ret; }
/**************** * Copy the option file skeleton for NAME to the given directory. * Returns true if the new option file has any option. */ static int copy_options_file (const char *destdir, const char *name) { const char *datadir = gnupg_datadir (); char *fname; FILE *src, *dst; int linefeeds=0; int c; mode_t oldmask; int esc = 0; int any_option = 0; if (opt.dry_run) return 0; fname = xstrconcat (datadir, DIRSEP_S, name, "-conf", SKELEXT, NULL); src = fopen (fname, "r"); if (src && is_secured_file (fileno (src))) { fclose (src); src = NULL; gpg_err_set_errno (EPERM); } if (!src) { log_info (_("can't open '%s': %s\n"), fname, strerror(errno)); xfree(fname); return 0; } xfree (fname); fname = xstrconcat (destdir, DIRSEP_S, name, EXTSEP_S, "conf", NULL); oldmask = umask (077); if (is_secured_filename (fname)) { dst = NULL; gpg_err_set_errno (EPERM); } else dst = fopen( fname, "w" ); umask (oldmask); if (!dst) { log_info (_("can't create '%s': %s\n"), fname, strerror(errno) ); fclose (src); xfree (fname); return 0; } while ((c = getc (src)) != EOF) { if (linefeeds < 3) { if (c == '\n') linefeeds++; } else { putc (c, dst); if (c== '\n') esc = 1; else if (esc == 1) { if (c == ' ' || c == '\t') ; else if (c == '#') esc = 2; else any_option = 1; } } } fclose (dst); fclose (src); log_info (_("new configuration file '%s' created\n"), fname); xfree (fname); return any_option; }
/* * Make an output filename for the inputfile INAME. * Returns an IOBUF and an errorcode * Mode 0 = use ".gpg" * 1 = use ".asc" * 2 = use ".sig" * 3 = use ".rev" * * If INP_FD is not -1 the function simply creates an IOBUF for that * file descriptor and ignore INAME and MODE. Note that INP_FD won't * be closed if the returned IOBUF is closed. With RESTRICTEDPERM a * file will be created with mode 700 if possible. */ int open_outfile (int inp_fd, const char *iname, int mode, int restrictedperm, iobuf_t *a) { int rc = 0; *a = NULL; if (inp_fd != -1) { char xname[64]; *a = iobuf_fdopen_nc (inp_fd, "wb"); if (!*a) { rc = gpg_error_from_syserror (); snprintf (xname, sizeof xname, "[fd %d]", inp_fd); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (rc)); } else if (opt.verbose) { snprintf (xname, sizeof xname, "[fd %d]", inp_fd); log_info (_("writing to '%s'\n"), xname); } } else if (iobuf_is_pipe_filename (iname) && !opt.outfile) { *a = iobuf_create (NULL, 0); if ( !*a ) { rc = gpg_error_from_syserror (); log_error (_("can't open '%s': %s\n"), "[stdout]", strerror(errno) ); } else if ( opt.verbose ) log_info (_("writing to stdout\n")); } else { char *buf = NULL; const char *name; if (opt.dry_run) name = NAME_OF_DEV_NULL; else if (opt.outfile) name = opt.outfile; else { #ifdef USE_ONLY_8DOT3 if (opt.mangle_dos_filenames) { /* It is quite common for DOS systems to have only one dot in a filename. If we have something like this, we simple replace the suffix except in cases where the suffix is larger than 3 characters and not the same as the new one. We don't map the filenames to 8.3 because this is a duty of the file system. */ char *dot; const char *newsfx; newsfx = (mode==1 ? ".asc" : mode==2 ? ".sig" : mode==3 ? ".rev" : ".gpg"); buf = xmalloc (strlen(iname)+4+1); strcpy (buf, iname); dot = strchr (buf, '.' ); if ( dot && dot > buf && dot[1] && strlen(dot) <= 4 && CMP_FILENAME (newsfx, dot) ) strcpy (dot, newsfx); else if (dot && !dot[1]) /* Do not duplicate a dot. */ strcpy (dot, newsfx+1); else strcat (buf, newsfx); } if (!buf) #endif /* USE_ONLY_8DOT3 */ { buf = xstrconcat (iname, (mode==1 ? EXTSEP_S "asc" : mode==2 ? EXTSEP_S "sig" : mode==3 ? EXTSEP_S "rev" : /* */ EXTSEP_S GPGEXT_GPG), NULL); } name = buf; } rc = 0; while ( !overwrite_filep (name) ) { char *tmp = ask_outfile_name (NULL, 0); if ( !tmp || !*tmp ) { xfree (tmp); rc = gpg_error (GPG_ERR_EEXIST); break; } xfree (buf); name = buf = tmp; } if ( !rc ) { if (is_secured_filename (name) ) { *a = NULL; gpg_err_set_errno (EPERM); } else *a = iobuf_create (name, restrictedperm); if (!*a) { rc = gpg_error_from_syserror (); log_error(_("can't create '%s': %s\n"), name, strerror(errno) ); } else if( opt.verbose ) log_info (_("writing to '%s'\n"), name ); } xfree(buf); } if (*a) iobuf_ioctl (*a, IOBUF_IOCTL_NO_CACHE, 1, NULL); return rc; }
/**************** * Copy the option file skeleton to the given directory. */ static void copy_options_file( const char *destdir ) { const char *datadir = gnupg_datadir (); char *fname; FILE *src, *dst; int linefeeds=0; int c; mode_t oldmask; int esc = 0; int any_option = 0; if( opt.dry_run ) return; fname = xmalloc( strlen(datadir) + strlen(destdir) + 15 ); strcpy(stpcpy(fname, datadir), DIRSEP_S "gpg-conf" SKELEXT ); src = fopen( fname, "r" ); if (src && is_secured_file (fileno (src))) { fclose (src); src = NULL; errno = EPERM; } if( !src ) { log_info (_("can't open `%s': %s\n"), fname, strerror(errno) ); xfree(fname); return; } strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" ); oldmask=umask(077); if ( is_secured_filename (fname) ) { dst = NULL; errno = EPERM; } else dst = fopen( fname, "w" ); umask(oldmask); if( !dst ) { log_info (_("can't create `%s': %s\n"), fname, strerror(errno) ); fclose( src ); xfree(fname); return; } while( (c=getc(src)) != EOF ) { if( linefeeds < 3 ) { if( c == '\n' ) linefeeds++; } else { putc( c, dst ); if (c== '\n') esc = 1; else if (esc == 1) { if (c == ' ' || c == '\t') ; else if (c == '#') esc = 2; else any_option = 1; } } } fclose( dst ); fclose( src ); log_info(_("new configuration file `%s' created\n"), fname ); if (any_option) log_info (_("WARNING: options in `%s'" " are not yet active during this run\n"), fname); xfree(fname); }
/**************** * Make an output filename for the inputfile INAME. * Returns an IOBUF and an errorcode * Mode 0 = use ".gpg" * 1 = use ".asc" * 2 = use ".sig" */ int open_outfile( const char *iname, int mode, IOBUF *a ) { int rc = 0; *a = NULL; if( iobuf_is_pipe_filename (iname) && !opt.outfile ) { *a = iobuf_create(NULL); if( !*a ) { rc = gpg_error_from_syserror (); log_error(_("can't open `%s': %s\n"), "[stdout]", strerror(errno) ); } else if( opt.verbose ) log_info(_("writing to stdout\n")); } else { char *buf = NULL; const char *name; if ( opt.dry_run ) { #ifdef HAVE_W32_SYSTEM name = "nul"; #else name = "/dev/null"; #endif } else if( opt.outfile ) name = opt.outfile; else { #ifdef USE_ONLY_8DOT3 if (opt.mangle_dos_filenames) { /* It is quite common DOS system to have only one dot in a * a filename So if we have something like this, we simple * replace the suffix execpt in cases where the suffix is * larger than 3 characters and not the same as. * We should really map the filenames to 8.3 but this tends to * be more complicated and is probaly a duty of the filesystem */ char *dot; const char *newsfx = mode==1 ? ".asc" : mode==2 ? ".sig" : ".gpg"; buf = xmalloc(strlen(iname)+4+1); strcpy(buf,iname); dot = strchr(buf, '.' ); if ( dot && dot > buf && dot[1] && strlen(dot) <= 4 && CMP_FILENAME(newsfx, dot) ) { strcpy(dot, newsfx ); } else if ( dot && !dot[1] ) /* don't duplicate a dot */ strcpy( dot, newsfx+1 ); else strcat ( buf, newsfx ); } if (!buf) #endif /* USE_ONLY_8DOT3 */ { buf = xmalloc(strlen(iname)+4+1); strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" : mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg"); } name = buf; } rc = 0; while( !overwrite_filep (name) ) { char *tmp = ask_outfile_name (NULL, 0); if ( !tmp || !*tmp ) { xfree (tmp); rc = gpg_error (GPG_ERR_EEXIST); break; } xfree (buf); name = buf = tmp; } if( !rc ) { if (is_secured_filename (name) ) { *a = NULL; errno = EPERM; } else *a = iobuf_create( name ); if( !*a ) { rc = gpg_error_from_syserror (); log_error(_("can't create `%s': %s\n"), name, strerror(errno) ); } else if( opt.verbose ) log_info(_("writing to `%s'\n"), name ); } xfree(buf); } if (*a) iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */ return rc; }
/* * Set the file name for the trustdb to NEW_DBNAME and if CREATE is * true create that file. If NEW_DBNAME is NULL a default name is * used, if the it does not contain a path component separator ('/') * the global GnuPG home directory is used. * * Returns: 0 on success or an error code. * * On the first call this function registers an atexit handler. * */ int tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) { char *fname, *p; struct stat statbuf; static int initialized = 0; int save_slash; if (!initialized) { atexit (cleanup); initialized = 1; } *r_nofile = 0; if (!new_dbname) { fname = make_filename (opt.homedir, "trustdb" EXTSEP_S GPGEXT_GPG, NULL); } else if (*new_dbname != DIRSEP_C ) { if (strchr (new_dbname, DIRSEP_C)) fname = make_filename (new_dbname, NULL); else fname = make_filename (opt.homedir, new_dbname, NULL); } else { fname = xstrdup (new_dbname); } xfree (db_name); db_name = fname; /* Quick check for (likely) case where there already is a * trustdb.gpg. This check is not required in theory, but it helps * in practice avoiding costly operations of preparing and taking * the lock. */ if (!stat (fname, &statbuf) && statbuf.st_size > 0) { /* 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) gpg_err_set_errno (ENOENT); else gpg_err_set_errno (EIO); #endif /*HAVE_W32CE_SYSTEM*/ if (errno != ENOENT) log_fatal ( _("can't access '%s': %s\n"), fname, 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); 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)); 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); } release_write_lock (); return 0; }