Я использую PostgreSQL 10.4 и обнаружил странное поведение.
Если мы создадим роль и предоставим ее CONNECT
базе данных:
CREATE ROLE dummy;
GRANT CONNECT ON DATABASE test TO dummy;
Тогда мы не можем отбросить эту роль, даже если ей вообще не принадлежит объект, эта команда:
DROP ROLE dummy;
Поднимает:
ERROR: role "dummy" cannot be dropped because some objects depend on it
SQL state: 2BP01
Detail: privileges for database test
Документация немного вводит в заблуждение:
Класс 2B - зависимые дескрипторы привилегий все еще существуют
2B000 independent_privilege_descriptors_still_exist
2BP01pendent_objects_still_exist
В нем говорится, что зависимые объекты все еще существуют , но кажется, что нет объектов, зависящих от этой конкретной роли, ему ничего не принадлежит в базе данных.
В любом случае, если мы отменим привилегию CONNECT
, роль можно будет отменить:
REVOKE CONNECT ON DATABASE test FROM dummy;
DROP ROLE dummy;
Я только что проверил поведение, также существующее в PostgreSQL 9.5. Мне это немного странно, и я не могу понять, почему эта конкретная привилегия делает сбрасывание роли неудачной.
Дополнительные наблюдения
Это действительно блокировка, потому что мы не можем ни переназначить этот объект:
REASSIGN OWNED BY dummy TO postgres;
Ни уронить объект:
DROP OWNED BY dummy;
Обе ошибки вызывают:
ERROR: permission denied to reassign objects
SQL state: 42501
ERROR: permission denied to drop objects
SQL state: 42501
Как указал @RaymondNijland, это должно быть потому, что привилегии CONNECT
рассматриваются как объект, зависящий от роли. Следующий запрос:
WITH
R AS (SELECT * FROM pg_roles WHERE rolname = 'dummy')
SELECT
D.*
FROM
R, pg_shdepend AS D
WHERE
refobjid = R.oid;
Возвращает одну строку, когда предоставляется CONNECT
:
"dbid";"classid";"objid";"objsubid";"refclassid";"refobjid";"deptype"
0;1262;27961;0;1260;27966;"a"
И вообще нет строки, когда привилегия отозвана. Это, по крайней мере, объясняет, почему мы не можем переназначить объект.
О типе зависимости, в документации указано:
SHARED_DEPENDENCY_ACL
(а)
Указанный объект (который должен быть ролью) упоминается в
ACL (список контроля доступа, то есть список привилегий) зависимого
объект. (A SHARED_DEPENDENCY_ACL
запись не сделана для владельца
объект, так как владелец будет иметь SHARED_DEPENDENCY_OWNER
запись
в любом случае.)
Но мне не хватает проницательности, чтобы понять это ясно.
Мой вопрос:
- Всегда ли Postgres требует отозвать привилегии перед удалением роли?
- Если нет, то почему эта конкретная привилегия ведет себя так?