MSSQLSERVER_15517

Se aplica a: SQL Server

Detalles

Attribute Valor
Nombre del producto SQL Server
Id. de evento 15517
Origen de eventos MSSQLSERVER
Componente SQLEngine
Nombre simbólico SEC_CANNOTEXECUTEASUSER
Texto del mensaje No se puede ejecutar como entidad de seguridad de base de datos porque la entidad de seguridad "principal" no existe, este tipo de entidad de seguridad no se puede suplantar o no tiene permiso.

Explicación

Este error suele producirse porque Microsoft SQL Server no puede obtener la información sobre el contexto de ejecución de la entidad de seguridad especificada en una instrucción de usuario o módulo mediante la EXECUTE AS instrucción .

El identificador de seguridad (SID) de la información de inicio de sesión se guarda automáticamente al crear una base de datos en una instancia de SQL Server como propietario de la base de datos en la fila de base de datos correspondiente de la sys.databases tabla y para el dbo elemento de usuario de la sys.database_principals tabla dentro de la base de datos.

Las instrucciones o módulos que usan la EXECUTE AS OWNER cláusula funcionarán según lo esperado si la entrada de SID almacenada para el usuario dbo es válida.

Nota:

El problema puede producirse para cualquier entidad de seguridad que se use en la EXECUTE AS instrucción y que no exista en el servidor en el que se restaura la base de datos.

Estos son algunos escenarios comunes que pueden provocar que se produzca este problema:

  • Restaure una base de datos en la misma instancia de servidor en la que se realizó originalmente la copia de seguridad, pero la entidad de seguridad de SQL Server que creó la base de datos ya no es válida por algún motivo. Por ejemplo:

    • Se quitó el inicio de sesión de autenticación de SQL Server.
    • El inicio de sesión de autenticación de Windows ya no es para un usuario válido en Active Directory porque el empleado abandonó la empresa.
  • Restaure una base de datos en un servidor diferente de la instancia en la que se realizó originalmente la copia de seguridad, pero la entidad de seguridad de SQL Server que creó la base de datos no es una entidad de seguridad válida en el nuevo servidor.

    • Si el usuario es un inicio de sesión de SQL Server, es posible que la entidad de seguridad exista en el servidor de destino o de destino, pero el sid valor será diferente.
    • Si el usuario es un inicio de sesión de Windows, el inicio de sesión de Windows no existe en el servidor de destino o ya no es válido.

El usuario o la aplicación que ejecuta el procedimiento almacenado, la función o el desencadenador no tiene los permisos necesarios para suplantar a la entidad de seguridad especificada en la EXECUTE AS instrucción .

Acción del usuario

Use el nombre de una entidad de seguridad existente o conceda el permiso IMPERSONATE a esa entidad de seguridad a los usuarios necesarios.

Para resolver el problema que se produce debido a un error de usuario de dbo no válido, cambie el dbo_User valor a un inicio de sesión válido en el servidor ejecutando el comando siguiente:

ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]  

Escenario de ejemplo

  1. Cree dos entidades de seguridad temporales:

    CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
    CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
    
  2. Agregue estos inicios de sesión al rol sysadmin (solo para demostración).

  3. Inicie sesión en la instancia de SQL Server mediante login1.

  4. Cree una base de datos de demostración y un procedimiento almacenado denominado testexec ejecutando el siguiente script:

    CREATE DATABASE Demodb_15517
    GO
    USE Demodb_15517
    GO
    CREATE procedure [dbo].[testexec]
    WITH EXECUTE AS owner
    AS SELECT @@VERSION
    GO
    EXEC dbo.testexec
    GO
    
  5. Ejecute las siguientes consultas y compruebe si los sid valores se resuelven en un inicio de sesión válido:

    • Consulta 1: compruebe el valor del Owner_Name valor en sys.databases.

      SELECT NAME AS Database_Name, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName
      FROM sys.databases
      WHERE NAME = N'Demodb_15517';
      
      Database_Name         owner_sid                               OwnerName
      --------------------- -------------------------------------- ----------------------------
      Demodb_15517          0xDB79ED7B6731CF4E8DC7DF02871E3E36      login1
      
    • Consulta 2: Compruebe el Owner_Name valor de la sys.database_principals tabla dentro de la base de datos de demostración:

      SELECT SUSER_SNAME(sid) AS Owner_Name, sid 
      FROM Demodb_15517.sys.database_principals 
      WHERE NAME = N'dbo'; 
      
      Owner_Name    SID
      ------------- ------------------------------------------------ 
      login1        0xDB79ED7B6731CF4E8DC7DF02871E3E36
      
  6. Realice una copia de seguridad de la base de datos de demostración mediante una consulta similar al siguiente script:

    BACKUP DATABASE [Demodb_15517] TO DISK = N'C:\SQLBackups\Demodb_15517.bak' WITH NOFORMAT, NOINIT, NAME = N'Demodb_15517 Full backup', SKIP, EWIND, NOUNLOAD, STATS = 10 
    GO
    
  7. Quite la base de datos de demostración y login1:

    DROP DATABASE demodb_15517
    GO
    DROP login login1
    GO
    
  8. Inicie sesión en SQL Server como login2.

  9. Restaure la base de datos de demostración a partir de la copia de seguridad mediante una instrucción similar al siguiente script:

    USE [master] 
    RESTORE DATABASE [Demodb_15517] FROM   
    DISK = N'C:\SQLBackups\Demodb_15517.bak' WITH FILE = 1,   
    MOVE N'Demodb_15517' TO N'C:\SQLBackups\Demodb_15517.mdf',   
    MOVE N'Demodb_15517_log' TO N'C:\SQLBackups\\Demodb_155172_log.ldf',   
    NOUNLOAD, STATS = 5 
    GO 
    
  10. Vuelva a ejecutar la consulta 1 y la consulta 2.

  11. En la consulta 1, compruebe el valor del Owner_Name valor en sys.databases. El valor ahora refleja login2.

    SELECT NAME AS Database_Name, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName 
    FROM sys.databases 
    WHERE NAME = N'Demodb_15517';
    
    Database_Name  owner_sid                               OwnerName
    -------------- --------------------------------------- ---------------------
    Demodb_15517   0xD63086DD7277BC4EB88013D359AF73A6      login2
    
  12. En la consulta 2, compruebe el valor del valor de la sys.database_principals tabla dentro de Owner_Name la base de datos de demostración. El valor ahora refleja NULL.

    SELECT SUSER_SNAME(sid) AS Owner_Name, sid
    FROM Demodb_15517.sys.database_principals
    WHERE NAME = N'dbo';
    
    Owner_Name         sid 
      ------------------ -----------------------------------------------
    NULL               0xDB79ED7B6731CF4E8DC7DF02871E3E36 
    
  13. Ejecute el testexec procedimiento almacenado. Ahora debería ver el mensaje de error "15517".

    USE Demodb_15517 
    GO 
    EXEC dbo.testexec 
    GO
    
    Msg 15517, Level 16, State 1, Procedure dbo.testexec, Line 0 [Batch Start Line 19] 
    Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission. 
    
  14. Para resolver el error, cambie dbo a un usuario válido (login2) mediante el comando siguiente:

    ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]   
    
  15. Vuelva a ejecutar la consulta 2 y compruebe que los usuarios dbo ahora se resuelven en el usuario login2.

    Owner_Name          SID
    ---------------------------------------------------------------- 
    login2              0xD63086DD7277BC4EB88013D359AF73A6 
    
  16. Inténtelo de nuevo para ejecutar el procedimiento almacenado de prueba. Observe que ahora se ejecuta correctamente.

    USE Demodb_15517 
    GO 
    EXEC dbo.testexec 
    GO
    
    /* -- You get an output that resembles the following 
    ---------------------------------------------------------------------------------------------------------
    Microsoft SQL Server 2019 (RTM-CU16-GDR) (KB5014353) - 15.0.4236.7 (X64)  
    May 29 2022 15:55:47  
    Copyright (C) 2019 Microsoft Corporation 
    Express Edition (64-bit) on Windows 10 Enterprise 10.0 <X64> (Build 22621: ) (Hypervisor) 
    */ 
    

Consulte también

Copiar bases de datos en otros servidores

Transferencia de inicios de sesión y contraseñas entre instancias