MSSQLSERVER_15517

Gäller för:SQL Server

Detaljer

Attribute Value
Produktnamn SQL Server
Händelse-ID 15517
Händelsekälla MSSQLSERVER
Component SQLEngine
Symboliskt namn SEC_CANNOTEXECUTEASUSER
Meddelandetext Kan inte köras som databasens huvudperson eftersom huvudpersonens "huvudsak" inte existerar, denna typ av princip kan inte imiteras, eller du har inte behörighet.

Explanation

Detta fel uppstår vanligtvis eftersom Microsoft SQL Server inte kan få informationen om exekveringskontexten för principalen som anges i en användarsats eller modul genom att använda satsenEXECUTE AS.

Din inloggningsinformation Security Identifier (SID) sparas automatiskt när du skapar en databas på en SQL Server-instans som databasägare i motsvarande databasrad i sys.databases tabellen och för användarobjektet dbo i sys.database_principals tabellen inom databasen.

Satserna eller modulerna som använder klausulen EXECUTE AS OWNER fungerar som förväntat om SID-posten som lagras för dbo-användaren är giltig.

Anmärkning

Problemet kan uppstå för vilken principal som helst som används i satsen EXECUTE AS och som inte finns på servern där databasen återställs.

Här är några vanliga scenarier som kan orsaka detta problem:

  • Du återställer en databas på samma serverinstans där säkerhetskopieringen ursprungligen togs, men SQL Server-principen som skapade databasen är av någon anledning inte längre giltig. Ett exempel:

    • SQL Server-autentiseringsinloggningen togs bort.
    • Windows authentication-inloggningen gäller inte längre för en giltig användare i služba Active Directory eftersom den anställde lämnade företaget.
  • Du återställer en databas på en server som skiljer sig från den instans där säkerhetskopian ursprungligen togs, men SQL Server-principen som skapade databasen är inte en giltig princip på den nya servern.

    • Om användaren är en SQL Server-inloggning kan principalen finnas på mål- eller destinationsservern men sid värdet kommer att vara annorlunda.
    • Om användaren är en Windows-inloggning finns inte Windows-inloggningen på målservern eller så är den inte längre gald.

Användaren eller applikationen som kör den lagrade proceduren, funktionen eller triggern har inte de nödvändiga behörigheterna för att imitera den principal som anges i satsen EXECUTE AS .

Användaråtgärd

Använd namnet på en befintlig huvudperson eller ge IMPERSONATE-tillstånd på den huvudpersonen till de nödvändiga användarna.

För att lösa problemet som uppstår på grund av ett ogiltigt dbo-användarfel, ändra dbo_User värdet till en giltig inloggning på din server genom att köra följande kommando:

ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]  

Exempel på ett scenario

  1. Skapa två tillfälliga principer:

    CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
    CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
    
  2. Lägg till dessa inloggningar i sysadmin-rollen (endast för demonstration).

  3. Logga in på din SQL Server-instans genom att använda login1.

  4. Skapa en demonstrationsdatabas och en lagrad procedur som namnges testexec genom att köra följande skript:

    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. Kör följande frågor och kontrollera om värdena sid upplöses till en giltig inloggning:

    • Fråga 1: Kontrollera värdet av Owner_Name värdet i 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
      
    • Fråga 2: Kontrollera Owner_Name värdet i sys.database_principals tabellen i demonstrationsdatabasen:

      SELECT SUSER_SNAME(sid) AS Owner_Name, sid 
      FROM Demodb_15517.sys.database_principals 
      WHERE NAME = N'dbo'; 
      
      Owner_Name    SID
      ------------- ------------------------------------------------ 
      login1        0xDB79ED7B6731CF4E8DC7DF02871E3E36
      
  6. Säkerhetskopiera demonstrationsdatabasen genom att använda en fråga som liknar följande skript:

    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. Släpp demonstrationsdatabasen och login1:

    DROP DATABASE demodb_15517
    GO
    DROP login login1
    GO
    
  8. Logga in på SQL Server som login2.

  9. Återställ demonstrationsdatabasen från backupen genom att använda en sats som liknar följande skript:

    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. Kör om Fråga 1 och Fråga 2.

  11. I Fråga 1, kontrollera värdet av Owner_Name värdet i sys.databases. Värdet speglar login2nu .

    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. I Fråga 2, kontrollera värdet av Owner_Name värdet i sys.database_principals tabellen i demonstrationsdatabasen. Värdet speglar NULLnu .

    SELECT SUSER_SNAME(sid) AS Owner_Name, sid
    FROM Demodb_15517.sys.database_principals
    WHERE NAME = N'dbo';
    
    Owner_Name         sid 
      ------------------ -----------------------------------------------
    NULL               0xDB79ED7B6731CF4E8DC7DF02871E3E36 
    
  13. Kör den lagrade testexec proceduren. Du bör nu se felmeddelandet "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. För att lösa felet, ändra databasen till en giltig användare (login2) genom att använda följande kommando:

    ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]   
    
  15. Kör Fråga 2 igen och verifiera att dbo-användare nu löser sig till login2-användaren.

    Owner_Name          SID
    ---------------------------------------------------------------- 
    login2              0xD63086DD7277BC4EB88013D359AF73A6 
    
  16. Försök igen för att köra testlagret procedur. Notera att den nu fungerar som den fungerar.

    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) 
    */