View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.ldap.handlers.request;
21  
22  
23  import org.apache.directory.api.ldap.model.message.LdapResult;
24  import org.apache.directory.api.ldap.model.message.ModifyDnRequest;
25  import org.apache.directory.api.ldap.model.message.ModifyDnResponse;
26  import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
27  import org.apache.directory.api.ldap.model.name.Dn;
28  import org.apache.directory.api.ldap.model.schema.SchemaManager;
29  import org.apache.directory.server.core.api.CoreSession;
30  import org.apache.directory.server.ldap.LdapSession;
31  import org.apache.directory.server.ldap.handlers.LdapRequestHandler;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  
36  /**
37   * A single reply MessageReceived handler for {@link org.apache.directory.api.ldap.model.message.ModifyDnRequest}s.
38   *
39   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
40   */
41  public class ModifyDnRequestHandler extends LdapRequestHandler<ModifyDnRequest>
42  {
43      private static final Logger LOG = LoggerFactory.getLogger( ModifyDnRequestHandler.class );
44  
45  
46      /**
47       * Deal with a ModifyDN request received from a client.
48       *
49       * A ModifyDN operation has more than one semantic, depending on its parameters.
50       *
51       * In any case, the first argument is the Dn entry to be changed. We then
52       * have the new relative Dn for this entry.
53       *
54       * Two other arguments can be provided :
55       * - deleteOldRdn : if the old Rdn attributes should be removed from the
56       * new entry or not (for instance, if the old Rdn was cn=acme, and the new
57       * one is sn=acme, then we may have to remove the cn: acme from the attributes
58       * list)
59       * - newSuperior : this is a move operation. The entry is removed from its
60       * current location, and created in the new one.
61       */
62      public void handle( LdapSession session, ModifyDnRequest modifyDnRequest )
63      {
64          ModifyDnResponse modifyDnResponse = ( ModifyDnResponse ) modifyDnRequest.getResultResponse(); 
65          LdapResult result = modifyDnResponse.getLdapResult();
66          LOG.debug( "Handling modify dn request while ignoring referrals: {}", modifyDnRequest );
67  
68          if ( modifyDnRequest.getName().isEmpty() )
69          {
70              // it is not allowed to modify the name of the Root DSE
71              String msg = "Modify Dn is not allowed on Root DSE.";
72              result.setResultCode( ResultCodeEnum.PROTOCOL_ERROR );
73              result.setDiagnosticMessage( msg );
74              session.getIoSession().write( modifyDnResponse );
75              return;
76          }
77  
78          try
79          {
80              SchemaManager schemaManager = session.getCoreSession().getDirectoryService().getSchemaManager();
81              Dn newRdn = new Dn( schemaManager, modifyDnRequest.getNewRdn().getName() );
82  
83              Dn oldRdn = new Dn( schemaManager, modifyDnRequest.getName().getRdn().getName() );
84  
85              boolean rdnChanged = modifyDnRequest.getNewRdn() != null && !newRdn.equals( oldRdn );
86  
87              CoreSession coreSession = session.getCoreSession();
88  
89              if ( rdnChanged )
90              {
91                  if ( modifyDnRequest.getNewSuperior() != null )
92                  {
93                      coreSession.moveAndRename( modifyDnRequest );
94                  }
95                  else
96                  {
97                      coreSession.rename( modifyDnRequest );
98                  }
99              }
100             else if ( modifyDnRequest.getNewSuperior() != null )
101             {
102                 modifyDnRequest.setNewRdn( null );
103                 coreSession.move( modifyDnRequest );
104             }
105             else
106             {
107                 result.setDiagnosticMessage( "Attempt to move entry onto itself." );
108                 result.setResultCode( ResultCodeEnum.ENTRY_ALREADY_EXISTS );
109                 result.setMatchedDn( modifyDnRequest.getName() );
110                 session.getIoSession().write( modifyDnResponse );
111                 
112                 return;
113             }
114 
115             result.setResultCode( ResultCodeEnum.SUCCESS );
116             session.getIoSession().write( modifyDnResponse );
117         }
118         catch ( Exception e )
119         {
120             handleException( session, modifyDnRequest, modifyDnResponse, e );
121         }
122     }
123 }