I am using PostgreSQL 10.4 and I found a strange behavior.
If we create an role and grant it to CONNECT
the database:
CREATE ROLE dummy;
GRANT CONNECT ON DATABASE test TO dummy;
Then we cannot drop this role, even if it owns no object at all, this command:
DROP ROLE dummy;
Raises:
ERROR: role "dummy" cannot be dropped because some objects depend on it
SQL state: 2BP01
Detail: privileges for database test
Documentation is a bit misleading:
Class 2B — Dependent Privilege Descriptors Still Exist
2B000 dependent_privilege_descriptors_still_exist
2BP01 dependent_objects_still_exist
It says dependent objects still exist, but it seems there are no objects dependent to this specific role, it owns nothing on the database.
Anyway, if we revoke the CONNECT
privilege, then role can be dropped:
REVOKE CONNECT ON DATABASE test FROM dummy;
DROP ROLE dummy;
I just checked the behavior also exists on PostgreSQL 9.5. I feel it a bit strange and I cannot understand why this specific privilege makes dropping role fails.
Additional observations
This is really blocking, because we can neither reassign this object:
REASSIGN OWNED BY dummy TO postgres;
Nor drop the object:
DROP OWNED BY dummy;
Both raise related errors:
ERROR: permission denied to reassign objects
SQL state: 42501
ERROR: permission denied to drop objects
SQL state: 42501
As @RaymondNijland pointed out, this must be because the CONNECT
privileges is viewed as a role dependent object. The following query:
WITH
R AS (SELECT * FROM pg_roles WHERE rolname = 'dummy')
SELECT
D.*
FROM
R, pg_shdepend AS D
WHERE
refobjid = R.oid;
Returns a single row when CONNECT
is granted:
"dbid";"classid";"objid";"objsubid";"refclassid";"refobjid";"deptype"
0;1262;27961;0;1260;27966;"a"
And no row at all when the privilege is revoked. This at least explain why we cannot reassign the object.
About the Dependency Type, the documentation states:
SHARED_DEPENDENCY_ACL
(a)The referenced object (which must be a role) is mentioned in the ACL (access control list, i.e., privileges list) of the dependent object. (
A SHARED_DEPENDENCY_ACL
entry is not made for the owner of the object, since the owner will have aSHARED_DEPENDENCY_OWNER
entry anyway.)
But I have not enough insight to understand it clearly.
My question are:
- Do Postgres always require to revoke privileges before dropping a role?
- If not, why this specific privilege behaves like this?
Detail: privileges for database test
...The system catalogpg_shdepend
( postgresql.org/docs/current/static/catalog-pg-shdepend.html ) should have this dependency relationship – Viola