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