source: trunk/third/cns/src/admin/kdb_edit.c @ 8789

Revision 8789, 12.1 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8788, which included commits to RCS files with non-trunk default branches.
Line 
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
12/*
13 * exit returns          0 ==> success -1 ==> error
14 */
15
16#include <mit-copyright.h>
17
18#include <stdio.h>
19#include <signal.h>
20#include <errno.h>
21#include <string.h>
22#include <sys/types.h>
23#include <sys/ioctl.h>
24#include <sys/file.h>
25
26#ifdef NEED_TIME_H
27#include <time.h>
28#endif
29#include <sys/time.h>
30
31#include <des.h>
32#include <krb.h>
33#include <krb_db.h>
34/* MKEYFILE is now defined in kdc.h */
35#include <kdc.h>
36
37extern char *errmsg();
38extern int errno;
39extern char *optarg;
40extern int optind;
41
42void    sig_exit();
43
44#define zaptime(foo) memset((char *)(foo), 0, sizeof(*(foo)))
45
46char    prog[32];
47char   *progname = prog;
48int     nflag = 0;
49int     cflag;
50int     lflag;
51int     uflag;
52int     debug;
53extern  krb_debug;
54#ifndef HAVE_SYS_ERRLIST_DECL
55extern char *sys_errlist[];
56#endif
57
58Key_schedule KS;
59C_Block new_key;
60unsigned char *input;
61
62unsigned char *ivec;
63int     i, j;
64int     more;
65
66char   *in_ptr;
67char    input_name[ANAME_SZ];
68char    input_instance[INST_SZ];
69char    input_string[ANAME_SZ];
70
71#define MAX_PRINCIPAL   10
72Principal principal_data[MAX_PRINCIPAL];
73
74static Principal old_principal;
75static Principal default_princ;
76
77static C_Block master_key;
78static C_Block session_key;
79static Key_schedule master_key_schedule;
80static char pw_str[255];
81static long master_key_version;
82static char *mkeyfile = NULL;
83
84main(argc, argv)
85    int     argc;
86    char   *argv[];
87
88{
89    /* Local Declarations */
90
91    int     opt;
92    long    n;
93
94    prog[sizeof prog - 1] = '\0';       /* make sure terminated */
95    strncpy(prog, argv[0], sizeof prog - 1);    /* salt away invoking
96                                                 * program */
97
98    /* Assume a long is four bytes */
99    if (sizeof(KRB_INT32) != 4) {
100        fprintf(stdout, "%s: size of long is %d.\n", prog, sizeof(KRB_INT32));
101        exit(-1);
102    }
103
104#if 0
105    /* This code has been here for years, but I do not know why.  */
106    /* Assume <=32 signals */
107    if (NSIG > 32) {
108        fprintf(stderr, "%s: warning: more than 32 signals defined.\n", prog);
109    }
110#endif
111
112    while ((opt = getopt (argc, argv, "dk:ln")) != EOF) {
113        switch (opt) {
114        case 'd':
115            /* debug flag */
116            debug = 1;
117            break;
118
119        case 'l':
120            /* debug flag */
121            krb_debug |= 1;
122            break;
123
124        case 'n':
125            /* read MKEYFILE for master key.  */
126            nflag = 1;
127            break;
128
129        case 'k':
130            /* read named file for master key.  */
131            nflag = 1;
132            mkeyfile = optarg;
133            break;
134
135        default:
136            Usage();    /* Give message and die */
137        }
138    }
139
140    fprintf(stdout, "Opening database...\n");
141    fflush(stdout);
142    kerb_init();
143    if (optind < argc) {
144        if (kerb_db_set_name(argv[optind]) != 0) {
145            fprintf(stderr, "Could not open altername database name\n");
146            exit(1);
147        }
148    }
149
150#ifdef  notdef
151    no_core_dumps();            /* diddle signals to avoid core dumps! */
152
153    /* ignore whatever is reasonable */
154    signal(SIGHUP, SIG_IGN);
155    signal(SIGINT, SIG_IGN);
156    signal(SIGTSTP, SIG_IGN);
157
158#endif
159
160    if (kdb_get_master_key_from ((nflag == 0),
161                                 master_key, master_key_schedule, 0,
162                                 mkeyfile) != 0) {
163      fprintf (stdout, "Couldn't read master key.\n");
164      fflush (stdout);
165      exit (-1);
166    }
167
168    if ((master_key_version = kdb_verify_master_key(master_key,
169                                                    master_key_schedule,
170                                                    stdout)) < 0)
171      exit (-1);
172
173    des_init_random_number_generator(master_key);
174
175    /* lookup the default values */
176    n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
177                           &default_princ, 1, &more);
178    if (n != 1) {
179        fprintf(stderr,
180             "%s: Kerberos error on default value lookup, %d found.\n",
181                progname, n);
182        exit(-1);
183    }
184    fprintf(stdout, "Previous or default values are in [brackets] ,\n");
185    fprintf(stdout, "enter return to leave the same, or new value.\n");
186
187    while (change_principal()) {
188    }
189
190    cleanup();
191    exit(0);
192}
193
194change_principal()
195{
196    static char temp[255];
197    int     creating = 0;
198    int     editpw = 0;
199    int     changed = 0;
200    int     temp_int;
201    int     n;
202    time_t  exp_date;
203    struct tm   *tp, edate, *localtime();
204    long        maketime();
205
206    fprintf(stdout, "\nPrincipal name: ");
207    fflush(stdout);
208    if (!gets(input_name) || *input_name == '\0')
209        return 0;
210    fprintf(stdout, "Instance: ");
211    fflush(stdout);
212    /* instance can be null */
213    gets(input_instance);
214    j = kerb_get_principal(input_name, input_instance, principal_data,
215                           MAX_PRINCIPAL, &more);
216    if (!j) {
217        fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
218        gets(temp);             /* Default case should work, it didn't */
219        if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
220            return -1;
221        /* make a new principal, fill in defaults */
222        j = 1;
223        creating = 1;
224        strcpy(principal_data[0].name, input_name);
225        strcpy(principal_data[0].instance, input_instance);
226        principal_data[0].old = NULL;
227        principal_data[0].exp_date = default_princ.exp_date;
228        principal_data[0].max_life = default_princ.max_life;
229        principal_data[0].attributes = default_princ.attributes;
230        principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
231        principal_data[0].key_version = 0; /* bumped up later */
232    }
233    exp_date = principal_data[0].exp_date;
234    tp = localtime(&exp_date);
235    (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
236                   tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
237                   tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
238    for (i = 0; i < j; i++) {
239        for (;;) {
240            fprintf(stdout,
241                    "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
242                    principal_data[i].name, principal_data[i].instance,
243                    principal_data[i].kdc_key_ver);
244            editpw = 1;
245            changed = 0;
246            if (!creating) {
247                /*
248                 * copy the existing data so we can use the old values
249                 * for the qualifier clause of the replace
250                 */
251                principal_data[i].old = (char *) &old_principal;
252                memcpy(&old_principal, &principal_data[i],
253                       sizeof(old_principal));
254                printf("\nChange password [n] ? ");
255                gets(temp);
256                if (strcmp("y", temp) && strcmp("Y", temp))
257                    editpw = 0;
258            }
259            /* password */
260            if (editpw) {
261#ifdef NOENCRYPTION
262                placebo_read_pw_string(pw_str, sizeof pw_str,
263                    "\nNew Password: ", TRUE);
264#else
265                des_read_pw_string(pw_str, sizeof pw_str,
266                    "\nNew Password: ", TRUE);
267#endif
268                if (!strcmp(pw_str, "RANDOM")) {
269                    printf("\nRandom password [y] ? ");
270                    gets(temp);
271                    if (!strcmp("n", temp) || !strcmp("N", temp)) {
272                        /* no, use literal */
273#ifdef NOENCRYPTION
274                        memset(new_key, 0, sizeof(C_Block));
275                        new_key[0] = 127;
276#else
277                        string_to_key(pw_str, new_key);
278#endif
279                        memset(pw_str, 0, sizeof pw_str);       /* "RANDOM" */
280                    } else {
281#ifdef NOENCRYPTION
282                        memset(new_key, 0, sizeof(C_Block));
283                        new_key[0] = 127;
284#else
285                        des_new_random_key(new_key);    /* yes, random */
286#endif
287                        memset(pw_str, 0, sizeof pw_str);
288                    }
289                } else if (!strcmp(pw_str, "NULL")) {
290                    printf("\nNull Key [y] ? ");
291                    gets(temp);
292                    if (!strcmp("n", temp) || !strcmp("N", temp)) {
293                        /* no, use literal */
294#ifdef NOENCRYPTION
295                        memset(new_key, 0, sizeof(C_Block));
296                        new_key[0] = 127;
297#else
298                        string_to_key(pw_str, new_key);
299#endif
300                        memset(pw_str, 0, sizeof pw_str);       /* "NULL" */
301                    } else {
302
303                        principal_data[i].key_low = 0;
304                        principal_data[i].key_high = 0;
305                        goto null_key;
306                    }
307                } else {
308#ifdef NOENCRYPTION
309                    memset(new_key, 0, sizeof(C_Block));
310                    new_key[0] = 127;
311#else
312                    string_to_key(pw_str, new_key);
313#endif
314                    memset(pw_str, 0, sizeof pw_str);
315                }
316
317                /* seal it under the kerberos master key */
318                kdb_encrypt_key (new_key, new_key,
319                                 master_key, master_key_schedule,
320                                 ENCRYPT);
321                memcpy(&principal_data[i].key_low, new_key, sizeof(KRB_INT32));
322                memcpy(&principal_data[i].key_high, ((KRB_INT32 *) new_key) + 1, sizeof(KRB_INT32));
323                memset(new_key, 0, sizeof(new_key));
324        null_key:
325                /* set master key version */
326                principal_data[i].kdc_key_ver =
327                    (unsigned char) master_key_version;
328                /* bump key version # */
329                principal_data[i].key_version++;
330                fprintf(stdout,
331                        "\nPrincipal's new key version = %d\n",
332                        principal_data[i].key_version);
333                fflush(stdout);
334                changed = 1;
335            }
336            /* expiration date */
337            fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
338                    principal_data[i].exp_date_txt);
339            zaptime(&edate);
340            while (gets(temp) && ((n = strlen(temp)) >
341                                  sizeof(principal_data[0].exp_date_txt))) {
342            bad_date:
343                fprintf(stdout, "\07\07Date Invalid\n");
344                fprintf(stdout,
345                        "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
346                        principal_data[i].exp_date_txt);
347                zaptime(&edate);
348            }
349
350            if (*temp) {
351                if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
352                              &edate.tm_mon, &edate.tm_mday) != 3)
353                    goto bad_date;
354                (void) strcpy(principal_data[i].exp_date_txt, temp);
355                edate.tm_mon--;         /* January is 0, not 1 */
356                edate.tm_hour = 23;     /* nearly midnight at the end of the */
357                edate.tm_min = 59;      /* specified day */
358                if (!(principal_data[i].exp_date = maketime(&edate, 1)))
359                    goto bad_date;
360                changed = 1;
361            }
362
363            /* maximum lifetime */
364            fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
365                    principal_data[i].max_life);
366            while (gets(temp) && *temp) {
367                if (sscanf(temp, "%d", &temp_int) != 1)
368                    goto bad_life;
369                if (temp_int > 255 || (temp_int < 0)) {
370                bad_life:
371                    fprintf(stdout, "\07\07Invalid, choose 0-255\n");
372                    fprintf(stdout,
373                            "Max ticket lifetime (*5 minutes) [ %d ] ? ",
374                            principal_data[i].max_life);
375                    continue;
376                }
377                changed = 1;
378                /* dont clobber */
379                principal_data[i].max_life = (unsigned short) temp_int;
380                break;
381            }
382
383            /* attributes */
384            fprintf(stdout, "Attributes [ %d ] ? ",
385                    principal_data[i].attributes);
386            while (gets(temp) && *temp) {
387                if (sscanf(temp, "%d", &temp_int) != 1)
388                    goto bad_att;
389                if (temp_int > 65535 || (temp_int < 0)) {
390                bad_att:
391                    fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
392                    fprintf(stdout, "Attributes [ %d ] ? ",
393                            principal_data[i].attributes);
394                    continue;
395                }
396                changed = 1;
397                /* dont clobber */
398                principal_data[i].attributes =
399                    (unsigned short) temp_int;
400                break;
401            }
402
403            /*
404             * remaining fields -- key versions and mod info, should
405             * not be directly manipulated
406             */
407            if (changed) {
408                if (kerb_put_principal(&principal_data[i], 1)) {
409                    fprintf(stdout,
410                        "\nError updating Kerberos database");
411                } else {
412                    fprintf(stdout, "Edit O.K.");
413                }
414            } else {
415                fprintf(stdout, "Unchanged");
416            }
417
418
419            memset(&principal_data[i].key_low, 0, 4);
420            memset(&principal_data[i].key_high, 0, 4);
421            fflush(stdout);
422            break;
423        }
424    }
425    if (more) {
426        fprintf(stdout, "\nThere were more tuples found ");
427        fprintf(stdout, "than there were space for");
428      }
429    return 1;
430}
431
432
433no_core_dumps()
434{
435
436    signal(SIGQUIT, sig_exit);
437    signal(SIGILL, sig_exit);
438    signal(SIGTRAP, sig_exit);
439    signal(SIGIOT, sig_exit);
440#ifdef SIGEMT
441    signal(SIGEMT, sig_exit);
442#endif
443    signal(SIGFPE, sig_exit);
444#ifdef SIGBUS
445    signal(SIGBUS, sig_exit);
446#endif
447    signal(SIGSEGV, sig_exit);
448#ifdef SIGSYS
449    signal(SIGSYS, sig_exit);
450#endif
451}
452
453void
454sig_exit(sig, code, scp)
455    int     sig, code;
456    struct sigcontext *scp;
457{
458    cleanup();
459
460#if defined(_AIX)
461#if defined(i386)
462    fprintf(stderr, "\nSignal caught, sig = %d code = %d\nexiting", sig, code);
463#else
464    fprintf(stderr,
465        "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
466        sig, code, scp->sc_jmpbuf.jmp_context.iar);
467#endif
468#else /* !_AIX */
469#ifdef NO_SIGCONTEXT
470    fprintf(stderr,
471        "\nSignal caught, sig = %d code = %d \nexiting",
472        sig, code);
473#else
474    fprintf(stderr,
475        "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
476        sig, code, scp->sc_pc);
477#endif
478#endif
479    exit(-1);
480}
481
482
483cleanup()
484{
485
486    memset(master_key, 0, sizeof(master_key));
487    memset(session_key, 0, sizeof(session_key));
488    memset(master_key_schedule, 0, sizeof(master_key_schedule));
489    memset(principal_data, 0, sizeof(principal_data));
490    memset(new_key, 0, sizeof(new_key));
491    memset(pw_str, 0, sizeof(pw_str));
492}
493Usage()
494{
495    fprintf(stderr,
496            "Usage: %s [-n] [-k mkeyfile] [database_pathname]\n",
497            progname);
498    exit(1);
499}
Note: See TracBrowser for help on using the repository browser.