home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / kerberosIV / kdb_edit / kdb_edit.c next >
Encoding:
C/C++ Source or Header  |  1991-03-07  |  11.6 KB  |  477 lines

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