From 0955c6dfd070f44b8b4b0fad965b97144b304b68 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <dgustafsson@postgresql.org>
Date: Tue, 2 Nov 2021 11:38:52 +0100
Subject: [PATCH] Disallow conflicting authentication options in pg_restore

--use-set-session-authorization and --role cannot be used together
as they have conflicting uses. --role is intended for running the
restore from non-superuser roles in systems where superusers are
prohibited from logging in. --use-set-session-authorization however
requires the originally authenticated role to be superuser.

Backpatch to all supported branches.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/11496.1581634533@sss.pgh.pa.us
Backpath-through: 9.6
---
 doc/src/sgml/ref/pg_restore.sgml |  5 +++++
 src/bin/pg_dump/pg_restore.c     | 13 +++++++++++++
 src/bin/pg_dump/t/001_basic.pl   |  8 +++++++-
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
index 93ea937ac8..bfa7a4dfa6 100644
--- a/doc/src/sgml/ref/pg_restore.sgml
+++ b/doc/src/sgml/ref/pg_restore.sgml
@@ -810,6 +810,11 @@ PostgreSQL documentation
         logging in directly as a superuser, and use of this option allows
         restores to be performed without violating the policy.
        </para>
+       <para>
+        This option cannot be used together with
+        <option>--use-set-session-authorization</option> since that option
+        requires the originally authenticated user to be a superuser.
+       </para>
       </listitem>
      </varlistentry>
 
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index 64aaa80eee..a5400fa90a 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -338,6 +338,19 @@ main(int argc, char **argv)
 		exit_nicely(1);
 	}
 
+	/*
+	 * The first SET SESSION AUTHORIZATION command will override the SET ROLE
+	 * command, making these options incompatible. SET SESSION AUTHORIZATION
+	 * also insists on the originally authenticated user be a superuser, which
+	 * goes against the usecase for --role which is to start the restore from
+	 * a non-superuser role.
+	 */
+	if (use_setsessauth && opts->use_role)
+	{
+		pg_log_error("options --role and --use-set-session-authorization cannot be used together");
+		exit_nicely(1);
+	}
+
 	/*
 	 * -C is not compatible with -1, because we can't create a database inside
 	 * a transaction block.
diff --git a/src/bin/pg_dump/t/001_basic.pl b/src/bin/pg_dump/t/001_basic.pl
index 863f4da3d8..8a91ea4fe4 100644
--- a/src/bin/pg_dump/t/001_basic.pl
+++ b/src/bin/pg_dump/t/001_basic.pl
@@ -7,7 +7,7 @@ use warnings;
 use Config;
 use PostgreSQL::Test::Cluster;
 use PostgreSQL::Test::Utils;
-use Test::More tests => 82;
+use Test::More tests => 84;
 
 my $tempdir       = PostgreSQL::Test::Utils::tempdir;
 
@@ -188,3 +188,9 @@ command_fails_like(
 	qr/\Qpg_dumpall: error: option --exclude-database cannot be used together with -g\/--globals-only\E/,
 	'pg_dumpall: option --exclude-database cannot be used together with -g/--globals-only'
 );
+
+command_fails_like(
+	[ 'pg_restore', '-d foo', '--role=foo', '--use-set-session-authorization' ],
+	qr/\Qpg_restore: error: options --role and --use-set-session-authorization cannot be used together\E/,
+	'pg_restore: options --role and --use-set-session-authorization cannot be used together'
+);
-- 
2.24.3 (Apple Git-128)

