确定用户为什么可以删除数据库


8

我有一个SQL Server用户,可以删除任何数据库。我一直在运行下面的代码,以检查用户在SQL Server中拥有的权限,但无法确定用户如何删除数据库。是否有一个SQL脚本可以帮助我确定该用户如何删除dbs?是否有命令拒绝他们删除任何数据库?(SSMS未将用户显示为dbcreator角色的一部分)

select USER_NAME(p.grantee_principal_id) AS principal_name,
    dp.type_desc AS principal_type_desc,
    p.class_desc,
    OBJECT_NAME(p.major_id) AS object_name,
    p.permission_name,
    p.state_desc AS permission_state_desc 
from    sys.database_permissions p
inner   JOIN sys.database_principals dp
on     p.grantee_principal_id = dp.principal_id
order by principal_name

如果有帮助,上面查询的输出将为用户提供以下三个记录

class_desc object_name权限名权限_state_desc OBJECT_OR_COLUMN xp_cmdshell EXECUTE GRANT DATABASE NULL CONNECT GRANT
DATABASE NULL CREATE DATABASE GRANT


该用户是否正在删除数据库?
Zane 2012年

我可以以该用户身份删除数据库。是。如果您要问是否有人恶意使用了该帐户,我宁愿等着看。
笨拙的

该用户具有的一般权限级别是什么?还是仅某些数据库还是此服务器范围广泛?
Zane 2012年

2
查看所需的权限(msdn.microsoft.com/zh-cn/library/ms178613.aspx)并进行反向工程。
Thomas Stringer

Answers:


4

您在那里的查询将仅列出您对其运行数据库的权限。获得删除数据库许可的一种方法是ALTER ANY DATABASE,这是服务器级别的许可。要检查这些,请尝试以下查询:

SELECT 
  [srvprin].[name] [server_principal],
  [srvprin].[type_desc] [principal_type],
  [srvperm].[permission_name],
  [srvperm].[state_desc] 
FROM [sys].[server_permissions] srvperm
  INNER JOIN [sys].[server_principals] srvprin
    ON [srvperm].[grantee_principal_id] = [srvprin].[principal_id]
WHERE [srvprin].[type] IN ('S', 'U', 'G')
ORDER BY [server_principal], [permission_name];

换句话说,用户可能正在服务器登录级别而不是数据库用户级别获得删除数据库的权限。


1
这是“更改任何数据库”权限
Lumpy 2012年

是的,绝对不是您希望Joe in Accounting拥有的权限。
KeithS 2012年

6

我建议在主机上运行此查询

SELECT  
    [UserName] = CASE princ.[type] 
                    WHEN 'S' THEN princ.[name]
                    WHEN 'U' THEN ulogin.[name] COLLATE Latin1_General_CI_AI
                 END,
    [UserType] = CASE princ.[type]
                    WHEN 'S' THEN 'SQL User'
                    WHEN 'U' THEN 'Windows User'
                 END,  
    [DatabaseUserName] = princ.[name],       
    [Role] = null,      
    [PermissionType] = perm.[permission_name],       
    [PermissionState] = perm.[state_desc],       
    [ObjectType] = obj.type_desc,--perm.[class_desc],       
    [ObjectName] = OBJECT_NAME(perm.major_id),
    [ColumnName] = col.[name]
FROM    
    --database user
    sys.database_principals princ  
LEFT JOIN
    --Login accounts
    sys.login_token ulogin on princ.[sid] = ulogin.[sid]
LEFT JOIN        
    --Permissions
    sys.database_permissions perm ON perm.[grantee_principal_id] = princ.[principal_id]
LEFT JOIN
    --Table columns
    sys.columns col ON col.[object_id] = perm.major_id 
                    AND col.[column_id] = perm.[minor_id]
LEFT JOIN
    sys.objects obj ON perm.[major_id] = obj.[object_id]
WHERE 
    princ.[type] in ('S','U')
UNION
--List all access provisioned to a sql user or windows user/group through a database or application role
SELECT  
    [UserName] = CASE memberprinc.[type] 
                    WHEN 'S' THEN memberprinc.[name]
                    WHEN 'U' THEN ulogin.[name] COLLATE Latin1_General_CI_AI
                 END,
    [UserType] = CASE memberprinc.[type]
                    WHEN 'S' THEN 'SQL User'
                    WHEN 'U' THEN 'Windows User'
                 END, 
    [DatabaseUserName] = memberprinc.[name],   
    [Role] = roleprinc.[name],      
    [PermissionType] = perm.[permission_name],       
    [PermissionState] = perm.[state_desc],       
    [ObjectType] = obj.type_desc,--perm.[class_desc],   
    [ObjectName] = OBJECT_NAME(perm.major_id),
    [ColumnName] = col.[name]
FROM    
    --Role/member associations
    sys.database_role_members members
JOIN
    --Roles
    sys.database_principals roleprinc ON roleprinc.[principal_id] = members.[role_principal_id]
JOIN
    --Role members (database users)
    sys.database_principals memberprinc ON memberprinc.[principal_id] = members.[member_principal_id]
LEFT JOIN
    --Login accounts
    sys.login_token ulogin on memberprinc.[sid] = ulogin.[sid]
LEFT JOIN        
    --Permissions
    sys.database_permissions perm ON perm.[grantee_principal_id] = roleprinc.[principal_id]
LEFT JOIN
    --Table columns
    sys.columns col on col.[object_id] = perm.major_id 
                    AND col.[column_id] = perm.[minor_id]
LEFT JOIN
    sys.objects obj ON perm.[major_id] = obj.[object_id]
UNION
--List all access provisioned to the public role, which everyone gets by default
SELECT  
    [UserName] = '{All Users}',
    [UserType] = '{All Users}', 
    [DatabaseUserName] = '{All Users}',       
    [Role] = roleprinc.[name],      
    [PermissionType] = perm.[permission_name],       
    [PermissionState] = perm.[state_desc],       
    [ObjectType] = obj.type_desc,--perm.[class_desc],  
    [ObjectName] = OBJECT_NAME(perm.major_id),
    [ColumnName] = col.[name]
FROM    
    --Roles
    sys.database_principals roleprinc
LEFT JOIN        
    --Role permissions
    sys.database_permissions perm ON perm.[grantee_principal_id] = roleprinc.[principal_id]
LEFT JOIN
    --Table columns
    sys.columns col on col.[object_id] = perm.major_id 
                    AND col.[column_id] = perm.[minor_id]                   
JOIN 
    --All objects   
    sys.objects obj ON obj.[object_id] = perm.[major_id]
WHERE
    --Only roles
    roleprinc.[type] = 'R' AND
    --Only public role
    roleprinc.[name] = 'public' AND
    --Only objects of ours, not the MS objects
    obj.is_ms_shipped = 0
ORDER BY
    princ.[Name],
    OBJECT_NAME(perm.major_id),
    col.[name],
    perm.[permission_name],
    perm.[state_desc],
    obj.type_desc--perm.[class_desc] 

这应该使您对可以访问您的主数据库并查看天气的角色有一个很好的了解,而用户是否具有这些角色中的任何一个。您还可以对任何其他数据库运行此命令,以按数据库级别检查用户对数据库的权限。这应该是一个重要的工具,可以帮助您追踪。


漂亮的脚本...

4

是否有一个SQL脚本可以帮助我确定该用户如何删除dbs?

我已经使用了几次,并取得了一些不错的效果,可以在这里找到以下代码的来源:


SELECT SP1.[name] AS 'Login', 'Role: ' + SP2.[name] COLLATE DATABASE_DEFAULT AS 'ServerPermission'  
FROM sys.server_principals SP1 
  JOIN sys.server_role_members SRM 
    ON SP1.principal_id = SRM.member_principal_id 
  JOIN sys.server_principals SP2 
    ON SRM.role_principal_id = SP2.principal_id 
UNION ALL 
SELECT SP.[name] AS 'Login' , SPerm.state_desc + ' ' + SPerm.permission_name COLLATE DATABASE_DEFAULT AS 'ServerPermission'  FROM sys.server_principals SP  
  JOIN sys.server_permissions SPerm  
    ON SP.principal_id = SPerm.grantee_principal_id  
ORDER BY [Login], [ServerPermission];

是否有命令拒绝他们删除任何数据库?

继续进行文档说明,用户删除数据库的安全性要求如下:

需要数据库的CONTROL权限,ALTER ANY DATABASE权限或db_owner固定数据库角色的成员身份

您可以明确拒绝对上述其中一项的许可,但要理解您拒绝的级别可能不会像您所想的那样受到影响。我回想起阅读过白皮书,该白皮书介绍了SQL Server如何在连接时验证用户的权限,但是现在无法找到它。如果我还记得,我可能会拒绝它们与数据库的连接,但是用户是该sysadmin角色的一部分这一事实居于优先地位。

我将专门针对DROP DATABASE命令的安全性进行审核。


这是任何数据库权限的更改。谢谢。
笨拙的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.