Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / crypto / kerberosIV / admin / kdb_edit.c
1 /*
2  * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
3  * of Technology.
4  *
5  * For copying and distribution information, please see the file
6  * <mit-copyright.h>.
7  *
8  * This routine changes the Kerberos encryption keys for principals,
9  * i.e., users or services. 
10  */
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 $ */
13
14 /*
15  * exit returns          0 ==> success -1 ==> error 
16  */
17
18 #include "adm_locl.h"
19
20 RCSID("$Id: kdb_edit.c,v 1.28 1999/09/16 20:37:21 assar Exp $");
21
22 #ifdef DEBUG
23 extern  kerb_debug;
24 #endif
25
26 static int     nflag = 0;
27 static int     debug;
28
29 static des_cblock new_key;
30
31 static int     i, j;
32 static int     more;
33
34 static char    input_name[ANAME_SZ];
35 static char    input_instance[INST_SZ];
36
37 #define MAX_PRINCIPAL   10
38 static Principal principal_data[MAX_PRINCIPAL];
39
40 static Principal old_principal;
41 static Principal default_princ;
42
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;
48
49 static void
50 Usage(void)
51 {
52     fprintf(stderr, "Usage: %s [-n]\n", __progname);
53     exit(1);
54 }
55
56 static char *
57 n_gets(char *buf, int size)
58 {
59     char *p;
60     char *ret;
61     ret = fgets(buf, size, stdin);
62   
63     if (ret && (p = strchr(buf, '\n')))
64         *p = 0;
65     return ret;
66 }
67
68
69 static int
70 change_principal(void)
71 {
72     static char temp[255];
73     int     creating = 0;
74     int     editpw = 0;
75     int     changed = 0;
76     long    temp_long;          /* Don't change to int32_t, used by scanf */
77     struct tm   edate;
78
79     fprintf(stdout, "\nPrincipal name: ");
80     fflush(stdout);
81     if (!n_gets(input_name, sizeof(input_name)) || *input_name == '\0')
82         return 0;
83     fprintf(stdout, "Instance: ");
84     fflush(stdout);
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);
89     if (!j) {
90         fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
91         fflush(stdout);
92         n_gets(temp, sizeof(temp));             /* Default case should work, it didn't */
93         if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
94             return -1;
95         /* make a new principal, fill in defaults */
96         j = 1;
97         creating = 1;
98         strlcpy(principal_data[0].name,
99                         input_name,
100                         ANAME_SZ);
101         strlcpy(principal_data[0].instance,
102                         input_instance,
103                         INST_SZ);
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 */
110         else
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 */
115     }
116     *principal_data[0].exp_date_txt = '\0';
117     for (i = 0; i < j; i++) {
118         for (;;) {
119             fprintf(stdout,
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);
123             fflush(stdout);
124             editpw = 1;
125             changed = 0;
126             if (!creating) {
127                 /*
128                  * copy the existing data so we can use the old values
129                  * for the qualifier clause of the replace 
130                  */
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))
137                     editpw = 0;
138             }
139             /* password */
140             if (editpw) {
141 #ifdef NOENCRYPTION
142                 placebo_read_pw_string(pw_str, sizeof pw_str,
143                     "\nNew Password: ", TRUE);
144 #else
145                 if(des_read_pw_string(pw_str, sizeof pw_str,
146                         "\nNew Password: ", TRUE))
147                     continue;
148 #endif
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 */
155 #ifdef NOENCRYPTION
156                         memset(new_key, 0, sizeof(des_cblock));
157                         new_key[0] = 127;
158 #else
159                         des_string_to_key(pw_str, &new_key);
160 #endif
161                         memset(pw_str, 0, sizeof pw_str);       /* "RANDOM" */
162                     } else {
163 #ifdef NOENCRYPTION
164                         memset(new_key, 0, sizeof(des_cblock));
165                         new_key[0] = 127;
166 #else
167                         des_random_key(new_key);
168 #endif
169                         memset(pw_str, 0, sizeof pw_str);
170                     }
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 */
176 #ifdef NOENCRYPTION
177                         memset(new_key, 0, sizeof(des_cblock));
178                         new_key[0] = 127;
179 #else
180                         des_string_to_key(pw_str, &new_key);
181 #endif
182                         memset(pw_str, 0, sizeof pw_str);       /* "NULL" */
183                     } else {
184
185                         principal_data[i].key_low = 0;
186                         principal_data[i].key_high = 0;
187                         goto null_key;
188                     }
189                 } else {
190 #ifdef NOENCRYPTION
191                     memset(new_key, 0, sizeof(des_cblock));
192                     new_key[0] = 127;
193 #else
194                     des_string_to_key(pw_str, &new_key);
195 #endif
196                     memset(pw_str, 0, sizeof pw_str);
197                 }
198
199                 /* seal it under the kerberos master key */
200                 kdb_encrypt_key (&new_key, &new_key, 
201                                  &master_key, master_key_schedule,
202                                  DES_ENCRYPT);
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));
207         null_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++;
213                 fprintf(stdout,
214                         "\nPrincipal's new key version = %d\n",
215                         principal_data[i].key_version);
216                 fflush(stdout);
217                 changed = 1;
218             }
219             /* expiration date */
220             {
221                 char d[DATE_SZ];
222                 struct tm *tm;
223                 tm = k_localtime(&principal_data[i].exp_date);
224                 strftime(d, sizeof(d), "%Y-%m-%d", tm);
225                 while(1) {
226                     printf("Expiration date (yyyy-mm-dd) [ %s ] ? ", d);
227                     fflush(stdout);
228                     if(n_gets(temp, sizeof(temp)) == NULL) {
229                         printf("Invalid date.\n");
230                         continue;
231                     }
232                     if (*temp) {
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");
237                             continue;
238                         }
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");
244                             continue;
245                         }
246                         edate.tm_year -= 1900;
247                         principal_data[i].exp_date = tm2time (edate, 1);
248                         changed = 1;
249                     }
250                     break;
251                 }
252             }
253
254             /* maximum lifetime */
255             fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
256                     principal_data[i].max_life);
257             fflush(stdout);
258             while (n_gets(temp, sizeof(temp)) && *temp) {
259                 if (sscanf(temp, "%ld", &temp_long) != 1)
260                     goto bad_life;
261                 if (temp_long > 255 || (temp_long < 0)) {
262                 bad_life:
263                     fprintf(stdout, "\07\07Invalid, choose 0-255\n");
264                     fprintf(stdout,
265                             "Max ticket lifetime (*5 minutes) [ %d ] ? ",
266                             principal_data[i].max_life);
267                     fflush(stdout);
268                     continue;
269                 }
270                 changed = 1;
271                 /* dont clobber */
272                 principal_data[i].max_life = (unsigned short) temp_long;
273                 break;
274             }
275
276             /* attributes */
277             fprintf(stdout, "Attributes [ %d ] ? ",
278                     principal_data[i].attributes);
279             fflush(stdout);
280             while (n_gets(temp, sizeof(temp)) && *temp) {
281                 if (sscanf(temp, "%ld", &temp_long) != 1)
282                     goto bad_att;
283                 if (temp_long > 65535 || (temp_long < 0)) {
284                 bad_att:
285                     fprintf(stdout, "Invalid, choose 0-65535\n");
286                     fprintf(stdout, "Attributes [ %d ] ? ",
287                             principal_data[i].attributes);
288                     fflush(stdout);
289                     continue;
290                 }
291                 changed = 1;
292                 /* dont clobber */
293                 principal_data[i].attributes =
294                     (unsigned short) temp_long;
295                 break;
296             }
297
298             /*
299              * remaining fields -- key versions and mod info, should
300              * not be directly manipulated 
301              */
302             if (changed) {
303                 if (kerb_put_principal(&principal_data[i], 1)) {
304                     fprintf(stdout,
305                         "\nError updating Kerberos database");
306                 } else {
307                     fprintf(stdout, "Edit O.K.");
308                 }
309             } else {
310                 fprintf(stdout, "Unchanged");
311             }
312
313
314             memset(&principal_data[i].key_low, 0, 4);
315             memset(&principal_data[i].key_high, 0, 4);
316             fflush(stdout);
317             break;
318         }
319     }
320     if (more) {
321         fprintf(stdout, "\nThere were more tuples found ");
322         fprintf(stdout, "than there were space for");
323       }
324     return 1;
325 }
326
327 static void
328 cleanup(void)
329 {
330
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));
337 }
338
339 int
340 main(int argc, char **argv)
341 {
342     /* Local Declarations */
343
344     long    n;
345
346     set_progname (argv[0]);
347
348     while (--argc > 0 && (*++argv)[0] == '-')
349         for (i = 1; argv[0][i] != '\0'; i++) {
350             switch (argv[0][i]) {
351
352                 /* debug flag */
353             case 'd':
354                 debug = 1;
355                 continue;
356
357                 /* debug flag */
358 #ifdef DEBUG
359             case 'l':
360                 kerb_debug |= 1;
361                 continue;
362 #endif
363             case 'n':           /* read MKEYFILE for master key */
364                 nflag = 1;
365                 continue;
366
367             default:
368                 warnx ("illegal flag \"%c\"", argv[0][i]);
369                 Usage();        /* Give message and die */
370             }
371         }
372
373     fprintf(stdout, "Opening database...\n");
374     fflush(stdout);
375     kerb_init();
376     if (argc > 0)
377         if (kerb_db_set_name(*argv) != 0)
378             errx (1, "Could not open altername database name");
379
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.");
383
384     if ((master_key_version = kdb_verify_master_key(&master_key,
385                                                     master_key_schedule,
386                                                     stdout)) < 0)
387       return 1;
388
389     /* lookup the default values */
390     n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
391                            &default_princ, 1, &more);
392     if (n != 1)
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");
396
397     while (change_principal()) {
398     }
399
400     cleanup();
401     return 0;
402 }