Question

One thing that I've always hated more than just about anything in MS SQL Server is the way that security works. The security context constantly switches if you look at the server funny and it's often very hard (for me anyway) to predict or debug.

In dealing with an issue today, I though, "I wish I could just add a line to my code that would display the security context that SQL Server is using when this code runs." Does such a command exist? For example, SELECT security_context()

To be a little clearer... if I'm in a stored procedure and am therefor subject to the security context of the owner of the SP then I'd like to see that. If I'm in code that was called by sp_executesql and it's causing the security to be under the context of the SQL Server service account, then I would want to see that.

At least then I might be able to figure out why SQL Server thinks that I shouldn't have access to something.

Thanks!


EXAMPLE

-- Set up
CREATE USER Test_User WITHOUT LOGIN
CREATE TABLE Test_Security_Context (my_id INT)
INSERT INTO Test_Security_Context VALUES (1)
DENY SELECT ON Test_Security_Context TO Test_User
GO
CREATE PROCEDURE Test_Security_Context_SP
AS
  SELECT SUSER_SNAME()
  SELECT * FROM Test_Security_Context  -- This will return ok
  EXEC('SELECT SUSER_SNAME(); SELECT * FROM Test_Security_Context')  -- SUSER_SNAME() will match above but select fails
GO
GRANT EXECUTE ON Test_Security_Context_SP TO Test_User
GO

-- Switch to the new user
SETUSER 'Test_User'
GO

-- Do the test
EXEC Test_Security_Context_SP
GO

-- Clean up
SETUSER
DROP PROCEDURE Test_Security_Context_SP
DROP TABLE Test_Security_Context
DROP USER Test_User
GO
Was it helpful?

Solution

Yes, there is such a pair of views that represents your current security context, considering all the details like EXECUTE AS or code signing:

Every single access you get is ultimately derived from a row in the return of these results. Note that some access are implicit from hard coded role membership (like db_datareader database role or sysadmin server role).

Other that that:

  • ownership chaining is not related to security context: you are not under the 'context' of the SP owner. Ownership chaining simply states that access checks are skipped for objects owned by the same owner as current object (SP, View).
  • sp_executesql does not change the security context in any way

OTHER TIPS

Not sure if this is what you mean by security context, but you can retrieve the user associated with your session like:

select SYSTEM_USER

This works for both a SQL Server login or a WIndows login. It even works inside stored procedures with execute as owner. For example,

create procedure dbo.Test
with execute as owner
as
select SYSTEM_USER
go
exec dbo.Test
select SYSTEM_USER

Prints:

sa
MyMachine\MyName

If you're looking for the Windows account that SQL Server is using to do things on your behalf, you could try to run whoami from the command like:

EXEC sp_configure 'show advanced options', 1
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE

EXEC master..xp_cmdshell 'whoami'

For me, that returns nt authority\network service.

I think you want to use CURRENT_USER to see the current security context. Here's an example:

SELECT CURRENT_USER AS 'Current User Name';
GO
EXECUTE AS LOGIN = 'junk'
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
REVERT
SELECT CURRENT_USER AS 'Current User Name';
GO

with output (note: I'm admin on my SQL Server for this)

Current User Name
------------------
dbo

(1 row(s) affected)

Current User Name
------------------
Junk

(1 row(s) affected)

Current User Name
------------------
dbo

(1 row(s) affected)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top