3 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
11 #include <ac/stdlib.h>
14 #include <ac/socket.h>
15 #include <ac/string.h>
17 #include <ac/unistd.h>
21 #include "lutil_ldap.h"
22 #include "ldap_defaults.h"
27 static char *newpw = NULL;
28 static char *oldpw = NULL;
29 static int want_newpw = 0;
30 static int want_oldpw = 0;
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"
51 const char options[] = "a:As:S"
52 "Cd:D:e:h:H:InO:p:QR:U:vVw:WxX:Y:Z";
55 handle_private_option( int i )
60 char *control, *cvalue;
61 case 'E': /* passwd controls */
62 if( protocol == LDAP_VERSION2 ) {
63 fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
68 /* should be extended to support comma separated list of
69 * [!]key[=value] parameters, e.g. -E !foo,bar=567
74 if( optarg[0] == '!' ) {
79 control = strdup( optarg );
80 if ( (cvalue = strchr( control, '=' )) != NULL ) {
83 fprintf( stderr, "Invalid passwd control name: %s\n", control );
87 case 'a': /* old password (secret) */
88 oldpw = strdup (optarg);
92 for( p = optarg; *p != '\0'; p++ ) {
98 case 'A': /* prompt for old password */
102 case 's': /* new password (secret) */
103 newpw = strdup (optarg);
106 for( p = optarg; *p != '\0'; p++ ) {
112 case 'S': /* prompt for user password */
124 main( int argc, char *argv[] )
130 struct berval bv = {0, NULL};
131 BerElement *ber = NULL;
133 int id, code = LDAP_OTHER;
135 char *matcheddn = NULL, *text = NULL, **refs = NULL;
137 struct berval *retdata = NULL;
139 prog = lutil_progname( "ldappasswd", argc, argv );
142 protocol = LDAP_VERSION3;
144 tool_args( argc, argv );
146 if( argc - optind > 1 ) {
148 } else if ( argc - optind == 1 ) {
149 user = strdup( argv[optind] );
154 if( want_oldpw && oldpw == NULL ) {
155 /* prompt for old password */
157 oldpw = strdup(getpassphrase("Old password: "));
158 ckoldpw = getpassphrase("Re-enter old password: ");
160 if( oldpw== NULL || ckoldpw == NULL ||
161 strcmp( oldpw, ckoldpw ))
163 fprintf( stderr, "passwords do not match\n" );
168 if( want_newpw && newpw == NULL ) {
169 /* prompt for new password */
171 newpw = strdup(getpassphrase("New password: "));
172 cknewpw = getpassphrase("Re-enter new password: ");
174 if( newpw== NULL || cknewpw == NULL ||
175 strcmp( newpw, cknewpw ))
177 fprintf( stderr, "passwords do not match\n" );
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;
188 ld = tool_conn_setup( 0, 0 );
192 if ( authzid || manageDSAit || noop )
193 tool_server_controls( ld, NULL, 0 );
195 if( user != NULL || oldpw != NULL || newpw != NULL ) {
196 /* build change password control */
197 ber = ber_alloc_t( LBER_USE_DER );
200 perror( "ber_alloc_t" );
205 ber_printf( ber, "{" /*}*/ );
208 ber_printf( ber, "ts",
209 LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user );
213 if( oldpw != NULL ) {
214 ber_printf( ber, "ts",
215 LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, oldpw );
219 if( newpw != NULL ) {
220 ber_printf( ber, "ts",
221 LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, newpw );
225 ber_printf( ber, /*{*/ "N}" );
227 rc = ber_flatten2( ber, &bv, 0 );
230 perror( "ber_flatten2" );
241 rc = ldap_extended_operation( ld,
242 LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL,
247 if( rc != LDAP_SUCCESS ) {
248 ldap_perror( ld, "ldap_extended_operation" );
253 rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
255 ldap_perror( ld, "ldappasswd: ldap_result" );
259 rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 );
261 if( rc != LDAP_SUCCESS ) {
262 ldap_perror( ld, "ldap_parse_result" );
266 rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
268 if( rc != LDAP_SUCCESS ) {
269 ldap_perror( ld, "ldap_parse_result" );
273 if( retdata != NULL ) {
276 ber = ber_init( retdata );
279 perror( "ber_init" );
284 /* we should check the tag */
285 tag = ber_scanf( ber, "{a}", &s);
287 if( tag == LBER_ERROR ) {
288 perror( "ber_scanf" );
290 printf("New password: %s\n", s);
297 if( verbose || code != LDAP_SUCCESS || matcheddn || text || refs ) {
298 printf( "Result: %s (%d)\n", ldap_err2string( code ), code );
300 if( text && *text ) {
301 printf( "Additional info: %s\n", text );
304 if( matcheddn && *matcheddn ) {
305 printf( "Matched DN: %s\n", matcheddn );
310 for( i=0; refs[i]; i++ ) {
311 printf("Referral: %s\n", refs[i] );
317 ber_memfree( matcheddn );
318 ber_memvfree( (void **) refs );
319 ber_memfree( retoid );
320 ber_bvfree( retdata );
323 /* disconnect from server */
326 return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;