feat: ensure missing NTFS permission groups
This commit is contained in:
@@ -134,19 +134,19 @@ namespace C4IT_IAM_Engine
|
||||
try
|
||||
{
|
||||
|
||||
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 folderName = sanitizedSegments.Length > 0
|
||||
? sanitizedSegments[sanitizedSegments.Length - 1]
|
||||
: Helper.SanitizePathSegment(Path.GetFileName(newFolderPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)));
|
||||
|
||||
foreach (var template in templates)
|
||||
{
|
||||
var GroupTypeTag = "";
|
||||
switch (template.Type)
|
||||
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 folderName = sanitizedSegments.Length > 0
|
||||
? sanitizedSegments[sanitizedSegments.Length - 1]
|
||||
: Helper.SanitizePathSegment(Path.GetFileName(newFolderPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)));
|
||||
|
||||
foreach (var template in templates)
|
||||
{
|
||||
var GroupTypeTag = "";
|
||||
switch (template.Type)
|
||||
{
|
||||
case SecurityGroupType.Owner:
|
||||
GroupTypeTag = groupOwnerTag;
|
||||
@@ -181,20 +181,20 @@ namespace C4IT_IAM_Engine
|
||||
tags.Add("GROUPTYPEPOSTFIX", GroupTypeTag);
|
||||
tags.Add("SCOPETAG", GroupScopeTag);
|
||||
|
||||
template.NamingTemplate = Helper.ApplyTemplatePlaceholders(template.NamingTemplate, template.Type != SecurityGroupType.Traverse, relativePath, sanitizedSegments, folderName)
|
||||
.ReplaceTags(customTags).ReplaceTags(tags)
|
||||
.ToUpper();
|
||||
|
||||
template.DescriptionTemplate = Helper.ApplyTemplatePlaceholders(template.DescriptionTemplate, template.Type != SecurityGroupType.Traverse, relativePath, sanitizedSegments, folderName)
|
||||
.ReplaceTags(customTags).ReplaceTags(tags)
|
||||
.ToUpper();
|
||||
|
||||
|
||||
template.WildcardTemplate = Helper.ApplyTemplatePlaceholders(template.WildcardTemplate, template.Type != SecurityGroupType.Traverse, relativePath, sanitizedSegments, folderName)
|
||||
.ReplaceTags(customTags).ReplaceTags(tags)
|
||||
.ToUpper();
|
||||
|
||||
}
|
||||
template.NamingTemplate = Helper.ApplyTemplatePlaceholders(template.NamingTemplate, template.Type != SecurityGroupType.Traverse, relativePath, sanitizedSegments, folderName)
|
||||
.ReplaceTags(customTags).ReplaceTags(tags)
|
||||
.ToUpper();
|
||||
|
||||
template.DescriptionTemplate = Helper.ApplyTemplatePlaceholders(template.DescriptionTemplate, template.Type != SecurityGroupType.Traverse, relativePath, sanitizedSegments, folderName)
|
||||
.ReplaceTags(customTags).ReplaceTags(tags)
|
||||
.ToUpper();
|
||||
|
||||
|
||||
template.WildcardTemplate = Helper.ApplyTemplatePlaceholders(template.WildcardTemplate, template.Type != SecurityGroupType.Traverse, relativePath, sanitizedSegments, folderName)
|
||||
.ReplaceTags(customTags).ReplaceTags(tags)
|
||||
.ToUpper();
|
||||
|
||||
}
|
||||
|
||||
IAM_SecurityGroupTemplate ownerGlobal = templates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Owner));
|
||||
IAM_SecurityGroup osecGroup = new IAM_SecurityGroup()
|
||||
@@ -359,9 +359,111 @@ namespace C4IT_IAM_Engine
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DirectoryEntry CreateADGroup(string ouPath, IAM_SecurityGroup secGroup, List<UserPrincipal> users)
|
||||
}
|
||||
|
||||
private DirectoryEntry FindGroupEntry(string groupName)
|
||||
{
|
||||
DirectoryEntry entry = new DirectoryEntry
|
||||
{
|
||||
Path = "LDAP://" + domainName,
|
||||
Username = username,
|
||||
Password = new NetworkCredential("", password).Password,
|
||||
AuthenticationType = AuthenticationTypes.Secure | AuthenticationTypes.Sealing
|
||||
};
|
||||
|
||||
DirectorySearcher search = new DirectorySearcher(entry)
|
||||
{
|
||||
Filter = "(&(objectClass=group)(sAMAccountName=" + groupName.ToUpper() + "))"
|
||||
};
|
||||
search.PageSize = 100000;
|
||||
|
||||
var result = search.FindOne();
|
||||
if (result == null)
|
||||
{
|
||||
entry.Dispose();
|
||||
search.Dispose();
|
||||
return null;
|
||||
}
|
||||
|
||||
var groupEntry = result.GetDirectoryEntry();
|
||||
search.Dispose();
|
||||
entry.Dispose();
|
||||
return groupEntry;
|
||||
}
|
||||
|
||||
private static bool HasMember(PropertyValueCollection members, string distinguishedName)
|
||||
{
|
||||
foreach (var member in members)
|
||||
{
|
||||
if (string.Equals(member?.ToString(), distinguishedName, StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void AddMissingMembers(DirectoryEntry group, IAM_SecurityGroup secGroup, List<UserPrincipal> users)
|
||||
{
|
||||
if (group == null)
|
||||
return;
|
||||
|
||||
var changed = false;
|
||||
if (users != null && secGroup.Scope == GroupScope.Global)
|
||||
{
|
||||
foreach (var user in users.Where(u => u != null && !string.IsNullOrWhiteSpace(u.DistinguishedName)))
|
||||
{
|
||||
if (HasMember(group.Properties["member"], user.DistinguishedName))
|
||||
continue;
|
||||
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Adding missing member: {user.DistinguishedName}");
|
||||
group.Properties["member"].Add(user.DistinguishedName);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (secGroup.Scope == GroupScope.Local)
|
||||
{
|
||||
foreach (var innerGroup in secGroup.memberGroups.Where(g => g != null && !string.IsNullOrWhiteSpace(g.technicalName)))
|
||||
{
|
||||
if (HasMember(group.Properties["member"], innerGroup.technicalName))
|
||||
continue;
|
||||
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Adding missing nested group: {innerGroup.technicalName}");
|
||||
group.Properties["member"].Add(innerGroup.technicalName);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
group.CommitChanges();
|
||||
}
|
||||
|
||||
public DirectoryEntry EnsureADGroup(string ouPath, IAM_SecurityGroup secGroup, List<UserPrincipal> users)
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
try
|
||||
{
|
||||
var existingGroup = FindGroupEntry(secGroup.Name);
|
||||
if (existingGroup == null)
|
||||
return CreateADGroup(ouPath, secGroup, users);
|
||||
|
||||
AddMissingMembers(existingGroup, secGroup, users);
|
||||
var objectid = getSID(existingGroup);
|
||||
secGroup.UID = objectid;
|
||||
return existingGroup;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
cLogManager.DefaultLogger.LogException(E);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
|
||||
public DirectoryEntry CreateADGroup(string ouPath, IAM_SecurityGroup secGroup, List<UserPrincipal> users)
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
try
|
||||
@@ -406,9 +508,13 @@ namespace C4IT_IAM_Engine
|
||||
}
|
||||
else
|
||||
{
|
||||
DirectoryEntry e = new DirectoryEntry("LDAP://" + domainName + "/" + "CN =" + secGroup.Name.ToUpper() + "," + ouPath, username, new NetworkCredential("", password).Password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
|
||||
DirectoryEntry e = FindGroupEntry(secGroup.Name);
|
||||
if (e == null)
|
||||
return null;
|
||||
var objectid = getSID(e);
|
||||
secGroup.UID = objectid;
|
||||
AddMissingMembers(e, secGroup, users);
|
||||
return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user