Refine rules for altering publication owner
authorPeter Eisentraut <peter_e@gmx.net>
Mon, 13 Feb 2017 13:57:45 +0000 (08:57 -0500)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 22 Mar 2017 15:19:30 +0000 (11:19 -0400)
Previously, the new owner had to be a superuser.  The new rules are more
refined similar to other objects.

Reviewed-by: Petr Jelinek <petr.jelinek@2ndquadrant.com>
doc/src/sgml/ref/alter_publication.sgml
src/backend/commands/publicationcmds.c
src/test/regress/expected/publication.out
src/test/regress/sql/publication.sql

index 47d83b80be5a3ccf37b73149385d98f32051ca52..776661bbeb3e48506b46636565687da45c20606a 100644 (file)
@@ -48,8 +48,11 @@ ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> DROP TABLE <
   </para>
 
   <para>
-   To alter the owner, you must also be a direct or indirect member of the
-   new owning role. The new owner has to be a superuser
+   To alter the owner, you must also be a direct or indirect member of the new
+   owning role. The new owner must have <literal>CREATE</literal> privilege on
+   the database.  Also, the new owner of a <literal>FOR ALL TABLES</literal>
+   publication must be a superuser.  However, a superuser can change the
+   ownership of a publication while circumventing these restrictions.
   </para>
 
   <para>
index 04f83e0a2ea7ad87e1d45111ca8092c9deb22a89..d69e39dc5b4b96524709bd044dc6e7f1aef11643 100644 (file)
@@ -670,17 +670,31 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
    if (form->pubowner == newOwnerId)
        return;
 
-   if (!pg_publication_ownercheck(HeapTupleGetOid(tup), GetUserId()))
-       aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PUBLICATION,
-                      NameStr(form->pubname));
+   if (!superuser())
+   {
+       AclResult   aclresult;
 
-   /* New owner must be a superuser */
-   if (!superuser_arg(newOwnerId))
-       ereport(ERROR,
-               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-                errmsg("permission denied to change owner of publication \"%s\"",
-                       NameStr(form->pubname)),
-                errhint("The owner of a publication must be a superuser.")));
+       /* Must be owner */
+       if (!pg_publication_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+           aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PUBLICATION,
+                          NameStr(form->pubname));
+
+       /* Must be able to become new owner */
+       check_is_member_of_role(GetUserId(), newOwnerId);
+
+       /* New owner must have CREATE privilege on database */
+       aclresult = pg_database_aclcheck(MyDatabaseId, newOwnerId, ACL_CREATE);
+       if (aclresult != ACLCHECK_OK)
+           aclcheck_error(aclresult, ACL_KIND_DATABASE,
+                          get_database_name(MyDatabaseId));
+
+       if (form->puballtables && !superuser_arg(newOwnerId))
+           ereport(ERROR,
+                   (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                    errmsg("permission denied to change owner of publication \"%s\"",
+                           NameStr(form->pubname)),
+                    errhint("The owner of a FOR ALL TABLES publication must be a superuser.")));
+   }
 
    form->pubowner = newOwnerId;
    CatalogTupleUpdate(rel, &tup->t_self, tup);
index 7c4834b213c05363614d0ff9af116b3e6d850750..5a7c0edf7d5da3d8c86c7f7637244317dd6ad940 100644 (file)
@@ -182,6 +182,14 @@ ALTER PUBLICATION testpub_default RENAME TO testpub_foo;
 
 -- rename back to keep the rest simple
 ALTER PUBLICATION testpub_foo RENAME TO testpub_default;
+ALTER PUBLICATION testpub_default OWNER TO regress_publication_user2;
+\dRp testpub_default
+                           List of publications
+      Name       |           Owner           | Inserts | Updates | Deletes 
+-----------------+---------------------------+---------+---------+---------
+ testpub_default | regress_publication_user2 | t       | t       | t
+(1 row)
+
 DROP PUBLICATION testpub_default;
 DROP PUBLICATION testpib_ins_trunct;
 DROP PUBLICATION testpub_fortbl;
index 46d275acc5988da313413050a373c00de9fa04e4..cff9931a77f56dff789c02876bf2e41a803e8094 100644 (file)
@@ -108,6 +108,10 @@ ALTER PUBLICATION testpub_default RENAME TO testpub_foo;
 -- rename back to keep the rest simple
 ALTER PUBLICATION testpub_foo RENAME TO testpub_default;
 
+ALTER PUBLICATION testpub_default OWNER TO regress_publication_user2;
+
+\dRp testpub_default
+
 DROP PUBLICATION testpub_default;
 DROP PUBLICATION testpib_ins_trunct;
 DROP PUBLICATION testpub_fortbl;