]> git.sur5r.net Git - openldap/blob - clients/tools/ldappasswd.c
Add ManageDSAit support to back-dnssrv
[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 "ldap_defaults.h"
23
24 static int      verbose = 0;
25
26 static void
27 usage(const char *s)
28 {
29         fprintf(stderr,
30 "Change the password of an LDAP entry\n\n"
31 "usage: %s [options] dn\n"
32 "       dn: the DN of the entry whose password must be changed\n"
33 "options:\n"
34 "       -a secret\told password\n"
35 "       -A\t\tprompt for old password\n"
36 "       -d level\tdebugging level\n"
37 "       -D binddn\tbind DN\n"
38 "       -E\t\trequest SASL privacy (-EE to make it critical)\n"
39 "       -h host\t\tLDAP server (default: localhost)\n"
40 "       -I\t\trequest SASL integrity checking (-II to make it\n"
41 "               \tcritical)\n"
42 "       -n\t\tmake no modifications\n"
43 "       -p port\t\tport on LDAP server\n"
44 "       -S\t\tprompt for new password\n"
45 "       -s secret\tnew password\n"
46 "       -U user\t\tSASL authentication identity (username)\n"
47 "       -v\t\tverbose mode\n"
48 "       -w passwd\tbind password (for simple authentication)\n"
49 "       -W\t\tprompt for bind password\n"
50 "       -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
51 "       -Y mech\t\tSASL mechanism\n"
52 "       -Z\t\trequest the use of TLS (-ZZ to make it critical)\n"
53                 , s );
54
55         exit( EXIT_FAILURE );
56 }
57
58 int
59 main( int argc, char *argv[] )
60 {
61         int rc;
62         char    *ldaphost = NULL;
63
64         char    *dn = NULL;
65         char    *binddn = NULL;
66
67         struct berval passwd = { 0, NULL};
68         char    *newpw = NULL;
69         char    *oldpw = NULL;
70
71         int             want_bindpw = 0;
72         int             want_newpw = 0;
73         int             want_oldpw = 0;
74
75         int             noupdates = 0;
76         int             i;
77         int             ldapport = 0;
78         int             debug = 0;
79         int             version = -1;
80         int             authmethod = LDAP_AUTH_SIMPLE;
81 #ifdef HAVE_CYRUS_SASL
82         char            *sasl_authc_id = NULL;
83         char            *sasl_authz_id = NULL;
84         char            *sasl_mech = NULL;
85         int             sasl_integrity = 0;
86         int             sasl_privacy = 0;
87 #endif
88         int             use_tls = 0;
89         LDAP           *ld;
90         struct berval *bv = NULL;
91
92         char    *retoid;
93         struct berval *retdata;
94
95         if (argc == 1)
96                 usage (argv[0]);
97
98         while( (i = getopt( argc, argv,
99                 "Aa:D:d:EIh:np:Ss:U:vWw:X:Y:Z" )) != EOF )
100         {
101                 switch (i) {
102                 case 'A':       /* prompt for oldr password */
103                         want_oldpw++;
104                         break;
105                 case 'a':       /* old password (secret) */
106                         oldpw = strdup (optarg);
107
108                         {
109                                 char* p;
110
111                                 for( p = optarg; *p == '\0'; p++ ) {
112                                         *p = '*';
113                                 }
114                         }
115                         break;
116                 case 'D':       /* bind distinguished name */
117                         binddn = strdup (optarg);
118                         break;
119
120                 case 'd':       /* debugging option */
121                         debug |= atoi (optarg);
122                         break;
123
124                 case 'h':       /* ldap host */
125                         ldaphost = strdup (optarg);
126                         break;
127
128                 case 'n':       /* don't update entry(s) */
129                         noupdates++;
130                         break;
131
132                 case 'p':       /* ldap port */
133                         ldapport = strtol( optarg, NULL, 10 );
134                         break;
135
136                 case 'S':       /* prompt for user password */
137                         want_newpw++;
138                         break;
139
140                 case 's':       /* new password (secret) */
141                         newpw = strdup (optarg);
142
143                         {
144                                 char* p;
145
146                                 for( p = optarg; *p == '\0'; p++ ) {
147                                         *p = '*';
148                                 }
149                         }
150                         break;
151
152                 case 'v':       /* verbose */
153                         verbose++;
154                         break;
155
156                 case 'W':       /* prompt for bind password */
157                         want_bindpw++;
158                         break;
159
160                 case 'w':       /* bind password */
161                         passwd.bv_val = strdup (optarg);
162                         {
163                                 char* p;
164
165                                 for( p = optarg; *p == '\0'; p++ ) {
166                                         *p = '*';
167                                 }
168                         }
169                         passwd.bv_len = strlen( passwd.bv_val );
170                         break;
171
172                 case 'I':
173 #ifdef HAVE_CYRUS_SASL
174                         sasl_integrity++;
175                         authmethod = LDAP_AUTH_SASL;
176 #else
177                         fprintf( stderr, "%s was not compiled with SASL "
178                                 "support\n", argv[0] );
179                         return( EXIT_FAILURE );
180 #endif
181                         break;
182                 case 'E':
183 #ifdef HAVE_CYRUS_SASL
184                         sasl_privacy++;
185                         authmethod = LDAP_AUTH_SASL;
186 #else
187                         fprintf( stderr, "%s was not compiled with SASL "
188                                 "support\n", argv[0] );
189                         return( EXIT_FAILURE );
190 #endif
191                         break;
192                 case 'Y':
193 #ifdef HAVE_CYRUS_SASL
194                         if ( strcasecmp( optarg, "any" ) &&
195                                         strcmp( optarg, "*" ) ) {
196                                 sasl_mech = strdup( optarg );
197                         }
198                         authmethod = LDAP_AUTH_SASL;
199 #else
200                         fprintf( stderr, "%s was not compiled with SASL "
201                                 "support\n", argv[0] );
202                         return( EXIT_FAILURE );
203 #endif
204                         break;
205                 case 'U':
206 #ifdef HAVE_CYRUS_SASL
207                         sasl_authc_id = strdup( optarg );
208                         authmethod = LDAP_AUTH_SASL;
209 #else
210                         fprintf( stderr, "%s was not compiled with SASL "
211                                 "support\n", argv[0] );
212                         return( EXIT_FAILURE );
213 #endif
214                         break;
215                 case 'X':
216 #ifdef HAVE_CYRUS_SASL
217                         sasl_authz_id = strdup( optarg );
218                         authmethod = LDAP_AUTH_SASL;
219 #else
220                         fprintf( stderr, "%s was not compiled with SASL "
221                                 "support\n", argv[0] );
222                         return( EXIT_FAILURE );
223 #endif
224                         break;
225                 case 'Z':
226 #ifdef HAVE_TLS
227                         use_tls++;
228 #else
229                         fprintf( stderr, "%s was not compiled with TLS "
230                                 "support\n", argv[0] );
231                         return( EXIT_FAILURE );
232 #endif
233                         break;
234
235                 default:
236                         usage (argv[0]);
237                 }
238         }
239
240         if( argc - optind != 1 ) {
241                 usage( argv[0] );
242         } 
243
244         dn = strdup( argv[optind] );
245
246         if( want_oldpw && oldpw == NULL ) {
247                 /* prompt for old password */
248                 char *ckoldpw;
249                 newpw = strdup(getpassphrase("Old password: "));
250                 ckoldpw = getpassphrase("Re-enter old password: ");
251
252                 if( strncmp( oldpw, ckoldpw, strlen(oldpw) )) {
253                         fprintf( stderr, "passwords do not match\n" );
254                         return EXIT_FAILURE;
255                 }
256         }
257
258         if( want_newpw && newpw == NULL ) {
259                 /* prompt for new password */
260                 char *cknewpw;
261                 newpw = strdup(getpassphrase("New password: "));
262                 cknewpw = getpassphrase("Re-enter new password: ");
263
264                 if( strncmp( newpw, cknewpw, strlen(newpw) )) {
265                         fprintf( stderr, "passwords do not match\n" );
266                         return EXIT_FAILURE;
267                 }
268         }
269
270         if( binddn == NULL && dn != NULL ) {
271                 binddn = dn;
272                 dn = NULL;
273
274                 if( passwd.bv_val == NULL ) {
275                         passwd.bv_val = oldpw;
276                         passwd.bv_len = oldpw == NULL ? 0 : strlen( oldpw );
277                 }
278         }
279
280         if (want_bindpw && passwd.bv_val == NULL ) {
281                 /* handle bind password */
282                 fprintf( stderr, "Bind DN: %s\n", binddn );
283                 passwd.bv_val = strdup( getpassphrase("Enter bind password: "));
284                 passwd.bv_len = strlen( passwd.bv_val );
285         }
286
287         if ( debug ) {
288                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
289                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
290                 }
291                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
292                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
293                 }
294         }
295
296 #ifdef SIGPIPE
297         (void) SIGNAL( SIGPIPE, SIG_IGN );
298 #endif
299
300         /* connect to server */
301         if ((ld = ldap_init( ldaphost, ldapport )) == NULL) {
302                 perror("ldap_init");
303                 return EXIT_FAILURE;
304         }
305
306         /* don't chase referrals */
307         ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
308
309         /* LDAPv3 only */
310         version = 3;
311         rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
312
313         if(rc != LDAP_OPT_SUCCESS ) {
314                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
315         }
316
317         if ( use_tls && ldap_start_tls( ld, NULL, NULL ) != LDAP_SUCCESS ) {
318                 if ( use_tls > 1 ) {
319                         ldap_perror( ld, "ldap_start_tls" );
320                         return( EXIT_FAILURE );
321                 }
322         }
323
324         if ( authmethod == LDAP_AUTH_SASL ) {
325 #ifdef HAVE_CYRUS_SASL
326                 int     minssf = 0, maxssf = 0;
327
328                 if ( sasl_integrity > 0 )
329                         maxssf = 1;
330                 if ( sasl_integrity > 1 )
331                         minssf = 1;
332                 if ( sasl_privacy > 0 )
333                         maxssf = 100000; /* Something big value */
334                 if ( sasl_privacy > 1 )
335                         minssf = 56;
336                 
337                 if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
338                                 (void *)&minssf ) != LDAP_OPT_SUCCESS ) {
339                         fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
340                                 "%d\n", minssf);
341                         return( EXIT_FAILURE );
342                 }
343                 if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
344                                 (void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
345                         fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
346                                 "%d\n", maxssf);
347                         return( EXIT_FAILURE );
348                 }
349                 
350                 rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
351                                 sasl_authz_id, sasl_mech,
352                                 passwd.bv_len ? &passwd : NULL,
353                                 NULL, NULL );
354
355                 if( rc != LDAP_SUCCESS ) {
356                         ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
357                         return( EXIT_FAILURE );
358                 }
359 #else
360                 fprintf( stderr, "%s was not compiled with SASL support\n",
361                         argv[0] );
362                 return( EXIT_FAILURE );
363 #endif
364         }
365         else {
366                 if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
367                                 != LDAP_SUCCESS ) {
368                         ldap_perror( ld, "ldap_bind" );
369                         return( EXIT_FAILURE );
370                 }
371         }
372
373         if( dn != NULL || oldpw != NULL || newpw != NULL ) {
374                 /* build change password control */
375                 BerElement *ber = ber_alloc_t( LBER_USE_DER );
376
377                 if( ber == NULL ) {
378                         perror( "ber_alloc_t" );
379                         ldap_unbind( ld );
380                         return EXIT_FAILURE;
381                 }
382
383                 ber_printf( ber, "{" /*}*/ );
384
385                 if( dn != NULL ) {
386                         ber_printf( ber, "ts",
387                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn );
388                         free(dn);
389                 }
390
391                 if( oldpw != NULL ) {
392                         ber_printf( ber, "ts",
393                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, oldpw );
394                         free(oldpw);
395                 }
396
397                 if( newpw != NULL ) {
398                         ber_printf( ber, "ts",
399                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw );
400                         free(newpw);
401                 }
402
403                 ber_printf( ber, /*{*/ "}" );
404
405                 rc = ber_flatten( ber, &bv );
406
407                 if( rc < 0 ) {
408                         perror( "ber_flatten" );
409                         ldap_unbind( ld );
410                         return EXIT_FAILURE;
411                 }
412
413                 ber_free( ber, 1 );
414         }
415
416         rc = ldap_extended_operation_s( ld,
417                 LDAP_EXOP_X_MODIFY_PASSWD, bv, 
418                 NULL, NULL,
419                 &retoid, &retdata );
420
421         ber_bvfree( bv );
422
423         if( retdata != NULL ) {
424                 ber_tag_t tag;
425                 char *s;
426                 BerElement *ber = ber_init( retdata );
427
428                 if( ber == NULL ) {
429                         perror( "ber_init" );
430                         ldap_unbind( ld );
431                         return EXIT_FAILURE;
432                 }
433
434                 /* we should check the tag */
435                 tag = ber_scanf( ber, "{a}", &s);
436
437                 if( tag == LBER_ERROR ) {
438                         perror( "ber_scanf" );
439                 } else {
440                         printf("New password: %s\n", s);
441                         free( s );
442                 }
443
444                 ber_free( ber, 1 );
445         }
446
447         if ( rc != LDAP_SUCCESS ) {
448                 ldap_perror( ld, "ldap_extended_operation" );
449                 ldap_unbind( ld );
450                 return EXIT_FAILURE;
451         }
452
453         ldap_memfree( retoid );
454         ber_bvfree( retdata );
455
456         /* disconnect from server */
457         ldap_unbind (ld);
458
459         return EXIT_SUCCESS;
460 }