Home > Software engineering >  Why won't T-SQL Stored Procedure return from SYS.DATABASE_PRINCIPALS
Why won't T-SQL Stored Procedure return from SYS.DATABASE_PRINCIPALS

Time:08-03

Create procedure test.access
      @principal_id int
      with execute as owner
      as
      set nocount on;
         begin
            select * from sys.database_principals where principal_id = @principal_id
         end;

I create the above procedure and execute but it returns nothing. However if I declare @principal_id as a variable, set it then run this code outside a procedure it returns the correct rows.

Why isn't it working inside the procedure?

CodePudding user response:

If the owner of the test schema does not have elevated permissions, then the rows that can be seen in sys.database_principals will be limited. From the documentation

Any user can see their own user name, the system users, and the fixed database roles. To see other users, requires ALTER ANY USER, or a permission on the user. To see user-defined roles, requires ALTER ANY ROLE, or membership in the role.

In the following script I create the user test, as well as a schema test. I make the test user the owner of the test schema.

I then create a procedure in that schema with execute as owner. It will therefore execute in the context of the test user.

But the test user does not have ALTER ANY USER permission, so the rows visible in sys.database_principals are limited:


create login test with password = 'test';
create user test for login test;
go

create schema test authorization test;
go

create procedure test.access with execute as owner as 
begin   
   select * from sys.database_principals;
end
go

exec test.access; -- returns a limited set principals

If I grant the test user the alter any user permission and then re-execute the procedure, I will get all of the users:


grant alter any user to test;

exec test.access; -- returns all users (but not user defined roles)

grant alter any role to test;

exec test.access; -- returns everyone and all roles

If the test schema is currently not owned by the correct user, you can change that:

alter authorization on schema::test to [user];
  • Related