dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Home/Hata Teşhis Kütüphanesi/sqlserver-229-permission-denied-select
SQL Server
SQL Server 2016–2022Güvenlik & Yetkilendirme
8 dk okuma
Msg 229, Level 14, State 5: The SELECT permission was denied on the object

SQL Server Msg 229 — Yetkiyi Kim Engelliyor?

229 hatasında etkin yetkiyi sys.fn_my_permissions ile görmek, DENY'ın GRANT'ı ezmesi, sahiplik zinciri ve guest kullanıcı tuzağı.

İnceleyen:Principal Database Reliability Architect
Test Edilen Sürümler: SQL Server 2022 CU15 & 2019 CU28 (Windows Server / RHEL 9 Docker)

Operasyonel Doğrulama & Güvenilirlik Standardı

Son Teknik İnceleme: 30 Ekim 2026
Test Edilen SürümlerSQL Server 2022 & 2019 (Docker 29.7, Windows Server 2022)
Gerekli YetkiCONTROL veya ALTER ANY ROLE / GRANT yetkisi (yetkileri düzenlemek için)
Risk Seviyesi
MediumDENY olan bir nesneye üstten GRANT vermek etki etmez; DENY tüm rolleri ezer
Beklenen Çıktısys.fn_my_permissions ile etkin yetkilerin doğrulanması, DENY önceliğinin ve guest kullanıcı tuzağının tespiti
Geri Dönüş (Rollback) Planı:REVOKE ile engelleyen DENY kaydını temizleyip rol tabanlı şema GRANT yapısı kurgulama
Microsoft Docs: Database Engine Permissions & Ownership Chaining
İlk 60 Saniye Teşhis Protokolü:

Hata mesajı semptomdur, kök neden değildir. Sunucuyu yeniden başlatmadan veya rastgele ayar değiştirmeden önce aşağıdaki "Nedeni ayırt eden tek sorgu"yu çalıştırarak gerçek senaryoyu netleştirin.

▸Belirti

plaintext
Msg 229, Level 14, State 5, Line 1 The SELECT permission was denied on the object 'Musteri', database 'app', schema 'dbo'.

Hatanın ilk cümlesi hedeflenen nesne türüne ve eyleme göre değişir:

plaintext
The EXECUTE permission was denied on the object 'sp_Rapor', database 'app', schema 'dbo'. The INSERT permission was denied on the object 'Musteri', database 'app', schema 'dbo'. The SELECT permission was denied on the column 'TCKimlik', database 'app', schema 'dbo'.

Bu hata, PostgreSQL'deki permission denied for table hatasının SQL Server karşılığıdır (H-34). Ancak SQL Server'da yetkilendirme mimarisi Rol Zinciri + DENY Önceliği + Sahiplik Zinciri (Ownership Chaining) olmak üzere üç katmandan oluşur ve hata metni bu katmanların hangisinde takıldığınızı söylemez.


▸Nedenini Doğrulayan Teşhis Sorguları

1. Gerçekten Kim Olarak Bağlandınız? (Guest Tuzağı!)

sql
SELECT SUSER_SNAME() AS server_login, USER_NAME() AS db_kullanici;
ÖNEMLİ
Guest Kullanıcı Tuzağı: Eğer db_kullanici sütununda guest görüyorsanız, sunucu oturumunuz (login) mevcuttur ancak hedef veritabanında bu oturuma eşlenmiş bir USER tanımlanmamıştır! SQL Server bağlantıyı reddetmek yerine oturumu guest kullanıcısına düşürür; uygulamanız da guest'in kısıtlı yetkileriyle çalışıp anında Msg 229 alır. Bu durum, hatanın en sık atlanan nedenidir.

2. Etkin Yetkileri Tek Adımda Doğrulayın

Rolleri tek tek çözmek yerine SQL Server'a fiili yetkinizi sorun:

sql
SELECT * FROM sys.fn_my_permissions('dbo.Musteri', 'OBJECT');

Liste boşsa yetkiniz yoktur; doluysa ama hala hata alıyorsanız yanlış veritabanına veya şemaya bakıyorsunuzdur.

3. Engelleyen Bir DENY Var mı?

SQL Server güvenlik modelinde altın kural: DENY HER ZAMAN GRANT'I EZER. Bir kullanıcıya 10 farklı rol üzerinden GRANT SELECT verilmiş olsa bile, üye olduğu tek bir grupta DENY SELECT varsa sonuç her zaman Msg 229'dur:

sql
SELECT prin.name AS principal, perm.permission_name, perm.state_desc FROM sys.database_permissions perm JOIN sys.database_principals prin ON prin.principal_id = perm.grantee_principal_id WHERE perm.major_id = OBJECT_ID('dbo.Musteri') AND perm.state_desc = 'DENY';

▸Sahiplik Zinciri (Ownership Chaining): Prosedür Çalışıyor Ama Tablo 229 Veriyor!

En kafa karıştırıcı senaryo: Bir kullanıcının sp_Rapor stored procedure'ü üzerinde EXECUTE yetkisi vardır. Prosedür çalışır, ancak içindeki bir tabloya ulaştığında Msg 229 fırlar.

Sahiplik Zinciri Nasıl Çalışır? Bir nesne (Stored Procedure) başka bir nesneye (Tablo) eriştiğinde, her iki nesnenin şema sahibi aynıysa (dbo), SQL Server aradaki tablo düzeyindeki izin kontrollerini atlar. Kullanıcıya tablo üzerinde doğrudan SELECT vermenize gerek kalmaz.

Zincir Ne Zaman Kırılır?

  1. 1Şema Sahipleri Farklıysa: Prosedür dbo şemasında, içindeki tablo muhasebe şemasında ise zincir kırılır. SQL Server çağıran kullanıcının tablo yetkilerini denetler ve 229 fırlatır.
  2. 2Dinamik SQL Kullanımı: Prosedür içinde EXEC(@sql) veya sp_executesql ile dinamik SQL çalıştırılıyorsa, sorgu prosedür sahibinin değil çağıran kullanıcının kimliğiyle yürütülür. Sahiplik zinciri tamamen geçersiz kalır!

▸Adım Adım Kalıcı Çözüm

1. Şema Düzeyinde Rol Bazlı Yetkilendirme

Tek tek nesnelere yetki vermek yerine şema düzeyinde rol oluşturun:

sql
CREATE ROLE app_okuyucu; GRANT SELECT ON SCHEMA::dbo TO app_okuyucu; ALTER ROLE app_okuyucu ADD MEMBER app_kullanici;

2. Eksik Veritabanı Kullanıcısını Eşleyin (Guest Çözümü)

sql
USE app; CREATE USER app_kullanici FOR LOGIN app_kullanici; ALTER ROLE app_okuyucu ADD MEMBER app_kullanici;

3. Çakışan DENY Kaydını Temizleyin

DENY olan bir nesneye üstten GRANT vermek işe yaramaz; DENY kaldırılmalıdır:

sql
REVOKE SELECT ON dbo.Musteri FROM raporlama_rolu;

4. Canlıya Çıkmadan Kullanıcı Kimliğine Bürünerek Test Edin

sql
EXECUTE AS USER = 'app_kullanici'; SELECT TOP 1 * FROM dbo.Musteri; REVERT;

▸İlgili Hata Rehberleri & Hub Bağlantıları

Diğer Veritabanı Hata Teşhisleri

Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.

Tüm Hatalar (50)