From 5927960fc25627c84b1fb175a056afac1e50b5e0 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Tue, 25 Apr 1995 01:23:16 +0000 Subject: [PATCH] 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/.Sanitize | 39 ++ src/kadmin.old/.cvsignore | 1 + src/kadmin.old/Makefile.in | 5 + src/kadmin.old/client/.Sanitize | 47 ++ src/kadmin.old/client/.cvsignore | 1 + src/kadmin.old/client/ChangeLog | 98 ++++ src/kadmin.old/client/Makefile.in | 49 ++ src/kadmin.old/client/configure.in | 10 + src/kadmin.old/client/kadmin.M | 2 + src/kadmin.old/client/kadmin.c | 725 +++++++++++++++++++++++ src/kadmin.old/client/kadmin_add.c | 236 ++++++++ src/kadmin.old/client/kadmin_adr.c | 129 +++++ src/kadmin.old/client/kadmin_cpr.c | 132 +++++ src/kadmin.old/client/kadmin_cpw.c | 246 ++++++++ src/kadmin.old/client/kadmin_del.c | 124 ++++ src/kadmin.old/client/kadmin_done.c | 70 +++ src/kadmin.old/client/kadmin_inq.c | 198 +++++++ src/kadmin.old/client/kadmin_mod.c | 185 ++++++ src/kadmin.old/client/kadmin_msnd.c | 273 +++++++++ src/kadmin.old/configure.in | 10 + src/kadmin.old/kpasswd/.Sanitize | 39 ++ src/kadmin.old/kpasswd/.cvsignore | 1 + src/kadmin.old/kpasswd/ChangeLog | 76 +++ src/kadmin.old/kpasswd/Makefile.in | 34 ++ src/kadmin.old/kpasswd/configure.in | 13 + src/kadmin.old/kpasswd/kpasswd.M | 1 + src/kadmin.old/kpasswd/kpasswd.c | 824 ++++++++++++++++++++++++++ src/kadmin.old/kpasswd/networked.c | 222 +++++++ 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 + 51 files changed, 9068 insertions(+) create mode 100644 src/kadmin.old/.Sanitize create mode 100644 src/kadmin.old/.cvsignore create mode 100644 src/kadmin.old/Makefile.in create mode 100644 src/kadmin.old/client/.Sanitize create mode 100644 src/kadmin.old/client/.cvsignore create mode 100644 src/kadmin.old/client/ChangeLog create mode 100644 src/kadmin.old/client/Makefile.in create mode 100644 src/kadmin.old/client/configure.in create mode 100644 src/kadmin.old/client/kadmin.M create mode 100644 src/kadmin.old/client/kadmin.c create mode 100644 src/kadmin.old/client/kadmin_add.c create mode 100644 src/kadmin.old/client/kadmin_adr.c create mode 100644 src/kadmin.old/client/kadmin_cpr.c create mode 100644 src/kadmin.old/client/kadmin_cpw.c create mode 100644 src/kadmin.old/client/kadmin_del.c create mode 100644 src/kadmin.old/client/kadmin_done.c create mode 100644 src/kadmin.old/client/kadmin_inq.c create mode 100644 src/kadmin.old/client/kadmin_mod.c create mode 100644 src/kadmin.old/client/kadmin_msnd.c create mode 100644 src/kadmin.old/configure.in create mode 100644 src/kadmin.old/kpasswd/.Sanitize create mode 100644 src/kadmin.old/kpasswd/.cvsignore create mode 100644 src/kadmin.old/kpasswd/ChangeLog create mode 100644 src/kadmin.old/kpasswd/Makefile.in create mode 100644 src/kadmin.old/kpasswd/configure.in create mode 100644 src/kadmin.old/kpasswd/kpasswd.M create mode 100644 src/kadmin.old/kpasswd/kpasswd.c create mode 100644 src/kadmin.old/kpasswd/networked.c 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 diff --git a/src/kadmin.old/.Sanitize b/src/kadmin.old/.Sanitize new file mode 100644 index 000000000..a27eed5fa --- /dev/null +++ b/src/kadmin.old/.Sanitize @@ -0,0 +1,39 @@ +# 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 +Makefile.in +client +configure +configure.in +kpasswd +server +v4server + +Things-to-lose: + +Do-last: + +# End of file. diff --git a/src/kadmin.old/.cvsignore b/src/kadmin.old/.cvsignore new file mode 100644 index 000000000..e8c05a6b1 --- /dev/null +++ b/src/kadmin.old/.cvsignore @@ -0,0 +1 @@ +configure diff --git a/src/kadmin.old/Makefile.in b/src/kadmin.old/Makefile.in new file mode 100644 index 000000000..534ff10ed --- /dev/null +++ b/src/kadmin.old/Makefile.in @@ -0,0 +1,5 @@ +CFLAGS = $(CCOPTS) +LDFLAGS = -g + +all:: + diff --git a/src/kadmin.old/client/.Sanitize b/src/kadmin.old/client/.Sanitize new file mode 100644 index 000000000..6aad222d5 --- /dev/null +++ b/src/kadmin.old/client/.Sanitize @@ -0,0 +1,47 @@ +# 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 +configure +configure.in +kadmin.M +kadmin.c +kadmin_add.c +kadmin_adr.c +kadmin_cpr.c +kadmin_cpw.c +kadmin_del.c +kadmin_done.c +kadmin_inq.c +kadmin_mod.c +kadmin_msnd.c + +Things-to-lose: + +Do-last: + +# End of file. diff --git a/src/kadmin.old/client/.cvsignore b/src/kadmin.old/client/.cvsignore new file mode 100644 index 000000000..e8c05a6b1 --- /dev/null +++ b/src/kadmin.old/client/.cvsignore @@ -0,0 +1 @@ +configure diff --git a/src/kadmin.old/client/ChangeLog b/src/kadmin.old/client/ChangeLog new file mode 100644 index 000000000..c51961207 --- /dev/null +++ b/src/kadmin.old/client/ChangeLog @@ -0,0 +1,98 @@ +Thu Apr 20 18:18:48 1995 Mark Eichin + + Changes from Ian Taylor to support testsuite. + Support -p port argument to kadmin client. + * kadmin.c (main): parse -p argument. + (adm5_init_link): new port argument, use it in preference to + getservbyname. + (usage): document new -p argument. + +Thu Apr 20 11:45:10 1995 + + * kadmin.c, kadmin_add.c, kadmin_adr.c, kadmin_cpr.c kadmin_cpw.c, + kadmin_del.c, kadmin_done.c, kadmin_inq.c, kadmin_mod.c, + kadmin_msnd.c: Add include of adm_defs.h, since that's no longer + included by krb5.h. + +Fri Mar 17 15:36:07 1995 Chris Provenzano (proven@mit.edu) + + * kadmin_inq.c, kadmin.c: + Cast malloc() return value to shut compiler up. + +Fri Mar 10 11:09:34 1995 Chris Provenzano (proven@mit.edu) + + * kadmin.c, kadmin_adr.c, kadmin_cpw.c, kadmin_done.c, kadmin_mod.c + * kadmin_add.c, kadmin_cpr.c, kadmin_del.c, kadmin_inq.c, kadmin_msnd.c + Use new calling convention for krb5_sendauth(), krb5_mk_priv(), + krb5_rd_priv(), krb5_mk_safe(), and krb5_rd_safe(). + +Thu Mar 2 12:24:25 1995 Theodore Y. Ts'o + + * Makefile.in (ISODELIB): Remove reference to $(ISODELIB). + +Wed Mar 1 16:29:19 1995 Theodore Y. Ts'o + + * configure.in: Remove ISODE_INCLUDE, replace check for -lsocket + and -lnsl with WITH_NETLIB check. + +Tue Feb 28 02:18:37 1995 John Gilmore (gnu at toad.com) + + * *.c: Avoid and includes. + +Tue Feb 14 15:30:55 1995 Chris Provenzano (proven@mit.edu) + + * kadmin.c Call krb5_sendauth() with new calling convention + +Fri Feb 10 17:50:39 1995 Theodore Y. Ts'o + + * kadmin_msnd.c: Remove needless #include of + +Mon Feb 06 17:19:04 1995 Chris Provenzano (proven@mit.edu) + + * kadmin.c: Removed krb5_keytype, changed krb5_enctype to + krb5_enctype *, changed krb5_preauthtype to krb5_preauthtype * + for krb5_get_in_tkt_with_password() rotuine. + +Fri Feb 3 03:03:27 1995 John Gilmore + + * kadmin.c (main): Real live non-kludged argument parsing. + Add -c option to specify ticket cache location (it really + should just use a cache in memory in the process, but that + isn't written yet). Make some error messages more explicit! + +Wed Jan 25 16:54:40 1995 Chris Provenzano (proven@mit.edu) + + * Removed all narrow types and references to wide.h and narrow.h + +Fri Jan 13 15:23:47 1995 Chris Provenzano (proven@mit.edu) + + * Added krb5_context to all krb5_routines + +Mon Oct 3 19:12:43 1994 Theodore Y. Ts'o (tytso@dcl) + + * Makefile.in: Use $(srcdir) to find manual page for make install. + +Thu Sep 29 22:39:10 1994 Theodore Y. Ts'o (tytso@dcl) + + * Makefile.in: relink executable if libraries change + +Thu Sep 15 16:49:19 1994 Theodore Y. Ts'o (tytso@dcl) + + * kadm_add.c (kadm_add_user): Don't chop off last character of + principal if it was supplied by the caller (instead of + prompting the user to enter a principal). + +Wed Sep 14 22:20:46 1994 Theodore Y. Ts'o (tytso@dcl) + + * kadmin_add.c (kadm_add_user): removed a duplicated + free(inbuf.data) call. + +Sat Jul 16 02:47:38 1994 Tom Yu (tlyu at dragons-lair) + + * kadmin.c (get_first_ticket): change error code to match + +Fri Jun 24 22:48:29 1994 Theodore Y. Ts'o (tytso at tsx-11) + + * kadmin_done (kadm_done): fix memory allocation bugs + + diff --git a/src/kadmin.old/client/Makefile.in b/src/kadmin.old/client/Makefile.in new file mode 100644 index 000000000..64140ed23 --- /dev/null +++ b/src/kadmin.old/client/Makefile.in @@ -0,0 +1,49 @@ +CFLAGS = $(CCOPTS) $(DEFS) $(LOCALINCLUDE) +LDFLAGS = -g + +COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a +SSLIB=$(BUILDTOP)/util/ss/libss.a +DBMLIB= +KDBLIB=$(TOPLIBD)/libkdb5.a + +all:: + +KLIB = $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(SSLIB) $(COMERRLIB) $(DBMLIB) +DEPKLIB = $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(SSLIB) $(COMERRLIB) $(DBMLIB) + +SRCS = \ + $(srcdir)/kadmin.c \ + $(srcdir)/kadmin_add.c \ + $(srcdir)/kadmin_adr.c \ + $(srcdir)/kadmin_cpr.c \ + $(srcdir)/kadmin_inq.c \ + $(srcdir)/kadmin_msnd.c \ + $(srcdir)/kadmin_mod.c \ + $(srcdir)/kadmin_cpw.c \ + $(srcdir)/kadmin_del.c \ + $(srcdir)/kadmin_done.c + +OBJS = \ + kadmin.o \ + kadmin_add.o \ + kadmin_adr.o \ + kadmin_cpr.o \ + kadmin_inq.o \ + kadmin_msnd.o \ + kadmin_mod.o \ + kadmin_cpw.o \ + kadmin_del.o \ + kadmin_done.o + +all:: kadmin + +kadmin: $(KDBDEPLIB) $(OBJS) $(DEPKLIB) + $(CC) $(CFLAGS) -o kadmin $(OBJS) $(KLIB) $(LIBS) + +install:: + $(INSTALL_PROGRAM) kadmin ${DESTDIR}$(CLIENT_BINDIR)/kadmin + $(INSTALL_DATA) $(srcdir)/kadmin.M ${DESTDIR}$(CLIENT_MANDIR)/kadmin.1 + +clean:: + $(RM) kadmin + diff --git a/src/kadmin.old/client/configure.in b/src/kadmin.old/client/configure.in new file mode 100644 index 000000000..55d33a6c8 --- /dev/null +++ b/src/kadmin.old/client/configure.in @@ -0,0 +1,10 @@ +AC_INIT(kadmin.c) +WITH_CCOPTS +CONFIG_RULES +AC_SET_BUILDTOP +AC_PROG_INSTALL +WITH_NETLIB +ET_RULES +KRB_INCLUDE +WITH_KRB5ROOT +V5_AC_OUTPUT_MAKEFILE diff --git a/src/kadmin.old/client/kadmin.M b/src/kadmin.old/client/kadmin.M new file mode 100644 index 000000000..180a1a958 --- /dev/null +++ b/src/kadmin.old/client/kadmin.M @@ -0,0 +1,2 @@ +.\" this file was somehow lost +.\" but CVS deals badly with 0 length files. diff --git a/src/kadmin.old/client/kadmin.c b/src/kadmin.old/client/kadmin.c new file mode 100644 index 000000000..397a7df0a --- /dev/null +++ b/src/kadmin.old/client/kadmin.c @@ -0,0 +1,725 @@ +/* + * kadmin/client/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. + */ + + +/* + * kadmin + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "com_err.h" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +#include "krb5.h" +#include "adm_defs.h" + +static krb5_error_code get_first_ticket + PROTOTYPE((krb5_context, + krb5_ccache, + krb5_principal, + krb5_creds *)); + +struct sockaddr_in local_sin, remote_sin; + +char cache_name[255] = ""; + +static void get_def_princ + PROTOTYPE((krb5_context, + krb5_principal * )); + +void decode_kadmind_reply(); +int print_status_message(); +extern char *optarg; +extern int optind; + + +void +main(argc,argv) + int argc; + char *argv[]; +{ + krb5_ccache cache = NULL; + + krb5_address local_addr, foreign_addr; + + krb5_principal client; + + char *client_name; /* Single string representation of client id */ + + krb5_data *requested_realm; + krb5_creds my_creds; + + krb5_error_code retval; /* return code */ + + int local_socket; + + krb5_error *err_ret; + krb5_ap_rep_enc_part *rep_ret; + + kadmin_requests rd_priv_resp; + + krb5_context context; + krb5_data msg_data, inbuf; + char buffer[255]; + char command_type[120]; + char princ_name[120]; + int i, valid; + int option; + int oper_type; + int nflag = 0; + int port = 0; + + krb5_auth_context * new_auth_context; + krb5_replay_data replaydata; + + krb5_init_context(&context); + krb5_init_ets(context); + + client_name = (char *) malloc(755); + memset((char *) client_name, 0, sizeof(client_name)); + + while ((option = getopt(argc, argv, "c:np:")) != EOF) { + switch (option) { + case 'c': + strcpy (cache_name, optarg); + break; + case 'n': + nflag++; + break; + case 'p': + port = htons(atoi(optarg)); + break; + case '?': + default: + usage(); + break; + } + } + + if (optind < argc) { + /* Admin name specified on command line */ + strcpy(client_name, argv[optind++]); + if (retval = krb5_parse_name(context, client_name, &client)) { + fprintf(stderr, "Error Parsing %s\n", client_name); + usage(); + } + } + else { + /* Admin name should be defaulted */ + get_def_princ(context, &client); + if (retval = krb5_unparse_name(context, client, &client_name)) { + fprintf(stderr, "Unable to unparse default administrator name!\n"); + usage(); + } + } + + /* At this point, both client and client_name are set up. */ + + if (!nflag) { + strcpy(client_name, client->data[0].data); + strncat(client_name, "/admin@", 7); + strncat(client_name, client->realm.data, client->realm.length); + if (retval = krb5_parse_name(context, client_name, &client)) { + fprintf(stderr, "Unable to Parse %s\n", client_name); + usage(); + } + } + + if (optind < argc) + usage(); + + /* Create credential cache for kadmin */ + if (!cache_name[0]) + (void) sprintf(cache_name, "FILE:/tmp/tkt_adm_%d", getpid()); + + if ((retval = krb5_cc_resolve(context, cache_name, &cache))) { + fprintf(stderr, "Unable to Resolve Cache: %s!\n", cache_name); + } + + if ((retval = krb5_cc_initialize(context, cache, client))) { + fprintf(stderr, "Error initializing cache: %s!\n", cache_name); + exit(1); + } + +/* + * Verify User by Obtaining Initial Credentials prior to Initial Link + */ + + if ((retval = get_first_ticket(context, cache, client, &my_creds))) { + (void) krb5_cc_destroy(context, cache); + exit(1); + } + /* my_creds has the necessary credentials for further processing: + Destroy credential cache for security reasons */ + (void) krb5_cc_destroy(context, cache); + + requested_realm = (krb5_data *) &client->realm; + + + /* Initiate Link to Server */ + if ((retval = adm5_init_link(context, requested_realm, port, + &local_socket))) { + (void) krb5_cc_destroy(context, cache); + exit(1); + } + +#ifdef unicos61 +#define SIZEOF_INADDR SIZEOF_in_addr +#else +#define SIZEOF_INADDR sizeof(struct in_addr) +#endif + +/* V4 kpasswd Protocol Hack + * Necessary for ALL kadmind clients + */ + { + int msg_length = 0; + + retval = krb5_net_write(context, local_socket, (char *) &msg_length + 2, 2); + if (retval < 0) { + fprintf(stderr, "krb5_net_write failure!\n"); + (void) krb5_cc_destroy(context, cache); + exit(1); + } + } + + local_addr.addrtype = ADDRTYPE_INET; + local_addr.length = SIZEOF_INADDR ; + local_addr.contents = (krb5_octet *) &local_sin.sin_addr; + + foreign_addr.addrtype = ADDRTYPE_INET; + foreign_addr.length = SIZEOF_INADDR ; + foreign_addr.contents = (krb5_octet *) &remote_sin.sin_addr; + + krb5_auth_con_init(context, &new_auth_context); + krb5_auth_con_setflags(context, new_auth_context, + KRB5_AUTH_CONTEXT_RET_SEQUENCE); + + krb5_auth_con_setaddrs(context, new_auth_context, + &local_addr, &foreign_addr); + + /* call Kerberos library routine to obtain an authenticator, + pass it over the socket to the server, and obtain mutual + authentication. */ + + inbuf.data = ADM5_ADM_VERSION; + inbuf.length = strlen(ADM5_ADM_VERSION); + + if ((retval = krb5_sendauth(context, &new_auth_context, + (krb5_pointer) &local_socket, + ADM_CPW_VERSION, + my_creds.client, + my_creds.server, + AP_OPTS_MUTUAL_REQUIRED, + &inbuf, + &my_creds, + 0, + &err_ret, + &rep_ret, + NULL))) { + fprintf(stderr, "Error while performing sendauth: %s!\n", + error_message(retval)); + exit(1); + } + + /* Read back what the server has to say ... */ + if (retval = krb5_read_message(context, &local_socket, &inbuf)){ + fprintf(stderr, " Read Message Error: %s!\n", + error_message(retval)); + exit(1); + } + + if ((inbuf.length != 2) || (inbuf.data[0] != KADMIND) || + (inbuf.data[1] != KADMSAG)){ + fprintf(stderr, " Invalid ack from admin server.!\n"); + exit(1); + } + free(inbuf.data); + + if ((inbuf.data = (char *) calloc(1, 2)) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + exit(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = 0xff; + inbuf.length = 2; + + if ((retval = krb5_mk_priv(context, new_auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during First Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + exit(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, &local_socket, &msg_data)){ + fprintf(stderr, "Write Error During First Message Transmission!\n"); + exit(1); + } + free(msg_data.data); + + for ( ; ; ) { + /* Ok Now let's get the private message */ + if (retval = krb5_read_message(context, &local_socket, &inbuf)){ + fprintf(stderr, "Read Error During First Reply: %s!\n", + error_message(retval)); + exit(1); + } + + if ((retval = krb5_rd_priv(context, new_auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during First Read Decoding: %s!\n", + error_message(retval)); + exit(1); + } + free(inbuf.data); + + valid = 0; + princ_name[0] = '\0'; +repeat: + printf("\n\nCommand (add, cpw, del, inq, mod, addrnd, cpwrnd, addv4, cpwv4, q): "); + fgets(buffer, sizeof(buffer), stdin); + buffer[strlen(buffer) -1] = '\0'; + sscanf(buffer,"%s %s", command_type, princ_name); + for (i = 0; command_type[i] != '\0'; i++) + if (isupper(command_type[i])) + command_type[i] = tolower(command_type[i]); + + if (!strcmp(command_type, "add")) { + valid++; + oper_type = ADDOPER; + if (retval = kadm_add_user(context, new_auth_context, &my_creds, + &local_socket, oper_type, princ_name)) + break; + } + if (!strcmp(command_type, "cpw")) { + valid++; + oper_type = CHGOPER; + if (retval = kadm_cpw_user(context, new_auth_context, &my_creds, + &local_socket, oper_type, princ_name)) + break; + } + if (!strcmp(command_type, "addrnd")) { + valid++; + if (retval = kadm_add_user_rnd(context, new_auth_context, &my_creds, + &local_socket, princ_name)) + break; + } + if (!strcmp(command_type, "cpwrnd")) { + valid++; + if (retval = kadm_cpw_user_rnd(context, new_auth_context, &my_creds, + &local_socket, princ_name)) + break; + } + if (!strcmp(command_type, "del")) { + valid++; + if (retval = kadm_del_user(context, new_auth_context, &my_creds, + &local_socket, princ_name)) + break; + } + if (!strcmp(command_type, "inq")) { + valid++; + if (retval = kadm_inq_user(context, new_auth_context, &my_creds, + &local_socket, princ_name)) + break; + } + if (!strcmp(command_type, "mod")) { + valid++; + if (retval = kadm_mod_user(context, new_auth_context, &my_creds, + &local_socket, princ_name)) + break; + } + if (!strcmp(command_type, "addv4")) { + valid++; + oper_type = AD4OPER; + if (retval = kadm_add_user(context, new_auth_context, &my_creds, + &local_socket, oper_type, princ_name)) + break; + } + if (!strcmp(command_type, "cpwv4")) { + valid++; + oper_type = CH4OPER; + if (retval = kadm_cpw_user(context, new_auth_context, &my_creds, + &local_socket, oper_type, princ_name)) + break; + } + if (!strcmp(command_type, "q")) { + valid++; + retval = kadm_done(context, new_auth_context, &my_creds, + &local_socket); + break; + } + + if (!valid) { + fprintf(stderr, "Invalid Input - Retry\n"); + goto repeat; + } + } + + if (retval) { + exit(1); + } + + /* Ok Now let's get the final private message */ + if (retval = krb5_read_message(context, &local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Final Reply: %s!\n", + error_message(retval)); + exit(1); + } + + if ((retval = krb5_rd_priv(context, new_auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Final Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + exit(1); + } + free(inbuf.data); + + decode_kadmind_reply(msg_data, &rd_priv_resp); + free(msg_data.data); + + if (!((rd_priv_resp.appl_code == KADMIN) && + (rd_priv_resp.retn_code == KADMGOOD))) { + if (rd_priv_resp.message) + fprintf(stderr, "%s\n", rd_priv_resp.message); + else + fprintf(stderr, "Generic Error During kadmin Termination!\n"); + retval = 1; + } else { + fprintf(stderr, "\nHave a Good Day.\n\n"); + } + + if (rd_priv_resp.message) + free(rd_priv_resp.message); + + + exit(retval); +} + +static krb5_error_code +get_first_ticket(context, cache, client, my_creds) + krb5_context context; + krb5_ccache cache; + krb5_principal client; + krb5_creds * my_creds; +{ + char prompt[255]; /* for the password prompt */ + + krb5_address **my_addresses; + + char *client_name; + krb5_error_code retval; + char *password; + int pwsize; + int i; + + if ((retval = krb5_unparse_name(context, client, &client_name))) { + fprintf(stderr, "Unable to Unparse Client Name!\n"); + return(1); + } + + if ((retval = krb5_os_localaddr(&my_addresses))) { + fprintf(stderr, "Unable to Get Principals Address!\n"); + return(1); + } + + memset((char *) my_creds, 0, sizeof(krb5_creds)); + + my_creds->client = client; + + if ((retval = krb5_build_principal_ext(context, &my_creds->server, + client->realm.length, + client->realm.data, + strlen(CPWNAME), + CPWNAME, /* kadmin */ + client->realm.length, + client->realm.data, + /* instance is */ + 0))) { + fprintf(stderr, "Error %s while building client name!\n", + error_message(retval)); + krb5_free_addresses(context, my_addresses); + return(1); + } + + (void) sprintf(prompt,"Password for %s: ", (char *) client_name); + + if ((password = (char *) calloc (1, 255)) == NULL) { + fprintf(stderr, "No Memory for Retrieving Admin Password!\n"); + return(1); + } + + pwsize = 255; + if ((retval = krb5_read_password(context, + prompt, + 0, + password, + &pwsize) || pwsize == 0)) { + fprintf(stderr, "Error while reading password for '%s'!\n", + client_name); + free(password); + krb5_free_addresses(context, my_addresses); + return(1); + } + + /* Build Request for Initial Credentials */ + retval = krb5_get_in_tkt_with_password(context, 0, /* options */ + my_addresses, + NULL, /* Default encryption list */ + NULL, /* Default preauth list */ + password, cache, my_creds, 0); + + /* Do NOT Forget to zap password */ + memset((char *) password, 0, pwsize); + free(password); + krb5_free_addresses(context, my_addresses); + + if (retval) { + fprintf(stderr, "\nUnable to Get Initial Credentials: %s!\n", + error_message(retval)); + return(1); + } + + return(0); +} + +krb5_error_code +adm5_init_link(context, realm_of_server, port, local_socket) + krb5_context context; + krb5_data *realm_of_server; + int port; + int * local_socket; +{ + struct servent *service_process; /* service we will talk to */ + struct hostent *remote_host; /* host we will talk to */ + char **hostlist; + int namelen; + int i; + + krb5_error_code retval; + + /* clear out the structure first */ + (void) memset((char *)&remote_sin, 0, sizeof(remote_sin)); + + if (port != 0) { + remote_sin.sin_port = port; + } else { + if ((service_process = getservbyname(CPW_SNAME, "tcp")) == NULL) { + fprintf(stderr, "Unable to find Service (%s) Check services file!\n", + CPW_SNAME); + return(1); + } + + /* Copy the Port Number */ + remote_sin.sin_port = service_process->s_port; + } + + hostlist = 0; + + /* Identify all Hosts Associated with this Realm */ + if ((retval = krb5_get_krbhst (context, realm_of_server, &hostlist))) { + fprintf(stderr, "krb5_get_krbhst: Unable to Determine Server Name!\n"); + return(retval); + } + + if (hostlist[0] == 0) { + fprintf(stderr, "No hosts found!\n"); + return KRB5_REALM_UNKNOWN; + } + + for (i=0; hostlist[i]; i++) { + remote_host = gethostbyname(hostlist[i]); + if (remote_host != 0) { + + /* set up the address of the foreign socket for connect() */ + remote_sin.sin_family = remote_host->h_addrtype; + (void) memcpy((char *) &remote_sin.sin_addr, + (char *) remote_host->h_addr, + sizeof(remote_host->h_addr)); + break; /* Only Need one */ + } + } + + krb5_free_krbhst(context, hostlist); + + /* open a TCP socket */ + *local_socket = socket(PF_INET, SOCK_STREAM, 0); + if (*local_socket < 0) { + retval = errno; + fprintf(stderr, "Cannot Open Socket!\n"); + return retval; + } + /* connect to the server */ + if (connect(*local_socket, &remote_sin, sizeof(remote_sin)) < 0) { + retval = errno; + fprintf(stderr, "Cannot Connect to Socket!\n"); + close(*local_socket); + return retval; + } + + /* find out who I am, now that we are connected and therefore bound */ + namelen = sizeof(local_sin); + if (getsockname(*local_socket, + (struct sockaddr *) &local_sin, &namelen) < 0) { + retval = errno; + fprintf(stderr, "Cannot Perform getsockname!\n"); + close(*local_socket); + return retval; + } + return 0; +} + +static void +get_def_princ(context, client) + krb5_context context; + krb5_principal *client; +{ + krb5_ccache cache = NULL; + struct passwd *pw; + int retval; + char client_name[755]; + krb5_flags cc_flags; + + /* Identify Default Credentials Cache */ + if (retval = krb5_cc_default(context, &cache)) { + fprintf(stderr, "Error while getting default ccache!\n"); + exit(1); + } + + /* + * Attempt to Modify Credentials Cache + * retval == 0 ==> ccache Exists - Use It + * retval == ENOENT ==> No Entries, but ccache Exists + * retval != 0 ==> Assume ccache does NOT Exist + */ + cc_flags = 0; + if (retval = krb5_cc_set_flags(context, cache, cc_flags)) { + /* Search passwd file for client */ + pw = getpwuid((int) getuid()); + if (pw) { + (void) strcpy(client_name, pw->pw_name); + if (!strncmp("root", client_name, strlen(client_name))) { + fprintf(stderr, + "root is not a valid Adimnistrator\n!\n"); + usage(); + } + } else { + fprintf(stderr, + "Unable to Identify Principal from Password File!\n"); + retval = 1; + usage(); + } + + /* Use this to get default_realm and format client_name */ + if ((retval = krb5_parse_name(context, client_name, client))) { + fprintf(stderr, "Unable to Parse Client Name!\n"); + usage(); + } + } else { + /* Read Client from Cache */ + if (retval = krb5_cc_get_principal(context, cache, client)) { + fprintf(stderr, + "Unable to Read Principal Credentials File!\n"); + exit(1); + } + + if (!strncmp("root", (*client)->data[0].data, + (*client)->data[0].length)) { + fprintf(stderr, "root is not a valid Administrator\n!\n"); + usage(); + } + + (void) krb5_cc_close(context, cache); + } +} + +usage() +{ + fprintf(stderr, "Usage: "); + fprintf(stderr, "kadmin [-n] [-p port] [Administrator name]\n\n"); + fprintf(stderr, " If an Administrator name is not supplied, kadmin "); + fprintf(stderr, "will first\n attempt to locate the name from "); + fprintf(stderr, "the default ticket file, then\n by using the "); + fprintf(stderr, "username from the 'passwd' file.\n\n"); + fprintf(stderr, " For Cross Realm Obtain a ticket for 'Administrator "); + fprintf(stderr, "name' in the\n Destination realm or "); + fprintf(stderr, "specify the Destination Realm\n as part of the "); + fprintf(stderr, "Administrator name option.\n\n"); + fprintf(stderr, " Note: If the Administrator Name is not "); + fprintf(stderr, "supplied, then the \n"); + fprintf(stderr, " '/admin' instance will be appended to the "); + fprintf(stderr, "default name unless\n"); + fprintf(stderr, " the -n option is used.\n\n"); + exit(0); +} + +void decode_kadmind_reply(data, response) + krb5_data data; + kadmin_requests *response; +{ + response->appl_code = data.data[0]; + response->oper_code = data.data[1]; + response->retn_code = data.data[2]; + if (data.length > 3 && data.data[3]) { + response->message = (char *)malloc(data.length - 2); + if (response->message) { + memcpy(response->message, data.data + 3, data.length - 3); + response->message[data.length - 3] = 0; + } + } else + response->message = NULL; + + return; +} + +int print_status_message(response, success_msg) + kadmin_requests *response; + char *success_msg; +{ + int retval = 1; + + if (response->appl_code == KADMIN) { + if (response->retn_code == KADMGOOD) { + fprintf(stderr, "%s\n", success_msg); + retval = 0; + } else if (response->retn_code == KADMBAD) + fprintf(stderr, "%s\n", response->message); + else + fprintf(stderr, "ERROR: unknown return code from server.\n"); + } else + fprintf(stderr, "ERROR: unknown application code from server.\n"); + + if (response->message) + free(response->message); + + return retval; +} diff --git a/src/kadmin.old/client/kadmin_add.c b/src/kadmin.old/client/kadmin_add.c new file mode 100644 index 000000000..c04eca844 --- /dev/null +++ b/src/kadmin.old/client/kadmin_add.c @@ -0,0 +1,236 @@ +/* + * kadmin/client/kadmin_add.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. + */ + + +/* + * kadmin_add + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include "com_err.h" + +#include + +#include "k5-int.h" +#include "adm_defs.h" + +void decode_kadmind_reply(); +int print_status_message(); + +krb5_error_code +kadm_add_user(context, auth_context, my_creds, local_socket, + oper_type, principal) + krb5_context context; + krb5_auth_context * auth_context; + krb5_creds * my_creds; + int * local_socket; + int oper_type; + char * principal; +{ + krb5_data msg_data, inbuf; + kadmin_requests rd_priv_resp; + char username[255]; + char *password; + int pwsize; + int count; + krb5_replay_data replaydata; + krb5_error_code retval; /* return code */ + + if ((inbuf.data = (char *) calloc(1, 3 + sizeof(username))) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + return(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = oper_type; + inbuf.data[2] = SENDDATA2; + + if (principal && principal[0] != '\0') + strcpy(username, principal); + else { + count = 0; + do { + fprintf(stdout, "\nName of Principal to be Added: "); + fgets(username, sizeof(username), stdin); + if (username[0] == '\n') + fprintf(stderr, "Invalid Principal name!\n"); + count++; + } while (username[0] == '\n' && count < 3); + + if (username[0] == '\n') { + fprintf(stderr, "Aborting!!\n\n"); + return(1); + } + + username[strlen(username) -1] = '\0'; + } + + (void) memcpy( inbuf.data + 3, username, strlen(username)); + inbuf.length = strlen(username) + 3; + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + + free(msg_data.data); + + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Second Reply: %s!\n", + error_message(retval)); + return(1); + } + + if (retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + fprintf(stderr, "Error during Second Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + if (msg_data.data[2] == KADMBAD) { + decode_kadmind_reply(msg_data, &rd_priv_resp); + + if (rd_priv_resp.message) { + fprintf(stderr, "%s\n\n", rd_priv_resp.message); + free(rd_priv_resp.message); + } else + fprintf(stderr, "Generic error from server.\n\n"); + return(0); + } + +#ifdef MACH_PASS + pwsize = msg_data.length; + if ((password = (char *) calloc (1, pwsize)) == (char *) 0) { + fprintf(stderr, "No Memory for allocation of password!\n"); + retval = 1; + free(msg_data.data); + return(1); + } + + memcpy(password, msg_data.data, pwsize); + memset(msg_data.data, 0, pwsize); + password[pwsize] = '\0'; + fprintf(stdout, "\nPassword for \"%s\" is \"%s\"\n", username, password); + memset(password, 0, pwsize); + free(password); + fprintf(stdout, "\nThis password can only be used to execute kpasswd\n\n"); + + free(msg_data.data); + + if ((inbuf.data = (char *) calloc(1, 2)) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + return(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = KADMGOOD; + inbuf.length = 2; + +#else + + if ((password = (char *) calloc (1, ADM_MAX_PW_LENGTH+1)) == (char *) 0) { + fprintf(stderr, "No Memory for allocation of password!\n"); + return(1); + } + + pwsize = ADM_MAX_PW_LENGTH+1; + + putchar('\n'); + if (retval = krb5_read_password(context, + DEFAULT_PWD_STRING1, + DEFAULT_PWD_STRING2, + password, + &pwsize)) { + fprintf(stderr, "Error while reading new password for %s: %s!\n", + username, error_message(retval)); + (void) memset((char *) password, 0, ADM_MAX_PW_LENGTH+1); + free(password); + return(1); + } + + if ((inbuf.data = (char *) calloc(1, strlen(password) + 1)) == (char *) 0) { + fprintf(stderr, "No Memory for allocation of buffer!\n"); + (void) memset((char *) password, 0, ADM_MAX_PW_LENGTH+1); + free(password); + return(1); + } + + inbuf.length = strlen(password); + (void) memcpy(inbuf.data, password, strlen(password)); + free(password); + +#endif /* MACH_PASS */ + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the final private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Final Reply: %s!\n", + error_message(retval)); + retval = 1; + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Final Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + decode_kadmind_reply(msg_data, &rd_priv_resp); + + free(msg_data.data); + + retval = print_status_message(&rd_priv_resp, + "Database Addition Successful."); + + return(retval); +} diff --git a/src/kadmin.old/client/kadmin_adr.c b/src/kadmin.old/client/kadmin_adr.c new file mode 100644 index 000000000..9a4cea7f8 --- /dev/null +++ b/src/kadmin.old/client/kadmin_adr.c @@ -0,0 +1,129 @@ +/* + * kadmin/client/kadmin_adr.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. + */ + + +/* + * kadmin_adr + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "adm_defs.h" + +void decode_kadmind_reply(); +int print_status_message(); + +krb5_error_code +kadm_add_user_rnd(context, auth_context, my_creds, + local_socket, seqno, principal) + krb5_context context; + krb5_auth_context *auth_context; + int *local_socket; + krb5_int32 *seqno; + char *principal; +{ + krb5_data msg_data, inbuf; + kadmin_requests rd_priv_resp; + char username[755]; + int count; + krb5_replay_data replaydata; + krb5_error_code retval; /* return code */ + + if ((inbuf.data = (char *) calloc(1, 3 + sizeof(username))) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + return(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = ADROPER; + inbuf.data[2] = SENDDATA2; + + if (principal && principal[0] != '\0') + strcpy(username, principal); + else { + count = 0; + do { + fprintf(stdout, "\nName of Principal to be Added: "); + fgets(username, sizeof(username), stdin); + if (username[0] == '\n') + fprintf(stderr, "Invalid Principal name!\n"); + count++; + } + while (username[0] == '\n' && count < 3); + + if (username[0] == '\n') { + fprintf(stderr, "Aborting!!\n\n"); + return(1); + } + username[strlen(username) -1] = '\0'; + } + + + (void) memcpy( inbuf.data + 3, username, strlen(username)); + inbuf.length = strlen(username) + 3; + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + + free(msg_data.data); + + /* Ok Now let's get the final private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Final Reply: %s!\n", + error_message(retval)); + retval = 1; + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Final Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + + decode_kadmind_reply(msg_data, &rd_priv_resp); + + free(inbuf.data); + free(msg_data.data); + + retval = print_status_message(&rd_priv_resp, + "Database Addition Successful."); + + return(retval); +} diff --git a/src/kadmin.old/client/kadmin_cpr.c b/src/kadmin.old/client/kadmin_cpr.c new file mode 100644 index 000000000..ee0b946b6 --- /dev/null +++ b/src/kadmin.old/client/kadmin_cpr.c @@ -0,0 +1,132 @@ +/* + * kadmin/client/kadmin_cpr.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. + */ + + +/* + * kadmin_cpr + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "adm_defs.h" + +void decode_kadmind_reply(); +int print_status_message(); + +krb5_error_code +kadm_cpw_user_rnd(context, auth_context, my_creds, + local_socket, seqno, principal) + krb5_context context; + krb5_auth_context *auth_context; + int *local_socket; + krb5_int32 *seqno; + char *principal; +{ + krb5_data msg_data, inbuf; + kadmin_requests rd_priv_resp; + char username[755]; + int count; + krb5_replay_data replaydata; + krb5_error_code retval; /* return code */ + + if ((inbuf.data = (char *) calloc(1, 3 + sizeof(username))) == (char *) 0) { fprintf(stderr, "No memory for command!\n"); + exit(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = CHROPER; + inbuf.data[2] = SENDDATA2; + + if (principal && principal[0] != '\0') + strcpy(username, principal); + else { + count = 0; + do { + fprintf(stdout, + "\nName of Principal Whose Password is to Change: "); + fgets(username, sizeof(username), stdin); + if (username[0] == '\n') + fprintf(stderr, "Invalid Principal name!\n"); + count++; + } + while (username[0] == '\n' && count < 3); + + if (username[0] == '\n') { + fprintf(stderr, "Aborting!!\n\n"); + return(1); + } + username[strlen(username) -1] = '\0'; + } + + (void) memcpy( inbuf.data + 3, username, strlen(username)); + inbuf.length = strlen(username) + 3; + + /* Transmit Principal Name */ + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the final private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Final Reply: %s!\n", + error_message(retval)); + retval = 1; + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Final Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + decode_kadmind_reply(msg_data, &rd_priv_resp); + + free(inbuf.data); + free(msg_data.data); + + print_status_message(&rd_priv_resp, + "Password Modification Successful."); + + return(0); +} + + diff --git a/src/kadmin.old/client/kadmin_cpw.c b/src/kadmin.old/client/kadmin_cpw.c new file mode 100644 index 000000000..5705b9f5e --- /dev/null +++ b/src/kadmin.old/client/kadmin_cpw.c @@ -0,0 +1,246 @@ +/* + * kadmin/client/kadmin_cpw.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. + */ + + +/* + * kadmin_cpw + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "adm_defs.h" + +void decode_kadmind_reply(); +int print_status_message(); + +krb5_error_code +kadm_cpw_user(context, auth_context, my_creds, + local_socket, oper_type, principal) + krb5_context context; + krb5_auth_context *auth_context; + int *local_socket; + int oper_type; + char *principal; +{ + krb5_data msg_data, inbuf; + kadmin_requests rd_priv_resp; + char username[255]; + char *password; + int pwsize; + int count; + krb5_replay_data replaydata; + krb5_error_code retval; /* return code */ + + if ((inbuf.data = (char *) calloc(1, 3 + sizeof(username))) == (char *) 0) { fprintf(stderr, "No memory for command!\n"); + exit(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = oper_type; + inbuf.data[2] = SENDDATA2; + + if (principal && principal[0] != '\0') + strcpy(username, principal); + else { + count = 0; + do { + fprintf(stdout, + "\nName of Principal Whose Password is to Change: "); + fgets(username, sizeof(username), stdin); + if (username[0] == '\n') + fprintf(stderr, "Invalid Principal name!\n"); + count++; + } + while (username[0] == '\n' && count < 3); + + if (username[0] == '\n') { + fprintf(stderr, "Aborting!!\n\n"); + return(1); + } + + username[strlen(username) -1] = '\0'; + } + + (void) memcpy( inbuf.data + 3, username, strlen(username)); + inbuf.length = strlen(username) + 3; + + /* Transmit Principal Name */ + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + free(msg_data.data); + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Second Reply: %s!\n", + error_message(retval)); + return(1); + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + if (msg_data.data[2] == KADMBAD) { + decode_kadmind_reply(msg_data, &rd_priv_resp); + + if (rd_priv_resp.message) { + fprintf(stderr, "%s\n\n", rd_priv_resp.message); + free(rd_priv_resp.message); + } else + fprintf(stderr, "Generic error from server.\n\n"); + memset(msg_data.data, 0, msg_data.length); + free(msg_data.data); + return(0); + } + + if ((oper_type == CHGOPER && msg_data.data[3] == KRB5_KDB_SALTTYPE_V4) || + (oper_type == CH4OPER && msg_data.data[3] == KRB5_KDB_SALTTYPE_NORMAL)) + fprintf(stderr, "WARNING: Changing Principal Salt type to %s!\n", + (msg_data.data[3] == KRB5_KDB_SALTTYPE_V4) ? + "Version 5 Normal" : "Version 4"); + +#ifdef MACH_PASS /* Machine-generated passwords */ + pwsize = msg_data.length; + if ((password = (char *) calloc (1, pwsize)) == (char *) 0) { + fprintf(stderr, "No Memory for allocation of password!\n"); + memset(msg_data.data, 0, msg_data.length); + free(msg_data.data); + return(1); + } + + memcpy(password, msg_data.data, pwsize); + memset(msg_data.data, 0, pwsize); + free(msg_data.data); + password[pwsize] = '\0'; + fprintf(stdout, "\nPassword for \"%s\" is \"%s\"\n", username, password); + memset(password, 0, pwsize); + free(password); + fprintf(stdout, "\nThis password can only be used to execute kpasswd\n\n"); + + if ((inbuf.data = (char *) calloc(1, 2)) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + return(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = KADMGOOD; + inbuf.length = 2; + +#else + + if ((password = (char *) calloc (1, ADM_MAX_PW_LENGTH+1)) == (char *) 0) { + fprintf(stderr, "No Memory for allocation of password!\n"); + return(1); + } + + pwsize = ADM_MAX_PW_LENGTH+1; + + putchar('\n'); + if ((retval = krb5_read_password(context, + DEFAULT_PWD_STRING1, + DEFAULT_PWD_STRING2, + password, + &pwsize))) { + fprintf(stderr, "Error while reading new password for %s: %s!\n", + username, error_message(retval)); + (void) memset((char *) password, 0, ADM_MAX_PW_LENGTH+1); + free(password); + return(1); + } + + if ((inbuf.data = (char *) calloc (1, strlen(password) + 1)) == + (char *) 0) { + fprintf(stderr, "No Memory for allocation of buffer!\n"); + (void) memset((char *) password, 0, ADM_MAX_PW_LENGTH+1); + free(password); + return(1); /* No Memory */ + } + + inbuf.length = strlen(password); + (void) memcpy(inbuf.data, password, strlen(password)); + free(password); + +#endif /* MACH_PASS */ + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the final private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Final Reply: %s!\n", + error_message(retval)); + retval = 1; + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Final Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + + decode_kadmind_reply(msg_data, &rd_priv_resp); + + free(inbuf.data); + free(msg_data.data); + + print_status_message(&rd_priv_resp, + "Password Modification Successful."); + + return(0); +} diff --git a/src/kadmin.old/client/kadmin_del.c b/src/kadmin.old/client/kadmin_del.c new file mode 100644 index 000000000..1753f007c --- /dev/null +++ b/src/kadmin.old/client/kadmin_del.c @@ -0,0 +1,124 @@ +/* + * kadmin/client/kadmin_del.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. + */ + + +/* + * kadmin_del + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "adm_defs.h" + +void decode_kadmind_reply(); +int print_status_message(); + +krb5_error_code +kadm_del_user(context, auth_context, my_creds, local_socket, principal) + krb5_context context; + krb5_auth_context *auth_context; + int *local_socket; + char *principal; +{ + krb5_data msg_data, inbuf; + kadmin_requests rd_priv_resp; + char username[755]; + int count; + krb5_replay_data replaydata; + krb5_error_code retval; /* return code */ + + if ((inbuf.data = (char *) calloc(1, 3 + sizeof(username))) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + return(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = DELOPER; + inbuf.data[2] = SENDDATA2; + + if (principal && principal[0] != '\0') + strcpy(username, principal); + else { + count = 0; + do { + fprintf(stdout, "\nName of Principal to be Deleted: "); + fgets(username, sizeof(username), stdin); + if (username[0] == '\n') + fprintf(stderr, "Invalid Principal name!\n"); + count++; + } + while (username[0] == '\n' && count < 3); + + if (username[0] == '\n') { + fprintf(stderr, "Aborting!!\n\n"); + return(1); + } + + username[strlen(username) -1] = '\0'; + } + + (void) memcpy( inbuf.data + 3, username, strlen(username)); + inbuf.length = strlen(username) + 3; + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + free(msg_data.data); + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the final private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Final Reply: %s!\n", + error_message(retval)); + return(1); + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Decoding :%s!\n", + error_message(retval)); + return(1); + } + + decode_kadmind_reply(msg_data, &rd_priv_resp); + + free(inbuf.data); + free(msg_data.data); + + print_status_message(&rd_priv_resp, + "Database Deletion Successful."); + + return(0); +} diff --git a/src/kadmin.old/client/kadmin_done.c b/src/kadmin.old/client/kadmin_done.c new file mode 100644 index 000000000..7f3f7bb94 --- /dev/null +++ b/src/kadmin.old/client/kadmin_done.c @@ -0,0 +1,70 @@ +/* + * kadmin/client/kadmin_done.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. + */ + + +/* + * kadmin_done + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "adm_defs.h" + +krb5_error_code +kadm_done(context, auth_context, my_creds, local_socket, seqno) + krb5_context context; + krb5_auth_context *auth_context; + int *local_socket; + krb5_int32 *seqno; +{ + krb5_replay_data replaydata; + krb5_data msg_data, inbuf; + krb5_error_code retval; /* return code */ + char buf[16]; + + inbuf.data = buf; + + inbuf.data[0] = KADMIN; + inbuf.data[1] = COMPLETE; + inbuf.data[2] = SENDDATA2; + inbuf.data[3] = 0xff; + (void) memset( inbuf.data + 4, 0, 4); + inbuf.length = 16; + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + return(1); + } + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)) { + free(msg_data.data); + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + return(0); +} diff --git a/src/kadmin.old/client/kadmin_inq.c b/src/kadmin.old/client/kadmin_inq.c new file mode 100644 index 000000000..374455b7c --- /dev/null +++ b/src/kadmin.old/client/kadmin_inq.c @@ -0,0 +1,198 @@ +/* + * kadmin/client/kadmin_inq.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. + */ + + +/* + * kadmin_inq + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "adm_defs.h" + +void decode_kadmind_reply(); +int print_status_message(); + +krb5_error_code +kadm_inq_user(context, auth_context, my_creds, local_socket, principal) + krb5_context context; + krb5_auth_context *auth_context; + int *local_socket; + char *principal; +{ + krb5_replay_data replaydata; + krb5_data msg_data, inbuf; + kadmin_requests rd_priv_resp; + char username[755]; + int count; + krb5_error_code retval; /* return code */ + char *my_data; + + if ((inbuf.data = (char *) calloc(1, 3 + sizeof(username))) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + return(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = INQOPER; + inbuf.data[2] = SENDDATA2; + + if (principal && principal[0] != '\0') + strcpy(username, principal); + else { + count = 0; + do { + fprintf(stdout, "\nName of Principal to be Displayed: "); + fgets(username, sizeof(username), stdin); + if (username[0] == '\n') + fprintf(stderr, "Invalid Principal name!\n"); + count++; + } + while (username[0] == '\n' && count < 3); + + if (username[0] == '\n') { + fprintf(stderr, "Aborting!!\n\n"); + return(1); + } + + username[strlen(username) -1] = '\0'; + } + + (void) memcpy( inbuf.data + 3, username, strlen(username)); + inbuf.length = strlen(username) + 3; + + if (retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the private message */ + if ((retval = krb5_read_message(context, local_socket, &inbuf))){ + fprintf(stderr, "Read Error During Second Reply: %s!\n", + error_message(retval)); + return(1); + } + + if (retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + fprintf(stderr, "Error during Second Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + if (!msg_data.data) { + fprintf(stderr, "kadm_inq_user: Error - empty message received!\n\n"); + return(0); + } + + if (msg_data.data[2] == KADMBAD) { + decode_kadmind_reply(msg_data, &rd_priv_resp); + + if (rd_priv_resp.message) { + fprintf(stderr, "%s\n\n", rd_priv_resp.message); + free(rd_priv_resp.message); + } else + fprintf(stderr, "Generic error from server.\n\n"); + return(0); + } + + my_data = (char *)malloc(msg_data.length + 1); + if (!my_data) { + fprintf(stderr, "kadmin_inq: Couldn't allocate space for my_data!\n"); + exit(1); + } + memcpy(my_data, msg_data.data, msg_data.length); + my_data[msg_data.length] = 0; + + /* Print Inquiry Information */ + fprintf(stdout, "%s\n", my_data); + free(my_data); + free(msg_data.data); + + if ((inbuf.data = (char *) calloc(1, 3)) == (char *) 0) { + fprintf(stderr, "inbuf.data allocation error!\n"); + return(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = KADMGOOD; + inbuf.length = 2; + + if (retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + free(msg_data.data); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the final private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Final Reply: %s!\n", + error_message(retval)); + retval = 1; + } + + if (retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata)) { + fprintf(stderr, "Error during Final Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + decode_kadmind_reply(msg_data, &rd_priv_resp); + + free(inbuf.data); + free(msg_data.data); + + print_status_message(&rd_priv_resp, + "Password Inquiry Successful."); + + return(0); +} diff --git a/src/kadmin.old/client/kadmin_mod.c b/src/kadmin.old/client/kadmin_mod.c new file mode 100644 index 000000000..e7d565413 --- /dev/null +++ b/src/kadmin.old/client/kadmin_mod.c @@ -0,0 +1,185 @@ +/* + * kadmin/client/kadmin_mod.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. + */ + + +/* + * kadmin_mod + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "adm_defs.h" + +void decode_kadmind_reply(); +int print_status_message(); + +krb5_error_code +kadm_mod_user(context, auth_context, my_creds, local_socket, principal) + krb5_context context; + krb5_auth_context *auth_context; + krb5_creds *my_creds; + int *local_socket; + char *principal; +{ + krb5_data msg_data, inbuf; + kadmin_requests rd_priv_resp; + char username[755]; + int count; + krb5_replay_data replaydata; + krb5_error_code retval; /* return code */ + + if ((inbuf.data = (char *) calloc(1, 3 + sizeof(username))) == (char *) 0) { fprintf(stderr, "No memory for command!\n"); + exit(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = MODOPER; + inbuf.data[2] = SENDDATA2; + + if (principal && principal[0] != '\0') + strcpy(username, principal); + else { + count = 0; + do { + fprintf(stdout, "\nName of Principal to be Modified: "); + fgets(username, sizeof(username), stdin); + if (username[0] == '\n') + fprintf(stderr, "Invalid Principal name!\n"); + count++; + } + while (username[0] == '\n' && count < 3); + + if (username[0] == '\n') { + fprintf(stderr, "Aborting!!\n\n"); + return(1); + } + + username[strlen(username) -1] = '\0'; + } + + (void) memcpy( inbuf.data + 3, username, strlen(username)); + inbuf.length = strlen(username) + 3; + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Second Reply: %s!\n", + error_message(retval)); + return(1); + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + if (msg_data.data[2] == KADMBAD) { + decode_kadmind_reply(msg_data, &rd_priv_resp); + + if (rd_priv_resp.message) { + fprintf(stderr, "%s\n\n", rd_priv_resp.message); + free(rd_priv_resp.message); + } else + fprintf(stderr, "Generic error from server.\n\n"); + free(msg_data.data); + return(0); + } + free(msg_data.data); + + kadm_snd_mod(context, auth_context, my_creds, local_socket); + + if ((inbuf.data = (char *) calloc(1, 2)) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + return(1); + } + + + inbuf.data[0] = KADMIN; + inbuf.data[1] = KADMGOOD; + inbuf.data[2] = SENDDATA3; + inbuf.length = 3; + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + free(msg_data.data); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the final private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Final Reply: %s!\n", + error_message(retval)); + retval = 1; + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Final Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + + + decode_kadmind_reply(msg_data, &rd_priv_resp); + + free(inbuf.data); + free(msg_data.data); + + print_status_message(&rd_priv_resp, + "Database Modification Successful."); + + return(0); +} diff --git a/src/kadmin.old/client/kadmin_msnd.c b/src/kadmin.old/client/kadmin_msnd.c new file mode 100644 index 000000000..7887e435e --- /dev/null +++ b/src/kadmin.old/client/kadmin_msnd.c @@ -0,0 +1,273 @@ +/* + * kadmin/client/kadmin_msnd.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. + */ + + +/* + * kadmin_snd_mod + * Perform Remote Kerberos Administrative Functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include "adm_defs.h" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +krb5_error_code +kadm_snd_mod(context, auth_context, my_creds, local_socket) + krb5_context context; + krb5_auth_context *auth_context; + krb5_creds *my_creds; + int *local_socket; +{ + krb5_replay_data replaydata; + krb5_error_code retval; /* return code */ + krb5_data msg_data, inbuf; + char mod_type[10]; + char attrib[20]; + char version[10]; + int value; + int valid_command; + int i; + + for ( ; ; ) { + valid_command = 0; +repeat1: +#ifdef SANDIA + fprintf(stdout, "\nParameter Type to be Modified (fcnt, vno, attr, or q): "); +#else + fprintf(stdout, "\nParameter Type to be Modified (vno, attr, or q): "); +#endif + + (void) fgets(mod_type, 10, stdin); + mod_type[strlen(mod_type) - 1] = '\0'; + + if ((inbuf.data = (char *) calloc(1, 80)) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + exit(1); + } + + if (!strcmp(mod_type, "q")) { + free(inbuf.data); + goto alldone; + } +#ifdef SANDIA + if (!strcmp(mod_type, "fcnt")) { + valid_command = 1; +repeat_cnt: + fprintf(stdout, "\nFailure Count: "); + (void) fgets(version, sizeof(version), stdin); + /* Make sure version is null terminated */ + version[sizeof(version) -1] = '\0'; + /* Strip linefeed */ + if (version[strlen(version) - 1] == '\n') + version[strlen(version) - 1] = '\0'; + if (!strcmp(version, "q")) { + free(inbuf.data); + goto alldone; + } + value = -1; + sscanf(version,"%d",&value); + if (value < 0 || value > 10 ) { + fprintf(stderr, "Value must be between 0 and 10!\n"); + goto repeat_cnt; + } + inbuf.data[3] = KMODFCNT; + (void) memcpy(inbuf.data + 4, version, strlen(version)); + inbuf.length = strlen(version) + 4; + } +#endif + if (!strcmp(mod_type, "vno")) { + valid_command = 1; +repeat2: + fprintf(stdout, "\nVersion Number: "); + (void) fgets(version, sizeof(version), stdin); + /* Make sure version is null terminated */ + version[sizeof(version) -1] = '\0'; + /* Strip linefeed */ + if (version[strlen(version) - 1] == '\n') + version[strlen(version) - 1] = '\0'; + if (!strcmp(version, "q")) { + free(inbuf.data); + goto alldone; + } + value = -1; + sscanf(version,"%d",&value); + if (value < 0 || value > 255 ) { + fprintf(stderr, "Value must be between 0 and 255!\n"); + goto repeat2; + } + inbuf.data[3] = KMODVNO; + (void) memcpy(inbuf.data + 4, version, strlen(version)); + inbuf.length = strlen(version) + 4; + } + + if (!strcmp(mod_type, "attr")) { + valid_command = 1; +repeat3: + fprintf(stdout, "\nAttribute: "); + fgets(attrib, 20, stdin); + attrib[strlen(attrib) - 1] = '\0'; + for (i = 0; attrib[i] != '\0'; i++) + if (isupper(attrib[i])) + attrib[i] = tolower(attrib[i]); + + inbuf.data[3] = KMODATTR; + inbuf.data[4] = BADATTR; + inbuf.length = 5; + if (!strcmp(attrib, "post")) inbuf.data[4] = ATTRPOST; + if (!strcmp(attrib, "nopost")) inbuf.data[4] = ATTRNOPOST; + if (!strcmp(attrib, "forward")) inbuf.data[4] = ATTRFOR; + if (!strcmp(attrib, "noforward")) inbuf.data[4] = ATTRNOFOR; + if (!strcmp(attrib, "tgt")) inbuf.data[4] = ATTRTGT; + if (!strcmp(attrib, "notgt")) inbuf.data[4] = ATTRNOTGT; + if (!strcmp(attrib, "ren")) inbuf.data[4] = ATTRREN; + if (!strcmp(attrib, "noren")) inbuf.data[4] = ATTRNOREN; + if (!strcmp(attrib, "proxy")) inbuf.data[4] = ATTRPROXY; + if (!strcmp(attrib, "noproxy")) inbuf.data[4] = ATTRNOPROXY; + if (!strcmp(attrib, "dskey")) inbuf.data[4] = ATTRDSKEY; + if (!strcmp(attrib, "nodskey")) inbuf.data[4] = ATTRNODSKEY; + if (!strcmp(attrib, "lock")) inbuf.data[4] = ATTRLOCK; + if (!strcmp(attrib, "unlock")) inbuf.data[4] = ATTRUNLOCK; + if (!strcmp(attrib, "svr")) inbuf.data[4] = ATTRSVR; + if (!strcmp(attrib, "nosvr")) inbuf.data[4] = ATTRNOSVR; + +#ifdef SANDIA + if (!strcmp(attrib, "preauth")) inbuf.data[4] = ATTRPRE; + if (!strcmp(attrib, "nopreauth")) inbuf.data[4] = ATTRNOPRE; + if (!strcmp(attrib, "pwok")) inbuf.data[4] = ATTRPWOK; + if (!strcmp(attrib, "pwchange")) inbuf.data[4] = ATTRPWCHG; + if (!strcmp(attrib, "sid")) inbuf.data[4] = ATTRSID; + if (!strcmp(attrib, "nosid")) inbuf.data[4] = ATTRNOSID; +#endif + if (!strcmp(attrib, "q")){ + free(inbuf.data); + goto alldone; + } + if (inbuf.data[4] == BADATTR) { + fprintf(stderr, "Valid Responses are:\n"); + fprintf(stderr, "post/nopost - Allow/Disallow postdating\n"); + fprintf(stderr, "forward/noforward - Allow/Disallow forwarding\n"); + fprintf(stderr, "tgt/notgt - Allow/Disallow initial tickets\n"); + fprintf(stderr, "ren/noren - Allow/Disallow renewable tickets\n"); + fprintf(stderr, + "proxy/noproxy - Allow/Disallow proxiable tickets\n"); + fprintf(stderr, + "dskey/nodskey - Allow/Disallow Duplicate Session Keys\n"); + fprintf(stderr, "lock/unlock - Lock/Unlock client\n"); + fprintf(stderr, + "svr/nosvr - Allow/Disallow Use of Principal as Server\n"); +#ifdef SANDIA + fprintf(stderr, + "preauth/nopreauth - Require/Do Not Require preauthentication\n"); + fprintf(stderr, + "pwok/pwchange - Password is OK/Needs to be changed\n"); + fprintf(stderr, + "sid/nosid - Require/Do Not Require Hardware Authentication\n"); +#endif + fprintf(stderr, "q - Quit from setting attributes.\n"); + goto repeat3; + } + } + + if (!valid_command) { + free(inbuf.data); + fprintf(stderr, "Invalid command - Try Again\n"); + goto repeat1; + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = MODOPER; + inbuf.data[2] = SENDDATA3; + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)) { + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + /* Ok Now let's get the private message */ + if (retval = krb5_read_message(context, local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Second Reply: %s!\n", + error_message(retval)); + return(1); + } + + if ((retval = krb5_rd_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Read Decoding :%s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + } /* for */ + +alldone: + if ((inbuf.data = (char *) calloc(1, 80)) == (char *) 0) { + fprintf(stderr, "No memory for command!\n"); + exit(1); + } + + inbuf.data[0] = KADMIN; + inbuf.data[1] = KADMGOOD; + inbuf.data[2] = SENDDATA3; + inbuf.length = 3; + + if ((retval = krb5_mk_priv(context, auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + free(inbuf.data); + return(1); + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, local_socket, &msg_data)) { + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + return(1); + } + free(msg_data.data); + + return(0); +} diff --git a/src/kadmin.old/configure.in b/src/kadmin.old/configure.in new file mode 100644 index 000000000..b242db084 --- /dev/null +++ b/src/kadmin.old/configure.in @@ -0,0 +1,10 @@ +AC_INIT(configure.in) +WITH_CCOPTS +AC_SET_BUILDTOP +CONFIG_DIRS(client kpasswd server) +MAKE_SUBDIRS("making",all) +MAKE_SUBDIRS("cleaning",clean) +MAKE_SUBDIRS("installing",install) +CONFIG_RULES +WITH_KRB5ROOT +V5_AC_OUTPUT_MAKEFILE diff --git a/src/kadmin.old/kpasswd/.Sanitize b/src/kadmin.old/kpasswd/.Sanitize new file mode 100644 index 000000000..5975c4d0a --- /dev/null +++ b/src/kadmin.old/kpasswd/.Sanitize @@ -0,0 +1,39 @@ +# 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 +configure +configure.in +kpasswd.M +kpasswd.c +networked.c + +Things-to-lose: + +Do-last: + +# End of file. diff --git a/src/kadmin.old/kpasswd/.cvsignore b/src/kadmin.old/kpasswd/.cvsignore new file mode 100644 index 000000000..e8c05a6b1 --- /dev/null +++ b/src/kadmin.old/kpasswd/.cvsignore @@ -0,0 +1 @@ +configure diff --git a/src/kadmin.old/kpasswd/ChangeLog b/src/kadmin.old/kpasswd/ChangeLog new file mode 100644 index 000000000..506f7ffbe --- /dev/null +++ b/src/kadmin.old/kpasswd/ChangeLog @@ -0,0 +1,76 @@ +Fri Mar 17 15:36:07 1995 Chris Provenzano (proven@mit.edu) + + * kpasswd.c: Cast malloc() return value to shut compiler up. + +Fri Mar 10 11:09:34 1995 Chris Provenzano (proven@mit.edu) + + * kpasswd.c: Use new calling convention for krb5_sendauth(), + krb5_mk_priv(), and krb5_rd_priv(). + +Thu Mar 2 12:25:29 1995 Theodore Y. Ts'o + + * Makefile.in (ISODELIB): Remove reference to $(ISODELIB). + +Wed Mar 1 16:29:34 1995 Theodore Y. Ts'o + + * configure.in: Remove ISODE_INCLUDE, replace check for -lsocket + and -lnsl with WITH_NETLIB check. + +Tue Feb 28 02:21:41 1995 John Gilmore (gnu at toad.com) + + * kpasswd.c: Avoid includes. + +Tue Feb 14 15:30:55 1995 Chris Provenzano (proven@mit.edu) + + * kpasswd.c: Call krb5_sendauth(), krb5_get_credentials() + with new calling convention. + +Fri Feb 10 17:48:05 1995 Theodore Y. Ts'o + + * kpasswd.c: Don't include ; use . + +Mon Feb 06 17:19:04 1995 Chris Provenzano (proven@mit.edu) + + * kpasswd.c Removed krb5_keytype, changed krb5_enctype to + krb5_enctype *, changed krb5_preauthtype to krb5_preauthtype * + for krb5_get_in_tkt_with_password() rotuine. + +Wed Jan 25 16:54:40 1995 Chris Provenzano (proven@mit.edu) + + * Removed all narrow types and references to wide.h and narrow.h + +Fri Jan 13 15:23:47 1995 Chris Provenzano (proven@mit.edu) + + * Added krb5_context to all krb5_routines + +Tue Dec 27 06:09:03 1994 Richard Basch (probe@tardis) + + * configure.in: + combined KRB5_UTPID, KRB5_UTTYPE, and KRB5_UTHOST + into CHECK_UTMP macro (and added additional checks) + +Fri Nov 18 01:08:39 1994 Mark Eichin + + * configure.in: use new macros KRB5_UTPID, KRB5_UTTYPE, and + KRB5_UTHOST (from epeisach). + +Wed Oct 19 12:18:26 1994 Theodore Y. Ts'o (tytso@dcl) + + * Makefile.in: Look for man page in the source directory. + +Fri Sep 30 22:30:21 1994 Theodore Y. Ts'o (tytso@dcl) + + * kpasswd.c: Add placeholders for magic numbers + +Thu Sep 29 22:40:10 1994 Theodore Y. Ts'o (tytso@dcl) + + * Makefile.in: relink executable if libraries change + +Tue Aug 9 21:42:02 1994 Tom Yu (tlyu@dragons-lair) + + * networked.c: yet another utent fix + +Sat Jul 16 02:51:25 1994 Tom Yu (tlyu at dragons-lair) + + * kpasswd.c (get_first_ticket): fix error codes + diff --git a/src/kadmin.old/kpasswd/Makefile.in b/src/kadmin.old/kpasswd/Makefile.in new file mode 100644 index 000000000..12e218a40 --- /dev/null +++ b/src/kadmin.old/kpasswd/Makefile.in @@ -0,0 +1,34 @@ +CFLAGS = $(CCOPTS) $(DEFS) $(LOCALINCLUDE) +LDFLAGS = -g + +COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a +SSLIB=$(BUILDTOP)/util/ss/libss.a +DBMLIB= +KDBLIB=$(TOPLIBD)/libkdb5.a + +all:: + +KLIB = $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(SSLIB) $(COMERRLIB) $(DBMLIB) +DEPKLIB = $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(SSLIB) $(COMERRLIB) $(DBMLIB) + +SRCS = \ + $(srcdir)/networked.c \ + $(srcdir)/kpasswd.c + +OBJS = \ + networked.o \ + kpasswd.o + + +all:: kpasswd + +kpasswd: $(KDBDEPLIB) $(OBJS) $(DEPKLIB) + $(CC) $(CFLAGS) -o kpasswd $(OBJS) $(KLIB) $(LIBS) + +install:: + $(INSTALL_PROGRAM) kpasswd ${DESTDIR}$(CLIENT_BINDIR)/kpasswd + $(INSTALL_DATA) $(srcdir)/kpasswd.M ${DESTDIR}$(CLIENT_MANDIR)/kpasswd.1 + +clean:: + $(RM) kpasswd + diff --git a/src/kadmin.old/kpasswd/configure.in b/src/kadmin.old/kpasswd/configure.in new file mode 100644 index 000000000..54b6bb7af --- /dev/null +++ b/src/kadmin.old/kpasswd/configure.in @@ -0,0 +1,13 @@ +AC_INIT(kpasswd.c) +WITH_CCOPTS +CONFIG_RULES +AC_SET_BUILDTOP +AC_PROG_INSTALL +WITH_NETLIB +AC_HAVE_HEADERS(unistd.h) +CHECK_UTMP +AC_FUNC_CHECK(getutent,AC_DEFINE(HAVE_GETUTENT)) +ET_RULES +KRB_INCLUDE +WITH_KRB5ROOT +V5_AC_OUTPUT_MAKEFILE diff --git a/src/kadmin.old/kpasswd/kpasswd.M b/src/kadmin.old/kpasswd/kpasswd.M new file mode 100644 index 000000000..f4e625896 --- /dev/null +++ b/src/kadmin.old/kpasswd/kpasswd.M @@ -0,0 +1 @@ +.\" this should not be empty diff --git a/src/kadmin.old/kpasswd/kpasswd.c b/src/kadmin.old/kpasswd/kpasswd.c new file mode 100644 index 000000000..5b1a182d0 --- /dev/null +++ b/src/kadmin.old/kpasswd/kpasswd.c @@ -0,0 +1,824 @@ +/* + * kadmin/kpasswd/kpasswd.c + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * change your password with kerberos + */ + +/* + * 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. + */ + + +/* + * kpasswd + * change your password with Version 5 Kerberos + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "krb5.h" +#ifdef USE_STRING_H +#include +#else +#include +#endif +#include "com_err.h" +#include "adm_defs.h" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +static krb5_error_code adm5_init_link + PROTOTYPE((krb5_context, + krb5_data *, + int *)); + +static krb5_error_code get_first_ticket + PROTOTYPE((krb5_context, + krb5_ccache, + krb5_principal, + krb5_creds *)); + +krb5_error_code print_and_choose_password + PROTOTYPE((char *, krb5_data *)); + +struct sockaddr_in local_sin, remote_sin; + + +extern char *krb5_default_pwd_prompt1; + +main(argc,argv) + int argc; + char *argv[]; +{ + krb5_context context; + krb5_ccache cache = NULL; + char cache_name[255]; + krb5_flags cc_flags; + + krb5_address local_addr, foreign_addr; + + struct passwd *pw; + + krb5_principal client; + + char default_name[256]; + char *client_name; /* Single string representation of client id */ + + krb5_data requested_realm; + + char input_string[768]; + + krb5_error_code retval; /* return code */ + + int local_socket; + + krb5_error *err_ret; + krb5_ap_rep_enc_part *rep_ret; + + kadmin_requests rd_priv_resp; + + krb5_data msg_data, inbuf; + krb5_int32 seqno; + + krb5_creds my_creds, * new_creds; + char *new_password; + int new_pwsize; + + krb5_auth_context * new_auth_context; + krb5_replay_data replaydata; + +#ifdef SANDIA + extern int networked(); + int krb_secure; + struct stat statbuf; +#endif /* SANDIA */ + +#ifdef SANDIA /* Allow or Disallow Remote Clients to Modify Passwords */ +/* + * If a Client Modifies a Password using kpasswd on this host + * from a remote host or network terminal, the Password selected + * is transmitted across the network in Cleartext. + * + * The systems administrator can disallow "remote" kpasswd usage by + * creating the file "/etc/krb.secure" + */ + + krb_secure = 0; +/* + * First check to see if the file /etc/krb.secure exists. + * If it does then krb_secure to 1. + */ + + if (stat("/etc/krb.secure", &statbuf) == 0) krb_secure = 1; + +/* + * Check to see if this process is tied to a physical terminal. + * Network() verifies the terminal device is not a pseudo tty + */ + if (networked() && krb_secure) { + fprintf(stderr,"Sorry but you cannot %s from a\n", argv[0]); + fprintf(stderr," pseudo tty terminal!\n"); + retval = 1; + goto finish; + } +#endif + + /* (3 * 255) + 1 (/) + 1 (@) + 1 (NULL) */ + if ((client_name = (char *) calloc (1, (3 * 256))) == NULL) { + fprintf(stderr, "No Memory for Client_name!\n"); + retval = 1; + goto finish; + } + + if ((requested_realm.data = (char *) calloc (1, 256)) == NULL) { + fprintf(stderr, "No Memory for realm_name!\n"); + retval = 1; + free(client_name); + goto finish; + } + + krb5_init_context(&context); + krb5_init_ets(context); + memset((char *) default_name, 0, sizeof(default_name)); + + switch (argc) { + case 1: /* No User Specified */ + + /* Identify Default Credentials Cache */ + if ((retval = krb5_cc_default(context, &cache))) { + fprintf(stderr, "Error while getting default ccache!\n"); + goto finish; + } + +/* + * Attempt to Modify Credentials Cache + * retval == 0 ==> ccache Exists - Use It + * retval == ENOENT ==> No Entries, but ccache Exists + * retval != 0 ==> Assume ccache does NOT Exist + */ + cc_flags = 0; + if ((retval = krb5_cc_set_flags(context, cache, cc_flags))) { + /* Search passwd file for client */ + pw = getpwuid((int) getuid()); + if (pw) { + (void) strcpy(default_name, pw->pw_name); + } else { + fprintf(stderr, + "Unable to Identify Customer from Password File!\n"); + retval = 1; + goto finish; + } + + /* Use this to get default_realm and format client_name */ + if ((retval = krb5_parse_name(context,default_name, &client))) { + fprintf(stderr, "Unable to Parse Client Name!\n"); + goto finish; + } + + if ((retval = krb5_unparse_name(context,client,&client_name))) { + fprintf(stderr, "Unable to Parse Client Name!\n"); + goto finish; + } + + requested_realm.length = client->realm.length; + memcpy((char *) requested_realm.data, + (char *) client->realm.data, + requested_realm.length); + } else { + /* Read Client from Cache */ + if ((retval = krb5_cc_get_principal(context, cache, + (krb5_principal *) &client))) { + fprintf(stderr, + "Unable to Read Customer Credentials File!\n"); + goto finish; + } + + if ((retval = krb5_unparse_name(context,client,&client_name))) { + fprintf(stderr, "Unable to Parse Client Name!\n"); + goto finish; + } + + requested_realm.length = client->realm.length; + memcpy((char *) requested_realm.data, + (char *) client->realm.data, + requested_realm.length); + + (void) krb5_cc_close(context, cache); + } + break; + + case 2: /* Client Gave us a Token - Use it */ + /* Hand Parse Entry */ + strcpy(input_string, argv[1]); + + if (retval = krb5_parse_name(context, input_string, &client)) { + fprintf(stderr, "Error Parsing -u option contents!\n"); + exit(0); + } + requested_realm.length = client->realm.length; + memcpy((char *) requested_realm.data, + (char *) client->realm.data, + requested_realm.length); + + break; + + default: + usage(); + break; + } + + /* Create credential cache for changepw */ + (void) sprintf(cache_name, "FILE:/tmp/tkt_cpw_%d", getpid()); + + if ((retval = krb5_cc_resolve(context, cache_name, &cache))) { + fprintf(stderr, "Unable to Resolve Cache: %s\n", cache_name); + } + + if ((retval = krb5_cc_initialize(context, cache, client))) { + fprintf(stderr, "Error initializing cache: %s\n", cache_name); + goto finish; + } + +/* + * Verify User by Obtaining Initial Credentials prior to Initial Link + */ + + if ((retval = get_first_ticket(context, cache, client, &my_creds))) { + goto finish; + } + + /* Initiate Link to Server */ + if ((retval = adm5_init_link(context, &requested_realm, &local_socket))) { + goto finish; + } + +#ifdef unicos61 +#define SIZEOF_INADDR SIZEOF_in_addr +#else +#define SIZEOF_INADDR sizeof(struct in_addr) +#endif + + /* V4 kpasswd Protocol Hack */ + { + int msg_length = 0; + + retval = krb5_net_write(context, local_socket, (char *) &msg_length + 2, 2); + if (retval < 0) { + fprintf(stderr, "krb5_net_write failure!\n"); + goto finish; + } + + } + + local_addr.addrtype = ADDRTYPE_INET; + local_addr.length = SIZEOF_INADDR ; + local_addr.contents = (krb5_octet *)&local_sin.sin_addr; + + foreign_addr.addrtype = ADDRTYPE_INET; + foreign_addr.length = SIZEOF_INADDR ; + foreign_addr.contents = (krb5_octet *)&remote_sin.sin_addr; + + krb5_auth_con_init(context, &new_auth_context); + krb5_auth_con_setflags(context, new_auth_context, + KRB5_AUTH_CONTEXT_RET_SEQUENCE); + + krb5_auth_con_setaddrs(context, new_auth_context, + &local_addr, &foreign_addr); + + /* call Kerberos library routine to obtain an authenticator, + pass it over the socket to the server, and obtain mutual + authentication. */ + + inbuf.data = ADM_CPW_VERSION; + inbuf.length = strlen(ADM_CPW_VERSION); + + if ((retval = krb5_sendauth(context, &new_auth_context, + (krb5_pointer) &local_socket, + ADM_CPW_VERSION, + my_creds.client, + my_creds.server, + AP_OPTS_MUTUAL_REQUIRED, + &inbuf, + NULL, + cache, + &err_ret, + &rep_ret, NULL))) { + fprintf(stderr, "Error while performing sendauth: %s!\n", + error_message(retval)); + goto finish; + } + + /* Get credentials : to use for safe and private messages */ + /* No need to pass my_creds because it's uninizialized. */ + if (retval = krb5_get_credentials(context,0,cache,&my_creds,&new_creds)){ + fprintf(stderr, "Error Obtaining Credentials: %s!\n", + error_message(retval)); + goto finish; + } + + /* Read back what the server has to say... */ + + if (retval = krb5_read_message(context, &local_socket, &inbuf)){ + fprintf(stderr, " Read Message Error: %s!\n", + error_message(retval)); + goto finish; + } + if ((inbuf.length != 2) || (inbuf.data[0] != KADMIND) || + (inbuf.data[1] != KADMSAG)){ + fprintf(stderr, " Invalid ack from admin server.\n"); + goto finish; + } + + inbuf.length = 2; + inbuf.data[0] = KPASSWD; + inbuf.data[1] = CHGOPER; + if ((retval = krb5_mk_priv(context, new_auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during First Message Encoding: %s!\n", + error_message(retval)); + goto finish; + } + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, &local_socket, &msg_data)){ + fprintf(stderr, "Write Error During First Message Transmission!\n"); + retval = 1; + goto finish; + } + free(msg_data.data); + +#ifdef MACH_PASS /* Machine-generated Passwords */ + /* Ok Now let's get the private message */ + if (retval = krb5_read_message(context, &local_socket, &inbuf)){ + fprintf(stderr, "Read Error During First Reply: %s!\n", + error_message(retval)); + retval = 1; + goto finish; + } + + if ((retval = krb5_rd_priv(context, new_auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during First Read Decoding: %s!\n", + error_message(retval)); + goto finish; + } + free(inbuf.data); +#endif + + if ((new_password = (char *) calloc (1, ADM_MAX_PW_LENGTH+1)) == NULL) { + fprintf(stderr, "Unable to Allocate Space for New Password!\n"); + goto finish; + } + +#ifdef MACH_PASS /* Machine-generated passwords */ + /* Offer Client Password Choices */ + if ((retval = print_and_choose_password(new_password, + &msg_data))) { + (void) memset((char *) new_password, 0, ADM_MAX_PW_LENGTH+1); + free(new_password); + goto finish; + } +#else + new_pwsize = ADM_MAX_PW_LENGTH+1; + putchar('\n'); + if ((retval = krb5_read_password(context, + "Enter new password: ", + "Re-enter new password for verification: ", + new_password, + &new_pwsize))) { + fprintf(stderr, "Error while reading new password for '%s'", + client_name); + (void) memset((char *) new_password, 0, ADM_MAX_PW_LENGTH+1); + free(new_password); + goto finish; + } + if (new_pwsize == 0) { + fprintf(stderr, "A null password is not allowed!\n"); + free(new_password); + goto finish; + } +#endif + + inbuf.data = new_password; + inbuf.length = strlen(new_password); + + if ((retval = krb5_mk_priv(context, new_auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Message Encoding: %s!\n", + error_message(retval)); + goto finish; + } + memset(inbuf.data,0,inbuf.length); + free(inbuf.data); + + /* write private message to server */ + if (krb5_write_message(context, &local_socket, &msg_data)){ + fprintf(stderr, "Write Error During Second Message Transmission!\n"); + retval = 1; + goto finish; + } + free(msg_data.data); + + /* Ok Now let's get the private message */ + if (retval = krb5_read_message(context, &local_socket, &inbuf)){ + fprintf(stderr, "Read Error During Second Reply: %s!\n", + error_message(retval)); + retval = 1; + goto finish; + } + + if ((retval = krb5_rd_priv(context, new_auth_context, &inbuf, + &msg_data, &replaydata))) { + fprintf(stderr, "Error during Second Read Decoding :%s!\n", + error_message(retval)); + goto finish; + } + + rd_priv_resp.appl_code = msg_data.data[0]; + rd_priv_resp.oper_code = msg_data.data[1]; + rd_priv_resp.retn_code = msg_data.data[2]; + if (msg_data.length > 3 && msg_data.data[3]) { + rd_priv_resp.message = (char *)malloc(msg_data.length - 2); + if (rd_priv_resp.message) { + memcpy(rd_priv_resp.message, msg_data.data + 3, + msg_data.length - 3); + rd_priv_resp.message[msg_data.length - 3] = 0; + } + } else + rd_priv_resp.message = NULL; + + + free(inbuf.data); + free(msg_data.data); + if (rd_priv_resp.appl_code == KPASSWD) { + if (rd_priv_resp.retn_code == KPASSGOOD) + printf("\n\nPassword changed.\n\n"); + else if (rd_priv_resp.retn_code == KPASSBAD) { + if (rd_priv_resp.message) + fprintf(stderr, "%s\n", rd_priv_resp.message); + else + fprintf(stderr, "Server returned KPASSBAD.\n"); + } else + fprintf(stderr, "Server returned unknown kerberos code.\n"); + } else + fprintf(stderr, "Server returned bad application code %d\n", + rd_priv_resp.appl_code); + + if (rd_priv_resp.message) + free(rd_priv_resp.message); + + finish: + + (void) krb5_cc_destroy(context, cache); + + free(client_name); + free(requested_realm.data); + + if (retval) { + fprintf(stderr, "\n\nProtocol Failure - Password NOT changed\n\n"); + exit(1); + } + + printf("\n\nPassword changed.\n\n"); + + exit(0); +} + + + +krb5_data cpwname = { + 0, + sizeof(CPWNAME)-1, + CPWNAME +}; + +static krb5_error_code +get_first_ticket(context, cache, client, my_creds) + krb5_context context; + krb5_ccache cache; + krb5_principal client; + krb5_creds *my_creds; +{ + char prompt[255]; /* for the password prompt */ + char pword[ADM_MAX_PW_LENGTH+1]; /* storage for the password */ + char *old_password; + int old_pwsize; + int i; + + krb5_address **my_addresses; + + char *client_name; + krb5_error_code retval; + + if ((retval = krb5_unparse_name(context, client, &client_name))) { + fprintf(stderr, "Unable to Unparse Client Name\n"); + return(1); + } + + (void) sprintf(prompt,"Old password for %s: ", (char *) client_name); + + if ((retval = krb5_os_localaddr(&my_addresses))) { + fprintf(stderr, "Unable to Get Customers Address\n"); + return(1); + } + + memset((char *) my_creds, 0, sizeof(krb5_creds)); + + my_creds->client = client; + + if ((retval = krb5_build_principal_ext(context, &my_creds->server, + client->realm.length, + client->realm.data, + cpwname.length, /* 6 */ + cpwname.data, /* "kadmin" */ + client->realm.length, + /* instance is local realm */ + client->realm.data, + 0))) { + fprintf(stderr, "Error %s while building server name\n", + error_message(retval)); + return(1); + } + + + if ((old_password = (char *) calloc (1, 255)) == NULL) { + fprintf(stderr, "No Memory for Retrieving old password\n"); + return(1); + } + + old_pwsize = 255; + if ((retval = krb5_read_password(context, + prompt, + 0, + old_password, + &old_pwsize))) { + fprintf(stderr, "Error while reading password for '%s'", + client_name); + return(1); + } + + retval = krb5_get_in_tkt_with_password(context, 0,/* options */ + my_addresses, + NULL, /* Default encryption list */ + NULL, /* Default preauth list */ + old_password, cache, my_creds, 0); + + if (retval) { + fprintf(stderr, "\nUnable to Get Initial Credentials : %s %d\n", + error_message(retval),retval); + } + + /* Do NOT Forget to zap password */ + memset((char *) old_password, 0, old_pwsize); + free(old_password); + memset((char *) pword, 0, sizeof(pword)); + return(retval); +} + +#ifdef MACH_PASS /* Machine-generated Passwords */ +krb5_error_code +print_and_choose_password(new_password, decodable_pwd_string) + char * new_password; + krb5_data * decodable_pwd_string; +{ +krb5_error_code retval; + krb5_pwd_data *pwd_data; + passwd_phrase_element **next_passwd_phrase_element; + char prompt[255]; + int i, j, k; + int legit_pswd = 0; /* Assume No Legitimate Password */ + char *password_list[ADM_MAX_PW_CHOICES]; + char verification_passwd[ADM_MAX_PW_LENGTH+1]; + /* char new_passwd[ADM_MAX_PW_LENGTH]; */ + char phrase_in[ADM_MAX_PHRASE_LENGTH]; + int new_passwd_length; + char *ptr; + int verify = 0; /* Do Not Request Password Selection Verification */ + int ok = 0; + +#define free_local_password_list() \ +{ for ( k = 0; k < i && k < ADM_MAX_PW_CHOICES; k++) { \ + (void) memset(password_list[k], 0, ADM_MAX_PW_LENGTH); \ + free(password_list[k]); } \ +} + + /* Decode Password and Phrase Information Obtained from krb5_rd_priv */ + if ((retval = decode_krb5_pwd_data(decodable_pwd_string , &pwd_data))) { + fprintf(stderr, "Unable to Decode Passwords and Phrases\n"); + fprintf(stderr, " Notify your System Administrator or the "); + fprintf(stderr, "Kerberos Administrator\n"); + return(1); + } + + next_passwd_phrase_element = pwd_data->element; + /* Display List in 5 Password/Phrase Increments up to MAX Iterations */ + memset((char *) phrase_in, 0, ADM_MAX_PHRASE_LENGTH); + for ( j = 0; j <= ADM_MAX_PW_ITERATIONS; j++) { + if (j == ADM_MAX_PW_ITERATIONS) { + fprintf(stderr, "\n\nSorry - You Have Exceeded the List of "); + fprintf(stderr, "Choices (%d) Allowed for Password\n", + ADM_MAX_PW_ITERATIONS * ADM_MAX_PW_CHOICES); + fprintf(stderr, " Modification. You Must Repeat this "); + fprintf(stderr, "Operation in order to Successfully\n"); + fprintf(stderr, " Change your Password.\n"); + break; + } + + display_print: + printf("\n\nChoose a password from the following list:\n"); + + printf("\n\nPassword Remembrance Aid\n\n\n"); + + /* Print Passwords and Assistance Phrases List */ + for ( i = 0; i < ADM_MAX_PW_CHOICES; i++){ + if ((password_list[i] = (char *) calloc (1, + ADM_MAX_PW_LENGTH + 1)) == NULL) { + fprintf(stderr, "Unable to Allocate Password List.\n"); + return(1); + } + + memcpy(password_list[i], + (*next_passwd_phrase_element)->passwd->data, + (*next_passwd_phrase_element)->passwd->length); + printf("%s ", password_list[i]); + + memcpy((char *) phrase_in, + (*next_passwd_phrase_element)->phrase->data, + (*next_passwd_phrase_element)->phrase->length); + for ( k = 0; + k < 50 && k < (*next_passwd_phrase_element)->phrase->length; + k++) { + printf("%c", phrase_in[k]); + } + for ( k = k; + k < 70 && k < (*next_passwd_phrase_element)->phrase->length; + k++) { + if (phrase_in[k] == ' ') { + printf("\n "); + k++; + break; + } else { + printf("%c", phrase_in[k]); + } + } + for ( k = k; + k < (*next_passwd_phrase_element)->phrase->length; + k++) { + printf("%c", phrase_in[k]); + } + printf("\n\n"); + memset((char *) phrase_in, 0, ADM_MAX_PHRASE_LENGTH); + next_passwd_phrase_element++; + } + + sprintf(prompt, + "\n\nEnter Password Selection or a to get new list: "); + + new_passwd_length = ADM_MAX_PW_LENGTH+1; + /* Read New Password from Terminal (Do Not Print on Screen) */ + if ((retval = krb5_read_password(context, &prompt[0], 0, + new_password, &new_passwd_length))) { + fprintf(stderr, + "\nError Reading Password Input or Input Aborted\n"); + free_local_password_list(); + break;; + } + + /* Check for ==> Provide a New List */ + if (new_passwd_length == 0) continue; + + /* Check that Selection is from List - Server also does this */ + legit_pswd = 0; + for (i = 0; i < ADM_MAX_PW_CHOICES && !legit_pswd; i++) + if ((retval = memcmp(new_password, + password_list[i], 8)) == 0) { + legit_pswd++; + } + free_local_password_list(); + + if (!(legit_pswd)) { + printf("\n\07\07Password must be from the specified list "); + printf("- Try Again!\n"); + } + + if (legit_pswd) break; /* Exit Loop */ + } /* ADM_MAX_PW_CHOICES Loop */ + + if (!(legit_pswd)) return (1); + + return(0); /* SUCCESS */ +} +#endif + +static krb5_error_code +adm5_init_link(context, realm_of_server, local_socket) + krb5_context context; + krb5_data *realm_of_server; + int * local_socket; +{ + struct servent *service_process; /* service we will talk to */ + struct hostent *remote_host; /* host we will talk to */ + + char **hostlist; + + int host_count; + int namelen; + int i, count; + + krb5_error_code retval; + + /* clear out the structure first */ + (void) memset((char *)&remote_sin, 0, sizeof(remote_sin)); + + if ((service_process = getservbyname(CPW_SNAME, "tcp")) == NULL) { + fprintf(stderr, "Unable to find Service (%s) Check services file\n", + CPW_SNAME); + return(1); + } + + /* Copy the Port Number */ + remote_sin.sin_port = service_process->s_port; + + hostlist = 0; + + /* Identify all Hosts Associated with this Realm */ + if ((retval = krb5_get_krbhst (context, realm_of_server, &hostlist))) { + fprintf(stderr, "krb5_get_krbhst: Unable to Determine Server Name\n"); + return(1); + } + + for (i=0; hostlist[i]; i++); + + count = i; + + if (count == 0) { + host_count = 0; + fprintf(stderr, "No hosts found\n"); + return(1); + } + + for (i=0; hostlist[i]; i++) { + remote_host = gethostbyname(hostlist[i]); + if (remote_host != 0) { + + /* set up the address of the foreign socket for connect() */ + remote_sin.sin_family = remote_host->h_addrtype; + (void) memcpy((char *) &remote_sin.sin_addr, + (char *) remote_host->h_addr, + sizeof(remote_host->h_addr)); + break; /* Only Need one */ + } + } + + free ((char *)hostlist); + + /* open a TCP socket */ + *local_socket = socket(PF_INET, SOCK_STREAM, 0); + if (*local_socket < 0) { + fprintf(stderr, "Cannot Open Socket\n"); + return(1); + } + /* connect to the server */ + if (connect(*local_socket, &remote_sin, sizeof(remote_sin)) < 0) { + fprintf(stderr, "Cannot Connect to Socket\n"); + close(*local_socket); + return(1); + } + + /* find out who I am, now that we are connected and therefore bound */ + namelen = sizeof(local_sin); + if (getsockname(*local_socket, + (struct sockaddr *) &local_sin, &namelen) < 0) { + fprintf(stderr, "Cannot Perform getsockname\n"); + close(*local_socket); + return(1); + } + return(0); +} + +usage() +{ + fprintf(stderr, "Usage: "); + fprintf(stderr, "kpasswd [name]\n"); + exit(0); +} diff --git a/src/kadmin.old/kpasswd/networked.c b/src/kadmin.old/kpasswd/networked.c new file mode 100644 index 000000000..e70e6f83f --- /dev/null +++ b/src/kadmin.old/kpasswd/networked.c @@ -0,0 +1,222 @@ +/* Networked */ +/* */ +/* Written by: Glenn Machin 2931 */ +/* Originated: Nov 12, 1990 */ +/* Description: */ +/* */ +/* This program/routine exits/returns with a status 1 if */ +/* the terminal associated with the current process is */ +/* connected from a remote host, otherwise exits/returns */ +/* with a value of 0. */ +/* */ +/* This program/routine makes some basic assumptions about */ +/* utmp: */ +/* *The login process, rcmd, or window application */ +/* makes an entry into utmp for all currents */ +/* users. */ +/* *For entries in which the users have logged in */ +/* locally. The line name is not a pseudo tty */ +/* device. */ +/* *For X window application in which */ +/* the device is a pseudo tty device but the */ +/* display is the local system, then the ut_host */ +/* has the format system_name:0.0 or :0.0. */ +/* All other entries will be assumed to be */ +/* networked. */ +/* */ +/* Changes: 11/15/90 Check for file /etc/krb.secure. */ +/* If it exists then perform network */ +/* check, otherwise return 0. */ +/****************************************************************/ +/* + * 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 +#ifdef HAVE_UNISTD_H +#include +#endif +#ifndef _TYPES_ +#include +#ifndef _TYPES_ +#define _TYPES_ +#endif +#endif +#include +#include + +#ifndef MAXHOSTNAME +#define MAXHOSTNAME 64 +#endif + +#ifdef NO_UT_PID + +static int utfile; + +#include + +static void kadmin_setutent() +{ + utfile = open("/etc/utmp",O_RDONLY); +} + +static struct utmp * kadmin_getutline(utmpent) +struct utmp *utmpent; +{ + static struct utmp tmputmpent; + int found = 0; + while ( read(utfile,&tmputmpent,sizeof(struct utmp)) > 0 ){ + if ( strcmp(tmputmpent.ut_line,utmpent->ut_line) == 0){ +#ifdef NO_UT_HOST + if ( ( 1) && +#else + if ( (strcmp(tmputmpent.ut_host,"") == 0) && +#endif + (strcmp(tmputmpent.ut_name,"") == 0)) continue; + found = 1; + break; + } + } + if (found) + return(&tmputmpent); + return((struct utmp *) 0); +} + +static void kadmin_endutent() +{ + close(utfile); +} +#else +#define kadmin_setutent setutent +#define kadmin_getutline getutline +#define kadmin_endutent endutent +#endif /* defined(HAVE_GETUTENT) && !defined(NO_UT_PID) */ + + +int network_connected() +{ +struct utmp utmpent; +struct utmp retutent, *tmpptr; +char *display_indx; +char currenthost[MAXHOSTNAME]; +char *username,*tmpname; + + +/* Macro for pseudo_tty */ +#define pseudo_tty(ut) \ + ((strncmp((ut).ut_line, "tty", 3) == 0 && ((ut).ut_line[3] == 'p' \ + || (ut).ut_line[3] == 'q' \ + || (ut).ut_line[3] == 'r' \ + || (ut).ut_line[3] == 's'))\ + || (strncmp((ut).ut_line, "pty", 3) == 0)) + + /* Check to see if getlogin returns proper name */ + if ( (tmpname = (char *) getlogin()) == (char *) 0) return(1); + username = (char *) malloc(strlen(tmpname) + 1); + if ( username == (char *) 0) return(1); + strcpy(username,tmpname); + + /* Obtain tty device for controlling tty of current process.*/ + strncpy(utmpent.ut_line,ttyname(0) + strlen("/dev/"), + sizeof(utmpent.ut_line)); + + /* See if this device is currently listed in /etc/utmp under + calling user */ +#ifndef NO_UT_TYPE + utmpent.ut_type = USER_PROCESS; +#define ut_name ut_user +#endif + kadmin_setutent(); + while ( (tmpptr = (struct utmp *) kadmin_getutline(&utmpent)) + != ( struct utmp *) 0) { + + /* If logged out name and host will be empty */ + if ((strcmp(tmpptr->ut_name,"") == 0) && +#ifdef NO_UT_HOST + ( 1)) continue; +#else + (strcmp(tmpptr->ut_host,"") == 0)) continue; +#endif + else break; + } + if ( tmpptr == (struct utmp *) 0) { + kadmin_endutent(); + return(1); + } + memcpy((char *)&retutent,(char *)tmpptr,sizeof(struct utmp)); + kadmin_endutent(); +#ifdef DEBUG +#ifdef NO_UT_HOST + printf("User %s on line %s :\n", + retutent.ut_name,retutent.ut_line); +#else + printf("User %s on line %s connected from host :%s:\n", + retutent.ut_name,retutent.ut_line,retutent.ut_host); +#endif +#endif + if (strcmp(retutent.ut_name,username) != 0) { + return(1); + } + + + /* If this is not a pseudo tty then everything is OK */ + if (! pseudo_tty(retutent)) return(0); + + /* OK now the work begins there is an entry in utmp and + the device is a pseudo tty. */ + + /* Check if : is in hostname if so this is xwindow display */ + + if (gethostname(currenthost,sizeof(currenthost))) return(1); +#ifdef NO_UT_HOST + display_indx = (char *) 0; +#else + display_indx = (char *) strchr(retutent.ut_host,':'); +#endif + if ( display_indx != (char *) 0) { + /* + We have X window application here. The host field should have + the form => local_system_name:0.0 or :0.0 + if the window is being displayed on the local system. + */ +#ifdef NO_UT_HOST + return(1); +#else + if (strncmp(currenthost,retutent.ut_host, + (display_indx - retutent.ut_host)) != 0) return(1); + else return(0); +#endif + } + + /* Host field is empty or is not X window entry. At this point + we can't trust that the pseudo tty is not connected to a + networked process so let's return 1. + */ + return(1); +} + +#ifdef NOTKERBEROS +main(argc,argv) +int argc; +char **argv; +{ + if (network_connected()){ +#ifdef DEBUG + printf("Networked\n"); +#endif + exit(1); + } + else { +#ifdef DEBUG + printf("Not networked\n"); +#endif + exit(0); + } +} +#else +int networked() +{ + return(network_connected()); +} +#endif 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 -- 2.26.2