Eu sou um programador, não um dba ... Eu sei apenas o suficiente para ser perigoso.
Eu herdei um banco de dados com um usuário herdado que é um db_owner para o banco de dados. Não podemos ajustar a permissão deste usuário para tabelas, esquemas, etc. existentes, por motivos comerciais, mas algumas novas tabelas estão sendo criadas e eu quero que esse usuário tenha apenas acesso SELECT nelas.
As permissões foram definidas para esse usuário para essas tabelas, para que tudo seja NEGADO, exceto SELECT, que está definido como GRANT.
No entanto, quando esse usuário (dbadmin) tenta executar um SELECT em uma dessas tabelas (AccountingAudit), esse erro ocorre:
The SELECT permission was denied on the object 'AccountingAudit', database 'billing', schema 'dbo'.
Eu executei este SQL para tentar ver quais permissões estão definidas para esta tabela / usuário:
select object_name(major_id) as object,
user_name(grantee_principal_id) as grantee,
user_name(grantor_principal_id) as grantor,
permission_name,
state_desc
from sys.database_permissions
E é isso que eu recebo de volta:
AccountingAudit dbadmin dbo ALTER DENY
AccountingAudit dbadmin dbo CONTROL DENY
AccountingAudit dbadmin dbo DELETE DENY
AccountingAudit dbadmin dbo INSERT DENY
AccountingAudit dbadmin dbo REFERENCES DENY
AccountingAudit dbadmin dbo SELECT GRANT
AccountingAudit dbadmin dbo TAKE OWNERSHIP DENY
AccountingAudit dbadmin dbo UPDATE DENY
AccountingAudit dbadmin dbo VIEW DEFINITION DENY
AccountingAudit dbadmin dbo VIEW CHANGE TRACKING DENY
Parece que deveria estar funcionando certo?
A chamada SELECT que estou fazendo é um SELECT * FROM AccountingAudit muito básico, no SSMS. Eu não estou fazendo nenhum sp_executesql especial ou algo assim.
Eu tentei conceder permissão explicitamente:
GRANT SELECT ON [dbo].AccountingAudit TO dbadmin
Isso não tem efeito (por que, a consulta acima já mostra que é concedida! ;-)
Eu procurei no stackoverflow.com e em outros lugares, e não consigo encontrar nada que ainda não tenha tentado. Gostaria de saber se tem algo a ver com a forma como os esquemas são configurados. (Neste ponto, eu sei muito pouco sobre esquemas.)
Alguma ideia? Obrigado!
fonte
Use o
sp_DBPermissions
procedimento armazenado de Ken Fisher para examinar as permissões.DENY CONTROL
não é aplicada para a mesa, além do comumDENY SELECT
,DENY INSERT
,DENY UPDATE
,DENY DELETE
eDENY REFERENCES
.SELECT
instrução contiver funções com valor de tabela, verifique se existe umaEXECUTE AS OWNER
função com valor de tabela ou umaGRANT EXECUTE
(e nãoDENY EXECUTE
!). Se for esse o caso, leia a mensagem de erro com mais cuidado, pois provavelmente não dirá que a permissão SELECT foi negada na tabela, mas sim algo sobre EXECUTE sendo negado.Se o usuário for um usuário ou grupo do AD, use o seguinte script para determinar o
login_token
(s) usuário (s):Veja o plano de execução real. Se o erro estiver dentro de um procedimento armazenado
SET NOCOUNT ON;
, o plano de execução real fornecerá informações sobre as quais você talvez não preste atenção, apenas observando a guia Mensagens no SSMS, pois "Linhas afetadas" podem estar fora de seu controle.Você pode compilar a instrução como um procedimento armazenado e o SSMS "Exibir Dependências de Objetos", bem como os truques descritos por Svetlana Golovko em Diferentes Maneiras de Encontrar Dependências de Objetos do SQL Server
Use o evento de segurança do SQL Server Profiler "Evento de acesso ao objeto de esquema de auditoria" e as colunas "TextData" e "Success" para rastrear em quais objetos o SQL Server está avaliando permissões. - Vi situações em que há duas linhas emitidas para este evento, e um valor diz Sucesso = 1 e o outro diz Sucesso = 0. Nesse cenário, a única solução que encontrei para trabalhar é reiniciar o servidor. Até a execução
repadmin /syncall
não resolveu o problema, nem o início e a parada do aplicativo (e, portanto, o conjunto de conexões).Determine as permissões efetivas para o logon:
Se o usuário estiver vinculado a um usuário ou grupo do AD, considere executar
repadmin /syncall
para forçar as alterações feitas no diretório ativo a serem sincronizadas nos controladores de domínio. - Se alguém souber uma boa maneira de comparar os valores atuais de dois controladores de domínio, informe-me.Antes de considerar uma reinicialização completa de todo o sistema, tente eliminar todas as conexões ativas desse usuário. O motivo é que o usuário obtém seu token do Windows no controlador de domínio, que inclui seus grupos. O token não será atualizado até que o usuário obtenha um novo token - geralmente efetuando logoff e logon novamente.
Reinicialize o sistema com força. Ele tem trabalhado para mim. Ainda não está 100% certo por que ainda. SOMENTE FAÇA ISSO SE PODE SOBREVIVER AO TEMPO ABAIXO! TENHA CUIDADO EM FAZER ISSO QUANDO TIVER GRANDES OPERAÇÕES EXCEPCIONAIS!
fonte