Search code examples
iisasp.net-corepermissionsapplication-poolasp.net-core-2.1

Programmatically modify ACL to give application pool all permissions to application (IIS)


I have a process that creates an application and application pool using the Server Manager object in the Microsoft.Web.Administration namespace, the application pool is created first and then the application, assigning the newly created app pool to the application, code below.

protected TResult UseServerManagerWrapper<TResult>(Func<ServerManager, TResult> func)
    {
        using (var serverManager = new ServerManager())
        {
            return func(serverManager);
        }
    }

Application creation function

public void CreateApplication(String siteName, String parentApplicationName, String organisationName, String applicationName, String applicationPoolName)
    {
        UseServerManagerWrapper(serverManager =>
            {
                var site = serverManager.Sites[siteName];

                var newApplication =
                    site.Applications.Add(
                        GetApplicationPath(parentApplicationName, organisationName, applicationName),
                        this.GetGeneratedApplicationPhysicalPath(siteName, parentApplicationName, organisationName, applicationName));

                newApplication.ApplicationPoolName = applicationPoolName;
                serverManager.CommitChanges();
                return true;
            });
    }

and app pool creation.

public Boolean CreateApplicationPool(String applicationPoolName)
    {
        return UseServerManagerWrapper(serverManager =>
            {
                var appPool = serverManager.ApplicationPools.Add(applicationPoolName);

                appPool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
                appPool.ManagedRuntimeVersion = "";
                serverManager.CommitChanges();
                return true;
            });
    }

This all works fine, the only problem I have is that I have to go into the application folder and manually assign permissions for the application pool.

I can't see anything in the ServerManager documentation that can help me and I can't figure out a way to use the Directory.SetAccessControl Method to give an application pool permissions. Is there anyway to do this in code?

Apologies if I'm using wrong terminology or anything, I'm new to publishing in general. Let me know if you need anymore info.


Solution

  • Ok, so after a lot of searching and some trial and error I've found the resolution and it's nothing to do with the ServerManager object. First of all to get this to work in ASP.NET Core 2.1 (1.x/2.x) I needed the System.IO.FileSystem.AccessControl Nuget and the Namespaces below.

    using System.Security.AccessControl;
    using System.Security.Principal;
    

    These give the ability to modify the ACL of files and folders and then the CreateApplication function becomes the below.

    public void CreateApplication(String siteName, String parentApplicationName, String organisationName, String applicationName, String applicationPoolName)
        {
            UseServerManagerWrapper(serverManager =>
                {
                    var site = serverManager.Sites[siteName];
                    var generatedPath = this.GetGeneratedApplicationPhysicalPath(siteName, parentApplicationName, organisationName, applicationName);
                    var newApplication =
                        site.Applications.Add(
                            GetApplicationPath(parentApplicationName, organisationName, applicationName),
                            generatedPath);
    
                    newApplication.ApplicationPoolName = applicationPoolName;
    
                    var dInfo = new DirectoryInfo(generatedPath);
                    var acl = dInfo.GetAccessControl();
                    var acct = new NTAccount($"IIS APPPOOL\\{applicationPoolName}");
                    acl.AddAccessRule(new FileSystemAccessRule(acct, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
                    dInfo.SetAccessControl(acl);
    
                    serverManager.CommitChanges();
                    return true;
                });
        }
    

    The code between "newApplication.ApplicationPoolName = applicationPoolName" and "serverManager.CommitChanges()" gets the ACL from the newly generated directory giving the ability to modify it and reassign with a new FileSystemAccessRule.