Пример #1
0
        protected void PopulateDomainNamingContexts(string partitionFqdn)
        {
            TopologyProvider.EnforceNonEmptyPartition(partitionFqdn);
            ADServerInfo defaultServerInfo = this.GetDefaultServerInfo(partitionFqdn);

            if (string.IsNullOrEmpty(defaultServerInfo.WritableNC) || string.IsNullOrEmpty(defaultServerInfo.RootDomainNC))
            {
                PooledLdapConnection pooledLdapConnection = LdapConnectionPool.CreateOneTimeConnection(null, defaultServerInfo, LocatorFlags.None);
                try
                {
                    if (string.IsNullOrEmpty(pooledLdapConnection.ADServerInfo.WritableNC) && !TopologyProvider.IsAdamTopology())
                    {
                        this.LogRootDSEReadFailureAndThrow("domainNamingContext", defaultServerInfo.FqdnPlusPort);
                    }
                    this.domainNCs[partitionFqdn] = ADObjectId.ParseExtendedDN(pooledLdapConnection.ADServerInfo.WritableNC);
                    if (string.IsNullOrEmpty(pooledLdapConnection.ADServerInfo.RootDomainNC) && !TopologyProvider.IsAdamTopology())
                    {
                        this.LogRootDSEReadFailureAndThrow("rootDomainNamingContext", defaultServerInfo.FqdnPlusPort);
                    }
                    this.rootDomainNCs[partitionFqdn] = ADObjectId.ParseExtendedDN(pooledLdapConnection.ADServerInfo.RootDomainNC);
                    return;
                }
                finally
                {
                    pooledLdapConnection.ReturnToPool();
                }
            }
            this.domainNCs[partitionFqdn]     = ADObjectId.ParseExtendedDN(defaultServerInfo.WritableNC);
            this.rootDomainNCs[partitionFqdn] = ADObjectId.ParseExtendedDN(defaultServerInfo.RootDomainNC);
        }
Пример #2
0
        public NspiRpcClientConnection GetNspiRpcClientConnection()
        {
            string text = base.ServerSettings.PreferredGlobalCatalog(base.SessionSettings.GetAccountOrResourceForestFqdn());
            string domainController;

            if (!string.IsNullOrEmpty(text))
            {
                domainController = text;
            }
            else
            {
                PooledLdapConnection pooledLdapConnection = null;
                try
                {
                    pooledLdapConnection = ConnectionPoolManager.GetConnection(ConnectionType.GlobalCatalog, base.SessionSettings.GetAccountOrResourceForestFqdn());
                    domainController     = pooledLdapConnection.ServerName;
                }
                finally
                {
                    if (pooledLdapConnection != null)
                    {
                        pooledLdapConnection.ReturnToPool();
                    }
                }
            }
            return(NspiRpcClientConnection.GetNspiRpcClientConnection(domainController));
        }
        protected virtual void UpdateRecipientSyncStateValueInAD(RecipientSyncOperation operation)
        {
            if (this.updateConnection == null)
            {
                ADObjectId        rootId            = null;
                ADOperationResult adoperationResult = ADNotificationAdapter.TryRunADOperation(delegate()
                {
                    PooledLdapConnection readConnection = this.ConfigSession.GetReadConnection(this.sourceConnection.Fqdn, ref rootId);
                    this.updateConnection = new Connection(readConnection, EdgeSyncSvc.EdgeSync.AppConfig);
                }, 3);
                if (!adoperationResult.Succeeded)
                {
                    ExTraceGlobals.TargetConnectionTracer.TraceError <string>((long)this.GetHashCode(), "Failed to get AD connection to update SyncState because of {0}", adoperationResult.Exception.Message);
                    throw new ExDirectoryException("Failed to get AD connection to update SyncState", adoperationResult.Exception);
                }
            }
            byte[]        array   = RecipientSyncState.SerializeRecipientSyncState(operation.RecipientSyncState);
            ModifyRequest request = new ModifyRequest(operation.DistinguishedName, DirectoryAttributeOperation.Replace, "msExchExternalSyncState", new object[]
            {
                array
            });

            this.updateConnection.SendRequest(request);
            ExTraceGlobals.TargetConnectionTracer.TraceDebug <string>((long)this.GetHashCode(), "Successfully updated SyncState in AD for {0}", operation.DistinguishedName);
            base.LogSession.LogEvent(EdgeSyncLoggingLevel.Low, EdgeSyncEvent.TargetConnection, operation.DistinguishedName, "Successfully synced to MSERV and updated SyncState");
        }
        // Token: 0x06000595 RID: 1429 RVA: 0x0001EE98 File Offset: 0x0001D098
        internal static ADServerInfo GetServerInfoFromFqdn(string fqdn, ConnectionType connectionType)
        {
            PooledLdapConnection pooledLdapConnection = null;
            string       empty = string.Empty;
            ADServerInfo adserverInfo;

            try
            {
                string partitionFqdn = Globals.IsMicrosoftHostedOnly ? ADServerSettings.GetPartitionFqdnFromADServerFqdn(fqdn) : TopologyProvider.LocalForestFqdn;
                pooledLdapConnection = ConnectionPoolManager.GetConnection(connectionType, partitionFqdn, null, fqdn, (connectionType == ConnectionType.GlobalCatalog) ? TopologyProvider.GetInstance().DefaultGCPort : TopologyProvider.GetInstance().DefaultDCPort);
                string writableNC = pooledLdapConnection.ADServerInfo.WritableNC;
                if (!pooledLdapConnection.SessionOptions.HostName.Equals(fqdn, StringComparison.OrdinalIgnoreCase))
                {
                    throw new ADOperationException(DirectoryStrings.ErrorInvalidServerFqdn(fqdn, pooledLdapConnection.SessionOptions.HostName));
                }
                adserverInfo = pooledLdapConnection.ADServerInfo;
            }
            finally
            {
                if (pooledLdapConnection != null)
                {
                    pooledLdapConnection.ReturnToPool();
                }
            }
            return(adserverInfo);
        }
Пример #5
0
        protected void PopulateConfigNamingContexts(string partitionFqdn)
        {
            TopologyProvider.EnforceNonEmptyPartition(partitionFqdn);
            ADServerInfo configDCInfo = this.GetConfigDCInfo(partitionFqdn, true);

            if (string.IsNullOrEmpty(configDCInfo.ConfigNC) || string.IsNullOrEmpty(configDCInfo.SchemaNC))
            {
                PooledLdapConnection pooledLdapConnection = LdapConnectionPool.CreateOneTimeConnection(null, configDCInfo, LocatorFlags.None);
                try
                {
                    if (string.IsNullOrEmpty(pooledLdapConnection.ADServerInfo.ConfigNC))
                    {
                        this.LogRootDSEReadFailureAndThrow("configurationNamingContext", configDCInfo.FqdnPlusPort);
                    }
                    this.configNCs[partitionFqdn] = ADObjectId.ParseExtendedDN(pooledLdapConnection.ADServerInfo.ConfigNC);
                    if (string.IsNullOrEmpty(pooledLdapConnection.ADServerInfo.SchemaNC))
                    {
                        this.LogRootDSEReadFailureAndThrow("schemaNamingContext", configDCInfo.FqdnPlusPort);
                    }
                    this.schemaNCs[partitionFqdn] = ADObjectId.ParseExtendedDN(pooledLdapConnection.ADServerInfo.SchemaNC);
                    return;
                }
                finally
                {
                    pooledLdapConnection.ReturnToPool();
                }
            }
            this.configNCs[partitionFqdn] = ADObjectId.ParseExtendedDN(configDCInfo.ConfigNC);
            this.schemaNCs[partitionFqdn] = ADObjectId.ParseExtendedDN(configDCInfo.SchemaNC);
        }
Пример #6
0
 public Connection(PooledLdapConnection connection, EdgeSyncAppConfig appConfig)
 {
     if (appConfig == null)
     {
         throw new ArgumentNullException("appConfig");
     }
     this.connection = connection;
     this.appConfig  = appConfig;
 }
        // Token: 0x06000DCB RID: 3531 RVA: 0x0003F978 File Offset: 0x0003DB78
        internal static PooledLdapConnection CreateOneTimeConnection(NetworkCredential networkCredential, ADServerInfo serverInfo, LocatorFlags connectionFlags = LocatorFlags.None)
        {
            string arg = "<null>\\<null>";

            if (networkCredential != null)
            {
                arg = networkCredential.Domain + "\\" + networkCredential.UserName;
            }
            else
            {
                using (WindowsIdentity current = WindowsIdentity.GetCurrent())
                {
                    if (current.ImpersonationLevel == TokenImpersonationLevel.Delegation || current.ImpersonationLevel == TokenImpersonationLevel.Impersonation)
                    {
                        arg = current.Name;
                    }
                }
            }
            ExTraceGlobals.ConnectionTracer.TraceDebug <string, string>(0L, "LdapConnectionPool::CreateOneTimeConnection - opening new ONE-TIME PooledLdapConnection to {0} as {1}", serverInfo.FqdnPlusPort, arg);
            ADProviderPerf.AddDCInstance(serverInfo.Fqdn);
            ADServerRole         role = (serverInfo.Port == 389) ? ADServerRole.DomainController : ADServerRole.GlobalCatalog;
            bool                 flag = false;
            PooledLdapConnection pooledLdapConnection = null;
            PooledLdapConnection result;

            try
            {
                pooledLdapConnection = new PooledLdapConnection(serverInfo, role, false, networkCredential);
                if (LocatorFlags.None != connectionFlags)
                {
                    pooledLdapConnection.SessionOptions.LocatorFlag |= connectionFlags;
                }
                Globals.LogEvent(DirectoryEventLogConstants.Tuple_DSC_EVENT_NEW_CONNECTION, null, new object[]
                {
                    serverInfo.Fqdn,
                    serverInfo.Port,
                    string.Empty
                });
                pooledLdapConnection.BindWithRetry(3);
                pooledLdapConnection.SetNamingContexts();
                flag   = true;
                result = pooledLdapConnection;
            }
            catch (LdapException ex)
            {
                throw new ADTransientException(DirectoryStrings.ExceptionCreateLdapConnection(serverInfo.FqdnPlusPort, ex.Message, (uint)ex.ErrorCode), ex);
            }
            finally
            {
                if (!flag && pooledLdapConnection != null)
                {
                    pooledLdapConnection.ReturnToPool();
                }
            }
            return(result);
        }
        private ADServerInfo GetDirectoryServer(string partitionFqdn, ADRole role)
        {
            ExTraceGlobals.TopologyProviderTracer.TraceDebug <string, ADRole>((long)this.GetHashCode(), "GetDirectoryServer PartitionFqdn {0}. Role {1}", partitionFqdn, role);
            LocatorFlags locatorFlags = LocatorFlags.ForceRediscovery | LocatorFlags.DirectoryServicesRequired | LocatorFlags.ReturnDnsName;
            string       text         = partitionFqdn;

            if (ADRole.GlobalCatalog == role)
            {
                ADObjectId rootDomainNamingContext = base.GetRootDomainNamingContext(partitionFqdn);
                ADObjectId domainNamingContext     = base.GetDomainNamingContext(partitionFqdn);
                if (!rootDomainNamingContext.DistinguishedName.Equals(domainNamingContext.DistinguishedName, StringComparison.OrdinalIgnoreCase))
                {
                    text = NativeHelpers.CanonicalNameFromDistinguishedName(rootDomainNamingContext.DistinguishedName);
                }
                locatorFlags |= LocatorFlags.GCRequired;
            }
            ExTraceGlobals.TopologyProviderTracer.TraceDebug <string, string, LocatorFlags>((long)this.GetHashCode(), "GetDirectoryServer. Partition Fqdn {0} Parent Domain {1}. Flags {2}", partitionFqdn, text, locatorFlags);
            ADServerInfo         serverInfo           = new ADServerInfo(null, text, (ADRole.GlobalCatalog == role) ? 3268 : 389, null, 100, AuthType.Kerberos, true);
            PooledLdapConnection pooledLdapConnection = null;
            ADServerInfo         adserverInfo         = null;

            try
            {
                pooledLdapConnection = LdapConnectionPool.CreateOneTimeConnection(null, serverInfo, locatorFlags);
                if (!string.IsNullOrEmpty(pooledLdapConnection.SessionOptions.HostName))
                {
                    adserverInfo = pooledLdapConnection.ADServerInfo.CloneWithServerNameResolved(pooledLdapConnection.SessionOptions.HostName);
                }
                ExTraceGlobals.TopologyProviderTracer.TraceDebug <string, string>((long)this.GetHashCode(), "GetDirectoryServer. Partition Fqdn {0}. Server {1}", partitionFqdn, pooledLdapConnection.SessionOptions.HostName ?? string.Empty);
            }
            finally
            {
                if (pooledLdapConnection != null)
                {
                    pooledLdapConnection.ReturnToPool();
                }
            }
            string          text2;
            LocalizedString localizedString;

            if (adserverInfo != null && SuitabilityVerifier.IsServerSuitableIgnoreExceptions(adserverInfo.Fqdn, ADRole.GlobalCatalog == role, null, out text2, out localizedString))
            {
                return(adserverInfo);
            }
            return(LdapTopologyProvider.FindDirectoryServerForForestOrDomain(text, null, ADRole.GlobalCatalog == role));
        }
Пример #9
0
        private static ADObjectId GetNamingContext(ADSession.ADNamingContext context, string domainController, NetworkCredential credential)
        {
            PooledLdapConnection pooledLdapConnection = null;
            ADObjectId           result = null;

            try
            {
                string partitionFqdn = Globals.IsMicrosoftHostedOnly ? ADServerSettings.GetPartitionFqdnFromADServerFqdn(domainController) : TopologyProvider.LocalForestFqdn;
                pooledLdapConnection = ConnectionPoolManager.GetConnection(ConnectionType.DomainController, partitionFqdn, credential, domainController, 389);
                switch (context)
                {
                case ADSession.ADNamingContext.RootDomain:
                    result = ADObjectId.ParseExtendedDN(pooledLdapConnection.ADServerInfo.RootDomainNC);
                    break;

                case ADSession.ADNamingContext.Domain:
                    result = ADObjectId.ParseExtendedDN(pooledLdapConnection.ADServerInfo.WritableNC);
                    break;

                case (ADSession.ADNamingContext) 3:
                    break;

                case ADSession.ADNamingContext.Config:
                    result = ADObjectId.ParseExtendedDN(pooledLdapConnection.ADServerInfo.ConfigNC);
                    break;

                default:
                    if (context == ADSession.ADNamingContext.Schema)
                    {
                        result = ADObjectId.ParseExtendedDN(pooledLdapConnection.ADServerInfo.SchemaNC);
                    }
                    break;
                }
            }
            finally
            {
                if (pooledLdapConnection != null)
                {
                    pooledLdapConnection.ReturnToPool();
                }
            }
            return(result);
        }
Пример #10
0
        public virtual EhfADAdapter GetConfigADAdapter(EdgeSyncDiag diagSession, out Exception exception)
        {
            exception = null;
            IConfigurationSession configSession        = DirectorySessionFactory.Default.GetTenantOrTopologyConfigurationSession(this.connection.Fqdn, true, ConsistencyMode.IgnoreInvalid, ADSessionSettings.FromRootOrgScopeSet(), 339, "GetConfigADAdapter", "f:\\15.00.1497\\sources\\dev\\EdgeSync\\src\\EHF\\EhfADAdapter.cs");
            ADObjectId            rootId               = null;
            PooledLdapConnection  pooledLdapConnection = null;
            ADOperationResult     adoperationResult    = ADNotificationAdapter.TryRunADOperation(delegate()
            {
                pooledLdapConnection = configSession.GetReadConnection(configSession.DomainController, ref rootId);
            }, 3);

            if (adoperationResult.Succeeded)
            {
                EhfADAdapter ehfADAdapter = new EhfADAdapter();
                ehfADAdapter.SetConnection(new Connection(pooledLdapConnection));
                return(ehfADAdapter);
            }
            exception = adoperationResult.Exception;
            return(null);
        }
Пример #11
0
        internal static string GetCurrentServerFromSession(IDirectorySession session)
        {
            string text = session.ServerSettings.PreferredGlobalCatalog(session.SessionSettings.GetAccountOrResourceForestFqdn());

            if (string.IsNullOrEmpty(text))
            {
                ADObjectId           adobjectId           = null;
                PooledLdapConnection pooledLdapConnection = null;
                try
                {
                    pooledLdapConnection = session.GetReadConnection(null, ref adobjectId);
                    text = pooledLdapConnection.ServerName;
                }
                finally
                {
                    if (pooledLdapConnection != null)
                    {
                        pooledLdapConnection.ReturnToPool();
                    }
                }
            }
            return(text);
        }
Пример #12
0
        protected SearchResultEntryCollection GetNextResultCollection(Type controlType, out DirectoryControl responseControl)
        {
            SearchRequest searchRequest = new SearchRequest(null, this.ldapFilter, (SearchScope)this.scope, this.ldapAttributes);

            searchRequest.Controls.AddRange(this.directoryControls);
            searchRequest.SizeLimit = this.SizeLimit;
            if (this.session.ServerTimeout != null)
            {
                searchRequest.TimeLimit = this.session.ServerTimeout.Value;
            }
            SearchResponse searchResponse = null;

            responseControl = null;
            RetryManager retryManager = new RetryManager();
            ADObjectId   adobjectId   = this.rootId;
            bool         flag         = !this.session.SessionSettings.IncludeSoftDeletedObjects && !this.session.SessionSettings.IncludeInactiveMailbox && this.session.EnforceContainerizedScoping;

            for (;;)
            {
                PooledLdapConnection readConnection = this.session.GetReadConnection(this.preferredServerName, null, ref adobjectId, this.ScopeDeterminingObject);
                Guid serviceProviderRequestId       = Guid.Empty;
                try
                {
                    try
                    {
                        if (this.useNullRoot)
                        {
                            searchRequest.DistinguishedName = null;
                        }
                        else
                        {
                            searchRequest.DistinguishedName = adobjectId.ToDNString();
                            if (flag && searchRequest.Scope == SearchScope.Subtree)
                            {
                                ADObjectId domainId = adobjectId.DomainId;
                                if (domainId != null)
                                {
                                    ADObjectId childId = domainId.GetChildId("OU", "Microsoft Exchange Hosted Organizations");
                                    ADObjectId parent  = adobjectId.Parent;
                                    if (childId != null && parent != null && ADObjectId.Equals(childId, parent))
                                    {
                                        searchRequest.Scope = SearchScope.OneLevel;
                                    }
                                }
                            }
                        }
                        if (TopologyProvider.IsAdamTopology() && string.IsNullOrEmpty(searchRequest.DistinguishedName))
                        {
                            searchRequest.Controls.Add(new SearchOptionsControl(SearchOption.PhantomRoot));
                        }
                        ExTraceGlobals.ADFindTracer.TraceDebug((long)this.GetHashCode(), "ADGenericReader::GetNextResultCollection({0}) using {1} - LDAP search from {2}, scope {3}, filter {4}", new object[]
                        {
                            controlType.Name,
                            readConnection.ADServerInfo.FqdnPlusPort,
                            searchRequest.DistinguishedName,
                            (int)searchRequest.Scope,
                            searchRequest.Filter
                        });
                        serviceProviderRequestId = Trace.TraceCasStart(CasTraceEventType.ActiveDirectory);
                        searchResponse           = (SearchResponse)readConnection.SendRequest(searchRequest, LdapOperation.Search, null, this.session.ActivityScope, this.session.CallerInfo);
                        this.preferredServerName = readConnection.ServerName;
                        this.session.UpdateServerSettings(readConnection);
                        break;
                    }
                    catch (DirectoryException de)
                    {
                        if (this.customExceptionHandler != null)
                        {
                            this.customExceptionHandler(de);
                        }
                        if (readConnection.IsResultCode(de, ResultCode.NoSuchObject))
                        {
                            ExTraceGlobals.ADFindTracer.TraceWarning <string, object>((long)this.GetHashCode(), "NoSuchObject caught when searching from {0} with filter {1}", searchRequest.DistinguishedName, searchRequest.Filter);
                            return(null);
                        }
                        if (readConnection.IsResultCode(de, ResultCode.VirtualListViewError) && this.lcid != LcidMapper.DefaultLcid)
                        {
                            ExTraceGlobals.ADFindTracer.TraceWarning <int, int>((long)this.GetHashCode(), "VirtualListView error caught when performing a VLV lookup using LCID 0x{0:X}. Falling back to US English 0x{1:X}", this.lcid, LcidMapper.DefaultLcid);
                            this.RefreshSortControlWithDefaultLCID(searchRequest);
                        }
                        else
                        {
                            retryManager.Tried(readConnection.ServerName);
                            this.session.AnalyzeDirectoryError(readConnection, searchRequest, de, retryManager.TotalRetries, retryManager[readConnection.ServerName]);
                        }
                    }
                    continue;
                }
                finally
                {
                    bool isSnapshotInProgress = PerformanceContext.Current.IsSnapshotInProgress;
                    bool flag2 = ETWTrace.ShouldTraceCasStop(serviceProviderRequestId);
                    if (isSnapshotInProgress || flag2)
                    {
                        string text = string.Format(CultureInfo.InvariantCulture, "scope: {0}, filter: {1}", new object[]
                        {
                            searchRequest.Scope,
                            searchRequest.Filter
                        });
                        if (isSnapshotInProgress)
                        {
                            PerformanceContext.Current.AppendToOperations(text);
                        }
                        if (flag2)
                        {
                            Trace.TraceCasStop(CasTraceEventType.ActiveDirectory, serviceProviderRequestId, 0, 0, readConnection.ADServerInfo.FqdnPlusPort, searchRequest.DistinguishedName, "ADGenericReader::GetNextResultCollection", text, string.Empty);
                        }
                    }
                    readConnection.ReturnToPool();
                }
                break;
            }
            responseControl = this.FindControlInCollection(searchResponse.Controls, controlType);
            return(searchResponse.Entries);
        }
Пример #13
0
 void IDirectorySession.UpdateServerSettings(PooledLdapConnection connection)
 {
     FfoDirectorySession.LogNotSupportedInFFO(null);
 }
Пример #14
0
 void IDirectorySession.AnalyzeDirectoryError(PooledLdapConnection connection, DirectoryRequest request, DirectoryException de, int totalRetries, int retriesOnServer)
 {
     FfoDirectorySession.LogNotSupportedInFFO(null);
 }
        void IDirectorySession.UpdateServerSettings(PooledLdapConnection connection)
        {
            TSession session = this.GetSession();

            session.UpdateServerSettings(connection);
        }
        void IDirectorySession.AnalyzeDirectoryError(PooledLdapConnection connection, DirectoryRequest request, DirectoryException de, int totalRetries, int retriesOnServer)
        {
            TSession session = this.GetSession();

            session.AnalyzeDirectoryError(connection, request, de, totalRetries, retriesOnServer);
        }
Пример #17
0
 public Connection(PooledLdapConnection connection)
 {
     this.connection = connection;
 }
        // Token: 0x06000DBA RID: 3514 RVA: 0x0003E8EC File Offset: 0x0003CAEC
        private void CheckBadConnections()
        {
            bool flag = false;

            try
            {
                this.poolLock.AcquireReaderLock(-1);
                if (!this.isActive)
                {
                    ExTraceGlobals.GetConnectionTracer.TraceWarning((long)this.GetHashCode(), "Pool is not active, skipping CheckBadConnections (R)");
                    return;
                }
                foreach (ConnectionInfo connectionInfo in this.connectionInfos)
                {
                    if (connectionInfo.ConnectionState == ConnectionState.Connected)
                    {
                        PooledLdapConnection pooledLdapConnection = connectionInfo.PooledLdapConnection;
                        if (!pooledLdapConnection.IsUp && !pooledLdapConnection.IsFatalError)
                        {
                            pooledLdapConnection.RetryDownConnection();
                        }
                        if (pooledLdapConnection.IsFatalError)
                        {
                            flag = true;
                        }
                    }
                }
            }
            finally
            {
                try
                {
                    this.poolLock.ReleaseReaderLock();
                }
                catch (ApplicationException)
                {
                }
            }
            if (flag)
            {
                try
                {
                    this.poolLock.AcquireWriterLock(-1);
                    if (!this.isActive)
                    {
                        ExTraceGlobals.GetConnectionTracer.TraceWarning((long)this.GetHashCode(), "Pool is not active, skipping CheckBadConnections (W)");
                        return;
                    }
                    foreach (ConnectionInfo connectionInfo2 in this.connectionInfos)
                    {
                        if (connectionInfo2.ConnectionState == ConnectionState.Connected)
                        {
                            PooledLdapConnection pooledLdapConnection2 = connectionInfo2.PooledLdapConnection;
                            if (pooledLdapConnection2.IsFatalError)
                            {
                                connectionInfo2.MakeEmpty();
                                Interlocked.Decrement(ref this.connectedCount);
                            }
                        }
                    }
                }
                finally
                {
                    try
                    {
                        this.poolLock.ReleaseWriterLock();
                    }
                    catch (ApplicationException)
                    {
                    }
                }
                return;
            }
        }
        // Token: 0x06000DC9 RID: 3529 RVA: 0x0003F560 File Offset: 0x0003D760
        internal PooledLdapConnection GetConnection(ADObjectId domain, string serverName, int port, ref bool newPoolAvailable, ref bool pendingConnections, ref bool serverConnectionPresentButDownOrDisconnected, ref Exception extraDownOrDisconnectedException)
        {
            PooledLdapConnection result = null;

            newPoolAvailable   = false;
            pendingConnections = false;
            serverConnectionPresentButDownOrDisconnected = false;
            int  tickCount = Environment.TickCount;
            bool flag      = serverName != null;
            bool flag2     = domain != null;
            bool flag3     = !flag2 && !flag;

            ExTraceGlobals.GetConnectionTracer.TraceDebug <ConnectionPoolType, string, string>((long)this.GetHashCode(), "LdapConnectionPool.GetConnection of type {0} by {1} ({2})", this.type, flag ? "Server" : (flag2 ? "Domain" : "Load balancing"), flag ? serverName : (flag2 ? domain.ToDNString() : "Least loaded"));
            this.CheckBadConnections();
            try
            {
                this.poolLock.AcquireReaderLock(-1);
                if (!this.isActive)
                {
                    ExTraceGlobals.GetConnectionTracer.TraceWarning((long)this.GetHashCode(), "Pool is not active, skipping GetConnection");
                    newPoolAvailable = true;
                    return(null);
                }
                bool flag4 = false;
                int  num   = int.MinValue;
                int  num2  = -1;
                for (int i = 0; i < this.connectionInfos.Length; i++)
                {
                    ConnectionInfo connectionInfo = this.connectionInfos[i];
                    if (!flag4 && connectionInfo.ConnectionState == ConnectionState.Empty)
                    {
                        ExTraceGlobals.GetConnectionTracer.TraceDebug <string>((long)this.GetHashCode(), "GetConnection: Opening connection for {0}.", connectionInfo.ADServerInfo.FqdnPlusPort);
                        this.OpenNewConnection(connectionInfo);
                    }
                    if (connectionInfo.ConnectionState == ConnectionState.Connecting)
                    {
                        ExTraceGlobals.GetConnectionTracer.TraceDebug <string>((long)this.GetHashCode(), "Connection to {0} is pending, skipping.", connectionInfo.ADServerInfo.FqdnPlusPort);
                        pendingConnections = true;
                    }
                    else if (connectionInfo.ConnectionState != ConnectionState.Connected || !connectionInfo.PooledLdapConnection.IsUp)
                    {
                        ExTraceGlobals.GetConnectionTracer.TraceDebug <string, int, string>((long)this.GetHashCode(), "Connection to {0} is {1}{2}, skipping.", connectionInfo.ADServerInfo.FqdnPlusPort, (int)connectionInfo.ConnectionState, (connectionInfo.ConnectionState == ConnectionState.Connected) ? (connectionInfo.PooledLdapConnection.IsUp ? "and UP" : "and DOWN") : string.Empty);
                        if (flag && this.IsServerMatch(i, serverName, port))
                        {
                            serverConnectionPresentButDownOrDisconnected = true;
                            extraDownOrDisconnectedException             = connectionInfo.LastLdapException;
                            ExTraceGlobals.GetConnectionTracer.TraceError <string, int>((long)this.GetHashCode(), "LdapConnectionPool.GetConnection: {0}:{1} is present but is down or disconnected", serverName, port);
                            break;
                        }
                    }
                    else
                    {
                        int num3 = int.MinValue;
                        if (flag3)
                        {
                            num3  = this.CalculateLoadBalancingQuality(i);
                            flag4 = (connectionInfo.PooledLdapConnection.OutstandingRequestCount == 0);
                        }
                        else if (flag)
                        {
                            num3  = this.CalculateQualityByServerMatch(i, serverName, port);
                            flag4 = (num3 > num);
                        }
                        else
                        {
                            if (this.IsDomainMatch(i, domain))
                            {
                                num3 = this.CalculateLoadBalancingQuality(i);
                            }
                            flag4 = (num3 > num);
                        }
                        ExTraceGlobals.GetConnectionTracer.TraceDebug((long)this.GetHashCode(), "Connection to {0}:{1} has quality {2}. suitableConnectionFound {3}", new object[]
                        {
                            connectionInfo.ADServerInfo.Fqdn,
                            connectionInfo.ADServerInfo.Port,
                            num3,
                            flag4
                        });
                        if (num3 > num)
                        {
                            num  = num3;
                            num2 = i;
                        }
                    }
                }
                if (num2 > -1)
                {
                    ConnectionInfo connectionInfo2 = this.connectionInfos[num2];
                    connectionInfo2.ADServerInfo.IncrementRequestCount();
                    Interlocked.Increment(ref this.totalRequestCount);
                    Interlocked.Exchange(ref this.lastUsedConnectionIndex, num2);
                    result = connectionInfo2.PooledLdapConnection.BorrowFromPool();
                    ExTraceGlobals.GetConnectionTracer.TraceDebug <string>((long)this.GetHashCode(), "Returning connection to {0}.", connectionInfo2.ADServerInfo.FqdnPlusPort);
                }
            }
            finally
            {
                try
                {
                    this.poolLock.ReleaseReaderLock();
                    ExTraceGlobals.GetConnectionTracer.TracePerformance <ulong>((long)this.GetHashCode(), "GetConnection time spend {0} milliseconds.", Globals.GetTickDifference(tickCount, Environment.TickCount));
                }
                catch (ApplicationException)
                {
                }
            }
            return(result);
        }