viernes, 8 de abril de 2011

CREATE USER WITHOUT LOGIN

Una instrucción no muy utilizada es la de create user without login. ¿En que consiste? tal como su nombre lo indica lo que hace es crear un usuario sin asociarlo a un login en el servidor, ahora veamos porque querríamos utilizar esto.
Antes que nada vayamos a la sintaxis

CREATE USER user_name
WITHOUT LOGIN
WITH DEFAULT_SCHEMA = [dbo]


Este usuario podrá recibir permisos, ser incluido en roles y todo lo que considere necesario, pero nadie podrá loguearse con dicho usuario. Un posible uso (aunque a mi ver no recomendado) es cuando aún no se el nombre del login que tendrá y quiero dejarlo listo para una vez definido todo modificar el login asociado y ya tengo todo andando. Esto lo podré hacer con la sentencia:

EXEC sp_change_users_login 'update_one', @username, @loginname

¿Porque digo que no recomiendo esto? porque en estos casos una mejor práctica es asignar los permisos a un role, y una vez definido y creado el usuario simlemente se lo agrega al role. Es mucho mas comoda la administración de permisos si uno utiliza roles.

EXECUTE AS

El uso mas interesante viene de la mano de la opción EXECUTE AS. Esta opción me permite hacer que un procedimiento, función o trigger se ejecute con los permisos de otro usuario que no sea necesariamente el que lo invocó. De esta forma podría por ejemplo hacer un procedimiento que muestre información que de otra forma el usuario no hubiera podido ver. Al no estar este usuario asociado a ningún login no se corre peligro de que alguien se loguee con dicho usuario y escale permisos.
La forma de hacer esto es, por ejemplo:
CREATE PROCEDURE dbo.procedimiento
WITH EXECUTE AS 'UsuarioSinLogin'
AS
TRUNCATE TABLE ...
GO
En este ejemplo un usuario con permisos de datareader y ejecución sobre el stored puede tener una forma comoda y segura de limpiar una tabla en particular.

Huerfanos

Hay un caso muy particular en el cual mucha gente se topa con la sentencia WITHOUT LOGIN sin desearlo, y a veces sin entender porque. Supongamos que tenemos el usuario1 y login1 en la base de datos1 en el servidor1. Mediante backup y restore movemos la base al servidor2. El usuario, como muchos ya saben, queda huerfano de su login, y es necesario utilizar la función nombrada en la primer parte para volver a asociarlo (esto se debe a los ids internos de los usuarios). Si deseamos hacer un script completo de la base nos vamos a encontrar que los logins van a aparecer como WITHOUT LOGIN y esto se debe a que al no coincidir el id interno el motor asume que no tiene login. Es importante considerar esto antes de ponerse a buscar como loco que procedimiento hace un EXECUTE AS o algo similar. En la página de microsoft se puede encontrar un script muy simple para corregir estos casos cuando el usuario y el login tienen el mismo nombre.


Para mas información:
http://msdn.microsoft.com/en-us/library/ms173463.aspx
http://msdn.microsoft.com/es-es/library/ms174378.aspx
http://msdn.microsoft.com/en-us/library/ms188354.aspx