]> git.sur5r.net Git - openldap/blob - clients/tools/ldappasswd.c
63bae54d04ef39f171d53d23b6d23708b80cdf28
[openldap] / clients / tools / ldappasswd.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 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/socket.h>
15 #include <ac/string.h>
16 #include <ac/time.h>
17 #include <ac/unistd.h>
18
19 #include <ldap.h>
20 #include "lutil.h"
21 #include "lutil_ldap.h"
22 #include "ldap_defaults.h"
23
24 #include "common.h"
25
26
27 static char     *newpw = NULL;
28 static char     *oldpw = NULL;
29 static int   want_newpw = 0;
30 static int   want_oldpw = 0;
31
32
33 void
34 usage( void )
35 {
36         fprintf(stderr,
37 "Change password of an LDAP user\n\n"
38 "usage: %s [options] [user]\n"
39 "  user: the autentication identity, commonly a DN\n"
40 "Password change options:\n"
41 "  -a secret  old password\n"
42 "  -A         prompt for old password\n"
43 "  -s secret  new password\n"
44 "  -S         prompt for new password\n"
45                 , prog );
46         tool_common_usage();
47         exit( EXIT_FAILURE );
48 }
49
50
51 const char options[] = "a:As:S" "Cd:D:e:h:H:InO:p:QR:U:vw:WxX:Y:Z";
52
53 int
54 handle_private_option( int i )
55 {
56         switch ( i ) {
57 #if 0
58                 int             crit;
59                 char    *control, *cvalue;
60         case 'E': /* passwd controls */
61                 if( version == LDAP_VERSION2 ) {
62                         fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
63                                  prog, version );
64                         exit( EXIT_FAILURE );
65                 }
66
67                 /* should be extended to support comma separated list of
68                  *      [!]key[=value] parameters, e.g.  -E !foo,bar=567
69                  */
70
71                 crit = 0;
72                 cvalue = NULL;
73                 if( optarg[0] == '!' ) {
74                         crit = 1;
75                         optarg++;
76                 }
77
78                 control = strdup( optarg );
79                 if ( (cvalue = strchr( control, '=' )) != NULL ) {
80                         *cvalue++ = '\0';
81                 }
82                 fprintf( stderr, "Invalid passwd control name: %s\n", control );
83                 usage();
84 #endif
85
86         case 'a':       /* old password (secret) */
87                 oldpw = strdup (optarg);
88
89                 {
90                         char* p;
91                         for( p = optarg; *p != '\0'; p++ ) {
92                                 *p = '\0';
93                         }
94                 }
95                 break;
96
97         case 'A':       /* prompt for old password */
98                 want_oldpw++;
99                 break;
100
101         case 's':       /* new password (secret) */
102                 newpw = strdup (optarg);
103                 {
104                         char* p;
105                         for( p = optarg; *p != '\0'; p++ ) {
106                                 *p = '\0';
107                         }
108                 }
109                 break;
110
111         case 'S':       /* prompt for user password */
112                 want_newpw++;
113                 break;
114
115         default:
116                 return 0;
117         }
118         return 1;
119 }
120
121
122 int
123 main( int argc, char *argv[] )
124 {
125         int rc;
126         char    *user = NULL;
127
128         LDAP           *ld = NULL;
129         struct berval bv = {0};
130         BerElement  *ber = NULL;
131
132         int id, code = LDAP_OTHER;
133         LDAPMessage *res;
134         char *matcheddn = NULL, *text = NULL, **refs = NULL;
135         char    *retoid = NULL;
136         struct berval *retdata = NULL;
137
138         prog = lutil_progname( "ldappasswd", argc, argv );
139
140         /* LDAPv3 only */
141         version = LDAP_VERSION3;
142
143         tool_args( argc, argv );
144
145         if( argc - optind > 1 ) {
146                 usage();
147         } else if ( argc - optind == 1 ) {
148                 user = strdup( argv[optind] );
149         } else {
150                 user = NULL;
151         }
152
153         if( want_oldpw && oldpw == NULL ) {
154                 /* prompt for old password */
155                 char *ckoldpw;
156                 oldpw = strdup(getpassphrase("Old password: "));
157                 ckoldpw = getpassphrase("Re-enter old password: ");
158
159                 if( oldpw== NULL || ckoldpw == NULL ||
160                         strcmp( oldpw, ckoldpw ))
161                 {
162                         fprintf( stderr, "passwords do not match\n" );
163                         return EXIT_FAILURE;
164                 }
165         }
166
167         if( want_newpw && newpw == NULL ) {
168                 /* prompt for new password */
169                 char *cknewpw;
170                 newpw = strdup(getpassphrase("New password: "));
171                 cknewpw = getpassphrase("Re-enter new password: ");
172
173                 if( newpw== NULL || cknewpw == NULL ||
174                         strcmp( newpw, cknewpw ))
175                 {
176                         fprintf( stderr, "passwords do not match\n" );
177                         return EXIT_FAILURE;
178                 }
179         }
180
181         if (want_bindpw && passwd.bv_val == NULL ) {
182                 /* handle bind password */
183                 passwd.bv_val = strdup( getpassphrase("Enter bind password: "));
184                 passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
185         }
186
187         ld = tool_conn_setup( 0, 0 );
188
189         tool_bind( ld );
190
191         if ( authzid || manageDSAit || noop )
192                 tool_server_controls( ld, NULL, 0 );
193
194         if( user != NULL || oldpw != NULL || newpw != NULL ) {
195                 /* build change password control */
196                 ber = ber_alloc_t( LBER_USE_DER );
197
198                 if( ber == NULL ) {
199                         perror( "ber_alloc_t" );
200                         ldap_unbind( ld );
201                         return EXIT_FAILURE;
202                 }
203
204                 ber_printf( ber, "{" /*}*/ );
205
206                 if( user != NULL ) {
207                         ber_printf( ber, "ts",
208                                 LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user );
209                         free(user);
210                 }
211
212                 if( oldpw != NULL ) {
213                         ber_printf( ber, "ts",
214                                 LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, oldpw );
215                         free(oldpw);
216                 }
217
218                 if( newpw != NULL ) {
219                         ber_printf( ber, "ts",
220                                 LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, newpw );
221                         free(newpw);
222                 }
223
224                 ber_printf( ber, /*{*/ "N}" );
225
226                 rc = ber_flatten2( ber, &bv, 0 );
227
228                 if( rc < 0 ) {
229                         perror( "ber_flatten2" );
230                         ldap_unbind( ld );
231                         return EXIT_FAILURE;
232                 }
233         }
234
235         if ( not ) {
236                 rc = LDAP_SUCCESS;
237                 goto skip;
238         }
239
240         rc = ldap_extended_operation( ld,
241                 LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL, 
242                 NULL, NULL, &id );
243
244         ber_free( ber, 1 );
245
246         if( rc != LDAP_SUCCESS ) {
247                 ldap_perror( ld, "ldap_extended_operation" );
248                 ldap_unbind( ld );
249                 return EXIT_FAILURE;
250         }
251
252         rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
253         if ( rc < 0 ) {
254                 ldap_perror( ld, "ldappasswd: ldap_result" );
255                 return rc;
256         }
257
258         rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 );
259
260         if( rc != LDAP_SUCCESS ) {
261                 ldap_perror( ld, "ldap_parse_result" );
262                 return rc;
263         }
264
265         rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
266
267         if( rc != LDAP_SUCCESS ) {
268                 ldap_perror( ld, "ldap_parse_result" );
269                 return rc;
270         }
271
272         if( retdata != NULL ) {
273                 ber_tag_t tag;
274                 char *s;
275                 ber = ber_init( retdata );
276
277                 if( ber == NULL ) {
278                         perror( "ber_init" );
279                         ldap_unbind( ld );
280                         return EXIT_FAILURE;
281                 }
282
283                 /* we should check the tag */
284                 tag = ber_scanf( ber, "{a}", &s);
285
286                 if( tag == LBER_ERROR ) {
287                         perror( "ber_scanf" );
288                 } else {
289                         printf("New password: %s\n", s);
290                         free( s );
291                 }
292
293                 ber_free( ber, 1 );
294         }
295
296         if( verbose || code != LDAP_SUCCESS || matcheddn || text || refs ) {
297                 printf( "Result: %s (%d)\n", ldap_err2string( code ), code );
298
299                 if( text && *text ) {
300                         printf( "Additional info: %s\n", text );
301                 }
302
303                 if( matcheddn && *matcheddn ) {
304                         printf( "Matched DN: %s\n", matcheddn );
305                 }
306
307                 if( refs ) {
308                         int i;
309                         for( i=0; refs[i]; i++ ) {
310                                 printf("Referral: %s\n", refs[i] );
311                         }
312                 }
313         }
314
315         ber_memfree( text );
316         ber_memfree( matcheddn );
317         ber_memvfree( (void **) refs );
318         ber_memfree( retoid );
319         ber_bvfree( retdata );
320
321 skip:
322         /* disconnect from server */
323         ldap_unbind (ld);
324
325         return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
326 }