]> git.sur5r.net Git - openldap/blob - clients/tools/ldapmodrdn.c
066ebfd6dc805436b5bddd50e55a4be1905341a3
[openldap] / clients / tools / ldapmodrdn.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP.
7  *
8  * Support for MODIFYDN REQUEST V3 (newSuperior) by:
9  * 
10  * Copyright 1999, Juan C. Gomez, All rights reserved.
11  * This software is not subject to any license of Silicon Graphics 
12  * Inc. or Purdue University.
13  *
14  * Redistribution and use in source and binary forms are permitted
15  * without restriction or fee of any kind as long as this notice
16  * is preserved.
17  *
18  */
19
20 #include "portable.h"
21
22 #include <stdio.h>
23
24 #include <ac/stdlib.h>
25
26 #include <ac/ctype.h>
27 #include <ac/signal.h>
28 #include <ac/string.h>
29 #include <ac/unistd.h>
30
31 #include <ldap.h>
32 #include "lutil_ldap.h"
33 #include "ldap_defaults.h"
34
35 static char *prog = NULL;
36 static char     *binddn = NULL;
37 static struct berval passwd = { 0, NULL };
38 static char     *ldapuri = NULL;
39 static char     *ldaphost = NULL;
40 static int      ldapport = 0;
41 #ifdef HAVE_CYRUS_SASL
42 static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
43 static char *sasl_realm = NULL;
44 static char     *sasl_authc_id = NULL;
45 static char     *sasl_authz_id = NULL;
46 static char     *sasl_mech = NULL;
47 static char     *sasl_secprops = NULL;
48 #endif
49 static int      use_tls = 0;
50 static int      not, verbose, contoper;
51 static LDAP     *ld = NULL;
52
53 static int domodrdn(
54     LDAP        *ld,
55     char        *dn,
56     char        *rdn,
57     char        *newSuperior,
58     int         remove );       /* flag: remove old RDN */
59
60 static void
61 usage( const char *s )
62 {
63         fprintf( stderr,
64 "Rename LDAP entries\n\n"
65 "usage: %s [options] [dn rdn]\n"
66 "       dn rdn: If given, rdn will replace the RDN of the entry specified by DN\n"
67 "               If not given, the list of modifications is read from stdin or\n"
68 "               from the file specified by \"-f file\" (see man page).\n"
69 "Rename options:\n"
70 "  -c         continuous operation mode (do not stop on errors)\n"
71 "  -f file    read operations from `file'\n"
72 "  -r         remove old RDN\n"
73 "  -s newsup  new superior entry\n"
74
75 "Common options:\n"
76 "  -d level   set LDAP debugging level to `level'\n"
77 "  -D binddn  bind DN\n"
78 "  -f file    read operations from `file'\n"
79 "  -h host    LDAP server\n"
80 "  -H URI     LDAP Uniform Resource Indentifier(s)\n"
81 "  -I         use SASL Interactive mode\n"
82 "  -k         use Kerberos authentication\n"
83 "  -K         like -k, but do only step 1 of the Kerberos bind\n"
84 "  -M         enable Manage DSA IT control (-MM to make critical)\n"
85 "  -n         show what would be done but don't actually search\n"
86 "  -O props   SASL security properties\n"
87 "  -p port    port on LDAP server\n"
88 "  -P version procotol version (default: 3)\n"
89 "  -Q         use SASL Quiet mode\n"
90 "  -R realm   SASL realm\n"
91 "  -U user    SASL authentication identity (username)\n"
92 "  -v         run in verbose mode (diagnostics to standard output)\n"
93 "  -w passwd  bind passwd (for simple authentication)\n"
94 "  -W         prompt for bind passwd\n"
95 "  -x         Simple authentication\n"
96 "  -X id      SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
97 "  -Y mech    SASL mechanism\n"
98 "  -Z         Start TLS request (-ZZ to require successful response)\n"
99 ,               s );
100
101         exit( EXIT_FAILURE );
102 }
103
104 int
105 main(int argc, char **argv)
106 {
107     char                *infile, *entrydn = NULL, *rdn = NULL, buf[ 4096 ];
108     FILE                *fp;
109         int             rc, i, remove, havedn, authmethod, version, want_bindpw, debug, manageDSAit;
110         int             referrals;
111     char        *newSuperior=NULL;
112
113     infile = NULL;
114     not = contoper = verbose = remove = want_bindpw =
115                 debug = manageDSAit = referrals = 0;
116     authmethod = LDAP_AUTH_SIMPLE;
117         version = -1;
118
119     prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : prog + 1;
120
121     while (( i = getopt( argc, argv, "cf:rs:" "Cd:D:h:H:IkKMnO:p:P:QRU:vw:WxX:Y:Z" )) != EOF ) {
122         switch( i ) {
123         /* Modrdn Options */
124         case 'c':
125                 contoper++;
126                 break;
127         case 'f':       /* read from file */
128                 if( infile != NULL ) {
129                         fprintf( stderr, "%s: -f previously specified\n" );
130                         return EXIT_FAILURE;
131                 }
132             infile = strdup( optarg );
133             break;
134         case 'r':       /* remove old RDN */
135             remove++;
136             break;
137         case 's':       /* newSuperior */
138                 if( version == LDAP_VERSION2 ) {
139                         fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
140                                 prog, version );
141                         return EXIT_FAILURE;
142                 }
143             newSuperior = strdup( optarg );
144             version = LDAP_VERSION3;
145             break;
146
147         /* Common Options */
148         case 'C':
149                 referrals++;
150                 break;
151         case 'd':
152             debug |= atoi( optarg );
153             break;
154         case 'D':       /* bind DN */
155                 if( binddn != NULL ) {
156                         fprintf( stderr, "%s: -D previously specified\n" );
157                         return EXIT_FAILURE;
158                 }
159             binddn = strdup( optarg );
160             break;
161         case 'h':       /* ldap host */
162                 if( ldapuri != NULL ) {
163                         fprintf( stderr, "%s: -h incompatible with -H\n" );
164                         return EXIT_FAILURE;
165                 }
166                 if( ldaphost != NULL ) {
167                         fprintf( stderr, "%s: -h previously specified\n" );
168                         return EXIT_FAILURE;
169                 }
170             ldaphost = strdup( optarg );
171             break;
172         case 'H':       /* ldap URI */
173                 if( ldaphost != NULL ) {
174                         fprintf( stderr, "%s: -H incompatible with -h\n" );
175                         return EXIT_FAILURE;
176                 }
177                 if( ldapport ) {
178                         fprintf( stderr, "%s: -H incompatible with -p\n" );
179                         return EXIT_FAILURE;
180                 }
181                 if( ldapuri != NULL ) {
182                         fprintf( stderr, "%s: -H previously specified\n" );
183                         return EXIT_FAILURE;
184                 }
185             ldapuri = strdup( optarg );
186             break;
187         case 'I':
188 #ifdef HAVE_CYRUS_SASL
189                 if( version == LDAP_VERSION2 ) {
190                         fprintf( stderr, "%s: -I incompatible with version %d\n",
191                                 prog, version );
192                         return EXIT_FAILURE;
193                 }
194                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
195                         fprintf( stderr, "%s: incompatible previous "
196                                 "authentication choice\n",
197                                 prog );
198                         return EXIT_FAILURE;
199                 }
200                 authmethod = LDAP_AUTH_SASL;
201                 version = LDAP_VERSION3;
202                 sasl_flags = LDAP_SASL_INTERACTIVE;
203                 break;
204 #else
205                 fprintf( stderr, "%s: was not compiled with SASL support\n",
206                         prog );
207                 return( EXIT_FAILURE );
208 #endif
209         case 'k':       /* kerberos bind */
210 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
211                 if( version > LDAP_VERSION2 ) {
212                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
213                                 prog, version );
214                         return EXIT_FAILURE;
215                 }
216
217                 if( authmethod != -1 ) {
218                         fprintf( stderr, "%s: -k incompatible with previous "
219                                 "authentication choice\n", prog );
220                         return EXIT_FAILURE;
221                 }
222                         
223                 authmethod = LDAP_AUTH_KRBV4;
224 #else
225                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
226                 return EXIT_FAILURE;
227 #endif
228             break;
229         case 'K':       /* kerberos bind, part one only */
230 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
231                 if( version > LDAP_VERSION2 ) {
232                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
233                                 prog, version );
234                         return EXIT_FAILURE;
235                 }
236                 if( authmethod != -1 ) {
237                         fprintf( stderr, "%s: incompatible with previous "
238                                 "authentication choice\n", prog );
239                         return EXIT_FAILURE;
240                 }
241
242                 authmethod = LDAP_AUTH_KRBV41;
243 #else
244                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
245                 return( EXIT_FAILURE );
246 #endif
247             break;
248         case 'M':
249                 /* enable Manage DSA IT */
250                 if( version == LDAP_VERSION2 ) {
251                         fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
252                                 prog, version );
253                         return EXIT_FAILURE;
254                 }
255                 manageDSAit++;
256                 version = LDAP_VERSION3;
257                 break;
258         case 'n':       /* print deletes, don't actually do them */
259             ++not;
260             break;
261         case 'O':
262 #ifdef HAVE_CYRUS_SASL
263                 if( sasl_secprops != NULL ) {
264                         fprintf( stderr, "%s: -O previously specified\n" );
265                         return EXIT_FAILURE;
266                 }
267                 if( version == LDAP_VERSION2 ) {
268                         fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
269                                 prog, version );
270                         return EXIT_FAILURE;
271                 }
272                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
273                         fprintf( stderr, "%s: incompatible previous "
274                                 "authentication choice\n", prog );
275                         return EXIT_FAILURE;
276                 }
277                 authmethod = LDAP_AUTH_SASL;
278                 version = LDAP_VERSION3;
279                 sasl_secprops = strdup( optarg );
280 #else
281                 fprintf( stderr, "%s: not compiled with SASL support\n",
282                         prog );
283                 return( EXIT_FAILURE );
284 #endif
285                 break;
286         case 'p':
287                 if( ldapport ) {
288                         fprintf( stderr, "%s: -p previously specified\n" );
289                         return EXIT_FAILURE;
290                 }
291             ldapport = atoi( optarg );
292             break;
293         case 'P':
294                 switch( atoi(optarg) ) {
295                 case 2:
296                         if( version == LDAP_VERSION3 ) {
297                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
298                                         prog, version );
299                                 return EXIT_FAILURE;
300                         }
301                         version = LDAP_VERSION2;
302                         break;
303                 case 3:
304                         if( version == LDAP_VERSION2 ) {
305                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
306                                         prog, version );
307                                 return EXIT_FAILURE;
308                         }
309                         version = LDAP_VERSION3;
310                         break;
311                 default:
312                         fprintf( stderr, "%s: protocol version should be 2 or 3\n",
313                                 prog );
314                         usage( prog );
315                         return( EXIT_FAILURE );
316                 } break;
317         case 'Q':
318 #ifdef HAVE_CYRUS_SASL
319                 if( version == LDAP_VERSION2 ) {
320                         fprintf( stderr, "%s: -Q incompatible with version %d\n",
321                                 prog, version );
322                         return EXIT_FAILURE;
323                 }
324                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
325                         fprintf( stderr, "%s: incompatible previous "
326                                 "authentication choice\n",
327                                 prog );
328                         return EXIT_FAILURE;
329                 }
330                 authmethod = LDAP_AUTH_SASL;
331                 version = LDAP_VERSION3;
332                 sasl_flags = LDAP_SASL_QUIET;
333                 break;
334 #else
335                 fprintf( stderr, "%s: not compiled with SASL support\n",
336                         prog );
337                 return( EXIT_FAILURE );
338 #endif
339         case 'R':
340 #ifdef HAVE_CYRUS_SASL
341                 if( sasl_realm != NULL ) {
342                         fprintf( stderr, "%s: -R previously specified\n" );
343                         return EXIT_FAILURE;
344                 }
345                 if( version == LDAP_VERSION2 ) {
346                         fprintf( stderr, "%s: -R incompatible with version %d\n",
347                                 prog, version );
348                         return EXIT_FAILURE;
349                 }
350                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
351                         fprintf( stderr, "%s: incompatible previous "
352                                 "authentication choice\n",
353                                 prog );
354                         return EXIT_FAILURE;
355                 }
356                 authmethod = LDAP_AUTH_SASL;
357                 version = LDAP_VERSION3;
358                 sasl_realm = strdup( optarg );
359 #else
360                 fprintf( stderr, "%s: not compiled with SASL support\n",
361                         prog );
362                 return( EXIT_FAILURE );
363 #endif
364                 break;
365         case 'U':
366 #ifdef HAVE_CYRUS_SASL
367                 if( sasl_authc_id != NULL ) {
368                         fprintf( stderr, "%s: -U previously specified\n" );
369                         return EXIT_FAILURE;
370                 }
371                 if( version == LDAP_VERSION2 ) {
372                         fprintf( stderr, "%s: -U incompatible with version %d\n",
373                                 prog, version );
374                         return EXIT_FAILURE;
375                 }
376                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
377                         fprintf( stderr, "%s: incompatible previous "
378                                 "authentication choice\n",
379                                 prog );
380                         return EXIT_FAILURE;
381                 }
382                 authmethod = LDAP_AUTH_SASL;
383                 version = LDAP_VERSION3;
384                 sasl_authc_id = strdup( optarg );
385 #else
386                 fprintf( stderr, "%s: not compiled with SASL support\n",
387                         prog );
388                 return( EXIT_FAILURE );
389 #endif
390                 break;
391         case 'v':       /* verbose mode */
392             verbose++;
393             break;
394         case 'w':       /* password */
395             passwd.bv_val = strdup( optarg );
396                 {
397                         char* p;
398
399                         for( p = optarg; *p == '\0'; p++ ) {
400                                 *p = '\0';
401                         }
402                 }
403                 passwd.bv_len = strlen( passwd.bv_val );
404             break;
405         case 'W':
406                 want_bindpw++;
407                 break;
408         case 'Y':
409 #ifdef HAVE_CYRUS_SASL
410                 if( sasl_mech != NULL ) {
411                         fprintf( stderr, "%s: -Y previously specified\n" );
412                         return EXIT_FAILURE;
413                 }
414                 if( version == LDAP_VERSION2 ) {
415                         fprintf( stderr, "%s: -Y incompatible with version %d\n",
416                                 prog, version );
417                         return EXIT_FAILURE;
418                 }
419                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
420                         fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
421                         return EXIT_FAILURE;
422                 }
423                 authmethod = LDAP_AUTH_SASL;
424                 version = LDAP_VERSION3;
425                 sasl_mech = strdup( optarg );
426 #else
427                 fprintf( stderr, "%s: not compiled with SASL support\n",
428                         prog );
429                 return( EXIT_FAILURE );
430 #endif
431                 break;
432         case 'x':
433                 if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
434                         fprintf( stderr, "%s: incompatible with previous "
435                                 "authentication choice\n", prog );
436                         return EXIT_FAILURE;
437                 }
438                 authmethod = LDAP_AUTH_SIMPLE;
439                 break;
440         case 'X':
441 #ifdef HAVE_CYRUS_SASL
442                 if( sasl_authz_id != NULL ) {
443                         fprintf( stderr, "%s: -X previously specified\n" );
444                         return EXIT_FAILURE;
445                 }
446                 if( version == LDAP_VERSION2 ) {
447                         fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
448                                 prog, version );
449                         return EXIT_FAILURE;
450                 }
451                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
452                         fprintf( stderr, "%s: -X incompatible with "
453                                 "authentication choice\n", prog );
454                         return EXIT_FAILURE;
455                 }
456                 authmethod = LDAP_AUTH_SASL;
457                 version = LDAP_VERSION3;
458                 sasl_authz_id = strdup( optarg );
459 #else
460                 fprintf( stderr, "%s: not compiled with SASL support\n",
461                         prog );
462                 return( EXIT_FAILURE );
463 #endif
464                 break;
465         case 'Z':
466 #ifdef HAVE_TLS
467                 if( version == LDAP_VERSION2 ) {
468                         fprintf( stderr, "%s: -Z incompatible with version %d\n",
469                                 prog, version );
470                         return EXIT_FAILURE;
471                 }
472                 version = LDAP_VERSION3;
473                 use_tls++;
474 #else
475                 fprintf( stderr, "%s: not compiled with TLS support\n",
476                         prog );
477                 return( EXIT_FAILURE );
478 #endif
479                 break;
480         default:
481                 fprintf( stderr, "%s: unrecongized option -%c\n",
482                         prog, optopt );
483             usage( argv[0] );
484             return( EXIT_FAILURE );
485         }
486     }
487
488         if (version == -1) {
489                 version = LDAP_VERSION3;
490         }
491         if (authmethod == -1 && version > LDAP_VERSION2) {
492 #ifdef HAVE_CYRUS_SASL
493                 authmethod = LDAP_AUTH_SASL;
494 #else
495                 authmethod = LDAP_AUTH_SIMPLE;
496 #endif
497         }
498
499     havedn = 0;
500     if (argc - optind == 2) {
501         if (( rdn = strdup( argv[argc - 1] )) == NULL ) {
502             perror( "strdup" );
503             return( EXIT_FAILURE );
504         }
505         if (( entrydn = strdup( argv[argc - 2] )) == NULL ) {
506             perror( "strdup" );
507             return( EXIT_FAILURE );
508         }
509         ++havedn;
510     } else if ( argc - optind != 0 ) {
511         fprintf( stderr, "%s: invalid number of arguments (%d), "
512                 "only two allowed\n", prog, argc-optind );
513         usage( argv[0] );
514         return( EXIT_FAILURE );
515     }
516
517     if ( infile != NULL ) {
518         if (( fp = fopen( infile, "r" )) == NULL ) {
519             perror( infile );
520             return( EXIT_FAILURE );
521         }
522     } else {
523         fp = stdin;
524     }
525
526         if ( debug ) {
527                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
528                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
529                 }
530                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
531                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
532                 }
533         }
534
535 #ifdef SIGPIPE
536         (void) SIGNAL( SIGPIPE, SIG_IGN );
537 #endif
538
539         if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
540                 if ( verbose ) {
541                         fprintf( stderr, "ldap_init( %s, %d )\n",
542                                 ldaphost != NULL ? ldaphost : "<DEFAULT>",
543                                 ldapport );
544                 }
545                 ld = ldap_init( ldaphost, ldapport );
546
547         } else {
548                 if ( verbose ) {
549                         fprintf( stderr, "ldap_initialize( %s )\n",
550                                 ldapuri != NULL ? ldapuri : "<DEFAULT>" );
551                 }
552                 (void) ldap_initialize( &ld, ldapuri );
553         }
554
555         if( ld == NULL ) {
556                 fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
557                         rc, ldap_err2string(rc) );
558                 return EXIT_FAILURE;
559         }
560
561         /* referrals */
562         if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
563                 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
564         {
565                 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
566                         referrals ? "on" : "off" );
567                 return EXIT_FAILURE;
568         }
569
570         if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
571                 != LDAP_OPT_SUCCESS )
572         {
573                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
574                         version );
575                 return EXIT_FAILURE;
576         }
577
578         if ( use_tls && ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
579                 if ( use_tls > 1 ) {
580                         ldap_perror( ld, "ldap_start_tls" );
581                         return( EXIT_FAILURE );
582                 }
583                 fprintf( stderr, "WARNING: could not start TLS\n" );
584         }
585
586         if (want_bindpw) {
587                 passwd.bv_val = getpassphrase("Enter LDAP Password: ");
588                 passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
589         }
590
591         if ( authmethod == LDAP_AUTH_SASL ) {
592 #ifdef HAVE_CYRUS_SASL
593                 void *defaults;
594
595                 if( sasl_secprops != NULL ) {
596                         rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
597                                 (void *) sasl_secprops );
598                         
599                         if( rc != LDAP_OPT_SUCCESS ) {
600                                 fprintf( stderr,
601                                         "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
602                                         sasl_secprops );
603                                 return( EXIT_FAILURE );
604                         }
605                 }
606                 
607                 defaults = lutil_sasl_defaults( ld,
608                         sasl_mech,
609                         sasl_realm,
610                         sasl_authc_id,
611                         passwd.bv_val,
612                         sasl_authz_id );
613
614                 rc = ldap_sasl_interactive_bind_s( ld, binddn,
615                         sasl_mech, NULL, NULL,
616                         sasl_flags, lutil_sasl_interact, defaults );
617
618                 if( rc != LDAP_SUCCESS ) {
619                         ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
620                         return( EXIT_FAILURE );
621                 }
622 #else
623                 fprintf( stderr, "%s: not compiled with SASL support\n",
624                         argv[0] );
625                 return( EXIT_FAILURE );
626 #endif
627         }
628         else {
629                 if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
630                                 != LDAP_SUCCESS ) {
631                         ldap_perror( ld, "ldap_bind" );
632                         return( EXIT_FAILURE );
633                 }
634         }
635
636         if ( manageDSAit ) {
637                 int err;
638                 LDAPControl c;
639                 LDAPControl *ctrls[2];
640                 ctrls[0] = &c;
641                 ctrls[1] = NULL;
642
643                 c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
644                 c.ldctl_value.bv_val = NULL;
645                 c.ldctl_value.bv_len = 0;
646                 c.ldctl_iscritical = manageDSAit > 1;
647
648                 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
649
650                 if( err != LDAP_OPT_SUCCESS ) {
651                         fprintf( stderr, "Could not set ManageDSAit %scontrol\n",
652                                 c.ldctl_iscritical ? "critical " : "" );
653                         if( c.ldctl_iscritical ) {
654                                 exit( EXIT_FAILURE );
655                         }
656                 }
657         }
658
659     rc = 0;
660     if (havedn)
661         rc = domodrdn( ld, entrydn, rdn, newSuperior, remove );
662     else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
663         if ( *buf != '\0' ) {   /* blank lines optional, skip */
664             buf[ strlen( buf ) - 1 ] = '\0';    /* remove nl */
665
666             if ( havedn ) {     /* have DN, get RDN */
667                 if (( rdn = strdup( buf )) == NULL ) {
668                     perror( "strdup" );
669                     return( EXIT_FAILURE );
670                 }
671                 rc = domodrdn(ld, entrydn, rdn, newSuperior, remove );
672                 havedn = 0;
673             } else if ( !havedn ) {     /* don't have DN yet */
674                 if (( entrydn = strdup( buf )) == NULL ) {
675                     perror( "strdup" );
676                     return( EXIT_FAILURE );
677                 }
678                 ++havedn;
679             }
680         }
681     }
682
683     ldap_unbind( ld );
684
685         /* UNREACHABLE */
686         return( rc );
687 }
688
689 static int domodrdn(
690     LDAP        *ld,
691     char        *dn,
692     char        *rdn,
693     char        *newSuperior,
694     int         remove ) /* flag: remove old RDN */
695 {
696         int rc, code, id;
697         char *matcheddn=NULL, *text=NULL, **refs=NULL;
698         LDAPMessage *res;
699
700     if ( verbose ) {
701                 printf( "Renaming \"%s\"\n", dn );
702                 printf( "\tnew rdn=\"%s\" (%s old rdn)\n",
703                         rdn, remove ? "delete" : "keep" );
704                 if( newSuperior != NULL ) {
705                         printf("\tnew parent=\"%s\"\n", newSuperior);
706                 }
707         }
708
709         if( not ) return LDAP_SUCCESS;
710
711         rc = ldap_rename( ld, dn, rdn, newSuperior, remove,
712                 NULL, NULL, &id );
713
714         if ( rc != LDAP_SUCCESS ) {
715                 fprintf( stderr, "%s: ldap_rename: %s (%d)\n",
716                         prog, ldap_err2string( rc ), rc );
717                 return rc;
718         }
719
720         rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
721         if ( rc < 0 ) {
722                 ldap_perror( ld, "ldapmodrdn: ldap_result" );
723                 return rc;
724         }
725
726         rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 1 );
727
728         if( rc != LDAP_SUCCESS ) {
729                 fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
730                         prog, ldap_err2string( rc ), rc );
731                 return rc;
732         }
733
734         if( verbose || code != LDAP_SUCCESS ||
735                 (matcheddn && *matcheddn) || (text && *text) || (refs && *refs) )
736         {
737                 printf( "Rename Result: %s (%d)\n",
738                         ldap_err2string( code ), code );
739
740                 if( text && *text ) {
741                         printf( "Additional info: %s\n", text );
742                 }
743
744                 if( matcheddn && *matcheddn ) {
745                         printf( "Matched DN: %s\n", matcheddn );
746                 }
747
748                 if( refs ) {
749                         int i;
750                         for( i=0; refs[i]; i++ ) {
751                                 printf("Referral: %s\n", refs[i] );
752                         }
753                 }
754         }
755
756         ber_memfree( text );
757         ber_memfree( matcheddn );
758         ber_memvfree( (void **) refs );
759
760         return code;
761 }