]> git.sur5r.net Git - openldap/blob - clients/tools/ldappasswd.c
04b4d469c99f0d5e9e8d55435c6e6de421601578
[openldap] / clients / tools / ldappasswd.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-1999 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/signal.h>
15 #include <ac/socket.h>
16 #include <ac/string.h>
17 #include <ac/time.h>
18 #include <ac/unistd.h>
19
20 #include <ldap.h>
21
22 #include "ldap_defaults.h"
23
24 static int      verbose = 0;
25
26 static void
27 usage(const char *s)
28 {
29         fprintf(stderr,
30                 "Usage: %s [options] dn\n"
31                 "  -A\t\tprompt for old password\n"
32                 "  -a secret\told password\n"
33                 "  -D binddn\tbind dn\n"
34                 "  -d level\tdebugging level\n"
35                 "  -h host\tldap server (default: localhost)\n"
36                 "  -n\t\tmake no modifications\n"
37                 "  -p port\tldap port\n"
38                 "  -S\t\tprompt for new password\n"
39                 "  -s secret\tnew password\n"
40                 "  -v\t\tincrease verbosity\n"
41                 "  -W\t\tprompt for bind password\n"
42                 "  -w passwd\tbind password (for simple authentication)\n"
43                 , s );
44
45         exit( EXIT_FAILURE );
46 }
47
48 int
49 main( int argc, char *argv[] )
50 {
51         int rc;
52         char    *ldaphost = NULL;
53
54         char    *dn = NULL;
55         char    *binddn = NULL;
56
57         char    *bindpw = NULL;
58         char    *newpw = NULL;
59         char    *oldpw = NULL;
60
61         int             want_bindpw = 0;
62         int             want_newpw = 0;
63         int             want_oldpw = 0;
64
65         int             noupdates = 0;
66         int             i;
67         int             ldapport = 0;
68         int             debug = 0;
69         int             version = -1;
70         LDAP           *ld;
71         struct berval *bv = NULL;
72
73         char    *retoid;
74         struct berval *retdata;
75
76         if (argc == 1)
77                 usage (argv[0]);
78
79         while( (i = getopt( argc, argv,
80                 "Aa:D:d:h:np:Ss:vWw:" )) != EOF )
81         {
82                 switch (i) {
83                 case 'A':       /* prompt for oldr password */
84                         want_oldpw++;
85                         break;
86                 case 'a':       /* old password (secret) */
87                         oldpw = strdup (optarg);
88
89                         {
90                                 char* p;
91
92                                 for( p = optarg; *p == '\0'; p++ ) {
93                                         *p = '*';
94                                 }
95                         }
96                         break;
97                 case 'D':       /* bind distinguished name */
98                         binddn = strdup (optarg);
99                         break;
100
101                 case 'd':       /* debugging option */
102                         debug |= atoi (optarg);
103                         break;
104
105                 case 'h':       /* ldap host */
106                         ldaphost = strdup (optarg);
107                         break;
108
109                 case 'n':       /* don't update entry(s) */
110                         noupdates++;
111                         break;
112
113                 case 'p':       /* ldap port */
114                         ldapport = strtol( optarg, NULL, 10 );
115                         break;
116
117                 case 'S':       /* prompt for user password */
118                         want_newpw++;
119                         break;
120
121                 case 's':       /* new password (secret) */
122                         newpw = strdup (optarg);
123
124                         {
125                                 char* p;
126
127                                 for( p = optarg; *p == '\0'; p++ ) {
128                                         *p = '*';
129                                 }
130                         }
131                         break;
132
133                 case 'v':       /* verbose */
134                         verbose++;
135                         break;
136
137                 case 'W':       /* prompt for bind password */
138                         want_bindpw++;
139                         break;
140
141                 case 'w':       /* bind password */
142                         bindpw = strdup (optarg);
143
144                         {
145                                 char* p;
146
147                                 for( p = optarg; *p == '\0'; p++ ) {
148                                         *p = '*';
149                                 }
150                         }
151                         break;
152
153
154                 default:
155                         usage (argv[0]);
156                 }
157         }
158
159         if( argc - optind != 1 ) {
160                 usage( argv[0] );
161         } 
162
163         dn = strdup( argv[optind] );
164
165         if( want_oldpw && oldpw == NULL ) {
166                 /* prompt for old password */
167                 char *ckoldpw;
168                 newpw = strdup(getpass("Old password: "));
169                 ckoldpw = getpass("Re-enter old password: ");
170
171                 if( strncmp( oldpw, ckoldpw, strlen(oldpw) )) {
172                         fprintf( stderr, "passwords do not match\n" );
173                         return EXIT_FAILURE;
174                 }
175         }
176
177         if( want_newpw && newpw == NULL ) {
178                 /* prompt for new password */
179                 char *cknewpw;
180                 newpw = strdup(getpass("New password: "));
181                 cknewpw = getpass("Re-enter new password: ");
182
183                 if( strncmp( newpw, cknewpw, strlen(newpw) )) {
184                         fprintf( stderr, "passwords do not match\n" );
185                         return EXIT_FAILURE;
186                 }
187         }
188
189         if( binddn == NULL && dn != NULL ) {
190                 binddn = dn;
191                 dn = NULL;
192
193                 if( bindpw == NULL ) bindpw = oldpw;
194         }
195
196         if (want_bindpw && bindpw == NULL ) {
197                 /* handle bind password */
198                 fprintf( stderr, "Bind DN: %s\n", binddn );
199                 bindpw = strdup( getpass("Enter bind password: "));
200         }
201
202         if ( debug ) {
203                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
204                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
205                 }
206                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
207                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
208                 }
209         }
210
211 #ifdef SIGPIPE
212         (void) SIGNAL( SIGPIPE, SIG_IGN );
213 #endif
214
215         /* connect to server */
216         if ((ld = ldap_init( ldaphost, ldapport )) == NULL) {
217                 perror("ldap_init");
218                 return EXIT_FAILURE;
219         }
220
221         /* don't chase referrals */
222         ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
223
224         version = 3;
225         rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
226
227         if(rc != LDAP_OPT_SUCCESS ) {
228                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
229         }
230
231         rc = ldap_bind_s( ld, binddn, bindpw, LDAP_AUTH_SIMPLE );
232
233         if ( rc != LDAP_SUCCESS ) {
234                 ldap_perror( ld, "ldap_bind" );
235                 ldap_unbind( ld );
236                 return EXIT_FAILURE;
237         }
238
239         if( dn != NULL || oldpw != NULL || newpw != NULL ) {
240                 /* build change password control */
241                 BerElement *ber = ber_alloc_t( LBER_USE_DER );
242
243                 if( ber == NULL ) {
244                         perror( "ber_alloc_t" );
245                         ldap_unbind( ld );
246                         return EXIT_FAILURE;
247                 }
248
249                 ber_printf( ber, "{" /*}*/ );
250
251                 if( dn != NULL ) {
252                         ber_printf( ber, "ts",
253                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn );
254                         free(dn);
255                 }
256
257                 if( oldpw != NULL ) {
258                         ber_printf( ber, "ts",
259                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, oldpw );
260                         free(oldpw);
261                 }
262
263                 if( newpw != NULL ) {
264                         ber_printf( ber, "ts",
265                                 LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw );
266                         free(newpw);
267                 }
268
269                 ber_printf( ber, /*{*/ "}" );
270
271                 rc = ber_flatten( ber, &bv );
272
273                 if( rc < 0 ) {
274                         perror( "ber_flatten" );
275                         ldap_unbind( ld );
276                         return EXIT_FAILURE;
277                 }
278
279                 ber_free( ber, 1 );
280         }
281
282         rc = ldap_extended_operation_s( ld,
283                 LDAP_EXOP_X_MODIFY_PASSWD, bv, 
284                 NULL, NULL,
285                 &retoid, &retdata );
286
287         ber_bvfree( bv );
288
289         if( retdata != NULL ) {
290                 ber_tag_t tag;
291                 char *s;
292                 BerElement *ber = ber_init( retdata );
293
294                 if( ber == NULL ) {
295                         perror( "ber_init" );
296                         ldap_unbind( ld );
297                         return EXIT_FAILURE;
298                 }
299
300                 /* we should check the tag */
301                 tag = ber_scanf( ber, "{a}", &s);
302
303                 if( tag == LBER_ERROR ) {
304                         perror( "ber_scanf" );
305                 } else {
306                         printf("New password: %s\n", s);
307                         free( s );
308                 }
309
310                 ber_free( ber, 1 );
311         }
312
313         if ( rc != LDAP_SUCCESS ) {
314                 ldap_perror( ld, "ldap_extended_operation" );
315                 ldap_unbind( ld );
316                 return EXIT_FAILURE;
317         }
318
319         ldap_memfree( retoid );
320         ber_bvfree( retdata );
321
322         /* disconnect from server */
323         ldap_unbind (ld);
324
325         return ( EXIT_SUCCESS );
326 }