1N/A/*
1N/A * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
1N/A * Use is subject to license terms.
1N/A */
1N/A
1N/A#pragma ident "%Z%%M% %I% %E% SMI"
1N/A
1N/A/* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP */
1N/A
1N/A#include <stdio.h>
1N/A#include <string.h>
1N/A#include <stdlib.h>
1N/A#include <locale.h>
1N/A#include <ctype.h>
1N/A#include <lber.h>
1N/A#include <ldap.h>
1N/A#include <locale.h>
1N/A#include "ldaptool.h"
1N/A
1N/Astatic int contoper, remove_oldrdn;
1N/Astatic LDAP *ld;
1N/A
1N/Astatic int domodrdn( LDAP *ld, char *dn, char *rdn, char *newsuperior,
1N/A int remove_oldrdn);
1N/Astatic void options_callback( int option, char *optarg );
1N/A
1N/Astatic void usage( void )
1N/A{
1N/A fprintf(stderr, gettext("usage: %s [options] [dn newrdn [newsuperior]]\n"), ldaptool_progname);
1N/A fprintf( stderr, gettext("options:\n"));
1N/A ldaptool_common_usage( 0 );
1N/A fprintf( stderr, gettext(" -c\t\tcontinuous mode\n") );
1N/A fprintf( stderr, gettext(" -r\t\tremove old RDN from the entries\n"));
1N/A fprintf( stderr, gettext(" -f file\tread changes from `file'\n") );
1N/A exit(LDAP_PARAM_ERROR );
1N/A}
1N/A
1N/Aint
1N/Amain(int argc, char **argv )
1N/A{
1N/A char *myname, *entrydn, *rdn, buf[ 4096 ];
1N/A int rc, havedn, deref, optind;
1N/A char * L_newParent = NULL;
1N/A int haverdn = 0;
1N/A
1N/A int L_protoVersion = LDAP_VERSION3;
1N/A
1N/A char *locale = setlocale(LC_ALL, "");
1N/A textdomain(TEXT_DOMAIN);
1N/A ldaplogconfigf(NULL);
1N/A
1N/A
1N/A contoper = remove_oldrdn = 0;
1N/A
1N/A if ((myname = strrchr(argv[0], '/')) == NULL)
1N/A myname = argv[0];
1N/A else
1N/A ++myname;
1N/A
1N/A optind = ldaptool_process_args( argc, argv, "cr", 0, options_callback);
1N/A
1N/A if ( optind == -1 ) {
1N/A usage();
1N/A }
1N/A
1N/A if ( ldaptool_fp == NULL ) {
1N/A ldaptool_fp = stdin;
1N/A }
1N/A
1N/A havedn = 0;
1N/A if (argc - optind == 3) /* accept as arguments: dn rdn newsuperior */
1N/A {
1N/A if (( L_newParent = strdup( argv[argc - 1] )) == NULL )
1N/A {
1N/A perror( "strdup" );
1N/A exit( LDAP_NO_MEMORY );
1N/A }
1N/A
1N/A if (( rdn = strdup( argv[argc - 2] )) == NULL )
1N/A {
1N/A perror( "strdup" );
1N/A exit( LDAP_NO_MEMORY );
1N/A }
1N/A
1N/A if (( entrydn = strdup( argv[argc - 3] )) == NULL )
1N/A {
1N/A perror( "strdup" );
1N/A exit( LDAP_NO_MEMORY );
1N/A }
1N/A ++havedn;
1N/A }
1N/A else if (argc - optind == 2) /* accept as arguments: dn rdn */
1N/A {
1N/A if (( rdn = strdup( argv[argc - 1] )) == NULL )
1N/A {
1N/A perror( "strdup" );
1N/A exit( LDAP_NO_MEMORY );
1N/A }
1N/A
1N/A if (( entrydn = strdup( argv[argc - 2] )) == NULL )
1N/A {
1N/A perror( "strdup" );
1N/A exit( 1 );
1N/A }
1N/A ++havedn;
1N/A }
1N/A else if ( argc - optind != 0 )
1N/A {
1N/A fprintf( stderr, gettext("%s: invalid number of arguments, only two or three allowed\n"), myname);
1N/A usage();
1N/A exit( 1 );
1N/A }
1N/A
1N/A ld = ldaptool_ldap_init (0);
1N/A
1N/A if ( !ldaptool_not ) {
1N/A deref = LDAP_DEREF_NEVER; /* this seems prudent */
1N/A ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
1N/A }
1N/A
1N/A ldaptool_bind( ld );
1N/A
1N/A rc = 0;
1N/A if (havedn)
1N/A {
1N/A rc = domodrdn(ld, entrydn, rdn, L_newParent, remove_oldrdn);
1N/A }
1N/A else while ( (rc == 0 || contoper) &&
1N/A (fgets(buf, sizeof(buf), ldaptool_fp) != NULL) )
1N/A
1N/A {
1N/A /*
1N/A * The format of the file is one of the following:
1N/A * dn
1N/A * rdn
1N/A * newsuperior
1N/A * <blank lines...>
1N/A * OR
1N/A * dn
1N/A * rdn
1N/A * <blank lines...>
1N/A * both types of sequences can be found in the file
1N/A */
1N/A
1N/A if ( (strlen(buf) == 1) && (ldaptool_fp == stdin) )
1N/A break;
1N/A
1N/A buf[ strlen( buf ) - 1 ] = '\0'; /* remove nl */
1N/A if ( *buf != '\0' ) /* blank lines optional, skip */
1N/A {
1N/A if ( haverdn ) /* first type of sequence */
1N/A {
1N/A if (( L_newParent = strdup( buf )) == NULL )
1N/A {
1N/A perror( "strdup" );
1N/A exit( LDAP_NO_MEMORY );
1N/A }
1N/A if ( L_newParent && (L_protoVersion == LDAP_VERSION) )
1N/A {
1N/A printf( gettext("LDAP Server is V2: <newsuperior> argument is ignored...\n") );
1N/A L_newParent = NULL;
1N/A }
1N/A rc = domodrdn(ld, entrydn, rdn, L_newParent, remove_oldrdn);
1N/A haverdn = 0;
1N/A }
1N/A else if ( havedn ) /* have DN, get RDN */
1N/A {
1N/A if (( rdn = strdup( buf )) == NULL )
1N/A {
1N/A perror( "strdup" );
1N/A exit( LDAP_NO_MEMORY );
1N/A }
1N/A havedn = 0;
1N/A ++haverdn;
1N/A }
1N/A else if ( !havedn ) /* don't have DN yet */
1N/A {
1N/A if (( entrydn = strdup( buf )) == NULL)
1N/A {
1N/A perror( "strdup" );
1N/A exit( LDAP_NO_MEMORY );
1N/A }
1N/A ++havedn;
1N/A }
1N/A }
1N/A else
1N/A {
1N/A printf(gettext("kex: new line %d\n"), rc);
1N/A if ( haverdn ) /* second type of sequence */
1N/A {
1N/A rc = domodrdn(ld, entrydn, rdn, NULL, remove_oldrdn);
1N/A haverdn = 0;
1N/A }
1N/A }
1N/A }
1N/A if ( (rc == 0 || contoper) && haverdn ) /* second type of sequence */
1N/A {
1N/A rc = domodrdn(ld, entrydn, rdn, NULL, remove_oldrdn);
1N/A haverdn = 0;
1N/A }
1N/A
1N/A ldaptool_cleanup( ld );
1N/A
1N/A exit( rc );
1N/A}
1N/A
1N/Astatic void
1N/Aoptions_callback( int option, char *optarg )
1N/A{
1N/A switch( option ) {
1N/A case 'c': /* continuous operation mode */
1N/A ++contoper;
1N/A break;
1N/A case 'r': /* remove old RDN */
1N/A ++remove_oldrdn;
1N/A break;
1N/A default:
1N/A usage();
1N/A }
1N/A}
1N/A
1N/Astatic int
1N/Adomodrdn( LDAP *ld, char *dn, char *rdn, char *newsuperior, int remove_oldrdn )
1N/A{
1N/A int rc = LDAP_SUCCESS;
1N/A
1N/A if ( ldaptool_verbose )
1N/A printf( gettext("new RDN: %1$s (%2$skeep existing values)\n"),
1N/A rdn, remove_oldrdn ? "do not " : "" );
1N/A
1N/A printf( gettext("%1$srenaming entry %2$s\n"),
1N/A ldaptool_not ? "!" : "", dn );
1N/A
1N/A if ( !ldaptool_not )
1N/A {
1N/A rc = ldap_rename_s( ld, dn, rdn, newsuperior, remove_oldrdn, NULL, NULL );
1N/A if ( rc != LDAP_SUCCESS )
1N/A fprintf(stderr, gettext("ldap_rename_s: %s\n"), ldap_err2string(rc));
1N/A else if ( ldaptool_verbose )
1N/A printf( gettext("rename completed\n") );
1N/A }
1N/A
1N/A putchar('\n');
1N/A
1N/A return( rc );
1N/A}