diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.OS.Windows2012/Windows2012.cs b/WebsitePanel/Sources/WebsitePanel.Providers.OS.Windows2012/Windows2012.cs index fae5194e..3542555e 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.OS.Windows2012/Windows2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.OS.Windows2012/Windows2012.cs @@ -68,7 +68,9 @@ namespace WebsitePanel.Providers.OS { Server.Utils.OS.WindowsVersion version = WebsitePanel.Server.Utils.OS.GetVersion(); return version == WebsitePanel.Server.Utils.OS.WindowsVersion.WindowsServer2012 - || version == WebsitePanel.Server.Utils.OS.WindowsVersion.Windows8; + || version == WebsitePanel.Server.Utils.OS.WindowsVersion.Windows8 + || version == WebsitePanel.Server.Utils.OS.WindowsVersion.WindowsServer2012R2 + || version == WebsitePanel.Server.Utils.OS.WindowsVersion.Windows81; } public override void SetQuotaLimitOnFolder(string folderPath, string shareNameDrive, string quotaLimit, int mode, string wmiUserName, string wmiPassword) diff --git a/WebsitePanel/Sources/WebsitePanel.Server.Utils/SecurityUtils.cs b/WebsitePanel/Sources/WebsitePanel.Server.Utils/SecurityUtils.cs index fbdecf14..b086cc60 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server.Utils/SecurityUtils.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server.Utils/SecurityUtils.cs @@ -352,11 +352,81 @@ namespace WebsitePanel.Providers.Utils private static FileSystemSecurity GetFileSystemSecurity(string path) { if (Directory.Exists(path)) - return new DirectoryInfo(path).GetAccessControl(); + { + DirectoryInfo directoryInfo = new DirectoryInfo(path); + var directorySecurity = directoryInfo.GetAccessControl(AccessControlSections.Access); + CanonicalizeDacl(directorySecurity); + directoryInfo.SetAccessControl(directorySecurity); + return directoryInfo.GetAccessControl(); + } else if (File.Exists(path)) return new FileInfo(path).GetAccessControl(); else return null; + + } + + private static void CanonicalizeDacl(NativeObjectSecurity objectSecurity) + { + if (objectSecurity == null) { throw new ArgumentNullException("objectSecurity"); } + if (objectSecurity.AreAccessRulesCanonical) { return; } + + // A canonical ACL must have ACES sorted according to the following order: + // 1. Access-denied on the object + // 2. Access-denied on a child or property + // 3. Access-allowed on the object + // 4. Access-allowed on a child or property + // 5. All inherited ACEs + RawSecurityDescriptor descriptor = new RawSecurityDescriptor(objectSecurity.GetSecurityDescriptorSddlForm(AccessControlSections.Access)); + + List implicitDenyDacl = new List(); + List implicitDenyObjectDacl = new List(); + List inheritedDacl = new List(); + List implicitAllowDacl = new List(); + List implicitAllowObjectDacl = new List(); + + foreach (CommonAce ace in descriptor.DiscretionaryAcl) + { + if ((ace.AceFlags & AceFlags.Inherited) == AceFlags.Inherited) { inheritedDacl.Add(ace); } + else + { + switch (ace.AceType) + { + case AceType.AccessAllowed: + implicitAllowDacl.Add(ace); + break; + + case AceType.AccessDenied: + implicitDenyDacl.Add(ace); + break; + + case AceType.AccessAllowedObject: + implicitAllowObjectDacl.Add(ace); + break; + + case AceType.AccessDeniedObject: + implicitDenyObjectDacl.Add(ace); + break; + } + } + } + + Int32 aceIndex = 0; + RawAcl newDacl = new RawAcl(descriptor.DiscretionaryAcl.Revision, descriptor.DiscretionaryAcl.Count); + implicitDenyDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x)); + implicitDenyObjectDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x)); + implicitAllowDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x)); + implicitAllowObjectDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x)); + inheritedDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x)); + + if (aceIndex != descriptor.DiscretionaryAcl.Count) + { + System.Diagnostics.Debug.Fail("The DACL cannot be canonicalized since it would potentially result in a loss of information"); + return; + } + + descriptor.DiscretionaryAcl = newDacl; + objectSecurity.SetSecurityDescriptorSddlForm(descriptor.GetSddlForm(AccessControlSections.Access), AccessControlSections.Access); } private static void SetFileSystemSecurity(string path, FileSystemSecurity security)