Встроенная аутентификация пользователей в InterBase 7.5

KDV, 14.05.2005, последнее обновление – 08.05.2007.

Одним из важных нововведений в InterBase 7.5 является аутентификация пользователей, встроенная в базу данных. Давайте сначала посмотрим, как было раньше:
 

Стандартная схема

В InterBase для хранения списка пользователей использовалась отдельная, специальная база данных под названием isc4.gdb. В InterBase 7.0 ее имя было сменено на admin.ib, и кроме того, в ibconfig появился параметр ADMIN_DB, который позволяет задать любое имя этой базы данных.


В isc4.gdb/admin.ib находится основная таблица USERS, в которой хранится имя пользователя, пароль и другие параметры. При подсоединении клиента к базе данных в InterBase происходит следующее:
  1. клиентская часть шифрует пароль алгоритмом des с потерей данных, и передает имя пользователя и зашифрованный пароль серверу.
  2. сервер шифрует полученный пароль еще раз алгоритмом des с потерей данных, затем обращается к isc4/admin к таблице USERS, находит нужного пользователя, и сверяет полученный пароль с хранимым.
  3. если пароли совпадают, пользователь "соединяется" с базой данных, которую он указал. Если не совпадают, коннекта пользователя к базе данных не происходит.
При этом, для доступа к любой базе данных на этом сервере, пользователь должен быть занесен в isc4/admin. Дальше, в конкретной базе данных, права доступа пользователя определяется выданными ему правами (grant).

Такая схема неудобна для
  • однопользовательских приложений. Распространять приходится и базу, и admin.ib.
  • распространяемых баз данных. Любой может "подсунуть" серверу свою admin.ib с SYSDBA/masterkey, и получить полный контроль над базой данных.
  • систем, где пользователь должен "попадать" только в те базы данных, с которыми ему можно работать.
 

Embedded User Authentification (EUA)

В InterBase 7.5 добавлена возможность либо отказаться от использования admin.ib, либо комбинировать admin.ib и контроль пользователей в базе данных. Для этого расширены атрибуты ряда системных таблиц, и добавлены новые SQL операторы для управления данной функциональностью (в gsec также добавлена опция -user_database для управления пользователями в таких базах.

Данная функциональность поддерживается только для ODS 11.2, то есть баз данных, созданных в InterBase 7.5. Причем, предыдущие версии InterBase, например, 7.1 и ниже, при попытке подсоединиться к такой базе данных будут выдавать два вида сообщений:
  • product DATABASE ACCESS is not licensed
для баз данных, в которых EUA включено или выключено
  • internal gds software consistency check (decompression overran buffer (179), file: sqz.c line: 229)
для баз данных, в которых EUA не включали ни разу

То есть, никаким способом, кроме как из InterBase 7.5 и, указав требуемый пароль для конкретного пользователя, хранимого в базе, подсоединиться к этой базе данных нельзя (опустим вариант "взлома" такой БД, то есть ее редактирования в HEX-editor).

Включение EUA

Включить EUA в базе можно двумя способами:
  1. При создании БД, указав в CREATE DATABASE дополнительную опцию WITH ADMIN OPTION
  2. Для любой БД ODS 11.2, выдав оператор
ALTER DATABASE ADD ADMIN OPTION

В любом случае среди системных таблиц баз данных ODS 11.2 всегда присутствует таблица RDB$USERS. Это эквивалент таблицы USERS из admin.ib (добавлены столбцы RDB$DEFAULT_ROLE, RDB$USER_ACTIVE, RDB$USER_PRIVILEGE).

При включении EUA оно сразу становится активным, и в таблице RDB$USERS появляется стандартная запись пользователя SYSDBA с паролем masterkey, и с RDB$USER_PRIVILEGE = 1. После этого при подсоединении к БД сервер игнорирует наличие или отсутствие данного пользователя в admin.ib, а так же его пароль. То есть, при включенной EUA к базе можно подсоединиться только указав точную комбинацию username/password, хранимую в rdb$users.

EUA можно на время деактивировать командой
ALTER DATABASE SET ADMIN OPTION INACTIVE
и активировать
ALTER DATABASE SET ADMIN OPTION ACTIVE

При деактивации во все записи пользователей в RDB$USERS просто выставляется RDB$USER_ACTIVE = 'N', в том числе и для SYSDBA. При активации наоборот, RDB$USER_ACTIVE устанавливается в 'Y', для всех пользователей. Будьте внимательны, если перед деактивацией EUA часть пользователей была заблокирована – при активации EUA к базе данных получат доступ все пользователи (то есть, все учетные записи EUA будут включены).

Удалить EUA целиком и полностью, вместе со всеми записями пользователей, можно командой
ALTER DATABASE DROP ADMIN OPTION

Это очистит таблицу RDB$USERS, и восстановит функционирование стандартной схемы аутентификации (через admin.ib).

Управление пользователями

После того, как EUA включено, можно управлять пользователями.
{CREATE | ALTER} USER SET
option : PASSWORD
[NO] DEFAULT ROLE
[NO] SYSTEM USER NAME
[NO] GROUP NAME
[NO] UID
[NO] GID
[NO] DESCRIPTION
[NO] FIRST NAME
[NO] MIDDLE NAME
[NO] LAST NAME ACTIVE INACTIVE

Примеры:
CREATE USER TEST SET PASSWORD 'TEST', NO LAST NAME, DEFAULT ROLE ABC

В результате будет создан и активен пользователь TEST с паролем TEST, с столбцом LAST_NAME равным NULL, и с ролью по умолчанию ABC (и rdb$user_privilege = 0, то есть "не владелец БД"). То же самое можно выполнить набором команд
CREATE USER TEST SET PASSWORD 'TEST';
ALTER USER TEST SET NO LAST NAME, DEFAULT ROLE ABC;

Обратите внимание, что можно "включать" и "выключать" пользователей командой alter user xxx set inactive/active. В стандартной admin.ib такой возможности нет.

Порядок аутентификации

Стоит пояснить, как именно происходит подключение в случае активной EUA в базе данных:
  • Сервер открывает конкретную БД.
  1. EUA выключено – аутентификация пользователя производится из admin.ib
  2. EUA включено – аутентификация пользователя (любого, в т. ч. SYSDBA) производится из rdb$users этой БД
То есть, при включении SYSDBA и смене пароля для SYSDBA, подключиться к данной БД от имени SYSDBA можно будет только указав этот пароль.
 
Внимание! Присутствие admin.ib все равно необходимо. Сервер при попытке соединения с БД требует наличия admin.ib независимо от того, включено EUA в подсоединяемой БД или нет.
 

Комбинирование схем пользователей

Итак, в InterBase 7.5 поддерживается 2 схемы управления пользователями – стандартная и EUA. Это позволяет строить следующие схемы:
  1. стандартная: Все пользователи в admin.ib, имеют доступ ко всем базам, права доступа в конкретной базе определяются grant.
  2. EUA: Пользователи конкретной БД определены только в ней, соответственно, только они могут к ней подсоединиться.
  3. стандартная+EUA 1: SYSDBA везде одинаков (включая пароль), то есть администрирует все базы на сервере. Базы на сервере можно разделить на 2 набора: один набор без EUA – общий доступ пользователей из admin.ib, и второй набор с EUA – доступ только тех пользователей, которые определены в конкретной БД
  4. стандартная+EUA 2: Пользователи везде одинаковые (копируются например из одного источника), у SYSDBA пароли разные. То есть, один SYSDBA управляет теми базами, где нет EUA, и другие SYSDBA – теми где EUA включено.
  5. стандартная+EUA 3: Пользователи и пароли SYSDBA разные для баз без EUA и с EUA.
На рисунке изображен пример, когда два разных пользователя подключаются к разным БД.


Пользователь 1 может подключиться к тем базам данных, где EUA не включен. Для доступа к DB1.IB необходимо создать пользователя USER1 в этой БД, и указать этот же или иной пароль (если необходимо).

Пользователь 2 может подключиться только к DB1.IB. Если его внести в ADMIN.IB, он сможет работать с базами, где EUA не включен.
 

Backup/Restore

В данный момент, в версии InterBase 7.5.0.174 обнаружено следующее поведение (исправлено в 7.5.1.162):
  • После restore столбец rdb$user_privilege таблицы rdb$users имеет значение null. Если для SYSDBA это "незаметно", то в случае, когда владельцем (owner) базы является не SYSDBA, а скажем, пользователь TEST – ни данный пользователь ни остальные пользователи не могут залогиниться к такой БД.
Исправить ситуацию можно залогинившись к этой БД пользователем SYSDBA, и изменив значение указанного столбца с null на 1 для владельца БД, и на 0 для остальных пользователей. После данной процедуры работоспособность EUA восстанавливается.

В Borland это признано багом IB 7.5.0.174. Вариант обхода проблемы: или обновиться до 7.5.1.162 и выше, или
перед backup отключаем EUA (alter database set admin option inactive), а после restore – включаем (alter database set admin option active). Однако, для избежания смены owner (если это не sysdba), в admin.ib должен быть пользователь, который является владельцем БД с EUA.

Другие вопросы

Иногда, с разными целями, базу данных создают не от имени SYSDBA – например, для того чтобы использовать владельца БД (owner) как "backup user" (при этом все объекты создаются и модифицируются от имени SYSDBA, а owner не может их изменить). В этом случае пользователь, создавший БД, является ее владельцем, и может делать backup/restore оставаясь владельцем как БД так и всех созданных им объектов. При включении EUA и использовании данной техники есть несколько особенностей.
  1. Создаем базу данных не от имени SYSDBA, а например от имени пользователя TEST. После создания TEST становится владельцем БД. Разумеется, на данном этапе в admin.ib должен быть пользователь TEST (с паролем test, например).
  2. Включаем EUA в базе.
ALTER DATABASE ADD ADMIN OPTION;
В таблице RDB$USERS появляется запись о пользователе TEST с паролем test (пароль хранится дважды зашифрованный, как и в admin.ib), rdb$user_active = Y и rdb$user_privilege = 1
  1. Добавим "локального" пользователя USR
create user USR set password 'usr';
  1. Теперь получается интересная ситуация. Backup может сделать пользователь TEST, но какой именно – из admin.ib, или из этой БД? Сменим пароль пользователя TEST в admin.ib на значение tttt.
  2. Пробуем backup от пользователя TEST из admin.ib
gbak -b db.ib db.ibk -v -user TEST -pass tttt
Не проходит. Пробуем пользователя из EUA
gbak -b db.ib db.ibk -v -user TEST -pass test
Проходит. То есть, делать backup может только пользователь, внесенный в eua (то есть владелец БД).
  1. На данном этапе кажется, что в admin.ib можно удалить пользователя TEST, или вообще удалить admin.ib. Но, без admin.ib сервер не будет соединяться даже с БД, в которой включено EUA. И, restore должен проходить от имени пользователя, присутствующего в admin.ib, т.к. на этапе restore базы данных до конца невозможно узнать, есть в ней EUA или нет.
gbak -c db.ibk 1.db -v user TEST -pass test
Не проходит, как и ожидалось. В admin.ib у пользователя TEST другой пароль.
gbak -c db.ibk 1.db -v user TEST -pass tttt
Restore прошел успешно.
 
Но, как уже было сказано выше, столбец rdb$user_privilege = NULL, и в результате подсоединиться к восстановленной БД не может ни один пользователь EUA (включая пользователя TEST с паролем test).

Подсоединяемся как TEST/tttt, меняем у записи TEST в rdb$users столбец rdb$user_privilege с null на 0, отсоединяемся, и ... EUA начинает работать опять (см. выше пример временного решения данной проблемы).

Отсюда можно сделать несколько выводов:
  • EUA в данной версии "не переживает" backup/restore не только для owner, но и для SYSDBA. SYSDBA для баз данных "царь и бог", поэтому rdb$user_privilege = null незаметно для разработчика. Это становится заметно, когда БД начинает эксплуатироваться в рабочем режиме.
  • При restore вообще то нет никакой необходимости проверять username/password. Для обычных БД restore с другим именем пользователя делается для смены владельца (owner) базы данных. Однако, поскольку при EUA все пользователи внутри базы, получается, что restore невозможно сделать никаким другим способом, кроме как указав другого пользователя при gbak -c. Собственно, SYSDBA из admin.ib может быть "не тем пользователем", что SYSDBA в базе с EUA, если у них разные пароли.
  • Возможно, было бы лучше сделать флаг в Header Page базы данных, означающий присутствие EUA, тогда можно было бы игнорировать пользователя при restore
  • Несмотря на кажущуюся "автономность" EUA, без наличия admin.ib невозможно ни подсоединиться к БД, и ни сделать restore.
 

Плюсы и минусы

Обобщим плюсы и минусы данной функциональности:

Плюсы

  • доступ sysdba контролируется самой базой данных, т. е. база "непереносима" между серверами без знания пароля SYSDBA в БД
  • пользователей можно "включать" и "выключать" без их удаления
  • пользователями можно оперировать при помощи SQL
  • информация о пользователях, включая ФИО и т. д. доступна в этой же БД
  • пользователи получают DEFAULT ROLE (роль по умолчанию – не проверял, поэтому не знаю, работает или нет).

Минусы

  • все равно нельзя обойтись без admin.ib
  • restore должен выполняться от пользователя из admin.ib
  • "защита" может быть взломана hex-editor-ом

Подпишитесь на новости Firebird в России

Подписаться