172445Sassar/* 2178825Sdfr * Copyright (c) 2000 - 2004 Kungliga Tekniska H�gskolan 372445Sassar * (Royal Institute of Technology, Stockholm, Sweden). 472445Sassar * All rights reserved. 572445Sassar * 672445Sassar * Redistribution and use in source and binary forms, with or without 772445Sassar * modification, are permitted provided that the following conditions 872445Sassar * are met: 972445Sassar * 1072445Sassar * 1. Redistributions of source code must retain the above copyright 1172445Sassar * notice, this list of conditions and the following disclaimer. 1272445Sassar * 1372445Sassar * 2. Redistributions in binary form must reproduce the above copyright 1472445Sassar * notice, this list of conditions and the following disclaimer in the 1572445Sassar * documentation and/or other materials provided with the distribution. 1672445Sassar * 1772445Sassar * 3. Neither the name of the Institute nor the names of its contributors 1872445Sassar * may be used to endorse or promote products derived from this software 1972445Sassar * without specific prior written permission. 2072445Sassar * 2172445Sassar * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2272445Sassar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2372445Sassar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2472445Sassar * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2572445Sassar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2672445Sassar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2772445Sassar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2872445Sassar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2972445Sassar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3072445Sassar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3172445Sassar * SUCH DAMAGE. 3272445Sassar */ 3372445Sassar 3472445Sassar#include "kpasswd_locl.h" 3572445Sassar 36178825SdfrRCSID("$Id: kpasswd-generator.c 19233 2006-12-06 08:04:05Z lha $"); 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); 6172445Sassar return n; 6272445Sassar} 6372445Sassar 6472445Sassarstatic int 6572445Sassarnop_prompter (krb5_context context, 6672445Sassar void *data, 6778527Sassar const char *name, 6872445Sassar const char *banner, 6972445Sassar int num_prompts, 7072445Sassar krb5_prompt prompts[]) 7172445Sassar{ 7272445Sassar return 0; 7372445Sassar} 7472445Sassar 7572445Sassarstatic void 7672445Sassargenerate_requests (const char *filename, unsigned nreq) 7772445Sassar{ 7872445Sassar krb5_context context; 7972445Sassar krb5_error_code ret; 8072445Sassar int i; 8172445Sassar char **words; 8272445Sassar unsigned nwords; 8372445Sassar 8472445Sassar ret = krb5_init_context (&context); 8572445Sassar if (ret) 8672445Sassar errx (1, "krb5_init_context failed: %d", ret); 8772445Sassar 8872445Sassar nwords = read_words (filename, &words); 8972445Sassar 9072445Sassar for (i = 0; i < nreq; ++i) { 9172445Sassar char *name = words[rand() % nwords]; 92178825Sdfr krb5_get_init_creds_opt *opt; 9372445Sassar krb5_creds cred; 9472445Sassar krb5_principal principal; 9572445Sassar int result_code; 9672445Sassar krb5_data result_code_string, result_string; 9772445Sassar char *old_pwd, *new_pwd; 9872445Sassar 99178825Sdfr krb5_get_init_creds_opt_alloc (context, &opt); 100178825Sdfr krb5_get_init_creds_opt_set_tkt_life (opt, 300); 101178825Sdfr krb5_get_init_creds_opt_set_forwardable (opt, FALSE); 102178825Sdfr krb5_get_init_creds_opt_set_proxiable (opt, FALSE); 10372445Sassar 10472445Sassar ret = krb5_parse_name (context, name, &principal); 10572445Sassar if (ret) 10672445Sassar krb5_err (context, 1, ret, "krb5_parse_name %s", name); 10772445Sassar 10872445Sassar asprintf (&old_pwd, "%s", name); 10972445Sassar asprintf (&new_pwd, "%s2", name); 11072445Sassar 11172445Sassar ret = krb5_get_init_creds_password (context, 11272445Sassar &cred, 11372445Sassar principal, 11472445Sassar old_pwd, 11572445Sassar nop_prompter, 11672445Sassar NULL, 11772445Sassar 0, 11872445Sassar "kadmin/changepw", 119178825Sdfr opt); 12072445Sassar if( ret == KRB5KRB_AP_ERR_BAD_INTEGRITY 12172445Sassar || ret == KRB5KRB_AP_ERR_MODIFIED) { 12272445Sassar char *tmp; 12372445Sassar 12472445Sassar tmp = new_pwd; 12572445Sassar new_pwd = old_pwd; 12672445Sassar old_pwd = tmp; 12772445Sassar 12872445Sassar ret = krb5_get_init_creds_password (context, 12972445Sassar &cred, 13072445Sassar principal, 13172445Sassar old_pwd, 13272445Sassar nop_prompter, 13372445Sassar NULL, 13472445Sassar 0, 13572445Sassar "kadmin/changepw", 136178825Sdfr opt); 13772445Sassar } 13872445Sassar if (ret) 13972445Sassar krb5_err (context, 1, ret, "krb5_get_init_creds_password"); 14072445Sassar 14172445Sassar krb5_free_principal (context, principal); 14272445Sassar 14372445Sassar ret = krb5_change_password (context, &cred, new_pwd, 14472445Sassar &result_code, 14572445Sassar &result_code_string, 14672445Sassar &result_string); 14772445Sassar if (ret) 14872445Sassar krb5_err (context, 1, ret, "krb5_change_password"); 14972445Sassar 15072445Sassar free (old_pwd); 15172445Sassar free (new_pwd); 152178825Sdfr krb5_free_cred_contents (context, &cred); 153178825Sdfr krb5_get_init_creds_opt_free(context, opt); 15472445Sassar } 15572445Sassar} 15672445Sassar 15772445Sassarstatic int version_flag = 0; 15872445Sassarstatic int help_flag = 0; 15972445Sassar 16072445Sassarstatic struct getargs args[] = { 16172445Sassar { "version", 0, arg_flag, &version_flag }, 16272445Sassar { "help", 0, arg_flag, &help_flag } 16372445Sassar}; 16472445Sassar 16572445Sassarstatic void 16672445Sassarusage (int ret) 16772445Sassar{ 16872445Sassar arg_printusage (args, 16972445Sassar sizeof(args)/sizeof(*args), 17072445Sassar NULL, 17172445Sassar "file [number]"); 17272445Sassar exit (ret); 17372445Sassar} 17472445Sassar 17572445Sassarint 17672445Sassarmain(int argc, char **argv) 17772445Sassar{ 17872445Sassar int optind = 0; 17972445Sassar int nreq; 18072445Sassar char *end; 18172445Sassar 18278527Sassar setprogname(argv[0]); 18372445Sassar if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) 18472445Sassar usage(1); 18590926Snectar if (help_flag) 18690926Snectar usage (0); 18790926Snectar if (version_flag) { 18890926Snectar print_version(NULL); 18990926Snectar return 0; 19090926Snectar } 19172445Sassar argc -= optind; 19272445Sassar argv += optind; 19372445Sassar 19472445Sassar if (argc != 2) 19572445Sassar usage (1); 19672445Sassar srand (0); 19772445Sassar nreq = strtol (argv[1], &end, 0); 19872445Sassar if (argv[1] == end || *end != '\0') 19972445Sassar usage (1); 20072445Sassar generate_requests (argv[0], nreq); 20172445Sassar return 0; 20272445Sassar} 203