Dynamic management views

  • Hi,

    Current SQL version: 2008 R2 SP1.

    Previous version: 2008 SP2.

    I have a procedure which executes on our previous version, but not on the current version.

    The procedure is executed by the user 'Report' and contains the statement 'EXECUTE AS DMView'. The execution returns the error 'The user does not have permission to perform this action.'

    My procedure:

    CREATE PROCEDURE [dbo].[spCounters]

    WITH EXECUTE AS 'DMView'

    AS

    SELECT physical_io FROM master..sysprocesses WITH (NOLOCK) WHERE spid = @@SPID

    SELECT cntr_value FROM master.sys.dm_os_performance_counters

    GO

    The above procedure, executed by the user 'Report', fails on the second statement (sys.dm_os...). The first statement is executed, the value physical_io is returned.

    Also when I start this procedure as user 'DMView', it fails (normal).

    Even when I logon as sa and execute the procedure, it fails with this error.

    The DMView user has been granted the 'VIEW SERVER STATE' permission.

    What surprised me: When I logon in SSMS with the user DMView, and execute the statement 'SELECT cntr_value FROM master.sys.dm_os_performance_counters', it works fine! No error!

    Thanks for all help.

  • First of all, sys.sysprocesses is deprecated, so you should start using a DMV instead of this compatibility view. I think the sum of the reads and writes columns from sys.dm_exec_sessions gives you desired result.



    Ole Kristian Velstadbråten Bangås - Virinco - Facebook - Twitter

    Concatenating Row Values in Transact-SQL[/url]

  • Also when I start this procedure as user 'DMView', it fails (normal).Even when I logon as sa and execute the procedure, it fails with this error.

    Can you please explain these two? Failing (normal) & Failing (with Error)

  • To Krsitian: OK, but sys.sysprocesses works fine.

    To Dev: I find it 'normal' because the procedure also failed when I started it with the 'EXECUTE AS DMView' clause.

  • 'VIEW SERVER STATE' is a permission given to login.

    GRANT permission [ ,...n ]

    TO <grantee_principal> [ ,...n ] [ WITH GRANT OPTION ]

    [ AS <grantor_principal> ]

    <grantee_principal> ::= SQL_Server_login

    | SQL_Server_login_mapped_to_Windows_login

    | SQL_Server_login_mapped_to_Windows_group

    | SQL_Server_login_mapped_to_certificate

    | SQL_Server_login_mapped_to_asymmetric_key

    <grantor_principal> ::= SQL_Server_login

    | SQL_Server_login_mapped_to_Windows_login

    | SQL_Server_login_mapped_to_Windows_group

    | SQL_Server_login_mapped_to_certificate

    | SQL_Server_login_mapped_to_asymmetric_key

    With your SP you are trying to run as user.

    Functions (except inline table-valued functions), Stored Procedures, and DML Triggers

    { EXEC | EXECUTE } AS { CALLER | SELF | OWNER | 'user_name' }

    DDL Triggers with Database Scope

    { EXEC | EXECUTE } AS { CALLER | SELF | 'user_name' }

    DDL Triggers with Server Scope and logon triggers

    { EXEC | EXECUTE } AS { CALLER | SELF | 'login_name' }

    Queues

    { EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }

    User's scope is limited to Database where as Login's scope is at Server Level. Hope it clarifies your doubt.

  • Change you SP to execute it in Login's Context...

    EXECUTE AS LOGIN = 'DMView'; -- Context Switch

    SELECT physical_io FROM master..sysprocesses WITH (NOLOCK) WHERE spid = @@SPID

    SELECT cntr_value FROM master.sys.dm_os_performance_counters

  • The error can be reproduced as follow:

    USE master;

    GO

    --Create two temporary principals

    CREATE LOGIN DMView WITH PASSWORD = '123456';

    CREATE LOGIN Report WITH PASSWORD = '123456';

    GO

    USE tempdb;

    GO

    CREATE USER DMView FOR LOGIN DMView;

    CREATE USER Report FOR LOGIN Report;

    GO

    USE master;

    GRANT VIEW SERVER STATE TO Report

    GO

    USE tempdb;

    GO

    CREATE PROCEDURE [dbo].[spCounters]

    AS SET NOCOUNT ON

    GO

    ALTER PROCEDURE [dbo].[spCounters]

    WITH EXECUTE AS 'DMView'

    AS

    SELECT Reads+Writes FROM master.sys.dm_exec_sessions WHERE session_id=@@SPID

    SELECT cntr_value FROM master.sys.dm_os_performance_counters

    GO

    GRANT EXECUTE ON spCounters TO Report

    -- execute in other windows with login=Report

    USE tempdb;

    GO

    EXEC spCounters

    GO

    -- Cleanup

    DROP PROCEDURE [dbo].[spCounters]

    DROP LOGIN DMView;

    DROP USER DMView;

    DROP LOGIN Report;

    DROP USER Report;

    GO

    This returns an error, on the statement

    SELECT cntr_value FROM master.sys.dm_os_performance_counters

    even if you execute this from within the SSMS and you are logged in with sa.

    What am I missing?

  • Dev (11/21/2011)


    Change you SP to execute it in Login's Context...

    EXECUTE AS LOGIN = 'DMView'; -- Context Switch

    SELECT physical_io FROM master..sysprocesses WITH (NOLOCK) WHERE spid = @@SPID

    SELECT cntr_value FROM master.sys.dm_os_performance_counters

    Returns the Physical_io and the error:

    The user does not have permission to perform this action.

  • aarded (11/21/2011)


    Dev (11/21/2011)


    Change you SP to execute it in Login's Context...

    EXECUTE AS LOGIN = 'DMView'; -- Context Switch

    SELECT physical_io FROM master..sysprocesses WITH (NOLOCK) WHERE spid = @@SPID

    SELECT cntr_value FROM master.sys.dm_os_performance_counters

    Returns the Physical_io and the error:

    The user does not have permission to perform this action.

    I can't run the code you posted below (don't have SQL Server / Client on my system). However I would recommend you to go through following example. In last part I guess you are missing on impersonation.

    USE AdventureWorks2008R2;

    GO

    --Create two temporary principals

    CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';

    CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';

    GO

    CREATE USER user1 FOR LOGIN login1;

    CREATE USER user2 FOR LOGIN login2;

    GO

    --Give IMPERSONATE permissions on user2 to user1

    --so that user1 can successfully set the execution context to user2.

    GRANT IMPERSONATE ON USER:: user2 TO user1;

    GO

    --Display current execution context.

    SELECT SUSER_NAME(), USER_NAME();

    -- Set the execution context to login1.

    EXECUTE AS LOGIN = 'login1';

    --Verify the execution context is now login1.

    SELECT SUSER_NAME(), USER_NAME();

    --Login1 sets the execution context to login2.

    EXECUTE AS USER = 'user2';

    --Display current execution context.

    SELECT SUSER_NAME(), USER_NAME();

    -- The execution context stack now has three principals: the originating caller, login1 and login2.

    --The following REVERT statements will reset the execution context to the previous context.

    REVERT;

    --Display current execution context.

    SELECT SUSER_NAME(), USER_NAME();

    REVERT;

    --Display current execution context.

    SELECT SUSER_NAME(), USER_NAME();

    --Remove temporary principals.

    DROP LOGIN login1;

    DROP LOGIN login2;

    DROP USER user1;

    DROP USER user2;

    GO

  • In your code you GRANT VIEW SERVER STATE to Report but not to DMView. The procedure works on my system if you grant VIEW SERVER STATE to DMView.

    [font="Verdana"]Markus Bohse[/font]

  • Dev (11/21/2011)


    In last part I guess you are missing on impersonation.

    Even with

    GRANT IMPERSONATE ON USER::Report TO DMView;

    it returns the error.

  • Dev (11/21/2011)


    aarded (11/21/2011)


    Dev (11/21/2011)


    Change you SP to execute it in Login's Context...

    EXECUTE AS LOGIN = 'DMView'; -- Context Switch

    SELECT physical_io FROM master..sysprocesses WITH (NOLOCK) WHERE spid = @@SPID

    SELECT cntr_value FROM master.sys.dm_os_performance_counters

    Even with

    GRANT IMPERSONATE ON USER::Report TO DMView;

    it returns the error.

  • MarkusB (11/21/2011)


    In your code you GRANT VIEW SERVER STATE to Report but not to DMView. The procedure works on my system if you grant VIEW SERVER STATE to DMView.

    OK this was a mistake.

    But after the change it keeps returning an error.

  • It was just an example. Please don't just follow it, try to understand it. You are missing on Server Level permissions.

    BTW Did you follow Markus advice? It should work for you.

  • aarded (11/21/2011)


    MarkusB (11/21/2011)


    In your code you GRANT VIEW SERVER STATE to Report but not to DMView. The procedure works on my system if you grant VIEW SERVER STATE to DMView.

    OK this was a mistake.

    But after the change it keeps returning an error.

    May I ask you a question? Why your SP is in dbo schema?

    My last bet, Can you please try following? Please login as 'DMView'.

    ALTER PROCEDURE [DMView].[spCounters] -- Change Schema

    --WITH EXECUTE AS 'DMView' -- Remove this

    AS

    SELECT Reads+Writes FROM master.sys.dm_exec_sessions WHERE session_id=@@SPID

    SELECT cntr_value FROM master.sys.dm_os_performance_counters

    GO

Viewing 15 posts - 1 through 15 (of 17 total)

You must be logged in to reply to this topic. Login to reply