Problems using WITH EXECUTE AS OWNER with Trigger - sql

I just implemented the WITH EXECUTE AS OWNER code on a new table trigger and now regular users who insert to the table are receiving the following error: Cannot execute as the database principal because the principal "dbo" does not exist, cannot be impersonated, or you do not have permission.
Users who are setup as sysadmins have no problem inserting to the table, no errors. What type of rights need to be granted to users/roles in order for them to be able to use WITH EXECUTE AS OWNER?

Apparently problem was unrelated to permissions after all but instead related to the fact that "dbo does not exist". Current db owner was set to an old login which no longer exists.
Fixed this by running the following SQL statement:
ALTER DATABASE [DB]
SET SINGLE_USER
GO
EXEC sp_changedbowner 'sa'
GO
ALTER DATABASE [DB]
SET MULTI_USER

Related

Grant truncate permissions on all tables with out modify

Is there a way I can grant truncate permission to a user without altering privileges in SQL Server?
The minimum permission required is ALTER on table_name. TRUNCATE TABLE permissions default to the table owner, members of the sysadmin fixed server role, and the db_owner and db_ddladmin fixed database roles, and are not transferable. However, you can incorporate the TRUNCATE TABLE statement within a module, such as a stored procedure, and grant appropriate permissions to the module using the EXECUTE AS clause.
CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'CompanyDomain\SqlUser1'
AS
SELECT user_name();
Source
You can go through this official documentation.
Create a test Login and User id then grant it execute permission on the stored procedure Truncate_Table_Loner. This id will be used to perform the truncate.
-- Grant Execute Permission
-- Setup ID on Database with Connect permission
USE master
GO
CREATE LOGIN [test_user_id] WITH PASSWORD = 'JustConnect123';
GO
USE TestSQL
GO
CREATE USER [test_user_id] FOR LOGIN [test_user_id];
GO
-- Grant Permission
GRANT EXECUTE ON dbo.Truncate_Table_Loner TO [test_user_id];
GO

EXECUTE permission denied on object

I'm currently working on an MVC5, EF6 project and needed a stored procedure for a piece of the project. I've written the stored procedure, and now when I try to use it within my code I get an error saying:
The EXECUTE permission was denied on object ....
Yet when I test the stored procedure in SQL Management Studio it let's me run the stored procedure just fine. I'm not really sure what to do to fix this as I've never come across this before.
First create an executor role and then grant exec permission to this role.Then make your user member of this role.
CREATE ROLE db_executor;
GRANT EXECUTE TO db_executor;
EXEC sp_addrolemember 'db_executor', 'user1'
Hopefully this is enough but in case you still have issue check the below.
The schema owner of SP and underlying objects should be the same for sql chaining permission to work.
Check schema owners by:
select name, USER_NAME(s.principal_id) AS Schema_Owner from sys.schemas s
To change the owner of an schema you can:
ALTER AUTHORIZATION ON SCHEMA::YOUR_SCHEMA TO YOUR_USER;
Examples:
ALTER AUTHORIZATION ON SCHEMA::Claim TO dbo
ALTER AUTHORIZATION ON SCHEMA::datix TO user1;
Finally if within your SP you are truncating a table or changing structure you may want to add WITH EXECUTE AS OWNER in your SP:
ALTER procedure [myProcedure]
WITH EXECUTE AS OWNER
as
truncate table etl.temp
Create a separate user role with access 'Execute' and then assign that to your current user. This is the best solution and helped me.
Please follow this link:
https://stackoverflow.com/a/26871428/6761105

SQL Trigger to grant 'dbowner' permissions upon new DB creation

I put together the following SQL script to create a trigger when a new DB is created, to grant db_owner permissions to a specific account:
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS
DECLARE #DatabaseName NVARCHAR(128), #SQL NVARCHAR(4000)
SELECT #DatabaseName = EVENTDATA().value('(/EVENT_INSTANCE/DatabaseName)[1]','NVARCHAR(128)');
SET #SQL = '
USE ' + #DatabaseName + ';
EXEC sp_addrolemember N''db_owner'', N''[accountname]'';'
EXEC(#SQL)
However, I get the following error when I try to create a new DB to test this Trigger:
Message: User or role '[accountname]' does not exist in this database.
Could not find database ID 45, name '45'. The database may be offline.
Wait a few minutes and try again.
I put this together using some examples found on the web. It appears that the Trigger is occurring right when DB is being created, instead of running after DB has been created. Is there a way to delay it?
Few things to be mentioned here:
The trigger is executed AFTER the database is created as this is the default behaviour
Not being able to find the database may point to lack of required permissions. Make sure you have enough permission by impersonating as a user that has been granted enough permissions i.e. some database owner. Use the WITH EXECUSE AS clause.
Make sure you have the "[accountname]" existing at the new DB or at the server level (depends what kind of account you are trying to add). You can add a database user, database role, Windows login, or Windows group.
References:
https://msdn.microsoft.com/en-us/library/ms189799.aspx
https://msdn.microsoft.com/en-us/library/ms187750.aspx
SQL Server 2008 - Does a trigger run with the same permissions as the login/user?

Principle dbo does not exist in Sql Server

While fetching data through a stored procedure in SQL Server I am getting error like
Cannot execute as the database principal because the principal "dbo"
does not exist, this type of principal cannot be impersonated, or you
do not have permission.
I am getting this error only for accessing a particular stored procedure, not for all SP's.
Give your database a valid owner. Try this:
ALTER AUTHORIZATION
ON DATABASE::[YourDatabaseName]
TO [LoginUser];
or you can try to set it like
USE [dbname]
GO
sp_changedbowner 'someLogin'
ALTER AUTHORIZATION ON DATABASE::Example TO sa;
Basically SQL Server login is mapped to database user and this mapping is not properly defined for SQL server principals then login will not be sucessfully for that specific user of database on that specific instance and this user is called orphan user.
First, check if the orphaned user is mapped or not.
USE <database>
EXEC sp_change_users_login #Action='Report';
if not mapped then, fix the orphaned user.
USE <database>
EXEC sp_change_users_login #Action='update_one', #UserNamePattern='YOURUSERNAME', #LoginName='YOURUSERNAME';

Creating database SQL script with login no password SQL Server 2005

I am trying to run some scripts from C# and I have a script createdb.sql.
When I execute it I get an error because login failed for mycompany\myname
This is the script
Use Master
-- Drop the database if it already exists
IF EXISTS (SELECT name
FROM sys.databases
WHERE name = N'TestDB')
BEGIN
ALTER DATABASE TestDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DROP DATABASE TestDB
CREATE DATABASE TestDB
ALTER DATABASE TestDB SET MULTI_USER
END
ELSE
BEGIN
CREATE DATABASE TestDB
What do I need to do to create a simple login as well?
Thanks
"mycompany\myname" looks like a domain login.
For "Windows security" SQL takes the currently logged on user, it's difficult to impersonate another user to run SQL commands (but not impossible).
You can create a simpler SQL Login by following the instructions here this will allow you to supply credentials in the connection string
You'll need to assign the Windows user sysadmin permissions (or at least greater security permissions) to be able to do that in the master database.