Microsoft SQL Server: контрольная по безопасности

Алексей Шуленин

Введение
Общие вопросы безопасности SQL Server
Уровень сервера
Аутентификация. Режимы аутентификации
Права на действия. Роли
Уровень базы данных
Пользователи БД
Роли БД
Уровень объекта
Вместо заключения

 

 

Введение

Почему изо всего богатого спектра новой функциональности SQL Server 7.0 мы выбрали предметом сегодняшнего разговора именно безопасность? Ответ очевиден: коль скоро мы доверяем серверу баз данных хранение информации и коль скоро информация в наши дни является одним из основных ресурсов любой организации, ее утеря или утечка представляет серьезную опасность и способна подчас поставить под угрозу само существование предприятия. Итак, все, что лежит на сервере, должно быть надежно защищено.

Часто под защитой данных подразумевается комплекс программных и/или аппаратных средств, предохраняющих данные от потери или порчи, например, при выходе из строя оборудования. В англоязычной литературе такая защита носит название «обеспечение высокой доступности» (high availability) информации, так как в критически важных для бизнеса (mission-critical) системах данные действительно должны быть доступны для приложений 24 часа в сутки 7 дней в неделю 365 дней в году без права на отказы и сбои. В зависимости от требований к степени доступности данных SQL Server обладает различными средствами для решения этой задачи:

  • Резервное копирование (полное, дифференциальное, журнала транзакций)
  • Сервер «теплого» резерва (на котором первоначально создается полная резервная копия БД, к которой с заданной периодичностью добавляются резервные копии журнала транзакций)
  • Сервер «горячего» резерва в составе отказоустойчивого кластера MSCS. Отметим, что в этом случае клиент обращается не к какому-то серверу в отдельности, а к имени виртуального сервиса на кластере, вне зависимости от того, каким конкретно узлом в данный момент обрабатывается его запрос
  • Тиражирование данных по принципам как плотной, так и слабой целостности, в зависимости от степени автономии автономности сайтов (которая, как известно имеет обратно обратную зависитмость от временного промежутка между внесением и отражением изменений в распределенной системе).

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

Традиционно защита от несанкционированного доступа подразделяется на два этапа. Первое – это аутентификация пользователя, позволяющая убедиться, что он именно тот, за кого себя выдает. Второе - — это управление правами доступа пользователя, с тем, чтобы он а) оперировал только теми объектами, которые ему разрешены и б) совершал над ними только те действия, которые ему дозволяются. Полный набор этих действий зависит от природы объекта, список дозволенных действий, скорее всего, будет разниться для каждого конкретного экземпляра объекта. Дальнейшее изложение материала в соответствии с названием статьи мы построим в форме вопросов (В) и ответов (О). Часть вопросов можно рассматривать как задаваемые от лица читателя автору. Другую часть составляют вопросы, которые, наоборот, автор позволил себе задать читателю. Ни те, ни другие не имеют ничего общего с официальными тестами Microsoft на сертификацию MCDBA, хотя, возможно, окажутся в некоторой степени полезными при подготовке к ним. Материал рассчитан на начинающих администраторов баз данных MS SQL Server 7.0. Мы постараемся сделать акцент на практических аспектах управления безопасностью, хотя ради стройности изложения будем вынуждены чередовать их с теоретическими вопросами по теории.

Общие вопросы безопасности SQL Server

В. Что такое иерархия уровней безопасности SQL Server?

О. Иерархия: Сервер баз данных -> База данных -> Объект базы (таблица, поле таблицы, представление, хранимая процедура, ...) На уровне сервера определяется, имеет ли пользователь вообще право доступа к нему (аутентификация), и если да, то какие действия на уровне сервера ему разрешены. На уровне базы данных проверяется, имеет ли пользователь, прошедший предыдущий уровень, право доступа к данной базе. Наконец, на уровне объекта проверяется, имеет ли пользователь, прошедший предыдущий уровень, право на то действие над объектом, которое он запрашивает.

В. На какие группы делятся права пользователя?

О. Права бывают на выполнение операторов (statement permissions) и на действия над объектами (object permissions). Выделение первой группы связано с необходимостью выполнять действия независимо от экземпляра объекта, например, CREATE TABLE. Некоторые действия не могут быть позволены произвольным пользователям, они четко закреплены за той или иной ролью. Например, выполнять SHUTDOWN могут только члены серверной роли sysadmin. Вторая группа связана с действиями, относящимися к данному конкретному объекту, например, EXECUTE для данной хранимой процедуры.

Уровень сервера

Аутентификация. Режимы аутентификации

В. Каковы способы аутентификации пользователей в SQL Server 7.0?

О. В версии 7.0, как и в предыдущих версиях, существует два основных способа аутентификации: средствами SQL Server и средствами операционной системы. При попытке доступа SQL Server проверяет наличие учетной записи пользователя в системной таблице master..syslogins. Имя учетной записи хранится в поле loginame. Это может быть имя пользователя собственно SQL Server или Windows NT. Для аутентификации первого требуется пароль, хранящийся в зашифрованном виде в поле password. Учетные записи Windows NT считаются уже проверенными операционной системой при получении доступа к ресурсам домена. В этом случае SQL Server получает имя пользователя от Windows NT и полагается на нее в плане проверки «личности» пользователя. Имя и пароль при такой аутентификации вводить, очевидно, не требуется. Собственные пользователи создаются на SQL Server 7.0 с помощью хранимой процедуры sp_addlogin ‘Имя пользователя’, ‘Пароль’, ‘БД по умолчанию’, ‘Язык по умолчанию’, ‘Шифровать ли пароль’. Доступ существующему пользователю Windows NT на SQL Server 7.0 дается хранимой процедурой sp_grantlogin ‘<Имя домена>\<Имя пользователя>’. Естественно, то же самое можно сделать и средствами графического интерфейса (UI) в Enterprise Manager (EM).

В. А как задать БД и язык по умолчанию для пользователей NT?

О. exec sp_defaultdb @loginame=..., @defdb=...; exec sp_defaultlanguage @loginame=..., @language=...

В. Получается, что для собственных пользователей пароли могут и не шифроваться?

О. Следует обратить внимание, что в случае выбора значения параметра encryptopt='skip_encryption' процедуры sp_addlogin пароль пользователя хранится в syslogins в незашифрованном виде как строка из Unicod’овских кодов символов, составляющих пароль. По умолчанию, пароль, естественно, шифруется.

В. Что еще, кроме пароля, шифрует SQL Server?

О. Шифруются следующие типы данных: все пароли, хранящиеся на SQL Server (в том числе, пароли прикладных ролей); определения представлений, хранимых процедур, триггеров (все, что хранится в syscomments) - — при употреблении опции CREATE / ALTER … WITH ENCRYPTION; содержимое сетевых пакетов, которыми обмениваются клиент и сервер, – при выборе сетевой библиотеки Multiprotocol и включении режима шифрации (Server Network Utility -> Multiprotocol -> Edit -> Enable Encryption). В ближайшей версии SQL Server возможность шифрования трафика будет доступна для всех сетевых библиотек.

В. Что означает параметр @sid процедуры sp_addlogin?

О. Security Identifier (секретный идентификатор) пользователя, который также хранится в syslogins, и который можно назначать принудительно при условии, что ни у кого на сервере такого нет. Просто в некоторых приложениях удобнее привязываться не к имени пользователя, а к его sid’у. При @sid=NULL (по умолчанию) он назначается автоматически.

В. Можно ли задать доступ к SQL Server не отдельного пользователя, а группы Windows NT?

О. Да. Exec sp_grantlogin ‘Домен\Группа’. Посмотреть учетные записи групп Windows NT, имеющих право доступа к SQL Server, можно, например, так: select loginame from syslogins where isntgroup = 1. Не найдя имени пользователя Windows NT в явном виде среди записей syslogins, у которых isntuser = 1, SQL Server просматривает у себя все авторизованные группы NT и проверяет членство пользователя в каждой из них. Как только такая группа находится, пользователю разрешается соединение с SQL Server.

В. А может это быть не доменная, а локальная группа того компьютера, на котором установлен SQL Server (если, конечно, этот компьютер не является PDC)?

О. Да, конечно. Вместо имени домена в этом случае нужно использовать префикс BUILTIN\:

exec sp_grantlogin @loginame='BUILTIN\Power Users'.

В. Пользователь NT «Юзер» имеет доступ к SQL Server 7.0 только через свою принадлежность группе «Группа», учетная запись которой имеется в master..sysxlogins. Его исключают из состава этой группы. Будет ли он по-прежнему иметь право доступа к SQL Server?

О. В отличие от предыдущих версий, где SQL Security Manager осуществлял статическое отображение групп и пользователей Windows NT на группы и пользователей SQL Server, в версии 7.0 изменения в принадлежности пользователя к группам учитываются динамически при каждом новом подключении к SQL Server. Утилита SQL Security Manager более не входит в состав SQL Server, так как версия 7.0 работает с действительными учетными записями Windows NT, не требуя их специального отображения на логины SQL Server.

В. В Enterprise Manager пользователя Windows NT, имеющего доступ к SQL Server, можно просто удалить, а можно запретить доступ (Deny Access). В чем разница этих двух опций?

О. В Т-SQL этим опциям соответствуют процедуры sp_revokelogin и sp_denylogin. Первая удаляет учетную запись из syslogins. Вторая вставляет в syslogins запись с явным запретом доступа к SQL Server (или меняет значение поля denylogin, если эта запись уже существует). Для иллюстрации сказанного см. следующий вопрос.

В. Пусть пользователь NT «Юзер» входит в группу NT «Группа». Было сделано sp_grantlogin ‘Домен\Юзер’, sp_grantlogin ‘Домен\Группа’, sp_revokelogin ‘Домен\Юзер’. Будет ли пользователь «Юзер» по-прежнему иметь доступ к SQL Server? А в случае sp_denylogin ‘Домен\Юзер’?

О. В первом случае – да (как член группы «Группа»), во втором – нет.

В. Предусмотрено ли задание отрицательных прав доступа для собственных пользователей SQL Server (аутентификация средствами SQL Server)?

О. Очевидно, нет, потому что если собственный пользователь теряет привилегию доступа к SQL Server, его можно просто удалить - sp_droplogin ‘Имя пользователя SQL Server’

В. Работает ли аутентификация средствами ОС, когда контроллеры домена недоступны?

О. В версиях 6.х – нет. В 7.0 – да. Как уже упоминалось, учетные записи Windows NT, имеющие право доступа к SQL Server 7.0, хранятся в системной таблице syslogins наряду с логинами SQL Server. Даже при недоступности xDC вы можете зайти в Windows NT с использованием кэшированной информации об имени пользователя и о пароле; это имя затем при попытке подключения к SQL Server будет проверено на наличие в syslogins.

В. Как увидеть имя текущего login’а?

О. С помощью функции SYSTEM_USER.

В. В чем отличие модели безопасности SQL Server 7.0 от предыдущей версии?

О. Для аутентификации средствами операционной системы клиент, очевидно, должен передать серверу удостоверяющую его информацию. В версии 6.5 это было возможно только для сетевых библиотек Named Pipes и Multiprotocol. Соответственно, в SQL Server 6.5 существовало три режима безопасности: стандартный (аутентификация средствами SQL Server), интегрированный (средствами ОС) и смешанный (то есть там, где это возможно,– для Named Pipes и Multiprotocol – интегрированный, а для остальных соединений - — стандартный). В SQL Server 7.0 передача аутентифицирующей пользователя информации поддерживается для всех сетевых библиотек, что дает возможность обойтись двумя режимами безопасности: интегрированным и смешанным (аутентификация как средствами SQL Server, так и Windows NT).

В. В предыдущих версиях при выборе режима интегрированной безопасности все администраторы Windows NT отображались на логин sa на SQL Server. Почему сетевой администратор должен автоматически получать административные привилегии на сервере баз данных?

О. В SQL Server 7.0 каждый пользователь или группа Windows NT, имеющие доступ к SQL Server, видны на нем под своими персональными сетевыми именами. Их права на SQL Server определяются администратором SQL Server и никак не связаны с правами Windows NT.

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

О. Режим безопасности выбирается при инсталляции SQL Server и впоследствии может быть изменен в свойствах сервера (Server Properties, закладка Security) в Enterprise Manager, либо через SQL-DMO. В системах, предъявляющих повышенные требования к безопасности, рекомендуется выбирать режим безопасности только средствами Windows NT. Его преимуществами являются возможности назначения срока действия паролей, минимальной длины пароля, закрытия учетной записи после определенного числа неудачных попыток, аудита и т.д. Смешанный режим следует использовать в гетерогенных средах, а также там, где аутентификация средствами Windows NT невозможна, например, если SQL Server установлен на Windows 9х.

В. Существует ли возможность управлять длиной пароля и истечением срока его действия для стандартной аутентификации?

О. Да. Для ограничений на длину пароля, разрешенные символы и пр. можно подправить хранимую процедуру master..sp_password. Например, поставить перед update master.dbo.sysxlogins проверку типа

if len(@new)<5 begin

raiserror('Длина пароля должна быть не меньше 5 символов', -1, -1)

return(1)

end.

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

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

О. Нет. Право редактирования системных процедур есть по сути право записи в поле text таблицы master..syscomments, которым по умолчанию обладает только администратор. Не надо давать его кому попало, только и всего. Защищать же систему от своего администратора, очевидно, бессмысленно – на то он и администратор. Впрочем, надежности ради можно зашифровать текст процедуры с помощью ALTER PROCEDURE … WITH ENCRYPTION. Еще раз подчеркну, что в системах повышенной конфиденциальности, вне сомнения, следует использовать только аутентификацию средствами Windows NT.

В. Хорошо, а как обстоят дела с временными ограничениями при соединении пользователей с SQL Server?

О. Проще всего это достигается при использовании middleware. В принципе, это можно реализовать и без ПО промежуточного слоя, что, однако, потребует определенных ухищрений на серверной стороне. Например, проверка того, разрешено ли пользователю в данное время соединиться с SQL Server затрудняется тем, что в программной модели SQL Server отсутствует в явном виде событие Connect (хотя Disconnect есть). Вот примерный путь решения этой задачи. Изначально пользователям даются минимальные права на SQL Server. Заводится процесс с административными привилегиями, постоянно сканирующий таблицу master..sysprocesses. Как только в ней обнаруживается запись, у которой loginame не имеет права заходить на сервер в login_time, делается KILL этого spid. Если же новое соединение было установлено в разрешенное время, пользователю loginame добавляются его рабочие полномочия, которые снова отбираются у него при его выходе. Событие выхода можно отлавливать через ODS, либо средствами T-SQL, сравнивая текущую sysprocesses c ее предварительно сохраненной предыдущей копией на шаге n-1: select spid, login_time, loginame into #tmp from dbo.sysprocesses. Тогда список логинов, которым нужно оставить минимальные права, на шаге n определяется так: select #tmp.loginame, s.loginame from sysprocesses s right outer join #tmp on #tmp.spid = s.spid and #tmp.login_time = s.login_time where s.spid is null and #tmp.loginame not in (select loginame from sysprocesses)

В. А не проще ли повесить триггер FOR INSERT, DELETE на sysprocesses?

О. SQL Server 7.0 не поддерживает пользовательские триггеры на системные таблицы.

В. Что такое делегирование и поддерживается ли оно в SQL Server 7.0?

О. Когда пользователь через свой локальный сервер запускает какое-либо приложение на удаленном сервере (это может быть выполнение части запроса на прилинкованном сервере или вызов удаленной хранимой процедуры) на удаленном сервере он действует «от лица» логина удаленного сервера, на который отображен его локальный логин (см. sp_addremotelogin, sp_addlinkedsrvlogin). Делегирование есть возможность запуска приложений на удаленном сервере от имени локального пользователя без необходимости создания на удаленном сервере логинов-посредников. Делегирование поддерживается SQL Server 7.0, однако в полной мере его преимуществами можно воспользоваться только при установке на Windows 2000.

В. Неожиданно пропали все счетчики SQL Server 6.5 в Windows NT Performance Monitor …

О. Наиболее вероятной причиной является удаление логина probe, под которым Performance Monitor соединяется с SQL Server. Необходимо снова создать логин с тем же именем, и проблема будет решена. Кстати, в той же версии 6.5 довольно часто встречалась обратная ситуация, когда после установки SQL Server в Performance Monitor обнаруживалась пропажа всех счетчиков, кроме тех, что относятся к SQL Server. Проблема «лечилась» удалением файлов perfc019.dat и perfh019.dat в %systemroot%\system32. В версии 7.0 Performance Monitor устанавливает соединение с SQL Server в режиме аутентификации Windows NT.

Права на действия. Роли

В. Что такое роли применительно к SQL Server?

О. После того, как пользователь доказал, что он – это действительно он, ему разрешается выполнять определенные действия на сервере в зависимости от его прав. Управление правами осуществляется при помощи ролей. Роль есть именованный набор прав в рамках всего сервера или одной из его баз данных. Соответственно, различаются серверные роли и роли базы данных. Сейчас, говоря об уровне сервера, мы будем иметь в виду серверные роли.

В. Можно ли создавать пользовательские роли уровня сервера?

О. Нет. SQL Server 7.0 имеет семь серверных ролей (sysadmin, securityadmin, serveradmin, setupadmin, processadmin, diskadmin, dbcreator), которые в совокупности обеспечивают достаточно гибкий набор полномочий. Все они фиксированы, то есть их нельзя удалять, добавлять новые или модифицировать набор прав в какой-нибудь из ролей.

В. Как посмотреть список ролей, и что имеет право делать та или иная роль?

О. В Enterprise Manager выбрать серверную роль -> контекстное меню -> Properties -> закладка Permissions. В Т-SQL просмотр серверных ролей с кратким описанием каждой делается с помощью sp_helpsrvrole; с подробным описанием - sp_srvrolepermission. Упражнение: вызовите sp_srvrolepermission для @srvrolename='serveradmin' и для 'sysadmin' и ответьте на вопрос, кто «главнее» – серверный администратор или системный администратор. Кроме того, серверные роли показываются в виде полей в таблице syslogins, в каждом поле показывается принадлежность логина данной роли.

В. Как добавить логин к серверной роли?

О. При добавлении логина (без разницы, собственного логина SQL Server или учетной записи Windows NT, авторизованной для доступа к SQL Server), он наследует все права, которыми обладает данная роль. Чтобы добавить несколько логинов к одной роли: EM -> Security -> Server Roles -> контекстное меню роли -> Properties -> Add / Remove, одного логина в несколько ролей: EM -> Security -> Logins -> контекстное меню логина -> Properties -> закладка Server Roles. Примеры добавления к серверной роли в Т-SQL: exec sp_addsrvrolemember @loginame=’Домен\Пользователь или группа NT’, @rolename='<Имя роли>'; exec sp_addsrvrolemember @loginame=’Собственный пользователь SQL Server’, @rolename='<Имя роли>'.

В. Как посмотреть, какие логины являются членами той или иной серверной роли?

О. sp_helpsrvrolemember @srvrolename='<Имя роли>'.

В. Оставлен ли в SQL Server 7.0 административный логин sa?

О. Да, по соображениям совместимости. Однако он не имеет более того «сакрального» значения, которым обладал в предыдущих версиях. Наделить административными правами можно любой логин, включив его в серверную роль sysadmin. Исключать из нее также можно любого, так что неприкосновенных логинов в 7.0 нет. Сразу после установки членами этой роли оказываются группа NT Administrators и собственный логин sa. По умолчанию, sa имеет пустой пароль. Если совместимость не диктует наличия sa, его лучше сразу удалить, а в противном случае сразу сменить пароль.

Уровень базы данных

Пользователи БД

В. Чем отличаются логины уровня сервера от пользователей уровня БД?

О. В масштабах базы данных каждый серверный логин (неважно, собственный логин SQL Server или учетная запись NT) может преломляться в имя пользователя БД. UI: EM -> Databases -> БД -> Users -> New User; T-SQL: sp_grantdbaccess ‘логин‘, ‘имя как пользователя БД’ (обратный эффект дает процедура sp_revokedbaccess ‘пользователь БД‘).

В. Может ли один логин отображаться как несколько пользователей одной и той же БД?

О. Нет. Обратное также неверно: несколько логинов не могут отображаться как один пользователь.

В. Как посмотреть соответствие логин <-> пользователь БД для текущей базы данных?

О. select l.name from sysusers u inner join master..syslogins l on l.sid = u.sid

В. В предыдущих версиях существовали псевдонимы (aliases), позволявшие отобразить нескольких логинов на одного пользователя БД. Что про них слышно в 7.0?

О. Да, действительно, псевдонимы были удобным механизмом в SQL Server 6.х. Например, если пользователь уходил в отпуск, другой под его псевдонимом мог выполнять его задачи с теми же правами. В версии 7.0 это легко реализовать, сведя обоих пользователей в одну роль, так что роли успешно заменяют псевдонимы. Тем не менее, псевдонимы продолжают поддерживаться из соображений совместимости (см. sp_addalias, sp_dropalias).

В. Как посмотреть текущего пользователя БД?

О. Функцией CURRENT_USER.

В. Кто такие предопределенные пользователи?

О. Предопределенными пользователями БД являются dbo и guest. В guest отображаются те логины, которые не имеют предварительно заданных соответствий логин <-> пользователь БД. Пользователь Guest по умолчанию не создается для пользовательских баз данных, но может быть создан впоследствии: sp_grantdbaccess guest, guest, а также удален. Guest существует в БД master и tempdb, откуда его удалить нельзя. Dbo (Database Owner) – владелец базы. Первоначально в него отображается логин, создавший эту базу данных. Dbo имеет неявные права на все операции над данной БД и объекты внутри нее, включая раздачу прав другим пользователям.

В. Без сообщений об ошибке был выполнен следующий скрипт:

use pubs

exec sp_grantdbaccess guest, guest

exec sp_addlogin @loginame='L1', @Passwd=NULL

exec sp_addlogin @loginame='L2', @Passwd=NULL

exec sp_grantdbaccess @loginame='L1', @name_in_db='u1'

Что будет выведено в результате а) isql -dPubs-UL1 -P -Q"select current_user"; б) isql -dPubs –UL2 -P -Q"select current_user"?

О. а) u1; б) guest.

В. Dbo отправился в длительное путешествие (например, к ядру Галактики) и по причине крайней спешки забыл оставить свой пароль или, по крайней мере, раздать остальным права на базу. Между тем руководство жаждет лицезреть данные из внезапно «осиротевшей» базы. Что делать?

О. Воспользоваться процедурой sp_changedbowner ‘Новый логин’, <map>, права на выполнение которой, помимо самого dbo, имеет еще серверная роль sysadmin. Параметр map = ‘true’ означает, что объекты БД, принадлежащие старому dbo, переназначаются под нового, при map = ‘false’ – уничтожаются.

В. Был сделан backup БД, перенесен на другой сервер, и с него база была восстановлена заново. Пользователи БД вместе со своими правами перенеслись в таблице sysusers, но толку от этого мало, так как сервер не имеет соответствующих им логинов, и пользователи попросту не видны. Что делать?

О. Создать логины и автоматически восстановить соответствие с пользователями с помощью sp_change_users_login. Как следует из ее названия, процедура меняет связь пользователя БД с логином сервера. К сожалению, работает только для собственных логинов SQL Server. Для учетных записей Windows NT единственный путь способ автоматизировать этот процесс состоит в непосредственнойая правкеа sysusers (см. sp_helptext sp_change_users_login), что, естественно, не рекомендуется.

Роли БД

В. Чем роли БД отличаются от серверных ролей?

О. В первую очередь тем, что действуют в масштабах своей базы данных, а не всего сервера. Существует девять фиксированных ролей БД: db_owner, db_accessadmin, db_securityadmin, db_ddladmin, db_backupoperator, db_datareader, db_datawriter, db_denydatareader, db_denydatawriter (см. sp_helpdbfixedrole), которые нельзя удалять и менять в них наборы прав. Перечень прав в каждой можно посмотреть с помощью sp_dbfixedrolepermission [‘Роль’]. Наиболее существенным отличием на уровне БД выступает возможность в дополнение к имеющимся создавать пользовательские роли.

В. Как создать пользовательскую роль?

О. Если наборы прав в фиксированных ролях БД не отвечают требованиям приложения, вы можете создать пользовательскую роль из UI (Roles -> New), либо с помощью Т-SQL (sp_addrole ‘Роль’, [‘Владелец’]). Удаляются они также через UI или sp_droprole ‘Роль’. Определение набора прав производится в UI как Properties -> Permissions, в T-SQL с помощью стандартных команд GRANT / REVOKE / DENY ... TO / FROM /TO <имя пользовательской роли>.

В. Чем REVOKE отличается от DENY?

О. Права пользователя прописываются в системной таблице sysprotects. Наиболее интересными полями в ней являются uid – кому даны права, grantor – кто их дал и action – на что именно. (Более читабельный вид предоставляет функция sp_helprotect). REVOKE просто удаляет соответствующую запись в sysprotects, и, если пользователь имеет косвенные права на то же самое действие через членство в ролях или группах NT, он будет продолжать его выполнять. DENY присваивает пользователю отрицательные права на операцию, то есть это действие данному пользователю запрещается выполнять в явной форме. Эти команды пользуются заслуженной любовью многих DBA, некоторые из них даже согласны терпеть существование оператора GRANT, рассматривая его как поставщика входных параметров для REVOKE / DENY (J ). Заметим, что команда DENY отсутствовала в SQL Server 6.х, эквивалентный ей эффект достигался там при помощи двойного REVOKE.

В. Как посмотреть / изменить состав пользователей в роли?

О. UI: EM -> БД -> Roles -> Выбрать интересующую -> Контекстное меню -> Properties. Т-SQL: sp_helprolemember @rolename=’Роль БД’; sp_addrolemember @rolename=’Роль БД’ @membername='Пользователь БД'; sp_droprolemember @rolename=’Роль БД’ @membername='Пользователь БД'.

В. Как решить обратную задачу – определить, каким ролям принадлежит тот или иной пользователь?

О. Вообще говоря, принадлежность пользователя ролям хранится в поле roles таблицы sysusers, если правильно проинтерпретировать находящееся там varbinary(2048). Как показывает Profiler, SQL Server решает эту задачу (например, когда вы заходите в свойства пользователя и видите список отмеченных ролей БД, членом которых этот пользователь является) сканированием списка ролей и проверкой принадлежности пользователя каждой роли (см. предыдущий вопрос). Для текущего пользователя помогает IS_MEMBER (‘Группа NT или роль БД (фиксированная или пользовательская)’).

В. Мне не удается никого добавить в фиксированную роль public. Как это сделать?

О. Роль public – особая. Она обладает минимальным набором прав. В нее не удастся никого добавить, так как каждый пользователь БД автоматически в нее попадает. Удалять членов роли public также нельзя.

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

О. В отличие от серверных ролей, права ролей БД начинают действовать непосредственно при отнесении пользователя к той или иной роли.

В. Может ли роль быть членом другой роли?

О. Нет, роли нельзя вкладывать друг в друга. Кстати, это же справедливо и для серверных ролей.

В. Роль db_datareader разрешает чтение таблиц базы, роль db_denydatareader, наоборот, запрещает. Пользователь является членом обеих ролей. Сможет ли он читать таблицы?

О. При конфликте прав действует более ограничительная комбинация. В нашем случае – db_denydatareader.

В. Похоже, роли пришли на смену группам. Однако в предыдущих версиях пользователь БД мог быть членом не более, чем одной группы. Как обстоит дело с этим в 7.0?

О. Пользователь может являться членом одновременно нескольких ролей.

В. Зачем вообще нужны роли, коль скоро мы можем выдавать права напрямую учетным записям Windows NT?

О. На самом деле и роли SQL Server, и группы NT могут с равным успехом использоваться для решения одних и тех же задач. Что предпочтительнее выбрать – сказать сложно. Наверное, это зависит от принципов администрирования: например, а) вся структура сети подчинена единому приложению по работе с БД или б) в небольших организациях администратор сети часто является и DBA. В этих случаях проще централизовать управление пользователями, заложившись исключительно на объединение средствами NT. В то же время на крупных предприятиях эти функции, скорее всего, разнесены, и тогда проще использовать роли SQL Server, чем каждый раз бегать за администратором сети, чтобы создать нужную группу.

Уровень объекта

В. БД некоторого финансового приложения содержит две таблицы – текущих операций клиента за день и накопительную историю движения средств. Оператор может видеть обе, но менять данные имеет право только в первой. Как это обеспечить?

 О. Из этого примера видно, что не все ситуации покрываются правами масштаба БД. Более мелкая гранулярность прав обеспечивается на уровне объектов внутри БД. Например, GRANT INSERT, UPDATE, DELETE ON OperationsTbl TO [Оператор]; GRANT SELECT ON HistoryTbl TO [Оператор]; DENY INSERT, UPDATE ON HistoryTbl TO [Оператор]. В общем случае, GRANT <Какое-то действие> ON <Объект в составе БД> TO <Пользователь, Роль, Учетная запись NT> [WITH GRANT OPTION]. Аналогично, REVOKE, DENY. Или через UI: один пользователь, несколько объектов – EM -> Databases -> БД -> Users -> Пользователь -> Properties -> Permissions; один объект, несколько пользователей - Properties -> Permissions. Просмотр прав выполняется с помощью уже упоминавшейся нами процедуры sp_helprotect: sp_helprotect @name=‘Объект или Действие’ – кто имеет права, sp_helprotect @username=‘Пользователь’, @permissionarea – правами на что обладает (@permissionarea=‘o’ – на кого, ‘s’ – что может делать).

В. Пользователи Вася и Петя имеют доступ к БД pubs. Администратор выдал права пользователю Васе: grant select on Authors to [Вася] with grant option. Может ли Вася теперь, в свою очередь, сделать grant select on Authors to [Петя] with grant option? Варианты ответов: а) да; б) нет; в) только без with grant option).

О. Да.

В. Вы дали права с опцией WITH GRANT OPTION пользователю Васе. Вася не стал тратить время даром и раздал эти же права с той же опцией Пете и Ване, Петя – Маше и т.д. Через некоторое время Вася утратил ваше доверие. Как посмотреть, кому он успел надавать прав?

О. sp_helprotect @grantorname = 'Вася'. Та же процедура позволит вам по имени пользователя и действию / объекту определить, кто дал права этому пользователю на это действие / объект: sp_helprotect @username = 'Вася', @name = 'Authors'

В. А можно ли теперь отобрать права не только у него, но и у всей разветвленной цепочки, которую он породил?

О. Можно. Revoke / deny … from / to [Вася] cascade.

В. Операционист имеет право на изменение остатка по счету, но не должен менять номера счета. Как это обеспечить?

О. Поля таблицы также относятся к объектам внутри БД и над ними также допустимы операции присвоения / отмены прав: REVOKE ALL ON OperationsTbl TO [Операционист]; GRANT SELECT ON OperationsTbl ([Номер Счета]) TO [Операционист]; GRANT SELECT, UPDATE ON OperationsTbl ([Остаток]) TO [Операционист]. Обратите внимание, что право на обновление поля само по себе еще не дает права на его просмотр.

В. К вам пришел продвинутый пользователь Саша, прослышавший про тоо том, что в SQL Server 7.0 есть блокировки уровня записи, и в ультимативной форме потребовал, чтобы ему выдали на них права, потому что когда он на одном соединении делает

begin tran

update Auth with (rowlock) set au_lname = au_lname where au_id = '172-32-1176',

а на другом

select * from auth where au_id = '213-46-8915',

второй запрос подвисаетзависает, пока на первом соединении не сказать скажешь commit tran или rollback. Отсюда, по мысли Саши, неопровержимо следует, что SQL Server все равно блокирует не запись, а страницу, несмотря на явный хинт. Ваши действия: а) grant rowlock on Auth to [Саша]; б) sp_addrolemember ‘db_lockadmins’, ‘Саша’; в) стартовать SQL Mail под профилем администратора и предложить Саше отправить сообщение c описанием проблемы, начинающееся словами «Дорогой SQL Server ...»; г) create index auth_ix on Auth(au_id)?

 О. г). Задача не имеет отношения к теме безопасности, так как блокировки являются внутренними объектами SQL Server и понятие прав пользователей для них не существует. После того, как проверены права пользователя на операцию, в ходе ее выполнения блокировки накладываются автоматически. В данном случае первый процесс действительно блокировал только одну запись (см. sp_lock), второй же останавливался из-за того, что не мог прочитать из нее поле au_id и проверить условие where для этой записи. После создания индекса он стал брать au_id из индексных страниц.

В. Кто является владельцем объекта?

О. Первоначально – создавший его пользователь БД. Владелец объекта, по определению, может выполнять любую команду T-SQL по отношению к данному объекту, а также раздавать права на него. Если владельца приходится «убить», а объект – оставить, надо предварительно сменить владельца: sp_changeobjectowner ‘Объект’, ‘Новый владелец’. Право на выполнение этой процедуры имеют роли db_owner, db_securityadmin, db_ddladmin.

В. Пользователь Вася, db_owner, создал таблицу AnyTable и раздал всем остальным права на нее. Однако при попытке select * from dbo.AnyTable, SQL Server говорит, что такой таблицы нет. Вася видит таблицу нормально. В чем дело?

О. Названия объектов внутри БД квалифицируются именем пользователя и именем объекта. В частности, разные пользователи могут создать таблицы с одинаковыми именами. Не квалифицированный именем владельца объект сначала ищется среди объектов, принадлежащих текущему пользователю, затем – принадлежащих dbo. При ненахождении генерится ошибка. Однако даже если создатель объекта имеет роль db_owner, SQL Server 7.0 по умолчанию квалифицирует объект не dbo, а его именем как пользователя БД. В данном случае решение состоит в том, что либо Вася должен создать таблицу явно как dbo.AnyTable, либо пользователи должны ссылаться на нее как select * from [Вася].AnyTable.

В. Имеем роли «Операционист» и «Старший операционист». Первый не имеет права делать проводки на сумму более $1000. Как решить это программно?

О. Например, так: CREATE PROCEDURE UpdateBalance @Account AS NCHAR(20), @Sum AS MONEY AS

BEGIN TRAN

UPDATE OperationsTable SET Balance = Balance + @Sum WHERE Account = @Account

IF (ABS(@Sum) > 1000 AND IS_MEMBER('Операционист')=1) ROLLBACK TRAN

ELSE COMMIT

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

В. Пользователь u1 (допустим, db_ddladmin) выполняет следующий скрипт:

deny all on tbl to u2 go

create proc MySp1 as select * from tbl go

grant execute on MySp1 to u2.

Пользователь u2 лишен всех прав на доступ к таблице. Создается хранимая процедура, которая читает эту таблицу. Пользователь получает права только на вызов этой процедуры. Сможет ли он ее выполнить?

 О. Да.

В. Схожий вопрос. Пользователь u1 выполняет следующий скрипт:

create table tbl …

deny all on tbl to u2

create view vw as select * from tbl

grant all on vw to u2

Сможет ли u2 сделать select * from vw несмотря на отсуствие прав на tbl?

О. Да.

В. Теперь слегка изменим задачу. Пользователь u1:

create table tbl …

deny all on tbl to u3

Пользователь u2:

create view vw on tbl as select * from tbl

grant all on vw to u3

Пользователь u3:

select * from vw

Удастся ли u3 это сделать?

О. Нет, так как у vw и объекта, от которого он зависит (tbl), разные владельцы. Иначе бы u3 смог посмотреть данные u1 (невзирая на явный его запрет) при помощи u2. Кстати, для хранимых процедур это положение также справедливо. Самостоятельно проиллюстрируйте это примером для хранимых процедур.

В. А кто имеет право на выполнение замечательной хранимой процедуры xp_cmdshell?

О. Расширенная хранимая процедура xp_cmdshell замечательна тем, что дает возможность пользователю, соединившемуся с SQL Server, выполнять команды операционной системы так, как если бы они вводились непосредственно из командного окна сервера. По умолчанию право на вызов этой процедуры принадлежит членам серверной роли sysadmin и может быть в принципе дано другим пользователям. Для членов роли sysadmin команды операционной системы, генерируемые с помощью xp_cmdshell, выполняются в контексте безопасности учетной записи Windows NT, под которой работает сервис MSSQLServer. Для всех остальных пользователей с правами вызова xp_cmdshell команды ОС будут выполняться в контексте учетной записи SQLAgentCmdExec. Таким образом, избежать неприятностей, связанных с неавторизованным доступом к xp_cmdshell, очень просто. Нужно, во-первых, не давать на нее прав кому не надо, иа во-вторых, не раздувать права учетной записи SQLAgentCmdExec сверх необходимости.

В. Имеется база данных, к которой возможен доступ для всех, кому угодно, например, через Интернет. Как максимально обезопасить при этом наши данные?

О. Самыми безопасными данными являются, как известно, те, которые никто не видит и не трогает. Коль скоро пользователям все-таки приходится дать возможность с ними работать (J ), лучше, чтобы эта работа происходила по нашему сценарию. Идеальный вариант при этом – вынесение бизнес-логики в ПО промежуточного слоя – находится вне темы нашего нынешнего обсуждения, так как любой сервер приложений имеет собственные механизмы безопасности. Оставаясь в рамках традиционной двухуровневой клиент-серверной платформы, можно порекомендовать максимально сосредоточить бизнес-логику на стороне сервера (хранимые процедуры, триггеры, правила, значения по умолчанию, декларативная ссылочная целостность и другие ограничения) с тем, чтобы пользователь вообще не имел прав на непосредственную модификацию данных, а только на выполнение необходимых ему по сценарию его работы хранимых процедур, внутри которых «спрятана» требуемая модификация. То есть, грубо говоря, чтобы с клиентского рабочего места на сервер уходило не UPDATE OperationsTable SET Balance = Balance + <В принципе, сколько угодно> WHERE Account =..., а exec spChangeBalance ..., внутри которой стоит куча проверок, журналирование — кто, когда, зачем изменил остаток по счету и т.п. Еще лучше, если клиент при этом будет работать не непосредственно с данными, а с их копией или представлением (views, серверные курсоры, временные таблицы).

В. Предположим, мы построим наше приложение, следуя вышеописанным рекомендациям. Однако, как бы то ни было, пользователю придется давать права на хранимые процедуры, скажем, на ту же spChangeBalance. Конечно, по-хорошему он должен вызывать ее только изнутри приложения сугубо для тех счетов и сумм, которые получаются по ходу бизнес-логики, но... Но представим себе, что продвинутый пользователь Саша, купив на «Горбушке» диск с SQL Server, поставил себе на рабочую станцию Query Analyzer, запустил запрос типа exec spChangeBalance @Sum=$1000000, @Account=<Подставной счет вклада>, далее каждый домысливает сам. Спрашивается, а) что будет в этом случае с DBA и б) как быть, чтобы этого не было?

О. Оставим первый вопрос как риторический и рассмотрим следующий кусочек кода:

revoke all from [Cаша]

exec sp_addapprole @rolename=’AppRole1’, @password='abc'

grant execute on spChangeBalance to ‘AppRole1’

Cымитируем работу приложения (исходный код пользователю, естественно, неизвестен и недоступен):

exec sp_setapprole @rolename=’AppRole1’, @password={Encrypt N'abc'}, @Encrypt='ODBC'

exec spChangeBalance …

Процедура вызывается и отрабатывает. Теперь откроем Query Analyzer, Microsoft Query, Access или любую другую программу, позволяющую послать на SQL Server интерактивный запрос, зарегистрируемся на нем под логином Саши и попробуем вызвать spChangeBalance. Вызов не сработает. Это был пример действия прикладной роли. Прикладные роли в SQL Server 7.0 ограничивают возможности пользователей по доступу к данным рамками конкретного приложения. Таким образом, даже если продвинутый пользователь Саша догадается, что изменение остатка по счету производится хранимой процедурой spChangeBalance, он все равно не сможет ей воспользоваться помимо своего сценария. Прикладные роли действуют не постоянно, а во время пользовательской сессии. Они защищены паролем, так как это единственный способ авторизации (в них нет четко приписанных логинов, потому что они могут быть активизированы из любого приложения. Следовательно, приложение должно само проверить пользователя, прежде чем включать ему прикладную роль. При активизации приложением прикладной роли в текущей БД все права и роли, соответствовавшие контексту безопасности пользователя, перестают быть действительными (кроме роли public). К другим БД можно обращаться из текущей с использованием полных имен объектов (обращения будут идти от имени guest). При смене текущей БД (явная команда USE) действие прикладной роли прекращается.

Вместо заключения

26 февраля 1999 года Microsoft SQL Server 6.5 (SP4) был сертифицирован Гостехкомиссией при Президенте РФ на соответствие требованиям по защите от несанкционированного доступа к информации. Проведение сертификации осуществлялось в рамках проекта по реализации Автоматизированных Систем учета и контроля ядерных материалов на стенде ЦНИИАтоминформ Минатома России.

Вышедший в декабре 1998 года Microsoft SQL Server 7.0 обладает усовершенствованными возможностями защиты данных по сравнению с предыдущими версиями.

Hosted by uCoz