From 5927960fc25627c84b1fb175a056afac1e50b5e0 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Tue, 25 Apr 1995 01:23:16 +0000 Subject: Add the Sandia kadmin libraries in their new location. (kadmin.old) git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5468 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kadmin.old/server/.Sanitize | 54 +++ src/kadmin.old/server/.cvsignore | 1 + src/kadmin.old/server/ChangeLog | 166 +++++++ src/kadmin.old/server/Makefile.in | 62 +++ src/kadmin.old/server/adm_adm_func.c | 831 +++++++++++++++++++++++++++++++++++ src/kadmin.old/server/adm_check.c | 136 ++++++ src/kadmin.old/server/adm_extern.c | 57 +++ src/kadmin.old/server/adm_extern.h | 237 ++++++++++ src/kadmin.old/server/adm_fmt_inq.c | 211 +++++++++ src/kadmin.old/server/adm_funcs.c | 574 ++++++++++++++++++++++++ src/kadmin.old/server/adm_kadmin.c | 341 ++++++++++++++ src/kadmin.old/server/adm_kpasswd.c | 113 +++++ src/kadmin.old/server/adm_listen.c | 197 +++++++++ src/kadmin.old/server/adm_msgs.c | 59 +++ src/kadmin.old/server/adm_nego.c | 314 +++++++++++++ src/kadmin.old/server/adm_network.c | 257 +++++++++++ src/kadmin.old/server/adm_parse.c | 262 +++++++++++ src/kadmin.old/server/adm_process.c | 428 ++++++++++++++++++ src/kadmin.old/server/adm_server.c | 519 ++++++++++++++++++++++ src/kadmin.old/server/adm_v4_pwd.c | 432 ++++++++++++++++++ src/kadmin.old/server/admin_acl_file | 12 + src/kadmin.old/server/configure.in | 14 + src/kadmin.old/server/kadmind.M | 1 + 23 files changed, 5278 insertions(+) create mode 100644 src/kadmin.old/server/.Sanitize create mode 100644 src/kadmin.old/server/.cvsignore create mode 100644 src/kadmin.old/server/ChangeLog create mode 100644 src/kadmin.old/server/Makefile.in create mode 100644 src/kadmin.old/server/adm_adm_func.c create mode 100644 src/kadmin.old/server/adm_check.c create mode 100644 src/kadmin.old/server/adm_extern.c create mode 100644 src/kadmin.old/server/adm_extern.h create mode 100644 src/kadmin.old/server/adm_fmt_inq.c create mode 100644 src/kadmin.old/server/adm_funcs.c create mode 100644 src/kadmin.old/server/adm_kadmin.c create mode 100644 src/kadmin.old/server/adm_kpasswd.c create mode 100644 src/kadmin.old/server/adm_listen.c create mode 100644 src/kadmin.old/server/adm_msgs.c create mode 100644 src/kadmin.old/server/adm_nego.c create mode 100644 src/kadmin.old/server/adm_network.c create mode 100644 src/kadmin.old/server/adm_parse.c create mode 100644 src/kadmin.old/server/adm_process.c create mode 100644 src/kadmin.old/server/adm_server.c create mode 100644 src/kadmin.old/server/adm_v4_pwd.c create mode 100644 src/kadmin.old/server/admin_acl_file create mode 100644 src/kadmin.old/server/configure.in create mode 100644 src/kadmin.old/server/kadmind.M (limited to 'src/kadmin.old/server') diff --git a/src/kadmin.old/server/.Sanitize b/src/kadmin.old/server/.Sanitize new file mode 100644 index 000000000..637718506 --- /dev/null +++ b/src/kadmin.old/server/.Sanitize @@ -0,0 +1,54 @@ +# Sanitize.in for Kerberos V5 + +# Each directory to survive it's way into a release will need a file +# like this one called "./.Sanitize". All keyword lines must exist, +# and must exist in the order specified by this file. Each directory +# in the tree will be processed, top down, in the following order. + +# Hash started lines like this one are comments and will be deleted +# before anything else is done. Blank lines will also be squashed +# out. + +# The lines between the "Do-first:" line and the "Things-to-keep:" +# line are executed as a /bin/sh shell script before anything else is +# done in this + +Do-first: + +# All files listed between the "Things-to-keep:" line and the +# "Files-to-sed:" line will be kept. All other files will be removed. +# Directories listed in this section will have their own Sanitize +# called. Directories not listed will be removed in their entirety +# with rm -rf. + +Things-to-keep: + +.cvsignore +ChangeLog +Makefile.in +adm_adm_func.c +adm_check.c +adm_extern.c +adm_extern.h +adm_fmt_inq.c +adm_funcs.c +adm_kadmin.c +adm_kpasswd.c +adm_listen.c +adm_msgs.c +adm_nego.c +adm_network.c +adm_parse.c +adm_process.c +adm_server.c +adm_v4_pwd.c +admin_acl_file +configure +configure.in +kadmind.M + +Things-to-lose: + +Do-last: + +# End of file. diff --git a/src/kadmin.old/server/.cvsignore b/src/kadmin.old/server/.cvsignore new file mode 100644 index 000000000..e8c05a6b1 --- /dev/null +++ b/src/kadmin.old/server/.cvsignore @@ -0,0 +1 @@ +configure diff --git a/src/kadmin.old/server/ChangeLog b/src/kadmin.old/server/ChangeLog new file mode 100644 index 000000000..6ffcb95eb --- /dev/null +++ b/src/kadmin.old/server/ChangeLog @@ -0,0 +1,166 @@ +Fri Apr 21 13:11:00 1995 Mark Eichin + + From Ian Taylor . Makes kadmind use -r for both + the database name and the service name, eliminating an + installation hassle. + * adm_extern.h: declare realm. + * adm_server.c: define realm. + (process_args): change db_realm to realm. + * adm_network.c (setup_network): use the preset realm, not the + default realm. + +Thu Apr 20 18:05:00 1995 Mark Eichin + + Changes from Ian Taylor to support testsuite. + * adm_extern.h: declare admin_port. + * adm_extern.c: define admin_port. + * adm_server.c (process_args): set admin_port from -p command line + argument. + (usage): document -p port option. + * adm_network.c (setup_network): use admin_port if set. + +Thu Apr 20 11:47:53 1995 + + * adm_extern.h: #include adm_defs.h, since that's no longer + included by krb5.h + +Mon Mar 27 07:56:26 1995 Chris Provenzano (proven@mit.edu) + + * adm_process.c, adm_kadmin.c, adm_adm_func.c, adm_kpasswd.c, + * adm_funcs, adm_nego.c adm_extern.c and adm_listen.c + Use new calling convention for krb5_recvauth(), krb5_mk_priv(), + krb5_rd_priv(), krb5_mk_safe(), and krb5_rd_safe(). + (Redid many of the internal functions to accomidate new a + uth_context structure and remove old unnecessary structures.) + +Fri Mar 24 14:38:06 1995 + + * adm_network.c (setup_network): If /etc/services doesn't have the + administration port, use a compiled in port. + +Thu Mar 2 12:24:50 1995 Theodore Y. Ts'o + + * Makefile.in (ISODELIB): Remove reference to $(ISODELIB). + +Wed Mar 1 16:29:53 1995 Theodore Y. Ts'o + + * configure.in: Remove ISODE_INCLUDE, replace check for -lsocket + and -lnsl with WITH_NETLIB check. + +Tue Feb 28 02:23:46 1995 John Gilmore (gnu at toad.com) + + * *.c: Avoid and includes. + +Fri Feb 3 07:50:14 1995 Theodore Y. Ts'o (tytso@dcl) + + * adm_v4_pwd.c: Don't use BITS64, use SIZEOF_LONG + +Wed Feb 01 22:05:35 1995 Chris Provenzano (proven@mit.edu) + + * adm_process.c, adm_extern.h (cpw_keyproc()) Added + krb5_keytype arg. + +Wed Jan 25 16:54:40 1995 Chris Provenzano (proven@mit.edu) + + * Removed all narrow types and references to wide.h and narrow.h + +Wed Jan 18 10:26:30 1995 + + * adm_server.c (process_args): Modify getopt args so that the 'M' + option takes an argument. (krb5 bugs 984) + +Fri Jan 13 15:23:47 1995 Chris Provenzano (proven@mit.edu) + + * Added krb5_context to all krb5_routines + +Mon Dec 19 18:12:18 1994 Theodore Y. Ts'o (tytso@dcl) + + * adm_listen.c (kill_children): Use syslog instead of krb_log. + +Tue Nov 1 18:19:36 1994 Mark Eichin (eichin@cygnus.com) + + * adm_listen.c (kill_children): use sigprocmask if available. + +Wed Oct 19 17:40:22 1994 Theodore Y. Ts'o (tytso@dcl) + + * adm_server.c (main): Select the cryptosystem to be used using + krb5_use_cstype() instead of using a implementation + specific assignment. Also, allow the encryption type to + be specified using a command line option. + +Tue Oct 4 17:08:25 1994 Theodore Y. Ts'o (tytso@dcl) + + * adm_process.c (cpw_keyproc): Add widen.h and narrow.h around + declaration so that argument types to keyproc are widened. + +Mon Oct 3 19:13:03 1994 Theodore Y. Ts'o (tytso@dcl) + + * Makefile.in: Use $(srcdir) to find manual page for make install. + +Thu Sep 29 22:41:08 1994 Theodore Y. Ts'o (tytso@dcl) + + * Makefile.in: relink executable if libraries change + +Wed Sep 14 22:33:23 1994 Theodore Y. Ts'o (tytso@dcl) + + * adm_server (init_db): Save a copy of the master key database + entry in the master_entry global variable. + + * adm_process.c (process_client): Removed calls to + free(final_msg.data), where final_msg.data was pointing to + an automatic variable. + + * adm_process.c (cpw_keyproc): In the case where the + keyprocarg->key is set, copy the keyblock instead of + passing a pointer down --- more pointer aliasing problems! + + * adm_funcs.c (adm_modify_kdb): Added calls to krb5_copy_principal + instead of merely assigning pointers to one another and + causing pointer aliasing problems. Make sure the master + key version number is propagated correctly. + +Thu Aug 4 03:38:58 1994 Tom Yu (tlyu@dragons-lair) + + * Makefile.in: whoops install manpage as kadmin.8, not kadmin.1 + + * Makefile.in: install kadmind in the right place + +Sat Jul 16 09:22:19 1994 Tom Yu (tlyu at dragons-lair) + + * configure.in: another attempt to make dbm libs dtrt + +Fri Jul 1 16:01:02 1994 Mark Eichin (eichin@cygnus.com) + + * adm_listen.c: if USE_SIGPROCMASK, replace sigblock et al. + configure.in: CHECK_SIGPROCMASK. + +Wed Jun 29 00:25:29 1994 Tom Yu (tlyu at dragons-lair) + + * adm_server.c: fixed error table calls to use krb5_init_ets + +Fri Jun 24 20:39:37 1994 Theodore Y. Ts'o (tytso at tsx-11) + + * adm_process.c (cpw_keyproc): return error codes on failure + + * adm_nego.c (adm_negotiate_key): added return on memory + allocation error + + * adm_fmt_inq.c (adm_fmt_prt, adm_print_exp_time, + adm_print_attributes): Sanitized error return strategies. + + * adm_kadmin.c (adm5_kadmin): Plug memory leaks, fix double + free's, fix message in error syslog. + + * adm_process.c (process_client): Plug memory leaks + + * adm_adm_func. (adm_inq_old_key): Plug memory leaks, return error + when adm_fmt_prt returns an error + + * adm_adm_func.c (adm_mod_old_key): Plug memory leaks, report error + if put_principal returns an error. + + * adm_adm_func.c (adm_change_pwd_rnd): Fix syslog information + + * adm_adm_func.c (adm_build_key): Plug memory leak + + diff --git a/src/kadmin.old/server/Makefile.in b/src/kadmin.old/server/Makefile.in new file mode 100644 index 000000000..0774ee4ce --- /dev/null +++ b/src/kadmin.old/server/Makefile.in @@ -0,0 +1,62 @@ +CFLAGS = $(CCOPTS) $(DEFS) $(LOCALINCLUDE) +LDFLAGS = -g + +COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a +SSLIB=$(BUILDTOP)/util/ss/libss.a +DBMLIB= +KDBLIB=$(TOPLIBD)/libkdb5.a +DEPKDBLIB=$(TOPLIBD)/libkdb5.a + +all:: + +KLIB = $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(SSLIB) $(COMERRLIB) $(DBMLIB) +DEPKLIB = $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(SSLIB) $(COMERRLIB) $(DBMLIB) + +DEPLIBS = $(DEPKDBLIB) $(DEPKLIB) +LOCAL_LIBRARIES = $(KDBLIB) $(KLIB) + + +SRCS = \ + $(srcdir)/adm_server.c \ + $(srcdir)/adm_parse.c \ + $(srcdir)/adm_network.c \ + $(srcdir)/adm_listen.c \ + $(srcdir)/adm_process.c \ + $(srcdir)/adm_nego.c \ + $(srcdir)/adm_kpasswd.c \ + $(srcdir)/adm_kadmin.c \ + $(srcdir)/adm_fmt_inq.c \ + $(srcdir)/adm_adm_func.c \ + $(srcdir)/adm_funcs.c \ + $(srcdir)/adm_check.c \ + $(srcdir)/adm_extern.c \ + $(srcdir)/adm_msgs.c + +OBJS = \ + adm_server.o \ + adm_parse.o \ + adm_network.o \ + adm_listen.o \ + adm_process.o \ + adm_nego.o \ + adm_kpasswd.o \ + adm_kadmin.o \ + adm_fmt_inq.o \ + adm_adm_func.o \ + adm_funcs.o \ + adm_check.o \ + adm_extern.o \ + adm_msgs.o + +all:: kadmind + +kadmind: $(KDBDEPLIB) $(OBJS) $(DEPLIBS) + $(CC) $(CFLAGS) -o kadmind $(OBJS) $(KDBLIB) $(K4LIB) $(KLIB) $(LIBS) + +install:: + $(INSTALL_PROGRAM) kadmind ${DESTDIR}$(SERVER_BINDIR)/kadmind + $(INSTALL_DATA) $(srcdir)/kadmind.M ${DESTDIR}$(SERVER_MANDIR)/kadmind.8 + +clean:: + $(RM) kadmind + diff --git a/src/kadmin.old/server/adm_adm_func.c b/src/kadmin.old/server/adm_adm_func.c new file mode 100644 index 000000000..8fd57b6e8 --- /dev/null +++ b/src/kadmin.old/server/adm_adm_func.c @@ -0,0 +1,831 @@ +/* + * kadmin/server/adm_adm_func.c + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * 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. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * Modify the Kerberos Database + */ + + +#include +#include +#include "com_err.h" + +#include +#include +#ifndef hpux +#include +#endif + +#include "k5-int.h" +#include "adm_extern.h" + +#ifdef SANDIA +extern int classification; +#endif + +krb5_error_code +adm_build_key (context, auth_context, new_passwd, oper_type, entry) + krb5_context context; + krb5_auth_context * auth_context; + char *new_passwd; + int oper_type; + krb5_db_entry entry; +{ + krb5_replay_data replaydata; + krb5_data outbuf; + int retval; +#if defined(MACH_PASS) || defined(SANDIA) + char *tmp_phrase; + char *tmp_passwd; + int pwd_length, phrase_length; +#endif + +#if defined(MACH_PASS) || defined(SANDIA) + + if ((tmp_passwd = (char *) calloc (1, 120)) == (char *) 0) { + com_err("adm_build_key", ENOMEM, "for tmp_passwd"); + return(3); /* No Memory */ + } + + if ((tmp_phrase = (char *) calloc (1, 120)) == (char *) 0) { + free(tmp_passwd); + com_err("adm_build_key", ENOMEM, "for tmp_phrase"); + return(3); /* No Memory */ + } + + if (retval = get_pwd_and_phrase("adm_build_key", &tmp_passwd, + &tmp_phrase)) { + free(tmp_passwd); + free(tmp_phrase); + return(4); /* Unable to get Password */ + } + + if ((outbuf.data = (char *) calloc (1, strlen(tmp_passwd) + 1)) == + (char *) 0) { + com_err("adm_build_key", ENOMEM, "for outbuf.data"); + free(tmp_passwd); + free(tmp_phrase); + return(3); /* No Memory */ + } + + outbuf.length = strlen(tmp_passwd); + (void) memcpy(outbuf.data, tmp_passwd, strlen(tmp_passwd)); + +#else + + if ((outbuf.data = (char *) calloc (1, 3)) == + (char *) 0) { + com_err("adm_build_key", ENOMEM, "for outbuf.data"); + return(3); /* No Memory */ + } + + outbuf.data[0] = KADMIN; + outbuf.data[1] = oper_type; + outbuf.data[2] = KADMGOOD; + outbuf.length = 3; + + if (oper_type == CHGOPER || oper_type == CH4OPER) { + outbuf.data[3] = entry.salt_type; + outbuf.length = 4; + } + +#endif + + /* Encrypt Password and Phrase */ + if (retval = krb5_mk_priv(context, auth_context, &outbuf, + &msg_data, &replaydata)) { + com_err("adm_build_key", retval, "during mk_priv"); +#if defined(MACH_PASS) || defined(SANDIA) + free(tmp_passwd); + free(tmp_phrase); +#endif + free(outbuf.data); + return(5); /* Protocol Failure */ + } + +#if defined(MACH_PASS) || defined(SANDIA) + (void) memcpy(new_passwd, tmp_passwd, strlen(tmp_passwd)); + new_passwd[strlen(tmp_passwd)] = '\0'; + + free(tmp_phrase); + free(tmp_passwd); +#endif + free(outbuf.data); + + /* Send private message to Client */ + if (krb5_write_message(context, &client_server_info.client_socket, + &msg_data)){ + free(msg_data.data); + com_err("adm_build_key", 0, "Error Performing Password Write"); + return(5); /* Protocol Failure */ + } + + free(msg_data.data); + + /* Read Client Response */ + if (krb5_read_message(context, &client_server_info.client_socket, &inbuf)){ + syslog(LOG_ERR | LOG_INFO, "Error Performing Password Read"); + return(5); /* Protocol Failure */ + } + + /* Decrypt Client Response */ + if (retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + syslog(LOG_ERR | LOG_INFO, "adm_build_key krb5_rd_priv error"); + free(inbuf.data); + return(5); /* Protocol Failure */ + } + free(inbuf.data); + +#if !defined(MACH_PASS) && !defined(SANDIA) + memcpy(new_passwd, msg_data.data, msg_data.length); +#endif + + free(msg_data.data); + return(0); +} + +/* kadmin change password request */ +krb5_error_code +adm_change_pwd(context, auth_context, prog, customer_name, salttype) + krb5_context context; + krb5_auth_context * auth_context; + char *prog; + char *customer_name; + int salttype; +{ + krb5_db_entry entry; + int nprincs = 1; + + krb5_error_code retval; + krb5_principal newprinc; + char *composite_name; + char *new_passwd; + int oper_type; + + syslog(LOG_AUTH | LOG_INFO, + "Remote Administrative Password Change Request for %s by %s", + customer_name, client_server_info.name_of_client); + + if (retval = krb5_parse_name(context, customer_name, &newprinc)) { + syslog(LOG_ERR | LOG_INFO, "parse failure while parsing '%s'", + customer_name); + return(5); /* Protocol Failure */ + } + + if (!(adm_princ_exists(context, "adm_change_pwd", newprinc, + &entry, &nprincs))) { + com_err("adm_change_pwd", 0, "Principal does not exist!"); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(1); /* Principal Unknown */ + } + + if ((new_passwd = (char *) calloc (1, ADM_MAX_PW_LENGTH+1)) == (char *) 0) { + com_err("adm_change_pwd", ENOMEM, "while allocating new_passwd!"); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(3); /* No Memory */ + } + + oper_type = (salttype == KRB5_KDB_SALTTYPE_NORMAL) ? CHGOPER : CH4OPER; + + if (retval = adm_build_key(context, auth_context, new_passwd, + oper_type, entry)) { + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + free(new_passwd); + return(retval); + } + + retval = krb5_unparse_name(context, newprinc, &composite_name); + + entry.salt_type = (krb5_int32) salttype; + + if (retval = adm_enter_pwd_key(context, "adm_change_pwd", + composite_name, + newprinc, + newprinc, + 1, /* chg_entry */ + salttype, + new_passwd, + &entry)) retval = 8; + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + free(composite_name); + + (void) memset(new_passwd, 0, strlen(new_passwd)); + free(new_passwd); + return(0); +} + +/* kadmin add new random key function */ +krb5_error_code +adm_change_pwd_rnd(context, cmdname, customer_name) + krb5_context context; + char *cmdname; + char *customer_name; +{ + krb5_db_entry entry; + int nprincs = 1; + krb5_error_code retval; + krb5_principal newprinc; + + + syslog(LOG_AUTH | LOG_INFO, + "Remote Administrative Random Password Change Request for %s by %s", + customer_name, client_server_info.name_of_client); + + if (retval = krb5_parse_name(context, customer_name, &newprinc)) { + com_err("adm_change_pwd_rnd", retval, "while parsing '%s'", customer_name); + return(5); /* Protocol Failure */ + } +#ifdef SANDIA + if (!(newprinc[2])) { + if (retval = check_security(newprinc, classification)) { + krb5_free_principal(context, newprinc); + syslog(LOG_ERR, "Principal (%s) - Incorrect Classification level", + customer_name); + return(6); + } + } +#endif + if (!(adm_princ_exists(context, "adm_change_pwd_rnd", newprinc, + &entry, &nprincs))) { + com_err("adm_change_pwd_rnd", 0, "Principal does not exist!"); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(1); /* Principal Unknown */ + } + + if (retval = adm_enter_rnd_pwd_key(context, "adm_change_pwd_rnd", + newprinc, + 1, /* change existing entry */ + &entry)) + retval = 8; + + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(retval); +} + +/* kadmin add new key function */ +krb5_error_code +adm_add_new_key(context, auth_context, cmdname, customer_name, salttype) + krb5_context context; + krb5_auth_context *auth_context; + char *cmdname; + char *customer_name; + int salttype; +{ + krb5_db_entry entry; + int nprincs = 1; + + krb5_error_code retval; + krb5_principal newprinc; + char *new_passwd; + + syslog(LOG_AUTH | LOG_INFO, + "Remote Administrative Addition Request for %s by %s", + customer_name, client_server_info.name_of_client); + + if (retval = krb5_parse_name(context, customer_name, &newprinc)) { + com_err("adm_add_new_key", retval, "while parsing '%s'", customer_name); + return(5); /* Protocol Failure */ + } +#ifdef SANDIA + if (!(newprinc[2])) { + if (retval = check_security(newprinc, classification)) { + krb5_free_principal(context, newprinc); + syslog(LOG_ERR, "Principal (%s) - Incorrect Classification level", + customer_name); + return(6); + } + } +#endif + if (adm_princ_exists(context, "adm_add_new_key",newprinc,&entry,&nprincs)) { + com_err("adm_add_new_key", 0, + "principal '%s' already exists", customer_name); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(2); /* Principal Already Exists */ + } + + if ((new_passwd = (char *) calloc (1, 255)) == (char *) 0) { + com_err("adm_add_new_key", ENOMEM, "for new_passwd"); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(3); /* No Memory */ + } + + if (retval = adm_build_key(context, auth_context, new_passwd, + ADDOPER, entry)) { + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + free(new_passwd); + return(retval); + } + + if (retval = adm_enter_pwd_key(context, "adm_add_new_key", + customer_name, + newprinc, + newprinc, + 0, /* new_entry */ + salttype, + new_passwd, + &entry)) + retval = 8; + (void) memset(new_passwd, 0, strlen(new_passwd)); + free(new_passwd); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(retval); +} + +/* kadmin add new random key function */ +krb5_error_code +adm_add_new_key_rnd(context, cmdname, customer_name) + krb5_context context; + char *cmdname; + char *customer_name; +{ + krb5_db_entry entry; + int nprincs = 1; + krb5_error_code retval; + krb5_principal newprinc; + + + syslog(LOG_AUTH | LOG_INFO, + "Remote Administrative Addition Request for %s by %s", + customer_name, client_server_info.name_of_client); + + if (retval = krb5_parse_name(context, customer_name, &newprinc)) { + com_err("adm_add_new_key_rnd", retval, "while parsing '%s'", customer_name); + return(5); /* Protocol Failure */ + } +#ifdef SANDIA + if (!(newprinc[2])) { + if (retval = check_security(newprinc, classification)) { + krb5_free_principal(context, newprinc); + syslog(LOG_ERR, "Principal (%s) - Incorrect Classification level", + customer_name); + return(6); + } + } +#endif + if (adm_princ_exists(context, "adm_add_new_key_rnd", newprinc, + &entry, &nprincs)) { + com_err("adm_add_new_key_rnd", 0, + "principal '%s' already exists", customer_name); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(2); /* Principal Already Exists */ + } + + if (retval = adm_enter_rnd_pwd_key(context, "adm_add_new_key_rnd", + newprinc, + 0, /* new entry */ + &entry)) + retval = 8; + + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(retval); +} + +/* kadmin delete old key function */ +krb5_error_code +adm_del_old_key(context, cmdname, customer_name) + krb5_context context; + char *cmdname; + char *customer_name; +{ + krb5_db_entry entry; + int nprincs = 1; + + krb5_error_code retval; + krb5_principal newprinc; + int one = 1; + + syslog(LOG_AUTH | LOG_INFO, + "Remote Administrative Deletion Request for %s by %s", + customer_name, client_server_info.name_of_client); + + if (retval = krb5_parse_name(context, customer_name, &newprinc)) { + com_err("adm_del_old_key", retval, "while parsing '%s'", customer_name); + return(5); /* Protocol Failure */ + } + + if (!adm_princ_exists(context, "adm_del_old_key", newprinc, + &entry, &nprincs)) { + com_err("adm_del_old_key", 0, "principal '%s' is not in the database", + customer_name); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(1); + } + + if (retval = krb5_db_delete_principal(context, newprinc, &one)) { + com_err("adm_del_old_key", retval, + "while deleting '%s'", customer_name); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(8); + } else if (one != 1) { + com_err("adm_del_old_key", 0, + "no principal deleted - unknown error"); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(8); + } + + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(0); +} + +/* kadmin modify existing Principal function */ +krb5_error_code +adm_mod_old_key(context, auth_context, cmdname, customer_name) + krb5_context context; + krb5_auth_context * auth_context; + char *cmdname; + char *customer_name; +{ + krb5_replay_data replaydata; + krb5_db_entry entry; + int nprincs = 1; + extern int errno; + + krb5_error_code retval; + krb5_principal newprinc; + + krb5_data outbuf; + char tempstr[20]; + + int one = 1; + + syslog(LOG_AUTH | LOG_INFO, + "Remote Administrative Modification Request for %s by %s", + customer_name, client_server_info.name_of_client); + + if (retval = krb5_parse_name(context, customer_name, &newprinc)) { + com_err("adm_mod_old_key", retval, "while parsing '%s'", customer_name); + return(5); /* Protocol Failure */ + } + + for ( ; ; ) { + + if (!adm_princ_exists(context, "adm_mod_old_key", newprinc, + &entry, &nprincs)) { + krb5_db_free_principal(context, &entry, nprincs); + com_err("adm_mod_old_key", 0, + "principal '%s' is not in the database", + customer_name); + krb5_free_principal(context, newprinc); + return(1); + } + + /* Send Acknowledgement */ + if ((outbuf.data = (char *) calloc (1, 255)) == (char *) 0) { + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + com_err("adm_mod_old_key", ENOMEM, "for outbuf.data"); + return(3); /* No Memory */ + } + + outbuf.length = 3; + outbuf.data[0] = KADMIND; + outbuf.data[1] = MODOPER; + outbuf.data[2] = SENDDATA3; + + if (retval = krb5_mk_priv(context, auth_context, &outbuf, + &msg_data, &replaydata)) { + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + com_err("adm_mod_old_key", retval, "during mk_priv"); + free(outbuf.data); + return(5); /* Protocol Failure */ + } + free(outbuf.data); + + if (krb5_write_message(context, &client_server_info.client_socket, + &msg_data)){ + free(msg_data.data); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + com_err("adm_mod_old_key", 0, + "Error Performing Modification Write"); + return(5); /* Protocol Failure */ + } + free(msg_data.data); + + /* Read Client Response */ + if (krb5_read_message(context, &client_server_info.client_socket, &inbuf)){ + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + com_err("adm_mod_old_key", errno, + "Error Performing Modification Read"); + return(5); /* Protocol Failure */ + } + + /* Decrypt Client Response */ + if (retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + com_err("adm_mod_old_key", retval, "krb5_rd_priv error %s", + error_message(retval)); + free(inbuf.data); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(5); /* Protocol Failure */ + } + + free(inbuf.data); + + if (msg_data.data[1] == KADMGOOD) break; + + /* Decode Message - Modify Database */ + if (msg_data.data[2] != SENDDATA3) { + free(msg_data.data); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(5); /* Protocol Failure */ + } +#ifdef SANDIA + if (msg_data.data[3] == KMODFCNT) { + (void) memcpy(tempstr, (char *) msg_data.data + 4, + msg_data.length - 4); + entry.fail_auth_count = atoi(tempstr); + } +#endif + if (msg_data.data[3] == KMODVNO) { + (void) memcpy(tempstr, (char *) msg_data.data + 4, + msg_data.length - 4); + entry.kvno = atoi(tempstr); + } + + if (msg_data.data[3] == KMODATTR) { + if (msg_data.data[4] == ATTRPOST) + entry.attributes &= ~KRB5_KDB_DISALLOW_POSTDATED; + if (msg_data.data[4] == ATTRNOPOST) + entry.attributes |= KRB5_KDB_DISALLOW_POSTDATED; + if (msg_data.data[4] == ATTRFOR) + entry.attributes &= ~KRB5_KDB_DISALLOW_FORWARDABLE; + if (msg_data.data[4] == ATTRNOFOR) + entry.attributes |= KRB5_KDB_DISALLOW_FORWARDABLE; + if (msg_data.data[4] == ATTRTGT) + entry.attributes &= ~KRB5_KDB_DISALLOW_TGT_BASED; + if (msg_data.data[4] == ATTRNOTGT) + entry.attributes |= KRB5_KDB_DISALLOW_TGT_BASED; + if (msg_data.data[4] == ATTRREN) + entry.attributes &= ~KRB5_KDB_DISALLOW_RENEWABLE; + if (msg_data.data[4] == ATTRNOREN) + entry.attributes |= KRB5_KDB_DISALLOW_RENEWABLE; + if (msg_data.data[4] == ATTRPROXY) + entry.attributes &= ~KRB5_KDB_DISALLOW_PROXIABLE; + if (msg_data.data[4] == ATTRNOPROXY) + entry.attributes |= KRB5_KDB_DISALLOW_PROXIABLE; + if (msg_data.data[4] == ATTRDSKEY) + entry.attributes &= ~KRB5_KDB_DISALLOW_DUP_SKEY; + if (msg_data.data[4] == ATTRNODSKEY) + entry.attributes |= KRB5_KDB_DISALLOW_DUP_SKEY; + if (msg_data.data[4] == ATTRLOCK) + entry.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; + if (msg_data.data[4] == ATTRUNLOCK) + entry.attributes &= ~KRB5_KDB_DISALLOW_ALL_TIX; + if (msg_data.data[4] == ATTRNOSVR) + entry.attributes |= KRB5_KDB_DISALLOW_SVR; + if (msg_data.data[4] == ATTRSVR) + entry.attributes &= ~KRB5_KDB_DISALLOW_SVR; +#ifdef SANDIA + if (msg_data.data[4] == ATTRPRE) + entry.attributes &= ~KRB5_KDB_REQUIRES_PRE_AUTH; + if (msg_data.data[4] == ATTRNOPRE) + entry.attributes |= KRB5_KDB_REQUIRES_PRE_AUTH; + if (msg_data.data[4] == ATTRPWOK) + entry.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; + if (msg_data.data[4] == ATTRPWCHG) + entry.attributes |= KRB5_KDB_REQUIRES_PWCHANGE; + if (msg_data.data[4] == ATTRSID) + entry.attributes &= ~KRB5_KDB_REQUIRES_SECUREID; + if (msg_data.data[4] == ATTRNOSID) + entry.attributes |= KRB5_KDB_REQUIRES_SECUREID; +#endif + } + + free(msg_data.data); + entry.mod_name = client_server_info.client; + if (retval = krb5_timeofday(context, &entry.mod_date)) { + com_err("adm_mod_old_key", retval, "while fetching date"); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(5); /* Protocol Failure */ + } + + retval = krb5_db_put_principal(context, &entry, &one); + if (retval) { + com_err("adm_mod_old_key", retval, "while storing principal"); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return(8); /* Update failed */ + } + one = 1; + } /* for */ + + krb5_db_free_principal(context, &entry, nprincs); + krb5_free_principal(context, newprinc); + + /* Read Client Response */ + if (krb5_read_message(context, &client_server_info.client_socket, &inbuf)){ + com_err("adm_mod_old_key", errno, "Error Performing Read"); + return(5); /* Protocol Failure */ + } + + /* Decrypt Client Response */ + if (retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + com_err("adm_mod_old_key", retval, "krb5_rd_priv error %s", + error_message(retval)); + free(inbuf.data); + return(5); /* Protocol Failure */ + } + + free(msg_data.data); + free(inbuf.data); + + return(0); +} + +/* kadmin inquire existing Principal function */ +krb5_error_code +adm_inq_old_key(context, auth_context, cmdname, customer_name) + krb5_context context; + krb5_auth_context * auth_context; + char *cmdname; + char *customer_name; +{ + krb5_replay_data replaydata; + krb5_db_entry entry; + int nprincs = 1; + + krb5_data outbuf; + krb5_error_code retval; + krb5_principal newprinc; + char *fullname; + + syslog(LOG_AUTH | LOG_INFO, + "Remote Administrative Inquiry Request for %s by %s", + customer_name, client_server_info.name_of_client); + + if (retval = krb5_parse_name(context, customer_name, &newprinc)) { + com_err("adm_inq_old_key", retval, "while parsing '%s'", customer_name); + return(5); /* Protocol Failure */ + } + + if (retval = krb5_unparse_name(context, newprinc, &fullname)) { + krb5_free_principal(context, newprinc); + com_err("adm_inq_old_key", retval, "while unparsing"); + return(5); /* Protocol Failure */ + } + + if (!adm_princ_exists(context, "adm_inq_old_key", newprinc, + &entry, &nprincs)) { + krb5_db_free_principal(context, &entry, nprincs); + krb5_free_principal(context, newprinc); + free(fullname); + com_err("adm_inq_old_key", 0, "principal '%s' is not in the database", + customer_name); + return(1); + } + + if ((outbuf.data = (char *) calloc (1, 2048)) == (char *) 0) { + krb5_db_free_principal(context, &entry, nprincs); + krb5_free_principal(context, newprinc); + free(fullname); + com_err("adm_inq_old_key", ENOMEM, "for outbuf.data"); + return(3); /* No Memory */ + } + + /* Format Inquiry Data */ + if ((retval = adm_fmt_prt(context, &entry, fullname, outbuf.data))) { + krb5_db_free_principal(context, &entry, nprincs); + krb5_free_principal(context, newprinc); + free(fullname); + com_err("adm_inq_old_key", 0, "Unable to Format Inquiry Data"); + return(5); /* XXX protocol failure --- not right, but.. */ + } + outbuf.length = strlen(outbuf.data); + krb5_db_free_principal(context, &entry, nprincs); + krb5_free_principal(context, newprinc); + free(fullname); + + /* Encrypt Inquiry Data */ + if (retval = krb5_mk_priv(context, auth_context, &outbuf, + &msg_data, &replaydata)) { + com_err("adm_inq_old_key", retval, "during mk_priv"); + free(outbuf.data); + return(5); /* Protocol Failure */ + } + free(outbuf.data); + + /* Send Inquiry Information */ + if (krb5_write_message(context, &client_server_info.client_socket, + &msg_data)){ + free(msg_data.data); + com_err("adm_inq_old_key", 0, "Error Performing Write"); + return(5); /* Protocol Failure */ + } + + free(msg_data.data); + + /* Read Client Response */ + if (krb5_read_message(context, &client_server_info.client_socket, &inbuf)){ + com_err("adm_inq_old_key", errno, "Error Performing Read"); + syslog(LOG_ERR, "adm_inq sock %d", client_server_info.client_socket); + return(5); /* Protocol Failure */ + } + + /* Decrypt Client Response */ + if (retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + com_err("adm_inq_old_key", retval, "krb5_rd_priv error %s", + error_message(retval)); + free(inbuf.data); + return(5); /* Protocol Failure */ + } + + /* XXX Decrypt client response.... and we don't use it?!? */ + + free(msg_data.data); + free(inbuf.data); + return(retval); +} + +#ifdef SANDIA +krb5_error_code + check_security(princ, class) +krb5_principal princ; +int class; +{ + char *input_name; + + if ((input_name = (char *) calloc (1, 255)) == 0) { + com_err("check_security", + ENOMEM, "while allocating memory for class check"); + return(3); + } + + memcpy((char *) input_name, princ->data[0].data, princ->data[0].length); + + if (class) { + /* Must be Classified Principal */ + if (strlen(input_name) == 8) { + if (!(strcmp(&input_name[7], "s") == 0) && + !(strcmp(&input_name[7], "c") == 0)) { + free(input_name); + return(6); + } + } else { + if (!((strncmp(&input_name[strlen(input_name) - 2], + "_s", 2) == 0) || + (strncmp(&input_name[strlen(input_name) - 2], "_c", 2) == 0))) { + free(input_name); + return(6); + } + } + } else { + /* Must be Unclassified Principal */ + if ((strlen(input_name) >= 8) || + ((strncmp(&input_name[strlen(input_name) - 2], "_s", 2) == 0) || + (strncmp(&input_name[strlen(input_name) - 2], "_c", 2) == 0))) { + free(input_name); + return(6); + } + } + + free(input_name); + return(0); +} +#endif diff --git a/src/kadmin.old/server/adm_check.c b/src/kadmin.old/server/adm_check.c new file mode 100644 index 000000000..67cd24bde --- /dev/null +++ b/src/kadmin.old/server/adm_check.c @@ -0,0 +1,136 @@ +/* + * kadmin/server/adm_check.c + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * 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. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + */ + + +#include +#include +#include +#include +#include "com_err.h" + +#include +#include +#ifndef hpux +#include +#endif + +#include "k5-int.h" +#include "adm_err.h" +#include "adm_extern.h" + +krb5_error_code +adm_check_acl(name_of_client, acl_type) + char *name_of_client; + char *acl_type; +{ + FILE *acl_file; + char input_string[255]; + char admin_name[255]; +#define num_of_privs 5 + char priv[num_of_privs]; + extern char *acl_file_name; + char *lcl_acl_file; + int i, j; + + if ((lcl_acl_file = (char *) calloc(1, 80)) == (char *) 0) { + com_err("adm_check_acl", ENOMEM, "allocating acl file name"); + return(KADM_ENOMEM); /* No Memory */ + } + + (void) sprintf(lcl_acl_file, "%s", acl_file_name); + + if ((acl_file = fopen(lcl_acl_file, "r")) == NULL) { + syslog(LOG_ERR, "Cannot open acl file (%s)", acl_file_name); + free(lcl_acl_file); + return(KADM_EPERM); + } + + for ( ;; ) { + + if ((fgets(input_string, sizeof(input_string), acl_file)) == NULL) { + syslog(LOG_ERR, "Administrator (%s) not in ACL file (%s)", + name_of_client, lcl_acl_file); + break; /* Not Found */ + } + + if (input_string[0] == '#') continue; + + i = 0; + while (!isspace(input_string[i]) && i < strlen(input_string)) { + admin_name[i] = input_string[i]; + i++; + } + + while (isspace(input_string[i]) && i < strlen(input_string)) { + i++; + } + + priv[0] = priv[1] = priv[2] = priv[3] = priv[4] = '\0'; + + j = 0; + while ((i < strlen(input_string)) && (j < num_of_privs) && + (!isspace(input_string[i]))) { + priv[j] = input_string[i]; + i++; j++; + } + + if (priv[0] == '*') { + priv[0] = 'a'; /* Add Priv */ + priv[1] = 'c'; /* Changepw Priv */ + priv[2] = 'd'; /* Delete Priv */ + priv[3] = 'i'; /* Inquire Priv */ + priv[4] = 'm'; /* Modify Priv */ + } + + if (!strncmp(admin_name, name_of_client, + strlen(name_of_client))) { + switch(acl_type[0]) { + case 'a': + case 'c': + case 'd': + case 'i': + case 'm': + for (i = 0; i < num_of_privs; i++) { + if (priv[i] == acl_type[0]) { + fclose(acl_file); + free(lcl_acl_file); + return(0); /* Found */ + } + } + break; + + default: + break; + } + } + } + + fclose(acl_file); + free(lcl_acl_file); + return(KADM_EPERM); +} diff --git a/src/kadmin.old/server/adm_extern.c b/src/kadmin.old/server/adm_extern.c new file mode 100644 index 000000000..24b2b39a9 --- /dev/null +++ b/src/kadmin.old/server/adm_extern.c @@ -0,0 +1,57 @@ +/* + * kadmin/server/adm_extern.c + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * Export of this software from the United States of America may + * 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. + * + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * allocations of adm_extern stuff + */ + +#include "k5-int.h" + +/* real declarations of KDC's externs */ +krb5_encrypt_block master_encblock; +krb5_keyblock master_keyblock; +krb5_principal master_princ; + +volatile int signal_requests_exit = 0; /* gets set when signal hits */ + +char *dbm_db_name = DEFAULT_KDB_FILE; +char *realm = NULL; + +krb5_keyblock tgs_key; +krb5_kvno tgs_kvno; + +krb5_data inbuf; +krb5_data msg_data; + +int send_seqno; + +/* +static krb5_data tgs_name = {KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME}; +krb5_data *tgs_server[4] = {0, &tgs_name, 0, 0}; +*/ + +krb5_principal tgs_server; + +short admin_port = 0; diff --git a/src/kadmin.old/server/adm_extern.h b/src/kadmin.old/server/adm_extern.h new file mode 100644 index 000000000..017689643 --- /dev/null +++ b/src/kadmin.old/server/adm_extern.h @@ -0,0 +1,237 @@ +/* + * kadmin/server/adm_extern.h + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * Export of this software from the United States of America may + * 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. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * <<< Description >>> + */ + +#ifndef __ADM_EXTERN__ +#define __ADM_EXTERN__ + +#include "adm_defs.h" + +typedef struct { + /* Client Info */ + struct sockaddr_in client_name; + krb5_address client_addr; + krb5_principal client; + char *name_of_client; + /* Server Info */ + struct sockaddr_in server_name; + krb5_address server_addr; + krb5_principal server; + char *name_of_service; + /* Miscellaneous */ + int server_socket; + int client_socket; +} global_client_server_info; + +/* various externs for KDC */ +extern krb5_encrypt_block master_encblock; +extern krb5_keyblock master_keyblock; +extern krb5_principal master_princ; +extern krb5_db_entry master_entry; + +extern volatile int signal_requests_exit; +extern char *dbm_db_name; +extern char *realm; + +extern krb5_keyblock tgs_key; +extern krb5_kvno tgs_kvno; +extern krb5_principal tgs_server; + +extern global_client_server_info client_server_info; +extern char *adm5_tcp_portname; +extern int adm5_tcp_port_fd; + +extern unsigned pidarraysize; +extern int *pidarray; + +extern char *adm5_ver_str; +extern int adm5_ver_len; + +extern int adm_debug_flag; + +extern int send_seqno; + +extern int exit_now; + +extern short admin_port; + +extern krb5_data inbuf; +extern krb5_data msg_data; + +extern char *oper_type[]; +extern char *ksrvutil_message[]; +extern char *kadmind_general_response[]; +extern char *kadmind_kpasswd_response[]; +extern char *kadmind_ksrvutil_response[]; +extern char *kadmind_kadmin_response[]; + +/* PROTOTYPES */ + +krb5_error_code adm_build_key + PROTOTYPE((krb5_context, + krb5_auth_context *, + char *, + int, + krb5_db_entry)); + +krb5_error_code adm_change_pwd + PROTOTYPE((krb5_context, + krb5_auth_context *, + char *, + char *, + int)); + +krb5_error_code adm_change_pwd_rnd + PROTOTYPE((krb5_context, + char *, + char *)); + +krb5_error_code adm_add_new_key + PROTOTYPE((krb5_context, + krb5_auth_context *, + char *, + char *, + int)); + +krb5_error_code adm_add_new_key_rnd + PROTOTYPE((krb5_context, + char *, + char *)); + +krb5_error_code adm_del_old_key + PROTOTYPE((krb5_context, + char *, + char *)); + +krb5_error_code adm_mod_old_key + PROTOTYPE((krb5_context, + krb5_auth_context *, + char *, + char *)); + +krb5_error_code adm_inq_old_key + PROTOTYPE((krb5_context, + krb5_auth_context *, + char *, + char *)); + +krb5_error_code adm_print_exp_time + PROTOTYPE((krb5_context, + char *, + krb5_timestamp)); + +krb5_kvno adm_princ_exists + PROTOTYPE((krb5_context, + char *, + krb5_principal, + krb5_db_entry *, + int *)); + +krb5_error_code adm_enter_rnd_pwd_key + PROTOTYPE((krb5_context, + char *, + krb5_principal, + int, + krb5_db_entry *)); + +krb5_error_code adm5_kadmin + PROTOTYPE((krb5_context, + krb5_auth_context *, + char *, + char *, + int *)); + +krb5_error_code adm_negotiate_key + PROTOTYPE((krb5_context, + krb5_auth_context *, + char const *, + char *)); + +krb5_error_code setup_network + PROTOTYPE((krb5_context, + const char *)); + +krb5_error_code process_client + PROTOTYPE((krb5_context, + char *)); + +krb5_error_code cleanexit + PROTOTYPE((krb5_context, + int)); + +krb5_error_code closedown_db + PROTOTYPE((krb5_context)); + +krb5_error_code process_args + PROTOTYPE((krb5_context, + int, + char **)); + +krb5_error_code init_db + PROTOTYPE((krb5_context, + char *, + krb5_principal, + krb5_keyblock *)); + +void setup_com_err + PROTOTYPE((krb5_context)); + +krb5_error_code princ_exists + PROTOTYPE((krb5_context, + krb5_principal, + krb5_db_entry *)); + +krb5_error_code adm_enter_pwd_key + PROTOTYPE((krb5_context, + char * , + char * , + krb5_const_principal , + krb5_const_principal , + int , + int , + char * , + krb5_db_entry * )); + +krb5_error_code adm5_change + PROTOTYPE((krb5_context, + krb5_auth_context *, + char *, + krb5_principal)); + +int adm5_listen_and_process + PROTOTYPE((krb5_context, + const char *)); + +krb5_error_code adm5_kpasswd + PROTOTYPE((krb5_context, + krb5_auth_context *, + char *, + kadmin_requests *, + char *, + int *)); + +#endif /* __ADM_EXTERN__ */ diff --git a/src/kadmin.old/server/adm_fmt_inq.c b/src/kadmin.old/server/adm_fmt_inq.c new file mode 100644 index 000000000..40c79a1fe --- /dev/null +++ b/src/kadmin.old/server/adm_fmt_inq.c @@ -0,0 +1,211 @@ +/* + * kadmin/server/adm_fmt_inq.c + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * 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. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * Administrative Display Routine + */ + +#include "k5-int.h" +#include + +#ifdef HAVE_SYS_TIME_H +#include +#ifdef TIME_WITH_SYS_TIME +#include +#endif +#else +#include +#endif + +#define REALM_SEP '@' +#define REALM_SEP_STR "@" + +krb5_error_code +adm_print_attributes(ret_data, attribs) +char *ret_data; +krb5_flags attribs; +{ + char *my_data; + + if ((my_data = (char *) calloc (1,255)) == (char *) 0) + return ENOMEM; + + sprintf(my_data, "Principal Attributes (PA): "); + if (attribs & KRB5_KDB_DISALLOW_POSTDATED) + strcat(my_data, "NOPOST "); + else + strcat(my_data, "POST "); + if (attribs & KRB5_KDB_DISALLOW_FORWARDABLE) + strcat(my_data, "NOFOR "); + else + strcat(my_data, "FOR "); + if (attribs & KRB5_KDB_DISALLOW_TGT_BASED) + strcat(my_data, "NOTGT "); + else + strcat(my_data, "TGT "); + if (attribs & KRB5_KDB_DISALLOW_RENEWABLE) + strcat(my_data, "NOREN "); + else + strcat(my_data, "REN "); + if (attribs & KRB5_KDB_DISALLOW_PROXIABLE) + strcat(my_data, "NOPROXY\n"); + else + strcat(my_data, "PROXY\n"); + strcat(my_data, " "); + if (attribs & KRB5_KDB_DISALLOW_DUP_SKEY) + strcat(my_data, "NODUPSKEY "); + else + strcat(my_data, "DUPSKEY "); + if (attribs & KRB5_KDB_DISALLOW_ALL_TIX) + strcat(my_data, "LOCKED "); + else + strcat(my_data, "UNLOCKED "); + if (attribs & KRB5_KDB_DISALLOW_SVR) + strcat(my_data, "NOSVR\n"); + else + strcat(my_data, "SVR\n"); + +#ifdef SANDIA + strcat(my_data, " "); + if (attribs & KRB5_KDB_REQUIRES_PRE_AUTH) + strcat(my_data, "PREAUTH "); + else + strcat(my_data, "NOPREAUTH "); + if (attribs & KRB5_KDB_REQUIRES_PWCHANGE) + strcat(my_data, "PWCHG "); + else + strcat(my_data, "PWOK "); + if (attribs & KRB5_KDB_REQUIRES_HW_AUTH) + strcat(my_data, "SID\n"); + else + strcat(my_data, "NOSID\n"); +#endif + (void) strcat(ret_data, my_data); + free(my_data); + return(0); +} + +krb5_error_code +adm_print_exp_time(context, ret_data, time_input) + krb5_context context; + char *ret_data; + krb5_timestamp *time_input; +{ + char *my_data; + struct tm *exp_time; + + if ((my_data = (char *) calloc (1,255)) == (char *) 0) + return ENOMEM; + + exp_time = localtime((time_t *) time_input); + sprintf(my_data, + "Principal Expiration Date (PED): %02d%02d/%02d/%02d:%02d:%02d:%02d\n", + (exp_time->tm_year >= 100) ? 20 : 19, + (exp_time->tm_year >= 100) ? exp_time->tm_year - 100 : exp_time->tm_year, + exp_time->tm_mon + 1, + exp_time->tm_mday, + exp_time->tm_hour, + exp_time->tm_min, + exp_time->tm_sec); + (void) strcat(ret_data, my_data); + free(my_data); + return(0); +} + +krb5_error_code +adm_fmt_prt(context, entry, Principal_name, ret_data) + krb5_context context; + krb5_db_entry *entry; + char *Principal_name; + char *ret_data; +{ + struct tm *mod_time; + krb5_error_code retval; +#ifdef SANDIA + struct tm *exp_time; + int pwd_expire; + krb5_timestamp now; +#endif + + char *my_data; + char thisline[80]; + + if ((my_data = (char *) calloc (1, 2048)) == (char *) 0) + return ENOMEM; + + (void) sprintf(my_data, "\n\nPrincipal: %s\n\n", Principal_name); + sprintf(thisline, + "Maximum Ticket Lifetime (MTL) = %d (seconds)\n", entry->max_life); + strcat(my_data, thisline); + sprintf(thisline, "Maximum Renewal Lifetime (MRL) = %d (seconds)\n", + entry->max_renewable_life); + strcat(my_data, thisline); + sprintf(thisline, "Principal Key Version (PKV) = %d\n", entry->kvno); + strcat(my_data, thisline); + if (retval = adm_print_exp_time(context, my_data, &entry->expiration)) { + free(my_data); + return retval; + } + mod_time = localtime((time_t *) &entry->mod_date); + sprintf(thisline, + "Last Modification Date (LMD): %02d%02d/%02d/%02d:%02d:%02d:%02d\n", + (mod_time->tm_year >= 100) ? 20 : 19, + (mod_time->tm_year >= 100) ? mod_time->tm_year - 100 : mod_time->tm_year, + mod_time->tm_mon + 1, + mod_time->tm_mday, + mod_time->tm_hour, + mod_time->tm_min, + mod_time->tm_sec); + strcat(my_data, thisline); + if (retval = adm_print_attributes(my_data, entry->attributes)) { + free(my_data); + return retval; + } + switch (entry->salt_type & 0xff) { + case 0 : strcat(my_data, + "Principal Salt Type (PST) = Version 5 Normal\n"); + break; + case 1 : strcat(my_data, "Principal Salt Type (PST) = Version 4\n"); + break; + case 2 : strcat(my_data, "Principal Salt Type (PST) = NOREALM\n"); + break; + case 3 : strcat(my_data, "Principal Salt Type (PST) = ONLYREALM\n"); + break; + case 4 : strcat(my_data, "Principal Salt Type (PST) = Special\n"); + break; + } +#ifdef SANDIA + sprintf(thisline, + "Invalid Authentication Count (FCNT) = %d\n", entry->fail_auth_count); + strcat(my_data, thisline); + retval = krb5_timeofday(context, &now); + pwd_expire = (now - entry->last_pwd_change) / 86400; + sprintf(thisline, "Password Age is %d Days\n", pwd_expire); + strcat(my_data, thisline); +#endif + (void) strcat(ret_data, my_data); + free(my_data); + return(0); +} diff --git a/src/kadmin.old/server/adm_funcs.c b/src/kadmin.old/server/adm_funcs.c new file mode 100644 index 000000000..7d61c7e06 --- /dev/null +++ b/src/kadmin.old/server/adm_funcs.c @@ -0,0 +1,574 @@ +/* + * kadmin/server/adm_funcs.c + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * 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. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * Modify the Kerberos Database + */ + +#include "com_err.h" +#include + +#include +#include +#ifndef hpux +#include +#endif + +#include "k5-int.h" +#include "adm_err.h" +#include "adm_extern.h" + +struct saltblock { + int salttype; + krb5_data saltdata; +}; + +extern krb5_encrypt_block master_encblock; +extern krb5_keyblock master_keyblock; + +typedef unsigned char des_cblock[8]; + +krb5_error_code adm_get_rnd_key PROTOTYPE((char *, + krb5_ticket *, + krb5_authenticator *, + krb5_principal, + int, + krb5_db_entry *)); + +static krb5_error_code adm_modify_kdb + PROTOTYPE((krb5_context, + char const *, + char const *, + krb5_const_principal, + const krb5_keyblock *, + const krb5_keyblock *, + int, + struct saltblock *, + struct saltblock *, + krb5_db_entry *)); + + +krb5_kvno +adm_princ_exists(context, cmdname, principal, entry, nprincs) + krb5_context context; + char *cmdname; + krb5_principal principal; + krb5_db_entry *entry; + int *nprincs; +{ + krb5_boolean more; + krb5_error_code retval; + + if (retval = krb5_db_get_principal(context, principal, entry, + nprincs, &more)) { + com_err("adm_princ_exists", retval, + "while attempting to verify principal's existence"); + return(0); + } + + if (! *nprincs) return(0); + + return(*nprincs); +} + +static krb5_error_code +adm_modify_kdb(context, cmdname, newprinc, principal, key, alt_key, req_type, + salt, altsalt, entry) + krb5_context context; + char const * cmdname; + char const * newprinc; + krb5_const_principal principal; + const krb5_keyblock * key; + const krb5_keyblock * alt_key; + int req_type; + struct saltblock * salt; + struct saltblock * altsalt; + krb5_db_entry * entry; +{ + krb5_error_code retval; + int one = 1; + + krb5_kvno KDB5_VERSION_NUM = 1; + extern krb5_flags NEW_ATTRIBUTES; + + if (!req_type) { /* New entry - initialize */ + memset((char *) entry, 0, sizeof(krb5_db_entry)); + retval = krb5_copy_principal(context, principal, &entry->principal); + if (retval) + return retval; + entry->kvno = KDB5_VERSION_NUM; + entry->max_life = master_entry.max_life; + entry->max_renewable_life = master_entry.max_renewable_life; + entry->mkvno = master_entry.mkvno; + entry->expiration = master_entry.expiration; + retval = krb5_copy_principal(context, master_princ, &entry->mod_name); + if (retval) { + krb5_free_principal(context, entry->principal); + entry->principal = 0; + return retval; + } + } else { /* Modify existing entry */ + entry->kvno++; +#ifdef SANDIA + entry->attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; +#endif + retval = krb5_copy_principal(context, principal, &entry->mod_name); + if (retval) + return retval; + } + + if (key && key->length) { + retval = krb5_kdb_encrypt_key(context, &master_encblock, + key, + &entry->key); + if (retval) { + com_err("adm_modify_kdb", retval, + "while encrypting key for '%s'", newprinc); + return(KADM_NO_ENCRYPT); + } + } + + if (alt_key && alt_key->length) { + retval = krb5_kdb_encrypt_key(context, &master_encblock, + alt_key, + &entry->alt_key); + if (retval) { + if (entry->key.contents) { + memset((char *) entry->key.contents, 0, entry->key.length); + krb5_xfree(entry->key.contents); + entry->key.contents = 0; + } + com_err("adm_modify_kdb", retval, + "while encrypting alt_key for '%s'", newprinc); + return(KADM_NO_ENCRYPT); + } + } + + if (retval = krb5_timeofday(context, &entry->mod_date)) { + com_err("adm_modify_kdb", retval, "while fetching date"); + if (entry->key.contents) { + memset((char *) entry->key.contents, 0, entry->key.length); + krb5_xfree(entry->key.contents); + entry->key.contents = 0; + } + if (entry->alt_key.contents) { + krb5_xfree(entry->alt_key.contents); + memset((char *) entry->alt_key.contents, 0, entry->alt_key.length); + entry->alt_key.contents = 0; + } + return(KRB_ERR_GENERIC); + } + + if (!req_type) { + if (salt->salttype == KRB5_KDB_SALTTYPE_V4) { + entry->attributes = (KRB5_KDB_DISALLOW_DUP_SKEY | NEW_ATTRIBUTES) +#ifdef SANDIA + & ~KRB5_KDB_REQUIRES_PRE_AUTH & ~KRB5_KDB_REQUIRES_HW_AUTH +#endif + ; + } else { + entry->attributes = NEW_ATTRIBUTES; + } + +#ifdef SANDIA + entry->last_pwd_change = entry->mod_date; + entry->last_success = entry->mod_date; + entry->fail_auth_count = 0; +#endif + + if (salt) { + entry->salt_type = salt->salttype; + entry->salt_length = salt->saltdata.length; + entry->salt = (krb5_octet *) salt->saltdata.data; + } else { + entry->salt_type = KRB5_KDB_SALTTYPE_NORMAL; + entry->salt_length = 0; + entry->salt = 0; + } + + /* Set up version 4 alt key and alt salt info.....*/ + if (altsalt) { + entry->alt_salt_type = altsalt->salttype; + entry->alt_salt_length = altsalt->saltdata.length; + entry->alt_salt = (krb5_octet *) altsalt->saltdata.data; + } else { + entry->alt_salt_type = KRB5_KDB_SALTTYPE_NORMAL; + entry->alt_salt_length = 0; + entry->alt_salt = 0; + } + } else { + if (retval = krb5_timeofday(context, &entry->last_pwd_change)) { + com_err("adm_modify_kdb", retval, "while fetching date"); + if (entry->key.contents) { + memset((char *) entry->key.contents, 0, entry->key.length); + krb5_xfree(entry->key.contents); + entry->key.contents = 0; + } + if (entry->alt_key.contents) { + memset((char *) entry->alt_key.contents, 0, + entry->alt_key.length); + krb5_xfree(entry->alt_key.contents); + entry->alt_key.contents = 0; + } + return(5); + } + } + + retval = krb5_db_put_principal(context, entry, &one); + + if (entry->key.contents) { + memset((char *) entry->key.contents, 0, entry->key.length); + krb5_xfree(entry->key.contents); + entry->key.contents = 0; + } + + if (entry->alt_key.contents) { + memset((char *) entry->alt_key.contents, 0, entry->alt_key.length); + krb5_xfree(entry->alt_key.contents); + entry->alt_key.contents = 0; + } + + if (retval) { + com_err("adm_modify_kdb", retval, + "while storing entry for '%s'\n", newprinc); + return(kdb5_err_base + retval); + } + + if (one != 1) + com_err("adm_modify_kdb", 0, "entry not stored in database (unknown failure)"); + return(0); +} + +krb5_error_code +adm_enter_pwd_key(context, cmdname, newprinc, princ, string_princ, req_type, + salttype, new_password, entry) + krb5_context context; + char * cmdname; + char * newprinc; + krb5_const_principal princ; + krb5_const_principal string_princ; + int req_type; + int salttype; + char * new_password; + krb5_db_entry * entry; +{ + krb5_error_code retval; + krb5_keyblock tempkey; + krb5_data pwd; + struct saltblock salt; + struct saltblock altsalt; + krb5_keyblock alttempkey; + + pwd.data = new_password; + pwd.length = strlen((char *) new_password); + + salt.salttype = salttype; + + tempkey.contents = alttempkey.contents = 0; + retval = KRB_ERR_GENERIC; + + switch (salttype) { + case KRB5_KDB_SALTTYPE_NORMAL: + if (retval = krb5_principal2salt(context,string_princ,&salt.saltdata)) { + com_err("adm_enter_pwd_key", retval, + "while converting principal to salt for '%s'", newprinc); + goto cleanup; + } + + altsalt.salttype = KRB5_KDB_SALTTYPE_V4; + altsalt.saltdata.data = 0; + altsalt.saltdata.length = 0; + break; + + case KRB5_KDB_SALTTYPE_V4: + salt.saltdata.data = 0; + salt.saltdata.length = 0; + if (retval = krb5_principal2salt(context, string_princ, + &altsalt.saltdata)) { + com_err("adm_enter_pwd_key", retval, + "while converting principal to altsalt for '%s'", newprinc); + goto cleanup; + } + + altsalt.salttype = KRB5_KDB_SALTTYPE_NORMAL; + break; + + case KRB5_KDB_SALTTYPE_NOREALM: + if (retval = krb5_principal2salt_norealm(context, string_princ, + &salt.saltdata)) { + com_err("adm_enter_pwd_key", retval, + "while converting principal to salt for '%s'", newprinc); + goto cleanup; + } + + altsalt.salttype = KRB5_KDB_SALTTYPE_V4; + altsalt.saltdata.data = 0; + altsalt.saltdata.length = 0; + break; + + case KRB5_KDB_SALTTYPE_ONLYREALM: + { + krb5_data *foo; + if (retval = krb5_copy_data(context, + krb5_princ_realm(context, string_princ), + &foo)) { + com_err("adm_enter_pwd_key", retval, + "while converting principal to salt for '%s'", newprinc); + goto cleanup; + } + + salt.saltdata = *foo; + krb5_xfree(foo); + altsalt.salttype = KRB5_KDB_SALTTYPE_V4; + altsalt.saltdata.data = 0; + altsalt.saltdata.length = 0; + break; + } + + default: + com_err("adm_enter_pwd_key", 0, + "Don't know how to enter salt type %d", salttype); + goto cleanup; + } + + if (retval = krb5_string_to_key(context, &master_encblock, + master_keyblock.keytype, + &tempkey, + &pwd, + &salt.saltdata)) { + com_err("adm_enter_pwd_key", retval, + "while converting password to key for '%s'", newprinc); + goto cleanup; + } + + if (retval = krb5_string_to_key(context, &master_encblock, + master_keyblock.keytype, + &alttempkey, + &pwd, + &altsalt.saltdata)) { + com_err("adm_enter_pwd_key", retval, + "while converting password to alt_key for '%s'", newprinc); + goto cleanup; + } + + memset((char *) new_password, 0, sizeof(new_password)); /* erase it */ + + retval = adm_modify_kdb(context, "adm_enter_pwd_key", + newprinc, + princ, + &tempkey, + &alttempkey, + req_type, + &salt, + &altsalt, + entry); + +cleanup: + if (salt.saltdata.data) + krb5_xfree(salt.saltdata.data); + if (altsalt.saltdata.data) + krb5_xfree(altsalt.saltdata.data); + if (tempkey.contents) { + memset((char *) tempkey.contents, 0, tempkey.length); + krb5_xfree(tempkey.contents); + } + if (alttempkey.contents) { + memset((char *) alttempkey.contents, 0, alttempkey.length); + krb5_xfree(alttempkey.contents); + } + memset((char *) new_password, 0, pwd.length); /* erase password */ + return(retval); +} + +krb5_error_code +adm5_change(context, auth_context, prog, newprinc) + krb5_context context; + krb5_auth_context * auth_context; + char *prog; + krb5_principal newprinc; +{ + krb5_db_entry entry; + int nprincs = 1; + + krb5_error_code retval; + char *composite_name; + char new_passwd[ADM_MAX_PW_LENGTH + 1]; + + if (!(adm_princ_exists(context, "adm5_change", newprinc, + &entry, &nprincs))) { + com_err("adm5_change", 0, "No principal exists!"); + krb5_free_principal(context, newprinc); + return(1); + } + + memset((char *) new_passwd, 0, ADM_MAX_PW_LENGTH + 1); + + /* Negotiate for New Key */ + if (retval = adm_negotiate_key(context, auth_context, "adm5_change", + new_passwd)) { + krb5_db_free_principal(context, &entry, nprincs); + krb5_free_principal(context, newprinc); + return(1); + } + + if (retval = krb5_unparse_name(context, newprinc, &composite_name)) { + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + return retval; + } + + if (entry.salt_type == KRB5_KDB_SALTTYPE_V4) { + entry.salt_type = KRB5_KDB_SALTTYPE_NORMAL; + entry.alt_salt_type = KRB5_KDB_SALTTYPE_V4; + com_err("adm5_change", 0, "Converting v4user to v5user"); + } + + retval = adm_enter_pwd_key(context, "adm5_change", + composite_name, + newprinc, + newprinc, + 1, /* change */ + KRB5_KDB_SALTTYPE_NORMAL, + new_passwd, + &entry); + (void) memset(new_passwd, 0, strlen(new_passwd)); + krb5_free_principal(context, newprinc); + krb5_db_free_principal(context, &entry, nprincs); + free(composite_name); + return(retval); +} + +#ifdef SANDIA +krb5_error_code +adm5_create_rnd(prog, change_princ, client_auth_data, client_creds) +char *prog; +krb5_principal change_princ; +krb5_authenticator *client_auth_data; +krb5_ticket *client_creds; +{ + krb5_db_entry entry; + int nprincs = 1; + + krb5_error_code retval; + + if (!(adm_princ_exists("adm5_create_rnd", + change_princ, + &entry, + &nprincs))) { + com_err("adm5_create_rnd", 0, "No principal exists!"); + krb5_free_principal(change_princ); + return(1); + } + + if (retval = adm_get_rnd_key("adm5_create_rnd", + client_creds, + client_auth_data, + change_princ, + 1, /* change */ + &entry)) { + krb5_db_free_principal(&entry, nprincs); + krb5_free_principal(change_princ); + return(retval); + } + + krb5_free_principal(change_princ); + krb5_db_free_principal(&entry, nprincs); + return(0); +} +#endif +#define MAXMSGSZ 255 + +krb5_error_code +adm_enter_rnd_pwd_key(context, cmdname, change_princ, req_type, entry) + krb5_context context; + char * cmdname; + krb5_principal change_princ; + int req_type; + krb5_db_entry * entry; +{ + krb5_error_code retval; + krb5_keyblock *tempkey; + krb5_pointer master_random; + int salttype = KRB5_KDB_SALTTYPE_NORMAL; + struct saltblock salt; + char *principal_name; + + salt.salttype = salttype; + entry->salt_type = salttype; + + if (retval = krb5_init_random_key(context, &master_encblock, + &master_keyblock, + &master_random)) { + com_err("adm_enter_rnd_pwd_key", 0, "Unable to Initialize Random Key"); + (void) krb5_finish_key(context, &master_encblock); + memset((char *)master_keyblock.contents, 0, master_keyblock.length); + krb5_xfree(master_keyblock.contents); + goto finish; + } + + /* Get Random Key */ + if (retval = krb5_random_key(context, &master_encblock, + master_random, + &tempkey)) { + com_err("adm_enter_rnd_pwd_key", 0, "Unable to Obtain Random Key"); + goto finish; + } + + /* Tie the Random Key to the Principal */ + if (retval = krb5_principal2salt(context, change_princ, &salt.saltdata)) { + com_err("adm_enter_rnd_pwd_key", 0, "Principal2salt Failure"); + goto finish; + } + + if (retval = krb5_unparse_name(context, change_princ, &principal_name)) + goto finish; + + /* Modify Database */ + retval = adm_modify_kdb(context, "adm_enter_rnd_pwd_key", + principal_name, + change_princ, + tempkey, + tempkey, + req_type, + &salt, + &salt, + entry); + free(principal_name); + + if (retval) { + com_err("adm_enter_rnd_pwd_key", 0, "Database Modification Failure"); + retval = 2; + goto finish; + } + + finish: + + if (tempkey->contents) { + memset((char *) tempkey->contents, 0, tempkey->length); + krb5_free_keyblock(context, tempkey); + } + + return(retval); +} diff --git a/src/kadmin.old/server/adm_kadmin.c b/src/kadmin.old/server/adm_kadmin.c new file mode 100644 index 000000000..556c35739 --- /dev/null +++ b/src/kadmin.old/server/adm_kadmin.c @@ -0,0 +1,341 @@ +/* + * kadmin/server/adm_kadmin.c + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + */ + +/* + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + */ + + +/* + adm_kadmin.c +*/ + +#include +#include +#include "com_err.h" + +#include +#include +#ifndef hpux +#include +#endif + +#include "k5-int.h" +#include "adm_extern.h" + +krb5_error_code +adm5_kadmin(context, auth_context, prog, retbuf, otype) + krb5_context context; + krb5_auth_context * auth_context; + char *prog; + char *retbuf; /* Allocated in Calling Routine */ + int *otype; +{ + krb5_replay_data replaydata; + krb5_error_code retval; + kadmin_requests request_type; + krb5_data msg_data, outbuf, inbuf; + + char *customer_name; + char *completion_msg; + int length_of_name; + + int salttype; + + outbuf.data = retbuf; /* Do NOT free outbuf.data */ + + for ( ; ; ) { /* Use "return", "break", or "goto" + to exit for loop */ + + /* Encode Acknowledgement Message */ + retbuf[0] = KADMIND; + retbuf[1] = KADMSAG; + retbuf[2] = SENDDATA2; + outbuf.length = 3; + + retval = krb5_mk_priv(context, auth_context, &outbuf, + &msg_data, &replaydata); + if (retval ) { + syslog(LOG_ERR, + "adm5_kadmin - Error Performing Acknowledgement mk_priv"); + return(5); /* Protocol Failure */ + } + + /* Send Acknowledgement Reply to Client */ + if (retval = krb5_write_message(context, &client_server_info.client_socket, + &msg_data)){ + free(msg_data.data); + syslog(LOG_ERR, + "adm5_kadmin - Error Performing Acknowledgement Write: %s", + error_message(retval)); + return(5); /* Protocol Failure */ + } + free(msg_data.data); + + /* Read Username */ + if (krb5_read_message(context, &client_server_info.client_socket, &inbuf)){ + syslog(LOG_ERR | LOG_INFO, "Error Performing Username Read"); + return(5); /* Protocol Failure */ + } + + /* Decrypt Client Response */ + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + free(inbuf.data); + syslog(LOG_ERR | LOG_INFO, "Error decoding Username - rd_priv"); + return(5); /* Protocol Failure */ + } + free(inbuf.data); + + request_type.appl_code = msg_data.data[0]; + request_type.oper_code = msg_data.data[1]; + if (msg_data.data[2] != SENDDATA2) { + syslog(LOG_ERR | LOG_INFO, + "Invalid Protocol String - Response not SENDDATA2"); + free(msg_data.data); + return(5); /* Protocol Failure */ + } + + length_of_name = msg_data.length - 3; + + if (request_type.oper_code == COMPLETE) { + *otype = 0; + free(msg_data.data); + retval = 0; + goto finish_req; + } + + if (!length_of_name) { + syslog(LOG_ERR, + "adm5_kadmin error: Invalid KADMIN request - No Customer"); + free(msg_data.data); + return(5); /* Protocol Error */ + } + + if ((customer_name = (char *) calloc(1, length_of_name + 1)) == + (char *) 0) { + syslog(LOG_ERR, "adm5_kadmin error: No Memory for Customer Name"); + free(msg_data.data); + return(3); /* No Memory */ + } + + (void) memcpy(customer_name, (char *) msg_data.data + 3, + length_of_name); + customer_name[length_of_name] = '\0'; + + free(msg_data.data); + + if ((completion_msg = (char *) calloc (1,512)) == (char *) 0) { + syslog(LOG_ERR, "adm5_kadmin - No Memory for completion_msg"); + free(customer_name); + return(3); /* No Memory */ + } + + switch(request_type.oper_code) { + case ADDOPER: + /* Check for Add Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "a")) { + retval = 7; + goto process_retval; + } + *otype = 1; + salttype = KRB5_KDB_SALTTYPE_NORMAL; + retval = adm_add_new_key(context, auth_context, "adm5_kadmin", + customer_name, salttype); + goto process_retval; + + case CHGOPER: + /* Check for Password Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "c")) { + retval = 7; + goto process_retval; + } + *otype = 2; + salttype = KRB5_KDB_SALTTYPE_NORMAL; + retval = adm_change_pwd(context, auth_context, "adm5_kadmin", + customer_name, salttype); + goto process_retval; + + case ADROPER: + /* Check for Add Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "a")) { + retval = 7; + goto process_retval; + } + *otype = 3; + retval = adm_add_new_key_rnd(context, "adm5_kadmin", + customer_name); + goto process_retval; + + case CHROPER: + /* Check for Password Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "c")) { + retval = 7; + goto process_retval; + } + *otype = 4; + retval = adm_change_pwd_rnd(context, "adm5_kadmin", + customer_name); + goto process_retval; + + case DELOPER: + /* Check for Delete Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "d")) { + retval = 7; + goto process_retval; + } + *otype = 5; + retval = adm_del_old_key(context, "adm5_kadmin", customer_name); + goto process_retval; + + case MODOPER: + /* Check for Modify Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "m")) { + retval = 7; + goto process_retval; + } + *otype = 6; + retval = adm_mod_old_key(context, auth_context, "adm5_kadmin", + customer_name); + goto process_retval; + + case INQOPER: + /* Check for Inquiry Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "i")) { + retval = 7; + goto process_retval; + } + *otype = 7; + retval = adm_inq_old_key(context, auth_context, "adm5_kadmin", + customer_name); + goto process_retval; + + case AD4OPER: + /* Check for Add Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "a")) { + retval = 7; + goto process_retval; + } + *otype = 8; + salttype = KRB5_KDB_SALTTYPE_V4; + retval = adm_add_new_key(context, auth_context, "adm5_kadmin", + customer_name, salttype); + goto process_retval; + + case CH4OPER: + /* Check for Password Privilege */ + if (retval = adm_check_acl(client_server_info.name_of_client, + "c")) { + retval = 7; + goto process_retval; + } + *otype = 9; + salttype = KRB5_KDB_SALTTYPE_V4; + retval = adm_change_pwd(context, auth_context, "adm5_kadmin", + customer_name, salttype); + goto process_retval; + + default: + retbuf[0] = KADMIN; + retbuf[1] = KUNKNOWNOPER; + retbuf[2] = '\0'; + sprintf(completion_msg, "%s %s from %s FAILED", + "kadmin", + "Unknown or Non-Implemented Operation Type!", + inet_ntoa(client_server_info.client_name.sin_addr)); + syslog(LOG_AUTH | LOG_INFO, completion_msg); + retval = 255; + goto send_last; + } /* switch (request_type.oper_code) */ + +process_retval: + switch (retval) { + case 0: + retbuf[0] = KADMIN; + retbuf[1] = request_type.oper_code; + retbuf[2] = KADMGOOD; + retbuf[3] = '\0'; + goto send_last; + + case 1: /* Principal Unknown */ + case 2: /* Principal Already Exists */ + case 3: /* ENOMEM */ + case 4: /* Password Failure */ + case 5: /* Protocol Failure */ + case 6: /* Security Failure */ + case 7: /* Admin Client Not in ACL List */ + case 8: /* Database Update Failure */ + retbuf[0] = KADMIN; + retbuf[1] = request_type.oper_code; + retbuf[2] = KADMBAD; + retbuf[3] = '\0'; + sprintf((char *)retbuf +3, "%s", + kadmind_kadmin_response[retval]); + sprintf(completion_msg, + "%s %s from %s FAILED - %s", + "kadmin", + oper_type[request_type.oper_code], + inet_ntoa(client_server_info.client_name.sin_addr), + kadmind_kadmin_response[retval]); + syslog(LOG_AUTH | LOG_INFO, completion_msg); + goto send_last; + + default: + retbuf[0] = KADMIN; + retbuf[1] = request_type.oper_code; + retbuf[2] = KUNKNOWNERR; + retbuf[3] = '\0'; + sprintf(completion_msg, "%s %s from %s FAILED", + "kadmin", + oper_type[1], + inet_ntoa( client_server_info.client_name.sin_addr)); + syslog(LOG_AUTH | LOG_INFO, completion_msg); + retval = 255; + goto send_last; + } /* switch(retval) */ + +send_last: + free(customer_name); + free(completion_msg); + outbuf.data = retbuf; + outbuf.length = strlen(retbuf) + 1; + + /* Send Completion Message */ + if (retval = krb5_mk_priv(context, auth_context, &outbuf, + &msg_data, &replaydata)) { + syslog(LOG_ERR, "adm5_kadmin - Error Performing Final mk_priv"); + return(1); + } + + /* Send Final Reply to Client */ + if (retval = krb5_write_message(context, + &client_server_info.client_socket, + &msg_data)){ + free(msg_data.data); + syslog(LOG_ERR, "adm5_kadmin - Error Performing Final Write: %s", + error_message(retval)); + return(1); + } + free(msg_data.data); + } /* for */ + +finish_req: + return(retval); +} diff --git a/src/kadmin.old/server/adm_kpasswd.c b/src/kadmin.old/server/adm_kpasswd.c new file mode 100644 index 000000000..5ab7c74d3 --- /dev/null +++ b/src/kadmin.old/server/adm_kpasswd.c @@ -0,0 +1,113 @@ +/* + * kadmin/server/adm_kpasswd.c + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + */ + +/* + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + */ + + +/* + adm_kpasswd.c +*/ + +#include +#include +#include +#include +#include "com_err.h" + +#include +#include +#ifndef hpux +#include +#endif + +#include "k5-int.h" +#include "adm_extern.h" + +extern krb5_encrypt_block master_encblock; +extern krb5_keyblock master_keyblock; + +struct cpw_keyproc_arg { + krb5_keyblock *key; +}; + +krb5_error_code +adm5_kpasswd(context, auth_context, prog, request_type, retbuf, otype) + krb5_context context; + krb5_auth_context *auth_context; + char *prog; + kadmin_requests *request_type; + char *retbuf; + int *otype; +{ + char completion_msg[520]; + krb5_error_code retval; + + switch (request_type->oper_code) { + case CHGOPER: + *otype = 3; + syslog(LOG_AUTH | LOG_INFO, + "adm_kpasswd: kpasswd change received"); + retval = adm5_change(context, auth_context, "adm5_kpasswd", + client_server_info.client); + + switch(retval) { + case 0: + retbuf[0] = KPASSWD; + retbuf[1] = CHGOPER; + retbuf[2] = KPASSGOOD; + retbuf[3] = '\0'; + break; + + case 1: + retbuf[0] = KPASSWD; + retbuf[1] = CHGOPER; + retbuf[2] = KPASSBAD; + retbuf[3] = '\0'; + sprintf((char *)retbuf +3, "%s", + kadmind_kpasswd_response[retval]); + sprintf(completion_msg, + "kpasswd change from %s FAILED: %s", + inet_ntoa(client_server_info.client_name.sin_addr), + kadmind_kpasswd_response[retval]); + syslog(LOG_AUTH | LOG_INFO, completion_msg); + goto finish; + + default: + retbuf[0] = KPASSWD; + retbuf[1] = CHGOPER; + retbuf[2] = KUNKNOWNERR; + retbuf[3] = '\0'; + sprintf(completion_msg, "kpasswd change from %s FAILED", + inet_ntoa(client_server_info.client_name.sin_addr)); + syslog(LOG_AUTH | LOG_INFO, completion_msg); + retval = 255; + goto finish; + } /* switch (retval) */ + break; + + default: + retbuf[0] = KPASSWD; + retbuf[1] = KUNKNOWNOPER; + retbuf[2] = '\0'; + sprintf(completion_msg, "kpasswd %s from %s FAILED", + "Unknown or Non-Implemented Operation Type!", + inet_ntoa(client_server_info.client_name.sin_addr )); + syslog(LOG_AUTH | LOG_INFO, completion_msg); + retval = 255; + goto finish; + } /* switch (request_type->oper_code) */ + +finish: + return(retval); +} diff --git a/src/kadmin.old/server/adm_listen.c b/src/kadmin.old/server/adm_listen.c new file mode 100644 index 000000000..a784b306b --- /dev/null +++ b/src/kadmin.old/server/adm_listen.c @@ -0,0 +1,197 @@ +/* + * kadmin/server/adm_listen.c + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Network Listen Loop for the Kerberos Version 5 Administration server + */ + +/* + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + */ + + +/* + adm_listen.c +*/ + +#ifdef _AIX +#include +#endif + +#include "k5-int.h" + +#include +#include +#include "com_err.h" + +#ifndef sigmask +#define sigmask(m) (1 <<((m)-1)) +#endif + +#include +#include +#ifndef hpux +#include +#endif + +#include "adm_extern.h" + +int adm_debug_flag = 0; + +#ifdef USE_SIGPROCMASK +/* just do it right */ +void +kill_children() +{ + int i; + sigset_t old, new; + + sigemptyset(&old); + sigemptyset(&new); + sigaddset(&new,SIGCHLD); + sigprocmask(SIG_BLOCK, &new, &old); + + for (i = 0; i < pidarraysize; i++) { + kill(pidarray[i], SIGINT); + syslog(LOG_AUTH | LOG_INFO, "Killing Admin Child %d", pidarray[i]); + } + + sigprocmask(SIG_SETMASK, &old, NULL); +} + +#else + +#ifdef USE_SIGPROCMASK +/* fake sigmask, sigblock, sigsetmask */ +#include +#define sigmask(x) (1L<<(x)-1) +#define sigsetmask(x) sigprocmask(SIG_SETMASK,&x,NULL) +static int _fake_sigstore; +#define sigblock(x) (_fake_sigstore=x,sigprocmask(SIG_BLOCK,&_fake_sigstore,0)) +#endif + +void +kill_children() +{ + register int i; + int osigmask; + + osigmask = sigblock(sigmask(SIGCHLD)); + + for (i = 0; i < pidarraysize; i++) { + kill(pidarray[i], SIGINT); + syslog(LOG_AUTH | LOG_INFO, "Killing Admin Child %d", pidarray[i]); + } + + sigsetmask(osigmask); + return; +} +#endif /* HAVE_SIGSET */ + +/* adm5_listen_and_process - listen on the admin servers port for a request */ + +int +adm5_listen_and_process(context, prog) + krb5_context context; + const char *prog; +{ + extern int errno; + int found; + fd_set mask, readfds; + int addrlen; + krb5_error_code process_client(); + krb5_error_code retval; + void kill_children(); + int pid; + + (void) listen(client_server_info.server_socket, 1); + + FD_ZERO(&mask); + FD_SET(client_server_info.server_socket, &mask); + + for (;;) { /* loop nearly forever */ + if (exit_now) { + kill_children(); + return(0); + } + + readfds = mask; + if ((found = select(client_server_info.server_socket + 1, + &readfds, + (fd_set *)0, + (fd_set *)0, + (struct timeval *)0)) == 0) + continue; /* no things read */ + + if (found < 0) { + if (errno != EINTR) + syslog(LOG_AUTH | LOG_INFO, + "%s: select: %s", "adm5_listen_and_process", + error_message(errno)); + continue; + } + + if (FD_ISSET(client_server_info.server_socket, &readfds)) { + /* accept the conn */ + addrlen = sizeof(client_server_info.client_name); + if ((client_server_info.client_socket = + accept(client_server_info.server_socket, + (struct sockaddr *) &client_server_info.client_name, + &addrlen)) < 0) { + syslog(LOG_AUTH | LOG_INFO, "%s: accept: %s", + "adm5_listen_and_process", + error_message(errno)); + continue; + } + + if (adm_debug_flag) { + retval = process_client(context, + "adm5_listen_and_process"); + exit(retval); + } + + /* if you want a sep daemon for each server */ + if (!(pid = fork())) { + /* child */ + (void) close(client_server_info.server_socket); + + retval = process_client(context, + "adm5_listen_and_process"); + exit(retval); + } else { + /* parent */ + if (pid < 0) { + syslog(LOG_AUTH | LOG_INFO, "%s: fork: %s", + "adm5_listen_and_process", + error_message(errno)); + (void) close(client_server_info.client_socket); + continue; + } + + /* fork succeded: keep tabs on child */ + + (void) close(client_server_info.client_socket); + if (pidarray) { + pidarray = (int *) realloc((char *)pidarray, + (++pidarraysize) * sizeof(int)); + pidarray[pidarraysize - 1] = pid; + } else { + pidarraysize = 1; + pidarray = + (int *) malloc(pidarraysize *sizeof(int)); + pidarray[0] = pid; + } + } + } else { + syslog(LOG_AUTH | LOG_INFO, "%s: something else woke me up!", + "adm5_listen_and_process"); + return(0); + } + } +} diff --git a/src/kadmin.old/server/adm_msgs.c b/src/kadmin.old/server/adm_msgs.c new file mode 100644 index 000000000..3a350f116 --- /dev/null +++ b/src/kadmin.old/server/adm_msgs.c @@ -0,0 +1,59 @@ +/* + * kadmin/server/adm_msgs.c + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Top-level loop of the Kerberos Version 5 Administration server + */ + +/* + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + */ + + +char *oper_type[] = { + "complete", /* 0 */ + "addition", /* 1 */ + "deletion", /* 2 */ + "change", /* 3 */ + "modification", /* 4 */ + "inquiry" /* 5 */ +}; + +char *ksrvutil_message[] = { + "Service Key Changed", /* 0 */ + "New Key and Version Received" /* 1 */ +}; + +char *kadmind_general_response[] = { + "Success", /* 0 */ + "Service Access Granted" /* 1 */ +}; + +char *kadmind_kpasswd_response[] = { + "Password Changed", /* 0 */ + "Password NOT Changed!" /* 1 */ +}; + +char *kadmind_ksrvutil_response[] = { + "Service Password Change Complete", /* 0 */ + "One or More Service Password Change(s) Failed!", /* 1 */ + "Database Update Failure - Possible Catastrophe!!" /* 2 */ +}; + +char *kadmind_kadmin_response[] = { + "Administrative Service Completed", /* 0 */ + "Principal Unknown!", /* 1 */ + "Principal Already Exists!", /* 2 */ + "Allocation Failure!", /* 3 */ + "Password Failure!", /* 4 */ + "Protocol Failure!", /* 5 */ + "Security Failure!", /* 6 */ + "Admin Client Not in ACL List!", /* 7 */ + "Database Update Failure - Possible Catastrophe!!" /* 8 */ +}; diff --git a/src/kadmin.old/server/adm_nego.c b/src/kadmin.old/server/adm_nego.c new file mode 100644 index 000000000..abde3419a --- /dev/null +++ b/src/kadmin.old/server/adm_nego.c @@ -0,0 +1,314 @@ +/* + * kadmin/server/adm_nego.c + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * 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. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * Modify the Kerberos Database + */ + + +#include "com_err.h" +#include + +#include +#include +#ifndef hpux +#include +#endif + +#include + +#include "k5-int.h" +#include "adm_extern.h" + +krb5_error_code +adm_negotiate_key(context, auth_context, prog, new_passwd) + krb5_context context; + krb5_auth_context *auth_context; + char const * prog; + char * new_passwd; +{ + krb5_replay_data replaydata; + krb5_data msg_data, inbuf; + krb5_error_code retval; +#if defined(MACH_PASS) || defined(SANDIA) /* Machine-generated passwords. */ + krb5_pwd_data *pwd_data; + krb5_pwd_data encodable_data; + krb5_data *encoded_pw_string; + passwd_phrase_element **next_passwd_phrase_element; + char *tmp_passwd, *tmp_phrase; + krb5_authenticator *client_auth_data; + int count, i, j, k; + int legit_passwd = 0; +#endif + extern int errno; + +#if defined(MACH_PASS) || defined(SANDIA) /* Machine-generated passwords. */ + +#define clear_encodable_data() \ +{ encodable_data.sequence_count = 0; \ + encodable_data.element = 0; \ +} + +#define free_seq_list() \ +{ free(encodable_data.element); \ +} + +#define free_pwd_and_phrase_structures() \ +{ next_passwd_phrase_element = encodable_data.element; \ + for (k = 0; \ + *next_passwd_phrase_element != 0 && k < encodable_data.sequence_count; \ + k++) { \ + free(*next_passwd_phrase_element); \ + *next_passwd_phrase_element = 0; \ + next_passwd_phrase_element++; } \ +} + +#define free_passwds() \ +{ next_passwd_phrase_element = encodable_data.element; \ + for (k = 0; \ + *next_passwd_phrase_element != 0 && k < encodable_data.sequence_count; \ + k++) { \ + memset((char *) (*next_passwd_phrase_element)->passwd->data, \ + 0, (*next_passwd_phrase_element)->passwd->length); \ + free((*next_passwd_phrase_element)->passwd->data); \ + next_passwd_phrase_element++; } \ +} + +#define free_phrases() \ +{ next_passwd_phrase_element = encodable_data.element; \ + for (k = 0; \ + *next_passwd_phrase_element != 0 && k < encodable_data.sequence_count; \ + k++) { \ + memset((char *) (*next_passwd_phrase_element)->phrase->data, \ + 0, (*next_passwd_phrase_element)->phrase->length); \ + free((*next_passwd_phrase_element)->phrase->data); \ + next_passwd_phrase_element++; } \ +} + + encodable_data.sequence_count = + ADM_MAX_PW_CHOICES * ADM_MAX_PW_ITERATIONS; + + /* Allocate List of Password and Phrase Addresses Pointers */ + if ((encodable_data.element = (passwd_phrase_element **) calloc( + encodable_data.sequence_count + 1, + sizeof(passwd_phrase_element *))) == + (passwd_phrase_element **) 0) { + clear_encodable_data(); + com_err("adm_negotiate_key", 0, + "No Memory for Password and Phrase List"); + return(1); + } + + next_passwd_phrase_element = encodable_data.element; + + /* Allow for ADM_MAX_PW_ITERATIONS Sets of Five Passwords/Phrases */ + for ( i = 0; i < ADM_MAX_PW_ITERATIONS; i++) { + if ( i == ADM_MAX_PW_ITERATIONS ) { + com_err("adm_negotiate_key", 0, + "Excessive Password List Requests"); + return(1); + } + + /* Allocate passwd_phrase_element structures */ + for (j = 0; j < ADM_MAX_PW_CHOICES; j++) { + if ((*next_passwd_phrase_element = + (passwd_phrase_element *) calloc(1, + sizeof(passwd_phrase_element))) == + (passwd_phrase_element *) 0) { + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); + com_err("adm_negotiate_key", 0, + "No Memory for Additional Password and Phrase Structures"); + return(1); + } + + if ((retval = get_pwd_and_phrase("adm_negotiate_key", + &tmp_passwd, &tmp_phrase))) { + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); + com_err("adm_negotiate_key", 0, "Unable to get_pwd_and_phrase"); + return(1); + } + + if (((*next_passwd_phrase_element)->passwd = + (krb5_data *) calloc(1, + sizeof(krb5_data))) == (krb5_data *) 0) { + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); + com_err("adm_negotiate_key", 0, + "No Memory for Additional Password and Phrase Structures"); + return(1); + } + + if (((*next_passwd_phrase_element)->passwd->data = + (char *) calloc (1, + strlen(tmp_passwd))) == (char *) 0) { + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); + com_err("adm_negotiate_key", ENOMEM, + "for Additional Passwords"); + } + + strcpy((*next_passwd_phrase_element)->passwd->data, tmp_passwd); + (*next_passwd_phrase_element)->passwd->length = strlen(tmp_passwd); + + if (((*next_passwd_phrase_element)->phrase = + (krb5_data *) calloc(1, + sizeof(krb5_data))) == (krb5_data *) 0) { + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); + com_err("adm_negotiate_key", 0, + "No Memory for Additional Password and Phrase Structures"); + return(1); + } + + if (((*next_passwd_phrase_element)->phrase->data = + (char *) calloc (1, + strlen(tmp_phrase))) == (char *) 0) { + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); + com_err("adm_negotiate_key", ENOMEM, + "for Additional Passwords"); + return(1); + } + + strcpy((*next_passwd_phrase_element)->phrase->data, tmp_phrase); + (*next_passwd_phrase_element)->phrase->length = strlen(tmp_phrase); + + free(tmp_passwd); + free(tmp_phrase); + + next_passwd_phrase_element++; + } + } /* for i <= KADM_MAX_PW_CHOICES */ + + /* Asn.1 Encode the Passwords and Phrases */ + if ((retval = encode_krb5_pwd_data(&encodable_data, + &encoded_pw_string))) { + com_err("adm_negotiate_key", 0, + "Unable to encode Password and Phrase Data"); + return(1); + } + + /* Free Phrases But Hold onto Passwds for Awhile*/ + free_phrases(); + + /* Encrypt Password/Phrases Encoding */ + retval = krb5_mk_priv(context, auth_context, encoded_pw_string, + &msg_data, &replaydata); + if (retval ) { + free_passwds(); + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); + com_err("adm_negotiate_key", retval, "during mk_priv"); + return(1); + } + + /* Send Encrypted/Encoded Passwords and Phrases to Client */ + if (krb5_write_message(context, &client_server_info.client_socket, &msg_data)){ + free(msg_data.data); + free_passwds(); + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); + com_err("adm_negotiate_key", 0, "Error Performing Password Write"); + return(1); + } + free(msg_data.data); + +#endif /* MACH_PASS - Machine-gen. passwords */ + /* Read Client Response */ + if (krb5_read_message(context, &client_server_info.client_socket, &inbuf)){ +#if defined(MACH_PASS) || defined(SANDIA) + free_passwds(); + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); +#endif + com_err("adm_negotiate_key", errno, "Error Performing Password Read"); + return(1); + } + + /* Decrypt Client Response */ + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + free(inbuf.data); +#if defined(MACH_PASS) || defined(SANDIA) + free_passwds(); + free_pwd_and_phrase_structures(); + free_seq_list(); + clear_encodable_data(); +#endif + com_err("adm_negotiate_key", retval, "krb5_rd_priv error %s", + error_message(retval)); + return(1); + } + free(inbuf.data); + +#if defined(MACH_PASS) || defined(SANDIA) /* Machine-generated passwords */ + legit_passwd = 0; + next_passwd_phrase_element = encodable_data.element; + /* Compare Response with Acceptable Passwords */ + for (j = 0; + j < ADM_MAX_PW_CHOICES * ADM_MAX_PW_ITERATIONS; + j++) { + if ((retval = memcmp(msg_data.data, + (*next_passwd_phrase_element)->passwd->data, + strlen((*next_passwd_phrase_element)->passwd->data))) == 0) { + legit_passwd++; + break; /* Exit Loop - Match Found */ + } + next_passwd_phrase_element++; + } + /* Now Free Passwds */ + free_passwds(); + + /* free password_and_phrase structures */ + free_pwd_and_phrase_structures(); + + /* free passwd_phrase_element list */ + free_seq_list(); + + /* clear krb5_pwd_data */ + clear_encodable_data(); + + if (!(legit_passwd)) { + com_err("adm_negotiate_key", 0, "Invalid Password Entered"); + return(1); + } +#endif + strncpy(new_passwd, msg_data.data, msg_data.length); + free(msg_data.data); + + return(0); +} + diff --git a/src/kadmin.old/server/adm_network.c b/src/kadmin.old/server/adm_network.c new file mode 100644 index 000000000..545784f73 --- /dev/null +++ b/src/kadmin.old/server/adm_network.c @@ -0,0 +1,257 @@ +/* + * kadmin/server/adm_network.c + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Network Initialization/Shutdown Component of the + * Version 5 Administration network + */ + +/* + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + */ + + +/* + * adm_network.c + */ + +#include +#include "com_err.h" +#include +#include +#include +#include + +#ifndef sigmask +#define sigmask(m) (1 <<((m)-1)) +#endif + +#include +#include +#ifndef hpux +#include +#endif +#include + +#include "k5-int.h" +#include "adm_extern.h" + +extern int errno; + +#ifdef POSIX_SIGTYPE +#define SIGNAL_RETURN return +#else +#define SIGNAL_RETURN return(0) +#endif + +krb5_error_code +closedown_network(prog) +const char *prog; +{ + if (client_server_info.server_socket == -1) return(1); + + (void) close(client_server_info.server_socket); + client_server_info.server_socket = -1; + return(0); +} + +krb5_sigtype +doexit() +{ + exit_now = 1; + SIGNAL_RETURN; +} + +/* + * SIGCHLD brings us here + */ +krb5_sigtype +do_child() +{ + /* + * has been included, so BSD will be defined on + * BSD systems + */ +#if BSD > 0 && BSD <= 43 +#ifndef WEXITSTATUS +#define WEXITSTATUS(w) (w).w_retcode +#define WTERMSIG(w) (w).w_termsig +#endif + union wait status; +#else + int status; +#endif + int pid, i, j; + + signal(SIGCHLD, do_child); + + pid = wait(&status); + if (pid < 0) + SIGNAL_RETURN; + + 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) ) { + com_err("adm_network", 0, "child %d: termsig %d", + pid, WTERMSIG(status) ); + com_err("adm_network", 0, "retcode %d", + WEXITSTATUS(status)); + } + + SIGNAL_RETURN; + } + + com_err("adm_network", 0, + "child %d not in list: termsig %d, retcode %d", pid, + WTERMSIG(status), WEXITSTATUS(status)); + + SIGNAL_RETURN; +} + +krb5_error_code +setup_network(context, prog) + krb5_context context; + const char *prog; +{ + krb5_error_code retval; + char server_host_name[MAXHOSTNAMELEN]; + krb5_sigtype doexit(), do_child(); + struct servent *service_servent; + struct hostent *service_hostent; + + 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); + + client_server_info.name_of_service = malloc(768); + if (!client_server_info.name_of_service) { + com_err("setup_network", 0, + "adm_network: No Memory for name_of_service"); + return ENOMEM; + } + + (void) sprintf(client_server_info.name_of_service, "%s%s%s%s%s", + CPWNAME, "/", realm, "@", realm); + +#ifdef DEBUG + fprintf(stderr, "client_server_info.name_of_service = %s\n", + client_server_info.name_of_service); +#endif /* DEBUG */ + + if ((retval = krb5_parse_name(context, client_server_info.name_of_service, + &client_server_info.server))) { + free(client_server_info.name_of_service); + com_err( "setup_network", retval, + "adm_network: Unable to Parse Server Name"); + return retval; + } + + if (gethostname(server_host_name, sizeof(server_host_name))) { + retval = errno; + krb5_free_principal(context, client_server_info.server); + free(client_server_info.name_of_service); + com_err( "setup_network", retval, + "adm_network: Unable to Identify Who I am"); + return retval; + } + + service_hostent = gethostbyname(server_host_name); + if (!service_hostent) { + retval = errno; + free(client_server_info.name_of_service); + com_err("setup_network", retval, "adm_network: Failed gethostname"); + return retval; + } + +#ifdef DEBUG + fprintf(stderr, "Official host name = %s\n", service_hostent->h_name); +#endif /* DEBUG */ + + client_server_info.server_name.sin_family = AF_INET; + +#ifdef unicos61 + memcpy((char *) &client_server_info.server_name.sin_addr, + (char *) service_hostent->h_addr, service_hostent->h_length); +#else + memcpy((char *) &client_server_info.server_name.sin_addr.s_addr, + (char *) service_hostent->h_addr, service_hostent->h_length); +#endif /* unicos61 */ + + client_server_info.server_socket = -1; + +#ifdef DEBUG + fprintf(stderr, "adm5_tcp_portname = %s\n", adm5_tcp_portname); +#endif /* DEBUG */ + + service_servent = getservbyname(adm5_tcp_portname, "tcp"); + if (admin_port) { + client_server_info.server_name.sin_port = admin_port; + } else if (service_servent) { + client_server_info.server_name.sin_port = service_servent->s_port; +#ifdef DEBUG + fprintf(stderr, "Official service name = %s\n", service_servent->s_name); +#endif /* DEBUG */ + } else { +#ifdef ADM5_DEFAULT_PORT + client_server_info.server_name.sin_port = htons(ADM5_DEFAULT_PORT); + com_err("setup_network", 0, "adm_network: using default port %d", + ADM5_DEFAULT_PORT); +#else + krb5_free_principal(client_server_info.server); + free(client_server_info.name_of_service); + com_err("setup_network", 0, "adm_network: %s/tcp service unknown", + adm5_tcp_portname); + return(1); +#endif + } + + + if ((client_server_info.server_socket = + socket(AF_INET, SOCK_STREAM, 0)) < 0) { + retval = errno; + krb5_free_principal(context, client_server_info.server); + free(client_server_info.name_of_service); + com_err("setup_network", retval, + "adm_network: Cannot create server socket."); + return(1); + } + +#ifdef DEBUG + fprintf(stderr, "Socket File Descriptor = %d\n", + client_server_info.server_socket); + fprintf(stderr, "sin_family = %d\n", + client_server_info.server_name.sin_family); + fprintf(stderr, "sin_port = %d\n", + client_server_info.server_name.sin_port); + fprintf(stderr, "in_addr.s_addr = %s\n", + inet_ntoa( client_server_info.server_name.sin_addr )); +#endif /* DEBUG */ + + if (bind(client_server_info.server_socket, + &client_server_info.server_name, + sizeof(client_server_info.server_name)) < 0) { + retval = errno; + krb5_free_principal(context, client_server_info.server); + free(client_server_info.name_of_service); + com_err("setup_network", retval, + "adm_network: Cannot bind server socket."); + return(1); + } + + return(0); +} diff --git a/src/kadmin.old/server/adm_parse.c b/src/kadmin.old/server/adm_parse.c new file mode 100644 index 000000000..305807b47 --- /dev/null +++ b/src/kadmin.old/server/adm_parse.c @@ -0,0 +1,262 @@ +#ifdef SANDIA +/* + * kadmin/server/adm_parse.c + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * 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. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * Edit a KDC database. + */ + +#include +#include + +#if defined (unicos61) || (defined(mips) && defined(SYSTYPE_BSD43)) || defined(sysvimp) +#include +#else +#include +#endif /* unicos61 */ +#if defined(aux20) +#include +#endif /* aux20 */ + +#include "k5-int.h" + +void +kadmin_parse_and_set(input_string) +char *input_string; +{ + extern int classification; + extern krb5_kvno KDB5_VERSION_NUM; + extern krb5_deltat KDB5_MAX_TKT_LIFE; + extern krb5_deltat KDB5_MAX_REN_LIFE; + extern krb5_timestamp KDB5_EXP_DATE; + extern krb5_flags NEW_ATTRIBUTES; + + int num_args; + char parameter[40]; + char first_token[40]; + char second_token[40]; + + int bypass = 0; + + struct tm exp_date; + long todays_date; + int year; + int month; + int mday; + + first_token[0] = second_token[0] = '\0'; + num_args = sscanf(input_string, "%s %s %s", parameter, + first_token, second_token); + + if (strcmp(parameter, "BYPASS") == 0) { + bypass++; + syslog(LOG_ERR, + "CAUTION: Classified and Unclassified Principals will be allowed"); + return; + } + + if (strcmp(parameter, "CLASSIFICATION") == 0) { + if (strcmp(first_token, "CLASS") == 0) { + classification = 1; + if (bypass) classification = 0; + } + return; + } + + if (strcmp(parameter, "VERSION_NUM") == 0) { + if (num_args < 2) { + KDB5_VERSION_NUM = 1; + } else { + KDB5_VERSION_NUM = atoi(first_token); + } + return; + } + + if (strcmp(parameter, "MAX_TKT_LIFE") == 0) { + if (num_args < 2) { + KDB5_MAX_TKT_LIFE = KRB5_KDB_MAX_LIFE; + } else { + switch (second_token[0]) { + case 's': + KDB5_MAX_TKT_LIFE = atoi(first_token); + break; + case 'm': + KDB5_MAX_TKT_LIFE = atoi(first_token) * 60; + break; + case 'h': + KDB5_MAX_TKT_LIFE = atoi(first_token) * 3600; + break; + case 'd': + KDB5_MAX_TKT_LIFE = atoi(first_token) * 86400; + break; + case 'w': + KDB5_MAX_TKT_LIFE = atoi(first_token) * 604800; + break; + case 'M': /* 30 days */ + KDB5_MAX_TKT_LIFE = atoi(first_token) * 18144000; + break; + case 'y': /* 365 days */ + KDB5_MAX_TKT_LIFE = atoi(first_token) * 220752000; + break; + case 'e': /* eternity */ + KDB5_MAX_TKT_LIFE = 2145830400; + break; + default: + break; + } + } + return; + } + + if (strcmp(parameter, "MAX_REN_LIFE") == 0) { + if (num_args < 2) { + KDB5_MAX_REN_LIFE = KRB5_KDB_MAX_RLIFE; + } else { + switch (second_token[0]) { + case 's': + KDB5_MAX_REN_LIFE = atoi(first_token); + break; + case 'm': + KDB5_MAX_REN_LIFE = atoi(first_token) * 60; + break; + case 'h': + KDB5_MAX_REN_LIFE = atoi(first_token) * 3600; + break; + case 'd': + KDB5_MAX_REN_LIFE = atoi(first_token) * 86400; + break; + case 'w': + KDB5_MAX_REN_LIFE = atoi(first_token) * 604800; + break; + case 'M': /* 30 days */ + KDB5_MAX_REN_LIFE = atoi(first_token) * 18144000; + break; + case 'y': /* 365 days */ + KDB5_MAX_REN_LIFE = atoi(first_token) * 220752000; + break; + case 'e': /* eternity */ + KDB5_MAX_REN_LIFE = 2145830400; + break; + default: + break; + } + } + return; + } + + + if (strcmp(parameter, "SET_EXP_DATE") == 0) { + (void) time(&todays_date); + switch (first_token[0]) { + case 'e': /* eternity */ + KDB5_EXP_DATE = 2145830400; + year = 2037; + month = 12; + mday = 30; + sprintf(first_token, "%s", "eternity"); + break; + case 'y': /* yesterday */ + KDB5_EXP_DATE = todays_date - 86400; + year = 1970; + month = 01; + mday = 01; + sprintf(first_token, "%s", "yesterday"); + break; + case '0': + case '1': + case '2': + case '3': + case '9': + sscanf(first_token, "%d/%d/%d", &year, &month, &mday); + year = (year > 1900) ? year - 1900 : year; + year = (year > 137) ? year - 100 : year; + year = (year > 137) ? 137 : year; + exp_date.tm_year = + ((year >= 00 && year < 38) || + (year >= 70 && year <= 138)) ? year : 137; + exp_date.tm_mon = + (month >= 1 && + month <= 12) ? month - 1 : 0; + exp_date.tm_mday = + (mday >= 1 && + mday <= 31) ? mday : 1; + exp_date.tm_hour = 0; + exp_date.tm_min = 1; + exp_date.tm_sec = 0; + KDB5_EXP_DATE = convert_tm_to_sec(&exp_date); + break; + default: + KDB5_EXP_DATE = KRB5_KDB_EXPIRATION; + sprintf(first_token, "%s", "Default KDB Expiration"); + break; + } + if (year < 1900) year += 1900; + if (year < 1938) year += 100; + return; + } + + if (strcmp(parameter, "SET_PWCHG") == 0) { + if (num_args < 2) { + NEW_ATTRIBUTES = NEW_ATTRIBUTES | KRB5_KDB_REQUIRES_PWCHANGE; + } else { + if (first_token[0] == 'y' || first_token[0] == 'Y') { + NEW_ATTRIBUTES = NEW_ATTRIBUTES | KRB5_KDB_REQUIRES_PWCHANGE; + } else { + NEW_ATTRIBUTES = NEW_ATTRIBUTES & ~KRB5_KDB_REQUIRES_PWCHANGE; + KDB5_VERSION_NUM = 1; + } + } + return; + } + + if (strcmp(parameter, "SET_PREAUTH") == 0) { + if (num_args < 2) { + NEW_ATTRIBUTES = NEW_ATTRIBUTES | KRB5_KDB_REQUIRES_PRE_AUTH; + } else { + if (first_token[0] == 'y' || first_token[0] == 'Y') { + NEW_ATTRIBUTES = NEW_ATTRIBUTES | KRB5_KDB_REQUIRES_PRE_AUTH; + } else { + NEW_ATTRIBUTES = NEW_ATTRIBUTES & ~KRB5_KDB_REQUIRES_PRE_AUTH; + } + } + return; + } + + if (strcmp(parameter, "SET_SECUREID") == 0) { + if (num_args < 2) { + NEW_ATTRIBUTES = NEW_ATTRIBUTES | KRB5_KDB_REQUIRES_HW_AUTH | + KRB5_KDB_REQUIRES_PRE_AUTH; + } else { + if (first_token[0] == 'y' || first_token[0] == 'Y') { + NEW_ATTRIBUTES = NEW_ATTRIBUTES | KRB5_KDB_REQUIRES_HW_AUTH | + KRB5_KDB_REQUIRES_PRE_AUTH; + } else { + NEW_ATTRIBUTES = NEW_ATTRIBUTES & ~KRB5_KDB_REQUIRES_HW_AUTH; + } + } + return; + } +} +#endif diff --git a/src/kadmin.old/server/adm_process.c b/src/kadmin.old/server/adm_process.c new file mode 100644 index 000000000..ab9add4ef --- /dev/null +++ b/src/kadmin.old/server/adm_process.c @@ -0,0 +1,428 @@ +/* + * kadmin/server/adm_process.c + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + */ + +/* + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + */ + + +/* + adm_process.c +*/ + +#include +#include +#include +#include +#include "com_err.h" + +#include +#include +#ifndef hpux +#include +#endif + +#include "k5-int.h" +#include "adm_extern.h" + +extern krb5_encrypt_block master_encblock; +extern krb5_keyblock master_keyblock; + +static krb5_error_code +cpw_keyproc(context, keyblock) + krb5_context context; + krb5_keyblock ** keyblock; +{ + krb5_error_code retval; + krb5_db_entry cpw_entry; + krb5_principal cpw_krb; + krb5_keyblock *realkey; + krb5_boolean more; + int nprincs = 1; + + if (*keyblock == NULL) { + if (retval = krb5_parse_name(context, + client_server_info.name_of_service, + &cpw_krb)) { + syslog(LOG_ERR, + "cpw_keyproc %d while attempting to parse \"%s\"", + client_server_info.name_of_service, retval); + return(retval); + } + + if (retval = krb5_db_get_principal(context, cpw_krb, &cpw_entry, + &nprincs, &more)) { + syslog(LOG_ERR, + "cpw_keyproc %d while extracting %s entry", + client_server_info.name_of_service, retval); + return(retval); + } + + if (!nprincs) return(0); + + if ((realkey = (krb5_keyblock *) calloc (1, + sizeof(krb5_keyblock))) == (krb5_keyblock * ) 0) { + krb5_db_free_principal(context, &cpw_entry, nprincs); + syslog(LOG_ERR, "cpw_keyproc: No Memory for server key"); + close(client_server_info.client_socket); + return(ENOMEM); + } + + /* Extract the real kadmin/ keyblock */ + if (retval = krb5_kdb_decrypt_key(context, + &master_encblock, + &cpw_entry.key, + realkey)) { + krb5_db_free_principal(context, &cpw_entry, nprincs); + free(realkey); + syslog(LOG_ERR, + "cpw_keyproc: Cannot extract %s from master key", + client_server_info.name_of_service); + exit(retval); + } + + *keyblock = realkey; + } + return(0); +} + +krb5_error_code +process_client(context, prog) + krb5_context context; + char *prog; +{ + krb5_error_code retval; + + krb5_keyblock * cpw_keyblock = NULL; + + int on = 1; + krb5_db_entry server_entry; + + char retbuf[512]; + + krb5_data final_msg; + char completion_msg[520]; + kadmin_requests request_type; + krb5_auth_context *auth_context = NULL; + krb5_ticket * client_ticket = NULL; + krb5_replay_data replaydata; + + int number_of_entries; + krb5_boolean more; + int namelen; + + char *req_type = ""; + int otype; + + u_short data_len; + krb5_data outbuf; + krb5_data inbuf, msg_data; + extern int errno; + + krb5_timestamp adm_time; + + outbuf.data = retbuf; + if (setsockopt(client_server_info.client_socket, + SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) { + syslog(LOG_ERR, "adm_process: setsockopt keepalive: %d", errno); + } + + /* V4 kpasswd Protocol Hack */ + /* Read Length of Data */ + retval = krb5_net_read(context, client_server_info.client_socket, + (char *) &data_len, 2); + if (retval < 0) { + syslog(LOG_ERR, "kadmind error: net_read Length Failure"); + (void) sprintf(retbuf, "kadmind error during net_read for Length\n"); + exit(0); + } + + if (retval = krb5_db_init(context)) { /* Open as client */ + syslog(LOG_ERR, "adm_process: Can't Open Database"); + close(client_server_info.client_socket); + exit(0); + } + +/* Get Server Credentials for Mutual Authentication and Private + * Messages Note: Here client is the kadmin/ server + */ + number_of_entries = 1; + if ((retval = krb5_db_get_principal(context, client_server_info.server, + &server_entry, + &number_of_entries, + &more))) { + syslog(LOG_ERR, + "kadmind error: krb5_db_get_principal error: %d", retval); + close(client_server_info.client_socket); + exit(0); + } + + if (more) { + krb5_db_free_principal(context, &server_entry, number_of_entries); + syslog(LOG_ERR, "kadmind error: kadmin/ service not unique"); + exit(1); + } + + if (number_of_entries != 1) { + krb5_db_free_principal(context, &server_entry, number_of_entries); + syslog(LOG_ERR, "kadmind error: kadmin/ service UNKNOWN"); + close(client_server_info.client_socket); + exit(0); + } + + if ((cpw_keyblock = (krb5_keyblock *) calloc (1, + sizeof(krb5_keyblock))) == (krb5_keyblock *) 0) { + krb5_db_free_principal(context, &server_entry, number_of_entries); + syslog(LOG_ERR, + "kadmind error: No Memory for server key"); + close(client_server_info.client_socket); + exit(0); + } + + /* Extract the real kadmin/ keyblock */ + if (retval = krb5_kdb_decrypt_key(context, + &master_encblock, + &server_entry.key, + cpw_keyblock)) { + krb5_db_free_principal(context, &server_entry, number_of_entries); + free(cpw_keyblock); + syslog(LOG_ERR, + "kadmind error: Cannot extract kadmin/ from master key"); + close(client_server_info.client_socket); + exit(0); + } + +/* + * To verify authenticity, we need to know the address of the + * client. + */ + + namelen = sizeof(client_server_info.client_addr); + if (getpeername(client_server_info.client_socket, + (struct sockaddr *) &client_server_info.client_addr, + &namelen) < 0) { + syslog(LOG_ERR, "kadmind error: Unable to Obtain Client Name."); + close(client_server_info.client_socket); + exit(0); + } + + /* we use mutual authentication */ + client_server_info.client_addr.addrtype = + client_server_info.client_name.sin_family; + client_server_info.client_addr.length = SIZEOF_INADDR; + client_server_info.client_addr.contents = + (krb5_octet *) &client_server_info.client_name.sin_addr; + + client_server_info.server_addr.addrtype = + client_server_info.server_name.sin_family; + client_server_info.server_addr.length = SIZEOF_INADDR; + client_server_info.server_addr.contents = + (krb5_octet *) &client_server_info.server_name.sin_addr; + + krb5_init_ets(context); + + syslog(LOG_AUTH | LOG_INFO, + "Request for Administrative Service Received from %s - Authenticating.", + inet_ntoa( client_server_info.client_name.sin_addr )); + + cpw_keyproc(context, &cpw_keyblock); + + if (krb5_auth_con_init(context, &auth_context)) + exit(1); + + krb5_auth_con_setflags(context,auth_context,KRB5_AUTH_CONTEXT_RET_SEQUENCE); + + krb5_auth_con_setaddrs(context, auth_context, + &client_server_info.server_addr, + &client_server_info.client_addr); + + if (krb5_auth_con_setuseruserkey(context, auth_context, cpw_keyblock)) + exit(1); + + if ((retval = krb5_recvauth(context, &auth_context, + (krb5_pointer) &client_server_info.client_socket, + ADM5_CPW_VERSION, + client_server_info.server, + NULL, + 0, + NULL, + &client_ticket + ))) { + syslog(LOG_ERR, "kadmind error: %s during recvauth\n", + error_message(retval)); + (void) sprintf(retbuf, "kadmind error during recvauth: %s\n", + error_message(retval)); + krb5_free_keyblock(context, cpw_keyblock); + goto finish; + } + krb5_free_keyblock(context, cpw_keyblock); + + if (retval = krb5_copy_principal(context, client_ticket->enc_part2->client, + &client_server_info.client)) + goto finish; + + /* Check if ticket was issued using password (and not tgt) + * within the last 5 minutes + */ + + if (!(client_ticket->enc_part2->flags & TKT_FLG_INITIAL)) { + syslog(LOG_ERR, "Client ticket not initial"); + close(client_server_info.client_socket); + exit(0); + } + + if (retval = krb5_timeofday(context, &adm_time)) { + syslog(LOG_ERR, "Can't get time of day"); + close(client_server_info.client_socket); + exit(0); + } + + if ((adm_time - client_ticket->enc_part2->times.authtime) > 60*5) { + syslog(LOG_ERR, "Client ticket not recent"); + close(client_server_info.client_socket); + exit(0); + } + + if ((client_server_info.name_of_client = + (char *) calloc (1, 3 * 255)) == (char *) 0) { + syslog(LOG_ERR, "kadmind error: No Memory for name_of_client"); + close(client_server_info.client_socket); + exit(0); + } + + if ((retval = krb5_unparse_name(context, client_server_info.client, + &client_server_info.name_of_client))) { + syslog(LOG_ERR, "kadmind error: unparse failed.", + error_message(retval)); + goto finish; + } + + syslog(LOG_AUTH | LOG_INFO, + "Request for Administrative Service Received from %s at %s.", + client_server_info.name_of_client, + inet_ntoa( client_server_info.client_name.sin_addr )); + + /* compose the reply */ + outbuf.data[0] = KADMIND; + outbuf.data[1] = KADMSAG; + outbuf.length = 2; + + /* write back the response */ + if ((retval = krb5_write_message(context, &client_server_info.client_socket, + &outbuf))){ + syslog(LOG_ERR, "kadmind error: Write Message Failure: %s", + error_message(retval)); + retval = 1; + goto finish; + } + + /* Ok Now let's get the first private message and respond */ + if (retval = krb5_read_message(context, &client_server_info.client_socket, + &inbuf)){ + syslog(LOG_ERR, "kadmind error: read First Message Failure: %s", + error_message(retval)); + retval = 1; + goto finish; + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + free(inbuf.data); + syslog(LOG_ERR, "kadmind error: rd_priv:%s\n", error_message(retval)); + goto finish; + } + free(inbuf.data); + + request_type.appl_code = msg_data.data[0]; + request_type.oper_code = msg_data.data[1]; + + free(msg_data.data); + + switch (request_type.appl_code) { + case KPASSWD: + req_type = "kpasswd"; + if (retval = adm5_kpasswd(context, auth_context, "process_client", + &request_type, retbuf, &otype)) { + goto finish; + } + break; + + case KADMIN: + req_type = "kadmin"; + if (retval = adm5_kadmin(context, auth_context, "process_client", + retbuf, &otype)) { + goto finish; + } + retbuf[0] = KADMIN; + retbuf[2] = KADMGOOD; + retbuf[3] = '\0'; + otype = 0; + break; + + + default: + retbuf[0] = KUNKNOWNAPPL; + retbuf[1] = '\0'; + sprintf(completion_msg, "%s from %s (%02x) FAILED", + "Unknown Application Type!", + inet_ntoa(client_server_info.client_name.sin_addr), + request_type.appl_code); + /* Service Not Supported */ + retval = 255; + syslog(LOG_AUTH | LOG_INFO, completion_msg); + goto finish; + } /* switch(request_type.appl_code) */ + + if ((final_msg.data = (char *) calloc(1,10)) == (char *) 0) { + syslog(LOG_ERR | LOG_INFO, "no Memory while allocating final_msg.data"); + return ENOMEM; + } + final_msg.data = retbuf; + final_msg.length = strlen(retbuf) + 1; + + /* Send Completion Message */ + if (retval = krb5_mk_priv(context, auth_context, &final_msg, + &msg_data, &replaydata)) { + syslog(LOG_ERR, "kadmind error Error Performing Final mk_priv"); + goto finish; + } + + /* Send Final Reply to Client */ + if (retval = krb5_write_message(context, &client_server_info.client_socket, + &msg_data)){ + free(msg_data.data); + syslog(LOG_ERR, "Error Performing Final Write: %s", + error_message(retval)); + retval = 1; + goto finish; + } + free(msg_data.data); + +finish: + + if (retval) { + free (client_server_info.name_of_client); + close(client_server_info.client_socket); + exit(1); + } + + sprintf(completion_msg, + "%s %s for %s at %s - Completed Successfully", + req_type, + oper_type[otype], + client_server_info.name_of_client, + inet_ntoa( client_server_info.client_name.sin_addr )); + syslog(LOG_AUTH | LOG_INFO, completion_msg); + free (client_server_info.name_of_client); + close(client_server_info.client_socket); + return 0; +} diff --git a/src/kadmin.old/server/adm_server.c b/src/kadmin.old/server/adm_server.c new file mode 100644 index 000000000..0b4905191 --- /dev/null +++ b/src/kadmin.old/server/adm_server.c @@ -0,0 +1,519 @@ +/* + * kadmin/server/adm_server.c + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Top-level loop of the Kerberos Version 5 Administration server + */ + +/* + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + */ + + +/* + adm_server.c + this holds the main loop and initialization and cleanup code for the server +*/ + +#include +#include +#include +#include +#include "com_err.h" + +#include +#ifndef sigmask +#define sigmask(m) (1 <<((m)-1)) +#endif + +#include +#include +#ifndef hpux +#include +#endif + +#ifndef __STDC__ +#include +#endif + +#include "k5-int.h" +#include "adm_extern.h" + +char prog[32]; +char *progname = prog; +char *acl_file_name = DEFAULT_ADMIN_ACL; +char *adm5_ver_str = ADM5_VERSTR; +int adm5_ver_len; + +char *adm5_tcp_portname = ADM5_PORTNAME; +int adm5_tcp_port_fd = -1; + +unsigned pidarraysize = 0; +int *pidarray = (int *) 0; + +int exit_now = 0; + +global_client_server_info client_server_info; + +#ifdef SANDIA +int classification; /* default = Unclassified */ +#endif + +krb5_db_entry master_entry; + +krb5_flags NEW_ATTRIBUTES; + +cleanexit(context, val) + krb5_context context; + int val; +{ + (void) krb5_db_fini(context); + exit(val); +} + +krb5_error_code +closedown_db(context) + krb5_context context; +{ + krb5_error_code retval; + + /* clean up master key stuff */ + retval = krb5_finish_key(context, &master_encblock); + + memset((char *)&master_encblock, 0, sizeof(master_encblock)); + memset((char *)tgs_key.contents, 0, tgs_key.length); + + /* close database */ + if (retval) { + (void) krb5_db_fini(context); + return(retval); + } else + return(krb5_db_fini(context)); +} + +void +usage(name) +char *name; +{ + fprintf(stderr, "Usage: %s\t[-a aclfile] [-d dbname] [-k masterkeytype]", + name); + fprintf(stderr, "\n\t[-h] [-m] [-M masterkeyname] [-r realm] [-p port]\n"); + return; +} + +krb5_error_code +process_args(context, argc, argv) + krb5_context context; + int argc; + char **argv; +{ + krb5_error_code retval; + int c; + krb5_boolean manual = FALSE; + int keytypedone = 0; + char *mkey_name = 0; + char *local_realm; + krb5_enctype etype; + krb5_enctype kdc_etype = DEFAULT_KDC_ETYPE; + +#ifdef SANDIA + char input_string[80]; + FILE *startup_file; +#endif + + extern char *optarg; + +#ifdef SANDIA + classification = 0; + + if ((startup_file = + fopen(DEFAULT_KDCPARM_NAME, "r")) == (FILE *) 0) { + syslog(LOG_ERR, + "Cannot open parameter file (%s) - Using default parameters", + DEFAULT_KDCPARM_NAME); + syslog(LOG_ERR, "Only Unclassified Principals will be allowed"); + } else { + for ( ;; ) { + if ((fgets(input_string, sizeof(input_string), startup_file)) == NULL) + break; + kadmin_parse_and_set(input_string); + } + fclose(startup_file); + } +#endif + while ((c = getopt(argc, argv, "hmM:a:d:k:r:De:p:")) != EOF) { + switch(c) { + case 'a': /* new acl directory */ + acl_file_name = optarg; + break; + + case 'd': + /* put code to deal with alt database place */ + dbm_db_name = optarg; + if (retval = krb5_dbm_db_set_name(context, dbm_db_name)) { + fprintf(stderr, "opening database %s: %s", + dbm_db_name, error_message(retval)); + exit(1); + } + break; + + case 'e': + kdc_etype = atoi(optarg); + break; + + case 'k': /* keytype for master key */ + master_keyblock.keytype = atoi(optarg); + keytypedone++; + break; + + case 'm': /* manual type-in of master key */ + manual = TRUE; + break; + + case 'M': /* master key name in DB */ + mkey_name = optarg; + break; + + case 'r': + realm = optarg; + break; + + case 'D': + adm_debug_flag = 1; + break; + + case 'p': + admin_port = htons(atoi(optarg)); + break; + + case 'h': /* get help on using adm_server */ + default: + usage(argv[0]); + exit(1); /* Failure - Exit */ + } + + } + + if (!realm) { + /* no realm specified, use default realm */ + if (retval = krb5_get_default_realm(context, &local_realm)) { + com_err(argv[0], retval, + "while attempting to retrieve default realm"); + exit(1); + } + realm = local_realm; + } + + if (!mkey_name) { + mkey_name = KRB5_KDB_M_NAME; + } + + if (!keytypedone) { + master_keyblock.keytype = KEYTYPE_DES; + } + + /* assemble & parse the master key name */ + if (retval = krb5_db_setup_mkey_name(context, mkey_name, + realm, + (char **) 0, + &master_princ)) { + com_err(argv[0], retval, "while setting up master key name"); + exit(1); + } + + if (!valid_etype(kdc_etype)) { + com_err(argv[0], KRB5_PROG_ETYPE_NOSUPP, + "while setting up etype %d", kdc_etype); + exit(1); + } + krb5_use_cstype(context, &master_encblock, kdc_etype); + + if (retval = krb5_db_fetch_mkey(context, + master_princ, + &master_encblock, + manual, + FALSE, /* only read it once, if at all */ + 0, /* No salt supplied */ + &master_keyblock)) { + com_err(argv[0], retval, "while fetching master key"); + exit(1); + } + + /* initialize random key generators */ + for (etype = 0; etype <= krb5_max_cryptosystem; etype++) { + if (krb5_csarray[etype]) { + if (retval = (*krb5_csarray[etype]->system-> + init_random_key)(&master_keyblock, + &krb5_csarray[etype]->random_sequence)) { + com_err(argv[0], retval, + "while setting up random key generator for etype %d--etype disabled", + etype); + krb5_csarray[etype] = 0; + } + } + } + + return(0); +} + +krb5_error_code +init_db(context, dbname, masterkeyname, masterkeyblock) + krb5_context context; + char *dbname; + krb5_principal masterkeyname; + krb5_keyblock *masterkeyblock; +{ + krb5_error_code retval; + + krb5_db_entry server_entry; + krb5_boolean more; + int number_of_entries; + char tgs_name[255]; + + /* set db name if appropriate */ + if (dbname && (retval = krb5_db_set_name(context, dbname))) + return(retval); + + /* initialize database */ + if (retval = krb5_db_init(context)) + return(retval); + + if (retval = krb5_db_verify_master_key(context, masterkeyname, + masterkeyblock, + &master_encblock)) { + master_encblock.crypto_entry = 0; + return(retval); + } + + /* do any necessary key pre-processing */ + if (retval = krb5_process_key(context, &master_encblock, masterkeyblock)) { + master_encblock.crypto_entry = 0; + (void) krb5_db_fini(context); + return(retval); + } + +/* + * fetch the master database entry, and hold on to it. + */ + number_of_entries = 1; + if (retval = krb5_db_get_principal(context, masterkeyname, &master_entry, + &number_of_entries, &more)) { + return(retval); + } + if (number_of_entries != 1) { + if (number_of_entries) + krb5_db_free_principal(context, &master_entry, number_of_entries); + return(KRB5_KDB_NOMASTERKEY); + } else if (more) { + krb5_db_free_principal(context, &master_entry, number_of_entries); + return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); + } + +/* + fetch the TGS key, and hold onto it; this is an efficiency hack + the master key name here is from the master_princ global, + so we can safely share its substructure + */ + strcpy(tgs_name, KRB5_TGS_NAME); + strcat(tgs_name, "/"); + strcat(tgs_name, masterkeyname->realm.data); + strcat(tgs_name, "@"); + strcat(tgs_name, masterkeyname->realm.data); + krb5_parse_name(context, tgs_name, &tgs_server); + + tgs_server->type = KRB5_NT_SRV_INST; + + number_of_entries = 1; + if (retval = krb5_db_get_principal(context, + tgs_server, + &server_entry, + &number_of_entries, + &more)) { + return(retval); + } + + if (more) { + krb5_db_free_principal(context, &server_entry, number_of_entries); + (void) krb5_finish_key(context, &master_encblock); + memset((char *)&master_encblock, 0, sizeof(master_encblock)); + (void) krb5_db_fini(context); + return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); + } else if (number_of_entries != 1) { + krb5_db_free_principal(context, &server_entry, number_of_entries); + (void) krb5_finish_key(context, &master_encblock); + memset((char *)&master_encblock, 0, sizeof(master_encblock)); + (void) krb5_db_fini(context); + return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); + } + +/* + convert server.key into a real key + (it may be encrypted in the database) + */ + if (retval = KDB_CONVERT_KEY_OUTOF_DB(context,&server_entry.key,&tgs_key)) { + krb5_db_free_principal(context, &server_entry, number_of_entries); + (void) krb5_finish_key(context, &master_encblock); + memset((char *)&master_encblock, 0, sizeof(master_encblock)); + (void) krb5_db_fini(context); + return(retval); + } + + tgs_kvno = server_entry.kvno; + krb5_db_free_principal(context, &server_entry, number_of_entries); + return(0); +} + +krb5_sigtype +request_exit() +{ + signal_requests_exit = 1; + return; +} + +void +setup_signal_handlers() +{ + krb5_sigtype request_exit(); + + (void)signal(SIGINT, request_exit); + (void)signal(SIGHUP, request_exit); + (void)signal(SIGTERM, request_exit); + return; +} + +static void +kdc_com_err_proc(whoami, code, format, pvar) + const char *whoami; + long code; + const char *format; + va_list pvar; +{ +#ifndef __STDC__ + extern int vfprintf(); +#endif + + if (whoami) { + fputs(whoami, stderr); + fputs(": ", stderr); + } + + if (code) { + fputs(error_message(code), stderr); + fputs(" ", stderr); + } + + if (format) { + vfprintf (stderr, format, pvar); + } + + putc('\n', stderr); + /* should do this only on a tty in raw mode */ + putc('\r', stderr); + fflush(stderr); + + if (format) { + /* now need to frob the format a bit... */ + if (code) { + char *nfmt; + nfmt = (char *) malloc( + strlen(format)+strlen(error_message(code))+2); + strcpy(nfmt, error_message(code)); + strcat(nfmt, " "); + strcat(nfmt, format); + vsyslog(LOG_ERR, nfmt, pvar); + } else { + vsyslog(LOG_ERR, format, pvar); + } + } else { + if (code) { + syslog(LOG_ERR, "%s", error_message(code)); + } + } + return; +} + +void +setup_com_err(context) + krb5_context context; +{ + krb5_init_ets(context); + + (void) set_com_err_hook(kdc_com_err_proc); + return; +} + +/* +** 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... +*/ +main(argc, argv) /* adm_server main routine */ +int argc; +char **argv; +{ + krb5_context context; + krb5_error_code retval; + int errout = 0; + + adm5_ver_len = ADM5_VERSIZE; + + /* Get the Name of this program (adm_server) for Error Messages */ + if (strrchr(argv[0], '/')) + argv[0] = (char *)strrchr(argv[0], '/') + 1; + + krb5_init_context(&context); + setup_com_err(context); + + /* Use Syslog for Messages */ +#ifndef LOG_AUTH /* 4.2 syslog */ +#define LOG_AUTH 0 + openlog(argv[0], LOG_CONS|LOG_NDELAY|LOG_PID, LOG_LOCAL6); +#else + openlog(argv[0], LOG_AUTH|LOG_CONS|LOG_NDELAY|LOG_PID, LOG_LOCAL6); +#endif /* LOG_AUTH */ + + process_args(context, argc, argv); /* includes reading master key */ + + setup_signal_handlers(); + + if (retval = init_db(context, dbm_db_name, master_princ,&master_keyblock)) { + com_err(argv[0], retval, "while initializing database"); + exit(1); + } + + if (retval = setup_network(context, argv[0])) { + exit(1); + } + + syslog(LOG_AUTH | LOG_INFO, "Admin Server Commencing Operation"); + + if (retval = adm5_listen_and_process(context, argv[0])){ + krb5_free_principal(context, client_server_info.server); + com_err(argv[0], retval, "while processing network requests"); + errout++; + } + + free(client_server_info.name_of_service); + krb5_free_principal(context, client_server_info.server); + + if (errout = closedown_network(argv[0])) { + com_err(argv[0], retval, "while shutting down network"); + retval = retval + errout; + } + + if (errout = closedown_db(context)) { + com_err(argv[0], retval, "while closing database"); + retval = retval + errout; + } + + syslog(LOG_AUTH | LOG_INFO, "Admin Server Shutting Down"); + + printf("Admin Server (kadmind) has completed operation.\n"); + + exit(retval); +} diff --git a/src/kadmin.old/server/adm_v4_pwd.c b/src/kadmin.old/server/adm_v4_pwd.c new file mode 100644 index 000000000..b74d92372 --- /dev/null +++ b/src/kadmin.old/server/adm_v4_pwd.c @@ -0,0 +1,432 @@ + +/* + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + */ + +#include +#include +#include +#include +#include + +#define MAX_KTXT_LEN 1250 +#define ANAME_SZ 40 +#define INST_SZ 40 +#define REALM_SZ 40 +#define DATE_SZ 26 + +typedef unsigned char des_cblock[8]; /* crypto-block size */ +#define C_Block des_cblock +typedef struct des_ks_struct { des_cblock _; } des_key_schedule[16]; +#define Key_schedule des_key_schedule + +int des_debug = 0; + +struct ktext { + int length; /* Length of the text */ + unsigned char dat[MAX_KTXT_LEN]; /* The data itself */ + unsigned long mbz; /* zero to catch runaway strings */ +}; + +typedef struct ktext *KTEXT; +typedef struct ktext KTEXT_ST; + +struct auth_dat { + unsigned char k_flags; /* Flags from ticket */ + char pname[ANAME_SZ]; /* Principal's name */ + char pinst[INST_SZ]; /* His Instance */ + char prealm[REALM_SZ]; /* His Realm */ + unsigned long checksum; /* Data checksum (opt) */ + C_Block session; /* Session Key */ + int life; /* Life of ticket */ + unsigned long time_sec; /* Time ticket issued */ + unsigned long address; /* Address in ticket */ + KTEXT_ST reply; /* Auth reply (opt) */ +}; + +typedef struct auth_dat AUTH_DAT; + +#define KADM_VERSTR "SKADM.m1" +#define KADM_VERSIZE strlen(KADM_VERSTR) + +struct msg_dat { + unsigned char *app_data; /* pointer to appl data */ + unsigned long app_length; /* length of appl data */ + unsigned long hash; /* hash to lookup replay */ + int swap; /* swap bytes? */ + long time_sec; /* msg timestamp seconds */ + unsigned char time_5ms; /* msg timestamp 5ms units */ +}; + +typedef struct msg_dat MSG_DAT; + +typedef struct { + char name[ANAME_SZ]; + char instance[INST_SZ]; + + unsigned long key_low; + unsigned long key_high; + unsigned long exp_date; + char exp_date_txt[DATE_SZ]; + unsigned long mod_date; + char mod_date_txt[DATE_SZ]; + unsigned short attributes; + unsigned char max_life; + unsigned char kdc_key_ver; + unsigned char key_version; + + char mod_name[ANAME_SZ]; + char mod_instance[INST_SZ]; + char *old; +} V4_Principal; + + /* V5 Definitions */ +#include "k5-int.h" +#include "adm_extern.h" + +struct saltblock { + int salttype; + krb5_data saltdata; +}; + +struct cpw_keyproc_arg { + krb5_keyblock *key; +}; + +/* +process_v4_kpasswd +unwrap the data stored in dat, process, and return it. + */ +process_v4_kpasswd(dat, dat_len, cpw_key) +u_char **dat; +int *dat_len; +struct cpw_keyproc_arg *cpw_key; + +{ + u_char *in_st; /* pointer into the sent packet */ + int in_len,retc; /* where in packet we are, for + returns */ + u_long r_len; /* length of the actual packet */ + KTEXT_ST authent; /* the authenticator */ + AUTH_DAT ad; /* who is this, klink */ + u_long ncksum; /* checksum of encrypted data */ + des_key_schedule sess_sched; /* our schedule */ + MSG_DAT msg_st; + u_char *retdat, *tmpdat; + int retval, retlen; + u_short dlen; + extern int errno; + + if (strncmp(KADM_VERSTR, (char *) *dat, KADM_VERSIZE)) { + syslog(LOG_ERR, "process_v4_kpasswd: Bad Version String"); + return(1); + } + + in_len = KADM_VERSIZE; + /* get the length */ + if ((retc = stv_long(*dat, &r_len, in_len, *dat_len)) < 0) { + syslog(LOG_AUTH | LOG_INFO, "process_v4_kpasswd: Bad Length"); + return(1); + } + + in_len += retc; + authent.length = *dat_len - r_len - KADM_VERSIZE - sizeof(u_long); + memcpy((char *) authent.dat, (char *) (*dat) + in_len, authent.length); + authent.mbz = 0; + + if (retval = krb_set_key(cpw_key->key->contents, 0) != 0) { + syslog(LOG_ERR, "process_v4_kpasswd: Bad set_key Request"); + return(1); + } + + /* service key should be set before here */ + if (retc = krb4_rd_req(&authent, + CPWNAME, + client_server_info.server->realm.data, + client_server_info.client_name.sin_addr.s_addr, + &ad, + (char *) 0)) { + syslog(LOG_AUTH | LOG_INFO, "process_v4_kpasswd: Bad Read Request"); + return(1); + } + +#define clr_cli_secrets() \ +{ \ + memset((char *) sess_sched, 0, sizeof(sess_sched)); \ + memset((char *) ad.session, 0, sizeof(ad.session)); \ +} + + in_st = *dat + *dat_len - r_len; + ncksum = des_quad_cksum(in_st, (u_long *) 0, (long) r_len, 0, ad.session); + if (ncksum!=ad.checksum) { /* yow, are we correct yet */ + clr_cli_secrets(); + syslog(LOG_ERR, "process_v4_kpasswd: Invalid Checksum"); + return(1); + } + + des_key_sched(ad.session, sess_sched); + + if (retc = (int) krb4_rd_priv(in_st, + r_len, + sess_sched, + ad.session, + &client_server_info.client_name, + &client_server_info.server_name, + &msg_st)) { + syslog(LOG_ERR, "process_v4_kpasswd: Bad Read Private Code = %d", + retc); + clr_cli_secrets(); + return(1); + } + + if (msg_st.app_data[0] != 2) { /* Only Valid Request is CHANGE_PW = 2 */ + syslog(LOG_ERR, "process_v4_kpasswd: Invalid V4 Request"); + clr_cli_secrets(); + return(1); + } + + retval = adm_v4_cpw(msg_st.app_data+1, + (int) msg_st.app_length, + &ad, + &retdat, + &retlen); + + if (retval) { + syslog(LOG_ERR, + "process_v4_kpasswd: Password Modification for %s%s%s Failed", + ad.pname, (ad.pinst[0] != '\0') ? "/" : "", + (ad.pinst[0] != '\0') ? ad.pinst : ""); + } else { + syslog(LOG_ERR, + "process_v4_kpasswd: Password Modification for %s%s%s Complete", + ad.pname, (ad.pinst[0] != '\0') ? "/" : "", + (ad.pinst[0] != '\0') ? ad.pinst : ""); + } + + /* Now seal the response back into a priv msg */ + free((char *)*dat); + tmpdat = (u_char *) malloc((unsigned)(retlen + KADM_VERSIZE + + sizeof(u_long))); + + (void) strncpy((char *) tmpdat, KADM_VERSTR, KADM_VERSIZE); + + retval = htonl((u_long) retval); + + memcpy((char *) tmpdat + KADM_VERSIZE, (char *) &retval, sizeof(u_long)); + + if (retlen) { + memcpy((char *) tmpdat + KADM_VERSIZE + sizeof(u_long), + (char *) retdat, retlen); + free((char *) retdat); + } + + /* slop for mk_priv stuff */ + *dat = (u_char *) malloc((unsigned) (retlen + KADM_VERSIZE + + sizeof(u_long) + 200)); + + if ((*dat_len = krb4_mk_priv(tmpdat, *dat, + (u_long) (retlen + KADM_VERSIZE + + sizeof(u_long)), + sess_sched, + ad.session, + &client_server_info.server_name, + &client_server_info.client_name)) < 0) { + clr_cli_secrets(); + syslog(LOG_ERR, "process_v4_kpasswd: Bad mk_priv"); + return(1); + } + + dlen = (u_short) *dat_len; + + dlen = htons(dlen); + + if (krb5_net_write(context, client_server_info.client_socket, + (char *) &dlen, 2) < 0) { + syslog(LOG_ERR, "process_v4_kpasswd: Error writing dlen to client"); + (void) close(client_server_info.client_socket); + } + + if (krb5_net_write(context, client_server_info.client_socket, + (char *) *dat, *dat_len) < 0) { + syslog(LOG_ERR, "writing to client: %s",error_message(errno)); + (void) close(client_server_info.client_socket); + } + + free((char *) *dat); + clr_cli_secrets(); + + return(0); +} + +krb5_kvno +princ_exists(context, principal, entry) + krb5_context context; + krb5_principal principal; + krb5_db_entry *entry; +{ + int nprincs = 1; + krb5_boolean more; + krb5_error_code retval; + krb5_kvno vno; + + nprincs = 1; + if (retval = krb5_db_get_principal(context, principal, entry, + &nprincs, &more)) { + return 0; + } + + if (!nprincs) + return 0; + + return(nprincs); +} + +/* +adm_v4_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 +adm_v4_cpw(dat, len, ad, datout, outlen) +u_char *dat; +int len; +AUTH_DAT *ad; +u_char **datout; +int *outlen; +{ + krb5_db_entry entry; + krb5_keyblock *v5_keyblock; + + int number_of_principals; + krb5_error_code retval; + int one = 1; + char v5_principal[255]; + + C_Block v4_clear_key; + unsigned long keylow, keyhigh; + int stvlen; + + /* Identify the Customer */ + (void) sprintf(v5_principal, "%s%s%s\0", ad->pname, + (ad->pinst[0] != '\0') ? "/" : "", + (ad->pinst[0] != '\0') ? ad->pinst : ""); + + /* take key off the stream, and change the database */ + + if ((stvlen = stv_long(dat, &keyhigh, 0, len)) < 0) { + syslog(LOG_ERR, "adm_v4_cpw - (keyhigh) Length Error for stv_long"); + return(1); + } + if (stv_long(dat, &keylow, stvlen, len) < 0) { + syslog(LOG_ERR, "adm_v4_cpw - (keylow) Length Error for stv_long"); + return(1); + } + + keylow = ntohl(keylow); + keyhigh = ntohl(keyhigh); + + /* Convert V4 Key to V5 Key */ + (void) memcpy(v4_clear_key, (char *) &keylow, 4); + (void) memcpy(((long *) v4_clear_key) + 1, (char *) &keyhigh, 4); + + /* Zero Next Output Entry */ + memset((char *) &entry, 0, sizeof(entry)); + + if (retval = krb5_parse_name(context, v5_principal, &entry.principal)) { + syslog(LOG_ERR, "adm_v4_cpw - Error parsing %s", + v5_principal); + return(1); + } + + if (!(number_of_principals = princ_exists(entry.principal, &entry))) { + syslog(LOG_ERR, "adm_v4_cpw - principal %s is NOT in the database", + v5_principal); + return(1); + } + + /* Allocate v5_keyblock and fill some fields */ + if (!(v5_keyblock = (krb5_keyblock *) calloc (1, + sizeof(krb5_keyblock)))) { + syslog(LOG_ERR, "adm_v4_cpw - Error Allocating krb5_keyblock"); + return(1); + } + + v5_keyblock->keytype = KEYTYPE_DES; + v5_keyblock->length = 8; + if (!(v5_keyblock->contents = (krb5_octet *) calloc (1, + 8))) { + syslog(LOG_ERR, + "adm_v4_cpw - Error Allocating krb5_keyblock->contents\n"); + free(v5_keyblock); + return(1); + } + + memcpy(v5_keyblock->contents, v4_clear_key, 8); + + if (retval = krb5_kdb_encrypt_key(context, &master_encblock, + v5_keyblock, + &entry.key)) { + syslog(LOG_ERR, + "adm_v4_cpw - Error %d while encrypting key for '%s'\n", retval, + v5_principal); + return(1); + } + entry.alt_key.length = 0; + + /* Increment Version Number */ + entry.kvno = entry.kvno + 1; +#ifdef SANDIA + entry.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; +#endif + if (retval = krb5_timeofday(context, &entry.mod_date)) { + syslog(LOG_ERR, "adm_v4_cpw - Error while fetching date"); + return(1); + } +#ifdef SANDIA + entry.last_pwd_change = entry.mod_date; +#endif + entry.mod_name = entry.principal; /* Should be Person who did Action */ + + /* Write the Modified Principal to the V5 Database */ + if (retval = krb5_db_put_principal(context, &entry, &one)) { + syslog(LOG_ERR, + "adm_v4_cpw - Error %d while Entering Principal for '%s'", + retval, v5_principal); + return(1); + } + + *datout = 0; + *outlen = 0; + + return(0); +} + +stv_long(st, dat, loc, maxlen) +u_char *st; /* a base pointer to the stream */ +u_long *dat; /* the attributes field */ +int loc; /* offset into the stream for current data */ +int maxlen; /* maximum length of st */ +{ + u_long temp = 0; /* to hold the net order short */ + +#if (SIZEOF_LONG == 4) + if (loc + 4 > maxlen) + return(-1); + (void) memcpy((char *) &temp + 4, (char *) ((u_long)st + (u_long)loc), 4); + *dat = ntohl(temp); /* convert to network order */ + return(4); +#else + if (loc + sizeof(u_long) > maxlen) + return(-1); + (void) memcpy((char *) &temp, (char *) ((u_long)st + (u_long)loc), + sizeof(u_long)); + *dat = ntohl(temp); /* convert to network order */ + return(sizeof(u_long)); +#endif +} diff --git a/src/kadmin.old/server/admin_acl_file b/src/kadmin.old/server/admin_acl_file new file mode 100644 index 000000000..77bddccba --- /dev/null +++ b/src/kadmin.old/server/admin_acl_file @@ -0,0 +1,12 @@ +# Administrator Access Control List +# Format: +# Name Privileges Comments +# Where Privileges is a string containing one or more of +# "a" Add New Principals +# "c" Change Passwords +# "d" Delete Current Principals +# "i" Inquire About Existing Principals +# "m" Modify Existing Principals +# "*" All Privileges +#jqsample/admin@realm * +#tomjones/admin@realm acim # Note - May Not Delete diff --git a/src/kadmin.old/server/configure.in b/src/kadmin.old/server/configure.in new file mode 100644 index 000000000..18c4b14a0 --- /dev/null +++ b/src/kadmin.old/server/configure.in @@ -0,0 +1,14 @@ +AC_INIT(adm_kadmin.c) +WITH_CCOPTS +CONFIG_RULES +AC_SET_BUILDTOP +AC_PROG_INSTALL +WITH_NETLIB +AC_CHECK_LIB(ndbm,main) +AC_CHECK_LIB(dbm,main) +AC_TIME_WITH_SYS_TIME +ET_RULES +KRB_INCLUDE +WITH_KRB5ROOT +CHECK_SIGPROCMASK +V5_AC_OUTPUT_MAKEFILE diff --git a/src/kadmin.old/server/kadmind.M b/src/kadmin.old/server/kadmind.M new file mode 100644 index 000000000..f4e625896 --- /dev/null +++ b/src/kadmin.old/server/kadmind.M @@ -0,0 +1 @@ +.\" this should not be empty -- cgit