Veritabanları arası sahiplik zinciri, veritabanı kullanıcılarının açıkça erişim izni verilmediği durumlarda, veritabanı kullanıcılarının aynı SQL Server örneğinde barındırılan diğer veritabanı nesnelerine erişmesine izin veren bir SQL Server güvenlik özelliğidir.
Veritabanları arası zincirleme olarak da bilinen veritabanları arası sahiplik zinciri, SQL Server’ın veritabanı kullanıcılarının şu anda kullanmakta oldukları veritabanlarının yanı sıra diğer veritabanlarına erişmesine olanak tanıyan bir güvenlik özelliğidir. Veritabanları arası, sahiplik zincirinin bir uzantısıdır ve aynı işlemi veritabanları arasında yapar. Sahiplik zinciri, SQL Server’da bir nesne üzerinde izinler ayarlayarak birden çok nesneye erişimin yönetilmesini sağlayan bir güvenlik özelliğidir. Veritabanları arası zincirlemede SQL Server, veritabanları arasında veya SQL Server’ın bir örneğindeki tüm veritabanlarında aynı şeye izin verecek şekilde yapılandırılabilir.
Veritabanları arası zincirlemeyi sunucu ve veritabanı düzeyinde açmak mümkündür.
ALTER DATABASE [MY_DATABASE_NAME] SET DB_CHAINING ON
Elimizde birden fazla veritabanı varsa onlardada bu özelliği aktif edebiliriz.
Sunucu düzeyinde açarsanız, tek tek veritabanı ayarlarından bağımsız olarak bu sunucudaki tüm veritabanları için veritabanları arası zincirleme etkinleştirilir.
Veritabanları arası zincirlemeyi sunucu ve veritabanı düzeyinde açmak mümkündür. Veritabanları arası sahiplik zinciri, sunucu düzeyinde kapalı olarak önceden ayarlanmıştır ve ayrıca master, msdb ve tempdb veritabanları dışındaki tüm veritabanlarında kapalı olarak ayarlanır. Bu sistem veritabanlarının düzgün çalışması için veritabanları arası sahiplik zincirinin açık olması gerekir.
Güvenlik nedenleriyle, veritabanları arası sahiplik zinciri genellikle sunucu düzeyinde açılmamalıdır. Aynı şekilde, zincirleme yalnızca genel bir kural olarak bunu gerektiren belirli veritabanları için açılmalıdır.
Bir View, yalnızca kendi veritabanındaki tablolara erişiyorsa, kullanıcıya yalnızca View üzerinde SELECT yetkisi verilmesi yeterlidir. Kullanıcı, ilgili tablolara doğrudan yetki almadan View üzerinden sorgu çalıştırabilir. Kendi veritabanı üzerinde oluşturduğu veya kendi veritabanı üzerinde bulunan tablolardaki şema yapısına takılmaz select çekilebilmektedir. Aşağıdaki resim B veritabanında bulunan tablo

B veritabanı altında oluşturulan viewler dikkat ederseniz dbo.ProductView – ProductSchema.ProductsView yukarıdaki resimde dikkat ederseniz schema ismi viewlerle aynı veya farklı.

Farklı bir kullanıcı oluşturup viewlerin bulunduğu Veritabanına public yetkisi verildikten sonra ilgili viewlere sağ tıklayıp properties ekranında permission bölümünde kullanıcı seçilip viewlere select yetkisi verilir. Sonuç olarak kullanıcıya tablo üzerinde yetki vermeden sadece viewe yetki vererek sonuçlarımızı görebiliriz. Bu işlem oluşturulan viewin içerisinde farklı bir veritabanına ait olmayan tablolarda geçerli bir işlemdir.


Sonuç olarak yukarıdaki açıklamalardan anladığımız aynı veritabanı tabanı üzerinde schema yapısı fark etmeksizin bir view oluşturup kullanıcıya yetki verildikten sonra select çektiğinde herhangi bir sıkıntı ile karşılaşmamış olur. Tabloya yetki verilmez son kullanıcı view içerisinde tabloları görmemiş olur.
Ancak View’in içinde başka bir veritabanındaki tablolar kullanılıyorsa, kullanıcının bu tablolara doğrudan erişim yetkisi olması gerekir. Aksi takdirde “The SELECT permission was denied on the object” veya “Could not find server” gibi bir yetki hatası alınır. Bunun sebebi, SQL Server’ın farklı veritabanları arasındaki güvenlik politikasıdır. Aşağıdaki hatayı alabilmemiz için öncelikle Select çeken kullanıcının view’in bağlantı sağladığı veritabanında public yetkisinin olması gerekmektedir. Yoksa aşağıdaki hata mesajı alınmaktadır.
The server principal “B1” is not able to access the database “A” under the current security context.
İlgili veritabanına public yetkisi verilince hata mesajı aşağıdaki şekilde gelmektedir.
Msg 229, Level 14, State 5, Line 2
The SELECT permission was denied on the object ‘Table_1’, database ‘A’, schema ‘dbo’.
Kullanıcı farklı veritabanındaki view veya tablodan verileri alabilmesi için A veritabanına public yetkisi daha sonra yetki verilen veritabanından hangi tablo veya viewden yetki veri alınacaksa ilgili ifadelere yetki verilir. Buda şu soruna sebep olur. Kullanıcı view haricinde view’in verileri almış olduğu veritabanı altında tablo veya viewıda görebilir. Buda tüm tabloya veya view’e erişmesi demektir. Resimde dikkat ederseniz viewın verileri almış olduğu veritabanı altında tabloda görülmektedir.

Not: Oluşturulan view’e son kullanıcının sorun yaşamaması için view ve tablo schema isimleri farklı olabilir sadece schema ownerlarının aynı olması gerekmektedir. İlgili veritabanının security sekmesi altında Schema owner aynı kullanıcı olması gerekmektedir.

Yukarıdaki sorundan dolayı db_chaining yapısı kullanılmaktadır. Yada kullanıcı view üzerinden direkt olarak tabloya değil de tablodan çekilecek kolanlar üzerinden bir view oluşturup bu view’e yeki verilebilir.
NOT: DROP, DELETE, INSERT, UPDATE gibi komutlar view tanımının içinde kullanılamaz. Eğer tabloyu silmek istiyorsan bu işlemi doğrudan yapman gerekir, view üzerinden dolaylı yoldan bu mümkün değil.
Server Seviyesinde de bu özellik aktif hale getirilebilir. Ama yukarıda bahsettiğim güvenlik sebebiyle bu özelliği aktif hale getirmemenizde fayda var. Yine de bazı durumlarda ihtiyaç olabileceğini düşünerek aşağıda script’ini paylaşıyorum.
USE master;
GO
EXECUTE sp_configure 'show advanced', 1;
RECONFIGURE;
EXECUTE sp_configure 'cross db ownership chaining', 1;
RECONFIGURE;
SELECT is_db_chaining_on, name FROM sys.databases;

Bu komut ile ownership Chains komutunun aktif edilip edilmediğini görebiliriz.
A ve B veritabanımda DB_CHAINING özelliğini aktif ediyorum.
ALTER DATABASE A SET DB_CHAINING ON
ALTER DATABASE B SET DB_CHAINING ON

Daha sonra B veritabanı altında A veritabanındaki tabloya bağlı olan view’e select çekiyorum.

Başarılı bir şekilde sonucumuz geldi. Resimde dikkat ederseniz A veritabanı altında tablo görülmemektedir. Veritabanları üzerinde kullanıcıya tablo veya view üzerinden yetki vermeden DB_CHAINING özelliğini aktif ederek tablodan verilerimizin son kullanıcının başka veritabanıdaki tabloları görmiyecek şekilde çekmiş oluyoruz.
Dikkat edersek A veritabanındaki tabloya select çekmemize rağmen tabloyu göremedik.

Tekrardan bu özelliği kapatmak isterseniz aşağıdaki komutlar kullanılmaktadır.
ALTER DATABASE A SET DB_CHAINING OFF
ALTER DATABASE B SET DB_CHAINING OFF
Tekrar bu özelliği kapattıktan sonra ilgili view’e select çektiğimizde hata mesajını almış oluyoruz.

Başka bir makalede görüşmek dileğiyle..
“Kıyamet saati hakkındaki bilgi yalnız Allah’ın katındadır; O, yağmuru yağdırmakta; rahimlerdekini bilmektedir. Hiç kimse yarın ne elde edeceğini bilemez; hiç kimse nerede öleceğini bilemez; ama Allah her şeyi bilir, her şeyden haberdardır.”Lokman-34