diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Installer.sln b/WebsitePanel.Installer/Sources/WebsitePanel.Installer.sln
index 6ded8966..2a9fa4c2 100644
--- a/WebsitePanel.Installer/Sources/WebsitePanel.Installer.sln
+++ b/WebsitePanel.Installer/Sources/WebsitePanel.Installer.sln
@@ -25,6 +25,9 @@ EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup.WIX", "Setup.WIX\Setup.WIX.wixproj", "{F963A4AF-CC72-4512-B636-829345C35318}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup.SchedulerService", "Setup.SchedulerService\Setup.SchedulerService.wixproj", "{EAD7C528-EA3D-40E8-9688-9F1D8DC8D758}"
+ ProjectSection(ProjectDependencies) = postProject
+ {24A4C231-73A9-4F03-ABAD-9A8FE5324495} = {24A4C231-73A9-4F03-ABAD-9A8FE5324495}
+ EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebsitePanel.SchedulerServiceInstaller", "WebsitePanel.SchedulerServiceInstaller\WebsitePanel.SchedulerServiceInstaller.csproj", "{24A4C231-73A9-4F03-ABAD-9A8FE5324495}"
EndProject
diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.SchedulerServiceInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.SchedulerServiceInstaller/CustomAction.cs
index f5655efd..eff618a7 100644
--- a/WebsitePanel.Installer/Sources/WebsitePanel.SchedulerServiceInstaller/CustomAction.cs
+++ b/WebsitePanel.Installer/Sources/WebsitePanel.SchedulerServiceInstaller/CustomAction.cs
@@ -35,6 +35,7 @@ using System.Linq;
using System.ServiceProcess;
using System.Text.RegularExpressions;
using Microsoft.Deployment.WindowsInstaller;
+using WebsitePanel.Setup;
namespace WebsitePanel.SchedulerServiceInstaller
{
@@ -72,11 +73,19 @@ namespace WebsitePanel.SchedulerServiceInstaller
{
try
{
- if (!ServiceController.GetServices().Any(s => s.DisplayName.Equals("WebsitePanel Scheduler", StringComparison.CurrentCultureIgnoreCase)))
+ var schedulerService =
+ ServiceController.GetServices().FirstOrDefault(
+ s => s.DisplayName.Equals("WebsitePanel Scheduler", StringComparison.CurrentCultureIgnoreCase));
+
+ if (schedulerService != null)
{
- ManagedInstallerClass.InstallHelper(new[] {"/i", Path.Combine(installFolder, "WebsitePanel.SchedulerService.exe")});
+ StopService(schedulerService.ServiceName);
+
+ SecurityUtils.DeleteService(schedulerService.ServiceName);
}
+ ManagedInstallerClass.InstallHelper(new[] { "/i", Path.Combine(installFolder, "WebsitePanel.SchedulerService.exe") });
+
StartService("WebsitePanel Scheduler");
}
catch (Exception)
@@ -122,6 +131,17 @@ namespace WebsitePanel.SchedulerServiceInstaller
}
}
+ private static void StopService(string serviceName)
+ {
+ var sc = new ServiceController(serviceName);
+
+ if (sc.Status == ServiceControllerStatus.Running)
+ {
+ sc.Stop();
+ sc.WaitForStatus(ServiceControllerStatus.Stopped);
+ }
+ }
+
private static void StartService(string serviceName)
{
var sc = new ServiceController(serviceName);
diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.SchedulerServiceInstaller/WebsitePanel.SchedulerServiceInstaller.csproj b/WebsitePanel.Installer/Sources/WebsitePanel.SchedulerServiceInstaller/WebsitePanel.SchedulerServiceInstaller.csproj
index 22f11548..10824162 100644
--- a/WebsitePanel.Installer/Sources/WebsitePanel.SchedulerServiceInstaller/WebsitePanel.SchedulerServiceInstaller.csproj
+++ b/WebsitePanel.Installer/Sources/WebsitePanel.SchedulerServiceInstaller/WebsitePanel.SchedulerServiceInstaller.csproj
@@ -37,6 +37,7 @@
+
@@ -47,6 +48,12 @@
+
+
+ {3951C0EC-BD98-450E-B228-CDBE5BD4AD49}
+ WebsitePanel.Setup
+
+
\ No newline at end of file
diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Common/SecurityUtils.cs b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Common/SecurityUtils.cs
index e69f9bbb..668e7875 100644
--- a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Common/SecurityUtils.cs
+++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Common/SecurityUtils.cs
@@ -27,6 +27,7 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
+using System.IO;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
@@ -1099,7 +1100,18 @@ namespace WebsitePanel.Setup
}
#endregion
- }
+
+ #region Windows Services
+
+ public static void DeleteService(string serviceName)
+ {
+ var wmiService = wmi.GetObject(String.Format("Win32_Service.Name='{0}'", serviceName));
+
+ wmiService.Delete();
+ }
+
+ #endregion
+ }
#region Enums
[Flags]
diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql
index 0d98ef0e..af169668 100644
--- a/WebsitePanel/Database/update_db.sql
+++ b/WebsitePanel/Database/update_db.sql
@@ -2604,6 +2604,15 @@ BEGIN
END
GO
+-- DNS.2013
+
+IF NOT EXISTS ( SELECT * FROM [dbo].[Providers] WHERE [ProviderID] = 410 )
+BEGIN
+ INSERT [dbo].[Providers] ([ProviderID], [GroupID], [ProviderName], [DisplayName], [ProviderType], [EditorControl], [DisableAutoDiscovery]) VALUES
+ (410, 7, N'MSDNS.2012', N'Microsoft DNS Server 2012+', N'WebsitePanel.Providers.DNS.MsDNS2012, WebsitePanel.Providers.DNS.MsDNS2012', N'MSDNS', NULL)
+END
+GO
+
-- CRM Provider fix
UPDATE Providers SET EditorControl = 'CRM2011' Where ProviderID = 1201;
@@ -2731,7 +2740,7 @@ WHERE
END
GO
-
+IF NOT EXISTS (SELECT * FROM [dbo].[Providers] WHERE [DisplayName] = 'MySQL Server 5.6')
-- CRM Quota
diff --git a/WebsitePanel/Lib/Microsoft.Management.Infrastructure.dll b/WebsitePanel/Lib/Microsoft.Management.Infrastructure.dll
new file mode 100644
index 00000000..9c72405b
Binary files /dev/null and b/WebsitePanel/Lib/Microsoft.Management.Infrastructure.dll differ
diff --git a/WebsitePanel/Lib/References/MySQL/MySql.Data.dll b/WebsitePanel/Lib/References/MySQL/MySql.Data.dll
index 088ef1c0..c029eae7 100644
Binary files a/WebsitePanel/Lib/References/MySQL/MySql.Data.dll and b/WebsitePanel/Lib/References/MySQL/MySql.Data.dll differ
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/EnterpriseStorage/EnterpriseStorageController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/EnterpriseStorage/EnterpriseStorageController.cs
index dec560e2..c4b90813 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/EnterpriseStorage/EnterpriseStorageController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/EnterpriseStorage/EnterpriseStorageController.cs
@@ -66,12 +66,12 @@ namespace WebsitePanel.EnterpriseServer
public static ResultObject DeleteEnterpriseStorage(int packageId, int itemId)
{
- return DeleteEnterpriseStorageInternal(packageId,itemId);
+ return DeleteEnterpriseStorageInternal(packageId, itemId);
}
public static SystemFile[] GetFolders(int itemId)
{
- return GetFoldersInternal(itemId);
+ return GetFoldersInternal(itemId);
}
public static SystemFile GetFolder(int itemId, string folderName)
@@ -102,7 +102,7 @@ namespace WebsitePanel.EnterpriseServer
public static ResultObject DeleteFolder(int itemId, string folderName)
{
return DeleteFolderInternal(itemId, folderName);
- }
+ }
public static List SearchESAccounts(int itemId, string filterColumn, string filterValue, string sortColumn)
{
@@ -121,7 +121,7 @@ namespace WebsitePanel.EnterpriseServer
public static ESPermission[] GetFolderPermission(int itemId, string folder)
{
- return ConvertToESPermission(itemId,GetFolderWebDavRulesInternal(itemId, folder));
+ return ConvertToESPermission(itemId, GetFolderWebDavRulesInternal(itemId, folder));
}
public static bool CheckFileServicesInstallation(int serviceId)
@@ -144,7 +144,7 @@ namespace WebsitePanel.EnterpriseServer
public static bool GetDirectoryBrowseEnabled(int itemId, string siteId)
{
- return GetDirectoryBrowseEnabledInternal(itemId, siteId);
+ return GetDirectoryBrowseEnabledInternal(itemId, siteId);
}
public static void SetDirectoryBrowseEnabled(int itemId, string siteId, bool enabled)
@@ -164,10 +164,10 @@ namespace WebsitePanel.EnterpriseServer
public static int DeleteWebDavDirectory(int packageId, string site, string vdirName)
{
return DeleteWebDavDirectoryInternal(packageId, site, vdirName);
- }
+ }
#endregion
-
+
#endregion
protected static bool CheckUsersDomainExistsInternal(int itemId)
@@ -227,7 +227,7 @@ namespace WebsitePanel.EnterpriseServer
string usersDomain = esSesstings["UsersDomain"];
WebServer web = GetWebServer(packageId);
-
+
if (!web.VirtualDirectoryExists(usersDomain, org.OrganizationId))
{
checkResult = false;
@@ -261,16 +261,16 @@ namespace WebsitePanel.EnterpriseServer
EnterpriseStorageController.AddWebDavDirectory(packageId, usersDomain, org.OrganizationId, homePath);
- int osId = PackageController.GetPackageServiceId(packageId, ResourceGroups.Os);
- bool enableHardQuota = (esSesstings["enablehardquota"] != null)
- ? bool.Parse(esSesstings["enablehardquota"])
- : false;
+ //int osId = PackageController.GetPackageServiceId(packageId, ResourceGroups.Os);
+ //bool enableHardQuota = (esSesstings["enablehardquota"] != null)
+ // ? bool.Parse(esSesstings["enablehardquota"])
+ // : false;
- if (enableHardQuota && osId != 0 && OperatingSystemController.CheckFileServicesInstallation(osId))
- {
- FilesController.SetFolderQuota(packageId, Path.Combine(usersHome, org.OrganizationId),
- locationDrive, Quotas.ENTERPRISESTORAGE_DISKSTORAGESPACE);
- }
+ //if (enableHardQuota && osId != 0 && OperatingSystemController.CheckFileServicesInstallation(osId))
+ //{
+ // FilesController.SetFolderQuota(packageId, Path.Combine(usersHome, org.OrganizationId),
+ // locationDrive, Quotas.ENTERPRISESTORAGE_DISKSTORAGESPACE);
+ //}
}
}
catch (Exception ex)
@@ -347,7 +347,7 @@ namespace WebsitePanel.EnterpriseServer
Organization org = OrganizationController.GetOrganization(itemId);
if (org == null)
{
- return null;
+ return new SystemFile[0];
}
EnterpriseStorage es = GetEnterpriseStorage(GetEnterpriseStorageServiceID(org.PackageId));
@@ -418,6 +418,8 @@ namespace WebsitePanel.EnterpriseServer
EnterpriseStorage es = GetEnterpriseStorage(GetEnterpriseStorageServiceID(org.PackageId));
es.CreateFolder(org.OrganizationId, folderName);
+
+ UpdateESHardQuota(org.PackageId);
}
catch (Exception ex)
{
@@ -473,7 +475,7 @@ namespace WebsitePanel.EnterpriseServer
return result;
}
-
+
protected static List SearchESAccountsInternal(int itemId, string filterColumn, string filterValue, string sortColumn)
{
// load organization
@@ -547,7 +549,7 @@ namespace WebsitePanel.EnterpriseServer
return result;
}
-
+
#region WebDav
protected static int AddWebDavDirectoryInternal(int packageId, string site, string vdirName, string contentpath)
@@ -579,11 +581,6 @@ namespace WebsitePanel.EnterpriseServer
dir.HttpErrors = null;
dir.MimeMaps = null;
- int serviceId = PackageController.GetPackageServiceId(packageId, ResourceGroups.Web);
-
- if (serviceId == -1)
- return serviceId;
-
// create directory
WebServer web = GetWebServer(packageId);
@@ -755,7 +752,7 @@ namespace WebsitePanel.EnterpriseServer
var account = ObjectUtils.FillObjectFromDataReader(DataProvider.GetExchangeAccountByAccountName(itemId, permission.Account));
- if (account.AccountType == ExchangeAccountType.SecurityGroup
+ if (account.AccountType == ExchangeAccountType.SecurityGroup
|| account.AccountType == ExchangeAccountType.DefaultSecurityGroup)
{
rule.Roles.Add(permission.Account);
@@ -838,6 +835,33 @@ namespace WebsitePanel.EnterpriseServer
}
+ private static void UpdateESHardQuota(int packageId)
+ {
+ int esServiceId = PackageController.GetPackageServiceId(packageId, ResourceGroups.EnterpriseStorage);
+
+ if (esServiceId != 0)
+ {
+
+ StringDictionary esSesstings = ServerController.GetServiceSettings(esServiceId);
+
+ string usersHome = esSesstings["UsersHome"];
+ string usersDomain = esSesstings["UsersDomain"];
+ string locationDrive = esSesstings["LocationDrive"];
+
+ string homePath = string.Format("{0}:\\{1}", locationDrive, usersHome);
+
+ int osId = PackageController.GetPackageServiceId(packageId, ResourceGroups.Os);
+ bool enableHardQuota = (esSesstings["enablehardquota"] != null)
+ ? bool.Parse(esSesstings["enablehardquota"])
+ : false;
+
+ if (enableHardQuota && osId != 0 && OperatingSystemController.CheckFileServicesInstallation(osId))
+ {
+ FilesController.SetFolderQuota(packageId, usersHome, locationDrive, Quotas.ENTERPRISESTORAGE_DISKSTORAGESPACE);
+ }
+ }
+ }
+
///
/// Get webserver (IIS) installed on server connected with packageId
///
@@ -847,15 +871,15 @@ namespace WebsitePanel.EnterpriseServer
{
try
{
- var group = ServerController.GetResourceGroupByName(ResourceGroups.Web);
+ var webGroup = ServerController.GetResourceGroupByName(ResourceGroups.Web);
+ var webProviders = ServerController.GetProvidersByGroupID(webGroup.GroupId);
+ var esServiceInfo = ServerController.GetServiceInfo(GetEnterpriseStorageServiceID(packageId));
- var webProviders = ServerController.GetProvidersByGroupID(group.GroupId);
-
- var package = PackageController.GetPackage(packageId);
+ var serverId = esServiceInfo.ServerId;
foreach (var webProvider in webProviders)
{
- BoolResult result = ServerController.IsInstalled(package.ServerId, webProvider.ProviderId);
+ BoolResult result = ServerController.IsInstalled(serverId, webProvider.ProviderId);
if (result.IsSuccess && result.Value)
{
@@ -867,7 +891,12 @@ namespace WebsitePanel.EnterpriseServer
cnfg.ProviderSettings.ProviderName = webProvider.DisplayName;
cnfg.ProviderSettings.ProviderType = webProvider.ProviderType;
- ServiceProviderProxy.ServerInit(web, cnfg, package.ServerId);
+ //// set service settings
+ //StringDictionary serviceSettings = ServerController.GetServiceSettings(serviceId);
+ //foreach (string key in serviceSettings.Keys)
+ // cnfg.ProviderSettings.Settings[key] = serviceSettings[key];
+
+ ServiceProviderProxy.ServerInit(web, cnfg, serverId);
return web;
}
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/ExchangeServer/ExchangeServerController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/ExchangeServer/ExchangeServerController.cs
index e533a752..2070d35c 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/ExchangeServer/ExchangeServerController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/ExchangeServer/ExchangeServerController.cs
@@ -1235,7 +1235,7 @@ namespace WebsitePanel.EnterpriseServer
DataProvider.DeleteExchangeAccount(itemId, accountId);
}
-
+/*
private static string BuildAccountName(string orgId, string name)
{
string accountName = name = name.Replace(" ", "");
@@ -1271,7 +1271,7 @@ namespace WebsitePanel.EnterpriseServer
}
}
-
+*/
#endregion
@@ -3041,7 +3041,7 @@ namespace WebsitePanel.EnterpriseServer
if (idx > -1)
name = email.Substring(0, idx);
- string accountName = BuildAccountName(org.OrganizationId, name);
+ string accountName = OrganizationController.BuildAccountNameEx(org, name);
// add contact
int exchangeServiceId = GetExchangeServiceID(org.PackageId);
@@ -3375,7 +3375,7 @@ namespace WebsitePanel.EnterpriseServer
int packageCheck = SecurityContext.CheckPackage(org.PackageId, DemandPackage.IsActive);
if (packageCheck < 0) return packageCheck;
- string accountName = OrganizationController.BuildAccountNameWithOrgId(org.OrganizationId, name, org.ServiceId);
+ string accountName = OrganizationController.BuildAccountNameEx(org, name);
// add account
// add contact
@@ -4179,7 +4179,7 @@ namespace WebsitePanel.EnterpriseServer
if (String.IsNullOrEmpty(name))
name = Utils.CleanIdentifier(folderName);
- string accountName = BuildAccountName(org.OrganizationId, name);
+ string accountName = OrganizationController.BuildAccountNameEx(org, name);
// add mailbox
int exchangeServiceId = GetExchangeServiceID(org.PackageId);
@@ -4324,7 +4324,7 @@ namespace WebsitePanel.EnterpriseServer
if (EmailAddressExists(email))
return BusinessErrorCodes.ERROR_EXCHANGE_EMAIL_EXISTS;
- string accountName = BuildAccountName(org.OrganizationId, name);
+ string accountName = OrganizationController.BuildAccountNameEx(org, name);
int exchangeServiceId = GetExchangeServiceID(org.PackageId);
ExchangeServer exchange = GetExchangeServer(exchangeServiceId, org.ServiceId);
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
index 5ed2188e..4239f90a 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
@@ -397,7 +397,7 @@ namespace WebsitePanel.EnterpriseServer
{
foreach (AdditionalGroup additionalGroup in GetAdditionalGroups(settings.UserId))
{
- string additionalGroupName = BuildAccountNameWithOrgId(org.OrganizationId, additionalGroup.GroupName.Replace(" ", ""), org.ServiceId);
+ string additionalGroupName = BuildAccountNameEx(org, additionalGroup.GroupName.Replace(" ", ""));
if (orgProxy.CreateSecurityGroup(org.OrganizationId, additionalGroupName) == 0)
{
@@ -1383,7 +1383,7 @@ namespace WebsitePanel.EnterpriseServer
return BusinessErrorCodes.ERROR_EXCHANGE_EMAIL_EXISTS;
// load organization
- Organization org = GetOrganization(itemId);
+ WebsitePanel.Providers.HostedSolution.Organization org = GetOrganization(itemId);
if (org == null)
{
@@ -1408,7 +1408,7 @@ namespace WebsitePanel.EnterpriseServer
Organizations orgProxy = GetOrganizationProxy(org.ServiceId);
string upn = string.Format("{0}@{1}", name, domain);
- string sAMAccountName = AppendOrgId(serviceSettings) ? BuildAccountNameWithOrgId(org.OrganizationId, name, org.ServiceId) : BuildAccountName(org.OrganizationId, name, org.ServiceId);
+ string sAMAccountName = BuildAccountNameEx(org, name);
TaskManager.Write("accountName :" + sAMAccountName);
TaskManager.Write("upn :" + upn);
@@ -1446,6 +1446,15 @@ namespace WebsitePanel.EnterpriseServer
return userId;
}
+
+ public static string BuildAccountNameEx(Organization org, string name)
+ {
+ StringDictionary serviceSettings = ServerController.GetServiceSettings(org.ServiceId);
+
+ return AppendOrgId(serviceSettings) ? BuildAccountNameWithOrgId(org.OrganizationId, name, org.ServiceId) : BuildAccountName(org.OrganizationId, name, org.ServiceId);
+ }
+
+
/// Checks should or not user name include organization id.
/// The service settings.
/// True - if organization id should be appended.
@@ -2370,8 +2379,8 @@ namespace WebsitePanel.EnterpriseServer
Organizations orgProxy = GetOrganizationProxy(org.ServiceId);
- string groupName = BuildAccountNameWithOrgId(org.OrganizationId, displayName.Replace(" ", ""), org.ServiceId);
-
+ string groupName = BuildAccountNameEx(org, displayName.Replace(" ", ""));
+
TaskManager.Write("accountName :" + groupName);
if (orgProxy.CreateSecurityGroup(org.OrganizationId, groupName) == 0)
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Packages/PackageController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Packages/PackageController.cs
index 1b89f3dc..cda59b87 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Packages/PackageController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Packages/PackageController.cs
@@ -489,7 +489,7 @@ namespace WebsitePanel.EnterpriseServer
ServerController.AddServiceDNSRecords(packageId, ResourceGroups.VPSForPC, domain, "");
}
}
-
+
if (createInstantAlias)
ServerController.CreateDomainInstantAlias("", domainId);
@@ -994,7 +994,7 @@ namespace WebsitePanel.EnterpriseServer
{
DataProvider.UpdatePackageBandwidthUpdate(packageId, updateDate);
}
-
+
// This gets the system quota and updates the home folder with the value
public static void UpdatePackageHardQuota(int packageId)
{
@@ -1019,6 +1019,33 @@ namespace WebsitePanel.EnterpriseServer
}
+ //public static void UpdateESHardQuota(int packageId)
+ //{
+ // int esServiceId = PackageController.GetPackageServiceId(packageId, ResourceGroups.EnterpriseStorage);
+
+ // if (esServiceId != 0)
+ // {
+
+ // StringDictionary esSesstings = ServerController.GetServiceSettings(esServiceId);
+
+ // string usersHome = esSesstings["UsersHome"];
+ // string usersDomain = esSesstings["UsersDomain"];
+ // string locationDrive = esSesstings["LocationDrive"];
+
+ // string homePath = string.Format("{0}:\\{1}", locationDrive, usersHome);
+
+ // int osId = PackageController.GetPackageServiceId(packageId, ResourceGroups.Os);
+ // bool enableHardQuota = (esSesstings["enablehardquota"] != null)
+ // ? bool.Parse(esSesstings["enablehardquota"])
+ // : false;
+
+ // if (enableHardQuota && osId != 0 && OperatingSystemController.CheckFileServicesInstallation(osId))
+ // {
+ // FilesController.SetFolderQuota(packageId, usersHome, locationDrive, Quotas.ENTERPRISESTORAGE_DISKSTORAGESPACE);
+ // }
+ // }
+ //}
+
#endregion
#region Package Add-ons
@@ -1061,7 +1088,7 @@ namespace WebsitePanel.EnterpriseServer
if (result.Result < 0)
result.Result = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive
| DemandAccount.IsResellerCSR);
-
+
if (result.Result < 0) return result;
int addonId = 0;
@@ -1108,7 +1135,6 @@ namespace WebsitePanel.EnterpriseServer
// Update the Hard quota on home folder in case it was enabled and in case there was a change in disk space
UpdatePackageHardQuota(addon.PackageId);
-
return result;
}
@@ -1119,12 +1145,13 @@ namespace WebsitePanel.EnterpriseServer
| DemandAccount.IsReseller);
if (accountCheck < 0) return accountCheck;
-
- // Update the Hard quota on home folder in case it was enabled and in case there was a change in disk space
- UpdatePackageHardQuota(GetPackageAddon(packageAddonId).PackageId);
+ var packageId = GetPackageAddon(packageAddonId).PackageId;
DataProvider.DeletePackageAddon(SecurityContext.User.UserId, packageAddonId);
+ // Update the Hard quota on home folder in case it was enabled and in case there was a change in disk space
+ UpdatePackageHardQuota(packageId);
+
return 0;
}
@@ -2075,7 +2102,7 @@ namespace WebsitePanel.EnterpriseServer
}
items["Addons"] = addOns;
-
+
// package contexts
Hashtable cntxs = new Hashtable();
foreach (PackageInfo package in packages)
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/DnsCommands.cs b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/DnsCommands.cs
new file mode 100644
index 00000000..52e0e367
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/DnsCommands.cs
@@ -0,0 +1,315 @@
+// Copyright (c) 2012 - 2013, 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.Linq;
+using System.Management.Automation;
+using System.Management.Automation.Runspaces;
+using System.Net;
+using WebsitePanel.Server.Utils;
+
+namespace WebsitePanel.Providers.DNS
+{
+ /// This class wraps MS DNS server PowerShell commands used by the WebsitePanel.
+ internal static class DnsCommands
+ {
+ /// Add parameter to PS command
+ /// command
+ /// Parameter name
+ /// Parameter value
+ /// Same command
+ private static Command addParam( this Command cmd, string name, object value )
+ {
+ cmd.Parameters.Add( name, value );
+ return cmd;
+ }
+
+ /// Add parameter without value to the PS command
+ /// command
+ /// Parameter name
+ /// Same command
+ private static Command addParam( this Command cmd, string name )
+ {
+ // http://stackoverflow.com/a/10304080/126995
+ cmd.Parameters.Add( name, true );
+ return cmd;
+ }
+
+ /// Create "Where-Object -Property ... -eq -Value ..." command
+ ///
+ ///
+ ///
+ private static Command where( string property, object value )
+ {
+ return new Command( "Where-Object" )
+ .addParam( "Property", property )
+ .addParam( "eq" )
+ .addParam( "Value", value );
+ }
+
+ /// Test-DnsServer -IPAddress 127.0.0.1
+ /// PowerShell host to use
+ /// true if localhost is an MS DNS server
+ public static bool Test_DnsServer( this PowerShellHelper ps )
+ {
+ if( null == ps )
+ throw new ArgumentNullException( "ps" );
+
+ var cmd = new Command( "Test-DnsServer" )
+ .addParam( "IPAddress", IPAddress.Loopback );
+
+ PSObject res = ps.RunPipeline( cmd ).FirstOrDefault();
+
+ if( null == res || null == res.Properties )
+ return false;
+ PSPropertyInfo p = res.Properties[ "Result" ];
+ if( null == p || null == p.Value )
+ return false;
+ return p.Value.ToString() == "Success";
+ }
+
+ #region Zones
+
+ /// Get-DnsServerZone | Select-Object -Property ZoneName
+ /// Only primary DNS zones are returned
+ /// Array of zone names
+ public static string[] Get_DnsServerZone_Names( this PowerShellHelper ps )
+ {
+ var allZones = ps.RunPipeline( new Command( "Get-DnsServerZone" ),
+ where( "IsAutoCreated", false ) );
+
+ string[] res = allZones
+ .Select( pso => new
+ {
+ name = (string)pso.Properties[ "ZoneName" ].Value,
+ type = (string)pso.Properties[ "ZoneType" ].Value
+ } )
+ .Where( obj => obj.type == "Primary" )
+ .Select( obj => obj.name )
+ .ToArray();
+
+ Log.WriteInfo( "Get_DnsServerZone_Names: {{{0}}}", String.Join( ", ", res ) );
+ return res;
+ }
+
+ /// Returns true if the specified zone exists.
+ /// The PS pipeline being run: Get-DnsServerZone | Where-Object -Property ZoneName -eq -Value "name"
+ ///
+ ///
+ ///
+ public static bool ZoneExists( this PowerShellHelper ps, string name )
+ {
+ Log.WriteStart( "ZoneExists {0}", name );
+ bool res = ps.RunPipeline( new Command( "Get-DnsServerZone" ),
+ where( "ZoneName", name ) )
+ .Any();
+ Log.WriteEnd( "ZoneExists: {0}", res );
+ return res;
+ }
+
+ /* public enum eReplicationScope: byte
+ {
+ Custom, Domain, Forest, Legacy
+ } */
+
+ ///
+ ///
+ ///
+ /// Specifies a partition on which to store an Active Directory-integrated zone.
+ ///
+ public static void Add_DnsServerPrimaryZone( this PowerShellHelper ps, string zoneName, string[] secondaryServers )
+ {
+ Log.WriteStart( "Add_DnsServerPrimaryZone {0} {{{1}}}", zoneName, String.Join( ", ", secondaryServers ) );
+
+ // Add-DnsServerPrimaryZone -Name zzz.com -ZoneFile zzz.com.dns
+ var cmd = new Command( "Add-DnsServerPrimaryZone" );
+ cmd.addParam( "Name", zoneName );
+ cmd.addParam( "ZoneFile", zoneName + ".dns" );
+ ps.RunPipeline( cmd );
+
+ // Set-DnsServerPrimaryZone -Name zzz.com -SecureSecondaries ... -Notify ... Servers ..
+ cmd = new Command( "Set-DnsServerPrimaryZone" );
+ cmd.addParam( "Name", zoneName );
+
+ if( secondaryServers == null || secondaryServers.Length == 0 )
+ {
+ // transfers are not allowed
+ // inParams2[ "SecureSecondaries" ] = 3;
+ // inParams2[ "Notify" ] = 0;
+ cmd.addParam( "SecureSecondaries", "NoTransfer" );
+ cmd.addParam( "Notify", "NoNotify" );
+ }
+ else if( secondaryServers.Length == 1 && secondaryServers[ 0 ] == "*" )
+ {
+ // allowed transfer from all servers
+ // inParams2[ "SecureSecondaries" ] = 0;
+ // inParams2[ "Notify" ] = 1;
+ cmd.addParam( "SecureSecondaries", "TransferAnyServer" );
+ cmd.addParam( "Notify", "Notify" );
+ }
+ else
+ {
+ // allowed transfer from specified servers
+ // inParams2[ "SecureSecondaries" ] = 2;
+ // inParams2[ "SecondaryServers" ] = secondaryServers;
+ // inParams2[ "NotifyServers" ] = secondaryServers;
+ // inParams2[ "Notify" ] = 2;
+ cmd.addParam( "SecureSecondaries", "TransferToSecureServers" );
+ cmd.addParam( "Notify", "NotifyServers" );
+ cmd.addParam( "SecondaryServers", secondaryServers );
+ cmd.addParam( "NotifyServers", secondaryServers );
+ }
+ ps.RunPipeline( cmd );
+ Log.WriteEnd( "Add_DnsServerPrimaryZone" );
+ }
+
+ /// Call Add-DnsServerSecondaryZone cmdlet
+ ///
+ /// a name of a zone
+ /// an array of IP addresses of the master servers of the zone. You can use both IPv4 and IPv6.
+ public static void Add_DnsServerSecondaryZone( this PowerShellHelper ps, string zoneName, string[] masterServers )
+ {
+ // Add-DnsServerSecondaryZone -Name zzz.com -ZoneFile zzz.com.dns -MasterServers ...
+ var cmd = new Command( "Add-DnsServerSecondaryZone" );
+ cmd.addParam( "Name", zoneName );
+ cmd.addParam( "ZoneFile", zoneName + ".dns" );
+ cmd.addParam( "MasterServers", masterServers );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Remove_DnsServerZone( this PowerShellHelper ps, string zoneName )
+ {
+ var cmd = new Command( "Remove-DnsServerZone" );
+ cmd.addParam( "Name", zoneName );
+ cmd.addParam( "Force" );
+ ps.RunPipeline( cmd );
+ }
+ #endregion
+
+ /// Get all records, except the SOA
+ ///
+ /// Name of the zone
+ /// Array of records
+ public static DnsRecord[] GetZoneRecords( this PowerShellHelper ps, string zoneName )
+ {
+ // Get-DnsServerResourceRecord -ZoneName xxxx.com
+ var allRecords = ps.RunPipeline( new Command( "Get-DnsServerResourceRecord" ).addParam( "ZoneName", zoneName ) );
+
+ return allRecords.Select( o => o.asDnsRecord( zoneName ) )
+ .Where( r => null != r )
+ .Where( r => r.RecordType != DnsRecordType.SOA )
+ // .Where( r => !( r.RecordName == "@" && DnsRecordType.NS == r.RecordType ) )
+ .ToArray();
+ }
+
+ #region Records add / remove
+
+ public static void Add_DnsServerResourceRecordA( this PowerShellHelper ps, string zoneName, string Name, string address )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecordA" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "IPv4Address", address );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordAAAA( this PowerShellHelper ps, string zoneName, string Name, string address )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecordAAAA" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "IPv6Address", address );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordCName( this PowerShellHelper ps, string zoneName, string Name, string alias )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecordCName" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "HostNameAlias", alias );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordMX( this PowerShellHelper ps, string zoneName, string Name, string mx, UInt16 pref )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecordMX" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "MailExchange", mx );
+ cmd.addParam( "Preference", pref );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordNS( this PowerShellHelper ps, string zoneName, string Name, string NameServer )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecord" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "NS" );
+ cmd.addParam( "NameServer", NameServer );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordTXT( this PowerShellHelper ps, string zoneName, string Name, string txt )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecord" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "Txt" );
+ cmd.addParam( "DescriptiveText", txt );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordSRV( this PowerShellHelper ps, string zoneName, string Name, string DomainName, UInt16 Port, UInt16 Priority, UInt16 Weight )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecord" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "Srv" );
+ cmd.addParam( "DomainName", DomainName );
+ cmd.addParam( "Port", Port );
+ cmd.addParam( "Priority", Priority );
+ cmd.addParam( "Weight", Weight );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Remove_DnsServerResourceRecord( this PowerShellHelper ps, string zoneName, string Name, string type )
+ {
+ // Remove-DnsServerResourceRecord -ZoneName xxxx.com -Name "@" -RRType Soa -Force
+ var cmd = new Command( "Remove-DnsServerResourceRecord" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "RRType", type );
+ cmd.addParam( "Force" );
+ ps.RunPipeline( cmd );
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/MsDNS.cs b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/MsDNS.cs
new file mode 100644
index 00000000..13b69fdb
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/MsDNS.cs
@@ -0,0 +1,422 @@
+// Copyright (c) 2012 - 2013, 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.Management;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Win32;
+
+using WebsitePanel.Server.Utils;
+using WebsitePanel.Providers.Utils;
+
+namespace WebsitePanel.Providers.DNS
+{
+ public class MsDNS: HostingServiceProviderBase, IDnsServer
+ {
+
+ protected int ExpireLimit
+ {
+ get { return ProviderSettings.GetInt( "ExpireLimit" ); }
+ }
+
+ protected int MinimumTTL
+ {
+ get { return ProviderSettings.GetInt( "MinimumTTL" ); }
+ }
+
+ protected int RefreshInterval
+ {
+ get { return ProviderSettings.GetInt( "RefreshInterval" ); }
+ }
+
+ protected int RetryDelay
+ {
+ get { return ProviderSettings.GetInt( "RetryDelay" ); }
+ }
+
+ protected bool AdMode
+ {
+ get { return ProviderSettings.GetBool( "AdMode" ); }
+ }
+
+ private PowerShellHelper ps = null;
+ private WmiHelper wmi = null; //< We still need WMI because PowerShell doesn't support SOA updates.
+ private bool bulkRecords;
+
+ public MsDNS()
+ {
+ // Create PowerShell helper
+ ps = new PowerShellHelper();
+ if( !this.IsInstalled() )
+ return;
+
+ // Create WMI helper
+ wmi = new WmiHelper( "root\\MicrosoftDNS" );
+ }
+
+ #region Zones
+
+ public virtual string[] GetZones()
+ {
+ return ps.Get_DnsServerZone_Names();
+ }
+
+ public virtual bool ZoneExists( string zoneName )
+ {
+ return ps.ZoneExists( zoneName );
+ }
+
+ public virtual DnsRecord[] GetZoneRecords( string zoneName )
+ {
+ return ps.GetZoneRecords( zoneName );
+ }
+
+ public virtual void AddPrimaryZone( string zoneName, string[] secondaryServers )
+ {
+ ps.Add_DnsServerPrimaryZone( zoneName, secondaryServers );
+
+ // delete orphan NS records
+ DeleteOrphanNsRecords( zoneName );
+ }
+
+ public virtual void AddSecondaryZone( string zoneName, string[] masterServers )
+ {
+ ps.Add_DnsServerSecondaryZone( zoneName, masterServers );
+
+ // delete orphan NS records
+ DeleteOrphanNsRecords( zoneName );
+ }
+
+ public virtual void DeleteZone( string zoneName )
+ {
+ try
+ {
+ ps.Remove_DnsServerZone( zoneName );
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( ex );
+ }
+ }
+
+ public virtual void AddZoneRecord( string zoneName, DnsRecord record )
+ {
+ try
+ {
+ string name = record.RecordName;
+ if( String.IsNullOrEmpty( name ) )
+ name = ".";
+
+ if( record.RecordType == DnsRecordType.A )
+ ps.Add_DnsServerResourceRecordA( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.AAAA )
+ ps.Add_DnsServerResourceRecordAAAA( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.CNAME )
+ ps.Add_DnsServerResourceRecordCName( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.MX )
+ ps.Add_DnsServerResourceRecordMX( zoneName, name, record.RecordData, (ushort)record.MxPriority );
+ else if( record.RecordType == DnsRecordType.NS )
+ ps.Add_DnsServerResourceRecordNS( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.TXT )
+ ps.Add_DnsServerResourceRecordTXT( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.SRV )
+ ps.Add_DnsServerResourceRecordSRV( zoneName, name, record.RecordData, (ushort)record.SrvPort, (ushort)record.SrvPriority, (ushort)record.SrvWeight );
+ else
+ throw new Exception( "Unknown record type" );
+ }
+ catch( Exception ex )
+ {
+ // log exception
+ Log.WriteError( ex );
+ }
+ }
+
+ public virtual void AddZoneRecords( string zoneName, DnsRecord[] records )
+ {
+ bulkRecords = true;
+ try
+ {
+ foreach( DnsRecord record in records )
+ AddZoneRecord( zoneName, record );
+ }
+ finally
+ {
+ bulkRecords = false;
+ }
+
+ UpdateSoaRecord( zoneName );
+ }
+
+ public virtual void DeleteZoneRecord( string zoneName, DnsRecord record )
+ {
+ try
+ {
+ string rrType;
+ if( !RecordTypes.rrTypeFromRecord.TryGetValue( record.RecordType, out rrType ) )
+ throw new Exception( "Unknown record type" );
+ ps.Remove_DnsServerResourceRecord( zoneName, record.RecordName, rrType );
+ }
+ catch( Exception ex )
+ {
+ // log exception
+ Log.WriteError( ex );
+ }
+ }
+
+ public virtual void DeleteZoneRecords( string zoneName, DnsRecord[] records )
+ {
+ foreach( DnsRecord record in records )
+ DeleteZoneRecord( zoneName, record );
+ }
+
+ public void AddZoneRecord( string zoneName, string recordText )
+ {
+ try
+ {
+ Log.WriteStart( string.Format( "Adding MS DNS Server zone '{0}' record '{1}'", zoneName, recordText ) );
+ AddDnsRecord( zoneName, recordText );
+ Log.WriteEnd( "Added MS DNS Server zone record" );
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( ex );
+ throw;
+ }
+ }
+ #endregion
+
+ #region SOA Record
+ public virtual void UpdateSoaRecord( string zoneName, string host, string primaryNsServer, string primaryPerson )
+ {
+ host = CorrectHostName( zoneName, host );
+
+ // delete record if exists
+ DeleteSoaRecord( zoneName );
+
+ // format record data
+ string recordText = GetSoaRecordText( host, primaryNsServer, primaryPerson );
+
+ // add record
+ AddDnsRecord( zoneName, recordText );
+
+ // update SOA record
+ UpdateSoaRecord( zoneName );
+ }
+
+ private void DeleteSoaRecord( string zoneName )
+ {
+ // TODO: find a PowerShell replacement
+
+ string query = String.Format( "SELECT * FROM MicrosoftDNS_SOAType " +
+ "WHERE OwnerName = '{0}'",
+ zoneName );
+ using( ManagementObjectCollection objRRs = wmi.ExecuteQuery( query ) )
+ {
+ foreach( ManagementObject objRR in objRRs ) using( objRR )
+ objRR.Delete();
+ }
+
+ // This doesn't work: no errors in PS, but the record stays in the DNS
+ /* try
+ {
+ ps.Remove_DnsServerResourceRecord( zoneName, "@", "Soa" );
+ }
+ catch( System.Exception ex )
+ {
+ Log.WriteWarning( "{0}", ex.Message );
+ } */
+ }
+
+ private string GetSoaRecordText( string host, string primaryNsServer, string primaryPerson )
+ {
+ return String.Format( "{0} IN SOA {1} {2} 1 900 600 86400 3600", host, primaryNsServer, primaryPerson );
+ }
+
+ private static string RemoveTrailingDot( string str )
+ {
+ return ( str.EndsWith( "." ) ) ? str.Substring( 0, str.Length - 1 ) : str;
+ }
+
+ private void UpdateSoaRecord( string zoneName )
+ {
+ if( bulkRecords )
+ return;
+
+ // TODO: find a PowerShell replacement
+
+ // get existing SOA record in order to read serial number
+ try
+ {
+
+ ManagementObject objSoa = wmi.GetWmiObject( "MicrosoftDNS_SOAType", "ContainerName = '{0}'", RemoveTrailingDot( zoneName ) );
+
+ if( objSoa != null )
+ {
+ if( objSoa.Properties[ "OwnerName" ].Value.Equals( zoneName ) )
+ {
+ string primaryServer = (string)objSoa.Properties[ "PrimaryServer" ].Value;
+ string responsibleParty = (string)objSoa.Properties[ "ResponsibleParty" ].Value;
+ UInt32 serialNumber = (UInt32)objSoa.Properties[ "SerialNumber" ].Value;
+
+ // update record's serial number
+ string sn = serialNumber.ToString();
+ string todayDate = DateTime.Now.ToString( "yyyyMMdd" );
+ if( sn.Length < 10 || !sn.StartsWith( todayDate ) )
+ {
+ // build a new serial number
+ sn = todayDate + "01";
+ serialNumber = UInt32.Parse( sn );
+ }
+ else
+ {
+ // just increment serial number
+ serialNumber += 1;
+ }
+
+ // update SOA record
+ using( ManagementBaseObject methodParams = objSoa.GetMethodParameters( "Modify" ) )
+ {
+ methodParams[ "ResponsibleParty" ] = responsibleParty;
+ methodParams[ "PrimaryServer" ] = primaryServer;
+ methodParams[ "SerialNumber" ] = serialNumber;
+
+ methodParams[ "ExpireLimit" ] = ExpireLimit;
+ methodParams[ "MinimumTTL" ] = MinimumTTL;
+ methodParams[ "TTL" ] = MinimumTTL;
+ methodParams[ "RefreshInterval" ] = RefreshInterval;
+ methodParams[ "RetryDelay" ] = RetryDelay;
+
+ ManagementBaseObject outParams = objSoa.InvokeMethod( "Modify", methodParams, null );
+ }
+ //
+ objSoa.Dispose();
+ }
+
+ }
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( ex );
+ }
+ }
+
+ #endregion
+
+ private void DeleteOrphanNsRecords( string zoneName )
+ {
+ // TODO: find a PowerShell replacement
+ string machineName = System.Net.Dns.GetHostEntry( "LocalHost" ).HostName.ToLower();
+ string computerName = Environment.MachineName.ToLower();
+
+ using( ManagementObjectCollection objRRs = wmi.ExecuteQuery( String.Format( "SELECT * FROM MicrosoftDNS_NSType WHERE DomainName = '{0}'", zoneName ) ) )
+ {
+ foreach( ManagementObject objRR in objRRs )
+ {
+ using( objRR )
+ {
+ string ns = ( (string)objRR.Properties[ "NSHost" ].Value ).ToLower();
+ if( ns.StartsWith( machineName ) || ns.StartsWith( computerName ) )
+ objRR.Delete();
+
+ }
+ }
+ }
+ }
+
+ #region private helper methods
+
+ private string GetDnsServerName()
+ {
+ // TODO: find a PowerShell replacement
+ using( ManagementObject objServer = wmi.GetObject( "MicrosoftDNS_Server.Name=\".\"" ) )
+ {
+ return (string)objServer.Properties[ "Name" ].Value;
+ }
+ }
+
+ private string AddDnsRecord( string zoneName, string recordText )
+ {
+ // get the name of the server
+ string serverName = GetDnsServerName();
+
+ // TODO: find a PowerShell replacement
+ // add record
+ using( ManagementClass clsRR = wmi.GetClass( "MicrosoftDNS_ResourceRecord" ) )
+ {
+ object[] prms = new object[] { serverName, zoneName, recordText, null };
+ clsRR.InvokeMethod( "CreateInstanceFromTextRepresentation", prms );
+ return (string)prms[ 3 ];
+ }
+ }
+
+ private string CorrectHostName( string zoneName, string host )
+ {
+ // if host is empty or null
+ if( host == null || host == "" )
+ return zoneName;
+
+ // if there are not dot at all
+ else if( host.IndexOf( "." ) == -1 )
+ return host + "." + zoneName;
+
+ // if only one dot at the end
+ else if( host[ host.Length - 1 ] == '.' && host.IndexOf( "." ) == ( host.Length - 1 ) )
+ return host + zoneName;
+
+ // other cases
+ else
+ return host;
+ }
+ #endregion
+
+ public override void DeleteServiceItems( ServiceProviderItem[] items )
+ {
+ foreach( ServiceProviderItem item in items )
+ {
+ if( item is DnsZone )
+ {
+ try
+ {
+ // delete DNS zone
+ DeleteZone( item.Name );
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( String.Format( "Error deleting '{0}' MS DNS zone", item.Name ), ex );
+ }
+ }
+ }
+ }
+
+ public override bool IsInstalled()
+ {
+ return ps.Test_DnsServer();
+ }
+ }
+}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/PowerShellHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/PowerShellHelper.cs
new file mode 100644
index 00000000..72f5563e
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/PowerShellHelper.cs
@@ -0,0 +1,112 @@
+// Copyright (c) 2012 - 2013, 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.Generic;
+using System.Collections.ObjectModel;
+using System.Management.Automation;
+using System.Management.Automation.Runspaces;
+using WebsitePanel.Server.Utils;
+
+namespace WebsitePanel.Providers.DNS
+{
+ /// This class is a generic helper hosting the PowerShell runtime.
+ /// It's probably a good idea to move to some utility module.
+ public class PowerShellHelper: IDisposable
+ {
+ private static InitialSessionState s_session = null;
+
+ static PowerShellHelper()
+ {
+ s_session = InitialSessionState.CreateDefault();
+ // s_session.ImportPSModule( new string[] { "FileServerResourceManager" } );
+ }
+
+ public PowerShellHelper()
+ {
+ Log.WriteStart( "PowerShellHelper::ctor" );
+
+ Runspace rs = RunspaceFactory.CreateRunspace( s_session );
+ rs.Open();
+ // rs.SessionStateProxy.SetVariable( "ConfirmPreference", "none" );
+
+ this.runSpace = rs;
+ Log.WriteEnd( "PowerShellHelper::ctor" );
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if( this.runSpace == null )
+ return;
+ if( this.runSpace.RunspaceStateInfo.State == RunspaceState.Opened )
+ this.runSpace.Close();
+ this.runSpace = null;
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( "Runspace error", ex );
+ }
+ }
+
+ public Runspace runSpace { get; private set; }
+
+ public Collection RunPipeline( params Command[] pipelineCommands )
+ {
+ Log.WriteStart( "ExecuteShellCommand" );
+ List