Clean up some copied-and-pasted code in pg_upgrade.

1. Don't reimplement S_ISDIR() and S_ISREG() badly.
2. Don't reimplement access() badly.

This code appears to have been copied from ancient versions of the
corresponding backend routines, and not patched to incorporate subsequent
fixes (see my commits of 2008-03-31 and 2010-01-14 respectively).
It might be a good idea to change it to just *call* those routines,
but for now I'll just transpose these fixes over.
This commit is contained in:
Tom Lane 2010-12-11 14:17:46 -05:00
parent 1319002e2e
commit 3864afa1d1
2 changed files with 7 additions and 66 deletions

View File

@ -10,7 +10,7 @@
#include "pg_upgrade.h"
#include <fcntl.h>
#include <grp.h>
#include <unistd.h>
static void check_data_dir(const char *pg_data);
@ -206,17 +206,9 @@ validate_exec(const char *path)
{
struct stat buf;
#ifndef WIN32
uid_t euid;
struct group *gp;
struct passwd *pwp;
int in_grp = 0;
#else
char path_exe[MAXPGPATH + sizeof(EXE_EXT) - 1];
#endif
#ifdef WIN32
/* Win32 requires a .exe suffix for stat() */
char path_exe[MAXPGPATH + sizeof(EXE_EXT) - 1];
if (strlen(path) >= strlen(EXE_EXT) &&
pg_strcasecmp(path + strlen(path) - strlen(EXE_EXT), EXE_EXT) != 0)
@ -233,68 +225,17 @@ validate_exec(const char *path)
if (stat(path, &buf) < 0)
return getErrorText(errno);
if ((buf.st_mode & S_IFMT) != S_IFREG)
if (!S_ISREG(buf.st_mode))
return "not an executable file";
/*
* Ensure that we are using an authorized executable.
*/
/*
* Ensure that the file is both executable and readable (required for
* dynamic loading).
*/
#ifndef WIN32
euid = geteuid();
/* If owned by us, just check owner bits */
if (euid == buf.st_uid)
{
if ((buf.st_mode & S_IRUSR) == 0)
return "can't read file (permission denied)";
if ((buf.st_mode & S_IXUSR) == 0)
return "can't execute (permission denied)";
return NULL;
}
/* OK, check group bits */
pwp = getpwuid(euid); /* not thread-safe */
if (pwp)
{
if (pwp->pw_gid == buf.st_gid) /* my primary group? */
++in_grp;
else if (pwp->pw_name &&
(gp = getgrgid(buf.st_gid)) != NULL &&
/* not thread-safe */ gp->gr_mem != NULL)
{
/* try list of member groups */
int i;
for (i = 0; gp->gr_mem[i]; ++i)
{
if (!strcmp(gp->gr_mem[i], pwp->pw_name))
{
++in_grp;
break;
}
}
}
if (in_grp)
{
if ((buf.st_mode & S_IRGRP) == 0)
return "can't read file (permission denied)";
if ((buf.st_mode & S_IXGRP) == 0)
return "can't execute (permission denied)";
return NULL;
}
}
/* Check "other" bits */
if ((buf.st_mode & S_IROTH) == 0)
if (access(path, R_OK) != 0)
return "can't read file (permission denied)";
if ((buf.st_mode & S_IXOTH) == 0)
if (access(path, X_OK) != 0)
return "can't execute (permission denied)";
return NULL;
#else

View File

@ -440,13 +440,13 @@ copy_dir(const char *src, const char *dst, bool force)
return -1;
}
if (fst.st_mode & S_IFDIR)
if (S_ISDIR(fst.st_mode))
{
/* recurse to handle subdirectories */
if (force)
copy_dir(src_file, dest_file, true);
}
else if (fst.st_mode & S_IFREG)
else if (S_ISREG(fst.st_mode))
{
if ((copy_file(src_file, dest_file, 1)) == -1)
{