summaryrefslogtreecommitdiffstats
path: root/eBones/usr.sbin
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1995-01-20 22:38:30 +0000
committerwollman <wollman@FreeBSD.org>1995-01-20 22:38:30 +0000
commit6e5293dd674013674bb5796d47c7982561429b2c (patch)
treec431546cf4eb18f0bbd6833846306e2d56d857ea /eBones/usr.sbin
parent6ba13d9dd9b3776799e712248ccad253c0c72f76 (diff)
downloadFreeBSD-src-6e5293dd674013674bb5796d47c7982561429b2c.zip
FreeBSD-src-6e5293dd674013674bb5796d47c7982561429b2c.tar.gz
Add last piece in fully-functional Kerberos implementation: ksrvutil,
a program to manage /etc/srvtab.
Diffstat (limited to 'eBones/usr.sbin')
-rw-r--r--eBones/usr.sbin/ksrvutil/Makefile10
-rw-r--r--eBones/usr.sbin/ksrvutil/ksrvutil.c580
2 files changed, 590 insertions, 0 deletions
diff --git a/eBones/usr.sbin/ksrvutil/Makefile b/eBones/usr.sbin/ksrvutil/Makefile
new file mode 100644
index 0000000..bdff452
--- /dev/null
+++ b/eBones/usr.sbin/ksrvutil/Makefile
@@ -0,0 +1,10 @@
+# $Id$
+
+PROG= ksrvutil
+SRCS= ksrvutil.c
+CFLAGS+= -I${.CURDIR}/../include -I${.CURDIR}/../libkadm
+LDADD+= -L${KADMOBJDIR} -lkadm -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes \
+ -lcom_err
+NOMAN= #man page installed by ../man
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/ksrvutil/ksrvutil.c b/eBones/usr.sbin/ksrvutil/ksrvutil.c
new file mode 100644
index 0000000..e240759
--- /dev/null
+++ b/eBones/usr.sbin/ksrvutil/ksrvutil.c
@@ -0,0 +1,580 @@
+/*
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * list and update contents of srvtab files
+ */
+
+#ifndef lint
+#if 0
+static char rcsid_ksrvutil_c[] =
+"BonesHeader: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/ksrvutil.c,v 4.1 89/09/26 09:33:49 jtkohl Exp ";
+#endif
+static const char rcsid[] =
+ "$Id$";
+#endif lint
+
+/*
+ * ksrvutil
+ * list and update the contents of srvtab files
+ */
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <kadm.h>
+#include <err.h>
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else /* NOENCRYPTION */
+#define read_long_pw_string des_read_pw_string
+#endif /* NOENCRYPTION */
+int read_long_pw_string();
+
+#define SRVTAB_MODE 0600 /* rw------- */
+#define PAD " "
+#define VNO_HEADER "Version"
+#define VNO_FORMAT "%4d "
+#define KEY_HEADER " Key " /* 17 characters long */
+#define PRINC_HEADER " Principal\n"
+#define PRINC_FORMAT "%s"
+
+extern int errno;
+
+extern void krb_set_tkt_string();
+void leave();
+unsigned short get_mode();
+
+void
+copy_keyfile(progname, keyfile, backup_keyfile)
+ char *progname;
+ char *keyfile;
+ char *backup_keyfile;
+{
+ int keyfile_fd;
+ int backup_keyfile_fd;
+ int keyfile_mode;
+ char buf[BUFSIZ]; /* for copying keyfiles */
+ int rcount; /* for copying keyfiles */
+ int try_again;
+
+ (void) bzero((char *)buf, sizeof(buf));
+
+ do {
+ try_again = FALSE;
+ if ((keyfile_fd = open(keyfile, O_RDONLY, 0)) < 0) {
+ if (errno != ENOENT) {
+ err(1, "unable to read %s", keyfile);
+ }
+ else {
+ try_again = TRUE;
+ if ((keyfile_fd =
+ open(keyfile,
+ O_WRONLY | O_TRUNC | O_CREAT, SRVTAB_MODE)) < 0) {
+ err(1, "unable to create %s", keyfile);
+ }
+ else
+ if (close(keyfile_fd) < 0) {
+ err(1, "failure closing %s", keyfile);
+ }
+ }
+ }
+ } while(try_again);
+
+ keyfile_mode = get_mode(keyfile);
+
+ if ((backup_keyfile_fd =
+ open(backup_keyfile, O_WRONLY | O_TRUNC | O_CREAT,
+ keyfile_mode)) < 0) {
+ err(1, "unable to write %s", backup_keyfile);
+ }
+ do {
+ if ((rcount = read(keyfile_fd, (char *)buf, sizeof(buf))) < 0) {
+ err(1, "error reading %s", keyfile);
+ }
+ if (rcount && (write(backup_keyfile_fd, buf, rcount) != rcount)) {
+ err(1, "error writing %s", backup_keyfile);
+ }
+ } while (rcount);
+ if (close(backup_keyfile_fd) < 0) {
+ err(1, "error closing %s", backup_keyfile);
+ }
+ if (close(keyfile_fd) < 0) {
+ err(1, "error closing %s", keyfile);
+ }
+}
+
+void
+safe_read_stdin(prompt, buf, size)
+ char *prompt;
+ char *buf;
+ int size;
+{
+ (void) printf(prompt);
+ (void) fflush(stdout);
+ (void) bzero(buf, size);
+ if (read(0, buf, size - 1) < 0) {
+ warn("failure reading from stdin");
+ leave((char *)NULL, 1);
+ }
+ fflush(stdin);
+ buf[strlen(buf)-1] = 0;
+}
+
+
+void
+safe_write(progname, filename, fd, buf, len)
+ char *progname;
+ char *filename;
+ int fd;
+ char *buf;
+ int len;
+{
+ if (write(fd, buf, len) != len) {
+ warn("failure writing %s", filename);
+ close(fd);
+ leave("In progress srvtab in this file.", 1);
+ }
+}
+
+int
+yn(string)
+ char *string;
+{
+ char ynbuf[5];
+
+ (void) printf("%s (y,n) [y] ", string);
+ for (;;) {
+ safe_read_stdin("", ynbuf, sizeof(ynbuf));
+
+ if ((ynbuf[0] == 'n') || (ynbuf[0] == 'N'))
+ return(0);
+ else if ((ynbuf[0] == 'y') || (ynbuf[0] == 'Y') || (ynbuf[0] == 0))
+ return(1);
+ else {
+ (void) printf("Please enter 'y' or 'n': ");
+ fflush(stdout);
+ }
+ }
+}
+
+void
+append_srvtab(progname, filename, fd, sname, sinst,
+ srealm, key_vno, key)
+ char *progname;
+ char *filename;
+ int fd;
+ char *sname;
+ char *sinst;
+ char *srealm;
+ unsigned char key_vno;
+ des_cblock key;
+{
+ /* Add one to append null */
+ safe_write(progname, filename, fd, sname, strlen(sname) + 1);
+ safe_write(progname, filename, fd, sinst, strlen(sinst) + 1);
+ safe_write(progname, filename, fd, srealm, strlen(srealm) + 1);
+ safe_write(progname, filename, fd, (char *)&key_vno, 1);
+ safe_write(progname, filename, fd, (char *)key, sizeof(des_cblock));
+ (void) fsync(fd);
+}
+
+unsigned short
+get_mode(filename)
+ char *filename;
+{
+ struct stat statbuf;
+ unsigned short mode;
+
+ (void) bzero((char *)&statbuf, sizeof(statbuf));
+
+ if (stat(filename, &statbuf) < 0)
+ mode = SRVTAB_MODE;
+ else
+ mode = statbuf.st_mode;
+
+ return(mode);
+}
+
+main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ char sname[ANAME_SZ]; /* name of service */
+ char sinst[INST_SZ]; /* instance of service */
+ char srealm[REALM_SZ]; /* realm of service */
+ unsigned char key_vno; /* key version number */
+ int status; /* general purpose error status */
+ des_cblock new_key;
+ des_cblock old_key;
+ char change_tkt[MAXPATHLEN]; /* Ticket to use for key change */
+ char keyfile[MAXPATHLEN]; /* Original keyfile */
+ char work_keyfile[MAXPATHLEN]; /* Working copy of keyfile */
+ char backup_keyfile[MAXPATHLEN]; /* Backup copy of keyfile */
+ unsigned short keyfile_mode; /* Protections on keyfile */
+ int work_keyfile_fd = -1; /* Initialize so that */
+ int backup_keyfile_fd = -1; /* compiler doesn't complain */
+ char local_realm[REALM_SZ]; /* local kerberos realm */
+ int i;
+ int interactive = FALSE;
+ int list = FALSE;
+ int change = FALSE;
+ int add = FALSE;
+ int key = FALSE; /* do we show keys? */
+ int arg_entered = FALSE;
+ int change_this_key = FALSE;
+ char databuf[BUFSIZ];
+ int first_printed = FALSE; /* have we printed the first item? */
+
+ int get_svc_new_key();
+ void get_key_from_password();
+ void print_key();
+ void print_name();
+
+ (void) bzero((char *)sname, sizeof(sname));
+ (void) bzero((char *)sinst, sizeof(sinst));
+ (void) bzero((char *)srealm, sizeof(srealm));
+
+ (void) bzero((char *)change_tkt, sizeof(change_tkt));
+ (void) bzero((char *)keyfile, sizeof(keyfile));
+ (void) bzero((char *)work_keyfile, sizeof(work_keyfile));
+ (void) bzero((char *)backup_keyfile, sizeof(backup_keyfile));
+ (void) bzero((char *)local_realm, sizeof(local_realm));
+
+ (void) sprintf(change_tkt, "/tmp/tkt_ksrvutil.%d", getpid());
+ krb_set_tkt_string(change_tkt);
+
+ /* This is used only as a default for adding keys */
+ if (krb_get_lrealm(local_realm, 1) != KSUCCESS)
+ (void) strcpy(local_realm, KRB_REALM);
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-i") == 0)
+ interactive++;
+ else if (strcmp(argv[i], "-k") == 0)
+ key++;
+ else if (strcmp(argv[i], "list") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ list++;
+ }
+ }
+ else if (strcmp(argv[i], "change") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ change++;
+ }
+ }
+ else if (strcmp(argv[i], "add") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ add++;
+ }
+ }
+ else if (strcmp(argv[i], "-f") == 0) {
+ if (++i == argc)
+ usage();
+ else
+ (void) strcpy(keyfile, argv[i]);
+ }
+ else
+ usage();
+ }
+
+ if (!arg_entered)
+ usage();
+
+ if (!keyfile[0])
+ (void) strcpy(keyfile, KEYFILE);
+
+ (void) strcpy(work_keyfile, keyfile);
+ (void) strcpy(backup_keyfile, keyfile);
+
+ if (change || add) {
+ (void) strcat(work_keyfile, ".work");
+ (void) strcat(backup_keyfile, ".old");
+
+ copy_keyfile(argv[0], keyfile, backup_keyfile);
+ }
+
+ if (add)
+ copy_keyfile(argv[0], backup_keyfile, work_keyfile);
+
+ keyfile_mode = get_mode(keyfile);
+
+ if (change || list) {
+ if ((backup_keyfile_fd = open(backup_keyfile, O_RDONLY, 0)) < 0) {
+ err(1, "unable to read %s", backup_keyfile);
+ }
+ }
+
+ if (change) {
+ if ((work_keyfile_fd =
+ open(work_keyfile, O_WRONLY | O_CREAT | O_TRUNC,
+ SRVTAB_MODE)) < 0) {
+ err(1, "unable to write %s", work_keyfile);
+ }
+ }
+ else if (add) {
+ if ((work_keyfile_fd =
+ open(work_keyfile, O_APPEND | O_WRONLY, SRVTAB_MODE)) < 0) {
+ err(1, "unable to append to %s", work_keyfile);
+ }
+ }
+
+ if (change || list) {
+ while ((getst(backup_keyfile_fd, sname, SNAME_SZ) > 0) &&
+ (getst(backup_keyfile_fd, sinst, INST_SZ) > 0) &&
+ (getst(backup_keyfile_fd, srealm, REALM_SZ) > 0) &&
+ (read(backup_keyfile_fd, &key_vno, 1) > 0) &&
+ (read(backup_keyfile_fd,(char *)old_key,sizeof(old_key)) > 0)) {
+ if (list) {
+ if (!first_printed) {
+ (void) printf(VNO_HEADER);
+ (void) printf(PAD);
+ if (key) {
+ (void) printf(KEY_HEADER);
+ (void) printf(PAD);
+ }
+ (void) printf(PRINC_HEADER);
+ first_printed = 1;
+ }
+ (void) printf(VNO_FORMAT, key_vno);
+ (void) printf(PAD);
+ if (key) {
+ print_key(old_key);
+ (void) printf(PAD);
+ }
+ print_name(sname, sinst, srealm);
+ (void) printf("\n");
+ }
+ else if (change) {
+ (void) printf("\nPrincipal: ");
+ print_name(sname, sinst, srealm);
+ (void) printf("; version %d\n", key_vno);
+ if (interactive)
+ change_this_key = yn("Change this key?");
+ else if (change)
+ change_this_key = 1;
+ else
+ change_this_key = 0;
+
+ if (change_this_key)
+ (void) printf("Changing to version %d.\n", key_vno + 1);
+ else if (change)
+ (void) printf("Not changing this key.\n");
+
+ if (change_this_key) {
+ /*
+ * Pick a new key and determine whether or not
+ * it is safe to change
+ */
+ if ((status =
+ get_svc_new_key(new_key, sname, sinst,
+ srealm, keyfile)) == KADM_SUCCESS)
+ key_vno++;
+ else {
+ (void) bcopy(old_key, new_key, sizeof(new_key));
+ (void) fprintf(stderr, "%s: Key NOT changed: %s\n",
+ argv[0], krb_err_txt[status]);
+ change_this_key = FALSE;
+ }
+ }
+ else
+ (void) bcopy(old_key, new_key, sizeof(new_key));
+ append_srvtab(argv[0], work_keyfile, work_keyfile_fd,
+ sname, sinst, srealm, key_vno, new_key);
+ if (key && change_this_key) {
+ (void) printf("Old key: ");
+ print_key(old_key);
+ (void) printf("; new key: ");
+ print_key(new_key);
+ (void) printf("\n");
+ }
+ if (change_this_key) {
+ if ((status = kadm_change_pw(new_key)) == KADM_SUCCESS) {
+ (void) printf("Key changed.\n");
+ (void) dest_tkt();
+ }
+ else {
+ com_err(argv[0], status,
+ " attempting to change password.");
+ (void) dest_tkt();
+ /* XXX This knows the format of a keyfile */
+ if (lseek(work_keyfile_fd, -9, L_INCR) >= 0) {
+ key_vno--;
+ safe_write(argv[0], work_keyfile,
+ work_keyfile_fd, (char *)&key_vno, 1);
+ safe_write(argv[0], work_keyfile, work_keyfile_fd,
+ (char *)old_key, sizeof(des_cblock));
+ (void) fsync(work_keyfile_fd);
+ (void) fprintf(stderr,"Key NOT changed.\n");
+ }
+ else {
+ warn("unable to revert keyfile");
+ leave("", 1);
+ }
+ }
+ }
+ }
+ bzero((char *)old_key, sizeof(des_cblock));
+ bzero((char *)new_key, sizeof(des_cblock));
+ }
+ }
+ else if (add) {
+ do {
+ do {
+ safe_read_stdin("Name: ", databuf, sizeof(databuf));
+ (void) strncpy(sname, databuf, sizeof(sname) - 1);
+ safe_read_stdin("Instance: ", databuf, sizeof(databuf));
+ (void) strncpy(sinst, databuf, sizeof(sinst) - 1);
+ safe_read_stdin("Realm: ", databuf, sizeof(databuf));
+ (void) strncpy(srealm, databuf, sizeof(srealm) - 1);
+ safe_read_stdin("Version number: ", databuf, sizeof(databuf));
+ key_vno = atoi(databuf);
+ if (!srealm[0])
+ (void) strcpy(srealm, local_realm);
+ (void) printf("New principal: ");
+ print_name(sname, sinst, srealm);
+ (void) printf("; version %d\n", key_vno);
+ } while (!yn("Is this correct?"));
+ get_key_from_password(new_key);
+ if (key) {
+ (void) printf("Key: ");
+ print_key(new_key);
+ (void) printf("\n");
+ }
+ append_srvtab(argv[0], work_keyfile, work_keyfile_fd,
+ sname, sinst, srealm, key_vno, new_key);
+ (void) printf("Key successfully added.\n");
+ } while (yn("Would you like to add another key?"));
+ }
+
+ if (change || list)
+ if (close(backup_keyfile_fd) < 0) {
+ warn("failure closing %s, continuing", backup_keyfile);
+ }
+
+ if (change || add) {
+ if (close(work_keyfile_fd) < 0) {
+ err(1, "failure closing %s", work_keyfile);
+ }
+ if (rename(work_keyfile, keyfile) < 0) {
+ err(1, "failure renaming %s to %s", work_keyfile, keyfile);
+ }
+ (void) chmod(backup_keyfile, keyfile_mode);
+ (void) chmod(keyfile, keyfile_mode);
+ (void) printf("Old keyfile in %s.\n", backup_keyfile);
+ }
+
+ exit(0);
+}
+
+void
+print_key(key)
+ des_cblock key;
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ (void) printf("%02x", key[i]);
+ (void) printf(" ");
+ for (i = 4; i < 8; i++)
+ (void) printf("%02x", key[i]);
+}
+
+void
+print_name(name, inst, realm)
+ char *name;
+ char *inst;
+ char *realm;
+{
+ (void) printf("%s%s%s%s%s", name, inst[0] ? "." : "", inst,
+ realm[0] ? "@" : "", realm);
+}
+
+int
+get_svc_new_key(new_key, sname, sinst, srealm, keyfile)
+ des_cblock new_key;
+ char *sname;
+ char *sinst;
+ char *srealm;
+ char *keyfile;
+{
+ int status = KADM_SUCCESS;
+
+ if (((status = krb_get_svc_in_tkt(sname, sinst, srealm, PWSERV_NAME,
+ KADM_SINST, 1, keyfile)) == KSUCCESS) &&
+ ((status = kadm_init_link("changepw", KRB_MASTER, srealm)) ==
+ KADM_SUCCESS)) {
+#ifdef NOENCRYPTION
+ (void) bzero((char *) new_key, sizeof(des_cblock));
+ new_key[0] = (unsigned char) 1;
+#else /* NOENCRYPTION */
+ (void) des_random_key(new_key);
+#endif /* NOENCRYPTION */
+ return(KADM_SUCCESS);
+ }
+
+ return(status);
+}
+
+void
+get_key_from_password(key)
+ des_cblock key;
+{
+ char password[MAX_KPW_LEN]; /* storage for the password */
+
+ if (read_long_pw_string(password, sizeof(password)-1, "Password: ", 1))
+ leave("Error reading password.", 1);
+
+#ifdef NOENCRYPTION
+ (void) bzero((char *) key, sizeof(des_cblock));
+ key[0] = (unsigned char) 1;
+#else /* NOENCRYPTION */
+ (void) des_string_to_key(password, key);
+#endif /* NOENCRYPTION */
+ (void) bzero((char *)password, sizeof(password));
+}
+
+usage()
+{
+ (void) fprintf(stderr, "Usage: ksrvutil [-f keyfile] [-i] [-k] ");
+ (void) fprintf(stderr, "{list | change | add}\n");
+ (void) fprintf(stderr, " -i causes the program to ask for ");
+ (void) fprintf(stderr, "confirmation before changing keys.\n");
+ (void) fprintf(stderr, " -k causes the key to printed for list or ");
+ (void) fprintf(stderr, "change.\n");
+ exit(1);
+}
+
+void
+leave(str,x)
+char *str;
+int x;
+{
+ if (str)
+ (void) fprintf(stderr, "%s\n", str);
+ (void) dest_tkt();
+ exit(x);
+}
OpenPOWER on IntegriCloud