Add configurable NTFS group name formatting

This commit is contained in:
Meik
2026-05-08 21:45:36 +02:00
parent b9edd16cab
commit 2b460ccc1a
6 changed files with 215 additions and 69 deletions

View File

@@ -24,6 +24,7 @@ namespace C4IT_IAM_Engine
public string username;
public SecureString password;
public bool ForceStrictAdGroupNames;
public bool PreserveAdGroupNameCase;
public List<IAM_SecurityGroup> IAM_SecurityGroups;
public string rootUID;
@@ -53,7 +54,7 @@ namespace C4IT_IAM_Engine
};
DirectorySearcher dSearch = new DirectorySearcher(entry)
{
Filter = "(&(CN=" + s.Name.ToUpper() + ")(objectClass=group))"
Filter = "(&(CN=" + GetConfiguredGroupName(s.Name) + ")(objectClass=group))"
};
dSearch.PageSize = 100000;
SearchResultCollection sr = dSearch.FindAll();
@@ -92,7 +93,7 @@ namespace C4IT_IAM_Engine
};
DirectorySearcher dSearch = new DirectorySearcher(entry)
{
Filter = "(&(CN=" + CN.ToUpper() + ")(objectClass=group))"
Filter = "(&(CN=" + GetConfiguredGroupName(CN) + ")(objectClass=group))"
};
dSearch.PageSize = 100000;
SearchResultCollection sr = dSearch.FindAll();
@@ -129,7 +130,9 @@ namespace C4IT_IAM_Engine
int writeACLPermission,
int ownerACLPermission,
int loop = 0,
int existingADGroupCount = 0)
int existingADGroupCount = 0,
string groupNameSanitizeReplacement = Helper.DefaultGroupNameSanitizeReplacement,
bool preserveAdGroupNameCase = false)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
@@ -145,12 +148,12 @@ namespace C4IT_IAM_Engine
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);
var sanitizedSegments = relativePathSegments.Select(Helper.SanitizePathSegment).ToArray();
var relativePath = sanitizedSegments.Length > 0 ? string.Join("_", sanitizedSegments) : string.Empty;
var sanitizedSegments = relativePathSegments.Select(i => Helper.SanitizePathSegment(i, groupNameSanitizeReplacement)).ToArray();
var relativePath = sanitizedSegments.Length > 0 ? Helper.JoinSanitizedPathSegments(sanitizedSegments, groupNameSanitizeReplacement) : string.Empty;
var folderName = sanitizedSegments.Length > 0
? sanitizedSegments[sanitizedSegments.Length - 1]
: Helper.SanitizePathSegment(Path.GetFileName(newFolderPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)));
var rootContext = Helper.GetRootPathTemplateContext(baseFolder);
: Helper.SanitizePathSegment(Path.GetFileName(newFolderPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)), groupNameSanitizeReplacement);
var rootContext = Helper.GetRootPathTemplateContext(baseFolder, groupNameSanitizeReplacement);
foreach (var template in resolvedTemplates)
{
@@ -209,7 +212,9 @@ namespace C4IT_IAM_Engine
Helper.MaxAdGroupNameLength,
$"{template.Type}/{template.Scope} fuer '{newFolderPath}'",
"AD-Gruppenname",
rootContext);
rootContext,
preserveAdGroupNameCase,
groupNameSanitizeReplacement);
var boundedDescriptionContext = Helper.GetBoundedAdGroupTemplateContext(
template.DescriptionTemplate,
@@ -221,27 +226,32 @@ namespace C4IT_IAM_Engine
Helper.MaxAdGroupDescriptionLength,
$"{template.Type}/{template.Scope} fuer '{newFolderPath}'",
"AD-Gruppenbeschreibung",
rootContext);
rootContext,
preserveAdGroupNameCase,
groupNameSanitizeReplacement);
var adjustedNameSegments = boundedNameContext.SanitizedSegments ?? Array.Empty<string>();
var adjustedNameRelativePath = adjustedNameSegments.Length > 0 ? string.Join("_", adjustedNameSegments) : string.Empty;
var adjustedNameRelativePath = adjustedNameSegments.Length > 0 ? Helper.JoinSanitizedPathSegments(adjustedNameSegments, groupNameSanitizeReplacement) : string.Empty;
var adjustedNameFolderName = boundedNameContext.FolderName;
var adjustedDescriptionSegments = boundedDescriptionContext.SanitizedSegments ?? Array.Empty<string>();
var adjustedDescriptionRelativePath = adjustedDescriptionSegments.Length > 0 ? string.Join("_", adjustedDescriptionSegments) : string.Empty;
var adjustedDescriptionRelativePath = adjustedDescriptionSegments.Length > 0 ? Helper.JoinSanitizedPathSegments(adjustedDescriptionSegments, groupNameSanitizeReplacement) : string.Empty;
var adjustedDescriptionFolderName = boundedDescriptionContext.FolderName;
template.NamingTemplate = Helper.ApplyTemplatePlaceholders(template.NamingTemplate, template.Type != SecurityGroupType.Traverse, adjustedNameRelativePath, adjustedNameSegments, adjustedNameFolderName, rootContext)
.ReplaceTags(customTags).ReplaceTags(tags)
.ToUpper();
template.NamingTemplate = Helper.ApplyAdGroupNameCasing(
Helper.ApplyTemplatePlaceholders(template.NamingTemplate, template.Type != SecurityGroupType.Traverse, adjustedNameRelativePath, adjustedNameSegments, adjustedNameFolderName, rootContext, groupNameSanitizeReplacement)
.ReplaceTags(customTags).ReplaceTags(tags),
preserveAdGroupNameCase);
template.DescriptionTemplate = Helper.ApplyTemplatePlaceholders(template.DescriptionTemplate, template.Type != SecurityGroupType.Traverse, adjustedDescriptionRelativePath, adjustedDescriptionSegments, adjustedDescriptionFolderName, rootContext)
.ReplaceTags(customTags).ReplaceTags(tags)
.ToUpper();
template.DescriptionTemplate = Helper.ApplyAdGroupNameCasing(
Helper.ApplyTemplatePlaceholders(template.DescriptionTemplate, template.Type != SecurityGroupType.Traverse, adjustedDescriptionRelativePath, adjustedDescriptionSegments, adjustedDescriptionFolderName, rootContext, groupNameSanitizeReplacement)
.ReplaceTags(customTags).ReplaceTags(tags),
preserveAdGroupNameCase);
template.WildcardTemplate = Helper.ApplyTemplatePlaceholders(template.WildcardTemplate, template.Type != SecurityGroupType.Traverse, adjustedNameRelativePath, adjustedNameSegments, adjustedNameFolderName, rootContext)
.ReplaceTags(customTags).ReplaceTags(tags)
.ToUpper();
template.WildcardTemplate = Helper.ApplyAdGroupNameCasing(
Helper.ApplyTemplatePlaceholders(template.WildcardTemplate, template.Type != SecurityGroupType.Traverse, adjustedNameRelativePath, adjustedNameSegments, adjustedNameFolderName, rootContext, groupNameSanitizeReplacement)
.ReplaceTags(customTags).ReplaceTags(tags),
preserveAdGroupNameCase);
}
@@ -429,7 +439,7 @@ namespace C4IT_IAM_Engine
DirectorySearcher search = new DirectorySearcher(entry)
{
Filter = "(&(objectClass=group)(sAMAccountName=" + groupName.ToUpper() + "))"
Filter = "(&(objectClass=group)(sAMAccountName=" + GetConfiguredGroupName(groupName) + "))"
};
search.PageSize = 100000;
@@ -718,13 +728,17 @@ namespace C4IT_IAM_Engine
try
{
secGroup.CreatedNewEntry = false;
if (!GroupAllreadyExisting(secGroup.Name.ToUpper()))
var groupName = GetConfiguredGroupName(secGroup.Name);
secGroup.Name = groupName;
secGroup.technicalName = "CN=" + groupName + "," + ouPath;
if (!GroupAllreadyExisting(groupName))
{
DirectoryEntry entry = new DirectoryEntry("LDAP://" + domainName + "/" + ouPath, username, new NetworkCredential("", password).Password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
DefaultLogger.LogEntry(LogLevels.Debug, $"Creating ad entry with CN / sAmAccountName: {secGroup.Name.ToUpper()}");
DirectoryEntry group = entry.Children.Add("CN=" + secGroup.Name.ToUpper(), "group");
group.Properties["sAmAccountName"].Value = secGroup.Name.ToUpper();
DefaultLogger.LogEntry(LogLevels.Debug, $"Creating ad entry with CN / sAmAccountName: {groupName}");
DirectoryEntry group = entry.Children.Add("CN=" + groupName, "group");
group.Properties["sAmAccountName"].Value = groupName;
if (users != null && secGroup.Scope == GroupScope.Global)
{
foreach (var user in users)
@@ -749,7 +763,7 @@ namespace C4IT_IAM_Engine
}
group.CommitChanges();
DirectoryEntry ent = new DirectoryEntry("LDAP://" + domainName + "/" + "CN =" + secGroup.Name.ToUpper() + "," + ouPath, username, new NetworkCredential("", password).Password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
DirectoryEntry ent = new DirectoryEntry("LDAP://" + domainName + "/" + "CN=" + groupName + "," + ouPath, username, new NetworkCredential("", password).Password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
var objectid = SecurityGroups.getSID(ent);
DefaultLogger.LogEntry(LogLevels.Debug, $"Security group created in ad: {secGroup.technicalName}");
@@ -778,6 +792,11 @@ namespace C4IT_IAM_Engine
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
private string GetConfiguredGroupName(string groupName)
{
return Helper.ApplyAdGroupNameCasing(groupName, PreserveAdGroupNameCase);
}
}
public enum GroupScopeValues : int
{