Ale*_*lex 6 sql-server permissions sql-server-2016
我有一个 SQL Server 2016 实例,我刚刚注意到某些用户的某些用户登录名未列出。例如,如果我执行此查询:
select count(*) FROM sys.database_principals a where type = 'U'
Run Code Online (Sandbox Code Playgroud)
我收到的计数是1348. 但是如果我执行这个查询:
execute as user = 'some_user';
select count(*) FROM sys.database_principals a where type = 'U';
revert;
Run Code Online (Sandbox Code Playgroud)
我收到的计数为92,这意味着存在1256上述用户看不到的用户。如果我授予用户db_accessadmin数据库角色成员资格,那么他们就可以看到1348从上述查询返回的所有用户。但我不想授予db_accessadmin所有用户,因为这提供的访问权限比我想要授予的要多得多。
我已将显示的 92 个用户之一的属性与未显示的用户的属性进行了比较,但我没有注意到任何看起来允许列出该用户的属性。
我该如何允许所有用户都列在对database_principals 的查询中?
查看用户需要对用户原则具有查看定义权限。这是由 ALTER USER 权限暗示的。
使用 ALTER USER,您可以方便地执行 ALTER ANY USER,这是 db_accessadmin 所获得的权利。但仅针对“视图定义”就没有这样的东西。
GRANT ALTER ANY USER TO Foo --Works
GRANT VIEW DEFINITION ANY USER TO Foo --Syntax Error
Run Code Online (Sandbox Code Playgroud)
因此,要完成您想要的任务,最简单的方法可能是创建一个新的数据库角色,通过脚本为其授予数据库中所有用户的“查看定义”权限。然后将用户分配给您想要授予这些权限的新角色。
IF DATABASE_PRINCIPAL_ID('OnlySeeAllUsers') IS NULL
BEGIN
RAISERROR('OnlySeeAllUsers role is not defined yet, creating it', 1, 1) WITH NOWAIT
CREATE ROLE OnlySeeAllUsers
END
DECLARE @QUERY NVARCHAR(MAX);
DECLARE @UserName NVARCHAR(256);
DECLARE @ErrorMessage NVARCHAR(4000), @ErrorSeverity INT, @ErrorState INT;
DECLARE userIterator CURSOR LOCAL FAST_FORWARD
FOR
SELECT [DAT].[name] FROM sys.database_principals AS DAT
WHERE ([DAT].[TYPE] = 'U' --Windows logins
OR [DAT].[TYPE] = 'S') --SQL Logins
AND [DAT].[SID] IS NOT NULL --Filters out sys/information schema,
--which will cause errors otherwise
OPEN userIterator;
FETCH NEXT FROM userIterator INTO @UserName;
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
SET @QUERY = N'GRANT VIEW DEFINITION ON USER::' + @UserName + ' TO OnlySeeAllUsers';
EXEC (@QUERY);
FETCH NEXT FROM userIterator INTO @UserName;
END TRY
BEGIN CATCH
SELECT @ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); --Get ErrorInfo
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState) WITH NOWAIT;
BREAK; --Abort while
END CATCH
END
CLOSE userIterator;
DEALLOCATE userIterator;
Run Code Online (Sandbox Code Playgroud)
上述脚本可以保存/制作成一个过程并在必要时重新运行,或者可以在创建新用户时触发触发器以将视图定义授予数据库角色。
然后将用户添加到该数据库角色(SQL Server 2012+)
ALTER ROLE OnlySeeAllUsers
ADD MEMBER Foo
EXEC sp_addrolemember 'OnlySeeAllUsers', 'Foo' --Method before SQL Server 2012
Run Code Online (Sandbox Code Playgroud)