001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.server.core.api; 021 022 023import static org.apache.directory.api.ldap.model.message.ResultCodeEnum.processResponse; 024 025import java.io.IOException; 026import java.util.Collection; 027import java.util.Iterator; 028import java.util.List; 029 030import org.apache.directory.api.asn1.util.Oid; 031import org.apache.directory.api.ldap.codec.api.BinaryAttributeDetector; 032import org.apache.directory.api.ldap.codec.api.LdapApiService; 033import org.apache.directory.api.ldap.model.constants.SchemaConstants; 034import org.apache.directory.api.ldap.model.cursor.Cursor; 035import org.apache.directory.api.ldap.model.cursor.EmptyCursor; 036import org.apache.directory.api.ldap.model.cursor.EntryCursor; 037import org.apache.directory.api.ldap.model.cursor.SearchCursor; 038import org.apache.directory.api.ldap.model.entry.Attribute; 039import org.apache.directory.api.ldap.model.entry.DefaultModification; 040import org.apache.directory.api.ldap.model.entry.Entry; 041import org.apache.directory.api.ldap.model.entry.Modification; 042import org.apache.directory.api.ldap.model.entry.ModificationOperation; 043import org.apache.directory.api.ldap.model.entry.Value; 044import org.apache.directory.api.ldap.model.exception.LdapException; 045import org.apache.directory.api.ldap.model.exception.LdapNoPermissionException; 046import org.apache.directory.api.ldap.model.exception.LdapOperationException; 047import org.apache.directory.api.ldap.model.message.AbandonRequest; 048import org.apache.directory.api.ldap.model.message.AddRequest; 049import org.apache.directory.api.ldap.model.message.AddRequestImpl; 050import org.apache.directory.api.ldap.model.message.AddResponse; 051import org.apache.directory.api.ldap.model.message.AddResponseImpl; 052import org.apache.directory.api.ldap.model.message.AliasDerefMode; 053import org.apache.directory.api.ldap.model.message.BindRequest; 054import org.apache.directory.api.ldap.model.message.BindRequestImpl; 055import org.apache.directory.api.ldap.model.message.BindResponse; 056import org.apache.directory.api.ldap.model.message.BindResponseImpl; 057import org.apache.directory.api.ldap.model.message.CompareRequest; 058import org.apache.directory.api.ldap.model.message.CompareRequestImpl; 059import org.apache.directory.api.ldap.model.message.CompareResponse; 060import org.apache.directory.api.ldap.model.message.CompareResponseImpl; 061import org.apache.directory.api.ldap.model.message.Control; 062import org.apache.directory.api.ldap.model.message.DeleteRequest; 063import org.apache.directory.api.ldap.model.message.DeleteRequestImpl; 064import org.apache.directory.api.ldap.model.message.DeleteResponse; 065import org.apache.directory.api.ldap.model.message.DeleteResponseImpl; 066import org.apache.directory.api.ldap.model.message.ExtendedRequest; 067import org.apache.directory.api.ldap.model.message.ExtendedResponse; 068import org.apache.directory.api.ldap.model.message.LdapResult; 069import org.apache.directory.api.ldap.model.message.Message; 070import org.apache.directory.api.ldap.model.message.ModifyDnRequest; 071import org.apache.directory.api.ldap.model.message.ModifyDnRequestImpl; 072import org.apache.directory.api.ldap.model.message.ModifyDnResponse; 073import org.apache.directory.api.ldap.model.message.ModifyDnResponseImpl; 074import org.apache.directory.api.ldap.model.message.ModifyRequest; 075import org.apache.directory.api.ldap.model.message.ModifyRequestImpl; 076import org.apache.directory.api.ldap.model.message.ModifyResponse; 077import org.apache.directory.api.ldap.model.message.ModifyResponseImpl; 078import org.apache.directory.api.ldap.model.message.ResultCodeEnum; 079import org.apache.directory.api.ldap.model.message.ResultResponseRequest; 080import org.apache.directory.api.ldap.model.message.SearchRequest; 081import org.apache.directory.api.ldap.model.message.SearchRequestImpl; 082import org.apache.directory.api.ldap.model.message.SearchScope; 083import org.apache.directory.api.ldap.model.name.Dn; 084import org.apache.directory.api.ldap.model.name.Rdn; 085import org.apache.directory.api.ldap.model.schema.SchemaManager; 086import org.apache.directory.api.util.exception.NotImplementedException; 087import org.apache.directory.ldap.client.api.AbstractLdapConnection; 088import org.apache.directory.ldap.client.api.EntryCursorImpl; 089import org.apache.directory.ldap.client.api.SaslRequest; 090import org.apache.directory.server.core.api.interceptor.context.BindOperationContext; 091import org.slf4j.Logger; 092import org.slf4j.LoggerFactory; 093 094 095/** 096 * An implementation of LdapConnection based on the CoreSession. 097 * 098 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 099 */ 100public class LdapCoreSessionConnection extends AbstractLdapConnection 101{ 102 /** The logger for this class */ 103 private static final Logger LOG = LoggerFactory.getLogger( LdapCoreSessionConnection.class ); 104 105 /** the CoreSession object */ 106 private CoreSession session; 107 108 /** the session's DirectoryService */ 109 private DirectoryService directoryService; 110 111 112 public LdapCoreSessionConnection() 113 { 114 super(); 115 } 116 117 118 public LdapCoreSessionConnection( DirectoryService directoryService ) 119 { 120 super(); 121 setDirectoryService( directoryService ); 122 } 123 124 125 public LdapCoreSessionConnection( CoreSession session ) 126 { 127 super(); 128 this.session = session; 129 setDirectoryService( session.getDirectoryService() ); 130 131 // treat the session was already bound, hence increment the message ID 132 messageId.incrementAndGet(); 133 } 134 135 136 /** 137 * {@inheritDoc} 138 */ 139 @Override 140 public void close() throws IOException 141 { 142 try 143 { 144 unBind(); 145 } 146 catch ( Exception e ) 147 { 148 IOException ioe = new IOException( e.getMessage() ); 149 ioe.initCause( e ); 150 throw ioe; 151 } 152 } 153 154 155 /** 156 * {@inheritDoc} 157 */ 158 @Override 159 public boolean connect() throws LdapException 160 { 161 return true; 162 } 163 164 165 /** 166 * {@inheritDoc} 167 */ 168 @Override 169 public AddResponse add( AddRequest addRequest ) throws LdapException 170 { 171 if ( addRequest == null ) 172 { 173 String msg = "Cannot process a null addRequest"; 174 LOG.debug( msg ); 175 throw new IllegalArgumentException( msg ); 176 } 177 178 if ( addRequest.getEntry() == null ) 179 { 180 String msg = "Cannot add a null entry"; 181 LOG.debug( msg ); 182 throw new IllegalArgumentException( msg ); 183 } 184 185 int newId = messageId.incrementAndGet(); 186 187 addRequest.setMessageId( newId ); 188 189 AddResponse resp = new AddResponseImpl( newId ); 190 resp.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS ); 191 192 try 193 { 194 session.add( addRequest ); 195 } 196 catch ( LdapException e ) 197 { 198 LOG.warn( e.getMessage(), e ); 199 200 resp.getLdapResult().setResultCode( ResultCodeEnum.getResultCode( e ) ); 201 resp.getLdapResult().setDiagnosticMessage( e.getMessage() ); 202 } 203 204 addResponseControls( addRequest, resp ); 205 return resp; 206 } 207 208 209 /** 210 * {@inheritDoc} 211 */ 212 @Override 213 public void add( Entry entry ) throws LdapException 214 { 215 if ( entry == null ) 216 { 217 String msg = "Cannot add an empty entry"; 218 LOG.debug( msg ); 219 throw new IllegalArgumentException( msg ); 220 } 221 222 AddRequest addRequest = new AddRequestImpl(); 223 addRequest.setEntry( entry ); 224 addRequest.setEntryDn( entry.getDn() ); 225 226 AddResponse addResponse = add( addRequest ); 227 228 processResponse( addResponse ); 229 } 230 231 232 /** 233 * Process the SASL Bind. It's a dialog with the server, we will send a first BindRequest, receive 234 * a response and the, if this response is a challenge, continue by sending a new BindRequest with 235 * the requested informations. 236 * 237 * @param saslRequest The SASL request object containing all the needed parameters 238 * @return A {@link BindResponse} containing the result 239 * @throws LdapException if some error occurred 240 */ 241 @Override 242 public BindResponse bind( SaslRequest saslRequest ) throws LdapException 243 { 244 throw new NotImplementedException(); 245 } 246 247 248 /** 249 * {@inheritDoc} 250 */ 251 @Override 252 public CompareResponse compare( CompareRequest compareRequest ) throws LdapException 253 { 254 if ( compareRequest == null ) 255 { 256 String msg = "Cannot process a null compareRequest"; 257 LOG.debug( msg ); 258 throw new IllegalArgumentException( msg ); 259 } 260 261 int newId = messageId.incrementAndGet(); 262 263 CompareResponse resp = new CompareResponseImpl( newId ); 264 resp.getLdapResult().setResultCode( ResultCodeEnum.COMPARE_TRUE ); 265 266 try 267 { 268 session.compare( compareRequest ); 269 } 270 catch ( Exception e ) 271 { 272 resp.getLdapResult().setResultCode( ResultCodeEnum.getResultCode( e ) ); 273 } 274 275 addResponseControls( compareRequest, resp ); 276 return resp; 277 } 278 279 280 /** 281 * {@inheritDoc} 282 */ 283 @Override 284 public boolean compare( Dn dn, String attributeName, byte[] value ) throws LdapException 285 { 286 CompareRequest compareRequest = new CompareRequestImpl(); 287 compareRequest.setName( dn ); 288 compareRequest.setAttributeId( attributeName ); 289 compareRequest.setAssertionValue( value ); 290 291 CompareResponse compareResponse = compare( compareRequest ); 292 293 return processResponse( compareResponse ); 294 } 295 296 297 /** 298 * {@inheritDoc} 299 */ 300 @Override 301 public boolean compare( Dn dn, String attributeName, String value ) throws LdapException 302 { 303 CompareRequest compareRequest = new CompareRequestImpl(); 304 compareRequest.setName( dn ); 305 compareRequest.setAttributeId( attributeName ); 306 compareRequest.setAssertionValue( value ); 307 308 CompareResponse compareResponse = compare( compareRequest ); 309 310 return processResponse( compareResponse ); 311 } 312 313 314 /** 315 * {@inheritDoc} 316 */ 317 @Override 318 public boolean compare( String dn, String attributeName, byte[] value ) throws LdapException 319 { 320 return compare( new Dn( schemaManager, dn ), attributeName, value ); 321 } 322 323 324 /** 325 * {@inheritDoc} 326 */ 327 @Override 328 public boolean compare( String dn, String attributeName, String value ) throws LdapException 329 { 330 return compare( new Dn( schemaManager, dn ), attributeName, value ); 331 } 332 333 334 /** 335 * {@inheritDoc} 336 */ 337 @Override 338 public boolean compare( Dn dn, String attributeName, Value value ) throws LdapException 339 { 340 CompareRequest compareRequest = new CompareRequestImpl(); 341 compareRequest.setName( dn ); 342 compareRequest.setAttributeId( attributeName ); 343 344 if ( value.isHumanReadable() ) 345 { 346 compareRequest.setAssertionValue( value.getString() ); 347 } 348 else 349 { 350 compareRequest.setAssertionValue( value.getBytes() ); 351 } 352 353 CompareResponse compareResponse = compare( compareRequest ); 354 355 return processResponse( compareResponse ); 356 } 357 358 359 /** 360 * {@inheritDoc} 361 */ 362 @Override 363 public boolean compare( String dn, String attributeName, Value value ) throws LdapException 364 { 365 return compare( new Dn( schemaManager, dn ), attributeName, value ); 366 } 367 368 369 /** 370 * {@inheritDoc} 371 */ 372 @Override 373 public DeleteResponse delete( DeleteRequest deleteRequest ) throws LdapException 374 { 375 if ( deleteRequest == null ) 376 { 377 String msg = "Cannot process a null deleteRequest"; 378 LOG.debug( msg ); 379 throw new IllegalArgumentException( msg ); 380 } 381 382 int newId = messageId.incrementAndGet(); 383 384 DeleteResponse resp = new DeleteResponseImpl( newId ); 385 resp.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS ); 386 387 try 388 { 389 session.delete( deleteRequest ); 390 } 391 catch ( LdapException e ) 392 { 393 LOG.warn( e.getMessage(), e ); 394 395 resp.getLdapResult().setResultCode( ResultCodeEnum.getResultCode( e ) ); 396 resp.getLdapResult().setDiagnosticMessage( e.getMessage() ); 397 } 398 399 addResponseControls( deleteRequest, resp ); 400 401 return resp; 402 } 403 404 405 /** 406 * {@inheritDoc} 407 */ 408 @Override 409 public void delete( Dn dn ) throws LdapException 410 { 411 DeleteRequest deleteRequest = new DeleteRequestImpl(); 412 deleteRequest.setName( dn ); 413 414 DeleteResponse deleteResponse = delete( deleteRequest ); 415 416 processResponse( deleteResponse ); 417 } 418 419 420 /** 421 * {@inheritDoc} 422 */ 423 @Override 424 public void delete( String dn ) throws LdapException 425 { 426 delete( new Dn( schemaManager, dn ) ); 427 } 428 429 430 /** 431 * {@inheritDoc} 432 */ 433 @Override 434 public boolean isRequestCompleted( int messageId ) 435 { 436 return false; 437 } 438 439 440 /** 441 * {@inheritDoc} 442 */ 443 @Override 444 public boolean doesFutureExistFor( int messageId ) 445 { 446 return false; 447 } 448 449 450 /** 451 * {@inheritDoc} 452 */ 453 @Override 454 public SchemaManager getSchemaManager() 455 { 456 return schemaManager; 457 } 458 459 460 /** 461 * {@inheritDoc} 462 */ 463 @Override 464 public LdapApiService getCodecService() 465 { 466 return codec; 467 } 468 469 470 /** 471 * {@inheritDoc} 472 */ 473 @Override 474 public List<String> getSupportedControls() throws LdapException 475 { 476 return null; 477 } 478 479 480 /** 481 * {@inheritDoc} 482 */ 483 @Override 484 public boolean isAuthenticated() 485 { 486 return session != null; 487 } 488 489 490 /** 491 * {@inheritDoc} 492 */ 493 @Override 494 public boolean isConnected() 495 { 496 return true; 497 } 498 499 500 /** 501 * {@inheritDoc} 502 */ 503 @Override 504 public boolean isControlSupported( String controlOID ) throws LdapException 505 { 506 return false; 507 } 508 509 510 /** 511 * {@inheritDoc} 512 */ 513 @Override 514 public void loadSchema() throws LdapException 515 { 516 // do nothing, cause we already have SchemaManager in the session's DirectoryService 517 } 518 519 520 /** 521 * {@inheritDoc} 522 */ 523 @Override 524 public void loadSchemaRelaxed() throws LdapException 525 { 526 // do nothing, cause we already have SchemaManager in the session's DirectoryService 527 } 528 529 530 /** 531 * {@inheritDoc} 532 */ 533 @Override 534 public Entry lookup( Dn dn, String... attributes ) throws LdapException 535 { 536 return lookup( dn, null, attributes ); 537 } 538 539 540 /** 541 * {@inheritDoc} 542 */ 543 @Override 544 public Entry lookup( Dn dn, Control[] controls, String... attributes ) throws LdapException 545 { 546 messageId.incrementAndGet(); 547 548 Entry entry = null; 549 550 try 551 { 552 entry = session.lookup( dn, controls, attributes ); 553 } 554 catch ( LdapException e ) 555 { 556 LOG.warn( e.getMessage(), e ); 557 } 558 559 return entry; 560 } 561 562 563 /** 564 * {@inheritDoc} 565 */ 566 @Override 567 public Entry lookup( String dn, String... attributes ) throws LdapException 568 { 569 Dn baseDn = new Dn( schemaManager, dn ); 570 571 return lookup( baseDn, null, attributes ); 572 } 573 574 575 /** 576 * {@inheritDoc} 577 */ 578 @Override 579 public Entry lookup( String dn, Control[] controls, String... attributes ) throws LdapException 580 { 581 Dn baseDn = new Dn( schemaManager, dn ); 582 583 return lookup( baseDn, controls, attributes ); 584 } 585 586 587 /** 588 * {@inheritDoc} 589 */ 590 @Override 591 public boolean exists( String dn ) throws LdapException 592 { 593 return exists( new Dn( schemaManager, dn ) ); 594 } 595 596 597 /** 598 * {@inheritDoc} 599 */ 600 @Override 601 public boolean exists( Dn dn ) throws LdapException 602 { 603 try 604 { 605 Entry entry = lookup( dn, SchemaConstants.NO_ATTRIBUTE ); 606 607 return entry != null; 608 } 609 catch ( LdapNoPermissionException lnpe ) 610 { 611 // Special case to deal with insufficient permissions 612 LOG.info( lnpe.getMessage(), lnpe ); 613 614 return false; 615 } 616 catch ( LdapException le ) 617 { 618 throw le; 619 } 620 } 621 622 623 /** 624 * {@inheritDoc} 625 */ 626 @Override 627 public Entry getRootDse() throws LdapException 628 { 629 return lookup( Dn.ROOT_DSE, SchemaConstants.ALL_USER_ATTRIBUTES_ARRAY ); 630 } 631 632 633 /** 634 * {@inheritDoc} 635 */ 636 @Override 637 public Entry getRootDse( String... attributes ) throws LdapException 638 { 639 return lookup( Dn.ROOT_DSE, attributes ); 640 } 641 642 643 /** 644 * {@inheritDoc} 645 */ 646 @Override 647 public Entry lookup( Dn dn ) throws LdapException 648 { 649 return lookup( dn, ( String[] ) null ); 650 } 651 652 653 /** 654 * {@inheritDoc} 655 */ 656 @Override 657 public Entry lookup( String dn ) throws LdapException 658 { 659 return lookup( new Dn( schemaManager, dn ), ( String[] ) null ); 660 } 661 662 663 /** 664 * {@inheritDoc} 665 */ 666 @Override 667 public void modify( Dn dn, Modification... modifications ) throws LdapException 668 { 669 if ( dn == null ) 670 { 671 LOG.debug( "received a null dn for modification" ); 672 throw new IllegalArgumentException( "The Dn to be modified cannot be null" ); 673 } 674 675 if ( ( modifications == null ) || ( modifications.length == 0 ) ) 676 { 677 String msg = "Cannot process a ModifyRequest without any modification"; 678 LOG.debug( msg ); 679 throw new IllegalArgumentException( msg ); 680 } 681 682 int newId = messageId.incrementAndGet(); 683 684 ModifyRequest modifyRequest = new ModifyRequestImpl(); 685 modifyRequest.setMessageId( newId ); 686 687 modifyRequest.setName( dn ); 688 689 for ( Modification modification : modifications ) 690 { 691 modifyRequest.addModification( modification ); 692 } 693 694 ModifyResponse modifyResponse = modify( modifyRequest ); 695 696 processResponse( modifyResponse ); 697 } 698 699 700 /** 701 * {@inheritDoc} 702 */ 703 @Override 704 public void modify( String dn, Modification... modifications ) throws LdapException 705 { 706 modify( new Dn( schemaManager, dn ), modifications ); 707 } 708 709 710 /** 711 * {@inheritDoc} 712 */ 713 @Override 714 public void modify( Entry entry, ModificationOperation modOp ) throws LdapException 715 { 716 if ( entry == null ) 717 { 718 LOG.debug( "received a null entry for modification" ); 719 throw new IllegalArgumentException( "Entry to be modified cannot be null" ); 720 } 721 722 int newId = messageId.incrementAndGet(); 723 ModifyRequest modifyRequest = new ModifyRequestImpl(); 724 modifyRequest.setMessageId( newId ); 725 726 modifyRequest.setName( entry.getDn() ); 727 728 Iterator<Attribute> itr = entry.iterator(); 729 730 while ( itr.hasNext() ) 731 { 732 modifyRequest.addModification( new DefaultModification( modOp, itr.next() ) ); 733 } 734 735 ModifyResponse modifyResponse = modify( modifyRequest ); 736 737 processResponse( modifyResponse ); 738 } 739 740 741 /** 742 * {@inheritDoc} 743 */ 744 @Override 745 public ModifyResponse modify( ModifyRequest modRequest ) throws LdapException 746 { 747 if ( modRequest == null ) 748 { 749 String msg = "Cannot process a null modifyRequest"; 750 LOG.debug( msg ); 751 throw new IllegalArgumentException( msg ); 752 } 753 754 int newId = messageId.incrementAndGet(); 755 756 modRequest.setMessageId( newId ); 757 ModifyResponse resp = new ModifyResponseImpl( newId ); 758 resp.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS ); 759 760 try 761 { 762 session.modify( modRequest ); 763 } 764 catch ( LdapException e ) 765 { 766 LOG.warn( e.getMessage(), e ); 767 768 resp.getLdapResult().setResultCode( ResultCodeEnum.getResultCode( e ) ); 769 resp.getLdapResult().setDiagnosticMessage( e.getMessage() ); 770 } 771 772 addResponseControls( modRequest, resp ); 773 774 return resp; 775 } 776 777 778 /** 779 * {@inheritDoc} 780 */ 781 @Override 782 public ModifyDnResponse modifyDn( ModifyDnRequest modDnRequest ) throws LdapException 783 { 784 if ( modDnRequest == null ) 785 { 786 String msg = "Cannot process a null modDnRequest"; 787 LOG.debug( msg ); 788 throw new IllegalArgumentException( msg ); 789 } 790 791 int newId = messageId.incrementAndGet(); 792 793 ModifyDnResponse resp = new ModifyDnResponseImpl( newId ); 794 LdapResult result = resp.getLdapResult(); 795 result.setResultCode( ResultCodeEnum.SUCCESS ); 796 797 if ( modDnRequest.getName().isEmpty() ) 798 { 799 // it is not allowed to modify the name of the Root DSE 800 String msg = "Modify Dn is not allowed on Root DSE."; 801 result.setResultCode( ResultCodeEnum.PROTOCOL_ERROR ); 802 result.setDiagnosticMessage( msg ); 803 804 return resp; 805 } 806 807 try 808 { 809 Rdn newRdn = modDnRequest.getNewRdn(); 810 811 if ( ( newRdn != null ) && !newRdn.isSchemaAware() ) 812 { 813 modDnRequest.setNewRdn( new Rdn( schemaManager, newRdn ) ); 814 } 815 816 Rdn oldRdn = modDnRequest.getName().getRdn(); 817 818 if ( !modDnRequest.getName().isSchemaAware() ) 819 { 820 modDnRequest.setName( new Dn( schemaManager, modDnRequest.getName() ) ); 821 oldRdn = modDnRequest.getName().getRdn(); 822 } 823 824 boolean rdnChanged = modDnRequest.getNewRdn() != null 825 && !newRdn.getNormName().equals( oldRdn.getNormName() ); 826 827 if ( rdnChanged ) 828 { 829 if ( modDnRequest.getNewSuperior() != null ) 830 { 831 session.moveAndRename( modDnRequest ); 832 } 833 else 834 { 835 session.rename( modDnRequest ); 836 } 837 } 838 else if ( modDnRequest.getNewSuperior() != null ) 839 { 840 modDnRequest.setNewRdn( null ); 841 session.move( modDnRequest ); 842 } 843 else 844 { 845 // This might be a simple change, we will update the DN and the entry 846 // with the new provided value by using a modify operation later on 847 session.rename( modDnRequest ); 848 } 849 850 } 851 catch ( LdapException e ) 852 { 853 LOG.warn( e.getMessage(), e ); 854 855 resp.getLdapResult().setResultCode( ResultCodeEnum.getResultCode( e ) ); 856 resp.getLdapResult().setDiagnosticMessage( e.getMessage() ); 857 } 858 859 addResponseControls( modDnRequest, resp ); 860 return resp; 861 } 862 863 864 /** 865 * {@inheritDoc} 866 */ 867 @Override 868 public void move( Dn entryDn, Dn newSuperiorDn ) throws LdapException 869 { 870 if ( entryDn == null ) 871 { 872 String msg = "Cannot process a move of a null Dn"; 873 LOG.debug( msg ); 874 throw new IllegalArgumentException( msg ); 875 } 876 877 if ( newSuperiorDn == null ) 878 { 879 String msg = "Cannot process a move to a null Dn"; 880 LOG.debug( msg ); 881 throw new IllegalArgumentException( msg ); 882 } 883 884 ModifyDnRequest modDnReq = new ModifyDnRequestImpl(); 885 modDnReq.setName( entryDn ); 886 modDnReq.setNewSuperior( newSuperiorDn ); 887 888 ModifyDnResponse modifyDnResponse = modifyDn( modDnReq ); 889 processResponse( modifyDnResponse ); 890 } 891 892 893 /** 894 * {@inheritDoc} 895 */ 896 @Override 897 public void move( String entryDn, String newSuperiorDn ) throws LdapException 898 { 899 if ( entryDn == null ) 900 { 901 String msg = "Cannot process a move of a null Dn"; 902 LOG.debug( msg ); 903 throw new IllegalArgumentException( msg ); 904 } 905 906 if ( newSuperiorDn == null ) 907 { 908 String msg = "Cannot process a move to a null Dn"; 909 LOG.debug( msg ); 910 throw new IllegalArgumentException( msg ); 911 } 912 913 move( new Dn( schemaManager, entryDn ), new Dn( schemaManager, newSuperiorDn ) ); 914 } 915 916 917 /** 918 * {@inheritDoc} 919 */ 920 @Override 921 public void rename( Dn entryDn, Rdn newRdn, boolean deleteOldRdn ) throws LdapException 922 { 923 if ( entryDn == null ) 924 { 925 String msg = "Cannot process a rename of a null Dn"; 926 LOG.debug( msg ); 927 throw new IllegalArgumentException( msg ); 928 } 929 930 if ( newRdn == null ) 931 { 932 String msg = "Cannot process a rename with a null Rdn"; 933 LOG.debug( msg ); 934 throw new IllegalArgumentException( msg ); 935 } 936 937 ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl(); 938 modifyDnRequest.setName( entryDn ); 939 modifyDnRequest.setNewRdn( newRdn ); 940 modifyDnRequest.setDeleteOldRdn( deleteOldRdn ); 941 942 ModifyDnResponse modifyDnResponse = modifyDn( modifyDnRequest ); 943 processResponse( modifyDnResponse ); 944 945 } 946 947 948 /** 949 * {@inheritDoc} 950 */ 951 @Override 952 public void rename( Dn entryDn, Rdn newRdn ) throws LdapException 953 { 954 rename( entryDn, newRdn, false ); 955 } 956 957 958 /** 959 * {@inheritDoc} 960 */ 961 @Override 962 public void rename( String entryDn, String newRdn, boolean deleteOldRdn ) throws LdapException 963 { 964 rename( new Dn( schemaManager, entryDn ), new Rdn( newRdn ), deleteOldRdn ); 965 } 966 967 968 /** 969 * {@inheritDoc} 970 */ 971 @Override 972 public void rename( String entryDn, String newRdn ) throws LdapException 973 { 974 if ( entryDn == null ) 975 { 976 String msg = "Cannot process a rename of a null Dn"; 977 LOG.debug( msg ); 978 throw new IllegalArgumentException( msg ); 979 } 980 981 if ( newRdn == null ) 982 { 983 String msg = "Cannot process a rename with a null Rdn"; 984 LOG.debug( msg ); 985 throw new IllegalArgumentException( msg ); 986 } 987 988 rename( new Dn( schemaManager, entryDn ), new Rdn( schemaManager, newRdn ) ); 989 } 990 991 992 /** 993 * Moves and renames the given entryDn.The old Rdn will be deleted 994 * 995 * @see #moveAndRename(org.apache.directory.api.ldap.model.name.Dn, org.apache.directory.api.ldap.model.name.Dn, boolean) 996 */ 997 @Override 998 public void moveAndRename( Dn entryDn, Dn newDn ) throws LdapException 999 { 1000 moveAndRename( entryDn, newDn, true ); 1001 } 1002 1003 1004 /** 1005 * Moves and renames the given entryDn.The old Rdn will be deleted 1006 * 1007 * @see #moveAndRename(org.apache.directory.api.ldap.model.name.Dn, org.apache.directory.api.ldap.model.name.Dn, boolean) 1008 */ 1009 @Override 1010 public void moveAndRename( String entryDn, String newDn ) throws LdapException 1011 { 1012 moveAndRename( new Dn( schemaManager, entryDn ), new Dn( schemaManager, newDn ), true ); 1013 } 1014 1015 1016 /** 1017 * Moves and renames the given entryDn.The old Rdn will be deleted if requested 1018 * 1019 * @param entryDn The original entry Dn 1020 * @param newDn The new Entry Dn 1021 * @param deleteOldRdn Tells if the old Rdn must be removed 1022 */ 1023 @Override 1024 public void moveAndRename( Dn entryDn, Dn newDn, boolean deleteOldRdn ) throws LdapException 1025 { 1026 // Check the parameters first 1027 if ( entryDn == null ) 1028 { 1029 throw new IllegalArgumentException( "The entry Dn must not be null" ); 1030 } 1031 1032 if ( entryDn.isRootDse() ) 1033 { 1034 throw new IllegalArgumentException( "The RootDSE cannot be moved" ); 1035 } 1036 1037 if ( newDn == null ) 1038 { 1039 throw new IllegalArgumentException( "The new Dn must not be null" ); 1040 } 1041 1042 if ( newDn.isRootDse() ) 1043 { 1044 throw new IllegalArgumentException( "The RootDSE cannot be the target" ); 1045 } 1046 1047 ModifyDnResponse resp = new ModifyDnResponseImpl(); 1048 resp.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS ); 1049 1050 ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl(); 1051 1052 modifyDnRequest.setName( entryDn ); 1053 modifyDnRequest.setNewRdn( newDn.getRdn() ); 1054 modifyDnRequest.setNewSuperior( newDn.getParent() ); 1055 modifyDnRequest.setDeleteOldRdn( deleteOldRdn ); 1056 1057 ModifyDnResponse modifyDnResponse = modifyDn( modifyDnRequest ); 1058 processResponse( modifyDnResponse ); 1059 } 1060 1061 1062 /** 1063 * Moves and renames the given entryDn.The old Rdn will be deleted if requested 1064 * 1065 * @param entryDn The original entry Dn 1066 * @param newDn The new Entry Dn 1067 * @param deleteOldRdn Tells if the old Rdn must be removed 1068 */ 1069 @Override 1070 public void moveAndRename( String entryDn, String newDn, boolean deleteOldRdn ) throws LdapException 1071 { 1072 moveAndRename( new Dn( schemaManager, entryDn ), new Dn( schemaManager, newDn ), deleteOldRdn ); 1073 } 1074 1075 1076 /** 1077 * {@inheritDoc} 1078 */ 1079 @Override 1080 public SearchCursor search( SearchRequest searchRequest ) throws LdapException 1081 { 1082 if ( searchRequest == null ) 1083 { 1084 String msg = "Cannot process a null searchRequest"; 1085 LOG.debug( msg ); 1086 throw new IllegalArgumentException( msg ); 1087 } 1088 1089 try 1090 { 1091 int newId = messageId.incrementAndGet(); 1092 1093 searchRequest.setMessageId( newId ); 1094 1095 Cursor<Entry> entryCursor = session.search( searchRequest ); 1096 entryCursor.beforeFirst(); 1097 1098 //TODO enforce the size and time limits, similar in the way SearchHandler does 1099 return new EntryToResponseCursor( searchRequest, newId, entryCursor ); 1100 } 1101 catch ( Exception e ) 1102 { 1103 LOG.warn( e.getMessage(), e ); 1104 } 1105 1106 return new EntryToResponseCursor( searchRequest, -1, new EmptyCursor<Entry>() ); 1107 } 1108 1109 1110 /** 1111 * {@inheritDoc} 1112 */ 1113 @Override 1114 public EntryCursor search( Dn baseDn, String filter, SearchScope scope, String... attributes ) 1115 throws LdapException 1116 { 1117 if ( baseDn == null ) 1118 { 1119 LOG.debug( "received a null dn for a search" ); 1120 throw new IllegalArgumentException( "The base Dn cannot be null" ); 1121 } 1122 1123 // generate some random operation number 1124 SearchRequest searchRequest = new SearchRequestImpl(); 1125 1126 searchRequest.setBase( baseDn ); 1127 1128 searchRequest.setFilter( filter ); 1129 searchRequest.setScope( scope ); 1130 searchRequest.addAttributes( attributes ); 1131 searchRequest.setDerefAliases( AliasDerefMode.DEREF_ALWAYS ); 1132 1133 return new EntryCursorImpl( search( searchRequest ) ); 1134 } 1135 1136 1137 /** 1138 * {@inheritDoc} 1139 */ 1140 @Override 1141 public EntryCursor search( String baseDn, String filter, SearchScope scope, String... attributes ) 1142 throws LdapException 1143 { 1144 return search( new Dn( schemaManager, baseDn ), filter, scope, attributes ); 1145 } 1146 1147 1148 /** 1149 * {@inheritDoc} 1150 */ 1151 @Override 1152 public void unBind() throws LdapException 1153 { 1154 messageId.set( 0 ); 1155 1156 if ( session != null ) 1157 { 1158 // No need to unbind if the session is anonymous 1159 if ( !session.isAnonymous() ) 1160 { 1161 session.unbind(); 1162 } 1163 1164 session = null; 1165 } 1166 } 1167 1168 1169 /** 1170 * {@inheritDoc} 1171 */ 1172 @Override 1173 public ExtendedResponse extended( String oid ) throws LdapException 1174 { 1175 throw new UnsupportedOperationException( 1176 "extended operations are not supported on CoreSession based connection" ); 1177 } 1178 1179 1180 /** 1181 * {@inheritDoc} 1182 */ 1183 @Override 1184 public ExtendedResponse extended( ExtendedRequest extendedRequest ) throws LdapException 1185 { 1186 if ( extendedRequest == null ) 1187 { 1188 String msg = "Cannot process a null extendedRequest"; 1189 LOG.debug( msg ); 1190 throw new IllegalArgumentException( msg ); 1191 } 1192 1193 return extended( ( String ) null ); 1194 1195 } 1196 1197 1198 /** 1199 * {@inheritDoc} 1200 */ 1201 @Override 1202 public ExtendedResponse extended( Oid oid, byte[] value ) throws LdapException 1203 { 1204 return extended( ( String ) null ); 1205 } 1206 1207 1208 /** 1209 * {@inheritDoc} 1210 */ 1211 @Override 1212 public ExtendedResponse extended( Oid oid ) throws LdapException 1213 { 1214 return extended( ( String ) null ); 1215 } 1216 1217 1218 /** 1219 * {@inheritDoc} 1220 */ 1221 @Override 1222 public ExtendedResponse extended( String oid, byte[] value ) throws LdapException 1223 { 1224 return extended( ( String ) null ); 1225 } 1226 1227 1228 /** 1229 * {@inheritDoc} 1230 */ 1231 @Override 1232 public void setTimeOut( long timeOut ) 1233 { 1234 throw new UnsupportedOperationException( "setting timeout is not supported on CoreSession" ); 1235 } 1236 1237 1238 /** 1239 * {@inheritDoc} 1240 */ 1241 @Override 1242 public void abandon( AbandonRequest abandonRequest ) 1243 { 1244 throw new UnsupportedOperationException( "abandon operation is not supported" ); 1245 } 1246 1247 1248 /** 1249 * {@inheritDoc} 1250 */ 1251 @Override 1252 public void abandon( int messageId ) 1253 { 1254 abandon( null ); 1255 } 1256 1257 1258 /** 1259 * {@inheritDoc} 1260 */ 1261 @Override 1262 public void bind() throws LdapException 1263 { 1264 throw new UnsupportedOperationException( 1265 "Bind operation using LdapConnectionConfig are not supported on CoreSession based connection" ); 1266 } 1267 1268 1269 /** 1270 * {@inheritDoc} 1271 */ 1272 @Override 1273 public void anonymousBind() throws LdapException 1274 { 1275 BindRequest bindRequest = new BindRequestImpl(); 1276 bindRequest.setName( "" ); 1277 bindRequest.setCredentials( ( byte[] ) null ); 1278 1279 BindResponse bindResponse = bind( bindRequest ); 1280 1281 processResponse( bindResponse ); 1282 } 1283 1284 1285 /** 1286 * {@inheritDoc} 1287 */ 1288 @Override 1289 public BindResponse bind( BindRequest bindRequest ) throws LdapException 1290 { 1291 if ( bindRequest == null ) 1292 { 1293 String msg = "Cannot process a null bindRequest"; 1294 LOG.debug( msg ); 1295 throw new IllegalArgumentException( msg ); 1296 } 1297 1298 int newId = messageId.incrementAndGet(); 1299 1300 BindOperationContext bindContext = new BindOperationContext( null ); 1301 bindContext.setCredentials( bindRequest.getCredentials() ); 1302 1303 Dn bindDn = bindRequest.getDn(); 1304 1305 if ( !bindDn.isSchemaAware() ) 1306 { 1307 bindDn = new Dn( directoryService.getSchemaManager(), bindDn ); 1308 } 1309 1310 bindContext.setDn( bindDn ); 1311 bindContext.setInterceptors( directoryService.getInterceptors( OperationEnum.BIND ) ); 1312 1313 for ( Control control : bindRequest.getControls().values() ) 1314 { 1315 bindContext.addRequestControl( control ); 1316 } 1317 1318 OperationManager operationManager = directoryService.getOperationManager(); 1319 1320 BindResponse bindResp = new BindResponseImpl( newId ); 1321 bindResp.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS ); 1322 1323 try 1324 { 1325 if ( !bindRequest.isSimple() ) 1326 { 1327 bindContext.setSaslMechanism( bindRequest.getSaslMechanism() ); 1328 } 1329 1330 operationManager.bind( bindContext ); 1331 session = bindContext.getSession(); 1332 1333 bindResp.addAllControls( bindContext.getResponseControls() ); 1334 } 1335 catch ( LdapOperationException e ) 1336 { 1337 LOG.warn( e.getMessage(), e ); 1338 LdapResult res = bindResp.getLdapResult(); 1339 res.setDiagnosticMessage( e.getMessage() ); 1340 res.setResultCode( e.getResultCode() ); 1341 } 1342 1343 return bindResp; 1344 } 1345 1346 1347 private void addResponseControls( ResultResponseRequest iReq, Message clientResp ) 1348 { 1349 Collection<Control> ctrlSet = iReq.getResultResponse().getControls().values(); 1350 1351 for ( Control c : ctrlSet ) 1352 { 1353 clientResp.addControl( c ); 1354 } 1355 } 1356 1357 1358 public DirectoryService getDirectoryService() 1359 { 1360 return directoryService; 1361 } 1362 1363 1364 public void setDirectoryService( DirectoryService directoryService ) 1365 { 1366 this.directoryService = directoryService; 1367 this.schemaManager = directoryService.getSchemaManager(); 1368 this.session = directoryService.getAdminSession(); 1369 } 1370 1371 1372 /** 1373 * {@inheritDoc} 1374 */ 1375 @Override 1376 public BinaryAttributeDetector getBinaryAttributeDetector() 1377 { 1378 return null; 1379 } 1380 1381 1382 /** 1383 * {@inheritDoc} 1384 */ 1385 @Override 1386 public void setBinaryAttributeDetector( BinaryAttributeDetector binaryAttributeDetector ) 1387 { 1388 // Does nothing 1389 } 1390 1391 1392 /** 1393 * {@inheritDoc} 1394 */ 1395 @Override 1396 public void setSchemaManager( SchemaManager schemaManager ) 1397 { 1398 this.schemaManager = schemaManager; 1399 } 1400 1401 1402 /** 1403 * @return The session, if we have some 1404 */ 1405 public CoreSession getSession() 1406 { 1407 return session; 1408 } 1409}