summaryrefslogtreecommitdiffstats
path: root/crypto/kerberosIV/kadmin
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>1997-09-04 06:04:33 +0000
committermarkm <markm@FreeBSD.org>1997-09-04 06:04:33 +0000
commita8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8 (patch)
tree0b84977f19022a965f8c6145f067f951173f6290 /crypto/kerberosIV/kadmin
downloadFreeBSD-src-a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8.zip
FreeBSD-src-a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8.tar.gz
Initial import of KTH eBones. This has been cleaned up to only include
the "core" Kerberos functionality. The rest of the userland will get their own changes later.
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