Normalmente tenho usuários comuns que se conectam ao meu banco de dados SQL Server e executam procedimentos armazenados no esquema chamado myschema
.
Se esses usuários tentarem obter dados das tabelas do banco de dados, eles não verão nenhuma tabela, mas poderão acessá-las por meio de um procedimento armazenado em myschema
.
Agora estou consultando sys.dm_exec_sessions
e sys.dm_exec_connections
gostaria de ter a mesma abordagem, mas não, tenho que conceder VIEW SERVER STATE
permissão para um usuário que está chamando a myschema.GetUserSessions
procedure!
Afinal eu quero que os usuários tenham acesso apenas a alguns campos de sys.dm_exec_sessions
e sys.dm_exec_connections
, não a todas as visualizações, e apenas através deste procedimento armazenado, mas não diretamente.
Atualmente estou usando uma solução alternativa que verifica a permissão e retorna um conjunto de resultados vazio com os tipos de dados corretos:
CREATE PROCEDURE myschema.GetUserSessions
AS
/* To be able to run this procedure an user should have VIEW SERVER STATE permission:
USE master;
GRANT VIEW SERVER STATE TO [HOST\Username];
*/
IF EXISTS(SELECT permission_name FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name = 'VIEW SERVER STATE') BEGIN
SELECT
ses.login_name,
ses.[host_name],
con.client_net_address,
ses.[program_name],
ses.login_time,
ses.last_request_start_time,
ses.last_request_end_time,
con.net_transport,
con.encrypt_option
FROM
sys.dm_exec_sessions ses
inner join sys.dm_exec_connections con on con.session_id = ses.session_id
WHERE
is_user_process = 1
END
ELSE BEGIN
SELECT
login_name = CAST('' AS NVARCHAR),
[host_name] = CAST(NULL AS NVARCHAR),
client_net_address = CAST(NULL AS VARCHAR),
[program_name] = CAST(NULL AS NVARCHAR),
login_time = CAST(0 AS DATETIME),
last_request_start_time = CAST(0 AS DATETIME),
last_request_end_time = CAST(NULL AS DATETIME),
net_transport = CAST('' AS NVARCHAR),
encrypt_option = CAST('' AS NVARCHAR)
WHERE
1 = 0
END
Sinceramente, não gosto da ideia de nem conceder VIEW SERVER STATE
permissão aos usuários nem salvar os dados de vez em quando em alguma tabela intermediária.
Você pode usar a assinatura de módulo para fazer isso, pois já está criando procedimentos armazenados para esse resultado final. Dependendo dos seus casos de uso, podem ser muitos módulos.
Se você vai mostrar a todos todos os resultados de qualquer maneira, não tenho certeza da necessidade de assinar o módulo e da aversão a visualizar o estado do servidor, mas também não é o meu ambiente. Você tem várias opções, escolha uma ou várias, mas isso será limitado pelas "limitações" do produto. Se nada disso funcionar para você, não deixe as pessoas verem ou faça uma concessão.