it-swarm.asia

Menerima "Izin SELECT ditolak pada objek" meskipun sudah diberikan

Saya seorang programmer, bukan dba ... Saya tahu cukup berbahaya.

Saya telah mewarisi database dengan pengguna lawas yang merupakan db_owner untuk database tersebut. Kami tidak dapat menyesuaikan izin pengguna ini untuk tabel, skema, dll yang ada, untuk alasan bisnis, tetapi beberapa tabel baru sedang dibuat, dan saya hanya ingin pengguna ini memiliki akses SELECT pada mereka.

Izin telah ditetapkan untuk pengguna ini untuk tabel ini sehingga semuanya DITOLAK, kecuali SELECT, yang diatur ke GRANT.

Namun ketika pengguna ini (dbadmin) mencoba melakukan SELECT pada salah satu tabel ini (AccountingAudit), kesalahan ini terjadi:

The SELECT permission was denied on the object 'AccountingAudit', database 'billing', schema 'dbo'.

Saya sudah menjalankan SQL ini untuk mencoba dan melihat izin apa yang ditetapkan untuk tabel/pengguna ini:

select object_name(major_id) as object,
 user_name(grantee_principal_id) as grantee,
 user_name(grantor_principal_id) as grantor,
 permission_name,
 state_desc
from sys.database_permissions

Dan inilah yang saya dapatkan:

AccountingAudit dbadmin dbo ALTER   DENY
AccountingAudit dbadmin dbo CONTROL DENY
AccountingAudit dbadmin dbo DELETE  DENY
AccountingAudit dbadmin dbo INSERT  DENY
AccountingAudit dbadmin dbo REFERENCES  DENY
AccountingAudit dbadmin dbo SELECT  GRANT
AccountingAudit dbadmin dbo TAKE OWNERSHIP  DENY
AccountingAudit dbadmin dbo UPDATE  DENY
AccountingAudit dbadmin dbo VIEW DEFINITION DENY
AccountingAudit dbadmin dbo VIEW CHANGE TRACKING    DENY

Sepertinya itu harusnya bekerja dengan baik?

Panggilan SELECT yang saya buat adalah SELECT * yang sangat mendasar dari AccountingAudit, dari dalam SSMS. Saya tidak melakukan sp_executesql khusus atau semacamnya.

Saya sudah mencoba memberikan izin secara eksplisit:

GRANT SELECT ON [dbo].AccountingAudit TO dbadmin

Ini tidak berpengaruh (mengapa, kueri di atas sudah menunjukkan itu diberikan! ;-)

Saya telah mencari melalui stackoverflow.com dan tempat lain, dan tidak dapat menemukan apa pun yang belum saya coba. Saya bertanya-tanya apakah itu ada hubungannya dengan bagaimana pengaturan skema. (Pada titik ini saya tahu sedikit tentang skema.)

Ada ide? Terima kasih!

11
Mason G. Zhwiti

Saya tidak yakin di sini, tapi saya akan mengambil risiko. Saya pikir masalah Anda mungkin dengan catatan DENY CONTROL Anda. Lihat di sini sekitar setengah halaman:

Menolak izin KONTROL pada database secara implisit menolak izin CONNECT pada database. Prinsipal yang ditolak izin KONTROL pada database tidak akan dapat terhubung ke database itu.

Saya menyadari bahwa contoh adalah untuk basis data, tetapi gunakan satu tingkat lagi. A DENY CONTROL Di atas tabel akan menolak semua hak istimewa di atasnya, saya menduga. Lakukan REVOKE CONTROL Untuk menyingkirkannya dan lihat apakah itu memperbaiki masalah Anda.

Jika demikian, Anda harus menempatkan pengguna dalam peran basis data atau menolak mereka hak istimewa eksplisit terhadap tabel.

10
Thomas Stringer
  1. Gunakan prosedur tersimpan Ken Fisher sp_DBPermissions Untuk melihat izin.

    1. Pastikan DENY CONTROL Tidak diterapkan pada tabel, di samping DENY SELECT Yang umum, DENY INSERT, DENY UPDATE, DENY DELETE Dan DENY REFERENCES.
    2. Jika pernyataan SELECT berisi fungsi bernilai tabel, pastikan ada EXECUTE AS OWNER Pada fungsi bernilai tabel atau GRANT EXECUTE Di atasnya (dan tidak ada DENY EXECUTE!). Jika ini masalahnya, baca pesan kesalahan lebih hati-hati karena sepertinya tidak akan mengatakan izin SELECT ditolak di atas meja, tetapi sebaliknya sesuatu tentang EXECUTE ditolak.
  2. Jika pengguna adalah pengguna atau grup AD, gunakan skrip berikut untuk menentukan pengguna login_token:

EXECUTE AS LOGIN = 'EXAMPLEDOMAIN\JOHN.DOE';
SELECT * FROM sys.login_token;
REVERT;
  1. Lihatlah rencana eksekusi yang sebenarnya. Jika kesalahan ada di dalam prosedur tersimpan dengan SET NOCOUNT ON;, Maka rencana eksekusi yang sebenarnya akan memberi Anda wawasan Anda mungkin tidak memperhatikan dengan hanya melihat tab Pesan di SSMS, karena "Baris yang terpengaruh" mungkin berada di luar Anda kontrol.

    1. Cari pemicu atau tabel temporal.
  2. Anda dapat mengkompilasi pernyataan sebagai prosedur tersimpan dan SSMS "Lihat Ketergantungan Objek", serta trik yang diuraikan oleh Svetlana Golovko di Cara Berbeda untuk menemukan Ketergantungan Objek SQL Server

  3. Gunakan acara Keamanan Profiler SQL Server "Acara Akses Objek Skema Audit" dan kolom "TextData" dan "Sukses" untuk melacak objek mana SQL Server sedang mengevaluasi izin. - Saya telah melihat situasi di mana ada dua baris yang dipancarkan untuk acara ini, dan satu nilai mengatakan Sukses = 1 dan yang lainnya mengatakan Sukses = 0. Dalam skenario ini, satu-satunya solusi yang saya temukan untuk berfungsi adalah me-reboot server. Bahkan menjalankan repadmin /syncall Tidak memperbaiki masalah, juga tidak memulai dan menghentikan aplikasi (dan karenanya kumpulan koneksi).

  4. Tentukan izin efektif untuk masuk:

-- '<domain>\<username>' is a domain user in the group you wish to test
EXECUTE AS LOGIN = '<domain>\<username>';
SELECT * FROM fn_my_permissions('Database.Schema.Table', 'OBJECT');
REVERT;
  1. Jika pengguna diikat ke pengguna atau grup AD, coba jalankan repadmin /syncall Untuk memaksakan setiap perubahan yang dibuat dalam Direktori Aktif untuk menyinkronkan seluruh pengontrol domain Anda. - Jika seseorang mengetahui cara yang baik untuk membandingkan nilai saat ini dari dua pengontrol domain, beri tahu saya.

  2. Sebelum mempertimbangkan untuk mem-boot ulang seluruh sistem, coba matikan semua koneksi yang aktif untuk pengguna tersebut. Alasannya adalah pengguna mendapatkan token windows mereka dari DC yang termasuk grup mereka. Token tidak akan diperbarui sampai pengguna mendapat token baru - biasanya dengan log off dan kemudian log on kembali .

  3. Hard reboot sistem. Ini berhasil untuk ku. Masih belum 100% yakin mengapa. HANYA LAKUKAN JIKA ANDA DAPAT MENYELAMATKAN WAKTU BAWAH! HATI-HATI TENTANG MELAKUKAN INI SAAT ANDA MEMILIKI TRANSAKSI YANG LUAR BIASA!

0
John Zabroski