Самоучитель по SQL-сервер в Linux



Предоставление привилегий

В PostgreSQL учет привилегий ведется при помощи списков управления доступом (access control lists, ACL). Информация, хранящаяся в этих списках, указывает, каким пользователям разрешена выборка, обновление и другие способы модификации объектов в базе данных. Для всех объектов баз данных PostgreSQL (таблиц, представлений и последовательностей) существует набор привилегий и ограничений доступа. Суперпользователи и владельцы объектов изменяют ACL при помощи пары команд SQL: GRANT и REVOKE.

Как было сказано в главе 9, когда пользователь создает базу данных, он косвенно становится владельцем этой базы. Аналогичный принцип распространяется и на другие объекты: они также принадлежат пользователю, который ввел соответствующую команду SQL CREATE.

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

Управление доступом

Как упоминалось выше, списки управления доступом относятся к трем категориям объектов баз данных: таблицам, спискам и последовательностям. Для этих объектов существуют четыре общие привилегии, которые могут предоставляться пользователям или группам и отбираться у них. Отзыв прав требуется только для отмены их предшествующего предоставления. Изначально пользователи и группы не имеют никаких прав.

Сводка прав ACL просматривается в клиенте psql при помощи команды \z. Команда выводит информацию обо всех правах доступа для базы данных, подключенной в настоящий момент. Чтобы просмотреть права для конкретного объекта, передайте имя этого объекта в качестве параметра команды \z. Вместо имени можно задать регулярное выражение, чтобы просмотреть привилегии для группы объектов.

В табл. 10.2 перечислены привилегии доступа, поддерживаемые в PostgreSQL. Каждой привилегии соответствует определенная буква, которая используется как сокращенное обозначение этой привилегии и включается в выходные данные команды \z клиента psql.

Таблица 10.2. Привилегии доступа в PostqreSQL

Ключевое слово

Символ

Описание

SELECT

r

Пользователю разрешается выборка данных из таблицы, представления или последовательности (хотя функция nextval О не может вызываться при наличии только права SELECT). Также используется термин «право чтения»

INSERT

a

Пользователю разрешается вставка новых записей в таблицу. Также используется термин «право дополнения»

UPDATE, DELETE

w

Пользователю разрешается модификация и удаление записей из таблицы. При предоставлении хотя бы одного из прав UPDATE или DELETE другое право предоставляется автоматически. Также используется термин «право записи»

RULE

R

Пользователю разрешается создание правила перезаписи для таблицы или представления

ALL

arwR

Сокращенное обозначение, используемое для предоставления или отзыва всех прав. Само по себе ключевое слово ALL правом не является. Указание ключевого слова ALL приводит к предоставлению прав SELECT, INSERT, UPDATE, DELETE и RULE

Предоставление привилегий командой GRANT

Для предоставления привилегий пользователям и группам используется команда SQL GRANT. Синтаксис команды GRANT:

GRANT привилегия [, ...] ON объект [, ...]

ТО { PUBLIC | пользователь \ GROUP группа }

Параметр привилегия заменяется любой из привилегий, перечисленных в табл. 10.2, а параметр объект определяет имя объекта базы данных (таблицы, представления или последовательности), для которого предоставляется привилегия. Секция, следующая после ключевого слова ТО, указывает, кому предоставляется привилегия. Допускается перечисление нескольких привилегии и объектов через запятую.

В одной команде GRANT может использоваться только один из вариантов, перечисленных за ключевым словом ТО. С ключевым словом PUBLIC привилегия предоставляется всем пользователям. Если указано имя пользователя или группы, привилегия предоставляется конкретному пользователю или группе.

Предположим, пользователю manager понадобились все права доступа к таблицам customers, books, editions и publishers. В листинге 10.17 все эти права предоставляются пользователю manager в одной команде GRANT.

Листинг 10.17. Предоставление привилегий пользователям

booktown=# GRANT ALL ON customers, books, editions, publishers

booktown-# TO manager;

CHANGE

Ключевое слово ALL предоставляет пользователю manager все возможные права доступа (SELECT, UPDATE и т. д.) к перечисленным объектам. Сообщение CHANGE означает, что модификация привилегий прошла успешно. Помните, что для проверки прав доступа к объекту базы данных в psql может использоваться команда \z:

booktown=# \z publishers

Access permissions for database "booktown"

Relation Access permissions

publishers | {"="."manager=arwR"}

(1 row)

Рассмотрим другой пример — использование ключевого слова GROUP для предоставления привилегий членам группы. Допустим, всему отделу сбыта нужно предоставить право просмотра таблицы customers, но без возможности ее модификации. В листинге 10.18 всем членам группы sales предоставляется право доступа SELECT к таблице customers.

Листинг 10.18. Предоставление групповых привилегий

booktown=# GRANT SELECT ON customers TO GROUP sales:

CHANGE

booktown=# \z customers

Access permissions for database "booktown"

Relation | Access permissions

customers | {"="."manager=arwR"."group sales=r"}

(1 row)

Ограничение прав командой REVOKE

По умолчанию обычный пользователь не имеет прав доступа к объектам данным, которые ему не принадлежат. Чтобы отозвать право после его предоставления, владелец объекта (или суперпользователь) может воспользоваться командой REVOKE, имеющей много общего с командой GRANT. Синтаксис команды REVOKE:

REVOKE привилегия [. ...] ON объект [. ... ]

FROM { PUBLIC | пользователь \ GROUP группа }

По своей структуре команда REVOKE идентична команде GRANT. Отличается только название самой команды и ключевое слово FROM заменяется словом ТО.

ПРИМЕЧАНИЕ

Отзыв привилегий с ключевым словом PUBLIC действует только на специальную группу public, в которую входят все пользователи. При этом отзыв прав не влияет на пользователей, которым эти привилегии были предоставлены явно (то есть с указанием конкретных имен).

Предположим, пользователю david было предоставлено право доступа UPDATE к таблице books. В другом отделе пользователю уже не придется редактировать сведения о книгах, и теперь вы хотите отнять у него привилегию UPDATE на доступ к таблице books.

В листинге 10.19 команда \z клиента psql выводит информацию о правах для таблицы books; из результатов видно, что пользователь david имеет право записи в эту таблицу. Команда REVOKE отнимает у пользователя david привилегии UPDATE и DELETE для таблицы books. Фрагмент завершается еще одной командой \z, которая показывает, что привилегия была отозвана успешно.

Листинг 10.19. Отзыв прав

booktown=# \z books

Access permissions for database "booktown"

Relation | Access permissions

books | {"="."manager=arwR"."david=w"}

(1 row)

booktown=# REVOKE UPDATE, DELETE ON books

booktown-# FROM david;

CHANGE

booktown=# \z books

Access permissions for database "booktown"

Relation Access permissions

books | {"="."manager=arwR"}

(1 row)

Представления при контроле доступа

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

Чтобы ограничить доступ к полям, перечислите их в списке полей команды SELECT при создании представления. В результате представление будет возвращать только те поля, которые были указаны вами. Ограничение доступа к записям осуществляется включением секции WHERE в команду SELECT, после чего представление будет состоять из записей, удовлетворяющих условию в секции WHERE (за дополнительной информацией о создании представлений обращайтесь к главе 4).

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

Допустим, в базе данных booktown имеется таблица stock, в которой код ISBN книги связывается с закупочной ценой, розничной ценой продажи и количеством экземпляров на складе. Структуру таблицы иллюстрирует табл. 10.3.

Таблица 10.3. Таблица stock

Поле

Тип

Модификатор

isbn

text

NOT NULL

cost

numeric (5. 2)

 

retail

numeric (5. 2)

 

stock

integer

 

Допустим, вы не хотите, чтобы работники из отдела продаж знали закупочную цену книг. Чтобы ограничить доступ к этой информации, создайте представление, в которое входят данные из полей 1 sbn, retai 1 и stock. В листинге 10.20 мы создаем представление, даем право доступа к нему группе sales и затем проверяем результат командой \z в клиенте psql.

Листинг 10.20. Управление привилегией SELECT с использованием представления

booktown=# CREATE VIEW stock_view

booktown-# AS SELECT isbn, retail, stock

booktown-# FROM stock;

CREATE

booktown=# GRANT SELECT ON stockjhew TO GROUP sales;

CHANGE

booktown=# \z stock

Access permissions for database "booktown"

Relation | Access permissions

stock |

stock_backup j

stock_view | {"=","manager=arwR"."group sales=r"}

(3 rows)

В листинге 10.21 создается новый пользователь barbara, которому предоставляется право SELECT для представления stock_view. Поскольку пользователь barbara изначально не обладает никакими правами доступа к таблице stock, таблица будет недоступна; ситуация не изменяется даже после получения доступа к представлению в результате выполнения команды GRANT.

Листинг 10.21. Управление привилегией SELECT

booktown=# CREATE USER barbara;

CREATE USER

booktown=# GRANT USER barbara SELECT ON stock_view;

booktown=# \c - barbara

You are now connected as new user barbara.

booktown=> SELECT * FROM stock;

ERROR: stock: Permission denied.

booktown=> SELECT * FROM stock_view;

Isbn retail stock

0385121679 36.95 65

039480001X 32.95 31

0394900014 23.95 0

044100590X 45.95 89

0441172717 21.95 77

0451160916 28.95 22

0451198492 46.95 0

0451457994 22.95 0

0590445065 23.95 10

0679803335 24.95 18

0694003611 28.95 50

0760720002 23.95 28

0823015505 28.95 16

0929605942 21.95 25

1885418035 24.95 77

0394800753 16.95 4

(16 rows)

При подключении под именем barbara команда SELECT для представления stock_v1ew выполняется успешно, а выборка из таблицы stock приводит к ошибке Permission denied.




Книжный магазин