xref: /titanic_52/usr/src/cmd/ldap/common/ldapmodrdn.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*7c478bd9Sstevel@tonic-gate 
8*7c478bd9Sstevel@tonic-gate /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP */
9*7c478bd9Sstevel@tonic-gate 
10*7c478bd9Sstevel@tonic-gate #include <stdio.h>
11*7c478bd9Sstevel@tonic-gate #include <string.h>
12*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
13*7c478bd9Sstevel@tonic-gate #include <locale.h>
14*7c478bd9Sstevel@tonic-gate #include <ctype.h>
15*7c478bd9Sstevel@tonic-gate #include <lber.h>
16*7c478bd9Sstevel@tonic-gate #include <ldap.h>
17*7c478bd9Sstevel@tonic-gate #include <locale.h>
18*7c478bd9Sstevel@tonic-gate #include "ldaptool.h"
19*7c478bd9Sstevel@tonic-gate 
20*7c478bd9Sstevel@tonic-gate static int	contoper, remove_oldrdn;
21*7c478bd9Sstevel@tonic-gate static LDAP	*ld;
22*7c478bd9Sstevel@tonic-gate 
23*7c478bd9Sstevel@tonic-gate static int domodrdn( LDAP *ld, char *dn, char *rdn, char *newsuperior,
24*7c478bd9Sstevel@tonic-gate 			int remove_oldrdn);
25*7c478bd9Sstevel@tonic-gate static void options_callback( int option, char *optarg );
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate static void usage( void )
28*7c478bd9Sstevel@tonic-gate {
29*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("usage: %s [options] [dn newrdn [newsuperior]]\n"), ldaptool_progname);
30*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("options:\n"));
31*7c478bd9Sstevel@tonic-gate 	ldaptool_common_usage( 0 );
32*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -c\t\tcontinuous mode\n") );
33*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -r\t\tremove old RDN from the entries\n"));
34*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -f file\tread changes from `file'\n") );
35*7c478bd9Sstevel@tonic-gate 	exit(LDAP_PARAM_ERROR );
36*7c478bd9Sstevel@tonic-gate }
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate int main( argc, argv )
39*7c478bd9Sstevel@tonic-gate int		argc;
40*7c478bd9Sstevel@tonic-gate char	**argv;
41*7c478bd9Sstevel@tonic-gate {
42*7c478bd9Sstevel@tonic-gate 	char *myname, *entrydn, *rdn, buf[ 4096 ];
43*7c478bd9Sstevel@tonic-gate 	int rc, havedn, deref, optind;
44*7c478bd9Sstevel@tonic-gate 	char * L_newParent = NULL;
45*7c478bd9Sstevel@tonic-gate 	int haverdn = 0;
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate 	int L_protoVersion = LDAP_VERSION3;
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate 	char *locale = setlocale(LC_ALL, "");
50*7c478bd9Sstevel@tonic-gate 	textdomain(TEXT_DOMAIN);
51*7c478bd9Sstevel@tonic-gate 	ldaplogconfigf(NULL);
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate 	contoper =  remove_oldrdn = 0;
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate 	myname = (myname = strrchr(argv[0], '/')) == NULL ? argv[0] : ++myname;
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate 	optind = ldaptool_process_args( argc, argv, "cr", 0, options_callback);
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate 	if ( optind == -1 ) {
61*7c478bd9Sstevel@tonic-gate 		usage();
62*7c478bd9Sstevel@tonic-gate 	}
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate 	if ( ldaptool_fp == NULL ) {
65*7c478bd9Sstevel@tonic-gate 	ldaptool_fp = stdin;
66*7c478bd9Sstevel@tonic-gate 	}
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate 	havedn = 0;
69*7c478bd9Sstevel@tonic-gate 	if (argc - optind == 3) 		/* accept as arguments: dn rdn newsuperior */
70*7c478bd9Sstevel@tonic-gate 	{
71*7c478bd9Sstevel@tonic-gate 		if (( L_newParent = strdup( argv[argc - 1] )) == NULL )
72*7c478bd9Sstevel@tonic-gate 		{
73*7c478bd9Sstevel@tonic-gate 			perror( "strdup" );
74*7c478bd9Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
75*7c478bd9Sstevel@tonic-gate 		}
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 		if (( rdn = strdup( argv[argc - 2] )) == NULL )
78*7c478bd9Sstevel@tonic-gate 		{
79*7c478bd9Sstevel@tonic-gate 			perror( "strdup" );
80*7c478bd9Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
81*7c478bd9Sstevel@tonic-gate 		}
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 		if (( entrydn = strdup( argv[argc - 3] )) == NULL )
84*7c478bd9Sstevel@tonic-gate 		{
85*7c478bd9Sstevel@tonic-gate 			perror( "strdup" );
86*7c478bd9Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
87*7c478bd9Sstevel@tonic-gate 		}
88*7c478bd9Sstevel@tonic-gate 		++havedn;
89*7c478bd9Sstevel@tonic-gate 	}
90*7c478bd9Sstevel@tonic-gate 	else if (argc - optind == 2) 		/* accept as arguments: dn rdn */
91*7c478bd9Sstevel@tonic-gate 	{
92*7c478bd9Sstevel@tonic-gate 		if (( rdn = strdup( argv[argc - 1] )) == NULL )
93*7c478bd9Sstevel@tonic-gate 		{
94*7c478bd9Sstevel@tonic-gate 			perror( "strdup" );
95*7c478bd9Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
96*7c478bd9Sstevel@tonic-gate 		}
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 		if (( entrydn = strdup( argv[argc - 2] )) == NULL )
99*7c478bd9Sstevel@tonic-gate 		{
100*7c478bd9Sstevel@tonic-gate 			perror( "strdup" );
101*7c478bd9Sstevel@tonic-gate 			exit( 1 );
102*7c478bd9Sstevel@tonic-gate 		}
103*7c478bd9Sstevel@tonic-gate 		++havedn;
104*7c478bd9Sstevel@tonic-gate 	}
105*7c478bd9Sstevel@tonic-gate 	else if ( argc - optind != 0 )
106*7c478bd9Sstevel@tonic-gate 	{
107*7c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: invalid number of arguments, only two or three allowed\n"), myname);
108*7c478bd9Sstevel@tonic-gate 		usage();
109*7c478bd9Sstevel@tonic-gate 		exit( 1 );
110*7c478bd9Sstevel@tonic-gate 	}
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate 	ld = ldaptool_ldap_init (0);
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate 	if ( !ldaptool_not ) {
115*7c478bd9Sstevel@tonic-gate 		deref = LDAP_DEREF_NEVER;	/* this seems prudent */
116*7c478bd9Sstevel@tonic-gate 		ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
117*7c478bd9Sstevel@tonic-gate 	}
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate 	ldaptool_bind( ld );
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 	rc = 0;
122*7c478bd9Sstevel@tonic-gate 	if (havedn)
123*7c478bd9Sstevel@tonic-gate 	{
124*7c478bd9Sstevel@tonic-gate 		rc = domodrdn(ld, entrydn, rdn, L_newParent, remove_oldrdn);
125*7c478bd9Sstevel@tonic-gate 	}
126*7c478bd9Sstevel@tonic-gate 	else while (	(rc == 0 || contoper) &&
127*7c478bd9Sstevel@tonic-gate 					(fgets(buf, sizeof(buf), ldaptool_fp) != NULL) )
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate 	{
130*7c478bd9Sstevel@tonic-gate 		/*
131*7c478bd9Sstevel@tonic-gate 		 * The format of the file is one of the following:
132*7c478bd9Sstevel@tonic-gate 		 * 	dn
133*7c478bd9Sstevel@tonic-gate 		 * 	rdn
134*7c478bd9Sstevel@tonic-gate 		 * 	newsuperior
135*7c478bd9Sstevel@tonic-gate 		 * 	<blank lines...>
136*7c478bd9Sstevel@tonic-gate 		 * OR
137*7c478bd9Sstevel@tonic-gate 		 * 	dn
138*7c478bd9Sstevel@tonic-gate 		 * 	rdn
139*7c478bd9Sstevel@tonic-gate 		 * 	<blank lines...>
140*7c478bd9Sstevel@tonic-gate 		 * both types of sequences can be found in the file
141*7c478bd9Sstevel@tonic-gate 		 */
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 		if ( (strlen(buf) == 1) && (ldaptool_fp == stdin) )
144*7c478bd9Sstevel@tonic-gate 			break;
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate 		buf[ strlen( buf ) - 1 ] = '\0';	/* remove nl */
147*7c478bd9Sstevel@tonic-gate 		if ( *buf != '\0' ) 		/* blank lines optional, skip */
148*7c478bd9Sstevel@tonic-gate 		{
149*7c478bd9Sstevel@tonic-gate 			if ( haverdn )		/* first type of sequence */
150*7c478bd9Sstevel@tonic-gate 			{
151*7c478bd9Sstevel@tonic-gate 				if (( L_newParent = strdup( buf )) == NULL )
152*7c478bd9Sstevel@tonic-gate 				{
153*7c478bd9Sstevel@tonic-gate 					perror( "strdup" );
154*7c478bd9Sstevel@tonic-gate 					exit( LDAP_NO_MEMORY );
155*7c478bd9Sstevel@tonic-gate 				}
156*7c478bd9Sstevel@tonic-gate 				if ( L_newParent && (L_protoVersion == LDAP_VERSION) )
157*7c478bd9Sstevel@tonic-gate 				{
158*7c478bd9Sstevel@tonic-gate 					printf( gettext("LDAP Server is V2: <newsuperior> argument is ignored...\n") );
159*7c478bd9Sstevel@tonic-gate 					L_newParent = NULL;
160*7c478bd9Sstevel@tonic-gate 				}
161*7c478bd9Sstevel@tonic-gate 				rc = domodrdn(ld, entrydn, rdn, L_newParent, remove_oldrdn);
162*7c478bd9Sstevel@tonic-gate 				haverdn = 0;
163*7c478bd9Sstevel@tonic-gate 			}
164*7c478bd9Sstevel@tonic-gate 			else if ( havedn ) 		/* have DN, get RDN */
165*7c478bd9Sstevel@tonic-gate 			{
166*7c478bd9Sstevel@tonic-gate 				if (( rdn = strdup( buf )) == NULL )
167*7c478bd9Sstevel@tonic-gate 				{
168*7c478bd9Sstevel@tonic-gate 					perror( "strdup" );
169*7c478bd9Sstevel@tonic-gate 					exit( LDAP_NO_MEMORY );
170*7c478bd9Sstevel@tonic-gate 				}
171*7c478bd9Sstevel@tonic-gate 				havedn = 0;
172*7c478bd9Sstevel@tonic-gate 				++haverdn;
173*7c478bd9Sstevel@tonic-gate 			}
174*7c478bd9Sstevel@tonic-gate 			else if ( !havedn ) 		/* don't have DN yet */
175*7c478bd9Sstevel@tonic-gate 			{
176*7c478bd9Sstevel@tonic-gate 				if (( entrydn = strdup( buf )) == NULL)
177*7c478bd9Sstevel@tonic-gate 				{
178*7c478bd9Sstevel@tonic-gate 					perror( "strdup" );
179*7c478bd9Sstevel@tonic-gate 					exit( LDAP_NO_MEMORY );
180*7c478bd9Sstevel@tonic-gate 				}
181*7c478bd9Sstevel@tonic-gate 				++havedn;
182*7c478bd9Sstevel@tonic-gate 			}
183*7c478bd9Sstevel@tonic-gate 		}
184*7c478bd9Sstevel@tonic-gate 		else
185*7c478bd9Sstevel@tonic-gate 		{
186*7c478bd9Sstevel@tonic-gate 			printf(gettext("kex: new line %d\n"), rc);
187*7c478bd9Sstevel@tonic-gate 			if ( haverdn )		/* second type of sequence */
188*7c478bd9Sstevel@tonic-gate 			{
189*7c478bd9Sstevel@tonic-gate 				rc = domodrdn(ld, entrydn, rdn, NULL, remove_oldrdn);
190*7c478bd9Sstevel@tonic-gate 				haverdn = 0;
191*7c478bd9Sstevel@tonic-gate 			}
192*7c478bd9Sstevel@tonic-gate 		}
193*7c478bd9Sstevel@tonic-gate 	}
194*7c478bd9Sstevel@tonic-gate 	if ( (rc == 0 || contoper) && haverdn )		/* second type of sequence */
195*7c478bd9Sstevel@tonic-gate 	{
196*7c478bd9Sstevel@tonic-gate 		rc = domodrdn(ld, entrydn, rdn, NULL, remove_oldrdn);
197*7c478bd9Sstevel@tonic-gate 		haverdn = 0;
198*7c478bd9Sstevel@tonic-gate 	}
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 	ldaptool_cleanup( ld );
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 	exit( rc );
203*7c478bd9Sstevel@tonic-gate }
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate static void
206*7c478bd9Sstevel@tonic-gate options_callback( int option, char *optarg )
207*7c478bd9Sstevel@tonic-gate {
208*7c478bd9Sstevel@tonic-gate 	switch( option ) {
209*7c478bd9Sstevel@tonic-gate 		case 'c':	/* continuous operation mode */
210*7c478bd9Sstevel@tonic-gate 			++contoper;
211*7c478bd9Sstevel@tonic-gate 			break;
212*7c478bd9Sstevel@tonic-gate 		case 'r':	/* remove old RDN */
213*7c478bd9Sstevel@tonic-gate 			++remove_oldrdn;
214*7c478bd9Sstevel@tonic-gate 			break;
215*7c478bd9Sstevel@tonic-gate 		default:
216*7c478bd9Sstevel@tonic-gate 		usage();
217*7c478bd9Sstevel@tonic-gate 	}
218*7c478bd9Sstevel@tonic-gate }
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate static int
221*7c478bd9Sstevel@tonic-gate domodrdn( LDAP *ld, char *dn, char *rdn, char *newsuperior, int remove_oldrdn )
222*7c478bd9Sstevel@tonic-gate {
223*7c478bd9Sstevel@tonic-gate 	int	rc = LDAP_SUCCESS;
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate 	if ( ldaptool_verbose )
226*7c478bd9Sstevel@tonic-gate 		printf( gettext("new RDN: %1$s (%2$skeep existing values)\n"),
227*7c478bd9Sstevel@tonic-gate 						rdn, remove ? "do not " : "" );
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate 	printf( gettext("%1$srenaming entry %2$s\n"),
230*7c478bd9Sstevel@tonic-gate 			ldaptool_not ? "!" : "", dn );
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	if ( !ldaptool_not )
233*7c478bd9Sstevel@tonic-gate 	{
234*7c478bd9Sstevel@tonic-gate 		rc = ldap_rename_s( ld, dn, rdn, newsuperior, remove_oldrdn, NULL, NULL );
235*7c478bd9Sstevel@tonic-gate 		if ( rc != LDAP_SUCCESS )
236*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("ldap_rename_s: %s\n"), ldap_err2string(rc));
237*7c478bd9Sstevel@tonic-gate 		else if ( ldaptool_verbose )
238*7c478bd9Sstevel@tonic-gate 			printf( gettext("rename completed\n") );
239*7c478bd9Sstevel@tonic-gate 	}
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate 	putchar('\n');
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	return( rc );
244*7c478bd9Sstevel@tonic-gate }
245