InterBase: тормозология и глюконавтика
Страница 17. Пароли и права доступа


Пароли и права доступа

Данная тема состоит из двух основных вопросов: как interbase узнаёт, с кем имеет дело (с каким пользователем) и как принимаются решения относительно того, давать пользователю возможность выполнить операцию, или нет.

Первый вопрос выясняется в момент подключения к БД. Во-первых, все средства, предусматривающие подключение, начиная от функций interbase API и кончая интерактивными утилитами предоставляют возможность явно задать имя и пароль. И если значения указаны, то они имеют приоритет надо всеми остальными умолчаниями. Если же нет, то пробуются два других источника - переменные окружения ISC_* и пользователи Unix, если дело происходит под соответствующей системой.

Из переменных окружения нас в данном случае интересуют две: ISC_USER=имя_пользователя и ISC_PASSWORD=пароль. Эти переменные одинаково воспринимаются подо всеми операционками, которые поддерживает InterBase. Кроме того, они одинаково воспринимаются как утилитами командной строки, так и интерактивными программами, потому что на клиенте их проверяет gds32.dll (linterbasegds.so).

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

Несмотря на то, что сегодня interbase применяется в основном под Windows, по своей природе и истории это в основном юниксовый продукт. Соответственно его система управления правами в большей степени оринетирована на Юниксы. В частности, interbase умеет доверять юниксовой системе, принимая соединения от неё пользователей без проверки пароля. Для этого достаточно, чтобы имя пользователя (без учёта регистра) совпало с именем пользователя, зарегистрированного в системе и чтобы этот пользователь подключался из системы, которой доверяет сервер.

Доверие между системами устанавливается традиционым для Юниксов способом. Во-первых, каждая система доверяет сама себе. То есть подвключения в пределах одного компьютера пройдут без проблем. Внешние подключения должны исходить с клиентов, перечисленных в файле /etc/hosts.eqiv на сервере. Или в файле /etc/gds_hosts.equiv. Первый - общесистемный, его воспринимают все сервисы. Второй Борландовцы придумали под себя. Форматы одинаковы и описаны в юниксовой документации.

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

И так, сервер выудил через параметры, переменные и доверия имя и пароль пользователя. Как же он узнает, допустимы ли они для него, или нет? Для этого существует специальная БД, которая обычно лежит непосредственно в установочном каталоге interbase и как правило, называется, isc4.gdb. Именно туда заносятся все пользователи, регистрируемые через gsec или Server Manager.

В базе всего две таблицы.

HOST_INFO - дополнительная информация об узлах сети. То есть о доверяемых системах, как описано выше. Полей всего два:

HOST_NAME - имя узла. Имеется в виду hostname из TCP/IP. Обратите внимание: без домена! По какой-то странной причине практически все утилиты InterBase не воспринимают имена с доменами. То есть нельзя написать gw.krista.ru, можно только просто gw. Соответственно клиент и сервер должны быть в одном домене.
HOST_KEY - какой-то ключ для данного узла. По всей видимости, предусмотрен какой-то дополнительный механизм для проверки возможности доверия через ключи. Только вот где указать этот ключ на клиенте, я в документации откопать так и не смог.
USERS - информация о самих пользователях.
USER_NAME - имя пользователя в InterBase.
SYS_USER_NAME - хотя по умолчанию имена пользователя в системе и в InterBase должны совпадать, вероятно предусмотрена (не задокументированная сейчас) возможность задавать произвольное соответствие. Это одна из гипотез по поводу существования этого следующего поля. Другая: пользователь, входящий в interbase под указанным именем обязан быть в системе тем-то и принадлежать к группе такой-то, если они указаны. Что из этого правда и работает ли вообще хоть что-то я не проверял.
GROUP_NAME - имя группы. См. замечание к предыдущему пункту.
UID - Численное значение идентификатора пользователя согласно Юниксу. В других системах игнорируется. Как я понял, именно под этим идентификатором в системе запускается процесс (или может где-то - поток), обслуживающий текущего пользователя. При условии, что головной процесс работает под правами root. Данный идентификатор самым непосредственным образом влияет на права доступа к файлам БД.
GID - аналогично предыдущему полю идентификатор группы.
PASSWD - пароль в зашифрованном виде. Шифруются и хранятся только первые 8 символов (хотя вводить можно и больше) согласно классическому юниксовому алгоритму. То есть можно взять какую-нибудь шифровку пароля из /etc/shadow и записать её сюда. И пользователь interbase приобретёт пароль взятый из Юникса.
PRIVILEGE - по всей видимости, ненулевое значение должно указывать на то, что пользователь привилегированный. Прикол в том, что в записи для SYSDBA там обычно null, как и у обычных пользователей.
COMMENT - какой-то комментарий к пользователю. Тоже обычно null.
FIRST_NAME - Имя.
MIDDLE_NAME - Отчество.
LAST_NAME - Фамилия.
FULL_NAME - поле, вычисляемое из FIRST_NAME, MIDDLE_NAME, LAST_NAME.

Итак, как мы видели, имеется предостаточно информации о том, под какими правами должен существовать в системе процесс или поток, работающий на пользователя. Эта информация актуальна для Unix, а так же для Windows NT при работе через протокол NetBEUI. Во всех остальных случаях все процессы InterBase работают под теми правами, под которыми их запустили.

Поведение под Unix описано в разделе Установка под Linux. Оно радикальным образом зависит от того, обезопасились ли Вы при установке, отобрав у interbase права root, или нет. Если да, то несмотря на все настройки, процессы interbase будут работать из-под одного и того же UID. Все файлы БД должны быть доступны ему для записи.

Если же interbase запускается, как root, то всё зависит от пользователя. В первую очередь interbase смотрит, не заданы ли для пользователя конкретные UID и GID. Если да, то процесс переключается на них. Иначе в системе ищется пользователь с тем же именем (ещё раз повторюсь: без учёта регистра). Если найден, то производится переключение на него. А вот если не найден, то процесс остаётся нормально работать под правами root! То есть любое наличие пользователя в InterBase, не прописанного в системе означает дыру в безопасности всей системы. В сочетании с возможностью писать UDF не составляет труда запустить привилегированный shell и получить полную власть.

Таким образом, установка под Unix черезвычайно опасна и требует либо очень внимательного сопровождения, либо переключения на непривилегированный UID. В заключение отмечу, что interbase делает особое исключение для SYSDBA и root. Подключения под SYSDBA порождают в системе процесс с правами root (если есть возможность), а подключения под системным пользователем root на уровне БД считаются эквивалентыми SYSDBA.

Что же касается NT, то там похожие эффекты возникают в NetBEUI. Этот протокол, а точнее, способ его использования Энтями, позволяет соединениям в сервере наследовать права того клиента, который соединение создал. Клиент же при установлении соединения предъявляет те права, под которыми пользователь зашёл в клиентскую систему. Это означает, что сервер сможет открыть БД от имени данного клиента тогда, и только тогда, когда данный клиент имеет права на доступ к файлу БД.

Самый большой прикол состоит в том, что пользователь interbase, в отличие от случая с Юниксом, здесь вообще не причём! Клиентский пользователь Windows предъявляется серверу Windows. Правда, проверка файловых прав делается после того, как пользователь прошёл обычную проверку InterBase. Если клиент вошёл в домен NT, то соответственно его подключение трактуется, примерно как попытка открыть файл БД по сети. Если же клиент в домен не входил, то с точки зрения сервера он рассматривается, как посторонний пользователь. То есть в этом случае база должна быть Read/Write для всех.

Отсюда мораль: если не хотите запутаться - пользуйтесь TCP/IP. Он учитывает только то, что прописано в InterBase, и ничего больше.

Итак, interbase идентифицировал пользователя, убедился, что это точно он, породил ему процесс (или поток) с нужными правами, и процесс успешно открыл файл БД. Всё, можно работать. Рассмотрим теперь, как определяются права пользователей на отдельные объекты БД. Операционная система здесь уже полностью не причём.

 
« Предыдущая статья