I'd like to create a SQL table which stores/captures user access or activities for a particular database.
For example, a table which has an entry for username, database accessed/queried, activity time etc everytime a user logs into a server and queries a particular db.
I know there's the .txt log file somewhere I would look up - but is there an easier way of doing it automatically?
How would I go about doing this?
Thanks in advance!
You can capture login activity in the SQL Server error log (turn on Login Auditing for "Both failed and successful Logins"):
USE [master];
GO
EXEC xp_instance_regwrite
N'HKEY_LOCAL_MACHINE',
N'Software\Microsoft\MSSQLServer\MSSQLServer',
N'AuditLevel',
REG_DWORD,
3;
Or by creating a LOGON TRIGGER and using that to log to a specific table.
However since there are no triggers on SELECT statements, capturing all queries would require pretty intrusive methods such as a server-side trace or SQL Server Audit.
Read about Logon Triggers in SQL Server
Related
It is possible to view and analyze queries in SQL Server before implement on database and log or drop it if necessary?
For example some application send an update query to SQL Server, can I first log it to a database, and then possibly reject it if the query is illegal based on my roles?
You can use SQL Profiler to monitor queries sent to server, but you can't do what you wnat to.
If you say it is illegal for smoe roles to execute some queries it should be specified in permissions - every role have assigned permissions.
One way to achieve what you want is to define user, which mentioned applciation would use (I would even create dedicated user). Then, if you want this user to execute SELECT, just execute such command
GRANT SELECT ON [table] TO [user]
Then the user won't be able to update table, just select rows from it.
I found solution to use SQL SERVER triggers so after insert or update I check my role so if there is any access problem I can rollback transaction and send error to user.
The standard in our company is to log the user name that inserts or updates a record at the time the record is inserted or updated. We inset and update the tables calling stored procedures from applications. We use SUSER_SNAME() in the stored procedures to get the name. Now we've added inserting records in a table on a linked server. The SUSER_SNAME function not is returning the same login name as it does on the native database. Instead it is returning the name of the account created to link with. I know I can pass the user name as another parameter to the query, but it would be easier if there is a built-in function that works both when connected to the server directly, and when connecting to a linked server. Is there a built-in function that does this?
Stored procedure
INSERT INTO Account (ForeignKey, AccountNumber, IsProcessed,
Origin, Updated, LoginName, Total)
VALUES (#ForeignKey, #AccountNumber, #IsProcessed,
GETDATE(), NULL, SUSER_SNAME(), #Total)
RETURN SCOPE_IDENTITY()
No, there's no function to do this. When you create a linked server, the linked server "opens a connection" to the 2nd server. You, the user, have a connection to the 1st server. So when you run suser_sname() on the 1st server, you get your username that you are connected with. When you run it on the 2nd server, you STILL get the user name that you are using to connect to the second server. The difference is that the connection to the 2nd server is controlled by the administrator that configured the Linked Server. In your case, it sounds like he created a special account that is used for a linked server connection. Another option is to map accounts from the current server to accounts on the 2nd server. (If your DBA had done that, you might be getting the results that you want right now and not had any issues.) There are different ways to configure a linked server, and security should generally be a priority when doing so.
So, if you want to execute a query on the 2nd server and use your user name from the 1st server, then you need to pass it to the 2nd server, because it has no way of knowing who you are on a different machine.
I have created a procedure in different database than the user used to create it,
The user I used to create the procedure is like 'vbhas' and the database it is created is like 'IFSRD', when I login as 'vbhas' and try to execute the proc it gives the error, could you please let me know how to modify the execute access so that I will be able to execute this procedure successfully?
Thanks
You have to add the SECURITY option. Depending on the SQL in the SP and your needs this might be SECURITY CREATOR|OWNER|INVOKER instead of the default DEFINER.
You should read the manuals for details
Thanks dnoeth...
Got to know that Teradata gives permissions at database level, so now I created the procedure in the database which has execute permissions to all objects.
I have a situation whereby an application we use has many databases used for storage, and creates new ones on the fly as needed (SQL Server 2008 R2).
ApplicationDatabase
ApplicationDatabase_Storage001
ApplicationDatabase_Storage002
ApplicationDatabase_Storage003
etc...
As needed the application will create a new storage database for itself.
My problem is that I have a sql server account that is used for the ApplicationDatabase, and I want to automatically give it permissions to the storage databases as they are created, but not to any other database that happens to be created in the same sql server instance. I have no control over the creation of the storage databases.
I read In the answer to this question that I can add the account in the model database however this appears to add the permissions for all new databases, when I only want it to apply to the databases mentioned above.
The best solution I could come up with is a SQL server job or external app that runs once a day or so and looks for the existence of each database, applying the permissions on each that it finds, but this does not seem ideal.
You can implement a DDL trigger that will be fired whenever a new database is created. Depending on the properties of the database, like name or storage definition, you can probably run additional scripts on the new database to set up the required security.
http://msdn.microsoft.com/en-us/library/ms186406.aspx
Here's a snippet from the article above:
IF EXISTS (SELECT * FROM sys.server_triggers
WHERE name = 'ddl_trig_database')
DROP TRIGGER ddl_trig_database
ON ALL SERVER;
GO
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS
PRINT 'Database Created.'
SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
GO
DROP TRIGGER ddl_trig_database
ON ALL SERVER;
GO
Regards
Piotr
I have many databases in one SQL Server instance. Also I have many individual domain users for logins and also domain groups as logins. These logins are attached to databases as database users. Now I would like to create a report (or a query) to find out when and where (which database) these logins take a connection. I tried to find this information from sys-schema, but I could not find this kind of information. Where SQL Server store this information and how to create this kind of report? I would also like to automate this using a stored procedure.
in the login stored procedure, along with the username, add a GetDate() and DB_NAME() to each record in a table called LoginData (or whatever you prefer)
You could set up a SQL trace logging all login events then just query that.