/* * A specialized wallet client for rekeying a keytab. * * Written by Russ Allbery * and Jon Robertson * Copyright 2018 Russ Allbery * Copyright 2010 * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ #include #include #include #include #include #include #include #include /* * Usage message. Use as a format and pass the port number and default server * name. */ static const char usage_message[] = "\ Usage: wallet-rekey [options] [ ...]\n\ \n\ Options:\n\ -c Command prefix to use (default: wallet)\n\ -k Kerberos principal of the server\n\ -h Display this help\n\ -p Port of server (default: %d, if zero, remctl default)\n\ -s Server hostname (default: %s)\n\ -u Authenticate as before rekeying\n\ -v Display the version of wallet\n"; /* * Display the usage message for wallet-rekey. */ static void __attribute__((__noreturn__)) usage(int status) { fprintf((status == 0) ? stdout : stderr, usage_message, WALLET_PORT, (WALLET_SERVER == NULL) ? "" : WALLET_SERVER); exit(status); } /* * Main routine. Parse the arguments and then perform the desired operation. */ int main(int argc, char *argv[]) { krb5_context ctx; krb5_error_code retval; struct options options; int option, i; bool okay = true; struct remctl *r; long tmp; char *end; /* Set up logging and identity. */ message_program_name = "wallet"; /* Initialize default configuration. */ retval = krb5_init_context(&ctx); if (retval != 0) die_krb5(ctx, retval, "cannot initialize Kerberos"); default_options(ctx, &options); while ((option = getopt(argc, argv, "c:k:hp:S:s:u:v")) != EOF) { switch (option) { case 'c': options.type = optarg; break; case 'k': options.principal = optarg; break; case 'h': usage(0); case 'p': errno = 0; tmp = strtol(optarg, &end, 10); if (tmp <= 0 || tmp > 65535 || *end != '\0') die("invalid port number %s", optarg); options.port = (unsigned short) tmp; break; case 's': options.server = optarg; break; case 'u': options.user = optarg; break; case 'v': printf("%s\n", PACKAGE_STRING); exit(0); default: usage(1); } } argc -= optind; argv += optind; /* * If no server was set at configure time and none was set on the command * line or with krb5.conf settings, we can't continue. */ if (options.server == NULL) die("no server specified in krb5.conf or with -s"); /* If a user was specified, obtain Kerberos tickets. */ if (options.user != NULL) kinit(ctx, options.user); /* Open a remctl connection. */ r = remctl_new(); if (r == NULL) sysdie("cannot allocate memory"); if (!remctl_open(r, options.server, options.port, options.principal)) die("%s", remctl_error(r)); /* * Rekey all the keytabs given on the command line, or the system keytab * if none were given. */ if (argc == 0) okay = rekey_keytab(r, ctx, options.type, "/etc/krb5.keytab"); else { for (i = 0; i < argc; i++) { okay = rekey_keytab(r, ctx, options.type, argv[i]); if (!okay) break; } } remctl_close(r); krb5_free_context(ctx); if (options.user != NULL) kdestroy(); exit(okay ? 0 : 1); }