En ocasiones nos encontramos con la necesidad de recrear ciertos objetos sin conocer todos los datos necesarios. Un caso típico (desgraciadamente) es la migración de un login de SQL Server del que se desconoce su password. Esto ocurre habitualmente en aplicaciones cerradas donde el fabricante ha codificado internamente “a fuego” el password. En estos escenarios es posible recrear el objeto sin conocer el password de forma sencilla utilizando la cláusula HASHED en el comando CREATE LOGIN.
Sin embargo, en otros casos, como los logins y password asociados a un linked server, la solución no es tan sencilla. Para comprender mejor dónde y cómo se almacenan dichos password analizaremos primero el procedimiento sp_addlinkedsrvlogin que es el responsable de esta función. En su código podemos ver lo siguiente:
-- ADD THE SPECIFIED MAPPING --
SELECT @pwd = convert(varbinary(256), @rmtpassword)
EXEC %%LinkedServer(Name=@rmtsrvname).NewLinkedLogin(
LocalID=@localid, UseSelf=@useselfbit, RemoteName=@rmtuser,
)
Como vemos la introducción del password se realiza mediante una llamada interna al método NewLinkedLogin del LinkedServer. Por otro lado, tenemos la vista de sistema sys.linked_logins cuya definición es la siguiente:
CREATE VIEW sys.linked_logins AS
SELECT srvid AS server_id,
lgnid AS local_principal_id,
sysconv(bit, status & 1) AS uses_self_credential, -- LGN_LINKED_USESELF
name AS remote_name,
modate AS modify_date
FROM master.sys.syslnklgns
WHERE lgnid = suser_id() OR has_access('SR', 0) = 1
Vemos que sys.linked_logins es una vista sobre sys.syslnklgns. Probablemente en la tabla base de dicha vista dispongamos de información adicional.
Para poder acceder a dicha tabla de sistema tenemos que conectar a la instancia mediante la conexión administrativa DAC. Podemos o bien utilizar sqlcmd con el parámetro –A o desde Management Studio podemos crear una nueva consulta y conectar a la base de datos anteponiendo el prefijo “admin:” al nombre del servidor.
Recordemos que únicamente los administradores (y solo uno de ellos concurrentemente) puede utilizar esta conexión:
Una vez conectados a través de la conexión administrativa podemos ver el contenido de dicha tabla de sistema:
La columna pwdhash almacena el hashing del password que originalmente se proporcionó al crear el linked server. Vamos a conectarnos ahora a la instancia donde queremos recrear el linked server del que no disponemos de su password y recrearemos el linked server pero con un password cualquiera:
Una vez recreado, conectaremos con la DAC a la nueva instancia y consultaremos la tabla syslnklgns:
Si intentamos validar la conectividad del linked server obtendremos, obviamente, un error de login:
Si intentamos lanzar un update sobre la tabla en cuestión obtenemos un error indicando que los cambios en el catálogo de sistema no están permitidos:
Para saltarnos esta protección necesitamos, por un lado arrancar la instancia en modo single-user (parámetro de arranque –m):
Por otro lado, necesitamos reconfigurar la instancia para que permita actualizaciones al catálogo de sistema con el siguiente comando:
Una vez configurada la instancia, lanzaremos el update el cual ejecutará sin problemas:
Una vez modificado, reiniciaremos la instancia. Tras el reinicio si intentamos validar el linked server obtendremos el siguiente error:
SQL Server está detectando que la clave encriptada que hemos introducido no corresponde a la actual instancia. La encriptación del password se realiza mediante la SMK (Service Master Key). Para conseguir que funcione el desencriptado deberemos primero exportar la SMK del servidor original donde se encriptó:
Una vez exportada, la importaremos en el servidor destino. Al tratarse de un backup de una SMK distinta a la que dispone la instancia será necesario forzar la operación (cláusula FORCE)
[box type=”warning”] ATENCIÓN: Debemos tener en cuenta que al realizar esta operación perderemos el acceso a información que previamente hubiésemos encriptado utilizando esta SMK en esta instancia (por ejemplo, otros linked server creados previamente en este servidor).[/box]
Una vez hemos restaurado la service key, comprobaremos que ya podemos acceder al linked server sin problemas:
La conclusión de este post es que es posible recrear, en caso de emergencia, un linked server del que desconocemos su password. Para conseguir esto necesitaremos utilizar la conexión administrativa para copiar el hash del password así como restaurar la Service Master Key del servidor origen. Este mecanismo deberá evitarse dentro de lo posible ya que implica modificaciones en las tablas de sistema.