"set role" semantics - Mailing list pgsql-general

From Bryn Llewellyn
Subject "set role" semantics
Date
Msg-id FE0F7CE2-F1E8-40C8-A097-0CFDB0E14933@yugabyte.com
Whole thread Raw
Responses Re: "set role" semantics  ("David G. Johnston" <david.g.johnston@gmail.com>)
Re: "set role" semantics  ("David G. Johnston" <david.g.johnston@gmail.com>)
List 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'; "

pgsql-general by date:

Previous
From: Tom Lane
Date:
Subject: Re: Segmentation Fault PG 14
Next
From: "David G. Johnston"
Date:
Subject: Re: "set role" semantics