]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Allow users with BYPASSRLS to alter their own passwords.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 3 Nov 2020 20:41:32 +0000 (15:41 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 3 Nov 2020 20:41:32 +0000 (15:41 -0500)
The intention in commit 491c029db was to require superuserness to
change the BYPASSRLS property, but the actual effect of the coding
in AlterRole() was to require superuserness to change anything at all
about a BYPASSRLS role.  Other properties of a BYPASSRLS role should
be changeable under the same rules as for a normal role, though.

Fix that, and also take care of some documentation omissions related
to BYPASSRLS and REPLICATION role properties.

Tom Lane and Stephen Frost, per bug report from Wolfgang Walther.
Back-patch to all supported branches.

Discussion: https://postgr.es/m/a5548a9f-89ee-3167-129d-162b5985fcf8@technowledgy.de

doc/src/sgml/ref/alter_role.sgml
doc/src/sgml/ref/create_role.sgml
src/backend/commands/user.c

index ec83c4a18a480e5619799bc2a8526fbc5ef25188..1c3df69e5408e6aebd9874e1d947eabb2e2a0c87 100644 (file)
@@ -69,8 +69,10 @@ ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | A
    <xref linkend="SQL-REVOKE"> for that.)
    Attributes not mentioned in the command retain their previous settings.
    Database superusers can change any of these settings for any role.
-   Roles having <literal>CREATEROLE</> privilege can change any of these
-   settings, but only for non-superuser and non-replication roles.
+   Roles having <literal>CREATEROLE</literal> privilege can change any of these
+   settings except <literal>SUPERUSER</literal>, <literal>REPLICATION</literal>,
+   and <literal>BYPASSRLS</literal>; but only for non-superuser and
+   non-replication roles.
    Ordinary roles can only change their own password.
   </para>
 
index 64209d714a166c3e9ad217037c7a171e7cc6941d..169bb458c1f6b09b815f6a04a02d61fcc61f4d87 100644 (file)
@@ -176,6 +176,8 @@ CREATE ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
         highly privileged role, and should only be used on roles actually
         used for replication. If not specified,
         <literal>NOREPLICATION</literal> is the default.
+        You must be a superuser to create a new role having the
+        <literal>REPLICATION</literal> attribute.
        </para>
       </listitem>
      </varlistentry>
@@ -187,11 +189,16 @@ CREATE ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
        <para>
         These clauses determine whether a role bypasses every row-level
         security (RLS) policy.  <literal>NOBYPASSRLS</literal> is the default.
+        You must be a superuser to create a new role having
+        the <literal>BYPASSRLS</literal> attribute.
+       </para>
+
+       <para>
         Note that pg_dump will set <literal>row_security</literal> to
         <literal>OFF</literal> by default, to ensure all contents of a table are
         dumped out.  If the user running pg_dump does not have appropriate
-        permissions, an error will be returned.  The superuser and owner of the
-        table being dumped always bypass RLS.
+        permissions, an error will be returned.  However, superusers and the
+        owner of the table being dumped always bypass RLS.
        </para>
       </listitem>
      </varlistentry>
index 0000f1b02110accc62e14ec3f79e3700ec6ce4ba..e7e24dfd98c69cc1a452282e65352d92fc72917b 100644 (file)
@@ -680,8 +680,10 @@ AlterRole(AlterRoleStmt *stmt)
        roleid = HeapTupleGetOid(tuple);
 
        /*
-        * To mess with a superuser you gotta be superuser; else you need
-        * createrole, or just want to change your own password
+        * To mess with a superuser or replication role in any way you gotta be
+        * superuser.  We also insist on superuser to change the BYPASSRLS
+        * property.  Otherwise, if you don't have createrole, you're only allowed
+        * to change your own password.
         */
        if (authform->rolsuper || issuper >= 0)
        {
@@ -697,7 +699,7 @@ AlterRole(AlterRoleStmt *stmt)
                                        (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                         errmsg("must be superuser to alter replication users")));
        }
-       else if (authform->rolbypassrls || bypassrls >= 0)
+       else if (bypassrls >= 0)
        {
                if (!superuser())
                        ereport(ERROR,
@@ -706,11 +708,11 @@ AlterRole(AlterRoleStmt *stmt)
        }
        else if (!have_createrole_privilege())
        {
+               /* We already checked issuper, isreplication, and bypassrls */
                if (!(inherit < 0 &&
                          createrole < 0 &&
                          createdb < 0 &&
                          canlogin < 0 &&
-                         isreplication < 0 &&
                          !dconnlimit &&
                          !rolemembers &&
                          !validUntil &&