Yetkilendirme Hataları: Windows Server’da Access Denied Sorunlarını Giderme
Bir sabah erken saatte telefonun çalmaya başlıyor. Kullanıcılar dosyalara erişemiyor, uygulama servisler çalışmıyor, ekip panik halinde. “Access Denied” hatası her yerde. Bu senaryo, Windows Server yöneticilerinin kâbusu haline gelebilir. Ama şunu söyleyeyim: bu hataların büyük çoğunluğu sistematik bir yaklaşımla çözülür. Paniklemeden, adım adım gidecek olursak her şeyin bir mantığı var.
Access Denied Hataları Neden Olur?
Windows Server ortamında “Access Denied” hatası aslında birden fazla katmanda oluşabilir. Sorunu doğru çözmek için önce hangi katmanda takıldığınızı anlamanız gerekiyor.
- NTFS İzinleri: Dosya sistemi seviyesindeki izinler. En yaygın sorun kaynağı.
- Paylaşım İzinleri (Share Permissions): Network üzerinden erişimde devreye giren izinler.
- Active Directory ve Grup Politikaları: Kullanıcı haklarını merkezi olarak kontrol eden yapılar.
- UAC (User Account Control): Yerel yönetici hesaplarında beklenmedik erişim sorunları yaratabilir.
- Token Boyut Sorunu: Çok fazla grup üyeliği olan kullanıcılarda Kerberos token boyutu limitine ulaşılması.
- Servis Hesapları: Yanlış yapılandırılmış servis hesaplarının izin eksiklikleri.
- Registry İzinleri: Uygulama sorunlarında sıkça atlanan bir alan.
Temel Araçlar: Nereden Başlamalısınız?
Hata ayıklamaya başlamadan önce elimizin altında bulunması gereken araçları tanıyalım.
icacls Komutu
Windows’un yerleşik NTFS izin yönetim aracıdır. Hem okuma hem de yazma işlemleri için kullanılır.
# Bir klasörün mevcut izinlerini görüntüleme
icacls "C:ProjeKlasoru"
# Belirli bir kullanıcıya tam kontrol verme
icacls "C:ProjeKlasoru" /grant "DOMAINkullanici:(F)"
# Alt klasörlere ve dosyalara kalıtımsal izin verme
icacls "C:ProjeKlasoru" /grant "DOMAINkullanici:(OI)(CI)F"
# Belirli bir kullanıcının iznini kaldırma
icacls "C:ProjeKlasoru" /remove "DOMAINkullanici"
# Kırık kalıtımı tamir etme, izinleri üst klasörden yeniden miras alma
icacls "C:ProjeKlasoru" /reset /T
Buradaki parametre açıklamaları:
- (F): Full Control, tam kontrol
- (M): Modify, değiştirme hakkı
- (R): Read, sadece okuma
- (W): Write, yazma hakkı
- (OI): Object Inherit, dosyalara kalıtım
- (CI): Container Inherit, alt klasörlere kalıtım
- /T: Tüm alt dizin ve dosyalara uygula
- /reset: Kalıtımsal izinleri sıfırla
whoami Komutu
Hangi kullanıcı ve grup bağlamında çalıştığınızı anlamak için olmazsa olmaz.
# Mevcut kullanıcı bilgileri
whoami
# Kullanıcının tüm grup üyeliklerini ve ayrıcalıklarını listele
whoami /all
# Sadece grup bilgisi
whoami /groups
# Kullanıcı ayrıcalıklarını listele
whoami /priv
Özellikle whoami /all komutu altın değerindedir. Token’daki tüm grupları ve hakları gösterir. Eğer bir kullanıcı bir gruba eklenmiş ama erişim hâlâ yoksa, log off / log on yapmadan token yenilenmez bunu unutmayın.
Senaryo 1: Paylaşım Klasörüne Erişilemiyor
En klasik senaryo budur. Kullanıcı \sunucupaylasim adresine erişmeye çalışıyor ama “Access Denied” alıyor.
İlk kontrol noktası: Share Permission ve NTFS Permission ayrımı. İkisi de “Allow” olmak zorundadır. Ancak efektif izin, bu ikisinin kesişim kümesidir. Share Permission “Read” ise NTFS “Full Control” verse bile kullanıcı sadece okuyabilir.
# PowerShell ile paylaşım izinlerini görüntüleme
Get-SmbShareAccess -Name "PaylaşımAdı"
# Paylaşım iznini güncelleme
Grant-SmbShareAccess -Name "PaylaşımAdı" -AccountName "DOMAINkullanici" -AccessRight Full -Force
# Net share komutuyla mevcut paylaşımları listeleme
net share
# Paylaşım detaylarını görme
net share PaylaşımAdı
Bir kullanıcı sorununu çözerken şöyle bir kontrol listesi izlerim:
- Share Permission’da kullanıcı veya grubu “Allow” ile ekle
- NTFS izinlerinde ilgili klasörde kullanıcı veya gruba gerekli izni ver
- Kullanıcının gerçekten o gruba üye olduğunu AD’de doğrula
gpupdate /forceile politikaları yenile- Kullanıcının yeniden oturum açmasını iste
Senaryo 2: Servis Hesabı “Access Denied” Alıyor
Bir uygulama servisi çalışmıyor, Event Log’da “Access Denied” hataları var. Bu durumda servis hesabının hangi bağlamda çalıştığı kritik önem taşır.
# Servis hesabını ve çalışma bağlamını kontrol etme
sc qc "ServisAdi"
# Servisin çalıştığı hesabı değiştirme
sc config "ServisAdi" obj= "DOMAINservisHesabi" password= "Sifre123!"
# Servis hesabına gerekli log on as a service hakkı verme
# Bu kısım için secedit veya Group Policy kullanılır
secedit /export /cfg C:tempsecpol.cfg
Servis hesabı sorunlarında sıkça gördüğüm durumlar:
- “Log on as a service” hakkı eksik: Local Security Policy üzerinden
secpol.mscaçıp “User Rights Assignment” kısmından bu hak verilmeli. - Şifre değişti ama servis güncellenmedi: Servis hesabı şifre değiştiğinde her servis manuel güncellenmeli.
- Managed Service Account (gMSA) yanlış yapılandırması: gMSA kullanıyorsanız bilgisayar hesabının Principal izni aldığından emin olun.
# gMSA hesabının doğru yapılandırıldığını test etme
Test-ADServiceAccount -Identity "gMSAHesabi$"
# Bilgisayara gMSA kullanım yetkisi verme
Set-ADServiceAccount -Identity "gMSAHesabi" -PrincipalsAllowedToRetrieveManagedPassword "SunucuAdi$"
Senaryo 3: Kerberos Token Boyut Sorunu
Bu sorun, kurumsal ortamlarda oldukça sinsi bir şekilde ortaya çıkar. Kullanıcı çok fazla güvenlik grubuna eklenmiş, Kerberos token boyutu MaxTokenSize sınırını aşmış ve bazı kaynaklara erişim kesilmiş durumda.
Belirtileri: Kullanıcı bazı sunuculara erişebilir, bazılarına erişemez. Oturum açıldıktan sonra sorun yaşanır ama birkaç servise erişim normaldir.
# Kullanıcının grup sayısını kontrol etme
(Get-ADUser -Identity "kullanici" -Properties MemberOf).MemberOf.Count
# Kullanıcının tüm grup üyeliklerini recursive olarak sayma
$user = "kullanici"
$groups = Get-ADUser $user -Properties MemberOf | Select-Object -ExpandProperty MemberOf
$nestedGroups = $groups | ForEach-Object { Get-ADGroup $_ -Properties MemberOf }
Write-Host "Toplam grup sayisi: $($groups.Count)"
MaxTokenSize varsayılan değeri eski sistemlerde 12000 byte, Windows 2012 R2 ve sonrasında 48000 byte’tır. Eğer kullanıcı 1015’ten fazla gruba üyeyse ciddi sorun yaşanır.
Çözüm yolları:
- Kullanıcıyı gereksiz gruplardan çıkar
- Registry’den MaxTokenSize değerini artır (geçici çözüm)
- Claim-based authorization’a geçiş düşünülebilir
# MaxTokenSize registry değerini artırma (tüm etkilenen sunucularda yapılmalı)
# HKLMSYSTEMCurrentControlSetControlLsaKerberosParameters
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlLsaKerberosParameters" `
-Name "MaxTokenSize" -Value 65535 -Type DWord
Event Log Analizi: Kanıtları Takip Edin
“Access Denied” sorunlarını çözerken Event Viewer en güvenilir dostunuzdur. Nereye bakacağınızı bilirseniz işler hızlanır.
Security Log (Güvenlik Günlüğü): Event ID 4625 başarısız oturum açma denemelerini, Event ID 4656 nesneye erişim denemelerini, Event ID 5145 paylaşım erişim denemelerini kaydeder.
Application Log: Uygulama tabanlı erişim hatalarını içerir.
# PowerShell ile son 50 başarısız erişim olayını çekme
Get-WinEvent -LogName Security -FilterXPath `
"*[System[EventID=4625]]" -MaxEvents 50 | `
Select-Object TimeCreated, Message | Format-List
# Belirli bir kullanıcıya ait güvenlik olaylarını filtreleme
Get-WinEvent -LogName Security | Where-Object {
$_.Message -like "*KullaniciAdi*" -and $_.Id -eq 4625
} | Select-Object TimeCreated, Message | Format-List
# Nesne erişim denetimleri için
Get-WinEvent -LogName Security -FilterXPath `
"*[System[EventID=4656 or EventID=4663]]" -MaxEvents 100
Event ID 4625 geldiğinde Failure Reason alanına dikkat edin:
- 0xC000006D: Yanlış kullanıcı adı veya şifre
- 0xC0000064: Kullanıcı hesabı bulunamadı
- 0xC000006E: Hesap kısıtlaması
- 0xC0000070: Geçersiz iş istasyonu kısıtlaması
- 0xC000015B: Log on type izni yok
Registry İzin Sorunları
Uygulama yüklemelerinde veya konfigürasyon değişikliklerinde “Access Denied” alıyorsanız sorun registry’de olabilir. Bu alan çok sık atlanır.
# PowerShell ile registry izinlerini görüntüleme
$acl = Get-Acl "HKLM:SOFTWAREUygulamaAdi"
$acl.Access | Format-List
# Registry anahtarına izin ekleme
$acl = Get-Acl "HKLM:SOFTWAREUygulamaAdi"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(
"DOMAINkullanici",
"FullControl",
"ContainerInherit,ObjectInherit",
"None",
"Allow"
)
$acl.SetAccessRule($rule)
Set-Acl -Path "HKLM:SOFTWAREUygulamaAdi" -AclObject $acl
Registry izin sorunlarını tespit etmek için Process Monitor (ProcMon) aracı olmadan olmaz. Sysinternals suite içindeki bu araç, hangi registry key’e veya dosyaya erişilmeye çalışıldığını ve hangi hesapla reddedildiğini net olarak gösterir.
ProcMon kullanırken filtre ayarı kritik önem taşır:
- Process Name filtresiyle sadece sorunlu uygulamayı izle
- Result filtresine “ACCESS DENIED” ekle
- Path filtrelemesiyle gürültüyü azalt
Grup Politikası Kaynaklı Sorunlar
Bazen izinler doğru görünür ama GPO bir şeyleri override ediyor olabilir.
# Uygulanan grup politikalarını görüntüleme
gpresult /R
# HTML formatında detaylı GPO raporu
gpresult /H C:tempGPOrapor.html
# Belirli bir kullanıcı için GPO analizi
gpresult /R /USER DOMAINkullanici
# Politikaları zorla yenile
gpupdate /force
# Sadece kullanıcı politikasını yenile
gpupdate /target:user /force
GPO sorunlarında sık karşılaştığım durumlar:
- Restricted Groups: GPO bir grubu “restricted” olarak tanımlamış, her GP uygulandığında izinler resetleniyor.
- Software Restriction Policies: Uygulamanın çalıştırılmasını engelleyen politikalar.
- User Rights Assignment çakışmaları: Birden fazla GPO aynı ayarı farklı değerlerle tanımlamış.
GPO çakışmalarını çözmek için RSOP (Resultant Set of Policy) konsolunu kullanın: rsop.msc
Dosya Sahipliği (Ownership) Sorunları
“Access Denied” alınan durumlarda bazen sorun izinlerde değil, dosya sahipliğindedir. Özellikle başka bir sunucudan taşınan veya kopyalanan dosyalarda bu sorun yaşanır.
# Bir dosyanın sahibini görme
icacls "C:dosya.txt" | Select-String "Owner"
# PowerShell ile sahiplik bilgisini alma
(Get-Acl "C:ProjeKlasoru").Owner
# Sahipliği mevcut kullanıcıya alma (takeown)
takeown /F "C:ProjeKlasoru" /R /D Y
# Sahipliği belirli bir kullanıcıya verme
$acl = Get-Acl "C:ProjeKlasoru"
$owner = New-Object System.Security.Principal.NTAccount("DOMAINkullanici")
$acl.SetOwner($owner)
Set-Acl -Path "C:ProjeKlasoru" -AclObject $acl
takeown komutunun parametreleri:
- /F: Dosya veya klasör yolu
- /R: Recursive, alt dizinleri dahil et
- /D Y: Onay istemeden kabul et
Sahipliği aldıktan sonra icacls ile gerekli izinleri tekrar set etmeyi unutmayın.
UAC ve Yerel Yönetici Hesapları
Yerel makinede yönetici olan bir kullanıcı hâlâ “Access Denied” alıyorsa UAC devreye girmiş olabilir. Yerel yöneticiler bile UAC ile sınırlandırılmış token alır.
# Komut satırını yönetici olarak açmak için (runas)
runas /user:Administrator cmd
# UAC'yi bypass ederek bir işlem başlatma
Start-Process powershell -Verb RunAs
# Yükseltilmiş komut istemiyle servisi yeniden başlatma
Start-Process cmd -ArgumentList "/c net stop ServisAdi && net start ServisAdi" -Verb RunAs
Domain ortamında local admin hesabına dikkat: Domain Controller’ın local security policy’si veya domain GPO’su, lokal admin hesaplarının network üzerinden erişimini engelleyebilir. Bu durum özellikle LAPS (Local Administrator Password Solution) kullanılan ortamlarda yaygındır.
Etkili Izin Testi: Effective Access Özelliği
Windows, bir kullanıcının bir kaynağa gerçekte ne kadar erişiminin olduğunu test etmenin kolay yolunu sunar.
Dosya veya klasöre sağ tıklayın, Properties > Security > Advanced > Effective Access sekmesine gidin. Buradan bir kullanıcı veya grup seçerek gerçek efektif izni görebilirsiniz. Bu özellik hem NTFS hem de share permission’ları birlikte hesaplar.
PowerShell ile de bunu yapmak mümkündür:
# Kullanıcının efektif izinlerini PowerShell ile kontrol etme
$path = "C:ProjeKlasoru"
$user = "DOMAINkullanici"
$acl = Get-Acl $path
$identity = New-Object System.Security.Principal.NTAccount($user)
$sid = $identity.Translate([System.Security.Principal.SecurityIdentifier])
$acl.Access | Where-Object {
$_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value -eq $sid.Value
} | Select-Object IdentityReference, FileSystemRights, AccessControlType
Kalıtım Sorunu ve Kırık İzin Zinciri
Bir klasörde izin kırıksa yani “inheritance disabled” durumu varsa, üst klasörden gelen izinler o klasöre yansımaz. Bu durum özellikle izin yönetimi otomasyonunun çalıştığı ortamlarda beklenmedik “Access Denied” sorunlarına yol açar.
# Belirli bir yoldaki tüm kırık kalıtımları tespit etme
Get-ChildItem "C:ProjeKlasoru" -Recurse | ForEach-Object {
$acl = Get-Acl $_.FullName
if ($acl.AreAccessRulesProtected) {
Write-Host "Kirık kalıtım: $($_.FullName)"
}
}
# Kalıtımı yeniden aktif hale getirme
$acl = Get-Acl "C:ProjeKlasoruAltKlasor"
$acl.SetAccessRuleProtection($false, $true)
Set-Acl -Path "C:ProjeKlasoruAltKlasor" -AclObject $acl
# icacls ile toplu kalıtım resetleme
icacls "C:ProjeKlasoru" /reset /T /C
/C parametresi hata oluştuğunda devam etmesini sağlar, büyük dizin yapılarında işe yarar.
Sık Yapılan Hatalar ve Tuzaklar
Yıllar içinde gördüğüm en yaygın hatalar şunlar:
- “Everyone” grubunu kaldırmak: Share Permission’dan Everyone’ı kaldırırken Authenticated Users grubunu eklemeden yapılan değişiklikler tüm erişimi keser.
- Deny iznini gereksiz kullanmak: Deny her zaman Allow’u geçersiz kılar. Eğer bir kullanıcı hem Allow hem Deny alan iki gruba üyeyse Deny kazanır.
- Sadece NTFS veya sadece Share iznine bakmak: Her ikisinin de doğru olması gerekir.
- Oturum yenilemeden test etmek: Token tabanlı izin değişikliklerinin etkili olması için kullanıcının yeniden giriş yapması şarttır.
- Audit politikası olmadan troubleshoot yapmak: Object Access Audit aktif değilse Security Log’da erişim izleme verisi olmaz.
Audit politikasını aktif etmek:
# Nesne erişim denetimini aktif etme
auditpol /set /subcategory:"File System" /success:enable /failure:enable
auditpol /set /subcategory:"Handle Manipulation" /success:enable /failure:enable
# Mevcut audit politikasını görüntüleme
auditpol /get /category:*
Sonuç
“Access Denied” hataları ilk bakışta kaotik görünse de her birinin arkasında sistematik bir neden vardır. Sorun giderirken önce hangi katmanda takıldığınızı belirleyin: NTFS mi, Share mi, GPO mu, token sorunu mu? Ardından doğru araçla o katmanı inceleyin.
Event Log’u ihmal etmeyin. Çoğu zaman cevap orada yazar, sadece bakmak gerekir. ProcMon ise görünmez sorunları görünür kılan bir araçtır, Sysinternals suite’ini her zaman yanınızda bulundurun.
Uzun vadeli çözüm için yetkilendirme yapısını mümkün olduğunca grup tabanlı tutun. Kullanıcılara tek tek izin vermek yerine gruplara izin verin, kullanıcıları gruplara ekleyin. Bu yaklaşım hem yönetilebilirlik hem de sorun giderme açısından hayatınızı büyük ölçüde kolaylaştırır. Ve son olarak, her kritik değişiklikten önce mevcut izin yapısını icacls /save ile yedekleyin. Geri dönüş noktanız olsun.
