Перейти к основному содержимому

Привилегии

Любой объект принадлежит какой-либо роли. При создании объекта во время сеанса роль становится его владельцем и получает права на любые действия с ним. Для получения доступа к объекту, владельцем которого роль не является, необходимы привилегии. Привилегии устанавливаются на объекты в их метаданных и запоминаются в форме ACL (Access Control List) следующим образом:

grantee=privilege[*].../grantor +

Используемые обозначения:

  • grantee — роль, которой были назначены привилегии;
  • privilege — сами привилегии;
  • [*] — символ, который означает возможность передачи привилегии;
  • grantor — роль, предоставившая привилегии;
  • + — такой символ ставится, если ролей с привилегиями много и они не помещаются на одну строчку.

Для каждого типа объектов в PostgreSQL существует отдельная команда просмотра привилегий. Полный перечень команд приведен в справочной таблице. Привилегии по умолчанию (полные права владельца) не отображаются в ACL до первого изменения списка доступа.

Создадим таблицу def_privs и проверим ее список доступа.

postgres@postgres=# CREATE TABLE def_privs(n int);
CREATE TABLE
postgres@postgres=# \dp def_privs
Access privileges
Schema | Name | Type |Access privileges|Column privileges|Policies
--------+-----------+---------+-----------------+-----------------+----------
public | def_privs | table | | |
(1 row)

В столбце Access privileges данные отсутствуют — привилегии владельца по умолчанию не выводятся.

Назначение привилегий​

Назначать привилегии может одна из трех ролей:

  • владелец объекта;
  • роль с правом передачи привилегий;
  • суперпользователь.

Для назначения привилегии используется команда GRANT. При ее применении нужно указать, какие привилегии, на какой объект и для какой роли необходимо выдать.

Создадим роль aspirant и попробуем выполнить запрос к таблице studentab с ее помощью.

postgres@postgres=# CREATE USER aspirant;
CREATE ROLE
Почему используется команда CREATE USER?

Поскольку дальше нужно будет выполнить запрос к таблице studentab, потребуется подключиться к базе данных my_db, а для этого нужен атрибут LOGIN. Его можно выдать явно как в команде CREATE ROLE, так и скрытно при помощи CREATE USER. Синтаксис команды получается короче и удобнее при том же результате.

postgres@postgres=# \c my_db aspirant
You are now connected to database "my_db" as user "aspirant".
aspirant@my_db=> SELECT * FROM studentab;
ERROR: permission denied for table suptab

Роль aspirant не входит в групповую роль grp_students, которая владеет таблицей studentab, поэтому на нее не распространяются права владельца объекта. Для выполнения запроса необходимо выдать соответствующую привилегию (разрешение на чтение таблицы) от имени владельца объекта.

aspirant@postgres=> \c my_db student
You are now connected to database "my_db" as user "student".
student@my_db=> GRANT SELECT ON studentab TO aspirant ;
GRANT
student@my_db=> \c - aspirant
You are now connected to database "my_db" as user "aspirant".
aspirant@my_db=> SELECT * FROM studentab;
id | str
----+-----
(0 rows)

Как видим, запрос успешно выполнен.

Действия с разными объектами отличаются. Рассмотрим их подробнее.

Привилегии для таблиц и представлений​

Для работы с таблицами и представлениями можно назначить следующие привилегии (в скобках указаны их буквенные обозначения в ACL):

  • SELECT — чтение таблицы, представления, столбца (r — read);
  • INSERT — вставка в таблицу или представление (a — append);
  • UPDATE — изменение значений столбцов таблиц или представлений (w — write);
  • DELETE — удаление строк в таблицах или представлениях (d — delete);
  • TRUNCATE — опустошение таблицы (D);
  • REFERENCES — создание ссылки на столбец внешним ключом (x);
  • TRIGGER — создание триггера для таблицы или представления (t).

Привилегии можно выдать не только на целый объект, но и на его часть — отдельные столбцы.

Установим для роли aspirant привилегии на чтение и вставку данных для некоторых столбцов. Для этого переключимся на student и создадим новую таблицу.

aspirant@my_db=> \c - student
You are now connected to database "my_db" as user "student".
student@my_db=> CREATE TABLE ptab (n integer, t text);
CREATE TABLE

Выдадим aspirant возможность чтения столбца n и вставки данных в столбцы n и t в таблице ptab.

student@my_db=> GRANT SELECT(n),INSERT(n,t) ON ptab TO aspirant;
GRANT

Получить установленные привилегии на таблицу можно метакомандой \dp.

student@my_db=> \dp ptab
Access privileges
Schema | Name | Type |Access privileges| Column privileges | Policies
--------+------+---------+-----------------+-----------------------+----------
public | ptab | table | | n: +|
| | | | aspirant=ar/student+|
| | | | t: +|
| | | | aspirant=a/student |
(1 row)

В столбце Access privileges перечислены все роли и их привилегии для данного объекта. Если привилегии выданы на конкретные столбцы, роли будут сгруппированы по этим столбцам, как в нашем случае. Разберем запись из ACL подробнее.

Столбец привилегий разделен на 2 группы: для столбца n и столбца t таблицы ptab.

Посмотрим на запись столбца n. Перед знаком равенства указана роль aspirant, которой выданы привилегии. Буквенные обозначения привилегий пишутся после знака равенства, в нашем случае это ar. Буква a соответствует разрешению на вставку данных в текущий столбец, а буква r— разрешению на чтение данных.

Запись столбца t практически не отличается от предыдущей: на текущий столбец выдана только привилегия на вставку данных.

Привилегии для баз данных​

По сравнению с таблицами у баз данных меньше возможных привилегий:

  • CREATE (C) — разрешает создание новых схем, публикаций и подключение расширений;
  • CONNECT (c) — разрешает подключение к базе данных;
  • TEMPORARY (T) — создание временных объектов в базе данных.

По умолчанию на все базы данных устанавливаются 2 привилегии: T и c. Подключение к базе данных требует не только наличия соответствующей привилегии, но и разрешения на подключение в файле pg_hba.conf, о котором будет рассказано позже.

В качестве демонстрации работы с привилегиями для баз данных выберем разрешение на создание схем (как раз дальше речь пойдет про них). Попробуем создать схему от имени aspirant.

student@my_db=> \c - aspirant
You are now connected to database "my_db" as user "aspirant".
aspirant@my_db=> CREATE SCHEMA asp_sch;
ERROR: permission denied for database my_db

Поскольку роль aspirant не входит в grp_students и пока не имеет нужной привилегии, то не может и создать схему — недостаточно прав. Переключимся на владельца базы данных, grp_students, и выдадим привилегию C.

aspirant@my_db=> SET ROLE grp_students;
SET
aspirant@my_db=> GRANT CREATE ON DATABASE my_db TO aspirant;
GRANT

Обратите внимание, что в команде выдачи прав добавилось ключевое слово DATABASE. Оно позволяет явно указать, что права выдаются именно на базу данных, а не объекты в ней. Если не указывать ключевое слово, система будет искать объект my_db внутри базы данных, к которой выполнено подключение на данный момент.

Теперь вернемся к роли aspirant и посмотрим на привилегии баз данных. Для получения информации по базам данных, в том числе выданных привилегий, используется метакоманда \l.

aspirant@my_db=> RESET ROLE;
RESET
aspirant@my_db=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+--------------+----------+-------------+-------------+------------+-----------------+-------------------------------
my_db | grp_students | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =Tc/grp_students +
| | | | | | | grp_students=CTc/grp_students+
| | | | | | | aspirant=C/grp_students
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
sch_db | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
(5 rows)

У my_db появилась запись для роли aspirant с привилегией C, выданной grp_students. Но обратим внимание на первую запись. Она отличается от остальных — нет имени роли перед знаком равенства. Это и есть маркер тех самых прав по умолчанию, которые работают для всех ролей. Устанавливаются они автоматически системой от имени владельца базы данных.

Попробуем вновь создать схему asp_sch.

aspirant@my_db=> CREATE SCHEMA asp_sch;
CREATE SCHEMA

С выданной привилегией проблем с нехваткой прав не возникло и схема была успешно создана.

Привилегии для схем​

Для схем привилегий еще меньше, их существует всего две:

  • USAGE (U) — разрешает взаимодействовать с объектами внутри схемы;
  • CREATE (C) — разрешает создавать объекты внутри схемы и переименовывать их.

Создадим новую схему и выдадим на нее право на взаимодействие роли aspirant. Поскольку student за счет членства в grp_students является владельцем my_db на ровне с групповой ролью, переключимся на него и создадим схему my_schema.

aspirant@my_db=> \c - student
You are now connected to database "my_db" as user "student".
student@my_db=> CREATE SCHEMA my_schema;
CREATE SCHEMA

Чтобы выдать привилегию на взаимодействие с будущими объектами схемы, применяем ту же команду GRANT вместе с ключевым словом — SCHEMA.

student@my_db=> GRANT USAGE ON SCHEMA my_schema TO aspirant;
GRANT

Проверить выданные привилегии для конкретной схемы можно с помощью метакоманды \dn+ и указания названия схемы.

student@my_db=> \dn+ my_schema
List of schemas
Name | Owner | Access privileges | Description
-----------+----------+--------------------+----------
my_schema | student | student=UC/student+|
| | aspirant=U/student |
(1 row)

Привилегии на установку параметров​

Суперпользователь может предоставить право изменять конкретные сессионные параметры с контекстом. Это позволяет делать привилегия SET (s). Также можно предоставить привилегию на изменение параметров на уровне экземпляра командой ALTER SYSTEM — привилегия ALTER SYSTEM с аббревиатурой (A).

Взаимодействовать со всеми параметрами может только суперпользователь или роль, которой были выданы такие привилегии. Поэтому для демонстрации выдачи привилегии на параметр переключимся на postgres.

student@my_db=> \c - postgres
You are now connected to database "my_db" as user "postgres".

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

postgres@my_db=# \dconfig+ commit_delay
List of configuration parameters
Parameter | Value | Type | Context |Access privileges
--------------+----------+---------+-----------+--------------------
commit_delay | 0 | integer | superuser |

В поле Context стоит superuser, что не позволяет обычным пользователям менять данный параметр.

Выдадим роли student право менять его в рамках сессии. Для параметров используется ключевое слово PARAMETER.

postgres@my_db=# GRANT SET ON PARAMETER commit_delay TO student;
GRANT

Вновь проверим привилегии на параметр commit_delay.

postgres@my_db=# \dconfig+ commit_delay
List of configuration parameters
Parameter | Value | Type | Context |Access privileges
--------------+----------+---------+-----------+----------------------
commit_delay | 0 | integer | superuser | postgres=sA/postgres+
| | | | student=s/postgres

Другие привилегии​

Реже остальных приходится взаимодействовать с последовательностями (ключевое слово для команды GRANT — SEQUENCE). Перечислим привилегии для них:

  • SELECT (r) — право вызывать функцию currval для получения ранее сгенерированного значения;
  • UPDATE (w) — право на выполнение функций nextval для получения нового значения последовательности и setval для установки начального значения последовательности;
  • USAGE (U) — право выполнять функции currval и nextval.

Кроме перечисленных выше привилегий есть еще несколько:

  • CREATE (C) — позволяет создавать объекты в табличных пространствах;

  • EXECUTE (X) — позволяет выполнять функции и процедуры;

  • USAGE (U):

    • использование процедурных языков;
    • право выполнять функции currval и nextval для последовательностей;
    • право создания нового сервера для оберток внешних данных;
    • позволяет создавать внешние таблицы для внешних серверов.

Привилегии, установленные на табличные пространства, можно увидеть с помощью метакоманды \db+. Привилегии на функции и процедуры показывает метакоманда \df+. Расширения для подключения внешних источников данных (FDW — Foreign Data Wrapper) будут обсуждаться далее по курсу.

Право передачи​

В PostgreSQL также реализован механизм передачи привилегий ролью-получателем. Для этого в конце команды GRANT есть опция GRANT OPTION. Рассмотрим такой случай на примере.

Создадим новую таблицу и предоставим роли student привилегии на нее с правом передачи.

postgres@my_db=# CREATE TABLE suptab (s date);
CREATE TABLE
postgres@my_db=# GRANT SELECT ON suptab TO student WITH GRANT OPTION;
GRANT

Опция GRANT OPTION указывается после ключевого слова WITH в конце команды.

Переключимся на student и проверим привилегии на таблицу.

postgres@my_db=# \c - student
You are now connected to database "my_db" as user "student".
student@my_db=> \dp suptab
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+--------+---------+---------------------------+--------------------+----------
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=r*/postgres | |

Сразу после буквенного обозначения привилегии SELECT (r) появился символ *, который означает, что роль может передавать данную привилегию.

Важно

Роль может передавать только те привилегии, при выдаче которых было указано право передачи. Если роли выдали несколько привилегий с правом передачи, запись привилегий в ACL будет выглядеть следующим образом:

student=r*а*/postgres

Попробуем передать привилегию чтения таблицы роли aspirant.

student@my_db=> GRANT SELECT ON suptab TO aspirant;
GRANT
student@my_db=> \dp suptab
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+--------+---------+---------------------------+--------------------+----------
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=r*/postgres +| |
| | | aspirant=r/student | |

Привилегия успешно была передана, теперь читать таблицу могут и роль student, и роль aspirant.

Изъятие привилегий​

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

Попробуем лишить роль aspirant привилегии чтения таблицы suptab от имени postgres.

student@my_db=> \c - postgres
You are now connected to database "my_db" as user "postgres".
postgres@my_db=# REVOKE SELECT ON suptab FROM aspirant;
REVOKE
postgres@my_db=# \dp suptab
Access privileges
Schema | Name | Type | Access privileges | Column privileges |
--------+--------+---------+---------------------------+--------------------+-
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=r*/postgres +| |
| | | aspirant=r/student | |
(1 row)

Несмотря на вроде выполненный отзыв привилегий, в поле Access privileges в записи роли aspirant ничего не изменилось.

Это специфика команды REVOKE. При выполнении запроса на отзыв привилегий система не нашла те, которые можно было бы отозвать. Такая ситуация не считается ошибкой, поэтому и вернула стандартный вывод.

Роль postgres не выдавала привилегию SELECT роли aspirant, поэтому напрямую отозвать ее не может. Есть три варианта, как это можно сделать:

  • отозвать привилегию от имени student;
  • отозвать только те привилегии, которые student выдавал с помощью права передачи, от имени postgres;
  • отозвать все привилегии, которые student когда-либо выдавал, от имени postgres.

У каждого варианта есть свои плюсы и минусы. Так отзыв привилегий от имени роли student позволяет точечно ограничить роль aspirant, лишив ее только привилегии SELECT. Однако в таком случае требуется доступ к роли student. В нашем случае действия выполняются от имени суперпользователя, поэтому проблем с переключением на роль student не возникло бы. Второй вариант позволяет лишить привилегии SELECT все роли, которые получили данное право от student благодаря праву передачи (GRANT OPTION). Самый радикальный вариант — третий, когда отзываются все привилегии, которые student когда либо выдавал.

Примеры использования вариантов команды REVOKE

Предположим, что для таблицы suptab выданы следующие привилегии:

Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+--------+-------+---------------------------+-------------------+----------
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=ar*/postgres +| |
| | | aspirant=r/student | |
(1 rows)

Применим первый вариант.

  1. Отозвать привилегию от имени student. Необходимо переключиться на роль student и от его имени отозвать привилегию роли aspirant.

    postgres@my_db=# SET ROLE student;
    SET ROLE
    postgres@my_db=# REVOKE SELECT ON suptab FROM aspirant;
    REVOKE

    postgres@my_db=# \dp suptab
    Access privileges
    Schema | Name | Type | Access privileges | Column privileges | Policies
    -------+--------+-------+---------------------------+-------------------+----------
    public | suptab | table | postgres=arwdDxt/postgres+| |
    | | | student=ar*/postgres +| |
    (1 rows)

    Данный способ позволяет изъять определенную привилегию у нужной роли.

Применим второй вариант к той же ситуации с привилегиями.

  1. Отозвать только те привилегии, которые student выдавал с помощью права передачи, от имени postgres можно двумя способами: с сохранением привилегии SELECT у student и с его изъятием.

    Если нет необходимости лишать роль student привилегии на чтение таблицы, в начале команды REVOKE нужно указать ключевое слово GRANT OPTION FOR, а в конце — CASCADE. Первое ключевое слово лишит роль права передачи, но сохранит привилегию, а второе — изымет привилегию у всех ролей, которые получили ее от student.

    postgres@my_db=# REVOKE GRANT OPTION FOR SELECT ON suptab FROM student CASCADE;
    REVOKE
    postgres@my_db=# \dp suptab
    Access privileges
    Schema | Name | Type | Access privileges | Column privileges | Policies
    --------+--------+-------+---------------------------+-------------------+----------
    public | suptab | table | postgres=arwdDxt/postgres+| |
    | | | student=ar/postgres | |
    (1 rows)

    Если же нужно лишить привилегии SELECT в том числе и саму роль student, ключевое слово GRANT OPTION FOR не указывается.

    postgres@my_db=# REVOKE SELECT ON suptab FROM student CASCADE;
    REVOKE
    postgres@my_db=# \dp suptab
    Access privileges
    Schema | Name | Type | Access privileges | Column privileges | Policies
    --------+--------+-------+---------------------------+-------------------+----------
    public | suptab | table | postgres=arwdDxt/postgres+| |
    | | | student=a/postgres | |
    (1 rows)

Перед применением третьего варианта немного усложним ситуацию с привилегиями.

Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+----------+-------+---------------------+-------------------+----------
public | suptab | table | student=r*/postgres+| |
| | | aspirant=r/student | |
public | suptab_1 | table | student=a*/postgres+| |
| | | aspirant=a/student | |
(2 rows)

Теперь есть две таблицы, в которых роль student имеет право передачи определенной привилегии, а роль aspirant получила их от student. Применим третий вариант.

  1. Отозвать все привилегии, которые student когда-либо выдавал, от имени postgres можно с помощью ключевого слова ALL PRIVILEGES ON. Поскольку есть две таблицы, на которые у роли student есть привилегии, чтобы изъять их все, добавим связку ключевых слов ALL TABLES IN SCHEMA public. Такая команда лишит и роль student всех привилегий на всех таблицы в общей схеме, но и роли, которые получили от student какие-либо привилегии.

    postgres@my_db=# REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM student CASCADE;
    REVOKE
    postgres@my_db=# \dp
    Access privileges
    Schema | Name | Type | Access privileges | Column privileges | Policies
    --------+----------+-------+--------------------------+-------------------+----------
    public | suptab | table | | |
    public | suptab_1 | table | | |
    (2 rows)

    Как видим, все привилегии исчезли. Данный способ является самым радикальным, и поэтому опасным.

Для демонстрации работы с отзывом не только привилегии, но и права передачи, выберем второй вариант. При указании ключевого слова GRANT OPTION роль student лишится права передачи привилегии, а ключевое слово CASCADE изымет привилегию у всех ролей, которые получили ее от student.

postgres@my_db=# REVOKE GRANT OPTION FOR SELECT ON suptab FROM student CASCADE;
REVOKE

Проверим привилегии на таблицу suptab.

postgres@my_db=# \dp suptab
Access privileges
Schema | Name | Type | Access privileges | Column privileges |
--------+--------+---------+---------------------------+--------------------+-
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=r/postgres | |

Привилегии у роли aspirant пропали, но сохранились у student уже без символа *.

Права по умолчанию​

Предоставлять каждый раз привилегии на новые объекты может быть весьма неудобно, поэтому в PostgreSQL есть механизм предоставления привилегий по умолчанию с помощью команды ALTER DEFAULT PRIVILEGES. Например, при установке привилегий по умолчанию на схему все новые объекты в ней автоматически получат данные привилегии.

Для примера создадим от имени student схему и установим на нее привилегии по умолчанию.

postgres@my_db=# \c - student
You are now connected to database "my_db" as user "student".
student@my_db=> CREATE SCHEMA def_sch;
CREATE SCHEMA

Установка привилегий по умолчанию не сильно отличается от выдачи привилегий: нужно только указать ключевое слово в начале и целевой объект.

student@my_db=> ALTER DEFAULT PRIVILEGES IN SCHEMA def_sch GRANT SELECT ON TABLES TO aspirant;
ALTER DEFAULT PRIVILEGES

Теперь при создании любой таблицы в схеме def_sch роль aspirant будет автоматически получать на них привилегию SELECT.

Для просмотра привилегий по умолчанию есть отдельная метакоманда \ddp.

student@my_db=> \ddp
Default access privileges
Owner | Schema | Type | Access privileges
----------+---------+-------+--------------------
student | def_sch | table | aspirant=r/student
(1 rows)

В выводе прописывается владелец схемы (student), тип объектов, на которые будут распространяться привилегии (table) и сама ACL запись, которая будет автоматически записана в метаданных объекта (aspirant=r/student).

Создадим в схеме def_sch пустую таблицу new_tab. Для этого нужно указать название схемы, а через точку — название таблицы. Чтобы создать пустую таблицу, можно использовать пустые скобки.

student@my_db=> CREATE TABLE def_sch.new_tab();
CREATE TABLE

Теперь проверим привилегии на новую таблицу.

student@my_db=> \dp def_sch.new_tab
Access privileges
Schema | Name | Type | Access privileges | Column privileges |
---------+---------+---------+-------------------------+--------------------+-
def_sch | new_tab | table | student=arwdDxt/student+| |
| | | aspirant=r/student | |
(1 row)

Роль aspirant успешно получила привилегию чтения для таблицы new_tab.

Итоги​

  • Привилегии хранятся в ACL в формате grantee=privilege[*]/grantor;
  • Назначать привилегии могут владелец объекта, роль с правом передачи и суперпользователь;
  • Команда GRANT выдает привилегии, команда REVOKE — изымает;
  • Для таблиц: SELECT (r), INSERT (a), UPDATE (w), DELETE (d), TRUNCATE (D), REFERENCES (x), TRIGGER (t);
  • Для баз данных: CREATE (C), CONNECT (c), TEMPORARY (T);
  • Для схем: USAGE (U), CREATE (C);
  • Привилегии можно выдавать на отдельные столбцы таблицы: GRANT SELECT(столбец) ON таблица TO роль;
  • Опция GRANT OPTION дает получателю право передавать привилегию — в ACL обозначается символом *;
  • REVOKE … CASCADE изымает привилегии у всех ролей, получивших их через право передачи.

Самопроверка​

Вопрос 1

Какие привилегии могут быть выданы на таблицы и представления? Выберите все верные варианты.

Вопрос 2

Выполнен запрос:

student@my_db=> GRANT SELECT(n),INSERT(n,t) ON ptab TO aspirant;

В выводе \dp ptab в столбце Column privileges для столбца n появится запись aspirant=ar/student. Что означает ar?

Вопрос 3

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

Вопрос 4

Выполнены команды:

postgres@my_db=# GRANT SELECT ON suptab TO student WITH GRANT OPTION;
student@my_db=> GRANT SELECT ON suptab TO aspirant;

В выводе \dp suptab для student в Access privileges появится символ. Какой?

Вопрос 5

Роль postgres пытается отозвать привилегию у aspirant, которую выдала student:

postgres@my_db=# REVOKE SELECT ON suptab FROM aspirant;

Что произойдет?

Вопрос 6

Выполнена команда:

postgres@my_db=# REVOKE GRANT OPTION FOR SELECT ON suptab FROM student CASCADE;

Что произойдет?

Вопрос 7

Выполнены команды:

student@my_db=> ALTER DEFAULT PRIVILEGES IN SCHEMA def_sch GRANT SELECT ON TABLES TO aspirant;
student@my_db=> CREATE TABLE def_sch.new_tab();

Какие привилегии получит aspirant на new_tab?