Files
LIAM/LiamNtfs/cActiveDirectoryBase.cs.txt
Meik 3d4f60d83e chore: sync LIAM solution snapshot incl. diagnostics tooling
- update multiple LIAM projects and solution/config files

- add LiamWorkflowDiagnostics app sources and generated outputs

- include current workspace state (dependencies and build outputs)
2026-02-27 09:12:34 +01:00

320 lines
11 KiB
Plaintext

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