]> git.sur5r.net Git - openldap/blob - servers/slapd/slappasswd.c
happy belated new year
[openldap] / servers / slapd / slappasswd.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2010 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 #include "slap.h"
41
42 static int      verbose = 0;
43
44 static void
45 usage(const char *s)
46 {
47         fprintf(stderr,
48                 "Usage: %s [options]\n"
49                 "  -c format\tcrypt(3) salt format\n"
50                 "  -g\t\tgenerate random password\n"
51                 "  -h hash\tpassword scheme\n"
52                 "  -n\t\tomit trailing newline\n"
53                 "  -s secret\tnew password\n"
54                 "  -u\t\tgenerate RFC2307 values (default)\n"
55                 "  -v\t\tincrease verbosity\n"
56                 "  -T file\tread file for new password\n"
57                 , s );
58
59         exit( EXIT_FAILURE );
60 }
61
62 int
63 slappasswd( int argc, char *argv[] )
64 {
65 #ifdef LUTIL_SHA1_BYTES
66         char    *default_scheme = "{SSHA}";
67 #else
68         char    *default_scheme = "{SMD5}";
69 #endif
70         char    *scheme = default_scheme;
71
72         char    *newpw = NULL;
73         char    *pwfile = NULL;
74         const char *text;
75         const char *progname = "slappasswd";
76
77         int             i;
78         char            *newline = "\n";
79         struct berval passwd = BER_BVNULL;
80         struct berval hash;
81
82         while( (i = getopt( argc, argv,
83                 "c:d:gh:ns:T:vu" )) != EOF )
84         {
85                 switch (i) {
86                 case 'c':       /* crypt salt format */
87                         scheme = "{CRYPT}";
88                         lutil_salt_format( optarg );
89                         break;
90
91                 case 'g':       /* new password (generate) */
92                         if ( pwfile != NULL ) {
93                                 fprintf( stderr, "Option -g incompatible with -T\n" );
94                                 return EXIT_FAILURE;
95
96                         } else if ( newpw != NULL ) {
97                                 fprintf( stderr, "New password already provided\n" );
98                                 return EXIT_FAILURE;
99
100                         } else if ( lutil_passwd_generate( &passwd, 8 )) {
101                                 fprintf( stderr, "Password generation failed\n" );
102                                 return EXIT_FAILURE;
103                         }
104                         break;
105
106                 case 'h':       /* scheme */
107                         if ( scheme != default_scheme ) {
108                                 fprintf( stderr, "Scheme already provided\n" );
109                                 return EXIT_FAILURE;
110
111                         } else {
112                                 scheme = ch_strdup( optarg );
113                         }
114                         break;
115
116                 case 'n':
117                         newline = "";
118                         break;
119
120                 case 's':       /* new password (secret) */
121                         if ( pwfile != NULL ) {
122                                 fprintf( stderr, "Option -s incompatible with -T\n" );
123                                 return EXIT_FAILURE;
124
125                         } else if ( newpw != NULL ) {
126                                 fprintf( stderr, "New password already provided\n" );
127                                 return EXIT_FAILURE;
128
129                         } else {
130                                 char* p;
131                                 newpw = ch_strdup( optarg );
132
133                                 for( p = optarg; *p != '\0'; p++ ) {
134                                         *p = '\0';
135                                 }
136                         }
137                         break;
138
139                 case 'T':       /* password file */
140                         if ( pwfile != NULL ) {
141                                 fprintf( stderr, "Password file already provided\n" );
142                                 return EXIT_FAILURE;
143
144                         } else if ( newpw != NULL ) {
145                                 fprintf( stderr, "Option -T incompatible with -s/-g\n" );
146                                 return EXIT_FAILURE;
147
148                         }
149                         pwfile = optarg;
150                         break;
151
152                 case 'u':       /* RFC2307 userPassword */
153                         break;
154
155                 case 'v':       /* verbose */
156                         verbose++;
157                         break;
158
159                 default:
160                         usage ( progname );
161                 }
162         }
163
164         if( argc - optind != 0 ) {
165                 usage( progname );
166         } 
167
168         if( pwfile != NULL ) {
169                 if( lutil_get_filed_password( pwfile, &passwd )) {
170                         return EXIT_FAILURE;
171                 }
172         } else if ( BER_BVISEMPTY( &passwd )) {
173                 if( newpw == NULL ) {
174                         /* prompt for new password */
175                         char *cknewpw;
176                         newpw = ch_strdup(getpassphrase("New password: "));
177                         cknewpw = getpassphrase("Re-enter new password: ");
178         
179                         if( strcmp( newpw, cknewpw )) {
180                                 fprintf( stderr, "Password values do not match\n" );
181                                 return EXIT_FAILURE;
182                         }
183                 }
184
185                 passwd.bv_val = newpw;
186                 passwd.bv_len = strlen(passwd.bv_val);
187         } else {
188                 hash = passwd;
189                 goto print_pw;
190         }
191
192         lutil_passwd_hash( &passwd, scheme, &hash, &text );
193         if( hash.bv_val == NULL ) {
194                 fprintf( stderr,
195                         "Password generation failed for scheme %s: %s\n",
196                         scheme, text ? text : "" );
197                 return EXIT_FAILURE;
198         }
199
200         if( lutil_passwd( &hash, &passwd, NULL, &text ) ) {
201                 fprintf( stderr, "Password verification failed. %s\n",
202                         text ? text : "" );
203                 return EXIT_FAILURE;
204         }
205
206 print_pw:;
207         printf( "%s%s" , hash.bv_val, newline );
208         return EXIT_SUCCESS;
209 }