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