예제 #1
0
        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);
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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();
        }
예제 #4
0
        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();
                }
            }
        }
예제 #5
0
 private void syncronizeFtpServer(CleanWebsite website)
 {
     if (website.Customer.FtpEnabled)
     {
         SetDefaultWebsiteSecurity(website);
     }
 }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
        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);
        }
예제 #10
0
 private void tryRemoveIisIdentity(CleanWebsite website)
 {
     if (wuManager.Exists(website.IisSite.IdentityUserName))
     {
         wuManager.Delete(website.IisSite.IdentityUserName);
     }
 }
예제 #11
0
        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);
            }
        }
예제 #12
0
        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();
        }
예제 #13
0
        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.");
                }
            }
        }
예제 #14
0
        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();
        }
예제 #15
0
        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;
            }
        }
예제 #16
0
        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);
        }
예제 #17
0
        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);
        }
예제 #18
0
 private DirectoryInfo getCustomerDirectory(CleanWebsite website)
 {
     return(website.Customer.GetDirectory(ServerConfig.WebsiteDirectory));
 }