Triggers in sql server 2008 management studio - sql-server

I am trying to set up the trigger in a way that when the administrator (not users) make any changes to the database, all the changed data with the administrator name and time gets saved in the audit table (already created) that has all the possible fields.
I have created triggers on each table for any sort of updates in those tables. The trigger saves the information in audittable. However, i want to restrict this action for administrators only. Like I only want to keep the record of changes made by adminsitrators with their name, time and changes made by them(I have a separate table for adminsitrator names, username, pw and all that).
Can someone please help me with that.
Thanks

To get the user you may use:
server level (login)
select system_user , suser_sname() , suser_sid()
db level (db user)
select session_user , current_user , user , user_name() , user_id()
Than and check that this user is admin or not in that additional table.

You can try one of these two functions, depending on what you define as "administrator".
SELECT IS_MEMBER('dbo'), IS_SRVROLEMEMBER('sysadmin')
The IS_MEMBER function evaluates the database role and the IS_SRVROLEMEMBER evaluates the server role. So, if you want to know if the user is a database admin, you would use IS_MEMBER. These will work for user-defined roles as well as built-in roles.
UPDATE:
Here's an example of the trigger that would add data to the audit table when a server administrator inserts data to the table.
CREATE TRIGGER trg_InfoUpdates ON tblCustomerInfo
FOR INSERT AS
IF IS_SRVROLEMEMBER('sysadmin') = 1
BEGIN
INSERT INTO tblAuditLog (CustomerID)
SELECT CustomerID
FROM inserted
END
;

Related

Block access to column without changing query

I have a Microsoft SQL Server with data that needs to be protected (certain sensitive columns of some tables) and an application that queries that database like this:
SELECT BoringColumn, SensitiveColumn FROM Table
I have the following restrictions:
I have multiple users (3-4) each with different columns visible or not.
In this example SensitiveColumn should not be accessible.
I can not directly update the queries that the application sends
What did I try already:
I tried to use SQL Servers Dynamic Data Masking feature. However it's not granular enough, you can just turn it on or off per user but not just for some columns. And its can leak data in queries, the link above explains that as well.
I know I can just deny the user SELECT on Table.SensitiveColumn.
However then any existing query asking for the table just breaks with permission errors.
What other options do I have left?
Ideally I would like something that replaces the query on the serverside and executes something like this:
SELECT BoringColumn, 'N/A' as SensitiveColumn FROM Table
I think I found a possible solution:
Change the table structure - Rename the SensitiveColumn to a different name, and add a computed column with the old name of the SensitiveColumn, that will show results based on current_user.
CREATE TABLE tblTest
(
boringColumn int,
SensitiveBase varchar(10), -- no user should have direct access to this column!
SensitiveColumn as
case current_user
when 'Trusted login' then SensitiveBase
else 'N/A'
end
)
The one thing I'm not sure about is if you can deny access to the SensitiveBase column but grant it to the SensitiveColumn.
I'll leave you to test it yourself.
If that can't be done, you can simply grant select permissions on the SensitiveBase column only to trusted login and deny them for everyone else.

SQLServer, temporarily disabling row level security

I have implemented row level security in SQLServer in Person table (to meet GDPR requirements) so that a basic user can see only subset of personal records. The
Person table has some data (RFID tag) that must be unique in the system. So my app checks that there is no duplicate RFIDtag.
How to do this check when RLS is on, because the query only sees a subset of rows, but the RFID must be globally unique ? What could be the best way to run this query with temporarily disabling RLS ?
My first idea is to use a stored function, to perform the check. The function executed as 'sa' user sa could see all rows. Any other (simpler) ideas ?
The UNIQUE index is the safest approach, like said in #Jeroen's comment.
Disabling row level security can be needed in other contexts, though. When needed, my suggestion is:
Create an 'admin' user just for this (CREATE USER admin WITHOUT LOGIN;)
Include logic in your validation function to account for this user:
CREATE FUNCTION Security.fn_securitypredicate(#param as VARCHAR(100))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS Result
WHERE
/* Your logic here */
OR
USER_NAME() = 'admin' ;
This way, when you are impersonating 'admin' user all records are accessible. Any other user, your row level security logic still applies.
To impersonate the user when running a query:
EXECUTE AS USER = 'admin';
SELECT * FROM MyTable;
REVERT; -- Returns to the original user context

Azure DB - How to give 1 user read-only permission for 1 table

I've been reading many answers but I am too weak at TSQL to filter out what I need.
I created a contained user for 1 DB...
CREATE USER appuser WITH PASSWORD = 'strongpwd';
So I need to allow a user in to read only the contents of 1 table - tableA (there are others in the DB) and do absolutely nothing else in the DB.
I do not want to affect any other users. I just want the user to be able to access the DB via say SSMS, see only tableA (well this is not that important), read it.
There are two ways one is to directly grant explicit SELECT only on Table 1 and the second one is to create a role, grant SELECT to role and addd the user to the role. Typically second way is the preferred way and can be done as below
CREATE ROLE [role_name]
GRANT SELECT ON [Table] to [role_name]
EXEC sp_addrolemember '[role_name]', 'appuser'

Dynamic Row Level Security In a SQL Server Database Using Extended Properties

We have a requirement to provide customer access to a staging database so that they can extract their data into their own servers, but every table contains all customers data. All of the tables have a 'CustomerID' column. Customers should only see rows where the customerID is the same as theirs.
I am not looking for suggestions to create separate databases or views for each customer as both suggestions are high maintenance and low efficiency.
My solution has to work with:
100GB database
400 Tables
Updates every 30 minutes from the core transaction database
Quarterly schema changes (Application is in continuous Development).
Can anyone give me a definitive answer as to why the following method is not secure or will not work?:
I've set up a database user for each customer, with their customerID as an extended property.
I've created a view of every table that dynamically selects * from the table where the customerID column is the same as the extended property CustomerID of the logged in user. The code looks like this and appears to work well:
CREATE VIEW [CustomerAccessDatabase].[vw_Sales]
AS SELECT * FROM [CustomerAccessDatabase].[Sales]
WHERE [Sales].[CustomerID]=
(SELECT CONVERT(INT,p.value) AS [Value]
FROM sys.extended_properties
JOIN sys.sysusers ON extended_properties.major_id=sysusers.[uid]
AND extended_properties.name = 'CustomerID'
AND sysusers.[SID]=(SELECT suser_sid())
);
GO
To provide access to the views I've created a generic database role 'Customer_Access_Role'. This role has access granted to all of the table views, but access to the database tables themselves is denied.
To prevent users from changing their own customerID I've denied access to the extended properties like so:
USE [master];
GO
DENY EXEC ON sys.sp_addextendedproperty to [public];
GO
DENY EXEC ON sys.sp_dropextendedproperty to [public];
GO
DENY EXEC ON sys.sp_updateextendedproperty to [public];
GO
The end result is that I only need one database, and one set of permissions.
To add a new customer all I would need to do is create a new user with their customerID as an extended attribute and add them to the Customer_Access_Role. Thats it!
I am going to reiterate what everyone is stating already and sum it up.
You are making your job harder than it has to be.
Create a View, that is just their data and then give them Security access to that View.
Alternatively, extract all their data out of the "Core" database and into their own and give them the necessary access to that data.

prevent some user from seeing db2 tables structure

How can I restrict some users in DB2, not to see the table structure. I set the user privilege and restrict user from table access. so that user can not select data or change table but still can see the table structure or describe it.
This problem refers to row access in tables which is added in db2 version 10.
I had this problem too.
you can use this version - if applicable- and restrict user access from specific table structures.
You need to remove the select grant on catalog tables. For example, the following query should return 0 rows when executing with q restricted user.
db2 "select tabschema, tabname from syscat.tables"
All tables and views in the following schemas should not have select on public, nor in any group the restrictive user is in.
sysibm
syscat
db2 revoke select on SYSIBM.SYSTABLES from username

Resources