1 /* $NetBSD: kpasswd-generator.c,v 1.1.1.1 2011/04/13 18:14:38 elric Exp $ */ 2 3 /* 4 * Copyright (c) 2000 - 2004 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "kpasswd_locl.h" 37 38 __RCSID("$NetBSD: kpasswd-generator.c,v 1.1.1.1 2011/04/13 18:14:38 elric Exp $"); 39 40 static unsigned 41 read_words (const char *filename, char ***ret_w) 42 { 43 unsigned n, alloc; 44 FILE *f; 45 char buf[256]; 46 char **w = NULL; 47 48 f = fopen (filename, "r"); 49 if (f == NULL) 50 err (1, "cannot open %s", filename); 51 alloc = n = 0; 52 while (fgets (buf, sizeof(buf), f) != NULL) { 53 buf[strcspn(buf, "\r\n")] = '\0'; 54 if (n >= alloc) { 55 alloc += 16; 56 w = erealloc (w, alloc * sizeof(char **)); 57 } 58 w[n++] = estrdup (buf); 59 } 60 *ret_w = w; 61 if (n == 0) 62 errx(1, "%s is an empty file, no words to try", filename); 63 fclose(f); 64 return n; 65 } 66 67 static int 68 nop_prompter (krb5_context context, 69 void *data, 70 const char *name, 71 const char *banner, 72 int num_prompts, 73 krb5_prompt prompts[]) 74 { 75 return 0; 76 } 77 78 static void 79 generate_requests (const char *filename, unsigned nreq) 80 { 81 krb5_context context; 82 krb5_error_code ret; 83 int i; 84 char **words; 85 unsigned nwords; 86 87 ret = krb5_init_context (&context); 88 if (ret) 89 errx (1, "krb5_init_context failed: %d", ret); 90 91 nwords = read_words (filename, &words); 92 93 for (i = 0; i < nreq; ++i) { 94 char *name = words[rand() % nwords]; 95 krb5_get_init_creds_opt *opt; 96 krb5_creds cred; 97 krb5_principal principal; 98 int result_code; 99 krb5_data result_code_string, result_string; 100 char *old_pwd, *new_pwd; 101 102 krb5_get_init_creds_opt_alloc (context, &opt); 103 krb5_get_init_creds_opt_set_tkt_life (opt, 300); 104 krb5_get_init_creds_opt_set_forwardable (opt, FALSE); 105 krb5_get_init_creds_opt_set_proxiable (opt, FALSE); 106 107 ret = krb5_parse_name (context, name, &principal); 108 if (ret) 109 krb5_err (context, 1, ret, "krb5_parse_name %s", name); 110 111 asprintf (&old_pwd, "%s", name); 112 asprintf (&new_pwd, "%s2", name); 113 114 ret = krb5_get_init_creds_password (context, 115 &cred, 116 principal, 117 old_pwd, 118 nop_prompter, 119 NULL, 120 0, 121 "kadmin/changepw", 122 opt); 123 if( ret == KRB5KRB_AP_ERR_BAD_INTEGRITY 124 || ret == KRB5KRB_AP_ERR_MODIFIED) { 125 char *tmp; 126 127 tmp = new_pwd; 128 new_pwd = old_pwd; 129 old_pwd = tmp; 130 131 ret = krb5_get_init_creds_password (context, 132 &cred, 133 principal, 134 old_pwd, 135 nop_prompter, 136 NULL, 137 0, 138 "kadmin/changepw", 139 opt); 140 } 141 if (ret) 142 krb5_err (context, 1, ret, "krb5_get_init_creds_password"); 143 144 krb5_free_principal (context, principal); 145 146 147 ret = krb5_set_password (context, 148 &cred, 149 new_pwd, 150 NULL, 151 &result_code, 152 &result_code_string, 153 &result_string); 154 if (ret) 155 krb5_err (context, 1, ret, "krb5_change_password"); 156 157 free (old_pwd); 158 free (new_pwd); 159 krb5_free_cred_contents (context, &cred); 160 krb5_get_init_creds_opt_free(context, opt); 161 } 162 } 163 164 static int version_flag = 0; 165 static int help_flag = 0; 166 167 static struct getargs args[] = { 168 { "version", 0, arg_flag, &version_flag }, 169 { "help", 0, arg_flag, &help_flag } 170 }; 171 172 static void 173 usage (int ret) 174 { 175 arg_printusage (args, 176 sizeof(args)/sizeof(*args), 177 NULL, 178 "file [number]"); 179 exit (ret); 180 } 181 182 int 183 main(int argc, char **argv) 184 { 185 int optind = 0; 186 int nreq; 187 char *end; 188 189 setprogname(argv[0]); 190 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) 191 usage(1); 192 if (help_flag) 193 usage (0); 194 if (version_flag) { 195 print_version(NULL); 196 return 0; 197 } 198 argc -= optind; 199 argv += optind; 200 201 if (argc != 2) 202 usage (1); 203 srand (0); 204 nreq = strtol (argv[1], &end, 0); 205 if (argv[1] == end || *end != '\0') 206 usage (1); 207 generate_requests (argv[0], nreq); 208 return 0; 209 } 210