Почему пользователь с разрешениями sysadmin не может получить доступ к msdb как пользователь EXECUTE AS? - PullRequest
0 голосов
/ 30 марта 2019

Я создал testuser имя входа, установленное как sysdamin, и использовал его для предложения execute as в следующей функции, созданной в тестовой базе данных, отличной от msdb.

CREATE FUNCTION [dbo].[MyTestFunction] 
    (@job_name SYSNAME)
RETURNS INT
WITH EXECUTE AS 'TestUser'
AS
BEGIN
    DECLARE @id INT 

    SELECT TOP 1 @id = schedule_id 
    FROM msdb.dbo.sysjobschedules

    RETURN @id
END

Когда я выполняю MyTestFunction, я получаю следующую ошибку:

В доступе SELECT отказано для объекта 'sysjobschedules', базы данных 'msdb', схемы 'dbo'.

В свою очередь, если я напрямую войду в систему с помощью логина TestUser и сразу выполню оператор SELECT с использованием тестовой базы данных, все будет работать нормально.

Пользователь TestUser может напрямую обращаться к msdb из тестовой базы данных, но не может получить доступ к msdb, если используется в предложении execute as функции тестовой базы данных.

Как получить доступ к базе данных msdb из функции, созданной в другой базе данных?

Заранее спасибо,

Игнасио

1 Ответ

0 голосов
/ 03 апреля 2019

Олицетворенный контекст безопасности EXECUTE AS помещается в изолированную программную среду для текущей базы данных.Вы не можете получить доступ к другим базам данных внутри функции, если база данных не является TRUSTWORTHY, что обычно не является хорошей практикой.

Для кросс-доступа к базе данных пользователями с минимальными привилегиями рассмотрите возможность использования подписи модуля .Это позволяет вам предоставлять доступ к другим базам данных и объектам в контексте выполнения модуля, не предоставляя конечным пользователям прямых разрешений.Пользователям нужны только разрешения для этой функции.

Ниже приведен пример сценария, подобранного из указанной статьи для вашей конкретной потребности.Хотя этот базовый метод может быть расширен для предоставления разрешений sysadmin, рекомендуется использовать учетную запись с минимальными привилегиями.

-- Create a certificate in msdb
USE msdb;
CREATE CERTIFICATE msdb_certificate
   ENCRYPTION BY PASSWORD = 'p@Ss0RDforTheceRT1cate'
   WITH SUBJECT = 'For cross-database access to msdb database';

-- create a user from certification with needed permissions
CREATE USER msdb_certificate_user FROM CERTIFICATE msdb_certificate;
GRANT SELECT ON msdb.dbo.sysjobschedules TO msdb_certificate_user;

-- Copy certificate to user database (Example)
DECLARE @cert_id int = cert_id('msdb_certificate');
DECLARE @public_key  varbinary(MAX) = certencoded(@cert_id),
        @private_key varbinary(MAX) =
           certprivatekey(@cert_id,
              'p@Ss0RDforTheceRT1cate',
              'p@Ss0RDforTheceRT1cate');
DECLARE @sql nvarchar(MAX) =
      'CREATE CERTIFICATE msdb_certificate
       FROM  BINARY = ' + convert(varchar(MAX), @public_key, 1) + '
       WITH PRIVATE KEY (BINARY = ' +
          convert(varchar(MAX), @private_key, 1) + ',
          DECRYPTION BY PASSWORD = ''p@Ss0RDforTheceRT1cate'',
          ENCRYPTION BY PASSWORD = ''p@Ss0RDforTheceRT1cate'')';
EXEC YourDatabase.sys.sp_executesql @sql;
ALTER CERTIFICATE msdb_certificate REMOVE PRIVATE KEY; --remove ephemeral private key
GO

--sign module with certificate 
USE YourDatabase;
ADD SIGNATURE TO dbo.MyTestFunction BY CERTIFICATE msdb_certificate
   WITH PASSWORD = 'p@Ss0RDforTheceRT1cate';
ALTER CERTIFICATE msdb_certificate REMOVE PRIVATE KEY; --remove ephemeral private key
GO
--users only need permissions on directly invoked module
GRANT EXECUTE ON dbo.MyTestFunction TO YourUser;
GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...