Add NTFS folder whitelist support

This commit is contained in:
Meik
2026-03-29 22:39:35 +02:00
parent 246af92f5d
commit 804eee20fd

View File

@@ -371,14 +371,16 @@ namespace C4IT.LIAM
foreach (var childPath in GetServerRootChildPaths(parentClassification.NormalizedPath)) foreach (var childPath in GetServerRootChildPaths(parentClassification.NormalizedPath))
{ {
var childClassification = ClassifyPath(childPath); var childClassification = ClassifyPath(childPath);
if (!ShouldIncludeDataArea(childClassification)) if (!ShouldTraverseDataArea(childClassification))
continue; continue;
var childDataArea = await BuildDataAreaAsync(childClassification); if (ShouldIncludeDataArea(childClassification))
if (childDataArea == null) {
continue; var childDataArea = await BuildDataAreaAsync(childClassification);
if (childDataArea != null)
children.Add(childDataArea);
}
children.Add(childDataArea);
if (depth > 1) if (depth > 1)
children.AddRange(await GetChildDataAreasAsync(childClassification, depth - 1)); children.AddRange(await GetChildDataAreasAsync(childClassification, depth - 1));
} }
@@ -393,14 +395,16 @@ namespace C4IT.LIAM
foreach (var entry in folderEntries.Values.OfType<cNtfsResultFolder>()) foreach (var entry in folderEntries.Values.OfType<cNtfsResultFolder>())
{ {
var childClassification = ClassifyPath(entry.Path); var childClassification = ClassifyPath(entry.Path);
if (!ShouldIncludeDataArea(childClassification)) if (!ShouldTraverseDataArea(childClassification))
continue; continue;
var childDataArea = await BuildDataAreaAsync(childClassification, entry); if (ShouldIncludeDataArea(childClassification))
if (childDataArea == null) {
continue; var childDataArea = await BuildDataAreaAsync(childClassification, entry);
if (childDataArea != null)
children.Add(childDataArea);
}
children.Add(childDataArea);
if (depth > 1) if (depth > 1)
children.AddRange(await GetChildDataAreasAsync(childClassification, depth - 1)); children.AddRange(await GetChildDataAreasAsync(childClassification, depth - 1));
} }
@@ -436,9 +440,44 @@ namespace C4IT.LIAM
return false; return false;
} }
if (!IsWhitelistedFolderPath(classification, true, out matchingConfigurationKey, out matchingRule))
{
LogEntry($"Skip NTFS path '{classification.NormalizedPath}' because no AdditionalConfiguration whitelist matched", LogLevels.Debug);
return false;
}
return true; return true;
} }
private bool ShouldTraverseDataArea(cNtfsPathClassification classification)
{
if (classification == null)
return false;
string matchingConfigurationKey;
string matchingRule;
if (IsBlacklistedFolderPath(classification, out matchingConfigurationKey, out matchingRule))
{
LogEntry($"Skip NTFS subtree '{classification.NormalizedPath}' due to AdditionalConfiguration rule '{matchingConfigurationKey}={matchingRule}'", LogLevels.Debug);
return false;
}
if (HasAdditionalConfigurationValues("NtfsIncludeFolderNames"))
return true;
if (!HasAdditionalConfigurationValues("NtfsIncludeRelativePaths"))
return true;
if (classification.Kind != eNtfsPathKind.Folder)
return true;
if (IsWhitelistedFolderPath(classification, true, out matchingConfigurationKey, out matchingRule))
return true;
LogEntry($"Skip NTFS subtree '{classification.NormalizedPath}' because it is outside AdditionalConfiguration whitelist 'NtfsIncludeRelativePaths'", LogLevels.Debug);
return false;
}
private bool MatchesDataAreaRegEx(string displayName) private bool MatchesDataAreaRegEx(string displayName)
{ {
if (string.IsNullOrEmpty(this.DataAreaRegEx)) if (string.IsNullOrEmpty(this.DataAreaRegEx))
@@ -479,6 +518,61 @@ namespace C4IT.LIAM
return false; return false;
} }
private bool IsWhitelistedFolderPath(cNtfsPathClassification classification, bool allowRelativePathAncestorMatches, out string matchingConfigurationKey, out string matchingRule)
{
matchingConfigurationKey = null;
matchingRule = null;
if (classification == null || classification.Kind != eNtfsPathKind.Folder)
return true;
var hasIncludeFolderNames = HasAdditionalConfigurationValues("NtfsIncludeFolderNames");
var hasIncludeRelativePaths = HasAdditionalConfigurationValues("NtfsIncludeRelativePaths");
if (!hasIncludeFolderNames && !hasIncludeRelativePaths)
return true;
foreach (var includedFolderName in GetAdditionalConfigurationValues("NtfsIncludeFolderNames"))
{
if (!MatchesAdditionalConfigurationPattern(classification.DisplayName, includedFolderName))
continue;
matchingConfigurationKey = "NtfsIncludeFolderNames";
matchingRule = includedFolderName;
return true;
}
var relativePath = GetRelativePathFromRoot(classification.NormalizedPath);
foreach (var includedRelativePath in GetAdditionalConfigurationValues("NtfsIncludeRelativePaths"))
{
if (!MatchesAdditionalConfigurationPattern(relativePath, includedRelativePath))
continue;
matchingConfigurationKey = "NtfsIncludeRelativePaths";
matchingRule = includedRelativePath;
return true;
}
if (allowRelativePathAncestorMatches)
{
foreach (var includedRelativePath in GetAdditionalConfigurationValues("NtfsIncludeRelativePaths"))
{
if (!IsRelativePathAncestorOfPattern(relativePath, includedRelativePath))
continue;
matchingConfigurationKey = "NtfsIncludeRelativePaths";
matchingRule = includedRelativePath;
return true;
}
}
return false;
}
private bool HasAdditionalConfigurationValues(string key)
{
return GetAdditionalConfigurationValues(key).Any();
}
private IEnumerable<string> GetAdditionalConfigurationValues(string key) private IEnumerable<string> GetAdditionalConfigurationValues(string key)
{ {
if (AdditionalConfiguration == null || string.IsNullOrWhiteSpace(key)) if (AdditionalConfiguration == null || string.IsNullOrWhiteSpace(key))
@@ -531,6 +625,29 @@ namespace C4IT.LIAM
return Regex.IsMatch(normalizedValue, regexPattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); return Regex.IsMatch(normalizedValue, regexPattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
} }
private bool IsRelativePathAncestorOfPattern(string relativePath, string pattern)
{
var normalizedRelativePath = (relativePath ?? string.Empty).Trim().Replace('/', '\\').Trim('\\');
if (string.IsNullOrWhiteSpace(normalizedRelativePath) || string.IsNullOrWhiteSpace(pattern))
return false;
var prefixSegments = new List<string>();
foreach (var patternSegment in pattern.Trim().Replace('/', '\\').Trim('\\').Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries))
{
if (patternSegment.Contains("*"))
break;
prefixSegments.Add(patternSegment);
}
if (prefixSegments.Count == 0)
return false;
var normalizedPatternPrefix = string.Join("\\", prefixSegments);
return normalizedPatternPrefix.Equals(normalizedRelativePath, StringComparison.OrdinalIgnoreCase)
|| normalizedPatternPrefix.StartsWith(normalizedRelativePath + "\\", StringComparison.OrdinalIgnoreCase);
}
private List<string> GetDfsObjectPrefixes(string path) private List<string> GetDfsObjectPrefixes(string path)
{ {
var normalizedPath = NormalizeUncPath(path); var normalizedPath = NormalizeUncPath(path);
@@ -847,7 +964,10 @@ namespace C4IT.LIAM
string matchingConfigurationKey; string matchingConfigurationKey;
string matchingRule; string matchingRule;
return !IsBlacklistedFolderPath(classification, out matchingConfigurationKey, out matchingRule); if (IsBlacklistedFolderPath(classification, out matchingConfigurationKey, out matchingRule))
return false;
return IsWhitelistedFolderPath(classification, false, out matchingConfigurationKey, out matchingRule);
} }
private IEnumerable<IAM_SecurityGroupTemplate> BuildSecurityGroupTemplates() private IEnumerable<IAM_SecurityGroupTemplate> BuildSecurityGroupTemplates()