Sự cố với quyền cơ sở dữ liệu cho sp_send_mail


8

Tôi đang cố gắng gửi thư cơ sở dữ liệu nhưng tôi đang nhận được EXECUTE permission denied on the object 'sp_send_dbmail' database 'msdb', schema 'dbo'.. Tôi mã tôi đang chạy như sau:

SELECT SUSER_NAME(), USER_NAME();
Create USER kyle_temp FOR LOGIN Foo
EXECUTE AS USER = 'kyle_temp';
SELECT SUSER_NAME(), USER_NAME();
EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Mail Profile',
            @recipients = 'test@test.com',
            @subject = 'Test',
              @body = 'Test'
REVERT;
DROP USER kyle_temp

Đăng nhập Foo cho thấy rằng nó được ánh xạ tới Người dùng Foo trong msdb. Khi tôi nhìn vào người dùng foo trong msdb, tôi thấy rằng nó đã kiểm tra "DatabaseMailUserRole" và Thực thi trên dbo sp_send_dbmail.

Tôi đang thiếu gì?

Câu trả lời:


10

Bạn đang chạy vào chế độ 'hộp cát' đáng sợ của EXECUTE ASbối cảnh, như được mô tả trong Mở rộng mạo danh cơ sở dữ liệu bằng cách sử dụng EXECUTE AS . Trong mã ngắn chạy dưới chỉ EXECUTE AS USER ...được tin cậy trong bối cảnh cơ sở dữ liệu , không phải trong bối cảnh thể hiện.

Có ba cách:

  • cách dễ dàng: đánh dấu cơ sở dữ liệu hiện tại là TRUSTWORTHY ALTER DATABASE [...] SET TRUSTWORTHY ON;
  • cách chính xác: sử dụng ký mã
  • gian lận: sử dụng EXECUTE AS LOGIN

Nếu trong môi trường của bạn, dbocơ sở dữ liệu hiện tại được tin cậy thì bạn có thể đi với TRUSTWORTHY. Nó sẽ hoạt động, nhưng nếu thuộc tính này được đặt thì bất kỳ db_ownerDB nào hiện tại cũng có thể tự nâng mình lên thành quản trị viên máy chủ.

Nếu bạn muốn một giải pháp 'chính xác' thì:

  1. di chuyển mã này trong một Proc được lưu trữ
  2. ký tên vào kho lưu trữ với một chứng chỉ
  3. thả khóa riêng (để không bao giờ có thể sử dụng lại để ký bất cứ thứ gì)
  4. xuất khóa công khai, nhập nó vào [msdb]
  5. tạo người dùng [msdb]bắt nguồn từ chứng chỉ này
  6. cấp các quyền cần thiết (AUTHENTICATE, EXECUTE trên sp_send_mail) cho người dùng xuất phát chứng chỉ

Tầm thường, heh? BTW, mỗi khi bạn sửa đổi Proc lưu trữ đã ký, chữ ký sẽ bị mất và thủ tục phải được lặp lại. Xem Gọi một thủ tục trong cơ sở dữ liệu khác từ một quy trình được kích hoạt để lấy ví dụ.

Tôi hoàn toàn không khuyên bạn nên sử dụng EXECUTE AS LOGINthay thế.


Về lâu dài, tôi đang cố gắng để điều này được thực thi như một trình kích hoạt, vì vậy EXECUTE AS của tôi là một cách để thử nghiệm trong thời gian ngắn ...
Kyle Brandt

1
Cách sạch nhất là có một Proc lưu trữ cục bộ trong DB của bạn và có lệnh gọi msdb.dbo.sp_send_mailtrong phần thân SP cục bộ này. Có kích hoạt gọi SP địa phương này. Mã ký SP.
Remus Rusanu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.