Sql-server – SQL Server 2014 user login keeps being dropped

loginsSecuritysql server 2014

I have an issue where I have a user login which keeps being dropped randomly without any trace in the error log. How do I find out why it's behaving as such or who is doing this, even though I am sure it's not a person who is doing this. Thanks

Best Answer

Possibly setup, sql audit, a server side trace/extended event and filter for sp_droplogin or a server-scoped trigger like below.

CREATE TABLE ##AuditDroppedLogin(UserName sysname, DateDropped DATETIME);
GO
CREATE TRIGGER WhoDidIt
ON ALL SERVER
FOR DROP_LOGIN
AS
BEGIN
INSERT INTO ##AuditDroppedLogin
SELECT USER_NAME(), GETDATE()
END

Then simply query ##AuditDroppedLogin for any events. Very basic example.

Below is also a server side trace script to track sp_droplogin

    /****************************************************/
/* Created by: SQL Server 2012  Profiler          */
/* Date: 10/01/2017  13:15:30         */
/****************************************************/


-- Create a Queue
declare @rc int
declare @TraceID int
declare @maxfilesize bigint
set @maxfilesize = 5 

-- Please replace the text C:\Traces\WhoDroppedLogin, with your existing appropriate
-- filename prefixed by a path, e.g., c:\MyFolder\MyTrace. The .trc extension
-- will be appended to the filename automatically. If you are writing from
-- remote server to local drive, please use UNC path and make sure server has
-- write access to your network share

declare @stoptime DATETIME 
declare @filecount int

SET @stoptime =DATEADD(hh,48,GETDATE()) -- runs for 48 hours

SET @filecount = 5


exec @rc = sp_trace_create @TraceID output, 2, N'C:\Traces\WhoDroppedLogin', @maxfilesize, @stoptime, @filecount 
if (@rc != 0) goto error

-- Client side File and Table cannot be scripted

-- Set the events
declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 12, 1, @on
exec sp_trace_setevent @TraceID, 12, 9, @on
exec sp_trace_setevent @TraceID, 12, 11, @on
exec sp_trace_setevent @TraceID, 12, 6, @on
exec sp_trace_setevent @TraceID, 12, 10, @on
exec sp_trace_setevent @TraceID, 12, 12, @on
exec sp_trace_setevent @TraceID, 12, 13, @on
exec sp_trace_setevent @TraceID, 12, 14, @on
exec sp_trace_setevent @TraceID, 12, 15, @on
exec sp_trace_setevent @TraceID, 12, 16, @on
exec sp_trace_setevent @TraceID, 12, 17, @on
exec sp_trace_setevent @TraceID, 12, 18, @on
exec sp_trace_setevent @TraceID, 13, 1, @on
exec sp_trace_setevent @TraceID, 13, 9, @on
exec sp_trace_setevent @TraceID, 13, 11, @on
exec sp_trace_setevent @TraceID, 13, 6, @on
exec sp_trace_setevent @TraceID, 13, 10, @on
exec sp_trace_setevent @TraceID, 13, 12, @on
exec sp_trace_setevent @TraceID, 13, 14, @on


-- Set the Filters
declare @intfilter int
declare @bigintfilter bigint

exec sp_trace_setfilter @TraceID, 1, 0, 6, N'%sp_droplogin%'

-- Set the trace status to start
exec sp_trace_setstatus @TraceID, 1

-- display trace id for future references
select TraceID=@TraceID
goto finish

error: 
select ErrorCode=@rc

finish: 
go

To stop before 48 hours run, replace 2 with your TraceID. EXEC sp_trace_setstatus 2, 0