logon failed due to trigger execution

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38357227/article/details/80185629

前几天在公司数据库布了一个触发器,用来审计所有链接到数据库的账号信息。
脚本如下:

CREATE TABLE master..Login_Info

(       Login_Name           NVARCHAR(256),
       Login_Time           DATETIME,
       Host_Name            NVARCHAR(128)
)
go


 CREATE TRIGGER tr_logon_audit
ON ALL SERVER 
FOR LOGON
AS
BEGIN
       INSERT INTO Login_Info
       SELECT ORIGINAL_LOGIN(), GETDATE(),
       EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]','NVARCHAR(128)')
END

select * from master.dbo.Login_Info

该触发器创建后,数据库连接开始陆续有报错信息,此时,除了dba用户外,其余用户都无法登录,报错信息如下:
这里写图片描述

临时禁用触发器后,该问题得到解决。
在网上搜到解决办法如下,即在all server 后面添加“WITH EXECUTE AS ‘sa’”。否则,只有DBA账号可以登录。
(https://sqlandme.com/2011/07/13/sql-server-login-auditing-using-logon-triggers/)
重新部署后,运行没有问题。脚本如下:

 CREATE TRIGGER tr_logon_audit
ON ALL SERVER WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN
       INSERT INTO Login_Info
       SELECT ORIGINAL_LOGIN(), GETDATE(),
       EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]','NVARCHAR(128)')
END

本以为这件事到这里就结束了。
但是在一周后,突然接到开发人员反馈:PYTHON程序连接数据库时报错:logon failed due to trigger execution。但是并未收到其他程序的报错。
由于报错原因尚未查明,我到服务器上去禁用此触发器。此时我用的图形化界面而不是TSQL语句。
然后就出问题了。。。

我的数据库卡住了.当我重新登录数据库时,报错信息如下,我已无法重新登录SSMS,且任何其他账号也无法重新登录。无法使用SSMS,意味着我无法通过TSQL或图形化界面去处理问题,意味着该问题得不到解决,所有对数据库的访问都将被拒绝。
OH MY GOD!
这里写图片描述

幸运的是在网上找到了解决办法。
(感谢:https://blog.sqlauthority.com/2009/06/27/sql-server-fix-error-17892-logon-failed-for-login-due-to-trigger-execution-changed-database-context-to-master/
在使用SSMS无法登陆到数据库的情况下,可以通过DAC连接数据库。(DAC是当与服务器的标准连接不可用时,为管理员提供的特殊的诊断连接)。
详细信息见:https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/diagnostic-connection-for-database-administrators?view=sql-server-2017
当我无法连接到SSMS以删除或禁用触发器时,此时只能通过DAC连接强制删除TRIGGER.
这里写图片描述

 sqlcmd -S LocalHost -d master -A 
1> DROP TRIGGER Tr_ServerLogon ON ALL SERVER 
2> GO

删除触发器后重新登录SSMS,发现此时已经可以登录,trigger已被删除。
又是一番在查资料。最终在 Microsoft Support 找到一篇文章,上面提到了EVENTDATA function有可能会造成登录出错。先不细究原因,把trigger 脚本做如下修改:

CREATE TRIGGER [tr_logon_audit]
ON ALL SERVER WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN
INSERT INTO Login_Info
SELECT ORIGINAL_LOGIN(), GETDATE()
,HOST_NAME
--EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]','NVARCHAR(128)')
FROM MASTER.sys.dm_exec_sessions a 
WHERE a.session_id = @@SPID 
END

重新启用后,python程序连接正常。
详细研究文档发现,解释的原因如下:
该函数返回XML,且区分大小写。但是用户并没有区分大小写,因此所有的EVENTDATA函数总是返回NULL,且所有sa等价登录都被拒绝访问。
这里写图片描述

但是为什么只有python连接报错?这个还要继续研究。。。

猜你喜欢

转载自blog.csdn.net/weixin_38357227/article/details/80185629
今日推荐