summaryrefslogtreecommitdiffstats
path: root/crypto/kerberosIV/kadmin/kadmin.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/kerberosIV/kadmin/kadmin.c')
-rw-r--r--crypto/kerberosIV/kadmin/kadmin.c1145
1 files changed, 1145 insertions, 0 deletions
diff --git a/crypto/kerberosIV/kadmin/kadmin.c b/crypto/kerberosIV/kadmin/kadmin.c
new file mode 100644
index 0000000..76abda5
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/kadmin.c
@@ -0,0 +1,1145 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+/*
+ * Kerberos database administrator's tool.
+ *
+ * The default behavior of kadmin is if the -m option is given
+ * on the commandline, multiple requests are allowed to be given
+ * with one entry of the admin password (until the tickets expire).
+ */
+
+#include "kadm_locl.h"
+#include "getarg.h"
+#include "parse_time.h"
+
+RCSID("$Id: kadmin.c,v 1.62 1999/11/02 17:02:14 bg Exp $");
+
+static int change_password(int argc, char **argv);
+static int change_key(int argc, char **argv);
+static int change_admin_password(int argc, char **argv);
+static int add_new_key(int argc, char **argv);
+static int del_entry(int argc, char **argv);
+static int get_entry(int argc, char **argv);
+static int mod_entry(int argc, char **argv);
+static int help(int argc, char **argv);
+static int clean_up_cmd(int argc, char **argv);
+static int quit_cmd(int argc, char **argv);
+static int set_timeout_cmd(int argc, char **argv);
+
+static int set_timeout(const char *);
+
+static SL_cmd cmds[] = {
+ {"change_password", change_password, "Change a user's password"},
+ {"cpw"},
+ {"passwd"},
+ {"change_key", change_key, "Change a user's password as a DES binary key"},
+ {"ckey"},
+ {"change_admin_password", change_admin_password,
+ "Change your admin password"},
+ {"cap"},
+ {"add_new_key", add_new_key, "Add new user to kerberos database"},
+ {"ank"},
+ {"del_entry", del_entry, "Delete entry from database"},
+ {"del"},
+ {"delete"},
+ {"get_entry", get_entry, "Get entry from kerberos database"},
+ {"mod_entry", mod_entry, "Modify entry in kerberos database"},
+ {"destroy_tickets", clean_up_cmd, "Destroy admin tickets"},
+ {"set_timeout", set_timeout_cmd, "Set ticket timeout"},
+ {"timeout" },
+ {"exit", quit_cmd, "Exit program"},
+ {"quit"},
+ {"help", help, "Help"},
+ {"?"},
+ {NULL}
+};
+
+#define BAD_PW 1
+#define GOOD_PW 0
+#define FUDGE_VALUE 15 /* for ticket expiration time */
+#define PE_NO 0
+#define PE_YES 1
+#define PE_UNSURE 2
+
+/* for get_password, whether it should do the swapping...necessary for
+ using vals structure, unnecessary for change_pw requests */
+#define DONTSWAP 0
+#define SWAP 1
+
+static krb_principal pr;
+static char default_realm[REALM_SZ]; /* default kerberos realm */
+static char krbrlm[REALM_SZ]; /* current realm being administered */
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else
+#define read_long_pw_string des_read_pw_string
+#endif
+
+static void
+get_maxlife(Kadm_vals *vals)
+{
+ char buff[BUFSIZ];
+ time_t life;
+ int l;
+
+ do {
+ printf("Maximum ticket lifetime? (%d) [%s] ",
+ vals->max_life, krb_life_to_atime(vals->max_life));
+ fflush(stdout);
+ if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+ clearerr(stdin);
+ return;
+ }
+ life = krb_atime_to_life(buff);
+ } while (life <= 0);
+
+ l = strlen(buff);
+ if (buff[l-2] == 'm')
+ life = krb_time_to_life(0L, life*60);
+ if (buff[l-2] == 'h')
+ life = krb_time_to_life(0L, life*60*60);
+
+ vals->max_life = life;
+ SET_FIELD(KADM_MAXLIFE,vals->fields);
+}
+
+static void
+get_attr(Kadm_vals *vals)
+{
+ char buff[BUFSIZ], *out;
+ int attr;
+
+ do {
+ printf("Attributes? [0x%.2x] ", vals->attributes);
+ fflush(stdout);
+ if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+ clearerr(stdin);
+ return;
+ }
+ attr = strtol(buff, &out, 0);
+ if (attr == 0 && out == buff)
+ attr = -1;
+ } while (attr < 0 || attr > 0xffff);
+
+ vals->attributes = attr;
+ SET_FIELD(KADM_ATTR,vals->fields);
+}
+
+static time_t
+parse_expdate(const char *str)
+{
+ struct tm edate;
+
+ memset(&edate, 0, sizeof(edate));
+ if (sscanf(str, "%d-%d-%d",
+ &edate.tm_year, &edate.tm_mon, &edate.tm_mday) == 3) {
+ edate.tm_mon--; /* January is 0, not 1 */
+ edate.tm_hour = 23; /* nearly midnight at the end of the */
+ edate.tm_min = 59; /* specified day */
+ }
+ if(krb_check_tm (edate))
+ return -1;
+ edate.tm_year -= 1900;
+ return tm2time (edate, 1);
+}
+
+static void
+get_expdate(Kadm_vals *vals)
+{
+ char buff[BUFSIZ];
+ time_t t;
+
+ do {
+ strftime(buff, sizeof(buff), "%Y-%m-%d", k_localtime(&vals->exp_date));
+ printf("Expiration date (enter yyyy-mm-dd) ? [%s] ", buff);
+ fflush(stdout);
+ if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+ clearerr(stdin);
+ return;
+ }
+ t = parse_expdate(buff);
+ }while(t < 0);
+ vals->exp_date = t;
+ SET_FIELD(KADM_EXPDATE,vals->fields);
+}
+
+static int
+princ_exists(char *name, char *instance, char *realm)
+{
+ int status;
+
+ int old = krb_use_admin_server(1);
+ status = krb_get_pw_in_tkt(name, instance, realm,
+ KRB_TICKET_GRANTING_TICKET,
+ realm, 1, "");
+ krb_use_admin_server(old);
+
+ if ((status == KSUCCESS) || (status == INTK_BADPW))
+ return(PE_YES);
+ else if (status == KDC_PR_UNKNOWN)
+ return(PE_NO);
+ else
+ return(PE_UNSURE);
+}
+
+static void
+passwd_to_lowhigh(u_int32_t *low, u_int32_t *high, char *password, int byteswap)
+{
+ des_cblock newkey;
+
+ if (strlen(password) == 0) {
+ printf("Using random password.\n");
+#ifdef NOENCRYPTION
+ memset(newkey, 0, sizeof(newkey));
+#else
+ des_new_random_key(&newkey);
+#endif
+ } else {
+#ifdef NOENCRYPTION
+ memset(newkey, 0, sizeof(newkey));
+#else
+ des_string_to_key(password, &newkey);
+#endif
+ }
+
+ memcpy(low, newkey, 4);
+ memcpy(high, ((char *)newkey) + 4, 4);
+
+ memset(newkey, 0, sizeof(newkey));
+
+#ifdef NOENCRYPTION
+ *low = 1;
+#endif
+
+ if (byteswap != DONTSWAP) {
+ *low = htonl(*low);
+ *high = htonl(*high);
+ }
+}
+
+static int
+get_password(u_int32_t *low, u_int32_t *high, char *prompt, int byteswap)
+{
+ char new_passwd[MAX_KPW_LEN]; /* new password */
+
+ if (read_long_pw_string(new_passwd, sizeof(new_passwd)-1, prompt, 1))
+ return(BAD_PW);
+ passwd_to_lowhigh (low, high, new_passwd, byteswap);
+ memset (new_passwd, 0, sizeof(new_passwd));
+ return(GOOD_PW);
+}
+
+static int
+get_admin_password(void)
+{
+ int status;
+ char admin_passwd[MAX_KPW_LEN]; /* Admin's password */
+ int ticket_life = 1; /* minimum ticket lifetime */
+ CREDENTIALS c;
+
+ alarm(0);
+ /* If admin tickets exist and are valid, just exit. */
+ memset(&c, 0, sizeof(c));
+ if (krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c) == KSUCCESS)
+ /*
+ * If time is less than lifetime - FUDGE_VALUE after issue date,
+ * tickets will probably last long enough for the next
+ * transaction.
+ */
+ if (time(0) < (c.issue_date + (5 * 60 * c.lifetime) - FUDGE_VALUE))
+ return(KADM_SUCCESS);
+ ticket_life = DEFAULT_TKT_LIFE;
+
+ if (princ_exists(pr.name, pr.instance, pr.realm) != PE_NO) {
+ char prompt[256];
+ snprintf(prompt, sizeof(prompt), "%s's Password: ",
+ krb_unparse_name(&pr));
+ if (read_long_pw_string(admin_passwd,
+ sizeof(admin_passwd)-1,
+ prompt, 0)) {
+ warnx ("Error reading admin password.");
+ goto bad;
+ }
+ status = krb_get_pw_in_tkt(pr.name, pr.instance, pr.realm,
+ PWSERV_NAME, KADM_SINST,
+ ticket_life, admin_passwd);
+ memset(admin_passwd, 0, sizeof(admin_passwd));
+
+ /* Initialize non shared random sequence from session key. */
+ memset(&c, 0, sizeof(c));
+ krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c);
+ des_init_random_number_generator(&c.session);
+ }
+ else
+ status = KDC_PR_UNKNOWN;
+
+ switch(status) {
+ case GT_PW_OK:
+ return(GOOD_PW);
+ case KDC_PR_UNKNOWN:
+ printf("Principal %s does not exist.\n", krb_unparse_name(&pr));
+ goto bad;
+ case GT_PW_BADPW:
+ printf("Incorrect admin password.\n");
+ goto bad;
+ default:
+ com_err("kadmin", status+krb_err_base,
+ "while getting password tickets");
+ goto bad;
+ }
+
+ bad:
+ memset(admin_passwd, 0, sizeof(admin_passwd));
+ dest_tkt();
+ return(BAD_PW);
+}
+
+static char *principal;
+static char *username;
+static char *realm;
+static char *timeout;
+static int tflag; /* use existing tickets */
+static int mflag; /* compatibility */
+static int version_flag;
+static int help_flag;
+
+static time_t destroy_timeout = 5 * 60;
+
+struct getargs args[] = {
+ { NULL, 'p', arg_string, &principal,
+ "principal to authenticate as"},
+ { NULL, 'u', arg_string, &username,
+ "username, other than default" },
+ { NULL, 'r', arg_string, &realm, "local realm" },
+ { NULL, 'm', arg_flag, &mflag, "disable ticket timeout" },
+ { NULL, 'T', arg_string, &timeout, "default ticket timeout" },
+ { NULL, 't', arg_flag, &tflag, "use existing tickets" },
+ { "version",0, arg_flag, &version_flag },
+ { "help", 'h', arg_flag, &help_flag },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static int
+clean_up()
+{
+ if(!tflag)
+ return dest_tkt() == KSUCCESS;
+ return 0;
+}
+
+static int
+clean_up_cmd (int argc, char **argv)
+{
+ clean_up();
+ return 0;
+}
+
+static int
+quit_cmd (int argc, char **argv)
+{
+ return 1;
+}
+
+static void
+usage(int code)
+{
+ arg_printusage(args, num_args, NULL, "[command]");
+ exit(code);
+}
+
+static int
+do_init(int argc, char **argv)
+{
+ int optind = 0;
+ int ret;
+
+ set_progname (argv[0]);
+
+ if(getarg(args, num_args, argc, argv, &optind) < 0)
+ usage(1);
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ memset(&pr, 0, sizeof(pr));
+ ret = krb_get_default_principal(pr.name, pr.instance, default_realm);
+ if(ret < 0)
+ errx(1, "Can't figure out default principal");
+ if(pr.instance[0] == '\0')
+ strlcpy(pr.instance, "admin", sizeof(pr.instance));
+ if(principal) {
+ if(username)
+ warnx("Ignoring username when principal is given");
+ ret = krb_parse_name(principal, &pr);
+ if(ret)
+ errx(1, "%s: %s", principal, krb_get_err_text(ret));
+ if(pr.realm[0] != '\0')
+ strlcpy(default_realm, pr.realm, sizeof(default_realm));
+ } else if(username) {
+ strlcpy(pr.name, username, sizeof(pr.name));
+ strlcpy(pr.instance, "admin", sizeof(pr.instance));
+ }
+
+ if(realm)
+ strlcpy(default_realm, realm, sizeof(default_realm));
+
+ strlcpy(krbrlm, default_realm, sizeof(krbrlm));
+
+ if(pr.realm[0] == '\0')
+ strlcpy(pr.realm, krbrlm, sizeof(pr.realm));
+
+ if (kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm) != KADM_SUCCESS)
+ *krbrlm = '\0';
+
+ if(timeout) {
+ if(set_timeout(timeout) == -1)
+ warnx("bad timespecification `%s'", timeout);
+ } else if(mflag)
+ destroy_timeout = 0;
+
+ if (tflag)
+ destroy_timeout = 0; /* disable timeout */
+ else{
+ char tktstring[128];
+ snprintf(tktstring, sizeof(tktstring), "%s_adm_%d",
+ TKT_ROOT, (int)getpid());
+ krb_set_tkt_string(tktstring);
+ }
+ return optind;
+}
+
+static void
+sigalrm(int sig)
+{
+ if(clean_up())
+ printf("\nTickets destroyed.\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = do_init(argc, argv);
+ if(argc > optind)
+ sl_command(cmds, argc - optind, argv + optind);
+ else {
+ void *data = NULL;
+ signal(SIGALRM, sigalrm);
+ while(sl_command_loop(cmds, "kadmin: ", &data) == 0)
+ alarm(destroy_timeout);
+ }
+ clean_up();
+ exit(0);
+}
+
+static int
+setvals(Kadm_vals *vals, char *string)
+{
+ char realm[REALM_SZ];
+ int status = KADM_SUCCESS;
+
+ memset(vals, 0, sizeof(*vals));
+ memset(realm, 0, sizeof(realm));
+
+ SET_FIELD(KADM_NAME,vals->fields);
+ SET_FIELD(KADM_INST,vals->fields);
+ if ((status = kname_parse(vals->name, vals->instance, realm, string))) {
+ printf("kerberos error: %s\n", krb_get_err_text(status));
+ return status;
+ }
+ if (!realm[0])
+ strlcpy(realm, default_realm, sizeof(realm));
+ if (strcmp(realm, krbrlm)) {
+ strlcpy(krbrlm, realm, sizeof(krbrlm));
+ if ((status = kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm))
+ != KADM_SUCCESS)
+ printf("kadm error for realm %s: %s\n",
+ krbrlm, error_message(status));
+ }
+ if (status)
+ return 1;
+ else
+ return KADM_SUCCESS;
+}
+
+static int
+set_timeout(const char *timespec)
+{
+ int t = parse_time(timespec, "s");
+ if(t == -1)
+ return -1;
+ destroy_timeout = t;
+ return 0;
+}
+
+static int
+set_timeout_cmd(int argc, char **argv)
+{
+ char ts[128];
+ if (argc > 2) {
+ printf("Usage: set_timeout [timeout]\n");
+ return 0;
+ }
+ if(argc == 2) {
+ if(set_timeout(argv[1]) == -1){
+ printf("Bad time specification `%s'\n", argv[1]);
+ return 0;
+ }
+ }
+ if(destroy_timeout == 0)
+ printf("Timeout disabled.\n");
+ else{
+ unparse_time(destroy_timeout, ts, sizeof(ts));
+ printf("Timeout after %s.\n", ts);
+ }
+ return 0;
+}
+
+static int
+change_password(int argc, char **argv)
+{
+ Kadm_vals old, new;
+ int status;
+ char pw_prompt[BUFSIZ];
+
+ char pw[32];
+ int generate_password = 0;
+ int i;
+ int optind = 0;
+ char *user = NULL;
+
+ struct getargs cpw_args[] = {
+ { "random", 'r', arg_flag, NULL, "generate random password" },
+ };
+ i = 0;
+ cpw_args[i++].value = &generate_password;
+
+ if(getarg(cpw_args, sizeof(cpw_args) / sizeof(cpw_args[0]),
+ argc, argv, &optind)){
+ arg_printusage(cpw_args,
+ sizeof(cpw_args) / sizeof(cpw_args[0]),
+ "cpw",
+ "principal");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ printf("Usage: change_password [options] principal\n");
+ return 0;
+ }
+
+ user = argv[0];
+
+ if (setvals(&old, user) != KADM_SUCCESS)
+ return 0;
+
+ new = old;
+
+ SET_FIELD(KADM_DESKEY,new.fields);
+
+ if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return 0;
+
+
+ if (generate_password) {
+ random_password(pw, sizeof(pw), &new.key_low, &new.key_high);
+ } else {
+ /* get the new password */
+ snprintf(pw_prompt, sizeof(pw_prompt),
+ "New password for %s:", user);
+
+ if (get_password(&new.key_low, &new.key_high,
+ pw_prompt, SWAP) != GOOD_PW) {
+ printf("Error reading password; password unchanged\n");
+ return 0;
+ }
+ }
+
+ status = kadm_mod(&old, &new);
+ if (status == KADM_SUCCESS) {
+ printf("Password changed for %s.\n", user);
+ if (generate_password)
+ printf("Password is: %s\n", pw);
+ } else {
+ printf("kadmin: %s\nwhile changing password for %s",
+ error_message(status), user);
+ }
+
+ memset(pw, 0, sizeof(pw));
+ memset(&new, 0, sizeof(new));
+ } else
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (old.name, old.instance, krbrlm));
+ return 0;
+}
+
+static int
+getkey(unsigned char *k)
+{
+ int i, c;
+ for (i = 0; i < 8; i++)
+ {
+ c = getchar();
+ if (c == EOF)
+ return 0;
+ else if (c == '\\')
+ {
+ int oct = -1;
+ scanf("%03o", &oct);
+ if (oct < 0 || oct > 255)
+ return 0;
+ k[i] = oct;
+ }
+ else if (!isalpha(c))
+ return 0;
+ else
+ k[i] = c;
+ }
+ c = getchar();
+ if (c != '\n')
+ return 0;
+ return 1; /* Success */
+}
+
+static void
+printkey(unsigned char *tkey)
+{
+ int j;
+ for(j = 0; j < 8; j++)
+ if(tkey[j] != '\\' && isalpha(tkey[j]) != 0)
+ printf("%c", tkey[j]);
+ else
+ printf("\\%03o",(unsigned char)tkey[j]);
+ printf("\n");
+}
+
+static int
+change_key(int argc, char **argv)
+{
+ Kadm_vals old, new;
+ unsigned char newkey[8];
+ int status;
+
+ if (argc != 2) {
+ printf("Usage: change_key principal-name\n");
+ return 0;
+ }
+
+ if (setvals(&old, argv[1]) != KADM_SUCCESS)
+ return 0;
+
+ new = old;
+
+ SET_FIELD(KADM_DESKEY,new.fields);
+
+ if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return 0;
+
+ /* get the new password */
+ printf("New DES key for %s: ", argv[1]);
+
+ if (getkey(newkey)) {
+ memcpy(&new.key_low, newkey, 4);
+ memcpy(&new.key_high, ((char *)newkey) + 4, 4);
+ printf("Entered key for %s: ", argv[1]);
+ printkey(newkey);
+ memset(newkey, 0, sizeof(newkey));
+
+ status = kadm_mod(&old, &new);
+ if (status == KADM_SUCCESS) {
+ printf("Key changed for %s.\n", argv[1]);
+ } else {
+ printf("kadmin: %s\nwhile changing key for %s",
+ error_message(status), argv[1]);
+ }
+ } else
+ printf("Error reading key; key unchanged\n");
+ memset(&new, 0, sizeof(new));
+ }
+ else
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (old.name, old.instance, krbrlm));
+ return 0;
+}
+
+static int
+change_admin_password(int argc, char **argv)
+{
+ des_cblock newkey;
+ int status;
+ char pword[MAX_KPW_LEN];
+ char *pw_msg;
+
+ alarm(0);
+ if (argc != 1) {
+ printf("Usage: change_admin_password\n");
+ return 0;
+ }
+ if (get_pw_new_pwd(pword, sizeof(pword), &pr, 1) == 0) {
+ des_string_to_key(pword, &newkey);
+ status = kadm_change_pw_plain(newkey, pword, &pw_msg);
+ if(status == KADM_INSECURE_PW)
+ printf("Insecure password: %s\n", pw_msg);
+ else if (status == KADM_SUCCESS)
+ printf("Admin password changed\n");
+ else
+ printf("kadm error: %s\n",error_message(status));
+ memset(newkey, 0, sizeof(newkey));
+ memset(pword, 0, sizeof(pword));
+ }
+ return 0;
+}
+
+void random_password(char*, size_t, u_int32_t*, u_int32_t*);
+
+static int
+add_new_key(int argc, char **argv)
+{
+ int i;
+ char pw_prompt[BUFSIZ];
+ int status;
+ int generate_password = 0;
+ char *password = NULL;
+
+ char *expiration_string = NULL;
+ time_t default_expiration = 0;
+ int expiration_set = 0;
+
+ char *life_string = NULL;
+ time_t default_life = 0;
+ int life_set = 0;
+
+ int attributes = -1;
+ int default_attributes = 0;
+ int attributes_set = 0;
+
+ int optind = 0;
+
+ /* XXX remember to update value assignments below */
+ struct getargs add_args[] = {
+ { "random", 'r', arg_flag, NULL, "generate random password" },
+ { "password", 'p', arg_string, NULL },
+ { "life", 'l', arg_string, NULL, "max ticket life" },
+ { "expiration", 'e', arg_string, NULL, "principal expiration" },
+ { "attributes", 'a', arg_integer, NULL }
+ };
+ i = 0;
+ add_args[i++].value = &generate_password;
+ add_args[i++].value = &password;
+ add_args[i++].value = &life_string;
+ add_args[i++].value = &expiration_string;
+ add_args[i++].value = &attributes;
+
+
+ if(getarg(add_args, sizeof(add_args) / sizeof(add_args[0]),
+ argc, argv, &optind)){
+ arg_printusage(add_args,
+ sizeof(add_args) / sizeof(add_args[0]),
+ "add",
+ "principal ...");
+ return 0;
+ }
+
+ if(expiration_string) {
+ default_expiration = parse_expdate(expiration_string);
+ if(default_expiration < 0)
+ warnx("Unknown expiration date `%s'", expiration_string);
+ else
+ expiration_set = 1;
+ }
+ if(life_string) {
+ time_t t = parse_time(life_string, "hour");
+ if(t == -1)
+ warnx("Unknown lifetime `%s'", life_string);
+ else {
+ default_life = krb_time_to_life(0, t);
+ life_set = 1;
+ }
+ }
+ if(attributes != -1) {
+ default_attributes = attributes;
+ attributes_set = 1;
+ }
+
+
+ {
+ char default_name[ANAME_SZ + INST_SZ + 1];
+ char old_default[INST_SZ + 1] = "";
+ Kadm_vals new, default_vals;
+ char pw[32];
+ u_char fields[4];
+
+ for(i = optind; i < argc; i++) {
+ if (setvals(&new, argv[i]) != KADM_SUCCESS)
+ return 0;
+ SET_FIELD(KADM_EXPDATE, new.fields);
+ SET_FIELD(KADM_ATTR, new.fields);
+ SET_FIELD(KADM_MAXLIFE, new.fields);
+ SET_FIELD(KADM_DESKEY, new.fields);
+
+ if (princ_exists(new.name, new.instance, krbrlm) == PE_YES) {
+ printf("kadmin: Principal %s already exists.\n", argv[i]);
+ continue;
+ }
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return 0;
+
+ snprintf (default_name, sizeof(default_name),
+ "default.%s", new.instance);
+ if(strcmp(old_default, default_name) != 0) {
+ memset(fields, 0, sizeof(fields));
+ SET_FIELD(KADM_NAME, fields);
+ SET_FIELD(KADM_INST, fields);
+ SET_FIELD(KADM_EXPDATE, fields);
+ SET_FIELD(KADM_ATTR, fields);
+ SET_FIELD(KADM_MAXLIFE, fields);
+ if (setvals(&default_vals, default_name) != KADM_SUCCESS)
+ return 0;
+
+ if (kadm_get(&default_vals, fields) != KADM_SUCCESS) {
+ /* no such entry, try just `default' */
+ if (setvals(&default_vals, "default") != KADM_SUCCESS)
+ continue;
+ if ((status = kadm_get(&default_vals, fields)) != KADM_SUCCESS) {
+ warnx ("kadm error: %s", error_message(status));
+ break; /* no point in continuing */
+ }
+ }
+
+ if (default_vals.max_life == 255) /* Defaults not set! */ {
+ /* This is the default maximum lifetime for new principals. */
+ if (strcmp(new.instance, "admin") == 0)
+ default_vals.max_life = 1 + (CLOCK_SKEW/(5*60)); /* 5+5 minutes */
+ else if (strcmp(new.instance, "root") == 0)
+ default_vals.max_life = 96; /* 8 hours */
+ else if (krb_life_to_time(0, 162) >= 24*60*60)
+ default_vals.max_life = 162; /* ca 100 hours */
+ else
+ default_vals.max_life = 255; /* ca 21 hours (maximum) */
+
+ /* Also fix expiration date. */
+ {
+ time_t now;
+ struct tm tm;
+
+ now = time(0);
+ tm = *gmtime(&now);
+ if (strcmp(new.name, "rcmd") == 0 ||
+ strcmp(new.name, "ftp") == 0 ||
+ strcmp(new.name, "pop") == 0)
+ tm.tm_year += 5;
+ else
+ tm.tm_year += 2;
+ default_vals.exp_date = mktime(&tm);
+ }
+ default_vals.attributes = default_vals.attributes;
+ }
+ if(!life_set)
+ default_life = default_vals.max_life;
+ if(!expiration_set)
+ default_expiration = default_vals.exp_date;
+ if(!attributes_set)
+ default_attributes = default_vals.attributes;
+ }
+
+ new.max_life = default_life;
+ new.exp_date = default_expiration;
+ new.attributes = default_attributes;
+ if(!life_set)
+ get_maxlife(&new);
+ if(!attributes_set)
+ get_attr(&new);
+ if(!expiration_set)
+ get_expdate(&new);
+
+ if(generate_password) {
+ random_password(pw, sizeof(pw), &new.key_low, &new.key_high);
+ } else if (password == NULL) {
+ /* get the new password */
+ snprintf(pw_prompt, sizeof(pw_prompt), "Password for %s:",
+ argv[i]);
+
+ if (get_password(&new.key_low, &new.key_high,
+ pw_prompt, SWAP) != GOOD_PW) {
+ printf("Error reading password: %s not added\n", argv[i]);
+ memset(&new, 0, sizeof(new));
+ return 0;
+ }
+ } else {
+ passwd_to_lowhigh (&new.key_low, &new.key_high, password, SWAP);
+ memset (password, 0, strlen(password));
+ }
+
+ status = kadm_add(&new);
+ if (status == KADM_SUCCESS) {
+ printf("%s added to database", argv[i]);
+ if (generate_password)
+ printf (" with password `%s'", pw);
+ printf (".\n");
+ } else
+ printf("kadm error: %s\n",error_message(status));
+
+ memset(pw, 0, sizeof(pw));
+ memset(&new, 0, sizeof(new));
+ }
+ }
+
+ return 0;
+}
+
+static int
+del_entry(int argc, char **argv)
+{
+ int status;
+ Kadm_vals vals;
+ int i;
+
+ if (argc < 2) {
+ printf("Usage: delete principal...\n");
+ return 0;
+ }
+
+ for(i = 1; i < argc; i++) {
+ if (setvals(&vals, argv[i]) != KADM_SUCCESS)
+ return 0;
+
+ if (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return 0;
+
+ if ((status = kadm_del(&vals)) == KADM_SUCCESS)
+ printf("%s removed from database.\n", argv[i]);
+ else
+ printf("kadm error: %s\n",error_message(status));
+ }
+ else
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (vals.name, vals.instance, krbrlm));
+ }
+ return 0;
+}
+
+static int
+get_entry(int argc, char **argv)
+{
+ int status;
+ u_char fields[4];
+ Kadm_vals vals;
+
+ if (argc != 2) {
+ printf("Usage: get_entry username\n");
+ return 0;
+ }
+
+ memset(fields, 0, sizeof(fields));
+
+ SET_FIELD(KADM_NAME,fields);
+ SET_FIELD(KADM_INST,fields);
+ SET_FIELD(KADM_EXPDATE,fields);
+ SET_FIELD(KADM_ATTR,fields);
+ SET_FIELD(KADM_MAXLIFE,fields);
+#if 0
+ SET_FIELD(KADM_DESKEY,fields);
+#endif
+#ifdef EXTENDED_KADM
+ SET_FIELD(KADM_MODDATE, fields);
+ SET_FIELD(KADM_MODNAME, fields);
+ SET_FIELD(KADM_MODINST, fields);
+ SET_FIELD(KADM_KVNO, fields);
+#endif
+
+ if (setvals(&vals, argv[1]) != KADM_SUCCESS)
+ return 0;
+
+
+ if (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return 0;
+
+ if ((status = kadm_get(&vals, fields)) == KADM_SUCCESS)
+ prin_vals(&vals);
+ else
+ printf("kadm error: %s\n",error_message(status));
+ }
+ else
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (vals.name, vals.instance, krbrlm));
+ return 0;
+}
+
+static int
+mod_entry(int argc, char **argv)
+{
+ int status;
+ u_char fields[4];
+ Kadm_vals ovals, nvals;
+ int i;
+
+ char *expiration_string = NULL;
+ time_t default_expiration = 0;
+ int expiration_set = 0;
+
+ char *life_string = NULL;
+ time_t default_life = 0;
+ int life_set = 0;
+
+ int attributes = -1;
+ int default_attributes = 0;
+ int attributes_set = 0;
+
+ int optind = 0;
+
+ /* XXX remember to update value assignments below */
+ struct getargs mod_args[] = {
+ { "life", 'l', arg_string, NULL, "max ticket life" },
+ { "expiration", 'e', arg_string, NULL, "principal expiration" },
+ { "attributes", 'a', arg_integer, NULL }
+ };
+ i = 0;
+ mod_args[i++].value = &life_string;
+ mod_args[i++].value = &expiration_string;
+ mod_args[i++].value = &attributes;
+
+
+ if(getarg(mod_args, sizeof(mod_args) / sizeof(mod_args[0]),
+ argc, argv, &optind)){
+ arg_printusage(mod_args,
+ sizeof(mod_args) / sizeof(mod_args[0]),
+ "mod",
+ "principal ...");
+ return 0;
+ }
+
+ if(expiration_string) {
+ default_expiration = parse_expdate(expiration_string);
+ if(default_expiration < 0)
+ warnx("Unknown expiration date `%s'", expiration_string);
+ else
+ expiration_set = 1;
+ }
+ if(life_string) {
+ time_t t = parse_time(life_string, "hour");
+ if(t == -1)
+ warnx("Unknown lifetime `%s'", life_string);
+ else {
+ default_life = krb_time_to_life(0, t);
+ life_set = 1;
+ }
+ }
+ if(attributes != -1) {
+ default_attributes = attributes;
+ attributes_set = 1;
+ }
+
+
+ for(i = optind; i < argc; i++) {
+
+ memset(fields, 0, sizeof(fields));
+
+ SET_FIELD(KADM_NAME,fields);
+ SET_FIELD(KADM_INST,fields);
+ SET_FIELD(KADM_EXPDATE,fields);
+ SET_FIELD(KADM_ATTR,fields);
+ SET_FIELD(KADM_MAXLIFE,fields);
+
+ if (setvals(&ovals, argv[i]) != KADM_SUCCESS)
+ return 0;
+
+ nvals = ovals;
+
+ if (princ_exists(ovals.name, ovals.instance, krbrlm) == PE_NO) {
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (ovals.name, ovals.instance, krbrlm));
+ return 0;
+ }
+
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return 0;
+
+ if ((status = kadm_get(&ovals, fields)) != KADM_SUCCESS) {
+ printf("[ unable to retrieve current settings: %s ]\n",
+ error_message(status));
+ nvals.max_life = DEFAULT_TKT_LIFE;
+ nvals.exp_date = 0;
+ nvals.attributes = 0;
+ } else {
+ nvals.max_life = ovals.max_life;
+ nvals.exp_date = ovals.exp_date;
+ nvals.attributes = ovals.attributes;
+ }
+
+ if(life_set) {
+ nvals.max_life = default_life;
+ SET_FIELD(KADM_MAXLIFE, nvals.fields);
+ } else
+ get_maxlife(&nvals);
+ if(attributes_set) {
+ nvals.attributes = default_attributes;
+ SET_FIELD(KADM_ATTR, nvals.fields);
+ } else
+ get_attr(&nvals);
+ if(expiration_set) {
+ nvals.exp_date = default_expiration;
+ SET_FIELD(KADM_EXPDATE, nvals.fields);
+ } else
+ get_expdate(&nvals);
+
+ if (IS_FIELD(KADM_MAXLIFE, nvals.fields) ||
+ IS_FIELD(KADM_ATTR, nvals.fields) ||
+ IS_FIELD(KADM_EXPDATE, nvals.fields)) {
+ if ((status = kadm_mod(&ovals, &nvals)) != KADM_SUCCESS) {
+ printf("kadm error: %s\n",error_message(status));
+ goto out;
+ }
+ if ((status = kadm_get(&ovals, fields)) != KADM_SUCCESS) {
+ printf("kadm error: %s\n",error_message(status));
+ goto out;
+ }
+ }
+ prin_vals(&ovals);
+ }
+
+out:
+ return 0;
+}
+
+static int
+help(int argc, char **argv)
+{
+ sl_help (cmds, argc, argv);
+ return 0;
+}
OpenPOWER on IntegriCloud