Re: Rollback issue with SET ROLE - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Rollback issue with SET ROLE
Date
Msg-id 3925.1122388754@sss.pgh.pa.us
Whole thread Raw
In response to Re: Rollback issue with SET ROLE  (Stephen Frost <sfrost@snowman.net>)
List pgsql-hackers
Stephen Frost <sfrost@snowman.net> writes:
> * Tom Lane (tgl@sss.pgh.pa.us) wrote:
>> Ideally the ROLLBACK should have restored the ROLE setting that obtained
>> prior to BEGIN.  The reason it doesn't is that the ROLLBACK effectively
>> does a "SET SESSION AUTHORIZATION <prior-auth-value>", and that naturally
>> clears the ROLE setting.

> In this case '<prior-auth-value>' is really both the 'user' and the
> 'role'.  Not sure that really helps though.

Yeah, the solutions I was looking at involved various combinations of
storing both values in one or both of the GUC variables.  They all
seemed pretty messy and fragile though.

>> Even with a fix for that, there are some related nasty cases.  Consider
>> BEGIN;
>> SET LOCAL SESSION AUTHORIZATION foo;
>> SET ROLE bar;
>> COMMIT;
>> The SET ROLE, being nonlocal, should persist past the COMMIT.  But the
>> right to do "SET ROLE bar" would have been checked against foo's role
>> memberships.  If the outer-level session user doesn't have membership
>> in foo, this leaves us in an illegal situation.

> To do SET SESSION AUTH, wouldn't the outer-level session user have to be
> superuser, and therefore you're actually fine (considering superuser is
> in all roles, etc)?

Hmm, true, but that doesn't mean you're out of the woods.  If you fix
the other problem by making AUTH and ROLE be effectively a single
variable, then what will happen here is that SET ROLE will set the
variable's value as foo/bar, and then that value will persist past
COMMIT, leaving you with the wrong AUTH setting at the outer level.

>> A possible plan B is to forbid doing either SET SESSION AUTHORIZATION
>> or SET ROLE inside a transaction block, so that none of these cases
>> arise.  This restriction is sanctioned by the SQL spec.  However, we've
>> historically allowed SET SESSION AUTHORIZATION inside a transaction
>> block, and in fact there's a SET LOCAL SESSION AUTHORIZATION in the
>> regression tests.

> My expectation is that they wouldn't be allowed in a transaction, I
> wasn't actually aware that we allowed SET SESSION AUTH in a transaction.
> I'm not sure I see what the use-case for it would be,

Yeah.  I actually put in code to forbid them in a transaction, but took
it out again when I found the regression tests failing :-(.  The
offending code is in the sequence test:

CREATE USER seq_user;

BEGIN;
SET LOCAL SESSION AUTHORIZATION seq_user;
CREATE SEQUENCE seq3;
SELECT nextval('seq3');
REVOKE ALL ON seq3 FROM seq_user;
SELECT lastval();
ROLLBACK;

DROP USER seq_user;
DROP SEQUENCE seq;

There isn't any amazingly good reason why this couldn't be handled
without a transaction, viz

SET SESSION AUTHORIZATION seq_user;
...
RESET SESSION AUTHORIZATION;

so unless someone comes up with a reasonable implementation plan
for handling changes to both values within a transaction,
I'll probably fall back to doing that.
        regards, tom lane


pgsql-hackers by date:

Previous
From: Stephen Frost
Date:
Subject: Re: Rollback issue with SET ROLE
Next
From: Tom Lane
Date:
Subject: Re: [PATCHES] Roles - SET ROLE Updated