Identifizieren Sie, warum ein Benutzer eine Datenbank löschen kann

8

Ich habe einen SQL Server-Benutzer, der jede Datenbank löschen kann. Ich habe den folgenden Code ausgeführt, um die Rechte des Benutzers in SQL Server zu überprüfen, konnte jedoch nicht feststellen, wie der Benutzer Datenbanken löschen kann. Gibt es ein SQL-Skript, mit dem ich feststellen kann, wie dieser Benutzer dbs löschen kann? Gibt es einen Befehl, um das Löschen von Datenbanken zu verweigern? (SSMS zeigt den Benutzer nicht als Teil der dbcreator-Rolle an.)

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

Die Ausgabe der obigen Abfrage enthält die folgenden drei Datensätze für den Benutzer, wenn dies hilfreich ist

class_desc Objektname Berechtigungsname Berechtigungsstatus_desc OBJECT_OR_COLUMN xp_cmdshell EXECUTE GRANT DATABASE NULL CONNECT GRANT
DATABASE NULL CREATE DATABASE GRANT

Klumpig
quelle
Löscht dieser Benutzer Datenbanken?
Zane
Ich kann Datenbanken als dieser Benutzer löschen. Ja. Wenn Sie fragen, ob jemand das Konto meliziös verwendet hat, würde ich lieber nicht warten, um zu sehen.
Klumpiger
Welche allgemeine Berechtigungsstufe hat dieser Benutzer? Auch sind es nur bestimmte Datenbanken oder ist dieser Server breit?
Zane
2
Überprüfen Sie, welche Berechtigungen erforderlich sind ( msdn.microsoft.com/en-us/library/ms178613.aspx ), und entwickeln Sie sie zurück.
Thomas Stringer

Antworten:

4

In der Abfrage, die Sie dort haben, werden nur Berechtigungen für die Datenbank aufgelistet, für die Sie sie ausführen. Eine Möglichkeit, die Berechtigung zum Löschen einer Datenbank zu erhalten, ist ALTER ANY DATABASE, eine Berechtigung auf Serverebene. Versuchen Sie diese Abfrage, um diese zu überprüfen:

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];

Mit anderen Worten, der Benutzer erhält möglicherweise die Berechtigung, Datenbanken auf der Serveranmeldungsebene und nicht auf der Datenbankbenutzerebene zu löschen.

mdoyle
quelle
1
Es war die Erlaubnis zum Ändern einer Datenbank
Lumpy
Ja, definitiv keine Erlaubnis, die Joe im Rechnungswesen haben soll.
KeithS
6

Ich würde vorschlagen, diese Abfrage auf dem Master auszuführen

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] 

Dies sollte Ihnen eine ziemlich gute Vorstellung von den Rollen geben, die Zugriff auf Ihre Master-Datenbank haben und sehen, ob der Benutzer eine dieser Rollen hat oder nicht. Sie können dies auch für jede Ihrer anderen Datenbanken ausführen, um die Berechtigungen des Benutzers für eine Datenbank nach Datenbankebene zu überprüfen. Dies sollte ein wichtiges Instrument sein, um dies aufzuspüren.

Zane
quelle
Schönes Skript ....
4

Gibt es ein SQL-Skript, mit dem ich feststellen kann, wie dieser Benutzer dbs löschen kann?

Ich habe dies einige Male mit einigen guten Ergebnissen verwendet. Die Quelle des folgenden Codes finden Sie hier :


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];

Gibt es einen Befehl, um das Löschen von Datenbanken zu verweigern?

In der Dokumentation hier werden die Sicherheitsanforderungen für einen Benutzer zum Löschen einer Datenbank wie folgt angegeben:

Erfordert die Berechtigung CONTROL für die Datenbank oder die Berechtigung ALTER ANY DATABASE oder die Mitgliedschaft in der festen Datenbankrolle db_owner

Sie können die oben genannte Erlaubnis explizit verweigern, aber verstehen, dass die Ebene, auf der Sie sie verweigern, möglicherweise keine Auswirkungen hat, wie Sie denken. Ich erinnere mich, dass ich ein Whitepaper gelesen habe, in dem beschrieben wurde, wie SQL Server die Berechtigungen eines Benutzers bei einer Verbindung überprüft, es jedoch derzeit nicht finden kann. Wenn ich mich erinnere, kann ich ihnen die Verbindung zu einer Datenbank verweigern, aber die Tatsache, dass der Benutzer Teil der sysadminRolle ist, hat Vorrang.

Ich würde mir die Prüfung speziell ansehen, um sicherzustellen, dass der DROP DATABASEBefehl sicher ist.


quelle
Es war die Änderung jeder Datenbankberechtigung. Vielen Dank.
Klumpiger