1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2011 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 42static int verbose = 0; 43 44static void 45usage(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 62int 63slappasswd( 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 206print_pw:; 207 printf( "%s%s" , hash.bv_val, newline ); 208 return EXIT_SUCCESS; 209} 210