Zrovna jsem narazil na pěkný a poučný problémeček s ApplicationPoolIdentity (AppPoolIdentity) v IIS 7 a novějších. Jak možná víte, už jsem o tom něco tuhle psal. Jde o to, že IIS umí spouštět aplikační pooly pod jejich vlastní identitou.
Například - máte app pool s názvem Fakturace-Sklady. Místo, abyste tak pro něho vytvářeli vlastní uživatelský účet, prostě ho necháte běžet pod ApplicationPoolIdentity. A on jeho W3WP proces potom běží pod účtem IIS APPPOOL\Fakturace-Sklady. To je paráda. Uživatelské účty jednotlivých aplikačních poolů jsou lokálně vzájemě izolované. A přitom se chovají do sítě jako Network Service.
Takže jsem chtěl adresář se soubory takové aplikace zpřístupnit jen tomu uživateli IIS APPPOOL. Prostě na NTFS nastavit oprávnění jen pro tohoto uživatele. Skriptem v PowerShellu. Vytvořil jsem si nový aplication pool pomocí příkazu APPCMD a rovnou chtěl vytvořit aplikaci a zabezpečit pomocí ICACLS:
appcmd add apppool /name:"Fakturace-Sklady"
icacls F:\WEB-Data\FASK /Grant "IIS APPPOOL\Fakturace-Sklady:RX"
Jenže ouha. Chyba:
Error: No mapping between account names and security IDs was done
Zkusil jsem tedy vyvořit ten application pool přes normální IIS konzoli a potom použít ICACLS a všechno jelo v pohodě. Dobrá, zkusil jsem tedy použít .NET Framework knihovnu System.Security a PowerShell Get-Acl:
appcmd add apppool /name:"Fakturace-Sklady"
$acl = Get-Acl F:\WEB-Data\FASK
$acl.SetAccessRuleProtection($true, $false)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ('IIS APPPOOL\Fakturace-Sklady', 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
$acl.AddAccessRule($accessRule)
Set-Acl -Path F:\WEB-Data\FASK -AclObject $acl
A zase ouha, podobná chyba:
Error: Exception calling "AddAccessRule" with 1 orgument: Some or all identity references could not be translated
Zkoušel jsem použít i iisreset, ale stejně to nepomohlo.
Takže co je za problém?
Po menžím pátrání jsem zjistil, že mapování mezi SIDy (s prefixem S-1-5-82) a jmény těch application poolů dělá ve skutečnosti služba Application Host Helper Service (AppHostSvc). Dokonce to má v popisku:
Provides administrative services for IIS, for example configuration history and Application Pool account mapping. If this service is stopped, configuration history and locking down files or directoris with Application Pool specific Access Control Entries (ACL/ACEs) will not work
Takže stačilo jenom tuto službu restartovat hned po přidání nového application pool. Je zajímavé, že iisreset na to nepomáhá. Ten zřejmě netuší, že i tato služba je součástí IIS a nerestartuje ji.
Restart-Service apphostsvc
nebo
NET STOP apphostsvc & NET START apphostsvc