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 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
 );
Esempio n. 3
0
 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 DWORD DsGetDcName(string computerName,
                                        string domainName,
                                        PGUID domainGuid,
                                        string siteName,
                                        DsGetDcNameFlags flags,
                                        out PDOMAIN_CONTROLLER_INFO dsInfo);
Esempio n. 6
0
 public static extern Win32Error DsGetDcName(string ComputerName, string DomainName, IntPtr DomainGuid,
                                             string SiteName, DsGetDcNameFlags Flags, out SafeNetApiBuffer DomainControllerInfo);
Esempio n. 7
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. 8
0
 public T FindDcAndExecuteWithRetry <T>(string domain, DsGetDcNameFlags flags, Func <string, T> action)
 {
     return(this.FindDcAndExecuteWithRetry(null, domain, flags, DcLocatorMode.LocalDcLocator, action));
 }
Esempio n. 9
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. 10
0
        public string GetDomainController(string server, string domainDns, DsGetDcNameFlags flags)
        {
            DcLocatorMode mode = DcLocatorMode.LocalDcLocator;

            return(this.GetDomainController(null, domainDns, flags, ref mode));
        }
Esempio n. 11
0
 private static string BuildDcCacheKey(string server, string domain, DsGetDcNameFlags flags)
 {
     return($"{server}{domain}{flags}");
 }