4

Is it possible to give a user rights for, say the business hours of the company.

GRANT SELECT 
ON client
  <WHERE CONDITION>
TO Emily 

I know something like this is possible to do this with MySQL where you can add a WHERE clause to the grant option so you can add context conditions to it. However, I'm working with MS SQL Server, can it be done in there?

Another solution would be to add a SQL Job to add and remove the rights on specific times, but I don't really like that, I'd prefer to do this on the granting level.

Ravenix
  • 1,010
  • 4
  • 15
  • 40
  • 1
    You could also use a [logon trigger](https://msdn.microsoft.com/en-us/library/bb326598(v=sql.105).aspx) if you don't want them to be able to connect at all - but that wouldn't do anything about killing connections already open when the expiry time passes. – Martin Smith Jul 01 '17 at 14:46
  • 2
    You could create a view which only gives results to the specific time an grant select on the view – Turo Jul 01 '17 at 14:52

1 Answers1

4

I like @Turo's suggestion of using a view.

It could just consist of something like

CREATE VIEW dbo.TimeFilteredClient
AS
  SELECT *
  FROM   dbo.Client
  WHERE  CAST(GETDATE() AS TIME) BETWEEN '09:00' AND '17:00' 

Then grant Emily permissions on the view and not the table. As long as the view and table share the same owner she will be able to select from the view but get no results outside the specified time.

If you are on 2016 you could also use row level security on the table to achieve much the same thing. Example below

CREATE TABLE dbo.Client
  (
     clientId INT IDENTITY PRIMARY KEY,
     Name     VARCHAR(50)
  );

INSERT dbo.Client
VALUES ('client1'),
       ('client2');

CREATE USER Emily WITHOUT LOGIN;

GRANT SELECT ON dbo.Client TO Emily;

GO

CREATE SCHEMA Security;

GO

CREATE FUNCTION Security.EmilyTimeFilterPredicate()
RETURNS TABLE
WITH SCHEMABINDING
AS
    RETURN
      SELECT 1 AS fn_securitypredicate_result
      WHERE  USER_NAME() <> 'Emily'
              OR CAST(GETDATE() AS TIME) BETWEEN '09:00' AND '17:00';

GO

CREATE SECURITY POLICY EmilyTimeFilter  
ADD FILTER PREDICATE Security.EmilyTimeFilterPredicate()   
ON dbo.Client 
WITH (STATE = ON);  

GO

EXECUTE AS USER = 'Emily';

SELECT *
FROM   dbo.Client;

REVERT;

SELECT *
FROM   dbo.Client; 

GO

DROP SECURITY POLICY EmilyTimeFilter ;

DROP TABLE dbo.Client

DROP USER Emily

DROP FUNCTION Security.EmilyTimeFilterPredicate

DROP SCHEMA Security; 
Martin Smith
  • 438,706
  • 87
  • 741
  • 845