Thrown when a server returns a referral and when a referral has not been followed. It contains a list of URL strings corresponding to the referrals or search continuation references received on an Ldap operation.
Inheritance: LdapException
        /// <summary>
        ///     Returns the next result as an LdapEntry.
        ///     If automatic referral following is disabled or if a referral
        ///     was not followed, next() will throw an LdapReferralException
        ///     when the referral is received.
        /// </summary>
        /// <returns>
        ///     The next search result as an LdapEntry.
        /// </returns>
        /// <exception>
        ///     LdapException A general exception which includes an error
        ///     message and an Ldap error code.
        /// </exception>
        /// <exception>
        ///     LdapReferralException A referral was received and not
        ///     followed.
        /// </exception>
        public virtual LdapEntry next()
        {
            if (completed && entryIndex >= entryCount && referenceIndex >= referenceCount)
            {
                throw new ArgumentOutOfRangeException("LdapSearchResults.next() no more results");
            }
            // Check if the enumeration is empty and must be reloaded
            resetVectors();

            object element = null;

            // Check for Search References & deliver to app as they come in
            // We only get here if not following referrals/references
            if (referenceIndex < referenceCount)
            {
                var refs = (string[])references[referenceIndex++];
                var rex  = new LdapReferralException(ExceptionMessages.REFERENCE_NOFOLLOW);
                rex.setReferrals(refs);
                throw rex;
            }
            if (entryIndex < entryCount)
            {
                // Check for Search Entries and the Search Result
                element = entries[entryIndex++];
                if (element is LdapResponse)
                {
                    // Search done w/bad status
                    if (((LdapResponse)element).hasException())
                    {
                        var lr = (LdapResponse)element;
                        var ri = lr.ActiveReferral;

                        if (ri != null)
                        {
                            // Error attempting to follow a search continuation reference
                            var rex = new LdapReferralException(ExceptionMessages.REFERENCE_ERROR, lr.Exception);
                            rex.setReferrals(ri.ReferralList);
                            rex.FailedReferral = ri.ReferralUrl.ToString();
                            throw rex;
                        }
                    }
                    // Throw an exception if not success
                    ((LdapResponse)element).chkResultCode();
                }
                else if (element is LdapException)
                {
                    throw (LdapException)element;
                }
            }
            else
            {
                // If not a Search Entry, Search Result, or search continuation
                // we are very confused.
                // LdapSearchResults.next(): No entry found & request is not complete
                throw new LdapException(ExceptionMessages.REFERRAL_LOCAL, new object[] { "next" },
                                        LdapException.LOCAL_ERROR, null);
            }
            return((LdapEntry)element);
        }
Beispiel #2
0
		/// <summary> Returns the next result as an LdapEntry.
		/// 
		/// If automatic referral following is disabled or if a referral
		/// was not followed, next() will throw an LdapReferralException
		/// when the referral is received.
		/// 
		/// </summary>
		/// <returns> The next search result as an LdapEntry.
		/// 
		/// </returns>
		/// <exception> LdapException A general exception which includes an error
		/// message and an Ldap error code.
		/// </exception>
		/// <exception> LdapReferralException A referral was received and not
		/// followed.
		/// </exception>
		public virtual LdapEntry next()
		{
			if (completed && (entryIndex >= entryCount) && (referenceIndex >= referenceCount))
			{
				throw new System.ArgumentOutOfRangeException("LdapSearchResults.next() no more results");
			}
			// Check if the enumeration is empty and must be reloaded
			resetVectors();
			
			System.Object element = null;
			// Check for Search References & deliver to app as they come in
			// We only get here if not following referrals/references
			if (referenceIndex < referenceCount)
			{
				System.String[] refs = (System.String[]) (references[referenceIndex++]);
				LdapReferralException rex = new LdapReferralException(ExceptionMessages.REFERENCE_NOFOLLOW);
				rex.setReferrals(refs);
				throw rex;
			}
			else if (entryIndex < entryCount)
			{
				// Check for Search Entries and the Search Result
				element = entries[entryIndex++];
				if (element is LdapResponse)
				{
					// Search done w/bad status
					if (((LdapResponse) element).hasException())
					{
						
						LdapResponse lr = (LdapResponse) element;
						ReferralInfo ri = lr.ActiveReferral;
						
						if (ri != null)
						{
							// Error attempting to follow a search continuation reference
							LdapReferralException rex = new LdapReferralException(ExceptionMessages.REFERENCE_ERROR, lr.Exception);
							rex.setReferrals(ri.ReferralList);
							rex.FailedReferral = ri.ReferralUrl.ToString();
							throw rex;
						}
					}
					// Throw an exception if not success
					((LdapResponse) element).chkResultCode();
				}
				else if (element is LdapException)
				{
					throw (LdapException) element;
				}
			}
			else
			{
				// If not a Search Entry, Search Result, or search continuation
				// we are very confused.
				// LdapSearchResults.next(): No entry found & request is not complete
				throw new LdapException(ExceptionMessages.REFERRAL_LOCAL, new System.Object[]{"next"}, LdapException.LOCAL_ERROR, (System.String) null);
			}
			return (LdapEntry) element;
		}
Beispiel #3
0
		/// <summary> Follow referrals if necessary referral following enabled.
		/// This function is called only by synchronous requests.
		/// Search responses come here only if referral following is
		/// enabled and if we are processing a SearchResultReference
		/// or a Response with a status of REFERRAL, i.e. we are
		/// going to follow a referral.
		/// 
		/// This functions recursively follows a referral until a result
		/// is returned or until the hop limit is reached.
		/// 
		/// </summary>
		/// <param name="queue">The LdapResponseQueue for this request
		/// 
		/// </param>
		/// <param name="cons">The constraints that apply to the request
		/// 
		/// </param>
		/// <param name="msg">The referral or search reference response message
		/// 
		/// </param>
		/// <param name="initialReferrals">The referral array returned from the
		/// initial request.
		/// 
		/// </param>
		/// <param name="hopCount">the number of hops already used while
		/// following this referral
		/// 
		/// </param>
		/// <param name="searchReference">true if the message is a search reference
		/// 
		/// </param>
		/// <param name="connectionList">An optional array list used to store
		/// the LdapConnection objects used in following the referral.
		/// 
		/// </param>
		/// <returns> The array list used to store the all LdapConnection objects
		/// used in following the referral.  The list will be empty
		/// if there were none.
		/// 
		/// </returns>
		/// <exception> LdapException A general exception which includes an error
		/// message and an Ldap error code.
		/// </exception>
		/* package */
		internal virtual System.Collections.ArrayList chaseReferral(LdapMessageQueue queue, LdapConstraints cons, LdapMessage msg, System.String[] initialReferrals, int hopCount, bool searchReference, System.Collections.ArrayList connectionList)
		{
			System.Collections.ArrayList connList = connectionList;
			LdapConnection rconn = null; // new conn for following referral
			ReferralInfo rinfo = null; // referral info
			LdapMessage origMsg;
			
			// Get a place to store new connections
			if (connList == null)
			{
				connList = new System.Collections.ArrayList(cons.HopLimit);
			}
			// Following referrals or search reference
			System.String[] refs; // referral list
			if (initialReferrals != null)
			{
				// Search continuation reference from a search request
				refs = initialReferrals;
				origMsg = msg.RequestingMessage;
			}
			else
			{
				// Not a search request
				LdapResponse resp = (LdapResponse) queue.getResponse();
				if (resp.ResultCode != LdapException.REFERRAL)
				{
					// Not referral result,throw Exception if nonzero result
					resp.chkResultCode();
					return connList;
				}
				// We have a referral response
				refs = resp.Referrals;
				origMsg = resp.RequestingMessage;
			}
			LdapUrl refUrl; // referral represented as URL
			try
			{
				// increment hop count, check max hops
				if (hopCount++ > cons.HopLimit)
				{
					throw new LdapLocalException("Max hops exceeded", LdapException.REFERRAL_LIMIT_EXCEEDED);
				}
				// Get a connection to follow the referral
				rinfo = getReferralConnection(refs);
				rconn = rinfo.ReferralConnection;
				refUrl = rinfo.ReferralUrl;
				connList.Add(rconn);
				
				
				// rebuild msg into new msg changing msgID,dn,scope,filter
				LdapMessage newMsg = rebuildRequest(origMsg, refUrl, searchReference);
				
				
				// Send new message on new connection
				try
				{
					MessageAgent agent;
					if (queue is LdapResponseQueue)
					{
						agent = queue.MessageAgent;
					}
					else
					{
						agent = queue.MessageAgent;
					}
					agent.sendMessage(rconn.Connection, newMsg, defSearchCons.TimeLimit, queue, null);
				}
				catch (InterThreadException ex)
				{
					// Error ending request to referred server
					LdapReferralException rex = new LdapReferralException(ExceptionMessages.REFERRAL_SEND, LdapException.CONNECT_ERROR, null, ex);
					rex.setReferrals(initialReferrals);
					ReferralInfo ref_Renamed = rconn.Connection.ActiveReferral;
					rex.FailedReferral = ref_Renamed.ReferralUrl.ToString();
					throw rex;
				}
				
				if (initialReferrals == null)
				{
					// For operation results, when all responses are complete,
					// the stack unwinds back to the original and returns
					// to the application.
					// An exception is thrown for an error
					connList = chaseReferral(queue, cons, null, null, hopCount, false, connList);
				}
				else
				{
					// For search, just return to LdapSearchResults object
					return connList;
				}
			}
			catch (System.Exception ex)
			{
				
				if (ex is LdapReferralException)
				{
					throw (LdapReferralException) ex;
				}
				else
				{
					
					// Set referral list and failed referral
					LdapReferralException rex = new LdapReferralException(ExceptionMessages.REFERRAL_ERROR, ex);
					rex.setReferrals(refs);
					if (rinfo != null)
					{
						rex.FailedReferral = rinfo.ReferralUrl.ToString();
					}
					else
					{
						rex.FailedReferral = refs[refs.Length - 1];
					}
					throw rex;
				}
			}
			return connList;
		}
Beispiel #4
0
		/// <summary> get an LdapConnection object so that we can follow a referral.
		/// This function is never called if cons.getReferralFollowing() returns
		/// false.
		/// 
		/// </summary>
		/// <param name="referrals">the array of referral strings
		/// 
		/// 
		/// </param>
		/// <returns> The referralInfo object
		/// 
		/// </returns>
		/// <exception> LdapReferralException A general exception which includes
		/// an error message and an Ldap error code.
		/// </exception>
		private ReferralInfo getReferralConnection(System.String[] referrals)
		{
			ReferralInfo refInfo = null;
			System.Exception ex = null;
			LdapConnection rconn = null;
			LdapReferralHandler rh = defSearchCons.getReferralHandler();
			int i = 0;
			// Check if we use LdapRebind to get authentication credentials
			if ((rh == null) || (rh is LdapAuthHandler))
			{
				for (i = 0; i < referrals.Length; i++)
				{
					// dn, pw are null in the default case (anonymous bind)
					System.String dn = null;
					sbyte[] pw = null;
					try
					{
						rconn = new LdapConnection();
						rconn.Constraints = defSearchCons;
						LdapUrl url = new LdapUrl(referrals[i]);
						rconn.Connect(url.Host, url.Port);
						if (rh != null)
						{
							if (rh is LdapAuthHandler)
							{
								// Get application supplied dn and pw
								LdapAuthProvider ap = ((LdapAuthHandler) rh).getAuthProvider(url.Host, url.Port);
								dn = ap.DN;
								pw = ap.Password;
							}
						}
						rconn.Bind(Ldap_V3, dn, pw);
						ex = null;
						refInfo = new ReferralInfo(rconn, referrals, url);
						// Indicate this connection created to follow referral
						rconn.Connection.ActiveReferral = refInfo;
						break;
					}
					catch (System.Exception lex)
					{
						if (rconn != null)
						{
							try
							{
								rconn.Disconnect();
								rconn = null;
								ex = lex;
							}
							catch (LdapException e)
							{
								; // ignore
							}
						}
					}
				}
			}
				// Check if application gets connection and does bind
			else
			{
				//  rh instanceof LdapBind
				try
				{
					rconn = ((LdapBindHandler) rh).Bind(referrals, this);
					if (rconn == null)
					{
						LdapReferralException rex = new LdapReferralException(ExceptionMessages.REFERRAL_ERROR);
						rex.setReferrals(referrals);
						throw rex;
					}
					// Figure out which Url belongs to the connection
					for (int idx = 0; idx < referrals.Length; idx++)
					{
						try
						{
							LdapUrl url = new LdapUrl(referrals[idx]);
							if (url.Host.ToUpper().Equals(rconn.Host.ToUpper()) && (url.Port == rconn.Port))
							{
								refInfo = new ReferralInfo(rconn, referrals, url);
								break;
							}
						}
						catch (System.Exception e)
						{
							; // ignore
						}
					}
					if (refInfo == null)
					{
						// Could not match LdapBind.bind() connecction with URL list
						ex = new LdapLocalException(ExceptionMessages.REFERRAL_BIND_MATCH, LdapException.CONNECT_ERROR);
					}
				}
				catch (System.Exception lex)
				{
					rconn = null;
					ex = lex;
				}
			}
			if (ex != null)
			{
				// Could not connect to any server, throw an exception
				LdapException ldapex;
				if (ex is LdapReferralException)
				{
					throw (LdapReferralException) ex;
				}
				else if (ex is LdapException)
				{
					ldapex = (LdapException) ex;
				}
				else
				{
					ldapex = new LdapLocalException(ExceptionMessages.SERVER_CONNECT_ERROR, new System.Object[]{conn.Host}, LdapException.CONNECT_ERROR, ex);
				}
				// Error attempting to follow a referral
				LdapReferralException rex = new LdapReferralException(ExceptionMessages.REFERRAL_ERROR, ldapex);
				rex.setReferrals(referrals);
				// Use last URL string for the failed referral
				rex.FailedReferral = referrals[referrals.Length - 1];
				throw rex;
			}
			
			// We now have an authenticated connection
			// to be used to follow the referral.
			return refInfo;
		}
        /// <summary>
        ///     Returns the next result as an LdapEntry.
        ///     If automatic referral following is disabled or if a referral
        ///     was not followed, next() will throw an LdapReferralException
        ///     when the referral is received.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns>
        ///     The next search result as an LdapEntry.
        /// </returns>
        /// <exception>
        ///     LdapException A general exception which includes an error
        ///     message and an Ldap error code.
        /// </exception>
        /// <exception>
        ///     LdapReferralException A referral was received and not
        ///     followed.
        /// </exception>
        private async Task <LdapEntry> NextAsync(CancellationToken cancellationToken)
        {
            if (_completed && _entryIndex >= _entryCount && _referenceIndex >= _referenceCount)
            {
                throw new ArgumentOutOfRangeException("LdapSearchResults.Next() no more results");
            }

            // Check if the enumeration is empty and must be reloaded
            await ResetVectorsAsync(cancellationToken).ConfigureAwait(false);

            // Check for Search References & deliver to app as they come in
            // We only get here if not following referrals/references
            if (_referenceIndex < _referenceCount)
            {
                var refs = _references[_referenceIndex++];
                var rex  = new LdapReferralException(ExceptionMessages.ReferenceNofollow);
                rex.SetReferrals(refs);
                throw rex;
            }

            object element;

            if (_entryIndex < _entryCount)
            {
                // Check for Search Entries and the Search Result
                element = _entries[_entryIndex++];
                if (element is LdapResponse)
                {
                    // Search done w/bad status
                    if (((LdapResponse)element).HasException())
                    {
                        var lr = (LdapResponse)element;
                        var ri = lr.ActiveReferral;

                        if (ri != null)
                        {
                            // Error attempting to follow a search continuation reference
                            var rex = new LdapReferralException(ExceptionMessages.ReferenceError, lr.Exception);
                            rex.SetReferrals(ri.ReferralList);
                            rex.FailedReferral = ri.ReferralUrl.ToString();
                            throw rex;
                        }
                    }

                    // Throw an exception if not success
                    ((LdapResponse)element).ChkResultCode();
                }
                else if (element is LdapException)
                {
                    throw (LdapException)element;
                }
            }
            else
            {
                // If not a Search Entry, Search Result, or search continuation
                // we are very confused.
                // LdapSearchResults.next(): No entry found & request is not complete
                throw new LdapException(ExceptionMessages.ReferralLocal, new object[] { "next" },
                                        LdapException.LocalError, null);
            }

            return((LdapEntry)element);
        }