Невозможно удалить роль, предоставленную для подключения к базе данных. - PullRequest
0 голосов
/ 24 июня 2018

Я использую 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 требует отозвать привилегии перед удалением роли?
  • Если нет, то почему эта конкретная привилегия ведет себя так?
...