Как просмотреть все права доступа к базам данных и объектам для роли?

Я пытаюсь проверить все разрешения для приложения перед выпуском и хочу убедиться, что ни одна роль не имеет большего доступа, чем ей нужно. Я просмотрел разные функции и системные таблицы, но все очень фрагментарно.

Есть ли хороший запрос или метод, чтобы иметь возможность выгружать каждый грант, который имеет конкретная роль?

Я использую пг 9.5.


person deinspanjer    schedule 01.10.2016    source источник


Ответы (2)


Столбец relacl системного каталога pg_class содержит всю информацию о привилегиях.

Пример данных в схеме public, принадлежащих postgres с грантами newuser:

create table test(id int);
create view test_view as select * from test;

grant select, insert, update on test to newuser;
grant select on test_view to newuser;

Запрос pg_class:

select 
    relname, 
    relkind, 
    coalesce(nullif(s[1], ''), 'public') as grantee, 
    s[2] as privileges
from 
    pg_class c
    join pg_namespace n on n.oid = relnamespace
    join pg_roles r on r.oid = relowner,
    unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) acl, 
    regexp_split_to_array(acl, '=|/') s
where nspname = 'public'
and relname like 'test%';

  relname  | relkind | grantee  | privileges 
-----------+---------+----------+------------
 test      | r       | postgres | arwdDxt      <- owner postgres has all privileges on the table
 test      | r       | newuser  | arw          <- newuser has append/read/write privileges
 test_view | v       | postgres | arwdDxt      <- owner postgres has all privileges on the view
 test_view | v       | newuser  | r            <- newuser has read privilege
(4 rows)

Комментарии:

  • coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)) - Null в relacl означает, что владелец имеет все привилегии;
  • unnest(...) acl - relacl представляет собой массив из aclitem, один элемент массива для пользователя;
  • regexp_split_to_array(acl, '=|/') s - разделить aclitem на: s[1] имя пользователя, s[2] привилегии;
  • coalesce(nullif(s[1], ''), 'public') as grantee - пустое имя пользователя означает public.

Измените запрос, чтобы выбрать отдельного пользователя или определенный тип отношения или другие схемы и т. д.

Читайте в документации:

Аналогичным образом можно получить информацию о привилегиях, предоставленных схемам (столбец nspacl в pg_namespace) и базах данных (datacl в pg_database )

person klin    schedule 02.10.2016
comment
Это круто. Я тратил слишком много времени на использование функций has_xxx_privivе() и различных таблиц и представлений pg_tables, pg_proc и т. д. - person deinspanjer; 03.10.2016

Столбец relacl (и другие столбцы типа aclitem) не нужно анализировать как текст. Функция aclexplode распаковывает массив, что делает его пригодным для бокового соединения. Результатом является запись с хорошо именованными полями, просто преобразуйте oid в удобочитаемое имя:

select c.*, n.nspname,
  acl.grantor, acl.grantee,
  pg_catalog.pg_get_userbyid(acl.grantor), pg_catalog.pg_get_userbyid(acl.grantee),
  acl.privilege_type, acl.is_grantable
from pg_catalog.pg_class c
join pg_catalog.pg_namespace n on n.oid = c.relnamespace,
lateral aclexplode(c.relacl) acl;
person Tomáš Záluský    schedule 12.04.2019
comment
Официально функция не документирована, ее описание, скорее всего, можно найти в документации Postgres 12. - person klin; 13.04.2019