private string GetDomainController(string server, string domainDns, DsGetDcNameFlags flags, ref DcLocatorMode mode) { string key = BuildDcCacheKey(server, domainDns, flags); DcLocatorMode mode2 = mode; try { if (flags.HasFlag(DsGetDcNameFlags.DS_FORCE_REDISCOVERY)) { return(dcCache.AddOrUpdate( key, a => this.GetDc(server, domainDns, flags, ref mode2), (a, b) => { this.logger.LogTrace("New DC requested"); return this.GetDc(server, domainDns, flags, ref mode2); })); } return(dcCache.GetOrAdd(key, k => this.GetDc(server, domainDns, flags, ref mode2))); } finally { mode = mode2; } }
private static extern int DsGetDcName ( [MarshalAs(UnmanagedType.LPTStr)] string computerName, [MarshalAs(UnmanagedType.LPTStr)] string domainName, [In] int domainGuid, [MarshalAs(UnmanagedType.LPTStr)] string siteName, [MarshalAs(UnmanagedType.U4)] DsGetDcNameFlags flags, out IntPtr pDomainControllerInfo );
private static extern int DsGetDcName(string computerName, string domainName, IntPtr domainGuid, string siteName, DsGetDcNameFlags flags, out IntPtr domainControllerInfo);
public static extern DWORD DsGetDcName(string computerName, string domainName, PGUID domainGuid, string siteName, DsGetDcNameFlags flags, out PDOMAIN_CONTROLLER_INFO dsInfo);
public static extern Win32Error DsGetDcName(string ComputerName, string DomainName, IntPtr DomainGuid, string SiteName, DsGetDcNameFlags Flags, out SafeNetApiBuffer DomainControllerInfo);
public T FindDcAndExecuteWithRetry <T>(string server, string domain, DsGetDcNameFlags flags, DcLocatorMode mode, Func <string, T> action) { int retryCount = 0; Exception lastException = null; HashSet <string> attemptedDCs = new HashSet <string>(StringComparer.OrdinalIgnoreCase); if (domain == null) { domain = Domain.GetComputerDomain().Name; } DcLocatorMode cachedMode = mode; string dc = this.GetDomainController(server, domain, flags, ref cachedMode); while (retryCount < MaxRetry && attemptedDCs.Add(dc)) { //this.logger.LogTrace("Attempting to execute operation in domain {domain} against DC {dc}", domain, dc); try { return(action.Invoke(dc)); } catch (COMException ex) when(ex.HResult == -2147016646) // Server is not operational { lastException = ex; } catch (Win32Exception we) when(we.HResult == -2147467259 || // RPC_NOT_AVAILABLE we.NativeErrorCode == 0x000020E1 || // ERROR_DS_GCVERIFY_ERROR we.NativeErrorCode == 0x0000200E || // ERROR_DS_BUSY we.NativeErrorCode == 0x0000200F || // ERROR_DS_UNAVAILABLE we.NativeErrorCode == 0x0000203A // ERROR_DS_SERVER_DOWN ) { lastException = we; } catch (Exception ex) when(ex.InnerException is Win32Exception we && (we.HResult == -2147467259 || // RPC_NOT_AVAILABLE we.NativeErrorCode == 0x000020E1 || // ERROR_DS_GCVERIFY_ERROR we.NativeErrorCode == 0x0000200E || // ERROR_DS_BUSY we.NativeErrorCode == 0x0000200F || // ERROR_DS_UNAVAILABLE we.NativeErrorCode == 0x0000203A // ERROR_DS_SERVER_DOWN )) { lastException = ex; } this.logger.LogTrace(lastException, "Operation failed in domain {domain} against DC {dc} due to retry-able error", domain, dc); dc = this.GetDomainController(server, domain, flags | DsGetDcNameFlags.DS_FORCE_REDISCOVERY, ref cachedMode); retryCount++; } dcCache.TryRemove(BuildDcCacheKey(server, domain, flags), out _); if (lastException != null) { throw lastException; } else { throw new DirectoryException("Unable to execute command against DC"); } }
public T FindDcAndExecuteWithRetry <T>(string domain, DsGetDcNameFlags flags, Func <string, T> action) { return(this.FindDcAndExecuteWithRetry(null, domain, flags, DcLocatorMode.LocalDcLocator, action)); }
public string GetDc(string server, string domainDns, DsGetDcNameFlags flags, ref DcLocatorMode mode) { string dc; if (server != null) { bool hadNextClosestSite = flags.HasFlag(DsGetDcNameFlags.DS_TRY_NEXTCLOSEST_SITE); if (mode.HasFlag(DcLocatorMode.RemoteDcLocator)) { try { flags |= DsGetDcNameFlags.DS_TRY_NEXTCLOSEST_SITE; this.logger.LogTrace("Remote DCLocator: Finding domain controller for server {server}, domain {domainDns} with flags {flags}", server, domainDns, flags.ToString()); dc = NativeMethods.GetDomainControllerForDnsDomain(server, domainDns, null, flags); this.logger.LogTrace("Remote DCLocator: Found DC {dc} for server {server} in domain {domainDns}, with flags {flags}", dc, server, domainDns, flags.ToString()); return(dc); } catch (DirectoryException dex) //when (dex.InnerException is Win32Exception wex && wex.NativeErrorCode == 1722) { mode &= ~DcLocatorMode.RemoteDcLocator; this.logger.LogWarning(dex, "Could not connect to server {server} to find DC", server); } } if (!hadNextClosestSite) { flags &= ~DsGetDcNameFlags.DS_TRY_NEXTCLOSEST_SITE; } if (mode.HasFlag(DcLocatorMode.SiteLookup)) { this.logger.LogTrace("Manual DCLocator: Finding site for server {server}, domain {domainDns} with flags {flags}", server, domainDns, flags.ToString()); string site = this.GetComputerSiteNameManual(domainDns, server); if (site != null) { try { this.logger.LogTrace("Manual DCLocator: Attempting to find domain controller for site {site}, in domain {domainDns} with flags {flags}", site, domainDns, flags.ToString()); dc = NativeMethods.GetDomainControllerForDnsDomain(null, domainDns, site, flags); this.logger.LogTrace("Manual DCLocator: Found DC {dc} for site {site} in domain {domainDns}, with flags {flags}", dc, site, domainDns, flags.ToString()); return(dc); } catch (DirectoryException dex) when(dex.InnerException is Win32Exception wex && wex.NativeErrorCode == 1355) { mode &= ~DcLocatorMode.SiteLookup; this.logger.LogWarning(dex, "There are no domain controllers in the site {site}", site); } } else { this.logger.LogTrace("Manual DCLocator: No site found for server {server}", server); } } } this.logger.LogTrace("Local DCLocator: Finding domain controller for domain {domainDns} with flags {flags}", domainDns, flags.ToString()); dc = NativeMethods.GetDomainControllerForDnsDomain(null, domainDns, null, flags); this.logger.LogTrace("Local DCLocator: Found DC {dc} for domain {domainDns}, with flags {flags}", dc, domainDns, flags.ToString()); return(dc); }
public string GetDomainController(string server, string domainDns, DsGetDcNameFlags flags) { DcLocatorMode mode = DcLocatorMode.LocalDcLocator; return(this.GetDomainController(null, domainDns, flags, ref mode)); }
private static string BuildDcCacheKey(string server, string domain, DsGetDcNameFlags flags) { return($"{server}{domain}{flags}"); }