2009-01-27 38 views
8

Làm cách nào để kiểm tra xem liệu người dùng có thể thực thi một thủ tục được lưu trữ trong máy chủ MS SQL không?Máy chủ MS SQL: Kiểm tra xem người dùng có thể thực hiện một thủ tục được lưu trữ

tôi có thể thấy nếu người dùng đã rõ ràng thực hiện quyền bằng cách kết nối với cơ sở dữ liệu tổng thể và thực hiện:

databasename..sp_helpprotect 'storedProcedureName', 'username' 

tuy nhiên nếu người dùng là thành viên của một vai trò có quyền thực thi sp_helprotect sẽ không giúp tôi .

Lý tưởng nhất là tôi muốn để có thể gọi một cái gì đó giống như

databasename..sp_canexecute 'storedProcedureName', 'username' 

mà sẽ trả về một bool.

+0

Ngoài ra, nếu bạn đang sử dụng SQL Server 2005 hoặc cao hơn và sự cho phép được gán cho các giản đồ hoặc cơ sở dữ liệu (EXECUTE có thể bây giờ), sp_helprotect sẽ không báo cáo nó. Thủ tục được lưu trữ được bao gồm cho khả năng tương thích ngược và báo cáo quyền dựa trên những gì đã có trong SQL Server 2000. –

Trả lời

13
+1

Tôi không nghĩ rằng các chức năng này trả lời câu hỏi ban đầu, đó là để kiểm tra xem ** _ bất kỳ người dùng nào _ ** đã thực thi quyền trên một proc được lưu trữ. Các bài viết MSDN cho cả hai chức năng nói rằng họ trả lại quyền cho ** _ gọi chính chỉ _ **, chứ không phải là bất kỳ chính. –

1

Giả sử các SP chỉ chạy một câu lệnh SELECT:

EXECUTE AS USER = [User ID/Đăng nhập]
EXEC sp_foobar (sna, fu)
trở

Điều quan trọng cần lưu ý là bạn sẽ cần chạy lệnh REVERT sau lời nhắc như SQL Server sẽ xem xét bạn là người dùng bạn đang thực hiện AS cho đến khi bạn tắt kết nối hoặc REVERT mạo danh. Điều đó nói rằng, bạn sẽ thấy chính xác những gì người dùng sẽ nhận được (nhận được một số hàng nhưng không phải tất cả? Điều này sẽ giúp bạn ra ngoài).

4

Hãy thử một cái gì đó như thế này:

CREATE PROCEDURE [dbo].[sp_canexecute] 
@procedure_name varchar(255), 
@username varchar(255), 
@has_execute_permissions bit OUTPUT 
AS 

IF EXISTS (
     /* Explicit permission */ 
     SELECT 1 
     FROM sys.database_permissions p 
     INNER JOIN sys.all_objects o ON p.major_id = o.[object_id] AND o.[name] = @procedure_name 
     INNER JOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id AND dp.[name] = @username 
    ) 
    OR EXISTS (
     /* Role-based permission */ 
     SELECT 1 
     FROM sys.database_permissions p 
     INNER JOIN sys.all_objects o ON p.major_id = o.[object_id] 
     INNER JOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id AND o.[name] = @procedure_name 
     INNER JOIN sys.database_role_members drm ON dp.principal_id = drm.role_principal_id 
     INNER JOIN sys.database_principals dp2 ON drm.member_principal_id = dp2.principal_id AND dp2.[name] = @username 
    ) 
BEGIN 
    SET @has_execute_permissions = 1 
END 
ELSE 
BEGIN 
    SET @has_execute_permissions = 0 
END 
GO 
+0

Điều đó có hiệu quả nếu người dùng là thành viên của vai trò có quyền và không được phép thực thi thủ tục được lưu trữ một cách rõ ràng không? – Andrew

+0

Không, nhưng bạn có thể đặt tên vai trò trong tham số @username và vẫn sẽ trả lại kết quả boolean đúng/mong đợi. – Dane

+0

Ok, tôi đã cập nhật mã proc ở trên để nhận các quyền được cấp theo vai trò cũng như cấp rõ ràng. – Dane

Các vấn đề liên quan