Log LIAM assembly identities and cap traverse depth

This commit is contained in:
Meik
2026-07-09 23:30:07 +02:00
parent e8b138f9c3
commit b9cd74c5a9
3 changed files with 70 additions and 4 deletions

View File

@@ -1521,10 +1521,33 @@ namespace C4IT.LIAM
private cNtfsLevelRange GetTraverseLevelRange() private cNtfsLevelRange GetTraverseLevelRange()
{ {
return GetConfiguredLevelRange( var range = GetConfiguredLevelRange(
AdditionalConfigurationTraverseGroupsMinLevelKey, AdditionalConfigurationTraverseGroupsMinLevelKey,
AdditionalConfigurationTraverseGroupsMaxLevelKey, AdditionalConfigurationTraverseGroupsMaxLevelKey,
"traverse group level range"); "traverse group level range");
if (range.IsValid
&& !HasAdditionalConfigurationValue(AdditionalConfigurationTraverseGroupsMaxLevelKey)
&& MaxDepth > 0)
{
var maxDepthLevel = MaxDepth - 1;
if (range.IsConfigured)
{
range.MaxLevel = Math.Min(range.MaxLevel, maxDepthLevel);
}
else
{
range.IsConfigured = true;
range.MaxLevel = maxDepthLevel;
}
if (range.MinLevel > range.MaxLevel)
{
range.IsValid = false;
range.ErrorMessage = $"AdditionalConfiguration traverse group level range is invalid because min level {range.MinLevel} is greater than effective max level {range.MaxLevel}.";
}
}
return range;
} }
private cNtfsLevelRange GetConfiguredLevelRange(string minKey, string maxKey, string label) private cNtfsLevelRange GetConfiguredLevelRange(string minKey, string maxKey, string label)
@@ -1572,6 +1595,11 @@ namespace C4IT.LIAM
return range; return range;
} }
private bool HasAdditionalConfigurationValue(string key)
{
return !string.IsNullOrWhiteSpace(GetAdditionalConfigurationValue(key));
}
private static bool IsSupportedPermissionManagedPathKind(cNtfsPathClassification classification, params eNtfsPathKind[] supportedKinds) private static bool IsSupportedPermissionManagedPathKind(cNtfsPathClassification classification, params eNtfsPathKind[] supportedKinds)
{ {
if (classification == null || supportedKinds == null || supportedKinds.Length == 0) if (classification == null || supportedKinds == null || supportedKinds.Length == 0)

View File

@@ -2,7 +2,9 @@
using System; using System;
using System.Activities; using System.Activities;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Security.Cryptography;
using static C4IT.Logging.cLogManager; using static C4IT.Logging.cLogManager;
using Matrix42.Contracts.Platform.Data; using Matrix42.Contracts.Platform.Data;
using Matrix42.ServiceRepository.Contracts.Components; using Matrix42.ServiceRepository.Contracts.Components;
@@ -120,6 +122,9 @@ namespace LiamWorkflowActivities
var CM = MethodBase.GetCurrentMethod(); var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM); LogMethodBegin(CM);
cLogManager.DefaultLogger.LogAssemblyInfo(Ass); cLogManager.DefaultLogger.LogAssemblyInfo(Ass);
LogAssemblyIdentity("WorkflowActivities", Ass);
LogAssemblyIdentity("LiamNtfs", typeof(cLiamProviderNtfs).Assembly);
LogAssemblyIdentity("LiamBaseClasses", typeof(cLiamProviderBase).Assembly);
IsInitialized = true; IsInitialized = true;
LogMethodEnd(CM); LogMethodEnd(CM);
} }
@@ -127,6 +132,39 @@ namespace LiamWorkflowActivities
catch { }; catch { };
} }
private static void LogAssemblyIdentity(string label, Assembly assembly)
{
if (assembly == null)
return;
var fileVersion = string.IsNullOrWhiteSpace(assembly.Location)
? null
: FileVersionInfo.GetVersionInfo(assembly.Location);
var informationalVersion = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? string.Empty;
LogEntry(
$"LIAM assembly identity: Label='{label}', Name='{assembly.GetName().Name}', AssemblyVersion='{assembly.GetName().Version}', InformationalVersion='{informationalVersion}', FileVersion='{fileVersion?.FileVersion}', ProductVersion='{fileVersion?.ProductVersion}', Sha256='{GetAssemblySha256(assembly)}', Location='{assembly.Location}'",
LogLevels.Info);
}
private static string GetAssemblySha256(Assembly assembly)
{
try
{
if (assembly == null || string.IsNullOrWhiteSpace(assembly.Location) || !File.Exists(assembly.Location))
return string.Empty;
using (var stream = File.OpenRead(assembly.Location))
using (var sha256 = SHA256.Create())
{
return BitConverter.ToString(sha256.ComputeHash(stream)).Replace("-", string.Empty);
}
}
catch
{
return string.Empty;
}
}
public bool LoadLicensingInformation(bool force = false) public bool LoadLicensingInformation(bool force = false)
{ {
if (cC4ITLicenseM42ESM.Instance == null || force) if (cC4ITLicenseM42ESM.Instance == null || force)

View File

@@ -211,7 +211,7 @@ Im Diagnose-JSON erscheinen diese Werte unter `AdditionalConfiguration`. Paramet
| `NtfsExcludePaths` | Pfadliste, getrennt mit `;`, &#124; oder Zeilenumbruechen | Schliesst passende Pfade von der NTFS-Verarbeitung aus. Excludes gewinnen gegen Includes. Unterstuetzt relative Pfade, absolute UNC-Pfade und einfache Wildcards mit `*`. | | `NtfsExcludePaths` | Pfadliste, getrennt mit `;`, &#124; oder Zeilenumbruechen | Schliesst passende Pfade von der NTFS-Verarbeitung aus. Excludes gewinnen gegen Includes. Unterstuetzt relative Pfade, absolute UNC-Pfade und einfache Wildcards mit `*`. |
| `NtfsTraverseBoundaryPath` | Relativer oder absoluter Pfad | Setzt eine Traverse-Grenze fuer die Traverse-Gruppenverarbeitung. Damit koennen Traverse-Gruppen ueber den eigentlichen Einsprung hinaus bis zu einer definierten Ebene sichergestellt werden. Der Boundary-Pfad selbst darf ebenfalls als Traverse-Ziel verarbeitet werden. | | `NtfsTraverseBoundaryPath` | Relativer oder absoluter Pfad | Setzt eine Traverse-Grenze fuer die Traverse-Gruppenverarbeitung. Damit koennen Traverse-Gruppen ueber den eigentlichen Einsprung hinaus bis zu einer definierten Ebene sichergestellt werden. Der Boundary-Pfad selbst darf ebenfalls als Traverse-Ziel verarbeitet werden. |
| `NtfsPermissionGroupsMinLevel` / `NtfsPermissionGroupsMaxLevel` | Ganzzahl, z. B. `0`, `1`, `2` | Optionaler Levelbereich fuer Owner/Write/Read-Ensure. Ebene `0` ist der `RootPath`; Unterordner sind `1`, `2`, `3`, ... Wenn beide Parameter leer sind, bleibt das bisherige Verhalten unveraendert. | | `NtfsPermissionGroupsMinLevel` / `NtfsPermissionGroupsMaxLevel` | Ganzzahl, z. B. `0`, `1`, `2` | Optionaler Levelbereich fuer Owner/Write/Read-Ensure. Ebene `0` ist der `RootPath`; Unterordner sind `1`, `2`, `3`, ... Wenn beide Parameter leer sind, bleibt das bisherige Verhalten unveraendert. |
| `NtfsTraverseGroupsMinLevel` / `NtfsTraverseGroupsMaxLevel` | Ganzzahl, z. B. `-1`, `0`, `2` | Optionaler Levelbereich fuer Traverse-Ensure. Ebene `0` ist der `RootPath`; Parent-Pfade oberhalb des `RootPath` sind `-1`, `-2`, ... Wenn beide Parameter leer sind, bleibt das bisherige Verhalten unveraendert. | | `NtfsTraverseGroupsMinLevel` / `NtfsTraverseGroupsMaxLevel` | Ganzzahl, z. B. `-1`, `0`, `2` | Optionaler Levelbereich fuer Traverse-Ensure. Ebene `0` ist der `RootPath`; Parent-Pfade oberhalb des `RootPath` sind `-1`, `-2`, ... Wenn `NtfsTraverseGroupsMaxLevel` nicht gesetzt ist, wird fuer Traverse implizit `MaxDepth - 1` verwendet. |
| `NtfsGroupNameSanitizeReplacement` | Zeichenfolge, z. B. `_`, `.`, leer, `none`, `remove`, `<empty>` | Legt fest, womit ungueltige Zeichen in dynamischen gruppennamenrelevanten Pfadbestandteilen ersetzt werden. Standard ist `_`. Mit leerem Wert oder `none`/`remove`/`<empty>` werden ungueltige Zeichen entfernt und Pfadsegmente ohne Trennzeichen verbunden. | | `NtfsGroupNameSanitizeReplacement` | Zeichenfolge, z. B. `_`, `.`, leer, `none`, `remove`, `<empty>` | Legt fest, womit ungueltige Zeichen in dynamischen gruppennamenrelevanten Pfadbestandteilen ersetzt werden. Standard ist `_`. Mit leerem Wert oder `none`/`remove`/`<empty>` werden ungueltige Zeichen entfernt und Pfadsegmente ohne Trennzeichen verbunden. |
| `PreserveNtfsAdGroupNameCase` | `true`, `1`, `yes` | Unterbindet das automatische Uppercase fuer generierte NTFS-AD-Gruppennamen. Ohne diesen Parameter werden generierte Gruppennamen wie bisher in Grossbuchstaben erzeugt. | | `PreserveNtfsAdGroupNameCase` | `true`, `1`, `yes` | Unterbindet das automatische Uppercase fuer generierte NTFS-AD-Gruppennamen. Ohne diesen Parameter werden generierte Gruppennamen wie bisher in Grossbuchstaben erzeugt. |
| `ForceStrictAdGroupNames` | `true`, `1`, `yes` | Erzwingt strikte AD-Gruppennamen. Wildcard-/ACL-basierte Wiederverwendung abweichender bestehender Gruppen wird damit eingeschraenkt; es werden nur exakt passende konfigurierte oder generierte Namen verwendet. | | `ForceStrictAdGroupNames` | `true`, `1`, `yes` | Erzwingt strikte AD-Gruppennamen. Wildcard-/ACL-basierte Wiederverwendung abweichender bestehender Gruppen wird damit eingeschraenkt; es werden nur exakt passende konfigurierte oder generierte Namen verwendet. |
@@ -269,7 +269,7 @@ In diesem Beispiel koennen Traverse-Gruppen fuer `...\Projekte` selbst und fuer
#### Levelbereiche fuer Ensure und Ordneranlage #### Levelbereiche fuer Ensure und Ordneranlage
Die optionalen Levelbereiche schraenken ein, auf welchen Ebenen Gruppen und ACLs automatisch sichergestellt werden. Wenn keiner der Level-Parameter gesetzt ist, bleibt das bisherige Verhalten unveraendert. Die optionalen Levelbereiche schraenken ein, auf welchen Ebenen Gruppen und ACLs automatisch sichergestellt werden. Wenn keine Permission-Level-Parameter gesetzt sind, bleibt Owner/Write/Read unveraendert. Fuer Traverse wird ohne explizites `NtfsTraverseGroupsMaxLevel` automatisch `MaxDepth - 1` als maximale Verarbeitungsebene verwendet.
Ebene `0` ist immer der konfigurierte `RootPath`. Unterordner unterhalb des `RootPath` haben positive Level (`1`, `2`, `3`, ...). Parent-Pfade oberhalb des `RootPath` haben negative Level (`-1`, `-2`, ...). Negative Level sind vor allem fuer Traverse relevant, wenn `NtfsTraverseBoundaryPath` oberhalb des `RootPath` liegt. Ebene `0` ist immer der konfigurierte `RootPath`. Unterordner unterhalb des `RootPath` haben positive Level (`1`, `2`, `3`, ...). Parent-Pfade oberhalb des `RootPath` haben negative Level (`-1`, `-2`, ...). Negative Level sind vor allem fuer Traverse relevant, wenn `NtfsTraverseBoundaryPath` oberhalb des `RootPath` liegt.
@@ -288,7 +288,7 @@ Damit werden Owner/Write/Read-Gruppen nur fuer `\\server\share\Bereich\...` auf
Die Permission-Level gelten auch fuer die explizite NTFS-Ordneranlage ueber `CreateDataArea`. Wenn der Zielordner ausserhalb des Permission-Levelbereichs liegt oder die Permission-Levelkonfiguration ungueltig ist, wird die Ordneranlage vor AD-/ACL-Aenderungen abgebrochen. Traverse-Level blockieren die Ordneranlage nicht; sie schraenken nur die Traverse-Gruppen und Traverse-ACLs ein. Die Permission-Level gelten auch fuer die explizite NTFS-Ordneranlage ueber `CreateDataArea`. Wenn der Zielordner ausserhalb des Permission-Levelbereichs liegt oder die Permission-Levelkonfiguration ungueltig ist, wird die Ordneranlage vor AD-/ACL-Aenderungen abgebrochen. Traverse-Level blockieren die Ordneranlage nicht; sie schraenken nur die Traverse-Gruppen und Traverse-ACLs ein.
Wenn nur ein Min- oder Max-Wert gesetzt ist, ist die andere Seite offen. Ungueltige Werte oder ein Min-Wert groesser als der Max-Wert fuehren dazu, dass die betroffene Ensure-Phase mit einer Warning uebersprungen wird; bei `CreateDataArea` fuehrt eine ungueltige Permission-Levelkonfiguration zum Abbruch vor der Anlage. Wenn nur ein Min- oder Max-Wert gesetzt ist, ist die andere Seite offen. Ausnahme: Fuer Traverse ist ein fehlender Max-Wert durch `MaxDepth - 1` begrenzt. Ungueltige Werte oder ein Min-Wert groesser als der Max-Wert fuehren dazu, dass die betroffene Ensure-Phase mit einer Warning uebersprungen wird; bei `CreateDataArea` fuehrt eine ungueltige Permission-Levelkonfiguration zum Abbruch vor der Anlage.
#### WhatIf / Preview #### WhatIf / Preview