Eu gostaria de escrever uma consulta no sql 2008 que relate todos os usuários que têm acesso a um banco de dados específico ou objetos dentro do banco de dados, como tabelas, visualizações e procedimentos armazenados, diretamente ou devido a funções, etc. O relatório seria usado para fins de auditoria de segurança. Não tenho certeza se alguém tem uma consulta que atenda às minhas necessidades completamente, mas espero que algo que me dê um bom começo. O sql 2008, 2005 ou 2000 serve, provavelmente posso converter conforme necessário.
191
Respostas:
Este é o meu primeiro crack em uma consulta, com base nas sugestões de Andomar. Esta consulta tem como objetivo fornecer uma lista de permissões que um usuário aplicou diretamente à conta do usuário ou por meio de funções que o usuário possui.
fonte
login_token
alterado parauser_token
Aqui está uma versão completa da consulta de Jeremy de agosto de 2011 com as alterações sugeridas por Brad (outubro de 2011) e iw.kuchin (maio de 2012) incorporadas:
[ObjectType]
e[ObjectName]
para esquemas.[ObjectType]
que seja melhor usarobj.type_desc
apenas para aOBJECT_OR_COLUMN
classe de permissão. Para todos os outros casos, useperm.[class_desc]
.IMPERSONATE
permissões.sys.login_token
porsys.server_principals
pois ele também mostrará os logins do SQL, não apenas os do Windows.sys
e INFORMATION_SCHEMA.Espero que isso salve outra pessoa por uma hora ou duas de suas vidas.
:)
fonte
sys.login_token
nemsys.server_principals
é suportado e necessidade de ser substituído porsys.user_token
A partir do SQL Server 2005, você pode usar as visualizações do sistema para isso. Por exemplo, esta consulta lista todos os usuários em um banco de dados, com seus direitos:
Esteja ciente de que um usuário também pode ter direitos através de uma função. Por exemplo, a
db_data_reader
função concedeselect
direitos na maioria dos objetos.fonte
select * from sys.database_principals where type_desc = 'EXTERNAL_GROUP'
), enquanto a resposta aceita não, mesmo após a correçãosys.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
Não é possível comentar a resposta aceita, então adicionarei alguns comentários aqui:
sys.objects
tabela de referência do MS, existem apenas objetos com escopo no esquema. Portanto, para obter informações sobre objetos de "nível superior" (ou seja, esquemas no nosso caso), você precisa usarsys.schemas
tabela.[ObjectType]
é melhor usarobj.type_desc
apenas para aOBJECT_OR_COLUMN
classe de permissão. Para todos os outros casos, useperm.[class_desc]
IMPERSONATE
. Para obter informações sobre imitações deve-seLEFT JOIN
comsys.database_principals
aperm.major_id = imp.principal_id
sys.login_token
-sys.server_principals
lo, pois ele também mostrará logons SQL, não apenas os do Windows'G'
aos tipos principais permitidos para permitir grupos do Windowssys
eINFORMATION_SCHEMA
da tabela resultante, pois esses usuários são usados apenas para serviçosVou postar a primeira parte do script com todas as correções propostas, outras partes também devem ser alteradas:
fonte
sysadmin
+securityadmin
são mapeadas comodbo
para todos os bancos de dados no servidor + há permissão de servidorCONTROL SERVER
que pode ser concedida ao usuário. Essa permissão concede quase os mesmos direitos que existemsysadmin
.Impressionante roteiro Jeremy e colaboradores! Obrigado!
Eu tenho muitos usuários, portanto, executar isso para todos os usuários foi um pesadelo. Não pude adicionar comentários, por isso estou postando o script inteiro com as alterações. Eu adicionei uma variável + where cláusula para que eu possa procurar qualquer coisa que corresponda a até 5 caracteres no nome do usuário (ou todos os usuários quando deixados em branco). Nada de especial, mas achei que seria útil em alguns casos de uso.
fonte
As outras respostas que eu vi perder algumas permissões possíveis no banco de dados. A primeira consulta no código abaixo obterá a permissão no nível do banco de dados para tudo que não é um objeto do sistema. Também gera as instruções GRANT apropriadas. A segunda consulta obtém todas as meberships de funções.
Isso deve ser executado para cada banco de dados, mas é muito longo para ser usado com sp_MSforeachdb. Se você quiser fazer isso, precisará adicioná-lo ao banco de dados mestre como um procedimento armazenado do sistema.
Para cobrir todas as possibilidades, você também precisa ter um script que verifique as permissões no nível do servidor.
ATUALIZAÇÃO: As consultas a seguir recuperam permissões e associações no nível do servidor.
fonte
Aqui está a minha versão, adaptada de outras pessoas. Passei apenas 30 minutos tentando lembrar como eu criei isso, e a resposta de @ Jeremy parece ser a inspiração principal. Eu não queria atualizar a resposta de Jeremy, apenas no caso de apresentar bugs, então estou postando minha versão aqui.
Sugiro emparelhar o script completo com alguma inspiração tirada do T-SQL Tuesday de Kenneth Fisher: Quais permissões um usuário específico possui? : Isso permitirá que você responda perguntas de conformidade / auditoria de baixo para cima, em vez de cima para baixo.
Para entender o que isso cobre, considere o
Contoso\DB_AdventureWorks_Accounting
Windows AD Group com um membroContoso\John.Doe
. John.Doe autentica no AdventureWorks via server_principalContoso\DB_AdventureWorks_Logins
Windows AD Group. Se alguém lhe perguntar: "Quais permissões o John.Doe tem?", Você não poderá responder a essa pergunta apenas com o script abaixo. Você precisa percorrer cada linha retornada pelo script abaixo e associá-lo ao script acima. (Você também pode precisar normalizar paraname
valores pesquisando o SID no seu provedor do Active Directory.)Aqui está o script, sem incorporar essa lógica de pesquisa inversa.
fonte
fonte
O procedimento armazenado GetPermissions acima é bom, no entanto, ele usa Sp_msforeachdb, o que significa que será interrompido se a instância SQL tiver nomes de bancos de dados que incluam espaços ou traços e outros caracteres não recomendados. Criei uma versão que evita o uso de Sp_msforeachdb e também inclui duas colunas que indicam 1 - se o Login for um login sysadmin (IsSysAdminLogin) e 2 - se o logon for um usuário órfão (IsEmptyRow).
fonte
you can use [] to resolve it. sp_msforeachdb ' use [?] select db_name()'
, suponho que sua resposta foi um comentário, mas como sua conta não preenche a reputação mínima, ele postou uma resposta.Eu tentei praticamente tudo isso, mas notei rapidamente que alguns estavam faltando, principalmente usuários do administrador de sistemas. Ter um buraco como esse não ficará bom em nossa próxima auditoria, então é isso que eu criei
fonte
Devido ao baixo rep, não é possível responder com isso às pessoas que pedem para executá-lo em vários bancos de dados / servidores SQL.
Crie um grupo de servidores registrados e consulte todos eles a seguir e apenas passe o cursor pelos bancos de dados:
Esse tópico me ajudou imensamente a todos!
fonte
DB_NAME()
e armazenando a saída em uma tabela temporária para evitar acabar com vários conjuntos de resultados. Obrigado!Muito obrigado por scripts de auditoria impressionantes.
Eu recomendo para o usuário de auditoria usar procedimentos armazenados de Kenneth Fisher ( b | t ) impressionantes :
fonte
Uma consulta simples que mostra apenas se você é um SysAdmin ou não:
fonte
Infelizmente, não pude comentar a postagem de Sean Rose devido à reputação insuficiente, no entanto, tive que alterar a parte da função "pública" do script, pois não mostrava permissões no escopo do SCHEMA devido ao (INNER) JOIN contra o sys. objetos. Depois que isso foi alterado para LEFT JOIN, tive que alterar ainda mais a lógica da cláusula WHERE para omitir objetos do sistema. Minha consulta alterada para as permissões públicas está abaixo.
fonte
Se você deseja verificar o acesso aos bancos de dados para um login específico, use este script simples como abaixo:
sys.sp_helplogins @LoginNamePattern = 'Domínio \ login' - sysname
fonte
--ok minha vez de contribuir de volta, aproveite
Esse cabeçalho do relatório captura dinamicamente o nome da Instância SQL, data \ hora e nome da conta em que o relatório é executado, tudo o que um bom auditor deseja saber. :)
Nota - se você tiver uma propriedade estendida chamada 'ambiente' no banco de dados Mestre, o valor (o que você usar: pré-produto, desenvolvimento, produção, DR, etc) será incluído no cabeçalho do relatório.
FIM
- ótimo para salvar como um processo armazenado
fonte