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