kpasswd-generator.c revision 78527
172445Sassar/*
278527Sassar * Copyright (c) 2000 - 2001 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
3678527SassarRCSID("$Id: kpasswd-generator.c,v 1.4 2001/05/12 15:17:10 assar Exp $");
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) {
5172445Sassar	if (buf[strlen (buf) - 1] == '\n')
5272445Sassar	    buf[strlen (buf) - 1] = '\0';
5372445Sassar	if (n >= alloc) {
5472445Sassar	    alloc += 16;
5572445Sassar	    w = erealloc (w, alloc * sizeof(char **));
5672445Sassar	}
5772445Sassar	w[n++] = estrdup (buf);
5872445Sassar    }
5972445Sassar    *ret_w = w;
6072445Sassar    return n;
6172445Sassar}
6272445Sassar
6372445Sassarstatic int
6472445Sassarnop_prompter (krb5_context context,
6572445Sassar	      void *data,
6678527Sassar	      const char *name,
6772445Sassar	      const char *banner,
6872445Sassar	      int num_prompts,
6972445Sassar	      krb5_prompt prompts[])
7072445Sassar{
7172445Sassar    return 0;
7272445Sassar}
7372445Sassar
7472445Sassarstatic void
7572445Sassargenerate_requests (const char *filename, unsigned nreq)
7672445Sassar{
7772445Sassar    krb5_context context;
7872445Sassar    krb5_error_code ret;
7972445Sassar    int i;
8072445Sassar    char **words;
8172445Sassar    unsigned nwords;
8272445Sassar
8372445Sassar    ret = krb5_init_context (&context);
8472445Sassar    if (ret)
8572445Sassar	errx (1, "krb5_init_context failed: %d", ret);
8672445Sassar
8772445Sassar    nwords = read_words (filename, &words);
8872445Sassar
8972445Sassar    for (i = 0; i < nreq; ++i) {
9072445Sassar	char *name = words[rand() % nwords];
9172445Sassar	krb5_get_init_creds_opt opt;
9272445Sassar	krb5_creds cred;
9372445Sassar	krb5_principal principal;
9472445Sassar	int result_code;
9572445Sassar	krb5_data result_code_string, result_string;
9672445Sassar	char *old_pwd, *new_pwd;
9772445Sassar
9872445Sassar	krb5_get_init_creds_opt_init (&opt);
9972445Sassar	krb5_get_init_creds_opt_set_tkt_life (&opt, 300);
10072445Sassar	krb5_get_init_creds_opt_set_forwardable (&opt, FALSE);
10172445Sassar	krb5_get_init_creds_opt_set_proxiable (&opt, FALSE);
10272445Sassar
10372445Sassar	ret = krb5_parse_name (context, name, &principal);
10472445Sassar	if (ret)
10572445Sassar	    krb5_err (context, 1, ret, "krb5_parse_name %s", name);
10672445Sassar
10772445Sassar	asprintf (&old_pwd, "%s", name);
10872445Sassar	asprintf (&new_pwd, "%s2", name);
10972445Sassar
11072445Sassar	ret = krb5_get_init_creds_password (context,
11172445Sassar					    &cred,
11272445Sassar					    principal,
11372445Sassar					    old_pwd,
11472445Sassar					    nop_prompter,
11572445Sassar					    NULL,
11672445Sassar					    0,
11772445Sassar					    "kadmin/changepw",
11872445Sassar					    &opt);
11972445Sassar	if( ret == KRB5KRB_AP_ERR_BAD_INTEGRITY
12072445Sassar	    || ret == KRB5KRB_AP_ERR_MODIFIED) {
12172445Sassar	    char *tmp;
12272445Sassar
12372445Sassar	    tmp = new_pwd;
12472445Sassar	    new_pwd = old_pwd;
12572445Sassar	    old_pwd = tmp;
12672445Sassar
12772445Sassar	    ret = krb5_get_init_creds_password (context,
12872445Sassar						&cred,
12972445Sassar						principal,
13072445Sassar						old_pwd,
13172445Sassar						nop_prompter,
13272445Sassar						NULL,
13372445Sassar						0,
13472445Sassar						"kadmin/changepw",
13572445Sassar						&opt);
13672445Sassar	}
13772445Sassar	if (ret)
13872445Sassar	    krb5_err (context, 1, ret, "krb5_get_init_creds_password");
13972445Sassar
14072445Sassar	krb5_free_principal (context, principal);
14172445Sassar
14272445Sassar	ret = krb5_change_password (context, &cred, new_pwd,
14372445Sassar				    &result_code,
14472445Sassar				    &result_code_string,
14572445Sassar				    &result_string);
14672445Sassar	if (ret)
14772445Sassar	    krb5_err (context, 1, ret, "krb5_change_password");
14872445Sassar
14972445Sassar	free (old_pwd);
15072445Sassar	free (new_pwd);
15172445Sassar	krb5_free_creds_contents (context, &cred);
15272445Sassar    }
15372445Sassar}
15472445Sassar
15572445Sassarstatic int version_flag	= 0;
15672445Sassarstatic int help_flag	= 0;
15772445Sassar
15872445Sassarstatic struct getargs args[] = {
15972445Sassar    { "version", 	0,   arg_flag, &version_flag },
16072445Sassar    { "help",		0,   arg_flag, &help_flag }
16172445Sassar};
16272445Sassar
16372445Sassarstatic void
16472445Sassarusage (int ret)
16572445Sassar{
16672445Sassar    arg_printusage (args,
16772445Sassar		    sizeof(args)/sizeof(*args),
16872445Sassar		    NULL,
16972445Sassar		    "file [number]");
17072445Sassar    exit (ret);
17172445Sassar}
17272445Sassar
17372445Sassarint
17472445Sassarmain(int argc, char **argv)
17572445Sassar{
17672445Sassar    int optind = 0;
17772445Sassar    int nreq;
17872445Sassar    char *end;
17972445Sassar
18078527Sassar    setprogname(argv[0]);
18172445Sassar    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
18272445Sassar	usage(1);
18372445Sassar    argc -= optind;
18472445Sassar    argv += optind;
18572445Sassar
18672445Sassar    if (argc != 2)
18772445Sassar	usage (1);
18872445Sassar    srand (0);
18972445Sassar    nreq = strtol (argv[1], &end, 0);
19072445Sassar    if (argv[1] == end || *end != '\0')
19172445Sassar	usage (1);
19272445Sassar    generate_requests (argv[0], nreq);
19372445Sassar    return 0;
19472445Sassar}
195