From 3864afa1d1478f7a76fde1ea160a7bc8f5d5b203 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 11 Dec 2010 14:17:46 -0500
Subject: [PATCH] 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.
---
 contrib/pg_upgrade/exec.c | 69 +++------------------------------------
 contrib/pg_upgrade/file.c |  4 +--
 2 files changed, 7 insertions(+), 66 deletions(-)

diff --git a/contrib/pg_upgrade/exec.c b/contrib/pg_upgrade/exec.c
index c0202adc23a..455d7ac45d6 100644
--- a/contrib/pg_upgrade/exec.c
+++ b/contrib/pg_upgrade/exec.c
@@ -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
diff --git a/contrib/pg_upgrade/file.c b/contrib/pg_upgrade/file.c
index 1b25a212c0b..e84110665fe 100644
--- a/contrib/pg_upgrade/file.c
+++ b/contrib/pg_upgrade/file.c
@@ -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)
 			{
-- 
GitLab