PageRenderTime 48ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://bitbucket.org/danipen/mono
C# | 862 lines | 513 code | 65 blank | 284 comment | 162 complexity | 83f94c2e00197e554b935747ae03dee3 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
  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.LdapUrl.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 ArrayEnumeration = Novell.Directory.Ldap.Utilclass.ArrayEnumeration;
  33. namespace Novell.Directory.Ldap
  34. {
  35. /// <summary>
  36. /// Encapsulates parameters of an Ldap URL query as defined in RFC2255.
  37. ///
  38. /// An LdapUrl object can be passed to LdapConnection.search to retrieve
  39. /// search results.
  40. ///
  41. /// </summary>
  42. /// <seealso cref="LdapConnection.Search">
  43. /// </seealso>
  44. public class LdapUrl : System.ICloneable
  45. {
  46. private void InitBlock()
  47. {
  48. scope = DEFAULT_SCOPE;
  49. }
  50. /// <summary> Returns an array of attribute names specified in the URL.
  51. ///
  52. /// </summary>
  53. /// <returns> An array of attribute names in the URL.
  54. /// </returns>
  55. virtual public System.String[] AttributeArray
  56. {
  57. get
  58. {
  59. return attrs;
  60. }
  61. }
  62. /// <summary> Returns an enumerator for the attribute names specified in the URL.
  63. ///
  64. /// </summary>
  65. /// <returns> An enumeration of attribute names.
  66. /// </returns>
  67. virtual public System.Collections.IEnumerator Attributes
  68. {
  69. get
  70. {
  71. return new ArrayEnumeration(attrs);
  72. }
  73. }
  74. /// <summary> Returns any Ldap URL extensions specified, or null if none are
  75. /// specified. Each extension is a type=value expression. The =value part
  76. /// MAY be omitted. The expression MAY be prefixed with '!' if it is
  77. /// mandatory for evaluation of the URL.
  78. ///
  79. /// </summary>
  80. /// <returns> string array of extensions.
  81. /// </returns>
  82. virtual public System.String[] Extensions
  83. {
  84. get
  85. {
  86. return extensions;
  87. }
  88. }
  89. /// <summary> Returns the search filter or <code>null</code> if none was specified.
  90. ///
  91. /// </summary>
  92. /// <returns> The search filter.
  93. /// </returns>
  94. virtual public System.String Filter
  95. {
  96. get
  97. {
  98. return filter;
  99. }
  100. }
  101. /// <summary> Returns the name of the Ldap server in the URL.
  102. ///
  103. /// </summary>
  104. /// <returns> The host name specified in the URL.
  105. /// </returns>
  106. virtual public System.String Host
  107. {
  108. get
  109. {
  110. return host;
  111. }
  112. }
  113. /// <summary> Returns the port number of the Ldap server in the URL.
  114. ///
  115. /// </summary>
  116. /// <returns> The port number in the URL.
  117. /// </returns>
  118. virtual public int Port
  119. {
  120. get
  121. {
  122. if (port == 0)
  123. {
  124. return LdapConnection.DEFAULT_PORT;
  125. }
  126. return port;
  127. }
  128. }
  129. /// <summary> Returns the depth of search. It returns one of the following from
  130. /// LdapConnection: SCOPE_BASE, SCOPE_ONE, or SCOPE_SUB.
  131. ///
  132. /// </summary>
  133. /// <returns> The search scope.
  134. /// </returns>
  135. virtual public int Scope
  136. {
  137. get
  138. {
  139. return scope;
  140. }
  141. }
  142. /// <summary> Returns true if the URL is of the type ldaps (Ldap over SSL, a predecessor
  143. /// to startTls)
  144. ///
  145. /// </summary>
  146. /// <returns> whether this is a secure Ldap url or not.
  147. /// </returns>
  148. virtual public bool Secure
  149. {
  150. get
  151. {
  152. return secure;
  153. }
  154. }
  155. private static readonly int DEFAULT_SCOPE = LdapConnection.SCOPE_BASE;
  156. // Broken out parts of the URL
  157. private bool secure = false; // URL scheme ldap/ldaps
  158. private bool ipV6 = false; // TCP/IP V6
  159. private System.String host = null; // Host
  160. private int port = 0; // Port
  161. private System.String dn = null; // Base DN
  162. private System.String[] attrs = null; // Attributes
  163. private System.String filter = null; // Filter
  164. private int scope; // Scope
  165. private System.String[] extensions = null; // Extensions
  166. /// <summary> Constructs a URL object with the specified string as the URL.
  167. ///
  168. /// </summary>
  169. /// <param name="url"> An Ldap URL string, e.g.
  170. /// "ldap://ldap.example.com:80/dc=example,dc=com?cn,
  171. /// sn?sub?(objectclass=inetOrgPerson)".
  172. ///
  173. /// </param>
  174. /// <exception> MalformedURLException The specified URL cannot be parsed.
  175. /// </exception>
  176. public LdapUrl(System.String url)
  177. {
  178. InitBlock();
  179. parseURL(url);
  180. return ;
  181. }
  182. /// <summary> Constructs a URL object with the specified host, port, and DN.
  183. ///
  184. /// This form is used to create URL references to a particular object
  185. /// in the directory.
  186. ///
  187. /// </summary>
  188. /// <param name="host"> Host identifier of Ldap server, or null for
  189. /// "localhost".
  190. ///
  191. /// </param>
  192. /// <param name="port"> The port number for Ldap server (use
  193. /// LdapConnection.DEFAULT_PORT for default port).
  194. ///
  195. /// </param>
  196. /// <param name="dn"> Distinguished name of the base object of the search.
  197. ///
  198. /// </param>
  199. public LdapUrl(System.String host, int port, System.String dn)
  200. {
  201. InitBlock();
  202. this.host = host;
  203. this.port = port;
  204. this.dn = dn;
  205. return ;
  206. }
  207. /// <summary> Constructs an Ldap URL with all fields explicitly assigned, to
  208. /// specify an Ldap search operation.
  209. ///
  210. /// </summary>
  211. /// <param name="host"> Host identifier of Ldap server, or null for
  212. /// "localhost".
  213. ///
  214. /// </param>
  215. /// <param name="port"> The port number for Ldap server (use
  216. /// LdapConnection.DEFAULT_PORT for default port).
  217. ///
  218. /// </param>
  219. /// <param name="dn"> Distinguished name of the base object of the search.
  220. ///
  221. ///
  222. /// </param>
  223. /// <param name="attrNames">Names or OIDs of attributes to retrieve. Passing a
  224. /// null array signifies that all user attributes are to be
  225. /// retrieved. Passing a value of "*" allows you to specify
  226. /// that all user attributes as well as any specified
  227. /// operational attributes are to be retrieved.
  228. ///
  229. ///
  230. /// </param>
  231. /// <param name="scope"> Depth of search (in DN namespace). Use one of
  232. /// SCOPE_BASE, SCOPE_ONE, SCOPE_SUB from LdapConnection.
  233. ///
  234. ///
  235. /// </param>
  236. /// <param name="filter"> The search filter specifying the search criteria.
  237. ///
  238. ///
  239. /// </param>
  240. /// <param name="extensions"> Extensions provide a mechanism to extend the
  241. /// functionality of Ldap URLs. Currently no
  242. /// Ldap URL extensions are defined. Each extension
  243. /// specification is a type=value expression, and may
  244. /// be <code>null</code> or empty. The =value part may be
  245. /// omitted. The expression may be prefixed with '!' if it
  246. /// is mandatory for the evaluation of the URL.
  247. /// </param>
  248. public LdapUrl(System.String host, int port, System.String dn, System.String[] attrNames, int scope, System.String filter, System.String[] extensions)
  249. {
  250. InitBlock();
  251. this.host = host;
  252. this.port = port;
  253. this.dn = dn;
  254. this.attrs = new System.String[attrNames.Length];
  255. attrNames.CopyTo(this.attrs, 0);
  256. this.scope = scope;
  257. this.filter = filter;
  258. this.extensions = new System.String[extensions.Length];
  259. extensions.CopyTo(this.extensions, 0);
  260. return ;
  261. }
  262. /// <summary> Constructs an Ldap URL with all fields explicitly assigned, including
  263. /// isSecure, to specify an Ldap search operation.
  264. ///
  265. /// </summary>
  266. /// <param name="host"> Host identifier of Ldap server, or null for
  267. /// "localhost".
  268. ///
  269. ///
  270. /// </param>
  271. /// <param name="port"> The port number for Ldap server (use
  272. /// LdapConnection.DEFAULT_PORT for default port).
  273. ///
  274. ///
  275. /// </param>
  276. /// <param name="dn"> Distinguished name of the base object of the search.
  277. ///
  278. ///
  279. /// </param>
  280. /// <param name="attrNames">Names or OIDs of attributes to retrieve. Passing a
  281. /// null array signifies that all user attributes are to be
  282. /// retrieved. Passing a value of "*" allows you to specify
  283. /// that all user attributes as well as any specified
  284. /// operational attributes are to be retrieved.
  285. ///
  286. ///
  287. /// </param>
  288. /// <param name="scope"> Depth of search (in DN namespace). Use one of
  289. /// SCOPE_BASE, SCOPE_ONE, SCOPE_SUB from LdapConnection.
  290. ///
  291. ///
  292. /// </param>
  293. /// <param name="filter"> The search filter specifying the search criteria.
  294. /// from LdapConnection: SCOPE_BASE, SCOPE_ONE, SCOPE_SUB.
  295. ///
  296. ///
  297. /// </param>
  298. /// <param name="extensions"> Extensions provide a mechanism to extend the
  299. /// functionality of Ldap URLs. Currently no
  300. /// Ldap URL extensions are defined. Each extension
  301. /// specification is a type=value expression, and may
  302. /// be <code>null</code> or empty. The =value part may be
  303. /// omitted. The expression may be prefixed with '!' if it
  304. /// is mandatory for the evaluation of the URL.
  305. ///
  306. ///
  307. /// </param>
  308. /// <param name="secure"> If true creates an Ldap URL of the ldaps type
  309. /// </param>
  310. public LdapUrl(System.String host, int port, System.String dn, System.String[] attrNames, int scope, System.String filter, System.String[] extensions, bool secure)
  311. {
  312. InitBlock();
  313. this.host = host;
  314. this.port = port;
  315. this.dn = dn;
  316. this.attrs = attrNames;
  317. this.scope = scope;
  318. this.filter = filter;
  319. this.extensions = new System.String[extensions.Length];
  320. extensions.CopyTo(this.extensions, 0);
  321. this.secure = secure;
  322. return ;
  323. }
  324. /// <summary> Returns a clone of this URL object.
  325. ///
  326. /// </summary>
  327. /// <returns> clone of this URL object.
  328. /// </returns>
  329. public System.Object Clone()
  330. {
  331. try
  332. {
  333. return base.MemberwiseClone();
  334. }
  335. catch (System.Exception ce)
  336. {
  337. throw new System.SystemException("Internal error, cannot create clone");
  338. }
  339. }
  340. /// <summary> Decodes a URL-encoded string.
  341. ///
  342. /// Any occurences of %HH are decoded to the hex value represented.
  343. /// However, this method does NOT decode "+" into " ".
  344. ///
  345. /// </summary>
  346. /// <param name="URLEncoded"> String to decode.
  347. ///
  348. /// </param>
  349. /// <returns> The decoded string.
  350. ///
  351. /// </returns>
  352. /// <exception> MalformedURLException The URL could not be parsed.
  353. /// </exception>
  354. public static System.String decode(System.String URLEncoded)
  355. {
  356. int searchStart = 0;
  357. int fieldStart;
  358. fieldStart = URLEncoded.IndexOf("%", searchStart);
  359. // Return now if no encoded data
  360. if (fieldStart < 0)
  361. {
  362. return URLEncoded;
  363. }
  364. // Decode the %HH value and copy to new string buffer
  365. int fieldEnd = 0; // end of previous field
  366. int dataLen = URLEncoded.Length;
  367. System.Text.StringBuilder decoded = new System.Text.StringBuilder(dataLen);
  368. while (true)
  369. {
  370. if (fieldStart > (dataLen - 3))
  371. {
  372. throw new System.UriFormatException("LdapUrl.decode: must be two hex characters following escape character '%'");
  373. }
  374. if (fieldStart < 0)
  375. fieldStart = dataLen;
  376. // Copy to string buffer from end of last field to start of next
  377. decoded.Append(URLEncoded.Substring(fieldEnd, (fieldStart) - (fieldEnd)));
  378. fieldStart += 1;
  379. if (fieldStart >= dataLen)
  380. break;
  381. fieldEnd = fieldStart + 2;
  382. try
  383. {
  384. decoded.Append((char) System.Convert.ToInt32(URLEncoded.Substring(fieldStart, (fieldEnd) - (fieldStart)), 16));
  385. }
  386. catch (System.FormatException ex)
  387. {
  388. throw new System.UriFormatException("LdapUrl.decode: error converting hex characters to integer \"" + ex.Message + "\"");
  389. }
  390. searchStart = fieldEnd;
  391. if (searchStart == dataLen)
  392. break;
  393. fieldStart = URLEncoded.IndexOf("%", searchStart);
  394. }
  395. return (decoded.ToString());
  396. }
  397. /// <summary> Encodes an arbitrary string using the URL encoding rules.
  398. ///
  399. /// Any illegal characters are encoded as %HH.
  400. ///
  401. /// </summary>
  402. /// <param name="toEncode"> The string to encode.
  403. ///
  404. /// </param>
  405. /// <returns> The URL-encoded string.
  406. ///
  407. /// Comment: An illegal character consists of any non graphical US-ASCII character, Unsafe, or reserved characters.
  408. /// </returns>
  409. public static System.String encode(System.String toEncode)
  410. {
  411. System.Text.StringBuilder buffer = new System.Text.StringBuilder(toEncode.Length); //empty but initial capicity of 'length'
  412. System.String temp;
  413. char currChar;
  414. for (int i = 0; i < toEncode.Length; i++)
  415. {
  416. currChar = toEncode[i];
  417. if ((((int) currChar <= 0x1F) || ((int) currChar == 0x7F) || (((int) currChar >= 0x80) && ((int) currChar <= 0xFF))) || ((currChar == '<') || (currChar == '>') || (currChar == '\"') || (currChar == '#') || (currChar == '%') || (currChar == '{') || (currChar == '}') || (currChar == '|') || (currChar == '\\') || (currChar == '^') || (currChar == '~') || (currChar == '[') || (currChar == '\'')) || ((currChar == ';') || (currChar == '/') || (currChar == '?') || (currChar == ':') || (currChar == '@') || (currChar == '=') || (currChar == '&')))
  418. {
  419. temp = System.Convert.ToString(currChar, 16);
  420. if (temp.Length == 1)
  421. buffer.Append("%0" + temp);
  422. //if(temp.length()==2) this can only be two or one digit long.
  423. else
  424. buffer.Append("%" + System.Convert.ToString(currChar, 16));
  425. }
  426. else
  427. buffer.Append(currChar);
  428. }
  429. return buffer.ToString();
  430. }
  431. /// <summary> Returns the base distinguished name encapsulated in the URL.
  432. ///
  433. /// </summary>
  434. /// <returns> The base distinguished name specified in the URL, or null if none.
  435. /// </returns>
  436. public virtual System.String getDN()
  437. {
  438. return dn;
  439. }
  440. /// <summary> Sets the base distinguished name encapsulated in the URL.</summary>
  441. /* package */
  442. internal virtual void setDN(System.String dn)
  443. {
  444. this.dn = dn;
  445. return ;
  446. }
  447. /// <summary> Returns a valid string representation of this Ldap URL.
  448. ///
  449. /// </summary>
  450. /// <returns> The string representation of the Ldap URL.
  451. /// </returns>
  452. public override System.String ToString()
  453. {
  454. System.Text.StringBuilder url = new System.Text.StringBuilder(256);
  455. // Scheme
  456. if (secure)
  457. {
  458. url.Append("ldaps://");
  459. }
  460. else
  461. {
  462. url.Append("ldap://");
  463. }
  464. // Host:port/dn
  465. if (ipV6)
  466. {
  467. url.Append("[" + host + "]");
  468. }
  469. else
  470. {
  471. url.Append(host);
  472. }
  473. // Port not specified
  474. if (port != 0)
  475. {
  476. url.Append(":" + port);
  477. }
  478. if (((System.Object) dn == null) && (attrs == null) && (scope == DEFAULT_SCOPE) && ((System.Object) filter == null) && (extensions == null))
  479. {
  480. return url.ToString();
  481. }
  482. url.Append("/");
  483. if ((System.Object) dn != null)
  484. {
  485. url.Append(dn);
  486. }
  487. if ((attrs == null) && (scope == DEFAULT_SCOPE) && ((System.Object) filter == null) && (extensions == null))
  488. {
  489. return url.ToString();
  490. }
  491. // attributes
  492. url.Append("?");
  493. if (attrs != null)
  494. {
  495. //should we check also for attrs != "*"
  496. for (int i = 0; i < attrs.Length; i++)
  497. {
  498. url.Append(attrs[i]);
  499. if (i < (attrs.Length - 1))
  500. {
  501. url.Append(",");
  502. }
  503. }
  504. }
  505. if ((scope == DEFAULT_SCOPE) && ((System.Object) filter == null) && (extensions == null))
  506. {
  507. return url.ToString();
  508. }
  509. // scope
  510. url.Append("?");
  511. if (scope != DEFAULT_SCOPE)
  512. {
  513. if (scope == LdapConnection.SCOPE_ONE)
  514. {
  515. url.Append("one");
  516. }
  517. else
  518. {
  519. url.Append("sub");
  520. }
  521. }
  522. if (((System.Object) filter == null) && (extensions == null))
  523. {
  524. return url.ToString();
  525. }
  526. // filter
  527. if ((System.Object) filter == null)
  528. {
  529. url.Append("?");
  530. }
  531. else
  532. {
  533. url.Append("?" + Filter);
  534. }
  535. if (extensions == null)
  536. {
  537. return url.ToString();
  538. }
  539. // extensions
  540. url.Append("?");
  541. if (extensions != null)
  542. {
  543. for (int i = 0; i < extensions.Length; i++)
  544. {
  545. url.Append(extensions[i]);
  546. if (i < (extensions.Length - 1))
  547. {
  548. url.Append(",");
  549. }
  550. }
  551. }
  552. return url.ToString();
  553. }
  554. private System.String[] parseList(System.String listStr, char delimiter, int listStart, int listEnd)
  555. // end of list + 1
  556. {
  557. System.String[] list;
  558. // Check for and empty string
  559. if ((listEnd - listStart) < 1)
  560. {
  561. return null;
  562. }
  563. // First count how many items are specified
  564. int itemStart = listStart;
  565. int itemEnd;
  566. int itemCount = 0;
  567. while (itemStart > 0)
  568. {
  569. // itemStart == 0 if no delimiter found
  570. itemCount += 1;
  571. itemEnd = listStr.IndexOf((System.Char) delimiter, itemStart);
  572. if ((itemEnd > 0) && (itemEnd < listEnd))
  573. {
  574. itemStart = itemEnd + 1;
  575. }
  576. else
  577. {
  578. break;
  579. }
  580. }
  581. // Now fill in the array with the attributes
  582. itemStart = listStart;
  583. list = new System.String[itemCount];
  584. itemCount = 0;
  585. while (itemStart > 0)
  586. {
  587. itemEnd = listStr.IndexOf((System.Char) delimiter, itemStart);
  588. if (itemStart <= listEnd)
  589. {
  590. if (itemEnd < 0)
  591. itemEnd = listEnd;
  592. if (itemEnd > listEnd)
  593. itemEnd = listEnd;
  594. list[itemCount] = listStr.Substring(itemStart, (itemEnd) - (itemStart));
  595. itemStart = itemEnd + 1;
  596. itemCount += 1;
  597. }
  598. else
  599. {
  600. break;
  601. }
  602. }
  603. return list;
  604. }
  605. private void parseURL(System.String url)
  606. {
  607. int scanStart = 0;
  608. int scanEnd = url.Length;
  609. if ((System.Object) url == null)
  610. throw new System.UriFormatException("LdapUrl: URL cannot be null");
  611. // Check if URL is enclosed by < & >
  612. if (url[scanStart] == '<')
  613. {
  614. if (url[scanEnd - 1] != '>')
  615. throw new System.UriFormatException("LdapUrl: URL bad enclosure");
  616. scanStart += 1;
  617. scanEnd -= 1;
  618. }
  619. // Determine the URL scheme and set appropriate default port
  620. if (url.Substring(scanStart, (scanStart + 4) - (scanStart)).ToUpper().Equals("URL:".ToUpper()))
  621. {
  622. scanStart += 4;
  623. }
  624. if (url.Substring(scanStart, (scanStart + 7) - (scanStart)).ToUpper().Equals("ldap://".ToUpper()))
  625. {
  626. scanStart += 7;
  627. port = LdapConnection.DEFAULT_PORT;
  628. }
  629. else if (url.Substring(scanStart, (scanStart + 8) - (scanStart)).ToUpper().Equals("ldaps://".ToUpper()))
  630. {
  631. secure = true;
  632. scanStart += 8;
  633. port = LdapConnection.DEFAULT_SSL_PORT;
  634. }
  635. else
  636. {
  637. throw new System.UriFormatException("LdapUrl: URL scheme is not ldap");
  638. }
  639. // Find where host:port ends and dn begins
  640. int dnStart = url.IndexOf("/", scanStart);
  641. int hostPortEnd = scanEnd;
  642. bool novell = false;
  643. if (dnStart < 0)
  644. {
  645. /*
  646. * Kludge. check for ldap://111.222.333.444:389??cn=abc,o=company
  647. *
  648. * Check for broken Novell referral format. The dn is in
  649. * the scope position, but the required slash is missing.
  650. * This is illegal syntax but we need to account for it.
  651. * Fortunately it can't be confused with anything real.
  652. */
  653. dnStart = url.IndexOf("?", scanStart);
  654. if (dnStart > 0)
  655. {
  656. if (url[dnStart + 1] == '?')
  657. {
  658. hostPortEnd = dnStart;
  659. dnStart += 1;
  660. novell = true;
  661. }
  662. else
  663. {
  664. dnStart = - 1;
  665. }
  666. }
  667. }
  668. else
  669. {
  670. hostPortEnd = dnStart;
  671. }
  672. // Check for IPV6 "[ipaddress]:port"
  673. int portStart;
  674. int hostEnd = hostPortEnd;
  675. if (url[scanStart] == '[')
  676. {
  677. hostEnd = url.IndexOf((System.Char) ']', scanStart + 1);
  678. if ((hostEnd >= hostPortEnd) || (hostEnd == - 1))
  679. {
  680. throw new System.UriFormatException("LdapUrl: \"]\" is missing on IPV6 host name");
  681. }
  682. // Get host w/o the [ & ]
  683. host = url.Substring(scanStart + 1, (hostEnd) - (scanStart + 1));
  684. portStart = url.IndexOf(":", hostEnd);
  685. if ((portStart < hostPortEnd) && (portStart != - 1))
  686. {
  687. // port is specified
  688. port = System.Int32.Parse(url.Substring(portStart + 1, (hostPortEnd) - (portStart + 1)));
  689. }
  690. else
  691. {
  692. }
  693. }
  694. else
  695. {
  696. portStart = url.IndexOf(":", scanStart);
  697. // Isolate the host and port
  698. if ((portStart < 0) || (portStart > hostPortEnd))
  699. {
  700. // no port is specified, we keep the default
  701. host = url.Substring(scanStart, (hostPortEnd) - (scanStart));
  702. }
  703. else
  704. {
  705. // port specified in URL
  706. host = url.Substring(scanStart, (portStart) - (scanStart));
  707. port = System.Int32.Parse(url.Substring(portStart + 1, (hostPortEnd) - (portStart + 1)));
  708. }
  709. }
  710. scanStart = hostPortEnd + 1;
  711. if ((scanStart >= scanEnd) || (dnStart < 0))
  712. return ;
  713. // Parse out the base dn
  714. scanStart = dnStart + 1;
  715. int attrsStart = url.IndexOf((System.Char) '?', scanStart);
  716. if (attrsStart < 0)
  717. {
  718. dn = url.Substring(scanStart, (scanEnd) - (scanStart));
  719. }
  720. else
  721. {
  722. dn = url.Substring(scanStart, (attrsStart) - (scanStart));
  723. }
  724. scanStart = attrsStart + 1;
  725. // Wierd novell syntax can have nothing beyond the dn
  726. if ((scanStart >= scanEnd) || (attrsStart < 0) || novell)
  727. return ;
  728. // Parse out the attributes
  729. int scopeStart = url.IndexOf((System.Char) '?', scanStart);
  730. if (scopeStart < 0)
  731. scopeStart = scanEnd - 1;
  732. attrs = parseList(url, ',', attrsStart + 1, scopeStart);
  733. scanStart = scopeStart + 1;
  734. if (scanStart >= scanEnd)
  735. return ;
  736. // Parse out the scope
  737. int filterStart = url.IndexOf((System.Char) '?', scanStart);
  738. System.String scopeStr;
  739. if (filterStart < 0)
  740. {
  741. scopeStr = url.Substring(scanStart, (scanEnd) - (scanStart));
  742. }
  743. else
  744. {
  745. scopeStr = url.Substring(scanStart, (filterStart) - (scanStart));
  746. }
  747. if (scopeStr.ToUpper().Equals("".ToUpper()))
  748. {
  749. scope = LdapConnection.SCOPE_BASE;
  750. }
  751. else if (scopeStr.ToUpper().Equals("base".ToUpper()))
  752. {
  753. scope = LdapConnection.SCOPE_BASE;
  754. }
  755. else if (scopeStr.ToUpper().Equals("one".ToUpper()))
  756. {
  757. scope = LdapConnection.SCOPE_ONE;
  758. }
  759. else if (scopeStr.ToUpper().Equals("sub".ToUpper()))
  760. {
  761. scope = LdapConnection.SCOPE_SUB;
  762. }
  763. else
  764. {
  765. throw new System.UriFormatException("LdapUrl: URL invalid scope");
  766. }
  767. scanStart = filterStart + 1;
  768. if ((scanStart >= scanEnd) || (filterStart < 0))
  769. return ;
  770. // Parse out the filter
  771. scanStart = filterStart + 1;
  772. System.String filterStr;
  773. int extStart = url.IndexOf((System.Char) '?', scanStart);
  774. if (extStart < 0)
  775. {
  776. filterStr = url.Substring(scanStart, (scanEnd) - (scanStart));
  777. }
  778. else
  779. {
  780. filterStr = url.Substring(scanStart, (extStart) - (scanStart));
  781. }
  782. if (!filterStr.Equals(""))
  783. {
  784. filter = filterStr; // Only modify if not the default filter
  785. }
  786. scanStart = extStart + 1;
  787. if ((scanStart >= scanEnd) || (extStart < 0))
  788. return ;
  789. // Parse out the extensions
  790. int end = url.IndexOf((System.Char) '?', scanStart);
  791. if (end > 0)
  792. throw new System.UriFormatException("LdapUrl: URL has too many ? fields");
  793. extensions = parseList(url, ',', scanStart, scanEnd);
  794. return ;
  795. }
  796. }
  797. }