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

2 comentarios:

  1. Para cuando pase eso, podemos correr el siguiente script para recuperar los logins, si es que ya existen en el servidor:

    BEGIN
    DECLARE @username varchar(25)

    DECLARE fixusers CURSOR FOR
    SELECT UserName = name FROM sysusers
    WHERE issqluser = 1
    AND (sid is not null AND sid <> 0x0)
    AND suser_sname(sid) is null

    OPEN fixusers
    FETCH NEXT FROM fixusers INTO @username
    WHILE @@FETCH_STATUS = 0
    BEGIN
    EXEC sp_change_users_login 'update_one', @username, @username
    FETCH NEXT FROM fixusers INTO @username
    END
    CLOSE fixusers
    DEALLOCATE fixusers
    END

    DE no contar con los logins en el servidor origen de donde se tomo el backup crear 2 scripts dependiendo de la version del SQL Server siguiendo el siguiente Articulo

    How to transfer logins and passwords between instances of SQL Server
    http://support.microsoft.com/kb/246133

    ResponderEliminar
  2. LGuevara,
    Antes que nada gracias por el interes :) Ese es el script al que hacía referencia de la página de MS, pero coincido que hubiera estado bueno si lo ponia inicialmente. No quise hacer foco en eso sino en cuando intencionalmente se deja sin login asociado pero hubiera quedado mas claro.
    Saludos,
    -
    Lic. Andrés M. Aiello
    DBA MS SQL - Oracle
    http://aiellodba.blogspot.com/
    @AndresAiello

    ResponderEliminar