"Nesne üzerinde SELECT izni reddedildi" ifadesi almasına rağmen


11

Ben bir programcıyım, dba değil ... Tehlikeli olmaya yetecek kadar biliyorum.

Ben veritabanı için bir db_owner olan eski bir kullanıcı ile bir veritabanını miras. Bu kullanıcının mevcut tablolar, şemalar, vb. İçin ticari nedenlerle iznini ayarlayamayız, ancak bazı yeni tablolar oluşturuluyor ve bu kullanıcının yalnızca bunlarda SELECT erişimine sahip olmasını istiyorum.

Bu tablolar için bu kullanıcı için izinler ayarlandı, böylece GRANT olarak ayarlanan SELECT hariç her şey DENIED.

Ancak bu kullanıcı (dbadmin) bu tablolardan birinde (AccountingAudit) bir SELECT gerçekleştirmeye çalıştığında, bu hata oluşur:

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

Bu tablo / kullanıcı için hangi izinlerin ayarlandığını görmek ve denemek için bu SQL çalıştırdım:

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

Ve işte geri döndüğüm şey:

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

Doğru çalışıyor olmalı gibi mi?

Yaptığım SELECT çağrısı, SSMS içinden çok temel bir SELECT * FROM AccountingAudit. Özel bir sp_executesql ya da bunun gibi bir şey yapmıyorum.

Açıkça izin vermeyi denedim:

GRANT SELECT ON [dbo].AccountingAudit TO dbadmin

Bunun bir etkisi yoktur (neden böyle olsun, yukarıdaki sorgu zaten verildiğini gösteriyor! ;-)

Stackoverflow.com ve başka bir yerde arama yaptım ve henüz denemediğim bir şey bulamıyorum. Şemaların nasıl kurulduğuyla ilgili bir şey olup olmadığını merak ediyorum. (Bu noktada şemalar hakkında çok az şey biliyorum.)

Herhangi bir fikir? Teşekkürler!

Yanıtlar:


10

Burada emin değilim, ama bir uzuv çıkacağım. Bence sorununuz DENY CONTROLkayıtlarınızda olabilir . Sayfanın yarısına kadar buraya bakın :

Bir veritabanındaki CONTROL izninin reddedilmesi, veritabanındaki CONNECT iznini dolaylı olarak reddeder. Veritabanında CONTROL iznine izin verilmeyen bir yönetici söz konusu veritabanına bağlanamaz.

Bu örneğin bir veritabanı için olduğunu anlıyorum, ancak bunu bir seviye daha ele alacağım. Bir DENY CONTROLmasadaki A , üzerindeki tüm ayrıcalıkları reddedecek , sanırım. Bundan REVOKE CONTROLkurtulmak için bunu yapın ve bunun sorununuzu çözüp çözmediğine bakın.

Öyleyse, kullanıcıyı bir veritabanı rolüne yerleştirmeniz veya tabloya karşı açık ayrıcalıkları reddetmeniz gerekir.


1
Teşekkür ederim! Başlangıçta denememde KONTROL reddedilmezse SEÇEBİLECEĞİNİ keşfettim. Ancak BOL okurken bunu yanlış bir şekilde yorumlamıştım, bu da kullanıcıya masa üzerinde tam kontrol sağladığım anlamına geliyordu. Şimdi görüyorum ki, onları kontrol etmediğim sürece, diğer izinleri (INSERT, DELETE, vb.) DENY düzeyinde tutabilirim ve istediğim izin seviyelerine ulaşabilirim. Teşekkürler!
Mason G.Zhwiti

Bu, sorunumu çözmeme rağmen en çok göz ardı edeceğimi hissettiğim, iptal ettiğim bir incelik. Ayrı olarak, Active Directory gruplarını kullandığınızda, grup üyeliğini değiştirdiyseniz, repadmin / syncall mutlaka sorunları gidermediğini ve sunucuyu yeniden başlatmanın sorunu çözdüğünü buldum. Yine de daha az balyoz yaklaşımı arıyor.
John Zabroski

0
  1. İzinlere sp_DBPermissionsbakmak için Ken Fisher'ın saklı yordamını kullanın.

    1. Yap emin DENY CONTROLortak yanı sıra, tabloya uygulanmaz DENY SELECT, DENY INSERT, DENY UPDATE, DENY DELETEve DENY REFERENCES.
    2. Eğer SELECTdeyim tablo değerli işlev içerir, emin ya bir orada yapmak EXECUTE AS OWNERtablo değerli işlev veya üzerinde GRANT EXECUTEüzerinde (ve hiçbir DENY EXECUTE!). Bu durumda, SELECT izninin masada reddedildiğini söylemeyeceği, ancak bunun yerine EXECUTE ile ilgili bir şeyin reddedildiğini söyleyemeyeceği için hata iletisini daha dikkatli okuyun.
  2. Kullanıcı bir AD kullanıcısı veya grubuysa, kullanıcı login_token(lar) ı belirlemek için aşağıdaki komut dosyasını kullanın :

EXECUTE AS LOGIN = 'EXAMPLEDOMAIN\JOHN.DOE';
SELECT * FROM sys.login_token;
REVERT;
  1. Gerçek yürütme planına bakın. Hata bir saklı yordamın içindeyse SET NOCOUNT ON;, gerçek yürütme planı size yalnızca SSMS'deki Mesajlar sekmesine bakarak dikkat etmeyebileceğiniz konusunda fikir verecektir, çünkü "Etkilenen satırlar" denetiminizin dışında olabilir.

    1. Tetikleyicileri veya geçici tabloları arayın.
  2. İfadeyi bir saklı yordam ve SSMS "Nesne Bağımlılıklarını Göster" olarak ve SQLlana Nesne Bağımlılıklarını bulmak için Svetlana Golovko tarafından Farklı yollarla özetlenen hileler olarak derleyebilirsiniz.

  3. SQL Server'ın izinleri değerlendirdiği nesneleri izlemek için SQL Server Profiler Güvenlik olayı "Denetim Şeması Nesne Erişim Olayı" ve "TextData" ve "Başarılı" sütunlarını kullanın. - Bu olay için iki satır yayılan durumları gördüm ve bir değerde Başarı = 1, diğerinde Başarı = 0 diyor. Bu senaryoda, bulduğum tek çözüm sunucuyu yeniden başlatmaktır. Çalışmak bile repadmin /syncallsorunu çözmedi, ne de uygulamayı (ve dolayısıyla bağlantı havuzunu) başlatmayı ve durdurmayı.

  4. Giriş için etkili izinleri belirleyin:

-- '<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. Kullanıcı bir AD kullanıcısına veya grubuna bağlıysa repadmin /syncall, etkin dizinde yapılan değişiklikleri etki alanı denetleyicileriniz arasında eşitlemeye zorlamak için çalıştırmayı düşünün . - Birisi iki etki alanı denetleyicisinin geçerli değerlerini karşılaştırmanın iyi bir yolunu biliyorsa, lütfen bana bildirin.

  2. Sistemin tamamının yeniden başlatılmasını düşünmeden önce, o kullanıcı için tüm etkin bağlantıları öldürmeyi deneyin. Bunun nedeni, kullanıcının kendi gruplarını içeren DC'den pencere belirtecini almasıdır. Jeton, kullanıcı yeni bir belirteç alana kadar (genellikle oturumu kapatıp tekrar açarak) güncellenmez.

  3. Sistemi sert bir şekilde yeniden başlatın. Bu benim için çalıştı. Hala neden% 100 emin değilim. SADECE AŞAĞI ZAMANI YAŞAYABİLİRSİNİZ! BÜYÜK İŞLEMLERİ BÜYÜK OLDUĞUNUZDA BU YAPMAK İÇİN DİKKATLİ OLUN!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.