sql stored procedure execution failing because of permissions on tables - sql-server

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?

Related

How can I allow someone to run my Oracle functions/procedures but not able to view its source codes

i have an oracle database schema with functions, stored procedures and packages. i want to allow some developers to access my tables read only so i create a user with READ ONLY access to my tables. i want to grant them EXECUTE on my stored procedures and functions but NOT allowing them to view its source (code). when i grant EXECUTE on my functions or stored procedures, they can easily DESCRIBE (in SQL developer or TOAD) and view from all_source. how do i prevent them from viewing my PL/SQL sources?
One way that I can see for this type of access is to use the package.
Create package specification and body with your procedure and grant execute on your package to other user.
Having execute rights, other user will be able to execute the procedure of the package and will be able to see only package specification and not the body (the actual code)

Minimal permission for Truncate table in SSIS

I have created several Data flows in my SSIS package that execute truncate table as part of the ETL process. I am running the package via a SQL job that is configured to use service account.
I had initially provided an ALTER authorization for that table to the service account however the DBA's have comeback saying that Alter cant be used and minimal permission need to be assigned to the service account for doing truncate.
For eg.
use CoreReferenceStaging
GRANT CONNECT,EXECUTE,SELECT,DELETE, INSERT, UPDATE,ALTER ON database::CoreReferenceStaging TO "INT\svc-w-corerefdata-qa";
ALTER AUTHORIZATION ON [PartiesIssuerCreditRating] TO "INT\svc-w-corerefdata-qa";
Currently I am having 16 stored data-flows that perform Truncate table individually.
I had initially thought of creating 16 store procedures containing Execute permissions but I feel its a maintenance issue just to call one truncate table each. Is there a better way of doing it either by assigning roles etc.
Could you let me know whats the best way to deal with this situation ?
To provide minimal permissions, encapsulate the TRUNCATE statement in a stored procedure. Either specify an EXECUTE AS clause for a database user account with the needed ALTER TABLE permission or sign the proc with a certificate based on a user with the permissions. See Erland Sommarskog's article for example scripts for the certificate, user, and TRUNCATE TABLE proc. The article also includes a detailed discussion of EXECUTE AS versus module signing to grant permissions via stored procedures.

SQL Server - preventing SQL injection

I have been looking through old posts but am seeing some conflicting info on this. I have a SQL Server database and I am talking to it with C# code (.Net 4.5). I used stored procedures to do everything in the database and parameterising the inputs when I make a call.
I would like to lock down the database so that it won't accept SQL code and will only respond to calls to the stored procedures. Is this possible?
Although there is no setting to disallow ad-hoc SQL entirely, you could grant only EXECUTE permissions on only the stored procedures called directly by application code. Permissions on objects referenced by stored procedures are not needed as long as the ownership chain is unbroken, meaning that the stored procedure and referenced schema/objects are owned by the same user (typically dbo). This method will prevent ad-hoc access by non-privileged accounts.
Be aware ownership chaining does not apply when dynamic SQL is used with the procs. If procs have dynamic SQL (with securely built SQL and parameterized), you can sign the module with a certificate to provide the needed permissions from within the proc without granting users direct permissions on objects referenced by the dynamic SQL statement. See giving permissions through stored procedures for details and examples.
Be sure to specify CommandType.StoredProcedure on all SqlCommand objects to ensure parameters must be passed separately. Although it is possible to execute stored procedures using CommandType.Text, more attention to detail is needed to do securely.

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.

Determing if stored procedure can execute based on AD login

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.

Resources