SQL Server 2005 DDL Triggers
I was at the Israeli Security User Group meeting today and I met with Justin, who mentioned his favoirate tough question for now is: "Can a DDL Trigger in SQL Server 2005 prevent dropping a DDL Trigget?"
It turns out that it can, but there is a catch. A DDL trigger is not called if the trigger that is being dropped is the same trigger. This mean that to implement this functionality we need something like:
CREATE TRIGGER Prevent_Drop_DDL_Trigger
ON DATABASE
FOR DROP_TRIGGER
as
if PATINDEX ('%on database%', EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')) > -1
BEGIN
PRINT 'No deleting of DDL Triggers!'
ROLLBACK
END
GO
CREATE TRIGGER Prevent_Drop_DDL_Trigger_Second
ON DATABASE
FOR DROP_TRIGGER
as
if PATINDEX ('%on database%', EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')) > -1
BEGIN
PRINT 'No deleting of DDL Triggers!'
ROLLBACK
END
GO
Now, let's try dropping one of the triggers:
drop
trigger Prevent_Drop_DDL_Trigger on databaseThis will call the Prevent_Drop_DDL_Trigger_Second which will fail the query. Prevent_Drop_DDL_Trigger is not called for its own drop, by the way.
Be aware that this means that in order to remove those triggers you need to ALTER one of them, DROP the second one, and then DROP the first one. It's possible to get into a situation where the two triggers doesn't allow drop / alter on either one, which potentially can lead to a trigger that you can modify without dropping the database.
I would classify this behavior as Evil (TM).
Comments
Comment preview