]> git.sur5r.net Git - openldap/blob - clients/tools/ldappasswd.c
be5f5d1b11f91f2da6408822be49e5c2f9027745
[openldap] / clients / tools / ldappasswd.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/stdlib.h>
12
13 #include <ac/ctype.h>
14 #include <ac/signal.h>
15 #include <ac/socket.h>
16 #include <ac/string.h>
17 #include <ac/time.h>
18 #include <ac/unistd.h>
19
20 #include <ldap.h>
21
22 #include "lutil_ldap.h"
23 #include "ldap_defaults.h"
24
25 static int      verbose = 0;
26
27 static void
28 usage(const char *s)
29 {
30         fprintf(stderr,
31 "Change password of an LDAP user\n\n"
32 "usage: %s [options] user\n"
33 "       user: the identity of the user, normally a DN\n"
34 "Password change options:\n"
35 "       -a secret\told password\n"
36 "       -A\t\tprompt for old password\n"
37 "       -s secret\tnew password\n"
38 "       -S\t\tprompt for new password\n"
39
40 "Common options:\n"
41 "       -d level\tdebugging level\n"
42 "       -C\t\tchase referrals\n"
43 "       -D binddn\tbind DN\n"
44 "       -h host\t\tLDAP server (default: localhost)\n"
45 "       -I\t\tuse SASL Interactive mode\n"
46 "       -n\t\tmake no modifications\n"
47 "       -O secprops\tSASL security properties\n"
48 "       -p port\t\tport on LDAP server\n"
49 "       -Q\t\tuse SASL Quiet mode\n"
50 "       -R realm\tSASL realm\n"
51 "       -U user\t\tSASL authentication identity (username)\n"
52 "       -v\t\tverbose mode\n"
53 "       -w passwd\tbind password (for simple authentication)\n"
54 "       -W\t\tprompt for bind password\n"
55 "       -x\t\tSimple authentication\n"
56 "       -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
57 "       -Y mech\t\tSASL mechanism\n"
58 "       -Z\t\tissue Start TLS request (-ZZ to require successful response)\n"
59                 , s );
60
61         exit( EXIT_FAILURE );
62 }
63
64 int
65 main( int argc, char *argv[] )
66 {
67         int rc;
68         char    *prog = NULL;
69         char    *ldaphost = NULL;
70
71         char    *dn = NULL;
72         char    *binddn = NULL;
73
74         struct berval passwd = { 0, NULL };
75         char    *newpw = NULL;
76         char    *oldpw = NULL;
77
78         int             want_bindpw = 0;
79         int             want_newpw = 0;
80         int             want_oldpw = 0;
81
82         int             not = 0;
83         int             i;
84         int             ldapport = 0;
85         int             debug = 0;
86         int             version = -1;
87         int             authmethod = -1;
88         int             manageDSAit = 0;
89 #ifdef HAVE_CYRUS_SASL
90         unsigned        sasl_flags = LUTIL_SASL_AUTOMATIC;
91         char            *sasl_realm = NULL;
92         char            *sasl_authc_id = NULL;
93         char            *sasl_authz_id = NULL;
94         char            *sasl_mech = NULL;
95         char            *sasl_secprops = NULL;
96 #endif
97         int             use_tls = 0;
98         int             referrals = 0;
99         LDAP           *ld;
100         struct berval *bv = NULL;
101
102         int id, code;
103         LDAPMessage *res;
104         char *matcheddn = NULL, *text = NULL, **refs = NULL;
105         char    *retoid = NULL;
106         struct berval *retdata = NULL;
107
108     prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : ++prog;
109
110         if (argc == 1)
111                 usage (argv[0]);
112
113         while( (i = getopt( argc, argv,
114                 "Aa:Ss:" "Cd:D:h:InO:p:QRU:vw:WxX:Y:Z" )) != EOF )
115         {
116                 switch (i) {
117                 /* Password Options */
118                 case 'A':       /* prompt for old password */
119                         want_oldpw++;
120                         break;
121
122                 case 'a':       /* old password (secret) */
123                         oldpw = strdup (optarg);
124
125                         {
126                                 char* p;
127
128                                 for( p = optarg; *p == '\0'; p++ ) {
129                                         *p = '\0';
130                                 }
131                         }
132                         break;
133
134                 case 'S':       /* prompt for user password */
135                         want_newpw++;
136                         break;
137
138                 case 's':       /* new password (secret) */
139                         newpw = strdup (optarg);
140                         {
141                                 char* p;
142
143                                 for( p = optarg; *p == '\0'; p++ ) {
144                                         *p = '\0';
145                                 }
146                         }
147                         break;
148
149         /* Common Options (including options we don't use) */
150         case 'C':
151                 referrals++;
152                 break;
153         case 'd':
154             debug |= atoi( optarg );
155             break;
156         case 'D':       /* bind DN */
157                 if( binddn != NULL ) {
158                         fprintf( stderr, "%s: -D previously specified\n" );
159                         return EXIT_FAILURE;
160                 }
161             binddn = strdup( optarg );
162             break;
163         case 'h':       /* ldap host */
164                 if( ldaphost != NULL ) {
165                         fprintf( stderr, "%s: -h previously specified\n" );
166                         return EXIT_FAILURE;
167                 }
168             ldaphost = strdup( optarg );
169             break;
170         case 'k':       /* kerberos bind */
171 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
172                 if( version > LDAP_VERSION2 ) {
173                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
174                                 prog, version );
175                         return EXIT_FAILURE;
176                 }
177
178                 if( authmethod != -1 ) {
179                         fprintf( stderr, "%s: -k incompatible with previous "
180                                 "authentication choice\n", prog );
181                         return EXIT_FAILURE;
182                 }
183                         
184                 authmethod = LDAP_AUTH_KRBV4;
185 #else
186                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
187                 return EXIT_FAILURE;
188 #endif
189             break;
190         case 'K':       /* kerberos bind, part one only */
191 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
192                 if( version > LDAP_VERSION2 ) {
193                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
194                                 prog, version );
195                         return EXIT_FAILURE;
196                 }
197                 if( authmethod != -1 ) {
198                         fprintf( stderr, "%s: incompatible with previous "
199                                 "authentication choice\n", prog );
200                         return EXIT_FAILURE;
201                 }
202
203                 authmethod = LDAP_AUTH_KRBV41;
204 #else
205                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
206                 return( EXIT_FAILURE );
207 #endif
208             break;
209         case 'M':
210                 /* enable Manage DSA IT */
211                 if( version == LDAP_VERSION2 ) {
212                         fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
213                                 prog, version );
214                         return EXIT_FAILURE;
215                 }
216                 manageDSAit++;
217                 version = LDAP_VERSION3;
218                 break;
219         case 'n':       /* print deletes, don't actually do them */
220             ++not;
221             break;
222         case 'O':
223 #ifdef HAVE_CYRUS_SASL
224                 if( sasl_secprops != NULL ) {
225                         fprintf( stderr, "%s: -O previously specified\n" );
226                         return EXIT_FAILURE;
227                 }
228                 if( version == LDAP_VERSION2 ) {
229                         fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
230                                 prog, version );
231                         return EXIT_FAILURE;
232                 }
233                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
234                         fprintf( stderr, "%s: incompatible previous "
235                                 "authentication choice\n", prog );
236                         return EXIT_FAILURE;
237                 }
238                 authmethod = LDAP_AUTH_SASL;
239                 version = LDAP_VERSION3;
240                 sasl_secprops = strdup( optarg );
241 #else
242                 fprintf( stderr, "%s: not compiled with SASL support\n",
243                         prog );
244                 return( EXIT_FAILURE );
245 #endif
246                 break;
247         case 'p':
248                 if( ldapport ) {
249                         fprintf( stderr, "%s: -p previously specified\n" );
250                         return EXIT_FAILURE;
251                 }
252             ldapport = atoi( optarg );
253             break;
254         case 'P':
255                 switch( atoi(optarg) ) {
256                 case 2:
257                         if( version == LDAP_VERSION3 ) {
258                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
259                                         prog, version );
260                                 return EXIT_FAILURE;
261                         }
262                         version = LDAP_VERSION2;
263                         break;
264                 case 3:
265                         if( version == LDAP_VERSION2 ) {
266                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
267                                         prog, version );
268                                 return EXIT_FAILURE;
269                         }
270                         version = LDAP_VERSION3;
271                         break;
272                 default:
273                         fprintf( stderr, "%s: protocol version should be 2 or 3\n",
274                                 prog );
275                         usage( prog );
276                         return( EXIT_FAILURE );
277                 } break;
278         case 'Q':
279 #ifdef HAVE_CYRUS_SASL
280                 if( version == LDAP_VERSION2 ) {
281                         fprintf( stderr, "%s: -Q incompatible with version %d\n",
282                                 prog, version );
283                         return EXIT_FAILURE;
284                 }
285                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
286                         fprintf( stderr, "%s: incompatible previous "
287                                 "authentication choice\n",
288                                 prog );
289                         return EXIT_FAILURE;
290                 }
291                 authmethod = LDAP_AUTH_SASL;
292                 version = LDAP_VERSION3;
293                 sasl_flags = LUTIL_SASL_QUIET;
294 #else
295                 fprintf( stderr, "%s: was not compiled with SASL support\n",
296                         prog );
297                 return( EXIT_FAILURE );
298 #endif
299         case 'R':
300 #ifdef HAVE_CYRUS_SASL
301                 if( sasl_realm != NULL ) {
302                         fprintf( stderr, "%s: -R previously specified\n" );
303                         return EXIT_FAILURE;
304                 }
305                 if( version == LDAP_VERSION2 ) {
306                         fprintf( stderr, "%s: -R incompatible with version %d\n",
307                                 prog, version );
308                         return EXIT_FAILURE;
309                 }
310                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
311                         fprintf( stderr, "%s: incompatible previous "
312                                 "authentication choice\n",
313                                 prog );
314                         return EXIT_FAILURE;
315                 }
316                 authmethod = LDAP_AUTH_SASL;
317                 version = LDAP_VERSION3;
318                 sasl_realm = strdup( optarg );
319 #else
320                 fprintf( stderr, "%s: was not compiled with SASL support\n",
321                         prog );
322                 return( EXIT_FAILURE );
323 #endif
324                 break;
325         case 'U':
326 #ifdef HAVE_CYRUS_SASL
327                 if( sasl_authc_id != NULL ) {
328                         fprintf( stderr, "%s: -U previously specified\n" );
329                         return EXIT_FAILURE;
330                 }
331                 if( version == LDAP_VERSION2 ) {
332                         fprintf( stderr, "%s: -U incompatible with version %d\n",
333                                 prog, version );
334                         return EXIT_FAILURE;
335                 }
336                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
337                         fprintf( stderr, "%s: incompatible previous "
338                                 "authentication choice\n",
339                                 prog );
340                         return EXIT_FAILURE;
341                 }
342                 authmethod = LDAP_AUTH_SASL;
343                 version = LDAP_VERSION3;
344                 sasl_authc_id = strdup( optarg );
345 #else
346                 fprintf( stderr, "%s: was not compiled with SASL support\n",
347                         prog );
348                 return( EXIT_FAILURE );
349 #endif
350                 break;
351         case 'v':       /* verbose mode */
352             verbose++;
353             break;
354         case 'w':       /* password */
355             passwd.bv_val = strdup( optarg );
356                 {
357                         char* p;
358
359                         for( p = optarg; *p == '\0'; p++ ) {
360                                 *p = '\0';
361                         }
362                 }
363                 passwd.bv_len = strlen( passwd.bv_val );
364             break;
365         case 'W':
366                 want_bindpw++;
367                 break;
368         case 'Y':
369 #ifdef HAVE_CYRUS_SASL
370                 if( sasl_mech != NULL ) {
371                         fprintf( stderr, "%s: -Y previously specified\n" );
372                         return EXIT_FAILURE;
373                 }
374                 if( version == LDAP_VERSION2 ) {
375                         fprintf( stderr, "%s: -Y incompatible with version %d\n",
376                                 prog, version );
377                         return EXIT_FAILURE;
378                 }
379                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
380                         fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
381                         return EXIT_FAILURE;
382                 }
383                 authmethod = LDAP_AUTH_SASL;
384                 version = LDAP_VERSION3;
385                 sasl_mech = strdup( optarg );
386 #else
387                 fprintf( stderr, "%s: was not compiled with SASL support\n",
388                         prog );
389                 return( EXIT_FAILURE );
390 #endif
391                 break;
392         case 'x':
393                 if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
394                         fprintf( stderr, "%s: incompatible with previous "
395                                 "authentication choice\n", prog );
396                         return EXIT_FAILURE;
397                 }
398                 authmethod = LDAP_AUTH_SIMPLE;
399                 break;
400         case 'X':
401 #ifdef HAVE_CYRUS_SASL
402                 if( sasl_authz_id != NULL ) {
403                         fprintf( stderr, "%s: -X previously specified\n" );
404                         return EXIT_FAILURE;
405                 }
406                 if( version == LDAP_VERSION2 ) {
407                         fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
408                                 prog, version );
409                         return EXIT_FAILURE;
410                 }
411                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
412                         fprintf( stderr, "%s: -X incompatible with "
413                                 "authentication choice\n", prog );
414                         return EXIT_FAILURE;
415                 }
416                 authmethod = LDAP_AUTH_SASL;
417                 version = LDAP_VERSION3;
418                 sasl_authz_id = strdup( optarg );
419 #else
420                 fprintf( stderr, "%s: not compiled with SASL support\n",
421                         prog );
422                 return( EXIT_FAILURE );
423 #endif
424                 break;
425         case 'Z':
426 #ifdef HAVE_TLS
427                 if( version == LDAP_VERSION2 ) {
428                         fprintf( stderr, "%s -Z incompatible with version %d\n",
429                                 prog, version );
430                         return EXIT_FAILURE;
431                 }
432                 version = LDAP_VERSION3;
433                 use_tls++;
434 #else
435                 fprintf( stderr, "%s: not compiled with TLS support\n",
436                         prog );
437                 return( EXIT_FAILURE );
438 #endif
439                 break;
440
441
442                 default:
443                         fprintf( stderr, "%s: unrecongized option -%c\n",
444                                 prog, optopt );
445                         usage (argv[0]);
446                 }
447         }
448
449         if( argc - optind != 1 ) {
450                 usage( argv[0] );
451         } 
452
453         if (authmethod == -1) {
454 #ifdef HAVE_CYRUS_SASL
455                 authmethod = LDAP_AUTH_SASL;
456 #else
457                 authmethod = LDAP_AUTH_SIMPLE;
458 #endif
459         }
460
461         dn = strdup( argv[optind] );
462
463         if( want_oldpw && oldpw == NULL ) {
464                 /* prompt for old password */
465                 char *ckoldpw;
466                 newpw = strdup(getpassphrase("Old password: "));
467                 ckoldpw = getpassphrase("Re-enter old password: ");
468
469                 if( newpw== NULL || ckoldpw == NULL ||
470                         strncmp( oldpw, ckoldpw, strlen(oldpw) ))
471                 {
472                         fprintf( stderr, "passwords do not match\n" );
473                         return EXIT_FAILURE;
474                 }
475         }
476
477         if( want_newpw && newpw == NULL ) {
478                 /* prompt for new password */
479                 char *cknewpw;
480                 newpw = strdup(getpassphrase("New password: "));
481                 cknewpw = getpassphrase("Re-enter new password: ");
482
483                 if( newpw== NULL || cknewpw == NULL ||
484                         strncmp( newpw, cknewpw, strlen(newpw) ))
485                 {
486                         fprintf( stderr, "passwords do not match\n" );
487                         return EXIT_FAILURE;
488                 }
489         }
490
491         if( binddn == NULL && dn != NULL ) {
492                 binddn = dn;
493                 dn = NULL;
494
495                 if( passwd.bv_val == NULL ) {
496                         passwd.bv_val = oldpw;
497                         passwd.bv_len = oldpw == NULL ? 0 : strlen( oldpw );
498                 }
499         }
500
501         if (want_bindpw && passwd.bv_val == NULL ) {
502                 /* handle bind password */
503                 fprintf( stderr, "Bind DN: %s\n", binddn );
504                 passwd.bv_val = strdup( getpassphrase("Enter bind password: "));
505                 passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
506         }
507
508         if ( debug ) {
509                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
510                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
511                 }
512                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
513                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
514                 }
515         }
516
517 #ifdef SIGPIPE
518         (void) SIGNAL( SIGPIPE, SIG_IGN );
519 #endif
520
521         /* connect to server */
522         if ((ld = ldap_init( ldaphost, ldapport )) == NULL) {
523                 perror("ldap_init");
524                 return EXIT_FAILURE;
525         }
526
527         /* referrals */
528         if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
529                 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
530         {
531                 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
532                         referrals ? "on" : "off" );
533                 return EXIT_FAILURE;
534         }
535
536         /* LDAPv3 only */
537         version = 3;
538         rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
539
540         if(rc != LDAP_OPT_SUCCESS ) {
541                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
542                 return EXIT_FAILURE;
543         }
544
545         if ( use_tls && ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
546                 if ( use_tls > 1 ) {
547                         ldap_perror( ld, "ldap_start_tls" );
548                         return( EXIT_FAILURE );
549                 }
550                 fprintf( stderr, "WARNING: could not start TLS\n" );
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, sasl_flags,
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                         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 was 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( dn != NULL || oldpw != NULL || newpw != NULL ) {
599                 /* build change password control */
600                 BerElement *ber = ber_alloc_t( LBER_USE_DER );
601
602                 if( ber == NULL ) {
603                         perror( "ber_alloc_t" );
604                         ldap_unbind( ld );
605                         return EXIT_FAILURE;
606                 }
607
608                 ber_printf( ber, "{" /*}*/ );
609
610                 if( dn != NULL ) {
611                         ber_printf( ber, "ts",
612                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn );
613                         free(dn);
614                 }
615
616                 if( oldpw != NULL ) {
617                         ber_printf( ber, "ts",
618                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, oldpw );
619                         free(oldpw);
620                 }
621
622                 if( newpw != NULL ) {
623                         ber_printf( ber, "ts",
624                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw );
625                         free(newpw);
626                 }
627
628                 ber_printf( ber, /*{*/ "N}" );
629
630                 rc = ber_flatten( ber, &bv );
631
632                 if( rc < 0 ) {
633                         perror( "ber_flatten" );
634                         ldap_unbind( ld );
635                         return EXIT_FAILURE;
636                 }
637
638                 ber_free( ber, 1 );
639         }
640
641         if ( not ) {
642                 rc = LDAP_SUCCESS;
643                 goto skip;
644         }
645
646         rc = ldap_extended_operation( ld,
647                 LDAP_EXOP_X_MODIFY_PASSWD, bv, 
648                 NULL, NULL, &id );
649
650         ber_bvfree( bv );
651
652         if( rc != LDAP_SUCCESS ) {
653                 ldap_perror( ld, "ldap_extended_operation" );
654                 ldap_unbind( ld );
655                 return EXIT_FAILURE;
656         }
657
658         rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
659         if ( rc < 0 ) {
660                 ldap_perror( ld, "ldappasswd: ldap_result" );
661                 return rc;
662         }
663
664         rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 );
665
666         if( rc != LDAP_SUCCESS ) {
667                 ldap_perror( ld, "ldap_parse_result" );
668                 return rc;
669         }
670
671         rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
672
673         if( rc != LDAP_SUCCESS ) {
674                 ldap_perror( ld, "ldap_parse_result" );
675                 return rc;
676         }
677
678         if( retdata != NULL ) {
679                 ber_tag_t tag;
680                 char *s;
681                 BerElement *ber = ber_init( retdata );
682
683                 if( ber == NULL ) {
684                         perror( "ber_init" );
685                         ldap_unbind( ld );
686                         return EXIT_FAILURE;
687                 }
688
689                 /* we should check the tag */
690                 tag = ber_scanf( ber, "{a}", &s);
691
692                 if( tag == LBER_ERROR ) {
693                         perror( "ber_scanf" );
694                 } else {
695                         printf("New password: %s\n", s);
696                         free( s );
697                 }
698
699                 ber_free( ber, 1 );
700         }
701
702         if( verbose || code != LDAP_SUCCESS || matcheddn || text || refs ) {
703                 printf( "Result: %s (%d)\n", ldap_err2string( code ), code );
704
705                 if( text && *text ) {
706                         printf( "Additional info: %s\n", text );
707                 }
708
709                 if( matcheddn && *matcheddn ) {
710                         printf( "Matched DN: %s\n", matcheddn );
711                 }
712
713                 if( refs ) {
714                         int i;
715                         for( i=0; refs[i]; i++ ) {
716                                 printf("Referral: %s\n", refs[i] );
717                         }
718                 }
719         }
720
721         ber_memfree( text );
722         ber_memfree( matcheddn );
723         ber_memvfree( (void **) refs );
724         ber_memfree( retoid );
725         ber_bvfree( retdata );
726
727 skip:
728         /* disconnect from server */
729         ldap_unbind (ld);
730
731         return EXIT_SUCCESS;
732 }