viernes, 25 de agosto de 2017

cross database ownership chaining



En esta entrada exploraremos una característica muy interesante de SQL Server que permite brincar de una base de datos a otra con permisos mínimos para el usuario.

Para que esto sea posible será necesario que ambas bases de datos tengan el mismo propietario.

Vamos a crear dos bases de datos, cada una con una tabla muy sencilla.

USE master
GO
CREATE DATABASE DatabaseA
GO
CREATE DATABASE DatabaseB
GO
USE DatabaseA
GO
CREATE TABLE TableA(
    Valor VARCHAR(10)
)
GO
USE DatabaseB
GO
CREATE TABLE TableB(
    Valor VARCHAR(10)
)



Ahora vamos a crear un procedimiento almacenado que nos permita insertar un registro en TableA de DatabaseA y que en el mismo procedimiento se inserte un registro en TableB de DatabaseB.

USE DatabaseA
GO
CREATE PROC pAgregarValor(
    @Valor VARCHAR(10)
)
AS
BEGIN
    BEGIN TRAN
    BEGIN TRY
        INSERT INTO TableA (Valor) VALUES (@Valor)
        INSERT INTO DatabaseB.dbo.TableB (Valor) VALUES (@Valor)

        COMMIT
    END TRY
    BEGIN CATCH
        ROLLBACK

        DECLARE @Error VARCHAR(4000) = ERROR_MESSAGE()
        RAISERROR (@Error, 16, 1)
    END CATCH
END


Crearemos un login y le daremos acceso a DatabaseA, también dándole permiso de ejecución sobre el procedimiento almacenado que acabamos de crear.

USE master
GO
CREATE LOGIN LoginA WITH PASSWORD = 'password'
GO
USE DatabaseA
GO
CREATE USER LoginA FOR LOGIN LoginA
GO
GRANT EXEC ON pAgregarValor TO LoginA


Si nos conectamos con el login que acabamos de crear e intentamos ejecutar el procedimiento almacenado en DatabaseA nos va a marcar el siguiente error:



El login por lo menos debe tener acceso a DatabaseB.   Vamos a darle un usuario al login en esa base de datos para que pueda ingresar.    Aquí hay que notar que lo único que tendrá permitido es entrar a la base de datos y ejecutar las tareas que tenga permitidas el rol "public".

USE DatabaseB
GO
CREATE USER LoginA FOR LOGIN LoginA


Si volvemos a ejecutar el procedimiento almacenado en DatabaseA, el mensaje de error cambiará debido a que el usuario ya puede entrar a DatabaseB pero no tiene permiso de inserción sobre TableB.


He aquí donde utilizaremos la opción "cross database ownership chaining" de SQL Server.    Al darle permiso de ejecución en un procedimiento almacenado de DatabaseA que realice una modificación en DatabaseB, el usuario tendrá la autorización porque ambas bases de datos tienen el mismo propietario.

Vamos a habilitar la opción cross database ownership chaining.

sp_configure 'cross db ownership chaining', 1
GO
RECONFIGURE
GO
sp_configure 'cross db ownership chaining'


Si ejecutamos nuestro procedimiento almacenado de nuevo, veremos que la inserción resultó exitosa.



Notarás que no es necesario darle permiso de inserción a LoginA sobre TableB de DatabaseB, tuvo permiso porque el propietario de ambas bases de datos es el mismo y cross database ownership chaining está habilitado.

Espero esta entrada te haya gustado y te ayude a mejorar en tu trabajo.   Te espero en la siguiente, ¡saludos!


No hay comentarios.:

Publicar un comentario