Я хотел бы написать запрос на SQL 2008, который будет сообщать обо всех пользователях, которые имеют доступ к определенной базе данных, или объектов в базе данных, таких как таблицы, представления и хранимые процедуры, напрямую или из-за ролей и т. Д. Это отчет будет использоваться в целях аудита безопасности. Не уверен, что у кого-то есть запрос, который полностью соответствует моим потребностям, но, надеюсь, что-то, что даст мне хорошее начало. Либо sql 2008, 2005 или 2000 подойдет, я, вероятно, могу конвертировать по мере необходимости.
192
Ответы:
Это мой первый треск на запрос, основанный на предложениях Andomar. Этот запрос предназначен для предоставления списка разрешений, которые пользователь применял либо непосредственно к учетной записи пользователя, либо через роли, которые пользователь имеет.
источник
login_token
изменен наuser_token
Вот полная версия запроса Джереми в августе 2011 года с внесенными изменениями, предложенными Брэдом (октябрь 2011 года) и iw.kuchin (май 2012 года):
[ObjectType]
и[ObjectName]
для схем.[ObjectType]
него лучше использоватьobj.type_desc
только дляOBJECT_OR_COLUMN
класса разрешения. Для всех остальных случаев используйтеperm.[class_desc]
.IMPERSONATE
разрешения.sys.login_token
на,sys.server_principals
поскольку он покажет также логины SQL, а не только Windows.sys
и INFORMATION_SCHEMA.Надеюсь, это спасет кого-то еще час или две их жизни.
:)
источник
sys.login_token
ни другое неsys.server_principals
поддерживается, и его необходимо заменить наsys.user_token
Начиная с SQL Server 2005, вы можете использовать системные представления для этого. Например, этот запрос перечисляет всех пользователей в базе данных с их правами:
Помните, что у пользователя могут быть права и через роль. Например,
db_data_reader
роль предоставляетselect
права на большинство объектов.источник
select * from sys.database_principals where type_desc = 'EXTERNAL_GROUP'
), а принятый ответ - нет, даже после исправленияsys.user_token
.SELECT PrincipalName = p.[name], p.[type_desc], dp.[permission_name], dp.[state_desc], CASE dp.class_desc WHEN 'DATABASE' THEN DB_NAME(dp.major_id) WHEN 'SCHEMA' THEN SCHEMA_NAME(dp.major_id) WHEN 'OBJECT_OR_COLUMN' THEN CONCAT_WS('.', OBJECT_SCHEMA_NAME(dp.major_id), OBJECT_NAME(dp.major_id), c.[name]) END FROM sys.database_principals AS p LEFT OUTER JOIN sys.database_permissions AS dp ON p.principal_id = dp.grantee_principal_id LEFT OUTER JOIN sys.columns AS c ON dp.major_id = c.[object_id] AND dp.minor_id = c.column_id
Не могу прокомментировать принятый ответ, поэтому я добавлю несколько комментариев здесь:
sys.objects
таблицы MS содержатся только объекты области схемы. Таким образом, для получения информации об объектах «более высокого уровня» (т.е. в нашем случае схемах) вам необходимо использоватьsys.schemas
таблицу.[ObjectType]
лучше использоватьobj.type_desc
только дляOBJECT_OR_COLUMN
разрешения класса. Для всех остальных случаев используйтеperm.[class_desc]
IMPERSONATE
. Для того, чтобы получить информацию о олицетворении следуетLEFT JOIN
сsys.database_principals
наperm.major_id = imp.principal_id
sys.login_token
с ,sys.server_principals
как он будет показывать также SQL логинов, а не только те , Windows ,'G'
к разрешенным основным типам, чтобы разрешить группы Windowssys
иINFORMATION_SCHEMA
из результирующей таблицы, так как эти пользователи используются только для обслуживанияЯ выложу первый фрагмент скрипта со всеми предлагаемыми исправлениями, остальные части также должны быть изменены:
источник
sysadmin
+securityadmin
сопоставляются, какdbo
для каждой БД на сервере + есть разрешение сервера,CONTROL SERVER
которое может быть предоставлено пользователю. Это разрешение дает почти те же права, что и бытьsysadmin
.Потрясающий сценарий Джереми и соавторов! Спасибо!
У меня есть тонна пользователей, поэтому запуск этого для всех пользователей был кошмаром. Я не мог добавить комментарии, поэтому я публикую весь сценарий с изменениями. Я добавил переменную +, где предложение, чтобы я мог искать все, что соответствует до 5 символов в имени пользователя (или всех пользователей, если оставить пустым). Ничего особенного, но я подумал, что это будет полезно в некоторых случаях.
источник
Другие ответы, которые я видел, пропускают некоторые разрешения, которые возможны в базе данных. Первый запрос в приведенном ниже коде получит разрешение на уровне базы данных для всего, что не является системным объектом. Он также генерирует соответствующие операторы GRANT. Второй запрос получает все роли ролей.
Это должно выполняться для каждой базы данных, но слишком долго для использования с sp_MSforeachdb. Если вы хотите сделать это, вам нужно добавить его в основную базу данных в качестве системной хранимой процедуры.
Чтобы охватить все возможности, вам также понадобится скрипт, который проверяет разрешения на уровне сервера.
ОБНОВЛЕНИЕ: Следующие запросы будут получать разрешения и членство на уровне сервера.
источник
Вот моя версия, адаптированная от других. Я потратил 30 минут только сейчас, пытаясь вспомнить, как я пришел к этому, и ответ @Jeremy, кажется, является основным источником вдохновения. Я не хотел обновлять ответ Джереми, на всякий случай, если я представил ошибки, поэтому я публикую свою версию здесь.
Я предлагаю объединить полный сценарий с вдохновением, взятым из T-SQL Кеннета Фишера во вторник: какие разрешения имеет конкретный пользователь? : Это позволит вам отвечать на вопросы соответствия / аудита снизу вверх, а не сверху вниз.
Чтобы понять, что это покрывает, рассмотрите
Contoso\DB_AdventureWorks_Accounting
Windows AD Group с участникомContoso\John.Doe
. John.Doe аутентифицируется в AdventureWorks через серверную группуContoso\DB_AdventureWorks_Logins
Windows AD. Если кто-то спросит вас: «Какие права есть у John.Doe?», Вы не сможете ответить на этот вопрос только с помощью приведенного ниже сценария. Затем необходимо выполнить итерацию по каждой строке, возвращаемой приведенным ниже сценарием, и присоединить его к указанному выше сценарию. (Вам также может понадобиться нормализовать устаревшиеname
значения, посмотрев SID в вашем поставщике Active Directory.)Вот сценарий, без включения такой логики обратного просмотра.
источник
источник
Хранимая процедура GetPermissions, описанная выше, хороша, однако она использует Sp_msforeachdb, что означает, что она прекратит работу, если в вашем экземпляре SQL есть имена баз данных, которые содержат пробелы или тире и другие не лучшие практики. Я создал версию, которая избегает использования Sp_msforeachdb, а также включает в себя два столбца, которые указывают 1 - если Логин - это логин sysadmin (IsSysAdminLogin) и 2 - если логин является пользователем-сиротой (IsEmptyRow).
источник
you can use [] to resolve it. sp_msforeachdb ' use [?] select db_name()'
я предполагаю, что его ответ был задуман как комментарий, но так как его аккаунт не заполняет минимальную репутацию, он вместо этого разместил ответ.Я попробовал почти все это, но я быстро заметил, что некоторые из них отсутствуют, особенно пользователи sysadmin. Наличие такой дыры не будет хорошо выглядеть в нашей предстоящей ревизии, так что это то, что я придумал
источник
Из-за низкой репутации не может ответить с этим людям, просящим запустить это на нескольких базах данных / серверах SQL.
Создайте зарегистрированную группу серверов и сделайте запрос к ним со всеми нами, а затем просто наведите курсор на базы данных:
Эта тема очень помогла мне, спасибо всем!
источник
DB_NAME()
и сохранив выходные данные во временной таблице, чтобы избежать получения множества наборов результатов. Спасибо!Большое спасибо за потрясающие сценарии аудита.
Я настоятельно рекомендую для аудита использовать удивительные хранимые процедуры Kenneth Fisher ( b | t ):
источник
Простой запрос, который показывает только, являетесь ли вы SysAdmin или нет:
источник
К сожалению, я не смог прокомментировать сообщение Шона Роуза из-за недостаточной репутации, однако мне пришлось изменить «публичную» роль скрипта, так как он не отображал права доступа SCHEMA из-за (INNER) JOIN против sys. объекты. После того, как это было изменено на LEFT JOIN, мне также пришлось изменить логику предложения WHERE, чтобы исключить системные объекты. Мой исправленный запрос на публичные пермиты ниже.
источник
Если вы хотите проверить доступ к базам данных для определенного входа, используйте этот простой скрипт, как показано ниже:
sys.sp_helplogins @LoginNamePattern = 'Домен \ логин' - имя пользователя
источник
- пошла моя очередь, чтобы помочь назад, наслаждайтесь
Этот заголовок отчета динамически захватывает имя экземпляра SQL, дату \ время и имя учетной записи, которой управляет отчет, все, что захочет знать хороший аудитор. :)
Примечание. Если у вас есть расширенное свойство «environment» в базе данных Master, значение (независимо от того, что вы используете: PreProd, Development, Production, DR и т. Д.) Будет включено в заголовок отчета.
КОНЕЦ
- большой, чтобы сохранить как сохраненный процесс
источник