Skip to content
Snippets Groups Projects
modrdn.c 2.54 KiB
Newer Older
  • Learn to ignore specific revisions
  • Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    /*
     * Copyright (c) 1995 Regents of the University of Michigan.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms are permitted
     * provided that this notice is preserved and that due credit is given
     * to the University of Michigan at Ann Arbor. The name of the University
     * may not be used to endorse or promote products derived from this
     * software without specific prior written permission. This software
     * is provided ``as is'' without express or implied warranty.
     */
    
    
    #include "portable.h"
    
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    #include <stdio.h>
    
    
    #include <ac/socket.h>
    #include <ac/string.h>
    
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    #include "slap.h"
    
    void
    do_modrdn(
        Connection	*conn,
        Operation	*op
    )
    {
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    	int	deloldrdn;
    	Backend	*be;
    
    	Debug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 );
    
    	/*
    	 * Parse the modrdn request.  It looks like this:
    	 *
    	 *	ModifyRDNRequest := SEQUENCE {
    	 *		entry	DistinguishedName,
    	 *		newrdn	RelativeDistinguishedName
    	 *	}
    	 */
    
    
    	if ( ber_scanf( op->o_ber, "{aab}", &ndn, &newrdn, &deloldrdn )
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    	    == LBER_ERROR ) {
    		Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
    		send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL, "" );
    		return;
    	}
    
    	Debug( LDAP_DEBUG_ARGS,
    
    	    "do_modrdn: dn (%s) newrdn (%s) deloldrdn (%d)\n", ndn, newrdn,
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    	    deloldrdn );
    
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    	Statslog( LDAP_DEBUG_STATS, "conn=%d op=%d MODRDN dn=\"%s\"\n",
    
    	    conn->c_connid, op->o_opid, ndn, 0, 0 );
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    
    	/*
    	 * We could be serving multiple database backends.  Select the
    	 * appropriate one, or send a referral to our "referral server"
    	 * if we don't hold it.
    	 */
    
    
    	if ( (be = select_backend( ndn )) == NULL ) {
    		free( ndn );
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    		free( newrdn );
    		send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL,
    		    default_referral );
    		return;
    	}
    
    
    	/* alias suffix if approp */
    	ndn = suffixAlias( ndn, op, be );
    
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    	/*
    	 * do the add if 1 && (2 || 3)
    	 * 1) there is an add function implemented in this backend;
    	 * 2) this backend is master for what it holds;
    
    	 * 3) it's a replica and the dn supplied is the update_ndn.
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    	 */
    	if ( be->be_modrdn != NULL ) {
    		/* do the update here */
    
    		if ( be->be_update_ndn == NULL ||
    			strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
    		{
    			if ( (*be->be_modrdn)( be, conn, op, ndn, newrdn,
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    			    deloldrdn ) == 0 ) {
    
    				replog( be, LDAP_REQ_MODRDN, ndn, newrdn,
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    				    deloldrdn );
    			}
    		} else {
    			send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL,
    			    default_referral );
    		}
    	} else {
    		send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
    		    "Function not implemented" );
    	}
    
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    	free( newrdn );
    }