xref: /onnv-gate/usr/src/cmd/ldap/common/ldapmodrdn.c (revision 702:9495c7c1ed3a)
10Sstevel@tonic-gate /*
2*702Sth160488  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
70Sstevel@tonic-gate 
80Sstevel@tonic-gate /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP */
90Sstevel@tonic-gate 
100Sstevel@tonic-gate #include <stdio.h>
110Sstevel@tonic-gate #include <string.h>
120Sstevel@tonic-gate #include <stdlib.h>
130Sstevel@tonic-gate #include <locale.h>
140Sstevel@tonic-gate #include <ctype.h>
150Sstevel@tonic-gate #include <lber.h>
160Sstevel@tonic-gate #include <ldap.h>
170Sstevel@tonic-gate #include <locale.h>
180Sstevel@tonic-gate #include "ldaptool.h"
190Sstevel@tonic-gate 
200Sstevel@tonic-gate static int	contoper, remove_oldrdn;
210Sstevel@tonic-gate static LDAP	*ld;
220Sstevel@tonic-gate 
230Sstevel@tonic-gate static int domodrdn( LDAP *ld, char *dn, char *rdn, char *newsuperior,
240Sstevel@tonic-gate 			int remove_oldrdn);
250Sstevel@tonic-gate static void options_callback( int option, char *optarg );
260Sstevel@tonic-gate 
usage(void)270Sstevel@tonic-gate static void usage( void )
280Sstevel@tonic-gate {
290Sstevel@tonic-gate 	fprintf(stderr, gettext("usage: %s [options] [dn newrdn [newsuperior]]\n"), ldaptool_progname);
300Sstevel@tonic-gate 	fprintf( stderr, gettext("options:\n"));
310Sstevel@tonic-gate 	ldaptool_common_usage( 0 );
320Sstevel@tonic-gate 	fprintf( stderr, gettext("    -c\t\tcontinuous mode\n") );
330Sstevel@tonic-gate 	fprintf( stderr, gettext("    -r\t\tremove old RDN from the entries\n"));
340Sstevel@tonic-gate 	fprintf( stderr, gettext("    -f file\tread changes from `file'\n") );
350Sstevel@tonic-gate 	exit(LDAP_PARAM_ERROR );
360Sstevel@tonic-gate }
370Sstevel@tonic-gate 
38*702Sth160488 int
main(int argc,char ** argv)39*702Sth160488 main(int argc, char **argv )
400Sstevel@tonic-gate {
410Sstevel@tonic-gate 	char *myname, *entrydn, *rdn, buf[ 4096 ];
420Sstevel@tonic-gate 	int rc, havedn, deref, optind;
430Sstevel@tonic-gate 	char * L_newParent = NULL;
440Sstevel@tonic-gate 	int haverdn = 0;
450Sstevel@tonic-gate 
460Sstevel@tonic-gate 	int L_protoVersion = LDAP_VERSION3;
470Sstevel@tonic-gate 
480Sstevel@tonic-gate 	char *locale = setlocale(LC_ALL, "");
490Sstevel@tonic-gate 	textdomain(TEXT_DOMAIN);
500Sstevel@tonic-gate 	ldaplogconfigf(NULL);
510Sstevel@tonic-gate 
520Sstevel@tonic-gate 
530Sstevel@tonic-gate 	contoper =  remove_oldrdn = 0;
540Sstevel@tonic-gate 
55*702Sth160488 	if ((myname = strrchr(argv[0], '/')) == NULL)
56*702Sth160488 		myname = argv[0];
57*702Sth160488 	else
58*702Sth160488 		++myname;
590Sstevel@tonic-gate 
600Sstevel@tonic-gate 	optind = ldaptool_process_args( argc, argv, "cr", 0, options_callback);
610Sstevel@tonic-gate 
620Sstevel@tonic-gate 	if ( optind == -1 ) {
630Sstevel@tonic-gate 		usage();
640Sstevel@tonic-gate 	}
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	if ( ldaptool_fp == NULL ) {
670Sstevel@tonic-gate 	ldaptool_fp = stdin;
680Sstevel@tonic-gate 	}
690Sstevel@tonic-gate 
700Sstevel@tonic-gate 	havedn = 0;
710Sstevel@tonic-gate 	if (argc - optind == 3) 		/* accept as arguments: dn rdn newsuperior */
720Sstevel@tonic-gate 	{
730Sstevel@tonic-gate 		if (( L_newParent = strdup( argv[argc - 1] )) == NULL )
740Sstevel@tonic-gate 		{
750Sstevel@tonic-gate 			perror( "strdup" );
760Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
770Sstevel@tonic-gate 		}
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 		if (( rdn = strdup( argv[argc - 2] )) == NULL )
800Sstevel@tonic-gate 		{
810Sstevel@tonic-gate 			perror( "strdup" );
820Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
830Sstevel@tonic-gate 		}
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 		if (( entrydn = strdup( argv[argc - 3] )) == NULL )
860Sstevel@tonic-gate 		{
870Sstevel@tonic-gate 			perror( "strdup" );
880Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
890Sstevel@tonic-gate 		}
900Sstevel@tonic-gate 		++havedn;
910Sstevel@tonic-gate 	}
920Sstevel@tonic-gate 	else if (argc - optind == 2) 		/* accept as arguments: dn rdn */
930Sstevel@tonic-gate 	{
940Sstevel@tonic-gate 		if (( rdn = strdup( argv[argc - 1] )) == NULL )
950Sstevel@tonic-gate 		{
960Sstevel@tonic-gate 			perror( "strdup" );
970Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
980Sstevel@tonic-gate 		}
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 		if (( entrydn = strdup( argv[argc - 2] )) == NULL )
1010Sstevel@tonic-gate 		{
1020Sstevel@tonic-gate 			perror( "strdup" );
1030Sstevel@tonic-gate 			exit( 1 );
1040Sstevel@tonic-gate 		}
1050Sstevel@tonic-gate 		++havedn;
1060Sstevel@tonic-gate 	}
1070Sstevel@tonic-gate 	else if ( argc - optind != 0 )
1080Sstevel@tonic-gate 	{
1090Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: invalid number of arguments, only two or three allowed\n"), myname);
1100Sstevel@tonic-gate 		usage();
1110Sstevel@tonic-gate 		exit( 1 );
1120Sstevel@tonic-gate 	}
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate 	ld = ldaptool_ldap_init (0);
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate 	if ( !ldaptool_not ) {
1170Sstevel@tonic-gate 		deref = LDAP_DEREF_NEVER;	/* this seems prudent */
1180Sstevel@tonic-gate 		ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
1190Sstevel@tonic-gate 	}
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	ldaptool_bind( ld );
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	rc = 0;
1240Sstevel@tonic-gate 	if (havedn)
1250Sstevel@tonic-gate 	{
1260Sstevel@tonic-gate 		rc = domodrdn(ld, entrydn, rdn, L_newParent, remove_oldrdn);
1270Sstevel@tonic-gate 	}
1280Sstevel@tonic-gate 	else while (	(rc == 0 || contoper) &&
1290Sstevel@tonic-gate 					(fgets(buf, sizeof(buf), ldaptool_fp) != NULL) )
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	{
1320Sstevel@tonic-gate 		/*
1330Sstevel@tonic-gate 		 * The format of the file is one of the following:
1340Sstevel@tonic-gate 		 * 	dn
1350Sstevel@tonic-gate 		 * 	rdn
1360Sstevel@tonic-gate 		 * 	newsuperior
1370Sstevel@tonic-gate 		 * 	<blank lines...>
1380Sstevel@tonic-gate 		 * OR
1390Sstevel@tonic-gate 		 * 	dn
1400Sstevel@tonic-gate 		 * 	rdn
1410Sstevel@tonic-gate 		 * 	<blank lines...>
1420Sstevel@tonic-gate 		 * both types of sequences can be found in the file
1430Sstevel@tonic-gate 		 */
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 		if ( (strlen(buf) == 1) && (ldaptool_fp == stdin) )
1460Sstevel@tonic-gate 			break;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 		buf[ strlen( buf ) - 1 ] = '\0';	/* remove nl */
1490Sstevel@tonic-gate 		if ( *buf != '\0' ) 		/* blank lines optional, skip */
1500Sstevel@tonic-gate 		{
1510Sstevel@tonic-gate 			if ( haverdn )		/* first type of sequence */
1520Sstevel@tonic-gate 			{
1530Sstevel@tonic-gate 				if (( L_newParent = strdup( buf )) == NULL )
1540Sstevel@tonic-gate 				{
1550Sstevel@tonic-gate 					perror( "strdup" );
1560Sstevel@tonic-gate 					exit( LDAP_NO_MEMORY );
1570Sstevel@tonic-gate 				}
1580Sstevel@tonic-gate 				if ( L_newParent && (L_protoVersion == LDAP_VERSION) )
1590Sstevel@tonic-gate 				{
1600Sstevel@tonic-gate 					printf( gettext("LDAP Server is V2: <newsuperior> argument is ignored...\n") );
1610Sstevel@tonic-gate 					L_newParent = NULL;
1620Sstevel@tonic-gate 				}
1630Sstevel@tonic-gate 				rc = domodrdn(ld, entrydn, rdn, L_newParent, remove_oldrdn);
1640Sstevel@tonic-gate 				haverdn = 0;
1650Sstevel@tonic-gate 			}
1660Sstevel@tonic-gate 			else if ( havedn ) 		/* have DN, get RDN */
1670Sstevel@tonic-gate 			{
1680Sstevel@tonic-gate 				if (( rdn = strdup( buf )) == NULL )
1690Sstevel@tonic-gate 				{
1700Sstevel@tonic-gate 					perror( "strdup" );
1710Sstevel@tonic-gate 					exit( LDAP_NO_MEMORY );
1720Sstevel@tonic-gate 				}
1730Sstevel@tonic-gate 				havedn = 0;
1740Sstevel@tonic-gate 				++haverdn;
1750Sstevel@tonic-gate 			}
1760Sstevel@tonic-gate 			else if ( !havedn ) 		/* don't have DN yet */
1770Sstevel@tonic-gate 			{
1780Sstevel@tonic-gate 				if (( entrydn = strdup( buf )) == NULL)
1790Sstevel@tonic-gate 				{
1800Sstevel@tonic-gate 					perror( "strdup" );
1810Sstevel@tonic-gate 					exit( LDAP_NO_MEMORY );
1820Sstevel@tonic-gate 				}
1830Sstevel@tonic-gate 				++havedn;
1840Sstevel@tonic-gate 			}
1850Sstevel@tonic-gate 		}
1860Sstevel@tonic-gate 		else
1870Sstevel@tonic-gate 		{
1880Sstevel@tonic-gate 			printf(gettext("kex: new line %d\n"), rc);
1890Sstevel@tonic-gate 			if ( haverdn )		/* second type of sequence */
1900Sstevel@tonic-gate 			{
1910Sstevel@tonic-gate 				rc = domodrdn(ld, entrydn, rdn, NULL, remove_oldrdn);
1920Sstevel@tonic-gate 				haverdn = 0;
1930Sstevel@tonic-gate 			}
1940Sstevel@tonic-gate 		}
1950Sstevel@tonic-gate 	}
1960Sstevel@tonic-gate 	if ( (rc == 0 || contoper) && haverdn )		/* second type of sequence */
1970Sstevel@tonic-gate 	{
1980Sstevel@tonic-gate 		rc = domodrdn(ld, entrydn, rdn, NULL, remove_oldrdn);
1990Sstevel@tonic-gate 		haverdn = 0;
2000Sstevel@tonic-gate 	}
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate 	ldaptool_cleanup( ld );
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate 	exit( rc );
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate static void
options_callback(int option,char * optarg)2080Sstevel@tonic-gate options_callback( int option, char *optarg )
2090Sstevel@tonic-gate {
2100Sstevel@tonic-gate 	switch( option ) {
2110Sstevel@tonic-gate 		case 'c':	/* continuous operation mode */
2120Sstevel@tonic-gate 			++contoper;
2130Sstevel@tonic-gate 			break;
2140Sstevel@tonic-gate 		case 'r':	/* remove old RDN */
2150Sstevel@tonic-gate 			++remove_oldrdn;
2160Sstevel@tonic-gate 			break;
2170Sstevel@tonic-gate 		default:
2180Sstevel@tonic-gate 		usage();
2190Sstevel@tonic-gate 	}
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate static int
domodrdn(LDAP * ld,char * dn,char * rdn,char * newsuperior,int remove_oldrdn)2230Sstevel@tonic-gate domodrdn( LDAP *ld, char *dn, char *rdn, char *newsuperior, int remove_oldrdn )
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate 	int	rc = LDAP_SUCCESS;
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	if ( ldaptool_verbose )
2280Sstevel@tonic-gate 		printf( gettext("new RDN: %1$s (%2$skeep existing values)\n"),
229*702Sth160488 						rdn, remove_oldrdn ? "do not " : "" );
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 	printf( gettext("%1$srenaming entry %2$s\n"),
2320Sstevel@tonic-gate 			ldaptool_not ? "!" : "", dn );
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	if ( !ldaptool_not )
2350Sstevel@tonic-gate 	{
2360Sstevel@tonic-gate 		rc = ldap_rename_s( ld, dn, rdn, newsuperior, remove_oldrdn, NULL, NULL );
2370Sstevel@tonic-gate 		if ( rc != LDAP_SUCCESS )
2380Sstevel@tonic-gate 			fprintf(stderr, gettext("ldap_rename_s: %s\n"), ldap_err2string(rc));
2390Sstevel@tonic-gate 		else if ( ldaptool_verbose )
2400Sstevel@tonic-gate 			printf( gettext("rename completed\n") );
2410Sstevel@tonic-gate 	}
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate 	putchar('\n');
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 	return( rc );
2460Sstevel@tonic-gate }
247