Fn my permissions: примеры (SQL)

Полный справочник по работе с fn_my_permissions в Microsoft SQL
Раздел: Функции атомарности меток доступа (LBAC), Безопасность
fn_my_permissions(securable, 'securable_class'): table

Описание функции fn_my_permissions

Встроенная функция fn_my_permissions в Microsoft SQL Server используется для возврата списка разрешений, которые есть у текущего пользователя (или участника) на указанный защищаемый объект. Эта функция удобна для аудита прав доступа и отладки проблем, связанных с разрешениями. Она доступна начиная с SQL Server 2005.

Функция возвращает табличное значение (таблицу), что позволяет использовать её в предложении FROM.

Синтаксис:
fn_my_permissions ( securable , 'securable_class' )

Аргументы:

  • securable (защищаемый объект): Имя защищаемого объекта. Если аргумент равен NULL (по умолчанию), функция возвращает разрешения для текущего пользователя для всего класса объектов. Может быть именем объекта (например, 'MyTable'), именем схемы или именем базы данных.
  • securable_class (класс защищаемого объекта): Имя класса, к которому относится защищаемый объект. Это обязательный строковый аргумент. Примеры значений: 'DATABASE', 'SCHEMA', 'OBJECT_OR_COLUMN', 'USER', 'ROLE'.

Возвращаемое значение:
Функция возвращает таблицу с тремя столбцами:

  • entity_name: Имя защищаемого объекта, для которого выводятся разрешения.
  • subentity_name: Имя столбца, если разрешение относится к столбцу таблицы или представления. В противном случае — NULL.
  • permission_name: Имя разрешения (например, SELECT, INSERT, UPDATE, DELETE, EXECUTE, CONTROL, ALTER, VIEW DEFINITION).

Примеры использования функции

Пример 1: Разрешения текущего пользователя в текущей базе данных.

SELECT * FROM fn_my_permissions(NULL, 'DATABASE');
entity_name | subentity_name | permission_name
------------|----------------|-----------------
MyDatabase  | NULL           | CONNECT
MyDatabase  | NULL           | CREATE SCHEMA
MyDatabase  | NULL           | CREATE TABLE

Пример 2: Разрешения на конкретную таблицу.

SELECT * FROM fn_my_permissions('Sales.Orders', 'OBJECT');
entity_name | subentity_name | permission_name
------------|----------------|-----------------
Orders      | NULL           | SELECT
Orders      | NULL           | INSERT

Пример 3: Разрешения на схему.

SELECT * FROM fn_my_permissions('Sales', 'SCHEMA');
entity_name | subentity_name | permission_name
------------|----------------|-----------------
Sales       | NULL           | SELECT
Sales       | NULL           | INSERT
Sales       | NULL           | UPDATE

Похожие функции в MS SQL Server

В SQL Server есть другие функции для проверки разрешений:

  • HAS_PERMS_BY_NAME: Возвращает скалярное значение (1, 0 или NULL), указывающее, есть ли у текущего пользователя определённое разрешение на указанный объект. Функция более специфична, так как проверяет конкретное право. Её использование предпочтительно в логических условиях (например, в IF или WHERE), когда нужно проверить наличие одного конкретного разрешения.
  • sys.fn_builtin_permissions: Возвращает список встроенных разрешений для сервера. Эта функция полезна для получения полного списка всех возможных разрешений в системе, а не прав текущего пользователя.
  • Динамические административные представления (DMV): Представления типа sys.database_permissions и sys.server_permissions предоставляют полную информацию о всех выданных разрешениях в базе данных или на сервере. Их использование сложнее, но они дают больше контроля и детализации для административных запросов.

Альтернативы в других СУБД и языках

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

PostgreSQL: Используются представления информационной схемы, такие как information_schema.table_privileges, или системные представления, например, pg_catalog.pg_roles в сочетании с функциями проверки членства.

SELECT grantee, privilege_type
FROM information_schema.role_table_grants
WHERE table_name = 'orders';

Oracle: Существуют представления, такие как USER_TAB_PRIVS (права на объекты пользователя) или SESSION_PRIVS (права текущей сессии).

SELECT privilege FROM USER_TAB_PRIVS WHERE table_name = 'EMPLOYEES';

MySQL: Для проверки привилегий используется оператор SHOW GRANTS или запросы к системным таблицам базы данных mysql, например, mysql.user.

SHOW GRANTS FOR CURRENT_USER();

SQLite: Концепция детальных разрешений отсутствует. Управление доступом обычно осуществляется на уровне файловой системы или через механизмы приложения.

Типичные ошибки при использовании

1. Некорректное указание класса объекта. Если класс указан неверно, функция вернёт пустой результат или ошибку.

-- Ошибка: 'MYCLASS' не является допустимым классом защищаемых объектов.
SELECT * FROM fn_my_permissions('MyTable', 'MYCLASS');
Сообщение 15505, уровень 16, состояние 1...
'MYCLASS' is not a valid securable class.

2. Отсутствие объекта или недостаточные права для его просмотра. Если указанного объекта не существует или у пользователя нет прав даже на его просмотр, функция вернёт пустой набор строк.

-- Таблица NonExistentTable не существует
SELECT * FROM fn_my_permissions('NonExistentTable', 'OBJECT');
(0 rows affected)

3. Попытка проверить разрешения для другого пользователя. Функция возвращает только права текущего пользователя. Для проверки прав другого участника потребуются другие средства, например, динамические административные представления.

Изменения в последних версиях

Функция fn_my_permissions появилась в SQL Server 2005 и с тех пор её синтаксис и основные возможности не претерпели значительных изменений. В новых версиях SQL Server (например, начиная с 2012) могут добавляться новые классы защищаемых объектов или новые разрешения (например, для компонентов Always On или маскирования данных), которые автоматически становятся доступны для проверки через эту функцию. Рекомендуется обращаться к документации по конкретной версии для получения списка всех поддерживаемых классов объектов.

Расширенные и нераспространённые примеры

Пример 1: Проверка разрешений на уровне столбца. Функция может показывать права GRANT или DENY на отдельные столбцы, если они были установлены.

Пример sql
-- Предположим, есть право SELECT на столбец PhoneNumber
SELECT * FROM fn_my_permissions('Person.Contact', 'OBJECT_OR_COLUMN');
entity_name | subentity_name | permission_name
------------|----------------|-----------------
Contact     | NULL           | SELECT
Contact     | PhoneNumber    | SELECT
Contact     | NULL           | UPDATE

Пример 2: Комбинация с HAS_PERMS_BY_NAME для детального аудита. Запрос, который для всех таблиц в схеме показывает, есть ли у текущего пользователя право SELECT.

Пример sql
SELECT
    t.name AS TableName,
    HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name), 'OBJECT', 'SELECT') AS HasSelect
FROM sys.tables AS t
WHERE t.schema_id = SCHEMA_ID('Sales');
TableName | HasSelect
----------|-----------
Orders    | 1
Customers | 0

Пример 3: Проверка серверных разрешений.

Пример sql
SELECT * FROM fn_my_permissions(NULL, 'SERVER');
entity_name | subentity_name | permission_name
------------|----------------|-----------------
null        | NULL           | CONNECT SQL
null        | NULL           | VIEW ANY DATABASE

Пример 4: Использование в процедуре для условного выполнения кода.

Пример sql
IF EXISTS (
    SELECT 1 FROM fn_my_permissions('Sales.Orders', 'OBJECT')
    WHERE permission_name = 'INSERT'
)
BEGIN
    PRINT 'У пользователя есть право INSERT на таблицу Orders.';
END

MS SQL fn_my_permissions function comments

En
Fn my permissions Returns a list of permissions effectively granted to the principal on a securable