简体   繁体   中英

How to assign IIS 7.5 file system access permissions on a Domain Controller?

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

http://blogs.technet.com/b/abizerh/archive/2009/07/16/should-iis-be-installed-on-domain-controller.aspx

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM