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 */
020 package org.apache.directory.server.ldap.handlers;
021
022
023 import org.apache.directory.server.core.CoreSession;
024 import org.apache.directory.server.ldap.LdapSession;
025 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
026 import org.apache.directory.shared.ldap.message.internal.InternalLdapResult;
027 import org.apache.directory.shared.ldap.message.internal.InternalModifyDnRequest;
028 import org.apache.directory.shared.ldap.name.DN;
029 import org.slf4j.Logger;
030 import org.slf4j.LoggerFactory;
031
032
033 /**
034 * A single reply handler for {@link InternalModifyDnRequest}s.
035 *
036 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037 * @version $Rev: 664302 $
038 */
039 public class ModifyDnHandler extends LdapRequestHandler<InternalModifyDnRequest>
040 {
041 private static final Logger LOG = LoggerFactory.getLogger( ModifyDnHandler.class );
042
043
044 /**
045 * Deal with a ModifyDN request received from a client.
046 *
047 * A ModifyDN operation has more than one semantic, depending on its parameters.
048 *
049 * In any case, the first argument is the DN entry to be changed. We then
050 * have the new relative DN for this entry.
051 *
052 * Two other arguments can be provided :
053 * - deleteOldRdn : if the old RDN attributes should be removed from the
054 * new entry or not (for instance, if the old RDN was cn=acme, and the new
055 * one is sn=acme, then we may have to remove the cn: acme from the attributes
056 * list)
057 * - newSuperior : this is a move operation. The entry is removed from its
058 * current location, and created in the new one.
059 */
060 public void handle( LdapSession session, InternalModifyDnRequest req )
061 {
062 InternalLdapResult result = req.getResultResponse().getLdapResult();
063 LOG.debug( "Handling modify dn request while ignoring referrals: {}", req );
064
065 if ( req.getName().isEmpty() )
066 {
067 // it is not allowed to modify the name of the Root DSE
068 String msg = "Modify DN is not allowed on Root DSE.";
069 result.setResultCode( ResultCodeEnum.PROTOCOL_ERROR );
070 result.setErrorMessage( msg );
071 session.getIoSession().write( req.getResultResponse() );
072 return;
073 }
074
075 try
076 {
077 DN newRdn = new DN( req.getNewRdn().getName() );
078 newRdn.normalize( session.getCoreSession().getDirectoryService()
079 .getSchemaManager().getNormalizerMapping() );
080
081 DN oldRdn = new DN( req.getName().getRdn().getName() );
082 oldRdn.normalize( session.getCoreSession().getDirectoryService()
083 .getSchemaManager().getNormalizerMapping() );
084
085 boolean rdnChanged = req.getNewRdn() != null &&
086 ! newRdn.getNormName().equals( oldRdn.getNormName() );
087
088 CoreSession coreSession = session.getCoreSession();
089
090 if ( rdnChanged )
091 {
092 if ( req.getNewSuperior() != null )
093 {
094 coreSession.moveAndRename( req );
095 }
096 else
097 {
098 coreSession.rename( req );
099 }
100 }
101 else if ( req.getNewSuperior() != null )
102 {
103 req.setNewRdn( null );
104 coreSession.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 }