/// <summary> Constructs an LdapSearchConstraints object initialized with values /// from an existing constraints object (LdapConstraints /// or LdapSearchConstraints). /// </summary> public LdapSearchConstraints(LdapConstraints cons) : base(cons.TimeLimit, cons.ReferralFollowing, cons.getReferralHandler(), cons.HopLimit) { InitBlock(); LdapControl[] lsc = cons.getControls(); if (lsc != null) { LdapControl[] generated_var = new LdapControl[lsc.Length]; lsc.CopyTo(generated_var, 0); setControls(generated_var); } System.Collections.Hashtable lp = cons.Properties; if (lp != null) { Properties = (System.Collections.Hashtable)lp.Clone(); } if (cons is LdapSearchConstraints) { LdapSearchConstraints scons = (LdapSearchConstraints)cons; serverTimeLimit = scons.ServerTimeLimit; dereference = scons.Dereference; maxResults = scons.MaxResults; batchSize = scons.BatchSize; } // Get a unique connection name for debug }
/// <summary> Constructs an LdapSearchConstraints object initialized with values /// from an existing constraints object (LdapConstraints /// or LdapSearchConstraints). /// </summary> public LdapSearchConstraints(LdapConstraints cons) : base(cons.TimeLimit, cons.ReferralFollowing, cons.getReferralHandler(), cons.HopLimit) { InitBlock(); LdapControl[] lsc = cons.getControls(); if (lsc != null) { LdapControl[] generated_var = new LdapControl[lsc.Length]; lsc.CopyTo(generated_var, 0); base.setControls(generated_var); } Hashtable lp = cons.Properties; if (lp != null) { base.Properties = (Hashtable)lp.Clone(); } if (cons is LdapSearchConstraints) { LdapSearchConstraints scons = (LdapSearchConstraints)cons; this.serverTimeLimit = scons.ServerTimeLimit; this.dereference = scons.Dereference; this.maxResults = scons.MaxResults; this.batchSize = scons.BatchSize; } }
/// <summary> /// Constructs an LdapSearchConstraints object initialized with values /// from an existing constraints object (LdapConstraints /// or LdapSearchConstraints). /// </summary> public LdapSearchConstraints(LdapConstraints cons) : base(cons.TimeLimit, cons.ReferralFollowing, cons.getReferralHandler(), cons.HopLimit) { var lsc = cons.GetControls(); if (lsc != null) { var generatedVar = new LdapControl[lsc.Length]; lsc.CopyTo(generatedVar, 0); SetControls(generatedVar); } var lp = cons.Properties; if (lp != null) { Properties = (Hashtable)lp.Clone(); } if (cons is LdapSearchConstraints) { var scons = (LdapSearchConstraints)cons; ServerTimeLimit = scons.ServerTimeLimit; Dereference = scons.Dereference; MaxResults = scons.MaxResults; BatchSize = scons.BatchSize; } }
/// <summary> /// Abandon the request associated with MsgId. /// </summary> /// <param name="msgId"> /// the message id to abandon. /// </param> /// <param name="cons"> /// constraints associated with this request. /// </param> internal void Abandon(int msgId, LdapConstraints cons) { try { // Send abandon request and remove from connection list var info = _messages.FindMessageById(msgId); _messages.Remove(info); info.Abandon(cons, null); } catch (FieldAccessException ex) { Logger.Log.LogWarning("Exception swallowed", ex); } }
/// <summary> /// Abandon the request associated with MsgId. /// </summary> /// <param name="msgId"> /// the message id to abandon. /// </param> /// <param name="cons"> /// constraints associated with this request. /// </param> /// <param name="cancellationToken"></param> internal async Task Abandon(int msgId, LdapConstraints cons, CancellationToken cancellationToken) { try { // Send abandon request and remove from connection list var info = _messages.FindMessageById(msgId); _messages.Remove(info); await info.Abandon(cons, null, cancellationToken).ConfigureAwait(false); } catch (FieldAccessException ex) { Logger.Log.LogWarning("Exception swallowed", ex); } }
/// <summary> /// Abandon the request associated with MsgId. /// </summary> /// <param name="msgId"> /// the message id to abandon. /// </param> /// <param name="cons"> /// constraints associated with this request. /// </param> internal void Abandon(int msgId, LdapConstraints cons) { try { // Send abandon request and remove from connection list var info = _messages.FindMessageById(msgId); SupportClass.VectorRemoveElement(_messages, info); // This message is now dead info.Abandon(cons, null); } catch (FieldAccessException ex) { Logger.Log.LogWarning("Exception swallowed", ex); } }
/// <summary> Abandon the request associated with MsgId /// /// </summary> /// <param name="msgId">the message id to abandon /// /// </param> /// <param name="cons">constraints associated with this request /// </param> /* package */ internal void Abandon(int msgId, LdapConstraints cons) //, boolean informUser) { Message info = null; try { // Send abandon request and remove from connection list info = messages.findMessageById(msgId); SupportClass.VectorRemoveElement(messages, info); // This message is now dead info.Abandon(cons, null); } catch (FieldAccessException ex) { } }
internal virtual void Abandon(LdapConstraints cons, InterThreadException informUserEx) { if (!waitForReply_Renamed_Field) { return; } acceptReplies = false; // don't listen to anyone waitForReply_Renamed_Field = false; // don't let sleeping threads lie if (!complete) { try { // If a bind, release bind semaphore & wake up waiting threads // Must do before writing abandon message, otherwise deadlock if (bindprops != null) { int id; if (conn.BindSemIdClear) { // Semaphore id for normal operations id = msgId; } else { // Semaphore id for sasl bind id = conn.BindSemId; conn.clearBindSemId(); } conn.freeWriteSemaphore(id); } // Create the abandon message, but don't track it. LdapControl[] cont = null; if (cons != null) { cont = cons.getControls(); } LdapMessage msg = new LdapAbandonRequest(msgId, cont); // Send abandon message to server conn.writeMessage(msg); } catch (LdapException ex) { LogManager.GetCurrentClassLogger().Warn("Exception swallowed", ex); } // If not informing user, remove message from agent if (informUserEx == null) { agent.Abandon(msgId, null); } conn.removeMessage(this); } // Get rid of all replies queued if (informUserEx != null) { replies.Add(new LdapResponse(informUserEx, conn.ActiveReferral)); stopTimer(); // wake up waiting threads to receive exception sleepersAwake(); // Message will get cleaned up when last response removed from queue } else { // Wake up any waiting threads, so they can terminate. // If informing the user, we wake sleepers after // caller queues dummy response with error status sleepersAwake(); cleanup(); } }
/// <summary> /// /// Notifies the server not to send additional results associated with /// this LdapSearchResults object, and discards any results already /// received. /// /// </summary> /// <param name="results"> An object returned from a search. /// /// </param> /// <param name="cons"> The contraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Abandon(LdapSearchResults results, LdapConstraints cons) { results.Abandon(); return ; }
/// <summary> Check the result code and throw an exception if needed. /// /// If referral following is enabled, checks if we need to /// follow a referral /// /// </summary> /// <param name="queue">- the message queue of the current response /// /// </param> /// <param name="cons">- the constraints that apply to the request /// /// </param> /// <param name="response">- the LdapResponse to check /// </param> private void chkResultCode(LdapMessageQueue queue, LdapConstraints cons, LdapResponse response) { if ((response.ResultCode == LdapException.REFERRAL) && cons.ReferralFollowing) { // Perform referral following and return System.Collections.ArrayList refConn = null; try { chaseReferral(queue, cons, response, response.Referrals, 0, false, null); } finally { releaseReferralConnections(refConn); } } else { // Throws exception for non success result response.chkResultCode(); } return ; }
/// <summary> Asynchronously renames an existing entry in the directory, using the /// specified constraints and possibily repositioning the entry in the /// directory. /// /// </summary> /// <param name="dn"> The current distinguished name of the entry. /// /// </param> /// <param name="newRdn"> The new relative distinguished name for the entry. /// /// </param> /// <param name="newParentdn"> The distinguished name of an existing entry which /// is to be the new parent of the entry. /// /// </param> /// <param name="deleteOldRdn"> If true, the old name is not retained as an /// attribute value. If false, the old name is /// retained as an attribute value. /// /// </param> /// <param name="queue"> The queue for messages returned from a server in /// response to this request. If it is null, a /// queue object is created internally. /// /// </param> /// <param name="cons"> The constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual LdapResponseQueue Rename(System.String dn, System.String newRdn, System.String newParentdn, bool deleteOldRdn, LdapResponseQueue queue, LdapConstraints cons) { if ((System.Object) dn == null || (System.Object) newRdn == null) { // Invalid DN or RDN parameter throw new System.ArgumentException(ExceptionMessages.RDN_PARAM_ERROR); } if (cons == null) cons = defSearchCons; LdapMessage msg = new LdapModifyDNRequest(dn, newRdn, newParentdn, deleteOldRdn, cons.getControls()); return SendRequestToServer(msg, cons.TimeLimit, queue, null); }
/// <summary> /// Synchronously renames an existing entry in the directory, using the /// specified constraints and possibly repositioning the entry in the /// directory tree. /// /// </summary> /// <param name="dn"> The current distinguished name of the entry. /// /// </param> /// <param name="newRdn"> The new relative distinguished name for the entry. /// /// </param> /// <param name="newParentdn"> The distinguished name of an existing entry which /// is to be the new parent of the entry. /// /// </param> /// <param name="deleteOldRdn"> If true, the old name is not retained as an /// attribute value. If false, the old name is /// retained as an attribute value. /// /// </param> /// <param name="cons"> The constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Rename(System.String dn, System.String newRdn, System.String newParentdn, bool deleteOldRdn, LdapConstraints cons) { LdapResponseQueue queue = Rename(dn, newRdn, newParentdn, deleteOldRdn, null, cons); // Get a handle to the rename response LdapResponse renameResponse = (LdapResponse) (queue.getResponse()); // Set local copy of responseControls synchronously - if there were any lock (responseCtlSemaphore) { responseCtls = renameResponse.Controls; } chkResultCode(queue, cons, renameResponse); return ; }
/// <summary> Asynchronously makes a set of changes to an existing entry in the /// directory, using the specified constraints and queue. /// /// For example, this modify method can change attribute values, add new /// attribute values, or remove existing attribute values. /// /// Because the server applies all changes in an LdapModification array /// atomically, the application can expect that no changes /// have been performed if an error is returned. /// If the request fails with {@link LdapException.CONNECT_ERROR}, /// it is indeterminate whether or not the server made the modifications. /// /// </summary> /// <param name="dn"> The distinguished name of the entry to modify. /// /// </param> /// <param name="mods"> The changes to be made to the entry. /// /// </param> /// <param name="queue"> The queue for messages returned from a server in /// response to this request. If it is null, a /// queue object is created internally. /// /// </param> /// <param name="cons"> Constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual LdapResponseQueue Modify(System.String dn, LdapModification[] mods, LdapResponseQueue queue, LdapConstraints cons) { if ((System.Object) dn == null) { // Invalid DN parameter throw new System.ArgumentException(ExceptionMessages.DN_PARAM_ERROR); } if (cons == null) cons = defSearchCons; LdapMessage msg = new LdapModifyRequest(dn, mods, cons.getControls()); return SendRequestToServer(msg, cons.TimeLimit, queue, null); }
/// <summary> Synchronously makes a set of changes to an existing entry in the /// directory, using the specified constraints. /// /// For example, this modify method changes attribute values, adds new /// attribute values, or removes existing attribute values. /// /// Because the server applies all changes in an LdapModification array /// atomically, the application can expect that no changes /// have been performed if an error is returned. /// If the request fails with {@link LdapException.CONNECT_ERROR}, /// it is indeterminate whether or not the server made the modifications. /// /// </summary> /// <param name="dn"> The distinguished name of the entry to modify. /// /// </param> /// <param name="mods"> The changes to be made to the entry. /// /// </param> /// <param name="cons"> The constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an /// error message and an Ldap error code. /// </exception> public virtual void Modify(System.String dn, LdapModification[] mods, LdapConstraints cons) { LdapResponseQueue queue = Modify(dn, mods, null, cons); // Get a handle to the modify response LdapResponse modifyResponse = (LdapResponse) (queue.getResponse()); // Set local copy of responseControls synchronously - if there were any lock (responseCtlSemaphore) { responseCtls = modifyResponse.Controls; } chkResultCode(queue, cons, modifyResponse); return ; }
public virtual LdapResponseQueue Bind(int version, System.String dn, sbyte[] passwd, LdapResponseQueue queue, LdapConstraints cons, string mech) { int msgId; BindProperties bindProps; if (cons == null) cons = defSearchCons; if ((System.Object) dn == null) { dn = ""; } else { dn = dn.Trim(); } if (passwd == null) passwd = new sbyte[]{}; bool anonymous = false; if (passwd.Length == 0) { anonymous = true; // anonymous, passwd length zero with simple bind dn = ""; // set to null if anonymous } LdapMessage msg; #if TARGET_JVM if (mech != null) msg = new LdapBindRequest(version, "", mech, passwd, cons.getControls()); else #endif msg = new LdapBindRequest(version, dn, passwd, cons.getControls()); msgId = msg.MessageID; bindProps = new BindProperties(version, dn, "simple", anonymous, null, null); // For bind requests, if not connected, attempt to reconnect if (!conn.Connected) { if ((System.Object) conn.Host != null) { conn.connect(conn.Host, conn.Port); } else { throw new LdapException(ExceptionMessages.CONNECTION_IMPOSSIBLE, LdapException.CONNECT_ERROR, null); } } #if TARGET_JVM // stopping reader to enable stream replace after secure binding is complete, see Connection.ReplaceStreams() if (mech != null) { if (conn.BindSemIdClear) { // need to acquire a semaphore only if bindSemId is clear // because if we receive SASL_BIND_IN_PROGRESS the semaphore is not // released when the response is queued conn.acquireWriteSemaphore(msgId); conn.BindSemId = msgId; } conn.stopReaderOnReply(msgId); } else #endif // The semaphore is released when the bind response is queued. conn.acquireWriteSemaphore(msgId); return SendRequestToServer(msg, cons.TimeLimit, queue, bindProps); }
public virtual void Bind(int version, System.String dn, sbyte[] passwd, LdapConstraints cons) { LdapResponseQueue queue = Bind(version, dn, passwd, null, cons, null); LdapResponse res = (LdapResponse) queue.getResponse(); if (res != null) { // Set local copy of responseControls synchronously if any lock (responseCtlSemaphore) { responseCtls = res.Controls; } chkResultCode(queue, cons, res); } return ; }
/// <summary> Synchronously authenticates to the Ldap server (that the object is /// currently connected to) using the specified name, password, Ldap version, /// and constraints. /// /// If the object has been disconnected from an Ldap server, /// this method attempts to reconnect to the server. If the object /// has already authenticated, the old authentication is discarded. /// /// </summary> /// <param name="version"> The Ldap protocol version, use Ldap_V3. /// Ldap_V2 is not supported. /// /// </param> /// <param name="dn"> If non-null and non-empty, specifies that the /// connection and all operations through it should /// be authenticated with dn as the distinguished /// name. /// /// </param> /// <param name="passwd"> If non-null and non-empty, specifies that the /// connection and all operations through it should /// be authenticated with dn as the distinguished /// name and passwd as password. /// /// Note: the application should use care in the use /// of String password objects. These are long lived /// objects, and may expose a security risk, especially /// in objects that are serialized. The LdapConnection /// keeps no long lived instances of these objects. /// /// </param> /// <param name="cons"> The constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// /// </exception> public virtual void Bind(int version, System.String dn, System.String passwd, LdapConstraints cons) { sbyte[] pw = null; if ((System.Object) passwd != null) { try { System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8"); byte[] ibytes = encoder.GetBytes(passwd); pw=SupportClass.ToSByteArray(ibytes); // pw = passwd.getBytes("UTF8"); passwd = null; // Keep no reference to String object } catch (System.IO.IOException ex) { passwd = null; // Keep no reference to String object throw new System.SystemException(ex.ToString()); } } Bind(version, dn, pw, cons); return ; }
/// <summary> Synchronously authenticates to the Ldap server (that the object is /// currently connected to) as an Ldapv3 bind, using the specified name, /// password, and constraints. /// /// If the object has been disconnected from an Ldap server, /// this method attempts to reconnect to the server. If the object /// has already authenticated, the old authentication is discarded. /// /// </summary> /// <param name="dn"> If non-null and non-empty, specifies that the /// connection and all operations through it should /// be authenticated with dn as the distinguished /// name. /// /// </param> /// <param name="passwd"> If non-null and non-empty, specifies that the /// connection and all operations through it should /// be authenticated with dn as the distinguished /// name and passwd as password. /// Note: the application should use care in the use /// of String password objects. These are long lived /// objects, and may expose a security risk, especially /// in objects that are serialized. The LdapConnection /// keeps no long lived instances of these objects. /// /// </param> /// <param name="cons"> Constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// /// </exception> public virtual void Bind(System.String dn, System.String passwd, LdapConstraints cons) { Bind(Ldap_V3, dn, passwd, cons); return ; }
/// <summary> Asynchronously adds an entry to the directory, using the specified /// constraints. /// /// </summary> /// <param name="entry"> LdapEntry object specifying the distinguished /// name and attributes of the new entry. /// /// </param> /// <param name="queue"> Handler for messages returned from a server in /// response to this request. If it is null, a /// queue object is created internally. /// /// </param> /// <param name="cons"> Constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual LdapResponseQueue Add(LdapEntry entry, LdapResponseQueue queue, LdapConstraints cons) { if (cons == null) cons = defSearchCons; // error check the parameters if (entry == null) { throw new System.ArgumentException("The LdapEntry parameter" + " cannot be null"); } if ((System.Object) entry.DN == null) { throw new System.ArgumentException("The DN value must be present" + " in the LdapEntry object"); } LdapMessage msg = new LdapAddRequest(entry, cons.getControls()); return SendRequestToServer(msg, cons.TimeLimit, queue, null); }
/// <summary> /// Synchronously adds an entry to the directory, using the specified /// constraints. /// /// </summary> /// <param name="entry"> LdapEntry object specifying the distinguished /// name and attributes of the new entry. /// /// </param> /// <param name="cons"> Constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Add(LdapEntry entry, LdapConstraints cons) { LdapResponseQueue queue = Add(entry, null, cons); // Get a handle to the add response LdapResponse addResponse = (LdapResponse) (queue.getResponse()); // Set local copy of responseControls synchronously if there were any lock (responseCtlSemaphore) { responseCtls = addResponse.Controls; } chkResultCode(queue, cons, addResponse); return ; }
/// <summary> Abandons all outstanding operations managed by the queue. /// /// All operations in progress, which are managed by the specified /// queue, are abandoned. /// /// </summary> /// <param name="queue"> The queue returned from an asynchronous request. /// All outstanding operations managed by the queue /// are abandoned, and the queue is emptied. /// /// </param> /// <param name="cons"> The contraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Abandon(LdapMessageQueue queue, LdapConstraints cons) { if (queue != null) { MessageAgent agent; if (queue is LdapSearchQueue) { agent = queue.MessageAgent; } else { agent = queue.MessageAgent; } int[] msgIds = agent.MessageIDs; for (int i = 0; i < msgIds.Length; i++) { agent.Abandon(msgIds[i], cons); } } return ; }
/// <summary> /// Synchronously checks to see if an entry contains an attribute with a /// specified value, using the specified constraints. /// /// </summary> /// <param name="dn"> The distinguished name of the entry to use in the /// comparison. /// /// </param> /// <param name="attr"> The attribute to compare against the entry. The /// method checks to see if the entry has an /// attribute with the same name and value as this /// attribute. /// /// </param> /// <param name="cons"> Constraints specific to the operation. /// /// </param> /// <returns> True if the entry has the value, /// and false if the entry does not /// have the value or the attribute. /// /// </returns> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual bool Compare(System.String dn, LdapAttribute attr, LdapConstraints cons) { bool ret = false; LdapResponseQueue queue = Compare(dn, attr, null, cons); LdapResponse res = (LdapResponse) queue.getResponse(); // Set local copy of responseControls synchronously - if there were any lock (responseCtlSemaphore) { responseCtls = res.Controls; } if (res.ResultCode == LdapException.COMPARE_TRUE) { ret = true; } else if (res.ResultCode == LdapException.COMPARE_FALSE) { ret = false; } else { chkResultCode(queue, cons, res); } return ret; }
public static async Task <LdapWhoAmIResponse> WhoAmIAsync(this LdapConnection conn, LdapConstraints cons = null) { var result = await conn.ExtendedOperationAsync(new LdapWhoAmIOperation(), cons).ConfigureAwait(false); if (result is LdapWhoAmIResponse whoami) { return(whoami); } return(new LdapWhoAmIResponse(result.Message)); }
/// <summary> Asynchronously compares an attribute value with one in the directory, /// using the specified queue and contraints. /// /// Please note that a successful completion of this command results in /// one of two status codes: LdapException.COMPARE_TRUE if the entry /// has the value, and LdapException.COMPARE_FALSE if the entry /// does not have the value or the attribute. /// /// </summary> /// <param name="dn"> The distinguished name of the entry containing an /// attribute to compare. /// /// </param> /// <param name="attr"> An attribute to compare. /// /// </param> /// <param name="queue"> Handler for messages returned from a server in /// response to this request. If it is null, a /// queue object is created internally. /// /// </param> /// <param name="cons"> Constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// /// </exception> /// <seealso cref="LdapException.COMPARE_TRUE"> /// </seealso> /// <seealso cref="LdapException.COMPARE_FALSE"> /// </seealso> public virtual LdapResponseQueue Compare(System.String dn, LdapAttribute attr, LdapResponseQueue queue, LdapConstraints cons) { if (attr.size() != 1) { throw new System.ArgumentException("compare: Exactly one value " + "must be present in the LdapAttribute"); } if ((System.Object) dn == null) { // Invalid parameter throw new System.ArgumentException("compare: DN cannot be null"); } if (cons == null) cons = defSearchCons; LdapMessage msg = new LdapCompareRequest(dn, attr.Name, attr.ByteValue, cons.getControls()); return SendRequestToServer(msg, cons.TimeLimit, queue, null); }
/// <summary> Asynchronously makes a single change to an existing entry in the /// directory, using the specified constraints and queue. /// /// For example, this modify method can change the value of an attribute, /// add a new attribute value, or remove an existing attribute value. /// /// The LdapModification object specifies both the change to be made /// and the LdapAttribute value to be changed. /// /// If the request fails with {@link LdapException.CONNECT_ERROR}, /// it is indeterminate whether or not the server made the modification. /// /// </summary> /// <param name="dn"> Distinguished name of the entry to modify. /// /// </param> /// <param name="mod"> A single change to be made to the entry. /// /// </param> /// <param name="queue"> Handler for messages returned from a server in /// response to this request. If it is null, a /// queue object is created internally. /// /// </param> /// <param name="cons"> Constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual LdapResponseQueue Modify(System.String dn, LdapModification mod, LdapResponseQueue queue, LdapConstraints cons) { LdapModification[] mods = new LdapModification[1]; mods[0] = mod; return Modify(dn, mods, queue, cons); }
/// <summary> Synchronously deletes the entry with the specified distinguished name /// from the directory, using the specified constraints. /// /// Note: A Delete operation will not remove an entry that contains /// subordinate entries, nor will it dereference alias entries. /// /// </summary> /// <param name="dn"> The distinguished name of the entry to delete. /// /// </param> /// <param name="cons"> Constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Delete(System.String dn, LdapConstraints cons) { LdapResponseQueue queue = Delete(dn, null, cons); // Get a handle to the delete response LdapResponse deleteResponse = (LdapResponse) (queue.getResponse()); // Set local copy of responseControls synchronously - if there were any lock (responseCtlSemaphore) { responseCtls = deleteResponse.Controls; } chkResultCode(queue, cons, deleteResponse); return ; }
/// <summary> /// Synchronously renames an existing entry in the directory, using the /// specified constraints. /// /// </summary> /// <param name="dn"> The current distinguished name of the entry. /// /// </param> /// <param name="newRdn"> The new relative distinguished name for the entry. /// /// </param> /// <param name="deleteOldRdn"> If true, the old name is not retained as an /// attribute value. If false, the old name is /// retained as an attribute value. /// /// </param> /// <param name="cons"> The constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Rename(System.String dn, System.String newRdn, bool deleteOldRdn, LdapConstraints cons) { // null for newParentdn means that this is originating as an Ldapv2 call Rename(dn, newRdn, null, deleteOldRdn, cons); return ; }
/// <summary> Synchronously disconnects from the Ldap server. /// /// Before the object can perform Ldap operations again, it must /// reconnect to the server by calling connect. /// /// The disconnect method abandons any outstanding requests, issues an /// unbind request to the server, and then closes the socket. /// /// </summary> /// <param name="cons">LDPConstraints to be set with the unbind request /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Disconnect(LdapConstraints cons) { // disconnect from API call Disconnect(cons, true); return ; }
/// <summary> Asynchronously renames an existing entry in the directory, using the /// specified constraints. /// /// </summary> /// <param name="dn"> The current distinguished name of the entry. /// /// </param> /// <param name="newRdn"> The new relative distinguished name for the entry. /// /// </param> /// <param name="deleteOldRdn"> If true, the old name is not retained as an /// attribute value. If false, the old name is /// retained as an attribute value. /// /// </param> /// <param name="queue"> The queue for messages returned from a server in /// response to this request. If it is null, a /// queue object is created internally. /// /// </param> /// <param name="cons"> The constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual LdapResponseQueue Rename(System.String dn, System.String newRdn, bool deleteOldRdn, LdapResponseQueue queue, LdapConstraints cons) { return Rename(dn, newRdn, null, deleteOldRdn, queue, cons); }
/// <summary> Synchronously disconnect from the server /// /// </summary> /// <param name="how">true if application call disconnect API, false if finalize. /// </param> private void Disconnect(LdapConstraints cons, bool how) { // disconnect doesn't affect other clones // If not a clone, distroys connection conn = conn.destroyClone(how); return ; }
/// <summary> Sends an Ldap request to a directory server. /// /// The specified the Ldap request is sent to the directory server /// associated with this connection. An Ldap request object is an /// {@link LdapMessage} with the operation type set to one of the request /// types. You can build a request by using the request classes found in this /// package /// /// You should note that, since Ldap requests sent to the server /// using sendRequest are asynchronous, automatic referral following /// does not apply to these requests. /// /// </summary> /// <param name="request">The Ldap request to send to the directory server. /// </param> /// <param name="queue"> The queue for messages returned from a server in /// response to this request. If it is null, a /// queue object is created internally. /// </param> /// <param name="cons"> The constraints that apply to this request /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// /// </exception> /// <seealso cref="LdapMessage.Type"> /// </seealso> /// <seealso cref="RfcLdapMessage.isRequest"> /// </seealso> public virtual LdapMessageQueue SendRequest(LdapMessage request, LdapMessageQueue queue, LdapConstraints cons) { if (!request.Request) { throw new System.SystemException("Object is not a request message"); } if (cons == null) { cons = defSearchCons; } // Get the correct queue for a search request MessageAgent agent; LdapMessageQueue myqueue = queue; if (myqueue == null) { agent = new MessageAgent(); if (request.Type == LdapMessage.SEARCH_REQUEST) { myqueue = new LdapSearchQueue(agent); } else { myqueue = new LdapResponseQueue(agent); } } else { if (request.Type == LdapMessage.SEARCH_REQUEST) { agent = queue.MessageAgent; } else { agent = queue.MessageAgent; } } try { agent.sendMessage(conn, request, cons.TimeLimit, myqueue, null); } catch (LdapException lex) { throw lex; } return myqueue; }
//, boolean informUser) /// <summary> Abandon the request associated with MsgId /// /// </summary> /// <param name="msgId">the message id to abandon /// /// </param> /// <param name="cons">constraints associated with this request /// </param> /* package */ internal void Abandon(int msgId, LdapConstraints cons) { Message info = null; try { // Send abandon request and remove from connection list info = messages.findMessageById(msgId); SupportClass.VectorRemoveElement(messages, info); // This message is now dead info.Abandon(cons, null); return ; } catch (System.FieldAccessException ex) { } return ; }
/// <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; }
/* * Asynchronous Ldap extended request with SearchConstraints */ /// <summary> Provides an asynchronous means to access extended, non-mandatory /// operations offered by a particular Ldapv3 compliant server. /// /// </summary> /// <param name="op"> The object which contains (1) an identifier of an extended /// operation which should be recognized by the particular Ldap /// server this client is connected to and (2) an operation- /// specific sequence of octet strings or BER-encoded values. /// /// </param> /// <param name="queue"> The queue for messages returned from a server in /// response to this request. If it is null, a queue /// object is created internally. /// /// </param> /// <param name="cons"> The constraints specific to this operation. /// /// </param> /// <returns> An operation-specific object, containing an ID and either an /// octet string or BER-encoded values. /// /// </returns> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual LdapResponseQueue ExtendedOperation(LdapExtendedOperation op, LdapConstraints cons, LdapResponseQueue queue) { // Use default constraints if none-specified if (cons == null) cons = defSearchCons; LdapMessage msg = MakeExtendedOperation(op, cons); return SendRequestToServer(msg, cons.TimeLimit, queue, null); }
/// <summary> Abandons an asynchronous operation, using the specified /// constraints. /// /// </summary> /// <param name="id">The ID of the asynchronous operation to abandon. /// The ID can be obtained from the search /// queue for the operation. /// /// </param> /// <param name="cons">The contraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Abandon(int id, LdapConstraints cons) { // We need to inform the Message Agent which owns this messageID to // remove it from the queue. try { MessageAgent agent = conn.getMessageAgent(id); agent.Abandon(id, cons); return ; } catch (System.FieldAccessException ex) { return ; // Ignore error } }
/// <summary> Formulates the extended operation, constraints into an /// LdapMessage and returns the LdapMessage. This is used by /// extendedOperation and startTLS which needs the LdapMessage to /// get the MessageID. /// </summary> protected internal virtual LdapMessage MakeExtendedOperation(LdapExtendedOperation op, LdapConstraints cons) { // Use default constraints if none-specified if (cons == null) cons = defSearchCons; // error check the parameters if ((System.Object) op.getID() == null) { // Invalid extended operation parameter, no OID specified throw new System.ArgumentException(ExceptionMessages.OP_PARAM_ERROR); } return new LdapExtendedRequest(op, cons.getControls()); }
internal virtual void Abandon(LdapConstraints cons, InterThreadException informUserEx) { if (!waitForReply_Renamed_Field) { return ; } acceptReplies = false; // don't listen to anyone waitForReply_Renamed_Field = false; // don't let sleeping threads lie if (!complete) { try { // If a bind, release bind semaphore & wake up waiting threads // Must do before writing abandon message, otherwise deadlock if (bindprops != null) { int id; if (conn.BindSemIdClear) { // Semaphore id for normal operations id = msgId; } else { // Semaphore id for sasl bind id = conn.BindSemId; conn.clearBindSemId(); } conn.freeWriteSemaphore(id); } // Create the abandon message, but don't track it. LdapControl[] cont = null; if (cons != null) { cont = cons.getControls(); } LdapMessage msg = new LdapAbandonRequest(msgId, cont); // Send abandon message to server conn.writeMessage(msg); } catch (LdapException ex) { ; // do nothing } // If not informing user, remove message from agent if (informUserEx == null) { agent.Abandon(msgId, null); } conn.removeMessage(this); } // Get rid of all replies queued if (informUserEx != null) { replies.Add(new LdapResponse(informUserEx, conn.ActiveReferral)); stopTimer(); // wake up waiting threads to receive exception sleepersAwake(); // Message will get cleaned up when last response removed from queue } else { // Wake up any waiting threads, so they can terminate. // If informing the user, we wake sleepers after // caller queues dummy response with error status sleepersAwake(); cleanup(); } return ; }
/// <summary> /// Synchronously makes a single change to an existing entry in the /// directory, using the specified constraints. /// /// For example, this modify method changes the value of an attribute, /// adds a new attribute value, or removes an existing attribute value. /// /// The LdapModification object specifies both the change to be /// made and the LdapAttribute value to be changed. /// /// If the request fails with {@link LdapException.CONNECT_ERROR}, /// it is indeterminate whether or not the server made the modification. /// /// </summary> /// <param name="dn"> The distinguished name of the entry to modify. /// /// </param> /// <param name="mod"> A single change to be made to the entry. /// /// </param> /// <param name="cons"> The constraints specific to the operation. /// /// </param> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual void Modify(System.String dn, LdapModification mod, LdapConstraints cons) { LdapModification[] mods = new LdapModification[1]; mods[0] = mod; Modify(dn, mods, cons); return ; }
/* * Synchronous Ldap extended request with SearchConstraints */ /// <summary> /// Provides a synchronous means to access extended, non-mandatory /// operations offered by a particular Ldapv3 compliant server. /// /// </summary> /// <param name="op"> The object which contains (1) an identifier of an extended /// operation which should be recognized by the particular Ldap /// server this client is connected to and (2) an /// operation-specific sequence of octet strings /// or BER-encoded values. /// /// </param> /// <param name="cons">The constraints specific to the operation. /// /// </param> /// <returns> An operation-specific object, containing an ID and either an /// octet string or BER-encoded values. /// /// </returns> /// <exception> LdapException A general exception which includes an error /// message and an Ldap error code. /// </exception> public virtual LdapExtendedResponse ExtendedOperation(LdapExtendedOperation op, LdapConstraints cons) { // Call asynchronous API and get back handler to reponse queue LdapResponseQueue queue = ExtendedOperation(op, cons, null); LdapExtendedResponse response = (LdapExtendedResponse) queue.getResponse(); // Set local copy of responseControls synchronously - if there were any lock (responseCtlSemaphore) { responseCtls = response.Controls; } chkResultCode(queue, cons, response); return response; }
private byte[] SendLdapSaslBindRequest(byte[] toWrite, string mechanism, BindProperties bindProps, LdapConstraints constraints) { constraints = constraints ?? _defSearchCons; var msg = new LdapSaslBindRequest(LdapV3, mechanism, constraints.GetControls(), toWrite); var queue = SendRequestToServer(msg, constraints.TimeLimit, null, bindProps); if (!(queue.GetResponse() is LdapResponse ldapResponse)) { throw new LdapException("Bind failure, no response received."); } var bindResponse = (RfcBindResponse)ldapResponse.Asn1Object.get_Renamed(1); lock (_responseCtlSemaphore) { _responseCtls = ldapResponse.Controls; } var serverCreds = bindResponse.ServerSaslCreds; var resultCode = ldapResponse.ResultCode; byte[] replyBuf = null; if (resultCode == LdapException.SaslBindInProgress || resultCode == LdapException.Success) { if (serverCreds != null) { replyBuf = serverCreds.ByteValue(); } } else { ldapResponse.ChkResultCode(); throw new LdapException("SASL Bind Error.", resultCode, null); } return(replyBuf); }