PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapConnection.cs

https://bitbucket.org/danipen/mono
C# | 3977 lines | 1403 code | 279 blank | 2295 comment | 204 complexity | 7f94a346a1157c05f6fce05a193a72e1 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /******************************************************************************
  2. * The MIT License
  3. * Copyright (c) 2003 Novell Inc. www.novell.com
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the Software), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. * SOFTWARE.
  22. *******************************************************************************/
  23. //
  24. // Novell.Directory.Ldap.LdapConnection.cs
  25. //
  26. // Author:
  27. // Sunil Kumar (Sunilk@novell.com)
  28. //
  29. // (C) 2003 Novell, Inc (http://www.novell.com)
  30. //
  31. using System;
  32. using Novell.Directory.Ldap;
  33. using Novell.Directory.Ldap.Asn1;
  34. using Novell.Directory.Ldap.Rfc2251;
  35. using Novell.Directory.Ldap.Utilclass;
  36. #if !TARGET_JVM
  37. using Mono.Security.Protocol.Tls;
  38. #else
  39. using org.ietf.jgss;
  40. using javax.security.auth;
  41. using javax.security.auth.login;
  42. using java.security;
  43. using Novell.Directory.Ldap.Security;
  44. using System.Collections.Specialized;
  45. using System.Configuration;
  46. #endif
  47. using System.Security.Cryptography.X509Certificates;
  48. namespace Novell.Directory.Ldap
  49. {
  50. /// <summary> The central class that encapsulates the connection
  51. /// to a directory server through the Ldap protocol.
  52. /// LdapConnection objects are used to perform common Ldap
  53. /// operations such as search, modify and add.
  54. ///
  55. /// In addition, LdapConnection objects allow you to bind to an
  56. /// Ldap server, set connection and search constraints, and perform
  57. /// several other tasks.
  58. ///
  59. /// An LdapConnection object is not connected on
  60. /// construction and can only be connected to one server at one
  61. /// port. Multiple threads may share this single connection, typically
  62. /// by cloning the connection object, one for each thread. An
  63. /// application may have more than one LdapConnection object, connected
  64. /// to the same or different directory servers.
  65. ///
  66. ///
  67. /// </summary>
  68. public class LdapConnection : System.ICloneable
  69. {
  70. private void InitBlock()
  71. {
  72. defSearchCons = new LdapSearchConstraints();
  73. responseCtlSemaphore = new System.Object();
  74. }
  75. /// <summary> Returns the protocol version uses to authenticate.
  76. ///
  77. /// 0 is returned if no authentication has been performed.
  78. ///
  79. /// </summary>
  80. /// <returns> The protol version used for authentication or 0
  81. /// not authenticated.
  82. ///
  83. /// </returns>
  84. virtual public int ProtocolVersion
  85. {
  86. get
  87. {
  88. BindProperties prop = conn.BindProperties;
  89. if (prop == null)
  90. {
  91. return Ldap_V3;
  92. }
  93. return prop.ProtocolVersion;
  94. }
  95. }
  96. /// <summary> Returns the distinguished name (DN) used for as the bind name during
  97. /// the last successful bind operation. <code>null</code> is returned
  98. /// if no authentication has been performed or if the bind resulted in
  99. /// an aonymous connection.
  100. ///
  101. /// </summary>
  102. /// <returns> The distinguished name if authenticated; otherwise, null.
  103. ///
  104. /// </returns>
  105. virtual public System.String AuthenticationDN
  106. {
  107. get
  108. {
  109. BindProperties prop = conn.BindProperties;
  110. if (prop == null)
  111. {
  112. return null;
  113. }
  114. if (prop.Anonymous)
  115. {
  116. return null;
  117. }
  118. return prop.AuthenticationDN;
  119. }
  120. }
  121. /// <summary> Returns the method used to authenticate the connection. The return
  122. /// value is one of the following:
  123. ///
  124. /// <ul>
  125. /// <li>"none" indicates the connection is not authenticated.</li>
  126. ///
  127. ///
  128. /// <li>"simple" indicates simple authentication was used or that a null
  129. /// or empty authentication DN was specified.</li>
  130. ///
  131. /// <li>"sasl" indicates that a SASL mechanism was used to authenticate</li>
  132. /// </ul>
  133. ///
  134. /// </summary>
  135. /// <returns> The method used to authenticate the connection.
  136. /// </returns>
  137. virtual public System.String AuthenticationMethod
  138. {
  139. get
  140. {
  141. BindProperties prop = conn.BindProperties;
  142. if (prop == null)
  143. {
  144. return "simple";
  145. }
  146. return conn.BindProperties.AuthenticationMethod;
  147. }
  148. }
  149. /// <summary> Returns the properties if any specified on binding with a
  150. /// SASL mechanism.
  151. ///
  152. /// Null is returned if no authentication has been performed
  153. /// or no authentication Map is present.
  154. ///
  155. /// </summary>
  156. /// <returns> The bind properties Map Object used for SASL bind or null if
  157. /// the connection is not present or not authenticated.
  158. ///
  159. /// </returns>
  160. virtual public System.Collections.IDictionary SaslBindProperties
  161. {
  162. get
  163. {
  164. BindProperties prop = conn.BindProperties;
  165. if (prop == null)
  166. {
  167. return null;
  168. }
  169. return conn.BindProperties.SaslBindProperties;
  170. }
  171. }
  172. /// <summary> Returns the call back handler if any specified on binding with a
  173. /// SASL mechanism.
  174. ///
  175. /// Null is returned if no authentication has been performed
  176. /// or no authentication call back handler is present.
  177. ///
  178. /// </summary>
  179. /// <returns> The call back handler used for SASL bind or null if the
  180. /// object is not present or not authenticated.
  181. ///
  182. /// </returns>
  183. virtual public System.Object SaslBindCallbackHandler
  184. {
  185. get
  186. {
  187. BindProperties prop = conn.BindProperties;
  188. if (prop == null)
  189. {
  190. return null;
  191. }
  192. return conn.BindProperties.SaslCallbackHandler;
  193. }
  194. }
  195. /// <summary> Returns a copy of the set of constraints associated with this
  196. /// connection. These constraints apply to all operations performed
  197. /// through this connection (unless a different set of constraints is
  198. /// specified when calling an operation method).
  199. ///
  200. /// </summary>
  201. /// <returns> The set of default contraints that apply to this connection.
  202. ///
  203. /// </returns>
  204. /// <summary> Sets the constraints that apply to all operations performed through
  205. /// this connection (unless a different set of constraints is specified
  206. /// when calling an operation method). An LdapSearchConstraints object
  207. /// which is passed to this method sets all constraints, while an
  208. /// LdapConstraints object passed to this method sets only base constraints.
  209. ///
  210. /// </summary>
  211. /// <param name="cons"> An LdapConstraints or LdapSearchConstraints Object
  212. /// containing the contstraint values to set.
  213. ///
  214. /// </param>
  215. /// <seealso cref="Constraints()">
  216. /// </seealso>
  217. /// <seealso cref="SearchConstraints()">
  218. /// </seealso>
  219. virtual public LdapConstraints Constraints
  220. {
  221. get
  222. {
  223. return (LdapConstraints) (this.defSearchCons).Clone();
  224. }
  225. set
  226. {
  227. // Set all constraints, replace the object with a new one
  228. if (value is LdapSearchConstraints)
  229. {
  230. defSearchCons = (LdapSearchConstraints) value.Clone();
  231. return ;
  232. }
  233. // We set the constraints this way, so a thread doesn't get an
  234. // conconsistant view of the referrals.
  235. LdapSearchConstraints newCons = (LdapSearchConstraints) defSearchCons.Clone();
  236. newCons.HopLimit = value.HopLimit;
  237. newCons.TimeLimit = value.TimeLimit;
  238. newCons.setReferralHandler(value.getReferralHandler());
  239. newCons.ReferralFollowing = value.ReferralFollowing;
  240. LdapControl[] lsc = value.getControls();
  241. if (lsc != null)
  242. {
  243. newCons.setControls(lsc);
  244. }
  245. System.Collections.Hashtable lp = newCons.Properties;
  246. if (lp != null)
  247. {
  248. newCons.Properties = lp;
  249. }
  250. defSearchCons = newCons;
  251. return ;
  252. }
  253. }
  254. /// <summary> Returns the host name of the Ldap server to which the object is or
  255. /// was last connected, in the format originally specified.
  256. ///
  257. /// </summary>
  258. /// <returns> The host name of the Ldap server to which the object last
  259. /// connected or null if the object has never connected.
  260. ///
  261. /// </returns>
  262. virtual public System.String Host
  263. {
  264. get
  265. {
  266. return conn.Host;
  267. }
  268. }
  269. /// <summary> Returns the port number of the Ldap server to which the object is or
  270. /// was last connected.
  271. ///
  272. /// </summary>
  273. /// <returns> The port number of the Ldap server to which the object last
  274. /// connected or -1 if the object has never connected.
  275. ///
  276. /// </returns>
  277. virtual public int Port
  278. {
  279. get
  280. {
  281. return conn.Port;
  282. }
  283. }
  284. /// <summary> Returns a copy of the set of search constraints associated with this
  285. /// connection. These constraints apply to search operations performed
  286. /// through this connection (unless a different set of
  287. /// constraints is specified when calling the search operation method).
  288. ///
  289. /// </summary>
  290. /// <returns> The set of default search contraints that apply to
  291. /// this connection.
  292. ///
  293. /// </returns>
  294. /// <seealso cref="Constraints">
  295. /// </seealso>
  296. /// <seealso cref="LdapSearchConstraints">
  297. /// </seealso>
  298. virtual public LdapSearchConstraints SearchConstraints
  299. {
  300. get
  301. {
  302. return (LdapSearchConstraints) this.defSearchCons.Clone();
  303. }
  304. }
  305. ///<summary> Indicates whther the perform Secure Operation or not
  306. ///</summary>
  307. ///
  308. ///<returns>
  309. /// True if SSL is on
  310. /// False if its not on
  311. ///</returns>
  312. public bool SecureSocketLayer
  313. {
  314. get
  315. {
  316. return conn.Ssl;
  317. }
  318. set
  319. {
  320. conn.Ssl=value;
  321. }
  322. }
  323. /// <summary> Indicates whether the object has authenticated to the connected Ldap
  324. /// server.
  325. ///
  326. /// </summary>
  327. /// <returns> True if the object has authenticated; false if it has not
  328. /// authenticated.
  329. ///
  330. /// </returns>
  331. virtual public bool Bound
  332. {
  333. get
  334. {
  335. return conn.Bound;
  336. }
  337. }
  338. /// <summary> Indicates whether the connection represented by this object is open
  339. /// at this time.
  340. ///
  341. /// </summary>
  342. /// <returns> True if connection is open; false if the connection is closed.
  343. /// </returns>
  344. virtual public bool Connected
  345. {
  346. get
  347. {
  348. return conn.Connected;
  349. }
  350. }
  351. /// <summary> Indicatates if the connection is protected by TLS.
  352. ///
  353. /// </summary>
  354. /// <returns> If startTLS has completed this method returns true.
  355. /// If stopTLS has completed or start tls failed, this method returns false.
  356. /// </returns>
  357. /// <returns> True if the connection is protected by TLS.
  358. ///
  359. /// </returns>
  360. virtual public bool TLS
  361. {
  362. get
  363. {
  364. return conn.TLS;
  365. }
  366. }
  367. /// <summary> Returns the Server Controls associated with the most recent response
  368. /// to a synchronous request on this connection object, or null
  369. /// if the latest response contained no Server Controls. The method
  370. /// always returns null for asynchronous requests. For asynchronous
  371. /// requests, the response controls are available in LdapMessage.
  372. ///
  373. /// </summary>
  374. /// <returns> The server controls associated with the most recent response
  375. /// to a synchronous request or null if the response contains no server
  376. /// controls.
  377. ///
  378. /// </returns>
  379. /// <seealso cref="LdapMessage.Controls">
  380. /// </seealso>
  381. virtual public LdapControl[] ResponseControls
  382. {
  383. get
  384. {
  385. if (responseCtls == null)
  386. {
  387. return null;
  388. }
  389. // We have to clone the control just in case
  390. // we have two client threads that end up retreiving the
  391. // same control.
  392. LdapControl[] clonedControl = new LdapControl[responseCtls.Length];
  393. // Also note we synchronize access to the local response
  394. // control object just in case another message containing controls
  395. // comes in from the server while we are busy duplicating
  396. // this one.
  397. lock (responseCtlSemaphore)
  398. {
  399. for (int i = 0; i < responseCtls.Length; i++)
  400. {
  401. clonedControl[i] = (LdapControl) (responseCtls[i]).Clone();
  402. }
  403. }
  404. // Return the cloned copy. Note we have still left the
  405. // control in the local responseCtls variable just in case
  406. // somebody requests it again.
  407. return clonedControl;
  408. }
  409. }
  410. /// <summary> Return the Connection object associated with this LdapConnection
  411. ///
  412. /// </summary>
  413. /// <returns> the Connection object
  414. /// </returns>
  415. virtual internal Connection Connection
  416. {
  417. /* package */
  418. get
  419. {
  420. return conn;
  421. }
  422. }
  423. /// <summary> Return the Connection object name associated with this LdapConnection
  424. ///
  425. /// </summary>
  426. /// <returns> the Connection object name
  427. /// </returns>
  428. virtual internal System.String ConnectionName
  429. {
  430. /* package */
  431. get
  432. {
  433. return name;
  434. }
  435. }
  436. private LdapSearchConstraints defSearchCons;
  437. private LdapControl[] responseCtls = null;
  438. // Synchronization Object used to synchronize access to responseCtls
  439. private System.Object responseCtlSemaphore;
  440. private Connection conn = null;
  441. private static System.Object nameLock; // protect agentNum
  442. private static int lConnNum = 0; // Debug, LdapConnection number
  443. private System.String name; // String name for debug
  444. /// <summary> Used with search to specify that the scope of entrys to search is to
  445. /// search only the base obect.
  446. ///
  447. /// SCOPE_BASE = 0
  448. /// </summary>
  449. public const int SCOPE_BASE = 0;
  450. /// <summary> Used with search to specify that the scope of entrys to search is to
  451. /// search only the immediate subordinates of the base obect.
  452. ///
  453. /// SCOPE_ONE = 1
  454. /// </summary>
  455. public const int SCOPE_ONE = 1;
  456. /// <summary> Used with search to specify that the scope of entrys to search is to
  457. /// search the base object and all entries within its subtree.
  458. ///
  459. /// SCOPE_ONE = 2
  460. /// </summary>
  461. public const int SCOPE_SUB = 2;
  462. /// <summary> Used with search instead of an attribute list to indicate that no
  463. /// attributes are to be returned.
  464. ///
  465. /// NO_ATTRS = "1.1"
  466. /// </summary>
  467. public const System.String NO_ATTRS = "1.1";
  468. /// <summary> Used with search instead of an attribute list to indicate that all
  469. /// attributes are to be returned.
  470. ///
  471. /// ALL_USER_ATTRS = "*"
  472. /// </summary>
  473. public const System.String ALL_USER_ATTRS = "*";
  474. /// <summary> Specifies the Ldapv3 protocol version when performing a bind operation.
  475. ///
  476. /// Specifies Ldap version V3 of the protocol, and is specified
  477. /// when performing bind operations.
  478. /// You can use this identifier in the version parameter
  479. /// of the bind method to specify an Ldapv3 bind.
  480. /// Ldap_V3 is the default protocol version
  481. ///
  482. /// Ldap_V3 = 3
  483. ///
  484. /// </summary>
  485. public const int Ldap_V3 = 3;
  486. /// <summary> The default port number for Ldap servers.
  487. ///
  488. /// You can use this identifier to specify the port when establishing
  489. /// a clear text connection to a server. This the default port.
  490. ///
  491. /// DEFAULT_PORT = 389
  492. ///
  493. /// </summary>
  494. public const int DEFAULT_PORT = 389;
  495. /// <summary> The default SSL port number for Ldap servers.
  496. ///
  497. /// DEFAULT_SSL_PORT = 636
  498. ///
  499. /// You can use this identifier to specify the port when establishing
  500. /// a an SSL connection to a server..
  501. /// </summary>
  502. public const int DEFAULT_SSL_PORT = 636;
  503. /// <summary> A string that can be passed in to the getProperty method.
  504. ///
  505. /// Ldap_PROPERTY_SDK = "version.sdk"
  506. ///
  507. /// You can use this string to request the version of the SDK.
  508. /// </summary>
  509. public const System.String Ldap_PROPERTY_SDK = "version.sdk";
  510. /// <summary> A string that can be passed in to the getProperty method.
  511. ///
  512. /// Ldap_PROPERTY_PROTOCOL = "version.protocol"
  513. ///
  514. /// You can use this string to request the version of the
  515. /// Ldap protocol.
  516. /// </summary>
  517. public const System.String Ldap_PROPERTY_PROTOCOL = "version.protocol";
  518. /// <summary> A string that can be passed in to the getProperty method.
  519. ///
  520. /// Ldap_PROPERTY_SECURITY = "version.security"
  521. ///
  522. /// You can use this string to request the type of security
  523. /// being used.
  524. /// </summary>
  525. public const System.String Ldap_PROPERTY_SECURITY = "version.security";
  526. /// <summary> A string that corresponds to the server shutdown notification OID.
  527. /// This notification may be used by the server to advise the client that
  528. /// the server is about to close the connection due to an error
  529. /// condition.
  530. ///
  531. /// SERVER_SHUTDOWN_OID = "1.3.6.1.4.1.1466.20036"
  532. /// </summary>
  533. public const System.String SERVER_SHUTDOWN_OID = "1.3.6.1.4.1.1466.20036";
  534. /// <summary> The OID string that identifies a StartTLS request and response.</summary>
  535. private const System.String START_TLS_OID = "1.3.6.1.4.1.1466.20037";
  536. public event CertificateValidationCallback UserDefinedServerCertValidationDelegate
  537. {
  538. add
  539. {
  540. this.conn.OnCertificateValidation += value;
  541. }
  542. remove
  543. {
  544. this.conn.OnCertificateValidation -= value;
  545. }
  546. }
  547. /*
  548. * Constructors
  549. */
  550. /// <summary> Constructs a new LdapConnection object, which will use the supplied
  551. /// class factory to construct a socket connection during
  552. /// LdapConnection.connect method.
  553. ///
  554. /// </summary>
  555. /// <param name="factory"> An object capable of producing a Socket.
  556. ///
  557. /// </param>
  558. public LdapConnection()
  559. {
  560. InitBlock();
  561. // Get a unique connection name for debug
  562. conn = new Connection();
  563. return ;
  564. }
  565. /* public LdapConnection(X509Certificate cert)
  566. {
  567. InitBlock();
  568. // Get a unique connection name for debug
  569. conn = new Connection();
  570. conn.Cert = cert;
  571. return ;
  572. }
  573. */
  574. /*
  575. * The following are methods that affect the operation of
  576. * LdapConnection, but are not Ldap requests.
  577. */
  578. /// <summary> Returns a copy of the object with a private context, but sharing the
  579. /// network connection if there is one.
  580. ///
  581. /// The network connection remains open until all clones have
  582. /// disconnected or gone out of scope. Any connection opened after
  583. /// cloning is private to the object making the connection.
  584. ///
  585. /// The clone can issue requests and freely modify options and search
  586. /// constraints, and , without affecting the source object or other clones.
  587. /// If the clone disconnects or reconnects, it is completely dissociated
  588. /// from the source object and other clones. Reauthenticating in a clone,
  589. /// however, is a global operation which will affect the source object
  590. /// and all associated clones, because it applies to the single shared
  591. /// physical connection. Any request by an associated object after one
  592. /// has reauthenticated will carry the new identity.
  593. ///
  594. /// </summary>
  595. /// <returns> A of the object.
  596. /// </returns>
  597. public System.Object Clone()
  598. {
  599. LdapConnection newClone;
  600. System.Object newObj;
  601. try
  602. {
  603. newObj = base.MemberwiseClone();
  604. newClone = (LdapConnection) newObj;
  605. }
  606. catch (System.Exception ce)
  607. {
  608. throw new System.SystemException("Internal error, cannot create clone");
  609. }
  610. newClone.conn = conn; // same underlying connection
  611. //now just duplicate the defSearchCons and responseCtls
  612. if (defSearchCons != null)
  613. {
  614. newClone.defSearchCons = (LdapSearchConstraints) defSearchCons.Clone();
  615. }
  616. else
  617. {
  618. newClone.defSearchCons = null;
  619. }
  620. if (responseCtls != null)
  621. {
  622. newClone.responseCtls = new LdapControl[responseCtls.Length];
  623. for (int i = 0; i < responseCtls.Length; i++)
  624. {
  625. newClone.responseCtls[i] = (LdapControl) responseCtls[i].Clone();
  626. }
  627. }
  628. else
  629. {
  630. newClone.responseCtls = null;
  631. }
  632. conn.incrCloneCount(); // Increment the count of clones
  633. return newObj;
  634. }
  635. /// <summary> Closes the connection, if open, and releases any other resources held
  636. /// by the object.
  637. ///
  638. /// </summary>
  639. /// <exception> LdapException A general exception which includes an error
  640. /// message and an Ldap error code.
  641. ///
  642. /// </exception>
  643. /// <seealso cref="Disconnect">
  644. /// </seealso>
  645. ~LdapConnection()
  646. {
  647. // Disconnect did not come from user API call
  648. Disconnect(defSearchCons, false);
  649. return ;
  650. }
  651. /// <summary> Returns a property of a connection object.
  652. ///
  653. /// </summary>
  654. /// <param name="name"> Name of the property to be returned.
  655. ///
  656. /// The following read-only properties are available
  657. /// for any given connection:
  658. /// <ul>
  659. /// <li>Ldap_PROPERTY_SDK returns the version of this SDK,
  660. /// as a Float data type.</li>
  661. ///
  662. /// <li>Ldap_PROPERTY_PROTOCOL returns the highest supported version of
  663. /// the Ldap protocol, as a Float data type.</li>
  664. ///
  665. /// <li>Ldap_PROPERTY_SECURITY returns a comma-separated list of the
  666. /// types of authentication supported, as a
  667. /// string.</li>
  668. /// </ul>
  669. ///
  670. /// A deep copy of the property is provided where applicable; a
  671. /// client does not need to clone the object received.
  672. ///
  673. /// </param>
  674. /// <returns> The object associated with the requested property,
  675. /// or null if the property is not defined.
  676. ///
  677. /// </returns>
  678. /// <seealso cref="LdapConstraints.getProperty">
  679. /// </seealso>
  680. /// <seealso cref="Object">
  681. /// </seealso>
  682. public virtual System.Object getProperty(System.String name)
  683. {
  684. if (name.ToUpper().Equals(Ldap_PROPERTY_SDK.ToUpper()))
  685. return Connection.sdk;
  686. else if (name.ToUpper().Equals(Ldap_PROPERTY_PROTOCOL.ToUpper()))
  687. return Connection.protocol;
  688. else if (name.ToUpper().Equals(Ldap_PROPERTY_SECURITY.ToUpper()))
  689. return Connection.security;
  690. else
  691. {
  692. return null;
  693. }
  694. }
  695. /// <summary> Registers an object to be notified on arrival of an unsolicited
  696. /// message from a server.
  697. ///
  698. /// An unsolicited message has the ID 0. A new thread is created and
  699. /// the method "messageReceived" in each registered object is called in
  700. /// turn.
  701. ///
  702. /// </summary>
  703. /// <param name="listener"> An object to be notified on arrival of an
  704. /// unsolicited message from a server. This object must
  705. /// implement the LdapUnsolicitedNotificationListener interface.
  706. ///
  707. /// </param>
  708. public virtual void AddUnsolicitedNotificationListener(LdapUnsolicitedNotificationListener listener)
  709. {
  710. if (listener != null)
  711. conn.AddUnsolicitedNotificationListener(listener);
  712. }
  713. /// <summary> Deregisters an object so that it will no longer be notified on
  714. /// arrival of an unsolicited message from a server. If the object is
  715. /// null or was not previously registered for unsolicited notifications,
  716. /// the method does nothing.
  717. ///
  718. ///
  719. /// </summary>
  720. /// <param name="listener"> An object to no longer be notified on arrival of
  721. /// an unsolicited message from a server.
  722. ///
  723. /// </param>
  724. public virtual void RemoveUnsolicitedNotificationListener(LdapUnsolicitedNotificationListener listener)
  725. {
  726. if (listener != null)
  727. conn.RemoveUnsolicitedNotificationListener(listener);
  728. }
  729. /// <summary> Starts Transport Layer Security (TLS) protocol on this connection
  730. /// to enable session privacy.
  731. ///
  732. /// This affects the LdapConnection object and all cloned objects. A
  733. /// socket factory that implements LdapTLSSocketFactory must be set on the
  734. /// connection.
  735. ///
  736. /// </summary>
  737. /// <exception> LdapException Thrown if TLS cannot be started. If a
  738. /// SocketFactory has been specified that does not implement
  739. /// LdapTLSSocketFactory an LdapException is thrown.
  740. ///
  741. /// </exception>
  742. public virtual void startTLS()
  743. {
  744. LdapMessage startTLS = MakeExtendedOperation(new LdapExtendedOperation(LdapConnection.START_TLS_OID, null), null);
  745. int tlsID = startTLS.MessageID;
  746. conn.acquireWriteSemaphore(tlsID);
  747. try
  748. {
  749. if (!conn.areMessagesComplete())
  750. {
  751. throw new LdapLocalException(ExceptionMessages.OUTSTANDING_OPERATIONS, LdapException.OPERATIONS_ERROR);
  752. }
  753. // Stop reader when response to startTLS request received
  754. conn.stopReaderOnReply(tlsID);
  755. // send tls message
  756. LdapResponseQueue queue = SendRequestToServer(startTLS, defSearchCons.TimeLimit, null, null);
  757. LdapExtendedResponse response = (LdapExtendedResponse) queue.getResponse();
  758. response.chkResultCode();
  759. conn.startTLS();
  760. }
  761. finally
  762. {
  763. //Free this semaphore no matter what exceptions get thrown
  764. conn.startReader();
  765. conn.freeWriteSemaphore(tlsID);
  766. }
  767. return ;
  768. }
  769. /// <summary> Stops Transport Layer Security(TLS) on the LDAPConnection and reverts
  770. /// back to an anonymous state.
  771. ///
  772. /// @throws LDAPException This can occur for the following reasons:
  773. /// <UL>
  774. /// <LI>StartTLS has not been called before stopTLS</LI>
  775. /// <LI>There exists outstanding messages that have not received all
  776. /// responses</LI>
  777. /// <LI>The sever was not able to support the operation</LI></UL>
  778. ///
  779. /// <p>Note: The Sun and IBM implementions of JSSE do not currently allow
  780. /// stopping TLS on an open Socket. In order to produce the same results
  781. /// this method currently disconnects the socket and reconnects, giving
  782. /// the application an anonymous connection to the server, as required
  783. /// by StopTLS</p>
  784. /// </summary>
  785. public virtual void stopTLS()
  786. {
  787. if (!TLS)
  788. {
  789. throw new LdapLocalException(ExceptionMessages.NO_STARTTLS, LdapException.OPERATIONS_ERROR);
  790. }
  791. int semaphoreID = conn.acquireWriteSemaphore();
  792. try
  793. {
  794. if (!conn.areMessagesComplete())
  795. {
  796. throw new LdapLocalException(ExceptionMessages.OUTSTANDING_OPERATIONS, LdapException.OPERATIONS_ERROR);
  797. }
  798. //stopTLS stops and starts the reader thread for us.
  799. conn.stopTLS();
  800. }
  801. finally
  802. {
  803. conn.freeWriteSemaphore(semaphoreID);
  804. /* Now that the TLS socket is closed, reset everything. This next
  805. line is temporary until JSSE is fixed to properly handle TLS stop */
  806. this.Connect(this.Host, this.Port);
  807. }
  808. return ;
  809. }
  810. //*************************************************************************
  811. // Below are all of the Ldap protocol operation methods
  812. //*************************************************************************
  813. //*************************************************************************
  814. // abandon methods
  815. //*************************************************************************
  816. /// <summary>
  817. ///
  818. /// Notifies the server not to send additional results associated with
  819. /// this LdapSearchResults object, and discards any results already
  820. /// received.
  821. ///
  822. /// </summary>
  823. /// <param name="results"> An object returned from a search.
  824. ///
  825. /// </param>
  826. /// <exception> LdapException A general exception which includes an error
  827. /// message and an Ldap error code.
  828. /// </exception>
  829. public virtual void Abandon(LdapSearchResults results)
  830. {
  831. Abandon(results, defSearchCons);
  832. return ;
  833. }
  834. /// <summary>
  835. ///
  836. /// Notifies the server not to send additional results associated with
  837. /// this LdapSearchResults object, and discards any results already
  838. /// received.
  839. ///
  840. /// </summary>
  841. /// <param name="results"> An object returned from a search.
  842. ///
  843. /// </param>
  844. /// <param name="cons"> The contraints specific to the operation.
  845. ///
  846. /// </param>
  847. /// <exception> LdapException A general exception which includes an error
  848. /// message and an Ldap error code.
  849. /// </exception>
  850. public virtual void Abandon(LdapSearchResults results, LdapConstraints cons)
  851. {
  852. results.Abandon();
  853. return ;
  854. }
  855. /// <summary>
  856. /// Abandons an asynchronous operation.
  857. ///
  858. /// </summary>
  859. /// <param name="id"> The ID of the asynchronous operation to abandon. The ID
  860. /// can be obtained from the response queue for the
  861. /// operation.
  862. ///
  863. /// </param>
  864. /// <exception> LdapException A general exception which includes an error
  865. /// message and an Ldap error code.
  866. /// </exception>
  867. public virtual void Abandon(int id)
  868. {
  869. Abandon(id, defSearchCons);
  870. return ;
  871. }
  872. /// <summary> Abandons an asynchronous operation, using the specified
  873. /// constraints.
  874. ///
  875. /// </summary>
  876. /// <param name="id">The ID of the asynchronous operation to abandon.
  877. /// The ID can be obtained from the search
  878. /// queue for the operation.
  879. ///
  880. /// </param>
  881. /// <param name="cons">The contraints specific to the operation.
  882. ///
  883. /// </param>
  884. /// <exception> LdapException A general exception which includes an error
  885. /// message and an Ldap error code.
  886. /// </exception>
  887. public virtual void Abandon(int id, LdapConstraints cons)
  888. {
  889. // We need to inform the Message Agent which owns this messageID to
  890. // remove it from the queue.
  891. try
  892. {
  893. MessageAgent agent = conn.getMessageAgent(id);
  894. agent.Abandon(id, cons);
  895. return ;
  896. }
  897. catch (System.FieldAccessException ex)
  898. {
  899. return ; // Ignore error
  900. }
  901. }
  902. /// <summary> Abandons all outstanding operations managed by the queue.
  903. ///
  904. /// All operations in progress, which are managed by the specified queue,
  905. /// are abandoned.
  906. ///
  907. /// </summary>
  908. /// <param name="queue"> The queue returned from an asynchronous request.
  909. /// All outstanding operations managed by the queue
  910. /// are abandoned, and the queue is emptied.
  911. ///
  912. /// </param>
  913. /// <exception> LdapException A general exception which includes an error
  914. /// message and an Ldap error code.
  915. /// </exception>
  916. public virtual void Abandon(LdapMessageQueue queue)
  917. {
  918. Abandon(queue, defSearchCons);
  919. return ;
  920. }
  921. /// <summary> Abandons all outstanding operations managed by the queue.
  922. ///
  923. /// All operations in progress, which are managed by the specified
  924. /// queue, are abandoned.
  925. ///
  926. /// </summary>
  927. /// <param name="queue"> The queue returned from an asynchronous request.
  928. /// All outstanding operations managed by the queue
  929. /// are abandoned, and the queue is emptied.
  930. ///
  931. /// </param>
  932. /// <param name="cons"> The contraints specific to the operation.
  933. ///
  934. /// </param>
  935. /// <exception> LdapException A general exception which includes an error
  936. /// message and an Ldap error code.
  937. /// </exception>
  938. public virtual void Abandon(LdapMessageQueue queue, LdapConstraints cons)
  939. {
  940. if (queue != null)
  941. {
  942. MessageAgent agent;
  943. if (queue is LdapSearchQueue)
  944. {
  945. agent = queue.MessageAgent;
  946. }
  947. else
  948. {
  949. agent = queue.MessageAgent;
  950. }
  951. int[] msgIds = agent.MessageIDs;
  952. for (int i = 0; i < msgIds.Length; i++)
  953. {
  954. agent.Abandon(msgIds[i], cons);
  955. }
  956. }
  957. return ;
  958. }
  959. //*************************************************************************
  960. // add methods
  961. //*************************************************************************
  962. /// <summary> Synchronously adds an entry to the directory.
  963. ///
  964. /// </summary>
  965. /// <param name="entry"> LdapEntry object specifying the distinguished
  966. /// name and attributes of the new entry.
  967. ///
  968. /// </param>
  969. /// <exception> LdapException A general exception which includes an error
  970. /// message and an Ldap error code.
  971. /// </exception>
  972. public virtual void Add(LdapEntry entry)
  973. {
  974. Add(entry, defSearchCons);
  975. return ;
  976. }
  977. /// <summary>
  978. /// Synchronously adds an entry to the directory, using the specified
  979. /// constraints.
  980. ///
  981. /// </summary>
  982. /// <param name="entry"> LdapEntry object specifying the distinguished
  983. /// name and attributes of the new entry.
  984. ///
  985. /// </param>
  986. /// <param name="cons"> Constraints specific to the operation.
  987. ///
  988. /// </param>
  989. /// <exception> LdapException A general exception which includes an error
  990. /// message and an Ldap error code.
  991. /// </exception>
  992. public virtual void Add(LdapEntry entry, LdapConstraints cons)
  993. {
  994. LdapResponseQueue queue = Add(entry, null, cons);
  995. // Get a handle to the add response
  996. LdapResponse addResponse = (LdapResponse) (queue.getResponse());
  997. // Set local copy of responseControls synchronously if there were any
  998. lock (responseCtlSemaphore)
  999. {
  1000. responseCtls = addResponse.Controls;
  1001. }
  1002. chkResultCode(queue, cons, addResponse);
  1003. return ;
  1004. }
  1005. /// <summary> Asynchronously adds an entry to the directory.
  1006. ///
  1007. /// </summary>
  1008. /// <param name="entry"> LdapEntry object specifying the distinguished
  1009. /// name and attributes of the new entry.
  1010. ///
  1011. /// </param>
  1012. /// <param name="queue"> Handler for messages returned from a server in
  1013. /// response to this request. If it is null, a
  1014. /// queue object is created internally.
  1015. ///
  1016. /// </param>
  1017. /// <exception> LdapException A general exception which includes an error
  1018. /// message and an Ldap error code.
  1019. /// </exception>
  1020. public virtual LdapResponseQueue Add(LdapEntry entry, LdapResponseQueue queue)
  1021. {
  1022. return Add(entry, queue, defSearchCons);
  1023. }
  1024. /// <summary> Asynchronously adds an entry to the directory, using the specified
  1025. /// constraints.
  1026. ///
  1027. /// </summary>
  1028. /// <param name="entry"> LdapEntry object specifying the distinguished
  1029. /// name and attributes of the new entry.
  1030. ///
  1031. /// </param>
  1032. /// <param name="queue"> Handler for messages returned from a server in
  1033. /// response to this request. If it is null, a
  1034. /// queue object is created internally.
  1035. ///
  1036. /// </param>
  1037. /// <param name="cons"> Constraints specific to the operation.
  1038. ///
  1039. /// </param>
  1040. /// <exception> LdapException A general exception which includes an error
  1041. /// message and an Ldap error code.
  1042. /// </exception>
  1043. public virtual LdapResponseQueue Add(LdapEntry entry, LdapResponseQueue queue, LdapConstraints cons)
  1044. {
  1045. if (cons == null)
  1046. cons = defSearchCons;
  1047. // error check the parameters
  1048. if (entry == null)
  1049. {
  1050. throw new System.ArgumentException("The LdapEntry parameter" + " cannot be null");
  1051. }
  1052. if ((System.Object) entry.DN == null)
  1053. {
  1054. throw new System.ArgumentException("The DN value must be present" + " in the LdapEntry object");
  1055. }
  1056. LdapMessage msg = new LdapAddRequest(entry, cons.getControls());
  1057. return SendRequestToServer(msg, cons.TimeLimit, queue, null);
  1058. }
  1059. //*************************************************************************
  1060. // bind methods
  1061. //*************************************************************************
  1062. /// <summary> Synchronously authenticates to the Ldap server (that the object is
  1063. /// currently connected to) as an Ldapv3 bind, using the specified name and
  1064. /// password.
  1065. ///
  1066. /// If the object has been disconnected from an Ldap server,
  1067. /// this method attempts to reconnect to the server. If the object
  1068. /// has already authenticated, the old authentication is discarded.
  1069. ///
  1070. /// </summary>
  1071. /// <param name="dn"> If non-null and non-empty, specifies that the
  1072. /// connection and all operations through it should
  1073. /// be authenticated with dn as the distinguished
  1074. /// name.
  1075. ///
  1076. /// </param>
  1077. /// <param name="passwd"> If non-null and non-empty, specifies that the
  1078. /// connection and all operations through it should
  1079. /// be authenticated with dn as the distinguished
  1080. /// name and passwd as password.
  1081. ///
  1082. /// Note: the application should use care in the use
  1083. /// of String password objects. These are long lived
  1084. /// objects, and may expose a security risk, especially
  1085. /// in objects that are serialized. The LdapConnection
  1086. /// keeps no long lived instances of these objects.
  1087. ///
  1088. /// </param>
  1089. /// <exception> LdapException A general exception which includes an error
  1090. /// message and an Ldap error code.
  1091. ///
  1092. /// </exception>
  1093. public virtual void Bind(System.String dn, System.String passwd)
  1094. {
  1095. Bind(dn, passwd, AuthenticationTypes.None);
  1096. return ;
  1097. }
  1098. public virtual void Bind(System.String dn, System.String passwd, AuthenticationTypes authenticationTypes)
  1099. {
  1100. #if TARGET_JVM
  1101. if (authenticationTypes != AuthenticationTypes.None &&
  1102. authenticationTypes != AuthenticationTypes.ServerBind &&
  1103. authenticationTypes != AuthenticationTypes.Anonymous)
  1104. BindSecure(dn, passwd, authenticationTypes);
  1105. else
  1106. #endif
  1107. Bind(Ldap_V3, dn, passwd, defSearchCons);
  1108. return ;
  1109. }
  1110. /// <summary> Synchronously authenticates to the Ldap server (that the object is
  1111. /// currently connected to) using the specified name, password,
  1112. /// and Ldap version.
  1113. ///
  1114. /// If the object has been disconnected from an Ldap server,
  1115. /// this method attempts to reconnect to the server. If the object
  1116. /// has already authenticated, the old authentication is discarded.
  1117. ///
  1118. /// </summary>
  1119. /// <param name="version"> The Ldap protocol version, use Ldap_V3.
  1120. /// Ldap_V2 is not supported.
  1121. ///
  1122. /// </param>
  1123. /// <param name="dn"> If non-null and non-empty, specifies that the
  1124. /// connection and all operations through it should
  1125. /// be authenticated with dn as the distinguished
  1126. /// name.
  1127. ///
  1128. /// </param>
  1129. /// <param name="passwd"> If non-null and non-empty, specifies that the
  1130. /// connection and all operations through it should
  1131. /// be authenticated with dn as the distinguished
  1132. /// name and passwd as password.
  1133. ///
  1134. /// Note: the application should use care in the use
  1135. /// of String password objects. These are long lived
  1136. /// objects, and may expose a security risk, especially
  1137. /// in objects that are serialized. The LdapConnection
  1138. /// keeps no long lived instances of these objects.
  1139. ///
  1140. /// </param>
  1141. /// <exception> LdapException A general exception which includes an error
  1142. /// message and an Ldap error code.
  1143. ///
  1144. /// </exception>
  1145. public virtual void Bind(int version, System.String dn, System.String passwd)
  1146. {
  1147. Bind(version, dn, passwd, defSearchCons);
  1148. return ;
  1149. }
  1150. /// <summary> Synchronously authenticates to the Ldap server (that the object is
  1151. /// currently connected to) as an Ldapv3 bind, using the specified name,
  1152. /// password, and constraints.
  1153. ///
  1154. /// If the object has been disconnected from an Ldap server,
  1155. /// this method attempts to reconnect to the server. If the object
  1156. /// has already authenticated, the old authentication is discarded.
  1157. ///
  1158. /// </summary>
  1159. /// <param name="dn"> If non-null and non-empty, specifies that the
  1160. /// connection and all operations through it should
  1161. /// be authenticated with dn as the distinguished
  1162. /// name.
  1163. ///
  1164. /// </param>
  1165. /// <param name="passwd"> If non-null and non-empty, specifies that the
  1166. /// connection and all operations through it should
  1167. /// be authenticated with dn as the distinguished
  1168. /// name and passwd as password.
  1169. /// Note: the application should use care in the use
  1170. /// of String password objects. These are long lived
  1171. /// objects, and may expose a security risk, especially
  1172. /// in objects that are serialized. The LdapConnection
  1173. /// keeps no long lived instances of these objects.
  1174. ///
  1175. /// </param>
  1176. /// <param name="cons"> Constraints specific to the operation.
  1177. ///
  1178. /// </param>
  1179. /// <exception> LdapException A general exception which includes an error
  1180. /// message and an Ldap error code.
  1181. ///
  1182. /// </exception>
  1183. public virtual void Bind(System.String dn, System.String passwd, LdapConstraints cons)
  1184. {
  1185. Bind(Ldap_V3, dn, passwd, cons);
  1186. return ;
  1187. }
  1188. /// <summary> Synchronously authenticates to the Ldap server (that the object is
  1189. /// currently connected to) using the specified name, password, Ldap version,
  1190. /// and constraints.
  1191. ///
  1192. /// If the object has been disconnected from an Ldap server,
  1193. /// this method attempts to reconnect to the server. If the object
  1194. /// has already authenticated, the old authentication is discarded.
  1195. ///
  1196. /// </summary>
  1197. /// <param name="version"> The Ldap protocol version, use Ldap_V3.
  1198. /// Ldap_V2 is not supported.
  1199. ///
  1200. /// </param>
  1201. /// <param name="dn"> If non-null and non-empty, specifies that the
  1202. /// connection and all operations through it should
  1203. /// be authenticated with dn as the distinguished
  1204. /// name.
  1205. ///
  1206. /// </param>
  1207. /// <param name="passwd"> If non-null and non-empty, specifies that the
  1208. /// connection and all operations through it should
  1209. /// be authenticated with dn as the distinguished
  1210. /// name and passwd as password.
  1211. ///
  1212. /// Note: the application should use care in the use
  1213. /// of String password objects. These are long lived
  1214. /// objects, and may expose a security risk, especially
  1215. /// in objects that are serialized. The LdapConnection
  1216. /// keeps no long lived instances of these objects.
  1217. ///
  1218. /// </param>
  1219. /// <param name="cons"> The constraints specific to the operation.
  1220. ///
  1221. /// </param>
  1222. /// <exception> LdapException A general exception which includes an error
  1223. /// message and an Ldap error code.
  1224. ///
  1225. /// </exception>
  1226. public virtual void Bind(int version, System.String dn, System.String passwd, LdapConstraints cons)
  1227. {
  1228. sbyte[] pw = null;
  1229. if ((System.Object) passwd != null)
  1230. {
  1231. try
  1232. {
  1233. System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
  1234. byte[] ibytes = encoder.GetBytes(passwd);
  1235. pw=SupportClass.ToSByteArray(ibytes);
  1236. // pw = passwd.getBytes("UTF8");
  1237. passwd = null; // Keep no reference to String object
  1238. }
  1239. catch (System.IO.IOException ex)
  1240. {
  1241. passwd = null; // Keep no reference to String object
  1242. throw new System.SystemException(ex.ToString());
  1243. }
  1244. }
  1245. Bind(version, dn, pw, cons);
  1246. return ;
  1247. }
  1248. /// <summary> Synchronously authenticates to the Ldap server (that the object is
  1249. /// currently connected to) using the specified name, password,
  1250. /// and Ldap version.
  1251. ///
  1252. /// If the object has been disconnected from an Ldap server,
  1253. /// this method attempts to reconnect to the server. If the object
  1254. /// has already authenticated, the old authentication is discarded.
  1255. ///
  1256. /// </summary>
  1257. /// <param name="version"> The version of the Ldap protocol to use
  1258. /// in the bind, use Ldap_V3. Ldap_V2 is not supported.
  1259. ///
  1260. /// </param>
  1261. /// <param name="dn"> If non-null and non-empty, specifies that the
  1262. /// connection and all operations through it should
  1263. /// be authenticated with dn as the distinguished
  1264. /// name.
  1265. ///
  1266. /// </param>
  1267. /// <param name="passwd"> If non-null and non-empty, specifies that the
  1268. /// connection and all operations through it should
  1269. /// be authenticated with dn as the distinguished
  1270. /// name and passwd as password.
  1271. ///
  1272. /// </param>
  1273. /// <exception> LdapException A general exception which includes an error
  1274. /// message and an Ldap error code.
  1275. /// </exception>
  1276. [CLSCompliantAttribute(false)]
  1277. public virtual void Bind(int version, System.String dn, sbyte[] passwd)
  1278. {
  1279. Bind(version, dn, passwd, defSearchCons);
  1280. return ;
  1281. }
  1282. /// <summary>
  1283. /// Synchronously authenticates to the Ldap server (that the object is
  1284. /// currently connected to) using the specified name, password, Ldap version,
  1285. /// and constraints.
  1286. ///
  1287. /// If the object has been disconnected from an Ldap server,
  1288. /// this method attempts to reconnect to the server. If the object
  1289. /// has already authenticated, the old authentication is discarded.
  1290. ///
  1291. /// </summary>
  1292. /// <param name="version"> The Ldap protocol version, use Ldap_V3.
  1293. /// Ldap_V2 is not supported.
  1294. ///
  1295. /// </param>
  1296. /// <param name="dn"> If non-null and non-empty, specifies that the
  1297. /// connection and all operations through it should
  1298. /// be authenticated with dn as the distinguished
  1299. /// name.
  1300. ///
  1301. /// </param>
  1302. /// <param name="passwd"> If non-null and non-empty, specifies that the
  1303. /// connection and all operations through it should
  1304. /// be authenticated with dn as the distinguished
  1305. /// name and passwd as password.
  1306. ///
  1307. /// </param>
  1308. /// <param name="cons"> The constraints specific to the operation.
  1309. ///
  1310. /// </param>
  1311. /// <exception> LdapException A general exception which includes an error
  1312. /// message and an Ldap error code.
  1313. /// </exception>
  1314. [CLSCompliantAttribute(false)]
  1315. public virtual void Bind(int version, System.String dn, sbyte[] passwd, LdapConstraints cons)
  1316. {
  1317. LdapResponseQueue queue = Bind(version, dn, passwd, null, cons, null);
  1318. LdapResponse res = (LdapResponse) queue.getResponse();
  1319. if (res != null)
  1320. {
  1321. // Set local copy of responseControls synchronously if any
  1322. lock (responseCtlSemaphore)
  1323. {
  1324. responseCtls = res.Controls;
  1325. }
  1326. chkResultCode(queue, cons, res);
  1327. }
  1328. return ;
  1329. }
  1330. /// <summary> Asynchronously authenticates to the Ldap server (that the object is
  1331. /// currently connected to) using the specified name, password, Ldap
  1332. /// version, and queue.
  1333. ///
  1334. /// If the object has been disconnected from an Ldap server,
  1335. /// this method attempts to reconnect to the server. If the object
  1336. /// has already authenticated, the old authentication is discarded.
  1337. ///
  1338. ///
  1339. /// </summary>
  1340. /// <param name="version"> The Ldap protocol version, use Ldap_V3.
  1341. /// Ldap_V2 is not supported.
  1342. ///
  1343. /// </param>
  1344. /// <param name="dn"> If non-null and non-empty, specifies that the
  1345. /// connection and all operations through it should
  1346. /// be authenticated with dn as the distinguished
  1347. /// name.
  1348. ///
  1349. /// </param>
  1350. /// <param name="passwd"> If non-null and non-empty, specifies that the
  1351. /// connection and all operations through it should
  1352. /// be authenticated with dn as the distinguished
  1353. /// name and passwd as password.
  1354. ///
  1355. /// </param>
  1356. /// <param name="queue"> Handler for messages returned from a server in
  1357. /// response to this request. If it is null, a
  1358. /// queue object is created internally.
  1359. ///
  1360. /// </param>
  1361. /// <exception> LdapException A general exception which includes an error
  1362. /// message and an Ldap error code.
  1363. /// </exception>
  1364. [CLSCompliantAttribute(false)]
  1365. public virtual LdapResponseQueue Bind(int version, System.String dn, sbyte[] passwd, LdapResponseQueue queue)
  1366. {
  1367. return Bind(version, dn, passwd, queue, defSearchCons, null);
  1368. }
  1369. /// <summary> Asynchronously authenticates to the Ldap server (that the object is
  1370. /// currently connected to) using the specified name, password, Ldap
  1371. /// version, queue, and constraints.
  1372. ///
  1373. /// If the object has been disconnected from an Ldap server,
  1374. /// this method attempts to reconnect to the server. If the object
  1375. /// had already authenticated, the old authentication is discarded.
  1376. ///
  1377. /// </summary>
  1378. /// <param name="version"> The Ldap protocol version, use Ldap_V3.
  1379. /// Ldap_V2 is not supported.
  1380. ///
  1381. /// </param>
  1382. /// <param name="dn"> If non-null and non-empty, specifies that the
  1383. /// connection and all operations through it should
  1384. /// be authenticated with dn as the distinguished
  1385. /// name.
  1386. ///
  1387. /// </param>
  1388. /// <param name="passwd"> If non-null and non-empty, specifies that the
  1389. /// connection and all operations through it should
  1390. /// be authenticated with dn as the distinguished
  1391. /// name and passwd as password.
  1392. ///
  1393. /// </param>
  1394. /// <param name="queue"> Handler for messages returned from a server in
  1395. /// response to this request. If it is null, a
  1396. /// queue object is created internally.
  1397. ///
  1398. /// </param>
  1399. /// <param name="cons"> Constraints specific to the operation.
  1400. ///
  1401. /// </param>
  1402. /// <exception> LdapException A general exception which includes an error
  1403. /// message and an Ldap error code.
  1404. /// </exception>
  1405. [CLSCompliantAttribute(false)]
  1406. public virtual LdapResponseQueue Bind(int version, System.String dn, sbyte[] passwd, LdapResponseQueue queue, LdapConstraints cons, string mech)
  1407. {
  1408. int msgId;
  1409. BindProperties bindProps;
  1410. if (cons == null)
  1411. cons = defSearchCons;
  1412. if ((System.Object) dn == null)
  1413. {
  1414. dn = "";
  1415. }
  1416. else
  1417. {
  1418. dn = dn.Trim();
  1419. }
  1420. if (passwd == null)
  1421. passwd = new sbyte[]{};
  1422. bool anonymous = false;
  1423. if (pa

Large files files are truncated, but you can click here to view the full file