Run pg_upgrade and pg_resetxlog with restricted token on Windows
authorAndrew Dunstan <andrew@dunslane.net>
Mon, 30 Mar 2015 21:07:52 +0000 (17:07 -0400)
committerAndrew Dunstan <andrew@dunslane.net>
Mon, 30 Mar 2015 21:07:52 +0000 (17:07 -0400)
As with initdb these programs need to run with a restricted token, and
if they don't pg_upgrade will fail when run as a user with Adminstrator
privileges.

Backpatch to all live branches. On the development branch the code is
reorganized so that the restricted token code is now in a single
location. On the stable bramches a less invasive change is made by
simply copying the relevant code to pg_upgrade.c and pg_resetxlog.c.

Patches and bug report from Muhammad Asif Naeem, reviewed by Michael
Paquier, slightly edited by me.

contrib/pg_upgrade/pg_upgrade.c
src/bin/initdb/initdb.c
src/bin/pg_resetxlog/pg_resetxlog.c
src/common/Makefile
src/common/restricted_token.c [new file with mode: 0644]
src/include/common/restricted_token.h [new file with mode: 0644]
src/test/regress/pg_regress.c
src/tools/msvc/Mkvcbuild.pm

index ed7de809c8ee2c5abc3b17614ba39b7c01afcb8b..eb48da779f9ed244267a74130ad3b166304883d3 100644 (file)
@@ -37,6 +37,7 @@
 #include "postgres_fe.h"
 
 #include "pg_upgrade.h"
+#include "common/restricted_token.h"
 
 #ifdef HAVE_LANGINFO_H
 #include <langinfo.h>
@@ -75,6 +76,8 @@ main(int argc, char **argv)
 
        parseCommandLine(argc, argv);
 
+       get_restricted_token(os_info.progname);
+
        adjust_data_dir(&old_cluster);
        adjust_data_dir(&new_cluster);
 
index 18614e7a678fc523ca143d98616f704b23d81329..b9d6092c2c018243e05be2b2948f70d40b054575 100644 (file)
@@ -61,6 +61,7 @@
 #endif
 
 #include "catalog/catalog.h"
+#include "common/restricted_token.h"
 #include "common/username.h"
 #include "mb/pg_wchar.h"
 #include "getaddrinfo.h"
@@ -178,9 +179,6 @@ static char *authwarning = NULL;
 static const char *boot_options = "-F";
 static const char *backend_options = "--single -F -O -c search_path=pg_catalog -c exit_on_error=true";
 
-#ifdef WIN32
-char      *restrict_env;
-#endif
 static const char *subdirs[] = {
        "global",
        "pg_xlog",
@@ -260,7 +258,6 @@ static void check_locale_name(int category, const char *locale,
 static bool check_locale_encoding(const char *locale, int encoding);
 static void setlocales(void);
 static void usage(const char *progname);
-void           get_restricted_token(void);
 void           setup_pgdata(void);
 void           setup_bin_paths(const char *argv0);
 void           setup_data_file_paths(void);
@@ -272,12 +269,6 @@ void               create_xlog_symlink(void);
 void           warn_on_mount_point(int error);
 void           initialize_data_directory(void);
 
-
-#ifdef WIN32
-static int     CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo);
-#endif
-
-
 /*
  * macros for running pipes to postgres
  */
@@ -2754,116 +2745,6 @@ setlocales(void)
 #endif
 }
 
-#ifdef WIN32
-typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
-
-/* Windows API define missing from some versions of MingW headers */
-#ifndef  DISABLE_MAX_PRIVILEGE
-#define DISABLE_MAX_PRIVILEGE  0x1
-#endif
-
-/*
- * Create a restricted token and execute the specified process with it.
- *
- * Returns 0 on failure, non-zero on success, same as CreateProcess().
- *
- * On NT4, or any other system not containing the required functions, will
- * NOT execute anything.
- */
-static int
-CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo)
-{
-       BOOL            b;
-       STARTUPINFO si;
-       HANDLE          origToken;
-       HANDLE          restrictedToken;
-       SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
-       SID_AND_ATTRIBUTES dropSids[2];
-       __CreateRestrictedToken _CreateRestrictedToken = NULL;
-       HANDLE          Advapi32Handle;
-
-       ZeroMemory(&si, sizeof(si));
-       si.cb = sizeof(si);
-
-       Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
-       if (Advapi32Handle != NULL)
-       {
-               _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
-       }
-
-       if (_CreateRestrictedToken == NULL)
-       {
-               fprintf(stderr, _("%s: WARNING: cannot create restricted tokens on this platform\n"), progname);
-               if (Advapi32Handle != NULL)
-                       FreeLibrary(Advapi32Handle);
-               return 0;
-       }
-
-       /* Open the current token to use as a base for the restricted one */
-       if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
-       {
-               fprintf(stderr, _("%s: could not open process token: error code %lu\n"), progname, GetLastError());
-               return 0;
-       }
-
-       /* Allocate list of SIDs to remove */
-       ZeroMemory(&dropSids, sizeof(dropSids));
-       if (!AllocateAndInitializeSid(&NtAuthority, 2,
-                SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
-                                                                 0, &dropSids[0].Sid) ||
-               !AllocateAndInitializeSid(&NtAuthority, 2,
-       SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
-                                                                 0, &dropSids[1].Sid))
-       {
-               fprintf(stderr, _("%s: could not allocate SIDs: error code %lu\n"),
-                               progname, GetLastError());
-               return 0;
-       }
-
-       b = _CreateRestrictedToken(origToken,
-                                                          DISABLE_MAX_PRIVILEGE,
-                                                          sizeof(dropSids) / sizeof(dropSids[0]),
-                                                          dropSids,
-                                                          0, NULL,
-                                                          0, NULL,
-                                                          &restrictedToken);
-
-       FreeSid(dropSids[1].Sid);
-       FreeSid(dropSids[0].Sid);
-       CloseHandle(origToken);
-       FreeLibrary(Advapi32Handle);
-
-       if (!b)
-       {
-               fprintf(stderr, _("%s: could not create restricted token: error code %lu\n"), progname, GetLastError());
-               return 0;
-       }
-
-#ifndef __CYGWIN__
-       AddUserToTokenDacl(restrictedToken);
-#endif
-
-       if (!CreateProcessAsUser(restrictedToken,
-                                                        NULL,
-                                                        cmd,
-                                                        NULL,
-                                                        NULL,
-                                                        TRUE,
-                                                        CREATE_SUSPENDED,
-                                                        NULL,
-                                                        NULL,
-                                                        &si,
-                                                        processInfo))
-
-       {
-               fprintf(stderr, _("%s: could not start process for command \"%s\": error code %lu\n"), progname, cmd, GetLastError());
-               return 0;
-       }
-
-       return ResumeThread(processInfo->hThread);
-}
-#endif
-
 /*
  * print help text
  */
@@ -2957,53 +2838,6 @@ check_need_password(const char *authmethodlocal, const char *authmethodhost)
        }
 }
 
-void
-get_restricted_token(void)
-{
-#ifdef WIN32
-
-       /*
-        * Before we execute another program, make sure that we are running with a
-        * restricted token. If not, re-execute ourselves with one.
-        */
-
-       if ((restrict_env = getenv("PG_RESTRICT_EXEC")) == NULL
-               || strcmp(restrict_env, "1") != 0)
-       {
-               PROCESS_INFORMATION pi;
-               char       *cmdline;
-
-               ZeroMemory(&pi, sizeof(pi));
-
-               cmdline = pg_strdup(GetCommandLine());
-
-               putenv("PG_RESTRICT_EXEC=1");
-
-               if (!CreateRestrictedProcess(cmdline, &pi))
-               {
-                       fprintf(stderr, _("%s: could not re-execute with restricted token: error code %lu\n"), progname, GetLastError());
-               }
-               else
-               {
-                       /*
-                        * Successfully re-execed. Now wait for child process to capture
-                        * exitcode.
-                        */
-                       DWORD           x;
-
-                       CloseHandle(pi.hThread);
-                       WaitForSingleObject(pi.hProcess, INFINITE);
-
-                       if (!GetExitCodeProcess(pi.hProcess, &x))
-                       {
-                               fprintf(stderr, _("%s: could not get exit code from subprocess: error code %lu\n"), progname, GetLastError());
-                               exit(1);
-                       }
-                       exit(x);
-               }
-       }
-#endif
-}
 
 void
 setup_pgdata(void)
@@ -3759,7 +3593,7 @@ main(int argc, char *argv[])
 
        check_need_password(authmethodlocal, authmethodhost);
 
-       get_restricted_token();
+       get_restricted_token(progname);
 
        setup_pgdata();
 
index a16089f3e8fecc4c02cc921a0cd5786205293ac3..3361111c38077c2cdc8ec389323c4946e31ed47f 100644 (file)
@@ -53,6 +53,7 @@
 #include "catalog/catversion.h"
 #include "catalog/pg_control.h"
 #include "common/fe_memutils.h"
+#include "common/restricted_token.h"
 #include "storage/large_object.h"
 #include "pg_getopt.h"
 
@@ -310,6 +311,8 @@ main(int argc, char *argv[])
        }
 #endif
 
+       get_restricted_token(progname);
+
        if (chdir(DataDir) < 0)
        {
                fprintf(stderr, _("%s: could not change directory to \"%s\": %s\n"),
index c71415ef17d86fada36bcc0d51d56c18e758bdb7..c2e456d89a25d03e579df5315b541340ce9c9eeb 100644 (file)
@@ -26,7 +26,7 @@ LIBS += $(PTHREAD_LIBS)
 OBJS_COMMON = exec.o pg_crc.o pg_lzcompress.o pgfnames.o psprintf.o relpath.o \
        rmtree.o string.o username.o wait_error.o
 
-OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o
+OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o restricted_token.o
 
 OBJS_SRV = $(OBJS_COMMON:%.o=%_srv.o)
 
diff --git a/src/common/restricted_token.c b/src/common/restricted_token.c
new file mode 100644 (file)
index 0000000..a8213c0
--- /dev/null
@@ -0,0 +1,193 @@
+/*-------------------------------------------------------------------------
+ *
+ * restricted_token.c
+ *             helper routine to ensure restricted token on Windows
+ *
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *       src/common/restricted_token.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef FRONTEND
+#error "This file is not expected to be compiled for backend code"
+#endif
+
+#include "postgres_fe.h"
+
+#include "common/restricted_token.h"
+
+#ifdef WIN32
+
+/* internal vars */
+char   *restrict_env;
+
+typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
+
+/* Windows API define missing from some versions of MingW headers */
+#ifndef  DISABLE_MAX_PRIVILEGE
+#define DISABLE_MAX_PRIVILEGE  0x1
+#endif
+
+/*
+ * Create a restricted token and execute the specified process with it.
+ *
+ * Returns restricted token on success and 0 on failure.
+ *
+ * On NT4, or any other system not containing the required functions, will
+ * NOT execute anything.
+ */
+HANDLE
+CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char *progname)
+{
+       BOOL            b;
+       STARTUPINFO si;
+       HANDLE          origToken;
+       HANDLE          restrictedToken;
+       SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+       SID_AND_ATTRIBUTES dropSids[2];
+       __CreateRestrictedToken _CreateRestrictedToken = NULL;
+       HANDLE          Advapi32Handle;
+
+       ZeroMemory(&si, sizeof(si));
+       si.cb = sizeof(si);
+
+       Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
+       if (Advapi32Handle != NULL)
+       {
+               _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
+       }
+
+       if (_CreateRestrictedToken == NULL)
+       {
+               fprintf(stderr, _("%s: WARNING: cannot create restricted tokens on this platform\n"), progname);
+               if (Advapi32Handle != NULL)
+                       FreeLibrary(Advapi32Handle);
+               return 0;
+       }
+
+       /* Open the current token to use as a base for the restricted one */
+       if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
+       {
+               fprintf(stderr, _("%s: could not open process token: error code %lu\n"), progname, GetLastError());
+               return 0;
+       }
+
+       /* Allocate list of SIDs to remove */
+       ZeroMemory(&dropSids, sizeof(dropSids));
+       if (!AllocateAndInitializeSid(&NtAuthority, 2,
+                SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
+                                                                 0, &dropSids[0].Sid) ||
+               !AllocateAndInitializeSid(&NtAuthority, 2,
+       SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
+                                                                 0, &dropSids[1].Sid))
+       {
+               fprintf(stderr, _("%s: could not allocate SIDs: error code %lu\n"),
+                               progname, GetLastError());
+               return 0;
+       }
+
+       b = _CreateRestrictedToken(origToken,
+                                                          DISABLE_MAX_PRIVILEGE,
+                                                          sizeof(dropSids) / sizeof(dropSids[0]),
+                                                          dropSids,
+                                                          0, NULL,
+                                                          0, NULL,
+                                                          &restrictedToken);
+
+       FreeSid(dropSids[1].Sid);
+       FreeSid(dropSids[0].Sid);
+       CloseHandle(origToken);
+       FreeLibrary(Advapi32Handle);
+
+       if (!b)
+       {
+               fprintf(stderr, _("%s: could not create restricted token: error code %lu\n"),
+                               progname, GetLastError());
+               return 0;
+       }
+
+#ifndef __CYGWIN__
+       AddUserToTokenDacl(restrictedToken);
+#endif
+
+       if (!CreateProcessAsUser(restrictedToken,
+                                                        NULL,
+                                                        cmd,
+                                                        NULL,
+                                                        NULL,
+                                                        TRUE,
+                                                        CREATE_SUSPENDED,
+                                                        NULL,
+                                                        NULL,
+                                                        &si,
+                                                        processInfo))
+
+       {
+               fprintf(stderr, _("%s: could not start process for command \"%s\": error code %lu\n"), progname, cmd, GetLastError());
+               return 0;
+       }
+
+       ResumeThread(processInfo->hThread);
+       return restrictedToken;
+}
+#endif
+
+/*
+ * On Windows make sure that we are running with a restricted token,
+ * On other platforms do nothing.
+ */
+void
+get_restricted_token(const char *progname)
+{
+#ifdef WIN32
+       HANDLE          restrictedToken;
+
+       /*
+        * Before we execute another program, make sure that we are running with a
+        * restricted token. If not, re-execute ourselves with one.
+        */
+
+       if ((restrict_env = getenv("PG_RESTRICT_EXEC")) == NULL
+               || strcmp(restrict_env, "1") != 0)
+       {
+               PROCESS_INFORMATION pi;
+               char       *cmdline;
+
+               ZeroMemory(&pi, sizeof(pi));
+
+               cmdline = pg_strdup(GetCommandLine());
+
+               putenv("PG_RESTRICT_EXEC=1");
+
+               if ((restrictedToken = CreateRestrictedProcess(cmdline, &pi, progname)) == 0)
+               {
+                       fprintf(stderr, _("%s: could not re-execute with restricted token: error code %lu\n"), progname, GetLastError());
+               }
+               else
+               {
+                       /*
+                        * Successfully re-execed. Now wait for child process to capture
+                        * exitcode.
+                        */
+                       DWORD           x;
+
+                       CloseHandle(restrictedToken);
+                       CloseHandle(pi.hThread);
+                       WaitForSingleObject(pi.hProcess, INFINITE);
+
+                       if (!GetExitCodeProcess(pi.hProcess, &x))
+                       {
+                               fprintf(stderr, _("%s: could not get exit code from subprocess: error code %lu\n"), progname, GetLastError());
+                               exit(1);
+                       }
+                       exit(x);
+               }
+       }
+#endif
+}
diff --git a/src/include/common/restricted_token.h b/src/include/common/restricted_token.h
new file mode 100644 (file)
index 0000000..e243744
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *     restricted_token.h
+ *             helper routine to ensure restricted token on Windows
+ *
+ *  Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ *  Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *     src/include/common/restricted_token.h
+ */
+#ifndef COMMON_RESTRICTED_TOKEN_H
+#define COMMON_RESTRICTED_TOKEN_H
+
+/*
+ * On Windows make sure that we are running with a restricted token,
+ * On other platforms do nothing.
+ */
+void   get_restricted_token(const char *progname);
+
+#ifdef WIN32
+/* Create a restricted token and execute the specified process with it. */
+HANDLE CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char *progname);
+#endif
+
+#endif   /* COMMON_RESTRICTED_TOKEN_H */
index 3de479023ad139a65a2ff33063970715a4b69814..098acf68762869970e3d64326360e2cfc0fada00 100644 (file)
@@ -29,6 +29,7 @@
 #include <sys/resource.h>
 #endif
 
+#include "common/restricted_token.h"
 #include "common/username.h"
 #include "getopt_long.h"
 #include "libpq/pqcomm.h"              /* needed for UNIXSOCK_PATH() */
@@ -135,15 +136,6 @@ static void header(const char *fmt,...) pg_attribute_printf(1, 2);
 static void status(const char *fmt,...) pg_attribute_printf(1, 2);
 static void psql_command(const char *database, const char *query,...) pg_attribute_printf(2, 3);
 
-#ifdef WIN32
-typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
-
-/* Windows API define missing from some versions of MingW headers */
-#ifndef  DISABLE_MAX_PRIVILEGE
-#define DISABLE_MAX_PRIVILEGE  0x1
-#endif
-#endif
-
 /*
  * allow core files if possible.
  */
@@ -1226,100 +1218,17 @@ spawn_process(const char *cmdline)
        /* in parent */
        return pid;
 #else
-       char       *cmdline2;
-       BOOL            b;
-       STARTUPINFO si;
-       PROCESS_INFORMATION pi;
-       HANDLE          origToken;
-       HANDLE          restrictedToken;
-       SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
-       SID_AND_ATTRIBUTES dropSids[2];
-       __CreateRestrictedToken _CreateRestrictedToken = NULL;
-       HANDLE          Advapi32Handle;
-
-       ZeroMemory(&si, sizeof(si));
-       si.cb = sizeof(si);
-
-       Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
-       if (Advapi32Handle != NULL)
-       {
-               _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
-       }
-
-       if (_CreateRestrictedToken == NULL)
-       {
-               if (Advapi32Handle != NULL)
-                       FreeLibrary(Advapi32Handle);
-               fprintf(stderr, _("%s: cannot create restricted tokens on this platform\n"),
-                               progname);
-               exit(2);
-       }
-
-       /* Open the current token to use as base for the restricted one */
-       if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
-       {
-               fprintf(stderr, _("could not open process token: error code %lu\n"),
-                               GetLastError());
-               exit(2);
-       }
-
-       /* Allocate list of SIDs to remove */
-       ZeroMemory(&dropSids, sizeof(dropSids));
-       if (!AllocateAndInitializeSid(&NtAuthority, 2,
-                                                                 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &dropSids[0].Sid) ||
-               !AllocateAndInitializeSid(&NtAuthority, 2,
-                                                                 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, &dropSids[1].Sid))
-       {
-               fprintf(stderr, _("could not allocate SIDs: error code %lu\n"), GetLastError());
-               exit(2);
-       }
-
-       b = _CreateRestrictedToken(origToken,
-                                                          DISABLE_MAX_PRIVILEGE,
-                                                          sizeof(dropSids) / sizeof(dropSids[0]),
-                                                          dropSids,
-                                                          0, NULL,
-                                                          0, NULL,
-                                                          &restrictedToken);
-
-       FreeSid(dropSids[1].Sid);
-       FreeSid(dropSids[0].Sid);
-       CloseHandle(origToken);
-       FreeLibrary(Advapi32Handle);
-
-       if (!b)
-       {
-               fprintf(stderr, _("could not create restricted token: error code %lu\n"),
-                               GetLastError());
-               exit(2);
-       }
+       PROCESS_INFORMATION     pi;
+       char    *cmdline2;
+       HANDLE  restrictedToken;
 
+       memset(&pi, 0, sizeof(pi));
        cmdline2 = psprintf("cmd /c \"%s\"", cmdline);
 
-#ifndef __CYGWIN__
-       AddUserToTokenDacl(restrictedToken);
-#endif
-
-       if (!CreateProcessAsUser(restrictedToken,
-                                                        NULL,
-                                                        cmdline2,
-                                                        NULL,
-                                                        NULL,
-                                                        TRUE,
-                                                        CREATE_SUSPENDED,
-                                                        NULL,
-                                                        NULL,
-                                                        &si,
-                                                        &pi))
-       {
-               fprintf(stderr, _("could not start process for \"%s\": error code %lu\n"),
-                               cmdline2, GetLastError());
+       if((restrictedToken =
+               CreateRestrictedProcess(cmdline2, &pi, progname)) == 0)
                exit(2);
-       }
-
-       free(cmdline2);
 
-       ResumeThread(pi.hThread);
        CloseHandle(pi.hThread);
        return pi.hProcess;
 #endif
index 0ca786c1df95553a680933e0794f62a03f272479..7f319dff67de08cbedb84491dc1cd1b7eff685a1 100644 (file)
@@ -95,7 +95,8 @@ sub mkvcbuild
          exec.c pg_crc.c pg_lzcompress.c pgfnames.c psprintf.c relpath.c rmtree.c
          string.c username.c wait_error.c);
 
-       our @pgcommonfrontendfiles = (@pgcommonallfiles, qw(fe_memutils.c));
+       our @pgcommonfrontendfiles = (@pgcommonallfiles, qw(fe_memutils.c
+         restricted_token.c));
 
        our @pgcommonbkndfiles = @pgcommonallfiles;