我想在 sql 2008 上编写一个查询,该查询将直接或由于角色等报告有权访问特定数据库的所有用户或数据库中的对象(例如表、视图和存储过程)。报告将用于安全审计目的。不确定是否有人有完全适合我需求的查询,但希望能给我一个良好的开始。 sql 2008、2005 或 2000 都可以,我可以根据需要进行转换。
I would like to write a query on a sql 2008 that will report all the users that have access to a specific database, or objects within the database such as tables, views, and stored procedures, either directly or due to roles, etc. This report would be used for security auditing purposes. Not sure if anyone has a query that will fit my needs completely, but hopefully something that will give me a good start. Either sql 2008, 2005 or 2000 will do, I can probably convert as needed.
发布评论
评论(19)
这是我根据 Andomar 建议进行的第一次查询。此查询旨在提供用户已直接应用于用户帐户或通过
用户拥有的角色。
This is my first crack at a query, based on Andomar's suggestions. This query is intended to provide a list of permissions that a user has either applied directly to the user account, or through
roles that the user has.
以下是 Jeremy 2011 年 8 月查询的完整版本,其中包含 Brad(2011 年 10 月)和 iw.kuchin(2012 年 5 月)合并:
[ObjectType]
和[ObjectName]
架构。[ObjectType]
,最好仅对OBJECT_OR_COLUMN
权限类别使用obj.type_desc
。对于所有其他情况,请使用perm.[class_desc]
。IMPERSONATE
权限。sys.login_token
替换为sys.server_principals
,因为它还会显示 SQL 登录,而不仅仅是 Windows 登录。sys
和 INFORMATION_SCHEMA。希望这可以节省其他人一两个小时的生命。 <代码>:)
Here is a complete version of Jeremy's Aug 2011 query with the changes suggested by Brad (Oct 2011) and iw.kuchin (May 2012) incorporated:
[ObjectType]
and[ObjectName]
for schemas.[ObjectType]
it's better to useobj.type_desc
only forOBJECT_OR_COLUMN
permission class. For all other cases useperm.[class_desc]
.IMPERSONATE
permissions.sys.login_token
withsys.server_principals
as it will show also SQL Logins, not only Windows ones.sys
and INFORMATION_SCHEMA.Hopefully this saves someone else an hour or two of their lives.
:)
从 SQL Server 2005 开始,您可以使用系统视图来实现此目的。例如,此查询列出了数据库中的所有用户及其权限:
请注意,用户也可以通过角色拥有权限。例如,
db_data_reader
角色授予大多数对象的select
权限。From SQL Server 2005 on, you can use system views for that. For example, this query lists all users in a database, with their rights:
Be aware that a user can have rights through a role as well. For example, the
db_data_reader
role grantsselect
rights on most objects.无法对接受的答案发表评论,因此我将在此处添加一些评论:
sys.objects
表仅包含架构范围的对象。因此,要获取有关“更高级别”对象(即我们案例中的模式)的信息,您需要使用 sys.schemas 表。[ObjectType]
,最好仅对OBJECT_OR_COLUMN
权限类使用obj.type_desc
。对于所有其他情况,请使用perm.[class_desc]
IMPERSONATE
。要获取有关模拟的信息,应该在perm.major_id = imp.principal_id
上使用LEFT JOIN
与sys.database_principals
sys.server_principals
因为它还会显示 SQL 登录,而不仅仅是 Windows 的登录'G'
允许主体类型允许 Windows 组sys
和INFORMATION_SCHEMA
,因为这些用户被使用仅针对服务,我将发布第一段脚本以及所有建议的修复,其他部分也应更改:
Can't comment on accepted answer so I'll add some comments here:
sys.objects
table contains only schema-scoped objects. So to get info about "higher level" objects (i.e. schemas in our case) you need to usesys.schemas
table.[ObjectType]
it's better to useobj.type_desc
only forOBJECT_OR_COLUMN
permission class. For all other cases useperm.[class_desc]
IMPERSONATE
. To get info about impersonations one shouldLEFT JOIN
withsys.database_principals
onperm.major_id = imp.principal_id
sys.login_token
withsys.server_principals
as it will show also SQL Logins, not only Windows ones'G'
to allowed principal types to allow Windows groupssys
andINFORMATION_SCHEMA
from resulting table, as these users are used only for serviceI'll post first piece of script with all proposed fixes, other parts should be changed as well:
我看到的其他答案错过了数据库中可能存在的一些权限。下面代码中的第一个查询将获取非系统对象的所有内容的数据库级别权限。它还生成适当的 GRANT 语句。第二个查询获取所有角色成员资格。
必须为每个数据库运行此命令,但与 sp_MSforeachdb 一起使用的时间太长。如果您想这样做,则必须将其作为系统存储过程添加到主数据库中。
为了涵盖所有可能性,您还必须有一个检查服务器级别权限的脚本。
更新:以下查询将检索服务器级别的权限和成员资格。
The other answers that I have seen miss some permissions that are possible in the database. The first query in the code below will get the database level permission for everything that is not a system object. It generates the appropriate GRANT statements as well. The second query gets all the role meberships.
This has to be run for each database, but is too long to use with sp_MSforeachdb. If you want to do that you'd have to add it to the master database as a system stored procedure.
To cover all possibilities you'd also have to have a script that checks the server level permissions.
UPDATE: The following queries will retrieve server level permissions and memberships.
非常棒的脚本 Jeremy 和贡献者!谢谢!
我有大量用户,因此为所有用户运行它是一场噩梦。我无法添加评论,因此我将发布包含更改的整个脚本。我添加了一个变量 + where 子句,这样我就可以搜索与用户名中最多 5 个字符匹配的任何内容(或留空时的所有用户)。没什么特别的,但我认为这在某些用例中会有帮助。
Awesome script Jeremy and contributors! Thanks!
I have a s-ton of users, so running this for all users was a nightmare. I couldn't add comments, so I am posting the whole script with the changes. I added a variable + where clause so I can search for anything matching up to 5 characters in the user name (or all users when left blank). Nothing special, but I thought it would be helpful in some use cases.
这是我的版本,改编自其他人。我刚才花了 30 分钟试图记住我是如何想到这个的,@Jeremy 的答案似乎是核心灵感。我不想更新 Jeremy 的答案,以防万一我引入了错误,所以我在这里发布我的版本。
我建议将完整的脚本与来自 Kenneth Fisher 的 T-SQL Tuesday:特定用户有哪些权限?:这将允许您回答合规性/审计问题自下而上,而不是自上而下。
要了解其涵盖的内容,请考虑包含成员
Contoso\John.Doe
的Contoso\DB_AdventureWorks_Accounting
Windows AD 组。 John.Doe 通过 server_principalContoso\DB_AdventureWorks_Logins
Windows AD 组向 AdventureWorks 进行身份验证。如果有人问您“John.Doe 有什么权限?”,您无法仅使用以下脚本来回答该问题。然后,您需要迭代以下脚本返回的每一行并将其连接到上面的脚本。 (您可能还需要通过在 Active Directory 提供程序中查找 SID 来规范过时的name
值。)以下是脚本,未合并此类反向查找逻辑。
Here is my version, adapted from others. I spent 30 minutes just now trying to remember how I came up with this, and @Jeremy 's answer seems to be the core inspiration. I didn't want to update Jeremy's answer, just in case I introduced bugs, so I am posting my version of it here.
I suggest pairing the full script with some inspiration taken from Kenneth Fisher's T-SQL Tuesday: What Permissions Does a Specific User Have?: This will allow you to answer compliance/audit questions bottom-up, as opposed to top-down.
To understand what this covers, consider
Contoso\DB_AdventureWorks_Accounting
Windows AD Group with memberContoso\John.Doe
. John.Doe authenticates to AdventureWorks via server_principalContoso\DB_AdventureWorks_Logins
Windows AD Group. If someone asks you, "What permissions does John.Doe have?", you cannot answer that question with just the below script. You need to then iterate through each row returned by the below script and join it to the above script. (You may also need to normalize for stalename
values via looking up the SID in your Active Directory provider.)Here is the script, without incorporating such reverse look-up logic.
上面的 GetPermissions 存储过程很好,但它使用 Sp_msforeachdb,这意味着如果您的 SQL 实例具有任何包含空格或破折号和其他非最佳实践字符的数据库名称,它将中断。我创建了一个避免使用 Sp_msforeachdb 的版本,并且还包括两列,分别指示 1 - 如果登录名是系统管理员登录名 (IsSysAdminLogin) 和 2 - 如果登录名是孤立用户 (IsEmptyRow)。
The GetPermissions Stored Procedure above is good however it uses Sp_msforeachdb which means that it will break if your SQL Instance has any databases names that include spaces or dashes and other non-best-practices characters. I have created a version that avoids the use of Sp_msforeachdb and also includes two columns that indicate 1 - if the Login is a sysadmin login (IsSysAdminLogin) and 2 - if the login is an orphan user (IsEmptyRow).
非常感谢出色的审计脚本。
我强烈建议审计用户使用很棒的 Kenneth Fisher (b | t) 存储过程:
Great thanks for awesome audit scripts.
I highly recommend for audit user use awesome Kenneth Fisher (b | t) stored procedures:
由于低代表无法回复要求在多个数据库/SQL Server 上运行此功能的人。
创建一个注册的服务器组并在它们之间查询以下所有内容,然后将光标浏览数据库:
这个线程极大地帮助了我,谢谢大家!
Due to low rep can't reply with this to the people asking to run this on multiple databases/SQL Servers.
Create a registered server group and query across them all us the following and just cursor through the databases:
This thread massively helped me thanks everyone!
我刚刚将以下内容添加到 Jeremy 的答案 中,因为我分配了一个分配给数据库 db_datareader 的角色,该角色没有显示以下权限作用了。我尝试浏览每个人帖子中的所有答案,但找不到任何可以执行此操作的内容,因此我添加了自己的查询。
I just added the following to Jeremy's answer because I had a role assigned to the database db_datareader which wasn't showing the permissions that role had. I tried going through all of the answers in everyone's posts but couldn't find anything that would do this so I added my own query.
这是 Jeremy 提交的最受欢迎的答案,但经过修改以包括 Greg Sipes 提到的系统管理员和禁用标志以及log_date_time 列。
两全其美?
Here's the most popular answer submitted by Jeremy, but modified to include the sysadmin and disabled flags mentioned by Greg Sipes as well as a log_date_time column.
Best of both worlds?
我尝试了几乎所有这些,但我很快注意到有些丢失了,尤其是系统管理员用户。在我们即将进行的审核中,出现这样的漏洞看起来不太好,所以这就是我想出的办法
I tried just about all of these but I quickly noticed that some were missing, especially sysadmin users. Having a hole like that won't look good in our upcoming audit, so this is what I came up with
一个简单的查询,仅显示您是否是系统管理员:
A simple query that shows only whether you are a SysAdmin or not :
不幸的是,由于声誉不足,我无法对 Sean Rose 帖子发表评论,但我不得不修改“公共”角色脚本的一部分,因为由于针对 sys.objects 的(内部)联接,它没有显示架构范围的权限。在更改为 LEFT JOIN 之后,我必须进一步修改 WHERE 子句逻辑以省略系统对象。我对公共权限的修改查询如下。
Unfortunately I couldn't comment on the Sean Rose post due to insufficient reputation, however I had to amend the "public" role portion of the script as it didn't show SCHEMA-scoped permissions due to the (INNER) JOIN against sys.objects. After that was changed to a LEFT JOIN I further had to amend the WHERE-clause logic to omit system objects. My amended query for the public perms is below.
如果您想检查特定登录名对数据库的访问权限,请使用以下简单脚本:
sys.sp_helplogins @LoginNamePattern = 'Domain\login' -- sysname
If you want check access to databases for a particular login has use this simple script as below:
sys.sp_helplogins @LoginNamePattern = 'Domain\login' -- sysname
--好吧,轮到我回馈了,享受
这个报告标题动态获取 SQL 实例名称、日期\时间和运行报告的帐户名称,这些都是优秀审计员想要知道的事情。 :)
注意 - 如果您在主数据库上有一个名为“环境”的扩展属性,则该值(无论您使用什么:PreProd、Development、Production、DR 等)将包含在报告标题中。
END——
非常适合保存为存储过程
--ok my turn to contribute back,enjoy
This report header dynamically grabs the SQL Instance name, date\time, and account name the report is run by, all things a good auditor will want to know. :)
Note - if you have a extended property called 'environment' on the Master database, the value (whatever you use: PreProd, Development, Production, DR, etc) will be included in the report header.
END
--great to save as a stored proc
提取数据库角色成员资格
Extract db role membership