172445Sassar/* 2233294Sstas * Copyright (c) 2000 - 2004 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 572445Sassar * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 972445Sassar * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1272445Sassar * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1672445Sassar * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2072445Sassar * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3272445Sassar */ 3372445Sassar 3472445Sassar#include "kpasswd_locl.h" 3572445Sassar 36233294SstasRCSID("$Id$"); 3772445Sassar 3872445Sassarstatic unsigned 3972445Sassarread_words (const char *filename, char ***ret_w) 4072445Sassar{ 4172445Sassar unsigned n, alloc; 4272445Sassar FILE *f; 4372445Sassar char buf[256]; 4472445Sassar char **w = NULL; 4572445Sassar 4672445Sassar f = fopen (filename, "r"); 4772445Sassar if (f == NULL) 4872445Sassar err (1, "cannot open %s", filename); 4972445Sassar alloc = n = 0; 5072445Sassar while (fgets (buf, sizeof(buf), f) != NULL) { 51178825Sdfr buf[strcspn(buf, "\r\n")] = '\0'; 5272445Sassar if (n >= alloc) { 5372445Sassar alloc += 16; 5472445Sassar w = erealloc (w, alloc * sizeof(char **)); 5572445Sassar } 5672445Sassar w[n++] = estrdup (buf); 5772445Sassar } 5872445Sassar *ret_w = w; 59178825Sdfr if (n == 0) 60178825Sdfr errx(1, "%s is an empty file, no words to try", filename); 61233294Sstas fclose(f); 6272445Sassar return n; 6372445Sassar} 6472445Sassar 6572445Sassarstatic int 6672445Sassarnop_prompter (krb5_context context, 6772445Sassar void *data, 6878527Sassar const char *name, 6972445Sassar const char *banner, 7072445Sassar int num_prompts, 7172445Sassar krb5_prompt prompts[]) 7272445Sassar{ 7372445Sassar return 0; 7472445Sassar} 7572445Sassar 7672445Sassarstatic void 7772445Sassargenerate_requests (const char *filename, unsigned nreq) 7872445Sassar{ 7972445Sassar krb5_context context; 8072445Sassar krb5_error_code ret; 8172445Sassar int i; 8272445Sassar char **words; 8372445Sassar unsigned nwords; 8472445Sassar 8572445Sassar ret = krb5_init_context (&context); 8672445Sassar if (ret) 8772445Sassar errx (1, "krb5_init_context failed: %d", ret); 8872445Sassar 8972445Sassar nwords = read_words (filename, &words); 9072445Sassar 9172445Sassar for (i = 0; i < nreq; ++i) { 9272445Sassar char *name = words[rand() % nwords]; 93178825Sdfr krb5_get_init_creds_opt *opt; 9472445Sassar krb5_creds cred; 9572445Sassar krb5_principal principal; 9672445Sassar int result_code; 9772445Sassar krb5_data result_code_string, result_string; 9872445Sassar char *old_pwd, *new_pwd; 9972445Sassar 100178825Sdfr krb5_get_init_creds_opt_alloc (context, &opt); 101178825Sdfr krb5_get_init_creds_opt_set_tkt_life (opt, 300); 102178825Sdfr krb5_get_init_creds_opt_set_forwardable (opt, FALSE); 103178825Sdfr krb5_get_init_creds_opt_set_proxiable (opt, FALSE); 10472445Sassar 10572445Sassar ret = krb5_parse_name (context, name, &principal); 10672445Sassar if (ret) 10772445Sassar krb5_err (context, 1, ret, "krb5_parse_name %s", name); 10872445Sassar 10972445Sassar asprintf (&old_pwd, "%s", name); 11072445Sassar asprintf (&new_pwd, "%s2", name); 11172445Sassar 11272445Sassar ret = krb5_get_init_creds_password (context, 11372445Sassar &cred, 11472445Sassar principal, 11572445Sassar old_pwd, 11672445Sassar nop_prompter, 11772445Sassar NULL, 11872445Sassar 0, 11972445Sassar "kadmin/changepw", 120178825Sdfr opt); 12172445Sassar if( ret == KRB5KRB_AP_ERR_BAD_INTEGRITY 12272445Sassar || ret == KRB5KRB_AP_ERR_MODIFIED) { 12372445Sassar char *tmp; 12472445Sassar 12572445Sassar tmp = new_pwd; 12672445Sassar new_pwd = old_pwd; 12772445Sassar old_pwd = tmp; 12872445Sassar 12972445Sassar ret = krb5_get_init_creds_password (context, 13072445Sassar &cred, 13172445Sassar principal, 13272445Sassar old_pwd, 13372445Sassar nop_prompter, 13472445Sassar NULL, 13572445Sassar 0, 13672445Sassar "kadmin/changepw", 137178825Sdfr opt); 13872445Sassar } 13972445Sassar if (ret) 14072445Sassar krb5_err (context, 1, ret, "krb5_get_init_creds_password"); 14172445Sassar 14272445Sassar krb5_free_principal (context, principal); 14372445Sassar 144233294Sstas 145233294Sstas ret = krb5_set_password (context, 146233294Sstas &cred, 147233294Sstas new_pwd, 148233294Sstas NULL, 149233294Sstas &result_code, 150233294Sstas &result_code_string, 151233294Sstas &result_string); 15272445Sassar if (ret) 15372445Sassar krb5_err (context, 1, ret, "krb5_change_password"); 15472445Sassar 15572445Sassar free (old_pwd); 15672445Sassar free (new_pwd); 157178825Sdfr krb5_free_cred_contents (context, &cred); 158178825Sdfr krb5_get_init_creds_opt_free(context, opt); 15972445Sassar } 16072445Sassar} 16172445Sassar 16272445Sassarstatic int version_flag = 0; 16372445Sassarstatic int help_flag = 0; 16472445Sassar 16572445Sassarstatic struct getargs args[] = { 16672445Sassar { "version", 0, arg_flag, &version_flag }, 16772445Sassar { "help", 0, arg_flag, &help_flag } 16872445Sassar}; 16972445Sassar 17072445Sassarstatic void 17172445Sassarusage (int ret) 17272445Sassar{ 17372445Sassar arg_printusage (args, 17472445Sassar sizeof(args)/sizeof(*args), 17572445Sassar NULL, 17672445Sassar "file [number]"); 17772445Sassar exit (ret); 17872445Sassar} 17972445Sassar 18072445Sassarint 18172445Sassarmain(int argc, char **argv) 18272445Sassar{ 18372445Sassar int optind = 0; 18472445Sassar int nreq; 18572445Sassar char *end; 18672445Sassar 18778527Sassar setprogname(argv[0]); 18872445Sassar if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) 18972445Sassar usage(1); 19090926Snectar if (help_flag) 19190926Snectar usage (0); 19290926Snectar if (version_flag) { 19390926Snectar print_version(NULL); 19490926Snectar return 0; 19590926Snectar } 19672445Sassar argc -= optind; 19772445Sassar argv += optind; 19872445Sassar 19972445Sassar if (argc != 2) 20072445Sassar usage (1); 20172445Sassar srand (0); 20272445Sassar nreq = strtol (argv[1], &end, 0); 20372445Sassar if (argv[1] == end || *end != '\0') 20472445Sassar usage (1); 20572445Sassar generate_requests (argv[0], nreq); 20672445Sassar return 0; 20772445Sassar} 208