]> git.sur5r.net Git - openldap/blob - servers/slapd/slappasswd.c
0d18eadf785e6308c3aa0d94b4a2db700f380e62
[openldap] / servers / slapd / slappasswd.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2006 The OpenLDAP Foundation.
5  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by Kurt Zeilenga for inclusion
18  * in OpenLDAP Software.
19  */
20
21 #include "portable.h"
22
23 #include <stdio.h>
24
25 #include <ac/stdlib.h>
26
27 #include <ac/ctype.h>
28 #include <ac/signal.h>
29 #include <ac/socket.h>
30 #include <ac/string.h>
31 #include <ac/time.h>
32 #include <ac/unistd.h>
33
34 #include <ldap.h>
35 #include <lber_pvt.h>
36 #include <lutil.h>
37 #include <lutil_sha1.h>
38
39 #include "ldap_defaults.h"
40
41 static int      verbose = 0;
42
43 static void
44 usage(const char *s)
45 {
46         fprintf(stderr,
47                 "Usage: %s [options]\n"
48                 "  -c format\tcrypt(3) salt format\n"
49                 "  -g\n"
50                 "  -h hash\tpassword scheme\n"
51                 "  -s secret\tnew password\n"
52                 "  -u\t\tgenerate RFC2307 values (default)\n"
53                 "  -v\t\tincrease verbosity\n"
54                 "  -T file\tread file for new password\n"
55                 , s );
56
57         exit( EXIT_FAILURE );
58 }
59
60 int
61 slappasswd( int argc, char *argv[] )
62 {
63         char    *cleartext_scheme = "{CLEARTEXT}";
64 #ifdef LUTIL_SHA1_BYTES
65         char    *default_scheme = "{SSHA}";
66 #else
67         char    *default_scheme = "{SMD5}";
68 #endif
69         char    *scheme = default_scheme;
70
71         char    *newpw = NULL;
72         char    *pwfile = NULL;
73         const char *text;
74         const char *progname = "slappasswd";
75
76         int             i;
77         struct berval passwd;
78         struct berval hash;
79
80         while( (i = getopt( argc, argv,
81                 "c:d:gh:s:T:vu" )) != EOF )
82         {
83                 switch (i) {
84                 case 'c':       /* crypt salt format */
85                         scheme = "{CRYPT}";
86                         lutil_salt_format( optarg );
87                         break;
88
89                 case 'g':       /* new password (generate) */
90                         if ( pwfile != NULL ) {
91                                 fprintf( stderr, "Option -s incompatible with -T\n" );
92                                 return EXIT_FAILURE;
93
94                         } else if ( newpw != NULL ) {
95                                 fprintf( stderr, "New password already provided\n" );
96                                 return EXIT_FAILURE;
97
98                         } else if ( scheme != default_scheme && strcmp( scheme, cleartext_scheme ) != 0 ) {
99                                 fprintf( stderr, "Option -g incompatible with scheme \"%s\"\n", scheme );
100                                 return EXIT_FAILURE;
101
102                         } else {
103                                 struct berval   p = BER_BVNULL;
104
105                                 lutil_passwd_generate( &p, 8 );
106
107                                 newpw = p.bv_val;
108
109                                 scheme = cleartext_scheme;
110                         }
111                         break;
112
113                 case 'h':       /* scheme */
114                         if ( scheme == cleartext_scheme ) {
115                                 if ( strcmp( optarg, cleartext_scheme ) != 0 ) {
116                                         fprintf( stderr, "Option -h incompatible with -g\n" );
117                                         return EXIT_FAILURE;
118                                 }
119                                 
120                         } else if ( scheme != default_scheme ) {
121                                 fprintf( stderr, "Scheme already provided\n" );
122                                 return EXIT_FAILURE;
123
124                         } else {
125                                 scheme = strdup( optarg );
126                         }
127                         break;
128
129                 case 's':       /* new password (secret) */
130                         if ( pwfile != NULL ) {
131                                 fprintf( stderr, "Option -s incompatible with -T\n" );
132                                 return EXIT_FAILURE;
133
134                         } else if ( newpw != NULL ) {
135                                 fprintf( stderr, "New password already provided\n" );
136                                 return EXIT_FAILURE;
137
138                         } else {
139                                 char* p;
140                                 newpw = strdup( optarg );
141
142                                 for( p = optarg; *p != '\0'; p++ ) {
143                                         *p = '\0';
144                                 }
145                         }
146                         break;
147
148                 case 'T':       /* password file */
149                         if ( pwfile != NULL ) {
150                                 fprintf( stderr, "Password file already provided\n" );
151                                 return EXIT_FAILURE;
152
153                         } else if ( newpw != NULL ) {
154                                 fprintf( stderr, "Option -T incompatible with -s/-g\n" );
155                                 return EXIT_FAILURE;
156
157                         }
158                         pwfile = optarg;
159                         break;
160
161                 case 'u':       /* RFC2307 userPassword */
162                         break;
163
164                 case 'v':       /* verbose */
165                         verbose++;
166                         break;
167
168                 default:
169                         usage ( progname );
170                 }
171         }
172
173         if( argc - optind != 0 ) {
174                 usage( progname );
175         } 
176
177         if( pwfile != NULL ) {
178                 if( lutil_get_filed_password( pwfile, &passwd )) {
179                         return EXIT_FAILURE;
180                 }
181         } else {
182                 if( newpw == NULL ) {
183                         /* prompt for new password */
184                         char *cknewpw;
185                         newpw = strdup(getpassphrase("New password: "));
186                         cknewpw = getpassphrase("Re-enter new password: ");
187         
188                         if( strcmp( newpw, cknewpw )) {
189                                 fprintf( stderr, "Password values do not match\n" );
190                                 return EXIT_FAILURE;
191                         }
192                 }
193
194                 passwd.bv_val = newpw;
195                 passwd.bv_len = strlen(passwd.bv_val);
196         }
197
198         lutil_passwd_hash( &passwd, scheme, &hash, &text );
199         if( hash.bv_val == NULL ) {
200                 fprintf( stderr,
201                         "Password generation failed for scheme %s: %s\n",
202                         scheme, text ? text : "" );
203                 return EXIT_FAILURE;
204         }
205
206         if( lutil_passwd( &hash, &passwd, NULL, &text ) ) {
207                 fprintf( stderr, "Password verification failed. %s\n",
208                         text ? text : "" );
209                 return EXIT_FAILURE;
210         }
211
212         printf( "%s\n" , hash.bv_val );
213         return EXIT_SUCCESS;
214 }