-
Notifications
You must be signed in to change notification settings - Fork 55
feat: comprehensive replacement for GetDomain with fallbacks #299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: ldap_beta_fixes
Are you sure you want to change the base?
Changes from all commits
7db7e42
b78b939
78ddc21
0b839f8
2e5c059
d3e697a
6821eb0
5de8170
ca5f73e
a90d8a3
6ba0ef4
9c3f16c
37004c8
7863689
6d2a1a4
f543ceb
04a18f2
9062696
b9920b2
fbd67ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace SharpHoundCommonLib | ||
| { | ||
| /// <summary> | ||
| /// Lightweight, transport-agnostic description of an Active Directory domain populated either | ||
| /// from controlled LDAP queries (honoring <see cref="LdapConfig"/>) or, when explicitly opted in | ||
| /// via <see cref="LdapConfig.AllowFallbackToUncontrolledLdap"/>, from | ||
| /// <c>System.DirectoryServices.ActiveDirectory.Domain.GetDomain</c>. | ||
| /// </summary> | ||
| public sealed class DomainInfo | ||
| { | ||
| /// <summary>Upper-cased DNS name of the domain (e.g. <c>CONTOSO.LOCAL</c>).</summary> | ||
| public string Name { get; } | ||
|
|
||
| /// <summary>Default naming context distinguished name (e.g. <c>DC=contoso,DC=local</c>).</summary> | ||
| public string DistinguishedName { get; } | ||
|
|
||
| /// <summary>Upper-cased DNS name of the forest root domain, when known.</summary> | ||
| public string ForestName { get; } | ||
|
|
||
| /// <summary>Domain SID (S-1-5-21-...) if resolved, otherwise null.</summary> | ||
| public string DomainSid { get; } | ||
|
|
||
| /// <summary>Legacy NetBIOS domain name if resolved from the Partitions container, otherwise null.</summary> | ||
| public string NetBiosName { get; } | ||
|
|
||
| /// <summary>DNS hostname of the PDC FSMO role owner if resolved, otherwise null.</summary> | ||
| public string PrimaryDomainController { get; } | ||
|
|
||
| /// <summary>DNS hostnames of known domain controllers for this domain.</summary> | ||
| public IReadOnlyList<string> DomainControllers { get; } | ||
|
|
||
| public DomainInfo( | ||
| string name = null, | ||
| string distinguishedName = null, | ||
| string forestName = null, | ||
| string domainSid = null, | ||
| string netBiosName = null, | ||
| string primaryDomainController = null, | ||
| IReadOnlyList<string> domainControllers = null) { | ||
| Name = name; | ||
| DistinguishedName = distinguishedName; | ||
| ForestName = forestName; | ||
| DomainSid = domainSid; | ||
| NetBiosName = netBiosName; | ||
| PrimaryDomainController = primaryDomainController; | ||
| DomainControllers = domainControllers ?? Array.Empty<string>(); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -89,6 +89,25 @@ IAsyncEnumerable<Result<string>> RangedRetrieval(string distinguishedName, | |
| /// <returns>True if the domain was found, false if not</returns> | ||
| bool GetDomain(out System.DirectoryServices.ActiveDirectory.Domain domain); | ||
|
|
||
| /// <summary> | ||
| /// Resolves a <see cref="DomainInfo"/> for the specified domain using controlled LDAP queries | ||
| /// that honor the configured <see cref="LdapConfig"/> (server, port, SSL, auth, signing, cert verification). | ||
| /// Falls back to <c>System.DirectoryServices.ActiveDirectory.Domain.GetDomain</c> only when | ||
| /// <see cref="LdapConfig.AllowFallbackToUncontrolledLdap"/> is enabled. | ||
| /// </summary> | ||
| /// <param name="domainName">The domain name to resolve</param> | ||
| /// <returns>A tuple containing success state as well as the populated DomainInfo if successful</returns> | ||
| Task<(bool Success, DomainInfo DomainInfo)> GetDomainInfoAsync(string domainName); | ||
|
|
||
| /// <summary> | ||
| /// Resolves a <see cref="DomainInfo"/> for the user's current domain using controlled LDAP queries | ||
| /// that honor the configured <see cref="LdapConfig"/>. Falls back to | ||
| /// <c>System.DirectoryServices.ActiveDirectory.Domain.GetDomain</c> only when | ||
| /// <see cref="LdapConfig.AllowFallbackToUncontrolledLdap"/> is enabled. | ||
| /// </summary> | ||
| /// <returns>A tuple containing success state as well as the populated DomainInfo if successful</returns> | ||
| Task<(bool Success, DomainInfo DomainInfo)> GetDomainInfoAsync(); | ||
|
Comment on lines
+92
to
+109
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This public interface change is source-breaking. Adding two required members to 🤖 Prompt for AI Agents |
||
|
|
||
| Task<(bool Success, string ForestName)> GetForest(string domain); | ||
| /// <summary> | ||
| /// Attempts to resolve an account name to its corresponding typed principal | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.