diff --git a/Sonstiges/LIAM_Finding.md b/Sonstiges/LIAM_Finding.md new file mode 100644 index 0000000..930db99 --- /dev/null +++ b/Sonstiges/LIAM_Finding.md @@ -0,0 +1,305 @@ +# LIAM NTFS Provider Findings + +## Umfang der Prüfung + +Die Prüfung umfasst den kompletten NTFS-Provider-Code im Projekt `LiamNtfs`, also nicht nur den aktuellen Provider-Einstieg, sondern auch die darunterliegenden Engine- und Hilfsklassen. + +Geprüft wurden insbesondere: + +- `LiamNtfs/C4IT.LIAM.Ntfs.cs` +- `LiamNtfs/cNtfsBase.cs` +- `LiamNtfs/cActiveDirectoryBase.cs` +- `LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs` +- `LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs` +- `LiamNtfs/C4IT_IAM_SET/DataArea.cs` +- `LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem_GET.cs` +- `LiamNtfs/C4IT_IAM_SET/cNetworkConnection.cs` +- `LiamNtfs/C4IT_IAM_SET/Helper.cs` +- `LiamNtfs/C4IT_IAM_SET/ResultToken.cs` + +Nicht im Detail geprüft wurden andere Provider wie Exchange, AD oder Teams in diesem Dokument. Verweise dorthin wurden nur dann berücksichtigt, wenn sie für das Verhalten des NTFS-Providers direkt relevant waren. + +## Priorisierte Findings + +### 1. Kritisch: Traverse-Fehler können als Erfolg zurückgegeben werden + +Der gefährlichste Punkt liegt im Schreibpfad für die Ordneranlage und das Ensure von Berechtigungen. + +Im Create-Pfad wird zunächst die AD-Gruppenanlage ausgeführt, danach der Ordner erstellt und danach `SetTraversePermissions()` aufgerufen. Das Problem ist, dass das Ergebnis der Ordnererstellung anschließend vollständig durch das Ergebnis des Traverse-Schritts überschrieben wird. Wenn `SetTraversePermissions()` intern in einen Fehlerzustand läuft, aber trotzdem ein `ResultToken` mit `resultErrorId = 0` zurückgibt, sieht der Aufrufer am Ende formal einen Erfolg. + +Genau das passiert in `SetTraversePermissions()` an mehreren Stellen. Dort werden Fehler zwar geloggt, aber häufig nur mit `return resultToken;` beendet, ohne einen fachlichen Fehlercode zu setzen. Damit ist die Methode in vielen Fällen „logisch fehlgeschlagen“, aber technisch weiterhin erfolgreich. + +Die Folge ist gefährlich: + +- Ordner kann erstellt worden sein, aber Traverse-Gruppen fehlen teilweise oder vollständig. +- AD-Gruppen können erzeugt worden sein, aber Traverse-Nesting ist unvollständig. +- Aufrufende Schichten wie Workflow, Diagnostics oder API können einen Erfolg anzeigen, obwohl das Ergebnis fachlich inkonsistent ist. + +Betroffene Stellen: + +- [DataArea_FileSystem.cs#L170](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L170) +- [DataArea_FileSystem.cs#L173](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L173) +- [DataArea_FileSystem.cs#L368](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L368) + +### 2. Hoch: Die Security-Group-Templates werden mutiert und danach wiederverwendet + +`SecurityGroups.GenerateNewSecurityGroups()` verändert die übergebenen Templates direkt. Dabei werden `NamingTemplate`, `DescriptionTemplate` und `WildcardTemplate` in-place mit konkreten Pfaden, Tags und Platzhaltern überschrieben. + +Das ist problematisch, weil dieselbe Template-Liste innerhalb derselben Engine-Instanz mehrfach verwendet wird: + +- im Retry-Loop bei Namenskollisionen während der Gruppenerzeugung +- später erneut beim Traverse-Handling +- potenziell auch zwischen Ensure- und Create-Pfaden innerhalb derselben Session + +Sobald das Template einmal materialisiert wurde, ist es kein Template mehr. Ein zweiter Lauf arbeitet nicht mehr mit der ursprünglichen Konfiguration, sondern mit bereits ersetzten Strings. Dadurch entstehen mehrere Risiken: + +- der Loop-Counter arbeitet nicht mehr auf dem Originalmuster +- spätere Durchläufe können bereits ersetzte Namen nochmals verarbeiten +- Wildcards passen nicht mehr sauber zum ursprünglichen Naming-Schema +- Traverse-Gruppen können auf anderen Namensmustern basieren als Owner/Write/Read + +Das ist kein kosmetisches Problem, sondern ein echter Zustandsfehler. Konfiguration wird in Laufzeitstatus verwandelt und danach weiterbenutzt. + +Betroffene Stellen: + +- [SecurityGroup.cs#L146](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs#L146) +- [SecurityGroup.cs#L184](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs#L184) +- [DataArea_FileSystem.cs#L1016](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L1016) +- [DataArea_FileSystem.cs#L411](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L411) + +### 3. Hoch: Drei Minuten harter Blocker im Traverse-Pfad + +Im Traverse-Pfad steckt ein explizites `Thread.Sleep(180000)`. Das blockiert den ausführenden Thread für drei Minuten. + +Das ist in einer Bibliothek dieser Art ein massiver Risikofaktor: + +- Workflows können in Timeouts laufen +- GUI-Aktionen wirken eingefroren +- Web-/Service-Threads werden unnötig belegt +- parallele Verarbeitung skaliert sehr schlecht + +Der Code dokumentiert das zusätzlich falsch mit „60 Sekunden warten“, obwohl tatsächlich 180 Sekunden geschlafen wird. Das erschwert Diagnose und Betrieb zusätzlich. + +Wenn dieses Sleep als AD-Replikations-Workaround gedacht war, ist es trotzdem der falsche technische Schnitt. Dann müsste stattdessen gezielt auf die Verfügbarkeit der erzeugten Gruppen geprüft werden, idealerweise mit Polling und Timeout statt blindem Warten. + +Betroffene Stelle: + +- [DataArea_FileSystem.cs#L676](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L676) +- [DataArea_FileSystem.cs#L678](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L678) + +### 4. Hoch: Unterschiedliches SMB-Verhalten zwischen Lesen und Schreiben + +Der Provider verwendet für das Lesen des NTFS-Baums `cNtfsBase.LogonAsync()`. Dort wird der bekannte SMB-Fehler `1219` abgefangen, die bestehende Verbindung getrennt und anschließend ein neuer Versuch gestartet. + +Die Create- und Ensure-Pfade verwenden dagegen `cNetworkConnection`, und diese Klasse wirft bei jedem Fehler direkt eine Exception. Ein Retry für `1219` findet dort nicht statt. + +Das führt zu einem inkonsistenten Betriebsverhalten: + +- Ein und dieselbe Konfiguration kann beim Lesen funktionieren. +- Dieselbe Konfiguration kann beim Schreiben scheitern, obwohl die Ursache nur eine bestehende Session auf den Share ist. + +Das ist besonders tückisch, weil es im Betrieb wie ein „sporadischer“ Fehler aussieht, tatsächlich aber ein systematischer Unterschied zwischen Read- und Write-Pfad ist. + +Betroffene Stellen: + +- [DataArea_FileSystem.cs#L161](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L161) +- [DataArea_FileSystem.cs#L300](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L300) +- [cNetworkConnection.cs#L41](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/cNetworkConnection.cs#L41) +- [cNtfsBase.cs#L61](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cNtfsBase.cs#L61) + +### 5. Hoch: Geerbte ACLs werden im Ensure-Pfad als „vorhanden“ behandelt + +Fachlich war bereits geklärt, dass geerbte Rechte hier keine Rolle spielen sollen. Genau das macht der neue Ensure-Pfad aktuell aber nicht konsequent. + +Bei der Prüfung, ob eine ACL bereits vorhanden ist, werden Regeln mit `GetAccessRules(true, true, ...)` geladen. Das zweite `true` bedeutet, dass auch geerbte Regeln berücksichtigt werden. Damit kann eine Berechtigung, die nur von oben geerbt wurde, dazu führen, dass der Provider glaubt, die explizite ACL sei bereits gesetzt. + +Im Ergebnis kann das Ensure-Feature damit stillschweigend zu wenig tun: + +- fehlende explizite ACLs werden nicht gesetzt +- das Ergebnis sieht erfolgreich aus +- späteres Mapping oder Downstream-Logik kann trotzdem unerwartetes Verhalten zeigen + +Das betrifft nicht nur Traverse, sondern auch die allgemeine ACL-Sicherstellung im neuen Ensure-Pfad. + +Betroffene Stellen: + +- [DataArea_FileSystem.cs#L808](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L808) +- [DataArea_FileSystem.cs#L646](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L646) + +### 6. Hoch: Per Call übergebene CustomTags erfüllen die Pflichtanforderungen nicht wirklich + +Im Provider wird in `CreateFilesystemEngine()` zwar eine gemergte Tag-Sammlung aufgebaut, in der Provider-Tags und per Aufruf übergebene Tags zusammengeführt werden. Das klingt zunächst korrekt. + +Die Pflichtwerte für `groupPrefix`, `groupOwnerTag`, `groupWriteTag`, `groupReadTag`, `groupTraverseTag`, `groupDLTag` und `groupGTag` werden aber nicht aus dieser gemergten Sammlung gelesen, sondern weiterhin direkt aus `Provider.CustomTags`. + +Die Folge ist eine verdeckte Inkonsistenz: + +- im Debug-/GUI-Output sehen die Tags vorhanden aus +- im Engine-Aufbau schlagen Pflichtprüfungen trotzdem fehl +- Call-spezifische Overrides wirken nur teilweise + +Das ist besonders ungünstig für Workflow- oder Diagnostics-Szenarien, in denen Tags bewusst pro Aufruf ergänzt oder überschrieben werden sollen. + +Betroffene Stellen: + +- [C4IT.LIAM.Ntfs.cs#L366](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L366) +- [C4IT.LIAM.Ntfs.cs#L384](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L384) +- [C4IT.LIAM.Ntfs.cs#L472](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L472) + +### 7. Hoch: `ReplaceNtfsCustomTags()` ist zu früh, zu strikt und verändert Konfiguration dauerhaft + +Bereits im Provider-Konstruktor wird `ReplaceNtfsCustomTags()` ausgeführt. Die Methode greift direkt per `CustomTags[...]` auf Dictionary-Einträge zu und ersetzt Platzhalter in den Naming-Conventions. + +Das erzeugt drei Probleme gleichzeitig: + +1. Fehlende Tags schlagen schon beim Provider-Aufbau fehl, bevor eine gezielte Validierung mit verständlicher Fehlermeldung greifen kann. +2. Die Naming-Conventions werden direkt verändert. Danach ist nicht mehr klar, was Originalkonfiguration und was bereits materialisierter Laufzeitzustand ist. +3. Alias-Verhalten wie `ADGroupPrefix` wird hier noch nicht sauber berücksichtigt, obwohl es später teilweise unterstützt wird. + +Damit wird Konfiguration zu früh und zu aggressiv „kompiliert“. + +Betroffene Stellen: + +- [C4IT.LIAM.Ntfs.cs#L39](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L39) +- [C4IT.LIAM.Ntfs.cs#L54](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L54) +- [C4IT.LIAM.Ntfs.cs#L63](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L63) +- [C4IT.LIAM.Ntfs.cs#L88](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L88) + +### 8. Mittel-Hoch: `LoadDataArea()` behandelt UNC-Pfade fachlich falsch + +Die Einzel-Ladefunktion `LoadDataArea()` ist sichtbar unfertig. Das ist nicht nur ein Stilproblem, sondern erzeugt reales Fehlverhalten. + +Der Code splittet den Pfad mit `UID.Split(Path.DirectorySeparatorChar)` ohne `RemoveEmptyEntries`. Bei UNC-Pfaden wie `\\server\share` entstehen dadurch führende leere Segmente. Das führt dazu, dass ein Share-Pfad nicht sauber als Share erkannt wird, sondern in den Default-Branch läuft. + +Zusätzlich wird `DisplayName` aus `Path.GetDirectoryName(UID)` ermittelt. Das ist für den Anwendungsfall falsch, weil damit der Elternpfad statt des Blattnamens verwendet wird. + +Konkrete Folgen: + +- Share-Roots können beim Einzel-Laden als Folder erscheinen +- Anzeigenamen stimmen nicht +- Root-Level und Child-Level verhalten sich inkonsistent + +Betroffene Stellen: + +- [C4IT.LIAM.Ntfs.cs#L225](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L225) +- [C4IT.LIAM.Ntfs.cs#L227](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L227) +- [C4IT.LIAM.Ntfs.cs#L236](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L236) + +### 9. Mittel-Hoch: `Depth = 0` verliert die Root-DataArea + +Der Provider baut in `getDataAreasAsync()` zunächst korrekt das Root-Objekt auf. Danach wird die Unterordnerliste über `ntfsBase.RequestFoldersListAsync()` geladen. Wenn `Depth == 0` ist, liefert `RequestFoldersListAsync()` aber `null` statt einer leeren Liste zurück. + +Im Provider wird `null` dann als harter Fehler interpretiert und es wird insgesamt `null` zurückgegeben. Das bereits erzeugte Root-Objekt geht damit verloren. + +Für einen Aufrufer, der bewusst nur Ebene 0 sehen möchte, ist das klar fehlerhaft. + +Betroffene Stellen: + +- [C4IT.LIAM.Ntfs.cs#L147](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L147) +- [C4IT.LIAM.Ntfs.cs#L183](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L183) +- [cNtfsBase.cs#L108](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cNtfsBase.cs#L108) +- [cNtfsBase.cs#L114](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cNtfsBase.cs#L114) + +### 10. Mittel: AD-Gruppenabfragen können still unvollständig sein + +`cActiveDirectoryBase.privRequestSecurityGroupsListAsync()` baut die Gruppenliste aus LDAP-Ergebnissen auf. Dort wird jedoch `GroupPrincipal.FindByIdentity(...).GroupScope` ohne Null-Check verwendet. + +Wenn eine Gruppe aus dem LDAP-Result zwar gefunden wird, aber nicht sauber als `GroupPrincipal` auflösbar ist, entsteht ein Fehler. Dieser wird anschließend durch einen allgemeinen `catch` verschluckt, und es wird einfach die bis dahin gesammelte Teilliste zurückgegeben. + +Das ist problematisch, weil der Aufrufer nicht klar zwischen „Liste vollständig“ und „Liste vorzeitig abgebrochen“ unterscheiden kann. + +Betroffene Stellen: + +- [cActiveDirectoryBase.cs#L167](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cActiveDirectoryBase.cs#L167) +- [cActiveDirectoryBase.cs#L186](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cActiveDirectoryBase.cs#L186) +- [cActiveDirectoryBase.cs#L192](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cActiveDirectoryBase.cs#L192) + +### 11. Mittel: Zentrale Fehlerschnittstelle des Providers deckt Schreibfehler nicht ab + +`GetLastErrorMessage()` sammelt nur Fehler aus `ntfsBase` und `activeDirectoryBase`. Die eigentlichen Fehler aus `DataArea_FileSystem` laufen aber über `ResultToken` und landen nicht in dieser zentralen Fehlerschnittstelle. + +Das bedeutet: + +- `Logon`- und Read-Fehler sind über `GetLastErrorMessage()` erkennbar +- Create-/Ensure-Fehler dagegen oft nicht + +Für aufrufende Schichten, die nur diese zentrale Schnittstelle kennen, entsteht damit ein unvollständiges Fehlerbild. + +Betroffene Stellen: + +- [C4IT.LIAM.Ntfs.cs#L506](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L506) +- [DataArea_FileSystem.cs#L137](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs#L137) + +### 12. Mittel: ACL-Mapping ist stark von vollständigen Naming-Conventions abhängig und fällt auf Sentinel-Werte zurück + +Die Permission-Auflösung in `ResolvePermissionGroupsAsync()` verwendet `.First(...)` für die Conventions von Owner, Write und Read. Fehlt eine passende Konvention, wirft der Code sofort eine Exception. + +Parallel dazu sind die Zielwerte mit `S-1-0-0` vorbelegt. Das führt zu zwei unterschiedlichen Fehlermustern: + +- bei fehlender Konfiguration: harter Laufzeitfehler +- bei nicht gefundenem Match: scheinbar gültige SID, fachlich aber nur ein Platzhalter + +Das macht Ergebnisse schwer interpretierbar und erhöht das Risiko, dass Fehler spät erkannt werden. + +Betroffene Stellen: + +- [C4IT.LIAM.Ntfs.cs#L522](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L522) +- [C4IT.LIAM.Ntfs.cs#L611](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L611) + +### 13. Mittel: Mitgliederauflösung bricht intern mit NullReference ab und wird dann nur noch als `null` sichtbar + +`GetMembersAsync()` ruft `privGetMembersAsync(sid).ToList()` auf, bevor geprüft wird, ob überhaupt ein Result vorliegt. Wenn die Gruppe nicht gefunden wird, kommt `null` zurück und `.ToList()` wirft intern. + +Die Exception wird zwar gefangen, aber nach außen sieht der Aufrufer nur noch `null`. Damit verschwimmt der Unterschied zwischen: + +- Gruppe nicht vorhanden +- AD-Auflösung fehlgeschlagen +- echte Kommunikationsstörung + +Betroffene Stellen: + +- [cActiveDirectoryBase.cs#L269](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cActiveDirectoryBase.cs#L269) +- [cActiveDirectoryBase.cs#L274](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cActiveDirectoryBase.cs#L274) +- [cActiveDirectoryBase.cs#L299](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/cActiveDirectoryBase.cs#L299) + +### 14. Mittel/Niedrig: Share-Objekte können keine Kinder nachladen + +`cLiamNtfsShare.getFolders()` und `getChildrenAsync()` liefern aktuell immer nur leere Listen zurück. Das bedeutet, dass Share-Objekte zwar initial erzeugt werden können, ein späteres Nachladen über die Objektmethoden aber praktisch nicht funktioniert. + +Wenn diese Methoden nicht mehr verwendet werden, ist das nur Altlast. Wenn doch, ist das ein funktionaler Bruch. + +Betroffene Stellen: + +- [C4IT.LIAM.Ntfs.cs#L706](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L706) +- [C4IT.LIAM.Ntfs.cs#L727](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT.LIAM.Ntfs.cs#L727) + +### 15. Niedrig, aber inkonsistent: Der alte GET-Pfad verhält sich anders als der aktuelle Providerpfad + +Im älteren `DataArea_FileSystem_GET`-Pfad wird die Root-Struktur anders aufgebaut als im aktuellen Providerpfad. Ebene 0 bekommt dort kein Root-ACL-Mapping, und das Verhalten unterscheidet sich insgesamt von der neueren Logik im eigentlichen Provider. + +Wenn dieser Altpfad noch produktiv verwendet wird, gibt es damit zwei unterschiedliche Wahrheiten für denselben fachlichen Bereich. + +Betroffene Stellen: + +- [DataArea_FileSystem_GET.cs#L228](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem_GET.cs#L228) +- [DataArea_FileSystem_GET.cs#L264](/mnt/c/Workspace/C4IT%20DEV%20LIAM%20WEB%20Service_git/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem_GET.cs#L264) + +## Fazit + +Der NTFS-Provider ist an mehreren Stellen funktionsfähig, aber der Schreibpfad ist deutlich fragiler als der Lesepfad. + +Die wichtigsten Risiken sind: + +- stille Erfolgsrückgaben trotz unvollständiger Traverse-Verarbeitung +- mutierende Templates mit Folgeschäden für Naming und Wiederholungslogik +- blockierende Wartezeiten und inkonsistentes SMB-Verbindungsverhalten +- Berücksichtigung geerbter ACLs im neuen Ensure-Pfad trotz fachlicher Gegenanforderung +- unvollständige oder irreführende Fehlerkommunikation nach außen + +Für eine technische Bereinigung würde ich die Themen in dieser Reihenfolge angehen: + +1. harte Erfolgs-/Fehlersemantik im Create-/Ensure-/Traverse-Pfad +2. Entfernen des `Thread.Sleep` und Ersatz durch kontrolliertes Polling +3. Templates unveränderlich behandeln und pro Lauf kopieren +4. ACL-Prüfungen im Ensure-Pfad auf explizite Regeln einschränken +5. Tag- und Konfigurationsauflösung sauber zentralisieren