none
Trigger hacia tabla en otra BD, usuario sin permiso RRS feed

  • Pregunta

  • Estimados expertos,
    Requiero sus consejos, tengo dos BD en un mismo servidor, una BD tiene a user1 como esquema y db_owner y la otra es todo hecho con el SA, esta 2da BD es basicamente para reporteria en PBI con nombres de tablas mas entendibles etc;
    Por medidas de seguridad el user1 no tiene acceso a la BD y viceversa.
    Obviamente requiere mantener la data actualizada en ambas, he tratado de usar la herramienta de VS comparacion, pero no detecta NADA, al parece porque las tablas no tienen nombres iguales y porque los esquemas son diferentes; :(
    Tambien he querido usar Integration Services pero me sale un error de que el nombre del servidor debe ser el real, los de infraestructura dicen que el nombre es ese; :(

    Ahora quise crear un TRIGGER AFTER INSERT
    CREATE TRIGGER CreaEnPBIData
       ON user1.tablaorigen
       AFTER INSERT
    AS
    BEGIN
        SET NOCOUNT ON;
        IF not exists(SELECT * FROM PBIDATA.SA.tablaDestino A
            JOIN inserted B ON A.CCOSTO=B.CCOSTO)
        BEGIN
            INSERT INTO PBIDATA.SA.tablaDestino(CCOSTO,DSC)
            VALUES('189901','PRUEBA DE INSERT')
        END
    END
    GO

    y me arroja:
    Msg 916, Level 14, State 1, Procedure CreaEnPBIData, Line 14 [Batch Start Line 254]
    La entidad de seguridad de servidor "user1" no puede tener acceso a la base de datos "PBIData" en el contexto de seguridad actual.

    como puedo hacer para que el trigger funcione?
    Lo intento hacer con el SA pero parece que la definicion es por esquema.

    jueves, 18 de enero de 2018 19:14

Respuestas

  • El truco para hacerlo funcionar es usar una característica de SQL Server que se llama "ownership chaining". Básicamente, consiste en que si un objeto llama a otro y los dos pertenecen al mismo propietario, entonces los permisos solo se comprueban durante el acceso al primer objeto, pero no al acceder al segundo.

    De esta manera, si la tabla1 de la BD1 pertenece al User2, y el Trigger pertenece al User2, y la tabla2 de la BD2 pertenece al User2, entonces basta con que el User1 solo tenga permisos en la Tabla1 y con eso será suficiente para que el trigger grabe en la Tabla2 (suponiendo, claro está, que el User2 tenga permiso en la tabla2). En tu caso, y tal como lo describes, lo que yo he llamado "User2" sería el "sa". Todos los objetos implicados tienen que tener como propietario al sa (el esquema es irrelevante, lo que importa es el propietario, que en las versiones antiguas de SQL Server coincidía con el esquema, pero en las modernas es independiente).

    El problema de esto es que de forma predeterminada el "ownership chaining" solo funciona dentro de una misma base de datos. Si lo quieres hacer funcionar desde una BD hacia otra, primero hay que activar a nivel de servidor una opción que se llama "cross-database ownership chaining" (es un checkbox en las propiedades de la instancia en SSMS). Si vas a hacer esto, primero estudia la documentación, porque tiene implicaciones a nivel de seguridad (por eso viene deshabilitado por defecto).

    jueves, 18 de enero de 2018 19:26