diff options
author | markm <markm@FreeBSD.org> | 1999-09-19 14:19:32 +0000 |
---|---|---|
committer | markm <markm@FreeBSD.org> | 1999-09-19 14:19:32 +0000 |
commit | fe83e8abf357ee11114856a5278bb38431a9517c (patch) | |
tree | 36ce70fe2e8419130e546c38a7790e8ab224a362 /crypto/kerberosIV/kadmin | |
parent | a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8 (diff) | |
download | FreeBSD-src-fe83e8abf357ee11114856a5278bb38431a9517c.zip FreeBSD-src-fe83e8abf357ee11114856a5278bb38431a9517c.tar.gz |
Clean import of KTH krb4-0.10.1.
Diffstat (limited to 'crypto/kerberosIV/kadmin')
-rw-r--r-- | crypto/kerberosIV/kadmin/Makefile.in | 54 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/admin_server.c | 78 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/kadm_funcs.c | 72 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/kadm_locl.h | 45 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/kadm_ser_wrap.c | 84 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/kadmin.c | 918 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/kpasswd.c | 36 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/ksrvutil.c | 224 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/ksrvutil.h | 7 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/ksrvutil_get.c | 231 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/new_pwd.c | 35 | ||||
-rw-r--r-- | crypto/kerberosIV/kadmin/random_password.c | 165 |
12 files changed, 1288 insertions, 661 deletions
diff --git a/crypto/kerberosIV/kadmin/Makefile.in b/crypto/kerberosIV/kadmin/Makefile.in index 947248e..0227ad6 100644 --- a/crypto/kerberosIV/kadmin/Makefile.in +++ b/crypto/kerberosIV/kadmin/Makefile.in @@ -1,18 +1,20 @@ -# $Id: Makefile.in,v 1.37 1997/05/02 17:50:35 assar Exp $ +# $Id: Makefile.in,v 1.47 1999/03/10 19:01:13 joda Exp $ SHELL = /bin/sh srcdir = @srcdir@ VPATH = @srcdir@ -topdir=.. +top_builddir=.. CC = @CC@ +LINK = @LINK@ AR = ar RANLIB = @RANLIB@ LN_S = @LN_S@ DEFS = @DEFS@ -CFLAGS = @CFLAGS@ +CFLAGS = @CFLAGS@ $(WFLAGS) +WFLAGS = @WFLAGS@ LD_FLAGS = @LD_FLAGS@ LIB_tgetent = @LIB_tgetent@ @@ -43,11 +45,11 @@ 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 + new_pwd.c random_password.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 + new_pwd.o random_password.o all: $(PROGS) @@ -55,32 +57,32 @@ 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) $< + $(CC) -c $(DEFS) -I../include -I$(srcdir) $(CFLAGS) $(CPPFLAGS) $< install: all - $(MKINSTALLDIRS) $(bindir) + $(MKINSTALLDIRS) $(DESTDIR)$(bindir) for x in $(PROG_BIN); do \ - $(INSTALL_PROGRAM) $$x $(bindir)/`echo $$x | sed '$(transform)'`; \ + $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/`echo $$x | sed '$(transform)'`; \ done - $(MKINSTALLDIRS) $(sbindir) + $(MKINSTALLDIRS) $(DESTDIR)$(sbindir) for x in $(PROG_SBIN); do \ - $(INSTALL_PROGRAM) $$x $(sbindir)/`echo $$x | sed '$(transform)'`; \ + $(INSTALL_PROGRAM) $$x $(DESTDIR)$(sbindir)/`echo $$x | sed '$(transform)'`; \ done - $(MKINSTALLDIRS) $(libexecdir) + $(MKINSTALLDIRS) $(DESTDIR)$(libexecdir) for x in $(PROG_LIBEXEC); do \ - $(INSTALL_PROGRAM) $$x $(libexecdir)/`echo $$x | sed '$(transform)'`; \ + $(INSTALL_PROGRAM) $$x $(DESTDIR)$(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)'`; \ + rm -f $(DESTDIR)$(bindir)/`echo $$x | sed '$(transform)'`; \ done for x in $(PROG_SBIN); do \ - rm -f $(sbindir)/`echo $$x | sed '$(transform)'`; \ + rm -f $(DESTDIR)$(sbindir)/`echo $$x | sed '$(transform)'`; \ done for x in $(PROG_LIBEXEC); do \ - rm -f $(libexecdir)/`echo $$x | sed '$(transform)'`; \ + rm -f $(DESTDIR)$(libexecdir)/`echo $$x | sed '$(transform)'`; \ done TAGS: $(SOURCES) @@ -99,27 +101,25 @@ distclean: clean 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 +KLIB=-L../lib/kadm -lkadm -L../lib/krb -lkrb -L../lib/des -ldes -L../lib/com_err -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) + $(LINK) $(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) +kadmin_OBJECTS = kadmin.o new_pwd.o random_password.o + +kadmin$(EXECSUFFIX): $(kadmin_OBJECTS) + $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ $(kadmin_OBJECTS) $(KLIB) -L../lib/sl -lsl $(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) + $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ $(KADMIND_OBJECTS) -L../lib/kdb -lkdb -L../lib/acl -lacl $(KLIB) $(CRACKLIB) $(LIBROKEN) $(LIB_DBM) $(LIBS) ksrvutil$(EXECSUFFIX): ksrvutil.o ksrvutil_get.o - $(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ ksrvutil.o ksrvutil_get.o $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN) + $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ ksrvutil.o ksrvutil_get.o $(KLIB) $(LIBROKEN) $(LIBS) $(OBJECTS): ../include/config.h + +.PHONY: all Wall install uninstall check clean mostlyclean distclean realclean diff --git a/crypto/kerberosIV/kadmin/admin_server.c b/crypto/kerberosIV/kadmin/admin_server.c index 2654c77..6421ac6 100644 --- a/crypto/kerberosIV/kadmin/admin_server.c +++ b/crypto/kerberosIV/kadmin/admin_server.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 1989 by the Massachusetts Institute of Technology Export of this software from the United States of America is assumed @@ -30,7 +30,7 @@ or implied warranty. #include "kadm_locl.h" -RCSID("$Id: admin_server.c,v 1.41 1997/05/27 15:52:53 bg Exp $"); +RCSID("$Id: admin_server.c,v 1.47 1999/07/07 12:41:07 assar Exp $"); /* Almost all procs and such need this, so it is global */ admin_params prm; /* The command line parameters struct */ @@ -40,7 +40,7 @@ char *acldir = DEFAULT_ACL_DIR; static char krbrlm[REALM_SZ]; static unsigned pidarraysize = 0; -static int *pidarray = (int *)0; +static int *pidarray = NULL; static int exit_now = 0; @@ -138,15 +138,19 @@ process_client(int fd, struct sockaddr_in *who) 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); + { + int on = 1; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, + (void *)&on, sizeof(on)) < 0) + krb_log("setsockopt keepalive: %d",errno); + } #endif server_parm.recv_addr = *who; @@ -158,18 +162,20 @@ process_client(int fd, struct sockaddr_in *who) /* need to set service key to changepw.KRB_MASTER */ status = kerb_get_principal(server_parm.sname, server_parm.sinst, &service, - 1, &more); + 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); + dat_len = KADM_VERSIZE + 4; + dat = (u_char *) malloc(dat_len); + if (dat == NULL) { + krb_log("malloc failed"); + cleanexit(4); + } pdat = (char *) dat; - retcode = htonl((u_int32_t) KADM_DB_INUSE); - strncpy(pdat, KADM_ULOSE, KADM_VERSIZE); - memcpy(pdat+KADM_VERSIZE, &retcode, sizeof(retcode)); + memcpy(pdat, KADM_ULOSE, KADM_VERSIZE); + krb_put_int (KADM_DB_INUSE, pdat + KADM_VERSIZE, 4, 4); goto out; } else if (!status) { krb_log("no service %s.%s",server_parm.sname, server_parm.sinst); @@ -185,6 +191,15 @@ process_client(int fd, struct sockaddr_in *who) memset(skey, 0, sizeof(skey)); while (1) { + void *errpkt; + + errpkt = malloc(KADM_VERSIZE + 4); + if (errpkt == NULL) { + krb_log("malloc: no memory"); + close(fd); + cleanexit(4); + } + if ((retval = krb_net_read(fd, &dlen, sizeof(u_short))) != sizeof(u_short)) { if (retval < 0) @@ -199,7 +214,7 @@ process_client(int fd, struct sockaddr_in *who) } dat_len = ntohs(dlen); dat = (u_char *) malloc(dat_len); - if (!dat) { + if (dat == NULL) { krb_log("malloc: No memory"); close(fd); cleanexit(4); @@ -215,7 +230,7 @@ process_client(int fd, struct sockaddr_in *who) if (exit_now) { cleanexit(0); } - if ((retval = kadm_ser_in(&dat,&dat_len)) != KADM_SUCCESS) + if ((retval = kadm_ser_in(&dat, &dat_len, errpkt)) != KADM_SUCCESS) krb_log("processing request: %s", error_message(retval)); /* kadm_ser_in did the processing and returned stuff in @@ -307,6 +322,8 @@ kadm_listen(void) #ifndef DEBUG /* if you want a sep daemon for each server */ if ((pid = fork())) { + void *tmp; + /* parent */ if (pid < 0) { krb_log("fork: %s",error_message(errno)); @@ -315,12 +332,14 @@ kadm_listen(void) } /* fork succeded: keep tabs on child */ close(peer_fd); - if (pidarray) { - pidarray = (int *)realloc(pidarray, ++pidarraysize); - pidarray[pidarraysize-1] = pid; + tmp = realloc(pidarray, + (pidarraysize + 1) * sizeof(*pidarray)); + if(tmp == NULL) { + krb_log ("malloc: no memory. pid %u on its own", + (unsigned)pid); } else { - pidarray = (int *)malloc(pidarraysize = 1); - pidarray[0] = pid; + pidarray = tmp; + pidarray[pidarraysize++] = pid; } } else { /* child */ @@ -356,18 +375,20 @@ main(int argc, char **argv) /* admin_server main routine */ { int errval; int c; + struct in_addr i_addr; set_progname (argv[0]); umask(077); /* Create protected files */ + i_addr.s_addr = INADDR_ANY; /* 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) + while ((c = getopt(argc, argv, "f:hmnd:a:r:i:")) != EOF) switch(c) { case 'f': /* Syslog file name change */ prm.sysfile = optarg; @@ -388,15 +409,22 @@ main(int argc, char **argv) /* admin_server main routine */ optarg, error_message(errval)); break; case 'r': - strncpy(krbrlm, optarg, sizeof(krbrlm) - 1); + strcpy_truncate (krbrlm, optarg, sizeof(krbrlm)); + break; + case 'i': + /* Only listen on this address */ + if(inet_aton (optarg, &i_addr) == 0) { + fprintf (stderr, "Bad address: %s\n", optarg); + exit (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]"); + errx(1, "Usage: kadmind [-h] [-n] [-m] [-r realm] [-d dbname] [-f filename] [-a acldir] [-i address_to_listen_on]"); } if (krbrlm[0] == 0) - if (krb_get_lrealm(krbrlm, 0) != KSUCCESS) + if (krb_get_lrealm(krbrlm, 1) != KSUCCESS) errx (1, "Unable to get local realm. Fix krb.conf or use -r."); printf("KADM Server %s initializing\n",KADM_VERSTR); @@ -414,7 +442,7 @@ main(int argc, char **argv) /* admin_server main routine */ byebye(); } /* set up the server_parm struct */ - if ((errval = kadm_ser_init(prm.inter, krbrlm))==KADM_SUCCESS) { + if ((errval = kadm_ser_init(prm.inter, krbrlm, i_addr))==KADM_SUCCESS) { kerb_fini(); /* Close the Kerberos database-- will re-open later */ errval = kadm_listen(); /* listen for calls to server from diff --git a/crypto/kerberosIV/kadmin/kadm_funcs.c b/crypto/kerberosIV/kadmin/kadm_funcs.c index 34a34b0..378d0d7 100644 --- a/crypto/kerberosIV/kadmin/kadm_funcs.c +++ b/crypto/kerberosIV/kadmin/kadm_funcs.c @@ -30,7 +30,7 @@ or implied warranty. #include "kadm_locl.h" -RCSID("$Id: kadm_funcs.c,v 1.16 1997/05/02 14:28:49 assar Exp $"); +RCSID("$Id: kadm_funcs.c,v 1.17 1998/06/09 19:24:53 joda Exp $"); static int check_access(char *pname, char *pinst, char *prealm, enum acl_types acltype) @@ -94,8 +94,14 @@ kadm_add_entry (char *rname, char *rinstance, char *rrealm, 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)); + strcpy_truncate(admin, + krb_unparse_name_long(rname, rinstance, rrealm), + sizeof(admin)); + strcpy_truncate(victim, + krb_unparse_name_long(valsin->name, + valsin->instance, + NULL), + sizeof(victim)); krb_log("ADD: %s by %s", victim, admin); @@ -118,8 +124,8 @@ kadm_add_entry (char *rname, char *rinstance, char *rrealm, } 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); + strcpy_truncate(data_i.name, valsin->name, ANAME_SZ); + strcpy_truncate(data_i.instance, valsin->instance, INST_SZ); if (!IS_FIELD(KADM_EXPDATE,valsin->fields)) data_i.exp_date = default_princ.exp_date; @@ -153,9 +159,9 @@ kadm_add_entry (char *rname, char *rinstance, char *rrealm, } 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); + strcpy_truncate(data_i.mod_name, rname, sizeof(data_i.mod_name)); + strcpy_truncate(data_i.mod_instance, rinstance, + sizeof(data_i.mod_instance)); numfound = kerb_put_principal(&data_i, 1); if (numfound == -1) { @@ -189,8 +195,14 @@ kadm_delete_entry (char *rname, char *rinstance, char *rrealm, 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)); + strcpy_truncate(admin, + krb_unparse_name_long(rname, rinstance, rrealm), + sizeof(admin)); + strcpy_truncate(victim, + krb_unparse_name_long(valsin->name, + valsin->instance, + NULL), + sizeof(victim)); krb_log("DELETE: %s by %s", victim, admin); @@ -232,8 +244,14 @@ kadm_get_entry (char *rname, char *rinstance, char *rrealm, 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)); + strcpy_truncate(admin, + krb_unparse_name_long(rname, rinstance, rrealm), + sizeof(admin)); + strcpy_truncate(victim, + krb_unparse_name_long(valsin->name, + valsin->instance, + NULL), + sizeof(victim)); krb_log("GET: %s by %s", victim, admin); @@ -272,8 +290,14 @@ kadm_mod_entry (char *rname, char *rinstance, char *rrealm, 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)); + strcpy_truncate(admin, + krb_unparse_name_long(rname, rinstance, rrealm), + sizeof(admin)); + strcpy_truncate(victim, + krb_unparse_name_long(valsin->name, + valsin->instance, + NULL), + sizeof(victim)); krb_log("MOD: %s by %s", victim, admin); @@ -292,8 +316,8 @@ kadm_mod_entry (char *rname, char *rinstance, char *rrealm, 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); + strcpy_truncate(data_o.name, valsin->name, ANAME_SZ); + strcpy_truncate(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)) @@ -320,9 +344,9 @@ kadm_mod_entry (char *rname, char *rinstance, char *rrealm, } 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); + strcpy_truncate(data_o.mod_name, rname, sizeof(data_o.mod_name)); + strcpy_truncate(data_o.mod_instance, rinstance, + sizeof(data_o.mod_instance)); more = kerb_put_principal(&data_o, 1); memset(&data_o, 0, sizeof(data_o)); @@ -363,7 +387,9 @@ kadm_change (char *rname, char *rinstance, char *rrealm, unsigned char *newpw) char admin[MAX_K_NAME_SZ]; - strcpy(admin, krb_unparse_name_long(rname, rinstance, rrealm)); + strcpy_truncate(admin, + krb_unparse_name_long(rname, rinstance, rrealm), + sizeof(admin)); krb_log("CHANGE: %s", admin); @@ -390,9 +416,9 @@ kadm_change (char *rname, char *rinstance, char *rrealm, unsigned char *newpw) 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); + strcpy_truncate(data_o.mod_name, rname, sizeof(data_o.mod_name)); + strcpy_truncate(data_o.mod_instance, rinstance, + sizeof(data_o.mod_instance)); more = kerb_put_principal(&data_o, 1); memset(local_pw, 0, sizeof(local_pw)); memset(&data_o, 0, sizeof(data_o)); diff --git a/crypto/kerberosIV/kadmin/kadm_locl.h b/crypto/kerberosIV/kadmin/kadm_locl.h index 07f9093..44708d9 100644 --- a/crypto/kerberosIV/kadmin/kadm_locl.h +++ b/crypto/kerberosIV/kadmin/kadm_locl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -36,7 +36,7 @@ * SUCH DAMAGE. */ -/* $Id: kadm_locl.h,v 1.25 1997/05/20 18:40:43 bg Exp $ */ +/* $Id: kadm_locl.h,v 1.30 1998/11/18 19:44:05 assar Exp $ */ #include "config.h" #include "protos.h" @@ -94,6 +94,9 @@ #ifdef HAVE_NETDB_H #include <netdb.h> #endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif #ifdef HAVE_SYSLOG_H #include <syslog.h> @@ -103,6 +106,9 @@ #ifdef SOCKS #include <socks.h> +/* This doesn't belong here. */ +struct tm *localtime(const time_t *); +struct hostent *gethostbyname(const char *); #endif #include <roken.h> @@ -118,6 +124,8 @@ #include <kadm_err.h> #include <acl.h> +#include <krb_log.h> + #include "kadm_server.h" #include "pw_check.h" @@ -129,20 +137,23 @@ 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)); +int kadm_change (char *, char *, char *, des_cblock); +int kadm_add_entry (char *, char *, char *, Kadm_vals *, Kadm_vals *); +int kadm_mod_entry (char *, char *, char *, Kadm_vals *, Kadm_vals *, Kadm_vals *); +int kadm_get_entry (char *, char *, char *, Kadm_vals *, u_char *, Kadm_vals *); +int kadm_delete_entry (char *, char *, char *, Kadm_vals *); +int kadm_ser_cpw (u_char *, int, AUTH_DAT *, u_char **, int *); +int kadm_ser_add (u_char *, int, AUTH_DAT *, u_char **, int *); +int kadm_ser_mod (u_char *, int, AUTH_DAT *, u_char **, int *); +int kadm_ser_get (u_char *, int, AUTH_DAT *, u_char **, int *); +int kadm_ser_delete (u_char *, int, AUTH_DAT *, u_char **, int *); +int kadm_ser_init (int inter, char realm[], struct in_addr); +int kadm_ser_in (u_char **, int *, u_char *); + +int get_pw_new_pwd (char *pword, int pwlen, krb_principal *pr, int print_realm); /* cracklib */ -char *FascistCheck __P((char *password, char *path, char **strings)); +char *FascistCheck (char *password, char *path, char **strings); + +void +random_password(char *pw, size_t len, u_int32_t *low, u_int32_t *high); diff --git a/crypto/kerberosIV/kadmin/kadm_ser_wrap.c b/crypto/kerberosIV/kadmin/kadm_ser_wrap.c index 6909a9f..c95af04 100644 --- a/crypto/kerberosIV/kadmin/kadm_ser_wrap.c +++ b/crypto/kerberosIV/kadmin/kadm_ser_wrap.c @@ -30,7 +30,7 @@ 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 $"); +RCSID("$Id: kadm_ser_wrap.c,v 1.24 1998/06/13 00:45:52 assar Exp $"); /* GLOBAL */ Kadm_Server server_parm; @@ -40,21 +40,27 @@ kadm_ser_init set up the server_parm structure */ int -kadm_ser_init(int inter, char *realm) - /* interactive or from file */ - +kadm_ser_init(int inter, /* interactive or from file */ + char *realm, + struct in_addr addr) { struct hostent *hp; char hostname[MaxHostNameLen]; init_kadm_err_tbl(); init_krb_err_tbl(); - if (k_gethostname(hostname, sizeof(hostname))) + if (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); + strcpy_truncate(server_parm.sname, + PWSERV_NAME, + sizeof(server_parm.sname)); + strcpy_truncate(server_parm.sinst, + KRB_MASTER, + sizeof(server_parm.sinst)); + strcpy_truncate(server_parm.krbrlm, + realm, + sizeof(server_parm.krbrlm)); server_parm.admin_fd = -1; /* setting up the addrs */ @@ -66,7 +72,7 @@ kadm_ser_init(int inter, char *realm) 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; + server_parm.admin_addr.sin_addr = addr; /* setting up the database */ if (kdb_get_master_key((inter==1), &server_parm.master_key, server_parm.master_key_schedule) != 0) @@ -78,19 +84,18 @@ kadm_ser_init(int inter, char *realm) return KADM_SUCCESS; } -static void errpkt(u_char **dat, int *dat_len, int code) -{ - u_int32_t retcode; - char *pdat; +/* + * + */ +static void +errpkt(u_char *errdat, u_char **dat, int *dat_len, int code) +{ 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; + *dat_len = KADM_VERSIZE + 4; + memcpy(errdat, KADM_ULOSE, KADM_VERSIZE); + krb_put_int (code, errdat + KADM_VERSIZE, 4, 4); + *dat = errdat; } /* @@ -98,7 +103,7 @@ kadm_ser_in unwrap the data stored in dat, process, and return it. */ int -kadm_ser_in(u_char **dat, int *dat_len) +kadm_ser_in(u_char **dat, int *dat_len, u_char *errdat) { u_char *in_st; /* pointer into the sent packet */ int in_len,retc; /* where in packet we are, for @@ -113,7 +118,7 @@ kadm_ser_in(u_char **dat, int *dat_len) int retval, retlen; if (strncmp(KADM_VERSTR, (char *)*dat, KADM_VERSIZE)) { - errpkt(dat, dat_len, KADM_BAD_VER); + errpkt(errdat, dat, dat_len, KADM_BAD_VER); return KADM_BAD_VER; } in_len = KADM_VERSIZE; @@ -128,7 +133,7 @@ kadm_ser_in(u_char **dat, int *dat_len) 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); + errpkt(errdat, dat, dat_len, retc + krb_err_base); return retc + krb_err_base; } @@ -142,7 +147,7 @@ kadm_ser_in(u_char **dat, int *dat_len) #endif if (ncksum!=ad.checksum) { /* yow, are we correct yet */ clr_cli_secrets(); - errpkt(dat, dat_len,KADM_BAD_CHK); + errpkt(errdat, dat, dat_len, KADM_BAD_CHK); return KADM_BAD_CHK; } #ifdef NOENCRYPTION @@ -154,7 +159,7 @@ kadm_ser_in(u_char **dat, int *dat_len) &server_parm.recv_addr, &server_parm.admin_addr, &msg_st))) { clr_cli_secrets(); - errpkt(dat, dat_len,retc + krb_err_base); + errpkt(errdat, dat, dat_len, retc + krb_err_base); return retc + krb_err_base; } switch (msg_st.app_data[0]) { @@ -180,24 +185,31 @@ kadm_ser_in(u_char **dat, int *dat_len) break; default: clr_cli_secrets(); - errpkt(dat, dat_len, KADM_NO_OPCODE); + errpkt(errdat, dat, dat_len, KADM_NO_OPCODE); return KADM_NO_OPCODE; } /* Now seal the response back into a priv msg */ + tmpdat = (u_char *) malloc(retlen + KADM_VERSIZE + 4); + if (tmpdat == NULL) { + clr_cli_secrets(); + errpkt(errdat, dat, dat_len, KADM_NOMEM); + return KADM_NOMEM; + } 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)); + memcpy(tmpdat, KADM_VERSTR, KADM_VERSIZE); + krb_put_int(retval, tmpdat + KADM_VERSIZE, 4, 4); if (retlen) { - memcpy((char *)tmpdat + KADM_VERSIZE + sizeof(u_int32_t), retdat, - retlen); + memcpy(tmpdat + KADM_VERSIZE + 4, retdat, retlen); free(retdat); } /* slop for mk_priv stuff */ - *dat = (u_char *) malloc((unsigned) (retlen + KADM_VERSIZE + - sizeof(u_int32_t) + 200)); + *dat = (u_char *) malloc(retlen + KADM_VERSIZE + + sizeof(u_int32_t) + 200); + if (*dat == NULL) { + clr_cli_secrets(); + errpkt(errdat, dat, dat_len, KADM_NOMEM); + return KADM_NOMEM; + } if ((*dat_len = krb_mk_priv(tmpdat, *dat, (u_int32_t) (retlen + KADM_VERSIZE + sizeof(u_int32_t)), @@ -205,7 +217,7 @@ kadm_ser_in(u_char **dat, int *dat_len) &ad.session, &server_parm.admin_addr, &server_parm.recv_addr)) < 0) { clr_cli_secrets(); - errpkt(dat, dat_len, KADM_NO_ENCRYPT); + errpkt(errdat, dat, dat_len, KADM_NO_ENCRYPT); return KADM_NO_ENCRYPT; } clr_cli_secrets(); diff --git a/crypto/kerberosIV/kadmin/kadmin.c b/crypto/kerberosIV/kadmin/kadmin.c index f117b6b..340a914 100644 --- a/crypto/kerberosIV/kadmin/kadmin.c +++ b/crypto/kerberosIV/kadmin/kadmin.c @@ -28,19 +28,24 @@ or implied warranty. */ #include "kadm_locl.h" +#include "getarg.h" +#include "parse_time.h" -RCSID("$Id: kadmin.c,v 1.48 1997/05/13 09:43:06 bg Exp $"); +RCSID("$Id: kadmin.c,v 1.59.2.1 1999/09/02 08:51:59 joda 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 int change_password(int argc, char **argv); +static int change_key(int argc, char **argv); +static int change_admin_password(int argc, char **argv); +static int add_new_key(int argc, char **argv); +static int del_entry(int argc, char **argv); +static int get_entry(int argc, char **argv); +static int mod_entry(int argc, char **argv); +static int help(int argc, char **argv); +static int clean_up_cmd(int argc, char **argv); +static int quit_cmd(int argc, char **argv); +static int set_timeout_cmd(int argc, char **argv); + +static int set_timeout(const char *); static SL_cmd cmds[] = { {"change_password", change_password, "Change a user's password"}, @@ -59,6 +64,8 @@ static SL_cmd cmds[] = { {"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"}, + {"set_timeout", set_timeout_cmd, "Set ticket timeout"}, + {"timeout" }, {"exit", quit_cmd, "Exit program"}, {"quit"}, {"help", help, "Help"}, @@ -81,7 +88,6 @@ static SL_cmd cmds[] = { 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 @@ -139,31 +145,41 @@ get_attr(Kadm_vals *vals) SET_FIELD(KADM_ATTR,vals->fields); } +static time_t +parse_expdate(const char *str) +{ + struct tm edate; + + memset(&edate, 0, sizeof(edate)); + if (sscanf(str, "%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 */ + } + if(krb_check_tm (edate)) + return -1; + edate.tm_year -= 1900; + return tm2time (edate, 1); +} + static void get_expdate(Kadm_vals *vals) { char buff[BUFSIZ]; - struct tm edate; + time_t t; - memset(&edate, 0, sizeof(edate)); do { - printf("Expiration date (enter yyyy-mm-dd) ? [%.24s] ", - asctime(k_localtime(&vals->exp_date))); + strftime(buff, sizeof(buff), "%Y-%m-%d", k_localtime(&vals->exp_date)); + printf("Expiration date (enter yyyy-mm-dd) ? [%s] ", buff); 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); + t = parse_expdate(buff); + }while(t < 0); + vals->exp_date = t; SET_FIELD(KADM_EXPDATE,vals->fields); } @@ -172,9 +188,11 @@ princ_exists(char *name, char *instance, char *realm) { int status; + int old = krb_use_admin_server(1); status = krb_get_pw_in_tkt(name, instance, realm, KRB_TICKET_GRANTING_TICKET, realm, 1, ""); + krb_use_admin_server(old); if ((status == KSUCCESS) || (status == INTK_BADPW)) return(PE_YES); @@ -184,15 +202,12 @@ princ_exists(char *name, char *instance, char *realm) return(PE_UNSURE); } -static int -get_password(u_int32_t *low, u_int32_t *high, char *prompt, int byteswap) +static void +passwd_to_lowhigh(u_int32_t *low, u_int32_t *high, char *password, 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) { + if (strlen(password) == 0) { printf("Using random password.\n"); #ifdef NOENCRYPTION memset(newkey, 0, sizeof(newkey)); @@ -203,9 +218,8 @@ get_password(u_int32_t *low, u_int32_t *high, char *prompt, int byteswap) #ifdef NOENCRYPTION memset(newkey, 0, sizeof(newkey)); #else - des_string_to_key(new_passwd, &newkey); + des_string_to_key(password, &newkey); #endif - memset(new_passwd, 0, sizeof(new_passwd)); } memcpy(low, newkey, 4); @@ -221,6 +235,17 @@ get_password(u_int32_t *low, u_int32_t *high, char *prompt, int byteswap) *low = htonl(*low); *high = htonl(*high); } +} + +static int +get_password(u_int32_t *low, u_int32_t *high, char *prompt, int byteswap) +{ + char new_passwd[MAX_KPW_LEN]; /* new password */ + + if (read_long_pw_string(new_passwd, sizeof(new_passwd)-1, prompt, 1)) + return(BAD_PW); + passwd_to_lowhigh (low, high, new_passwd, byteswap); + memset (new_passwd, 0, sizeof(new_passwd)); return(GOOD_PW); } @@ -232,23 +257,23 @@ get_admin_password(void) 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; - } + alarm(0); + /* 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)); + snprintf(prompt, sizeof(prompt), "%s's Password: ", + krb_unparse_name(&pr)); if (read_long_pw_string(admin_passwd, sizeof(admin_passwd)-1, prompt, 0)) { @@ -259,7 +284,7 @@ get_admin_password(void) 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); @@ -289,107 +314,144 @@ get_admin_password(void) 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); -} +static char *principal; +static char *username; +static char *realm; +static char *timeout; +static int tflag; /* use existing tickets */ +static int mflag; /* compatibility */ +static int version_flag; +static int help_flag; + +static time_t destroy_timeout = 5 * 60; + +struct getargs args[] = { + { NULL, 'p', arg_string, &principal, + "principal to authenticate as"}, + { NULL, 'u', arg_string, &username, + "username, other than default" }, + { NULL, 'r', arg_string, &realm, "local realm" }, + { NULL, 'm', arg_flag, &mflag, "disable ticket timeout" }, + { NULL, 'T', arg_string, &timeout, "default ticket timeout" }, + { NULL, 't', arg_flag, &tflag, "use existing tickets" }, + { "version",0, arg_flag, &version_flag }, + { "help", 'h', arg_flag, &help_flag }, +}; -/* GLOBAL */ -static void +static int num_args = sizeof(args) / sizeof(args[0]); + +static int clean_up() { - dest_tkt(); + if(!tflag) + return dest_tkt() == KSUCCESS; + return 0; } -static void +static int clean_up_cmd (int argc, char **argv) { clean_up(); + return 0; } -/* GLOBAL */ -static void -quit() +static int +quit_cmd (int argc, char **argv) { - printf("Cleaning up and exiting.\n"); - clean_up(); - exit(0); + return 1; } -static void -quit_cmd (int argc, char **argv) +static void +usage(int code) { - quit(); + arg_printusage(args, num_args, NULL, "[command]"); + exit(code); } -static void +static int do_init(int argc, char **argv) { - int c; - int tflag = 0; - char tktstring[MaxPathLen]; - int k_errno; - + int optind = 0; + int ret; + set_progname (argv[0]); + + if(getarg(args, num_args, argc, argv, &optind) < 0) + usage(1); + if(help_flag) + usage(0); + if(version_flag) { + print_version(NULL); + exit(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); + ret = krb_get_default_principal(pr.name, pr.instance, default_realm); + if(ret < 0) + errx(1, "Can't figure out default principal"); + if(pr.instance[0] == '\0') + strcpy_truncate(pr.instance, "admin", sizeof(pr.instance)); + if(principal) { + if(username) + warnx("Ignoring username when principal is given"); + ret = krb_parse_name(principal, &pr); + if(ret) + errx(1, "%s: %s", principal, krb_get_err_text(ret)); + if(pr.realm[0] != '\0') + strcpy_truncate(default_realm, pr.realm, sizeof(default_realm)); + } else if(username) { + strcpy_truncate(pr.name, username, sizeof(pr.name)); + strcpy_truncate(pr.instance, "admin", sizeof(pr.instance)); + } + + if(realm) + strcpy_truncate(default_realm, realm, sizeof(default_realm)); + + strcpy_truncate(krbrlm, default_realm, sizeof(krbrlm)); + + if(pr.realm[0] == '\0') + strcpy_truncate(pr.realm, krbrlm, sizeof(pr.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()); + if(timeout) { + if(set_timeout(timeout) == -1) + warnx("bad timespecification `%s'", timeout); + } else if(mflag) + destroy_timeout = 0; + + if (tflag) + destroy_timeout = 0; /* disable timeout */ + else{ + char tktstring[128]; + snprintf(tktstring, sizeof(tktstring), + TKT_ROOT "_adm_%d",(int)getpid()); krb_set_tkt_string(tktstring); } - + return optind; +} + +static void +sigalrm(int sig) +{ + if(clean_up()) + printf("\nTickets destroyed.\n"); } 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(); + int optind = do_init(argc, argv); + if(argc > optind) + sl_command(cmds, argc - optind, argv + optind); + else { + void *data = NULL; + signal(SIGALRM, sigalrm); + while(sl_command_loop(cmds, "kadmin: ", &data) == 0) + alarm(destroy_timeout); + } + clean_up(); exit(0); } @@ -409,9 +471,9 @@ setvals(Kadm_vals *vals, char *string) return status; } if (!realm[0]) - strcpy(realm, default_realm); + strcpy_truncate(realm, default_realm, sizeof(realm)); if (strcmp(realm, krbrlm)) { - strcpy(krbrlm, realm); + strcpy_truncate(krbrlm, realm, sizeof(krbrlm)); if ((status = kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm)) != KADM_SUCCESS) printf("kadm error for realm %s: %s\n", @@ -423,20 +485,79 @@ setvals(Kadm_vals *vals, char *string) return KADM_SUCCESS; } -static void +static int +set_timeout(const char *timespec) +{ + int t = parse_time(timespec, "s"); + if(t == -1) + return -1; + destroy_timeout = t; + return 0; +} + +static int +set_timeout_cmd(int argc, char **argv) +{ + char ts[128]; + if (argc > 2) { + printf("Usage: set_timeout [timeout]\n"); + return 0; + } + if(argc == 2) { + if(set_timeout(argv[1]) == -1){ + printf("Bad time specification `%s'\n", argv[1]); + return 0; + } + } + if(destroy_timeout == 0) + printf("Timeout disabled.\n"); + else{ + unparse_time(destroy_timeout, ts, sizeof(ts)); + printf("Timeout after %s.\n", ts); + } + return 0; +} + +static int 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; + char pw[32]; + int generate_password = 0; + int i; + int optind = 0; + char *user = NULL; + + struct getargs cpw_args[] = { + { "random", 'r', arg_flag, NULL, "generate random password" }, + }; + i = 0; + cpw_args[i++].value = &generate_password; + + if(getarg(cpw_args, sizeof(cpw_args) / sizeof(cpw_args[0]), + argc, argv, &optind)){ + arg_printusage(cpw_args, + sizeof(cpw_args) / sizeof(cpw_args[0]), + "cpw", + "principal"); + return 0; } - if (setvals(&old, argv[1]) != KADM_SUCCESS) - return; + argc -= optind; + argv += optind; + + if (argc != 1) { + printf("Usage: change_password [options] principal\n"); + return 0; + } + + user = argv[0]; + + if (setvals(&old, user) != KADM_SUCCESS) + return 0; new = old; @@ -445,30 +566,39 @@ change_password(int argc, char **argv) if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) { /* get the admin's password */ if (get_admin_password() != GOOD_PW) - return; + return 0; - /* get the new password */ - snprintf(pw_prompt, sizeof(pw_prompt), "New password for %s:", argv[1]); + + if (generate_password) { + random_password(pw, sizeof(pw), &new.key_low, &new.key_high); + } else { + /* get the new password */ + snprintf(pw_prompt, sizeof(pw_prompt), + "New password for %s:", user); - 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]); + if (get_password(&new.key_low, &new.key_high, + pw_prompt, SWAP) != GOOD_PW) { + printf("Error reading password; password unchanged\n"); + return 0; } - } else - printf("Error reading password; password unchanged\n"); + } + + status = kadm_mod(&old, &new); + if (status == KADM_SUCCESS) { + printf("Password changed for %s.\n", user); + if (generate_password) + printf("Password is: %s\n", pw); + } else { + printf("kadmin: %s\nwhile changing password for %s", + error_message(status), user); + } + + memset(pw, 0, sizeof(pw)); memset(&new, 0, sizeof(new)); - if (!multiple) - clean_up(); - } - else + } else printf("kadmin: Principal %s does not exist.\n", krb_unparse_name_long (old.name, old.instance, krbrlm)); - return; + return 0; } static int @@ -511,7 +641,7 @@ printkey(unsigned char *tkey) printf("\n"); } -static void +static int change_key(int argc, char **argv) { Kadm_vals old, new; @@ -520,11 +650,11 @@ change_key(int argc, char **argv) if (argc != 2) { printf("Usage: change_key principal-name\n"); - return; + return 0; } if (setvals(&old, argv[1]) != KADM_SUCCESS) - return; + return 0; new = old; @@ -533,7 +663,7 @@ change_key(int argc, char **argv) if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) { /* get the admin's password */ if (get_admin_password() != GOOD_PW) - return; + return 0; /* get the new password */ printf("New DES key for %s: ", argv[1]); @@ -555,16 +685,14 @@ change_key(int argc, char **argv) } 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; + return 0; } -static void +static int change_admin_password(int argc, char **argv) { des_cblock newkey; @@ -572,9 +700,10 @@ change_admin_password(int argc, char **argv) char pword[MAX_KPW_LEN]; char *pw_msg; + alarm(0); if (argc != 1) { printf("Usage: change_admin_password\n"); - return; + return 0; } if (get_pw_new_pwd(pword, sizeof(pword), &pr, 1) == 0) { des_string_to_key(pword, &newkey); @@ -588,140 +717,241 @@ change_admin_password(int argc, char **argv) memset(newkey, 0, sizeof(newkey)); memset(pword, 0, sizeof(pword)); } - if (!multiple) - clean_up(); - return; + return 0; } -static void +void random_password(char*, size_t, u_int32_t*, u_int32_t*); + +static int add_new_key(int argc, char **argv) { - Kadm_vals new; + int i; char pw_prompt[BUFSIZ]; int status; + int generate_password = 0; + char *password = NULL; + + char *expiration_string = NULL; + time_t default_expiration = 0; + int expiration_set = 0; + + char *life_string = NULL; + time_t default_life = 0; + int life_set = 0; + + int attributes = -1; + int default_attributes = 0; + int attributes_set = 0; + + int optind = 0; + + /* XXX remember to update value assignments below */ + struct getargs add_args[] = { + { "random", 'r', arg_flag, NULL, "generate random password" }, + { "password", 'p', arg_string, NULL }, + { "life", 'l', arg_string, NULL, "max ticket life" }, + { "expiration", 'e', arg_string, NULL, "principal expiration" }, + { "attributes", 'a', arg_integer, NULL } + }; + i = 0; + add_args[i++].value = &generate_password; + add_args[i++].value = &password; + add_args[i++].value = &life_string; + add_args[i++].value = &expiration_string; + add_args[i++].value = &attributes; + + + if(getarg(add_args, sizeof(add_args) / sizeof(add_args[0]), + argc, argv, &optind)){ + arg_printusage(add_args, + sizeof(add_args) / sizeof(add_args[0]), + "add", + "principal ..."); + return 0; + } - if (argc != 2) { - printf("Usage: add_new_key user_name.\n"); - return; + if(expiration_string) { + default_expiration = parse_expdate(expiration_string); + if(default_expiration < 0) + warnx("Unknown expiration date `%s'", expiration_string); + else + expiration_set = 1; + } + if(life_string) { + time_t t = parse_time(life_string, "hour"); + if(t == -1) + warnx("Unknown lifetime `%s'", life_string); + else { + default_life = krb_time_to_life(0, t); + life_set = 1; + } + } + if(attributes != -1) { + default_attributes = attributes; + attributes_set = 1; } - 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; + { + char default_name[ANAME_SZ + INST_SZ + 1]; + char old_default[INST_SZ + 1] = ""; + Kadm_vals new, default_vals; + char pw[32]; u_char fields[4]; - char n[ANAME_SZ + INST_SZ + 1]; - /* get the admin's password */ - if (get_admin_password() != GOOD_PW) - return; + for(i = optind; i < argc; i++) { + if (setvals(&new, argv[i]) != KADM_SUCCESS) + return 0; + 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) { + printf("kadmin: Principal %s already exists.\n", argv[i]); + continue; + } + /* get the admin's password */ + if (get_admin_password() != GOOD_PW) + return 0; - 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; + snprintf (default_name, sizeof(default_name), + "default.%s", new.instance); + if(strcmp(old_default, default_name) != 0) { + 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(&default_vals, default_name) != KADM_SUCCESS) + return 0; + + if (kadm_get(&default_vals, fields) != KADM_SUCCESS) { + /* no such entry, try just `default' */ + if (setvals(&default_vals, "default") != KADM_SUCCESS) + continue; + if ((status = kadm_get(&default_vals, fields)) != KADM_SUCCESS) { + warnx ("kadm error: %s", error_message(status)); + break; /* no point in continuing */ + } + } - 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 (default_vals.max_life == 255) /* Defaults not set! */ { + /* This is the default maximum lifetime for new principals. */ + if (strcmp(new.instance, "admin") == 0) + default_vals.max_life = 1 + (CLOCK_SKEW/(5*60)); /* 5+5 minutes */ + else if (strcmp(new.instance, "root") == 0) + default_vals.max_life = 96; /* 8 hours */ + else if (krb_life_to_time(0, 162) >= 24*60*60) + default_vals.max_life = 162; /* ca 100 hours */ + else + default_vals.max_life = 255; /* ca 21 hours (maximum) */ + + /* Also fix expiration date. */ + { + time_t now; + struct tm tm; + + now = time(0); + tm = *gmtime(&now); + if (strcmp(new.name, "rcmd") == 0 || + strcmp(new.name, "ftp") == 0 || + strcmp(new.name, "pop") == 0) + tm.tm_year += 5; + else + tm.tm_year += 2; + default_vals.exp_date = mktime(&tm); + } + default_vals.attributes = default_vals.attributes; + } + if(!life_set) + default_life = default_vals.max_life; + if(!expiration_set) + default_expiration = default_vals.exp_date; + if(!attributes_set) + default_attributes = default_vals.attributes; } - } - 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]); + new.max_life = default_life; + new.exp_date = default_expiration; + new.attributes = default_attributes; + if(!life_set) + get_maxlife(&new); + if(!attributes_set) + get_attr(&new); + if(!expiration_set) + get_expdate(&new); + + if(generate_password) { + random_password(pw, sizeof(pw), &new.key_low, &new.key_high); + } else if (password == NULL) { + /* get the new password */ + snprintf(pw_prompt, sizeof(pw_prompt), "Password for %s:", + argv[i]); - if (get_password(&new.key_low, &new.key_high, - pw_prompt, SWAP) == GOOD_PW) { + if (get_password(&new.key_low, &new.key_high, + pw_prompt, SWAP) != GOOD_PW) { + printf("Error reading password: %s not added\n", argv[i]); + memset(&new, 0, sizeof(new)); + return 0; + } + } else { + passwd_to_lowhigh (&new.key_low, &new.key_high, password, SWAP); + memset (password, 0, strlen(password)); + } + status = kadm_add(&new); if (status == KADM_SUCCESS) { - printf("%s added to database.\n", argv[1]); - } else { + printf("%s added to database", argv[i]); + if (generate_password) + printf (" with password `%s'", pw); + printf (".\n"); + } 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(); + + memset(pw, 0, sizeof(pw)); + memset(&new, 0, sizeof(new)); + } } - else - printf("kadmin: Principal already exists.\n"); - return; + + return 0; } -static void +static int del_entry(int argc, char **argv) { int status; Kadm_vals vals; + int i; - if (argc != 2) { - printf("Usage: del_entry username\n"); - return; + if (argc < 2) { + printf("Usage: delete principal...\n"); + return 0; } - 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; + for(i = 1; i < argc; i++) { + if (setvals(&vals, argv[i]) != KADM_SUCCESS) + return 0; - 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 (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) { + /* get the admin's password */ + if (get_admin_password() != GOOD_PW) + return 0; + + if ((status = kadm_del(&vals)) == KADM_SUCCESS) + printf("%s removed from database.\n", argv[i]); + 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)); } - else - printf("kadmin: Principal %s does not exist.\n", - krb_unparse_name_long (vals.name, vals.instance, krbrlm)); - return; + return 0; } -static void +static int get_entry(int argc, char **argv) { int status; @@ -730,7 +960,7 @@ get_entry(int argc, char **argv) if (argc != 2) { printf("Usage: get_entry username\n"); - return; + return 0; } memset(fields, 0, sizeof(fields)); @@ -743,103 +973,173 @@ get_entry(int argc, char **argv) #if 0 SET_FIELD(KADM_DESKEY,fields); #endif +#ifdef EXTENDED_KADM + SET_FIELD(KADM_MODDATE, fields); + SET_FIELD(KADM_MODNAME, fields); + SET_FIELD(KADM_MODINST, fields); + SET_FIELD(KADM_KVNO, fields); +#endif if (setvals(&vals, argv[1]) != KADM_SUCCESS) - return; + return 0; if (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) { /* get the admin's password */ if (get_admin_password() != GOOD_PW) - return; + return 0; 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; + return 0; } -static void +static int mod_entry(int argc, char **argv) { int status; u_char fields[4]; Kadm_vals ovals, nvals; + int i; + + char *expiration_string = NULL; + time_t default_expiration = 0; + int expiration_set = 0; + + char *life_string = NULL; + time_t default_life = 0; + int life_set = 0; + + int attributes = -1; + int default_attributes = 0; + int attributes_set = 0; + + int optind = 0; + + /* XXX remember to update value assignments below */ + struct getargs mod_args[] = { + { "life", 'l', arg_string, NULL, "max ticket life" }, + { "expiration", 'e', arg_string, NULL, "principal expiration" }, + { "attributes", 'a', arg_integer, NULL } + }; + i = 0; + mod_args[i++].value = &life_string; + mod_args[i++].value = &expiration_string; + mod_args[i++].value = &attributes; + + + if(getarg(mod_args, sizeof(mod_args) / sizeof(mod_args[0]), + argc, argv, &optind)){ + arg_printusage(mod_args, + sizeof(mod_args) / sizeof(mod_args[0]), + "mod", + "principal ..."); + return 0; + } - if (argc != 2) { - printf("Usage: mod_entry username\n"); - return; + if(expiration_string) { + default_expiration = parse_expdate(expiration_string); + if(default_expiration < 0) + warnx("Unknown expiration date `%s'", expiration_string); + else + expiration_set = 1; + } + if(life_string) { + time_t t = parse_time(life_string, "hour"); + if(t == -1) + warnx("Unknown lifetime `%s'", life_string); + else { + default_life = krb_time_to_life(0, t); + life_set = 1; + } + } + if(attributes != -1) { + default_attributes = attributes; + attributes_set = 1; } - 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); + for(i = optind; i < argc; i++) { + + 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; + if (setvals(&ovals, argv[i]) != KADM_SUCCESS) + return 0; - nvals = ovals; + 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; - } + 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 0; + } - /* get the admin's password */ - if (get_admin_password() != GOOD_PW) - return; + /* get the admin's password */ + if (get_admin_password() != GOOD_PW) + return 0; - 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; + 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(life_set) { + nvals.max_life = default_life; + SET_FIELD(KADM_MAXLIFE, nvals.fields); + } else + get_maxlife(&nvals); + if(attributes_set) { + nvals.attributes = default_attributes; + SET_FIELD(KADM_ATTR, nvals.fields); + } else + get_attr(&nvals); + if(expiration_set) { + nvals.exp_date = default_expiration; + SET_FIELD(KADM_EXPDATE, nvals.fields); + } else + 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; + 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); } - prin_vals(&ovals); - + out: - if (!multiple) - clean_up(); - return; + return 0; } -static void +static int help(int argc, char **argv) { sl_help (cmds, argc, argv); + return 0; } diff --git a/crypto/kerberosIV/kadmin/kpasswd.c b/crypto/kerberosIV/kadmin/kpasswd.c index f4c0cda..f32946b 100644 --- a/crypto/kerberosIV/kadmin/kpasswd.c +++ b/crypto/kerberosIV/kadmin/kpasswd.c @@ -25,7 +25,7 @@ or implied warranty. #include "kadm_locl.h" -RCSID("$Id: kpasswd.c,v 1.25 1997/05/02 14:28:51 assar Exp $"); +RCSID("$Id: kpasswd.c,v 1.26 1998/06/09 19:24:54 joda Exp $"); static void usage(int value) @@ -70,7 +70,9 @@ main(int argc, char **argv) break; case 'n': if (k_isname(optarg)) - strncpy(principal.name, optarg, sizeof(principal.name) - 1); + strcpy_truncate(principal.name, + optarg, + sizeof(principal.name)); else { warnx("Bad name: %s", optarg); usage(1); @@ -78,9 +80,9 @@ main(int argc, char **argv) break; case 'i': if (k_isinst(optarg)) - strncpy(principal.instance, - optarg, - sizeof(principal.instance) - 1); + strcpy_truncate(principal.instance, + optarg, + sizeof(principal.instance)); else { warnx("Bad instance: %s", optarg); usage(1); @@ -88,7 +90,9 @@ main(int argc, char **argv) break; case 'r': if (k_isrealm(optarg)) { - strncpy(principal.realm, optarg, sizeof(principal.realm) - 1); + strcpy_truncate(principal.realm, + optarg, + sizeof(principal.realm)); realm_given++; } else { warnx("Bad realm: %s", optarg); @@ -112,14 +116,24 @@ main(int argc, char **argv) } if (use_default) { - strcpy(principal.name, default_principal.name); - strcpy(principal.instance, default_principal.instance); - strcpy(principal.realm, default_principal.realm); + strcpy_truncate(principal.name, + default_principal.name, + sizeof(principal.name)); + strcpy_truncate(principal.instance, + default_principal.instance, + sizeof(principal.instance)); + strcpy_truncate(principal.realm, + default_principal.realm, + sizeof(principal.realm)); } else { if (!principal.name[0]) - strcpy(principal.name, default_principal.name); + strcpy_truncate(principal.name, + default_principal.name, + sizeof(principal.name)); if (!principal.realm[0]) - strcpy(principal.realm, default_principal.realm); + strcpy_truncate(principal.realm, + default_principal.realm, + sizeof(principal.realm)); } snprintf(tktstring, sizeof(tktstring), diff --git a/crypto/kerberosIV/kadmin/ksrvutil.c b/crypto/kerberosIV/kadmin/ksrvutil.c index 108481c..8f75d52 100644 --- a/crypto/kerberosIV/kadmin/ksrvutil.c +++ b/crypto/kerberosIV/kadmin/ksrvutil.c @@ -30,7 +30,7 @@ or implied warranty. #include "kadm_locl.h" -RCSID("$Id: ksrvutil.c,v 1.39 1997/05/02 14:28:52 assar Exp $"); +RCSID("$Id: ksrvutil.c,v 1.47 1999/06/29 18:53:58 bg Exp $"); #include "ksrvutil.h" @@ -86,7 +86,7 @@ copy_keyfile(char *keyfile, char *backup_keyfile) try_again = FALSE; if ((keyfile_fd = open(keyfile, O_RDONLY, 0)) < 0) { if (errno != ENOENT) - err (1, "read %s", keyfile); + err (1, "open %s", keyfile); else { try_again = TRUE; if ((keyfile_fd = @@ -105,7 +105,7 @@ copy_keyfile(char *keyfile, char *backup_keyfile) if ((backup_keyfile_fd = open(backup_keyfile, O_WRONLY | O_TRUNC | O_CREAT, keyfile_mode)) < 0) - err (1, "write %s", backup_keyfile); + err (1, "open %s", backup_keyfile); do { if ((rcount = read(keyfile_fd, buf, sizeof(buf))) < 0) err (1, "read %s", keyfile); @@ -184,7 +184,8 @@ int ny(char *string) } static void -append_srvtab(char *filename, int fd, char *sname, char *sinst, char *srealm, unsigned char key_vno, unsigned char *key) +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); @@ -259,13 +260,14 @@ static void usage(void) { fprintf(stderr, "Usage: ksrvutil [-f keyfile] [-i] [-k] "); - fprintf(stderr, "[-p principal] [-r realm] "); + fprintf(stderr, "[-p principal] [-r realm] [-u]"); 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"); + fprintf(stderr, "{list | change | add | get | delete}\n"); + fprintf(stderr, " -i causes the program to ask for " + "confirmation before changing keys.\n"); + fprintf(stderr, " -k causes the key to printed for list or change.\n"); + fprintf(stderr, " -u creates one keyfile for each principal " + "(only used with `get')\n"); exit(1); } @@ -292,7 +294,9 @@ main(int argc, char **argv) int interactive = FALSE; int list = FALSE; int change = FALSE; + int unique_filename = FALSE; int add = FALSE; + int delete = FALSE; int get = FALSE; int key = FALSE; /* do we show keys? */ int arg_entered = FALSE; @@ -318,101 +322,116 @@ main(int argc, char **argv) /* This is used only as a default for adding keys */ if (krb_get_lrealm(local_realm, 1) != KSUCCESS) - strcpy(local_realm, KRB_REALM); + strcpy_truncate(local_realm, + KRB_REALM, + sizeof(local_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(); - } + while((c = getopt(argc, argv, "ikc:f:p:r:u")) != EOF) { + switch (c) { + case 'i': + interactive++; + break; + case 'k': + key++; + break; + case 'c': + strcpy_truncate(cellname, optarg, sizeof(cellname)); + break; + case 'f': + strcpy_truncate(keyfile, optarg, sizeof(keyfile)); + 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_truncate(u_realm, optarg, sizeof(u_realm)); + break; + case 'u': + unique_filename = 1; + break; + case '?': + usage(); + } } if (optind >= argc) - usage(); + usage(); if (*u_realm == '\0') - strcpy (u_realm, local_realm); + strcpy_truncate (u_realm, local_realm, sizeof(u_realm)); if (strcmp(argv[optind], "list") == 0) { - if (arg_entered) - usage(); - else { - arg_entered++; - list++; - } + if (arg_entered) + usage(); + else { + arg_entered++; + list++; + } } else if (strcmp(argv[optind], "change") == 0) { - if (arg_entered) - usage(); - else { - arg_entered++; - change++; - } + if (arg_entered) + usage(); + else { + arg_entered++; + change++; + } } else if (strcmp(argv[optind], "add") == 0) { - if (arg_entered) - usage(); - else { - arg_entered++; - add++; - } + if (arg_entered) + usage(); + else { + arg_entered++; + add++; + } } else if (strcmp(argv[optind], "get") == 0) { - if (arg_entered) - usage(); - else { - arg_entered++; - get++; - } + if (arg_entered) + usage(); + else { + arg_entered++; + get++; + } + } + else if (strcmp(argv[optind], "delete") == 0) { + if (arg_entered) + usage(); + else { + arg_entered++; + delete++; + } } else - usage(); + usage(); ++optind; if (!arg_entered) usage(); + if(unique_filename && !get) + warnx("`-u' flag is only used with `get'"); + if (!keyfile[0]) - strcpy(keyfile, KEYFILE); - - strcpy(work_keyfile, keyfile); - strcpy(backup_keyfile, keyfile); + strcpy_truncate(keyfile, KEYFILE, sizeof(keyfile)); + + strcpy_truncate(work_keyfile, keyfile, sizeof(work_keyfile)); + strcpy_truncate(backup_keyfile, keyfile, sizeof(backup_keyfile)); - if (change || add || get) { - strcat(work_keyfile, ".work"); - strcat(backup_keyfile, ".old"); - + if (change || add || (get && !unique_filename) || delete) { + snprintf(work_keyfile, sizeof(work_keyfile), "%s.work", keyfile); + snprintf(backup_keyfile, sizeof(backup_keyfile), "%s.old", keyfile); copy_keyfile(keyfile, backup_keyfile); } - if (add || get) + if (add || (get && !unique_filename)) copy_keyfile(backup_keyfile, work_keyfile); keyfile_mode = get_mode(keyfile); - if (change || list) + if (change || list || delete) if ((backup_keyfile_fd = open(backup_keyfile, O_RDONLY, 0)) < 0) err (1, "open %s", backup_keyfile); - if (change) { + if (change || delete) { if ((work_keyfile_fd = open(work_keyfile, O_WRONLY | O_CREAT | O_TRUNC, SRVTAB_MODE)) < 0) @@ -423,13 +442,13 @@ main(int argc, char **argv) open(work_keyfile, O_APPEND | O_WRONLY, SRVTAB_MODE)) < 0) err (1, "open with append %s", work_keyfile ); } - else if (get) { + else if (get && !unique_filename) { 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) { + if (change || list || delete) { 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) && @@ -467,10 +486,8 @@ main(int argc, char **argv) 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; + change_this_key = 1; if (change_this_key) printf("Changing to version %d.\n", key_vno + 1); @@ -539,6 +556,20 @@ main(int argc, char **argv) } } } + } else if(delete) { + int delete_this_key; + printf("\nPrincipal: "); + print_name(sname, sinst, srealm); + printf("; version %d\n", key_vno); + delete_this_key = yn("Delete this key?"); + + if (delete_this_key) + printf("Deleting this key.\n"); + + if (!delete_this_key) { + append_srvtab(work_keyfile, work_keyfile_fd, + sname, sinst, srealm, key_vno, old_key); + } } memset(old_key, 0, sizeof(des_cblock)); memset(new_key, 0, sizeof(des_cblock)); @@ -547,23 +578,30 @@ main(int argc, char **argv) else if (add) { do { do { + char *p; + 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; + p = strchr(databuf, '.'); + if (p != NULL) { + *p++ = '\0'; + strcpy_truncate (sname, databuf, sizeof(sname)); + strcpy_truncate (sinst, p, sizeof(sinst)); } else { - safe_read_stdin("Instance: ", databuf, sizeof(databuf)); - strncpy(sinst, databuf, sizeof(sinst) - 1); + strcpy_truncate (sname, databuf, sizeof(sname)); + safe_read_stdin("Instance: ", databuf, sizeof(databuf)); + strcpy_truncate (sinst, databuf, sizeof(databuf)); } + safe_read_stdin("Realm: ", databuf, sizeof(databuf)); - strncpy(srealm, databuf, sizeof(srealm) - 1); + if (databuf[0] != '\0') + strcpy_truncate (srealm, databuf, sizeof(srealm)); + else + strcpy_truncate (srealm, local_realm, sizeof(srealm)); + 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); + strcpy_truncate(srealm, local_realm, sizeof(srealm)); printf("New principal: "); print_name(sname, sinst, srealm); printf("; version %d\n", key_vno); @@ -580,15 +618,15 @@ main(int argc, char **argv) } while (yn("Would you like to add another key?")); } else if (get) { - ksrvutil_get(work_keyfile_fd, work_keyfile, + ksrvutil_get(unique_filename, work_keyfile_fd, work_keyfile, argc - optind, argv + optind); } - if (change || list) + if (change || list || delete) if (close(backup_keyfile_fd) < 0) warn ("close %s", backup_keyfile); - if (change || add || get) { + if (change || add || (get && !unique_filename) || delete) { if (close(work_keyfile_fd) < 0) err (1, "close %s", work_keyfile); if (rename(work_keyfile, keyfile) < 0) diff --git a/crypto/kerberosIV/kadmin/ksrvutil.h b/crypto/kerberosIV/kadmin/ksrvutil.h index 64e2fe4..b548fc7 100644 --- a/crypto/kerberosIV/kadmin/ksrvutil.h +++ b/crypto/kerberosIV/kadmin/ksrvutil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ */ /* - * $Id: ksrvutil.h,v 1.8 1997/04/01 03:58:55 assar Exp $ + * $Id: ksrvutil.h,v 1.9 1998/01/16 19:01:31 joda Exp $ * */ @@ -51,4 +51,5 @@ 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); +void ksrvutil_get(int unique_filename, int fd, + char *filename, int argc, char **argv); diff --git a/crypto/kerberosIV/kadmin/ksrvutil_get.c b/crypto/kerberosIV/kadmin/ksrvutil_get.c index 7b97d35..a9c0797 100644 --- a/crypto/kerberosIV/kadmin/ksrvutil_get.c +++ b/crypto/kerberosIV/kadmin/ksrvutil_get.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,7 +39,7 @@ #include "kadm_locl.h" #include "ksrvutil.h" -RCSID("$Id: ksrvutil_get.c,v 1.32 1997/05/05 21:14:57 assar Exp $"); +RCSID("$Id: ksrvutil_get.c,v 1.38 1999/06/29 21:19:37 bg Exp $"); #define BAD_PW 1 #define GOOD_PW 0 @@ -48,7 +48,7 @@ RCSID("$Id: ksrvutil_get.c,v 1.32 1997/05/05 21:14:57 assar Exp $"); #define PE_YES 1 #define PE_UNSURE 2 -static char tktstring[128]; +static char tktstring[MaxPathLen]; static int princ_exists(char *name, char *instance, char *realm) @@ -92,8 +92,7 @@ get_admin_password(char *myname, char *myinst, char *myrealm) memset(&c, 0, sizeof(c)); krb_get_cred(PWSERV_NAME, KADM_SINST, myrealm, &c); des_init_random_number_generator(&c.session); - } - else + } else status = KDC_PR_UNKNOWN; switch(status) { @@ -122,8 +121,8 @@ 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 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; @@ -163,7 +162,10 @@ struct srv_ent{ }; static int -key_to_key(char *user, char *instance, char *realm, void *arg, +key_to_key(const char *user, + char *instance, + const char *realm, + const void *arg, des_cblock *key) { memcpy(key, arg, sizeof(des_cblock)); @@ -171,92 +173,116 @@ key_to_key(char *user, char *instance, char *realm, void *arg, } static void -get_srvtab_ent(int fd, char *filename, char *name, char *inst, char *realm) +get_srvtab_ent(int unique_filename, 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); + 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; + + strcpy_truncate(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; - } + memset(&values, 0, sizeof(values)); + strcpy_truncate(values.name, name, sizeof(values.name)); + strcpy_truncate(values.instance, inst, sizeof(values.instance)); + 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; - } + values.key_low = values.key_high = 0; + + /* get the key version number */ + { + int old = krb_use_admin_server(1); + + strcpy_truncate(old_tktfile, tkt_string(), sizeof(old_tktfile)); + 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); + krb_use_admin_server(old); + } + + 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); + 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)); + 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; + } - fprintf (stderr, "Added %s\n", krb_unparse_name_long (name, inst, realm)); + /* Write the new key & c:o to the srvtab file */ + + if(unique_filename){ + char *fn; + asprintf(&fn, "%s-%s", filename, + krb_unparse_name_long(name, inst, realm)); + if(fn == NULL){ + warnx("Out of memory"); + leave(NULL, 1); + } + fd = open(fn, O_RDWR | O_CREAT | O_TRUNC, 0600); /* XXX flags, mode? */ + if(fd < 0){ + warn("%s", fn); + leave(NULL, 1); + } + srvtab_put_key (fd, fn, name, inst, realm, kvno, newkey); + close(fd); + fprintf (stderr, "Created %s\n", fn); + free(fn); + }else{ + srvtab_put_key (fd, filename, name, inst, realm, kvno, newkey); + fprintf (stderr, "Added %s\n", + krb_unparse_name_long (name, inst, realm)); + } + memset(&newkey, 0, sizeof(newkey)); } static void -ksrvutil_kadm(int fd, char *filename, struct srv_ent *p) +ksrvutil_kadm(int unique_filename, int fd, char *filename, struct srv_ent *p) { int ret; CREDENTIALS c; @@ -276,7 +302,8 @@ ksrvutil_kadm(int fd, char *filename, struct srv_ent *p) /* * create ticket file and get admin tickets */ - snprintf(tktstring, sizeof(tktstring), TKT_ROOT "_ksrvutil_%d", (int)getpid()); + snprintf(tktstring, sizeof(tktstring), + TKT_ROOT "_ksrvutil_%d", (int)getpid()); krb_set_tkt_string(tktstring); destroyp = TRUE; @@ -287,7 +314,7 @@ ksrvutil_kadm(int fd, char *filename, struct srv_ent *p) } } for(;p;){ - get_srvtab_ent(fd, filename, p->name, p->inst, p->realm); + get_srvtab_ent(unique_filename, fd, filename, p->name, p->inst, p->realm); p=p->next; } unlink(tktstring); @@ -300,7 +327,7 @@ parseinput (char *result, size_t sz, char *val, char *def) int inq; if (val[0] == '\0') { - strncpy (result, def, sz-1); + strcpy_truncate (result, def, sz); return; } lim = result + sz - 1; @@ -323,7 +350,7 @@ parseinput (char *result, size_t sz, char *val, char *def) } void -ksrvutil_get(int fd, char *filename, int argc, char **argv) +ksrvutil_get(int unique_filename, int fd, char *filename, int argc, char **argv) { char sname[ANAME_SZ]; /* name of service */ char sinst[INST_SZ]; /* instance of service */ @@ -334,8 +361,10 @@ ksrvutil_get(int fd, char *filename, int argc, char **argv) struct srv_ent *head=NULL; int i; - k_gethostname(local_hostname, sizeof(local_hostname)); - strcpy(local_hostname, krb_get_phost(local_hostname)); + gethostname(local_hostname, sizeof(local_hostname)); + strcpy_truncate(local_hostname, + krb_get_phost(local_hostname), + sizeof(local_hostname)); if (argc) for(i=0; i < argc; ++i) { @@ -346,7 +375,7 @@ ksrvutil_get(int fd, char *filename, int argc, char **argv) leave(NULL,1); } p->next = head; - strcpy (p->realm, u_realm); + strcpy_truncate (p->realm, u_realm, sizeof(p->realm)); if (kname_parse (p->name, p->inst, p->realm, argv[i]) != KSUCCESS) { warnx ("parse error on '%s'\n", argv[i]); @@ -354,11 +383,11 @@ ksrvutil_get(int fd, char *filename, int argc, char **argv) continue; } if (p->name[0] == '\0') - strcpy(p->name, "rcmd"); + strcpy_truncate(p->name, "rcmd", sizeof(p->name)); if (p->inst[0] == '\0') - strcpy(p->inst, local_hostname); + strcpy_truncate(p->inst, local_hostname, sizeof(p->inst)); if (p->realm[0] == '\0') - strcpy(p->realm, u_realm); + strcpy_truncate(p->realm, u_realm, sizeof(p->realm)); head = p; } @@ -377,16 +406,20 @@ ksrvutil_get(int fd, char *filename, int argc, char **argv) if(yn("Is this correct?")){ struct srv_ent *p=(struct srv_ent*)malloc(sizeof(struct srv_ent)); + if (p == NULL) { + warnx ("out of memory in malloc"); + leave(NULL,1); + } p->next=head; head=p; - strcpy(p->name, sname); - strcpy(p->inst, sinst); - strcpy(p->realm, srealm); + strcpy_truncate(p->name, sname, sizeof(p->name)); + strcpy_truncate(p->inst, sinst, sizeof(p->inst)); + strcpy_truncate(p->realm, srealm, sizeof(p->realm)); } }while(ny("Add more keys?")); - ksrvutil_kadm(fd, filename, head); + ksrvutil_kadm(unique_filename, fd, filename, head); { struct srv_ent *p=head, *q; diff --git a/crypto/kerberosIV/kadmin/new_pwd.c b/crypto/kerberosIV/kadmin/new_pwd.c index 88fb7a9..64756f7 100644 --- a/crypto/kerberosIV/kadmin/new_pwd.c +++ b/crypto/kerberosIV/kadmin/new_pwd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,7 +38,7 @@ #include "kadm_locl.h" -RCSID("$Id: new_pwd.c,v 1.11 1997/05/02 14:28:54 assar Exp $"); +RCSID("$Id: new_pwd.c,v 1.13 1998/06/09 19:24:55 joda Exp $"); #ifdef NOENCRYPTION #define read_long_pw_string placebo_read_pw_string @@ -49,24 +49,22 @@ RCSID("$Id: new_pwd.c,v 1.11 1997/05/02 14:28:54 assar Exp $"); 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) + int ret = kadm_check_pw(pword); + switch(ret) { + case 0: + return NULL; + case KADM_PASS_Q_NULL: + return "Null passwords are not allowed - " + "Please enter a longer password."; + case KADM_PASS_Q_TOOSHORT: 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."; + case KADM_PASS_Q_CLASS: + /* XXX */ + return "Please don't use an all-lower case password.\n" + "\tUnusual capitalization, delimiter characters or " + "digits are suggested."; } - - return NULL; + return "Password is insecure"; /* XXX this shouldn't happen */ } int @@ -119,6 +117,7 @@ get_pw_new_pwd(char *pword, int pwlen, krb_principal *pr, int print_realm) 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, diff --git a/crypto/kerberosIV/kadmin/random_password.c b/crypto/kerberosIV/kadmin/random_password.c new file mode 100644 index 0000000..d274831 --- /dev/null +++ b/crypto/kerberosIV/kadmin/random_password.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 1998 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 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: random_password.c,v 1.2 1998/06/09 19:24:56 joda Exp $"); + +/* This file defines some a function that generates a random password, + that can be used when creating a large amount of principals (such + as for a batch of students). Since this is a political matter, you + should think about how secure generated passwords has to be. + + Both methods defined here will give you at least 55 bits of + entropy. + */ + +/* If you want OTP-style passwords, define OTP_STYLE */ + +#ifdef OTP_STYLE +#include <otp.h> +#else +static void generate_password(char **pw, int num_classes, ...); +#endif + +void +random_password(char *pw, size_t len, u_int32_t *low, u_int32_t *high) +{ + des_cblock newkey; +#ifdef OTP_STYLE + des_new_random_key(&newkey); + otp_print_stddict (newkey, pw, len); + strlwr(pw); +#else + char *pass; + generate_password(&pass, 3, + "abcdefghijklmnopqrstuvwxyz", 7, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2, + "@$%&*()-+=:,/<>1234567890", 1); + strcpy_truncate(pw, pass, len); + memset(pass, 0, strlen(pass)); + free(pass); +#endif + des_string_to_key(pw, &newkey); + memcpy(low, newkey, 4); + memcpy(high, ((char *)newkey) + 4, 4); + memset(newkey, 0, sizeof(newkey)); + + *low = htonl(*low); + *high = htonl(*high); +} + +/* some helper functions */ + +#ifndef OTP_STYLE +/* return a random value in range 0-127 */ +static int +RND(des_cblock *key, int *left) +{ + if(*left == 0){ + des_new_random_key(key); + *left = 8; + } + (*left)--; + return ((unsigned char*)key)[*left]; +} + +/* This a helper function that generates a random password with a + number of characters from a set of character classes. + + If there are n classes, and the size of each class is Pi, and the + number of characters from each class is Ni, the number of possible + passwords are (given that the character classes are disjoint): + + n n + ----- / ---- \ + | | Ni | \ | + | | Pi | \ Ni| ! + | | ---- * | / | + | | Ni! | /___ | + i=1 \ i=1 / + + Since it uses the RND function above, neither the size of each + class, nor the total length of the generated password should be + larger than 127 (without fixing RND). + + */ +static void +generate_password(char **pw, int num_classes, ...) +{ + struct { + const char *str; + int len; + int freq; + } *classes; + va_list ap; + int len, i; + des_cblock rbuf; /* random buffer */ + int rleft = 0; + + classes = malloc(num_classes * sizeof(*classes)); + va_start(ap, num_classes); + len = 0; + for(i = 0; i < num_classes; i++){ + classes[i].str = va_arg(ap, const char*); + classes[i].len = strlen(classes[i].str); + classes[i].freq = va_arg(ap, int); + len += classes[i].freq; + } + va_end(ap); + *pw = malloc(len + 1); + if(*pw == NULL) + return; + for(i = 0; i < len; i++) { + int j; + int x = RND(&rbuf, &rleft) % (len - i); + int t = 0; + for(j = 0; j < num_classes; j++) { + if(x < t + classes[j].freq) { + (*pw)[i] = classes[j].str[RND(&rbuf, &rleft) % classes[j].len]; + classes[j].freq--; + break; + } + t += classes[j].freq; + } + } + (*pw)[len] = '\0'; + memset(rbuf, 0, sizeof(rbuf)); + free(classes); +} +#endif |