websitepanel/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIS70/IIs70.cs
omara_vworks a2beec7fe4 Commit Contribution from Helicon
Includes:

- complete re-write of Web Application Gallery
- Addition of Web PI Installer in Server module
2012-07-19 13:16:33 -04:00

4037 lines
145 KiB
C#

// Copyright (c) 2012, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Collections;
using System.Management;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Collections.Generic;
using System.Text;
using System.IO;
using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.Providers.OS;
using WebsitePanel.Providers.ResultObjects;
using WebsitePanel.Providers.Utils;
using WebsitePanel.Providers.Web.Handlers;
using WebsitePanel.Providers.Web.HttpRedirect;
using WebsitePanel.Providers.Web.Iis.Authentication;
using WebsitePanel.Providers.Web.Iis.ClassicAsp;
using WebsitePanel.Providers.Web.Iis.DefaultDocuments;
using WebsitePanel.Providers.Web.Iis.DirectoryBrowse;
using WebsitePanel.Providers.Web.Iis.WebObjects;
using WebsitePanel.Providers.Web.Iis.Extensions;
using WebsitePanel.Providers.Web.MimeTypes;
using WebsitePanel.Providers.Web.Iis.Utility;
using Microsoft.Web.Administration;
using Microsoft.Web.Management.Server;
using WebsitePanel.Providers.Utils.LogParser;
using Microsoft.Win32;
using WebsitePanel.Providers.Common;
using System.Collections.Specialized;
using WebsitePanel.Providers.Web.WebObjects;
using WebsitePanel.Providers.Web.Iis.Common;
using WebsitePanel.Providers.Web.Iis;
using Ionic.Zip;
using WebsitePanel.Providers.WebAppGallery;
using WebsitePanel.Server.Utils;
using WebsitePanel.Providers.Web.Delegation;
namespace WebsitePanel.Providers.Web
{
internal abstract class Constants
{
public const string CachingSection = "system.webServer/caching";
public const string DefaultDocumentsSection = "system.webServer/defaultDocument";
public const string DirectoryBrowseSection = "system.webServer/directoryBrowse";
public const string FactCgiSection = "system.webServer/fastCgi";
public const string HandlersSection = "system.webServer/handlers";
public const string HttpErrorsSection = "system.webServer/httpErrors";
public const string HttpProtocolSection = "system.webServer/httpProtocol";
public const string HttpRedirectSection = "system.webServer/httpRedirect";
public const string AnonymousAuthenticationSection = "system.webServer/security/authentication/anonymousAuthentication";
public const string BasicAuthenticationSection = "system.webServer/security/authentication/basicAuthentication";
public const string WindowsAuthenticationSection = "system.webServer/security/authentication/windowsAuthentication";
public const string StaticContentSection = "system.webServer/staticContent";
public const string ModulesSection = "system.webServer/modules";
public const string IsapiCgiRestrictionSection = "system.webServer/security/isapiCgiRestriction";
public const string APP_POOL_NAME_FORMAT_STRING = "#SITE-NAME# #IIS7-ASPNET-VERSION# (#PIPELINE-MODE#)";
public const string AspNet11Pool = "AspNet11Pool";
public const string ClassicAspNet20Pool = "ClassicAspNet20Pool";
public const string IntegratedAspNet20Pool = "IntegratedAspNet20Pool";
public const string ClassicAspNet40Pool = "ClassicAspNet40Pool";
public const string IntegratedAspNet40Pool = "IntegratedAspNet40Pool";
public const string AspPathSetting = "AspPath";
public const string AspNet11PathSetting = "AspNet11Path";
public const string AspNet20PathSetting = "AspNet20Path";
public const string AspNet20x64PathSetting = "AspNet20x64Path";
public const string AspNet40PathSetting = "AspNet40Path";
public const string AspNet40x64PathSetting = "AspNet40x64Path";
public const string WEBSITEPANEL_IISMODULES = "WebsitePanel.IIsModules";
public const string HeliconApeModule = "Helicon Ape";
public const string HeliconApeHandlerPath = "*.apehandler";
public const string IsapiModule = "IsapiModule";
public const string FastCgiModule = "FastCgiModule";
public const string CgiModule = "CgiModule";
internal abstract class PhpMode
{
public const string FastCGI = "FastCGI";
public const string CGI = "CGI";
public const string ISAPI = "ISAPI";
}
internal abstract class HandlerAlias
{
public const string CLASSIC_ASP = "ASPClassic (*{0})";
public const string PHP_FASTCGI = "PHP via FastCGI (*{0})";
public const string PHP_CGI = "PHP via CGI (*{0})";
public const string PERL_ISAPI = "Perl via ISAPI (*{0})";
public const string PHP_ISAPI = "PHP via ISAPI (*{0})";
public const string COLDFUSION = "ColdFusion (*{0})";
}
public static bool X64Environment
{
get { return (IntPtr.Size == 8); }
}
}
public class WebAppPool
{
public static readonly Dictionary<SiteAppPoolMode, string> AspNetVersions = new Dictionary<SiteAppPoolMode, string>
{
{ SiteAppPoolMode.dotNetFramework1, "v1.1" },
{ SiteAppPoolMode.dotNetFramework2, "v2.0" },
{ SiteAppPoolMode.dotNetFramework4, "v4.0" }
};
public string AspNetInstalled { get; set; }
public SiteAppPoolMode Mode { get; set; }
public string Name { get; set; }
}
public class WebAppPoolHelper
{
private List<WebAppPool> supportedAppPools;
public List<WebAppPool> SupportedAppPools
{
get
{
return supportedAppPools;
}
}
public static Dictionary<string, SiteAppPoolMode> SupportedAppPoolModes = new Dictionary<string, SiteAppPoolMode>
{
{ "1", SiteAppPoolMode.dotNetFramework1 | SiteAppPoolMode.Classic },
{ "2", SiteAppPoolMode.dotNetFramework2 | SiteAppPoolMode.Classic },
{ "2I", SiteAppPoolMode.dotNetFramework2 | SiteAppPoolMode.Integrated },
{ "4", SiteAppPoolMode.dotNetFramework4 | SiteAppPoolMode.Classic },
{ "4I", SiteAppPoolMode.dotNetFramework4 | SiteAppPoolMode.Integrated }
};
//
public WebAppPoolHelper(ServiceProviderSettings s)
{
SetupSupportedAppPools(s);
}
//
public SiteAppPoolMode dotNetVersion(SiteAppPoolMode m)
{
return m & (SiteAppPoolMode.dotNetFramework1 | SiteAppPoolMode.dotNetFramework2 | SiteAppPoolMode.dotNetFramework4);
}
//
public SiteAppPoolMode pipeline(SiteAppPoolMode m)
{
return m & (SiteAppPoolMode.Classic | SiteAppPoolMode.Integrated);
}
//
public SiteAppPoolMode isolation(SiteAppPoolMode m)
{
return m & (SiteAppPoolMode.Shared | SiteAppPoolMode.Dedicated);
}
//
public string aspnet_runtime(SiteAppPoolMode m)
{
return WebAppPool.AspNetVersions[dotNetVersion(m)];
}
//
public ManagedPipelineMode runtime_pipeline(SiteAppPoolMode m)
{
return (pipeline(m) == SiteAppPoolMode.Classic) ? ManagedPipelineMode.Classic : ManagedPipelineMode.Integrated;
}
//
public bool is_shared_pool(string poolName)
{
return Array.Exists<WebAppPool>(supportedAppPools.ToArray(),
x => x.Name.Equals(poolName) && isolation(x.Mode) == SiteAppPoolMode.Shared);
}
//
public WebAppPool match_webapp_pool(WebVirtualDirectory vdir)
{
// Detect isolation mode
SiteAppPoolMode sisMode = is_shared_pool(vdir.ApplicationPool) ?
SiteAppPoolMode.Shared : SiteAppPoolMode.Dedicated;
// Match proper app pool
return Array.Find<WebAppPool>(SupportedAppPools.ToArray(),
x => x.AspNetInstalled.Equals(vdir.AspNetInstalled) && isolation(x.Mode) == sisMode);
}
//
private void SetupSupportedAppPools(ServiceProviderSettings settings)
{
supportedAppPools = new List<WebAppPool>();
#region Populate Shared Application Pools
// ASP.NET 1.1
if (!String.IsNullOrEmpty(settings[Constants.AspNet11Pool]))
{
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "1",
Mode = SiteAppPoolMode.dotNetFramework1 | SiteAppPoolMode.Classic | SiteAppPoolMode.Shared,
Name = settings[Constants.AspNet11Pool].Trim()
});
}
// ASP.NET 2.0 (Classic pipeline)
if (!String.IsNullOrEmpty(settings[Constants.ClassicAspNet20Pool]))
{
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "2",
Mode = SiteAppPoolMode.dotNetFramework2 | SiteAppPoolMode.Classic | SiteAppPoolMode.Shared,
Name = settings[Constants.ClassicAspNet20Pool].Trim()
});
}
// ASP.NET 2.0 (Integrated pipeline)
if (!String.IsNullOrEmpty(settings[Constants.IntegratedAspNet20Pool]))
{
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "2I",
Mode = SiteAppPoolMode.dotNetFramework2 | SiteAppPoolMode.Integrated | SiteAppPoolMode.Shared,
Name = settings[Constants.IntegratedAspNet20Pool].Trim()
});
}
// ASP.NET 4.0 (Classic pipeline)
if (!String.IsNullOrEmpty(settings[Constants.ClassicAspNet40Pool]))
{
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "4",
Mode = SiteAppPoolMode.dotNetFramework4 | SiteAppPoolMode.Classic | SiteAppPoolMode.Shared,
Name = settings[Constants.ClassicAspNet40Pool].Trim()
});
}
// ASP.NET 4.0 (Integrated pipeline)
if (!String.IsNullOrEmpty(settings[Constants.IntegratedAspNet40Pool]))
{
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "4I",
Mode = SiteAppPoolMode.dotNetFramework4 | SiteAppPoolMode.Integrated | SiteAppPoolMode.Shared,
Name = settings[Constants.IntegratedAspNet40Pool].Trim()
});
}
#endregion
#region Populate Dedicated Application Pools
// ASP.NET 1.1
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "1",
Mode = SiteAppPoolMode.dotNetFramework1 | SiteAppPoolMode.Classic | SiteAppPoolMode.Dedicated,
Name = Constants.APP_POOL_NAME_FORMAT_STRING
});
// ASP.NET 2.0 (Classic pipeline)
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "2",
Mode = SiteAppPoolMode.dotNetFramework2 | SiteAppPoolMode.Classic | SiteAppPoolMode.Dedicated,
Name = Constants.APP_POOL_NAME_FORMAT_STRING
});
// ASP.NET 2.0 (Integrated pipeline)
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "2I",
Mode = SiteAppPoolMode.dotNetFramework2 | SiteAppPoolMode.Integrated | SiteAppPoolMode.Dedicated,
Name = Constants.APP_POOL_NAME_FORMAT_STRING
});
// ASP.NET 4.0 (Classic pipeline)
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "4",
Mode = SiteAppPoolMode.dotNetFramework4 | SiteAppPoolMode.Classic | SiteAppPoolMode.Dedicated,
Name = Constants.APP_POOL_NAME_FORMAT_STRING
});
// ASP.NET 4.0 (Integrated pipeline)
supportedAppPools.Add(new WebAppPool
{
AspNetInstalled = "4I",
Mode = SiteAppPoolMode.dotNetFramework4 | SiteAppPoolMode.Integrated | SiteAppPoolMode.Dedicated,
Name = Constants.APP_POOL_NAME_FORMAT_STRING
});
#endregion
// Make some corrections for frameworks with the version number greater or less than 2.0 ...
#region No ASP.NET 1.1 has been found - so remove extra pools
if (String.IsNullOrEmpty(settings[Constants.AspNet11PathSetting]))
supportedAppPools.RemoveAll(x => dotNetVersion(x.Mode) == SiteAppPoolMode.dotNetFramework1);
#endregion
#region No ASP.NET 4.0 has been found - so remove extra pools
var aspNet40PathSetting = (Constants.X64Environment)
? Constants.AspNet40x64PathSetting : Constants.AspNet40PathSetting;
//
if (String.IsNullOrEmpty(settings[aspNet40PathSetting]))
supportedAppPools.RemoveAll(x => dotNetVersion(x.Mode) == SiteAppPoolMode.dotNetFramework4);
#endregion
}
}
public class WebManagementServiceSettings
{
public string Port { get; set; }
public string NETBIOS { get; set; }
public string ServiceUrl { get; set; }
public int RequiresWindowsCredentials { get; set; }
}
public class IIs70 : IIs60, IWebServer
{
private WebObjectsModuleService webObjectsSvc;
private DirectoryBrowseModuleService dirBrowseSvc;
private AnonymAuthModuleService anonymAuthSvc;
private WindowsAuthModuleService winAuthSvc;
private BasicAuthModuleService basicAuthSvc;
private DefaultDocsModuleService defaultDocSvc;
private CustomHttpErrorsModuleService customErrorsSvc;
private CustomHttpHeadersModuleService customHeadersSvc;
private ClassicAspModuleService classicAspSvc;
private MimeTypesModuleService mimeTypesSvc;
private ExtensionsModuleService extensionsSvc;
private HandlersModuleService handlersSvc;
private HttpRedirectModuleService httpRedirectSvc;
//
#region Constants
public const string IIS_IUSRS_GROUP = "IIS_IUSRS";
//
public const string FPSE2002_OWSADM_PATH_x86 = @"%CommonProgramFiles%\Microsoft Shared\Web Server Extensions\50\bin\owsadm.exe";
public const string FPSE2002_OWSADM_PATH_x64 = @"%CommonProgramFiles(x86)%\Microsoft Shared\Web Server Extensions\50\bin\owsadm.exe";
//
public const string FRONTPAGE_2002_REGLOC_x86 = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\5.0";
public const string FRONTPAGE_2002_REGLOC_x64 = @"SOFTWARE\Wow6432Node\Microsoft\Shared Tools\Web Server Extensions\5.0";
//
public const string FRONTPAGE_ALLPORTS_REGLOC_x86 = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\All Ports\";
public const string FRONTPAGE_ALLPORTS_REGLOC_x64 = @"SOFTWARE\Wow6432Node\Microsoft\Shared Tools\Web Server Extensions\All Ports\";
//
public const string FRONTPAGE_PORT_REGLOC_x86 = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\Ports\";
public const string FRONTPAGE_PORT_REGLOC_x64 = @"SOFTWARE\Wow6432Node\Microsoft\Shared Tools\Web Server Extensions\Ports\";
private string[] INSTALL_SECTIONS_ALLOWED = new string[] {
Constants.CachingSection,
Constants.DefaultDocumentsSection,
Constants.DirectoryBrowseSection,
Constants.FactCgiSection,
Constants.HandlersSection,
Constants.HttpErrorsSection,
Constants.HttpProtocolSection,
Constants.HttpRedirectSection,
Constants.AnonymousAuthenticationSection,
Constants.BasicAuthenticationSection,
Constants.WindowsAuthenticationSection,
Constants.StaticContentSection
};
#endregion
#region Helper Properties
protected string FPSE2002_OWSADM_PATH
{
get
{
if (Constants.X64Environment)
return FPSE2002_OWSADM_PATH_x64;
else
return FPSE2002_OWSADM_PATH_x86;
}
}
new protected string FRONTPAGE_2002_REGLOC
{
get
{
if (Constants.X64Environment)
return FRONTPAGE_2002_REGLOC_x64;
else
return FRONTPAGE_2002_REGLOC_x86;
}
}
new protected string FRONTPAGE_ALLPORTS_REGLOC
{
get
{
if (Constants.X64Environment)
return FRONTPAGE_ALLPORTS_REGLOC_x64;
else
return FRONTPAGE_ALLPORTS_REGLOC_x86;
}
}
new protected string FRONTPAGE_PORT_REGLOC
{
get
{
if (Constants.X64Environment)
return FRONTPAGE_PORT_REGLOC_x64;
else
return FRONTPAGE_PORT_REGLOC_x86;
}
}
#endregion
#region Provider Properties
public bool Enable32BitAppOnWin64
{
get { return ProviderSettings["AspNetBitnessMode"] == "32"; }
}
/// <summary>
/// Gets shared iisAppObject pool name (Classic Managed Pipeline)
/// </summary>
public string ClassicAspNet20Pool
{
get { return ProviderSettings["ClassicAspNet20Pool"]; }
}
/// <summary>
/// Gets shared iisAppObject pool name (Integrated Managed Pipeline)
/// </summary>
public string IntegratedAspNet20Pool
{
get { return ProviderSettings["IntegratedAspNet20Pool"]; }
}
/// <summary>
/// Gets shared iisAppObject pool name (Classic Managed Pipeline)
/// </summary>
public string ClassicAspNet40Pool
{
get { return ProviderSettings["ClassicAspNet40Pool"]; }
}
/// <summary>
/// Gets shared iisAppObject pool name (Integrated Managed Pipeline)
/// </summary>
public string IntegratedAspNet40Pool
{
get { return ProviderSettings["IntegratedAspNet40Pool"]; }
}
public string PhpMode
{
get { return ProviderSettings["PhpMode"]; }
}
public string PhpExecutablePath
{
get { return FileUtils.EvaluateSystemVariables(ProviderSettings["PhpPath"]); }
}
public string SecureFoldersModuleAssembly
{
get { return ProviderSettings["SecureFoldersModuleAssembly"]; }
}
protected override string ProtectedAccessFile
{
get
{
return ".htaccess";
}
}
protected override string ProtectedFoldersFile
{
get
{
return ".htfolders";
}
}
#endregion
public IIs70()
{
if (IsIISInstalled())
{
// New implementation avoiding locks and other sync issues
winAuthSvc = new WindowsAuthModuleService();
anonymAuthSvc = new AnonymAuthModuleService();
basicAuthSvc = new BasicAuthModuleService();
defaultDocSvc = new DefaultDocsModuleService();
classicAspSvc = new ClassicAspModuleService();
httpRedirectSvc = new HttpRedirectModuleService();
extensionsSvc = new ExtensionsModuleService();
customErrorsSvc = new CustomHttpErrorsModuleService();
customHeadersSvc = new CustomHttpHeadersModuleService();
webObjectsSvc = new WebObjectsModuleService();
dirBrowseSvc = new DirectoryBrowseModuleService();
mimeTypesSvc = new MimeTypesModuleService();
handlersSvc = new HandlersModuleService();
}
}
#region Helper methods
private void CreateWebSiteAnonymousAccount(WebSite site)
{
// anonymous user groups
List<string> webGroups = new List<string>();
webGroups.Add(WebGroupName);
// create web site anonymous account
SystemUser user = new SystemUser();
user.Name = GetNonQualifiedAccountName(site.AnonymousUsername);
user.FullName = GetNonQualifiedAccountName(site.AnonymousUsername);
// Fix. Import web site that runs under NETWORK_SERVICE identity fails.
// WebsitePanel cannot create anonymous account.
/*if (!user.Name.Contains(site.Name.Replace(".", "")))
{
user.Name = user.FullName = site.Name.Replace(".", "") + "_web";
}*/
//check is user name less than 20 symbols (Windows name length restriction)
if (user.Name.Length > 20)
{
int separatorPlace = user.Name.IndexOf("_");
user.Name = user.Name.Remove(separatorPlace - (user.Name.Length - 20), user.Name.Length - 20);
}
site.AnonymousUsername = user.Name;
user.Description = "WebsitePanel System Account";
user.MemberOf = webGroups.ToArray();
//set new password for created Anonymous Account
if (String.IsNullOrEmpty(site.AnonymousUserPassword))
{
site.AnonymousUserPassword = Guid.NewGuid().ToString();
}
user.Password = site.AnonymousUserPassword;
user.PasswordCantChange = true;
user.PasswordNeverExpires = true;
user.AccountDisabled = false;
user.System = true;
// create in the system
try
{
SecurityUtils.CreateUser(user, ServerSettings, UsersOU, GroupsOU);
}
catch (Exception ex)
{
// the possible reason the account already exists
// check this
if (SecurityUtils.UserExists(user.Name, ServerSettings, UsersOU))
{
// yes
// try to give it original name
for (int i = 2; i < 99; i++)
{
string username = user.Name + i.ToString();
if (!SecurityUtils.UserExists(username, ServerSettings, UsersOU))
{
user.Name = username;
site.AnonymousUsername = username;
// try to create again
SecurityUtils.CreateUser(user, ServerSettings, UsersOU, GroupsOU);
break;
}
}
}
else
{
throw ex;
}
}
}
private void FillVirtualDirectoryFromIISObject(ServerManager srvman, WebVirtualDirectory virtualDir)
{
// Set physical path.
virtualDir.ContentPath = webObjectsSvc.GetPhysicalPath(srvman, virtualDir);
// load iisDirObject browse
PropertyBag bag = dirBrowseSvc.GetDirectoryBrowseSettings(srvman, virtualDir.FullQualifiedPath);
virtualDir.EnableDirectoryBrowsing = (bool)bag[DirectoryBrowseGlobals.Enabled];
// load anonym auth
bag = anonymAuthSvc.GetAuthenticationSettings(srvman, virtualDir.FullQualifiedPath);
virtualDir.AnonymousUsername = (string)bag[AuthenticationGlobals.AnonymousAuthenticationUserName];
virtualDir.AnonymousUserPassword = (string)bag[AuthenticationGlobals.AnonymousAuthenticationPassword];
virtualDir.EnableAnonymousAccess = (bool)bag[AuthenticationGlobals.Enabled];
// load windows auth
bag = winAuthSvc.GetAuthenticationSettings(srvman, virtualDir.FullQualifiedPath);
virtualDir.EnableWindowsAuthentication = (bool)bag[AuthenticationGlobals.Enabled];
// load basic auth
basicAuthSvc.GetAuthenticationSettings(srvman, virtualDir);
// load default docs
virtualDir.DefaultDocs = defaultDocSvc.GetDefaultDocumentSettings(srvman, virtualDir.FullQualifiedPath);
// load classic asp
bag = classicAspSvc.GetClassicAspSettings(srvman, virtualDir.FullQualifiedPath);
virtualDir.EnableParentPaths = (bool)bag[ClassicAspGlobals.EnableParentPaths];
//
virtualDir.IIs7 = true;
}
private void FillIISObjectFromVirtualDirectory(WebVirtualDirectory virtualDir)
{
dirBrowseSvc.SetDirectoryBrowseEnabled(virtualDir.FullQualifiedPath, virtualDir.EnableDirectoryBrowsing);
//
SetAnonymousAuthentication(virtualDir);
//
winAuthSvc.SetEnabled(virtualDir.FullQualifiedPath, virtualDir.EnableWindowsAuthentication);
//
basicAuthSvc.SetAuthenticationSettings(virtualDir);
//
defaultDocSvc.SetDefaultDocumentSettings(virtualDir.FullQualifiedPath, virtualDir.DefaultDocs);
//
classicAspSvc.SetClassicAspSettings(virtualDir);
}
private void FillVirtualDirectoryRestFromIISObject(ServerManager srvman, WebVirtualDirectory virtualDir)
{
// HTTP REDIRECT
httpRedirectSvc.GetHttpRedirectSettings(srvman, virtualDir);
// HTTP HEADERS
customHeadersSvc.GetCustomHttpHeaders(srvman, virtualDir);
// HTTP ERRORS
customErrorsSvc.GetCustomErrors(srvman, virtualDir);
// MIME MAPPINGS
mimeTypesSvc.GetMimeMaps(srvman, virtualDir);
// SCRIPT MAPS
// Load installed script maps.
virtualDir.AspInstalled = false; // not installed
virtualDir.PhpInstalled = ""; // none
virtualDir.PerlInstalled = false; // not installed
virtualDir.PythonInstalled = false; // not installed
virtualDir.ColdFusionInstalled = false; // not installed
//
var config = srvman.GetWebConfiguration(virtualDir.FullQualifiedPath);
var handlersSection = config.GetSection(Constants.HandlersSection);
// Loop through available maps and fill installed processors
foreach (ConfigurationElement action in handlersSection.GetCollection())
{
// Extract and evaluate scripting processor path
string processor = FileUtils.EvaluateSystemVariables(
Convert.ToString(action.GetAttributeValue("scriptProcessor")));
//
string actionName = Convert.ToString(action.GetAttributeValue("name"));
// Detect whether ASP scripting is enabled
if (!String.IsNullOrEmpty(AspPath) && String.Equals(AspPath, processor, StringComparison.InvariantCultureIgnoreCase))
virtualDir.AspInstalled = true;
// Detect whether PHP 5 scripting is enabled
if (!String.IsNullOrEmpty(PhpExecutablePath) && String.Equals(PhpExecutablePath, processor, StringComparison.InvariantCultureIgnoreCase))
virtualDir.PhpInstalled = PHP_5;
// Detect whether PHP 4 scripting is enabled
if (!String.IsNullOrEmpty(Php4Path) && String.Equals(Php4Path, processor, StringComparison.InvariantCultureIgnoreCase))
virtualDir.PhpInstalled = PHP_4;
// Detect whether ColdFusion scripting is enabled
if (!String.IsNullOrEmpty(ColdFusionPath) && String.Compare(ColdFusionPath, processor, true) == 0 && actionName.Contains(".cfm"))
virtualDir.ColdFusionInstalled = true;
// Detect whether Perl scripting is enabled
if (!String.IsNullOrEmpty(PerlPath) && String.Equals(PerlPath, processor, StringComparison.InvariantCultureIgnoreCase))
virtualDir.PerlInstalled = true;
}
//
string fqPath = virtualDir.FullQualifiedPath;
if (!fqPath.EndsWith(@"/"))
fqPath += "/";
//
fqPath += CGI_BIN_FOLDER;
//
HandlerAccessPolicy policy = handlersSvc.GetHandlersAccessPolicy(srvman, fqPath);
virtualDir.CgiBinInstalled = (policy & HandlerAccessPolicy.Execute) > 0;
// ASP.NET
FillAspNetSettingsFromIISObject(srvman, virtualDir);
}
private void FillAspNetSettingsFromIISObject(ServerManager srvman, WebVirtualDirectory vdir)
{
// Read ASP.NET settings
if (String.IsNullOrEmpty(vdir.ApplicationPool))
return;
//
try
{
var appool = srvman.ApplicationPools[vdir.ApplicationPool];
//
var aphl = new WebAppPoolHelper(ProviderSettings);
// ASP.NET 2.0 pipeline is supposed by default
var dotNetVersion = SiteAppPoolMode.dotNetFramework2;
//
#region Iterate over managed runtime keys of the helper class to properly evaluate ASP.NET version installed
foreach (var k in WebAppPool.AspNetVersions)
{
if (k.Value.Equals(appool.ManagedRuntimeVersion))
{
dotNetVersion = k.Key;
break;
}
}
#endregion
// Detect pipeline mode being used
if (appool.ManagedPipelineMode == ManagedPipelineMode.Classic)
dotNetVersion |= SiteAppPoolMode.Classic;
else
dotNetVersion |= SiteAppPoolMode.Integrated;
//
var aspNetVersion = String.Empty;
#region Iterate over supported ASP.NET versions based on result of the previous runtime version assesement
foreach (var item in WebAppPoolHelper.SupportedAppPoolModes)
{
if (item.Value == dotNetVersion)
{
// Obtain ASP.NET version installed
aspNetVersion = item.Key;
//
break;
}
}
#endregion
// Assign the result of assesement
vdir.AspNetInstalled = aspNetVersion;
}
catch (Exception ex)
{
Log.WriteError(String.Format("Failed to read ASP.NET settings from {0}.", vdir.Name), ex);
// Re-throw
throw (ex);
}
}
private void DeleteDedicatedPoolsAllocated(string siteName)
{
try
{
WebAppPoolHelper aphl = new WebAppPoolHelper(ProviderSettings);
//
var dedicatedPools = Array.FindAll<WebAppPool>(aphl.SupportedAppPools.ToArray(),
x => aphl.isolation(x.Mode) == SiteAppPoolMode.Dedicated);
// cleanup app pools
using (var srvman = webObjectsSvc.GetServerManager())
{
foreach (var item in dedicatedPools)
{
string poolName = WSHelper.InferAppPoolName(item.Name, siteName, item.Mode);
//
ApplicationPool pool = srvman.ApplicationPools[poolName];
if (pool == null)
continue;
//
srvman.ApplicationPools.Remove(pool);
}
// save changes
srvman.CommitChanges();
}
}
catch (Exception ex)
{
Log.WriteError(ex);
throw (ex);
}
}
private void FillIISObjectFromVirtualDirectoryRest(WebVirtualDirectory virtualDir)
{
// TO-DO: HTTP REDIRECT
httpRedirectSvc.SetHttpRedirectSettings(virtualDir);
// TO-DO: HTTP HEADERS
customHeadersSvc.SetCustomHttpHeaders(virtualDir);
// TO-DO: HTTP ERRORS
customErrorsSvc.SetCustomErrors(virtualDir);
// TO-DO: MIME MAPPINGS
mimeTypesSvc.SetMimeMaps(virtualDir);
// Revert script mappings to the parent to simplify script mappings cleanup
//handlersSvc.InheritScriptMapsFromParent(virtualDir.FullQualifiedPath);
// TO-DO: SCRIPT MAPS
#region ASP script mappings
if (!String.IsNullOrEmpty(AspPath) && File.Exists(AspPath))
{
// Classic ASP
if (virtualDir.AspInstalled)
{
handlersSvc.AddScriptMaps(virtualDir, ASP_EXTENSIONS, AspPath,
Constants.HandlerAlias.CLASSIC_ASP, Constants.IsapiModule);
}
else
{
handlersSvc.RemoveScriptMaps(virtualDir, ASP_EXTENSIONS, AspPath);
}
}
#endregion
#region PHP 5 script mappings
if (!String.IsNullOrEmpty(PhpExecutablePath) && File.Exists(PhpExecutablePath))
{
if (virtualDir.PhpInstalled == PHP_5)
{
switch (PhpMode)
{
case Constants.PhpMode.FastCGI:
handlersSvc.AddScriptMaps(virtualDir, PHP_EXTENSIONS,
PhpExecutablePath, Constants.HandlerAlias.PHP_FASTCGI, Constants.FastCgiModule);
break;
case Constants.PhpMode.CGI:
handlersSvc.AddScriptMaps(virtualDir, PHP_EXTENSIONS,
PhpExecutablePath, Constants.HandlerAlias.PHP_CGI, Constants.CgiModule);
break;
case Constants.PhpMode.ISAPI:
handlersSvc.AddScriptMaps(virtualDir, PHP_EXTENSIONS,
PhpExecutablePath, Constants.HandlerAlias.PHP_ISAPI, Constants.IsapiModule);
break;
}
}
else
{
handlersSvc.RemoveScriptMaps(virtualDir, PHP_EXTENSIONS, PhpExecutablePath);
}
}
//
#endregion
#region PHP 4 script mappings (IsapiModule only)
if (!String.IsNullOrEmpty(Php4Path) && File.Exists(Php4Path))
{
if (virtualDir.PhpInstalled == PHP_4)
{
handlersSvc.AddScriptMaps(virtualDir, PHP_EXTENSIONS, Php4Path,
Constants.HandlerAlias.PHP_ISAPI, Constants.IsapiModule);
}
else
{
handlersSvc.RemoveScriptMaps(virtualDir, PHP_EXTENSIONS, Php4Path);
}
}
//
#endregion
#region PERL scrit mappings
//
if (!String.IsNullOrEmpty(PerlPath) && File.Exists(PerlPath))
{
// Start from building Perl-specific CGI-executable definition
// IsapiModule
if (virtualDir.PerlInstalled)
{
// Perl works only in 32-bit mode on x64 environment
webObjectsSvc.ForceEnableAppPoolWow6432Mode(virtualDir.ApplicationPool);
//
handlersSvc.AddScriptMaps(virtualDir, PERL_EXTENSIONS, PerlPath,
Constants.HandlerAlias.PERL_ISAPI, Constants.IsapiModule);
}
else
{
handlersSvc.RemoveScriptMaps(virtualDir, PERL_EXTENSIONS, PerlPath);
}
}
//
#endregion
#region ColdFusion script mappings
//ColdFusion code
if (virtualDir.ColdFusionInstalled)
{
handlersSvc.AddScriptMaps(virtualDir, COLDFUSION_EXTENSIONS, ColdFusionPath,
Constants.HandlerAlias.COLDFUSION, Constants.IsapiModule);
}
else
{
handlersSvc.RemoveScriptMaps(virtualDir, COLDFUSION_EXTENSIONS, ColdFusionPath);
}
#endregion
// TO-DO: REST
}
/// <summary>
/// Update CGI-Bin
/// </summary>
/// <param name="installedHandlers">Already installed scrip maps.</param>
/// <param name="extensions">Extensions to check.</param>
/// <param name="processor">Extensions processor.</param>
private void UpdateCgiBinFolder(WebVirtualDirectory virtualDir)
{
//
string fqPath = virtualDir.FullQualifiedPath;
if (!fqPath.EndsWith(@"/"))
fqPath += "/";
//
fqPath += CGI_BIN_FOLDER;
string cgiBinPath = Path.Combine(virtualDir.ContentPath, CGI_BIN_FOLDER);
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
//
HandlerAccessPolicy policy = handlersSvc.GetHandlersAccessPolicy(srvman, fqPath);
policy &= ~HandlerAccessPolicy.Execute;
//
if (virtualDir.CgiBinInstalled)
{
// create folder if not exists
if (!FileUtils.DirectoryExists(cgiBinPath))
FileUtils.CreateDirectory(cgiBinPath);
//
policy |= HandlerAccessPolicy.Execute;
}
//
if (FileUtils.DirectoryExists(cgiBinPath))
handlersSvc.SetHandlersAccessPolicy(srvman, fqPath, policy);
// save
srvman.CommitChanges();
}
}
/// <summary>
/// Sets anonymous authentication for the virtual iisDirObject
/// </summary>
/// <param name="vdir"></param>
private void SetAnonymousAuthentication(WebVirtualDirectory virtualDir)
{
// set anonymous credentials
anonymAuthSvc.SetAuthenticationSettings(virtualDir.FullQualifiedPath,
GetQualifiedAccountName(virtualDir.AnonymousUsername),
virtualDir.AnonymousUserPassword, virtualDir.EnableAnonymousAccess);
// configure "Connect As" feature
if (virtualDir.ContentPath.StartsWith(@"\\"))
webObjectsSvc.ConfigureConnectAsFeature(virtualDir);
}
/// <summary>
/// Creates if needed dedicated iisAppObject pools and assigns to specified site iisAppObject pool according to
/// selected ASP.NET version.
/// </summary>
/// <param name="site">WEb site to operate on.</param>
/// <param name="createAppPools">A value which shows whether iisAppObject pools has to be created.</param>
private void SetWebSiteApplicationPool(WebSite site, bool createAppPools)
{
var aphl = new WebAppPoolHelper(ProviderSettings);
// Site isolation mode
var sisMode = site.DedicatedApplicationPool ? SiteAppPoolMode.Dedicated : SiteAppPoolMode.Shared;
// Create dedicated iisAppObject pool name for the site with installed ASP.NET version
if (createAppPools && site.DedicatedApplicationPool)
{
// Find dedicated app pools
var dedicatedPools = Array.FindAll<WebAppPool>(aphl.SupportedAppPools.ToArray(),
x => aphl.isolation(x.Mode) == SiteAppPoolMode.Dedicated);
// Generate dedicated iisAppObject pools names and create them.
foreach (var item in dedicatedPools)
{
// Retrieve .NET Framework version
var dotNetVersion = aphl.dotNetVersion(item.Mode);
//
var enable32BitAppOnWin64 = Enable32BitAppOnWin64;
// Force "enable32BitAppOnWin64" set to true for .NET v1.1
if (dotNetVersion == SiteAppPoolMode.dotNetFramework1)
enable32BitAppOnWin64 = true;
//
var poolName = WSHelper.InferAppPoolName(item.Name, site.Name, item.Mode);
// Ensure we are not going to add an existing app pool
if (webObjectsSvc.IsApplicationPoolExist(poolName))
continue;
//
using (var srvman = webObjectsSvc.GetServerManager())
{
// Create iisAppObject pool
var pool = srvman.ApplicationPools.Add(poolName);
pool.ManagedRuntimeVersion = aphl.aspnet_runtime(item.Mode);
pool.ManagedPipelineMode = aphl.runtime_pipeline(item.Mode);
pool.Enable32BitAppOnWin64 = enable32BitAppOnWin64;
pool.AutoStart = true;
// Identity
pool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;
pool.ProcessModel.UserName = GetQualifiedAccountName(site.AnonymousUsername);
pool.ProcessModel.Password = site.AnonymousUserPassword;
// Commit changes
srvman.CommitChanges();
}
}
}
// Find
var siteAppPool = Array.Find<WebAppPool>(aphl.SupportedAppPools.ToArray(),
x => x.AspNetInstalled.Equals(site.AspNetInstalled) && aphl.isolation(x.Mode) == sisMode);
// Assign iisAppObject pool according to ASP.NET version installed and isolation mode specified.
site.ApplicationPool = WSHelper.InferAppPoolName(siteAppPool.Name, site.Name, siteAppPool.Mode);
}
private void CheckEnableWritePermissions(ServerManager srvman, WebVirtualDirectory virtualDir)
{
string anonymousUsername = virtualDir.AnonymousUsername;
//
if (virtualDir.DedicatedApplicationPool)
{
ApplicationPool appPool = webObjectsSvc.GetApplicationPool(srvman, virtualDir);
//
if (appPool != null)
anonymousUsername = appPool.ProcessModel.UserName;
}
//
if (!String.IsNullOrEmpty(anonymousUsername))
virtualDir.EnableWritePermissions = CheckWriteAccessEnabled(virtualDir.ContentPath,
GetNonQualifiedAccountName(anonymousUsername));
}
#endregion
#region IWebServer Members
public override void ChangeSiteState(string siteId, ServerState state)
{
webObjectsSvc.ChangeSiteState(siteId, state);
}
public override ServerState GetSiteState(string siteId)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
return GetSiteState(srvman, siteId);
}
}
public ServerState GetSiteState(ServerManager srvman, string siteId)
{
return webObjectsSvc.GetSiteState(srvman, siteId);
}
public override bool SiteExists(string siteId)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
return webObjectsSvc.SiteExists(srvman, siteId);
}
}
public override string[] GetSites()
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
return webObjectsSvc.GetSites(srvman);
}
}
public new string GetSiteId(string siteName)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
return webObjectsSvc.GetWebSiteNameFromIIS(srvman, siteName);
}
}
public override WebSite GetSite(string siteId)
{
WebSite site = null;
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
WebAppPoolHelper aphl = new WebAppPoolHelper(ProviderSettings);
//
site = webObjectsSvc.GetWebSiteFromIIS(srvman, siteId);
//
site.Bindings = webObjectsSvc.GetSiteBindings(srvman, siteId);
//
FillVirtualDirectoryFromIISObject(srvman, site);
//
FillVirtualDirectoryRestFromIISObject(srvman, site);
// check frontpage
site.FrontPageAvailable = IsFrontPageSystemInstalled();
site.FrontPageInstalled = IsFrontPageInstalled(srvman, siteId);
//check ColdFusion
if (IsColdFusionSystemInstalled())
{
if (IsColdFusion7Installed())
{
site.ColdFusionVersion = "7";
site.ColdFusionAvailable = true;
}
else
{
if (IsColdFusion8Installed())
{
site.ColdFusionVersion = "8";
site.ColdFusionAvailable = true;
}
}
if (IsColdFusion9Installed())
{
site.ColdFusionVersion = "9";
site.ColdFusionAvailable = true;
}
}
else
{
site.ColdFusionAvailable = false;
}
site.CreateCFVirtualDirectories = ColdFusionDirectoriesAdded(srvman, siteId);
//site.ColdFusionInstalled = IsColdFusionEnabledOnSite(GetSiteId(site.Name));
// check sharepoint
site.SharePointInstalled = false;
//
site.DedicatedApplicationPool = !aphl.is_shared_pool(site.ApplicationPool);
//
CheckEnableWritePermissions(srvman, site);
//
ReadWebManagementAccessDetails(srvman, site);
//
ReadWebDeployPublishingAccessDetails(site);
//
site.SecuredFoldersInstalled = IsSecuredFoldersInstalled(srvman, siteId);
// check Helicon Ape
HeliconApeStatus heliconApeStatus = GetHeliconApeStatus(srvman, siteId);
site.HeliconApeInstalled = heliconApeStatus.IsInstalled;
site.HeliconApeEnabled = heliconApeStatus.IsEnabled;
//
site.SiteState = GetSiteState(srvman, siteId);
//
site.SecuredFoldersInstalled = IsSecuredFoldersInstalled(srvman, siteId);
//
site.SiteState = GetSiteState(srvman, siteId);
//
}
return site;
}
public new string[] GetSitesAccounts(string[] siteIds)
{
List<string> accounts = new List<string>();
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
for (int i = 0; i < siteIds.Length; i++)
{
try
{
accounts.Add((string)anonymAuthSvc.GetAuthenticationSettings(srvman, siteIds[i])[AuthenticationGlobals.AnonymousAuthenticationUserName]);
}
catch (Exception ex)
{
Log.WriteError(String.Format("Web site {0} is either deleted or doesn't exist", siteIds[i]), ex);
}
}
}
return accounts.ToArray();
}
public override ServerBinding[] GetSiteBindings(string siteId)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
return webObjectsSvc.GetSiteBindings(srvman, siteId);
}
}
public override string CreateSite(WebSite site)
{
// assign site id
site.SiteId = site.Name;
// create anonymous user
CreateWebSiteAnonymousAccount(site);
// Grant IIS_WPG group membership to site's anonymous account
SecurityUtils.GrantLocalGroupMembership(site.AnonymousUsername, IIS_IUSRS_GROUP, ServerSettings);
// set iisAppObject pools
SetWebSiteApplicationPool(site, true);
// set folder permissions
SetWebFolderPermissions(site.ContentPath, GetNonQualifiedAccountName(site.AnonymousUsername),
site.EnableWritePermissions, site.DedicatedApplicationPool);
// set DATA folder permissions
SetWebFolderPermissions(site.DataPath, GetNonQualifiedAccountName(site.AnonymousUsername),
true, site.DedicatedApplicationPool);
// qualify account name with AD Domain
site.AnonymousUsername = GetQualifiedAccountName(site.AnonymousUsername);
//
try
{
// Create site
webObjectsSvc.CreateSite(site);
// Update web site bindings
webObjectsSvc.UpdateSiteBindings(site.SiteId, site.Bindings);
// Set web site logging settings
webObjectsSvc.SetWebSiteLoggingSettings(site);
}
catch (Exception ex)
{
Log.WriteError(ex);
}
//
SetAnonymousAuthentication(site);
// create logs folder if not exists
if (!FileUtils.DirectoryExists(site.LogsPath))
FileUtils.CreateDirectory(site.LogsPath);
//
FillIISObjectFromVirtualDirectory(site);
//
FillIISObjectFromVirtualDirectoryRest(site);
//
UpdateCgiBinFolder(site);
//
try
{
webObjectsSvc.ChangeSiteState(site.SiteId, ServerState.Started);
}
catch (Exception ex)
{
Log.WriteError(ex);
}
//
return site.SiteId;
}
public override void UpdateSite(WebSite site)
{
// load original site settings
WebSite origSite = GetSite(site.SiteId);
// Get non-qualified anonymous account user name (eq. without domain name or machine name)
string anonymousAccount = GetNonQualifiedAccountName(site.AnonymousUsername);
string origAnonymousAccount = GetNonQualifiedAccountName(origSite.AnonymousUsername);
// if folder has been changed
if (String.Compare(origSite.ContentPath, site.ContentPath, true) != 0)
RemoveWebFolderPermissions(origSite.ContentPath, origAnonymousAccount);
// ensure anonumous user account exists
if (!SecurityUtils.UserExists(anonymousAccount, ServerSettings, UsersOU))
{
CreateWebSiteAnonymousAccount(site);
}
anonymousAccount = GetNonQualifiedAccountName(site.AnonymousUsername);
// Grant IIS_IUSRS group membership
if (!SecurityUtils.HasLocalGroupMembership(anonymousAccount, IIS_IUSRS_GROUP, ServerSettings, UsersOU))
{
SecurityUtils.GrantLocalGroupMembership(anonymousAccount, IIS_IUSRS_GROUP, ServerSettings);
}
//
bool appPoolFlagChanged = origSite.DedicatedApplicationPool != site.DedicatedApplicationPool;
// check if we need to remove dedicated app pools
bool deleteDedicatedPools = (appPoolFlagChanged && !site.DedicatedApplicationPool);
//
SetWebSiteApplicationPool(site, false);
//
if (!webObjectsSvc.IsApplicationPoolExist(site.ApplicationPool) &&
site.DedicatedApplicationPool)
{
// CREATE dedicated pool
SetWebSiteApplicationPool(site, true);
}
//
FillIISObjectFromVirtualDirectory(site);
//
FillIISObjectFromVirtualDirectoryRest(site);
// set logs folder permissions
if (!FileUtils.DirectoryExists(site.LogsPath))
FileUtils.CreateDirectory(site.LogsPath);
// Update website
webObjectsSvc.UpdateSite(site);
// Update website bindings
webObjectsSvc.UpdateSiteBindings(site.SiteId, site.Bindings);
// Set website logging settings
webObjectsSvc.SetWebSiteLoggingSettings(site);
//
UpdateCgiBinFolder(site);
// TO-DO
// update all child virtual directories to use new pool
if (appPoolFlagChanged)
{
WebVirtualDirectory[] dirs = GetVirtualDirectories(site.SiteId);
foreach (WebVirtualDirectory dir in dirs)
{
// set dedicated pool flag
//dir.DedicatedApplicationPool = site.DedicatedApplicationPool;
WebVirtualDirectory vdir = GetVirtualDirectory(site.SiteId, dir.Name);
vdir.AspNetInstalled = site.AspNetInstalled;
vdir.ApplicationPool = site.ApplicationPool;
// update iisDirObject
UpdateVirtualDirectory(site.SiteId, vdir);
}
// Enforce Web Deploy publishing settings if enabled to ensure we use correct settings all the time
if (site.WebDeploySitePublishingEnabled == true)
{
EnforceDelegationRulesRestrictions(site.Name, site.WebDeployPublishingAccount);
}
}
#region ColdFusion Virtual Directories
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
//TODO: NANOFIX:Added the If block and put the rest of the code in the else block(For Virtual Directory)
if (string.IsNullOrEmpty(base.CFFlashRemotingDirPath))
{
DeleteCFVirtualDirectories(site.SiteId);
site.CreateCFVirtualDirectories = false;
}
else
{
if (ColdFusionDirectoriesAdded(srvman, site.SiteId))
{
if (!site.CreateCFVirtualDirectories)
{
DeleteCFVirtualDirectories(site.SiteId);
site.CreateCFVirtualDirectories = false;
}
}
else
{
if (site.CreateCFVirtualDirectories)
{
CreateCFVirtualDirectories(site.SiteId);
site.CreateCFVirtualDirectories = true;
}
}
}
}
#endregion
#region ColdFusionHandlerFix
//TODO: NANOFIX: Region Added for Cold Fusion Handler Fix
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
var appConfig = srvman.GetApplicationHostConfiguration();
ConfigurationSection handlersSection = appConfig.GetSection(Constants.HandlersSection, (site as WebVirtualDirectory).FullQualifiedPath);
var handlersCollection = handlersSection.GetCollection();
List<ConfigurationElement> cfElementList = new List<ConfigurationElement>();
foreach (var action in handlersCollection)
{
var name = action["name"].ToString();
if (string.Compare(name, "coldfusion", true) == 0)
{
cfElementList.Add(action);
}
}
foreach (var e in cfElementList)
{
handlersCollection.Remove(e);
}
if (site.ColdFusionInstalled)
{
var cfElement = handlersCollection.CreateElement("add");
cfElement["name"] = "coldfusion";
cfElement["modules"] = "IsapiModule";
cfElement["path"] = "*";
cfElement["scriptProcessor"] = base.ColdFusionPath;
cfElement["verb"] = "*";
cfElement["resourceType"] = "Unspecified";
cfElement["requireAccess"] = "None";
cfElement["preCondition"] = "bitness64";
handlersCollection.AddAt(0, cfElement);
}
srvman.CommitChanges();
}
#endregion
// remove dedicated pools if any
if (deleteDedicatedPools)
DeleteDedicatedPoolsAllocated(site.Name);
// set WEB folder permissions
SetWebFolderPermissions(site.ContentPath, anonymousAccount, site.EnableWritePermissions, site.DedicatedApplicationPool);
// set DATA folder permissions
SetWebFolderPermissions(site.DataPath, anonymousAccount, true, site.DedicatedApplicationPool);
}
/// <summary>
/// Updates site's bindings with supplied ones.
/// </summary>
/// <param name="siteId">Site's id to update bindings for.</param>
/// <param name="bindings">Bindings information.</param>
public override void UpdateSiteBindings(string siteId, ServerBinding[] bindings)
{
this.webObjectsSvc.UpdateSiteBindings(siteId, bindings);
}
/// <summary>
/// Deletes site with specified id.
/// </summary>
/// <param name="siteId">Site's id to be deleted.</param>
public override void DeleteSite(string siteId)
{
// Load site description.
WebSite site = this.GetSite(siteId);
#region Fix for bug #594
// Disable Remote Management Access and revoke access permissions if any
if (IsWebManagementServiceInstalled() && IsWebManagementAccessEnabled(site))
{
RevokeWebManagementAccess(siteId, site[WebSite.WmSvcAccountName]);
}
#endregion
// Disable Web Deploy publishing functionality and revoke access permissions if any
if (IsWebDeployInstalled() && site.WebDeploySitePublishingEnabled)
{
RevokeWebDeployPublishingAccess(site.SiteId, site.WebDeployPublishingAccount);
}
// Get non-qualified account name
string anonymousAccount = GetNonQualifiedAccountName(site.AnonymousUsername);
// Remove unnecessary permissions.
RemoveWebFolderPermissions(site.ContentPath, anonymousAccount);
// Stop web site
webObjectsSvc.ChangeSiteState(site.Name, ServerState.Stopped);
Log.WriteInfo(String.Format("Site {0} was stopped before deleting.", site.Name));
// Delete site in IIS
webObjectsSvc.DeleteSite(siteId);
// Delete dedicated pool if required
if (site.DedicatedApplicationPool)
{
DeleteDedicatedPoolsAllocated(site.Name);
}
// ensure anonymous account is shared account
if (!String.Equals("IUSR", anonymousAccount))
{
// Revoke IIS_IUSRS membership first
if (SecurityUtils.HasLocalGroupMembership(anonymousAccount, IIS_IUSRS_GROUP, ServerSettings, UsersOU))
{
SecurityUtils.RevokeLocalGroupMembership(anonymousAccount, IIS_IUSRS_GROUP, ServerSettings);
}
// delete anonymous user account
if (SecurityUtils.UserExists(anonymousAccount, ServerSettings, UsersOU))
{
SecurityUtils.DeleteUser(anonymousAccount, ServerSettings, UsersOU);
}
}
}
/// <summary>
/// Checks whether virtual iisDirObject with supplied name under specified site exists.
/// </summary>
/// <param name="siteId">Site id.</param>
/// <param name="directoryName">Directory name to check.</param>
/// <returns>true - if it exists; false - otherwise.</returns>
public override bool VirtualDirectoryExists(string siteId, string directoryName)
{
return this.webObjectsSvc.VirtualDirectoryExists(siteId, directoryName);
}
/// <summary>
/// Gets virtual directories that belong to site with supplied id.
/// </summary>
/// <param name="siteId">Site's id to get virtual directories for.</param>
/// <returns>virtual directories that belong to site with supplied id.</returns>
public override WebVirtualDirectory[] GetVirtualDirectories(string siteId)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
return GetVirtualDirectories(srvman, siteId);
}
}
private WebVirtualDirectory[] GetVirtualDirectories(ServerManager srvman, string siteId)
{
// get all virt dirs
WebVirtualDirectory[] virtDirs = webObjectsSvc.GetVirtualDirectories(srvman, siteId);
// filter
string sharedToolsFolder = GetMicrosoftSharedFolderPath();
List<WebVirtualDirectory> result = new List<WebVirtualDirectory>();
foreach (WebVirtualDirectory dir in virtDirs)
{
// check if this is a system (FrontPage or SharePoint) virtual iisDirObject
if (!String.IsNullOrEmpty(sharedToolsFolder)
&& dir.ContentPath.ToLower().StartsWith(sharedToolsFolder.ToLower()))
continue;
result.Add(dir);
}
return result.ToArray();
}
/// <summary>
/// Gets virtual iisDirObject description that belongs to site with supplied id and has specified name.
/// </summary>
/// <param name="siteId">Site's id that owns virtual iisDirObject.</param>
/// <param name="directoryName">Directory's name to get description for.</param>
/// <returns>virtual iisDirObject description that belongs to site with supplied id and has specified name.</returns>
public override WebVirtualDirectory GetVirtualDirectory(string siteId, string directoryName)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
WebAppPoolHelper aphl = new WebAppPoolHelper(ProviderSettings);
//
WebVirtualDirectory webVirtualDirectory = webObjectsSvc.GetVirtualDirectory(siteId, directoryName);
//
this.FillVirtualDirectoryFromIISObject(srvman, webVirtualDirectory);
this.FillVirtualDirectoryRestFromIISObject(srvman, webVirtualDirectory);
//
webVirtualDirectory.DedicatedApplicationPool = !aphl.is_shared_pool(webVirtualDirectory.ApplicationPool);
//
CheckEnableWritePermissions(srvman, webVirtualDirectory);
//
ReadWebManagementAccessDetails(srvman, webVirtualDirectory);
//
ReadWebDeployPublishingAccessDetails(webVirtualDirectory);
//
return webVirtualDirectory;
}
}
/// <summary>
/// Creates virtual iisDirObject under site with specified id.
/// </summary>
/// <param name="siteId">Site's id to create virtual iisDirObject under.</param>
/// <param name="iisDirObject">Virtual iisDirObject description.</param>
public override void CreateVirtualDirectory(string siteId, WebVirtualDirectory directory)
{
// Create iisDirObject folder if not exists.
if (!FileUtils.DirectoryExists(directory.ContentPath))
{
FileUtils.CreateDirectory(directory.ContentPath);
}
//
WebSite webSite = GetSite(siteId);
// copy props from parent site
directory.ParentSiteName = siteId;
directory.AspNetInstalled = webSite.AspNetInstalled;
directory.ApplicationPool = webSite.ApplicationPool;
// Create record in IIS's configuration.
webObjectsSvc.CreateVirtualDirectory(siteId, directory.VirtualPath, directory.ContentPath);
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
PropertyBag bag = anonymAuthSvc.GetAuthenticationSettings(srvman, siteId);
directory.AnonymousUsername = (string)bag[AuthenticationGlobals.AnonymousAuthenticationUserName];
directory.AnonymousUserPassword = (string)bag[AuthenticationGlobals.AnonymousAuthenticationPassword];
directory.EnableAnonymousAccess = (bool)bag[AuthenticationGlobals.Enabled];
// Update virtual iisDirObject.
this.UpdateVirtualDirectory(siteId, directory);
}
}
/// <summary>
/// Updates virtual iisDirObject settings.
/// </summary>
/// <param name="siteId">Site's id that owns supplied iisDirObject.</param>
/// <param name="iisDirObject">Web iisDirObject that needs to be updated.</param>
public override void UpdateVirtualDirectory(string siteId, WebVirtualDirectory directory)
{
string origPath = null;
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
if (!this.webObjectsSvc.SiteExists(srvman, siteId))
return;
// get original path
origPath = webObjectsSvc.GetPhysicalPath(srvman, directory);
}
WebAppPoolHelper aphl = new WebAppPoolHelper(ProviderSettings);
//
bool dedicatedPool = !aphl.is_shared_pool(directory.ApplicationPool);
//
SiteAppPoolMode sisMode = dedicatedPool ? SiteAppPoolMode.Dedicated : SiteAppPoolMode.Shared;
//
directory.ParentSiteName = siteId;
// remove unnecessary permissions
// if original folder has been changed
if (String.Compare(origPath, directory.ContentPath, true) != 0)
RemoveWebFolderPermissions(origPath, GetNonQualifiedAccountName(directory.AnonymousUsername));
// set folder permissions
SetWebFolderPermissions(directory.ContentPath, GetNonQualifiedAccountName(directory.AnonymousUsername),
directory.EnableWritePermissions, dedicatedPool);
//
var pool = Array.Find<WebAppPool>(aphl.SupportedAppPools.ToArray(),
x => x.AspNetInstalled.Equals(directory.AspNetInstalled) && aphl.isolation(x.Mode) == sisMode);
// Assign to virtual iisDirObject iisAppObject pool
directory.ApplicationPool = WSHelper.InferAppPoolName(pool.Name, siteId, pool.Mode);
//
webObjectsSvc.UpdateVirtualDirectory(directory);
//
this.FillIISObjectFromVirtualDirectory(directory);
this.FillIISObjectFromVirtualDirectoryRest(directory);
}
/// <summary>
/// Deletes virtual iisDirObject within specified site.
/// </summary>
/// <param name="siteId">Site id.</param>
/// <param name="directoryName">Directory name to delete.</param>
public override void DeleteVirtualDirectory(string siteId, string directoryName)
{
var virtualDir = new WebVirtualDirectory
{
ParentSiteName = siteId,
Name = directoryName
};
//
webObjectsSvc.DeleteVirtualDirectory(virtualDir);
anonymAuthSvc.RemoveAuthenticationSettings(virtualDir.FullQualifiedPath);
}
public new void GrantWebSiteAccess(string path, string siteId, NTFSPermission permission)
{
// TODO
}
#endregion
#region IISPassword
protected override bool IsSecuredFoldersInstalled(string siteId)
{
using (var srvman = webObjectsSvc.GetServerManager())
{
return IsSecuredFoldersInstalled(srvman, siteId);
}
}
private bool IsSecuredFoldersInstalled(ServerManager srvman, string siteId)
{
var appConfig = srvman.GetApplicationHostConfiguration();
//
var modulesSection = appConfig.GetSection(Constants.ModulesSection, siteId);
//
var modulesCollection = modulesSection.GetCollection();
//
foreach (var moduleEntry in modulesCollection)
{
if (String.Equals(moduleEntry["name"].ToString(), Constants.WEBSITEPANEL_IISMODULES, StringComparison.InvariantCultureIgnoreCase))
return true;
}
//
return false;
}
protected override string GetSiteContentPath(string siteId)
{
using (var srvman = webObjectsSvc.GetServerManager())
{
return GetSiteContentPath(srvman, siteId);
}
}
protected string GetSiteContentPath(ServerManager srvman, string siteId)
{
var webSite = webObjectsSvc.GetWebSiteFromIIS(srvman, siteId);
//
if (webSite != null)
return webObjectsSvc.GetPhysicalPath(srvman, webSite);
//
return String.Empty;
}
/// <summary>
///
/// </summary>
/// <exception cref="System.ArgumentNullException" />
/// <exception cref="System.ApplicationException" />
/// <param name="siteId"></param>
public override void InstallSecuredFolders(string siteId)
{
using (var srvman = webObjectsSvc.GetServerManager())
{
//
if (String.IsNullOrEmpty(siteId))
throw new ArgumentNullException("siteId");
// WebsitePanel.IIsModules works for apps working in Integrated Pipeline mode
#region Switch automatically to the app pool with Integrated Pipeline enabled
var webSite = webObjectsSvc.GetWebSiteFromIIS(srvman, siteId);
//
if (webSite == null)
throw new ApplicationException(String.Format("Could not find a web site with the following identifier: {0}.", siteId));
//
var aphl = new WebAppPoolHelper(ProviderSettings);
// Fill ASP.NET settings
FillAspNetSettingsFromIISObject(srvman, webSite);
//
var currentPool = aphl.match_webapp_pool(webSite);
var dotNetVersion = aphl.dotNetVersion(currentPool.Mode);
var sisMode = aphl.isolation(currentPool.Mode);
// AT least ASP.NET 2.0 is allowed to provide such capabilities...
if (dotNetVersion == SiteAppPoolMode.dotNetFramework1)
dotNetVersion = SiteAppPoolMode.dotNetFramework2;
// and Integrated pipeline...
if (aphl.pipeline(currentPool.Mode) != SiteAppPoolMode.Integrated)
{
// Lookup for the opposite pool matching the criteria
var oppositePool = Array.Find<WebAppPool>(aphl.SupportedAppPools.ToArray(),
x => aphl.dotNetVersion(x.Mode) == dotNetVersion && aphl.isolation(x.Mode) == sisMode
&& aphl.pipeline(x.Mode) == SiteAppPoolMode.Integrated);
//
webSite.AspNetInstalled = oppositePool.AspNetInstalled;
//
SetWebSiteApplicationPool(webSite, false);
//
var iisSiteObject = srvman.Sites[siteId];
iisSiteObject.Applications["/"].ApplicationPoolName = webSite.ApplicationPool;
//
srvman.CommitChanges();
}
}
#endregion
#region Disable automatically Integrated Windows Authentication
//
using (var srvman = webObjectsSvc.GetServerManager())
{
PropertyBag winAuthBag = winAuthSvc.GetAuthenticationSettings(srvman, siteId);
//
if ((bool)winAuthBag[AuthenticationGlobals.Enabled])
{
Configuration config = srvman.GetApplicationHostConfiguration();
ConfigurationSection windowsAuthenticationSection = config.GetSection(
"system.webServer/security/authentication/windowsAuthentication",
siteId);
//
windowsAuthenticationSection["enabled"] = false;
//
srvman.CommitChanges();
}
}
#endregion
//
using (var srvman = webObjectsSvc.GetServerManager())
{
//
Configuration appConfig = srvman.GetApplicationHostConfiguration();
//
ConfigurationSection modulesSection = appConfig.GetSection(Constants.ModulesSection, siteId);
//
ConfigurationElementCollection modulesCollection = modulesSection.GetCollection();
//
ConfigurationElement moduleAdd = modulesCollection.CreateElement("add");
//
moduleAdd["name"] = Constants.WEBSITEPANEL_IISMODULES;
moduleAdd["type"] = SecureFoldersModuleAssembly;
// Enable module for all content despite ASP.NET is enabled or not
moduleAdd["preCondition"] = "";
//
modulesCollection.Add(moduleAdd);
//
srvman.CommitChanges();
}
}
public override void UninstallSecuredFolders(string siteId)
{
//
if (String.IsNullOrEmpty(siteId))
throw new ArgumentNullException("siteId");
//
using (var srvman = webObjectsSvc.GetServerManager())
{
//
Configuration appConfig = srvman.GetApplicationHostConfiguration();
//
ConfigurationSection modulesSection = appConfig.GetSection(Constants.ModulesSection, siteId);
//
ConfigurationElementCollection modulesCollection = modulesSection.GetCollection();
//
ConfigurationElement iisModulesEntry = null;
//
foreach (ConfigurationElement moduleEntry in modulesCollection)
{
if (String.Equals(moduleEntry["name"].ToString(), Constants.WEBSITEPANEL_IISMODULES, StringComparison.InvariantCultureIgnoreCase))
{
iisModulesEntry = moduleEntry;
break;
}
}
//
if (iisModulesEntry != null)
{
modulesCollection.Remove(iisModulesEntry);
srvman.CommitChanges();
}
}
}
#endregion
#region Helicon Ape
public override HeliconApeStatus GetHeliconApeStatus(string siteId)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
return GetHeliconApeStatus(srvman, siteId);
}
}
private HeliconApeStatus GetHeliconApeStatus(ServerManager srvman, string siteId)
{
string installDir = GetHeliconApeInstallDir(siteId);
string registrationInfo = GetRegistrationInfo(siteId, installDir);
return new HeliconApeStatus
{
IsEnabled = IsHeliconApeEnabled(srvman, siteId),
InstallDir = installDir,
IsInstalled = IsHeliconApeInstalled(srvman, siteId, installDir),
Version = GetHeliconApeVersion(siteId, installDir),
IsRegistered = IsHeliconApeRegistered(siteId, registrationInfo),
RegistrationInfo = registrationInfo
};
}
private bool IsHeliconApeEnabled(ServerManager srvman, string siteId)
{
var appConfig = srvman.GetApplicationHostConfiguration();
var modulesSection = appConfig.GetSection(Constants.ModulesSection, siteId);
var modulesCollection = modulesSection.GetCollection();
foreach (var moduleEntry in modulesCollection)
{
if (String.Equals(moduleEntry["name"].ToString(), Constants.HeliconApeModule, StringComparison.InvariantCultureIgnoreCase))
return true;
}
//
return false;
}
/// <summary>
/// Creates the specified account and grants it Web Publishing Access permissions
/// </summary>
/// <param name="siteName">Web site name to enable Web Publishing Access at</param>
/// <param name="accountName">User name to grant the access for</param>
/// <param name="accountPassword">User password</param>
public new void GrantWebDeployPublishingAccess(string siteName, string accountName, string accountPassword)
{
// Web Publishing Access feature requires FullControl permissions on the web site's wwwroot folder
GrantWebManagementAccessInternally(siteName, accountName, accountPassword, NTFSPermission.FullControl);
//
EnforceDelegationRulesRestrictions(siteName, accountName);
}
/// <summary>
/// Creates the specified account and grants it Web Publishing Access permissions
/// </summary>
/// <param name="siteName">Web site name to enable Web Publishing Access at</param>
/// <param name="accountName">User name to grant the access for</param>
/// <param name="accountPassword">User password</param>
public new void RevokeWebDeployPublishingAccess(string siteName, string accountName)
{
// Web Publishing Access feature requires FullControl permissions on the web site's wwwroot folder
RevokeWebManagementAccess(siteName, accountName);
//
RemoveDelegationRulesRestrictions(siteName, accountName);
}
private void RemoveDelegationRulesRestrictions(string siteName, string accountName)
{
WebSite webSite = null;
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
webSite = webObjectsSvc.GetWebSiteFromIIS(srvman, siteName);
}
var moduleService = new DelegationRulesModuleService();
// Adjust web publishing permissions to the user accordingly to deny some rules for shared app pools
var fqUsername = GetFullQualifiedAccountName(accountName);
// Instantiate application pool helper to retrieve the app pool mode web site is running in
WebAppPoolHelper aphl = new WebAppPoolHelper(ProviderSettings);
//
// Shared app pool is a subject restrictions to change ASP.NET version and recycle the pool,
// so we need to remove these restrictions
if (aphl.is_shared_pool(webSite.ApplicationPool) == true)
{
//
moduleService.RemoveUserFromRule("recycleApp", "{userScope}", fqUsername);
moduleService.RemoveUserFromRule("appPoolPipeline,appPoolNetFx", "{userScope}", fqUsername);
}
}
public void EnforceDelegationRulesRestrictions(string siteName, string accountName)
{
WebSite webSite = null;
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
webSite = webObjectsSvc.GetWebSiteFromIIS(srvman, siteName);
}
var moduleService = new DelegationRulesModuleService();
// Adjust web publishing permissions to the user accordingly to deny some rules for shared app pools
var fqUsername = GetFullQualifiedAccountName(accountName);
// Instantiate application pool helper to retrieve the app pool mode web site is running in
WebAppPoolHelper aphl = new WebAppPoolHelper(ProviderSettings);
// Shared app pool is a subject restrictions to change ASP.NET version and recycle the pool
if (aphl.is_shared_pool(webSite.ApplicationPool) == true)
{
//
moduleService.RestrictRuleToUser("recycleApp", "{userScope}", fqUsername);
moduleService.RestrictRuleToUser("appPoolPipeline,appPoolNetFx", "{userScope}", fqUsername);
}
// Dedicated app pool is not a subject for any restrictions
else
{
//
moduleService.AllowRuleToUser("recycleApp", "{userScope}", fqUsername);
moduleService.AllowRuleToUser("appPoolPipeline,appPoolNetFx", "{userScope}", fqUsername);
}
}
private string GetHeliconApeInstallDir(string siteId)
{
//Check global registration
return Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Helicon\\Ape", "InstallDir", string.Empty) as string;
}
private bool IsHeliconApeInstalled(ServerManager srvman, string siteId, string installDir)
{
//Check global registration
bool result = !string.IsNullOrEmpty(installDir);
if (!result && !string.IsNullOrEmpty(siteId))
{
//Check per-site installation
string sitepath = GetSiteContentPath(srvman, siteId);
string dllPath = Path.Combine(sitepath, "Bin\\Helicon.Ape.dll");
result = File.Exists(dllPath);
}
return result;
}
private static string HELICON_APE_NOT_REGISTERED = "Not registered";
private string GetHeliconApeVersion(string siteId, string installDir)
{
if (string.IsNullOrEmpty(installDir))
return HELICON_APE_NOT_REGISTERED;
return System.Diagnostics.FileVersionInfo.GetVersionInfo(Path.Combine(installDir, "Helicon.Ape.Editor.dll")).FileVersion;
}
private string GetHeliconApeModuleType(string siteId)
{
string installDir = GetHeliconApeInstallDir(siteId);
string version = GetHeliconApeVersion(siteId, installDir);
if (version.Equals(HELICON_APE_NOT_REGISTERED))
{
// Ape installed for site
return "Helicon.Ape.ApeModule";
}
else
{
// Ape installed globally in GAC
// return full type with version
return
string.Format(
"Helicon.Ape.ApeModule, Helicon.Ape, Version={0}, Culture=neutral, PublicKeyToken=95bfbfd1a38437eb",
version);
}
}
private string GetHeliconApeHandlerType(string siteId)
{
string installDir = GetHeliconApeInstallDir(siteId);
string version = GetHeliconApeVersion(siteId, installDir);
if (version.Equals(HELICON_APE_NOT_REGISTERED))
{
// Ape installed for site
return "Helicon.Ape.Handler";
}
else
{
// Ape installed globally in GAC
// return full type with version
return
string.Format(
"Helicon.Ape.Handler, Helicon.Ape, Version={0}, Culture=neutral, PublicKeyToken=95bfbfd1a38437eb",
version);
}
}
private string FindregistrationInfo(string path)
{
System.Text.RegularExpressions.Regex reRegistrationName = new System.Text.RegularExpressions.Regex("^\\s*RegistrationName\\s*=\\s*([^#=]+)\\s*(?:#.*)?", System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.CultureInvariant | System.Text.RegularExpressions.RegexOptions.Compiled);
string registrationName = "";
using (StreamReader sr = File.OpenText(path))
{
while (sr.Peek() >= 0)
{
string line = sr.ReadLine();
if (reRegistrationName.Match(line).Success)
{
registrationName = reRegistrationName.Match(line).Groups[1].Value;
if (
!string.IsNullOrEmpty(registrationName)
)
{
return string.Format("Registered to: {0}", registrationName);
}
break;
}
}
}
//Not found
return string.Empty;
}
private string GetRegistrationInfo(string siteId, string installDir)
{
if (string.IsNullOrEmpty(installDir))
return string.Empty;
string registrationInfo = FindregistrationInfo(Path.Combine(installDir, "licenses.conf"));
if (!string.IsNullOrEmpty(registrationInfo))
return registrationInfo;
registrationInfo = FindregistrationInfo(Path.Combine(installDir, "httpd.conf"));
if (!string.IsNullOrEmpty(registrationInfo))
return registrationInfo;
long dtFirstRunBinary = (long)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Helicon\\Ape", "FirstRun", 0L);
DateTime dtFirstRun;
if (0 == dtFirstRunBinary)
{
dtFirstRun = DateTime.Now;
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Helicon\\Ape", "FirstRun", dtFirstRun.ToBinary(),RegistryValueKind.QWord );
}
else
{
dtFirstRun = DateTime.FromBinary(dtFirstRunBinary);
}
int trialDays = 45 - (DateTime.Now - dtFirstRun).Days;
if (trialDays < 0)
trialDays = 0;
return string.Format("Trial days left: {0}", trialDays);
}
private bool IsHeliconApeRegistered(string siteId, string registrationInfo)
{
if (string.IsNullOrEmpty(registrationInfo))
return false;
return registrationInfo.StartsWith("Registered to:");
}
public override void EnableHeliconApe(string siteId)
{
WebSite webSite = null;
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
//
if (String.IsNullOrEmpty(siteId))
throw new ArgumentNullException("siteId");
// Helicon.Ape.ApeModule works for apps working in Integrated Pipeline mode
// Switch automatically to the app pool with Integrated Pipeline enabled
webSite = webObjectsSvc.GetWebSiteFromIIS(srvman, siteId);
//
if (webSite == null)
throw new ApplicationException(String.Format("Could not find a web site with the following identifier: {0}.", siteId));
// Fill ASP.NET settings
FillAspNetSettingsFromIISObject(srvman, webSite);
}
//
var aphl = new WebAppPoolHelper(ProviderSettings);
var currentPool = aphl.match_webapp_pool(webSite);
var dotNetVersion = aphl.dotNetVersion(currentPool.Mode);
var sisMode = aphl.isolation(currentPool.Mode);
// AT least ASP.NET 2.0 is allowed to provide such capabilities...
if (dotNetVersion == SiteAppPoolMode.dotNetFramework1)
dotNetVersion = SiteAppPoolMode.dotNetFramework2;
// and Integrated pipeline...
if (aphl.pipeline(currentPool.Mode) != SiteAppPoolMode.Integrated)
{
// Lookup for the opposite pool matching the criteria
var oppositePool = Array.Find<WebAppPool>(aphl.SupportedAppPools.ToArray(),
x => aphl.dotNetVersion(x.Mode) == dotNetVersion && aphl.isolation(x.Mode) == sisMode
&& aphl.pipeline(x.Mode) == SiteAppPoolMode.Integrated);
//
webSite.AspNetInstalled = oppositePool.AspNetInstalled;
//
SetWebSiteApplicationPool(webSite, false);
//
using (var srvman = webObjectsSvc.GetServerManager())
{
var iisSiteObject = srvman.Sites[siteId];
iisSiteObject.Applications["/"].ApplicationPoolName = webSite.ApplicationPool;
//
srvman.CommitChanges();
}
}
#region Disable automatically Integrated Windows Authentication
using (var srvman = webObjectsSvc.GetServerManager())
{
PropertyBag winAuthBag = winAuthSvc.GetAuthenticationSettings(srvman, siteId);
//
if ((bool)winAuthBag[AuthenticationGlobals.Enabled])
{
Configuration config = srvman.GetApplicationHostConfiguration();
ConfigurationSection windowsAuthenticationSection = config.GetSection(
"system.webServer/security/authentication/windowsAuthentication",
siteId);
//
windowsAuthenticationSection["enabled"] = false;
//
srvman.CommitChanges();
}
}
#endregion
#region Disable automatically Secured Folders
if (IsSecuredFoldersInstalled(siteId))
{
UninstallSecuredFolders(siteId);
}
#endregion
//
using (var srvman = webObjectsSvc.GetServerManager())
{
//
Configuration appConfig = srvman.GetApplicationHostConfiguration();
// add Helicon.Ape module
ConfigurationSection modulesSection = appConfig.GetSection(Constants.ModulesSection, siteId);
ConfigurationElementCollection modulesCollection = modulesSection.GetCollection();
ConfigurationElement moduleAdd = modulesCollection.CreateElement("add");
moduleAdd["name"] = Constants.HeliconApeModule;
moduleAdd["type"] = GetHeliconApeModuleType(siteId);
//
modulesCollection.Add(moduleAdd);
// add Helicon.Ape handler
ConfigurationSection handlersSection = appConfig.GetSection(Constants.HandlersSection, siteId);
ConfigurationElementCollection handlersCollection = handlersSection.GetCollection();
ConfigurationElement handlerAdd = handlersCollection.CreateElement("add");
handlerAdd["name"] = Constants.HeliconApeModule;
handlerAdd["type"] = GetHeliconApeHandlerType(siteId);
handlerAdd["path"] = Constants.HeliconApeHandlerPath;
handlerAdd["verb"] = "*";
handlerAdd["resourceType"] = "Unspecified";
//
handlersCollection.Add(handlerAdd);
//
srvman.CommitChanges();
}
}
public override void DisableHeliconApe(string siteId)
{
//
if (String.IsNullOrEmpty(siteId))
throw new ArgumentNullException("siteId");
//
using (var srvman = webObjectsSvc.GetServerManager())
{
//
Configuration appConfig = srvman.GetApplicationHostConfiguration();
// remove Helicon.Ape module
ConfigurationSection modulesSection = appConfig.GetSection(Constants.ModulesSection, siteId);
ConfigurationElementCollection modulesCollection = modulesSection.GetCollection();
ConfigurationElement htaccessModuleEntry = null;
foreach (ConfigurationElement moduleEntry in modulesCollection)
{
if (String.Equals(moduleEntry["name"].ToString(), Constants.HeliconApeModule, StringComparison.InvariantCultureIgnoreCase))
{
htaccessModuleEntry = moduleEntry;
break;
}
}
if (htaccessModuleEntry != null)
{
modulesCollection.Remove(htaccessModuleEntry);
}
// remove Helicon.Ape handler
ConfigurationSection handlersSection = appConfig.GetSection(Constants.HandlersSection, siteId);
ConfigurationElementCollection handlersCollection = handlersSection.GetCollection();
ConfigurationElement htaccessHandlerEntry = null;
foreach (ConfigurationElement handlerEntry in handlersCollection)
{
if (String.Equals(handlerEntry["name"].ToString(), Constants.HeliconApeModule, StringComparison.InvariantCultureIgnoreCase))
{
htaccessHandlerEntry = handlerEntry;
break;
}
}
//
if (htaccessHandlerEntry != null)
{
handlersCollection.Remove(htaccessHandlerEntry);
}
// commit changes to metabase
if (htaccessModuleEntry != null || htaccessHandlerEntry != null)
{
srvman.CommitChanges();
}
}
}
public override List<HtaccessFolder> GetHeliconApeFolders(string siteId)
{
string siteRootPath = GetSiteContentPath(siteId);
List<HtaccessFolder> folders = new List<HtaccessFolder>();
// walk through the virtual directories
WebVirtualDirectory[] virtualDirectories = GetVirtualDirectories(siteId);
foreach (WebVirtualDirectory webVirtualDirectory in virtualDirectories)
{
HtaccessFolder.GetDirectoriesWithHtaccess(siteRootPath, "\\" + webVirtualDirectory.FullQualifiedPath, webVirtualDirectory.ContentPath, webVirtualDirectory.ContentPath, folders);
}
// walk through the filesystem
HtaccessFolder.GetDirectoriesWithHtaccess(siteRootPath, "", siteRootPath, siteRootPath, folders);
folders.Sort();
return folders;
}
public override HtaccessFolder GetHeliconApeFolder(string siteId, string folderPath)
{
// search folder
List<HtaccessFolder> htaccessFolders = GetHeliconApeFolders(siteId);
foreach (HtaccessFolder htaccessFolder in htaccessFolders)
{
if (string.Equals(folderPath, htaccessFolder.Path, StringComparison.OrdinalIgnoreCase))
{
htaccessFolder.ReadHtaccess();
return htaccessFolder;
}
}
// create new htaccess folder
return HtaccessFolder.CreateHtaccessFolder(GetSiteContentPath(siteId), folderPath);
}
public override HtaccessFolder GetHeliconApeHttpdFolder()
{
return HtaccessFolder.CreateHttpdConfFolder(GetHeliconApeInstallDir("-1"));
}
public override void UpdateHeliconApeFolder(string siteId, HtaccessFolder folder)
{
if (null != folder)
{
if (string.IsNullOrEmpty(folder.ContentPath))
{
HtaccessFolder newFolder = GetHeliconApeFolder(siteId, folder.Path);
newFolder.HtaccessContent = folder.HtaccessContent;
newFolder.Update();
}
else
{
if (string.IsNullOrEmpty(folder.SiteRootPath))
{
folder.SiteRootPath = GetSiteContentPath(siteId);
}
folder.Update();
}
}
}
public override void UpdateHeliconApeHttpdFolder(HtaccessFolder folder)
{
if (null != folder)
{
HtaccessFolder newFolder = GetHeliconApeHttpdFolder();
newFolder.HtaccessContent = folder.HtaccessContent;
newFolder.Update();
}
}
public override void DeleteHeliconApeFolder(string siteId, string folderPath)
{
string rootPath = GetSiteContentPath(siteId);
string contentPath = Path.Combine(rootPath, folderPath);
string htaccessPath = Path.Combine(contentPath, HtaccessFolder.HTACCESS_FILE);
if (File.Exists(htaccessPath))
{
File.Delete(htaccessPath);
}
return;
}
#endregion
#region Secured Helicon Ape Users
public static string GeneratePasswordHash(HtaccessUser user)
{
if (HtaccessFolder.AUTH_TYPE_BASIC == user.AuthType)
{
// BASIC
switch (user.EncType)
{
case HtaccessUser.ENCODING_TYPE_APACHE_MD5:
return PasswdHelper.MD5Encode(user.Password, PasswdHelper.GetRandomSalt());
case HtaccessUser.ENCODING_TYPE_SHA1:
return PasswdHelper.SHA1Encode(user.Password);
case HtaccessUser.ENCODING_TYPE_UNIX_CRYPT:
default:
BsdDES bsdDes = new BsdDES();
return bsdDes.Crypt(user.Password);
}
}
// DIGEST
return string.Format("{0}:{1}", user.Realm, PasswdHelper.DigestEncode(user.Name, user.Password, user.Realm));
}
public override List<HtaccessUser> GetHeliconApeUsers(string siteId)
{
string rootPath = GetSiteContentPath(siteId);
List<HtaccessUser> users = new List<HtaccessUser>();
//users.Add(new WebUser {Name = HtaccessFolder.VALID_USER});
// load users file
string usersPath = Path.Combine(rootPath, HtaccessFolder.HTPASSWDS_FILE);
List<string> lines = HtaccessFolder.ReadLinesFile(usersPath);
// iterate through all lines
for (int i = 0; i < lines.Count; i++)
{
string line = lines[i];
int colonIdx = line.IndexOf(":");
if (colonIdx != -1)
{
string username = line.Substring(0, colonIdx);
// add it to the return collection
users.Add(GetHeliconApeUser(siteId, username));
}
}
return users;
}
public override HtaccessUser GetHeliconApeUser(string siteId, string userName)
{
// load users file
string rootPath = GetSiteContentPath(siteId);
string usersPath = Path.Combine(rootPath, HtaccessFolder.HTPASSWDS_FILE);
List<string> lines = HtaccessFolder.ReadLinesFile(usersPath);
// iterate through all lines
HtaccessUser user = null;
for (int i = 0; i < lines.Count; i++)
{
string line = lines[i];
int colonIdx = line.IndexOf(":");
if (colonIdx != -1)
{
string username = line.Substring(0, colonIdx);
string password = line.Substring(colonIdx + 1);
if (String.Compare(username, userName, true) == 0)
{
// exists
user = new HtaccessUser();
user.Name = username;
user.Password = password;
break;
}
}
}
if (user == null)
return null; // user doesn't exist
List<string> userGroups = new List<string>();
// read groups information
// open groups file
string groupsPath = Path.Combine(rootPath, HtaccessFolder.HTGROUPS_FILE);
List<string> groupLines = HtaccessFolder.ReadLinesFile(groupsPath);
for (int i = 0; i < groupLines.Count; i++)
{
string groupLine = groupLines[i];
int colonIdx = groupLine.IndexOf(":");
if (colonIdx != -1)
{
string groupName = groupLine.Substring(0, colonIdx);
string[] groupMembers = groupLine.Substring(colonIdx + 1).Split(' ');
// check group members
for (int j = 0; j < groupMembers.Length; j++)
{
if (String.Compare(groupMembers[j], user.Name, true) == 0)
{
userGroups.Add(groupName);
break;
}
}
}
} // end iterating groups
user.Groups = userGroups.ToArray();
return user;
}
public override void UpdateHeliconApeUser(string siteId, HtaccessUser user)
{
UpdateHeliconApeUser(siteId, user, false);
}
private void UpdateHeliconApeUser(string siteId, HtaccessUser user, bool deleteUser)
{
if (HtaccessFolder.VALID_USER == user.Name)
return;
string rootPath = GetSiteContentPath(siteId);
string usersPath = Path.Combine(rootPath, HtaccessFolder.HTPASSWDS_FILE);
// load users file
List<string> lines = HtaccessFolder.ReadLinesFile(usersPath);
// check if the user already exists
List<string> updatedLines = new List<string>();
bool exists = false;
for (int i = 0; i < lines.Count; i++)
{
string line = lines[i];
string updatedLine = line;
int colonIdx = line.IndexOf(":");
if (colonIdx != -1)
{
string username = line.Substring(0, colonIdx);
string password = line.Substring(colonIdx + 1);
if (String.Compare(username, user.Name, true) == 0)
{
// already exists
exists = true;
// check if we need to delete this user
if (deleteUser)
continue;
// change password if required
if (!String.IsNullOrEmpty(user.Password))
{
// hash password
password = GeneratePasswordHash(user);
// update line
updatedLine = username + ":" + password;
}
}
}
updatedLines.Add(updatedLine);
}
if (!exists && !deleteUser)
{
// new user has been added
updatedLines.Add(user.Name + ":" + GeneratePasswordHash(user));
}
// save users file
HtaccessFolder.WriteLinesFile(usersPath, updatedLines);
if (user.Groups == null)
user.Groups = new string[] { };
// update groups
// open groups file
string groupsPath = Path.Combine(rootPath, HtaccessFolder.HTGROUPS_FILE);
List<string> groupLines = HtaccessFolder.ReadLinesFile(groupsPath);
for (int i = 0; i < groupLines.Count; i++)
{
string groupLine = groupLines[i];
int colonIdx = groupLine.IndexOf(":");
if (colonIdx != -1)
{
string groupName = groupLine.Substring(0, colonIdx);
string[] groupMembers = groupLine.Substring(colonIdx + 1).Split(' ');
// check if user is assigned to this group
bool assigned = false;
for (int j = 0; j < user.Groups.Length; j++)
{
if (String.Compare(user.Groups[j], groupName, true) == 0)
{
assigned = true;
break;
}
}
// remove current user
List<string> updatedMembers = new List<string>();
for (int j = 0; j < groupMembers.Length; j++)
{
// user exists in the members
// check if he should be really added to this group
if (String.Compare(groupMembers[j], user.Name, true) == 0)
continue;
updatedMembers.Add(groupMembers[j]);
}
if (assigned)
updatedMembers.Add(user.Name);
// modify group line
groupLines[i] = groupName + ":" + String.Join(" ", updatedMembers.ToArray());
}
} // end iterating groups
// save group file
HtaccessFolder.WriteLinesFile(groupsPath, groupLines);
}
public override void DeleteHeliconApeUser(string siteId, string userName)
{
string rootPath = GetSiteContentPath(siteId);
HtaccessUser user = new HtaccessUser();
user.Name = userName;
// update users and groups
UpdateHeliconApeUser(siteId, user, true);
// update foleds
//DeleteNonexistentUsersAndGroups(rootPath);
}
#endregion
#region Secured Helicon Ape Groups
public override List<WebGroup> GetHeliconApeGroups(string siteId)
{
string rootPath = GetSiteContentPath(siteId);
List<WebGroup> groups = new List<WebGroup>();
// open groups file
string groupsPath = Path.Combine(rootPath, HtaccessFolder.HTGROUPS_FILE);
List<string> groupLines = HtaccessFolder.ReadLinesFile(groupsPath);
for (int i = 0; i < groupLines.Count; i++)
{
string groupLine = groupLines[i];
int colonIdx = groupLine.IndexOf(":");
if (colonIdx != -1)
{
string name = groupLine.Substring(0, colonIdx);
// add group to the collection
groups.Add(GetHeliconApeGroup(siteId, name));
}
} // end iterating groups
return groups;
}
public override WebGroup GetHeliconApeGroup(string siteId, string groupName)
{
string rootPath = GetSiteContentPath(siteId);
// open groups file
string groupsPath = Path.Combine(rootPath, HtaccessFolder.HTGROUPS_FILE);
List<string> groupLines = HtaccessFolder.ReadLinesFile(groupsPath);
WebGroup group = null;
for (int i = 0; i < groupLines.Count; i++)
{
string groupLine = groupLines[i];
int colonIdx = groupLine.IndexOf(":");
if (colonIdx != -1)
{
string name = groupLine.Substring(0, colonIdx);
string[] members = groupLine.Substring(colonIdx + 1).Split(' ');
if (String.Compare(groupName, name, true) == 0)
{
group = new WebGroup();
group.Name = groupName;
group.Users = members;
}
}
} // end iterating groups
return group;
}
public override void UpdateHeliconApeGroup(string siteId, WebGroup group)
{
UpdateHeliconApeGroup(siteId, group, false);
}
private void UpdateHeliconApeGroup(string siteId, WebGroup group, bool deleteGroup)
{
string rootPath = GetSiteContentPath(siteId);
if (group.Users == null)
group.Users = new string[] { };
List<string> updatedGroups = new List<string>();
// open groups file
string groupsPath = Path.Combine(rootPath, HtaccessFolder.HTGROUPS_FILE);
List<string> groupLines = HtaccessFolder.ReadLinesFile(groupsPath);
bool exists = false;
for (int i = 0; i < groupLines.Count; i++)
{
string groupLine = groupLines[i];
int colonIdx = groupLine.IndexOf(":");
if (colonIdx != -1)
{
string name = groupLine.Substring(0, colonIdx);
// add group to the collection
if (String.Compare(group.Name, name, true) == 0)
{
exists = true;
if (deleteGroup)
continue;
// update group members
groupLine = group.Name + ":" + String.Join(" ", group.Users);
}
}
updatedGroups.Add(groupLine);
} // end iterating groups
if (!exists && !deleteGroup)
updatedGroups.Add(group.Name + ":" + String.Join(" ", group.Users));
// save groups
HtaccessFolder.WriteLinesFile(groupsPath, updatedGroups);
}
public override void DeleteHeliconApeGroup(string siteId, string groupName)
{
string rootPath = GetSiteContentPath(siteId);
// delete group
WebGroup group = new WebGroup();
group.Name = groupName;
UpdateHeliconApeGroup(siteId, group, true);
// update foleds
//DeleteNonexistentUsersAndGroups(rootPath);
}
#endregion
#region FrontPage
public override bool IsFrontPageInstalled(string siteId)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
return IsFrontPageInstalled(srvman, siteId);
}
}
private bool IsFrontPageInstalled(ServerManager srvman, string siteId)
{
// Get IIS web site id
string m_webSiteId = webObjectsSvc.GetWebSiteIdFromIIS(srvman, siteId, "W3SVC/{0}");
// site port
RegistryKey sitePortKey = Registry.LocalMachine.OpenSubKey(String.Format("{0}Port /LM/{1}:",
FRONTPAGE_PORT_REGLOC, m_webSiteId));
if (sitePortKey == null)
return false;
// get required keys
string keyAuthoring = (string)sitePortKey.GetValue("authoring");
string keyFrontPageRoot = (string)sitePortKey.GetValue("frontpageroot");
return (keyAuthoring != null && keyAuthoring.ToUpper() == "ENABLED" &&
keyFrontPageRoot != null && keyFrontPageRoot.IndexOf("\\50") != -1);
}
public override bool InstallFrontPage(string siteId, string username, string password)
{
// Ensure requested user account doesn't exist
if (SecurityUtils.UserExists(username, ServerSettings, UsersOU))
return false;
// Ensure a web site exists
if (!SiteExists(siteId))
return false;
// create user account
SystemUser user = new SystemUser
{
Name = username,
FullName = username,
Description = "WebsitePanel System Account",
Password = password,
PasswordCantChange = true,
PasswordNeverExpires = true,
AccountDisabled = false,
System = true,
};
// create in the system
SecurityUtils.CreateUser(user, ServerSettings, UsersOU, GroupsOU);
try
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
string cmdPath = null;
string cmdArgs = null;
//
string m_webSiteId = webObjectsSvc.GetWebSiteIdFromIIS(srvman, siteId, null);
// try to install FPSE2002
// add registry key for anonymous group if not exists
RegistryKey portsKey = Registry.LocalMachine.OpenSubKey(FRONTPAGE_ALLPORTS_REGLOC, true);
portsKey.SetValue("anonusergroupprefix", "anonfp");
#region Create anonymous group to get FPSE work
string groupName = "anonfp_" + m_webSiteId;
if (!SecurityUtils.GroupExists(groupName, ServerSettings, GroupsOU))
{
SystemGroup fpseGroup = new SystemGroup();
fpseGroup.Name = groupName;
fpseGroup.Description = "Anonymous FPSE group for " + siteId + " web site";
fpseGroup.Members = new string[] { username };
SecurityUtils.CreateGroup(fpseGroup, ServerSettings, UsersOU, GroupsOU);
}
#endregion
#region Install FPSE 2002 to the website by owsadm.exe install command
cmdPath = Environment.ExpandEnvironmentVariables(FPSE2002_OWSADM_PATH);
cmdArgs = String.Format("-o install -p /LM/W3SVC/{0} -u {1}", m_webSiteId, username);
Log.WriteInfo("Command path: " + cmdPath);
Log.WriteInfo("Command path: " + cmdArgs);
Log.WriteInfo("FPSE2002 Install Log: " + FileUtils.ExecuteSystemCommand(cmdPath, cmdArgs));
#endregion
}
// Enable Windows Authentication mode
winAuthSvc.SetEnabled(siteId, true);
}
catch (Exception ex)
{
Log.WriteError(ex);
// Signal to the client installation request has been failed.
return false;
}
return true;
}
public override void UninstallFrontPage(string siteId, string username)
{
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
// Ensure a web site exists
if (!webObjectsSvc.SiteExists(srvman, siteId))
return;
try
{
string m_webSiteId = webObjectsSvc.GetWebSiteIdFromIIS(srvman, siteId, null);
// remove anonymous group
string groupName = "anonfp_" + m_webSiteId;
if (SecurityUtils.GroupExists(groupName, ServerSettings, GroupsOU))
SecurityUtils.DeleteGroup(groupName, ServerSettings, GroupsOU);
#region Trying to uninstall FPSE2002 from the web site
//
string cmdPath = null;
string cmdArgs = null;
cmdPath = Environment.ExpandEnvironmentVariables(FPSE2002_OWSADM_PATH);
cmdArgs = String.Format("-o fulluninstall -p /LM/W3SVC/{0}", m_webSiteId);
// launch system process
Log.WriteInfo("FPSE2002 Uninstall Log: " + FileUtils.ExecuteSystemCommand(cmdPath, cmdArgs));
#endregion
// delete user account
if (SecurityUtils.UserExists(username, ServerSettings, UsersOU))
SecurityUtils.DeleteUser(username, ServerSettings, UsersOU);
// Disable Windows Authentication mode
winAuthSvc.SetEnabled(siteId, false);
}
catch (Exception ex)
{
Log.WriteError(String.Format("FPSE2002 uninstall error. Web site: {0}.", siteId), ex);
}
}
}
public override bool IsFrontPageSystemInstalled()
{
// we will lookup in the registry for the required information
// check for FPSE 2002
RegistryKey keyFrontPage = Registry.LocalMachine.OpenSubKey(FRONTPAGE_2002_REGLOC);
if (keyFrontPage == null)
return false;
string[] subKeys = keyFrontPage.GetSubKeyNames();
if (subKeys != null && subKeys.Length > 0)
{
foreach (string key in subKeys)
{
if (key == IIs60.FRONTPAGE_2002_INSTALLED || key == IIs60.SHAREPOINT_INSTALLED)
return true;
}
}
return false;
}
#endregion
#region ColdFusion
public override void CreateCFVirtualDirectories(string siteId)
{
WebVirtualDirectory scriptsDirectory = new WebVirtualDirectory();
scriptsDirectory.Name = "CFIDE";
scriptsDirectory.ContentPath = CFScriptsDirectoryPath;
scriptsDirectory.EnableAnonymousAccess = true;
scriptsDirectory.EnableWindowsAuthentication = true;
scriptsDirectory.EnableBasicAuthentication = false;
scriptsDirectory.DefaultDocs = null; // inherit from service
scriptsDirectory.HttpRedirect = "";
scriptsDirectory.HttpErrors = null;
scriptsDirectory.MimeMaps = null;
if (!VirtualDirectoryExists(siteId, scriptsDirectory.Name))
{
CreateVirtualDirectory(siteId, scriptsDirectory);
}
WebVirtualDirectory flashRemotingDir = new WebVirtualDirectory();
flashRemotingDir.Name = "JRunScripts";
flashRemotingDir.ContentPath = CFFlashRemotingDirPath;
flashRemotingDir.EnableAnonymousAccess = true;
flashRemotingDir.EnableWindowsAuthentication = true;
flashRemotingDir.EnableBasicAuthentication = false;
flashRemotingDir.DefaultDocs = null; // inherit from service
flashRemotingDir.HttpRedirect = "";
flashRemotingDir.HttpErrors = null;
flashRemotingDir.MimeMaps = null;
if (!VirtualDirectoryExists(siteId, flashRemotingDir.Name))
{
CreateVirtualDirectory(siteId, flashRemotingDir);
}
}
public override void DeleteCFVirtualDirectories(string siteId)
{
DeleteVirtualDirectory(siteId, "CFIDE");
DeleteVirtualDirectory(siteId, "JRunScripts");
}
public bool ColdFusionDirectoriesAdded(ServerManager srvman, string siteId)
{
int identifier = 0;
WebVirtualDirectory[] dirs = GetVirtualDirectories(srvman, siteId);
foreach (WebVirtualDirectory dir in dirs)
{
if (dir.FullQualifiedPath.Equals("CFIDE") || dir.FullQualifiedPath.Equals("JRunScripts"))
identifier++;
}
return identifier.Equals(2);
}
protected override bool IsColdFusionEnabledOnSite(string siteId)
{
bool isCFenabled = false;
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
string ID = webObjectsSvc.GetWebSiteIdFromIIS(srvman, siteId, "{0}");
if (IsColdFusionSystemInstalled())
{
string pathWsConfigSettings = Path.Combine(GetColdFusionRootPath(), @"runtime\lib\wsconfig\wsconfig.properties");
StreamReader file = new StreamReader(pathWsConfigSettings);
string line = String.Empty;
int counter = 0;
while ((line = file.ReadLine()) != null)
{
if (line.Contains(String.Format("=IIS,{0},", ID)))
{
isCFenabled = true;
break;
}
counter++;
}
file.Close();
}
return isCFenabled;
}
}
#endregion
#region HostingServiceProvider methods
public override SettingPair[] GetProviderDefaultSettings()
{
List<SettingPair> allSettings = new List<SettingPair>();
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
allSettings.AddRange(extensionsSvc.GetISAPIExtensionsInstalled(srvman));
// add default web management settings
WebManagementServiceSettings wmSettings = GetWebManagementServiceSettings();
if (wmSettings != null)
{
allSettings.Add(new SettingPair("WmSvc.Port", wmSettings.Port));
allSettings.Add(new SettingPair("WmSvc.ServiceUrl", wmSettings.ServiceUrl));
allSettings.Add(new SettingPair("WmSvc.RequiresWindowsCredentials", wmSettings.RequiresWindowsCredentials.ToString()));
}
}
// return settings
return allSettings.ToArray();
}
/// <summary>
/// Installs the provider.
/// </summary>
/// <returns>Error messsages if any specified.</returns>
public override string[] Install()
{
List<string> messages = new List<string>();
string[] cfgMsgs = webObjectsSvc.GrantConfigurationSectionAccess(INSTALL_SECTIONS_ALLOWED);
//
if (cfgMsgs.Length > 0)
{
messages.AddRange(cfgMsgs);
return messages.ToArray();
}
try
{
SecurityUtils.EnsureOrganizationalUnitsExist(ServerSettings, UsersOU, GroupsOU);
}
catch (Exception ex)
{
Log.WriteError(ex);
messages.Add(String.Format("Could not check/create Organizational Units: {0}", ex.Message));
return messages.ToArray();
}
// Create web group name.
if (String.IsNullOrEmpty(WebGroupName))
{
messages.Add("Web Group can not be blank");
}
else
{
try
{
// create group
if (!SecurityUtils.GroupExists(WebGroupName, ServerSettings, GroupsOU))
{
SystemGroup group = new SystemGroup();
group.Name = WebGroupName;
group.Members = new string[] { };
group.Description = "WebsitePanel System Group";
SecurityUtils.CreateGroup(group, ServerSettings, UsersOU, GroupsOU);
}
}
catch (Exception ex)
{
Log.WriteError(ex);
messages.Add(String.Format("There was an error while adding '{0}' group: {1}",
WebGroupName, ex.Message));
}
}
// Setting up shared iisAppObject pools.
try
{
WebAppPoolHelper aphl = new WebAppPoolHelper(ProviderSettings);
// Find shared pools
var sharedPools = Array.FindAll<WebAppPool>(aphl.SupportedAppPools.ToArray(),
x => aphl.isolation(x.Mode) == SiteAppPoolMode.Shared);
//
foreach (var item in sharedPools)
{
using (var srvman = webObjectsSvc.GetServerManager())
{
// Local variables
bool enable32BitAppOnWin64 = (aphl.dotNetVersion(item.Mode) == SiteAppPoolMode.dotNetFramework1) ? true : false;
//
if (srvman.ApplicationPools[item.Name] == null)
{
ApplicationPool pool = srvman.ApplicationPools.Add(item.Name);
//
pool.ManagedRuntimeVersion = aphl.aspnet_runtime(item.Mode);
pool.ManagedPipelineMode = aphl.runtime_pipeline(item.Mode);
pool.ProcessModel.IdentityType = ProcessModelIdentityType.NetworkService;
pool.AutoStart = true;
pool.Enable32BitAppOnWin64 = enable32BitAppOnWin64;
//
srvman.CommitChanges();
}
}
}
}
catch (Exception ex)
{
Log.WriteError(ex);
//
messages.Add(String.Format("There was an error while creating shared iisAppObject pools: {0}", ex.Message));
}
// Ensure logging settings are configured correctly on a web server level
try
{
webObjectsSvc.SetWebServerDefaultLoggingSettings(LogExtFileFlags.SiteName
| LogExtFileFlags.BytesRecv | LogExtFileFlags.BytesSent | LogExtFileFlags.Date);
}
catch (Exception ex)
{
Log.WriteError(ex);
//
messages.Add(String.Format(@"There was an error while configure web server's default
logging settings. Reason: {0}", ex.StackTrace));
}
// Ensure logging settings are configured correctly on a web server level
try
{
webObjectsSvc.SetWebServerDefaultLoggingSettings(LogExtFileFlags.SiteName
| LogExtFileFlags.BytesRecv | LogExtFileFlags.BytesSent | LogExtFileFlags.Date);
}
catch (Exception ex)
{
Log.WriteError(ex);
//
messages.Add(String.Format(@"There was an error while configure web server's default
logging settings. Reason: {0}", ex.StackTrace));
}
// Setup Web Deploy publishing settings and rules
SetupWebDeployPublishingOnServer(messages);
return messages.ToArray();
}
public const string WDeployEnabled = "WDeployEnabled";
public const string WDeployRepair = "WDeployRepair";
public const string WDeployAppHostConfigWriter = "WDeployAppHostConfigWriter";
public const string WDeployAppPoolConfigEditor = "WDeployAppPoolConfigEditor";
private void SetupWebDeployPublishingOnServer(List<string> messages)
{
if (IsWebDeployInstalled() == false
|| String.IsNullOrEmpty(ProviderSettings[WDeployEnabled]))
return;
//
var enableFeature = Convert.ToBoolean(ProviderSettings[WDeployEnabled]);
var repairFeature = Convert.ToBoolean(ProviderSettings[WDeployRepair]);
//
var appHostConfigWriter = "WDeployConfigWriter";
var appHostConfigWriterPassword = Guid.NewGuid().ToString();
//
var appPoolConfigEditor = "WDeployAdmin";
var appPoolConfigEditorPassword = Guid.NewGuid().ToString();
//
var appHostConfigFilePath = FileUtils.EvaluateSystemVariables(@"%WINDIR%\system32\inetsrv\config\applicationHost.config");
//
#region Repair feature
if (repairFeature == true && enableFeature == true)
{
// Cleanup NTFS permissions
SecurityUtils.RemoveNtfsPermissions(appHostConfigFilePath, appHostConfigWriter, ServerSettings, UsersOU, GroupsOU);
// Remove applicationHost.config writer account
SecurityUtils.DeleteUser(appHostConfigWriter, ServerSettings, UsersOU);
// Remove local admin user to recycle app pools
SecurityUtils.DeleteUser(appPoolConfigEditor, ServerSettings, UsersOU);
// Remove delegation rules if any
var moduleService = new DelegationRulesModuleService();
//
moduleService.RemoveDelegationRule("contentPath,iisApp", "{userScope}");
moduleService.RemoveDelegationRule("dbFullSql", "Data Source=");
moduleService.RemoveDelegationRule("dbMySql", "Server=");
moduleService.RemoveDelegationRule("createApp", "{userScope}");
moduleService.RemoveDelegationRule("setAcl", "{userScope}");
moduleService.RemoveDelegationRule("recycleApp", "{userScope}");
moduleService.RemoveDelegationRule("appPoolPipeline,appPoolNetFx", "{userScope}");
}
#endregion
// Create applicationHost.config writer account
#region appHostConfigWriter account provisioning
if (enableFeature == true)
{
//
if (SecurityUtils.UserExists(appHostConfigWriter, ServerSettings, UsersOU) == false)
{
//
try
{
SecurityUtils.CreateUser(new SystemUser
{
Name = appHostConfigWriter,
FullName = appHostConfigWriter,
Password = appHostConfigWriterPassword,
PasswordCantChange = true,
PasswordNeverExpires = true,
MemberOf = new string[] { },
Description = "Web Deploy applicationHost.config writer account",
},
ServerSettings,
UsersOU,
GroupsOU);
// Grant appropriate NTFS permissions
SecurityUtils.GrantNtfsPermissions(appHostConfigFilePath, appHostConfigWriter, NTFSPermission.Modify, true, true, ServerSettings, UsersOU, GroupsOU);
}
catch (Exception ex)
{
var errorMessage = "Could not create applicationHost.config writer account";
//
Log.WriteError(errorMessage, ex);
//
messages.Add(errorMessage);
}
}
}
else
{
if (SecurityUtils.UserExists(appHostConfigWriter, ServerSettings, UsersOU) == true)
{
//
try
{
// Remove NTFS permissions
SecurityUtils.RemoveNtfsPermissions(appHostConfigFilePath, appHostConfigWriter, ServerSettings, UsersOU, GroupsOU);
// Remove writer account
SecurityUtils.DeleteUser(appHostConfigWriter, ServerSettings, UsersOU);
}
catch (Exception ex)
{
var errorMessage = "Could not remove applicationHost.config writer user account";
//
Log.WriteError(errorMessage, ex);
//
messages.Add(errorMessage);
}
}
}
#endregion
// Create local admin user to recycle app pools
#region appPoolConfigEditor account provisioning
if (enableFeature)
{
//
if (SecurityUtils.UserExists(appPoolConfigEditor, ServerSettings, UsersOU) == false)
{
//
try
{
SecurityUtils.CreateUser(new SystemUser
{
Name = appPoolConfigEditor,
FullName = appPoolConfigEditor,
Password = appPoolConfigEditorPassword,
PasswordCantChange = true,
PasswordNeverExpires = true,
MemberOf = new string[] { "Administrators" },
Description = "Web Deploy AppPool configuration editor account",
},
ServerSettings,
UsersOU,
GroupsOU);
}
catch (Exception ex)
{
var errorMessage = "Could not create application pool configuration editor account";
//
Log.WriteError(errorMessage, ex);
//
messages.Add(errorMessage);
}
}
}
else
{
if (SecurityUtils.UserExists(appPoolConfigEditor, ServerSettings, UsersOU) == true)
{
//
try
{
// Remove appPool config editor account
SecurityUtils.DeleteUser(appPoolConfigEditor, ServerSettings, UsersOU);
}
catch (Exception ex)
{
var errorMessage = "Could not remove applicationHost.config writer user account";
//
Log.WriteError(errorMessage, ex);
//
messages.Add(errorMessage);
}
}
}
#endregion
// Add delegation rules
#region Delegation rules provisioning
if (enableFeature)
{
var moduleService = new DelegationRulesModuleService();
//
if (moduleService.DelegationRuleExists("contentPath,iisApp", "{userScope}") == false)
{
moduleService.AddDelegationRule("contentPath,iisApp", "{userScope}", "PathPrefix", "CurrentUser", String.Empty, String.Empty);
}
//
if (moduleService.DelegationRuleExists("dbFullSql", "Data Source=") == false)
{
moduleService.AddDelegationRule("dbFullSql", "Data Source=", "ConnectionString", "CurrentUser", String.Empty, String.Empty);
}
//
if (moduleService.DelegationRuleExists("dbMySql", "Server=") == false)
{
moduleService.AddDelegationRule("dbMySql", "Server=", "ConnectionString", "CurrentUser", String.Empty, String.Empty);
}
//
if (moduleService.DelegationRuleExists("createApp", "{userScope}") == false)
{
moduleService.AddDelegationRule("createApp", "{userScope}", "PathPrefix", "SpecificUser", appHostConfigWriter, appHostConfigWriterPassword);
}
//
if (moduleService.DelegationRuleExists("setAcl", "{userScope}") == false)
{
moduleService.AddDelegationRule("setAcl", "{userScope}", "PathPrefix", "CurrentUser", String.Empty, String.Empty);
}
//
if (moduleService.DelegationRuleExists("recycleApp", "{userScope}") == false)
{
moduleService.AddDelegationRule("recycleApp", "{userScope}", "PathPrefix", "SpecificUser", appPoolConfigEditor, appPoolConfigEditorPassword);
}
//
if (moduleService.DelegationRuleExists("appPoolPipeline,appPoolNetFx", "{userScope}") == false)
{
moduleService.AddDelegationRule("appPoolPipeline,appPoolNetFx", "{userScope}", "PathPrefix", "SpecificUser", appHostConfigWriter, appHostConfigWriterPassword);
}
}
else
{
var moduleService = new DelegationRulesModuleService();
//
moduleService.RemoveDelegationRule("contentPath,iisApp", "{userScope}");
moduleService.RemoveDelegationRule("dbFullSql", "Data Source=");
moduleService.RemoveDelegationRule("dbMySql", "Server=");
moduleService.RemoveDelegationRule("createApp", "{userScope}");
moduleService.RemoveDelegationRule("setAcl", "{userScope}");
moduleService.RemoveDelegationRule("recycleApp", "{userScope}");
moduleService.RemoveDelegationRule("appPoolPipeline,appPoolNetFx", "{userScope}");
}
#endregion
}
public override ServiceProviderItemBandwidth[] GetServiceItemsBandwidth(ServiceProviderItem[] items, DateTime since)
{
ServiceProviderItemBandwidth[] itemsBandwidth = new ServiceProviderItemBandwidth[items.Length];
// update items with diskspace
for (int i = 0; i < items.Length; i++)
{
ServiceProviderItem item = items[i];
// create new bandwidth object
itemsBandwidth[i] = new ServiceProviderItemBandwidth();
itemsBandwidth[i].ItemId = item.Id;
itemsBandwidth[i].Days = new DailyStatistics[0];
if (item is WebSite)
{
try
{
WebSite site = GetSite(item.Name);
string siteId = site[WebSite.IIS7_SITE_ID];
string logsPath = Path.Combine(site.LogsPath, siteId);
if (!Directory.Exists(logsPath))
continue;
// create parser object
// and update statistics
LogParser parser = new LogParser("Web", siteId, logsPath, "s-sitename");
parser.ParseLogs();
// get daily statistics
itemsBandwidth[i].Days = parser.GetDailyStatistics(since, new string[] { siteId });
}
catch (Exception ex)
{
Log.WriteError(ex);
}
}
}
return itemsBandwidth;
}
public override ServiceProviderItemDiskSpace[] GetServiceItemsDiskSpace(ServiceProviderItem[] items)
{
List<ServiceProviderItemDiskSpace> itemsDiskspace = new List<ServiceProviderItemDiskSpace>();
// update items with diskspace
foreach (ServiceProviderItem item in items)
{
if (item is WebSite)
{
try
{
Log.WriteStart(String.Format("Calculating '{0}' site logs size", item.Name));
WebSite site = GetSite(item.Name);
//
string logsPath = Path.Combine(site.LogsPath, site[WebSite.IIS7_SITE_ID]);
// calculate disk space
ServiceProviderItemDiskSpace diskspace = new ServiceProviderItemDiskSpace();
diskspace.ItemId = item.Id;
diskspace.DiskSpace = -1 * FileUtils.CalculateFolderSize(logsPath);
itemsDiskspace.Add(diskspace);
Log.WriteEnd(String.Format("Calculating '{0}' site logs size", item.Name));
}
catch (Exception ex)
{
Log.WriteError(ex);
}
}
}
return itemsDiskspace.ToArray();
}
#endregion
public new bool IsIISInstalled()
{
int value = 0;
RegistryKey root = Registry.LocalMachine;
RegistryKey rk = root.OpenSubKey("SOFTWARE\\Microsoft\\InetStp");
if (rk != null)
{
value = (int)rk.GetValue("MajorVersion", null);
rk.Close();
}
return value == 7;
}
public override bool IsInstalled()
{
return IsIISInstalled();
}
#region Remote Management Access
/// <summary>
/// Provides Windows or IIS Management Users identities credentials mode
/// </summary>
public string IdentityCredentialsMode
{
get { return ProviderSettings["WmSvc.CredentialsMode"]; }
}
public override bool CheckWebManagementAccountExists(string accountName)
{
// Preserve setting to restore it back
bool adEnabled = ServerSettings.ADEnabled;
// !!! Bypass AD for WMSVC as it requires full-qualified username to authenticate user
// against the web server
//ServerSettings.ADEnabled = false;
if (IdentityCredentialsMode == "IISMNGR")
{
if (ManagementAuthentication.GetUser(accountName) != null)
return true;
else
return false;
}
else
{
return SecurityUtils.UserExists(accountName, ServerSettings, String.Empty);
}
}
public override ResultObject CheckWebManagementPasswordComplexity(string accountPassword)
{
// Preserve setting to restore it back
bool adEnabled = ServerSettings.ADEnabled;
// !!! Bypass AD for WMSVC as it requires full-qualified username to authenticate user
// against the web server
//ServerSettings.ADEnabled = false;
//
ResultObject result = new ResultObject { IsSuccess = true };
//
if (IdentityCredentialsMode == "IISMNGR")
{
InvalidPasswordReason reason = ManagementAuthentication.IsPasswordStrongEnough(accountPassword);
//
if (reason != InvalidPasswordReason.NoError)
{
result.IsSuccess = false;
result.AddError(reason.ToString(), new Exception("Password complexity check failed"));
}
}
// Restore setting back
ServerSettings.ADEnabled = adEnabled;
//
return result;
}
public override void GrantWebManagementAccess(string siteName, string accountName, string accountPassword)
{
// Remote Management Access feature requires Modify permissions on the web site's wwwroot folder
GrantWebManagementAccessInternally(siteName, accountName, accountPassword, NTFSPermission.Modify);
}
private void GrantWebManagementAccessInternally(string siteName, string accountName, string accountPassword, NTFSPermission permissions)
{
// Preserve setting to restore it back
bool adEnabled = ServerSettings.ADEnabled;
// !!! Bypass AD for WMSVC as it requires full-qualified username to authenticate user
// against the web server
//ServerSettings.ADEnabled = false;
//
string fqWebPath = String.Format("/{0}", siteName);
// Trace input parameters
Log.WriteInfo("Site Name: {0}; Account Name: {1}; Account Password: {2}; FqWebPath: {3};",
siteName, accountName, accountPassword, fqWebPath);
string contentPath = string.Empty;
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
WebSite site = webObjectsSvc.GetWebSiteFromIIS(srvman, siteName);
//
contentPath = webObjectsSvc.GetPhysicalPath(srvman, site);
//
Log.WriteInfo("Site Content Path: {0};", contentPath);
}
string FTPRoot = string.Empty;
string FTPDir = string.Empty;
if (contentPath.IndexOf("\\\\") != -1)
{
string[] Tmp = contentPath.Split('\\');
FTPRoot = "\\\\" + Tmp[2] + "\\" + Tmp[3];
FTPDir = contentPath.Replace(FTPRoot, "");
}
//
string accountNameSid = string.Empty;
//
if (IdentityCredentialsMode == "IISMNGR")
{
ManagementAuthentication.CreateUser(accountName, accountPassword);
}
else
{
// Create Windows user
SecurityUtils.CreateUser(
new SystemUser
{
Name = accountName,
FullName = accountName,
Description = "WMSVC Service Account created by WebsitePanel",
PasswordCantChange = true,
PasswordNeverExpires = true,
AccountDisabled = false,
Password = accountPassword,
System = true,
MsIIS_FTPDir = FTPDir,
MsIIS_FTPRoot = FTPRoot
},
ServerSettings,
UsersOU,
GroupsOU);
// Convert account name to the full-qualified one
accountName = GetFullQualifiedAccountName(accountName);
accountNameSid = GetFullQualifiedAccountNameSid(accountName);
//
Log.WriteInfo("FQ Account Name: {0};", accountName);
}
ManagementAuthorization.Grant(accountName, fqWebPath, false);
//
if (IdentityCredentialsMode == "IISMNGR")
{
SecurityUtils.GrantNtfsPermissionsBySid(contentPath, SystemSID.LOCAL_SERVICE, permissions, true, true);
}
else
{
SecurityUtils.GrantNtfsPermissions(contentPath, accountNameSid, NTFSPermission.Modify, true, true, ServerSettings, UsersOU, GroupsOU);
}
}
public override void ChangeWebManagementAccessPassword(string accountName, string accountPassword)
{
// Preserve setting to restore it back
bool adEnabled = ServerSettings.ADEnabled;
// !!! Bypass AD for WMSVC as it requires full-qualified username to authenticate user
// against the web server
//ServerSettings.ADEnabled = false;
// Trace input parameters
Log.WriteInfo("Account Name: {0}; Account Password: {1};", accountName, accountPassword);
if (IdentityCredentialsMode == "IISMNGR")
{
ManagementAuthentication.SetPassword(accountName, accountPassword);
}
else
{
//
SystemUser user = SecurityUtils.GetUser(accountName, ServerSettings, String.Empty);
//
user.Password = accountPassword;
//
SecurityUtils.UpdateUser(user, ServerSettings, String.Empty, String.Empty);
}
// Restore setting back
ServerSettings.ADEnabled = adEnabled;
}
public override void RevokeWebManagementAccess(string siteName, string accountName)
{
// Preserve setting to restore it back
bool adEnabled = ServerSettings.ADEnabled;
// !!! Bypass AD for WMSVC as it requires full-qualified username to authenticate user
// against the web server
//ServerSettings.ADEnabled = false;
//
string fqWebPath = String.Format("/{0}", siteName);
// Trace input parameters
Log.WriteInfo("Site Name: {0}; Account Name: {1}; FqWebPath: {2};",
siteName, accountName, fqWebPath);
using (ServerManager srvman = webObjectsSvc.GetServerManager())
{
//
WebSite site = webObjectsSvc.GetWebSiteFromIIS(srvman, siteName);
//
string contentPath = webObjectsSvc.GetPhysicalPath(srvman, site);
//
Log.WriteInfo("Site Content Path: {0};", contentPath);
// Revoke access permissions
if (IdentityCredentialsMode == "IISMNGR")
{
ManagementAuthorization.Revoke(accountName, fqWebPath);
ManagementAuthentication.DeleteUser(accountName);
SecurityUtils.RemoveNtfsPermissionsBySid(contentPath, SystemSID.LOCAL_SERVICE);
}
else
{
if (adEnabled)
{
ManagementAuthorization.Revoke(GetFullQualifiedAccountName(accountName), fqWebPath);
SecurityUtils.RemoveNtfsPermissions(contentPath, accountName, ServerSettings, UsersOU, GroupsOU);
SecurityUtils.DeleteUser(accountName, ServerSettings, UsersOU);
}
else
{
ManagementAuthorization.Revoke(GetFullQualifiedAccountName(accountName), fqWebPath);
SecurityUtils.RemoveNtfsPermissions(contentPath, accountName, ServerSettings, String.Empty, String.Empty);
SecurityUtils.DeleteUser(accountName, ServerSettings, String.Empty);
}
}
// Restore setting back
ServerSettings.ADEnabled = adEnabled;
}
}
private void ReadWebDeployPublishingAccessDetails(WebVirtualDirectory iisObject)
{
iisObject.WebDeployPublishingAvailable = IsWebDeployInstalled() && IsWebManagementServiceInstalled();
// No way to find out Web Deploy Publishing Access password
//iisObject.
}
private bool IsWebDeployInstalled()
{
// TO-DO: Implement Web Deploy detection (x64/x86)
var isInstalled = false;
//
try
{
var msdeployRegKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\IIS Extensions\MSDeploy\2");
//
var keyValue = msdeployRegKey.GetValue("Install");
// We have found the required key in the registry hive
if (keyValue != null && keyValue.Equals(1))
{
isInstalled = true;
}
}
catch (Exception ex)
{
Log.WriteError("Could not retrieve Web Deploy key from the registry", ex);
}
//
return isInstalled;
}
private bool? isWmSvcInstalled;
protected void ReadWebManagementAccessDetails(ServerManager srvman, WebVirtualDirectory iisObject)
{
bool wmSvcAvailable = IsWebManagementServiceInstalled();
//
iisObject.SetValue<bool>(WebSite.WmSvcAvailable, wmSvcAvailable);
//
if (wmSvcAvailable)
{
//
iisObject.SetValue<bool>(
WebVirtualDirectory.WmSvcSiteEnabled,
IsWebManagementAccessEnabled(iisObject));
//
string fqWebPath = @"/" + iisObject.FullQualifiedPath;
//
Configuration config = srvman.GetAdministrationConfiguration();
ConfigurationSection authorizationSection = config.GetSection("system.webServer/management/authorization");
ConfigurationElementCollection authorizationRulesCollection = authorizationSection.GetCollection("authorizationRules");
ConfigurationElement scopeElement = FindElement(authorizationRulesCollection, "scope", "path", fqWebPath);
Log.WriteInfo("FQ WebPath: " + fqWebPath);
if (scopeElement != null)
{
ConfigurationElementCollection scopeCollection = scopeElement.GetCollection();
// Retrieve account name
if (scopeCollection.Count > 0)
{
/*
iisObject.SetValue<string>(
WebSite.WmSvcAccountName,
GetNonQualifiedAccountName((String)scopeCollection[0]["name"]));
*/
iisObject.SetValue<string>(
WebSite.WmSvcAccountName, (String)scopeCollection[0]["name"]);
//
iisObject.SetValue<string>(
WebSite.WmSvcServiceUrl, ProviderSettings["WmSvc.ServiceUrl"]);
//
iisObject.SetValue<string>(
WebSite.WmSvcServicePort, ProviderSettings["WmSvc.Port"]);
}
}
}
}
protected ConfigurationElement FindElement(ConfigurationElementCollection collection, string elementTagName, params string[] keyValues)
{
foreach (ConfigurationElement element in collection)
{
if (String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase))
{
bool matches = true;
for (int i = 0; i < keyValues.Length; i += 2)
{
object o = element.GetAttributeValue(keyValues[i]);
string value = null;
if (o != null)
{
value = o.ToString();
}
if (!String.Equals(value, keyValues[i + 1], StringComparison.OrdinalIgnoreCase))
{
matches = false;
break;
}
}
if (matches)
{
return element;
}
}
}
return null;
}
private bool IsWebManagementAccessEnabled(WebVirtualDirectory iisObject)
{
using (var serverManager = webObjectsSvc.GetServerManager())
{
//
string fqWebPath = String.Format("/{0}", iisObject.FullQualifiedPath);
//
Log.WriteInfo("FQ Web Path: " + fqWebPath);
//
Configuration config = serverManager.GetAdministrationConfiguration();
ConfigurationSection authorizationSection = config.GetSection("system.webServer/management/authorization");
ConfigurationElementCollection authorizationRulesCollection = authorizationSection.GetCollection("authorizationRules");
ConfigurationElement scopeElement = FindElement(authorizationRulesCollection, "scope", "path", fqWebPath);
if (scopeElement != null)
{
// At least one authorization rule exists
if (scopeElement.GetCollection().Count > 0)
{
return true;
}
}
}
//
return false;
}
private bool IsWebManagementServiceInstalled()
{
if (!isWmSvcInstalled.HasValue)
{
try
{
// Software key has been found, so report the check as succeeded
if (PInvoke.RegistryHive.HKLM.SubKeyExists_x64(@"SOFTWARE\Microsoft\WebManagement\Server"))
{
// Make sure Enable Remote Connections flag is turned on.
int remoteConnEnabled = PInvoke.RegistryHive.HKLM.GetDwordSubKeyValue_x64(@"SOFTWARE\Microsoft\WebManagement\Server",
"EnableRemoteManagement");
//
if (remoteConnEnabled == 1)
isWmSvcInstalled = true;
}
else
isWmSvcInstalled = false;
}
catch (Exception ex)
{
Log.WriteError("Failed to determine whether Web Management Service is installed", ex);
}
}
// Service not installed
return isWmSvcInstalled.GetValueOrDefault();
}
protected WebManagementServiceSettings GetWebManagementServiceSettings()
{
WebManagementServiceSettings settings = null;
try
{
// Trying to retrieve Web Management Server key
if (PInvoke.RegistryHive.HKLM.SubKeyExists_x64(@"SOFTWARE\Microsoft\WebManagement\Server"))
{
settings = new WebManagementServiceSettings();
// port number
settings.Port = PInvoke.RegistryHive.HKLM.GetDwordSubKeyValue_x64(@"SOFTWARE\Microsoft\WebManagement\Server", "Port").ToString();
// service URL
settings.ServiceUrl = PInvoke.RegistryHive.HKLM.GetSubKeyValue_x64(@"SOFTWARE\Microsoft\WebManagement\Server", "IPAddress");
// credentials mode
settings.RequiresWindowsCredentials =
PInvoke.RegistryHive.HKLM.GetDwordSubKeyValue_x64(@"SOFTWARE\Microsoft\WebManagement\Server", "RequiresWindowsCredentials");
}
}
catch (Exception ex)
{
Log.WriteError("Failed to retrieve Web Management Service settings", ex);
}
//
return settings;
}
protected string GetFullQualifiedAccountName(string accountName)
{
//
if (!ServerSettings.ADEnabled)
return String.Format(@"{0}\{1}", Environment.MachineName, accountName);
if (accountName.IndexOf("\\") != -1)
return accountName; // already has domain information
// DO IT FOR ACTIVE DIRECTORY MODE ONLY
string domainName = null;
try
{
DirectoryContext objContext = new DirectoryContext(DirectoryContextType.Domain, ServerSettings.ADRootDomain);
Domain objDomain = Domain.GetDomain(objContext);
domainName = objDomain.Name;
}
catch (Exception ex)
{
Log.WriteError("Get domain name error", ex);
}
return domainName != null ? domainName + "\\" + accountName : accountName;
}
protected string GetFullQualifiedAccountNameSid(string accountName)
{
//
if (!ServerSettings.ADEnabled)
return String.Format(@"{0}\{1}", Environment.MachineName, accountName);
if (accountName.IndexOf("\\") != -1)
return accountName; // already has domain information
// DO IT FOR ACTIVE DIRECTORY MODE ONLY
string domainName = null;
try
{
DirectoryContext objContext = new DirectoryContext(DirectoryContextType.Domain, ServerSettings.ADRootDomain);
Domain objDomain = Domain.GetDomain(objContext);
domainName = objDomain.Name;
}
catch (Exception ex)
{
Log.WriteError("Get domain name error", ex);
}
return domainName != null ? domainName + "\\" + accountName : accountName;
}
#endregion
#region SSL
public override SSLCertificate generateCSR(SSLCertificate certificate)
{
var sslObjectService = new SSLModuleService();
//
sslObjectService.GenerateCsr(certificate);
return certificate;
}
public override SSLCertificate installCertificate(SSLCertificate certificate, WebSite website)
{
var sslObjectService = new SSLModuleService();
//
return sslObjectService.InstallCertificate(certificate, website);
}
public override List<SSLCertificate> getServerCertificates()
{
var sslObjectService = new SSLModuleService();
//
return sslObjectService.GetServerCertificates();
}
public override SSLCertificate installPFX(byte[] certificate, string password, WebSite website)
{
var sslObjectService = new SSLModuleService();
//
return sslObjectService.InstallPfx(certificate, password, website);
}
public override byte[] exportCertificate(string serialNumber, string password)
{
var sslObjectService = new SSLModuleService();
//
return sslObjectService.ExportPfx(serialNumber, password);
}
public override ResultObject DeleteCertificate(SSLCertificate certificate, WebSite website)
{
var sslObjectService = new SSLModuleService();
//
return sslObjectService.DeleteCertificate(certificate, website);
}
public override SSLCertificate ImportCertificate(WebSite website)
{
var sslObjectService = new SSLModuleService();
//
return sslObjectService.ImportCertificate(website);
}
public override bool CheckCertificate(WebSite webSite)
{
var sslObjectService = new SSLModuleService();
//
return sslObjectService.CheckCertificate(webSite);
}
#endregion
#region Web Platform Installer Application Gallery
// moved down to IIs60
#endregion
}
}