I'm working with a system which had to create objects in one database based on objects being created in another database. The objects are not duplicates, so I can't simply replicate the objects.
I have code below which gives a simplified demonstration of what I'm trying to do. If you uncomment the ALTER DATABASE
statements then it will run without any errors. That has the potential of creating a security hole though, so I'd like to avoid it if possible.
I've tried using certificates and impersonation, but nothing seems to work. I think that the DDL trigger is ignoring a lot of the security when it comes to users vs. logins. I've also tried creating a stored procedure in Test_DB_2 which calls the SP in Test_DB_1 and having the trigger call that stored procedure instead, but that didn't help either.
So, your challenge, if you're willing to accept it, is to get the code below to work without setting TRUSTWORTHY ON (or turning on db chaining if that has any effect).
Thanks for any help that you can give!
/************************
SET-UP THE TEST
************************/
USE master
GO
CREATE LOGIN Test_Security_Login WITH PASSWORD = 'p@ssw0rd1!'
CREATE DATABASE Test_DB_1
CREATE DATABASE Test_DB_2
GO
USE Test_DB_1
GO
CREATE PROCEDURE dbo.Create_View
AS
BEGIN
EXEC('CREATE VIEW Test_View AS SELECT 1 AS one')
END
GO
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login
GRANT EXECUTE ON dbo.Create_View TO Test_Security_User
GO
USE Test_DB_2
GO
CREATE TRIGGER DDL_TRIGGER ON DATABASE WITH EXECUTE AS 'dbo' FOR DDL_VIEW_EVENTS
AS
BEGIN
EXEC Test_DB_1.dbo.Create_View
END
GO
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login
EXEC sp_addrolemember 'db_ddladmin', 'Test_Security_User'
/************************
RUN THE TEST
************************/
USE Test_DB_2
GO
--ALTER DATABASE Test_DB_1 SET TRUSTWORTHY ON
--ALTER DATABASE Test_DB_2 SET TRUSTWORTHY ON
EXECUTE AS USER = 'Test_Security_User'
GO
CREATE VIEW dbo.Test_View_2 AS SELECT 2 AS two
GO
REVERT
GO
/************************
CLEAN-UP
************************/
USE master
GO
DROP DATABASE Test_DB_1
DROP DATABASE Test_DB_2
DROP LOGIN Test_Security_Login
GO