Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1a2aaeb

Browse files
author
Amit Kapila
committed
Fix changing the ownership of ALL TABLES IN SCHEMA publication.
Ensure that the new owner of ALL TABLES IN SCHEMA publication must be a superuser. The same is already ensured during CREATE PUBLICATION. Author: Vignesh C Reviewed-by: Nathan Bossart, Greg Nancarrow, Michael Paquier, Haiying Tang Discussion: https://postgr.es/m/CALDaNm0E5U-RqxFuFrkZrQeG7ae5trGa=xs=iRtPPHULtT4zOw@mail.gmail.com
1 parent a61bff2 commit 1a2aaeb

File tree

5 files changed

+68
-0
lines changed

5 files changed

+68
-0
lines changed

src/backend/catalog/pg_publication.c

+30
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,36 @@ is_publishable_relation(Relation rel)
193193
return is_publishable_class(RelationGetRelid(rel), rel->rd_rel);
194194
}
195195

196+
/*
197+
* Returns true if any schema is associated with the publication, false if no
198+
* schema is associated with the publication.
199+
*/
200+
bool
201+
is_schema_publication(Oid pubid)
202+
{
203+
Relation pubschsrel;
204+
ScanKeyData scankey;
205+
SysScanDesc scan;
206+
HeapTuple tup;
207+
bool result = false;
208+
209+
pubschsrel = table_open(PublicationNamespaceRelationId, AccessShareLock);
210+
ScanKeyInit(&scankey,
211+
Anum_pg_publication_namespace_pnpubid,
212+
BTEqualStrategyNumber, F_OIDEQ,
213+
ObjectIdGetDatum(pubid));
214+
215+
scan = systable_beginscan(pubschsrel,
216+
PublicationNamespacePnnspidPnpubidIndexId,
217+
true, NULL, 1, &scankey);
218+
tup = systable_getnext(scan);
219+
result = HeapTupleIsValid(tup);
220+
221+
systable_endscan(scan);
222+
table_close(pubschsrel, AccessShareLock);
223+
224+
return result;
225+
}
196226

197227
/*
198228
* SQL-callable variant of the above

src/backend/commands/publicationcmds.c

+7
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,13 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
11921192
errmsg("permission denied to change owner of publication \"%s\"",
11931193
NameStr(form->pubname)),
11941194
errhint("The owner of a FOR ALL TABLES publication must be a superuser.")));
1195+
1196+
if (!superuser_arg(newOwnerId) && is_schema_publication(form->oid))
1197+
ereport(ERROR,
1198+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1199+
errmsg("permission denied to change owner of publication \"%s\"",
1200+
NameStr(form->pubname)),
1201+
errhint("The owner of a FOR ALL TABLES IN SCHEMA publication must be a superuser.")));
11951202
}
11961203

11971204
form->pubowner = newOwnerId;

src/include/catalog/pg_publication.h

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ extern List *GetPubPartitionOptionRelations(List *result,
122122
Oid relid);
123123

124124
extern bool is_publishable_relation(Relation rel);
125+
extern bool is_schema_publication(Oid pubid);
125126
extern ObjectAddress publication_add_relation(Oid pubid, PublicationRelInfo *targetrel,
126127
bool if_not_exists);
127128
extern ObjectAddress publication_add_schema(Oid pubid, Oid schemaid,

src/test/regress/expected/publication.out

+15
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,21 @@ ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1; -- ok
373373
DROP PUBLICATION testpub2;
374374
DROP PUBLICATION testpub3;
375375
SET ROLE regress_publication_user;
376+
CREATE ROLE regress_publication_user3;
377+
GRANT regress_publication_user2 TO regress_publication_user3;
378+
SET client_min_messages = 'ERROR';
379+
CREATE PUBLICATION testpub4 FOR ALL TABLES IN SCHEMA pub_test;
380+
RESET client_min_messages;
381+
ALTER PUBLICATION testpub4 OWNER TO regress_publication_user3;
382+
SET ROLE regress_publication_user3;
383+
-- fail - new owner must be superuser
384+
ALTER PUBLICATION testpub4 owner to regress_publication_user2; -- fail
385+
ERROR: permission denied to change owner of publication "testpub4"
386+
HINT: The owner of a FOR ALL TABLES IN SCHEMA publication must be a superuser.
387+
ALTER PUBLICATION testpub4 owner to regress_publication_user; -- ok
388+
SET ROLE regress_publication_user;
389+
DROP PUBLICATION testpub4;
390+
DROP ROLE regress_publication_user3;
376391
REVOKE CREATE ON DATABASE regression FROM regress_publication_user2;
377392
DROP TABLE testpub_parted;
378393
DROP TABLE testpub_tbl1;

src/test/regress/sql/publication.sql

+15
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,21 @@ DROP PUBLICATION testpub2;
218218
DROP PUBLICATION testpub3;
219219

220220
SET ROLE regress_publication_user;
221+
CREATE ROLE regress_publication_user3;
222+
GRANT regress_publication_user2 TO regress_publication_user3;
223+
SET client_min_messages = 'ERROR';
224+
CREATE PUBLICATION testpub4 FOR ALL TABLES IN SCHEMA pub_test;
225+
RESET client_min_messages;
226+
ALTER PUBLICATION testpub4 OWNER TO regress_publication_user3;
227+
SET ROLE regress_publication_user3;
228+
-- fail - new owner must be superuser
229+
ALTER PUBLICATION testpub4 owner to regress_publication_user2; -- fail
230+
ALTER PUBLICATION testpub4 owner to regress_publication_user; -- ok
231+
232+
SET ROLE regress_publication_user;
233+
DROP PUBLICATION testpub4;
234+
DROP ROLE regress_publication_user3;
235+
221236
REVOKE CREATE ON DATABASE regression FROM regress_publication_user2;
222237

223238
DROP TABLE testpub_parted;

0 commit comments

Comments
 (0)