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 $ */
14 * exit returns 0 ==> success -1 ==> error
19 RCSID("$Id: kdb_edit.c,v 1.28 1999/09/16 20:37:21 assar Exp $");
28 static des_cblock new_key;
33 static char input_name[ANAME_SZ];
34 static char input_instance[INST_SZ];
36 #define MAX_PRINCIPAL 10
37 static Principal principal_data[MAX_PRINCIPAL];
39 static Principal old_principal;
40 static Principal default_princ;
42 static des_cblock master_key;
43 static des_cblock session_key;
44 static des_key_schedule master_key_schedule;
45 static char pw_str[255];
46 static long master_key_version;
51 fprintf(stderr, "Usage: %s [-n]\n", __progname);
56 n_gets(char *buf, int size)
60 ret = fgets(buf, size, stdin);
62 if (ret && (p = strchr(buf, '\n')))
69 change_principal(void)
71 static char temp[255];
75 long temp_long; /* Don't change to int32_t, used by scanf */
78 fprintf(stdout, "\nPrincipal name: ");
80 if (!n_gets(input_name, sizeof(input_name)) || *input_name == '\0')
82 fprintf(stdout, "Instance: ");
84 /* instance can be null */
85 n_gets(input_instance, sizeof(input_instance));
86 j = kerb_get_principal(input_name, input_instance, principal_data,
87 MAX_PRINCIPAL, &more);
89 fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
91 n_gets(temp, sizeof(temp)); /* Default case should work, it didn't */
92 if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
94 /* make a new principal, fill in defaults */
97 strlcpy(principal_data[0].name,
100 strlcpy(principal_data[0].instance,
103 principal_data[0].old = NULL;
104 principal_data[0].exp_date = default_princ.exp_date;
105 if (strcmp(input_instance, "admin") == 0)
106 principal_data[0].max_life = 1 + (CLOCK_SKEW/(5*60)); /*5+5 minutes*/
107 else if (strcmp(input_instance, "root") == 0)
108 principal_data[0].max_life = 96; /* 8 hours */
110 principal_data[0].max_life = default_princ.max_life;
111 principal_data[0].attributes = default_princ.attributes;
112 principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
113 principal_data[0].key_version = 0; /* bumped up later */
115 *principal_data[0].exp_date_txt = '\0';
116 for (i = 0; i < j; i++) {
119 "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
120 principal_data[i].name, principal_data[i].instance,
121 principal_data[i].kdc_key_ver);
127 * copy the existing data so we can use the old values
128 * for the qualifier clause of the replace
130 principal_data[i].old = (char *) &old_principal;
131 memcpy(&old_principal, &principal_data[i],
132 sizeof(old_principal));
133 printf("\nChange password [n] ? ");
134 n_gets(temp, sizeof(temp));
135 if (strcmp("y", temp) && strcmp("Y", temp))
141 placebo_read_pw_string(pw_str, sizeof pw_str,
142 "\nNew Password: ", TRUE);
144 if(des_read_pw_string(pw_str, sizeof pw_str,
145 "\nNew Password: ", TRUE))
148 if ( strcmp(pw_str, "RANDOM") == 0
149 || strcmp(pw_str, "") == 0) {
150 printf("\nRandom password [y] ? ");
151 n_gets(temp, sizeof(temp));
152 if (!strcmp("n", temp) || !strcmp("N", temp)) {
153 /* no, use literal */
155 memset(new_key, 0, sizeof(des_cblock));
158 des_string_to_key(pw_str, &new_key);
160 memset(pw_str, 0, sizeof pw_str); /* "RANDOM" */
163 memset(new_key, 0, sizeof(des_cblock));
166 des_random_key(new_key);
168 memset(pw_str, 0, sizeof pw_str);
170 } else if (!strcmp(pw_str, "NULL")) {
171 printf("\nNull Key [y] ? ");
172 n_gets(temp, sizeof(temp));
173 if (!strcmp("n", temp) || !strcmp("N", temp)) {
174 /* no, use literal */
176 memset(new_key, 0, sizeof(des_cblock));
179 des_string_to_key(pw_str, &new_key);
181 memset(pw_str, 0, sizeof pw_str); /* "NULL" */
184 principal_data[i].key_low = 0;
185 principal_data[i].key_high = 0;
190 memset(new_key, 0, sizeof(des_cblock));
193 des_string_to_key(pw_str, &new_key);
195 memset(pw_str, 0, sizeof pw_str);
198 /* seal it under the kerberos master key */
199 kdb_encrypt_key (&new_key, &new_key,
200 &master_key, master_key_schedule,
202 copy_from_key(new_key,
203 &principal_data[i].key_low,
204 &principal_data[i].key_high);
205 memset(new_key, 0, sizeof(new_key));
207 /* set master key version */
208 principal_data[i].kdc_key_ver =
209 (unsigned char) master_key_version;
210 /* bump key version # */
211 principal_data[i].key_version++;
213 "\nPrincipal's new key version = %d\n",
214 principal_data[i].key_version);
218 /* expiration date */
222 tm = k_localtime(&principal_data[i].exp_date);
223 strftime(d, sizeof(d), "%Y-%m-%d", tm);
225 printf("Expiration date (yyyy-mm-dd) [ %s ] ? ", d);
227 if(n_gets(temp, sizeof(temp)) == NULL) {
228 printf("Invalid date.\n");
232 memset(&edate, 0, sizeof(edate));
233 if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
234 &edate.tm_mon, &edate.tm_mday) != 3) {
235 printf("Invalid date.\n");
238 edate.tm_mon--; /* January is 0, not 1 */
239 edate.tm_hour = 23; /* at the end of the */
240 edate.tm_min = 59; /* specified day */
241 if (krb_check_tm (edate)) {
242 printf("Invalid date.\n");
245 edate.tm_year -= 1900;
246 principal_data[i].exp_date = tm2time (edate, 1);
253 /* maximum lifetime */
254 fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
255 principal_data[i].max_life);
257 while (n_gets(temp, sizeof(temp)) && *temp) {
258 if (sscanf(temp, "%ld", &temp_long) != 1)
260 if (temp_long > 255 || (temp_long < 0)) {
262 fprintf(stdout, "\07\07Invalid, choose 0-255\n");
264 "Max ticket lifetime (*5 minutes) [ %d ] ? ",
265 principal_data[i].max_life);
271 principal_data[i].max_life = (unsigned short) temp_long;
276 fprintf(stdout, "Attributes [ %d ] ? ",
277 principal_data[i].attributes);
279 while (n_gets(temp, sizeof(temp)) && *temp) {
280 if (sscanf(temp, "%ld", &temp_long) != 1)
282 if (temp_long > 65535 || (temp_long < 0)) {
284 fprintf(stdout, "Invalid, choose 0-65535\n");
285 fprintf(stdout, "Attributes [ %d ] ? ",
286 principal_data[i].attributes);
292 principal_data[i].attributes =
293 (unsigned short) temp_long;
298 * remaining fields -- key versions and mod info, should
299 * not be directly manipulated
302 if (kerb_put_principal(&principal_data[i], 1)) {
304 "\nError updating Kerberos database");
306 fprintf(stdout, "Edit O.K.");
309 fprintf(stdout, "Unchanged");
313 memset(&principal_data[i].key_low, 0, 4);
314 memset(&principal_data[i].key_high, 0, 4);
320 fprintf(stdout, "\nThere were more tuples found ");
321 fprintf(stdout, "than there were space for");
330 memset(master_key, 0, sizeof(master_key));
331 memset(session_key, 0, sizeof(session_key));
332 memset(master_key_schedule, 0, sizeof(master_key_schedule));
333 memset(principal_data, 0, sizeof(principal_data));
334 memset(new_key, 0, sizeof(new_key));
335 memset(pw_str, 0, sizeof(pw_str));
339 main(int argc, char **argv)
341 /* Local Declarations */
345 set_progname (argv[0]);
347 while (--argc > 0 && (*++argv)[0] == '-')
348 for (i = 1; argv[0][i] != '\0'; i++) {
349 switch (argv[0][i]) {
362 case 'n': /* read MKEYFILE for master key */
367 warnx ("illegal flag \"%c\"", argv[0][i]);
368 Usage(); /* Give message and die */
372 fprintf(stdout, "Opening database...\n");
376 if (kerb_db_set_name(*argv) != 0)
377 errx (1, "Could not open altername database name");
379 if (kdb_get_master_key ((nflag == 0) ? KDB_GET_PROMPT : 0,
380 &master_key, master_key_schedule) != 0)
381 errx (1, "Couldn't read master key.");
383 if ((master_key_version = kdb_verify_master_key(&master_key,
388 /* lookup the default values */
389 n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
390 &default_princ, 1, &more);
392 errx (1, "Kerberos error on default value lookup, %ld found.", n);
393 fprintf(stdout, "Previous or default values are in [brackets] ,\n");
394 fprintf(stdout, "enter return to leave the same, or new value.\n");
396 while (change_principal()) {