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