This commit is contained in:
Drechsler, Meik
2025-10-15 14:56:07 +02:00
commit f563d78417
896 changed files with 654481 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using System.Reflection;
namespace C4IT_IAM_Engine
{
public class DataArea
{
public List<IAM_Folder> IAM_Folders;
public string rootUID;
public static string GetRelativePath(string childFolder, string rootFolder)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
// Folders must end in a slash
if (!childFolder.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
childFolder += Path.DirectorySeparatorChar;
}
Uri childUri = new Uri(childFolder);
// Folders must end in a slash
if (!rootFolder.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
rootFolder += Path.DirectorySeparatorChar;
}
Uri folderUri = new Uri(rootFolder);
return Uri.UnescapeDataString(folderUri.MakeRelativeUri(childUri).ToString().Replace('/', Path.DirectorySeparatorChar));
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public static string GetUniqueDataAreaID(string name)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
var utf8 = new System.Text.UTF8Encoding();
var hash = BitConverter.ToString(md5.ComputeHash(utf8.GetBytes(name)));
hash = hash.ToLower().Replace("-", "");
return hash;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public DataArea()
{
IAM_Folders = new List<IAM_Folder>();
}
public static void AddDirectorySecurity(string baseFolderTechnicalName, string newFolderTechnicalName, SecurityIdentifier Account, FileSystemRights Rights, AccessControlType ControlType)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(newFolderTechnicalName);
//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.
dSecurity.AddAccessRule(new FileSystemAccessRule(Account,
Rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None,
AccessControlType.Allow));
DefaultLogger.LogEntry(LogLevels.Debug, $"Set ACL for folder: {newFolderTechnicalName} for { Account }");
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
// Removes an ACL entry on the specified directory for the specified account.
public static void RemoveDirectorySecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(FileName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.RemoveAccessRule(new FileSystemAccessRule(Account,
Rights,
ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
}
public class IAM_Folder
{
public string Name = String.Empty;
public string technicalName = String.Empty;
public string UID = String.Empty;
public string Parent = String.Empty;
public string ParentUID = String.Empty;
public string Owner = String.Empty;
public string Write = String.Empty;
public string Read = String.Empty;
public string Traverse = String.Empty;
public string CreatedDate = String.Empty;
public int Level = 0;
public int targetType;
public string configurationID = String.Empty;
public string baseFolder = String.Empty;
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace C4IT_IAM_Engine
{
public class DataArea_Enums
{
}
public enum IAM_TargetType { FileSystem = 1, Matrix42 = 2, Sharepoint = 3 }
}

View 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);
}
}
}

View File

@@ -0,0 +1,543 @@
using C4IT_IAM_Engine;
using C4IT_IAM;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using System.Reflection;
namespace C4IT_IAM_GET
{
public enum AccessRights { Owner = 2032127, Write = 1245631, Read = 1179817 }
public enum PermissionGroupStrategy
{
AGP,
AGDLP
}
public class DataArea_FileSystem
{
public const string constApplicationDataPath = "%ProgramData%\\Consulting4IT GmbH\\LIAM";
public string domainName;
public string DomainIPAddress;
public string username;
private SecureString password;
private cNetworkConnection Connection;
public string groupWildCard_Owner;
public string groupWildCard_Read;
public string groupWildCard_Write;
public string groupWildCard_Traverse;
public string groupGOwnerWildcard = string.Empty;
public string groupGWriteWildcard = string.Empty;
public string groupGReadWildcard = string.Empty;
public string groupTraverseWildcard = string.Empty;
public string groupDLOwnerWildcard = string.Empty;
public string groupDLWriteWildcard = string.Empty;
public string groupDLReadWildcard = string.Empty;
public IDictionary<string, string> groupCustomTags;
public string groupDLTag;
public string groupGTag;
public string groupOwnerTag;
public string groupReadTag;
public string groupWriteTag;
public string groupTraverseTag;
public string groupPrefix;
public PermissionGroupStrategy groupPermissionStrategy;
public string groupLDAPFilter;
private string exportFolder;
private PrincipalContext ctx;
public string ConfigID;
public int maxDepth = 1;
public string groupLDAPPath;
public bool console;
private string startDir;
public string SecGroupXML;
public string DataAreasXML;
public SecureString Password { get => password; set => password = value; }
public string StartDir { get => startDir; set => startDir = value; }
public string ExportFolder { get => exportFolder; set => exportFolder = value; }
private ResultToken checkRequiredVariables()
{
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
resultToken.resultErrorId = 0;
if (String.IsNullOrEmpty(ConfigID))
{
resultToken.resultErrorId = 20001;
resultToken.resultMessage = "Keine Config ID angegeben";
return resultToken;
}
if (String.IsNullOrEmpty(StartDir))
{
resultToken.resultErrorId = 20007;
resultToken.resultMessage = "Kein Startverzeichnis gewählt ";
return resultToken;
}
if (string.IsNullOrEmpty(username) | String.IsNullOrEmpty(new NetworkCredential("", password).Password) | String.IsNullOrEmpty(domainName))
{
resultToken.resultErrorId = 20002;
resultToken.resultMessage = "Fehlende Anmeldeinformationen";
return resultToken;
}
if (String.IsNullOrEmpty(groupWildCard_Owner) | String.IsNullOrEmpty(groupWildCard_Read) | String.IsNullOrEmpty(groupWildCard_Write))
{
resultToken.resultErrorId = 20004;
resultToken.resultMessage = "Keine AD Gruppen Wildcards";
return resultToken;
}
if (String.IsNullOrEmpty(groupLDAPFilter))
{
resultToken.resultErrorId = 20005;
resultToken.resultMessage = "Kein LDAP Gruppenfilter angegeben";
return resultToken;
}
if (String.IsNullOrEmpty(groupLDAPPath))
{
resultToken.resultErrorId = 20006;
resultToken.resultMessage = "Kein LDAP Pfad angegeben";
return resultToken;
}
return resultToken;
}
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");
}
private void FillMatchingGroups()
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
groupWildCard_Owner = (groupPermissionStrategy == PermissionGroupStrategy.AGP ? groupGOwnerWildcard.Replace("{{PREFIX}}", groupPrefix).Replace("{{SCOPETAG}}", groupGTag) : groupDLOwnerWildcard.Replace("{{PREFIX}}", groupPrefix).Replace("{{SCOPETAG}}", groupDLTag)).Replace("{{GROUPTYPEPOSTFIX}}", groupOwnerTag).ReplaceTags(groupCustomTags);
groupWildCard_Write = (groupPermissionStrategy == PermissionGroupStrategy.AGP ? groupGWriteWildcard.Replace("{{PREFIX}}", groupPrefix).Replace("{{SCOPETAG}}", groupGTag) : groupDLWriteWildcard.Replace("{{PREFIX}}", groupPrefix).Replace("{{SCOPETAG}}", groupDLTag)).Replace("{{GROUPTYPEPOSTFIX}}", groupWriteTag).ReplaceTags(groupCustomTags);
groupWildCard_Read = (groupPermissionStrategy == PermissionGroupStrategy.AGP ? groupGReadWildcard.Replace("{{PREFIX}}", groupPrefix).Replace("{{SCOPETAG}}", groupGTag) : groupDLReadWildcard.Replace("{{PREFIX}}", groupPrefix).Replace("{{SCOPETAG}}", groupDLTag)).Replace("{{GROUPTYPEPOSTFIX}}", groupReadTag).ReplaceTags(groupCustomTags);
groupWildCard_Traverse = (groupPermissionStrategy == PermissionGroupStrategy.AGP ? groupTraverseWildcard.Replace("{{PREFIX}}", groupPrefix).Replace("{{SCOPETAG}}", groupGTag) : groupTraverseWildcard.Replace("{{PREFIX}}", groupPrefix).Replace("{{SCOPETAG}}", groupDLTag)).Replace("{{GROUPTYPEPOSTFIX}}", groupTraverseTag).ReplaceTags(groupCustomTags);
DefaultLogger.LogEntry(LogLevels.Debug, $"Owner regex: {groupWildCard_Owner}");
DefaultLogger.LogEntry(LogLevels.Debug, $"Write regex: {groupWildCard_Write}");
DefaultLogger.LogEntry(LogLevels.Debug, $"Read regex: {groupWildCard_Read}");
DefaultLogger.LogEntry(LogLevels.Debug, $"Traverse regex: {groupWildCard_Traverse}");
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public ResultToken BuildRootStructureWrapper()
{
LogMethodBegin(MethodBase.GetCurrentMethod());
FillMatchingGroups();
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
resultToken.resultErrorId = 0;
try
{
if (checkRequiredVariables().resultErrorId == 0)
{
if (Connection != null)
Connection.Dispose();
DefaultLogger.LogEntry(LogLevels.Debug, $"Establishing connection to {startDir}, User: {username}, Password: {Helper.MaskAllButLastAndFirst(new NetworkCredential("", password).Password)}");
using (Connection = new cNetworkConnection(startDir, username, new NetworkCredential("", password).Password))
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Creating Domain Context: {domainName}");
ctx = new PrincipalContext(ContextType.Domain, domainName, username, new NetworkCredential("", password).Password);
try
{
BuildRootStructure(startDir);
}
catch (Exception e)
{
resultToken.resultErrorId = 20200;
resultToken.resultMessage = "Fehler bei der Analyse der Verzeichnisstruktur \n " + e.Message;
}
}
}
else
{
return checkRequiredVariables();
}
}
catch (Exception E)
{
DefaultLogger.LogException(E);
resultToken.resultErrorId = 20000;
resultToken.resultMessage = $"Fehler beim Ermitteln der Dateistruktur \n{E.Message}";
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
return resultToken;
}
public void BuildRootStructure(string currentDirectory, int currentDepth = 0, DataArea dA = null)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
var firstRun = false;
try
{
string[] folders = Directory.GetDirectories(currentDirectory);
if (dA == null)
{
firstRun = true;
dA = new DataArea();
dA.rootUID = DataArea.GetUniqueDataAreaID(currentDirectory);
DirectoryInfo dADir = new DirectoryInfo(currentDirectory);
IAM_Folder iamFolder = new IAM_Folder()
{
Name = dADir.Name,
technicalName = dADir.FullName,
UID = DataArea.GetUniqueDataAreaID(dADir.FullName),
Parent = string.Empty,
ParentUID = string.Empty,
CreatedDate = dADir.CreationTimeUtc.ToString("s"),
Level = 0,
targetType = Convert.ToInt32(IAM_TargetType.FileSystem),
configurationID = ConfigID
};
dA.IAM_Folders.Add(iamFolder);
}
currentDepth++;
DefaultLogger.LogEntry(LogLevels.Debug, $"Current folder: {currentDirectory}, Level: {currentDepth}, Subdirectories: {folders.Length}");
foreach (string folder in folders)
{
DirectoryInfo dADir = new DirectoryInfo(folder);
IAM_Folder iamFolder = new IAM_Folder()
{
Name = dADir.Name,
technicalName = dADir.FullName,
UID = DataArea.GetUniqueDataAreaID(dADir.FullName),
Parent = dADir.Parent.FullName,
ParentUID = DataArea.GetUniqueDataAreaID(dADir.Parent.FullName),
CreatedDate = dADir.CreationTimeUtc.ToString("s"),
Level = currentDepth,
targetType = Convert.ToInt32(IAM_TargetType.FileSystem),
configurationID = ConfigID
};
var dAACL = dADir.GetAccessControl();
var dAAR = dAACL.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier));
var k = "";
DefaultLogger.LogEntry(LogLevels.Debug, $"Current folder: {folder}, Access Control Rules: {dAAR.Count}");
foreach (FileSystemAccessRule rule in dAAR)
{
//skip ACLs for user "everyone"
if (rule.IdentityReference.Value == "S-1-1-0")
continue;
k += rule.FileSystemRights + " - ";
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Sid, rule.IdentityReference.Value);
if (grp != null)
{
if (Regex.IsMatch(grp.SamAccountName, groupWildCard_Owner, RegexOptions.IgnoreCase))
{
iamFolder.Owner = rule.IdentityReference.Value;
DefaultLogger.LogEntry(LogLevels.Debug, $"ACL on folder: {folder}, matching Owner: {grp.Name}");
}
else if (Regex.IsMatch(grp.SamAccountName, groupWildCard_Write, RegexOptions.IgnoreCase))
{
DefaultLogger.LogEntry(LogLevels.Debug, $"ACL on folder: {folder}, matching Write: {grp.Name}");
iamFolder.Write = rule.IdentityReference.Value;
}
else if (Regex.IsMatch(grp.SamAccountName, groupWildCard_Read, RegexOptions.IgnoreCase))
{
DefaultLogger.LogEntry(LogLevels.Debug, $"ACL on folder: {folder}, matching Read: {grp.Name}");
iamFolder.Read = rule.IdentityReference.Value;
}
else if (Regex.IsMatch(grp.SamAccountName, groupWildCard_Traverse, RegexOptions.IgnoreCase))
{
DefaultLogger.LogEntry(LogLevels.Debug, $"ACL on folder: {folder}, matching Traverse: {grp.Name}");
iamFolder.Traverse = rule.IdentityReference.Value;
}
else
DefaultLogger.LogEntry(LogLevels.Debug, $"No match for: {grp.Name}");
}
}
dA.IAM_Folders.Add(iamFolder);
if (currentDepth < maxDepth)
{
BuildRootStructure(folder, currentDepth, dA);
}
DefaultLogger.LogEntry(LogLevels.Debug, $"Max level ({ maxDepth }) reached");
}
if (firstRun)
SetDataAreaXML(dA);
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw E;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public ResultToken GetRelevantADGroupsWrapper()
{
LogMethodBegin(MethodBase.GetCurrentMethod());
FillMatchingGroups();
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
resultToken.resultErrorId = 0;
try
{
if (checkRequiredVariables().resultErrorId == 0)
{
GetRelevantADGroups();
}
else
{
return checkRequiredVariables();
}
}
catch (Exception E)
{
resultToken.resultErrorId = 20000;
resultToken.resultMessage = "Fehler Ermitteln der AD-Gruppen \n" + E.Message;
cLogManager.DefaultLogger.LogException(E);
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
return resultToken;
}
public void GetRelevantADGroups()
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
SecurityGroups secGroups = new SecurityGroups();
var ldapPath = $"LDAP://{domainName}/{groupLDAPPath}";
DefaultLogger.LogEntry(LogLevels.Debug, $"Connecting to LDAP using: Domain: {domainName}, LDAPPath: {ldapPath}, User: {username}, Password: {Helper.MaskAllButLastAndFirst(new NetworkCredential("", password).Password)}");
ctx = new PrincipalContext(ContextType.Domain, domainName, username, new NetworkCredential("", password).Password);
DefaultLogger.LogEntry(LogLevels.Debug, $"1 " + ctx.ConnectedServer);
DefaultLogger.LogEntry(LogLevels.Debug, $"2 " + ctx.UserName);
DefaultLogger.LogEntry(LogLevels.Debug, $"3 " + ctx.ValidateCredentials(username, new NetworkCredential("", password).Password));
// DefaultLogger.LogEntry(LogLevels.Debug, $"3.5 " + ctx.ToString());
DirectoryEntry entry = new DirectoryEntry
{
Path = ldapPath,
Username = username,
Password = new NetworkCredential(username, password).Password,
AuthenticationType = AuthenticationTypes.Secure | AuthenticationTypes.Sealing
};
DefaultLogger.LogEntry(LogLevels.Debug, $"4 " + entry.NativeGuid);
DefaultLogger.LogEntry(LogLevels.Debug, $"5 " + entry.Path);
var tmpFilter = "(&(" + groupLDAPFilter + ")(objectClass=group))";
DefaultLogger.LogEntry(LogLevels.Debug, $"6 " + tmpFilter);
//DefaultLogger.LogEntry(LogLevels.Debug, $"6.5 " + entry.ToString());
DirectorySearcher dSearch = new DirectorySearcher(entry)
{
Filter = tmpFilter
};
dSearch.PageSize = 100000;
DefaultLogger.LogEntry(LogLevels.Debug, $"7 " + dSearch.Filter);
SearchResultCollection sr = dSearch.FindAll();
DefaultLogger.LogEntry(LogLevels.Debug, $"8 " + sr.Count);
if (sr.Count > 0)
{
foreach (SearchResult k in sr)
{
IAM_SecurityGroup sec = new IAM_SecurityGroup();
sec.Name = k.Properties["Name"][0].ToString();
setGroupType(sec);
SecurityIdentifier sid = new SecurityIdentifier(k.Properties["objectSid"][0] as byte[], 0);
sec.UID = sid.Value;
sec.technicalName = k.Properties["distinguishedname"][0].ToString();
sec.targetTyp = Convert.ToInt32(IAM_TargetType.FileSystem);
var group = GroupPrincipal.FindByIdentity(ctx, IdentityType.Sid, sid.Value);
sec.Scope = (GroupScope)group.GroupScope;
var filter = "(&(" + groupLDAPFilter + ")(objectClass=group)(memberOf=" + sec.technicalName + "))";
DirectorySearcher iDSearch = new DirectorySearcher(entry)
{
Filter = filter
};
SearchResultCollection iSr = iDSearch.FindAll();
if (iSr.Count > 0 )
{
foreach (SearchResult iK in iSr)
{
IAM_SecurityGroup iSec = new IAM_SecurityGroup();
iSec.Name = iK.Properties["Name"][0].ToString();
setGroupType(iSec);
SecurityIdentifier iSid = new SecurityIdentifier(iK.Properties["objectSid"][0] as byte[], 0);
iSec.UID = iSid.Value;
iSec.technicalName = iK.Properties["distinguishedname"][0].ToString();
iSec.targetTyp = Convert.ToInt32(IAM_TargetType.FileSystem);
iSec.Parent = sec.UID;
var iGroup = GroupPrincipal.FindByIdentity(ctx, IdentityType.Sid, iSid.Value);
iSec.Scope = (GroupScope)iGroup.GroupScope;
if (!secGroups.IAM_SecurityGroups.Any(s => s.technicalName.Equals(iSec.technicalName)))
{
secGroups.IAM_SecurityGroups.Add(iSec);
DefaultLogger.LogEntry(LogLevels.Debug, $"Found security group: {iSec.technicalName}");
}
}
}
else
if (!secGroups.IAM_SecurityGroups.Any(s => s.technicalName.Equals(sec.technicalName)))
{
secGroups.IAM_SecurityGroups.Add(sec);
DefaultLogger.LogEntry(LogLevels.Debug, $"Found security group: {sec.technicalName}");
}
}
}
ctx.Dispose();
entry.Dispose();
dSearch.Dispose();
sr.Dispose();
SetSecGroupXML(secGroups);
DefaultLogger.LogEntry(LogLevels.Debug, $"{secGroups.IAM_SecurityGroups.Count} AD groups retrieved with following lDAPQuery {groupLDAPFilter}");
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw E;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
void setGroupType(IAM_SecurityGroup sec)
{
if (sec.Name.EndsWith(groupOwnerTag))
sec.securityGroupType = SecurityGroupType.Owner;
else if (sec.Name.EndsWith(groupReadTag))
sec.securityGroupType = SecurityGroupType.Read;
else if (sec.Name.EndsWith(groupWriteTag))
sec.securityGroupType = SecurityGroupType.Write;
else if (sec.Name.EndsWith(groupTraverseTag))
sec.securityGroupType = SecurityGroupType.Traverse;
}
}
public void SetDataAreaXML(DataArea dA)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
var xmlserializer = new XmlSerializer(typeof(DataArea));
using (var sww = new StringWriter())
{
XmlWriterSettings setting = new XmlWriterSettings();
setting.OmitXmlDeclaration = true;
using (XmlWriter writer = XmlWriter.Create(sww, setting))
{
xmlserializer.Serialize(writer, dA);
XmlDocument xml = new XmlDocument();
xml.LoadXml(sww.ToString());
DataAreasXML = xml.OuterXml;
}
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw E;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public void SetSecGroupXML(SecurityGroups secGroups)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
var xmlserializer = new XmlSerializer(typeof(SecurityGroups));
using (var sww = new StringWriter())
{
XmlWriterSettings setting = new XmlWriterSettings();
setting.OmitXmlDeclaration = true;
using (XmlWriter writer = XmlWriter.Create(sww, setting))
{
xmlserializer.Serialize(writer, secGroups);
XmlDocument xml = new XmlDocument();
xml.LoadXml(sww.ToString());
SecGroupXML = xml.OuterXml;
}
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw E;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace C4IT_IAM_Engine
{
public static class Helper
{
public static string ReplaceLoopTag(this string str, int loop)
{
return Regex.Replace(str, @"(?<loopTag>{{(?<prefix>[^}]*)(?<loop>LOOP)(?<postfix>[^{]*)}})", loop <= 0 ? "" : "${prefix}" + loop + "${postfix}");
}
public static string ReplaceTags(this string str, IDictionary<string, string> dict)
{
if (str.Equals(string.Empty) || str == null || dict == null || dict.Count == 0)
return str;
return dict.Aggregate(str, (current, value) =>
current.Replace("{{" + value.Key + "}}", value.Value));
}
public static string ApplyTemplatePlaceholders(string templateValue, bool allowRelativePath, string defaultRelativePath, string[] sanitizedSegments, string folderName)
{
if (templateValue == null)
return string.Empty;
var result = Regex.Replace(templateValue, @"{{\s*NAME\s*}}", folderName ?? string.Empty, RegexOptions.IgnoreCase);
if (allowRelativePath)
{
result = Regex.Replace(result, @"{{\s*RELATIVEPATH(?:\s*\(\s*(\d+)\s*\))?\s*}}", match =>
{
if (sanitizedSegments == null || sanitizedSegments.Length == 0)
return string.Empty;
if (!match.Groups[1].Success)
return defaultRelativePath;
if (!int.TryParse(match.Groups[1].Value, out var segmentIndex) || segmentIndex < 0)
return defaultRelativePath;
var segmentCount = Math.Min(sanitizedSegments.Length, segmentIndex + 1);
var skip = sanitizedSegments.Length - segmentCount;
return string.Join("_", sanitizedSegments.Skip(skip));
}, RegexOptions.IgnoreCase);
}
return result;
}
public static string SanitizePathSegment(string segment)
{
if (string.IsNullOrEmpty(segment))
return string.Empty;
return Regex.Replace(segment, @"[\s\-]", "_");
}
public static void CreatePathWithWriteAccess(string FilePath)
{
try
{
var PF = Environment.ExpandEnvironmentVariables(FilePath);
Directory.CreateDirectory(PF);
}
catch { }
}
public static string MaskAllButLastAndFirst(this string input, char maskingChar = '*')
{
if (input.Length > 3)
{
var pattern = @"^(.{1})(.+)(.{1})$";
var match = Regex.Match(input, pattern);
var mask = new string(maskingChar, match.Groups[2].Length);
return $"{match.Groups[1]}{mask}{match.Groups[3]}";
}
else
return new string(maskingChar, input.Length);
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace C4IT_IAM_Engine
{
public class ResultToken
{
public string resultMessage;
public int resultErrorId;
public string resultFunction;
public ResultToken(string function)
{
this.resultFunction = function;
}
}
}

View File

@@ -0,0 +1,503 @@
using C4IT_IAM_GET;
using System;
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 System.Xml.Serialization;
using static C4IT.Logging.cLogManager;
using System.Reflection;
using C4IT.Logging;
namespace C4IT_IAM_Engine
{
public class SecurityGroups
{
public string domainName;
public string username;
public SecureString password;
public List<IAM_SecurityGroup> IAM_SecurityGroups;
public string rootUID;
public SecurityGroups()
{
IAM_SecurityGroups = new List<IAM_SecurityGroup>();
}
public bool GroupsAllreadyExisting(string ouPath)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
int groupCount = 0;
if (IAM_SecurityGroups != null)
foreach (var s in IAM_SecurityGroups)
{
if (s.securityGroupType != SecurityGroupType.Traverse)
{
DirectoryEntry entry = new DirectoryEntry
{
Path = "LDAP://" + domainName,
Username = username,
Password = new NetworkCredential("", password).Password,
AuthenticationType = AuthenticationTypes.Secure | AuthenticationTypes.Sealing
};
DirectorySearcher dSearch = new DirectorySearcher(entry)
{
Filter = "(&(CN=" + s.Name.ToUpper() + ")(objectClass=group))"
};
dSearch.PageSize = 100000;
SearchResultCollection sr = dSearch.FindAll();
groupCount += sr.Count;
}
}
return groupCount > 0;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public bool GroupAllreadyExisting(string CN)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
int groupCount = 0;
if (CN != string.Empty)
{
DirectoryEntry entry = new DirectoryEntry
{
Path = "LDAP://" + domainName,
Username = username,
Password = new NetworkCredential("", password).Password,
AuthenticationType = AuthenticationTypes.Secure | AuthenticationTypes.Sealing
};
DirectorySearcher dSearch = new DirectorySearcher(entry)
{
Filter = "(&(CN=" + CN.ToUpper() + ")(objectClass=group))"
};
dSearch.PageSize = 100000;
SearchResultCollection sr = dSearch.FindAll();
groupCount += sr.Count;
}
return groupCount > 0;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public void GenerateNewSecurityGroups(
string baseFolder,
string newFolderPath,
string groupPrefix,
string ouPath,
PermissionGroupStrategy groupPermissionStrategy,
string groupTraverseTag,
string groupReadTag,
string groupWriteTag,
string groupOwnerTag,
string groupDLTag,
string groupGTag,
IDictionary<string, string> customTags,
List<IAM_SecurityGroupTemplate> templates,
int readACLPermission,
int writeACLPermission,
int ownerACLPermission,
int loop = 0,
int existingADGroupCount = 0)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
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)
{
case SecurityGroupType.Owner:
GroupTypeTag = groupOwnerTag;
break;
case SecurityGroupType.Write:
GroupTypeTag = groupWriteTag;
break;
case SecurityGroupType.Read:
GroupTypeTag = groupReadTag;
break;
case SecurityGroupType.Traverse:
GroupTypeTag = groupTraverseTag;
break;
default:
break;
}
var GroupScopeTag = "";
switch (template.Scope)
{
case GroupScope.Global:
GroupScopeTag = groupGTag;
break;
case GroupScope.Local:
GroupScopeTag = groupDLTag;
break;
default:
break;
}
var tags = new Dictionary<string, string>();
tags.Add("PREFIX", groupPrefix);
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();
}
IAM_SecurityGroupTemplate ownerGlobal = templates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Owner));
IAM_SecurityGroup osecGroup = new IAM_SecurityGroup()
{
Name = ownerGlobal.NamingTemplate,
description = ownerGlobal.DescriptionTemplate,
technicalName = "CN=" + ownerGlobal.NamingTemplate + "," + ouPath,
targetTyp = (int)IAM_TargetType.FileSystem,
rights = (FileSystemRights)ownerACLPermission,
Scope = GroupScope.Global
};
IAM_SecurityGroups.Add(osecGroup);
IAM_SecurityGroupTemplate writeGlobal = templates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Write));
IAM_SecurityGroup wsecGroup = new IAM_SecurityGroup()
{
Name = writeGlobal.NamingTemplate,
description = writeGlobal.DescriptionTemplate,
technicalName = "CN=" + writeGlobal.NamingTemplate + "," + ouPath,
targetTyp = (int)IAM_TargetType.FileSystem,
rights = (FileSystemRights)writeACLPermission,
Scope = GroupScope.Global
};
IAM_SecurityGroups.Add(wsecGroup);
IAM_SecurityGroupTemplate readGlobal = templates.First(t => t.Scope.Equals(GroupScope.Global) && t.Type.Equals(SecurityGroupType.Read));
IAM_SecurityGroup rsecGroup = new IAM_SecurityGroup()
{
Name = readGlobal.NamingTemplate,
description = readGlobal.DescriptionTemplate,
technicalName = "CN=" + readGlobal.NamingTemplate + "," + ouPath,
targetTyp = (int)IAM_TargetType.FileSystem,
rights = (FileSystemRights)readACLPermission,
Scope = GroupScope.Global
};
IAM_SecurityGroups.Add(rsecGroup);
//
if (groupPermissionStrategy == PermissionGroupStrategy.AGDLP)
{
IAM_SecurityGroupTemplate ownerDL = templates.First(t => t.Scope.Equals(GroupScope.Local) && t.Type.Equals(SecurityGroupType.Owner));
IAM_SecurityGroup osecDLGroup = new IAM_SecurityGroup()
{
Name = ownerDL.NamingTemplate,
description = ownerDL.DescriptionTemplate,
technicalName = "CN=" + ownerDL.NamingTemplate + "," + ouPath,
targetTyp = (int)IAM_TargetType.FileSystem,
rights = (FileSystemRights)ownerACLPermission,
Scope = GroupScope.Local
};
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_SecurityGroup wsecDLGroup = new IAM_SecurityGroup()
{
Name = writeDL.NamingTemplate,
description = writeDL.DescriptionTemplate,
technicalName = "CN=" + writeDL.NamingTemplate + "," + ouPath,
targetTyp = (int)IAM_TargetType.FileSystem,
rights = (FileSystemRights)writeACLPermission,
Scope = GroupScope.Local
};
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_SecurityGroup rsecDLGroup = new IAM_SecurityGroup()
{
Name = readDL.NamingTemplate,
description = readDL.DescriptionTemplate,
technicalName = "CN=" + readDL.NamingTemplate + "," + ouPath,
targetTyp = (int)IAM_TargetType.FileSystem,
rights = (FileSystemRights)readACLPermission,
Scope = GroupScope.Local
};
rsecDLGroup.memberGroups.Add(rsecGroup);
IAM_SecurityGroups.Add(rsecDLGroup);
}
foreach (var secGroup in IAM_SecurityGroups)
{
secGroup.description = secGroup.description.ReplaceLoopTag(0);
secGroup.Name = secGroup.Name.ReplaceLoopTag(loop);
secGroup.technicalName = secGroup.technicalName.ReplaceLoopTag(loop);
DefaultLogger.LogEntry(LogLevels.Debug, $"Security group generated: {secGroup.technicalName}");
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public static string GetRightPartOfPath(string path, string startAfterPart)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
// use the correct seperator for the environment
var pathParts = path.Split(Path.DirectorySeparatorChar);
if (startAfterPart.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
startAfterPart = startAfterPart.Substring(0, startAfterPart.Length - 1);
}
var startAfter = startAfterPart.Split(Path.DirectorySeparatorChar);
string newPath = String.Empty;
if (pathParts.Length > startAfter.Length)
{
for (int i = startAfter.Length; pathParts.Length > i; i++)
{
newPath += pathParts[i] + Path.DirectorySeparatorChar;
}
}
if (newPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
newPath = newPath.Substring(0, newPath.Length - 1);
}
// try and work out if last part was a directory - if not, drop the last part as we don't want the filename
return newPath;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public static string getSID(DirectoryEntry ent)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
var usrId = (byte[])ent.Properties["objectSid"][0];
return (new SecurityIdentifier(usrId, 0)).ToString();
}
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
{
if (!GroupAllreadyExisting(secGroup.Name.ToUpper()))
{
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();
if (users != null && secGroup.Scope == GroupScope.Global)
{
foreach (var user in users)
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Adding member: {user.DistinguishedName}");
group.Properties["member"].Add(user.DistinguishedName);
}
}
if(!String.IsNullOrEmpty(secGroup.description))
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Setting description: {secGroup.description}");
group.Properties["description"].Value = secGroup.description;
}
var groupType = secGroup.Scope == GroupScope.Global ? GroupScopeValues.Global : GroupScopeValues.Local;
DefaultLogger.LogEntry(LogLevels.Debug, $"Setting groupType to: {groupType}");
group.Properties["groupType"].Value = groupType;
if (secGroup.Scope == GroupScope.Local)
foreach (var iGroup in secGroup.memberGroups)
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Adding member: {iGroup.technicalName}");
group.Properties["member"].Add(iGroup.technicalName);
}
group.CommitChanges();
DirectoryEntry ent = new DirectoryEntry("LDAP://" + domainName + "/" + "CN =" + secGroup.Name.ToUpper() + "," + 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}");
secGroup.UID = objectid;
return ent;
}
else
{
DirectoryEntry e = new DirectoryEntry("LDAP://" + domainName + "/" + "CN =" + secGroup.Name.ToUpper() + "," + ouPath, username, new NetworkCredential("", password).Password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
var objectid = getSID(e);
secGroup.UID = objectid;
}
return null;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
}
public enum GroupScopeValues : int
{
Global = -2147483646,
Local = -2147483644
}
public class IAM_SecurityGroupTemplate
{
private string namingTemplate;
private string descriptionTemplate;
private string wildcardTemplate;
private SecurityGroupType type;
private GroupScope scope;
public IAM_SecurityGroupTemplate(string namingTemplate, string descriptionTemplate, string wildcardTemplate, SecurityGroupType type, GroupScope scope)
{
NamingTemplate = namingTemplate;
DescriptionTemplate = descriptionTemplate;
WildcardTemplate = wildcardTemplate;
Type = type;
Scope = scope;
}
public string NamingTemplate
{
get => namingTemplate; set
{
namingTemplate = value == null ? "" : value;
}
}
public string DescriptionTemplate
{
get => descriptionTemplate; set
{
descriptionTemplate = value == null ? "" : value;
}
}
public string WildcardTemplate
{
get => wildcardTemplate; set
{
wildcardTemplate = value == null ? "" : value;
}
}
public SecurityGroupType Type { get => type; set => type = value; }
public GroupScope Scope { get => scope; set => scope = value; }
}
public class IAM_SecurityGroup
{
public string UID;
public string Parent = "";
public string description;
public List<IAM_SecurityGroup> memberGroups;
public string Name;
public string technicalName;
public SecurityGroupType securityGroupType;
public int targetTyp;
public GroupScope Scope;
public FileSystemRights rights;
public IAM_SecurityGroup()
{
memberGroups = new List<IAM_SecurityGroup>();
}
}
public enum SecurityGroupType
{
[XmlEnum(Name = "0")]
Owner,
[XmlEnum(Name = "1")]
Write,
[XmlEnum(Name = "2")]
Read,
[XmlEnum(Name = "3")]
Traverse
}
}

View File

@@ -0,0 +1,208 @@
using System;
using System.Net;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using System.Reflection;
namespace C4IT_IAM
{
public class cNetworkConnection : IDisposable
{
private const uint MAX_PREFERRED_LENGTH = 0xFFFFFFFF;
private const int NERR_Success = 0;
string _networkName;
public cNetworkConnection(string networkName,
string userName, string Password)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
_networkName = networkName;
var netResource = new NetResource()
{
Scope = ResourceScope.GlobalNetwork,
ResourceType = ResourceType.Disk,
DisplayType = ResourceDisplaytype.Share,
RemoteName = networkName
};
var result = WNetAddConnection2(
netResource,
Password,
userName,
0);
if (result != 0)
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Error in connect occured ({result}) {new Win32Exception(result).Message}");
throw new Win32Exception(result);
}
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
~cNetworkConnection()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
WNetCancelConnection2(_networkName, 0, true);
}
public SHARE_INFO_1[] EnumNetShares(string Server)
{
List<SHARE_INFO_1> ShareInfos = new List<SHARE_INFO_1>();
int entriesread = 0;
int totalentries = 0;
int resume_handle = 0;
int nStructSize = Marshal.SizeOf(typeof(SHARE_INFO_1));
IntPtr bufPtr = IntPtr.Zero;
StringBuilder server = new StringBuilder(Server);
int ret = NetShareEnum(server, 1, ref bufPtr, MAX_PREFERRED_LENGTH, ref entriesread, ref totalentries, ref resume_handle);
if (ret == NERR_Success)
{
IntPtr currentPtr = bufPtr;
for (int i = 0; i < entriesread; i++)
{
SHARE_INFO_1 shi1 = (SHARE_INFO_1)Marshal.PtrToStructure(currentPtr, typeof(SHARE_INFO_1));
ShareInfos.Add(shi1);
currentPtr += nStructSize;
}
NetApiBufferFree(bufPtr);
return ShareInfos.ToArray();
}
else
{
ShareInfos.Add(new SHARE_INFO_1("ERROR=" + ret.ToString(), 10, string.Empty));
return ShareInfos.ToArray();
}
}
[DllImport("mpr.dll")]
private static extern int WNetAddConnection2(NetResource netResource,
string password, string username, int flags);
[DllImport("mpr.dll")]
private static extern int WNetCancelConnection2(string name, int flags,
bool force);
[DllImport("Netapi32.dll", SetLastError = true)]
static extern int NetApiBufferFree(IntPtr Buffer);
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode)]
private static extern int NetShareEnum(
StringBuilder ServerName,
int level,
ref IntPtr bufPtr,
uint prefmaxlen,
ref int entriesread,
ref int totalentries,
ref int resume_handle
);
}
[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
public ResourceScope Scope;
public ResourceType ResourceType;
public ResourceDisplaytype DisplayType;
public int Usage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}
public enum ResourceScope : int
{
Connected = 1,
GlobalNetwork,
Remembered,
Recent,
Context
};
public enum ResourceType : int
{
Any = 0,
Disk = 1,
Print = 2,
Reserved = 8,
}
public enum ResourceDisplaytype : int
{
Generic = 0x0,
Domain = 0x01,
Server = 0x02,
Share = 0x03,
File = 0x04,
Group = 0x05,
Network = 0x06,
Root = 0x07,
Shareadmin = 0x08,
Directory = 0x09,
Tree = 0x0a,
Ndscontainer = 0x0b
}
public enum NetError : uint
{
NERR_Success = 0,
NERR_BASE = 2100,
NERR_UnknownDevDir = (NERR_BASE + 16),
NERR_DuplicateShare = (NERR_BASE + 18),
NERR_BufTooSmall = (NERR_BASE + 23),
}
public enum SHARE_TYPE : uint
{
STYPE_DISKTREE = 0,
STYPE_PRINTQ = 1,
STYPE_DEVICE = 2,
STYPE_IPC = 3,
STYPE_SPECIAL = 0x80000000,
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_1
{
public string shi1_netname;
public uint shi1_type;
public string shi1_remark;
public SHARE_INFO_1(string sharename, uint sharetype, string remark)
{
this.shi1_netname = sharename;
this.shi1_type = sharetype;
this.shi1_remark = remark;
}
public override string ToString()
{
return shi1_netname;
}
}
}