001/* 002 * Copyright 2009-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2009-2020 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2009-2020 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.migrate.ldapjdk; 037 038 039 040import com.unboundid.asn1.ASN1OctetString; 041import com.unboundid.ldap.sdk.AddRequest; 042import com.unboundid.ldap.sdk.AsyncRequestID; 043import com.unboundid.ldap.sdk.BindResult; 044import com.unboundid.ldap.sdk.CompareRequest; 045import com.unboundid.ldap.sdk.CompareResult; 046import com.unboundid.ldap.sdk.Control; 047import com.unboundid.ldap.sdk.DeleteRequest; 048import com.unboundid.ldap.sdk.DereferencePolicy; 049import com.unboundid.ldap.sdk.ExtendedRequest; 050import com.unboundid.ldap.sdk.ExtendedResult; 051import com.unboundid.ldap.sdk.Filter; 052import com.unboundid.ldap.sdk.InternalSDKHelper; 053import com.unboundid.ldap.sdk.LDAPConnectionOptions; 054import com.unboundid.ldap.sdk.LDAPResult; 055import com.unboundid.ldap.sdk.Modification; 056import com.unboundid.ldap.sdk.ModifyDNRequest; 057import com.unboundid.ldap.sdk.ModifyRequest; 058import com.unboundid.ldap.sdk.ResultCode; 059import com.unboundid.ldap.sdk.SearchRequest; 060import com.unboundid.ldap.sdk.SearchResult; 061import com.unboundid.ldap.sdk.SearchScope; 062import com.unboundid.ldap.sdk.SimpleBindRequest; 063import com.unboundid.ldap.sdk.UpdatableLDAPRequest; 064import com.unboundid.util.Debug; 065import com.unboundid.util.Mutable; 066import com.unboundid.util.NotExtensible; 067import com.unboundid.util.ThreadSafety; 068import com.unboundid.util.ThreadSafetyLevel; 069 070 071 072/** 073 * This class provides an object that may be used to communicate with an LDAP 074 * directory server. 075 * <BR><BR> 076 * This class is primarily intended to be used in the process of updating 077 * applications which use the Netscape Directory SDK for Java to switch to or 078 * coexist with the UnboundID LDAP SDK for Java. For applications not written 079 * using the Netscape Directory SDK for Java, the 080 * {@link com.unboundid.ldap.sdk.LDAPConnection} class should be used instead. 081 */ 082@Mutable() 083@NotExtensible() 084@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 085public class LDAPConnection 086{ 087 /** 088 * The integer value for the DEREF_NEVER dereference policy. 089 */ 090 public static final int DEREF_NEVER = DereferencePolicy.NEVER.intValue(); 091 092 093 094 /** 095 * The integer value for the DEREF_SEARCHING dereference policy. 096 */ 097 public static final int DEREF_SEARCHING = 098 DereferencePolicy.SEARCHING.intValue(); 099 100 101 102 /** 103 * The integer value for the DEREF_FINDING dereference policy. 104 */ 105 public static final int DEREF_FINDING = 106 DereferencePolicy.FINDING.intValue(); 107 108 109 110 /** 111 * The integer value for the DEREF_ALWAYS dereference policy. 112 */ 113 public static final int DEREF_ALWAYS = 114 DereferencePolicy.ALWAYS.intValue(); 115 116 117 118 /** 119 * The integer value for the SCOPE_BASE search scope. 120 */ 121 public static final int SCOPE_BASE = SearchScope.BASE_INT_VALUE; 122 123 124 125 /** 126 * The integer value for the SCOPE_ONE search scope. 127 */ 128 public static final int SCOPE_ONE = SearchScope.ONE_INT_VALUE; 129 130 131 132 /** 133 * The integer value for the SCOPE_SUB search scope. 134 */ 135 public static final int SCOPE_SUB = SearchScope.SUB_INT_VALUE; 136 137 138 139 // The connection used to perform the actual communication with the server. 140 private volatile com.unboundid.ldap.sdk.LDAPConnection conn; 141 142 // The default constraints that will be used for non-search operations. 143 private LDAPConstraints constraints; 144 145 // The set of controls returned from the last operation. 146 private LDAPControl[] responseControls; 147 148 // The default constraints that will be used for search operations. 149 private LDAPSearchConstraints searchConstraints; 150 151 // The socket factory for this connection. 152 private LDAPSocketFactory socketFactory; 153 154 // The DN last used to bind to the server. 155 private String authDN; 156 157 // The password last used to bind to the server. 158 private String authPW; 159 160 161 162 /** 163 * Creates a new LDAP connection which will use the default socket factory. 164 */ 165 public LDAPConnection() 166 { 167 this(null); 168 } 169 170 171 172 /** 173 * Creates a new LDAP connection which will use the provided socket factory. 174 * 175 * @param socketFactory The socket factory to use when creating the socket 176 * to use for communicating with the server. 177 */ 178 public LDAPConnection(final LDAPSocketFactory socketFactory) 179 { 180 this.socketFactory = socketFactory; 181 if (socketFactory == null) 182 { 183 conn = new com.unboundid.ldap.sdk.LDAPConnection(); 184 } 185 else 186 { 187 188 conn = new com.unboundid.ldap.sdk.LDAPConnection( 189 new LDAPToJavaSocketFactory(socketFactory)); 190 } 191 192 authDN = null; 193 authPW = null; 194 195 constraints = new LDAPConstraints(); 196 searchConstraints = new LDAPSearchConstraints(); 197 } 198 199 200 201 /** 202 * Closes the connection to the server if the client forgets to do so. 203 * 204 * @throws Throwable If a problem occurs. 205 */ 206 @Override() 207 protected void finalize() 208 throws Throwable 209 { 210 conn.close(); 211 212 super.finalize(); 213 } 214 215 216 217 /** 218 * Retrieves the {@link com.unboundid.ldap.sdk.LDAPConnection} object used to 219 * back this connection. 220 * 221 * @return The {@code com.unboundid.ldap.sdk.LDAPConnection} object used to 222 * back this connection. 223 */ 224 public com.unboundid.ldap.sdk.LDAPConnection getSDKConnection() 225 { 226 return conn; 227 } 228 229 230 231 /** 232 * Retrieves the address to which the connection is established. 233 * 234 * @return The address to which the connection is established. 235 */ 236 public String getHost() 237 { 238 return conn.getConnectedAddress(); 239 } 240 241 242 243 /** 244 * Retrieves the port to which the connection is established. 245 * 246 * @return The port to which the connection is established. 247 */ 248 public int getPort() 249 { 250 return conn.getConnectedPort(); 251 } 252 253 254 255 /** 256 * Retrieves the DN of the user that last authenticated on this connection. 257 * 258 * @return The DN of the user that last authenticated on this connection, 259 * or {@code null} if it is not available. 260 */ 261 public String getAuthenticationDN() 262 { 263 return authDN; 264 } 265 266 267 268 /** 269 * Retrieves the password of the user that last authenticated on this 270 * connection. 271 * 272 * @return The password of the user that last authenticated on this 273 * connection, or {@code null} if it is not available. 274 */ 275 public String getAuthenticationPassword() 276 { 277 return authPW; 278 } 279 280 281 282 /** 283 * Retrieves the maximum length of time to wait for the connection to be 284 * established, in seconds. 285 * 286 * @return The maximum length of time to wait for the connection to be 287 * established. 288 */ 289 public int getConnectTimeout() 290 { 291 final int connectTimeoutMillis = 292 conn.getConnectionOptions().getConnectTimeoutMillis(); 293 if (connectTimeoutMillis > 0) 294 { 295 return Math.max(1, (connectTimeoutMillis / 1000)); 296 } 297 else 298 { 299 return 0; 300 } 301 } 302 303 304 305 /** 306 * Specifies the maximum length of time to wait for the connection to be 307 * established, in seconds. 308 * 309 * @param timeout The maximum length of time to wait for the connection to 310 * be established. 311 */ 312 public void setConnectTimeout(final int timeout) 313 { 314 final LDAPConnectionOptions options = conn.getConnectionOptions(); 315 316 if (timeout > 0) 317 { 318 options.setConnectTimeoutMillis(1000 * timeout); 319 } 320 else 321 { 322 options.setConnectTimeoutMillis(0); 323 } 324 325 conn.setConnectionOptions(options); 326 } 327 328 329 330 /** 331 * Retrieves the socket factory for this LDAP connection, if specified. 332 * 333 * @return The socket factory for this LDAP connection, or {@code null} if 334 * none has been provided. 335 */ 336 public LDAPSocketFactory getSocketFactory() 337 { 338 return socketFactory; 339 } 340 341 342 343 /** 344 * Sets the socket factory for this LDAP connection. 345 * 346 * @param socketFactory The socket factory for this LDAP connection. 347 */ 348 public void setSocketFactory(final LDAPSocketFactory socketFactory) 349 { 350 this.socketFactory = socketFactory; 351 352 if (socketFactory == null) 353 { 354 conn.setSocketFactory(null); 355 } 356 else 357 { 358 conn.setSocketFactory(new LDAPToJavaSocketFactory(socketFactory)); 359 } 360 } 361 362 363 364 /** 365 * Retrieves the constraints for this connection. 366 * 367 * @return The constraints for this connection. 368 */ 369 public LDAPConstraints getConstraints() 370 { 371 return constraints; 372 } 373 374 375 376 /** 377 * Updates the constraints for this connection. 378 * 379 * @param constraints The constraints for this connection. 380 */ 381 public void setConstraints(final LDAPConstraints constraints) 382 { 383 if (constraints == null) 384 { 385 this.constraints = new LDAPConstraints(); 386 } 387 else 388 { 389 this.constraints = constraints; 390 } 391 } 392 393 394 395 /** 396 * Retrieves the search constraints for this connection. 397 * 398 * @return The search constraints for this connection. 399 */ 400 public LDAPSearchConstraints getSearchConstraints() 401 { 402 return searchConstraints; 403 } 404 405 406 407 /** 408 * Updates the search constraints for this connection. 409 * 410 * @param searchConstraints The search constraints for this connection. 411 */ 412 public void setSearchConstraints( 413 final LDAPSearchConstraints searchConstraints) 414 { 415 if (searchConstraints == null) 416 { 417 this.searchConstraints = new LDAPSearchConstraints(); 418 } 419 else 420 { 421 this.searchConstraints = searchConstraints; 422 } 423 } 424 425 426 427 /** 428 * Retrieves the response controls from the last operation processed on this 429 * connection. 430 * 431 * @return The response controls from the last operation processed on this 432 * connection, or {@code null} if there were none. 433 */ 434 public LDAPControl[] getResponseControls() 435 { 436 return responseControls; 437 } 438 439 440 441 /** 442 * Indicates whether this connection is currently established. 443 * 444 * @return {@code true} if this connection is currently established, or 445 * {@code false} if not. 446 */ 447 public boolean isConnected() 448 { 449 return conn.isConnected(); 450 } 451 452 453 454 /** 455 * Attempts to establish this connection with the provided information. 456 * 457 * @param host The address of the server to which the connection should be 458 * established. 459 * @param port The port of the server to which the connection should be 460 * established. 461 * 462 * @throws LDAPException If a problem occurs while attempting to establish 463 * this connection. 464 */ 465 public void connect(final String host, final int port) 466 throws LDAPException 467 { 468 authDN = null; 469 authPW = null; 470 responseControls = null; 471 472 try 473 { 474 conn.close(); 475 if (socketFactory == null) 476 { 477 conn = new com.unboundid.ldap.sdk.LDAPConnection(host, port); 478 } 479 else 480 { 481 482 conn = new com.unboundid.ldap.sdk.LDAPConnection( 483 new LDAPToJavaSocketFactory(socketFactory), host, port); 484 } 485 } 486 catch (final com.unboundid.ldap.sdk.LDAPException le) 487 { 488 Debug.debugException(le); 489 throw new LDAPException(le); 490 } 491 } 492 493 494 495 /** 496 * Attempts to establish and authenticate this connection with the provided 497 * information. 498 * 499 * @param host The address of the server to which the connection should 500 * be established. 501 * @param port The port of the server to which the connection should be 502 * established. 503 * @param dn The DN to use to bind to the server. 504 * @param password The password to use to bind to the server. 505 * 506 * @throws LDAPException If a problem occurs while attempting to establish 507 * or authenticate this connection. If an exception 508 * is thrown, then the connection will not be 509 * established. 510 */ 511 public void connect(final String host, final int port, final String dn, 512 final String password) 513 throws LDAPException 514 { 515 connect(3, host, port, dn, password, null); 516 } 517 518 519 520 /** 521 * Attempts to establish and authenticate this connection with the provided 522 * information. 523 * 524 * @param host The address of the server to which the connection 525 * should be established. 526 * @param port The port of the server to which the connection should 527 * be established. 528 * @param dn The DN to use to bind to the server. 529 * @param password The password to use to bind to the server. 530 * @param constraints The constraints to use when processing the bind. 531 * 532 * @throws LDAPException If a problem occurs while attempting to establish 533 * or authenticate this connection. If an exception 534 * is thrown, then the connection will not be 535 * established. 536 */ 537 public void connect(final String host, final int port, final String dn, 538 final String password, final LDAPConstraints constraints) 539 throws LDAPException 540 { 541 connect(3, host, port, dn, password, constraints); 542 } 543 544 545 546 /** 547 * Attempts to establish and authenticate this connection with the provided 548 * information. 549 * 550 * @param version The LDAP protocol version to use for the connection. 551 * This will be ignored, since this implementation only 552 * supports LDAPv3. 553 * @param host The address of the server to which the connection should 554 * be established. 555 * @param port The port of the server to which the connection should be 556 * established. 557 * @param dn The DN to use to bind to the server. 558 * @param password The password to use to bind to the server. 559 * 560 * @throws LDAPException If a problem occurs while attempting to establish 561 * or authenticate this connection. If an exception 562 * is thrown, then the connection will not be 563 * established. 564 */ 565 public void connect(final int version, final String host, final int port, 566 final String dn, final String password) 567 throws LDAPException 568 { 569 connect(version, host, port, dn, password, null); 570 } 571 572 573 574 /** 575 * Attempts to establish and authenticate this connection with the provided 576 * information. 577 * 578 * @param version The LDAP protocol version to use for the connection. 579 * This will be ignored, since this implementation only 580 * supports LDAPv3. 581 * @param host The address of the server to which the connection 582 * should be established. 583 * @param port The port of the server to which the connection should 584 * be established. 585 * @param dn The DN to use to bind to the server. 586 * @param password The password to use to bind to the server. 587 * @param constraints The constraints to use when processing the bind. 588 * 589 * @throws LDAPException If a problem occurs while attempting to establish 590 * or authenticate this connection. If an exception 591 * is thrown, then the connection will not be 592 * established. 593 */ 594 public void connect(final int version, final String host, final int port, 595 final String dn, final String password, 596 final LDAPConstraints constraints) 597 throws LDAPException 598 { 599 connect(host, port); 600 601 try 602 { 603 if ((dn != null) && (password != null)) 604 { 605 bind(version, dn, password, constraints); 606 } 607 } 608 catch (final LDAPException le) 609 { 610 conn.close(); 611 throw le; 612 } 613 } 614 615 616 617 /** 618 * Unbinds and disconnects from the directory server. 619 * 620 * @throws LDAPException If a problem occurs. 621 */ 622 public void disconnect() 623 throws LDAPException 624 { 625 authDN = null; 626 authPW = null; 627 628 conn.close(); 629 if (socketFactory == null) 630 { 631 conn = new com.unboundid.ldap.sdk.LDAPConnection(); 632 } 633 else 634 { 635 636 conn = new com.unboundid.ldap.sdk.LDAPConnection( 637 new LDAPToJavaSocketFactory(socketFactory)); 638 } 639 } 640 641 642 643 /** 644 * Disconnects from the directory server and attempts to re-connect and 645 * re-authenticate. 646 * 647 * @throws LDAPException If a problem occurs. If an exception is thrown, 648 * the connection will have been closed. 649 */ 650 public void reconnect() 651 throws LDAPException 652 { 653 final String host = getHost(); 654 final int port = getPort(); 655 final String dn = authDN; 656 final String pw = authPW; 657 658 if ((dn == null) || (pw == null)) 659 { 660 connect(host, port); 661 } 662 else 663 { 664 connect(host, port, dn, pw); 665 } 666 } 667 668 669 670 /** 671 * Sends a request to abandon the request with the specified message ID. 672 * 673 * @param id The message ID of the operation to abandon. 674 * 675 * @throws LDAPException If a problem occurs while sending the request. 676 */ 677 public void abandon(final int id) 678 throws LDAPException 679 { 680 try 681 { 682 conn.abandon(InternalSDKHelper.createAsyncRequestID(id, conn), 683 getControls(null)); 684 } 685 catch (final com.unboundid.ldap.sdk.LDAPException le) 686 { 687 Debug.debugException(le); 688 throw new LDAPException(le); 689 } 690 } 691 692 693 694 /** 695 * Sends a request to abandon the provided search operation. 696 * 697 * @param searchResults The search results object for the search to abandon. 698 * 699 * @throws LDAPException If a problem occurs while sending the request. 700 */ 701 public void abandon(final LDAPSearchResults searchResults) 702 throws LDAPException 703 { 704 try 705 { 706 final AsyncRequestID requestID = searchResults.getAsyncRequestID(); 707 if (requestID != null) 708 { 709 searchResults.setAbandoned(); 710 conn.abandon(requestID); 711 } 712 else 713 { 714 // This should never happen. 715 throw new LDAPException( 716 "The search request has not been sent to the server", 717 LDAPException.PARAM_ERROR); 718 } 719 } 720 catch (final com.unboundid.ldap.sdk.LDAPException le) 721 { 722 Debug.debugException(le); 723 throw new LDAPException(le); 724 } 725 } 726 727 728 729 /** 730 * Adds the provided entry to the directory. 731 * 732 * @param entry The entry to be added. 733 * 734 * @throws LDAPException If a problem occurs while adding the entry. 735 */ 736 public void add(final LDAPEntry entry) 737 throws LDAPException 738 { 739 add(entry, null); 740 } 741 742 743 744 /** 745 * Adds the provided entry to the directory. 746 * 747 * @param entry The entry to be added. 748 * @param constraints The constraints to use for the add operation. 749 * 750 * @throws LDAPException If a problem occurs while adding the entry. 751 */ 752 public void add(final LDAPEntry entry, final LDAPConstraints constraints) 753 throws LDAPException 754 { 755 final AddRequest addRequest = new AddRequest(entry.toEntry()); 756 update(addRequest, constraints); 757 758 try 759 { 760 final LDAPResult result = conn.add(addRequest); 761 setResponseControls(result); 762 } 763 catch (final com.unboundid.ldap.sdk.LDAPException le) 764 { 765 Debug.debugException(le); 766 setResponseControls(le); 767 throw new LDAPException(le); 768 } 769 } 770 771 772 773 /** 774 * Authenticates to the directory server using a simple bind with the provided 775 * information. 776 * 777 * @param dn The DN of the user for the bind. 778 * @param password The password to use for the bind. 779 * 780 * @throws LDAPException If the bind attempt fails. 781 */ 782 public void authenticate(final String dn, final String password) 783 throws LDAPException 784 { 785 bind(3, dn, password, null); 786 } 787 788 789 790 /** 791 * Authenticates to the directory server using a simple bind with the provided 792 * information. 793 * 794 * @param dn The DN of the user for the bind. 795 * @param password The password to use for the bind. 796 * @param constraints The constraints to use for the bind operation. 797 * 798 * @throws LDAPException If the bind attempt fails. 799 */ 800 public void authenticate(final String dn, final String password, 801 final LDAPConstraints constraints) 802 throws LDAPException 803 { 804 bind(3, dn, password, constraints); 805 } 806 807 808 809 /** 810 * Authenticates to the directory server using a simple bind with the provided 811 * information. 812 * 813 * @param version The LDAP protocol version to use. This will be ignored, 814 * since this implementation only supports LDAPv3. 815 * @param dn The DN of the user for the bind. 816 * @param password The password to use for the bind. 817 * 818 * @throws LDAPException If the bind attempt fails. 819 */ 820 public void authenticate(final int version, final String dn, 821 final String password) 822 throws LDAPException 823 { 824 bind(version, dn, password, null); 825 } 826 827 828 829 /** 830 * Authenticates to the directory server using a simple bind with the provided 831 * information. 832 * 833 * @param version The LDAP protocol version to use. This will be 834 * ignored, since this implementation only supports 835 * LDAPv3. 836 * @param dn The DN of the user for the bind. 837 * @param password The password to use for the bind. 838 * @param constraints The constraints to use for the bind operation. 839 * 840 * @throws LDAPException If the bind attempt fails. 841 */ 842 public void authenticate(final int version, final String dn, 843 final String password, 844 final LDAPConstraints constraints) 845 throws LDAPException 846 { 847 bind(version, dn, password, constraints); 848 } 849 850 851 852 /** 853 * Authenticates to the directory server using a simple bind with the provided 854 * information. 855 * 856 * @param dn The DN of the user for the bind. 857 * @param password The password to use for the bind. 858 * 859 * @throws LDAPException If the bind attempt fails. 860 */ 861 public void bind(final String dn, final String password) 862 throws LDAPException 863 { 864 bind(3, dn, password, null); 865 } 866 867 868 869 /** 870 * Authenticates to the directory server using a simple bind with the provided 871 * information. 872 * 873 * @param dn The DN of the user for the bind. 874 * @param password The password to use for the bind. 875 * @param constraints The constraints to use for the bind operation. 876 * 877 * @throws LDAPException If the bind attempt fails. 878 */ 879 public void bind(final String dn, final String password, 880 final LDAPConstraints constraints) 881 throws LDAPException 882 { 883 bind(3, dn, password, constraints); 884 } 885 886 887 888 /** 889 * Authenticates to the directory server using a simple bind with the provided 890 * information. 891 * 892 * @param version The LDAP protocol version to use. This will be ignored, 893 * since this implementation only supports LDAPv3. 894 * @param dn The DN of the user for the bind. 895 * @param password The password to use for the bind. 896 * 897 * @throws LDAPException If the bind attempt fails. 898 */ 899 public void bind(final int version, final String dn, final String password) 900 throws LDAPException 901 { 902 bind(version, dn, password, null); 903 } 904 905 906 907 /** 908 * Authenticates to the directory server using a simple bind with the provided 909 * information. 910 * 911 * @param version The LDAP protocol version to use. This will be 912 * ignored, since this implementation only supports 913 * LDAPv3. 914 * @param dn The DN of the user for the bind. 915 * @param password The password to use for the bind. 916 * @param constraints The constraints to use for the bind operation. 917 * 918 * @throws LDAPException If the bind attempt fails. 919 */ 920 public void bind(final int version, final String dn, final String password, 921 final LDAPConstraints constraints) 922 throws LDAPException 923 { 924 final SimpleBindRequest bindRequest = 925 new SimpleBindRequest(dn, password, getControls(constraints)); 926 authDN = null; 927 authPW = null; 928 929 try 930 { 931 final BindResult bindResult = conn.bind(bindRequest); 932 setResponseControls(bindResult); 933 if (bindResult.getResultCode() == ResultCode.SUCCESS) 934 { 935 authDN = dn; 936 authPW = password; 937 } 938 } 939 catch (final com.unboundid.ldap.sdk.LDAPException le) 940 { 941 Debug.debugException(le); 942 setResponseControls(le); 943 throw new LDAPException(le); 944 } 945 } 946 947 948 949 /** 950 * Indicates whether the specified entry has the given attribute value. 951 * 952 * @param dn The DN of the entry to compare. 953 * @param attribute The attribute (which must have exactly one value) to use 954 * for the comparison. 955 * 956 * @return {@code true} if the compare matched the target entry, or 957 * {@code false} if not. 958 * 959 * @throws LDAPException If a problem occurs while processing the compare. 960 */ 961 public boolean compare(final String dn, final LDAPAttribute attribute) 962 throws LDAPException 963 { 964 return compare(dn, attribute, null); 965 } 966 967 968 969 /** 970 * Indicates whether the specified entry has the given attribute value. 971 * 972 * @param dn The DN of the entry to compare. 973 * @param attribute The attribute (which must have exactly one value) to 974 * use for the comparison. 975 * @param constraints The constraints to use for the compare operation. 976 * 977 * @return {@code true} if the compare matched the target entry, or 978 * {@code false} if not. 979 * 980 * @throws LDAPException If a problem occurs while processing the compare. 981 */ 982 public boolean compare(final String dn, final LDAPAttribute attribute, 983 final LDAPConstraints constraints) 984 throws LDAPException 985 { 986 final CompareRequest compareRequest = new CompareRequest(dn, 987 attribute.getName(), attribute.getByteValueArray()[0]); 988 update(compareRequest, constraints); 989 990 try 991 { 992 final CompareResult result = conn.compare(compareRequest); 993 setResponseControls(result); 994 return result.compareMatched(); 995 } 996 catch (final com.unboundid.ldap.sdk.LDAPException le) 997 { 998 Debug.debugException(le); 999 setResponseControls(le); 1000 throw new LDAPException(le); 1001 } 1002 } 1003 1004 1005 1006 /** 1007 * Removes an entry from the directory. 1008 * 1009 * @param dn The DN of the entry to delete. 1010 * 1011 * @throws LDAPException If a problem occurs while processing the delete. 1012 */ 1013 public void delete(final String dn) 1014 throws LDAPException 1015 { 1016 delete(dn, null); 1017 } 1018 1019 1020 1021 /** 1022 * Removes an entry from the directory. 1023 * 1024 * @param dn The DN of the entry to delete. 1025 * @param constraints The constraints to use for the delete operation. 1026 * 1027 * @throws LDAPException If a problem occurs while processing the delete. 1028 */ 1029 public void delete(final String dn, final LDAPConstraints constraints) 1030 throws LDAPException 1031 { 1032 final DeleteRequest deleteRequest = new DeleteRequest(dn); 1033 update(deleteRequest, constraints); 1034 1035 try 1036 { 1037 final LDAPResult result = conn.delete(deleteRequest); 1038 setResponseControls(result); 1039 } 1040 catch (final com.unboundid.ldap.sdk.LDAPException le) 1041 { 1042 Debug.debugException(le); 1043 setResponseControls(le); 1044 throw new LDAPException(le); 1045 } 1046 } 1047 1048 1049 1050 /** 1051 * Processes an extended operation in the directory. 1052 * 1053 * @param extendedOperation The extended operation to process. 1054 * 1055 * @return The result returned from the extended operation. 1056 * 1057 * @throws LDAPException If a problem occurs while processing the operation. 1058 */ 1059 public LDAPExtendedOperation extendedOperation( 1060 final LDAPExtendedOperation extendedOperation) 1061 throws LDAPException 1062 { 1063 return extendedOperation(extendedOperation, null); 1064 } 1065 1066 1067 1068 /** 1069 * Processes an extended operation in the directory. 1070 * 1071 * @param extendedOperation The extended operation to process. 1072 * @param constraints The constraints to use for the operation. 1073 * 1074 * @return The result returned from the extended operation. 1075 * 1076 * @throws LDAPException If a problem occurs while processing the operation. 1077 */ 1078 public LDAPExtendedOperation extendedOperation( 1079 final LDAPExtendedOperation extendedOperation, 1080 final LDAPConstraints constraints) 1081 throws LDAPException 1082 { 1083 final ExtendedRequest extendedRequest = new ExtendedRequest( 1084 extendedOperation.getID(), 1085 new ASN1OctetString(extendedOperation.getValue()), 1086 getControls(constraints)); 1087 1088 try 1089 { 1090 final ExtendedResult result = 1091 conn.processExtendedOperation(extendedRequest); 1092 setResponseControls(result); 1093 1094 if (result.getResultCode() != ResultCode.SUCCESS) 1095 { 1096 throw new LDAPException(result.getDiagnosticMessage(), 1097 result.getResultCode().intValue(), result.getDiagnosticMessage(), 1098 result.getMatchedDN()); 1099 } 1100 1101 final byte[] valueBytes; 1102 final ASN1OctetString value = result.getValue(); 1103 if (value == null) 1104 { 1105 valueBytes = null; 1106 } 1107 else 1108 { 1109 valueBytes = value.getValue(); 1110 } 1111 1112 return new LDAPExtendedOperation(result.getOID(), valueBytes); 1113 } 1114 catch (final com.unboundid.ldap.sdk.LDAPException le) 1115 { 1116 Debug.debugException(le); 1117 setResponseControls(le); 1118 throw new LDAPException(le); 1119 } 1120 } 1121 1122 1123 1124 /** 1125 * Modifies an entry in the directory. 1126 * 1127 * @param dn The DN of the entry to modify. 1128 * @param mod The modification to apply to the entry. 1129 * 1130 * @throws LDAPException If a problem occurs while processing the delete. 1131 */ 1132 public void modify(final String dn, final LDAPModification mod) 1133 throws LDAPException 1134 { 1135 modify(dn, new LDAPModification[] { mod }, null); 1136 } 1137 1138 1139 1140 /** 1141 * Modifies an entry in the directory. 1142 * 1143 * @param dn The DN of the entry to modify. 1144 * @param mods The modifications to apply to the entry. 1145 * 1146 * @throws LDAPException If a problem occurs while processing the delete. 1147 */ 1148 public void modify(final String dn, final LDAPModification[] mods) 1149 throws LDAPException 1150 { 1151 modify(dn, mods, null); 1152 } 1153 1154 1155 1156 /** 1157 * Modifies an entry in the directory. 1158 * 1159 * @param dn The DN of the entry to modify. 1160 * @param mod The modification to apply to the entry. 1161 * @param constraints The constraints to use for the modify operation. 1162 * 1163 * @throws LDAPException If a problem occurs while processing the delete. 1164 */ 1165 public void modify(final String dn, final LDAPModification mod, 1166 final LDAPConstraints constraints) 1167 throws LDAPException 1168 { 1169 modify(dn, new LDAPModification[] { mod }, constraints); 1170 } 1171 1172 1173 1174 /** 1175 * Modifies an entry in the directory. 1176 * 1177 * @param dn The DN of the entry to modify. 1178 * @param mods The modifications to apply to the entry. 1179 * @param constraints The constraints to use for the modify operation. 1180 * 1181 * @throws LDAPException If a problem occurs while processing the delete. 1182 */ 1183 public void modify(final String dn, final LDAPModification[] mods, 1184 final LDAPConstraints constraints) 1185 throws LDAPException 1186 { 1187 final Modification[] m = new Modification[mods.length]; 1188 for (int i=0; i < mods.length; i++) 1189 { 1190 m[i] = mods[i].toModification(); 1191 } 1192 1193 final ModifyRequest modifyRequest = new ModifyRequest(dn, m); 1194 update(modifyRequest, constraints); 1195 1196 try 1197 { 1198 final LDAPResult result = conn.modify(modifyRequest); 1199 setResponseControls(result); 1200 } 1201 catch (final com.unboundid.ldap.sdk.LDAPException le) 1202 { 1203 Debug.debugException(le); 1204 setResponseControls(le); 1205 throw new LDAPException(le); 1206 } 1207 } 1208 1209 1210 1211 /** 1212 * Modifies an entry in the directory. 1213 * 1214 * @param dn The DN of the entry to modify. 1215 * @param mods The modifications to apply to the entry. 1216 * 1217 * @throws LDAPException If a problem occurs while processing the delete. 1218 */ 1219 public void modify(final String dn, final LDAPModificationSet mods) 1220 throws LDAPException 1221 { 1222 modify(dn, mods.toArray(), null); 1223 } 1224 1225 1226 1227 /** 1228 * Modifies an entry in the directory. 1229 * 1230 * @param dn The DN of the entry to modify. 1231 * @param mods The modifications to apply to the entry. 1232 * @param constraints The constraints to use for the modify operation. 1233 * 1234 * @throws LDAPException If a problem occurs while processing the delete. 1235 */ 1236 public void modify(final String dn, final LDAPModificationSet mods, 1237 final LDAPConstraints constraints) 1238 throws LDAPException 1239 { 1240 modify(dn, mods.toArray(), constraints); 1241 } 1242 1243 1244 1245 /** 1246 * Retrieves an entry from the directory server. 1247 * 1248 * @param dn The DN of the entry to retrieve. 1249 * 1250 * @return The entry that was read. 1251 * 1252 * @throws LDAPException If a problem occurs while performing the search. 1253 */ 1254 public LDAPEntry read(final String dn) 1255 throws LDAPException 1256 { 1257 return read(dn, null, null); 1258 } 1259 1260 1261 1262 /** 1263 * Retrieves an entry from the directory server. 1264 * 1265 * @param dn The DN of the entry to retrieve. 1266 * @param constraints The constraints to use for the search operation. 1267 * 1268 * @return The entry that was read. 1269 * 1270 * @throws LDAPException If a problem occurs while performing the search. 1271 */ 1272 public LDAPEntry read(final String dn, 1273 final LDAPSearchConstraints constraints) 1274 throws LDAPException 1275 { 1276 return read(dn, null, constraints); 1277 } 1278 1279 1280 1281 /** 1282 * Retrieves an entry from the directory server. 1283 * 1284 * @param dn The DN of the entry to retrieve. 1285 * @param attrs The set of attributes to request. 1286 * 1287 * @return The entry that was read. 1288 * 1289 * @throws LDAPException If a problem occurs while performing the search. 1290 */ 1291 public LDAPEntry read(final String dn, final String[] attrs) 1292 throws LDAPException 1293 { 1294 return read(dn, attrs, null); 1295 } 1296 1297 1298 1299 /** 1300 * Retrieves an entry from the directory server. 1301 * 1302 * @param dn The DN of the entry to retrieve. 1303 * @param attrs The set of attributes to request. 1304 * @param constraints The constraints to use for the search operation. 1305 * 1306 * @return The entry that was read. 1307 * 1308 * @throws LDAPException If a problem occurs while performing the search. 1309 */ 1310 public LDAPEntry read(final String dn, final String[] attrs, 1311 final LDAPSearchConstraints constraints) 1312 throws LDAPException 1313 { 1314 final Filter filter = Filter.createORFilter( 1315 Filter.createPresenceFilter("objectClass"), 1316 Filter.createEqualityFilter("objectClass", "ldapSubentry")); 1317 1318 final SearchRequest searchRequest = 1319 new SearchRequest(dn, SearchScope.BASE, filter, attrs); 1320 update(searchRequest, constraints); 1321 1322 try 1323 { 1324 final SearchResult searchResult = conn.search(searchRequest); 1325 setResponseControls(searchResult); 1326 1327 if (searchResult.getEntryCount() != 1) 1328 { 1329 throw new LDAPException(null, LDAPException.NO_RESULTS_RETURNED); 1330 } 1331 1332 return new LDAPEntry(searchResult.getSearchEntries().get(0)); 1333 } 1334 catch (final com.unboundid.ldap.sdk.LDAPException le) 1335 { 1336 Debug.debugException(le); 1337 setResponseControls(le); 1338 throw new LDAPException(le); 1339 } 1340 } 1341 1342 1343 1344 /** 1345 * Alters the DN of an entry in the directory. 1346 * 1347 * @param dn The DN of the entry to modify. 1348 * @param newRDN The new RDN to use for the entry. 1349 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1350 * 1351 * @throws LDAPException If a problem occurs while processing the delete. 1352 */ 1353 public void rename(final String dn, final String newRDN, 1354 final boolean deleteOldRDN) 1355 throws LDAPException 1356 { 1357 rename(dn, newRDN, null, deleteOldRDN, null); 1358 } 1359 1360 1361 1362 /** 1363 * Alters the DN of an entry in the directory. 1364 * 1365 * @param dn The DN of the entry to modify. 1366 * @param newRDN The new RDN to use for the entry. 1367 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1368 * @param constraints The constraints to use for the modify operation. 1369 * 1370 * @throws LDAPException If a problem occurs while processing the delete. 1371 */ 1372 public void rename(final String dn, final String newRDN, 1373 final boolean deleteOldRDN, 1374 final LDAPConstraints constraints) 1375 throws LDAPException 1376 { 1377 rename(dn, newRDN, null, deleteOldRDN, constraints); 1378 } 1379 1380 1381 1382 /** 1383 * Alters the DN of an entry in the directory. 1384 * 1385 * @param dn The DN of the entry to modify. 1386 * @param newRDN The new RDN to use for the entry. 1387 * @param newParentDN The DN of the new parent, or {@code null} if it 1388 * should not be moved below a new parent. 1389 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1390 * 1391 * @throws LDAPException If a problem occurs while processing the delete. 1392 */ 1393 public void rename(final String dn, final String newRDN, 1394 final String newParentDN, final boolean deleteOldRDN) 1395 throws LDAPException 1396 { 1397 rename(dn, newRDN, newParentDN, deleteOldRDN, null); 1398 } 1399 1400 1401 1402 /** 1403 * Alters the DN of an entry in the directory. 1404 * 1405 * @param dn The DN of the entry to modify. 1406 * @param newRDN The new RDN to use for the entry. 1407 * @param newParentDN The DN of the new parent, or {@code null} if it 1408 * should not be moved below a new parent. 1409 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1410 * @param constraints The constraints to use for the modify operation. 1411 * 1412 * @throws LDAPException If a problem occurs while processing the delete. 1413 */ 1414 public void rename(final String dn, final String newRDN, 1415 final String newParentDN, final boolean deleteOldRDN, 1416 final LDAPConstraints constraints) 1417 throws LDAPException 1418 { 1419 final ModifyDNRequest modifyDNRequest = 1420 new ModifyDNRequest(dn, newRDN, deleteOldRDN, newParentDN); 1421 update(modifyDNRequest, constraints); 1422 1423 try 1424 { 1425 final LDAPResult result = conn.modifyDN(modifyDNRequest); 1426 setResponseControls(result); 1427 } 1428 catch (final com.unboundid.ldap.sdk.LDAPException le) 1429 { 1430 Debug.debugException(le); 1431 setResponseControls(le); 1432 throw new LDAPException(le); 1433 } 1434 } 1435 1436 1437 1438 /** 1439 * Processes a search in the directory server. 1440 * 1441 * @param baseDN The base DN for the search. 1442 * @param scope The scope for the search. 1443 * @param filter The filter for the search. 1444 * @param attributes The set of attributes to request. 1445 * @param typesOnly Indicates whether to return attribute types only or 1446 * both types and values. 1447 * 1448 * @return The entry that was read. 1449 * 1450 * @throws LDAPException If a problem occurs while performing the search. 1451 */ 1452 public LDAPSearchResults search(final String baseDN, final int scope, 1453 final String filter, final String[] attributes, 1454 final boolean typesOnly) 1455 throws LDAPException 1456 { 1457 return search(baseDN, scope, filter, attributes, typesOnly, null); 1458 } 1459 1460 1461 1462 /** 1463 * Processes a search in the directory server. 1464 * 1465 * @param baseDN The base DN for the search. 1466 * @param scope The scope for the search. 1467 * @param filter The filter for the search. 1468 * @param attributes The set of attributes to request. 1469 * @param typesOnly Indicates whether to return attribute types only or 1470 * both types and values. 1471 * @param constraints The constraints to use for the search operation. 1472 * 1473 * @return The entry that was read. 1474 * 1475 * @throws LDAPException If a problem occurs while performing the search. 1476 */ 1477 public LDAPSearchResults search(final String baseDN, final int scope, 1478 final String filter, final String[] attributes, 1479 final boolean typesOnly, final LDAPSearchConstraints constraints) 1480 throws LDAPException 1481 { 1482 final LDAPSearchResults results; 1483 final LDAPSearchConstraints c = 1484 (constraints == null) ? searchConstraints : constraints; 1485 results = new LDAPSearchResults(c.getTimeLimit()); 1486 1487 try 1488 { 1489 final SearchRequest searchRequest = new SearchRequest(results, baseDN, 1490 SearchScope.valueOf(scope), filter, attributes); 1491 1492 searchRequest.setDerefPolicy( 1493 DereferencePolicy.valueOf(c.getDereference())); 1494 searchRequest.setSizeLimit(c.getMaxResults()); 1495 searchRequest.setTimeLimitSeconds(c.getServerTimeLimit()); 1496 searchRequest.setTypesOnly(typesOnly); 1497 1498 update(searchRequest, constraints); 1499 1500 results.setAsyncRequestID(conn.asyncSearch(searchRequest)); 1501 return results; 1502 } 1503 catch (final com.unboundid.ldap.sdk.LDAPException le) 1504 { 1505 Debug.debugException(le); 1506 setResponseControls(le); 1507 throw new LDAPException(le); 1508 } 1509 } 1510 1511 1512 1513 /** 1514 * Retrieves the set of controls to use in a request. 1515 * 1516 * @param c The constraints to be applied. 1517 * 1518 * @return The set of controls to use in a request. 1519 */ 1520 private Control[] getControls(final LDAPConstraints c) 1521 { 1522 Control[] controls = null; 1523 if (c != null) 1524 { 1525 controls = LDAPControl.toControls(c.getServerControls()); 1526 } 1527 else if (constraints != null) 1528 { 1529 controls = LDAPControl.toControls(constraints.getServerControls()); 1530 } 1531 1532 if (controls == null) 1533 { 1534 return new Control[0]; 1535 } 1536 else 1537 { 1538 return controls; 1539 } 1540 } 1541 1542 1543 1544 /** 1545 * Updates the provided request to account for the given set of constraints. 1546 * 1547 * @param request The request to be updated. 1548 * @param constraints The constraints to be applied. 1549 */ 1550 private void update(final UpdatableLDAPRequest request, 1551 final LDAPConstraints constraints) 1552 { 1553 final LDAPConstraints c = 1554 (constraints == null) ? this.constraints : constraints; 1555 1556 request.setControls(LDAPControl.toControls(c.getServerControls())); 1557 request.setResponseTimeoutMillis(c.getTimeLimit()); 1558 request.setFollowReferrals(c.getReferrals()); 1559 } 1560 1561 1562 1563 /** 1564 * Sets the response controls for this connection. 1565 * 1566 * @param ldapResult The result containing the controls to use. 1567 */ 1568 private void setResponseControls(final LDAPResult ldapResult) 1569 { 1570 if (ldapResult.hasResponseControl()) 1571 { 1572 responseControls = 1573 LDAPControl.toLDAPControls(ldapResult.getResponseControls()); 1574 } 1575 else 1576 { 1577 responseControls = null; 1578 } 1579 } 1580 1581 1582 1583 /** 1584 * Sets the response controls for this connection. 1585 * 1586 * @param ldapException The exception containing the controls to use. 1587 */ 1588 private void setResponseControls( 1589 final com.unboundid.ldap.sdk.LDAPException ldapException) 1590 { 1591 if (ldapException.hasResponseControl()) 1592 { 1593 responseControls = 1594 LDAPControl.toLDAPControls(ldapException.getResponseControls()); 1595 } 1596 else 1597 { 1598 responseControls = null; 1599 } 1600 } 1601}