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