2010-08-16 17 views
3

Je travaille avec un système qui devait créer des objets dans une base de données en fonction des objets créés dans une autre base de données. Les objets ne sont pas des doublons, donc je ne peux pas simplement répliquer les objets.Éviter l'utilisation de SET TRUSTWORTHY ON

J'ai le code ci-dessous qui donne une démonstration simplifiée de ce que j'essaie de faire. Si vous décommentez les instructions ALTER DATABASE, il s'exécutera sans aucune erreur. Cela a le potentiel de créer un trou de sécurité, donc je voudrais l'éviter si possible.

J'ai essayé d'utiliser des certificats et des usurpations d'identité, mais rien ne semble fonctionner. Je pense que le déclencheur DDL ignore une grande partie de la sécurité en ce qui concerne les utilisateurs et les connexions. J'ai également essayé de créer une procédure stockée dans Test_DB_2 qui appelle le SP dans Test_DB_1 et ayant l'appel de déclencheur cette procédure stockée à la place, mais cela n'a pas aidé non plus. Donc, votre défi, si vous voulez l'accepter, est de faire fonctionner le code ci-dessous sans activer TRUSTWORTHY ON (ou activer le chaînage db si cela a un effet).

Merci pour toute aide que vous pouvez donner!

/************************ 
    SET-UP THE TEST 
************************/ 
USE master 
GO 
CREATE LOGIN Test_Security_Login WITH PASSWORD = '[email protected]!' 
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 

Répondre

7

Trop facile. Utilisez le code de signature:

  • créer auto certificat signé en DB1
  • signe le déclencheur avec un certificat
  • chute de clé privée
  • pour prévenir les abus
  • de certificat d'exportation dans db2 (sauvegarde/créer à partir du fichier)
  • créer un justificatif à partir du certificat en db2
  • accorder AUTHENTICATE et toute autre autorisation nécessaire pour obtenir un certificat d'accréditation dérivé
  • ?
  • profit

Ceci est une preuve de balle. Voir Call a procedure in another database from an activated procedure pour un exemple à part entière.

+0

Trop facile? Pas tout à fait ... vous ne pouvez pas signer un déclencheur DDL: http://social.msdn.microsoft.com/Forums/en/sqlsecurity/thread/1333eecd-4c66-43d4-ab8f-03511cad4174;) –

+1

D'oh. .. OK, alors à la dure: au lieu d'utiliser les déclencheurs DDL, utilisez les notifications d'événements. Cela rendra l'ajout de la vue asynchrone (se produira après que le DDL original a été engagé). Il existe plusieurs manières: niveau serveur EN avec procédure dans [msdb], niveau db EN avec procédure locale signée pour accéder à x-db ou niveau db EN avec livraison SSB x-db et exécution de procédure dans la cible db. Choisissez votre favori et je vais vous guider comment le faire. –

+4

J'ai effectivement réussi à le faire fonctionner en utilisant une procédure stub stockée appelée par le déclencheur DDL avec le SP stub utilisant EXECUTE AS et avec des certificats implémentés en utilisant GRANT AUTHENTICATE. J'avais essayé d'utiliser un SP stub avant et j'avais essayé d'utiliser des certificats, mais la pièce manquante je pense était la permission AUTHENTICATE. Une fois que je l'aurai réduit au minimum requis, je posterai une réponse avec le code complet, mais puisque vous m'avez indiqué la bonne direction, je vais accepter votre réponse. Merci! –