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 }