freebsd-dev/eBones/usr.sbin/kdb_edit/kdb_edit.c
Geoff Rehmet 60643d379b Initial import of eBones.
(Including all changes for FreeBSD - importing the original eBones distribution
would be too complex at this stage, since I don't have access to Piero's 
CVS.)
(If you want to include eBones in your system, don't forget to include
MAKE_EBONES in /etc/make.conf.)
(This stuff is now also suppable from braae.ru.ac.za.)

Bones originally from MIT SIPB.
Original port to FreeBSD 1.x  by Piero Serini.
Moved to FreeBSD 2.0 by Doug Rabson and Geoff Rehmet.
Nice bug fixes from Doug Rabson.
1994-09-30 14:50:09 +00:00

471 lines
12 KiB
C

/*
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
* of Technology.
* For copying and distribution information, please see the file
* <Copyright.MIT>.
*
* This routine changes the Kerberos encryption keys for principals,
* i.e., users or services.
*
* from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $
* $Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $
*/
/*
* exit returns 0 ==> success -1 ==> error
*/
#ifndef lint
static char rcsid[] =
"$Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $";
#endif lint
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <strings.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include "time.h"
#include <des.h>
#include <krb.h>
#include <krb_db.h>
/* MKEYFILE is now defined in kdc.h */
#include <kdc.h>
extern char *errmsg();
extern int errno;
extern char *strcpy();
void sig_exit();
#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
char prog[32];
char *progname = prog;
int nflag = 0;
int cflag;
int lflag;
int uflag;
int debug;
extern kerb_debug;
Key_schedule KS;
C_Block new_key;
unsigned char *input;
unsigned char *ivec;
int i, j;
int more;
char *in_ptr;
char input_name[ANAME_SZ];
char input_instance[INST_SZ];
char input_string[ANAME_SZ];
#define MAX_PRINCIPAL 10
Principal principal_data[MAX_PRINCIPAL];
static Principal old_principal;
static Principal default_princ;
static C_Block master_key;
static C_Block session_key;
static Key_schedule master_key_schedule;
static char pw_str[255];
static long master_key_version;
/*
* gets replacement
*/
static char * s_gets(char * str, int len)
{
int i;
char *s;
if((s = fgets(str, len, stdin)) == NULL)
return(s);
if(str[i = (strlen(str)-1)] == '\n')
str[i] = '\0';
return(s);
}
main(argc, argv)
int argc;
char *argv[];
{
/* Local Declarations */
long n;
prog[sizeof prog - 1] = '\0'; /* make sure terminated */
strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking
* program */
/* Assume a long is four bytes */
if (sizeof(long) != 4) {
fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog);
exit(-1);
}
/* Assume <=32 signals */
if (NSIG > 32) {
fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
exit(-1);
}
while (--argc > 0 && (*++argv)[0] == '-')
for (i = 1; argv[0][i] != '\0'; i++) {
switch (argv[0][i]) {
/* debug flag */
case 'd':
debug = 1;
continue;
/* debug flag */
case 'l':
kerb_debug |= 1;
continue;
case 'n': /* read MKEYFILE for master key */
nflag = 1;
continue;
default:
fprintf(stderr, "%s: illegal flag \"%c\"\n",
progname, argv[0][i]);
Usage(); /* Give message and die */
}
};
fprintf(stdout, "Opening database...\n");
fflush(stdout);
kerb_init();
if (argc > 0) {
if (kerb_db_set_name(*argv) != 0) {
fprintf(stderr, "Could not open altername database name\n");
exit(1);
}
}
#ifdef notdef
no_core_dumps(); /* diddle signals to avoid core dumps! */
/* ignore whatever is reasonable */
signal(SIGHUP, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
#endif
if (kdb_get_master_key ((nflag == 0),
master_key, master_key_schedule) != 0) {
fprintf (stdout, "Couldn't read master key.\n");
fflush (stdout);
exit (-1);
}
if ((master_key_version = kdb_verify_master_key(master_key,
master_key_schedule,
stdout)) < 0)
exit (-1);
/* lookup the default values */
n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
&default_princ, 1, &more);
if (n != 1) {
fprintf(stderr,
"%s: Kerberos error on default value lookup, %d found.\n",
progname, n);
exit(-1);
}
fprintf(stdout, "Previous or default values are in [brackets] ,\n");
fprintf(stdout, "enter return to leave the same, or new value.\n");
while (change_principal()) {
}
cleanup();
}
change_principal()
{
static char temp[255];
int creating = 0;
int editpw = 0;
int changed = 0;
long temp_long;
int n;
struct tm *tp, edate, *localtime();
long maketime();
fprintf(stdout, "\nPrincipal name: ");
fflush(stdout);
if (!s_gets(input_name, ANAME_SZ-1) || *input_name == '\0')
return 0;
fprintf(stdout, "Instance: ");
fflush(stdout);
/* instance can be null */
s_gets(input_instance, INST_SZ-1);
j = kerb_get_principal(input_name, input_instance, principal_data,
MAX_PRINCIPAL, &more);
if (!j) {
fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
s_gets(temp, sizeof(temp)-1); /* Default case should work, it didn't */
if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
return -1;
/* make a new principal, fill in defaults */
j = 1;
creating = 1;
strcpy(principal_data[0].name, input_name);
strcpy(principal_data[0].instance, input_instance);
principal_data[0].old = NULL;
principal_data[0].exp_date = default_princ.exp_date;
principal_data[0].max_life = default_princ.max_life;
principal_data[0].attributes = default_princ.attributes;
principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
principal_data[0].key_version = 0; /* bumped up later */
}
tp = localtime(&principal_data[0].exp_date);
(void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
for (i = 0; i < j; i++) {
for (;;) {
fprintf(stdout,
"\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
principal_data[i].name, principal_data[i].instance,
principal_data[i].kdc_key_ver);
editpw = 1;
changed = 0;
if (!creating) {
/*
* copy the existing data so we can use the old values
* for the qualifier clause of the replace
*/
principal_data[i].old = (char *) &old_principal;
bcopy(&principal_data[i], &old_principal,
sizeof(old_principal));
printf("\nChange password [n] ? ");
s_gets(temp, sizeof(temp)-1);
if (strcmp("y", temp) && strcmp("Y", temp))
editpw = 0;
}
/* password */
if (editpw) {
#ifdef NOENCRYPTION
placebo_read_pw_string(pw_str, sizeof pw_str,
"\nNew Password: ", TRUE);
#else
des_read_pw_string(pw_str, sizeof pw_str,
"\nNew Password: ", TRUE);
#endif
if (!strcmp(pw_str, "RANDOM")) {
printf("\nRandom password [y] ? ");
s_gets(temp, sizeof(temp)-1);
if (!strcmp("n", temp) || !strcmp("N", temp)) {
/* no, use literal */
#ifdef NOENCRYPTION
bzero(new_key, sizeof(C_Block));
new_key[0] = 127;
#else
string_to_key(pw_str, new_key);
#endif
bzero(pw_str, sizeof pw_str); /* "RANDOM" */
} else {
#ifdef NOENCRYPTION
bzero(new_key, sizeof(C_Block));
new_key[0] = 127;
#else
random_key(new_key);
#endif
bzero(pw_str, sizeof pw_str);
}
} else if (!strcmp(pw_str, "NULL")) {
printf("\nNull Key [y] ? ");
s_gets(temp, sizeof(temp)-1);
if (!strcmp("n", temp) || !strcmp("N", temp)) {
/* no, use literal */
#ifdef NOENCRYPTION
bzero(new_key, sizeof(C_Block));
new_key[0] = 127;
#else
string_to_key(pw_str, new_key);
#endif
bzero(pw_str, sizeof pw_str); /* "NULL" */
} else {
principal_data[i].key_low = 0;
principal_data[i].key_high = 0;
goto null_key;
}
} else {
#ifdef NOENCRYPTION
bzero(new_key, sizeof(C_Block));
new_key[0] = 127;
#else
string_to_key(pw_str,new_key);
#endif
bzero(pw_str, sizeof pw_str);
}
/* seal it under the kerberos master key */
kdb_encrypt_key (new_key, new_key,
master_key, master_key_schedule,
ENCRYPT);
bcopy(new_key, &principal_data[i].key_low, 4);
bcopy(((long *) new_key) + 1,
&principal_data[i].key_high, 4);
bzero(new_key, sizeof(new_key));
null_key:
/* set master key version */
principal_data[i].kdc_key_ver =
(unsigned char) master_key_version;
/* bump key version # */
principal_data[i].key_version++;
fprintf(stdout,
"\nPrincipal's new key version = %d\n",
principal_data[i].key_version);
fflush(stdout);
changed = 1;
}
/* expiration date */
fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
principal_data[i].exp_date_txt);
zaptime(&edate);
while (s_gets(temp, sizeof(temp)-1) && ((n = strlen(temp)) >
sizeof(principal_data[0].exp_date_txt))) {
bad_date:
fprintf(stdout, "\07\07Date Invalid\n");
fprintf(stdout,
"Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
principal_data[i].exp_date_txt);
zaptime(&edate);
}
if (*temp) {
if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
&edate.tm_mon, &edate.tm_mday) != 3)
goto bad_date;
(void) strcpy(principal_data[i].exp_date_txt, temp);
edate.tm_mon--; /* January is 0, not 1 */
edate.tm_hour = 23; /* nearly midnight at the end of the */
edate.tm_min = 59; /* specified day */
if (!(principal_data[i].exp_date = maketime(&edate, 1)))
goto bad_date;
changed = 1;
}
/* maximum lifetime */
fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
principal_data[i].max_life);
while (s_gets(temp, sizeof(temp)-1) && *temp) {
if (sscanf(temp, "%d", &temp_long) != 1)
goto bad_life;
if (temp_long > 255 || (temp_long < 0)) {
bad_life:
fprintf(stdout, "\07\07Invalid, choose 0-255\n");
fprintf(stdout,
"Max ticket lifetime (*5 minutes) [ %d ] ? ",
principal_data[i].max_life);
continue;
}
changed = 1;
/* dont clobber */
principal_data[i].max_life = (unsigned short) temp_long;
break;
}
/* attributes */
fprintf(stdout, "Attributes [ %d ] ? ",
principal_data[i].attributes);
while (s_gets(temp, sizeof(temp)-1) && *temp) {
if (sscanf(temp, "%d", &temp_long) != 1)
goto bad_att;
if (temp_long > 65535 || (temp_long < 0)) {
bad_att:
fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
fprintf(stdout, "Attributes [ %d ] ? ",
principal_data[i].attributes);
continue;
}
changed = 1;
/* dont clobber */
principal_data[i].attributes =
(unsigned short) temp_long;
break;
}
/*
* remaining fields -- key versions and mod info, should
* not be directly manipulated
*/
if (changed) {
if (kerb_put_principal(&principal_data[i], 1)) {
fprintf(stdout,
"\nError updating Kerberos database");
} else {
fprintf(stdout, "Edit O.K.");
}
} else {
fprintf(stdout, "Unchanged");
}
bzero(&principal_data[i].key_low, 4);
bzero(&principal_data[i].key_high, 4);
fflush(stdout);
break;
}
}
if (more) {
fprintf(stdout, "\nThere were more tuples found ");
fprintf(stdout, "than there were space for");
}
return 1;
}
no_core_dumps()
{
signal(SIGQUIT, sig_exit);
signal(SIGILL, sig_exit);
signal(SIGTRAP, sig_exit);
signal(SIGIOT, sig_exit);
signal(SIGEMT, sig_exit);
signal(SIGFPE, sig_exit);
signal(SIGBUS, sig_exit);
signal(SIGSEGV, sig_exit);
signal(SIGSYS, sig_exit);
}
void
sig_exit(sig, code, scp)
int sig, code;
struct sigcontext *scp;
{
cleanup();
fprintf(stderr,
"\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
sig, code, scp->sc_pc);
exit(-1);
}
cleanup()
{
bzero(master_key, sizeof(master_key));
bzero(session_key, sizeof(session_key));
bzero(master_key_schedule, sizeof(master_key_schedule));
bzero(principal_data, sizeof(principal_data));
bzero(new_key, sizeof(new_key));
bzero(pw_str, sizeof(pw_str));
}
Usage()
{
fprintf(stderr, "Usage: %s [-n]\n", progname);
exit(1);
}