Estou tentando implementar um gatilho DDL em todo o servidor que auditará as alterações DDL nos bancos de dados do servidor usando um script muito semelhante ao artigo encontrado aqui
O gatilho registrará os eventos DDL em uma tabela dentro de um banco de dados, no entanto, estou enfrentando problemas de permissão e alguns usuários, até mesmo eu com privilégios de administrador do sistema, recebem a seguinte mensagem de erro.
Msg 297, Level 16, State 1, Procedure LogDDLEvent, Line 19
The user does not have permission to perform this action.
Eu li sobre o uso da WITH EXECUTE AS
cláusula e a criação de um login especificamente com a finalidade de executar o gatilho, embora isso não pareça ter resolvido o problema.
Alguém poderia aconselhar sobre o método correto para implementar uma trigger desse tipo e quais permissões são necessárias aos usuários ou a um login específico a ser utilizado no WITH EXECUTE AS?
EDIT: Algumas informações adicionais
O servidor está executando o SQL Server 2008 R2 e o DDL Trigger está definido como DDL_EVENTS da seguinte maneira:
CREATE TRIGGER LogDDLEvent
ON ALL SERVER
FOR DDL_EVENTS
AS
DECLARE @eventInfo XML
SET @eventInfo = EVENTDATA()
INSERT INTO Tools.audit.DDLEvent
VALUES
(
REPLACE(CONVERT(VARCHAR(128), @eventInfo.query('data(/EVENT_INSTANCE/PostTime)')),'T', ' ') -- EventTime
, CONVERT(VARCHAR(128), @eventInfo.query('data(/EVENT_INSTANCE/EventType)')) -- EventType
, CONVERT(VARCHAR(128), @eventInfo.query('data(/EVENT_INSTANCE/LoginName)')) -- LoginName
, CONVERT(VARCHAR(128), @eventInfo.query('data(/EVENT_INSTANCE/UserName)')) -- UserName
, CAST(HOST_NAME() AS VARCHAR(128)) -- MachineName
, (SELECT CAST(client_net_address AS VARCHAR(128))
FROM sys.dm_exec_connections
WHERE Session_id = CONVERT(INT, @eventInfo.value('data(/EVENT_INSTANCE/SPID)[1]', 'int'))) -- IPAddress
, CONVERT(VARCHAR(128), @eventInfo.query('data(/EVENT_INSTANCE/DatabaseName)')) -- DatabaseName
, CONVERT(VARCHAR(128), @eventInfo.query('data(/EVENT_INSTANCE/SchemaName)')) -- SchemaName
, CONVERT(VARCHAR(128), @eventInfo.query('data(/EVENT_INSTANCE/ObjectName)')) -- ObjectName
, CONVERT(VARCHAR(128), @eventInfo.query('data(/EVENT_INSTANCE/ObjectType)')) -- ObjectType
, CONVERT(VARCHAR(MAX), @eventInfo.query('data(/EVENT_INSTANCE/TSQLCommand/CommandText)')) -- DDLCommand
, @eventInfo -- DDLEventXML
)
O script acima é como eu originalmente criei o gatilho e isso funcionou bem para mim e alguns outros usuários, embora um usuário que tinha a função db_owner para um banco de dados específico continuasse recebendo a mensagem de erro acima.
Depois de tentar implementar o WITH EXECUTE AS, descobri que o gatilho não funcionaria para mim.
Definir o gatilho para EXECUTE WITH 'sa' pareceu funcionar. Não tenho certeza se isso apresenta alguma preocupação de segurança. Tentei criar um login separado com permissões apenas para o banco de dados de ferramentas e a tabela DDLEvent, mas os usuários que não são administradores de sistema obtiveram erros.