SQL user can only run proc, but that proc can do anything - sql-server

In SQL Server 2005, I want a user, called LimitedUser, to only be able to run one proc:
GRANT EXEC ON [usp_RunETL] TO [LimitedUser]
However, that proc needs to be able to do everything -- UPDATE, DELETE, INSERT, EXEC.. everything. How do I do that without having to give all those permissions to LimitedUser?

LimitedUser only needs permission to run the sproc. They don't need any other permissions.

You only need to GRANT EXEC to the limited user. As long as the user has permissions to the stored procedure, it ignores/overrides permissions for operations inside of the procedure.
I would be very careful doing this though, this sounds like a big potential security hole. Typically you would use multiple procedures to have the flexibility to adjust permissions as necessary. I would recommend to assign the permissions to the procedure, or to the underlying tables and views, rather than decide that there will be only one super procedure.

Related

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.

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.

Stored Procedures access when no access in a table

All,
In SQL Server, can a stored procedure (beeing ran from a user) write to table where the user doesn't have access to write directly to the table?
Rgds,
MK
The correct answer is NO, a stored procedure does not have access to write into a table. However most users perceive it, incorrectly, as YES because of Ownership Chains:
When multiple database objects access
each other sequentially, the sequence
is known as a chain. Although such
chains do not independently exist,
when SQL Server traverses the links in
a chain, SQL Server evaluates
permissions on the constituent objects
differently than it would if it were
accessing the objects separately.
These differences have important
implications for managing security.
Ownership chaining enables managing
access to multiple objects, such as
multiple tables, by setting
permissions on one object, such as a
view.
So a procedure will be able to write into a table that the user has no permissions to write into if they form an ownership chain. This means that if the owner of the schema that contains the table is the same as the owner of the schema that contains the procedure, an ownership chain is formed and the procedure is allowed to write into the table. Since the vast majority of objects deployed in practice belong to the dbo schema, an ownership chain is almost always formed.
It is important to comprehend these details, so you can troubleshoot problems and understand why is the procedure allowed to write into the table. Erland Sommarskog has an excellent comprehensive write up on this topic: Giving Permissions through Stored Procedures. This article goes into great detail explaining all the options available. Your best option, far better than ownership chaining, is code signing.
Understanding how this works also helps understanding why dynamic SQL seems to 'break': running dynamic SQL is an automatic break in the ownership chain, which causes all 'magic' to disappear. And it also helps understand why this 'magic' appears not to work outside the database: cross db ownership chaining Option default value is 0.
In short, yes.
The main restriction in play in this scenario is whether the user can execute the stored procedure.
When creating the stored procedure, it needs to be done with a login/user that has the necessary write access to the table in question.
Yes, if the user is GRANTed EXEC permissions on the SP, any actions it takes (within that database) are allowed.
Going over to another database will require permissions on the underlying user to be examined.
Also, dynamic SQL built within the SP will require the underlying user to have permissions.

Why is there no built-in "stored procedure executor" database role?

I've always wondered why the list of database roles (db_datareader, db_datawriter, db_ddladmin, etc) never included a db_storedprocedureexecutor. The others make sense, but it seems like being able to grant the ability to execute all stored procs to a particular user (without granting them db_owner, which is the only other way to accomplish the same thing) would be a handy thing.
For example, say I want to give all of my developers the rights to run stored procedures, while not let them execute any DDL - without explicitly granting EXECUTE on every stored procedure (and then remembering to add the new ones when additional SPs are deployed), there's not way to do this (I know that SPs can contain DDL, so they may still be indirectly allowed access to DDL this way).
If I have an application service account and a number of stored procedures that go along with my application, I have to grant rights explicitly to every SP (since I don't want to grant my application service account DBO), whereas I can use a role to allow them to update/delete anything they want.
While it initially seemed obvious, I'm now not sure why this role is missing from the database server - can anybody offer an explanation of why this is a terrible idea (as I assume it is, or it would already exist)?
EDIT:
Seems I'm not the only one with this expectation - and it's worked around with a handful of T-SQL (it seems you can grant a blanket EXECUTE right, which I wasn't aware you could do), which just leaves me wondering why it's not standard!
If you use schemas, then you only have to GRANT EXECUTE ON SCHEMA::storedprocschema
eg CREATE PROC storedprocschema.DoStuff ...
As to why, no idea...
Because if you can execute all stored procedures, you can execute sp_addrolemember, and you can do everything that a database_owner can.

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