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