From 29799942d3109ddf33f408118d267b64b5768abe Mon Sep 17 00:00:00 2001 From: Meik Date: Tue, 10 Mar 2026 11:36:52 +0100 Subject: [PATCH] fix: avoid mutating ntfs security group templates --- LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs | 23 +++++++++++++++-------- Sonstiges/LIAM_Finding.md | 7 +++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs b/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs index b0f8170..81aff60 100644 --- a/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs +++ b/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs @@ -133,7 +133,14 @@ namespace C4IT_IAM_Engine LogMethodBegin(MethodBase.GetCurrentMethod()); try { - + var resolvedTemplates = (templates ?? new List()) + .Select(template => new IAM_SecurityGroupTemplate( + template.NamingTemplate, + template.DescriptionTemplate, + template.WildcardTemplate, + template.Type, + template.Scope)) + .ToList(); var relativePathRaw = DataArea.GetRelativePath(newFolderPath, baseFolder).Trim(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); relativePathRaw = relativePathRaw.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); var relativePathSegments = relativePathRaw.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); @@ -143,7 +150,7 @@ namespace C4IT_IAM_Engine ? sanitizedSegments[sanitizedSegments.Length - 1] : Helper.SanitizePathSegment(Path.GetFileName(newFolderPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))); - foreach (var template in templates) + foreach (var template in resolvedTemplates) { var GroupTypeTag = ""; switch (template.Type) @@ -196,7 +203,7 @@ namespace C4IT_IAM_Engine } - IAM_SecurityGroupTemplate ownerGlobal = templates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Owner)); + IAM_SecurityGroupTemplate ownerGlobal = resolvedTemplates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Owner)); IAM_SecurityGroup osecGroup = new IAM_SecurityGroup() { Name = ownerGlobal.NamingTemplate, @@ -209,7 +216,7 @@ namespace C4IT_IAM_Engine }; IAM_SecurityGroups.Add(osecGroup); - IAM_SecurityGroupTemplate writeGlobal = templates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Write)); + IAM_SecurityGroupTemplate writeGlobal = resolvedTemplates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Write)); IAM_SecurityGroup wsecGroup = new IAM_SecurityGroup() { Name = writeGlobal.NamingTemplate, @@ -222,7 +229,7 @@ namespace C4IT_IAM_Engine }; IAM_SecurityGroups.Add(wsecGroup); - IAM_SecurityGroupTemplate readGlobal = templates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Read)); + IAM_SecurityGroupTemplate readGlobal = resolvedTemplates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Read)); IAM_SecurityGroup rsecGroup = new IAM_SecurityGroup() { Name = readGlobal.NamingTemplate, @@ -239,7 +246,7 @@ namespace C4IT_IAM_Engine // if (groupPermissionStrategy == PermissionGroupStrategy.AGDLP) { - IAM_SecurityGroupTemplate ownerDL = templates.First(t => t.Scope.Equals(GroupScope.Local) && t.Type.Equals(SecurityGroupType.Owner)); + IAM_SecurityGroupTemplate ownerDL = resolvedTemplates.First(t => t.Scope.Equals(GroupScope.Local) && t.Type.Equals(SecurityGroupType.Owner)); IAM_SecurityGroup osecDLGroup = new IAM_SecurityGroup() { Name = ownerDL.NamingTemplate, @@ -253,7 +260,7 @@ namespace C4IT_IAM_Engine osecDLGroup.memberGroups.Add(osecGroup); IAM_SecurityGroups.Add(osecDLGroup); - IAM_SecurityGroupTemplate writeDL = templates.First(t => t.Scope.Equals(GroupScope.Local) && t.Type.Equals(SecurityGroupType.Write)); + IAM_SecurityGroupTemplate writeDL = resolvedTemplates.First(t => t.Scope.Equals(GroupScope.Local) && t.Type.Equals(SecurityGroupType.Write)); IAM_SecurityGroup wsecDLGroup = new IAM_SecurityGroup() { Name = writeDL.NamingTemplate, @@ -267,7 +274,7 @@ namespace C4IT_IAM_Engine wsecDLGroup.memberGroups.Add(wsecGroup); IAM_SecurityGroups.Add(wsecDLGroup); - IAM_SecurityGroupTemplate readDL = templates.First(t => t.Scope.Equals(GroupScope.Local) && t.Type.Equals(SecurityGroupType.Read)); + IAM_SecurityGroupTemplate readDL = resolvedTemplates.First(t => t.Scope.Equals(GroupScope.Local) && t.Type.Equals(SecurityGroupType.Read)); IAM_SecurityGroup rsecDLGroup = new IAM_SecurityGroup() { Name = readDL.NamingTemplate, diff --git a/Sonstiges/LIAM_Finding.md b/Sonstiges/LIAM_Finding.md index 930db99..8f104e9 100644 --- a/Sonstiges/LIAM_Finding.md +++ b/Sonstiges/LIAM_Finding.md @@ -67,6 +67,13 @@ Betroffene Stellen: - [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) +Status: + +- Am 2026-03-10 umgesetzt. +- `GenerateNewSecurityGroups()` arbeitet jetzt auf einer pro Aufruf geklonten Template-Liste statt auf der übergebenen Originalsammlung. +- Die Konfigurationstemplates im Engine-Kontext bleiben dadurch unverändert und können in Retry-Loops und später im Traverse-Pfad erneut korrekt materialisiert werden. +- Der Fix adressiert bewusst nur die Zustandsmutation. Die fachliche Gruppenerzeugung und das Naming-Verhalten selbst wurden dabei nicht geändert. + ### 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.