MSSQLSERVER_15517

Van toepassing op:SQL Server

Details

Attribute Value
Productnaam SQL Server
Gebeurtenis-id 15517
Bron van gebeurtenis MSSQLSERVER
Onderdeel SQLEngine
Symbolische naam SEC_CANNOTEXECUTEASUSER
Berichttekst Kan niet uitvoeren als databaseprincipal omdat de principal "principal" niet bestaat, dit type principal niet kan worden geïmiteerd, of je hebt geen toestemming.

Explanation

Deze fout ontstaat meestal omdat Microsoft SQL Server de informatie over de uitvoeringscontext van de principal die in een user statement of module is gespecificeerd niet kan verkrijgen door de EXECUTE AS instructie te gebruiken.

Je inloggegevens Security Identifier (SID) worden automatisch opgeslagen wanneer je een database aanmaakt op een SQL Server-instantie als database-eigenaar in de overeenkomstige databaserij in de sys.databases tabel en voor het dbo gebruikersitem in de sys.database_principals tabel binnen de database.

De statements of modules die de EXECUTE AS OWNER clausule gebruiken, werken zoals verwacht als de SID-invoer die voor de DBO-gebruiker is opgeslagen geldig is.

Note

Het probleem kan optreden bij elke principal die in de EXECUTE AS instructie wordt gebruikt en die niet bestaat op de server waarop de database wordt hersteld.

Hier zijn een paar veelvoorkomende scenario's die dit probleem kunnen veroorzaken:

  • Je herstelt een database op dezelfde serverinstantie waar de back-up oorspronkelijk is gemaakt, maar de SQL Server-principal die de database heeft gemaakt is om de een of andere reden niet langer geldig. Voorbeeld:

    • De SQL Server-authenticatielogin is verwijderd.
    • De Windows authentication-login is niet langer voor een geldige gebruiker in Active Directory omdat de werknemer het bedrijf heeft verlaten.
  • Je herstelt een database op een server die anders is dan de instantie waar de back-up oorspronkelijk is gemaakt, maar de SQL Server-principal die de database heeft gemaakt is geen geldige principal op de nieuwe server.

    • Als de gebruiker een SQL Server-login is, kan de principal op de doel- of bestemmingsserver bestaan, maar de sid waarde zal anders zijn.
    • Als de gebruiker een Windows-login is, bestaat de Windows-login niet meer op de doelserver of is deze niet langer geldig.

De gebruiker of applicatie die de opgeslagen procedure, functie of trigger uitvoert, heeft niet de benodigde rechten om de principal te imiteren die in de EXECUTE AS instructie is gespecificeerd.

Gebruikersactie

Gebruik de naam van een bestaande opdrachtgever of geef de IMPERSONATE-toestemming op die principaal aan de vereiste gebruikers.

Om het probleem op te lossen dat ontstaat door een ongeldige dbo-gebruikersfout, verander je de dbo_User waarde naar een geldige login op je server door het volgende commando uit te voeren:

ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]  

Voorbeeldscenario

  1. Maak twee tijdelijke principes:

    CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
    CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
    
  2. Voeg deze inloggegevens toe aan de sysadmin-rol (alleen voor demonstratie).

  3. Log in op je SQL Server-instantie door gebruik te maken van login1.

  4. Maak een demonstratiedatabase en een opgeslagen procedure aan die wordt benoemd testexec door het volgende script uit te voeren:

    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. Voer de volgende queries uit en controleer of de sid waarden een geldige login zijn:

    • Query 1: Controleer de waarde van de Owner_Name waarde in 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
      
    • Vraag 2: Controleer de Owner_Name waarde in de sys.database_principals tabel binnen de demonstratiedatabase:

      SELECT SUSER_SNAME(sid) AS Owner_Name, sid 
      FROM Demodb_15517.sys.database_principals 
      WHERE NAME = N'dbo'; 
      
      Owner_Name    SID
      ------------- ------------------------------------------------ 
      login1        0xDB79ED7B6731CF4E8DC7DF02871E3E36
      
  6. Maak een back-up van de demonstratiedatabase door een query te gebruiken die lijkt op het volgende 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. Laat de demonstratiedatabase vallen en login1:

    DROP DATABASE demodb_15517
    GO
    DROP login login1
    GO
    
  8. Log in op SQL Server als login2.

  9. Herstel de demonstratiedatabase uit de back-up door een instructie te gebruiken die lijkt op het volgende 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. Voer Query 1 en Query 2 opnieuw uit.

  11. Controleer in Query 1 de waarde van de Owner_Name waarde in sys.databases. De waarde weerspiegelt 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. Controleer in Query 2 de waarde van de Owner_Name waarde in de sys.database_principals tabel binnen de demonstratiedatabase. De waarde weerspiegelt 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. Voer de testexec opgeslagen procedure uit. Je zou nu de foutmelding "15517" moeten zien.

    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. Om de fout op te lossen, verander je de dbo naar een geldige gebruiker (login2) door het volgende commando te gebruiken:

    ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]   
    
  15. Voer Query 2 opnieuw uit en verifieer dat dbo-gebruikers nu worden opgelost naar de login2-gebruiker.

    Owner_Name          SID
    ---------------------------------------------------------------- 
    login2              0xD63086DD7277BC4EB88013D359AF73A6 
    
  16. Probeer opnieuw de testopgeslagen procedure uit te voeren. Let op dat hij nu succesvol werkt.

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