Знайдіть об’єкти, пов’язані з роллю PostgreSQL


12

Деякий час тому я створив користувача PostgreSQL на ім’я user1 (PostgreSQL 9.4.9).

Я хочу скинути цього користувача. Тому я спочатку відкликаю всі дозволи на таблиці, послідовності, функції, привілеї та права власності за замовчуванням:

ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON SEQUENCES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM user1;

REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM user1;

REASSIGN OWNED BY user1 TO postgres;

Однак здається, що один об’єкт залишається пов'язаним з цим користувачем у двох базах даних:

postgres=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  1 object in database db1
1 object in database db2

Це навіть здається функцією:

postgres=# \c db1
You are now connected to database "db1" as user "postgres".
db1=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  privileges for function text(boolean)
1 object in database db2

Але я не можу визначити, який об’єкт належить або пов’язаний з користувачем1.

Якщо я pg_dump -s db1 | grep user1не отримаю результату! Чи може це бути глобальним об’єктом?

Як я можу визначити відсутній об’єкт?

Я виконував команди у кожній базі даних (db1 та db2). Я не хочу скидати об’єкти, якими володіє user1, просто хочу перепризначити або видалити гранти для цього користувача.

Відповіді:


10

Відповідь на поставлене запитання

Щоб шукати функцію у повідомленні про помилку та її власника:

SELECT oid::regprocedure AS function
     , pg_get_userbyid(proowner) AS owner
FROM   pg_proc
WHERE  oid = 'text(boolean)'::regprocedure;

Пов'язані:

Актуальна проблема

Повідомлення про помилку говорить:

ДЕТАЛ: привілеї для тексту функції (булева)

Йдеться не про право власності, а про привілеї .

Посібник для DROP ROLE:

Перш ніж відмовитися від ролі, ви повинні скинути всі об’єкти, якими вона володіє (або перепризначити їх право власності) та скасувати будь-які привілеї, наділені роллю для інших об’єктів .

І для ALTER DEFAULT PRIVILEGES:

Якщо ви хочете відмовитись від ролі, для якої були змінені привілеї за замовчуванням, необхідно змінити зміни у своїх привілеях за замовчуванням або використати DROP OWNEDBY, щоб позбутися від запису привілеїв за замовчуванням для ролі .

Схоже, ви виконані лише REASSIGN OWNEDв одній БД, але інструкція вказує:

Оскільки REASSIGN OWNEDне впливає на об'єкти в інших базах даних, зазвичай потрібно виконати цю команду в кожній базі даних, що містить об'єкти, що належать ролі, яку потрібно видалити.

Сміливий акцент мій.

І ви обмежили свої команди IN SCHEMA public. Відкиньте цей пункт, щоб націлити цілу БД. Але не турбуйся, є ...

Просте рішення з DROP OWNED

REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;

Усі об’єкти ролі змінили право власності на postgresпершу команду і зараз є безпечними. Формулювання DROP OWNEDдещо оманливе, оскільки воно також позбавляється всіх привілеїв та привілеїв за замовчуванням. Посібник для DROP OWNED:

DROP OWNEDскидає всі об'єкти в поточну базу даних, які належать одній із зазначених ролей. Будь-які привілеї, надані даним ролям на об'єкти в поточній базі даних та на спільних об'єктах (базах даних, табличних просторах), також будуть відкликані.

Повторіть у всіх відповідних БД, тоді ви можете перейти до вбивства:

DROP ROLE user1;

6

У запиті нижче перелічені об’єкти з власниками. На всі привілеї насправді потрібно більше.

--r = ordinary table, i = index, S = sequence, v = view, m = materialized view, c = composite type, t = TOAST table, f = foreign table
SELECT 
    n.nspname AS schema_name,
    c.relname AS rel_name,
    c.relkind AS rel_kind,
    pg_get_userbyid(c.relowner) AS owner_name
  FROM pg_class c
  JOIN pg_namespace n ON n.oid = c.relnamespace

UNION ALL

-- functions (or procedures)
SELECT
    n.nspname AS schema_name,
    p.proname,
    'p',
    pg_get_userbyid(p.proowner)
  FROM pg_proc p
  JOIN pg_namespace n ON n.oid = p.pronamespace

Я досі не знаходжу зниклого об’єкта з цим.
Ніколя Пайарт

@NicolasPayart: Ви виконуєте запит у потрібній базі даних?
Ервін Брандстеттер

1

Спочатку потрібно підключитися до бази даних. У вашому випадку це було б

\c db1

і

\c db2

Потім спробуйте повторно запустити операції REVOKE ALL PRIVILEGES і REASSIGN WOWED / DROP WANEDED.


1
Гей, дякую за вашу першу відповідь. Однак, перш ніж розміщувати, будь ласка, подумайте про те, що це додає до існуючих відповідей, і опишіть це у своїй відповіді.
дезсо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.