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ğı.
Operasyonel Doğrulama & Güvenilirlik Standardı
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
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:
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ğı!)
SELECT SUSER_SNAME() AS server_login, USER_NAME() AS db_kullanici;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:
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:
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Şema Sahipleri Farklıysa: Prosedür
dboşemasında, içindeki tablomuhasebeşemasında ise zincir kırılır. SQL Server çağıran kullanıcının tablo yetkilerini denetler ve 229 fırlatır. - 2Dinamik SQL Kullanımı: Prosedür içinde
EXEC(@sql)veyasp_executesqlile 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:
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ü)
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:
REVOKE SELECT ON dbo.Musteri FROM raporlama_rolu;4. Canlıya Çıkmadan Kullanıcı Kimliğine Bürünerek Test Edin
EXECUTE AS USER = 'app_kullanici';
SELECT TOP 1 * FROM dbo.Musteri;
REVERT;▸İlgili Hata Rehberleri & Hub Bağlantıları
- •PostgreSQL Permission Denied for Table (H-34) — PostgreSQL tarafındaki karşılığı
- •SQL Server Cannot Open Database (H-15) — Veritabanı erişim kısıtlamaları
- •SQL Server Hub — Güvenlik mimarisi ve rol yönetimi
Diğer Veritabanı Hata Teşhisleri
Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.
SQL Server Error 18456: State Kodlarına Göre Gerçek Neden
18456 hatasında State numarası gerçek nedeni söyler. State 5, 8, 11, 18, 38 ve 40 için ayrı çözümler, ERRORLOG okuma komutları.
SQL Server Error 1205 Deadlock: Grafiği Bulma ve Önleme
SQL Server 1205 hatasında deadlock grafiğini system_health oturumundan çıkarma, kurban seçimini anlama ve kalıcı önleme yöntemleri.
SQL Server Pool Timeout: Bağlantı Havuzu Tükenmesi Çözümü
"Timeout expired prior to obtaining a connection from the pool" hatasının komut zaman aşımından farkı, sızıntı tespiti ve .NET tarafında kalıcı düzeltme.