2 * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
5 * For copying and distribution information, please see the file
8 * This routine changes the Kerberos encryption keys for principals,
9 * i.e., users or services.
11 /* $FreeBSD: src/crypto/kerberosIV/admin/kdb_edit.c,v 1.1.1.3.2.1 2003/02/14 22:37:37 nectar Exp $ */
12 /* $DragonFly: src/crypto/kerberosIV/admin/Attic/kdb_edit.c,v 1.2 2003/06/17 04:24:36 dillon Exp $ */
15 * exit returns 0 ==> success -1 ==> error
20 RCSID("$Id: kdb_edit.c,v 1.28 1999/09/16 20:37:21 assar Exp $");
29 static des_cblock new_key;
34 static char input_name[ANAME_SZ];
35 static char input_instance[INST_SZ];
37 #define MAX_PRINCIPAL 10
38 static Principal principal_data[MAX_PRINCIPAL];
40 static Principal old_principal;
41 static Principal default_princ;
43 static des_cblock master_key;
44 static des_cblock session_key;
45 static des_key_schedule master_key_schedule;
46 static char pw_str[255];
47 static long master_key_version;
52 fprintf(stderr, "Usage: %s [-n]\n", __progname);
57 n_gets(char *buf, int size)
61 ret = fgets(buf, size, stdin);
63 if (ret && (p = strchr(buf, '\n')))
70 change_principal(void)
72 static char temp[255];
76 long temp_long; /* Don't change to int32_t, used by scanf */
79 fprintf(stdout, "\nPrincipal name: ");
81 if (!n_gets(input_name, sizeof(input_name)) || *input_name == '\0')
83 fprintf(stdout, "Instance: ");
85 /* instance can be null */
86 n_gets(input_instance, sizeof(input_instance));
87 j = kerb_get_principal(input_name, input_instance, principal_data,
88 MAX_PRINCIPAL, &more);
90 fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
92 n_gets(temp, sizeof(temp)); /* Default case should work, it didn't */
93 if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
95 /* make a new principal, fill in defaults */
98 strlcpy(principal_data[0].name,
101 strlcpy(principal_data[0].instance,
104 principal_data[0].old = NULL;
105 principal_data[0].exp_date = default_princ.exp_date;
106 if (strcmp(input_instance, "admin") == 0)
107 principal_data[0].max_life = 1 + (CLOCK_SKEW/(5*60)); /*5+5 minutes*/
108 else if (strcmp(input_instance, "root") == 0)
109 principal_data[0].max_life = 96; /* 8 hours */
111 principal_data[0].max_life = default_princ.max_life;
112 principal_data[0].attributes = default_princ.attributes;
113 principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
114 principal_data[0].key_version = 0; /* bumped up later */
116 *principal_data[0].exp_date_txt = '\0';
117 for (i = 0; i < j; i++) {
120 "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
121 principal_data[i].name, principal_data[i].instance,
122 principal_data[i].kdc_key_ver);
128 * copy the existing data so we can use the old values
129 * for the qualifier clause of the replace
131 principal_data[i].old = (char *) &old_principal;
132 memcpy(&old_principal, &principal_data[i],
133 sizeof(old_principal));
134 printf("\nChange password [n] ? ");
135 n_gets(temp, sizeof(temp));
136 if (strcmp("y", temp) && strcmp("Y", temp))
142 placebo_read_pw_string(pw_str, sizeof pw_str,
143 "\nNew Password: ", TRUE);
145 if(des_read_pw_string(pw_str, sizeof pw_str,
146 "\nNew Password: ", TRUE))
149 if ( strcmp(pw_str, "RANDOM") == 0
150 || strcmp(pw_str, "") == 0) {
151 printf("\nRandom password [y] ? ");
152 n_gets(temp, sizeof(temp));
153 if (!strcmp("n", temp) || !strcmp("N", temp)) {
154 /* no, use literal */
156 memset(new_key, 0, sizeof(des_cblock));
159 des_string_to_key(pw_str, &new_key);
161 memset(pw_str, 0, sizeof pw_str); /* "RANDOM" */
164 memset(new_key, 0, sizeof(des_cblock));
167 des_random_key(new_key);
169 memset(pw_str, 0, sizeof pw_str);
171 } else if (!strcmp(pw_str, "NULL")) {
172 printf("\nNull Key [y] ? ");
173 n_gets(temp, sizeof(temp));
174 if (!strcmp("n", temp) || !strcmp("N", temp)) {
175 /* no, use literal */
177 memset(new_key, 0, sizeof(des_cblock));
180 des_string_to_key(pw_str, &new_key);
182 memset(pw_str, 0, sizeof pw_str); /* "NULL" */
185 principal_data[i].key_low = 0;
186 principal_data[i].key_high = 0;
191 memset(new_key, 0, sizeof(des_cblock));
194 des_string_to_key(pw_str, &new_key);
196 memset(pw_str, 0, sizeof pw_str);
199 /* seal it under the kerberos master key */
200 kdb_encrypt_key (&new_key, &new_key,
201 &master_key, master_key_schedule,
203 copy_from_key(new_key,
204 &principal_data[i].key_low,
205 &principal_data[i].key_high);
206 memset(new_key, 0, sizeof(new_key));
208 /* set master key version */
209 principal_data[i].kdc_key_ver =
210 (unsigned char) master_key_version;
211 /* bump key version # */
212 principal_data[i].key_version++;
214 "\nPrincipal's new key version = %d\n",
215 principal_data[i].key_version);
219 /* expiration date */
223 tm = k_localtime(&principal_data[i].exp_date);
224 strftime(d, sizeof(d), "%Y-%m-%d", tm);
226 printf("Expiration date (yyyy-mm-dd) [ %s ] ? ", d);
228 if(n_gets(temp, sizeof(temp)) == NULL) {
229 printf("Invalid date.\n");
233 memset(&edate, 0, sizeof(edate));
234 if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
235 &edate.tm_mon, &edate.tm_mday) != 3) {
236 printf("Invalid date.\n");
239 edate.tm_mon--; /* January is 0, not 1 */
240 edate.tm_hour = 23; /* at the end of the */
241 edate.tm_min = 59; /* specified day */
242 if (krb_check_tm (edate)) {
243 printf("Invalid date.\n");
246 edate.tm_year -= 1900;
247 principal_data[i].exp_date = tm2time (edate, 1);
254 /* maximum lifetime */
255 fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
256 principal_data[i].max_life);
258 while (n_gets(temp, sizeof(temp)) && *temp) {
259 if (sscanf(temp, "%ld", &temp_long) != 1)
261 if (temp_long > 255 || (temp_long < 0)) {
263 fprintf(stdout, "\07\07Invalid, choose 0-255\n");
265 "Max ticket lifetime (*5 minutes) [ %d ] ? ",
266 principal_data[i].max_life);
272 principal_data[i].max_life = (unsigned short) temp_long;
277 fprintf(stdout, "Attributes [ %d ] ? ",
278 principal_data[i].attributes);
280 while (n_gets(temp, sizeof(temp)) && *temp) {
281 if (sscanf(temp, "%ld", &temp_long) != 1)
283 if (temp_long > 65535 || (temp_long < 0)) {
285 fprintf(stdout, "Invalid, choose 0-65535\n");
286 fprintf(stdout, "Attributes [ %d ] ? ",
287 principal_data[i].attributes);
293 principal_data[i].attributes =
294 (unsigned short) temp_long;
299 * remaining fields -- key versions and mod info, should
300 * not be directly manipulated
303 if (kerb_put_principal(&principal_data[i], 1)) {
305 "\nError updating Kerberos database");
307 fprintf(stdout, "Edit O.K.");
310 fprintf(stdout, "Unchanged");
314 memset(&principal_data[i].key_low, 0, 4);
315 memset(&principal_data[i].key_high, 0, 4);
321 fprintf(stdout, "\nThere were more tuples found ");
322 fprintf(stdout, "than there were space for");
331 memset(master_key, 0, sizeof(master_key));
332 memset(session_key, 0, sizeof(session_key));
333 memset(master_key_schedule, 0, sizeof(master_key_schedule));
334 memset(principal_data, 0, sizeof(principal_data));
335 memset(new_key, 0, sizeof(new_key));
336 memset(pw_str, 0, sizeof(pw_str));
340 main(int argc, char **argv)
342 /* Local Declarations */
346 set_progname (argv[0]);
348 while (--argc > 0 && (*++argv)[0] == '-')
349 for (i = 1; argv[0][i] != '\0'; i++) {
350 switch (argv[0][i]) {
363 case 'n': /* read MKEYFILE for master key */
368 warnx ("illegal flag \"%c\"", argv[0][i]);
369 Usage(); /* Give message and die */
373 fprintf(stdout, "Opening database...\n");
377 if (kerb_db_set_name(*argv) != 0)
378 errx (1, "Could not open altername database name");
380 if (kdb_get_master_key ((nflag == 0) ? KDB_GET_PROMPT : 0,
381 &master_key, master_key_schedule) != 0)
382 errx (1, "Couldn't read master key.");
384 if ((master_key_version = kdb_verify_master_key(&master_key,
389 /* lookup the default values */
390 n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
391 &default_princ, 1, &more);
393 errx (1, "Kerberos error on default value lookup, %ld found.", n);
394 fprintf(stdout, "Previous or default values are in [brackets] ,\n");
395 fprintf(stdout, "enter return to leave the same, or new value.\n");
397 while (change_principal()) {