initial
This commit is contained in:
828
LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs
Normal file
828
LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs
Normal file
@@ -0,0 +1,828 @@
|
||||
using C4IT_IAM;
|
||||
using C4IT_IAM_Engine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
using System.DirectoryServices.AccountManagement;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Text.RegularExpressions;
|
||||
using C4IT.Logging;
|
||||
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using System.Reflection;
|
||||
using C4IT_IAM_GET;
|
||||
|
||||
|
||||
namespace C4IT_IAM_SET
|
||||
{
|
||||
public class DataArea_FileSystem
|
||||
{
|
||||
public const string constApplicationDataPath = "%ProgramData%\\Consulting4IT GmbH\\LIAM";
|
||||
|
||||
public string domainName;
|
||||
public string username;
|
||||
public SecureString password;
|
||||
private cNetworkConnection Connection;
|
||||
|
||||
public string groupPrefix;
|
||||
public string groupOUPath;
|
||||
public string baseFolder;
|
||||
public string newFolderPath;
|
||||
public string newFolder;
|
||||
public string newFolderParent;
|
||||
|
||||
public PermissionGroupStrategy groupPermissionStrategy;
|
||||
public string groupDescriptionTemplate;
|
||||
public string groupNamingTemplate;
|
||||
public string groupDLTag;
|
||||
public string groupGTag;
|
||||
public string groupOwnerTag;
|
||||
public string groupReadTag;
|
||||
public string groupWriteTag;
|
||||
public string groupTraverseTag;
|
||||
public string groupWildcard;
|
||||
public IDictionary<string, string> groupCustomTags;
|
||||
public ICollection<string> ownerUserSids;
|
||||
public ICollection<string> readerUserSids;
|
||||
public ICollection<string> writerUserSids;
|
||||
|
||||
public int ReadACLPermission = 0x200A9;
|
||||
public int WriteACLPermission = 0x301BF;
|
||||
public int OwnerACLPermission = 0x1F01FF;
|
||||
|
||||
|
||||
public string ConfigID;
|
||||
Dictionary<FileSystemRights, string> adGroupDic;
|
||||
public DataArea newDataArea;
|
||||
public SecurityGroups newSecurityGroups;
|
||||
|
||||
public List<IAM_SecurityGroupTemplate> templates;
|
||||
|
||||
public int createTraverseGroupLvl = 0;
|
||||
|
||||
public DataArea_FileSystem()
|
||||
{
|
||||
var logDirectory = Environment.ExpandEnvironmentVariables(constApplicationDataPath);
|
||||
Helper.CreatePathWithWriteAccess(logDirectory);
|
||||
var LogPath = Path.Combine(logDirectory, "Logs");
|
||||
cLogManagerFile.CreateInstance(Path.Combine(LogPath, "LIAM.log"));
|
||||
|
||||
DefaultLogger.LogEntry(LogLevels.Info, "=================================================");
|
||||
DefaultLogger.LogEntry(LogLevels.Info, $"LIAM engine v{Assembly.GetExecutingAssembly().GetName().Version} started");
|
||||
|
||||
templates = new List<IAM_SecurityGroupTemplate>();
|
||||
}
|
||||
|
||||
private ResultToken checkRequiredVariables()
|
||||
{
|
||||
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
|
||||
resultToken.resultErrorId = 0;
|
||||
if (String.IsNullOrEmpty(ConfigID))
|
||||
{
|
||||
resultToken.resultErrorId = 30001;
|
||||
resultToken.resultMessage = "Kein ConfigID gewählt ";
|
||||
return resultToken;
|
||||
}
|
||||
if (string.IsNullOrEmpty(username) | String.IsNullOrEmpty(new NetworkCredential("", password).Password) | String.IsNullOrEmpty(domainName))
|
||||
{
|
||||
resultToken.resultErrorId = 30002;
|
||||
resultToken.resultMessage = "Fehlende Anmeldeinformationen";
|
||||
return resultToken;
|
||||
}
|
||||
if (String.IsNullOrEmpty(groupPrefix))
|
||||
{
|
||||
resultToken.resultErrorId = 30004;
|
||||
resultToken.resultMessage = "Kein Gruppen Präfix angegeben";
|
||||
return resultToken;
|
||||
}
|
||||
if (String.IsNullOrEmpty(newFolderPath))
|
||||
{
|
||||
resultToken.resultErrorId = 30005;
|
||||
resultToken.resultMessage = "Kein Pfad für neues Verzeichnis angegeben";
|
||||
return resultToken;
|
||||
}
|
||||
if (String.IsNullOrEmpty(newFolderParent))
|
||||
{
|
||||
resultToken.resultErrorId = 30006;
|
||||
resultToken.resultMessage = "Kein Pfad für neues Übergeordnetesverzeichnis angegeben";
|
||||
return resultToken;
|
||||
}
|
||||
if (String.IsNullOrEmpty(baseFolder))
|
||||
{
|
||||
resultToken.resultErrorId = 30007;
|
||||
resultToken.resultMessage = "Kein Basisverzeichnis angegeben";
|
||||
return resultToken;
|
||||
}
|
||||
if (ownerUserSids == null || ownerUserSids.Count == 0)
|
||||
{
|
||||
resultToken.resultErrorId = 30008;
|
||||
resultToken.resultMessage = "Kein Verantwortlicher angegeben";
|
||||
return resultToken;
|
||||
}
|
||||
return resultToken;
|
||||
}
|
||||
public ResultToken createDataArea()
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
|
||||
resultToken.resultErrorId = 0;
|
||||
if (checkRequiredVariables().resultErrorId == 0)
|
||||
{
|
||||
newDataArea = new DataArea();
|
||||
IAM_Folder folder = new IAM_Folder();
|
||||
folder.configurationID = ConfigID;
|
||||
folder.technicalName = newFolderPath;
|
||||
folder.targetType = (int)IAM_TargetType.FileSystem;
|
||||
folder.Parent = newFolderParent;
|
||||
folder.ParentUID = DataArea.GetUniqueDataAreaID(newFolderParent);
|
||||
newDataArea.IAM_Folders.Add(folder);
|
||||
newSecurityGroups = new SecurityGroups();
|
||||
newSecurityGroups.username = username;
|
||||
newSecurityGroups.domainName = domainName;
|
||||
newSecurityGroups.password = password;
|
||||
try
|
||||
{
|
||||
// ImpersonationHelper.Impersonate(domainName, username, new NetworkCredential("", password).Password, delegate
|
||||
// {
|
||||
if (Connection != null)
|
||||
Connection.Dispose();
|
||||
|
||||
DefaultLogger.LogEntry(LogLevels.Info, $"Establishing connection to {baseFolder}, User: {username}, Password: {Helper.MaskAllButLastAndFirst(new NetworkCredential("", password).Password)}");
|
||||
using (Connection = new cNetworkConnection(baseFolder, username, new NetworkCredential("", password).Password))
|
||||
{
|
||||
if (checkFolder().resultErrorId == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
createADGroups();
|
||||
try
|
||||
{
|
||||
resultToken = createFolder();
|
||||
try
|
||||
{
|
||||
resultToken = SetTraversePermissions();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
resultToken.resultErrorId = 30200;
|
||||
resultToken.resultMessage = "Fehler beim setzen der Traverserechte \n" + e.Message;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
resultToken.resultErrorId = 30200;
|
||||
resultToken.resultMessage = "Fehler beim Erstellen der Verzeichnisse \n" + e.Message;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
resultToken.resultErrorId = 30100;
|
||||
resultToken.resultMessage = "Fehler beim Erstellen der AD Gruppen \n" + e.Message;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
resultToken = checkFolder();
|
||||
}
|
||||
/* },
|
||||
logonType,
|
||||
logonProvider);
|
||||
*/
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
resultToken.resultErrorId = 30000;
|
||||
resultToken.resultMessage = "Fehler beim Herstellen der Verbindung \n " + e.Message;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return checkRequiredVariables();
|
||||
}
|
||||
return resultToken;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
cLogManager.DefaultLogger.LogException(E);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
|
||||
private ResultToken SetTraversePermissions()
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
|
||||
try
|
||||
{
|
||||
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
|
||||
resultToken.resultErrorId = 0;
|
||||
|
||||
// Loggen der DomainContext-Parameter
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"DomainName: {domainName}, Username: {username}");
|
||||
|
||||
if (string.IsNullOrEmpty(domainName) || string.IsNullOrEmpty(username) || password is null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "Eines der DomainContext-Parameter ist null oder leer.");
|
||||
return resultToken;
|
||||
}
|
||||
|
||||
var domainContext = new PrincipalContext(ContextType.Domain, domainName, username, new NetworkCredential("", password).Password);
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "PrincipalContext erfolgreich erstellt.");
|
||||
|
||||
// Überprüfen von newDataArea und IAM_Folders
|
||||
if (newDataArea == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "newDataArea ist null.");
|
||||
return resultToken;
|
||||
}
|
||||
|
||||
if (newDataArea.IAM_Folders == null || newDataArea.IAM_Folders.Count == 0)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "IAM_Folders ist null oder leer.");
|
||||
return resultToken;
|
||||
}
|
||||
|
||||
DirectoryInfo newDir = new DirectoryInfo(newDataArea.IAM_Folders[0].technicalName);
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Neues Verzeichnis: {newDir.FullName}");
|
||||
|
||||
DirectoryInfo parent = newDir.Parent;
|
||||
if (parent == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "Parent-Verzeichnis ist null.");
|
||||
return resultToken;
|
||||
}
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Parent-Verzeichnis: {parent.FullName}");
|
||||
|
||||
var lvl = DataArea.GetRelativePath(parent.FullName, baseFolder).Count(n => n == Path.DirectorySeparatorChar);
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Ebene (lvl): {lvl}");
|
||||
|
||||
// Überprüfen der Templates
|
||||
if (templates == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "templates ist null.");
|
||||
return resultToken;
|
||||
}
|
||||
|
||||
var traverseGroupTemplate = templates.FirstOrDefault(t => t.Type.Equals(SecurityGroupType.Traverse));
|
||||
if (traverseGroupTemplate == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "traverseGroupTemplate ist null.");
|
||||
return resultToken;
|
||||
}
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"traverseGroupTemplate gefunden");
|
||||
|
||||
// Überprüfen der traverseGroupTemplate-Eigenschaften
|
||||
if (traverseGroupTemplate.WildcardTemplate == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "WildcardTemplate von traverseGroupTemplate ist null.");
|
||||
return resultToken;
|
||||
}
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"traverseGroupTemplate.WildcardTemplate: {traverseGroupTemplate.WildcardTemplate}");
|
||||
|
||||
if (traverseGroupTemplate.NamingTemplate == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "NamingTemplate von traverseGroupTemplate ist null.");
|
||||
return resultToken;
|
||||
}
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"traverseGroupTemplate.NamingTemplate: {traverseGroupTemplate.NamingTemplate}");
|
||||
|
||||
if (string.IsNullOrEmpty(baseFolder))
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "baseFolder ist null oder leer.");
|
||||
return resultToken;
|
||||
}
|
||||
|
||||
GroupPrincipal traverseGroup = null;
|
||||
|
||||
// Überprüfen, ob createTraverseGroupLvl initialisiert ist
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"createTraverseGroupLvl: {createTraverseGroupLvl}");
|
||||
|
||||
if (createTraverseGroupLvl == -1)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "createTraverseGroupLvl ist auf -1 gesetzt.");
|
||||
return resultToken;
|
||||
}
|
||||
|
||||
for (int i = lvl; i >= createTraverseGroupLvl; i--)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Verarbeite Ebene {i}.");
|
||||
|
||||
if (parent == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "Parent ist null innerhalb der Schleife.");
|
||||
break;
|
||||
}
|
||||
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Hole ACL für Ordner: {parent.FullName}");
|
||||
AuthorizationRuleCollection ACLs = null;
|
||||
try
|
||||
{
|
||||
ACLs = parent.GetAccessControl(AccessControlSections.Access).GetAccessRules(true, true, typeof(NTAccount));
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "ACLs erfolgreich abgerufen.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Abrufen der ACLs: {ex.Message}");
|
||||
continue; // Weiter zur nächsten Iteration
|
||||
}
|
||||
|
||||
if (ACLs == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "ACLs ist null.");
|
||||
continue;
|
||||
}
|
||||
|
||||
GroupPrincipal parentTraverseGroup = null;
|
||||
string relativePathRaw = DataArea.GetRelativePath(parent.FullName, baseFolder).Trim(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
relativePathRaw = relativePathRaw.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"relativePath vor Normalisierung: {relativePathRaw}");
|
||||
|
||||
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;
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"relativePath nach Normalisierung: {relativePath}");
|
||||
var folderName = sanitizedSegments.Length > 0
|
||||
? sanitizedSegments[sanitizedSegments.Length - 1]
|
||||
: Helper.SanitizePathSegment(Path.GetFileName(parent.FullName.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)));
|
||||
|
||||
string traverseRegex = null;
|
||||
try
|
||||
{
|
||||
traverseRegex = Helper.ApplyTemplatePlaceholders(traverseGroupTemplate.WildcardTemplate, true, relativePath, sanitizedSegments, folderName);
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"traverseRegex: {traverseRegex}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler bei der Erstellung von traverseRegex: {ex.Message}");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (FileSystemAccessRule acl in ACLs)
|
||||
{
|
||||
var searchString = acl.IdentityReference.Value;
|
||||
var aclSplit = searchString.Split('\\');
|
||||
if (aclSplit.Length == 2)
|
||||
{
|
||||
searchString = aclSplit[1];
|
||||
}
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Suche GroupPrincipal für: {searchString}");
|
||||
|
||||
var princ = GroupPrincipal.FindByIdentity(domainContext, searchString);
|
||||
if (princ != null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Gefundene Gruppe: {princ.Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Keine Gruppe gefunden für: {searchString}");
|
||||
}
|
||||
|
||||
if (princ != null && Regex.IsMatch(princ.Name, traverseRegex, RegexOptions.IgnoreCase))
|
||||
{
|
||||
parentTraverseGroup = princ;
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"parentTraverseGroup gesetzt: {parentTraverseGroup.Name}");
|
||||
}
|
||||
if (parentTraverseGroup != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (parentTraverseGroup == null && !traverseGroupTemplate.NamingTemplate.Equals(string.Empty))
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "Erstelle neue TraverseGroup.");
|
||||
if (newSecurityGroups == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "newSecurityGroups ist null.");
|
||||
continue;
|
||||
}
|
||||
|
||||
IAM_SecurityGroup newTraverseGroup = null;
|
||||
var traverseNameTemplate = Helper.ApplyTemplatePlaceholders(traverseGroupTemplate.NamingTemplate, true, relativePath, sanitizedSegments, folderName);
|
||||
var traverseDescriptionTemplate = Helper.ApplyTemplatePlaceholders(traverseGroupTemplate.DescriptionTemplate, true, relativePath, sanitizedSegments, folderName);
|
||||
var loop = 0;
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
newTraverseGroup = new IAM_SecurityGroup()
|
||||
{
|
||||
Name = traverseNameTemplate.ReplaceLoopTag(loop),
|
||||
description = traverseDescriptionTemplate.ReplaceLoopTag(loop),
|
||||
technicalName = "CN=" + traverseNameTemplate.ReplaceLoopTag(loop) + "," + groupOUPath,
|
||||
Scope = traverseGroupTemplate.Scope
|
||||
};
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Erstellte TraverseGroup: {newTraverseGroup.Name} (Loop: {loop})");
|
||||
loop++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Erstellen von newTraverseGroup: {ex.Message}");
|
||||
break;
|
||||
}
|
||||
} while (newSecurityGroups.GroupAllreadyExisting(newTraverseGroup.Name.ToUpper()) && loop < 20);
|
||||
|
||||
if (newTraverseGroup != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(groupOUPath))
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "groupOUPath ist null oder leer.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parent.Parent != null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "Parent.Parent ist nicht null. Erstelle AD-Gruppe.");
|
||||
try
|
||||
{
|
||||
newSecurityGroups.CreateADGroup(groupOUPath, newTraverseGroup, null);
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"AD-Gruppe erstellt: {newTraverseGroup.Name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Erstellen der AD-Gruppe: {ex.Message}");
|
||||
continue;
|
||||
}
|
||||
|
||||
parentTraverseGroup = GroupPrincipal.FindByIdentity(domainContext, newTraverseGroup.Name);
|
||||
if (parentTraverseGroup == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"parentTraverseGroup konnte nach Erstellung der Gruppe nicht gefunden werden: {newTraverseGroup.Name}");
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var accesscontrol = parent.GetAccessControl();
|
||||
accesscontrol.AddAccessRule(new FileSystemAccessRule(parentTraverseGroup.Sid,
|
||||
FileSystemRights.Read, InheritanceFlags.None, PropagationFlags.None,
|
||||
AccessControlType.Allow));
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Setze Traverse-ACL auf: {parent.FullName} für {parentTraverseGroup.DistinguishedName}");
|
||||
parent.SetAccessControl(accesscontrol);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Setzen der ACL: {ex.Message}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "Parent.Parent ist null. Traverse-ACL kann nicht gesetzt werden.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parentTraverseGroup != null)
|
||||
{
|
||||
if (i == lvl)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "Verarbeite SecurityGroups bei oberster Ebene.");
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "Warte 3min.");
|
||||
System.Threading.Thread.Sleep(180000); // 60 Sekunden warten
|
||||
foreach (var currentSecGroup in newSecurityGroups.IAM_SecurityGroups)
|
||||
{
|
||||
if (currentSecGroup == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, "currentSecGroup ist null.");
|
||||
continue;
|
||||
}
|
||||
using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, currentSecGroup.UID))
|
||||
{
|
||||
if (groupPrincipal == null)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"GroupPrincipal nicht gefunden für UID: {currentSecGroup.UID}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentSecGroup.Scope == GroupScope.Global)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!parentTraverseGroup.Members.Contains(groupPrincipal))
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Füge {groupPrincipal.DistinguishedName} zur Traverse-Gruppe {parentTraverseGroup.DistinguishedName} hinzu");
|
||||
parentTraverseGroup.Members.Add(groupPrincipal);
|
||||
parentTraverseGroup.Save();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Hinzufügen der Gruppe: {ex.Message}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
traverseGroup = parentTraverseGroup;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (traverseGroup != null && parentTraverseGroup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!parentTraverseGroup.Members.Contains(traverseGroup))
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Füge {traverseGroup.DistinguishedName} zur Traverse-Gruppe {parentTraverseGroup.DistinguishedName} hinzu");
|
||||
parentTraverseGroup.Members.Add(traverseGroup);
|
||||
parentTraverseGroup.Save();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Hinzufügen der Traverse-Gruppe: {ex.Message}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
parentTraverseGroup.Save();
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"parentTraverseGroup gespeichert: {parentTraverseGroup.Name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Speichern der parentTraverseGroup: {ex.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "parentTraverseGroup ist null.");
|
||||
}
|
||||
|
||||
// Aktualisiere parent und lvl für die nächste Iteration
|
||||
parent = parent.Parent;
|
||||
if (parent != null)
|
||||
{
|
||||
lvl = DataArea.GetRelativePath(parent.FullName, baseFolder).Count(n => n == Path.DirectorySeparatorChar);
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Neue Ebene (lvl) nach Aktualisierung: {lvl}");
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, "Parent nach Aktualisierung ist null.");
|
||||
}
|
||||
}
|
||||
|
||||
return resultToken;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
cLogManager.DefaultLogger.LogException(E);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ResultToken checkFolder()
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
|
||||
try
|
||||
{
|
||||
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
|
||||
resultToken.resultErrorId = 0;
|
||||
if (Directory.Exists(newDataArea.IAM_Folders[0].technicalName))
|
||||
{
|
||||
resultToken.resultMessage = "New folder " + newDataArea.IAM_Folders[0].technicalName + " already exists";
|
||||
resultToken.resultErrorId = 30201;
|
||||
|
||||
}
|
||||
return resultToken;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
cLogManager.DefaultLogger.LogException(E);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
private ResultToken createFolder()
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
try
|
||||
{
|
||||
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
|
||||
resultToken.resultErrorId = 0;
|
||||
|
||||
|
||||
if (!Directory.Exists(newFolderParent))
|
||||
{
|
||||
resultToken.resultMessage = "Übergeordnetesverzeichnis " + newDataArea.IAM_Folders[0].Parent + " des neuen Ordners " + newDataArea.IAM_Folders[0].technicalName + " existiert nicht";
|
||||
resultToken.resultErrorId = 30202;
|
||||
return resultToken;
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Creating folder: {newDataArea.IAM_Folders[0].technicalName}");
|
||||
DirectoryInfo newDir = Directory.CreateDirectory(newDataArea.IAM_Folders[0].technicalName);
|
||||
newDataArea.IAM_Folders[0].UID = DataArea.GetUniqueDataAreaID(newDir.FullName);
|
||||
for (int i = 0; newSecurityGroups.IAM_SecurityGroups.Count > i; i++)
|
||||
{
|
||||
var currentSecGroup = newSecurityGroups.IAM_SecurityGroups[i];
|
||||
var sid = new SecurityIdentifier(currentSecGroup.UID);
|
||||
if (groupPermissionStrategy == PermissionGroupStrategy.AGDLP && currentSecGroup.Scope == GroupScope.Local
|
||||
|| groupPermissionStrategy == PermissionGroupStrategy.AGP && currentSecGroup.Scope == GroupScope.Global)
|
||||
DataArea.AddDirectorySecurity(newDataArea.IAM_Folders[0].baseFolder, newDataArea.IAM_Folders[0].technicalName, sid, currentSecGroup.rights, AccessControlType.Allow);
|
||||
}
|
||||
AddDirectorySecurityACLDenyFolderDeletion(newDataArea.IAM_Folders[0].technicalName);
|
||||
|
||||
resultToken.resultErrorId = 0;
|
||||
resultToken.resultMessage = "Verzeichnis erfolgreich erstellt";
|
||||
}
|
||||
return resultToken;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
cLogManager.DefaultLogger.LogException(E);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
|
||||
private void AddDirectorySecurityACLDenyFolderDeletion(string technicalName)
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
// Create a new DirectoryInfo object.
|
||||
DirectoryInfo dInfo = new DirectoryInfo(technicalName);
|
||||
//DirectoryInfo dInfoBaseFolder = new DirectoryInfo(baseFolderTechnicalName);
|
||||
|
||||
// Get a DirectorySecurity object that represents the
|
||||
// current security settings.
|
||||
DirectorySecurity dSecurity = dInfo.GetAccessControl();
|
||||
|
||||
// Add the FileSystemAccessRule to the security settings.
|
||||
var everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
|
||||
|
||||
dSecurity.AddAccessRule(new FileSystemAccessRule(everyone,
|
||||
FileSystemRights.Delete, InheritanceFlags.None, PropagationFlags.None,
|
||||
AccessControlType.Deny));
|
||||
// Set the new access settings.
|
||||
dInfo.SetAccessControl(dSecurity);
|
||||
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
|
||||
private void createADGroups()
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
|
||||
try
|
||||
{
|
||||
Dictionary<FileSystemRights, string> currentGroupDIC = new Dictionary<FileSystemRights, string>();
|
||||
adGroupDic = new Dictionary<FileSystemRights, string>();
|
||||
|
||||
var existingADGroupCount = 0;
|
||||
do
|
||||
{
|
||||
newSecurityGroups.IAM_SecurityGroups.Clear();
|
||||
newSecurityGroups.GenerateNewSecurityGroups(baseFolder,
|
||||
newDataArea.IAM_Folders[0].technicalName,
|
||||
groupPrefix,
|
||||
groupOUPath,
|
||||
groupPermissionStrategy,
|
||||
groupTraverseTag,
|
||||
groupReadTag,
|
||||
groupWriteTag,
|
||||
groupOwnerTag,
|
||||
groupDLTag,
|
||||
groupGTag,
|
||||
groupCustomTags,
|
||||
templates,
|
||||
ReadACLPermission,
|
||||
WriteACLPermission,
|
||||
OwnerACLPermission,
|
||||
existingADGroupCount);
|
||||
/*
|
||||
if (existingADGroupCount > 0 && !templates.All(t => t.Type == SecurityGroupType.Traverse || Regex.IsMatch(t.NamingTemplate, @"(?<loopTag>{{(?<prefix>[^}]*)(?<loop>LOOP)(?<postfix>[^{]*)}})")))
|
||||
{
|
||||
var nt = templates.First(t => t.Type == SecurityGroupType.Traverse || Regex.IsMatch(t.NamingTemplate, @"(?<loopTag>{{(?<prefix>[^}]*)(?<loop>LOOP)(?<postfix>[^{]*)}})")).NamingTemplate;
|
||||
DefaultLogger.LogEntry(LogLevels.Debug, $"Naming template: {nt}");
|
||||
throw new Exception("AD groups already existing and loop tag not found");
|
||||
}
|
||||
*/
|
||||
existingADGroupCount++;
|
||||
|
||||
} while (newSecurityGroups.GroupsAllreadyExisting(groupOUPath) && existingADGroupCount < 1000);
|
||||
if(newSecurityGroups.GroupsAllreadyExisting(groupOUPath) && existingADGroupCount>= 1000)
|
||||
{
|
||||
throw new Exception("Unique AD Group could not be generated after 1000 iterations");
|
||||
}
|
||||
List<UserPrincipal> users;
|
||||
List<UserPrincipal> owners = getUserPrincipalBySid(ownerUserSids);
|
||||
List<UserPrincipal> writers = getUserPrincipalBySid(writerUserSids);
|
||||
List<UserPrincipal> readers = getUserPrincipalBySid(readerUserSids);
|
||||
for (int i = 0; newSecurityGroups.IAM_SecurityGroups.Count > i; i++)
|
||||
{
|
||||
if (newSecurityGroups.IAM_SecurityGroups[i].Name.ToUpper().EndsWith(groupOwnerTag.ToUpper()))
|
||||
users = owners;
|
||||
else if (newSecurityGroups.IAM_SecurityGroups[i].Name.ToUpper().EndsWith(groupWriteTag.ToUpper()))
|
||||
users = writers;
|
||||
else if (newSecurityGroups.IAM_SecurityGroups[i].Name.ToUpper().EndsWith(groupReadTag.ToUpper()))
|
||||
users = readers;
|
||||
else
|
||||
users = null;
|
||||
newSecurityGroups.CreateADGroup(groupOUPath, newSecurityGroups.IAM_SecurityGroups[i], users);
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
cLogManager.DefaultLogger.LogException(E);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
|
||||
private List<UserPrincipal> getUserPrincipalBySid(ICollection<string> UserSids)
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
|
||||
try
|
||||
{
|
||||
List<UserPrincipal> result = new List<UserPrincipal>();
|
||||
if (UserSids != null)
|
||||
{
|
||||
foreach (var sid in UserSids)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sid))
|
||||
{
|
||||
UserPrincipal user = getUserPrincipalBySid(sid);
|
||||
if (user != null && !result.Any(item => item.DistinguishedName == user.DistinguishedName))
|
||||
{
|
||||
result.Add(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
cLogManager.DefaultLogger.LogException(E);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
|
||||
private UserPrincipal getUserPrincipalBySid(string sid)
|
||||
{
|
||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||
|
||||
try
|
||||
{
|
||||
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName, username, new NetworkCredential("", password).Password);
|
||||
UserPrincipal user;
|
||||
user = UserPrincipal.FindByIdentity(ctx, IdentityType.Sid, (sid));
|
||||
return user;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
cLogManager.DefaultLogger.LogException(E);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(MethodBase.GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
private string getTraverseRegex()
|
||||
{
|
||||
return groupWildcard
|
||||
.Replace("{{PREFIX}}", groupPrefix)
|
||||
.Replace("{{SCOPETAG}}", groupDLTag)
|
||||
.Replace("{{GROUPTYPEPOSTFIX}}", groupTraverseTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user