diff options
Diffstat (limited to 'g10/misc.c')
-rw-r--r-- | g10/misc.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/g10/misc.c b/g10/misc.c index 9240f12e7..acbd78d88 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -339,35 +339,53 @@ openpgp_md_test_algo( int algo ) } int -check_permissions(const char *path,int checkonly) +check_permissions(const char *path,int extension,int checkonly) { #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM) - + char *tmppath; struct stat statbuf; + int ret=1; int isdir=0; if(opt.no_perm_warn) return 0; + if(extension && path[0]!=DIRSEP_C) + { + if(strchr(path,DIRSEP_C)) + tmppath=make_filename(path,NULL); + else + tmppath=make_filename(GNUPG_LIBDIR,path,NULL); + } + else + tmppath=m_strdup(path); + /* It's okay if the file doesn't exist */ - if(stat(path,&statbuf)!=0) - return 0; + if(stat(tmppath,&statbuf)!=0) + { + ret=0; + goto end; + } isdir=S_ISDIR(statbuf.st_mode); - /* The user doesn't own the file */ - if(statbuf.st_uid != getuid()) + /* Per-user files must be owned by the user. Extensions must be + owned by the user or root. */ + if((!extension && statbuf.st_uid != getuid()) || + (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid())) { if(!checkonly) log_info(_("Warning: unsafe ownership on %s \"%s\"\n"), - isdir?"directory":"file",path); - return 1; + isdir?"directory":extension?"extension":"file",path); + goto end; } /* This works for both directories and files - basically, we don't care what the owner permissions are, so long as the group and - other permissions are 0. */ - if((statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0) + other permissions are 0 for per-user files, and non-writable for + extensions. */ + if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) || + (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0)) { char *dir; @@ -377,22 +395,30 @@ check_permissions(const char *path,int checkonly) directory /, but for the sake of sanity, I'm stopping at one level down. */ - dir=make_dirname(path); + dir=make_dirname(tmppath); if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() && S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0) { m_free(dir); - return 0; + ret=0; + goto end; } m_free(dir); if(!checkonly) log_info(_("Warning: unsafe permissions on %s \"%s\"\n"), - isdir?"directory":"file",path); - return 1; + isdir?"directory":extension?"extension":"file",path); + goto end; } + ret=0; + + end: + m_free(tmppath); + + return ret; + #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */ return 0; |