Re: CREATEROLE and role ownership hierarchies
Mark Dilger <mark.dilger@enterprisedb.com>
From: Mark Dilger <mark.dilger@enterprisedb.com>
To: Shinya Kato <Shinya11.Kato@oss.nttdata.com>
Cc: "Bossart, Nathan" <bossartn@amazon.com>,
PostgreSQL-development <pgsql-hackers@postgresql.org>,
Andrew Dunstan <andrew@dunslane.net>,
Jeff Davis <pgsql@j-davis.com>
Date: 2021-10-28T15:24:23Z
Lists: pgsql-hackers
> On Oct 27, 2021, at 7:32 PM, Shinya Kato <Shinya11.Kato@oss.nttdata.com> wrote:
>
> I was able to add the membership of a role with a different owner.
> In brief, "a" was able to change the membership of owner "shinya".
> Is this the correct behavior?
I believe it is required for backwards compatibility. In a green field, we might consider doing things differently.
The only intentional backward compatibility break in this patch set is the the behavior of CREATEROLE. The general hope is that such a compatibility break will help far more than it hurts, as CREATEROLE does not appear to be a well adopted feature. I would expect that breaking the behavior of the WITH ADMIN OPTION feature would cause a lot more pain.
Trying your example on both the unpatched and the patched sources, things appear to work as they should:
UNPATCHED
------------------
mark.dilger=# CREATE ROLE a LOGIN;
CREATE ROLE
mark.dilger=# GRANT pg_execute_server_program TO a WITH ADMIN OPTION;
GRANT ROLE
mark.dilger=# CREATE ROLE b;
CREATE ROLE
mark.dilger=# \du+ a
List of roles
Role name | Attributes | Member of | Description
-----------+------------+-----------------------------+-------------
a | | {pg_execute_server_program} |
mark.dilger=# \du+ b
List of roles
Role name | Attributes | Member of | Description
-----------+--------------+-----------+-------------
b | Cannot login | {} |
mark.dilger=# \c - a
You are now connected to database "mark.dilger" as user "a".
mark.dilger=> GRANT pg_execute_server_program TO b;
GRANT ROLE
mark.dilger=> \du+ b
List of roles
Role name | Attributes | Member of | Description
-----------+--------------+-----------------------------+-------------
b | Cannot login | {pg_execute_server_program} |
mark.dilger=> \du+ "mark.dilger"
List of roles
Role name | Attributes | Member of | Description
-------------+------------------------------------------------------------+-----------+-------------
mark.dilger | Superuser, Create role, Create DB, Replication, Bypass RLS | {} |
PATCHED:
---------------
mark.dilger=# CREATE ROLE a LOGIN;
CREATE ROLE
mark.dilger=# GRANT pg_execute_server_program TO a WITH ADMIN OPTION;
GRANT ROLE
mark.dilger=# CREATE ROLE b;
CREATE ROLE
mark.dilger=# \du+ a
List of roles
Role name | Owner | Attributes | Member of | Description
-----------+-------------+------------+-----------------------------+-------------
a | mark.dilger | | {pg_execute_server_program} |
mark.dilger=# \du+ b
List of roles
Role name | Owner | Attributes | Member of | Description
-----------+-------------+--------------+-----------+-------------
b | mark.dilger | Cannot login | {} |
mark.dilger=# \c - a
You are now connected to database "mark.dilger" as user "a".
mark.dilger=> GRANT pg_execute_server_program TO b;
GRANT ROLE
mark.dilger=> \du+ b
List of roles
Role name | Owner | Attributes | Member of | Description
-----------+-------------+--------------+-----------------------------+-------------
b | mark.dilger | Cannot login | {pg_execute_server_program} |
mark.dilger=> \du+ "mark.dilger"
List of roles
Role name | Owner | Attributes | Member of | Description
-------------+-------------+------------------------------------------------------------+-----------+-------------
mark.dilger | mark.dilger | Superuser, Create role, Create DB, Replication, Bypass RLS | {} |
You should notice that the owner of role "b" is the superuser "mark.dilger", and that owner's attributes are unchanged. But your point that role "a" can change the attributes of role "mark.dilger" is correct, as shown here:
mark.dilger=> GRANT pg_execute_server_program TO "mark.dilger";
GRANT ROLE
mark.dilger=> \du+ "mark.dilger"
List of roles
Role name | Owner | Attributes | Member of | Description
-------------+-------------+------------------------------------------------------------+-----------------------------+-------------
mark.dilger | mark.dilger | Superuser, Create role, Create DB, Replication, Bypass RLS | {pg_execute_server_program} |
—
Mark Dilger
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Commits
-
Make role grant system more consistent with other privileges.
- ce6b672e4455 16.0 landed
-
Ensure that pg_auth_members.grantor is always valid.
- 6566133c5f52 16.0 landed
-
Remove the ability of a role to administer itself.
- 79de9842ab03 15.0 landed
-
Add tests of the CREATEROLE attribute
- e9d4001ec592 15.0 landed
-
Replace explicit PIN entries in pg_depend with an OID range test.
- a49d08123599 15.0 cited
-
Shore up ADMIN OPTION restrictions.
- fea164a72a7b 9.4.0 cited
-
Add pg_has_role() family of privilege inquiry functions modeled after the
- f9fd1764615e 8.1.0 cited
-
Align GRANT/REVOKE behavior more closely with the SQL spec, per discussion
- 4b2dafcc0b1a 8.0.0 cited