"set role" semantics

From: Bryn Llewellyn <bryn(at)yugabyte(dot)com>
To: pgsql-general list <pgsql-general(at)lists(dot)postgresql(dot)org>
Subject: "set role" semantics
Date: 2022-11-09 00:16:31
Message-ID: FE0F7CE2-F1E8-40C8-A097-0CFDB0E14933@yugabyte.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

I created a little test to demonstrate to myself how “set role” works. I ran it in a freshly-created PG 11.17 cluster on Ubuntu, installed and configured like I’ve recently discussed on this list. I copied my "pg-init.sh" script at the end.

I then did this test, after starting like this (as the system admin O/S user for my VM):

----------------------

source pg-init.sh
sudo -u postgres psql

This is the SQL script:

create role clstr$mgr with
create role clstr$mgr with
nosuperuser
createrole
createdb
noreplication
nobypassrls
connection limit 0
login password null;

set role clstr$mgr;

create role d1$mgr
nosuperuser
nocreaterole
nocreatedb
noreplication
nobypassrls
connection limit 0
login password null;

create role d2$mgr
nosuperuser
nocreaterole
nocreatedb
noreplication
nobypassrls
connection limit 0
login password null;

create database d1;
revoke all on database d1 from public;

create database d2;
revoke all on database d2 from public;

\c d1 postgres

set role clstr$mgr;
grant create on database d1 to d1$mgr;
create schema s;
grant usage on schema s to d1$mgr;
grant create on schema s to d1$mgr;

set role d1$mgr;
select current_database()||' > '||session_user||' > '||current_user;
create table s.t(k int);
insert into s.t(k) values(17);
select * from s.t;

set role d2$mgr;
select current_database()||' > '||session_user||' > '||current_user;

-- permission denied...
select * from s.t;

----------------------

Notice that I didn't grant "connect" on either of the databases, "d1" or "d2", to any of the roles, "clstr$mgr, "d1$mgr", or "d2$mgr".

I couldn't find the doc that tells me what to expect. Where is it? I was a bit surprised that I could end up with the "current_database()" as "d1" or "d2" and the "current_user" as "clstr$mgr" when this role doesn't have "connect" on either of the databases. But I guessed that permission to do this was implied by the "createdb" attribute (as a special case of the general unstoppability of a superuser). However, I was very surprised that I could end up with the "current_database()" as "d1" or "d2" and the "current_user" as "d2$mgr" or because it is so far minimally privileged (and in particular doesn't have "connect" on "d1" or "d2").

I'd been hoping that "set role d2$mgr" would fail when "d2$mgr" doesn't have "connect" on the target database, "d1". My plan, then, had been to set up "d1$mgr" as the manager for "d1" by granting it "connect on "d1" but not on "d2". Then I'd've used a similar scheme for "d2$mgr".

Is there anything that can be done to limit the scope of the ability to end up in a database like I'd thought would be possible? (A little test showed me that "set role" doesn't fire an event trigger.)

I do see that, as far as I've taken this test, "d2$mgr" is entirely impotent when the "current_database()" is "d1". Is this, maybe, just as good as it gets. I suppose I can live with what seems to me to be very odd as long as no harm can come of it.

----------------------
# pg-init.sh

sudo pg_dropcluster --stop 11 main
sudo rm -Rf /etc/ybmt-generated/pg-logs/*

sudo pg_createcluster 11 main \
-e UTF8 --locale=C --lc-collate=C --lc-ctype=en_US.UTF-8 \
-d /var/lib/postgresql/11/main \
> /dev/null

sudo cp /etc/ybmt-code/pg-and-yb-config-files/*.conf \
/etc/postgresql/11/main

sudo chown postgres /etc/postgresql/11/main/*.conf
sudo chgrp postgres /etc/postgresql/11/main/*.conf
sudo chmod 644 /etc/postgresql/11/main/*.conf
sudo chmod 640 /etc/postgresql/11/main/pg_hba.conf
sudo chmod 640 /etc/postgresql/11/main/pg_ident.conf

sudo pg_ctlcluster start 11/main

sudo -u postgres psql -c " alter role postgres with superuser connection limit -1 login password 'x'; alter database postgres with allow_connections = true connection_limit = -1; "

sudo -u postgres psql -c " select name, setting from pg_settings where category = 'File Locations'; "

Responses

Browse pgsql-general by date

  From Date Subject
Next Message David G. Johnston 2022-11-09 00:24:11 Re: "set role" semantics
Previous Message Tom Lane 2022-11-08 17:16:10 Re: Segmentation Fault PG 14