Обсуждение: BUG #17346: pg_upgrade fails with role granted by other role

Поиск
Список
Период
Сортировка

BUG #17346: pg_upgrade fails with role granted by other role

От
PG Bug reporting form
Дата:
The following bug has been logged on the website:

Bug reference:      17346
Logged by:          Andrew Bille
Email address:      andrewbille@gmail.com
PostgreSQL version: Unsupported/Unknown
Operating system:   Ubuntu 20.04
Description:

Hello!
After the commit:

commit 371087d006e04991080bf17cf2287db38d3ea92e
Author: Daniel Gustafsson <dgustafsson@postgresql.org>
Date:   Fri Nov 26 14:02:01 2021 +0100

    Fix GRANTED BY support in REVOKE ROLE statements
    
    Commit 6aaaa76bb added support for the GRANTED BY clause in GRANT and
    REVOKE statements, but missed adding support for checking the role in
    the REVOKE ROLE case. Fix by checking that the parsed role matches the
    CURRENT_ROLE/CURRENT_USER requirement, and also add some tests for it.
    Backpatch to v14 where GRANTED BY support was introduced.
    
    Discussion:
https://postgr.es/m/B7F6699A-A984-4943-B9BF-CEB84C003527@yesql.se
    Backpatch-through: 14
    
pg_upgrade for example from 10.19 version causes the error:

10/bin/initdb -D d10
14/bin/initdb -D d14
10/bin/pg_ctl -D d10 -l logfile start
10/bin/psql -c "CREATE ROLE user1; CREATE ROLE user2; GRANT user1 TO user2
GRANTED BY user1;"
10/bin/pg_ctl -D d10 -l logfile stop
14/bin/pg_upgrade -d d10 -D d14 -b 10.19/bin/ -B 14/bin/

.........
Copying old pg_multixact/members to new server              ok
Setting next multixact ID and offset for new cluster        ok
Resetting WAL archives                                      ok
Setting frozenxid and minmxid counters in new cluster       ok
Restoring global objects in the new cluster                 
*failure*

Consult the last few lines of "pg_upgrade_utility.log" for
the probable cause of the failure.
Failure, exiting

Last lines of pg_upgrade_utility.log:
...
CREATE ROLE "user2";
CREATE ROLE
ALTER ROLE "user2" WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN
NOREPLICATION NOBYPASSRLS;
ALTER ROLE
GRANT "user1" TO "user2" GRANTED BY "user1";
psql:pg_upgrade_dump_globals.sql:37: ERROR:  grantor must be current user


Regards! Andrew Bille


Re: BUG #17346: pg_upgrade fails with role granted by other role

От
Tom Lane
Дата:
PG Bug reporting form <noreply@postgresql.org> writes:
> After the commit:

> commit 371087d006e04991080bf17cf2287db38d3ea92e
> Author: Daniel Gustafsson <dgustafsson@postgresql.org>
> Date:   Fri Nov 26 14:02:01 2021 +0100
>     Fix GRANTED BY support in REVOKE ROLE statements

> pg_upgrade for example from 10.19 version causes the error:

Yeah, you don't even need pg_upgrade.  Just do

regression=# CREATE ROLE user1; CREATE ROLE user2; GRANT user1 TO user2 GRANTED BY user1;
CREATE ROLE
CREATE ROLE
ERROR:  grantor must be current user

A superuser, or really anyone who's a member of the user1 role,
ought to be able to do that (especially since it used to be allowed).
So it seems the permissions check was coded incorrectly.

            regards, tom lane



Re: BUG #17346: pg_upgrade fails with role granted by other role

От
Daniel Gustafsson
Дата:

> On 27 Dec 2021, at 17:07, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> PG Bug reporting form <noreply@postgresql.org> writes:
>> After the commit:
>
>> commit 371087d006e04991080bf17cf2287db38d3ea92e
>> Author: Daniel Gustafsson <dgustafsson@postgresql.org>
>> Date:   Fri Nov 26 14:02:01 2021 +0100
>>    Fix GRANTED BY support in REVOKE ROLE statements
>
>> pg_upgrade for example from 10.19 version causes the error:
>
> Yeah, you don't even need pg_upgrade.  Just do
>
> regression=# CREATE ROLE user1; CREATE ROLE user2; GRANT user1 TO user2 GRANTED BY user1;
> CREATE ROLE
> CREATE ROLE
> ERROR:  grantor must be current user
>
> A superuser, or really anyone who's a member of the user1 role,
> ought to be able to do that (especially since it used to be allowed).
> So it seems the permissions check was coded incorrectly.
>
>            regards, tom lane

Thanks for the report, I’m OOO until late tonight but I’ll have a look when in.

cheers ./daniel


Re: BUG #17346: pg_upgrade fails with role granted by other role

От
Daniel Gustafsson
Дата:
> On 27 Dec 2021, at 17:02, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> PG Bug reporting form <noreply@postgresql.org> writes:
>> After the commit:
>
>> commit 371087d006e04991080bf17cf2287db38d3ea92e
>> Author: Daniel Gustafsson <dgustafsson@postgresql.org>
>> Date:   Fri Nov 26 14:02:01 2021 +0100
>>    Fix GRANTED BY support in REVOKE ROLE statements
>
>> pg_upgrade for example from 10.19 version causes the error:
>
> Yeah, you don't even need pg_upgrade.  Just do
>
> regression=# CREATE ROLE user1; CREATE ROLE user2; GRANT user1 TO user2 GRANTED BY user1;
> CREATE ROLE
> CREATE ROLE
> ERROR:  grantor must be current user
>
> A superuser, or really anyone who's a member of the user1 role,
> ought to be able to do that (especially since it used to be allowed).
> So it seems the permissions check was coded incorrectly.

Reading the SQL spec for GRANT and REVOKE, and specifically the "Grantor
Determination" subsection, it's not clear to me that this is wrong *per spec*
and that any value except CURRENT_USER and CURRENT_ROLE is supported (which is
what 6aaaa76bb implemented and the above referenced commit amended).  Given the
time of day I'm undercaffeinated for spec reading so I might be missing
something though.  Is <grantor> really handled differently for GRANT/REVOKE
ROLE to PRIVILEGE?

That being said, *iff* my spec reading is right, since this is something that
was working, and the benefit in supporting this is slim, reverting might be the
best (only) course.  Question is then how far that revert should stretch?  Is
there value in being spec compliant for PRIVILEGE and not ROLE?

If my spec reading is wrong then reverting is pretty obvious, but I would
appreciate a second pair of eyes on this before ripping it out.

--
Daniel Gustafsson        https://vmware.com/




Re: BUG #17346: pg_upgrade fails with role granted by other role

От
Tom Lane
Дата:
Daniel Gustafsson <daniel@yesql.se> writes:
> On 27 Dec 2021, at 17:02, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> A superuser, or really anyone who's a member of the user1 role,
>> ought to be able to do that (especially since it used to be allowed).
>> So it seems the permissions check was coded incorrectly.

> Reading the SQL spec for GRANT and REVOKE, and specifically the "Grantor
> Determination" subsection, it's not clear to me that this is wrong *per spec*
> and that any value except CURRENT_USER and CURRENT_ROLE is supported (which is
> what 6aaaa76bb implemented and the above referenced commit amended).  Given the
> time of day I'm undercaffeinated for spec reading so I might be missing
> something though.  Is <grantor> really handled differently for GRANT/REVOKE
> ROLE to PRIVILEGE?

Not sure.  However, it is certainly true that we have long supported
other grantors in GRANT <role> ... GRANTED BY (at least back to 8.4,
I didn't try anything older).  Whether that's within the spec or an
extension, breaking the case now isn't okay.

So the code change in b2a459edf is flat wrong AFAICS.  The fact that
it didn't break any existing test cases says we've got a testing gap,
which probably ought to be filled.

ISTM that 6aaaa76bb left a lot on the table too; would it have been
that hard to support other roles in the cases it added, given
that (at least most of) the ACL infrastructure is there?  I do agree
with the idea that GRANT <role> and GRANT <privilege> ought to
behave the same on this point --- but we have to do that by adding
capability, not subtracting it.

There do seem to be some bugs/limitations in the GRANT <role> case.
Trying this in v13:

regression=# create user user1;
CREATE ROLE
regression=# create user user2;
CREATE ROLE
regression=# create user user3;
CREATE ROLE
regression=# grant user3 to user2 with admin option;
GRANT ROLE
regression=# \c - user2
You are now connected to database "regression" as user "user2".
regression=> grant user3 to user1 granted by postgres;
ERROR:  must be superuser to set grantor
regression=> grant user3 to user1 granted by user3;
ERROR:  must have admin option on role "user3"
regression=> grant user3 to user1 granted by user2;
GRANT ROLE

So the "must be superuser" message is pretty misleading, it should
be more like "must be superuser to set grantor to another role".
And the second error is flat out wrong, since user2 *does* have that
admin option.  Both of those errors are coming out of AddRoleMems,
but I didn't look at the code in detail.

            regards, tom lane



Re: BUG #17346: pg_upgrade fails with role granted by other role

От
Daniel Gustafsson
Дата:
> On 27 Dec 2021, at 23:52, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> Daniel Gustafsson <daniel@yesql.se> writes:
>> On 27 Dec 2021, at 17:02, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>>> A superuser, or really anyone who's a member of the user1 role,
>>> ought to be able to do that (especially since it used to be allowed).
>>> So it seems the permissions check was coded incorrectly.
>
>> Reading the SQL spec for GRANT and REVOKE, and specifically the "Grantor
>> Determination" subsection, it's not clear to me that this is wrong *per spec*
>> and that any value except CURRENT_USER and CURRENT_ROLE is supported (which is
>> what 6aaaa76bb implemented and the above referenced commit amended).  Given the
>> time of day I'm undercaffeinated for spec reading so I might be missing
>> something though.  Is <grantor> really handled differently for GRANT/REVOKE
>> ROLE to PRIVILEGE?
>
> Not sure.  However, it is certainly true that we have long supported
> other grantors in GRANT <role> ... GRANTED BY (at least back to 8.4,
> I didn't try anything older).  Whether that's within the spec or an
> extension, breaking the case now isn't okay.

Agreed.

> So the code change in b2a459edf is flat wrong AFAICS.  The fact that
> it didn't break any existing test cases says we've got a testing gap,
> which probably ought to be filled.
>
> ISTM that 6aaaa76bb left a lot on the table too; would it have been
> that hard to support other roles in the cases it added, given
> that (at least most of) the ACL infrastructure is there?  I do agree
> with the idea that GRANT <role> and GRANT <privilege> ought to
> behave the same on this point --- but we have to do that by adding
> capability, not subtracting it.

I'll craft a revert of b2a459edf when I'm less tired, a proper fix can then be
worked on separately.

--
Daniel Gustafsson        https://vmware.com/




Re: BUG #17346: pg_upgrade fails with role granted by other role

От
Daniel Gustafsson
Дата:
> On 28 Dec 2021, at 00:26, Daniel Gustafsson <daniel@yesql.se> wrote:

> I'll craft a revert of b2a459edf when I'm less tired, a proper fix can then be
> worked on separately.

I prepared a revert patch tonight and ran it through CI, but won't have ample
time to monitor the buildfarm so I have it slated for pushing in the morning.
I opted for keeping the tests even though they aren't excercising all that much
code but they at least show the current behavior.

--
Daniel Gustafsson        https://vmware.com/


Вложения