It is also crucial for the DBA to track such actions as failed login attempts and to audit, as far as possible, the actions of users once they are in amongst the data.. Listing 7.7 shows
Trang 1ServerName Service_Name Service_Account
Server1 MSSQLServerOLAPService LocalSystem
Server1 SQLAgent$SRVSAT LocalSystem
Server1 SQLBackupAgent_SRVSAT LocalSystem
Table 7.4: Service credentials query results
While I do not use this query often, it always saves me many frustrating minutes
of trying to manually find the same information, via tools such as Computer
Management and Services
Surveillance
To this point, I have focused on finding logins, users, groups and service accounts The queries presented so far have all been useful for managing many
hundreds if not thousands of accounts, all with some level of privilege to my SQL
Server instances
However, knowing who has access to the data, and what level of access they have,
is only one aspect of security I want to touch on in this chapter It is also crucial
for the DBA to track such actions as failed login attempts and to audit, as far as
possible, the actions of users once they are in amongst the data
In this section, I will introduce three surveillance techniques to help with these
issues: Error Log interrogation with T-SQL, DDL Triggers and Server-side Tracing
Error log interrogation
Unlike a lot of DBAs that I know, I do not scour the SQL Error logs daily I tend
Trang 2would much prefer to read the logs with T-SQL Fortunately, SQL Server offers two stored procedures to make this possible, namely sp_enumerrorlogs and
sp_readerrolog
As Figure 7.2 shows, sp_enumerrorlogs simply lists the available SQL Server error logs
Figure 7.2: Querying the SQL Server error logs with sp_enumerrorlogs.
The procedure sp_readerrorlog accepts the Archive #, from
sp_enumerrorlogs, as input and displays the error log in table form, as shown in Figure 7.3, where you can see that the first archived log file (1) is passed in as a parameter Archive number 0 refers to the current error log
It is possible to load and query every error log file by combining the two stored procedures with a bit of iterative code Listing 7.7 shows the custom code used to loop through each log file, store the data in a temp table, and subsequently query that data to find more than five consecutive failed login attempts, as well as the last good login attempt
In order for this to work, you will need to enable security logging for both successful and failed logins, as most production servers should do This can be configured via the Security tab of the Server Properties Finally, note that this query will only work for SQL Server 2005 and 2008
Trang 3Figure 7.3: Using sp_readerrorlog
DECLARE @TSQL NVARCHAR ( 2000 )
DECLARE @lC INT
CREATE TABLE #TempLog (
LogDate DATETIME ,
ProcessInfo NVARCHAR ( 50 ),
[Text] NVARCHAR ( MAX ))
CREATE TABLE #logF (
ArchiveNumber INT ,
LogDate DATETIME ,
LogSize INT
)
INSERT INTO #logF
EXEC sp_enumerrorlogs
SELECT @lC = MIN ( ArchiveNumber ) FROM #logF
WHILE @lC IS NOT NULL
BEGIN
INSERT INTO #TempLog
EXEC sp_readerrorlog @lC
Trang 4Failed login counts Useful for security audits
SELECT Text , COUNT ( Text ) Number_Of_Attempts
FROM #TempLog where
Text like '%failed%' and ProcessInfo = 'LOGON'
Group by Text
Find Last Successful login Useful to know before deleting
"obsolete" accounts
SELECT Distinct MAX ( logdate ) last_login , Text
FROM #TempLog
where ProcessInfo = 'LOGON' and Text like '%SUCCEEDED%'
and Text not like '%NT AUTHORITY%'
Group by Text
DROP TABLE #TempLog
DROP TABLE #logF
Listing 7.7: Searching for failed login attempts
The results of this query are shown in Figure 7.4
Figure 7.4: Querying for successful and unsuccessful login attempts
We can see that there is a "BadPerson" out there who has tried 15 times to access this server The second result set shows the st successful login for a certain account, retrieved using the MAX() function for the last_login field
While this particular example probes login attempts for security auditing purposes, the same solution can be easily tweaked to accommodate all manner of error log analysis, from database errors to backup failures
Trang 5DDL triggers
In Chapter 1, I included in the Configuration script (Listing 1.2) code to create a DDL trigger that would alert the DBA to any database creation or deletion (drop) I'm now going to demonstrate how to use this to track DDL actions, and what you can expect to see with this DDL trigger enabled on your SQL Servers
DDL (Data Definition Language) triggers are very similar to the DML (Data Manipulation Language) triggers, with which you are undoubtedly familiar DDL triggers can be scoped at either the database or server level, meaning they can be set to fire when a particular statement, such as ALTER TABLE, is issued against a specific database, or when a DDL statement is issued at the server level, such as
CREATE LOGIN
Listing 7.7 shows the code to create the DDL trigger, AuditDatabaseDDL, which you may have missed amongst everything else going on in Listing 1.2
Notice that the scope of the trigger, in this case, is ALL SERVER The Eventdata()
function is employed to set the values of the variables that will ultimately be mailed to the DBAs when the DDL event occurs, in this case when a database is created or dropped from the server where the trigger is created
Setup DDL Triggers
Setup Create Database or Drop Database DDL Trigger
/****** Object: DdlTrigger [AuditDatabaseDDL]
Script Date: 02/05/2009 19:56:33 ******/ SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [AuditDatabaseDDL]
ON ALL SERVER
FOR CREATE_DATABASE , DROP_DATABASE
AS
DECLARE @data XML ,
@tsqlCommand NVARCHAR ( MAX ),
@eventType NVARCHAR ( 100 ),
@serverName NVARCHAR ( 100 ),
@loginName NVARCHAR ( 100 ),
@username NVARCHAR ( 100 ),
@databaseName NVARCHAR ( 100 ),
@objectName NVARCHAR ( 100 ),