Esempio n. 1
0
        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;
            }
        }
Esempio n. 2
0
        private DcLocatorMode GetDcLocatorMode()
        {
            if (this.options.DcLocatorMode == JitDcLocatorMode.Default)
            {
                return(DcLocatorMode.RemoteDcLocator | DcLocatorMode.SiteLookup);
            }

            DcLocatorMode mode = DcLocatorMode.LocalDcLocator;

            if (this.options.DcLocatorMode.HasFlag(JitDcLocatorMode.RemoteDcLocator))
            {
                mode |= DcLocatorMode.RemoteDcLocator;
            }

            if (this.options.DcLocatorMode.HasFlag(JitDcLocatorMode.SiteLookup))
            {
                mode |= DcLocatorMode.SiteLookup;
            }

            return(mode);
        }
Esempio n. 3
0
        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");
            }
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        public string GetDomainController(string server, string domainDns, DsGetDcNameFlags flags)
        {
            DcLocatorMode mode = DcLocatorMode.LocalDcLocator;

            return(this.GetDomainController(null, domainDns, flags, ref mode));
        }
Esempio n. 6
0
        public string GetDomainController(string domainDns, bool forceRediscovery)
        {
            DcLocatorMode mode = DcLocatorMode.LocalDcLocator;

            return(this.GetDomainController(null, domainDns, DsGetDcNameFlags.DS_DIRECTORY_SERVICE_REQUIRED | DsGetDcNameFlags.DS_FORCE_REDISCOVERY, ref mode));
        }
Esempio n. 7
0
        public string GetDomainController(string domainDns)
        {
            DcLocatorMode mode = DcLocatorMode.LocalDcLocator;

            return(this.GetDomainController(null, domainDns, DsGetDcNameFlags.DS_DIRECTORY_SERVICE_REQUIRED, ref mode));
        }