private void syncronizeHosting(Website dirtyWebsite, CleanWebsite cleanWebsite) { // Where the IIS site ID has not been set and the IIS is due to be created, get ID ready. if ((cleanWebsite.IisSite.SiteID == 0) && (cleanWebsite.IisSite.Mode != WebsiteIisMode.Disabled)) { // Get the next ID and hope it doesn't get used before site is created. long nextSiteID = getNextIisSiteID(); // Ensure that both clean and dirty know about the new ID. cleanWebsite.IisSite.SiteID = nextSiteID; dirtyWebsite.IisSite.SiteID = nextSiteID; } // PrimaryHost relies on HostArray which may be empty in the clean version. cleanWebsite.HostArray = dirtyWebsite.HostArray; syncronizeDirectory(cleanWebsite); syncronizeIisIdentity(cleanWebsite); // IIS identity sync may have set a new SID. dirtyWebsite.IisSite.IdentitySid = cleanWebsite.IisSite.IdentitySid; processSecurity(dirtyWebsite); syncronizeIisAppPool(cleanWebsite); syncronizeIisSite(cleanWebsite); processDnsZones(dirtyWebsite); syncronizeFtpServer(cleanWebsite); }
private void moveChangedDirectory(Website currentWebsite) { CleanWebsite previousWebsite = getClean(currentWebsite.DataID); DirectoryInfo previousDirectory = getWebsiteDirectory(previousWebsite); DirectoryInfo currentDirectory = getWebsiteDirectory(currentWebsite); if (previousDirectory.FullName != currentDirectory.FullName) { // If target already exists, make obsolete. MakeDirectoryObsolete(currentDirectory); // First remove security from previous path to avoid security leaks. clearFileZillaSecurity(previousDirectory); try { // Only move if website requires a directory (and needs it). if (previousDirectory.Exists) { // If the directory has changed, move it. previousDirectory.MoveTo(currentDirectory.FullName); } } catch (Exception ex) { throw new Exception( "Could not move website directory '" + previousDirectory + "' to '" + currentDirectory + "'.", ex); } } }
private void syncronizeIisAppPool(CleanWebsite website) { var q = from a in iisManager.ApplicationPools where a.Name == website.IisSite.ApplicationPoolName select a; ApplicationPool ap = null; if (q.Count() != 0) { ap = q.First(); if (website.IisSite.Mode != WebsiteIisMode.Disabled) { // Update existing app pool settings. applyIisApplicationPoolValues(website, ap); } else { // Delete the application pool when it's not needed. iisManager.ApplicationPools.Remove(ap); } } else { if (website.IisSite.Mode != WebsiteIisMode.Disabled) { // Only create the IIS app pool when site isn't disabled. ap = iisManager.ApplicationPools.Add(website.IisSite.ApplicationPoolName); applyIisApplicationPoolValues(website, ap); } } iisManager.CommitChanges(); }
private void syncronizeDirectory(CleanWebsite website) { // Website directory may not exist after first install. if (!ServerConfig.WebsiteDirectory.Exists) { ServerConfig.WebsiteDirectory.Create(); } DirectoryInfo customerDirectory = getCustomerDirectory(website); DirectoryInfo websiteDirectory = getWebsiteDirectory(website); // Only create directory if IIS is not disabled. if (website.IisSite.Mode != WebsiteIisMode.Disabled) { if (!customerDirectory.Exists) { customerDirectory.Create(); } if (!websiteDirectory.Exists) { websiteDirectory.Create(); } } }
private void syncronizeFtpServer(CleanWebsite website) { if (website.Customer.FtpEnabled) { SetDefaultWebsiteSecurity(website); } }
public void Update(Website website) { setDependantProperties(website); enforceConstraints(website); // Call before update, so the previous directory can be discovered. moveChangedDirectory(website); // Update the config first, so the clean website reflects new values. Context.HostingConfig.Update(website); // Process hosts so primary host is known when getting clean site. processWebsiteHosts(website); // Get a clean website in case read only values have been changed. CleanWebsite cleanWebsite = getClean(website.DataID); // Generate a new password only if empty (i.e. not set yet). cleanWebsite.GenerateIisPasswordIfEmpty(this); // Sync first, as IDs may change. syncronizeHosting(website, cleanWebsite); // Sets the clean values to the dirty website. website.TakeCleanValues(cleanWebsite); // Update afterwards so new IDs can be saved. Context.HostingConfig.Update(website); }
public void Create(Website website) { setDependantProperties(website); enforceConstraints(website); // Create first, so clean version has correct values. Context.HostingConfig.Create(website); // Process hosts so primary host is known when getting clean site. processWebsiteHosts(website); // Get a clean website in case passwords, etc have been changed. CleanWebsite cleanWebsite = getClean(website.DataID); // Generate a password, and set the initial read only values. cleanWebsite.GenerateIisPassword(this); // Then syncronize hosting (affects the clean website). syncronizeHosting(website, cleanWebsite); // Sets the clean values to the dirty website. website.TakeCleanValues(cleanWebsite); // Update afterwards so new IDs can be saved. Context.HostingConfig.Update(website); }
private void syncronizeIisIdentity(CleanWebsite website) { // Only create or update when IIS is enabled. if (website.IisSite.Mode != WebsiteIisMode.Disabled) { // Create the user if it does not exist and IIS is not disabled. if (!wuManager.Exists(website.IisSite.IdentityUserName)) { SecurityIdentifier sid = wuManager.Create(website.GetIisIdentity(this)); website.IisSite.IdentitySid = sid.Value; } else { // Ensure that SID is kept up to date (as it may become out of sync). website.IisSite.IdentitySid = wuManager.Get(website.IisSite.IdentityUserName).Sid.Value; // Update user in case site name has changed. wuManager.Update(website.GetIisIdentity(this)); // Ensure that the password is correct. wuManager.SetPassword( new SecurityIdentifier(website.IisSite.IdentitySid), DecryptPassword(website.IisSite.IdentityPassword)); } } else { // If user exists, then remove the user to keep the system tidy. tryRemoveIisIdentity(website); // Remove directory security belonging to user to keep system tidy. removeWebsiteSecurity(website); } }
public bool SecurityValid(Website website, string currentPrimaryHostName) { // Ensure there is a customer object so we can get the website directory. website.Customer = CreateManager <CustomerManager>().Get(website.CustomerID); // Use old directory, as it may be different in the new site (i.e. not yet exists). DirectoryInfo websiteDirectory = getDirectory(website.Customer, currentPrimaryHostName); // Set the website so relative so that relativePathAndUserExists method can work. CleanWebsite cleanWebsite = getClean(website.DataID); website.SecurityArray.ToList().ForEach(s => s.Website = cleanWebsite); // TODO: check if in create mode, then bypass relative path exists? (only if root) var q = from st in website.SecurityArray where // Ignore records that will be deleted. st.PendingAction != ChildPendingAction.Delete // Website is invalid only if relative path doesn't refer to root. && !relativePathIsRoot(st) // Website is invalid if either path or user does not exist. && relativePathAndUserExists(st, websiteDirectory) select st; // If 0, then no invalid security found. return(q.Count() == 0); }
private void tryRemoveIisIdentity(CleanWebsite website) { if (wuManager.Exists(website.IisSite.IdentityUserName)) { wuManager.Delete(website.IisSite.IdentityUserName); } }
private void removeWebsiteSecurity(CleanWebsite website) { SecurityIdentifier sid = null; if (website.IisSite.IdentitySid != null) { // In most cases, the SID will exist. sid = new SecurityIdentifier(website.IisSite.IdentitySid); } else if (!string.IsNullOrEmpty(website.IisSite.IdentityUserName)) { // In some cases because of an earlier bug, only the username may exist. WindowsUser windowsUser = wuManager.Find(website.IisSite.IdentityUserName); if (windowsUser != null) { sid = windowsUser.Sid; } } if (sid != null) { // If no record of the user exists, then we can't remove security. removeSecurityRecursive(getWebsiteDirectory(website), sid); } }
private void syncronizeIisSite(CleanWebsite website) { var sq = from s in iisManager.Sites where s.Id == website.IisSite.SiteID select s; Site site = null; if (sq.Count() != 0) { site = sq.First(); if (website.IisSite.Mode != WebsiteIisMode.Disabled) { // Simply update the site and it's structure. applySiteValues(website, site); updateIisSite(website, site); // Commit the update before updating redirect (name could have changed). iisManager.CommitChanges(); // Update redirect once any name changes have been made in XML config. updateIisRedirect(website, site.GetWebConfiguration()); } else { // Remove the site as it shouldn't exist. iisManager.Sites.Remove(site); // Mark the website as non-existant. website.IisSite.SiteID = 0; } } else { if (website.IisSite.Mode != WebsiteIisMode.Disabled) { // Give the site an unused ID (not auto generated by config). site = iisManager.Sites.CreateElement(); site.Id = website.IisSite.SiteID; // Apply the neccecary values, then add to config. applySiteValues(website, site); iisManager.Sites.Add(site); // After adding the site, add application, hosts, etc. updateIisSite(website, site); // Commit the creation of site before updating redirect. iisManager.CommitChanges(); // Update redirect once the site exists in the XML config. updateIisRedirect(website, site.GetWebConfiguration()); } } // Commit changes so redirect update can read from config XML file. iisManager.CommitChanges(); }
private void enforceConstraints(Website dirtyWebsite) { if (string.IsNullOrEmpty(dirtyWebsite.PrimaryHost.Name)) { throw new Exception( "Primary host name cannot be null or empty."); } if (dirtyWebsite.PrimaryHost.Port != WebsiteHost.DefaultHttpPort) { throw new Exception( "Primary host must use the default http " + "port (" + WebsiteHost.DefaultHttpPort + ")."); } if (dirtyWebsite.PrimaryHost.Protocol != WebsiteHostProtocol.Http) { throw new Exception( "Primary host must use the http protocol."); } if (dirtyWebsite.CustomerID == null) { throw new Exception( "Customer ID was not defined for website."); } WebsiteHost[] conflictArray; if (ExistsWithAnyHost(dirtyWebsite, out conflictArray)) { throw new Exception( "A website already exists with host names: " + string.Join(", ", conflictArray.Select(h => h.Name).ToArray()) + "."); } if (dirtyWebsite.PrimaryHostID == null) { throw new Exception( "Primary host ID was not set."); } if (HostingConfig.Exists <Website>(dirtyWebsite.DataID)) { CleanWebsite cleanWebsite = getClean(dirtyWebsite.DataID); if (cleanWebsite.CustomerID != dirtyWebsite.CustomerID) { throw new Exception("Customer cannot be changed."); } } }
private void deleteIisObjects(CleanWebsite website) { var siteQuery = iisManager.Sites.Where(s => s.Id == website.IisSite.SiteID); var apQuery = iisManager.ApplicationPools.Where(ap => ap.Name == website.IisSite.ApplicationPoolName); if (siteQuery.Count() != 0) { iisManager.Sites.Remove(siteQuery.Single()); } if (apQuery.Count() != 0) { iisManager.ApplicationPools.Remove(apQuery.Single()); } iisManager.CommitChanges(); }
private void applyIisApplicationPoolValues(CleanWebsite website, ApplicationPool ap) { ap.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser; ap.ProcessModel.UserName = website.IisSite.IdentityUserName; ap.ProcessModel.Password = DecryptPassword(website.IisSite.IdentityPassword); ap.ManagedRuntimeVersion = website.IisSite.ManagedRuntimeVersion; switch (website.IisSite.ManagedPipelineMode) { case WebsiteIisManagedPipelineMode.Classic: ap.ManagedPipelineMode = ManagedPipelineMode.Classic; break; case WebsiteIisManagedPipelineMode.Integrated: ap.ManagedPipelineMode = ManagedPipelineMode.Integrated; break; } }
private DeleteHostingResult deleteHosting(CleanWebsite website) { DeleteHostingResult r = new DeleteHostingResult(); deleteIisObjects(website); clearFileZillaSecurity(getWebsiteDirectory(website)); tryRemoveIisIdentity(website); removeWebsiteSecurity(website); MakeDirectoryObsoleteResult mdor = TryMakeDirectoryObsolete(getWebsiteDirectory(website)); if (mdor.Error != null) { r.Errors.Add(mdor.Error); } return(r); }
public WebsiteDeleteResult Delete(RhspDataID dataID) { WebsiteDeleteResult r = new WebsiteDeleteResult(); CleanWebsite website = Get <CleanWebsite>(dataID); DeleteHostingResult dhr = deleteHosting(website); if (dhr.Errors.Count() != 0) { r.Errors.AddRange(dhr.Errors.Select(e => e.Message)); } IEnumerable <IRhspDataChild> cd = website.GetDataChildren(); cd.OfType <DnsZone>().ToList().ForEach(dz => deleteDnsZone(dz)); cd.OfType <SecurityTemplate>().ToList().ForEach(st => deleteSecurityTemplate(st)); cd.OfType <WebsiteHost>().ToList().ForEach(wh => deleteWebsiteHost(wh)); // Delete website after dependancies have been deleted. Context.HostingConfig.Delete <Website>(dataID); return(r); }
private DirectoryInfo getCustomerDirectory(CleanWebsite website) { return(website.Customer.GetDirectory(ServerConfig.WebsiteDirectory)); }