web-dev-qa-db-ja.com

ストアドプロシージャ、関数、ビューに対する実行権限の付与

読み取り権限のみのユーザーを使用しています。基本的には

  • 接続する
  • Execute

ただし、関数とストアドプロシージャに対する実行権限はありません。一部のレポートでは、自分の関数を呼び出しています。 SP、関数、ビューを実行するreadonlyuser権限を与えたいのですが。

私は このコード に遭遇しました。これは、特定のユーザーにストアドプロシージャと関数の実行権限を与える方法を示しています。

- Grant Execute on all functions for testuser
declare @username varchar(255)  
set @username = 'testuser'  
SELECT 'grant exec on ' + QUOTENAME(ROUTINE_SCHEMA) + '.' +  
QUOTENAME(ROUTINE_NAME) + ' TO ' + @username FROM INFORMATION_SCHEMA.ROUTINES  
WHERE OBJECTPROPERTY(OBJECT_ID(ROUTINE_NAME),'IsMSShipped') = 0   
and ROUTINE_TYPE='PROCEDURE'  

および関数

declare @username varchar(255)  
set @username = 'testuser'  
SELECT 'grant exec on ' + QUOTENAME(ROUTINE_SCHEMA) + '.' +  
QUOTENAME(ROUTINE_NAME) + ' TO ' + @username FROM INFORMATION_SCHEMA.ROUTINES  
WHERE OBJECTPROPERTY(OBJECT_ID(ROUTINE_NAME),'IsMSShipped') = 0   
and ROUTINE_TYPE='FUNCTION'  

さて、ここでは既存のSPおよび関数のみにこの権限が適用されているようです。新しい関数を追加する場合は、このコードを再度実行して権限を付与する必要があります。

ご質問

  1. 上記の解釈が間違っていない場合、読み取り専用ユーザーに実行権限を付与して、新しい関数を作成した場合でも、すべての関数とストアドプロシージャに対する権限を付与する方法はありますか?

  2. ビューに同じ権限を適用できますか?

  3. this thread では、テーブルを返す関数に実行権限を与えることができないと言われています。本当?

いくつか質問があることは知っていますが、それらはすべて関連しています。 1つの場所にいる方がよい。

6
Jackofall

テーブルを返す関数にEXEC権限を付与できないのは事実です。このタイプの関数は、実際には関数というよりビューです。代わりにSELECTを付与する必要があります。例:

_GRANT SELECT ON dbo.Table_Valued_Function TO [testuser];
_

したがって、スクリプトは次のようになります(申し訳ありませんが、 私は_INFORMATION_SCHEMA_ を絶対に嫌っています。また、OBJECTPROPERTYなどの関数を必要としないカタログビューを使用することをお勧めします。 ):

_DECLARE 
    @sql      NVARCHAR(MAX) = N'',
    @username VARCHAR(255)  = 'testuser';

SELECT @sql += CHAR(13) + CHAR(10) + N'GRANT ' + CASE 
    WHEN type_desc LIKE 'SQL_%TABLE_VALUED_FUNCTION'
      OR type_desc = 'VIEW'
    THEN ' SELECT ' ELSE ' EXEC ' END 
    + ' ON ' + QUOTENAME(SCHEMA_NAME([schema_id])) 
    + '.' + QUOTENAME(name) 
    + ' TO ' + @username + ';'
 FROM sys.all_objects
WHERE is_ms_shipped = 0 AND
( 
    type_desc LIKE '%PROCEDURE' 
    OR type_desc LIKE '%FUNCTION'
    OR type_desc = 'VIEW'
);

PRINT @sql;
-- EXEC sp_executesql @sql;
_

これで、スキーマにEXECを付与し、そのスキーマでこれらのプロシージャを作成できます(実際にはスキーマの目的の1つです)。これは、@ jgardner04ですでに提案されていますが、このソリューションをテーブルに適用するには、値のある関数も同様に、SELECTも付与する必要があります。そのスキーマのテーブルにデータを保存しない場合(または少なくとも非表示にする場合)は問題ありませんが、意図していない可能性があるすべてのテーブルとビューにも適用されます。

別のアイデア(たとえば、スキーマを使用できない、または使用したくない場合)は、_CREATE_PROCEDURE_、_CREATE_FUNCTION_および_CREATE_VIEW_イベントをキャプチャするDDLトリガーを作成し、許可することです。ユーザー(または、テーブルに格納する場合は、ユーザーのセット)に対する権限:

_CREATE TRIGGER ApplyPermissionsToAllProceduressAndFunctions -- be more creative!
    ON DATABASE FOR CREATE_PROCEDURE, CREATE_FUNCTION, CREATE_VIEW
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE
        @sql       NVARCHAR(MAX),
        @EventData XML = EVENTDATA();

    ;WITH x ( sch, obj ) 
    AS
    (
        SELECT
          @EventData.value('(/EVENT_INSTANCE/SchemaName)[1]',  'NVARCHAR(255)'), 
          @EventData.value('(/EVENT_INSTANCE/ObjectName)[1]',  'NVARCHAR(255)')
    )
    SELECT @sql = N'GRANT ' + CASE 
      WHEN o.type_desc LIKE 'SQL_%TABLE_VALUED_FUNCTION' 
        OR o.type_desc = 'VIEW'
      THEN ' SELECT ' 
      ELSE ' EXEC ' END 
        + ' ON ' + QUOTENAME(x.sch) 
        + '.' + QUOTENAME(x.obj) 
        + ' TO testuser;' -- hard-code this, use a variable, or store in a table
    FROM x
    INNER JOIN sys.objects AS o
    ON o.[object_id] = OBJECT_ID(QUOTENAME(x.sch) + '.' + QUOTENAME(x.obj));

    EXEC sp_executesql @sql;
END
GO
_

私がDDLトリガーで見つけた欠点は、それらがそこにあることをすぐに忘れることができることです。したがって、すべての新しいオブジェクトへのこれらのアクセス許可の付与をやめることに決めた1年後、それがまだ起こっている理由のトラブルシューティングには時間がかかる場合があります。私の最後の仕事では、DDLトリガーによって呼び出されたすべてのアクションを一種の中央の「イベントログ」に記録しました。これは、誰も覚えていないようにサーバーで発生したアクションを追跡するための最適な場所でした(そしてそれはDDLは約半分の時間でトリガーされます)。そのため、これに役立つロジックをいくつか追加することを検討してください。

[〜#〜]編集[〜#〜]

スキーマベースのコードを追加します。これにより、fooスキーマで作成されたすべてのプロシージャ、関数、およびテーブルへのアクセス許可が付与されることを再度説明します。

_CREATE SCHEMA foo;
GRANT EXEC, SELECT ON SCHEMA::foo TO testuser;
_

次のプロシージャを作成すると、testuserを実行できるようになります。

_CREATE PROCEDURE foo.proc1
AS 
BEGIN
    SET NOCOUNT ON;
    SELECT 1;
END
GO
_
9
Aaron Bertrand

スキーマを利用して、スキーマ内のアイテムを実行する権限をユーザーに付与できますか?スキーマに関する詳細情報は、ここにあります: http://msdn.Microsoft.com/en-us/library/ms187940.aspx

3
jgardner04