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;
21  
22   
23  import org.apache.directory.server.core.entry.ClonedServerEntry;
24  import org.apache.directory.server.ldap.LdapSession;
25  import org.apache.directory.shared.ldap.message.LdapResult;
26  import org.apache.directory.shared.ldap.message.ModifyDnRequest;
27  import org.apache.directory.shared.ldap.message.ResultCodeEnum;
28  import org.apache.directory.shared.ldap.name.LdapDN;
29  
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  
34  /**
35   * A single reply handler for {@link ModifyDnRequest}s.
36   *
37   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38   * @version $Rev: 664302 $
39   */
40  public class ModifyDnHandler extends ReferralAwareRequestHandler<ModifyDnRequest>
41  {
42      private static final Logger LOG = LoggerFactory.getLogger( ModifyDnHandler.class );
43  
44      
45      /**
46       * Deal with a ModifyDN request received from a client.
47       *
48       * A ModifyDN operation has more than one semantic, depending on its parameters.
49       *
50       * In any case, the first argument is the DN entry to be changed. We then
51       * have the new relative DN for this entry.
52       *
53       * Two other arguments can be provided :
54       * - deleteOldRdn : if the old RDN attributes should be removed from the
55       * new entry or not (for instance, if the old RDN was cn=acme, and the new
56       * one is sn=acme, then we may have to remove the cn: acme from the attributes
57       * list)
58       * - newSuperior : this is a move operation. The entry is removed from its
59       * current location, and created in the new one.
60       */
61      public void handleIgnoringReferrals( LdapSession session, LdapDN reqTargetDn, 
62          ClonedServerEntry entry, ModifyDnRequest req )
63      {
64          LdapResult result = req.getResultResponse().getLdapResult();
65          LOG.debug( "Handling modify dn request while ignoring referrals: {}", req );
66  
67          if ( req.getName().isEmpty() )
68          {
69              // it is not allowed to modify the name of the Root DSE
70              String msg = "Modify DN is not allowed on Root DSE.";
71              result.setResultCode( ResultCodeEnum.PROTOCOL_ERROR );
72              result.setErrorMessage( msg );
73              session.getIoSession().write( req.getResultResponse() );
74              return;
75          }
76          
77          try
78          {
79              LdapDN newRdn = new LdapDN( req.getNewRdn().toString() );
80              newRdn.normalize( session.getCoreSession().getDirectoryService()
81                  .getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
82              
83              LdapDN oldRdn = new LdapDN( req.getName().getRdn().toString() );
84              oldRdn.normalize( session.getCoreSession().getDirectoryService()
85                  .getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
86              
87              boolean rdnChanged = req.getNewRdn() != null && 
88                  ! newRdn.getNormName().equals( oldRdn.getNormName() );
89              
90              if ( rdnChanged )
91              {
92                  if ( req.getNewSuperior() != null )
93                  {
94                      session.getCoreSession().moveAndRename( req );
95                  }
96                  else
97                  {
98                      session.getCoreSession().rename( req );
99                  }
100             }
101             else if ( req.getNewSuperior() != null )
102             {
103                 req.setNewRdn( null );
104                 session.getCoreSession().move( req );
105             }
106             else
107             {
108                 result.setErrorMessage( "Attempt to move entry onto itself." );
109                 result.setResultCode( ResultCodeEnum.ENTRY_ALREADY_EXISTS );
110                 result.setMatchedDn( req.getName() );
111                 session.getIoSession().write( req.getResultResponse() );
112                 return;
113             }
114 
115             result.setResultCode( ResultCodeEnum.SUCCESS );
116             session.getIoSession().write( req.getResultResponse() );
117         }
118         catch ( Exception e )
119         {
120             handleException( session, req, e );
121         }
122     }
123 }