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

674
LiamNtfs/C4IT.LIAM.Ntfs.cs Normal file
View File

@@ -0,0 +1,674 @@
using System;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.AccessControl;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using C4IT.Logging;
using C4IT.Matrix42.ServerInfo;
using C4IT_IAM_Engine;
using C4IT_IAM_SET;
using LiamNtfs;
using static C4IT.Logging.cLogManager;
using static LiamNtfs.cActiveDirectoryBase;
namespace C4IT.LIAM
{
public static class LiamInitializer
{
static public cLiamProviderBase CreateInstance(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData)
{
return new cLiamProviderNtfs(LiamConfiguration, ProviderData);
}
}
public class cLiamProviderNtfs : cLiamProviderBase
{
public static Guid nftsModuleId = new Guid("77e213a1-6517-ea11-4881-000c2980fd94");
public readonly cNtfsBase ntfsBase = new cNtfsBase();
public readonly cActiveDirectoryBase activeDirectoryBase = new cActiveDirectoryBase();
//public readonly bool WithoutPrivateFolders = true;
public cLiamProviderNtfs(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData) :
base(LiamConfiguration, ProviderData)
{
this.ReplaceNtfsCustomTags();
}
public override async Task<bool> LogonAsync()
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(nftsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return false;
}
return await LogonAsync(true);
}
private void ReplaceNtfsCustomTags()
{
foreach (var namingConvention in NamingConventions)
{
String key = null;
String value = null;
key = "GROUPTYPEPOSTFIX";
if (namingConvention.AccessRole == eLiamAccessRoles.Owner)
{
value = CustomTags["Filesystem_GroupOwnerTag"];
}
else if (namingConvention.AccessRole == eLiamAccessRoles.Write)
{
value = CustomTags["Filesystem_GroupWriteTag"];
}
else if (namingConvention.AccessRole == eLiamAccessRoles.Read)
{
value = CustomTags["Filesystem_GroupReadTag"];
}
else if (namingConvention.AccessRole == eLiamAccessRoles.Traverse)
{
value = CustomTags["Filesystem_GroupTraverseTag"];
}
if (!String.IsNullOrEmpty(key) && !String.IsNullOrEmpty(value))
{
namingConvention.DescriptionTemplate = namingConvention.DescriptionTemplate.Replace($"{{{{{key}}}}}", value);
namingConvention.NamingTemplate = namingConvention.NamingTemplate.Replace($"{{{{{key}}}}}", value);
namingConvention.Wildcard = namingConvention.Wildcard.Replace($"{{{{{key}}}}}", value);
}
value = null;
key = "SCOPE";
if (namingConvention.Scope == eLiamAccessRoleScopes.DomainLocal)
{
value = CustomTags["Filesystem_GroupDomainLocalTag"];
}
else if (namingConvention.Scope == eLiamAccessRoleScopes.Global)
{
value = CustomTags["Filesystem_GroupGlobalTag"];
}
if (!String.IsNullOrEmpty(key) && !String.IsNullOrEmpty(value))
{
namingConvention.DescriptionTemplate = namingConvention.DescriptionTemplate.Replace($"{{{{{key}}}}}", value);
namingConvention.NamingTemplate = namingConvention.NamingTemplate.Replace($"{{{{{key}}}}}", value);
namingConvention.Wildcard = namingConvention.Wildcard.Replace($"{{{{{key}}}}}", value);
}
}
}
public async Task<bool> LogonAsync(bool force = false)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var LI = new cNtfsLogonInfo()
{
Domain = Domain,
User = Credential?.Identification,
UserSecret = Credential?.Secret,
TargetNetworkName = RootPath,
TargetGroupPath = this.GroupPath
};
var RetVal = await ntfsBase.LogonAsync(LI) && await activeDirectoryBase.LogonAsync(LI);
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return false;
}
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int Depth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(nftsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return new List<cLiamDataAreaBase>();
}
if (!await LogonAsync())
return null;
if (string.IsNullOrEmpty(this.RootPath))
return null;
var DataAreas = new List<cLiamDataAreaBase>();
var rootpathSplit = this.RootPath.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
cLiamNtfsShare share = null;
cLiamNtfsFolder NtfsRootFolder = null;
switch (rootpathSplit.Length)
{
case 0:
case 1:
return null;
case 2:
{
share = new cLiamNtfsShare(this, new cNtfsResultShare()
{
DisplayName = rootpathSplit.Last(),
Path = RootPath,
Level = 0
});
DataAreas.Add(share);
break;
}
default:
{
NtfsRootFolder = new cLiamNtfsFolder(this, null, null, new cNtfsResultFolder()
{
DisplayName = rootpathSplit.Last(),
Path = RootPath,
Level = 0
});
DataAreas.Add(NtfsRootFolder);
break;
}
}
var DAL = await ntfsBase.RequestFoldersListAsync(this.RootPath, Depth);
if (DAL == null)
return null;
foreach (var Entry in DAL)
{
if (!string.IsNullOrEmpty(this.DataAreaRegEx) && !Regex.Match(Entry.Value.DisplayName, this.DataAreaRegEx).Success)
continue;
var Folder = new cLiamNtfsFolder(this, share, NtfsRootFolder, (cNtfsResultFolder)Entry.Value);
DataAreas.Add(Folder);
}
return DataAreas;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public override async Task<cLiamDataAreaBase> LoadDataArea(string UID)
{
//TODO implement LoadDataArea
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(nftsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var splt = UID.Split(System.IO.Path.DirectorySeparatorChar);
var name = Path.GetDirectoryName(UID);
switch (splt.Length)
{
case 0:
case 1:
return null;
case 2:
{
return new cLiamNtfsShare(this, new cNtfsResultShare()
{
DisplayName = name,
Path = UID,
Level = getDepth(UID)
});
}
default:
{
return new cLiamNtfsFolder(this, null, null, new cNtfsResultFolder()
{
DisplayName = name,
Path = UID,
Level = getDepth(UID)
});
}
}
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(nftsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return new List<cLiamDataAreaBase>();
}
if (!await LogonAsync())
return null;
if (string.IsNullOrEmpty(this.GroupPath))
return null;
var SecurityGroups = new List<cLiamDataAreaBase>();
var SGL = await activeDirectoryBase.RequestSecurityGroupsListAsync(groupFilter);
if (SGL == null)
return null;
foreach (var Entry in SGL)
{
if (!string.IsNullOrEmpty(this.GroupRegEx) && !Regex.Match(Entry.Value.DisplayName, this.GroupRegEx).Success)
continue;
var SecurityGroup = new cLiamAdGroup(this, (cSecurityGroupResult)Entry.Value);
SecurityGroups.Add(SecurityGroup);
}
return SecurityGroups;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public async Task<ResultToken> CreateDataAreaAsync(
string newFolderPath,
string newFolderParent,
IDictionary<string, string> customTags,
IEnumerable<string> ownerSids,
IEnumerable<string> readerSids,
IEnumerable<string> writerSids
)
{
// 1) Instanziere DataArea_FileSystem und fülle Konfiguration:
var engine = new DataArea_FileSystem
{
domainName = this.Domain,
username = this.Credential.Identification,
password = new NetworkCredential("", this.Credential.Secret).SecurePassword,
baseFolder = this.RootPath,
newFolderPath = newFolderPath,
newFolderParent = newFolderParent,
groupPrefix = CustomTags["Filesystem_GroupPrefixTag"],
groupOUPath = this.GroupPath,
groupPermissionStrategy = (C4IT_IAM_GET.PermissionGroupStrategy)this.GroupStrategy,
groupCustomTags = customTags,
ownerUserSids = ownerSids?.ToList(),
readerUserSids = readerSids?.ToList(),
writerUserSids = writerSids?.ToList(),
// Templates aus NamingConventions übernehmen…
};
// 2) Engine starten
var result = engine.createDataArea();
return result;
}
public int getDepth(string path)
{
return getDepth(this.RootPath, path);
}
public static int getDepth(DirectoryInfo root, DirectoryInfo folder)
{
var rootDepth = root.FullName.TrimEnd(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar).Length;
var folderDepth = folder.FullName.TrimEnd(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar).Length;
return folderDepth - rootDepth;
}
public static int getDepth(string root, string folder)
{
return getDepth(new DirectoryInfo(root), new DirectoryInfo(folder));
}
public override string GetLastErrorMessage()
{
throw new NotImplementedException();
}
}
public class cLiamNtfsShare : cLiamDataAreaBase
{
public new readonly cLiamProviderNtfs Provider = null;
private readonly cNtfsResultBase Share = null;
public cLiamNtfsShare(cLiamProviderNtfs Provider, cNtfsResultBase Share) :
base(Provider)
{
this.Provider = Provider;
this.Share = Share;
this.DisplayName = Share.Path.Split('\\').Last();
this.TechnicalName = Share.Path;
this.UID = cLiamNtfsFolder.GetUniqueDataAreaID(Share.Path);
this.Level = Share.Level;
this.DataType = eLiamDataAreaTypes.NtfsShare;
this.SupportsOwners = false;
this.SupportsPermissions = false;
}
internal async Task<List<cLiamDataAreaBase>> getFolders()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
var RetVal = new List<cLiamDataAreaBase>(0);
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
var RetVal = new List<cLiamDataAreaBase>();
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
}
public class cLiamAdGroup : cLiamDataAreaBase
{
public new readonly cLiamProviderNtfs Provider = null;
public readonly string dn = null;
public readonly string scope = null;
public override Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
throw new NotImplementedException();
}
public cLiamAdGroup(cLiamProviderNtfs Provider, cSecurityGroupResult secGroup) : base(Provider)
{
this.UID = secGroup.ID;
this.TechnicalName = secGroup.DisplayName;
this.Provider = Provider;
this.dn = secGroup.Path;
this.scope = secGroup.Scope.ToString();
}
}
public class cLiamNtfsFolder : cLiamDataAreaBase
{
public new readonly cLiamProviderNtfs Provider = null;
public readonly cLiamNtfsShare Share = null;
public readonly cLiamNtfsFolder NtfsRootFolder = null;
public string OwnerGroupIdentifier = "S-1-0-0";
public string WriteGroupIdentifier = "S-1-0-0";
public string ReadGroupIdentifier = "S-1-0-0";
public string TraverseGroupIdentifier = "S-1-0-0";
public cLiamNtfsFolder(cLiamProviderNtfs Provider, cLiamNtfsShare share, cLiamNtfsFolder ntfsRootFolder, cNtfsResultFolder NtfsFolder) : base(Provider)
{
var ntfsParent = NtfsFolder.Parent;
this.Provider = Provider;
this.NtfsRootFolder = ntfsRootFolder;
this.Share = share;
this.TechnicalName = NtfsFolder.Path;
this.UID =GetUniqueDataAreaID(NtfsFolder.Path);
this.DisplayName = new DirectoryInfo(NtfsFolder.Path).Name;
this.Level = NtfsFolder.Level;
this.DataType = eLiamDataAreaTypes.NtfsFolder;
this.SupportsPermissions = true;
this.CreatedDate = NtfsFolder.CreatedDate;
if (ntfsParent != null)
{
this.ParentUID = GetUniqueDataAreaID(ntfsParent.Path);
}
else if (this.Level == 1)
{
this.ParentUID = GetUniqueDataAreaID(this.Provider.RootPath);
}
assignPermissionGroups(Provider, NtfsFolder);
}
public override async Task<List<cLiamUserInfo>> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
return await GetMembersAsync(true);
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
private async Task<List<cLiamUserInfo>> GetMembersAsync(bool owners)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var AD = this.Provider?.activeDirectoryBase;
if (AD == null)
{
LogEntry($"Could not get ad class from Provider for folder '{this.TechnicalName}'", LogLevels.Warning);
return null;
}
cADCollectionBase lstMembers;
this.OwnerGroupIdentifier = this.OwnerRef ?? this.OwnerGroupIdentifier;
if (owners && !String.IsNullOrEmpty(this.OwnerGroupIdentifier))
lstMembers = await AD.GetMembersAsync(this.OwnerGroupIdentifier);
else
lstMembers = null;
if (lstMembers == null)
{
LogEntry($"Could not get owner list for folder '{this.TechnicalName}'", LogLevels.Warning);
return null;
}
var RetVal = new List<cLiamUserInfo>(lstMembers.Count);
LogEntry($"Owners for folder found: {lstMembers.Count}", LogLevels.Debug);
foreach (var MemberEntry in lstMembers.Values)
{
var User = new cLiamUserInfo()
{
DisplayName = MemberEntry.DisplayName,
UserPrincipalName = (MemberEntry as cADUserResult).UserPrincipalName,
SID = MemberEntry.ID
};
RetVal.Add(User);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
private async void assignPermissionGroups(cLiamProviderNtfs Provider, cNtfsResultFolder NtfsFolder)
{
var ACLs = Provider.activeDirectoryBase.GetAccessControlList(NtfsFolder.Path);
var ownerNamingConvention = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Owner && (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGP && i.Scope == eLiamAccessRoleScopes.Global || Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP && i.Scope == eLiamAccessRoleScopes.DomainLocal));
var writeNamingConvention = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Write && (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGP && i.Scope == eLiamAccessRoleScopes.Global || Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP && i.Scope == eLiamAccessRoleScopes.DomainLocal));
var readNamingConvention = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Read && (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGP && i.Scope == eLiamAccessRoleScopes.Global || Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP && i.Scope == eLiamAccessRoleScopes.DomainLocal));
var traverseNamingConvention = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Traverse);
foreach (FileSystemAccessRule rule in ACLs)
{
//skip ACLs for user "everyone"
if (rule.IdentityReference.Value == "S-1-1-0")
continue;
GroupPrincipal grp = GroupPrincipal.FindByIdentity(Provider.activeDirectoryBase.adContext, IdentityType.Sid, rule.IdentityReference.Value);
if (grp != null)
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Try matching: {grp.Name}");
if (Regex.IsMatch(grp.SamAccountName, ownerNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
this.OwnerGroupIdentifier = rule.IdentityReference.Value;
if (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP)
{
var ldapFilter = String.Format("memberOf={0}", grp.DistinguishedName);
var res = await Provider.activeDirectoryBase.RequestSecurityGroupsListAsync(ldapFilter);
var ownerNamingConventionGlobal = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Owner && i.Scope == eLiamAccessRoleScopes.Global);
foreach (var memberItem in res)
{
var SecurityGroup = new cLiamAdGroup(this.Provider, (cSecurityGroupResult)memberItem.Value);
if (Regex.IsMatch( SecurityGroup.TechnicalName,ownerNamingConventionGlobal.Wildcard, RegexOptions.IgnoreCase))
this.OwnerGroupIdentifier = SecurityGroup.UID;
}
}
}
else if (Regex.IsMatch(grp.SamAccountName, writeNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
WriteGroupIdentifier = rule.IdentityReference.Value;
if (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP)
{
var ldapFilter = String.Format("memberOf={0}", grp.DistinguishedName);
var res = await Provider.activeDirectoryBase.RequestSecurityGroupsListAsync(ldapFilter);
var writeNamingConventionGlobal = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Write && i.Scope == eLiamAccessRoleScopes.Global);
foreach (var memberItem in res)
{
var SecurityGroup = new cLiamAdGroup(this.Provider, (cSecurityGroupResult)memberItem.Value);
if (Regex.IsMatch(SecurityGroup.TechnicalName, writeNamingConventionGlobal.Wildcard, RegexOptions.IgnoreCase))
this.WriteGroupIdentifier = SecurityGroup.UID;
}
}
}
else if (Regex.IsMatch(grp.SamAccountName, readNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
ReadGroupIdentifier = rule.IdentityReference.Value;
if (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP)
{
var ldapFilter = String.Format("memberOf={0}", grp.DistinguishedName);
var res = await Provider.activeDirectoryBase.RequestSecurityGroupsListAsync(ldapFilter);
var readNamingConventionGlobal = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Read && i.Scope == eLiamAccessRoleScopes.Global);
foreach (var memberItem in res)
{
var SecurityGroup = new cLiamAdGroup(this.Provider, (cSecurityGroupResult)memberItem.Value);
if (Regex.IsMatch(SecurityGroup.TechnicalName, readNamingConventionGlobal.Wildcard, RegexOptions.IgnoreCase))
this.ReadGroupIdentifier = SecurityGroup.UID;
}
}
}
else if (Regex.IsMatch(grp.SamAccountName, traverseNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
TraverseGroupIdentifier = rule.IdentityReference.Value;
}
else
DefaultLogger.LogEntry(LogLevels.Debug, $"No match for: {grp.Name}");
}
}
}
public static string GetUniqueDataAreaID(string fullPath)
{
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(fullPath)));
hash = hash.ToLower().Replace("-", "");
return hash;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public string GetUniqueDataAreaID()
{
return GetUniqueDataAreaID(this.TechnicalName);
}
public override async Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = 1)
{
//TODO implement getChildrenAsync
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
var DataAreas = new List<cLiamDataAreaBase>();
return DataAreas;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
}
}

View File

@@ -0,0 +1,637 @@
using System;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.AccessControl;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using C4IT.Logging;
using C4IT.Matrix42.ServerInfo;
using LiamNtfs;
using static C4IT.Logging.cLogManager;
using static LiamNtfs.cActiveDirectoryBase;
namespace C4IT.LIAM
{
public static class LiamInitializer
{
static public cLiamProviderBase CreateInstance(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData)
{
return new cLiamProviderNtfs(LiamConfiguration, ProviderData);
}
}
public class cLiamProviderNtfs : cLiamProviderBase
{
public static Guid nftsModuleId = new Guid("77e213a1-6517-ea11-4881-000c2980fd94");
public readonly cNtfsBase ntfsBase = new cNtfsBase();
public readonly cActiveDirectoryBase activeDirectoryBase = new cActiveDirectoryBase();
//public readonly bool WithoutPrivateFolders = true;
public cLiamProviderNtfs(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData) :
base(LiamConfiguration, ProviderData)
{
this.ReplaceNtfsCustomTags();
}
public override async Task<bool> LogonAsync()
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(nftsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return false;
}
return await LogonAsync(true);
}
private void ReplaceNtfsCustomTags()
{
foreach (var namingConvention in NamingConventions)
{
String key = null;
String value = null;
key = "GROUPTYPEPOSTFIX";
if (namingConvention.AccessRole == eLiamAccessRoles.Owner)
{
value = CustomTags["Filesystem_GroupOwnerTag"];
}
else if (namingConvention.AccessRole == eLiamAccessRoles.Write)
{
value = CustomTags["Filesystem_GroupWriteTag"];
}
else if (namingConvention.AccessRole == eLiamAccessRoles.Read)
{
value = CustomTags["Filesystem_GroupReadTag"];
}
else if (namingConvention.AccessRole == eLiamAccessRoles.Traverse)
{
value = CustomTags["Filesystem_GroupTraverseTag"];
}
if (!String.IsNullOrEmpty(key) && !String.IsNullOrEmpty(value))
{
namingConvention.DescriptionTemplate = namingConvention.DescriptionTemplate.Replace($"{{{{{key}}}}}", value);
namingConvention.NamingTemplate = namingConvention.NamingTemplate.Replace($"{{{{{key}}}}}", value);
namingConvention.Wildcard = namingConvention.Wildcard.Replace($"{{{{{key}}}}}", value);
}
value = null;
key = "SCOPE";
if (namingConvention.Scope == eLiamAccessRoleScopes.DomainLocal)
{
value = CustomTags["Filesystem_GroupDomainLocalTag"];
}
else if (namingConvention.Scope == eLiamAccessRoleScopes.Global)
{
value = CustomTags["Filesystem_GroupGlobalTag"];
}
if (!String.IsNullOrEmpty(key) && !String.IsNullOrEmpty(value))
{
namingConvention.DescriptionTemplate = namingConvention.DescriptionTemplate.Replace($"{{{{{key}}}}}", value);
namingConvention.NamingTemplate = namingConvention.NamingTemplate.Replace($"{{{{{key}}}}}", value);
namingConvention.Wildcard = namingConvention.Wildcard.Replace($"{{{{{key}}}}}", value);
}
}
}
public async Task<bool> LogonAsync(bool force = false)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var LI = new cNtfsLogonInfo()
{
Domain = Domain,
User = Credential?.Identification,
UserSecret = Credential?.Secret,
TargetNetworkName = RootPath,
TargetGroupPath = this.GroupPath
};
var RetVal = await ntfsBase.LogonAsync(LI) && await activeDirectoryBase.LogonAsync(LI);
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return false;
}
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int Depth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(nftsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return new List<cLiamDataAreaBase>();
}
if (!await LogonAsync())
return null;
if (string.IsNullOrEmpty(this.RootPath))
return null;
var DataAreas = new List<cLiamDataAreaBase>();
var rootpathSplit = this.RootPath.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
cLiamNtfsShare share = null;
cLiamNtfsFolder NtfsRootFolder = null;
switch (rootpathSplit.Length)
{
case 0:
case 1:
return null;
case 2:
{
share = new cLiamNtfsShare(this, new cNtfsResultShare()
{
DisplayName = rootpathSplit.Last(),
Path = RootPath,
Level = 0
});
DataAreas.Add(share);
break;
}
default:
{
NtfsRootFolder = new cLiamNtfsFolder(this, null, null, new cNtfsResultFolder()
{
DisplayName = rootpathSplit.Last(),
Path = RootPath,
Level = 0
});
DataAreas.Add(NtfsRootFolder);
break;
}
}
var DAL = await ntfsBase.RequestFoldersListAsync(this.RootPath, Depth);
if (DAL == null)
return null;
foreach (var Entry in DAL)
{
if (!string.IsNullOrEmpty(this.DataAreaRegEx) && !Regex.Match(Entry.Value.DisplayName, this.DataAreaRegEx).Success)
continue;
var Folder = new cLiamNtfsFolder(this, share, NtfsRootFolder, (cNtfsResultFolder)Entry.Value);
DataAreas.Add(Folder);
}
return DataAreas;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public override async Task<cLiamDataAreaBase> LoadDataArea(string UID)
{
//TODO implement LoadDataArea
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(nftsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var splt = UID.Split(System.IO.Path.DirectorySeparatorChar);
var name = Path.GetDirectoryName(UID);
switch (splt.Length)
{
case 0:
case 1:
return null;
case 2:
{
return new cLiamNtfsShare(this, new cNtfsResultShare()
{
DisplayName = name,
Path = UID,
Level = getDepth(UID)
});
}
default:
{
return new cLiamNtfsFolder(this, null, null, new cNtfsResultFolder()
{
DisplayName = name,
Path = UID,
Level = getDepth(UID)
});
}
}
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(nftsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return new List<cLiamDataAreaBase>();
}
if (!await LogonAsync())
return null;
if (string.IsNullOrEmpty(this.GroupPath))
return null;
var SecurityGroups = new List<cLiamDataAreaBase>();
var SGL = await activeDirectoryBase.RequestSecurityGroupsListAsync(groupFilter);
if (SGL == null)
return null;
foreach (var Entry in SGL)
{
if (!string.IsNullOrEmpty(this.GroupRegEx) && !Regex.Match(Entry.Value.DisplayName, this.GroupRegEx).Success)
continue;
var SecurityGroup = new cLiamAdGroup(this, (cSecurityGroupResult)Entry.Value);
SecurityGroups.Add(SecurityGroup);
}
return SecurityGroups;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public int getDepth(string path)
{
return getDepth(this.RootPath, path);
}
public static int getDepth(DirectoryInfo root, DirectoryInfo folder)
{
var rootDepth = root.FullName.TrimEnd(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar).Length;
var folderDepth = folder.FullName.TrimEnd(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar).Length;
return folderDepth - rootDepth;
}
public static int getDepth(string root, string folder)
{
return getDepth(new DirectoryInfo(root), new DirectoryInfo(folder));
}
public override string GetLastErrorMessage()
{
throw new NotImplementedException();
}
}
public class cLiamNtfsShare : cLiamDataAreaBase
{
public new readonly cLiamProviderNtfs Provider = null;
private readonly cNtfsResultBase Share = null;
public cLiamNtfsShare(cLiamProviderNtfs Provider, cNtfsResultBase Share) :
base(Provider)
{
this.Provider = Provider;
this.Share = Share;
this.DisplayName = Share.Path.Split('\\').Last();
this.TechnicalName = Share.Path;
this.UID = cLiamNtfsFolder.GetUniqueDataAreaID(Share.Path);
this.Level = Share.Level;
this.DataType = eLiamDataAreaTypes.NtfsShare;
this.SupportsOwners = false;
this.SupportsPermissions = false;
}
internal async Task<List<cLiamDataAreaBase>> getFolders()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
var RetVal = new List<cLiamDataAreaBase>(0);
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
var RetVal = new List<cLiamDataAreaBase>();
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
}
public class cLiamAdGroup : cLiamDataAreaBase
{
public new readonly cLiamProviderNtfs Provider = null;
public readonly string dn = null;
public readonly string scope = null;
public override Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
throw new NotImplementedException();
}
public cLiamAdGroup(cLiamProviderNtfs Provider, cSecurityGroupResult secGroup) : base(Provider)
{
this.UID = secGroup.ID;
this.TechnicalName = secGroup.DisplayName;
this.Provider = Provider;
this.dn = secGroup.Path;
this.scope = secGroup.Scope.ToString();
}
}
public class cLiamNtfsFolder : cLiamDataAreaBase
{
public new readonly cLiamProviderNtfs Provider = null;
public readonly cLiamNtfsShare Share = null;
public readonly cLiamNtfsFolder NtfsRootFolder = null;
public string OwnerGroupIdentifier = "S-1-0-0";
public string WriteGroupIdentifier = "S-1-0-0";
public string ReadGroupIdentifier = "S-1-0-0";
public string TraverseGroupIdentifier = "S-1-0-0";
public cLiamNtfsFolder(cLiamProviderNtfs Provider, cLiamNtfsShare share, cLiamNtfsFolder ntfsRootFolder, cNtfsResultFolder NtfsFolder) : base(Provider)
{
var ntfsParent = NtfsFolder.Parent;
this.Provider = Provider;
this.NtfsRootFolder = ntfsRootFolder;
this.Share = share;
this.TechnicalName = NtfsFolder.Path;
this.UID =GetUniqueDataAreaID(NtfsFolder.Path);
this.DisplayName = new DirectoryInfo(NtfsFolder.Path).Name;
this.Level = NtfsFolder.Level;
this.DataType = eLiamDataAreaTypes.NtfsFolder;
this.SupportsPermissions = true;
this.CreatedDate = NtfsFolder.CreatedDate;
if (ntfsParent != null)
{
this.ParentUID = GetUniqueDataAreaID(ntfsParent.Path);
}
else if (this.Level == 1)
{
this.ParentUID = GetUniqueDataAreaID(this.Provider.RootPath);
}
assignPermissionGroups(Provider, NtfsFolder);
}
public override async Task<List<cLiamUserInfo>> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
return await GetMembersAsync(true);
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
private async Task<List<cLiamUserInfo>> GetMembersAsync(bool owners)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var AD = this.Provider?.activeDirectoryBase;
if (AD == null)
{
LogEntry($"Could not get ad class from Provider for folder '{this.TechnicalName}'", LogLevels.Warning);
return null;
}
cADCollectionBase lstMembers;
this.OwnerGroupIdentifier = this.OwnerRef ?? this.OwnerGroupIdentifier;
if (owners && !String.IsNullOrEmpty(this.OwnerGroupIdentifier))
lstMembers = await AD.GetMembersAsync(this.OwnerGroupIdentifier);
else
lstMembers = null;
if (lstMembers == null)
{
LogEntry($"Could not get owner list for folder '{this.TechnicalName}'", LogLevels.Warning);
return null;
}
var RetVal = new List<cLiamUserInfo>(lstMembers.Count);
LogEntry($"Owners for folder found: {lstMembers.Count}", LogLevels.Debug);
foreach (var MemberEntry in lstMembers.Values)
{
var User = new cLiamUserInfo()
{
DisplayName = MemberEntry.DisplayName,
UserPrincipalName = (MemberEntry as cADUserResult).UserPrincipalName,
SID = MemberEntry.ID
};
RetVal.Add(User);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
private async void assignPermissionGroups(cLiamProviderNtfs Provider, cNtfsResultFolder NtfsFolder)
{
var ACLs = Provider.activeDirectoryBase.GetAccessControlList(NtfsFolder.Path);
var ownerNamingConvention = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Owner && (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGP && i.Scope == eLiamAccessRoleScopes.Global || Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP && i.Scope == eLiamAccessRoleScopes.DomainLocal));
var writeNamingConvention = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Write && (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGP && i.Scope == eLiamAccessRoleScopes.Global || Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP && i.Scope == eLiamAccessRoleScopes.DomainLocal));
var readNamingConvention = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Read && (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGP && i.Scope == eLiamAccessRoleScopes.Global || Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP && i.Scope == eLiamAccessRoleScopes.DomainLocal));
var traverseNamingConvention = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Traverse);
foreach (FileSystemAccessRule rule in ACLs)
{
//skip ACLs for user "everyone"
if (rule.IdentityReference.Value == "S-1-1-0")
continue;
GroupPrincipal grp = GroupPrincipal.FindByIdentity(Provider.activeDirectoryBase.adContext, IdentityType.Sid, rule.IdentityReference.Value);
if (grp != null)
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Try matching: {grp.Name}");
if (Regex.IsMatch(grp.SamAccountName, ownerNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
this.OwnerGroupIdentifier = rule.IdentityReference.Value;
if (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP)
{
var ldapFilter = String.Format("memberOf={0}", grp.DistinguishedName);
var res = await Provider.activeDirectoryBase.RequestSecurityGroupsListAsync(ldapFilter);
var ownerNamingConventionGlobal = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Owner && i.Scope == eLiamAccessRoleScopes.Global);
foreach (var memberItem in res)
{
var SecurityGroup = new cLiamAdGroup(this.Provider, (cSecurityGroupResult)memberItem.Value);
if (Regex.IsMatch( SecurityGroup.TechnicalName,ownerNamingConventionGlobal.Wildcard, RegexOptions.IgnoreCase))
this.OwnerGroupIdentifier = SecurityGroup.UID;
}
}
}
else if (Regex.IsMatch(grp.SamAccountName, writeNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
WriteGroupIdentifier = rule.IdentityReference.Value;
if (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP)
{
var ldapFilter = String.Format("memberOf={0}", grp.DistinguishedName);
var res = await Provider.activeDirectoryBase.RequestSecurityGroupsListAsync(ldapFilter);
var writeNamingConventionGlobal = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Write && i.Scope == eLiamAccessRoleScopes.Global);
foreach (var memberItem in res)
{
var SecurityGroup = new cLiamAdGroup(this.Provider, (cSecurityGroupResult)memberItem.Value);
if (Regex.IsMatch(SecurityGroup.TechnicalName, writeNamingConventionGlobal.Wildcard, RegexOptions.IgnoreCase))
this.WriteGroupIdentifier = SecurityGroup.UID;
}
}
}
else if (Regex.IsMatch(grp.SamAccountName, readNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
ReadGroupIdentifier = rule.IdentityReference.Value;
if (Provider.GroupStrategy == eLiamGroupStrategies.Ntfs_AGDLP)
{
var ldapFilter = String.Format("memberOf={0}", grp.DistinguishedName);
var res = await Provider.activeDirectoryBase.RequestSecurityGroupsListAsync(ldapFilter);
var readNamingConventionGlobal = Provider.NamingConventions.First(i => i.AccessRole == eLiamAccessRoles.Read && i.Scope == eLiamAccessRoleScopes.Global);
foreach (var memberItem in res)
{
var SecurityGroup = new cLiamAdGroup(this.Provider, (cSecurityGroupResult)memberItem.Value);
if (Regex.IsMatch(SecurityGroup.TechnicalName, readNamingConventionGlobal.Wildcard, RegexOptions.IgnoreCase))
this.ReadGroupIdentifier = SecurityGroup.UID;
}
}
}
else if (Regex.IsMatch(grp.SamAccountName, traverseNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
TraverseGroupIdentifier = rule.IdentityReference.Value;
}
else
DefaultLogger.LogEntry(LogLevels.Debug, $"No match for: {grp.Name}");
}
}
}
public static string GetUniqueDataAreaID(string fullPath)
{
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(fullPath)));
hash = hash.ToLower().Replace("-", "");
return hash;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
public string GetUniqueDataAreaID()
{
return GetUniqueDataAreaID(this.TechnicalName);
}
public override async Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = 1)
{
//TODO implement getChildrenAsync
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
var DataAreas = new List<cLiamDataAreaBase>();
return DataAreas;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
}
}

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

78
LiamNtfs/LiamNtfs.csproj Normal file
View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7F3085F7-1B7A-4DB2-B66F-1B69CCB0002F}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LiamNtfs</RootNamespace>
<AssemblyName>LiamNtfs</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>\\srvwsm001.imagoverum.com\c$\Program Files (x86)\Matrix42\Matrix42 Workplace Management\svc\bin\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.DirectoryServices" />
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="C4IT.LIAM.Ntfs.cs" />
<Compile Include="C4IT_IAM_SET\cNetworkConnection.cs" />
<Compile Include="C4IT_IAM_SET\DataArea.cs" />
<Compile Include="C4IT_IAM_SET\DataArea_Enums.cs" />
<Compile Include="C4IT_IAM_SET\DataArea_FileSystem.cs" />
<Compile Include="C4IT_IAM_SET\DataArea_FileSystem_GET.cs" />
<Compile Include="C4IT_IAM_SET\Helper.cs" />
<Compile Include="C4IT_IAM_SET\ResultToken.cs" />
<Compile Include="C4IT_IAM_SET\SecurityGroup.cs" />
<Compile Include="cActiveDirectoryBase.cs" />
<Compile Include="cNtfsBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LiamBaseClasses\LiamBaseClasses.csproj">
<Project>{3531c9e6-cf6e-458e-b604-4a5a8d1c7ab0}</Project>
<Name>LiamBaseClasses</Name>
</ProjectReference>
<ProjectReference Include="..\LiamHelper\LiamHelper.csproj">
<Project>{6b0e73a6-f918-42d5-9525-d59d4d16283d}</Project>
<Name>LiamHelper</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("LiamNtfs")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LiamNtfs")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7f3085f7-1b7a-4db2-b66f-1b69ccb0002f")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,319 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
namespace LiamNtfs
{
public class cActiveDirectoryBase
{
private cNtfsLogonInfo privLogonInfo = null;
public PrincipalContext adContext = null;
public DirectoryEntry directoryEntry = null;
public Exception LastException { get; private set; } = null;
public string LastErrorMessage { get; private set; } = null;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ResetError()
{
LastException = null;
LastErrorMessage = null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetErrorException(string Action, Exception E, LogLevels lev = LogLevels.Error)
{
LastException = E;
LastErrorMessage = Action + ": " + E.Message;
cLogManager.LogEntry(Action, lev);
}
private async Task<bool> privLogonAsync(cNtfsLogonInfo LogonInfo)
{
try
{
//TODO: remove dummy delay?
await Task.Delay(0);
ResetError();
adContext = new PrincipalContext(ContextType.Domain, LogonInfo.Domain, LogonInfo.User, new NetworkCredential("", LogonInfo.UserSecret).Password);
var ldapPath = $"LDAP://{LogonInfo.Domain}/{LogonInfo.TargetGroupPath}";
directoryEntry = new DirectoryEntry
{
Path = ldapPath,
Username = LogonInfo.User,
Password = new NetworkCredential(LogonInfo.User, LogonInfo.UserSecret).Password,
AuthenticationType = AuthenticationTypes.Secure | AuthenticationTypes.Sealing
};
return adContext != null;
}
catch (Exception E)
{
SetErrorException("exception error while ad login", E, LogLevels.Debug);
cLogManager.LogException(E, LogLevels.Debug);
}
return false;
}
private async Task<bool> privRelogon()
{
if (privLogonInfo == null)
return false;
var RetVal = await privLogonAsync(privLogonInfo);
return RetVal;
}
public async Task<bool> LogonAsync(cNtfsLogonInfo LogonInfo)
{
var RetVal = await privLogonAsync(LogonInfo);
if (RetVal == true)
privLogonInfo = LogonInfo;
return RetVal;
}
internal AuthorizationRuleCollection GetAccessControlList(string path)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
DirectoryInfo dADir = new DirectoryInfo(path);
var dAACL = dADir.GetAccessControl();
return dAACL.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier));
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
internal string resolveSid(string sid)
{
try
{
return new System.Security.Principal.SecurityIdentifier(sid).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
}
catch (Exception E)
{
LogException(E);
return null;
}
}
internal async Task<cADCollectionBase> RequestSecurityGroupsListAsync(string groupFilter)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
var Result = privRequestSecurityGroupsListAsync(groupFilter);
if (Result != null)
{
var RetVal = new cADCollectionBase(Result.Count);
foreach (var Entry in Result)
{
var res = new cSecurityGroupResult(Entry);
RetVal.Add(res);
}
return RetVal;
}
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
return null;
}
private List<cSecurityGroupResult> privRequestSecurityGroupsListAsync(string groupFilter = null, string rawLDAPFilter = null)
{
ResetError();
List<cSecurityGroupResult> securityGroups = new List<cSecurityGroupResult>();
try
{
var res = new List<cSecurityGroupResult>();
if (String.IsNullOrEmpty(privLogonInfo.TargetGroupPath) || string.IsNullOrEmpty(groupFilter) && string.IsNullOrEmpty(rawLDAPFilter))
return res;
try
{
var ctx = adContext;
var entry = directoryEntry;
DirectorySearcher dSearch = new DirectorySearcher(entry)
{
Filter = string.IsNullOrEmpty(rawLDAPFilter) ? "(&(" + groupFilter + ")(objectClass=group))" : rawLDAPFilter
};
dSearch.PageSize = 100000;
SearchResultCollection sr = dSearch.FindAll();
if (sr.Count > 0)
{
foreach (SearchResult k in sr)
{
var sid = new SecurityIdentifier(k.Properties["objectSid"][0] as byte[], 0).Value;
var dn = k.Properties["distinguishedname"][0].ToString();
cSecurityGroupResult group = new cSecurityGroupResult()
{
ID = sid,
Path = k.Properties["distinguishedname"][0].ToString(),
DisplayName = k.Properties["Name"][0].ToString(),
Scope = (GroupScope)GroupPrincipal.FindByIdentity(ctx, IdentityType.Sid, sid).GroupScope
};
securityGroups.Add(group);
}
}
}
catch
{
return new List<cSecurityGroupResult>(securityGroups);
}
return new List<cSecurityGroupResult>(securityGroups);
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
public class cADCollectionBase : SortedList<string, cADResultBase>
{
public cADCollectionBase() { }
public cADCollectionBase(int n) : base(n) { }
public void Add(cADResultBase adr)
{
if (!this.ContainsKey(adr.ID))
this.Add(adr.ID, adr);
}
}
public class cSecurityGroupResult : cADResultBase
{
public cSecurityGroupResult() { }
public cSecurityGroupResult(cADResultBase b) : base(b) { }
public GroupScope Scope { get; internal set; }
}
public class cADUserResult : cADResultBase
{
public string GivenName { get; internal set; }
public string SurName { get; internal set; }
public string UserPrincipalName { get; internal set; }
public string Email { get; internal set; }
public cADUserResult() { }
public cADUserResult(cADResultBase b) : base(b) {
}
public cADUserResult(Principal Result) : base(Result)
{
UserPrincipalName = Result.UserPrincipalName;
}
public GroupScope Scope { get; internal set; }
}
public class cADResultBase
{
public string ID { get; set; } = null;
public string DisplayName { get; set; } = null;
public string Path { get; set; } = null;
public cADResultBase()
{ }
public cADResultBase(cADResultBase Result)
{
if (Result == null)
return;
ID = Result.ID;
DisplayName = Result.DisplayName;
Path = Result.Path;
}
public cADResultBase(Principal Result)
{
if (Result == null)
return;
ID = Result.Sid.ToString();
DisplayName = Result.DisplayName;
Path = Result.DistinguishedName;
}
}
internal async Task<cADCollectionBase> GetMembersAsync(string Sid)
{
try
{
await Task.Delay(0);
var Result = privGetMembersAsync(Sid).ToList();
if (Result != null)
{
var RetVal = new cADCollectionBase(Result.Count);
foreach (var Entry in Result)
{
var res = new cADUserResult(Entry);
if (!string.IsNullOrEmpty(res.Path))
RetVal.Add(res);
}
return RetVal;
}
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
private PrincipalSearchResult<Principal> privGetMembersAsync(string sid)
{
try
{
using (var group = GroupPrincipal.FindByIdentity(adContext,sid))
{
if (group == null)
{
return null;
}
else
{
return group.GetMembers(true);
}
}
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
}
}

View File

@@ -0,0 +1,319 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
namespace LiamNtfs
{
public class cActiveDirectoryBase
{
private cNtfsLogonInfo privLogonInfo = null;
public PrincipalContext adContext = null;
public DirectoryEntry directoryEntry = null;
public Exception LastException { get; private set; } = null;
public string LastErrorMessage { get; private set; } = null;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ResetError()
{
LastException = null;
LastErrorMessage = null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetErrorException(string Action, Exception E, LogLevels lev = LogLevels.Error)
{
LastException = E;
LastErrorMessage = Action + ": " + E.Message;
cLogManager.LogEntry(Action, lev);
}
private async Task<bool> privLogonAsync(cNtfsLogonInfo LogonInfo)
{
try
{
//TODO: remove dummy delay?
await Task.Delay(0);
ResetError();
adContext = new PrincipalContext(ContextType.Domain, LogonInfo.Domain, LogonInfo.User, new NetworkCredential("", LogonInfo.UserSecret).Password);
var ldapPath = $"LDAP://{LogonInfo.Domain}/{LogonInfo.TargetGroupPath}";
directoryEntry = new DirectoryEntry
{
Path = ldapPath,
Username = LogonInfo.User,
Password = new NetworkCredential(LogonInfo.User, LogonInfo.UserSecret).Password,
AuthenticationType = AuthenticationTypes.Secure | AuthenticationTypes.Sealing
};
return adContext != null;
}
catch (Exception E)
{
SetErrorException("exception error while ad login", E, LogLevels.Debug);
cLogManager.LogException(E, LogLevels.Debug);
}
return false;
}
private async Task<bool> privRelogon()
{
if (privLogonInfo == null)
return false;
var RetVal = await privLogonAsync(privLogonInfo);
return RetVal;
}
public async Task<bool> LogonAsync(cNtfsLogonInfo LogonInfo)
{
var RetVal = await privLogonAsync(LogonInfo);
if (RetVal == true)
privLogonInfo = LogonInfo;
return RetVal;
}
internal AuthorizationRuleCollection GetAccessControlList(string path)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
DirectoryInfo dADir = new DirectoryInfo(path);
var dAACL = dADir.GetAccessControl();
return dAACL.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier));
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
internal string resolveSid(string sid)
{
try
{
return new System.Security.Principal.SecurityIdentifier(sid).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
}
catch (Exception E)
{
LogException(E);
return null;
}
}
internal async Task<cADCollectionBase> RequestSecurityGroupsListAsync(string groupFilter)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
var Result = privRequestSecurityGroupsListAsync(groupFilter);
if (Result != null)
{
var RetVal = new cADCollectionBase(Result.Count);
foreach (var Entry in Result)
{
var res = new cSecurityGroupResult(Entry);
RetVal.Add(res);
}
return RetVal;
}
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
return null;
}
private List<cSecurityGroupResult> privRequestSecurityGroupsListAsync(string groupFilter = null, string rawLDAPFilter = null)
{
ResetError();
List<cSecurityGroupResult> securityGroups = new List<cSecurityGroupResult>();
try
{
var res = new List<cSecurityGroupResult>();
if (String.IsNullOrEmpty(privLogonInfo.TargetGroupPath) || string.IsNullOrEmpty(groupFilter) && string.IsNullOrEmpty(rawLDAPFilter))
return res;
try
{
var ctx = adContext;
var entry = directoryEntry;
DirectorySearcher dSearch = new DirectorySearcher(entry)
{
Filter = string.IsNullOrEmpty(rawLDAPFilter) ? "(&(" + groupFilter + ")(objectClass=group))" : rawLDAPFilter
};
dSearch.PageSize = 100000;
SearchResultCollection sr = dSearch.FindAll();
if (sr.Count > 0)
{
foreach (SearchResult k in sr)
{
var sid = new SecurityIdentifier(k.Properties["objectSid"][0] as byte[], 0).Value;
var dn = k.Properties["distinguishedname"][0].ToString();
cSecurityGroupResult group = new cSecurityGroupResult()
{
ID = sid,
Path = k.Properties["distinguishedname"][0].ToString(),
DisplayName = k.Properties["Name"][0].ToString(),
Scope = (GroupScope)GroupPrincipal.FindByIdentity(ctx, IdentityType.Sid, sid).GroupScope
};
securityGroups.Add(group);
}
}
}
catch
{
return new List<cSecurityGroupResult>(securityGroups);
}
return new List<cSecurityGroupResult>(securityGroups);
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
public class cADCollectionBase : SortedList<string, cADResultBase>
{
public cADCollectionBase() { }
public cADCollectionBase(int n) : base(n) { }
public void Add(cADResultBase adr)
{
if (!this.ContainsKey(adr.ID))
this.Add(adr.ID, adr);
}
}
public class cSecurityGroupResult : cADResultBase
{
public cSecurityGroupResult() { }
public cSecurityGroupResult(cADResultBase b) : base(b) { }
public GroupScope Scope { get; internal set; }
}
public class cADUserResult : cADResultBase
{
public string GivenName { get; internal set; }
public string SurName { get; internal set; }
public string UserPrincipalName { get; internal set; }
public string Email { get; internal set; }
public cADUserResult() { }
public cADUserResult(cADResultBase b) : base(b) {
}
public cADUserResult(Principal Result) : base(Result)
{
UserPrincipalName = Result.UserPrincipalName;
}
public GroupScope Scope { get; internal set; }
}
public class cADResultBase
{
public string ID { get; set; } = null;
public string DisplayName { get; set; } = null;
public string Path { get; set; } = null;
public cADResultBase()
{ }
public cADResultBase(cADResultBase Result)
{
if (Result == null)
return;
ID = Result.ID;
DisplayName = Result.DisplayName;
Path = Result.Path;
}
public cADResultBase(Principal Result)
{
if (Result == null)
return;
ID = Result.Sid.ToString();
DisplayName = Result.DisplayName;
Path = Result.DistinguishedName;
}
}
internal async Task<cADCollectionBase> GetMembersAsync(string Sid)
{
try
{
await Task.Delay(0);
var Result = privGetMembersAsync(Sid).ToList();
if (Result != null)
{
var RetVal = new cADCollectionBase(Result.Count);
foreach (var Entry in Result)
{
var res = new cADUserResult(Entry);
if (!string.IsNullOrEmpty(res.Path))
RetVal.Add(res);
}
return RetVal;
}
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
private PrincipalSearchResult<Principal> privGetMembersAsync(string sid)
{
try
{
using (var group = GroupPrincipal.FindByIdentity(adContext,sid))
{
if (group == null)
{
return null;
}
else
{
return group.GetMembers(true);
}
}
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
}
}

420
LiamNtfs/cNtfsBase.cs Normal file
View File

@@ -0,0 +1,420 @@
using C4IT.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.DirectoryServices.AccountManagement;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace LiamNtfs
{
public class cNtfsBase
{
private cNtfsLogonInfo privLogonInfo = null;
private int scanningDepth;
public PrincipalContext adContext = null;
public Exception LastException { get; private set; } = null;
public string LastErrorMessage { get; private set; } = null;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ResetError()
{
LastException = null;
LastErrorMessage = null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetErrorException(string Action, Exception E, LogLevels lev = LogLevels.Error)
{
LastException = E;
LastErrorMessage = Action + ": " + E.Message;
cLogManager.LogEntry(Action, lev);
}
private async Task<bool> privLogonAsync(cNtfsLogonInfo LogonInfo)
{
try
{
//TODO: remove dummy delay?
await Task.Delay(0);
ResetError();
var netResource = new NetResource()
{
Scope = ResourceScope.GlobalNetwork,
ResourceType = ResourceType.Disk,
DisplayType = ResourceDisplaytype.Share,
RemoteName = LogonInfo.TargetNetworkName
};
var result = WNetAddConnection2(
netResource,
LogonInfo.UserSecret,
LogonInfo.User,
0);
if(result == 1219)
{
result = WNetCancelConnection2(LogonInfo.TargetNetworkName,0,true);
if (result == 0)
return await privLogonAsync(LogonInfo);
}
if (result != 0)
{
throw new Win32Exception(result);
}
var FSLogon = true;
adContext = new PrincipalContext(ContextType.Domain, LogonInfo.Domain, LogonInfo.User, new NetworkCredential("", LogonInfo.UserSecret).Password);
return FSLogon && adContext != null;
}
catch (Exception E)
{
SetErrorException("exception error while Ntfs login", E, LogLevels.Debug);
cLogManager.LogException(E, LogLevels.Debug);
}
return false;
}
private async Task<bool> privRelogon()
{
if (privLogonInfo == null)
return false;
var RetVal = await privLogonAsync(privLogonInfo);
return RetVal;
}
public async Task<bool> LogonAsync(cNtfsLogonInfo LogonInfo)
{
var RetVal = await privLogonAsync(LogonInfo);
if (RetVal == true)
privLogonInfo = LogonInfo;
return RetVal;
}
[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);
public async Task<cNtfsCollectionBase> RequestFoldersListAsync(string rootPath, int depth)
{
ResetError();
try
{
await Task.Delay(0);
if (depth == 0)
return null;
var Result = privRequestFoldersListAsync(rootPath, depth);
if (Result != null)
{
var RetVal = new cNtfsCollectionBase(Result.Count);
foreach (var Entry in Result)
{
var res = new cNtfsResultFolder((cNtfsResultFolder)Entry);
RetVal.Add(res);
}
return RetVal;
}
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
private List<cNtfsResultBase> privRequestFoldersListAsync(string rootPath, int depth)
{
if (String.IsNullOrEmpty(rootPath))
return new List<cNtfsResultBase>();
scanningDepth = depth;
return privRequestFoldersListAsync(new DirectoryInfo(rootPath), depth);
}
private List<cNtfsResultBase> privRequestFoldersListAsync(DirectoryInfo rootPath, int depth, cNtfsResultFolder parent = null)
{
ResetError();
List<cNtfsResultBase> folders = new List<cNtfsResultBase>();
try
{
var res = new List<cNtfsResultBase>();
if (depth == 0)
return res;
try
{
foreach (var directory in rootPath.GetDirectories())
{
cNtfsResultFolder folder = new cNtfsResultFolder()
{
ID = generateUniquId(directory.FullName),
Path = directory.FullName,
CreatedDate = directory.CreationTimeUtc.ToString("s"),
DisplayName = directory.Name,
Level = scanningDepth - depth+1,
Parent = parent
};
folders.Add(folder);
if (depth > 0)
{
var result = privRequestFoldersListAsync(directory, depth - 1, folder);
folders.AddRange(result);
}
}
}
catch
{
return new List<cNtfsResultBase>(folders);
}
return new List<cNtfsResultBase>(folders);
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
public async Task<cNtfsCollectionBase> RequestFoldersListAsync(cNtfsResultBase folder, cNtfsResultBase parent)
{
ResetError();
try
{
await Task.Delay(0);
var Result = new List<cNtfsResultBase>();
if (Result != null)
{
var RetVal = new cNtfsCollectionBase(Result.Count);
foreach (var Entry in Result)
{
var res = new cNtfsResultFolder((cNtfsResultFolder)Entry);
res.Parent = parent;
RetVal.Add(res);
}
return RetVal;
}
}
catch (Exception E)
{
cLogManager.LogException(E);
}
return null;
}
internal static int getDepth(DirectoryInfo root, DirectoryInfo folder)
{
var rootDepth = root.FullName.TrimEnd(Path.DirectorySeparatorChar).Split(System.IO.Path.DirectorySeparatorChar).Length;
var folderDepth = folder.FullName.TrimEnd(Path.DirectorySeparatorChar).Split(System.IO.Path.DirectorySeparatorChar).Length;
return folderDepth - rootDepth;
}
internal static int getDepth(string root, string folder)
{
return getDepth(new DirectoryInfo(root), new DirectoryInfo(folder));
}
internal static string generateUniquId(string name)
{
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;
}
}
}
public class cNtfsLogonInfo
{
public string Domain;
public string User;
public string UserSecret;
public string TargetNetworkName;
public string TargetGroupPath;
}
public class cNtfsResultBase
{
public string ID { get; set; } = null;
public string DisplayName { get; set; } = null;
public string Path { get; set; } = null;
public int Level { get; set; } = -1;
public cNtfsResultBase()
{ }
public cNtfsResultBase(cNtfsResultBase Result)
{
if (Result == null)
return;
ID = Result.ID;
DisplayName = Result.DisplayName;
Path = Result.Path;
}
}
public class cNtfsResultFolder : cNtfsResultBase
{
public string Description { get; set; } = null;
public string Visibility { get; set; } = null;
public string OwnerADGroup { get; set; } = null;
public string WriteADGroup { get; set; } = null;
public string ReadADGroup { get; set; } = null;
public cNtfsResultBase Parent { get;set;} = null;
public string CreatedDate { get; set; } = DateTime.MinValue.ToString("s");
public cNtfsResultFolder Folders { get; private set; } = null;
public cNtfsResultFolder(cNtfsResultFolder Result) : base(Result)
{
Description = Result.Description;
Visibility = Result.Visibility;
CreatedDate = Result.CreatedDate;
Folders = Result.Folders;
Level = Result.Level;
Parent = Result.Parent;
OwnerADGroup = Result.OwnerADGroup;
WriteADGroup = Result.WriteADGroup;
ReadADGroup = Result.ReadADGroup;
}
public cNtfsResultFolder()
{
}
}
public class cNtfsResultShare : cNtfsResultBase
{
public cNtfsCollectionBase Folders { get; private set; } = null;
public cNtfsResultShare(cNtfsResultBase Result) : base(Result) { }
public cNtfsResultShare()
{
}
public async Task<bool> ResolveFolders(cNtfsBase ntfs)
{
Folders = await ntfs.RequestFoldersListAsync(this.Path, 0);
return Folders != null;
}
}
public class cNtfsCollectionBase : SortedList<string, cNtfsResultBase>
{
public cNtfsCollectionBase() { }
public cNtfsCollectionBase(int n) : base(n) { }
public void Add(cNtfsResultBase Folder)
{
if (!this.ContainsKey(Folder.ID))
this.Add(Folder.ID, Folder);
}
}
public class cFileshareLogonInfo
{
public string Domain;
public string User;
public string UserSecret;
public string TargetNetworkName;
}
[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;
}
}
}

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]

View File

@@ -0,0 +1 @@
5c2919173b43f9b375209e9457f30a5e7741dbf8813f3ad78961e1bea2016ee2

View File

@@ -0,0 +1,13 @@
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Debug\LiamNtfs.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Debug\LiamNtfs.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Debug\LiamBaseClasses.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Debug\LiamHelper.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Debug\Newtonsoft.Json.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Debug\LiamBaseClasses.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Debug\LiamHelper.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Debug\LiamNtfs.csproj.AssemblyReference.cache
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Debug\LiamNtfs.csproj.CoreCompileInputs.cache
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Debug\LiamNtfs.csproj.Up2Date
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Debug\LiamNtfs.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Debug\LiamNtfs.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Debug\Newtonsoft.Json.xml

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]

View File

@@ -0,0 +1 @@
996cedbd3500552bf89c5a6dc16f6a0d3e37959669c87acb96b2754b7fa0435d

View File

@@ -0,0 +1,13 @@
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Release\LiamNtfs.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Release\LiamNtfs.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Release\LiamBaseClasses.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Release\LiamHelper.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Release\Newtonsoft.Json.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Release\LiamBaseClasses.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Release\LiamHelper.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Release\LiamNtfs.csproj.AssemblyReference.cache
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Release\LiamNtfs.csproj.CoreCompileInputs.cache
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Release\LiamNtfs.csproj.Up2Date
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Release\LiamNtfs.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\obj\Release\LiamNtfs.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamNtfs\bin\Release\Newtonsoft.Json.xml

Binary file not shown.

Binary file not shown.