Identificare il motivo per cui un utente può eliminare un database


8

Ho un utente SQL Server che ha la possibilità di eliminare qualsiasi database. Ho eseguito il codice seguente per verificare i diritti dell'utente in SQL Server ma non sono stato in grado di identificare come l'utente ha la possibilità di eliminare i database. Esiste uno script sql che può aiutarmi a identificare come questo utente può rilasciare dbs? Esiste un comando per negare loro di eliminare alcuni database? (SSMS non mostra l'utente come parte del ruolo 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

L'output della query precedente fornisce i seguenti tre record per l'utente, se è utile

class_desc nome_oggetto nome_autorizzazione permesso_stato_desc OBJECT_OR_COLUMN xp_cmdshell ESEGUI GRAN DATABASE NULL CONNECT GRANT
DATABASE NULL CREATE DATABASE GRANT


Questo utente sta lasciando cadere i database?
Zane,

Posso rilasciare database come quell'utente. Sì. Se stai chiedendo se qualcuno ha usato l'account in modo melodioso, preferirei non aspettare di vedere.
Lumpy

Qual è il livello generale di autorizzazione di questo utente? Inoltre è solo alcuni database o questo server è largo?
Zane,

2
Guarda quali autorizzazioni sono necessarie ( msdn.microsoft.com/en-us/library/ms178613.aspx ) e decodificale.
Thomas Stringer,

Risposte:


4

La query che hai lì elencherà solo le autorizzazioni per il database su cui lo esegui. Un modo per ottenere l'autorizzazione a eliminare un database è ALTER ANY DATABASE, che è un'autorizzazione a livello di server. Per controllare quelli, prova questa query:

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

In altre parole, l'utente potrebbe ottenere l'autorizzazione per eliminare i database a livello di accesso al server anziché a livello di utente del database.


1
È stata la modifica di qualsiasi autorizzazione per il database
Lumpy,

Sì, sicuramente non è un permesso che vuoi avere a Joe in Accounting.
Keith

6

Suggerirei di eseguire questa query sul master

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] 

Questo dovrebbe darti una buona idea dei ruoli che hanno accesso al tuo database principale e vedere il tempo o meno che l'utente abbia uno di quei ruoli. È inoltre possibile eseguirlo su qualsiasi altro database per verificare le autorizzazioni dell'utente su un database a livello di database. Questo dovrebbe essere uno strumento importante per aiutare a rintracciarlo.


Bel script ....

4

Esiste uno script sql che può aiutarmi a identificare come questo utente può rilasciare dbs?

L'ho usato alcune volte con alcuni buoni risultati, la fonte del codice qui sotto può essere trovata qui :


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

Esiste un comando per negare loro di eliminare alcuni database?

Andando sulla documentazione qui , i requisiti di sicurezza per un utente di eliminare un database sono indicati come:

Richiede l'autorizzazione CONTROL sul database o l'autorizzazione ALTER ANY DATABASE o l'appartenenza al ruolo predefinito del database db_owner

Puoi negare esplicitamente l'autorizzazione a uno di cui sopra, ma capire che il livello in cui lo neghi potrebbe non avere effetto come pensi. Ricordo di aver letto un white paper che illustrava come SQL Server esegue la convalida delle autorizzazioni di un utente al momento della connessione, ma non è in grado di individuarlo in questo momento. Se ricordo che posso negare loro la connessione a un database ma il fatto che l'utente faccia parte del sysadminruolo ha la precedenza.

Vorrei esaminare l'auditing in modo specifico affinché il DROP DATABASEcomando fosse sicuro.


era l'alterazione di qualsiasi permesso del database. Grazie.
Lumpy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.