summaryrefslogtreecommitdiffstats
path: root/crypto/kerberosIV/kadmin
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/kerberosIV/kadmin')
-rw-r--r--crypto/kerberosIV/kadmin/Design.txt23
-rw-r--r--crypto/kerberosIV/kadmin/Makefile.in125
-rw-r--r--crypto/kerberosIV/kadmin/admin_server.c432
-rw-r--r--crypto/kerberosIV/kadmin/kadm_funcs.c411
-rw-r--r--crypto/kerberosIV/kadmin/kadm_locl.h148
-rw-r--r--crypto/kerberosIV/kadmin/kadm_ser_wrap.c213
-rw-r--r--crypto/kerberosIV/kadmin/kadm_server.c198
-rw-r--r--crypto/kerberosIV/kadmin/kadm_server.h66
-rw-r--r--crypto/kerberosIV/kadmin/kadmin.c845
-rw-r--r--crypto/kerberosIV/kadmin/kpasswd.c163
-rw-r--r--crypto/kerberosIV/kadmin/ksrvutil.c601
-rw-r--r--crypto/kerberosIV/kadmin/ksrvutil.h54
-rw-r--r--crypto/kerberosIV/kadmin/ksrvutil_get.c400
-rw-r--r--crypto/kerberosIV/kadmin/new_pwd.c146
-rw-r--r--crypto/kerberosIV/kadmin/pw_check.c87
-rw-r--r--crypto/kerberosIV/kadmin/pw_check.h45
16 files changed, 3957 insertions, 0 deletions
diff --git a/crypto/kerberosIV/kadmin/Design.txt b/crypto/kerberosIV/kadmin/Design.txt
new file mode 100644
index 0000000..7763a04
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/Design.txt
@@ -0,0 +1,23 @@
+// This file attempts to present the internal functioning of the new kerberos
+// admin server and interface..
+
+//
+// The calling side
+//
+
+// Outer interface (programmers interface)
+kadm_mod_entry(vals *old_dat, vals *new_dat) returns (vals *cur_dat)
+ // sends a command telling the server to change all entries which match
+ // old_dat to entries matching new_dat
+ // returns in cur_dat the actual current values of the modified records
+ // implemented with calls to _vals_to_stream, _send_out, _take_in, and
+ // _stream_to_vals, _interpret_ret
+
+// Inner calls
+_vals_to_stream (vals *, unsigned char *)
+ // converts a vals structure to a byte stream for transmission over the net
+
+_stream_to_vals (unsigned char *, vals *)
+ // converts a byte stream recieved into a vals structure
+
+
diff --git a/crypto/kerberosIV/kadmin/Makefile.in b/crypto/kerberosIV/kadmin/Makefile.in
new file mode 100644
index 0000000..947248e
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/Makefile.in
@@ -0,0 +1,125 @@
+# $Id: Makefile.in,v 1.37 1997/05/02 17:50:35 assar Exp $
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+topdir=..
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+LN_S = @LN_S@
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+LD_FLAGS = @LD_FLAGS@
+
+LIB_tgetent = @LIB_tgetent@
+LIB_readline = @LIB_readline@
+LIB_DBM = @LIB_DBM@
+LIBS = @LIBS@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+CRACKLIB = @CRACKLIB@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sbindir = @sbindir@
+transform=@program_transform_name@
+EXECSUFFIX=@EXECSUFFIX@
+
+PROG_BIN = kpasswd$(EXECSUFFIX) \
+ kadmin$(EXECSUFFIX)
+PROG_SBIN = ksrvutil$(EXECSUFFIX)
+PROG_LIBEXEC = kadmind$(EXECSUFFIX)
+PROGS = $(PROG_BIN) $(PROG_SBIN) $(PROG_LIBEXEC)
+
+SOURCES = kpasswd.c kadmin.c kadm_server.c kadm_funcs.c pw_check.c \
+ admin_server.c kadm_ser_wrap.c ksrvutil.c ksrvutil_get.c \
+ new_pwd.c
+
+OBJECTS = kpasswd.o kadmin.o kadm_server.o kadm_funcs.o \
+ admin_server.o kadm_ser_wrap.o ksrvutil.o ksrvutil_get.o \
+ new_pwd.o
+
+all: $(PROGS)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I../include -I$(srcdir) $(CFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(bindir)
+ for x in $(PROG_BIN); do \
+ $(INSTALL_PROGRAM) $$x $(bindir)/`echo $$x | sed '$(transform)'`; \
+ done
+ $(MKINSTALLDIRS) $(sbindir)
+ for x in $(PROG_SBIN); do \
+ $(INSTALL_PROGRAM) $$x $(sbindir)/`echo $$x | sed '$(transform)'`; \
+ done
+ $(MKINSTALLDIRS) $(libexecdir)
+ for x in $(PROG_LIBEXEC); do \
+ $(INSTALL_PROGRAM) $$x $(libexecdir)/`echo $$x | sed '$(transform)'`; \
+ done
+ @rm -f $(prefix)/sbin/kadmin
+
+uninstall:
+ for x in $(PROG_BIN); do \
+ rm -f $(bindir)/`echo $$x | sed '$(transform)'`; \
+ done
+ for x in $(PROG_SBIN); do \
+ rm -f $(sbindir)/`echo $$x | sed '$(transform)'`; \
+ done
+ for x in $(PROG_LIBEXEC); do \
+ rm -f $(libexecdir)/`echo $$x | sed '$(transform)'`; \
+ done
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f *.a *.o $(PROGS)
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *.tab.c *~
+
+realclean: distclean
+ rm -f TAGS
+
+dist: $(DISTFILES)
+ for file in $(DISTFILES); do \
+ ln $$file ../`cat ../.fname`/lib \
+ || cp -p $$file ../`cat ../.fname`/lib; \
+ done
+
+KLIB=-L../lib/kadm -lkadm -L../lib/krb -lkrb -L../lib/des -ldes -L../util/et -lcom_err
+LIBROKEN=-L../lib/roken -lroken
+
+kpasswd$(EXECSUFFIX): kpasswd.o new_pwd.o
+ $(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ kpasswd.o new_pwd.o $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN)
+
+kadmin$(EXECSUFFIX): kadmin.o new_pwd.o
+ $(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ new_pwd.o kadmin.o -L../lib/kadm -lkadm -L../lib/krb -lkrb -L../lib/des -ldes -L../lib/sl -lsl -L../util/et -lcom_err $(LIBROKEN) $(LIBS) $(LIB_readline) $(LIBROKEN)
+
+KADMIND_OBJECTS=kadm_server.o kadm_funcs.o admin_server.o kadm_ser_wrap.o pw_check.o
+
+kadmind$(EXECSUFFIX): $(KADMIND_OBJECTS)
+ $(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(KADMIND_OBJECTS) -L../lib/kdb -lkdb -L../lib/acl -lacl $(KLIB) $(CRACKLIB) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
+
+ksrvutil$(EXECSUFFIX): ksrvutil.o ksrvutil_get.o
+ $(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ ksrvutil.o ksrvutil_get.o $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN)
+
+$(OBJECTS): ../include/config.h
diff --git a/crypto/kerberosIV/kadmin/admin_server.c b/crypto/kerberosIV/kadmin/admin_server.c
new file mode 100644
index 0000000..2654c77
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/admin_server.c
@@ -0,0 +1,432 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+/*
+ * Top-level loop of the kerberos Administration server
+ */
+
+/*
+ admin_server.c
+ this holds the main loop and initialization and cleanup code for the server
+*/
+
+#include "kadm_locl.h"
+
+RCSID("$Id: admin_server.c,v 1.41 1997/05/27 15:52:53 bg Exp $");
+
+/* Almost all procs and such need this, so it is global */
+admin_params prm; /* The command line parameters struct */
+
+/* GLOBAL */
+char *acldir = DEFAULT_ACL_DIR;
+static char krbrlm[REALM_SZ];
+
+static unsigned pidarraysize = 0;
+static int *pidarray = (int *)0;
+
+static int exit_now = 0;
+
+static
+RETSIGTYPE
+doexit(int sig)
+{
+ exit_now = 1;
+ SIGRETURN(0);
+}
+
+static
+RETSIGTYPE
+do_child(int sig)
+{
+ int pid;
+ int i, j;
+
+ int status;
+
+ pid = wait(&status);
+
+ /* Reinstall signal handlers for SysV. Must be done *after* wait */
+ signal(SIGCHLD, do_child);
+
+ for (i = 0; i < pidarraysize; i++)
+ if (pidarray[i] == pid) {
+ /* found it */
+ for (j = i; j < pidarraysize-1; j++)
+ /* copy others down */
+ pidarray[j] = pidarray[j+1];
+ pidarraysize--;
+ if ((WIFEXITED(status) && WEXITSTATUS(status) != 0)
+ || WIFSIGNALED(status))
+ krb_log("child %d: termsig %d, retcode %d", pid,
+ WTERMSIG(status), WEXITSTATUS(status));
+ SIGRETURN(0);
+ }
+ krb_log("child %d not in list: termsig %d, retcode %d", pid,
+ WTERMSIG(status), WEXITSTATUS(status));
+ SIGRETURN(0);
+}
+
+static void
+kill_children(void)
+{
+ int i;
+
+ for (i = 0; i < pidarraysize; i++) {
+ kill(pidarray[i], SIGINT);
+ krb_log("killing child %d", pidarray[i]);
+ }
+}
+
+/* close the system log file */
+static void
+close_syslog(void)
+{
+ krb_log("Shutting down admin server");
+}
+
+static void
+byebye(void) /* say goodnight gracie */
+{
+ printf("Admin Server (kadm server) has completed operation.\n");
+}
+
+static void
+clear_secrets(void)
+{
+ memset(server_parm.master_key, 0, sizeof(server_parm.master_key));
+ memset(server_parm.master_key_schedule, 0,
+ sizeof(server_parm.master_key_schedule));
+ server_parm.master_key_version = 0L;
+}
+
+#ifdef DEBUG
+#define cleanexit(code) {kerb_fini(); return;}
+#endif
+
+#ifndef DEBUG
+static void
+cleanexit(int val)
+{
+ kerb_fini();
+ clear_secrets();
+ exit(val);
+}
+#endif
+
+static void
+process_client(int fd, struct sockaddr_in *who)
+{
+ u_char *dat;
+ int dat_len;
+ u_short dlen;
+ int retval;
+ int on = 1;
+ Principal service;
+ des_cblock skey;
+ int more;
+ int status;
+
+#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)) < 0)
+ krb_log("setsockopt keepalive: %d",errno);
+#endif
+
+ server_parm.recv_addr = *who;
+
+ if (kerb_init()) { /* Open as client */
+ krb_log("can't open krb db");
+ cleanexit(1);
+ }
+ /* need to set service key to changepw.KRB_MASTER */
+
+ status = kerb_get_principal(server_parm.sname, server_parm.sinst, &service,
+ 1, &more);
+ if (status == -1) {
+ /* db locked */
+ int32_t retcode = KADM_DB_INUSE;
+ char *pdat;
+
+ dat_len = KADM_VERSIZE + sizeof(retcode);
+ dat = (u_char *) malloc((unsigned)dat_len);
+ pdat = (char *) dat;
+ retcode = htonl((u_int32_t) KADM_DB_INUSE);
+ strncpy(pdat, KADM_ULOSE, KADM_VERSIZE);
+ memcpy(pdat+KADM_VERSIZE, &retcode, sizeof(retcode));
+ goto out;
+ } else if (!status) {
+ krb_log("no service %s.%s",server_parm.sname, server_parm.sinst);
+ cleanexit(2);
+ }
+
+ copy_to_key(&service.key_low, &service.key_high, skey);
+ memset(&service, 0, sizeof(service));
+ kdb_encrypt_key (&skey, &skey, &server_parm.master_key,
+ server_parm.master_key_schedule, DES_DECRYPT);
+ krb_set_key(skey, 0); /* if error, will show up when
+ rd_req fails */
+ memset(skey, 0, sizeof(skey));
+
+ while (1) {
+ if ((retval = krb_net_read(fd, &dlen, sizeof(u_short))) !=
+ sizeof(u_short)) {
+ if (retval < 0)
+ krb_log("dlen read: %s",error_message(errno));
+ else if (retval)
+ krb_log("short dlen read: %d",retval);
+ close(fd);
+ cleanexit(retval ? 3 : 0);
+ }
+ if (exit_now) {
+ cleanexit(0);
+ }
+ dat_len = ntohs(dlen);
+ dat = (u_char *) malloc(dat_len);
+ if (!dat) {
+ krb_log("malloc: No memory");
+ close(fd);
+ cleanexit(4);
+ }
+ if ((retval = krb_net_read(fd, dat, dat_len)) != dat_len) {
+ if (retval < 0)
+ krb_log("data read: %s",error_message(errno));
+ else
+ krb_log("short read: %d vs. %d", dat_len, retval);
+ close(fd);
+ cleanexit(5);
+ }
+ if (exit_now) {
+ cleanexit(0);
+ }
+ if ((retval = kadm_ser_in(&dat,&dat_len)) != KADM_SUCCESS)
+ krb_log("processing request: %s", error_message(retval));
+
+ /* kadm_ser_in did the processing and returned stuff in
+ dat & dat_len , return the appropriate data */
+
+ out:
+ dlen = htons(dat_len);
+
+ if (krb_net_write(fd, &dlen, sizeof(u_short)) < 0) {
+ krb_log("writing dlen to client: %s",error_message(errno));
+ close(fd);
+ cleanexit(6);
+ }
+
+ if (krb_net_write(fd, dat, dat_len) < 0) {
+ krb_log("writing to client: %s", error_message(errno));
+ close(fd);
+ cleanexit(7);
+ }
+ free(dat);
+ }
+ /*NOTREACHED*/
+}
+
+/*
+kadm_listen
+listen on the admin servers port for a request
+*/
+static int
+kadm_listen(void)
+{
+ int found;
+ int admin_fd;
+ int peer_fd;
+ fd_set mask, readfds;
+ struct sockaddr_in peer;
+ int addrlen;
+ int pid;
+
+ signal(SIGINT, doexit);
+ signal(SIGTERM, doexit);
+ signal(SIGHUP, doexit);
+ signal(SIGQUIT, doexit);
+ signal(SIGPIPE, SIG_IGN); /* get errors on write() */
+ signal(SIGALRM, doexit);
+ signal(SIGCHLD, do_child);
+ if (setsid() < 0)
+ krb_log("setsid() failed");
+
+ if ((admin_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ return KADM_NO_SOCK;
+#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
+ {
+ int one=1;
+ setsockopt(admin_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
+ sizeof(one));
+ }
+#endif
+ if (bind(admin_fd, (struct sockaddr *)&server_parm.admin_addr,
+ sizeof(struct sockaddr_in)) < 0)
+ return KADM_NO_BIND;
+ listen(admin_fd, 1);
+ FD_ZERO(&mask);
+ FD_SET(admin_fd, &mask);
+
+ for (;;) { /* loop nearly forever */
+ if (exit_now) {
+ clear_secrets();
+ kill_children();
+ return(0);
+ }
+ readfds = mask;
+ if ((found = select(admin_fd+1, &readfds, 0,
+ 0, (struct timeval *)0)) == 0)
+ continue; /* no things read */
+ if (found < 0) {
+ if (errno != EINTR)
+ krb_log("select: %s",error_message(errno));
+ continue;
+ }
+ if (FD_ISSET(admin_fd, &readfds)) {
+ /* accept the conn */
+ addrlen = sizeof(peer);
+ if ((peer_fd = accept(admin_fd, (struct sockaddr *)&peer,
+ &addrlen)) < 0) {
+ krb_log("accept: %s",error_message(errno));
+ continue;
+ }
+#ifndef DEBUG
+ /* if you want a sep daemon for each server */
+ if ((pid = fork())) {
+ /* parent */
+ if (pid < 0) {
+ krb_log("fork: %s",error_message(errno));
+ close(peer_fd);
+ continue;
+ }
+ /* fork succeded: keep tabs on child */
+ close(peer_fd);
+ if (pidarray) {
+ pidarray = (int *)realloc(pidarray, ++pidarraysize);
+ pidarray[pidarraysize-1] = pid;
+ } else {
+ pidarray = (int *)malloc(pidarraysize = 1);
+ pidarray[0] = pid;
+ }
+ } else {
+ /* child */
+ close(admin_fd);
+#endif /* DEBUG */
+ /*
+ * If we are multihomed we need to figure out which
+ * local address that is used this time since it is
+ * used in "direction" comparison.
+ */
+ getsockname(peer_fd,
+ (struct sockaddr *)&server_parm.admin_addr,
+ &addrlen);
+ /* do stuff */
+ process_client (peer_fd, &peer);
+#ifndef DEBUG
+ }
+#endif
+ } else {
+ krb_log("something else woke me up!");
+ return(0);
+ }
+ }
+ /*NOTREACHED*/
+}
+
+/*
+** Main does the logical thing, it sets up the database and RPC interface,
+** as well as handling the creation and maintenance of the syslog file...
+*/
+int
+main(int argc, char **argv) /* admin_server main routine */
+{
+ int errval;
+ int c;
+
+ set_progname (argv[0]);
+
+ umask(077); /* Create protected files */
+
+ /* initialize the admin_params structure */
+ prm.sysfile = KADM_SYSLOG; /* default file name */
+ prm.inter = 0;
+
+ memset(krbrlm, 0, sizeof(krbrlm));
+
+ while ((c = getopt(argc, argv, "f:hmnd:a:r:")) != EOF)
+ switch(c) {
+ case 'f': /* Syslog file name change */
+ prm.sysfile = optarg;
+ break;
+ case 'n':
+ prm.inter = 0;
+ break;
+ case 'm':
+ prm.inter = 1;
+ break;
+ case 'a': /* new acl directory */
+ acldir = optarg;
+ break;
+ case 'd':
+ /* put code to deal with alt database place */
+ if ((errval = kerb_db_set_name(optarg)))
+ errx (1, "opening database %s: %s",
+ optarg, error_message(errval));
+ break;
+ case 'r':
+ strncpy(krbrlm, optarg, sizeof(krbrlm) - 1);
+ break;
+ case 'h': /* get help on using admin_server */
+ default:
+ errx(1, "Usage: kadmind [-h] [-n] [-m] [-r realm] [-d dbname] [-f filename] [-a acldir]");
+ }
+
+ if (krbrlm[0] == 0)
+ if (krb_get_lrealm(krbrlm, 0) != KSUCCESS)
+ errx (1, "Unable to get local realm. Fix krb.conf or use -r.");
+
+ printf("KADM Server %s initializing\n",KADM_VERSTR);
+ printf("Please do not use 'kill -9' to kill this job, use a\n");
+ printf("regular kill instead\n\n");
+
+ kset_logfile(prm.sysfile);
+ krb_log("Admin server starting");
+
+ kerb_db_set_lockmode(KERB_DBL_NONBLOCKING);
+ errval = kerb_init(); /* Open the Kerberos database */
+ if (errval) {
+ warnx ("error: kerb_init() failed");
+ close_syslog();
+ byebye();
+ }
+ /* set up the server_parm struct */
+ if ((errval = kadm_ser_init(prm.inter, krbrlm))==KADM_SUCCESS) {
+ kerb_fini(); /* Close the Kerberos database--
+ will re-open later */
+ errval = kadm_listen(); /* listen for calls to server from
+ clients */
+ }
+ if (errval != KADM_SUCCESS) {
+ warnx("error: %s",error_message(errval));
+ kerb_fini(); /* Close if error */
+ }
+ close_syslog(); /* Close syslog file, print
+ closing note */
+ byebye(); /* Say bye bye on the terminal
+ in use */
+ exit(1);
+} /* procedure main */
diff --git a/crypto/kerberosIV/kadmin/kadm_funcs.c b/crypto/kerberosIV/kadmin/kadm_funcs.c
new file mode 100644
index 0000000..34a34b0
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/kadm_funcs.c
@@ -0,0 +1,411 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+*/
+
+/*
+ * Kerberos administration server-side database manipulation routines
+ */
+
+/*
+ * kadm_funcs.c
+ * the actual database manipulation code
+ */
+
+#include "kadm_locl.h"
+
+RCSID("$Id: kadm_funcs.c,v 1.16 1997/05/02 14:28:49 assar Exp $");
+
+static int
+check_access(char *pname, char *pinst, char *prealm, enum acl_types acltype)
+{
+ char checkname[MAX_K_NAME_SZ];
+ char filename[MaxPathLen];
+
+ snprintf(checkname, sizeof(checkname), "%s.%s@%s", pname, pinst, prealm);
+
+ switch (acltype) {
+ case ADDACL:
+ snprintf(filename, sizeof(filename), "%s%s", acldir, ADD_ACL_FILE);
+ break;
+ case GETACL:
+ snprintf(filename, sizeof(filename), "%s%s", acldir, GET_ACL_FILE);
+ break;
+ case MODACL:
+ snprintf(filename, sizeof(filename), "%s%s", acldir, MOD_ACL_FILE);
+ break;
+ case DELACL:
+ snprintf(filename, sizeof(filename), "%s%s", acldir, DEL_ACL_FILE);
+ break;
+ default:
+ krb_log("WARNING in check_access: default case in switch");
+ return 0;
+ }
+ return(acl_check(filename, checkname));
+}
+
+static int
+wildcard(char *str)
+{
+ if (!strcmp(str, WILDCARD_STR))
+ return(1);
+ return(0);
+}
+
+static int
+fail(int code, char *oper, char *princ)
+{
+ krb_log("ERROR: %s: %s (%s)", oper, princ, error_message(code));
+ return code;
+}
+
+#define failadd(code) { fail(code, "ADD", victim); return code; }
+#define faildelete(code) { fail(code, "DELETE", victim); return code; }
+#define failget(code) { fail(code, "GET", victim); return code; }
+#define failmod(code) { fail(code, "MOD", victim); return code; }
+#define failchange(code) { fail(code, "CHANGE", admin); return code; }
+
+int
+kadm_add_entry (char *rname, char *rinstance, char *rrealm,
+ Kadm_vals *valsin, Kadm_vals *valsout)
+{
+ long numfound; /* check how many we get written */
+ int more; /* pointer to more grabbed records */
+ Principal data_i, data_o; /* temporary principal */
+ u_char flags[4];
+ des_cblock newpw;
+ Principal default_princ;
+
+ char admin[MAX_K_NAME_SZ], victim[MAX_K_NAME_SZ];
+
+ strcpy(admin, krb_unparse_name_long(rname, rinstance, rrealm));
+ strcpy(victim, krb_unparse_name_long(valsin->name, valsin->instance, NULL));
+
+ krb_log("ADD: %s by %s", victim, admin);
+
+ if (!check_access(rname, rinstance, rrealm, ADDACL)) {
+ krb_log("WARNING: ADD: %s permission denied", admin);
+ return KADM_UNAUTH;
+ }
+
+ /* Need to check here for "legal" name and instance */
+ if (wildcard(valsin->name) || wildcard(valsin->instance)) {
+ failadd(KADM_ILL_WILDCARD);
+ }
+
+ numfound = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+ if (numfound == -1) {
+ failadd(KADM_DB_INUSE);
+ } else if (numfound != 1) {
+ failadd(KADM_UK_RERROR);
+ }
+
+ kadm_vals_to_prin(valsin->fields, &data_i, valsin);
+ strncpy(data_i.name, valsin->name, ANAME_SZ);
+ strncpy(data_i.instance, valsin->instance, INST_SZ);
+
+ if (!IS_FIELD(KADM_EXPDATE,valsin->fields))
+ data_i.exp_date = default_princ.exp_date;
+ if (!IS_FIELD(KADM_ATTR,valsin->fields))
+ data_i.attributes = default_princ.attributes;
+ if (!IS_FIELD(KADM_MAXLIFE,valsin->fields))
+ data_i.max_life = default_princ.max_life;
+
+ memset(&default_princ, 0, sizeof(default_princ));
+
+ /* convert to host order */
+ data_i.key_low = ntohl(data_i.key_low);
+ data_i.key_high = ntohl(data_i.key_high);
+
+
+ copy_to_key(&data_i.key_low, &data_i.key_high, newpw);
+
+ /* encrypt new key in master key */
+ kdb_encrypt_key (&newpw, &newpw, &server_parm.master_key,
+ server_parm.master_key_schedule, DES_ENCRYPT);
+ copy_from_key(newpw, &data_i.key_low, &data_i.key_high);
+ memset(newpw, 0, sizeof(newpw));
+
+ data_o = data_i;
+ numfound = kerb_get_principal(valsin->name, valsin->instance,
+ &data_o, 1, &more);
+ if (numfound == -1) {
+ failadd(KADM_DB_INUSE);
+ } else if (numfound) {
+ failadd(KADM_INUSE);
+ } else {
+ data_i.key_version++;
+ data_i.kdc_key_ver = server_parm.master_key_version;
+ strncpy(data_i.mod_name, rname, sizeof(data_i.mod_name)-1);
+ strncpy(data_i.mod_instance, rinstance,
+ sizeof(data_i.mod_instance)-1);
+
+ numfound = kerb_put_principal(&data_i, 1);
+ if (numfound == -1) {
+ failadd(KADM_DB_INUSE);
+ } else if (numfound) {
+ failadd(KADM_UK_SERROR);
+ } else {
+ numfound = kerb_get_principal(valsin->name, valsin->instance,
+ &data_o, 1, &more);
+ if ((numfound!=1) || (more!=0)) {
+ failadd(KADM_UK_RERROR);
+ }
+ memset(flags, 0, sizeof(flags));
+ SET_FIELD(KADM_NAME,flags);
+ SET_FIELD(KADM_INST,flags);
+ SET_FIELD(KADM_EXPDATE,flags);
+ SET_FIELD(KADM_ATTR,flags);
+ SET_FIELD(KADM_MAXLIFE,flags);
+ kadm_prin_to_vals(flags, valsout, &data_o);
+ krb_log("ADD: %s added", victim);
+ return KADM_DATA; /* Set all the appropriate fields */
+ }
+ }
+}
+
+int
+kadm_delete_entry (char *rname, char *rinstance, char *rrealm,
+ Kadm_vals *valsin)
+{
+ int ret;
+
+ char admin[MAX_K_NAME_SZ], victim[MAX_K_NAME_SZ];
+
+ strcpy(admin, krb_unparse_name_long(rname, rinstance, rrealm));
+ strcpy(victim, krb_unparse_name_long(valsin->name, valsin->instance, NULL));
+
+ krb_log("DELETE: %s by %s", victim, admin);
+
+ if (!check_access(rname, rinstance, rrealm, DELACL)) {
+ krb_log("WARNING: DELETE: %s permission denied", admin);
+ return KADM_UNAUTH;
+ }
+
+ /* Need to check here for "legal" name and instance */
+ if (wildcard(valsin->name) || wildcard(valsin->instance)) {
+ faildelete(KADM_ILL_WILDCARD);
+ }
+
+#define EQ(V,N,I) (strcmp((V)->name, (N)) == 0 && strcmp((V)->instance, (I)) == 0)
+
+ if(EQ(valsin, PWSERV_NAME, KRB_MASTER) ||
+ EQ(valsin, "K", "M") ||
+ EQ(valsin, "default", "") ||
+ EQ(valsin, KRB_TICKET_GRANTING_TICKET, server_parm.krbrlm)){
+ krb_log("WARNING: DELETE: %s is immutable", victim);
+ return KADM_IMMUTABLE; /* XXX */
+ }
+
+ ret = kerb_delete_principal(valsin->name, valsin->instance);
+ if(ret == -1)
+ return KADM_DB_INUSE; /* XXX */
+ krb_log("DELETE: %s removed.", victim);
+ return KADM_SUCCESS;
+}
+
+
+int
+kadm_get_entry (char *rname, char *rinstance, char *rrealm,
+ Kadm_vals *valsin, u_char *flags, Kadm_vals *valsout)
+{
+ long numfound; /* check how many were returned */
+ int more; /* To point to more name.instances */
+ Principal data_o; /* Data object to hold Principal */
+
+ char admin[MAX_K_NAME_SZ], victim[MAX_K_NAME_SZ];
+
+ strcpy(admin, krb_unparse_name_long(rname, rinstance, rrealm));
+ strcpy(victim, krb_unparse_name_long(valsin->name, valsin->instance, NULL));
+
+ krb_log("GET: %s by %s", victim, admin);
+
+ if (!check_access(rname, rinstance, rrealm, GETACL)) {
+ krb_log("WARNING: GET: %s permission denied", admin);
+ return KADM_UNAUTH;
+ }
+
+ if (wildcard(valsin->name) || wildcard(valsin->instance)) {
+ failget(KADM_ILL_WILDCARD);
+ }
+
+ /* Look up the record in the database */
+ numfound = kerb_get_principal(valsin->name, valsin->instance,
+ &data_o, 1, &more);
+ if (numfound == -1) {
+ failget(KADM_DB_INUSE);
+ } else if (numfound) { /* We got the record, let's return it */
+ kadm_prin_to_vals(flags, valsout, &data_o);
+ krb_log("GET: %s retrieved", victim);
+ return KADM_DATA; /* Set all the appropriate fields */
+ } else {
+ failget(KADM_NOENTRY); /* Else whimper and moan */
+ }
+}
+
+int
+kadm_mod_entry (char *rname, char *rinstance, char *rrealm,
+ Kadm_vals *valsin, Kadm_vals *valsin2, Kadm_vals *valsout)
+{
+ long numfound;
+ int more;
+ Principal data_o, temp_key;
+ u_char fields[4];
+ des_cblock newpw;
+
+ char admin[MAX_K_NAME_SZ], victim[MAX_K_NAME_SZ];
+
+ strcpy(admin, krb_unparse_name_long(rname, rinstance, rrealm));
+ strcpy(victim, krb_unparse_name_long(valsin->name, valsin->instance, NULL));
+
+ krb_log("MOD: %s by %s", victim, admin);
+
+ if (wildcard(valsin->name) || wildcard(valsin->instance)) {
+ failmod(KADM_ILL_WILDCARD);
+ }
+
+ if (!check_access(rname, rinstance, rrealm, MODACL)) {
+ krb_log("WARNING: MOD: %s permission denied", admin);
+ return KADM_UNAUTH;
+ }
+
+ numfound = kerb_get_principal(valsin->name, valsin->instance,
+ &data_o, 1, &more);
+ if (numfound == -1) {
+ failmod(KADM_DB_INUSE);
+ } else if (numfound) {
+ kadm_vals_to_prin(valsin2->fields, &temp_key, valsin2);
+ strncpy(data_o.name, valsin->name, ANAME_SZ);
+ strncpy(data_o.instance, valsin->instance, INST_SZ);
+ if (IS_FIELD(KADM_EXPDATE,valsin2->fields))
+ data_o.exp_date = temp_key.exp_date;
+ if (IS_FIELD(KADM_ATTR,valsin2->fields))
+ data_o.attributes = temp_key.attributes;
+ if (IS_FIELD(KADM_MAXLIFE,valsin2->fields))
+ data_o.max_life = temp_key.max_life;
+ if (IS_FIELD(KADM_DESKEY,valsin2->fields)) {
+ data_o.key_version++;
+ data_o.kdc_key_ver = server_parm.master_key_version;
+
+
+ /* convert to host order */
+ temp_key.key_low = ntohl(temp_key.key_low);
+ temp_key.key_high = ntohl(temp_key.key_high);
+
+
+ copy_to_key(&temp_key.key_low, &temp_key.key_high, newpw);
+
+ /* encrypt new key in master key */
+ kdb_encrypt_key (&newpw, &newpw, &server_parm.master_key,
+ server_parm.master_key_schedule, DES_ENCRYPT);
+ copy_from_key(newpw, &data_o.key_low, &data_o.key_high);
+ memset(newpw, 0, sizeof(newpw));
+ }
+ memset(&temp_key, 0, sizeof(temp_key));
+
+ strncpy(data_o.mod_name, rname, sizeof(data_o.mod_name)-1);
+ strncpy(data_o.mod_instance, rinstance,
+ sizeof(data_o.mod_instance)-1);
+ more = kerb_put_principal(&data_o, 1);
+
+ memset(&data_o, 0, sizeof(data_o));
+
+ if (more == -1) {
+ failmod(KADM_DB_INUSE);
+ } else if (more) {
+ failmod(KADM_UK_SERROR);
+ } else {
+ numfound = kerb_get_principal(valsin->name, valsin->instance,
+ &data_o, 1, &more);
+ if ((more!=0)||(numfound!=1)) {
+ failmod(KADM_UK_RERROR);
+ }
+ memset(fields, 0, sizeof(fields));
+ SET_FIELD(KADM_NAME,fields);
+ SET_FIELD(KADM_INST,fields);
+ SET_FIELD(KADM_EXPDATE,fields);
+ SET_FIELD(KADM_ATTR,fields);
+ SET_FIELD(KADM_MAXLIFE,fields);
+ kadm_prin_to_vals(fields, valsout, &data_o);
+ krb_log("MOD: %s modified", victim);
+ return KADM_DATA; /* Set all the appropriate fields */
+ }
+ }
+ else {
+ failmod(KADM_NOENTRY);
+ }
+}
+
+int
+kadm_change (char *rname, char *rinstance, char *rrealm, unsigned char *newpw)
+{
+ long numfound;
+ int more;
+ Principal data_o;
+ des_cblock local_pw;
+
+ char admin[MAX_K_NAME_SZ];
+
+ strcpy(admin, krb_unparse_name_long(rname, rinstance, rrealm));
+
+ krb_log("CHANGE: %s", admin);
+
+ if (strcmp(server_parm.krbrlm, rrealm)) {
+ krb_log("ERROR: CHANGE: request from wrong realm %s", rrealm);
+ return(KADM_WRONG_REALM);
+ }
+
+ if (wildcard(rname) || wildcard(rinstance)) {
+ failchange(KADM_ILL_WILDCARD);
+ }
+
+ memcpy(local_pw, newpw, sizeof(local_pw));
+
+ /* encrypt new key in master key */
+ kdb_encrypt_key (&local_pw, &local_pw, &server_parm.master_key,
+ server_parm.master_key_schedule, DES_ENCRYPT);
+
+ numfound = kerb_get_principal(rname, rinstance,
+ &data_o, 1, &more);
+ if (numfound == -1) {
+ failchange(KADM_DB_INUSE);
+ } else if (numfound) {
+ copy_from_key(local_pw, &data_o.key_low, &data_o.key_high);
+ data_o.key_version++;
+ data_o.kdc_key_ver = server_parm.master_key_version;
+ strncpy(data_o.mod_name, rname, sizeof(data_o.mod_name)-1);
+ strncpy(data_o.mod_instance, rinstance,
+ sizeof(data_o.mod_instance)-1);
+ more = kerb_put_principal(&data_o, 1);
+ memset(local_pw, 0, sizeof(local_pw));
+ memset(&data_o, 0, sizeof(data_o));
+ if (more == -1) {
+ failchange(KADM_DB_INUSE);
+ } else if (more) {
+ failchange(KADM_UK_SERROR);
+ } else {
+ krb_log("CHANGE: %s's password changed", admin);
+ return KADM_SUCCESS;
+ }
+ }
+ else {
+ failchange(KADM_NOENTRY);
+ }
+}
diff --git a/crypto/kerberosIV/kadmin/kadm_locl.h b/crypto/kerberosIV/kadmin/kadm_locl.h
new file mode 100644
index 0000000..07f9093
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/kadm_locl.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: kadm_locl.h,v 1.25 1997/05/20 18:40:43 bg Exp $ */
+
+#include "config.h"
+#include "protos.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <errno.h>
+#include <signal.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+#include <err.h>
+
+#ifdef SOCKS
+#include <socks.h>
+#endif
+
+#include <roken.h>
+
+#include <com_err.h>
+#include <sl.h>
+
+#include <des.h>
+#include <krb.h>
+#include <krb_err.h>
+#include <krb_db.h>
+#include <kadm.h>
+#include <kadm_err.h>
+#include <acl.h>
+
+#include "kadm_server.h"
+#include "pw_check.h"
+
+/* from libacl */
+/* int acl_check(char *acl, char *principal); */
+
+/* GLOBALS */
+extern char *acldir;
+extern Kadm_Server server_parm;
+
+/* Utils */
+int kadm_change __P((char *, char *, char *, des_cblock));
+int kadm_add_entry __P((char *, char *, char *, Kadm_vals *, Kadm_vals *));
+int kadm_mod_entry __P((char *, char *, char *, Kadm_vals *, Kadm_vals *, Kadm_vals *));
+int kadm_get_entry __P((char *, char *, char *, Kadm_vals *, u_char *, Kadm_vals *));
+int kadm_delete_entry __P((char *, char *, char *, Kadm_vals *));
+int kadm_ser_cpw __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_add __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_mod __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_get __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_delete __P((u_char *, int, AUTH_DAT *, u_char **, int *));
+int kadm_ser_init __P((int inter, char realm[]));
+int kadm_ser_in __P((u_char **, int *));
+
+int get_pw_new_pwd __P((char *pword, int pwlen, krb_principal *pr, int print_realm));
+
+/* cracklib */
+char *FascistCheck __P((char *password, char *path, char **strings));
diff --git a/crypto/kerberosIV/kadmin/kadm_ser_wrap.c b/crypto/kerberosIV/kadmin/kadm_ser_wrap.c
new file mode 100644
index 0000000..6909a9f
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/kadm_ser_wrap.c
@@ -0,0 +1,213 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+/*
+ * Kerberos administration server-side support functions
+ */
+
+/*
+kadm_ser_wrap.c
+unwraps wrapped packets and calls the appropriate server subroutine
+*/
+
+#include "kadm_locl.h"
+
+RCSID("$Id: kadm_ser_wrap.c,v 1.20 1997/05/02 10:29:14 joda Exp $");
+
+/* GLOBAL */
+Kadm_Server server_parm;
+
+/*
+kadm_ser_init
+set up the server_parm structure
+*/
+int
+kadm_ser_init(int inter, char *realm)
+ /* interactive or from file */
+
+{
+ struct hostent *hp;
+ char hostname[MaxHostNameLen];
+
+ init_kadm_err_tbl();
+ init_krb_err_tbl();
+ if (k_gethostname(hostname, sizeof(hostname)))
+ return KADM_NO_HOSTNAME;
+
+ strcpy(server_parm.sname, PWSERV_NAME);
+ strcpy(server_parm.sinst, KRB_MASTER);
+ strcpy(server_parm.krbrlm, realm);
+
+ server_parm.admin_fd = -1;
+ /* setting up the addrs */
+ memset(&server_parm.admin_addr,0, sizeof(server_parm.admin_addr));
+
+ server_parm.admin_addr.sin_port = k_getportbyname (KADM_SNAME,
+ "tcp",
+ htons(751));
+ server_parm.admin_addr.sin_family = AF_INET;
+ if ((hp = gethostbyname(hostname)) == NULL)
+ return KADM_NO_HOSTNAME;
+ server_parm.admin_addr.sin_addr.s_addr = INADDR_ANY;
+ /* setting up the database */
+ if (kdb_get_master_key((inter==1), &server_parm.master_key,
+ server_parm.master_key_schedule) != 0)
+ return KADM_NO_MAST;
+ if ((server_parm.master_key_version =
+ kdb_verify_master_key(&server_parm.master_key,
+ server_parm.master_key_schedule,stderr))<0)
+ return KADM_NO_VERI;
+ return KADM_SUCCESS;
+}
+
+static void errpkt(u_char **dat, int *dat_len, int code)
+{
+ u_int32_t retcode;
+ char *pdat;
+
+ free(*dat); /* free up req */
+ *dat_len = KADM_VERSIZE + sizeof(u_int32_t);
+ *dat = (u_char *) malloc((unsigned)*dat_len);
+ pdat = (char *) *dat;
+ retcode = htonl((u_int32_t) code);
+ strncpy(pdat, KADM_ULOSE, KADM_VERSIZE);
+ memcpy(&pdat[KADM_VERSIZE], &retcode, sizeof(u_int32_t));
+ return;
+}
+
+/*
+kadm_ser_in
+unwrap the data stored in dat, process, and return it.
+*/
+int
+kadm_ser_in(u_char **dat, int *dat_len)
+{
+ u_char *in_st; /* pointer into the sent packet */
+ int in_len,retc; /* where in packet we are, for
+ returns */
+ u_int32_t r_len; /* length of the actual packet */
+ KTEXT_ST authent; /* the authenticator */
+ AUTH_DAT ad; /* who is this, klink */
+ u_int32_t ncksum; /* checksum of encrypted data */
+ des_key_schedule sess_sched; /* our schedule */
+ MSG_DAT msg_st;
+ u_char *retdat, *tmpdat;
+ int retval, retlen;
+
+ if (strncmp(KADM_VERSTR, (char *)*dat, KADM_VERSIZE)) {
+ errpkt(dat, dat_len, KADM_BAD_VER);
+ return KADM_BAD_VER;
+ }
+ in_len = KADM_VERSIZE;
+ /* get the length */
+ if ((retc = stv_long(*dat, &r_len, in_len, *dat_len)) < 0)
+ return KADM_LENGTH_ERROR;
+ in_len += retc;
+ authent.length = *dat_len - r_len - KADM_VERSIZE - sizeof(u_int32_t);
+ memcpy(authent.dat, (char *)(*dat) + in_len, authent.length);
+ authent.mbz = 0;
+ /* service key should be set before here */
+ if ((retc = krb_rd_req(&authent, server_parm.sname, server_parm.sinst,
+ server_parm.recv_addr.sin_addr.s_addr, &ad, NULL)))
+ {
+ errpkt(dat, dat_len,retc + krb_err_base);
+ return retc + krb_err_base;
+ }
+
+#define clr_cli_secrets() {memset(sess_sched, 0, sizeof(sess_sched)); memset(ad.session, 0,sizeof(ad.session));}
+
+ in_st = *dat + *dat_len - r_len;
+#ifdef NOENCRYPTION
+ ncksum = 0;
+#else
+ ncksum = des_quad_cksum((des_cblock *)in_st, (des_cblock *)0, (long) r_len, 0, &ad.session);
+#endif
+ if (ncksum!=ad.checksum) { /* yow, are we correct yet */
+ clr_cli_secrets();
+ errpkt(dat, dat_len,KADM_BAD_CHK);
+ return KADM_BAD_CHK;
+ }
+#ifdef NOENCRYPTION
+ memset(sess_sched, 0, sizeof(sess_sched));
+#else
+ des_key_sched(&ad.session, sess_sched);
+#endif
+ if ((retc = (int) krb_rd_priv(in_st, r_len, sess_sched, &ad.session,
+ &server_parm.recv_addr,
+ &server_parm.admin_addr, &msg_st))) {
+ clr_cli_secrets();
+ errpkt(dat, dat_len,retc + krb_err_base);
+ return retc + krb_err_base;
+ }
+ switch (msg_st.app_data[0]) {
+ case CHANGE_PW:
+ retval = kadm_ser_cpw(msg_st.app_data+1,(int) msg_st.app_length - 1,
+ &ad, &retdat, &retlen);
+ break;
+ case ADD_ENT:
+ retval = kadm_ser_add(msg_st.app_data+1,(int) msg_st.app_length - 1,
+ &ad, &retdat, &retlen);
+ break;
+ case GET_ENT:
+ retval = kadm_ser_get(msg_st.app_data+1,(int) msg_st.app_length - 1,
+ &ad, &retdat, &retlen);
+ break;
+ case MOD_ENT:
+ retval = kadm_ser_mod(msg_st.app_data+1,(int) msg_st.app_length - 1,
+ &ad, &retdat, &retlen);
+ break;
+ case DEL_ENT:
+ retval = kadm_ser_delete(msg_st.app_data + 1, msg_st.app_length - 1,
+ &ad, &retdat, &retlen);
+ break;
+ default:
+ clr_cli_secrets();
+ errpkt(dat, dat_len, KADM_NO_OPCODE);
+ return KADM_NO_OPCODE;
+ }
+ /* Now seal the response back into a priv msg */
+ free(*dat);
+ tmpdat = (u_char *) malloc((unsigned)(retlen + KADM_VERSIZE +
+ sizeof(u_int32_t)));
+ strncpy((char *)tmpdat, KADM_VERSTR, KADM_VERSIZE);
+ retval = htonl((u_int32_t)retval);
+ memcpy((char *)tmpdat + KADM_VERSIZE, &retval, sizeof(u_int32_t));
+ if (retlen) {
+ memcpy((char *)tmpdat + KADM_VERSIZE + sizeof(u_int32_t), retdat,
+ retlen);
+ free(retdat);
+ }
+ /* slop for mk_priv stuff */
+ *dat = (u_char *) malloc((unsigned) (retlen + KADM_VERSIZE +
+ sizeof(u_int32_t) + 200));
+ if ((*dat_len = krb_mk_priv(tmpdat, *dat,
+ (u_int32_t) (retlen + KADM_VERSIZE +
+ sizeof(u_int32_t)),
+ sess_sched,
+ &ad.session, &server_parm.admin_addr,
+ &server_parm.recv_addr)) < 0) {
+ clr_cli_secrets();
+ errpkt(dat, dat_len, KADM_NO_ENCRYPT);
+ return KADM_NO_ENCRYPT;
+ }
+ clr_cli_secrets();
+ return KADM_SUCCESS;
+}
diff --git a/crypto/kerberosIV/kadmin/kadm_server.c b/crypto/kerberosIV/kadmin/kadm_server.c
new file mode 100644
index 0000000..1006f20
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/kadm_server.c
@@ -0,0 +1,198 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+/*
+ * Kerberos administration server-side subroutines
+ */
+
+#include "kadm_locl.h"
+
+RCSID("$Id: kadm_server.c,v 1.9 1997/05/02 10:29:08 joda Exp $");
+
+/*
+kadm_ser_cpw - the server side of the change_password routine
+ recieves : KTEXT, {key}
+ returns : CKSUM, RETCODE
+ acl : caller can change only own password
+
+Replaces the password (i.e. des key) of the caller with that specified in key.
+Returns no actual data from the master server, since this is called by a user
+*/
+int
+kadm_ser_cpw(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen)
+{
+ u_int32_t keylow, keyhigh;
+ des_cblock newkey;
+ int status;
+ int stvlen=0;
+ char *pw_msg;
+ char pword[MAX_KPW_LEN];
+ char *strings[4];
+
+ /* take key off the stream, and change the database */
+
+ if ((status = stv_long(dat, &keyhigh, 0, len)) < 0)
+ return(KADM_LENGTH_ERROR);
+ stvlen=status;
+ if ((status = stv_long(dat, &keylow, stvlen, len)) < 0)
+ return(KADM_LENGTH_ERROR);
+ stvlen+=status;
+
+ if((status = stv_string(dat, pword, stvlen, sizeof(pword), len))<0)
+ pword[0]=0;
+
+ keylow = ntohl(keylow);
+ keyhigh = ntohl(keyhigh);
+ memcpy(((char *)newkey) + 4, &keyhigh, 4);
+ memcpy(newkey, &keylow, 4);
+
+ strings[0] = ad->pname;
+ strings[1] = ad->pinst;
+ strings[2] = ad->prealm;
+ strings[3] = NULL;
+ status = kadm_pw_check(pword, &newkey, &pw_msg, strings);
+
+ memset(pword, 0, sizeof(pword));
+ memset(dat, 0, len);
+
+ if(status != KADM_SUCCESS){
+ *datout=malloc(0);
+ *outlen=vts_string(pw_msg, datout, 0);
+ return status;
+ }
+ *datout=0;
+ *outlen=0;
+
+ return(kadm_change(ad->pname, ad->pinst, ad->prealm, newkey));
+}
+
+
+/*
+kadm_ser_add - the server side of the add_entry routine
+ recieves : KTEXT, {values}
+ returns : CKSUM, RETCODE, {values}
+ acl : su, sms (as alloc)
+
+Adds and entry containing values to the database
+returns the values of the entry, so if you leave certain fields blank you will
+ be able to determine the default values they are set to
+*/
+int
+kadm_ser_add(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen)
+{
+ Kadm_vals values, retvals;
+ long status;
+
+ if ((status = stream_to_vals(dat, &values, len)) < 0)
+ return(KADM_LENGTH_ERROR);
+ if ((status = kadm_add_entry(ad->pname, ad->pinst, ad->prealm,
+ &values, &retvals)) == KADM_DATA) {
+ *outlen = vals_to_stream(&retvals,datout);
+ return KADM_SUCCESS;
+ } else {
+ *outlen = 0;
+ return status;
+ }
+}
+
+/*
+kadm_ser_mod - the server side of the mod_entry routine
+ recieves : KTEXT, {values, values}
+ returns : CKSUM, RETCODE, {values}
+ acl : su, sms (as register or dealloc)
+
+Modifies all entries corresponding to the first values so they match the
+ second values.
+returns the values for the changed entries
+*/
+int
+kadm_ser_mod(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen)
+{
+ Kadm_vals vals1, vals2, retvals;
+ int wh;
+ long status;
+
+ if ((wh = stream_to_vals(dat, &vals1, len)) < 0)
+ return KADM_LENGTH_ERROR;
+ if ((status = stream_to_vals(dat+wh,&vals2, len-wh)) < 0)
+ return KADM_LENGTH_ERROR;
+ if ((status = kadm_mod_entry(ad->pname, ad->pinst, ad->prealm, &vals1,
+ &vals2, &retvals)) == KADM_DATA) {
+ *outlen = vals_to_stream(&retvals,datout);
+ return KADM_SUCCESS;
+ } else {
+ *outlen = 0;
+ return status;
+ }
+}
+
+int
+kadm_ser_delete(u_char *dat, int len, AUTH_DAT *ad,
+ u_char **datout, int *outlen)
+{
+ Kadm_vals values;
+ int wh;
+ int status;
+
+ if((wh = stream_to_vals(dat, &values, len)) < 0)
+ return KADM_LENGTH_ERROR;
+ if(wh != len)
+ return KADM_LENGTH_ERROR;
+ status = kadm_delete_entry(ad->pname, ad->pinst, ad->prealm,
+ &values);
+ *outlen = 0;
+ return status;
+}
+
+/*
+kadm_ser_get
+ recieves : KTEXT, {values, flags}
+ returns : CKSUM, RETCODE, {count, values, values, values}
+ acl : su
+
+gets the fields requested by flags from all entries matching values
+returns this data for each matching recipient, after a count of how many such
+ matches there were
+*/
+int
+kadm_ser_get(u_char *dat, int len, AUTH_DAT *ad, u_char **datout, int *outlen)
+{
+ Kadm_vals values, retvals;
+ u_char fl[FLDSZ];
+ int loop,wh;
+ long status;
+
+ if ((wh = stream_to_vals(dat, &values, len)) < 0)
+ return KADM_LENGTH_ERROR;
+ if (wh + FLDSZ > len)
+ return KADM_LENGTH_ERROR;
+ for (loop=FLDSZ-1; loop>=0; loop--)
+ fl[loop] = dat[wh++];
+ if ((status = kadm_get_entry(ad->pname, ad->pinst, ad->prealm,
+ &values, fl, &retvals)) == KADM_DATA) {
+ *outlen = vals_to_stream(&retvals,datout);
+ return KADM_SUCCESS;
+ } else {
+ *outlen = 0;
+ return status;
+ }
+}
+
diff --git a/crypto/kerberosIV/kadmin/kadm_server.h b/crypto/kerberosIV/kadmin/kadm_server.h
new file mode 100644
index 0000000..c730574
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/kadm_server.h
@@ -0,0 +1,66 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+/* $Id: kadm_server.h,v 1.10 1997/05/11 04:08:26 assar Exp $ */
+
+/*
+ * Definitions for Kerberos administration server & client
+ */
+
+#ifndef KADM_SERVER_DEFS
+#define KADM_SERVER_DEFS
+
+/*
+ * kadm_server.h
+ * Header file for the fourth attempt at an admin server
+ * Doug Church, December 28, 1989, MIT Project Athena
+ * ps. Yes that means this code belongs to athena etc...
+ * as part of our ongoing attempt to copyright all greek names
+ */
+
+typedef struct {
+ struct sockaddr_in admin_addr;
+ struct sockaddr_in recv_addr;
+ int recv_addr_len;
+ int admin_fd; /* our link to clients */
+ char sname[ANAME_SZ];
+ char sinst[INST_SZ];
+ char krbrlm[REALM_SZ];
+ des_cblock master_key;
+ des_cblock session_key;
+ des_key_schedule master_key_schedule;
+ long master_key_version;
+} Kadm_Server;
+
+/* the default syslog file */
+#ifndef KADM_SYSLOG
+#define KADM_SYSLOG "/var/log/admin_server.syslog"
+#endif /* KADM_SYSLOG */
+
+#ifndef DEFAULT_ACL_DIR
+#define DEFAULT_ACL_DIR "/var/kerberos"
+#endif /* DEFAULT_ACL_DIR */
+#define ADD_ACL_FILE "/admin_acl.add"
+#define GET_ACL_FILE "/admin_acl.get"
+#define MOD_ACL_FILE "/admin_acl.mod"
+#define DEL_ACL_FILE "/admin_acl.del"
+
+#endif /* KADM_SERVER_DEFS */
diff --git a/crypto/kerberosIV/kadmin/kadmin.c b/crypto/kerberosIV/kadmin/kadmin.c
new file mode 100644
index 0000000..f117b6b
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/kadmin.c
@@ -0,0 +1,845 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+/*
+ * Kerberos database administrator's tool.
+ *
+ * The default behavior of kadmin is if the -m option is given
+ * on the commandline, multiple requests are allowed to be given
+ * with one entry of the admin password (until the tickets expire).
+ */
+
+#include "kadm_locl.h"
+
+RCSID("$Id: kadmin.c,v 1.48 1997/05/13 09:43:06 bg Exp $");
+
+static void change_password(int argc, char **argv);
+static void change_key(int argc, char **argv);
+static void change_admin_password(int argc, char **argv);
+static void add_new_key(int argc, char **argv);
+static void del_entry(int argc, char **argv);
+static void get_entry(int argc, char **argv);
+static void mod_entry(int argc, char **argv);
+static void help(int argc, char **argv);
+static void clean_up_cmd(int argc, char **argv);
+static void quit_cmd(int argc, char **argv);
+
+static SL_cmd cmds[] = {
+ {"change_password", change_password, "Change a user's password"},
+ {"cpw"},
+ {"passwd"},
+ {"change_key", change_key, "Change a user's password as a DES binary key"},
+ {"ckey"},
+ {"change_admin_password", change_admin_password,
+ "Change your admin password"},
+ {"cap"},
+ {"add_new_key", add_new_key, "Add new user to kerberos database"},
+ {"ank"},
+ {"del_entry", del_entry, "Delete entry from database"},
+ {"del"},
+ {"delete"},
+ {"get_entry", get_entry, "Get entry from kerberos database"},
+ {"mod_entry", mod_entry, "Modify entry in kerberos database"},
+ {"destroy_tickets", clean_up_cmd, "Destroy admin tickets"},
+ {"exit", quit_cmd, "Exit program"},
+ {"quit"},
+ {"help", help, "Help"},
+ {"?"},
+ {NULL}
+};
+
+#define BAD_PW 1
+#define GOOD_PW 0
+#define FUDGE_VALUE 15 /* for ticket expiration time */
+#define PE_NO 0
+#define PE_YES 1
+#define PE_UNSURE 2
+
+/* for get_password, whether it should do the swapping...necessary for
+ using vals structure, unnecessary for change_pw requests */
+#define DONTSWAP 0
+#define SWAP 1
+
+static krb_principal pr;
+static char default_realm[REALM_SZ]; /* default kerberos realm */
+static char krbrlm[REALM_SZ]; /* current realm being administered */
+static int multiple = 0; /* Allow multiple requests per ticket */
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else
+#define read_long_pw_string des_read_pw_string
+#endif
+
+static void
+get_maxlife(Kadm_vals *vals)
+{
+ char buff[BUFSIZ];
+ time_t life;
+ int l;
+
+ do {
+ printf("Maximum ticket lifetime? (%d) [%s] ",
+ vals->max_life, krb_life_to_atime(vals->max_life));
+ fflush(stdout);
+ if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+ clearerr(stdin);
+ return;
+ }
+ life = krb_atime_to_life(buff);
+ } while (life <= 0);
+
+ l = strlen(buff);
+ if (buff[l-2] == 'm')
+ life = krb_time_to_life(0L, life*60);
+ if (buff[l-2] == 'h')
+ life = krb_time_to_life(0L, life*60*60);
+
+ vals->max_life = life;
+ SET_FIELD(KADM_MAXLIFE,vals->fields);
+}
+
+static void
+get_attr(Kadm_vals *vals)
+{
+ char buff[BUFSIZ], *out;
+ int attr;
+
+ do {
+ printf("Attributes? [0x%.2x] ", vals->attributes);
+ fflush(stdout);
+ if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+ clearerr(stdin);
+ return;
+ }
+ attr = strtol(buff, &out, 0);
+ if (attr == 0 && out == buff)
+ attr = -1;
+ } while (attr < 0 || attr > 0xffff);
+
+ vals->attributes = attr;
+ SET_FIELD(KADM_ATTR,vals->fields);
+}
+
+static void
+get_expdate(Kadm_vals *vals)
+{
+ char buff[BUFSIZ];
+ struct tm edate;
+
+ memset(&edate, 0, sizeof(edate));
+ do {
+ printf("Expiration date (enter yyyy-mm-dd) ? [%.24s] ",
+ asctime(k_localtime(&vals->exp_date)));
+ fflush(stdout);
+ if (fgets(buff, sizeof(buff), stdin) == NULL || *buff == '\n') {
+ clearerr(stdin);
+ return;
+ }
+ if (sscanf(buff, "%d-%d-%d",
+ &edate.tm_year, &edate.tm_mon, &edate.tm_mday) == 3) {
+ 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 */
+ }
+ } while (krb_check_tm (edate));
+
+ edate.tm_year -= 1900;
+ vals->exp_date = tm2time (edate, 1);
+ SET_FIELD(KADM_EXPDATE,vals->fields);
+}
+
+static int
+princ_exists(char *name, char *instance, char *realm)
+{
+ int status;
+
+ status = krb_get_pw_in_tkt(name, instance, realm,
+ KRB_TICKET_GRANTING_TICKET,
+ realm, 1, "");
+
+ if ((status == KSUCCESS) || (status == INTK_BADPW))
+ return(PE_YES);
+ else if (status == KDC_PR_UNKNOWN)
+ return(PE_NO);
+ else
+ return(PE_UNSURE);
+}
+
+static int
+get_password(u_int32_t *low, u_int32_t *high, char *prompt, int byteswap)
+{
+ char new_passwd[MAX_KPW_LEN]; /* new password */
+ des_cblock newkey;
+
+ if (read_long_pw_string(new_passwd, sizeof(new_passwd)-1, prompt, 1))
+ return(BAD_PW);
+ if (strlen(new_passwd) == 0) {
+ printf("Using random password.\n");
+#ifdef NOENCRYPTION
+ memset(newkey, 0, sizeof(newkey));
+#else
+ des_new_random_key(&newkey);
+#endif
+ } else {
+#ifdef NOENCRYPTION
+ memset(newkey, 0, sizeof(newkey));
+#else
+ des_string_to_key(new_passwd, &newkey);
+#endif
+ memset(new_passwd, 0, sizeof(new_passwd));
+ }
+
+ memcpy(low, newkey, 4);
+ memcpy(high, ((char *)newkey) + 4, 4);
+
+ memset(newkey, 0, sizeof(newkey));
+
+#ifdef NOENCRYPTION
+ *low = 1;
+#endif
+
+ if (byteswap != DONTSWAP) {
+ *low = htonl(*low);
+ *high = htonl(*high);
+ }
+ return(GOOD_PW);
+}
+
+static int
+get_admin_password(void)
+{
+ int status;
+ char admin_passwd[MAX_KPW_LEN]; /* Admin's password */
+ int ticket_life = 1; /* minimum ticket lifetime */
+ CREDENTIALS c;
+
+ if (multiple) {
+ /* If admin tickets exist and are valid, just exit. */
+ memset(&c, 0, sizeof(c));
+ if (krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c) == KSUCCESS)
+ /*
+ * If time is less than lifetime - FUDGE_VALUE after issue date,
+ * tickets will probably last long enough for the next
+ * transaction.
+ */
+ if (time(0) < (c.issue_date + (5 * 60 * c.lifetime) - FUDGE_VALUE))
+ return(KADM_SUCCESS);
+ ticket_life = DEFAULT_TKT_LIFE;
+ }
+
+ if (princ_exists(pr.name, pr.instance, pr.realm) != PE_NO) {
+ char prompt[256];
+ snprintf(prompt, sizeof(prompt), "%s's Password: ", krb_unparse_name(&pr));
+ if (read_long_pw_string(admin_passwd,
+ sizeof(admin_passwd)-1,
+ prompt, 0)) {
+ warnx ("Error reading admin password.");
+ goto bad;
+ }
+ status = krb_get_pw_in_tkt(pr.name, pr.instance, pr.realm,
+ PWSERV_NAME, KADM_SINST,
+ ticket_life, admin_passwd);
+ memset(admin_passwd, 0, sizeof(admin_passwd));
+
+ /* Initialize non shared random sequence from session key. */
+ memset(&c, 0, sizeof(c));
+ krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c);
+ des_init_random_number_generator(&c.session);
+ }
+ else
+ status = KDC_PR_UNKNOWN;
+
+ switch(status) {
+ case GT_PW_OK:
+ return(GOOD_PW);
+ case KDC_PR_UNKNOWN:
+ printf("Principal %s does not exist.\n", krb_unparse_name(&pr));
+ goto bad;
+ case GT_PW_BADPW:
+ printf("Incorrect admin password.\n");
+ goto bad;
+ default:
+ com_err("kadmin", status+krb_err_base,
+ "while getting password tickets");
+ goto bad;
+ }
+
+ bad:
+ memset(admin_passwd, 0, sizeof(admin_passwd));
+ dest_tkt();
+ return(BAD_PW);
+}
+
+static void
+usage(void)
+{
+ fprintf (stderr, "Usage: kadmin [[-u|-p] admin_name] [-r default_realm]"
+ " [-m]\n"
+ " -m allows multiple admin requests to be "
+ "serviced with one entry of admin\n"
+ " password.\n");
+ exit (1);
+}
+
+/* GLOBAL */
+static void
+clean_up()
+{
+ dest_tkt();
+}
+
+static void
+clean_up_cmd (int argc, char **argv)
+{
+ clean_up();
+}
+
+/* GLOBAL */
+static void
+quit()
+{
+ printf("Cleaning up and exiting.\n");
+ clean_up();
+ exit(0);
+}
+
+static void
+quit_cmd (int argc, char **argv)
+{
+ quit();
+}
+
+static void
+do_init(int argc, char **argv)
+{
+ int c;
+ int tflag = 0;
+ char tktstring[MaxPathLen];
+ int k_errno;
+
+ set_progname (argv[0]);
+
+ memset(&pr, 0, sizeof(pr));
+ if (krb_get_default_principal(pr.name, pr.instance, default_realm) < 0)
+ errx (1, "I could not even guess who you might be");
+ while ((c = getopt(argc, argv, "p:u:r:mt")) != EOF)
+ switch (c) {
+ case 'p':
+ case 'u':
+ if((k_errno = krb_parse_name(optarg, &pr)) != KSUCCESS)
+ errx (1, "%s", krb_get_err_text(k_errno));
+ break;
+ case 'r':
+ memset(default_realm, 0, sizeof(default_realm));
+ strncpy(default_realm, optarg, sizeof(default_realm) - 1);
+ break;
+ case 'm':
+ multiple++;
+ break;
+ case 't':
+ tflag++;
+ break;
+ default:
+ usage();
+ break;
+ }
+ if (optind < argc)
+ usage();
+ strcpy(krbrlm, default_realm);
+
+ if (kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm) != KADM_SUCCESS)
+ *krbrlm = '\0';
+ if (pr.realm[0] == '\0')
+ strcpy (pr.realm, krbrlm);
+ if (pr.instance[0] == '\0')
+ strcpy(pr.instance, "admin");
+
+ if (!tflag) {
+ snprintf(tktstring, sizeof(tktstring), TKT_ROOT "_adm_%d",(int)getpid());
+ krb_set_tkt_string(tktstring);
+ }
+
+}
+
+int
+main(int argc, char **argv)
+{
+ do_init(argc, argv);
+
+ printf("Welcome to the Kerberos Administration Program, version 2\n");
+ printf("Type \"help\" if you need it.\n");
+ sl_loop (cmds, "kadmin: ");
+ printf("\n");
+ quit();
+ exit(0);
+}
+
+static int
+setvals(Kadm_vals *vals, char *string)
+{
+ char realm[REALM_SZ];
+ int status = KADM_SUCCESS;
+
+ memset(vals, 0, sizeof(*vals));
+ memset(realm, 0, sizeof(realm));
+
+ SET_FIELD(KADM_NAME,vals->fields);
+ SET_FIELD(KADM_INST,vals->fields);
+ if ((status = kname_parse(vals->name, vals->instance, realm, string))) {
+ printf("kerberos error: %s\n", krb_get_err_text(status));
+ return status;
+ }
+ if (!realm[0])
+ strcpy(realm, default_realm);
+ if (strcmp(realm, krbrlm)) {
+ strcpy(krbrlm, realm);
+ if ((status = kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm))
+ != KADM_SUCCESS)
+ printf("kadm error for realm %s: %s\n",
+ krbrlm, error_message(status));
+ }
+ if (status)
+ return 1;
+ else
+ return KADM_SUCCESS;
+}
+
+static void
+change_password(int argc, char **argv)
+{
+ Kadm_vals old, new;
+ int status;
+ char pw_prompt[BUFSIZ];
+
+ if (argc != 2) {
+ printf("Usage: change_password loginname\n");
+ return;
+ }
+
+ if (setvals(&old, argv[1]) != KADM_SUCCESS)
+ return;
+
+ new = old;
+
+ SET_FIELD(KADM_DESKEY,new.fields);
+
+ if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ /* get the new password */
+ snprintf(pw_prompt, sizeof(pw_prompt), "New password for %s:", argv[1]);
+
+ if (get_password(&new.key_low, &new.key_high,
+ pw_prompt, SWAP) == GOOD_PW) {
+ status = kadm_mod(&old, &new);
+ if (status == KADM_SUCCESS) {
+ printf("Password changed for %s.\n", argv[1]);
+ } else {
+ printf("kadmin: %s\nwhile changing password for %s",
+ error_message(status), argv[1]);
+ }
+ } else
+ printf("Error reading password; password unchanged\n");
+ memset(&new, 0, sizeof(new));
+ if (!multiple)
+ clean_up();
+ }
+ else
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (old.name, old.instance, krbrlm));
+ return;
+}
+
+static int
+getkey(unsigned char *k)
+{
+ int i, c;
+ for (i = 0; i < 8; i++)
+ {
+ c = getchar();
+ if (c == EOF)
+ return 0;
+ else if (c == '\\')
+ {
+ int oct = -1;
+ scanf("%03o", &oct);
+ if (oct < 0 || oct > 255)
+ return 0;
+ k[i] = oct;
+ }
+ else if (!isalpha(c))
+ return 0;
+ else
+ k[i] = c;
+ }
+ c = getchar();
+ if (c != '\n')
+ return 0;
+ return 1; /* Success */
+}
+
+static void
+printkey(unsigned char *tkey)
+{
+ int j;
+ for(j = 0; j < 8; j++)
+ if(tkey[j] != '\\' && isalpha(tkey[j]) != 0)
+ printf("%c", tkey[j]);
+ else
+ printf("\\%03o",(unsigned char)tkey[j]);
+ printf("\n");
+}
+
+static void
+change_key(int argc, char **argv)
+{
+ Kadm_vals old, new;
+ unsigned char newkey[8];
+ int status;
+
+ if (argc != 2) {
+ printf("Usage: change_key principal-name\n");
+ return;
+ }
+
+ if (setvals(&old, argv[1]) != KADM_SUCCESS)
+ return;
+
+ new = old;
+
+ SET_FIELD(KADM_DESKEY,new.fields);
+
+ if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ /* get the new password */
+ printf("New DES key for %s: ", argv[1]);
+
+ if (getkey(newkey)) {
+ memcpy(&new.key_low, newkey, 4);
+ memcpy(&new.key_high, ((char *)newkey) + 4, 4);
+ printf("Entered key for %s: ", argv[1]);
+ printkey(newkey);
+ memset(newkey, 0, sizeof(newkey));
+
+ status = kadm_mod(&old, &new);
+ if (status == KADM_SUCCESS) {
+ printf("Key changed for %s.\n", argv[1]);
+ } else {
+ printf("kadmin: %s\nwhile changing key for %s",
+ error_message(status), argv[1]);
+ }
+ } else
+ printf("Error reading key; key unchanged\n");
+ memset(&new, 0, sizeof(new));
+ if (!multiple)
+ clean_up();
+ }
+ else
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (old.name, old.instance, krbrlm));
+ return;
+}
+
+static void
+change_admin_password(int argc, char **argv)
+{
+ des_cblock newkey;
+ int status;
+ char pword[MAX_KPW_LEN];
+ char *pw_msg;
+
+ if (argc != 1) {
+ printf("Usage: change_admin_password\n");
+ return;
+ }
+ if (get_pw_new_pwd(pword, sizeof(pword), &pr, 1) == 0) {
+ des_string_to_key(pword, &newkey);
+ status = kadm_change_pw_plain(newkey, pword, &pw_msg);
+ if(status == KADM_INSECURE_PW)
+ printf("Insecure password: %s\n", pw_msg);
+ else if (status == KADM_SUCCESS)
+ printf("Admin password changed\n");
+ else
+ printf("kadm error: %s\n",error_message(status));
+ memset(newkey, 0, sizeof(newkey));
+ memset(pword, 0, sizeof(pword));
+ }
+ if (!multiple)
+ clean_up();
+ return;
+}
+
+static void
+add_new_key(int argc, char **argv)
+{
+ Kadm_vals new;
+ char pw_prompt[BUFSIZ];
+ int status;
+
+ if (argc != 2) {
+ printf("Usage: add_new_key user_name.\n");
+ return;
+ }
+ if (setvals(&new, argv[1]) != KADM_SUCCESS)
+ return;
+
+ SET_FIELD(KADM_EXPDATE,new.fields);
+ SET_FIELD(KADM_ATTR,new.fields);
+ SET_FIELD(KADM_MAXLIFE,new.fields);
+ SET_FIELD(KADM_DESKEY,new.fields);
+
+ if (princ_exists(new.name, new.instance, krbrlm) != PE_YES) {
+ Kadm_vals vals;
+ u_char fields[4];
+ char n[ANAME_SZ + INST_SZ + 1];
+
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ memset(fields, 0, sizeof(fields));
+ SET_FIELD(KADM_NAME,fields);
+ SET_FIELD(KADM_INST,fields);
+ SET_FIELD(KADM_EXPDATE,fields);
+ SET_FIELD(KADM_ATTR,fields);
+ SET_FIELD(KADM_MAXLIFE,fields);
+ snprintf (n, sizeof(n), "default.%s", new.instance);
+ if (setvals(&vals, n) != KADM_SUCCESS)
+ return;
+
+ if (kadm_get(&vals, fields) != KADM_SUCCESS) {
+ if (setvals(&vals, "default") != KADM_SUCCESS)
+ return;
+ if ((status = kadm_get(&vals, fields)) != KADM_SUCCESS) {
+ printf ("kadm error: %s\n", error_message(status));
+ return;
+ }
+ }
+
+ if (vals.max_life == 255) /* Defaults not set! */ {
+ /* This is the default maximum lifetime for new principals. */
+ if (strcmp(new.instance, "admin") == 0)
+ vals.max_life = 1 + (CLOCK_SKEW/(5*60)); /* 5+5 minutes */
+ else if (strcmp(new.instance, "root") == 0)
+ vals.max_life = 96; /* 8 hours */
+ else if (krb_life_to_time(0, 162) >= 24*60*60)
+ vals.max_life = 162; /* ca 100 hours */
+ else
+ vals.max_life = 255; /* ca 21 hours (maximum) */
+
+ /* Also fix expiration date. */
+ if (strcmp(new.name, "rcmd") == 0)
+ vals.exp_date = 1104814999; /* Tue Jan 4 06:03:19 2005 */
+ else
+ vals.exp_date = time(0) + 2*(365*24*60*60); /* + ca 2 years */
+ }
+
+ new.max_life = vals.max_life;
+ new.exp_date = vals.exp_date;
+ new.attributes = vals.attributes;
+ get_maxlife(&new);
+ get_attr(&new);
+ get_expdate(&new);
+
+ /* get the new password */
+ snprintf(pw_prompt, sizeof(pw_prompt), "Password for %s:", argv[1]);
+
+ if (get_password(&new.key_low, &new.key_high,
+ pw_prompt, SWAP) == GOOD_PW) {
+ status = kadm_add(&new);
+ if (status == KADM_SUCCESS) {
+ printf("%s added to database.\n", argv[1]);
+ } else {
+ printf("kadm error: %s\n",error_message(status));
+ }
+ } else
+ printf("Error reading password; %s not added\n",argv[1]);
+ memset(&new, 0, sizeof(new));
+ if (!multiple)
+ clean_up();
+ }
+ else
+ printf("kadmin: Principal already exists.\n");
+ return;
+}
+
+static void
+del_entry(int argc, char **argv)
+{
+ int status;
+ Kadm_vals vals;
+
+ if (argc != 2) {
+ printf("Usage: del_entry username\n");
+ return;
+ }
+
+ if (setvals(&vals, argv[1]) != KADM_SUCCESS)
+ return;
+
+ if (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ if ((status = kadm_del(&vals)) == KADM_SUCCESS){
+ printf("%s removed from database.\n", argv[1]);
+ } else {
+ printf("kadm error: %s\n",error_message(status));
+ }
+
+ if (!multiple)
+ clean_up();
+ }
+ else
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (vals.name, vals.instance, krbrlm));
+ return;
+}
+
+static void
+get_entry(int argc, char **argv)
+{
+ int status;
+ u_char fields[4];
+ Kadm_vals vals;
+
+ if (argc != 2) {
+ printf("Usage: get_entry username\n");
+ return;
+ }
+
+ memset(fields, 0, sizeof(fields));
+
+ SET_FIELD(KADM_NAME,fields);
+ SET_FIELD(KADM_INST,fields);
+ SET_FIELD(KADM_EXPDATE,fields);
+ SET_FIELD(KADM_ATTR,fields);
+ SET_FIELD(KADM_MAXLIFE,fields);
+#if 0
+ SET_FIELD(KADM_DESKEY,fields);
+#endif
+
+ if (setvals(&vals, argv[1]) != KADM_SUCCESS)
+ return;
+
+
+ if (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ if ((status = kadm_get(&vals, fields)) == KADM_SUCCESS)
+ prin_vals(&vals);
+ else
+ printf("kadm error: %s\n",error_message(status));
+
+ if (!multiple)
+ clean_up();
+ }
+ else
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (vals.name, vals.instance, krbrlm));
+ return;
+}
+
+static void
+mod_entry(int argc, char **argv)
+{
+ int status;
+ u_char fields[4];
+ Kadm_vals ovals, nvals;
+
+ if (argc != 2) {
+ printf("Usage: mod_entry username\n");
+ return;
+ }
+
+ memset(fields, 0, sizeof(fields));
+
+ SET_FIELD(KADM_NAME,fields);
+ SET_FIELD(KADM_INST,fields);
+ SET_FIELD(KADM_EXPDATE,fields);
+ SET_FIELD(KADM_ATTR,fields);
+ SET_FIELD(KADM_MAXLIFE,fields);
+
+ if (setvals(&ovals, argv[1]) != KADM_SUCCESS)
+ return;
+
+ nvals = ovals;
+
+ if (princ_exists(ovals.name, ovals.instance, krbrlm) == PE_NO) {
+ printf("kadmin: Principal %s does not exist.\n",
+ krb_unparse_name_long (ovals.name, ovals.instance, krbrlm));
+ return;
+ }
+
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ if ((status = kadm_get(&ovals, fields)) != KADM_SUCCESS) {
+ printf("[ unable to retrieve current settings: %s ]\n",
+ error_message(status));
+ nvals.max_life = DEFAULT_TKT_LIFE;
+ nvals.exp_date = 0;
+ nvals.attributes = 0;
+ } else {
+ nvals.max_life = ovals.max_life;
+ nvals.exp_date = ovals.exp_date;
+ nvals.attributes = ovals.attributes;
+ }
+
+ get_maxlife(&nvals);
+ get_attr(&nvals);
+ get_expdate(&nvals);
+
+ if (IS_FIELD(KADM_MAXLIFE, nvals.fields) ||
+ IS_FIELD(KADM_ATTR, nvals.fields) ||
+ IS_FIELD(KADM_EXPDATE, nvals.fields)) {
+ if ((status = kadm_mod(&ovals, &nvals)) != KADM_SUCCESS) {
+ printf("kadm error: %s\n",error_message(status));
+ goto out;
+ }
+ if ((status = kadm_get(&ovals, fields)) != KADM_SUCCESS) {
+ printf("kadm error: %s\n",error_message(status));
+ goto out;
+ }
+ }
+ prin_vals(&ovals);
+
+out:
+ if (!multiple)
+ clean_up();
+ return;
+}
+
+static void
+help(int argc, char **argv)
+{
+ sl_help (cmds, argc, argv);
+}
diff --git a/crypto/kerberosIV/kadmin/kpasswd.c b/crypto/kerberosIV/kadmin/kpasswd.c
new file mode 100644
index 0000000..f4c0cda
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/kpasswd.c
@@ -0,0 +1,163 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+/*
+ * change your password with kerberos
+ */
+
+#include "kadm_locl.h"
+
+RCSID("$Id: kpasswd.c,v 1.25 1997/05/02 14:28:51 assar Exp $");
+
+static void
+usage(int value)
+{
+ fprintf(stderr, "Usage: ");
+ fprintf(stderr, "kpasswd [-h ] [-n user] [-i instance] [-r realm] ");
+ fprintf(stderr, "[-u fullname]\n");
+ exit(value);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb_principal principal;
+ krb_principal default_principal;
+ int realm_given = 0; /* True if realm was give on cmdline */
+ int use_default = 1; /* True if we should use default name */
+ int status; /* return code */
+ char pword[MAX_KPW_LEN];
+ int c;
+ char tktstring[MaxPathLen];
+
+ set_progname (argv[0]);
+
+ memset (&principal, 0, sizeof(principal));
+ memset (&default_principal, 0, sizeof(default_principal));
+
+ krb_get_default_principal (default_principal.name,
+ default_principal.instance,
+ default_principal.realm);
+
+ while ((c = getopt(argc, argv, "u:n:i:r:h")) != EOF) {
+ switch (c) {
+ case 'u':
+ status = krb_parse_name (optarg, &principal);
+ if (status != KSUCCESS)
+ errx (2, "%s", krb_get_err_text(status));
+ if (principal.realm[0])
+ realm_given++;
+ else if (krb_get_lrealm(principal.realm, 1) != KSUCCESS)
+ errx (1, "Could not find default realm!");
+ break;
+ case 'n':
+ if (k_isname(optarg))
+ strncpy(principal.name, optarg, sizeof(principal.name) - 1);
+ else {
+ warnx("Bad name: %s", optarg);
+ usage(1);
+ }
+ break;
+ case 'i':
+ if (k_isinst(optarg))
+ strncpy(principal.instance,
+ optarg,
+ sizeof(principal.instance) - 1);
+ else {
+ warnx("Bad instance: %s", optarg);
+ usage(1);
+ }
+ break;
+ case 'r':
+ if (k_isrealm(optarg)) {
+ strncpy(principal.realm, optarg, sizeof(principal.realm) - 1);
+ realm_given++;
+ } else {
+ warnx("Bad realm: %s", optarg);
+ usage(1);
+ }
+ break;
+ case 'h':
+ usage(0);
+ break;
+ default:
+ usage(1);
+ break;
+ }
+ use_default = 0;
+ }
+ if (optind < argc) {
+ use_default = 0;
+ status = krb_parse_name (argv[optind], &principal);
+ if(status != KSUCCESS)
+ errx (1, "%s", krb_get_err_text (status));
+ }
+
+ if (use_default) {
+ strcpy(principal.name, default_principal.name);
+ strcpy(principal.instance, default_principal.instance);
+ strcpy(principal.realm, default_principal.realm);
+ } else {
+ if (!principal.name[0])
+ strcpy(principal.name, default_principal.name);
+ if (!principal.realm[0])
+ strcpy(principal.realm, default_principal.realm);
+ }
+
+ snprintf(tktstring, sizeof(tktstring),
+ TKT_ROOT "_cpw_%u", (unsigned)getpid());
+ krb_set_tkt_string(tktstring);
+
+ if (get_pw_new_pwd(pword, sizeof(pword), &principal,
+ realm_given)) {
+ dest_tkt ();
+ exit(1);
+ }
+
+ status = kadm_init_link (PWSERV_NAME, KRB_MASTER, principal.realm);
+ if (status != KADM_SUCCESS)
+ com_err(argv[0], status, "while initializing");
+ else {
+ des_cblock newkey;
+ char *pw_msg; /* message from server */
+
+ des_string_to_key(pword, &newkey);
+ status = kadm_change_pw_plain((unsigned char*)&newkey, pword, &pw_msg);
+ memset(newkey, 0, sizeof(newkey));
+
+ if (status == KADM_INSECURE_PW)
+ warnx ("Insecure password: %s", pw_msg);
+ else if (status != KADM_SUCCESS)
+ com_err(argv[0], status, " attempting to change password.");
+ }
+ memset(pword, 0, sizeof(pword));
+
+ if (status != KADM_SUCCESS)
+ fprintf(stderr,"Password NOT changed.\n");
+ else
+ printf("Password changed.\n");
+
+ dest_tkt();
+ if (status)
+ return 2;
+ else
+ return 0;
+}
diff --git a/crypto/kerberosIV/kadmin/ksrvutil.c b/crypto/kerberosIV/kadmin/ksrvutil.c
new file mode 100644
index 0000000..108481c
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/ksrvutil.c
@@ -0,0 +1,601 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+/*
+ * list and update contents of srvtab files
+ */
+
+/*
+ * ksrvutil
+ * list and update the contents of srvtab files
+ */
+
+#include "kadm_locl.h"
+
+RCSID("$Id: ksrvutil.c,v 1.39 1997/05/02 14:28:52 assar Exp $");
+
+#include "ksrvutil.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 */
+
+#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"
+
+char u_name[ANAME_SZ];
+char u_inst[INST_SZ];
+char u_realm[REALM_SZ];
+
+int destroyp = FALSE; /* Should the ticket file be destroyed? */
+
+static unsigned short
+get_mode(char *filename)
+{
+ struct stat statbuf;
+ unsigned short mode;
+
+ memset(&statbuf, 0, sizeof(statbuf));
+
+ if (stat(filename, &statbuf) < 0)
+ mode = SRVTAB_MODE;
+ else
+ mode = statbuf.st_mode;
+
+ return(mode);
+}
+
+static void
+copy_keyfile(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;
+
+ memset(buf, 0, sizeof(buf));
+
+ do {
+ try_again = FALSE;
+ if ((keyfile_fd = open(keyfile, O_RDONLY, 0)) < 0) {
+ if (errno != ENOENT)
+ err (1, "read %s", keyfile);
+ else {
+ try_again = TRUE;
+ if ((keyfile_fd =
+ open(keyfile,
+ O_WRONLY | O_TRUNC | O_CREAT, SRVTAB_MODE)) < 0)
+ err(1, "create %s", keyfile);
+ else
+ if (close(keyfile_fd) < 0)
+ err (1, "close %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, "write %s", backup_keyfile);
+ do {
+ if ((rcount = read(keyfile_fd, buf, sizeof(buf))) < 0)
+ err (1, "read %s", keyfile);
+ if (rcount && (write(backup_keyfile_fd, buf, rcount) != rcount))
+ err (1, "write %s", backup_keyfile);
+ } while (rcount);
+ if (close(backup_keyfile_fd) < 0)
+ err(1, "close %s", backup_keyfile);
+ if (close(keyfile_fd) < 0)
+ err(1, "close %s", keyfile);
+}
+
+void
+leave(char *str, int x)
+{
+ if (str)
+ fprintf(stderr, "%s\n", str);
+ if (destroyp)
+ dest_tkt();
+ exit(x);
+}
+
+void
+safe_read_stdin(char *prompt, char *buf, size_t size)
+{
+ printf("%s", prompt);
+ fflush(stdout);
+ memset(buf, 0, size);
+ if (read(0, buf, size - 1) < 0) {
+ warn("read stdin");
+ leave(NULL, 1);
+ }
+ buf[strlen(buf)-1] = 0;
+}
+
+void
+safe_write(char *filename, int fd, void *buf, size_t len)
+{
+ if (write(fd, buf, len) != len) {
+ warn("write %s", filename);
+ close(fd);
+ leave("In progress srvtab in this file.", 1);
+ }
+}
+
+static int
+yes_no(char *string, int dflt)
+{
+ char ynbuf[5];
+
+ printf("%s (y,n) [%c]", string, dflt?'y':'n');
+ for (;;) {
+ safe_read_stdin("", ynbuf, sizeof(ynbuf));
+
+ if ((ynbuf[0] == 'n') || (ynbuf[0] == 'N'))
+ return(0);
+ else if ((ynbuf[0] == 'y') || (ynbuf[0] == 'Y'))
+ return(1);
+ else if(ynbuf[0] == 0)
+ return dflt;
+ else {
+ printf("Please enter 'y' or 'n': ");
+ fflush(stdout);
+ }
+ }
+}
+
+int yn(char *string)
+{
+ return yes_no(string, 1);
+}
+
+int ny(char *string)
+{
+ return yes_no(string, 0);
+}
+
+static void
+append_srvtab(char *filename, int fd, char *sname, char *sinst, char *srealm, unsigned char key_vno, unsigned char *key)
+{
+ /* Add one to append null */
+ safe_write(filename, fd, sname, strlen(sname) + 1);
+ safe_write(filename, fd, sinst, strlen(sinst) + 1);
+ safe_write(filename, fd, srealm, strlen(srealm) + 1);
+ safe_write(filename, fd, &key_vno, 1);
+ safe_write(filename, fd, key, sizeof(des_cblock));
+ fsync(fd);
+}
+
+static void
+print_key(unsigned char *key)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ printf("%02x", key[i]);
+ printf(" ");
+ for (i = 4; i < 8; i++)
+ printf("%02x", key[i]);
+}
+
+static void
+print_name(char *name, char *inst, char *realm)
+{
+ printf("%s", krb_unparse_name_long(name, inst, realm));
+}
+
+static int
+get_svc_new_key(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(PWSERV_NAME, KRB_MASTER, srealm)) ==
+ KADM_SUCCESS)) {
+#ifdef NOENCRYPTION
+ memset(new_key, 0, sizeof(des_cblock));
+ (*new_key)[0] = (unsigned char) 1;
+#else /* NOENCRYPTION */
+ des_new_random_key(new_key);
+#endif /* NOENCRYPTION */
+ return(KADM_SUCCESS);
+ }
+
+ return(status);
+}
+
+static void
+get_key_from_password(des_cblock (*key), char *cellname)
+{
+ 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
+ memset(key, 0, sizeof(des_cblock));
+ (*key)[0] = (unsigned char) 1;
+#else /* NOENCRYPTION */
+ if (strlen(cellname) == 0)
+ des_string_to_key(password, key);
+ else
+ afs_string_to_key(password, cellname, key);
+#endif /* NOENCRYPTION */
+ memset(password, 0, sizeof(password));
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: ksrvutil [-f keyfile] [-i] [-k] ");
+ fprintf(stderr, "[-p principal] [-r realm] ");
+ fprintf(stderr, "[-c AFS cellname] ");
+ fprintf(stderr, "{list | change | add | get}\n");
+ fprintf(stderr, " -i causes the program to ask for ");
+ fprintf(stderr, "confirmation before changing keys.\n");
+ fprintf(stderr, " -k causes the key to printed for list or ");
+ fprintf(stderr, "change.\n");
+ exit(1);
+}
+
+int
+main(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 */
+ char cellname[1024]; /* AFS cell name */
+ int c;
+ int interactive = FALSE;
+ int list = FALSE;
+ int change = FALSE;
+ int add = FALSE;
+ int get = 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? */
+
+ memset(sname, 0, sizeof(sname));
+ memset(sinst, 0, sizeof(sinst));
+ memset(srealm, 0, sizeof(srealm));
+
+ memset(change_tkt, 0, sizeof(change_tkt));
+ memset(keyfile, 0, sizeof(keyfile));
+ memset(work_keyfile, 0, sizeof(work_keyfile));
+ memset(backup_keyfile, 0, sizeof(backup_keyfile));
+ memset(local_realm, 0, sizeof(local_realm));
+ memset(cellname, 0, sizeof(cellname));
+
+ set_progname (argv[0]);
+
+ if (krb_get_default_principal(u_name, u_inst, u_realm) < 0)
+ errx (1, "could not get default principal");
+
+ /* This is used only as a default for adding keys */
+ if (krb_get_lrealm(local_realm, 1) != KSUCCESS)
+ strcpy(local_realm, KRB_REALM);
+
+ while((c = getopt(argc, argv, "ikc:f:p:r:")) != EOF) {
+ switch (c) {
+ case 'i':
+ interactive++;
+ break;
+ case 'k':
+ key++;
+ break;
+ case 'c':
+ strcpy(cellname, optarg);
+ break;
+ case 'f':
+ strcpy(keyfile, optarg);
+ break;
+ case 'p':
+ if((status = kname_parse (u_name, u_inst, u_realm, optarg)) !=
+ KSUCCESS)
+ errx (1, "principal %s: %s", optarg,
+ krb_get_err_text(status));
+ break;
+ case 'r':
+ strcpy(u_realm, optarg);
+ break;
+ case '?':
+ usage();
+ }
+ }
+ if (optind >= argc)
+ usage();
+ if (*u_realm == '\0')
+ strcpy (u_realm, local_realm);
+ if (strcmp(argv[optind], "list") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ list++;
+ }
+ }
+ else if (strcmp(argv[optind], "change") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ change++;
+ }
+ }
+ else if (strcmp(argv[optind], "add") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ add++;
+ }
+ }
+ else if (strcmp(argv[optind], "get") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ get++;
+ }
+ }
+ else
+ usage();
+ ++optind;
+
+ if (!arg_entered)
+ usage();
+
+ if (!keyfile[0])
+ strcpy(keyfile, KEYFILE);
+
+ strcpy(work_keyfile, keyfile);
+ strcpy(backup_keyfile, keyfile);
+
+ if (change || add || get) {
+ strcat(work_keyfile, ".work");
+ strcat(backup_keyfile, ".old");
+
+ copy_keyfile(keyfile, backup_keyfile);
+ }
+
+ if (add || get)
+ copy_keyfile(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, "open %s", backup_keyfile);
+
+ if (change) {
+ if ((work_keyfile_fd =
+ open(work_keyfile, O_WRONLY | O_CREAT | O_TRUNC,
+ SRVTAB_MODE)) < 0)
+ err (1, "creat %s", work_keyfile);
+ }
+ else if (add) {
+ if ((work_keyfile_fd =
+ open(work_keyfile, O_APPEND | O_WRONLY, SRVTAB_MODE)) < 0)
+ err (1, "open with append %s", work_keyfile );
+ }
+ else if (get) {
+ if ((work_keyfile_fd =
+ open(work_keyfile, O_RDWR | O_CREAT, SRVTAB_MODE)) < 0)
+ err (1, "open for writing %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, old_key, sizeof(old_key)) > 0)) {
+ if (list) {
+ if (!first_printed) {
+ printf(VNO_HEADER);
+ printf(PAD);
+ if (key) {
+ printf(KEY_HEADER);
+ printf(PAD);
+ }
+ printf(PRINC_HEADER);
+ first_printed = 1;
+ }
+ printf(VNO_FORMAT, key_vno);
+ printf(PAD);
+ if (key) {
+ print_key(old_key);
+ printf(PAD);
+ }
+ print_name(sname, sinst, srealm);
+ printf("\n");
+ }
+ else if (change) {
+ snprintf(change_tkt, sizeof(change_tkt),
+ TKT_ROOT "_ksrvutil.%u",
+ (unsigned)getpid());
+ krb_set_tkt_string(change_tkt);
+ destroyp = TRUE;
+
+ printf("\nPrincipal: ");
+ print_name(sname, sinst, srealm);
+ 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)
+ printf("Changing to version %d.\n", key_vno + 1);
+ else if (change)
+ printf("Not changing this key.\n");
+
+ if (change_this_key) {
+ /*
+ * This is not a good choice of seed when/if the
+ * key has been compromised so we also use a
+ * random sequence number!
+ */
+ des_init_random_number_generator(&old_key);
+ {
+ des_cblock seqnum;
+ des_generate_random_block(&seqnum);
+ des_set_sequence_number((unsigned char *)&seqnum);
+ }
+ /*
+ * 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 {
+ memcpy(new_key, old_key, sizeof(new_key));
+ warnx ("Key NOT changed: %s\n",
+ krb_get_err_text(status));
+ change_this_key = FALSE;
+ }
+ }
+ else
+ memcpy(new_key, old_key, sizeof(new_key));
+ append_srvtab(work_keyfile, work_keyfile_fd,
+ sname, sinst, srealm, key_vno, new_key);
+ if (key && change_this_key) {
+ printf("Old key: ");
+ print_key(old_key);
+ printf("; new key: ");
+ print_key(new_key);
+ printf("\n");
+ }
+ if (change_this_key) {
+ if ((status = kadm_change_pw(new_key)) == KADM_SUCCESS) {
+ printf("Key changed.\n");
+ dest_tkt();
+ }
+ else {
+ com_err(__progname, status,
+ " attempting to change password.");
+ dest_tkt();
+ /* XXX This knows the format of a keyfile */
+ if (lseek(work_keyfile_fd, -9, SEEK_CUR) >= 0) {
+ key_vno--;
+ safe_write(work_keyfile,
+ work_keyfile_fd, &key_vno, 1);
+ safe_write(work_keyfile, work_keyfile_fd,
+ old_key, sizeof(des_cblock));
+ fsync(work_keyfile_fd);
+ fprintf(stderr,"Key NOT changed.\n");
+ } else {
+ warn ("Unable to revert keyfile");
+ leave("", 1);
+ }
+ }
+ }
+ }
+ memset(old_key, 0, sizeof(des_cblock));
+ memset(new_key, 0, sizeof(des_cblock));
+ }
+ }
+ else if (add) {
+ do {
+ do {
+ safe_read_stdin("Name: ", databuf, sizeof(databuf));
+ strncpy(sname, databuf, sizeof(sname) - 1);
+ if (strchr(sname, '.') != 0) {
+ strcpy(sinst, strchr(sname, '.') + 1);
+ *(strchr(sname, '.')) = 0;
+ } else {
+ safe_read_stdin("Instance: ", databuf, sizeof(databuf));
+ strncpy(sinst, databuf, sizeof(sinst) - 1);
+ }
+ safe_read_stdin("Realm: ", databuf, sizeof(databuf));
+ strncpy(srealm, databuf, sizeof(srealm) - 1);
+ safe_read_stdin("Version number: ", databuf, sizeof(databuf));
+ key_vno = atoi(databuf);
+ if (key_vno == 0)
+ key_vno = 1; /* Version numbers are never 0 */
+ if (!srealm[0])
+ strcpy(srealm, local_realm);
+ printf("New principal: ");
+ print_name(sname, sinst, srealm);
+ printf("; version %d\n", key_vno);
+ } while (!yn("Is this correct?"));
+ get_key_from_password(&new_key, cellname);
+ if (key) {
+ printf("Key: ");
+ print_key(new_key);
+ printf("\n");
+ }
+ append_srvtab(work_keyfile, work_keyfile_fd,
+ sname, sinst, srealm, key_vno, new_key);
+ printf("Key successfully added.\n");
+ } while (yn("Would you like to add another key?"));
+ }
+ else if (get) {
+ ksrvutil_get(work_keyfile_fd, work_keyfile,
+ argc - optind, argv + optind);
+ }
+
+ if (change || list)
+ if (close(backup_keyfile_fd) < 0)
+ warn ("close %s", backup_keyfile);
+
+ if (change || add || get) {
+ if (close(work_keyfile_fd) < 0)
+ err (1, "close %s", work_keyfile);
+ if (rename(work_keyfile, keyfile) < 0)
+ err (1, "rename(%s, %s)", work_keyfile, keyfile);
+ chmod(backup_keyfile, keyfile_mode);
+ chmod(keyfile, keyfile_mode);
+ printf("Old keyfile in %s.\n", backup_keyfile);
+ }
+ return 0;
+}
diff --git a/crypto/kerberosIV/kadmin/ksrvutil.h b/crypto/kerberosIV/kadmin/ksrvutil.h
new file mode 100644
index 0000000..64e2fe4
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/ksrvutil.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $Id: ksrvutil.h,v 1.8 1997/04/01 03:58:55 assar Exp $
+ *
+ */
+
+extern char u_name[], u_inst[], u_realm[];
+extern int destroyp;
+
+void leave(char *str, int x);
+void safe_read_stdin(char *prompt, char *buf, size_t size);
+void safe_write(char *filename, int fd, void *buf, size_t len);
+
+int yn(char *string);
+int ny(char *string);
+
+void ksrvutil_get(int fd, char *filename, int argc, char **argv);
diff --git a/crypto/kerberosIV/kadmin/ksrvutil_get.c b/crypto/kerberosIV/kadmin/ksrvutil_get.c
new file mode 100644
index 0000000..7b97d35
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/ksrvutil_get.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "kadm_locl.h"
+#include "ksrvutil.h"
+
+RCSID("$Id: ksrvutil_get.c,v 1.32 1997/05/05 21:14:57 assar Exp $");
+
+#define BAD_PW 1
+#define GOOD_PW 0
+#define FUDGE_VALUE 15 /* for ticket expiration time */
+#define PE_NO 0
+#define PE_YES 1
+#define PE_UNSURE 2
+
+static char tktstring[128];
+
+static int
+princ_exists(char *name, char *instance, char *realm)
+{
+ int status;
+
+ status = krb_get_pw_in_tkt(name, instance, realm,
+ KRB_TICKET_GRANTING_TICKET,
+ realm, 1, "");
+
+ if ((status == KSUCCESS) || (status == INTK_BADPW))
+ return(PE_YES);
+ else if (status == KDC_PR_UNKNOWN)
+ return(PE_NO);
+ else
+ return(PE_UNSURE);
+}
+
+static int
+get_admin_password(char *myname, char *myinst, char *myrealm)
+{
+ int status;
+ char admin_passwd[MAX_KPW_LEN]; /* Admin's password */
+ int ticket_life = 1; /* minimum ticket lifetime */
+ char buf[1024];
+ CREDENTIALS c;
+
+ if (princ_exists(myname, myinst, myrealm) != PE_NO) {
+ snprintf(buf, sizeof(buf), "Password for %s: ",
+ krb_unparse_name_long (myname, myinst, myrealm));
+ if (des_read_pw_string(admin_passwd, sizeof(admin_passwd)-1,
+ buf, 0)) {
+ fprintf(stderr, "Error reading admin password.\n");
+ goto bad;
+ }
+ status = krb_get_pw_in_tkt(myname, myinst, myrealm, PWSERV_NAME,
+ KADM_SINST, ticket_life, admin_passwd);
+ memset(admin_passwd, 0, sizeof(admin_passwd));
+
+ /* Initialize non shared random sequence from session key. */
+ memset(&c, 0, sizeof(c));
+ krb_get_cred(PWSERV_NAME, KADM_SINST, myrealm, &c);
+ des_init_random_number_generator(&c.session);
+ }
+ else
+ status = KDC_PR_UNKNOWN;
+
+ switch(status) {
+ case GT_PW_OK:
+ return(GOOD_PW);
+ case KDC_PR_UNKNOWN:
+ printf("Principal %s does not exist.\n",
+ krb_unparse_name_long(myname, myinst, myrealm));
+ goto bad;
+ case GT_PW_BADPW:
+ printf("Incorrect admin password.\n");
+ goto bad;
+ default:
+ com_err("kadmin", status+krb_err_base,
+ "while getting password tickets");
+ goto bad;
+ }
+
+bad:
+ memset(admin_passwd, 0, sizeof(admin_passwd));
+ dest_tkt();
+ return(BAD_PW);
+}
+
+static void
+srvtab_put_key (int fd, char *filename, char *name, char *inst, char *realm,
+ int8_t kvno, des_cblock key)
+{
+ char sname[ANAME_SZ]; /* name of service */
+ char sinst[INST_SZ]; /* instance of service */
+ char srealm[REALM_SZ]; /* realm of service */
+ int8_t skvno;
+ des_cblock skey;
+
+ lseek(fd, 0, SEEK_SET);
+
+ while(getst(fd, sname, SNAME_SZ) > 0 &&
+ getst(fd, sinst, INST_SZ) > 0 &&
+ getst(fd, srealm, REALM_SZ) > 0 &&
+ read(fd, &skvno, sizeof(skvno)) > 0 &&
+ read(fd, skey, sizeof(skey)) > 0) {
+ if(strcmp(name, sname) == 0 &&
+ strcmp(inst, sinst) == 0 &&
+ strcmp(realm, srealm) == 0) {
+ lseek(fd, lseek(fd,0,SEEK_CUR)-(sizeof(skvno) + sizeof(skey)), SEEK_SET);
+ safe_write(filename, fd, &kvno, sizeof(kvno));
+ safe_write(filename, fd, key, sizeof(des_cblock));
+ return;
+ }
+ }
+ safe_write(filename, fd, name, strlen(name) + 1);
+ safe_write(filename, fd, inst, strlen(inst) + 1);
+ safe_write(filename, fd, realm, strlen(realm) + 1);
+ safe_write(filename, fd, &kvno, sizeof(kvno));
+ safe_write(filename, fd, key, sizeof(des_cblock));
+}
+
+/*
+ * node list of services
+ */
+
+struct srv_ent{
+ char name[SNAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ struct srv_ent *next;
+};
+
+static int
+key_to_key(char *user, char *instance, char *realm, void *arg,
+ des_cblock *key)
+{
+ memcpy(key, arg, sizeof(des_cblock));
+ return 0;
+}
+
+static void
+get_srvtab_ent(int fd, char *filename, char *name, char *inst, char *realm)
+{
+ char chname[128];
+ des_cblock newkey;
+ char old_tktfile[MaxPathLen], new_tktfile[MaxPathLen];
+ char garbage_name[ANAME_SZ];
+ char garbage_inst[ANAME_SZ];
+ CREDENTIALS c;
+ u_int8_t kvno;
+ Kadm_vals values;
+ int ret;
+
+ strncpy(chname, krb_get_phost(inst), sizeof(chname));
+ if(strcmp(inst, chname))
+ fprintf(stderr,
+ "Warning: Are you sure `%s' should not be `%s'?\n",
+ inst, chname);
+
+ memset(&values, 0, sizeof(values));
+ strcpy(values.name, name);
+ strcpy(values.instance, inst);
+ des_new_random_key(&newkey);
+ values.key_low = (newkey[0] << 24) | (newkey[1] << 16)
+ | (newkey[2] << 8) | (newkey[3] << 0);
+ values.key_high = (newkey[4] << 24) | (newkey[5] << 16)
+ | (newkey[6] << 8) | (newkey[7] << 0);
+
+ SET_FIELD(KADM_NAME,values.fields);
+ SET_FIELD(KADM_INST,values.fields);
+ SET_FIELD(KADM_DESKEY,values.fields);
+
+ ret = kadm_mod(&values, &values);
+ if(ret == KADM_NOENTRY)
+ ret = kadm_add(&values);
+ if (ret != KSUCCESS) {
+ warnx ("Couldn't get srvtab entry for %s.%s: %s",
+ name, inst, error_message(ret));
+ return;
+ }
+
+ values.key_low = values.key_high = 0;
+
+ /* get the key version number */
+
+ strcpy(old_tktfile, tkt_string());
+ snprintf(new_tktfile, sizeof(new_tktfile),
+ TKT_ROOT "_ksrvutil-get.%u",
+ (unsigned)getpid());
+ krb_set_tkt_string(new_tktfile);
+
+ ret = krb_get_in_tkt(name, inst, realm, name, inst,
+ 1, key_to_key, NULL, &newkey);
+
+ if (ret == KSUCCESS &&
+ (ret = tf_init(tkt_string(), R_TKT_FIL)) == KSUCCESS &&
+ (ret = tf_get_pname(garbage_name)) == KSUCCESS &&
+ (ret = tf_get_pinst(garbage_inst)) == KSUCCESS &&
+ (ret = tf_get_cred(&c)) == KSUCCESS)
+ kvno = c.kvno;
+ else {
+ warnx ("Could not find the cred in the ticket file");
+ return;
+ }
+
+ tf_close();
+ krb_set_tkt_string(old_tktfile);
+ unlink(new_tktfile);
+
+ if(ret != KSUCCESS) {
+ memset(&newkey, 0, sizeof(newkey));
+ warnx ("Could not get a ticket for %s: %s\n",
+ krb_unparse_name_long(name, inst, realm),
+ krb_get_err_text(ret));
+ return;
+ }
+
+ /* Write the new key & c:o to the srvtab file */
+
+ srvtab_put_key (fd, filename, name, inst, realm, kvno, newkey);
+ memset(&newkey, 0, sizeof(newkey));
+
+ fprintf (stderr, "Added %s\n", krb_unparse_name_long (name, inst, realm));
+}
+
+static void
+ksrvutil_kadm(int fd, char *filename, struct srv_ent *p)
+{
+ int ret;
+ CREDENTIALS c;
+
+ ret = kadm_init_link(PWSERV_NAME, KADM_SINST, u_realm);
+ if (ret != KADM_SUCCESS) {
+ warnx("Couldn't initialize kadmin link: %s", error_message(ret));
+ leave(NULL, 1);
+ }
+
+ ret = krb_get_cred (PWSERV_NAME, KADM_SINST, u_realm, &c);
+ if (ret == KSUCCESS)
+ des_init_random_number_generator (&c.session);
+ else {
+ umask(077);
+
+ /*
+ * create ticket file and get admin tickets
+ */
+ snprintf(tktstring, sizeof(tktstring), TKT_ROOT "_ksrvutil_%d", (int)getpid());
+ krb_set_tkt_string(tktstring);
+ destroyp = TRUE;
+
+ ret = get_admin_password(u_name, u_inst, u_realm);
+ if (ret) {
+ warnx("Couldn't get admin password.");
+ leave(NULL, 1);
+ }
+ }
+ for(;p;){
+ get_srvtab_ent(fd, filename, p->name, p->inst, p->realm);
+ p=p->next;
+ }
+ unlink(tktstring);
+}
+
+static void
+parseinput (char *result, size_t sz, char *val, char *def)
+{
+ char *lim;
+ int inq;
+
+ if (val[0] == '\0') {
+ strncpy (result, def, sz-1);
+ return;
+ }
+ lim = result + sz - 1;
+ inq = 0;
+ while(*val && result < lim) {
+ switch(*val) {
+ case '\'' :
+ inq = !inq;
+ ++val;
+ break;
+ case '\\' :
+ if(!inq)
+ val++;
+ default:
+ *result++ = *val++;
+ break;
+ }
+ }
+ *result = '\0';
+}
+
+void
+ksrvutil_get(int fd, char *filename, 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 */
+ char databuf[BUFSIZ];
+ char local_hostname[100];
+ char prompt[100];
+ struct srv_ent *head=NULL;
+ int i;
+
+ k_gethostname(local_hostname, sizeof(local_hostname));
+ strcpy(local_hostname, krb_get_phost(local_hostname));
+
+ if (argc)
+ for(i=0; i < argc; ++i) {
+ struct srv_ent *p=malloc(sizeof(*p));
+
+ if(p == NULL) {
+ warnx ("out of memory in malloc");
+ leave(NULL,1);
+ }
+ p->next = head;
+ strcpy (p->realm, u_realm);
+ if (kname_parse (p->name, p->inst, p->realm, argv[i]) !=
+ KSUCCESS) {
+ warnx ("parse error on '%s'\n", argv[i]);
+ free(p);
+ continue;
+ }
+ if (p->name[0] == '\0')
+ strcpy(p->name, "rcmd");
+ if (p->inst[0] == '\0')
+ strcpy(p->inst, local_hostname);
+ if (p->realm[0] == '\0')
+ strcpy(p->realm, u_realm);
+ head = p;
+ }
+
+ else
+ do{
+ safe_read_stdin("Name [rcmd]: ", databuf, sizeof(databuf));
+ parseinput (sname, sizeof(sname), databuf, "rcmd");
+
+ snprintf(prompt, sizeof(prompt), "Instance [%s]: ", local_hostname);
+ safe_read_stdin(prompt, databuf, sizeof(databuf));
+ parseinput (sinst, sizeof(sinst), databuf, local_hostname);
+
+ snprintf(prompt, sizeof(prompt), "Realm [%s]: ", u_realm);
+ safe_read_stdin(prompt, databuf, sizeof(databuf));
+ parseinput (srealm, sizeof(srealm), databuf, u_realm);
+
+ if(yn("Is this correct?")){
+ struct srv_ent *p=(struct srv_ent*)malloc(sizeof(struct srv_ent));
+ p->next=head;
+ head=p;
+ strcpy(p->name, sname);
+ strcpy(p->inst, sinst);
+ strcpy(p->realm, srealm);
+ }
+ }while(ny("Add more keys?"));
+
+
+ ksrvutil_kadm(fd, filename, head);
+
+ {
+ struct srv_ent *p=head, *q;
+ while(p){
+ q=p;
+ p=p->next;
+ free(q);
+ }
+ }
+
+}
diff --git a/crypto/kerberosIV/kadmin/new_pwd.c b/crypto/kerberosIV/kadmin/new_pwd.c
new file mode 100644
index 0000000..88fb7a9
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/new_pwd.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "kadm_locl.h"
+
+RCSID("$Id: new_pwd.c,v 1.11 1997/05/02 14:28:54 assar Exp $");
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else
+#define read_long_pw_string des_read_pw_string
+#endif
+
+static char *
+check_pw (char *pword)
+{
+ if (strlen(pword) == 0)
+ return "Null passwords are not allowed - Please enter a longer password.";
+
+ if (strlen(pword) < MIN_KPW_LEN)
+ return "Password is to short - Please enter a longer password.";
+
+ /* Don't allow all lower case passwords regardless of length */
+ {
+ char *t;
+ for (t = pword; *t && islower(*t); t++)
+ ;
+ if (*t == 0)
+ return "Please don't use an all-lower case password.\n"
+ "\tUnusual capitalization, delimiter characters or "
+ "digits are suggested.";
+ }
+
+ return NULL;
+}
+
+int
+get_pw_new_pwd(char *pword, int pwlen, krb_principal *pr, int print_realm)
+{
+ char ppromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
+ char npromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
+
+ char p[MAX_K_NAME_SZ];
+
+ char local_realm[REALM_SZ];
+ int status;
+ char *expl;
+
+ /*
+ * We don't care about failure; this is to determine whether or
+ * not to print the realm in the prompt for a new password.
+ */
+ krb_get_lrealm(local_realm, 1);
+
+ if (strcmp(local_realm, pr->realm))
+ print_realm++;
+
+ {
+ char *q;
+ krb_unparse_name_r(pr, p);
+ if(print_realm == 0 && (q = strrchr(p, '@')))
+ *q = 0;
+ }
+
+ snprintf(ppromp, sizeof(ppromp), "Old password for %s:", p);
+ if (read_long_pw_string(pword, pwlen-1, ppromp, 0)) {
+ fprintf(stderr, "Error reading old password.\n");
+ return -1;
+ }
+
+ status = krb_get_pw_in_tkt(pr->name, pr->instance, pr->realm,
+ PWSERV_NAME, KADM_SINST, 1, pword);
+ if (status != KSUCCESS) {
+ if (status == INTK_BADPW) {
+ printf("Incorrect old password.\n");
+ return -1;
+ }
+ else {
+ fprintf(stderr, "Kerberos error: %s\n", krb_get_err_text(status));
+ return -1;
+ }
+ }
+ memset(pword, 0, pwlen);
+
+ do {
+ char verify[MAX_KPW_LEN];
+ snprintf(npromp, sizeof(npromp), "New Password for %s:",p);
+ if (read_long_pw_string(pword, pwlen-1, npromp, 0)) {
+ fprintf(stderr,
+ "Error reading new password, password unchanged.\n");
+ return -1;
+ }
+ expl = check_pw (pword);
+ if (expl) {
+ printf("\n\t%s\n\n", expl);
+ continue;
+ }
+ /* Now we got an ok password, verify it. */
+ snprintf(npromp, sizeof(npromp), "Verifying New Password for %s:", p);
+ if (read_long_pw_string(verify, MAX_KPW_LEN-1, npromp, 0)) {
+ fprintf(stderr,
+ "Error reading new password, password unchanged.\n");
+ return -1;
+ }
+ if (strcmp(pword, verify) != 0) {
+ printf("Verify failure - try again\n");
+ expl = ""; /* continue */
+ }
+ } while (expl);
+ return 0;
+}
diff --git a/crypto/kerberosIV/kadmin/pw_check.c b/crypto/kerberosIV/kadmin/pw_check.c
new file mode 100644
index 0000000..ac6912b
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/pw_check.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "kadm_locl.h"
+
+RCSID("$Id: pw_check.c,v 1.13 1997/04/01 08:17:50 joda Exp $");
+
+/*
+ * kadm_pw_check
+ *
+ * pw : new password or "" if none passed
+ * newkey : key for pw as passed from client
+ * strings : interesting strings to check for
+ *
+ * returns NULL if pw is ok, else an explanatory string
+ */
+int
+kadm_pw_check(char *pw, des_cblock *newkey, char **pw_msg,
+ char **strings)
+{
+ des_cblock pwkey;
+ int status=KADM_SUCCESS;
+
+ if (pw == NULL || *pw == '\0')
+ return status; /* XXX - Change this later */
+
+#ifndef NO_PW_CHECK
+ *pw_msg = NULL;
+ des_string_to_key(pw, &pwkey); /* Check AFS string to key also! */
+ if (memcmp(pwkey, *newkey, sizeof(pwkey)) != 0)
+ {
+ /* no password or bad key */
+ status=KADM_PW_MISMATCH;
+ *pw_msg = "Password doesn't match supplied DES key";
+ }
+ else if (strlen(pw) < MIN_KPW_LEN)
+ {
+ status = KADM_INSECURE_PW;
+ *pw_msg="Password is too short";
+ }
+
+#ifdef DICTPATH
+ *pw_msg = FascistCheck(pw, DICTPATH, strings);
+ if (*pw_msg)
+ return KADM_INSECURE_PW;
+#endif
+
+ memset(pwkey, 0, sizeof(pwkey));
+#endif
+
+ return status;
+}
diff --git a/crypto/kerberosIV/kadmin/pw_check.h b/crypto/kerberosIV/kadmin/pw_check.h
new file mode 100644
index 0000000..c5a5d69
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/pw_check.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $Id: pw_check.h,v 1.6 1997/04/01 08:17:50 joda Exp $
+ */
+
+int kadm_pw_check(char *pw, des_cblock *newkey,
+ char **pw_msg, char **strings);
+
OpenPOWER on IntegriCloud