I have a somewhat unusual situation.
I am dealing with IIS 7.5 installed on a Windows Server 2008 R2 Domain Controller machine.
I am trying to write a C# program that installs my web application on that IIS. Everything works OK, except the moment when I need to assign access permissions for the Application Pool to the folder where the web app is installed.
After having done some research I found that I need to assign access for the following user account:
IIS AppPool\\[AppPoolName]
So I came up with this code:
setFolderPermissions(@"C:\inetpub\www_test1",
@"IIS AppPool\" + strAppPoolName,
System.Security.AccessControl.FileSystemRights.Read | System.Security.AccessControl.FileSystemRights.ListDirectory,
System.Security.AccessControl.AccessControlType.Allow);
public static string setFolderPermissions(string strFolderPath, string sUserName, FileSystemRights rights, AccessControlType access)
{
DirectoryInfo info = new DirectoryInfo(strFolderPath);
DirectorySecurity ds = info.GetAccessControl();
ds.AddAccessRule(new FileSystemAccessRule(sUserName,
rights,
InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
PropagationFlags.None,
access));
info.SetAccessControl(ds);
}
The method above works except when it is useed on a Domain Controller. It throws this exception:
Some or all identity references could not be translated.
And the only way how I can assign those required permissions is by doing this manually from a command line:
C:\Users\Administrator>icacls "C:\inetpub\www_test1" /grant "IIS AppPool\MyAppsoolName":(CI)(OI)(M)
Any idea how to do this icacls
stuff with C#?
Better, create your own application pool that runs using the given credential. And the assign the permissions for the given credential (user name) on the web application installed folder.
You shouldn't be running IIS on domain controller as advised my Microsoft as this may cause issues with security and permissions.
If you really want to do this you should use domain account to run application pool, not integrated IIS Apppool. This doesn't work because domain controller doesn't have local accounts and IIS APPool accounts are local.
Check this for more details
I think I got it using an unmanaged approach. It turns out kinda ugly in C#, but here's the concept:
uint nOSErr;
if(!(nOSErr = setFolderPermissions(@"C:\inetpub\www_test1", @"IIS AppPool\" + strAppPoolName, OSFileAccess.FILE_GENERIC_READ)))
{
throw new Exception("Failed to change permissions, error code=" + nOSErr);
}
public static uint setFolderPermissions(string strFolderPath, string strUserName, OSFileAccess access)
{
//Set folder permissions
//RETURN:
// = 0 if success
// = Otherwise error code -- check GetLastError
uint dwRes = 0;
try
{
IntPtr pZero = IntPtr.Zero;
IntPtr pSecDesc = pZero;
IntPtr pDacl = pZero;
if ((dwRes = GetNamedSecurityInfo(strFolderPath, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION,
out pZero, out pZero, out pDacl, out pZero, out pSecDesc)) == ERROR_SUCCESS)
{
try
{
EXPLICIT_ACCESS ea = new EXPLICIT_ACCESS();
ea.grfAccessPermissions = access;
ea.grfAccessMode = AccessMode.GRANT_ACCESS;
ea.grfInheritance = AceFlags.CONTAINER_INHERIT_ACE | AceFlags.OBJECT_INHERIT_ACE;
ea.Trustee.MultipleTrusteeOperation = UIntPtr.Zero;
ea.Trustee.pMultipleTrustee = UIntPtr.Zero;
ea.Trustee.TrusteeForm = (UIntPtr)(TrusteeForm.TRUSTEE_IS_NAME);
ea.Trustee.ptstrName = strUserName;
IntPtr pNewDacl = pZero;
if((dwRes = SetEntriesInAcl(1, ref ea, pDacl, out pNewDacl)) == ERROR_SUCCESS)
{
try
{
if ((dwRes = SetNamedSecurityInfo(strFolderPath, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION,
IntPtr.Zero, IntPtr.Zero, pNewDacl, IntPtr.Zero)) == ERROR_SUCCESS)
{
//Done
}
}
finally
{
//Free mem
if (pNewDacl != IntPtr.Zero)
{
LocalFree(pNewDacl);
pNewDacl = IntPtr.Zero;
}
}
}
}
finally
{
//Free mem
if (pSecDesc != IntPtr.Zero)
{
LocalFree(pSecDesc);
pSecDesc = IntPtr.Zero;
}
}
}
}
catch
{
dwRes = ERROR_INVALID_DATA;
}
return dwRes;
}
enum SE_OBJECT_TYPE
{
SE_UNKNOWN_OBJECT_TYPE = 0,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT,
SE_REGISTRY_WOW64_32KEY
}
[Flags]
enum SECURITY_INFORMATION : uint
{
OWNER_SECURITY_INFORMATION = 0x00000001,
GROUP_SECURITY_INFORMATION = 0x00000002,
DACL_SECURITY_INFORMATION = 0x00000004,
SACL_SECURITY_INFORMATION = 0x00000008,
UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,
UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
static extern uint GetNamedSecurityInfo(
string pObjectName,
SE_OBJECT_TYPE ObjectType,
SECURITY_INFORMATION SecurityInfo,
out IntPtr pSidOwner,
out IntPtr pSidGroup,
out IntPtr pDacl,
out IntPtr pSacl,
out IntPtr pSecurityDescriptor);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LocalFree(IntPtr hMem);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 0)] //Platform independent (32 & 64 bit) - use Pack = 0 for both platforms. IntPtr works as well.
internal struct TRUSTEE
{
internal UIntPtr pMultipleTrustee; // must be null
internal UIntPtr MultipleTrusteeOperation;
internal UIntPtr TrusteeForm;
internal UIntPtr TrusteeType;
//[MarshalAs(UnmanagedType.LPStr)]
internal string ptstrName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct EXPLICIT_ACCESS
{
internal OSFileAccess grfAccessPermissions;
internal AccessMode grfAccessMode;
internal AceFlags grfInheritance;
internal TRUSTEE Trustee;
}
private const uint ERROR_SUCCESS = 0;
[Flags]
public enum OSFileAccess : uint
{
AccessSystemSecurity = 0x1000000, // AccessSystemAcl access type
MaximumAllowed = 0x2000000, // MaximumAllowed access type
Delete = 0x10000,
ReadControl = 0x20000,
WriteDAC = 0x40000,
WriteOwner = 0x80000,
Synchronize = 0x100000,
StandardRightsRequired = 0xF0000,
StandardRightsRead = ReadControl,
StandardRightsWrite = ReadControl,
StandardRightsExecute = ReadControl,
StandardRightsAll = 0x1F0000,
SpecificRightsAll = 0xFFFF,
FILE_READ_DATA = 0x0001, // file & pipe
FILE_LIST_DIRECTORY = 0x0001, // directory
FILE_WRITE_DATA = 0x0002, // file & pipe
FILE_ADD_FILE = 0x0002, // directory
FILE_APPEND_DATA = 0x0004, // file
FILE_ADD_SUBDIRECTORY = 0x0004, // directory
FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
FILE_READ_EA = 0x0008, // file & directory
FILE_WRITE_EA = 0x0010, // file & directory
FILE_EXECUTE = 0x0020, // file
FILE_TRAVERSE = 0x0020, // directory
FILE_DELETE_CHILD = 0x0040, // directory
FILE_READ_ATTRIBUTES = 0x0080, // all
FILE_WRITE_ATTRIBUTES = 0x0100, // all
GENERIC_READ = 0x80000000,
GENERIC_WRITE = 0x40000000,
GENERIC_EXECUTE = 0x20000000,
GENERIC_ALL = 0x10000000,
SPECIFIC_RIGHTS_ALL = 0x00FFFF,
FILE_ALL_ACCESS = StandardRightsRequired | Synchronize | 0x1FF,
FILE_GENERIC_READ = StandardRightsRead | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | Synchronize,
FILE_GENERIC_WRITE = StandardRightsWrite | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | Synchronize,
FILE_GENERIC_EXECUTE = StandardRightsExecute | FILE_READ_ATTRIBUTES | FILE_EXECUTE | Synchronize
}
internal enum AccessMode
{
NOT_USED_ACCESS = 0,
GRANT_ACCESS,
SET_ACCESS,
DENY_ACCESS,
REVOKE_ACCESS,
SET_AUDIT_SUCCESS,
SET_AUDIT_FAILURE
}
[Flags]
internal enum AceFlags
{
OBJECT_INHERIT_ACE = 0x1,
CONTAINER_INHERIT_ACE = 0x2,
NO_PROPAGATE_INHERIT_ACE = 0x4,
INHERIT_ONLY_ACE = 0x8,
INHERITED_ACE = 0x10,
SUCCESSFUL_ACCESS_ACE_FLAG = 0x40,
FAILED_ACCESS_ACE_FLAG = 0x80
}
enum TrusteeForm
{
TRUSTEE_IS_SID,
TRUSTEE_IS_NAME,
TRUSTEE_BAD_FORM,
TRUSTEE_IS_OBJECTS_AND_SID,
TRUSTEE_IS_OBJECTS_AND_NAME
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint SetEntriesInAcl(
int cCountOfExplicitEntries,
ref EXPLICIT_ACCESS pListOfExplicitEntries,
IntPtr OldAcl,
out IntPtr NewAcl);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
static extern uint SetNamedSecurityInfo(
string pObjectName,
SE_OBJECT_TYPE ObjectType,
SECURITY_INFORMATION SecurityInfo,
IntPtr psidOwner,
IntPtr psidGroup,
IntPtr pDacl,
IntPtr pSacl);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.