SQL EXECUTE AS Clause - sql-server

I have an SQL user 'ABC', having sysadmin rights and access to all the databases, lets say database A and Database B, of the specific server. Where as my application uses users having access to only one database A.
I have created an stored procedure to insert records in tables of database B. So I am using EXECUTE AS clause to execute stored procedure with user ABC, but after testing I found that if my application users don't have exactly the same server roles as the use ABC have,it don't work.
When I make my other user sysadmin, it gives no error and works great.
If both users needs to have same roles then what's the use of this EXECUTE AS clause? Or am I missing something?

I think you question has already been answered here: SQL Server Execute Impersonation
execute as user = 'ABC' --The scope of impersonation is restricted to the current database.
vs
execute as login = 'ABC' --The scope of impersonation is at the server level.

Related

How to create a login that ONLY has access to run stored procedures?

I have a C# Winform application that interacts with an SQL Server DB via stored procedures. In SSMS, how do I create a login that ONLY has permissions to run stored procedures? That login wouldn't be able to view/edit/create table definitions, etc. It would also only have access to a single specified DB.
The reason I want to create such a login is because I store the SQL Server credentials used by my Winform application in its App.config file. Since the app.config can easily be read, anyone with malicious intent can easily perform unwanted operations on the database if the given login had any other permissions than just stored procedures.
A neat trick in this scenario is to create a separate (custom) SQL Server role that can only execute stored procedures:
CREATE ROLE db_executor;
GRANT EXECUTE TO db_executor;
This role now has the permission to execute any stored procedure in the database in which it's been created - and in addition: that permission will also extend to any future stored procedures you might create later on in this database.
Now create a user in your database and give it only this database role - this user will only be able to execute stored procedures - any and all of them in your database.
If you user should be allowed to execute any and all stored procedures - this is a very convenient way to allow this (and you don't have to constantly update the permissions when new stored procedures are created).
You can use the following query in order to allow stored procedure execute permision to your user
USE [DB]
GRANT EXECUTE ON dbo.procname TO username;
However, in my humble opinion , you should secure the connection string in the app.config.
Maybe , this How to store login details securely in the application config file link can be helped to you.
The access to a specific database is done through creating a user on the database that you want him to operate on. You can find more infos about users here.
If the user is created you can Grant, With Grant and Deny actions for every single item on the database.
The user will then be granted/denied those rights by a grantor, which is the dbo by default.
You can use this to also deny him access to every item on your database that isn't your stored procedure, which is what you're looking for if I understand you correctly.
Try folloiwng approach (grant execute should be repeated for every SP). Note that MyStoredProcedure has to be in MyDatabase :)
-- create login to server
create login test_user with password = 'test';
-- create user mapped to a database
use MyDatabase
go
create user test_user for login test_user;
-- grant permission to execute SP
grant execute on MyStoredProcedure to test_user

Sql Server Agent job failing to execute stored procedure

I have a stored procedure that I can execute in SSMS with a non domain SQL Server user.
This stored procedure selects data from tables in one database (DB1) truncates and selects into a table in DB2.
The user has datareader,datawriter and dbowner for both databases.
Problem:
When I execute the stored procedure via SS Agent with execute as the user I get the following error
The server principal [user] is not able to access the database [DB1]
under the current security context.
Actions taken So far:
I have tried to resolve this so far by:
Turning on db chaining for both databases
Deleted the user from DB1 and added again
Checked using EXEC sp_change_users_login #Action=’Report’ to see if user orphaned. As this is a database that is a restore of a live one. However I added the user after the restore. The user was not listed as orphaned
A possible workaround if you don't want to have the owner be sa is to have the user be a member of msdb and grant the the SQLAgentOperatorRole in msdb. See if that works.
But to be honest, either use sa or a dedicated service account with enough permissions. It's better if the job runs under that context.

SQL owner chaining

Basically I have a front end application called AdminProgram. In SQL Server I have a role called AdminProgramUsers.
Now this role has permissions to various SPs and the like but, crucially, there is no select permission on any table. Everything they see or modify is done through SPs.
Now I've just written a new SP for them. I have had no choice but to use dynamic SQL, that is constructing the actual SQL query in a String variable called #FinalQuery and then running EXECUTE #FinalQuery.
Now initially I was getting a lot of user doesn't have access to the tables, needed to either grant SELECTs to the columns in question, but that solution won't work due to internal politics.
The other thing I seem to understand is that I need to use EXECUTE AS somehow. I have Googled, but I'm struggling to get this right.
And to pre-emptively answer a couple of questions, there is no option but to use dynamic SQL in this SP much to my displeasure, we're talking about SQL Server 2005 and there will be no way of signing any SPs with certificates (mainly as the DBA will flip a nut at the prospect of anything complicated).
So... I think the answer lies somewhere in EXECUTE AS with ownership chaining... but I need to know how to do it... assuming that the role available is AdminProgramUsers...
The current solution I have is:
CREATE SP MySp AS
DECLARE #FinalTable (columns)
DECLARE #FinalQuery
SET #FinalQuery = "EXECUTE AS CALLER
SELECT blah blah"
INSERT #FinalTable
EXECUTE (#QueryString) AS user ='AdminProgramUsers'
Do some more processing on #FinalTable
Select * from #FinalTable
The error I get is:
Unexpected Error in My Sp
Cannot execute as the database principal because the principal "AdminProgramUsers" does not exist, this type of principal cannot be impersonated, or you do not have permission.
here is an excerpt from ms documentation about execute on sql server 2005:
The user or login name specified in AS { LOGIN | USER } = ' name '
must exist as a principal in sys.database_principals or
sys.server_principals, respectively, or the statement will fail.
Additionally, IMPERSONATE permissions must be granted on the
principal. Unless the caller is the database owner or is a member of
the sysadmin fixed server role, the principal must exist even when the
user is accessing the database or instance of SQL Server through a
Windows group membership.
in your code you feed the execute a role but a user or login is expected instead.
the above text is not very clear if you don't read this:
LOGIN
Specifies the context to be impersonated is a login. The scope
of impersonation is the server.
USER
Specifies the context to be
impersonated is a user in the current database. The scope of
impersonation is restricted to the current database. A context switch
to a database user does not inherit the server-level permissions of
that user.
you can specify a user or a login as impersonation context; a role is neither a login nor a user.

security context problem when accessing through synonyms

There is a user and two databases on server (db1 and db2).
User can connect to server having default database db1 where he can exec sp.
In sp syntax we use synonyms for db2 tables under dbo scheme.
All that is done in order to allow user just connect and exec one stored procedure. It worked noraml but now The server principal "user" is not able to access the database "db2" under the current security context.
User gets output from sp when code does not touch synonyms to db2.
What should be updated? I cant grant select to user for db2 objects.
I know the question is old, but still relevant
the procedure has to have permission on the synonym object
the procedure has to have permission on the object the synonym is targeting
you have to correctly setup trustworthy database property
By default, the procedure executes under the caller account, but it can be changed with execute as clause.

Cannot Find Stored Procedure Error

I recently did an import of database from a sql server 2000 database to a sql server 2005 database. I've gone through and setup what I thought were the same login credentials and owner permissions that I had previously setup in my old database.
All of the code base I'm working has stored procedures listed simply by stored procedure name.
In order to make sure I have the proper logins created, I am logging into the SQL Server Management studio with the connection information my application is using (i.e. using the username "licensemgr" and it's associated password). I can see all the tables, stored procedures, etc... in my database when I log in with combination. When I try to run a stored procedure, Sql Server Management Studio uses the following syntax to execute it:
EXEC: #return_value = [licensemgr].[Stored_Procedure_Name]
and it executes without error.
If I try to remove the [licensemgr]. from before the [Stored_Procedure_Name], however I get the error "Cannot find stored procedure: Stored_Procedure_Name". This is the same error I get when running my application off this database. I changed one stored procedure call in my application to have "licensemgr." in front of the stored procedure name and that seemed to correct the problem, however, I don't want to do that for each and every stored procedure call in my application. I am therefore wondering what type of setup / permissions type issue I might be missing in my SQL Server instance so that even when I'm logged into the database as licensemgr, I cannot see the stored procedure which is in the schema "licensemgr".
In SQL server 2000 the [licensemgr] referred to the owner of the table. So when you are logged in as [licensemgr] you do not need the prefix.
In SQL Server 2005 this has been changed to the schema, therefore it must be specified. See:
http://msdn.microsoft.com/en-us/library/ms190387.aspx
EDIT
There are two things that you need to watch out for:
If the user is in the sysadmin role, he will always default to the dbo schema, therefore you need to prefix
If your user needs to run code that is in different schemas you will need to prefix
If none of the two above it should work by setting the default schema for the user
When you created your user, did you specify DEFAULT_SCHEMA?
CREATE USER ... WITH DEFAULT_SCHEMA = "licensemgr"
If not, you may need to use ALTER USER to fix this for your user in the new system.

Resources