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