GRANT SELECT ON sys.server_principals 给 usersys 角色。如何?
Posted
技术标签:
【中文标题】GRANT SELECT ON sys.server_principals 给 usersys 角色。如何?【英文标题】:GRANT SELECT ON sys.server_principals to usersys role. How? 【发布时间】:2018-11-28 23:45:28 【问题描述】:我找不到这个问题的答案。问题是我需要使用主数据库,然后我不知道如何指定我将此选择授予另一个数据库中的角色。使用“use master”时它不起作用,因为主体在另一个数据库中,你不能添加例如Database.dbo.role 原则的前缀。我怎么做?即使通过 SSMS UI 授予也不起作用。
我需要这个:GRANT SELECT ON Syf.sys.server_principals to Syf.dbo.usersys
我错过了什么?我是否以错误的方式思考这个问题?
即使我在 master 数据库上尝试使用用户并调用“execute as user = 'user'”,然后从 sys.server_principals 中选择它仍然只返回几条记录。我显然不明白这些权限是如何工作的,这超出了我的逻辑。似乎还有一些其他对象需要我授予权限。
我需要使用“with execute as 'privilegedUser'”,当我这样做时,我们处于该 SP 数据库的用户上下文中,并且该用户无权访问 sys.server_principals。?我需要这个,因为如果存在同名登录,SP 会删除用户和登录。我需要使用特权用户执行的原因是因为我的数据库具有多租户并且每个用户都绑定到一个 TenantId,当他或其他用户去删除用户时,安全策略抱怨他无权这样做。
我找到了一种方法来做到这一点,我必须将选择授予 sys.server_principals 给主数据库上的来宾用户,从而为来宾提供更多特权。
【问题讨论】:
你可以试试看这个:dba.stackexchange.com/questions/96629/… 但我不认为它适用于大师 dba.stackexchange.com 可能是找到答案的更好地方。sys.server_principals
是服务器级登录和组的视图。它仅存在于master
中(在Syf
中引用它只是将其重定向到master
)。你在想sys.database_principals
吗? SELECT * FROM Syf.sys.database_principals;
- 你在那里看到你的用户吗?这是您试图授予访问权限的视图吗?您实际上试图通过授予对该视图的访问权限来做什么?最终目标是什么?
所有登录名/用户权限不足,但他们可以更改任何登录权限,以便他们可以添加新登录名和具有相同权限的用户。他们还可以删除用户和登录名,但存在问题:当他们调用删除用户的存储过程时,相同的存储过程需要检查是否是最后一个链接到登录名的用户,以及是否存在具有相同名称的登录名,如果存在然后程序也会删除登录名,我这样做是因为一个登录名可能有多个数据库中的用户,如果所有用户都被删除,我也需要删除登录名。
【参考方案1】:
我找到了一个解决方案,我不需要在第一个过程中使用“以所有者身份执行”,但在第一个过程调用的第二个过程中。在第一个中,我可以从 sys 表中选择我需要的所有内容,然后将信息传递给第二个具有“以所有者身份执行”的数据,该模式位于禁止用户使用的模式中。
更好的解决方案:
alter trigger [dbo].[AfterInsertUpdateTenant_Korisnici]
on [dbo].[Korisnici]
with execute as owner
for insert
as
execute as user = original_login();
declare @TenantId int = dbo.GetCurrentTenantId();
revert;
update dbo.Korisnici
set TenantId = @TenantId
from Inserted i
where dbo.Korisnici.Id = i.Id;
【讨论】:
【参考方案2】:根据 sys.server_principals 的文档,所需的权限是:
任何登录名都可以看到自己的登录名、系统登录名和固定的服务器角色。要查看其他登录名,需要 ALTER ANY LOGIN 或登录权限。要查看用户定义的服务器角色,需要 ALTER ANY SERVER ROLE 或角色中的成员身份。
目录视图中元数据的可见性仅限于用户拥有或已被授予某些权限的安全对象。有关详细信息,请参阅元数据可见性配置。
但一切都没有丢失。我们可以使用模块签名来创建一个存储过程,让您可以做您需要做的事情。
use master;
create master key encryption by password = 'an unguessable password!'
alter master key add encryption by service master key
create certificate [CodeSigningCert]
with expiry_date = '2018-12-31',
subject = 'Code signing'
go
create login [CodeSigningLogin] from certificate [CodeSigningCert]
grant alter any login to [CodeSigningLogin]
go
SELECT 'CREATE CERTIFICATE ' + QUOTENAME([name])
+ ' AUTHORIZATION ' + USER_NAME([c].[principal_id])
+ ' FROM BINARY = ' + CONVERT(VARCHAR(MAX), CERTENCODED([c].[certificate_id]), 1)
+ ' WITH PRIVATE KEY (BINARY = '
+ CONVERT(VARCHAR(MAX), CERTPRIVATEKEY([c].[certificate_id], 'f00bar!23'), 1)
+ ', DECRYPTION BY PASSWORD = ''f00bar!23'')'
FROM [sys].[certificates] AS [c]
WHERE [name] = 'CodeSigningCert'
use tempdb
go
create master key encryption by password = 'foobar!23'
-- c/p the create certificate code generated above here
-- to create the same certificate in tempdb
create user CodeSigningUser from certificate CodeSigningCert
go
create login [foobar] with password = 'foobar!23'
create user [foobar]
go
create procedure dbo.listServerPrincipals
as
begin
select *
from sys.server_principals
end
go
grant execute on dbo.listServerPrincipals to foobar
go
execute as login = 'foobar'
go
exec dbo.listServerPrincipals
revert
go
add signature to dbo.listServerPrincipals by certificate [CodeSigningCert]
go
execute as login = 'foobar'
go
exec dbo.listServerPrincipals
revert
go
看起来很多,但实质上您正在执行以下操作:
-
在 master 中创建证书
从该证书创建登录
在您的用户数据库中创建相同的证书(我在这里使用 tempdb 作为替代)
为该证书创建一个用户
创建一个登录名/用户来代表您的应用程序用户
创建一个执行选择的过程
尝试在应用登录时执行它。它“有效”,但看起来与您自己完成选择没有什么不同
为过程添加签名
尝试再次执行该过程。这一次,它应该返回所有数据
【讨论】:
您能解释一下为什么要使用证书吗?是不是因为这一行:“通过证书 [CodeSigningCert] 向 dbo.listServerPrincipals 添加签名”,证书是否赋予 SP 从 sys.server_principals 中选择的权利? 在高层次上,是的。还需要从该证书创建用户和登录(登录以便可以将权限附加到它;用户以便它可以链接到登录)。 它不起作用:“对象 'server_principals'、数据库 'mssqlsystemresource'、架构 'sys' 的 SELECT 权限被拒绝。”把它扔到“exec dbo.listServerPrincipals”这一行。我使用的是我的数据库而不是 tempdb。 嗯……听起来好像有什么不对劲的地方。向后工作。检查sys.crypt_properties
中是否有一行用于您的过程(表明它已签名),用户是否存在该证书,以及登录是否存在同一证书。
如果此解决方案适合您,请考虑将其标记为已接受的答案。不是因为我是为了上网点,而是因为它可以帮助那些追随你的人知道你认为这个解决方案是最好的。但我不会撒谎......那些互联网点也感觉很好。 :)以上是关于GRANT SELECT ON sys.server_principals 给 usersys 角色。如何?的主要内容,如果未能解决你的问题,请参考以下文章
mysql 赋给用户远程权限 grant all privileges on