Sql Server Agent job failing to execute stored procedure - sql-server

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.

Related

When EXECUTE AS user = 'dbo', permissions are being denied to view/query other DB objects

I have sysadmin privileges on a SQL Server (2014). When I query the table sys.databases from one of my user database (test_db) I get the full list of databases (13 of them inclusive of system databases) that are actually on the server.
But when I execute as 'dbo', some kind of permission deny seems to be applied and the full list of databases don't appear. Neither am I able to see the list of databases nor I am not able to query objects within them as well. For example: I am not able to query msdb.dbo.sysjobs.
Here is what I am running on my user database called "test_db":
EXECUTE AS user = 'dbo'
Then I do the following query:
select * from sys.databases
I see only 3 databases (out of 13 databases) as shown below (master, tempdb, test_db):
I checked the login and principal identifications after the "execute as" and below you can see what those are:
After revert, it executes as myself and I am able to see the full list of DBs back again.
As user 'dbo' which is the database principal for server principal 'sa' it is supposed to have full db_owner access across all databases on the server, but unfortunately it is not so, in this case.
One additional information here is, "test_db" gets restored from a prod server backup every 2 weeks.
Can you help me to figure out why this is happening, please?
Edit: sorry i meant server principal 'sa' not login.

SQL SERVER: Lack of permissions for user to create copy of database with all privileges

First of all, here it is what I've got:
two users: user and sa
sa is database admin
one main database with readonly permissions (db_datareader role) and executing some selected stored procedures (including database copying procedure) for user
user has global dbcreator role
SQL Server is located on a Windows Server machine with granted permissions for reading/writing files
database copying stored procedure which when sa or user executes the procedure, it copies the db with all its content and granted permissions for user in original db. Afterwards sa has to map user to copied db and add him db_owner role.
What I already tried:
to add execute as sa to procedure, but user can't IMPERSONATE sa (admin restriction)
to add line to the procedure such as:
ALTER AUTHORIZATION ON DATABASE::copyDB TO user
Just been wondering, if there is any possibility to grant temporary permission to user or just grant him ownership for the copied database in any other way.
The secure way to handle this is to created a signed procedure that can do the database copy. A user only has to have execute rights to run the procedure. The procedure will run using the context of the account used for signing, not as the user. Any change to the procedure requires re-signing. (Don't want somebody altering the code to do bad things.)
For example, I signed a procedure using an account with sysadmin access. It allowed users to execute a procedure using xp_cmdshell to execute COBOL without granting users sysadmin access. If a developer alters the code, it is no longer signed and executes using the normal context of the connection. This will cause it to fail if executing xp_cmdshell. DBA needs to verify the code and resign it before it will work again. This management overhead is the cost of security.
https://learn.microsoft.com/en-us/sql/relational-databases/tutorial-signing-stored-procedures-with-a-certificate?view=sql-server-ver15
The signing is retained if restoring a backup to the same server. Restoring to a different server will require resigning. (The master database master key is normally different.)

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

Which privileges does a user need to query used size in SQL Azure database?

I'm trying to query the consumed size of a SQL Azure database using code from this answer:
SELECT SUM(reserved_page_count)*8.0/1024 FROM sys.dm_db_partition_stats;
That query runs just fine under the database admin, but not under another user - I get
The user does not have permission to perform this action.
and when I try to GRANT SELECT permission I get this error message:
Permissions on server scoped catalog views or system stored procedures or extended stored procedures can be granted only when the current database is master.
If I log to master and try to GRANT there I get this message:
Permissions for system stored procedures, server scoped catalog views, and extended stored procedures cannot be changed in this version of SQL Server.
So it looks like users other than database admin can't get the used space.
How do I query the used space in the SQL Azure database under a user other than database admin?
I seem to recall that we had to grant the login "VIEW DATABASE STATE" and "VIEW DEFINITION" in order to run that query.

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.

Resources