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 struct berval newpw = { 0, NULL };
28 static struct berval oldpw = { 0, NULL };
30 static int want_newpw = 0;
31 static int want_oldpw = 0;
33 static char *oldpwfile = NULL;
34 static char *newpwfile = NULL;
40 "Change password of an LDAP user\n\n"
41 "usage: %s [options] [user]\n"
42 " user: the autentication identity, commonly a DN\n"
43 "Password change options:\n"
44 " -a secret old password\n"
45 " -A prompt for old password\n"
46 " -t file read file for old password\n"
47 " -s secret new password\n"
48 " -S prompt for new password\n"
49 " -T file read file for new password\n"
56 const char options[] = "a:As:St:T:"
57 "Cd:D:e:h:H:InO:p:QR:U:vVw:WxX:y:Y:Z";
60 handle_private_option( int i )
64 case 'E': /* passwd controls */ {
66 char *control, *cvalue;
67 if( protocol == LDAP_VERSION2 ) {
68 fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
73 /* should be extended to support comma separated list of
74 * [!]key[=value] parameters, e.g. -E !foo,bar=567
79 if( optarg[0] == '!' ) {
84 control = strdup( optarg );
85 if ( (cvalue = strchr( control, '=' )) != NULL ) {
89 fprintf( stderr, "Invalid passwd control name: %s\n", control );
94 case 'a': /* old password (secret) */
95 oldpw.bv_val = strdup( optarg );
98 for( p = optarg; *p != '\0'; p++ ) {
102 oldpw.bv_len = strlen( oldpw.bv_val );
105 case 'A': /* prompt for old password */
109 case 's': /* new password (secret) */
110 newpw.bv_val = strdup (optarg);
113 for( p = optarg; *p != '\0'; p++ ) {
117 newpw.bv_len = strlen( newpw.bv_val );
120 case 'S': /* prompt for user password */
140 main( int argc, char *argv[] )
146 struct berval bv = {0, NULL};
147 BerElement *ber = NULL;
149 int id, code = LDAP_OTHER;
151 char *matcheddn = NULL, *text = NULL, **refs = NULL;
153 struct berval *retdata = NULL;
155 prog = lutil_progname( "ldappasswd", argc, argv );
158 protocol = LDAP_VERSION3;
160 tool_args( argc, argv );
162 if( argc - optind > 1 ) {
164 } else if ( argc - optind == 1 ) {
165 user = strdup( argv[optind] );
171 rc = lutil_get_filed_password( prog, &oldpw );
172 if( rc ) return EXIT_FAILURE;
175 if( want_oldpw && oldpw.bv_val == NULL ) {
176 /* prompt for old password */
178 oldpw.bv_val = strdup(getpassphrase("Old password: "));
179 ckoldpw = getpassphrase("Re-enter old password: ");
181 if( oldpw.bv_val == NULL || ckoldpw == NULL ||
182 strcmp( oldpw.bv_val, ckoldpw ))
184 fprintf( stderr, "passwords do not match\n" );
188 oldpw.bv_len = strlen( oldpw.bv_val );
192 rc = lutil_get_filed_password( prog, &newpw );
193 if( rc ) return EXIT_FAILURE;
196 if( want_newpw && newpw.bv_val == NULL ) {
197 /* prompt for new password */
199 newpw.bv_val = strdup(getpassphrase("New password: "));
200 cknewpw = getpassphrase("Re-enter new password: ");
202 if( newpw.bv_val == NULL || cknewpw == NULL ||
203 strcmp( newpw.bv_val, cknewpw ))
205 fprintf( stderr, "passwords do not match\n" );
209 newpw.bv_len = strlen( newpw.bv_val );
212 if( want_bindpw && passwd.bv_val == NULL ) {
213 /* handle bind password */
214 passwd.bv_val = strdup( getpassphrase("Enter bind password: "));
215 passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
218 ld = tool_conn_setup( 0, 0 );
222 if ( authzid || manageDSAit || noop )
223 tool_server_controls( ld, NULL, 0 );
225 if( user != NULL || oldpw.bv_val != NULL || newpw.bv_val != NULL ) {
226 /* build change password control */
227 ber = ber_alloc_t( LBER_USE_DER );
230 perror( "ber_alloc_t" );
235 ber_printf( ber, "{" /*}*/ );
238 ber_printf( ber, "ts",
239 LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user );
243 if( oldpw.bv_val != NULL ) {
244 ber_printf( ber, "tO",
245 LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &oldpw );
249 if( newpw.bv_val != NULL ) {
250 ber_printf( ber, "tO",
251 LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &newpw );
255 ber_printf( ber, /*{*/ "N}" );
257 rc = ber_flatten2( ber, &bv, 0 );
260 perror( "ber_flatten2" );
271 rc = ldap_extended_operation( ld,
272 LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL,
277 if( rc != LDAP_SUCCESS ) {
278 ldap_perror( ld, "ldap_extended_operation" );
283 rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
285 ldap_perror( ld, "ldappasswd: ldap_result" );
289 rc = ldap_parse_result( ld, res,
290 &code, &matcheddn, &text, &refs, NULL, 0 );
292 if( rc != LDAP_SUCCESS ) {
293 ldap_perror( ld, "ldap_parse_result" );
297 rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
299 if( rc != LDAP_SUCCESS ) {
300 ldap_perror( ld, "ldap_parse_result" );
304 if( retdata != NULL ) {
307 ber = ber_init( retdata );
310 perror( "ber_init" );
315 /* we should check the tag */
316 tag = ber_scanf( ber, "{a}", &s);
318 if( tag == LBER_ERROR ) {
319 perror( "ber_scanf" );
321 printf("New password: %s\n", s);
328 if( verbose || code != LDAP_SUCCESS || matcheddn || text || refs ) {
329 printf( "Result: %s (%d)\n", ldap_err2string( code ), code );
331 if( text && *text ) {
332 printf( "Additional info: %s\n", text );
335 if( matcheddn && *matcheddn ) {
336 printf( "Matched DN: %s\n", matcheddn );
341 for( i=0; refs[i]; i++ ) {
342 printf("Referral: %s\n", refs[i] );
348 ber_memfree( matcheddn );
349 ber_memvfree( (void **) refs );
350 ber_memfree( retoid );
351 ber_bvfree( retdata );
354 /* disconnect from server */
357 return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;