Clear logs from SQL Server Audit File - sql-server

Is it possible to Clear SQL Server Audit File logs. I want to delete old logs by date but can't find a way to delete it both from interface and sql Query.

Yes, it is.
By sys.server_audits select old names via create_date column.
Then loop the names and delete them by using the next code for deleting:
ALTER SERVER AUDIT [Audit_name] WITH (STATE = OFF)
GO
USE [master]
GO
DROP SERVER AUDIT [Audit_name]
GO

Related

SQL Server Database Auditing not working for Sysadmin users

I'm trying to Audit Sysadmin users at Database level; however, none of the SELECTS, INSERTS, UPDATES and DELETES are being audited.
I created the Server Audit, followed by the Server Audit specification
ADD (DATABASE_OBJECT_ACCESS_GROUP) and then the Database Audit specification to audit the database as a whole: ADD (SELECT, UPDATE, INSERT, DELETE, EXECUTE, RECEIVE, REFERENCES ON DATABASE::TestAuditDB BY newsa2);
I tested it by INSERTing and SELECTing with that user 'newsa2'; however, no audit entries were found.
I need very specific entries for each sysadmin user to be entered into the Audit log
Here is my code:
USE [master]
GO
DROP SERVER AUDIT [Audit_sql2016]
TO FILE
( FILEPATH = N'C:\Audit\SQL2016'
,MAXSIZE = 100 MB
,MAX_ROLLOVER_FILES = 2147483647
,RESERVE_DISK_SPACE = OFF
)
WITH
( QUEUE_DELAY = 1000
,ON_FAILURE = CONTINUE
);
GO
CREATE SERVER AUDIT SPECIFICATION [Audit_sql2016Specification]
FOR SERVER AUDIT [Audit_sql2016]
ADD (DATABASE_OBJECT_ACCESS_GROUP)
WITH (STATE = OFF);
GO
ALTER SERVER AUDIT SPECIFICATION [Audit_sql2016Specification]
FOR SERVER AUDIT [Audit_sql2016]
WITH (STATE = ON);
ALTER SERVER AUDIT Audit_sql2016 WITH (STATE = OFF)
GO
USE TestAuditDB
GO
DROP DATABASE AUDIT SPECIFICATION [Audit_sql2016SpecificationDatabase]
FOR SERVER AUDIT [Audit_sql2016]
ADD (SELECT, UPDATE, INSERT, DELETE, EXECUTE, RECEIVE, REFERENCES ON DATABASE::TestAuditDB BY newsa2);
ALTER DATABASE AUDIT SPECIFICATION [Audit_sql2016SpecificationDatabase]
--FOR SERVER AUDIT [Audit_sql2016]
WITH (STATE = ON);
I have adapted and fixed your script (there is a missing step to enable SERVER AUDIT - I noticed with SQL Server Management Studio where there was a red cross for related icon):
USE [master]
GO
ALTER SERVER AUDIT [audit_server] WITH (STATE=OFF)
GO
DROP SERVER AUDIT [audit_server]
GO
ALTER SERVER AUDIT SPECIFICATION [audit_spec] WITH (STATE = OFF)
GO
DROP SERVER AUDIT SPECIFICATION [audit_spec]
GO
CREATE SERVER AUDIT [audit_server]
TO FILE
( FILEPATH = 'C:\Audit'
)
WHERE database_name='test';
GO
ALTER SERVER AUDIT [audit_server] WITH (STATE = ON);
GO
CREATE SERVER AUDIT SPECIFICATION [audit_spec]
FOR SERVER AUDIT [audit_server]
WITH (STATE = OFF);
GO
ALTER SERVER AUDIT SPECIFICATION [audit_spec]
FOR SERVER AUDIT [audit_server]
ADD (DATABASE_OBJECT_ACCESS_GROUP)
WITH (STATE = ON);
USE Test
GO
ALTER DATABASE AUDIT SPECIFICATION [audit_db]
WITH (STATE = OFF);
GO
DROP DATABASE AUDIT SPECIFICATION [audit_db]
GO
CREATE DATABASE AUDIT SPECIFICATION [audit_db]
FOR SERVER AUDIT [audit_server]
ADD (SELECT, UPDATE, INSERT, DELETE, EXECUTE, RECEIVE, REFERENCES ON DATABASE::test by public);
GO
ALTER DATABASE AUDIT SPECIFICATION [audit_db]
WITH (STATE = ON);
GO
With this setup I can have in audit following DML statements run by user dbo in database test (corresponding login has sysadmin role):
use test
go
delete from t;
go
insert into t values(1);
go
Tested with SQL Server 2019.
You can audit only a specific schema with:
CREATE DATABASE AUDIT SPECIFICATION [audit_db]
FOR SERVER AUDIT [audit_server]
ADD (SELECT, UPDATE, INSERT, DELETE, EXECUTE, RECEIVE, REFERENCES ON SCHEMA::myschema by public);
GO
Should we add the SCHEMA_OBJECT_ACCESS_GROUP to the Audit Server specification? I want to audit only the dbo schema, as the sys schema audits are generating too much noise.
Ans: Not required. The DATABASE_OBJECT_ACCESS_GROUP takes care of this as well.

My query sys.database_audit_specification does't send back any record

I'm studying about SQL Server Audit. I have deployed Server Audit Specification. Now I want to query all the records but It doesn't return anything.
I use Windows Server 2012 Datacenter - SQL Server 2014 Developer Version
use master
go
select *
from sys.database_audit_specifications;
go
I got no output and don't understand why.
How can I fix it?
Here is an example that creates a server-level audit, then adds a database-level audit specification to track multiple operations on any object in the dbo schema.
USE master;
GO
-- create aserver audit
CREATE SERVER AUDIT Test_Server_Audit
TO FILE ( FILEPATH = 'C:\temp\' ); -- you may need to change that'
GO
-- turn it on
ALTER SERVER AUDIT Test_Server_Audit WITH (STATE = ON);
GO
-- create a demo database
CREATE DATABASE floob;
GO
USE floob;
GO
CREATE TABLE dbo.blat(x INT);
GO
-- create a database audit specification that monitors for activity
-- against any dbo object:
CREATE DATABASE AUDIT SPECIFICATION Test_Database_Audit
FOR SERVER AUDIT Test_Server_Audit
ADD (SELECT, UPDATE, DELETE, INSERT, EXECUTE ON SCHEMA::dbo BY PUBLIC)
WITH (STATE = ON);
GO
-- do a couple of things:
SELECT * FROM dbo.blat;
DELETE dbo.blat;
GO
-- you should see those couple of things in the audit file:
SELECT * FROM sys.fn_get_audit_file('C:\temp\*.sqlaudit', NULL, NULL);
GO
For Further Reading follow this

How to protect SQL Server Database from accidental deletion?

I would like to somehow protect databases on my SQL Server from being deleted without entering a password, even by someone with administrative access. There are times where a database has been deleted accidentally (for example, when two databases have similar names) and I'd like to prevent this from being an easy mistake to make.
I'm also open to any suggestions or alternative ideas on how to handle this. Thank you!
Create a Server Level Trigger that Rolls back any attempt to delete a database.
The Trigger will need to be disabled then re-enabled to perform any legitimate deletions.
USE [master]
GO
CREATE TRIGGER [Trig_Prevent_Drop_Database] ON ALL SERVER
FOR DROP_DATABASE
AS
RAISERROR('Dropping of databases has been disabled on this server.', 16,1);
ROLLBACK;
GO
DISABLE TRIGGER [Trig_Prevent_Drop_Database] ON ALL SERVER
GO
Or as a process:
Create a single-column, one row table in Master that will hold a database name.
Insert the name of the database in the Table.
Add an If statement to the trigger to check if the Database being dropped is identical to the Database in the table created in step 1. Otherwise Roll-back.
In this case you wouldn't need to disable the Trigger. But you're creating 2 points in the process where you define the database name.
Capturing the Database Name in a Server Level Trigger should be possible with:
SELECT CAST(eventdata().query('/EVENT_INSTANCE/DatabaseName[1]/text()') as NVarchar(128))

Not able to create table in SQL job

If I need to delete data from any of the table from my database,first I will create backup table and move data in my backup database by date and time and I will delete the data. all the above process i'm doing inside an procedure, my delete script I'm pass as an input parameter. If i run the procedure manually it is Woking and my data also creating in backup table.
But, if I keep this exce procedure inside a SQL server agent job Data is deleting but not able to create table in my backup database.
Can anybody pls give me a solution to why my table is not creating inside SQL job.
Based on your comment, you need to grant the service account that runs SQL Server Agent, ddladmin permissions
EXECUTE sp_addrolemember 'db_ddladmin', [serviceaccount]
or permissions to create tables:
GRANT CREATE TABLE to [serviceaccount];

Default schema for DROP and SELECT INTO in stored procedures

I am a bit confused as to how the default database schema is determined in MS SQL server.
I have the following stored procedure as a minimal working example:
CREATE PROCEDURE [dbo].[SampleSP]
AS
SELECT 'HI' as [SampleColumn]
INTO [SampleTable]
DROP TABLE [SampleTable]
All tests are executed using a user User on MS SQL server using Windows Auth with a default database schema of the same name.
When I execute this SP on MS SQL Server 2005 installation (running in compatibility mode 80, i.e. Server 2000) the table is created as [User].[SampleTable] and DROP TABLE fails with Invalid object name 'SampleTable' (I assume because it looks for [dbo].[SampleTable])
When I DROP TABLE [SampleTable] in a separate query it does work
When I execute the SP on MS SQL Server 2008 R2 (also running in compat. 80) the table is created as [dbo].[SampleTable] and dropped without error
I have found this answer describing the lookup in stored procedures, but it doesn't mention the user default in that context, even though it is used on 2005. Maybe someone knows how this changed and whether new versions can be configured to behave the same way.
It sounds like you just need to set the default schema for the user to dbo:
ALTER USER YourUser WITH DEFAULT_SCHEMA = dbo;
That way it's set at the user level and you won't need to alter any code.

Resources