Determing if stored procedure can execute based on AD login - sql-server

I have a stored procedure that updates data in a table for a specific record. I have several users who will be making use of this stored procedure however I only want to them to be able to update records that are assigned to them.
Each record that is to be updated by the stored procedure has a field named "UserID" which define who has control over the record. I also have a mapping table that maps active directory logins to the UserID's.
I am using Active Directory so SQL Server knows who is attempting to execute the stored procedure. Is there a way within the stored procedure to look-up the users active directory login in another table and then determine if they have access to the records attempting to be updated?

You can find out who the current user is in the proc by calling SYSTEM_USER and incorporating that into the query that updates the rows.

Does this article help? Granting Row-Level Permissions in SQL Server
It recommends the following steps
Create the table, adding an additional column to store the name.
Create a view that has a WHERE clause based on the user name column. This will restrict the rows returned to those with the specified value. Use one of the built-in functions to specify a database user or login name. This eliminates the need to create different views for different users.
Create stored procedures to select, insert, update, and delete data based on the view, not the base tables. The view provides a filter that restricts the rows returned or modified.
For stored procedures that insert data, capture the user name using the same function specified in the WHERE clause of the view and insert that value into the UserName column.
Deny all permissions on the tables and views to the public role. Users will not be able to inherit permissions from other database roles, because the WHERE clause is based on user or login names, not on roles.
Grant EXECUTE on the stored procedures to database roles. Users can only access data through the stored procedures provided.

I'm no application designer but on the surface, your solution sounds unnecessarily complicated to me.
That said, you can issue the following query to get the Windows AD Login name of the user currently executing the stored procedure. You can use this information to cross reference with your mapping table to determine if the AD account has the required privileges to perform the operation.
SELECT SYSTEM_USER
Do keep in mind that this returns the name of the currently executing context, so keep in mind that this can be explicitly changed using the "Execute As" statement.
EDIT:
I wonder if perhaps a view could be used to limit the data visible to a given AD account. The Stored Procedure logic could then focus on the data modification aspect, rather than security implementation. Controlling your data access using views would also ensure that a consistent security access method is used across multiple stored procedures if required, as opposed to having to implement security checking within each.
Since writing this, the link provided by Martin Smith, details how this solution can be implemented:
Granting Row-Level Permissions in SQL Server
In conclusion, a combination of both is how Microsoft suggest you implement the solution to your problem.

Related

How to prevent users from creating new tables/stored procedures or modifying existing procedures. SQL Server 2017

Is there a way to lock down (preferably at the server level but DB level is also fine) tables and stored procedures? I don't want specific users creating new procedures or tables, but want them to be able to write to tables (via some Excel macros we have in place) and execute existing procedures. I would not want this to be a blanket policy, I'd prefer to specify which users this applies to.
Do you have individual ms SQL server logins for every user? Then you can set the access rights of these to Datareader and datawriter only in the security section or on database level.
If everyone uses the same login, you will have to create trigger on the data definition level. E.g. a trigger on CREATE TABLE that aborts any action.
Edit: I suggest you create a new login specifically for those excel macros.

Access table indirectly, while still allowing to update the table

I plan to pass exam 'Querying Microsoft SQL Server 2012'. I would like to better understand one question.
Question is:
How would you accomplish this task?
You work as a database developer
at ABC.com. ABC.com has a SQL Server 2012 database named SalesDB with
a table named Invoices. Application developers are developing several
in-house applications that will access the Invoices table. You need to
develop a solution that will allow the applications to access the
table indirectly while still allowing them to update the Invoice
table. How would you accomplish this task?
possible answers are.
A. You should create a view on the Invoices table.
B. You should create a columnstore index on all columns used by the
applications.
C. You should allow the applications access to the Invoices table via
stored procedures.
D. You should drop and recreate the Invoices table as a partitioned
table. Possible answers are
This is source: How would you accomplish this task?
They say that correct answer is C, but I don't know why? I think that correct is A, because view works 'indirectly' with data.
Thank for help.
The commented ownership-chaining of stored procs only come into place when the stored proc and the used tables have the same owner.
So I would like to point out another argument.
You can EXECUTE a stored proc AS another user. That means you could create a user without a login and grant UPDATE permissions. Let's say the name of the user is UPDATEInvoices. When you create a stored proc you can define that it has to execute as the comtext of the user.
So, when you give the user who wants to call the stored proc EXECUTE permissions he can UPDATE rows in the table because it runs with other permissions.

Enable/Disable stored procedures

I am working with a large group of stored procedures (~300) in SQL Server 2012 Web Edition and I need to enable/disable some of the stored procedures at various times.
Is there a way to create a sub-folder under "Programmability" in SQL Server Management Studio to place inactive stored procedures in? If not, is there an option to enable/disable a specific stored procedure without removing it from the database? Since I frequently need to enable/disable I would rather not remove the procedure and then re-script it when it is needed?
Create those stored procedure in a separate schema (use CREATE SCHEMA) and then GRANT or REVOKE execution right on all stored procedures in that schema for the users in charge.
As a suggestion, you can have contract in naming for example spTest is enables and spTest_Disabled is the same one which is disabled, so you can write another storedprocedue with this sugnature spChangeSpStatus(spName,state) this sp uses sp_rename to rename the procedure to new one,(I mean adding _disabled to its name or remove _disabled form the name)
I hope this helps
You can't create a subfolder, but can create another schema. Name it whatever you like (say inactive) and set permissions on it appropriately.
Then write a script to move objects from the working schema (say dbo) to inactive:
alter schema inactive transfer dbo.proc
There is an inexpensive tool called SQLTreeo that allows you to create folders in the Object Explorer. If I remember correctly, there are two modes of operation, one that allows each user with the tool to have their individual folder structure, and another that imposes a common folder structure appear on all machines that have SQLTreeo installed.
Create a new table to manage your SP, and in each SP just add an IF that always ask for the table created dbo.ManagerSP if that sp is Active=true, if true the SP runs,,,if not,,,not runs,,
And with that for control all your SP just need run an UPDATE of active status in dbo.ManagerSP

Role for read-only access to execute SP/get result set, without indirectly modifying db?

For example
if a SQL Server user account is given
only the DataReader role and ability to execute one stored
procedure that modifies data in some
way, should the execution of that
stored procedure by that user cause
the modification to occur?
Overall, I want to give one user only read ability to the entire database including use of SQL syntax, Views and to execute any store procedures that return result sets. But I don't want any side effects to cause changes in the database. Therefore in the aforementioned stored procedure example, the attempt would ideally error out to satisfy my requirement, and all similar scenarios where a side-effect might cause a change. I want to ensure my database is protected against those.
Is this doable simply at the role level?
Product: SQL Server 2005 and up
Sure you can do this. Simply create a database role at the database level, and grant that role read on the tables and execute on only the stored procedures you want (i.e. the ones that read). Then, add the desired user(s) to your database role.
However, all things considering, if you are using stored procedures to read data, do so completely and do not grant read on tables for users of any level. Drive all data access through stored procedures (and views).
EDIT: Just noticed you said SQL 2005 "and up." If you are using SQL Server 2008, look at application roles instead of the traditional database roles.

sql stored procedure execution failing because of permissions on tables

Let me explain the context first.
There are two databases sitting on two distinct servers on the same network. There is a stored procedure which copies data from a table in one database to a table in the other database (the two databases have same structure, but contain different data). Users do not have permissions to query tables directly (unless their role permits them to do so), only trough stored procedures.
Now the problem.
When the stored procedure is executed by a user, it fails giving an error message that the permissions on the target table of an insert statement do not allow the user to access it. However, since the user has permission to execute the stored procedure, this should not stand in a way, should it?
an excerpt form msdn documentation:
"Stored procedures take advantage of ownership chaining to provide access to data so that users do not need to have explicit permission to access database objects. An ownership chain exists when objects that access each other sequentially are owned by the same user. For example, a stored procedure can call other stored procedures, or a stored procedure can access multiple tables. If all objects in the chain of execution have the same owner, then SQL Server only checks the EXECUTE permission for the caller, not the caller's permissions on other objects. Therefore you need to grant only EXECUTE permissions on stored procedures; you can revoke or deny all permissions on the underlying tables."
Why is the execution failing then? All the tables have the same owner.
Are you using a "OpenQuery" inside the procedure ? try using fully qualified names including the linked server.
INSERT INTO Linked_Server.Database.schema.table_name
Select .............
The stored procedure you have does it insert data into tables on both servers. Are you using a linked server and if you are does the user have permissions to do the insert into the table via the linked server as well as having permissions to execute the stored procedure?

Resources