summaryrefslogtreecommitdiff
path: root/kerberosIV/kadm
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>1995-12-14 06:52:55 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>1995-12-14 06:52:55 +0000
commit8cf1f2a33575f93a2a1411591dea02dadfff25a0 (patch)
tree546551ebd40f0dfbbb6016a6028d467641b4ed8b /kerberosIV/kadm
parent02a248da23b192dd04bdb0fe2d61202086e9ceb3 (diff)
Kerberos IV code, based on a merge of fixed code from KTH and original
4.4BSD Lite code (international edition). Provides all functionality from the original 4.4BSD code plus standard Kerberos elements that were omitted in the 4.4BSD code.
Diffstat (limited to 'kerberosIV/kadm')
-rw-r--r--kerberosIV/kadm/Makefile23
-rw-r--r--kerberosIV/kadm/kadm_cli_wrap.c509
-rw-r--r--kerberosIV/kadm/kadm_err.et52
-rw-r--r--kerberosIV/kadm/kadm_local.h31
-rw-r--r--kerberosIV/kadm/kadm_stream.c294
-rw-r--r--kerberosIV/kadm/kadm_supp.c126
-rw-r--r--kerberosIV/kadm/shlib_version2
7 files changed, 1037 insertions, 0 deletions
diff --git a/kerberosIV/kadm/Makefile b/kerberosIV/kadm/Makefile
new file mode 100644
index 00000000000..04aed4e8afb
--- /dev/null
+++ b/kerberosIV/kadm/Makefile
@@ -0,0 +1,23 @@
+# $Id: Makefile,v 1.1 1995/12/14 06:52:45 tholo Exp $
+
+LIB= kadm
+SRCS= kadm_err.c kadm_cli_wrap.c kadm_stream.c kadm_supp.c
+CFLAGS+=-I. -I${.CURDIR}
+.if exists(${.CURDIR}/../krb/obj)
+CFLAGS+=-I${.CURDIR}/../krb/obj
+.else
+CFLAGS+=-I${.CURDIR}/../krb
+.endif
+LDADD+= ${COM_ERR}
+CLEANFILES+= kadm_err.c kadm_err.h
+
+kadm_err.c kadm_err.h: kadm_err.et
+ test -e kadm_err.et || ln -s ${.CURDIR}/kadm_err.et .
+ ${COMPILE_ET} kadm_err.et
+ -test -h kadm_err.et && rm kadm_err.et
+
+beforeinstall:
+ -cd ${.OBJDIR}; cmp -s kadm_err.h ${DESTDIR}/usr/include/kerberosIV/kadm_err.h || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 kadm_err.h ${DESTDIR}/usr/include/kerberosIV
+
+.include <bsd.lib.mk>
diff --git a/kerberosIV/kadm/kadm_cli_wrap.c b/kerberosIV/kadm/kadm_cli_wrap.c
new file mode 100644
index 00000000000..91a5f5c4c33
--- /dev/null
+++ b/kerberosIV/kadm/kadm_cli_wrap.c
@@ -0,0 +1,509 @@
+/* $Id: kadm_cli_wrap.c,v 1.1 1995/12/14 06:52:45 tholo Exp $ */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+/*
+ * Kerberos administration server client-side routines
+ */
+
+/*
+ * kadm_cli_wrap.c the client side wrapping of the calls to the admin server
+ */
+
+#include "kadm_local.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+static Kadm_Client client_parm;
+
+/* Macros for use in returning data... used in kadm_cli_send */
+#define RET_N_FREE(r) {clear_secrets(); free((char *)act_st); free((char *)priv_pak); return r;}
+
+/* Keys for use in the transactions */
+static des_cblock sess_key; /* to be filled in by kadm_cli_keyd */
+static des_key_schedule sess_sched;
+
+static void
+clear_secrets()
+{
+ bzero((char *)sess_key, sizeof(sess_key));
+ bzero((char *)sess_sched, sizeof(sess_sched));
+ return;
+}
+
+static void (*opipe)();
+
+static void
+kadm_cli_disconn()
+{
+ (void) close(client_parm.admin_fd);
+ (void) signal(SIGPIPE, opipe);
+ return;
+}
+
+/*
+ * kadm_init_link
+ * receives : name, inst, realm
+ *
+ * initializes client parm, the Kadm_Client structure which holds the
+ * data about the connection between the server and client, the services
+ * used, the locations and other fun things
+ */
+int
+kadm_init_link(n, i, r)
+ char *n;
+ char *i;
+ char *r;
+{
+ struct servent *sep; /* service we will talk to */
+ struct hostent *hop; /* host we will talk to */
+ char adm_hostname[MAXHOSTNAMELEN];
+
+ (void) init_kadm_err_tbl();
+ (void) init_krb_err_tbl();
+ (void) strcpy(client_parm.sname, n);
+ (void) strcpy(client_parm.sinst, i);
+ (void) strcpy(client_parm.krbrlm, r);
+ client_parm.admin_fd = -1;
+
+ /* set up the admin_addr - fetch name of admin host */
+ if (krb_get_admhst(adm_hostname, client_parm.krbrlm, 1) != KSUCCESS)
+ return KADM_NO_HOST;
+ if ((hop = gethostbyname(adm_hostname)) == NULL)
+ return KADM_UNK_HOST; /* couldnt find the admin servers
+ * address */
+ if ((sep = getservbyname(KADM_SNAME, "tcp")) == NULL)
+ return KADM_NO_SERV; /* couldnt find the admin service */
+ bzero((char *) &client_parm.admin_addr,
+ sizeof(client_parm.admin_addr));
+ client_parm.admin_addr.sin_family = hop->h_addrtype;
+ bcopy((char *) hop->h_addr, (char *) &client_parm.admin_addr.sin_addr,
+ hop->h_length);
+ client_parm.admin_addr.sin_port = sep->s_port;
+
+ return KADM_SUCCESS;
+} /* procedure kadm_init_link */
+
+static int
+kadm_cli_conn()
+{ /* this connects and sets my_addr */
+ int on = 1;
+
+ if ((client_parm.admin_fd =
+ socket(client_parm.admin_addr.sin_family, SOCK_STREAM,0)) < 0)
+ return KADM_NO_SOCK; /* couldnt create the socket */
+ if (connect(client_parm.admin_fd,
+ (struct sockaddr *) & client_parm.admin_addr,
+ sizeof(client_parm.admin_addr))) {
+ (void) close(client_parm.admin_fd);
+ client_parm.admin_fd = -1;
+ return KADM_NO_CONN; /* couldnt get the connect */
+ }
+ opipe = signal(SIGPIPE, SIG_IGN);
+ client_parm.my_addr_len = sizeof(client_parm.my_addr);
+ if (getsockname(client_parm.admin_fd,
+ (struct sockaddr *) & client_parm.my_addr,
+ &client_parm.my_addr_len) < 0) {
+ (void) close(client_parm.admin_fd);
+ client_parm.admin_fd = -1;
+ (void) signal(SIGPIPE, opipe);
+ return KADM_NO_HERE; /* couldnt find out who we are */
+ }
+ if (setsockopt(client_parm.admin_fd, SOL_SOCKET, SO_KEEPALIVE, &on,
+ sizeof(on)) < 0) {
+ (void) close(client_parm.admin_fd);
+ client_parm.admin_fd = -1;
+ (void) signal(SIGPIPE, opipe);
+ return KADM_NO_CONN; /* XXX */
+ }
+ return KADM_SUCCESS;
+}
+
+/* takes in the sess_key and key_schedule and sets them appropriately */
+static int
+kadm_cli_keyd(s_k, s_s)
+ des_cblock *s_k; /* session key */
+ struct des_ks_struct *s_s; /* session key schedule */
+{
+ CREDENTIALS cred; /* to get key data */
+ int stat;
+
+ /* want .sname and .sinst here.... */
+ if ((stat = krb_get_cred(client_parm.sname, client_parm.sinst,
+ client_parm.krbrlm, &cred)))
+ return stat + krb_err_base;
+ bcopy((char *) cred.session, (char *) s_k, sizeof(des_cblock));
+ bzero((char *) cred.session, sizeof(des_cblock));
+#ifdef NOENCRYPTION
+ bzero(s_s, sizeof(des_key_schedule));
+#else
+ if ((stat = des_key_sched(s_k,s_s)))
+ return(stat+krb_err_base);
+#endif
+ return KADM_SUCCESS;
+} /* This code "works" */
+
+static int
+kadm_cli_out(dat, dat_len, ret_dat, ret_siz)
+ u_char *dat;
+ int dat_len;
+ u_char **ret_dat;
+ int *ret_siz;
+{
+ u_short dlen;
+ int retval;
+
+ dlen = (u_short) dat_len;
+
+ if (dat_len != (int)dlen)
+ return (KADM_NO_ROOM);
+
+ dlen = htons(dlen);
+ if (krb_net_write(client_parm.admin_fd, (char *) &dlen,
+ sizeof(u_short)) < 0)
+ return (errno); /* XXX */
+
+ if (krb_net_write(client_parm.admin_fd, (char *) dat, dat_len) < 0)
+ return (errno); /* XXX */
+
+ if ((retval = krb_net_read(client_parm.admin_fd, (char *) &dlen,
+ sizeof(u_short)) != sizeof(u_short))) {
+ if (retval < 0)
+ return(errno); /* XXX */
+ else
+ return(EPIPE); /* short read ! */
+ }
+
+ dlen = ntohs(dlen);
+ *ret_dat = (u_char *)malloc((unsigned)dlen);
+ if (!*ret_dat)
+ return(KADM_NOMEM);
+
+ if ((retval = krb_net_read(client_parm.admin_fd, (char *) *ret_dat,
+ (int) dlen) != dlen)) {
+ if (retval < 0)
+ return(errno); /* XXX */
+ else
+ return(EPIPE); /* short read ! */
+ }
+ *ret_siz = (int) dlen;
+ return KADM_SUCCESS;
+}
+
+/*
+ * kadm_cli_send
+ * recieves : opcode, packet, packet length, serv_name, serv_inst
+ * returns : return code from the packet build, the server, or
+ * something else
+ *
+ * It assembles a packet as follows:
+ * 8 bytes : VERSION STRING
+ * 4 bytes : LENGTH OF MESSAGE DATA and OPCODE
+ * : KTEXT
+ * : OPCODE \
+ * : DATA > Encrypted (with make priv)
+ * : ...... /
+ *
+ * If it builds the packet and it is small enough, then it attempts to open the
+ * connection to the admin server. If the connection is succesfully open
+ * then it sends the data and waits for a reply.
+ */
+static int
+kadm_cli_send(st_dat, st_siz, ret_dat, ret_siz)
+ u_char *st_dat; /* the actual data */
+ int st_siz; /* length of said data */
+ u_char **ret_dat; /* to give return info */
+ int *ret_siz; /* length of returned info */
+{
+ int act_len, retdat; /* current offset into packet, return
+ * data */
+ KTEXT_ST authent; /* the authenticator we will build */
+ u_char *act_st; /* the pointer to the complete packet */
+ u_char *priv_pak; /* private version of the packet */
+ int priv_len; /* length of private packet */
+ u_int32_t cksum; /* checksum of the packet */
+ MSG_DAT mdat;
+ u_char *return_dat;
+
+ act_st = (u_char *) malloc(KADM_VERSIZE); /* verstr stored first */
+ (void) strncpy((char *)act_st, KADM_VERSTR, KADM_VERSIZE);
+ act_len = KADM_VERSIZE;
+
+ if ((retdat = kadm_cli_keyd(&sess_key, sess_sched)) != KADM_SUCCESS) {
+ free((char *)act_st);
+ return retdat; /* couldnt get key working */
+ }
+ priv_pak = (u_char *) malloc((unsigned)(st_siz + 200));
+ /* 200 bytes for extra info case */
+ if ((priv_len = krb_mk_priv(st_dat, priv_pak, (u_int32_t)st_siz,
+ sess_sched, &sess_key, &client_parm.my_addr,
+ &client_parm.admin_addr)) < 0)
+ RET_N_FREE(KADM_NO_ENCRYPT); /* whoops... we got a lose
+ * here */
+ /* here is the length of priv data. receiver calcs
+ size of authenticator by subtracting vno size, priv size, and
+ sizeof(u_int32_t) (for the size indication) from total size */
+
+ act_len += vts_long((u_int32_t) priv_len, &act_st, act_len);
+#ifdef NOENCRYPTION
+ cksum = 0;
+#else
+ cksum = des_quad_cksum((des_cblock *)priv_pak, (des_cblock *)0, (long)priv_len, 0,
+ &sess_key);
+#endif
+ if ((retdat = krb_mk_req(&authent, client_parm.sname, client_parm.sinst,
+ client_parm.krbrlm, (long)cksum))) {
+ /* authenticator? */
+ RET_N_FREE(retdat + krb_err_base);
+ }
+
+ act_st = (u_char *) realloc((char *) act_st,
+ (unsigned) (act_len + authent.length
+ + priv_len));
+ if (!act_st) {
+ clear_secrets();
+ free((char *)priv_pak);
+ return(KADM_NOMEM);
+ }
+ bcopy((char *) authent.dat, (char *) act_st + act_len, authent.length);
+ bcopy((char *) priv_pak, (char *) act_st + act_len + authent.length,
+ priv_len);
+ free((char *)priv_pak);
+ if ((retdat = kadm_cli_out(act_st,
+ act_len + authent.length + priv_len,
+ ret_dat, ret_siz)) != KADM_SUCCESS)
+ RET_N_FREE(retdat);
+ free((char *)act_st);
+#define RET_N_FREE2(r) {free((char *)*ret_dat); clear_secrets(); return(r);}
+
+ /* first see if it's a YOULOUSE */
+ if ((*ret_siz >= KADM_VERSIZE) &&
+ !strncmp(KADM_ULOSE, (char *)*ret_dat, KADM_VERSIZE)) {
+ u_int32_t errcode;
+ /* it's a youlose packet */
+ if (*ret_siz < KADM_VERSIZE + sizeof(u_int32_t))
+ RET_N_FREE2(KADM_BAD_VER);
+ bcopy((char *)(*ret_dat) + KADM_VERSIZE, (char *)&errcode,
+ sizeof(u_int32_t));
+ retdat = (int) ntohl(errcode);
+ RET_N_FREE2(retdat);
+ }
+ /* need to decode the ret_dat */
+ if ((retdat = krb_rd_priv(*ret_dat, (u_int32_t)*ret_siz, sess_sched,
+ &sess_key, &client_parm.admin_addr,
+ &client_parm.my_addr, &mdat)))
+ RET_N_FREE2(retdat+krb_err_base);
+ if (mdat.app_length < KADM_VERSIZE + 4)
+ /* too short! */
+ RET_N_FREE2(KADM_BAD_VER);
+ if (strncmp((char *)mdat.app_data, KADM_VERSTR, KADM_VERSIZE))
+ /* bad version */
+ RET_N_FREE2(KADM_BAD_VER);
+ bcopy((char *)mdat.app_data+KADM_VERSIZE,
+ (char *)&retdat, sizeof(u_int32_t));
+ retdat = ntohl((u_int32_t)retdat);
+ if (!(return_dat = (u_char *)malloc((unsigned)(mdat.app_length -
+ KADM_VERSIZE - sizeof(u_int32_t)))))
+ RET_N_FREE2(KADM_NOMEM);
+ bcopy((char *) mdat.app_data + KADM_VERSIZE + sizeof(u_int32_t),
+ (char *)return_dat,
+ (int)mdat.app_length - KADM_VERSIZE - sizeof(u_int32_t));
+ free((char *)*ret_dat);
+ clear_secrets();
+ *ret_dat = return_dat;
+ *ret_siz = mdat.app_length - KADM_VERSIZE - sizeof(u_int32_t);
+ return retdat;
+}
+
+/*
+ * kadm_change_pw
+ * recieves : key
+ *
+ * Replaces the password (i.e. des key) of the caller with that specified in
+ * key. Returns no actual data from the master server, since this is called
+ * by a user
+ */
+int
+kadm_change_pw(newkey)
+ unsigned char *newkey; /* The DES form of the users key */
+{
+ int stsize, retc; /* stream size and return code */
+ u_char *send_st; /* send stream */
+ u_char *ret_st;
+ int ret_sz;
+ u_int32_t keytmp;
+
+ if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+ return(retc);
+ /* possible problem with vts_long on a non-multiple of four boundary */
+
+ stsize = 0; /* start of our output packet */
+ send_st = (u_char *) malloc(1);/* to make it reallocable */
+ send_st[stsize++] = (u_char) CHANGE_PW;
+
+ /* change key to stream */
+
+ bcopy((char *) (((long *) newkey) + 1), (char *) &keytmp, 4);
+ keytmp = htonl(keytmp);
+ stsize += vts_long(keytmp, &send_st, stsize);
+
+ bcopy((char *) newkey, (char *) &keytmp, 4);
+ keytmp = htonl(keytmp);
+ stsize += vts_long(keytmp, &send_st, stsize);
+
+ retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz);
+ free((char *)send_st);
+ if (retc == KADM_SUCCESS) {
+ free((char *)ret_st);
+ }
+ kadm_cli_disconn();
+ return(retc);
+}
+
+/*
+ * kadm_add
+ * receives : vals
+ * returns : vals
+ *
+ * Adds and entry containing values to the database returns the values of the
+ * entry, so if you leave certain fields blank you will be able to determine
+ * the default values they are set to
+ */
+int
+kadm_add(vals)
+ Kadm_vals *vals;
+{
+ u_char *st, *st2; /* st will hold the stream of values */
+ int st_len; /* st2 the final stream with opcode */
+ int retc; /* return code from call */
+ u_char *ret_st;
+ int ret_sz;
+
+ if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+ return(retc);
+ st_len = vals_to_stream(vals, &st);
+ st2 = (u_char *) malloc((unsigned)(1 + st_len));
+ *st2 = (u_char) ADD_ENT; /* here's the opcode */
+ bcopy((char *) st, (char *) st2 + 1, st_len); /* append st on */
+ retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz);
+ free((char *)st);
+ free((char *)st2);
+ if (retc == KADM_SUCCESS) {
+ /* ret_st has vals */
+ if (stream_to_vals(ret_st, vals, ret_sz) < 0)
+ retc = KADM_LENGTH_ERROR;
+ free((char *)ret_st);
+ }
+ kadm_cli_disconn();
+ return(retc);
+}
+
+/*
+ * kadm_mod
+ * receives : KTEXT, {values, values}
+ * returns : CKSUM, RETCODE, {values}
+ * acl : su, sms (as register or dealloc)
+ *
+ * Modifies all entries corresponding to the first values so they match the
+ * second values. returns the values for the changed entries in vals2
+ */
+int
+kadm_mod(vals1, vals2)
+ Kadm_vals *vals1;
+ Kadm_vals *vals2;
+{
+ u_char *st, *st2; /* st will hold the stream of values */
+ int st_len, nlen; /* st2 the final stream with opcode */
+ u_char *ret_st;
+ int ret_sz;
+
+ /* nlen is the length of second vals */
+ int retc; /* return code from call */
+
+ if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+ return(retc);
+
+ st_len = vals_to_stream(vals1, &st);
+ st2 = (u_char *) malloc((unsigned)(1 + st_len));
+ *st2 = (u_char) MOD_ENT; /* here's the opcode */
+ bcopy((char *) st, (char *) st2 + 1, st_len++); /* append st on */
+ free((char *)st);
+ nlen = vals_to_stream(vals2, &st);
+ st2 = (u_char *) realloc((char *) st2, (unsigned)(st_len + nlen));
+ bcopy((char *) st, (char *) st2 + st_len, nlen); /* append st on */
+ retc = kadm_cli_send(st2, st_len + nlen, &ret_st, &ret_sz);
+ free((char *)st);
+ free((char *)st2);
+ if (retc == KADM_SUCCESS) {
+ /* ret_st has vals */
+ if (stream_to_vals(ret_st, vals2, ret_sz) < 0)
+ retc = KADM_LENGTH_ERROR;
+ free((char *)ret_st);
+ }
+ kadm_cli_disconn();
+ return(retc);
+}
+
+/*
+ * kadm_get
+ * receives : KTEXT, {values, flags}
+ * returns : CKSUM, RETCODE, {count, values, values, values}
+ * acl : su
+ *
+ * gets the fields requested by flags from all entries matching values returns
+ * this data for each matching recipient, after a count of how many such
+ * matches there were
+ */
+int
+kadm_get(vals, fl)
+ Kadm_vals *vals;
+ u_char *fl;
+{
+ int loop; /* for copying the fields data */
+ u_char *st, *st2; /* st will hold the stream of values */
+ int st_len; /* st2 the final stream with opcode */
+ int retc; /* return code from call */
+ u_char *ret_st;
+ int ret_sz;
+
+ if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+ return(retc);
+ st_len = vals_to_stream(vals, &st);
+ st2 = (u_char *) malloc((unsigned)(1 + st_len + FLDSZ));
+ *st2 = (u_char) GET_ENT; /* here's the opcode */
+ bcopy((char *) st, (char *) st2 + 1, st_len); /* append st on */
+ for (loop = FLDSZ - 1; loop >= 0; loop--)
+ *(st2 + st_len + FLDSZ - loop) = fl[loop]; /* append the flags */
+ retc = kadm_cli_send(st2, st_len + 1 + FLDSZ, &ret_st, &ret_sz);
+ free((char *)st);
+ free((char *)st2);
+ if (retc == KADM_SUCCESS) {
+ /* ret_st has vals */
+ if (stream_to_vals(ret_st, vals, ret_sz) < 0)
+ retc = KADM_LENGTH_ERROR;
+ free((char *)ret_st);
+ }
+ kadm_cli_disconn();
+ return(retc);
+}
diff --git a/kerberosIV/kadm/kadm_err.et b/kerberosIV/kadm/kadm_err.et
new file mode 100644
index 00000000000..fb1c47dbdf6
--- /dev/null
+++ b/kerberosIV/kadm/kadm_err.et
@@ -0,0 +1,52 @@
+# $Id: kadm_err.et,v 1.1 1995/12/14 06:52:45 tholo Exp $
+
+# Copyright 1988 by the Massachusetts Institute of Technology.
+#
+# For copying and distribution information, please see the file
+# <mit-copyright.h>.
+#
+# Kerberos administration server error table
+#
+ et kadm
+
+# KADM_SUCCESS, as all success codes should be, is zero
+
+ec KADM_RCSID, "$Header: /cvs/OpenBSD/src/kerberosIV/kadm/Attic/kadm_err.et,v 1.1 1995/12/14 06:52:45 tholo Exp $"
+# /* Building and unbuilding the packet errors */
+ec KADM_NO_REALM, "Cannot fetch local realm"
+ec KADM_NO_CRED, "Unable to fetch credentials"
+ec KADM_BAD_KEY, "Bad key supplied"
+ec KADM_NO_ENCRYPT, "Can't encrypt data"
+ec KADM_NO_AUTH, "Cannot encode/decode authentication info"
+ec KADM_WRONG_REALM, "Principal attemping change is in wrong realm"
+ec KADM_NO_ROOM, "Packet is too large"
+ec KADM_BAD_VER, "Version number is incorrect"
+ec KADM_BAD_CHK, "Checksum does not match"
+ec KADM_NO_READ, "Unsealing private data failed"
+ec KADM_NO_OPCODE, "Unsupported operation"
+ec KADM_NO_HOST, "Could not find administrating host"
+ec KADM_UNK_HOST, "Administrating host name is unknown"
+ec KADM_NO_SERV, "Could not find service name in services database"
+ec KADM_NO_SOCK, "Could not create socket"
+ec KADM_NO_CONN, "Could not connect to server"
+ec KADM_NO_HERE, "Could not fetch local socket address"
+ec KADM_NO_MAST, "Could not fetch master key"
+ec KADM_NO_VERI, "Could not verify master key"
+
+# /* From the server side routines */
+ec KADM_INUSE, "Entry already exists in database"
+ec KADM_UK_SERROR, "Database store error"
+ec KADM_UK_RERROR, "Database read error"
+ec KADM_UNAUTH, "Insufficient access to perform requested operation"
+# KADM_DATA isn't really an error, but...
+ec KADM_DATA, "Data is available for return to client"
+ec KADM_NOENTRY, "No such entry in the database"
+
+ec KADM_NOMEM, "Memory exhausted"
+ec KADM_NO_HOSTNAME, "Could not fetch system hostname"
+ec KADM_NO_BIND, "Could not bind port"
+ec KADM_LENGTH_ERROR, "Length mismatch problem"
+ec KADM_ILL_WILDCARD, "Illegal use of wildcard"
+
+ec KADM_DB_INUSE, "Database is locked or in use--try again later"
+end
diff --git a/kerberosIV/kadm/kadm_local.h b/kerberosIV/kadm/kadm_local.h
new file mode 100644
index 00000000000..32b533e9ca5
--- /dev/null
+++ b/kerberosIV/kadm/kadm_local.h
@@ -0,0 +1,31 @@
+/* $Id: kadm_local.h,v 1.1 1995/12/14 06:52:45 tholo Exp $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#include "krb_err.h"
+#include <kerberosIV/krb_db.h>
+#include <kerberosIV/kadm.h>
+#include "kadm_err.h"
+
+int vts_long __P((u_int32_t, u_char **, int));
+int vals_to_stream __P((Kadm_vals *, u_char **));
+int stream_to_vals __P((u_char *, Kadm_vals *, int));
+
+int kadm_init_link __P((char n[], char i[], char r[]));
+int kadm_change_pw __P((des_cblock));
+int kadm_add __P((Kadm_vals *));
+int kadm_mod __P((Kadm_vals *, Kadm_vals *));
+int kadm_get __P((Kadm_vals *, u_char fl[4]));
diff --git a/kerberosIV/kadm/kadm_stream.c b/kerberosIV/kadm/kadm_stream.c
new file mode 100644
index 00000000000..50aae668868
--- /dev/null
+++ b/kerberosIV/kadm/kadm_stream.c
@@ -0,0 +1,294 @@
+/* $Id: kadm_stream.c,v 1.1 1995/12/14 06:52:45 tholo Exp $ */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Stream conversion functions for Kerberos administration server
+ */
+
+/*
+ kadm_stream.c
+ this holds the stream support routines for the kerberos administration server
+
+ vals_to_stream: converts a vals struct to a stream for transmission
+ internals build_field_header, vts_[string, char, long, short]
+ stream_to_vals: converts a stream to a vals struct
+ internals check_field_header, stv_[string, char, long, short]
+ error: prints out a kadm error message, returns
+ fatal: prints out a kadm fatal error message, exits
+*/
+
+#include "kadm_local.h"
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+static int
+build_field_header(cont, st)
+ u_char *cont; /* container for fields data */
+ u_char **st; /* stream */
+{
+ *st = (u_char *) malloc (4);
+ bcopy((char *) cont, (char *) *st, 4);
+ return 4; /* return pointer to current stream location */
+}
+
+static int
+check_field_header(st, cont, maxlen)
+ u_char *st; /* stream */
+ u_char *cont; /* container for fields data */
+ int maxlen;
+{
+ if (4 > maxlen)
+ return(-1);
+ bcopy((char *) st, (char *) cont, 4);
+ return 4; /* return pointer to current stream location */
+}
+
+static int
+vts_string(dat, st, loc)
+ char *dat; /* a string to put on the stream */
+ u_char **st; /* base pointer to the stream */
+ int loc; /* offset into the stream for current data */
+{
+ *st = (u_char *) realloc ((char *)*st, (unsigned) (loc + strlen(dat) + 1));
+ bcopy(dat, (char *)(*st + loc), strlen(dat)+1);
+ return strlen(dat)+1;
+}
+
+
+static int
+vts_short(dat, st, loc)
+ u_int16_t dat; /* the attributes field */
+ u_char **st; /* a base pointer to the stream */
+ int loc; /* offset into the stream for current data */
+{
+ u_int16_t temp; /* to hold the net order short */
+
+ temp = htons(dat); /* convert to network order */
+ *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_int16_t)));
+ bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_int16_t));
+ return sizeof(u_int16_t);
+}
+
+static int
+vts_char(dat, st, loc)
+ u_char dat; /* the attributes field */
+ u_char **st; /* a base pointer to the stream */
+ int loc; /* offset into the stream for current data */
+{
+ *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_char)));
+ (*st)[loc] = (u_char) dat;
+ return 1;
+}
+
+int
+vts_long(dat, st, loc)
+ u_int32_t dat; /* the attributes field */
+ u_char **st; /* a base pointer to the stream */
+ int loc; /* offset into the stream for current data */
+{
+ u_int32_t temp; /* to hold the net order short */
+
+ temp = htonl(dat); /* convert to network order */
+ *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_int32_t)));
+ bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_int32_t));
+ return sizeof(u_int32_t);
+}
+
+static int
+stv_string(st, dat, loc, stlen, maxlen)
+ register u_char *st; /* base pointer to the stream */
+ char *dat; /* a string to read from the stream */
+ register int loc; /* offset into the stream for current data */
+ int stlen; /* max length of string to copy in */
+ int maxlen; /* max length of input stream */
+{
+ int maxcount; /* max count of chars to copy */
+
+ maxcount = min(maxlen - loc, stlen);
+
+ (void) strncpy(dat, (char *)st + loc, maxcount);
+
+ if (dat[maxcount-1]) /* not null-term --> not enuf room */
+ return(-1);
+ return strlen(dat)+1;
+}
+
+static int
+stv_short(st, dat, loc, maxlen)
+ u_char *st; /* a base pointer to the stream */
+ u_int16_t *dat; /* the attributes field */
+ int loc; /* offset into the stream for current data */
+ int maxlen;
+{
+ u_int16_t temp; /* to hold the net order short */
+
+ if (loc + sizeof(temp) > maxlen)
+ return(-1);
+ /*bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_short));*/
+ bcopy(st + loc, (char *) &temp, sizeof(temp));
+ *dat = ntohs(temp); /* convert to network order */
+ return sizeof(temp);
+}
+
+int
+stv_long(st, dat, loc, maxlen)
+ u_char *st; /* a base pointer to the stream */
+ u_int32_t *dat; /* the attributes field */
+ int loc; /* offset into the stream for current data */
+ int maxlen; /* maximum length of st */
+{
+ u_int32_t temp; /* to hold the net order short */
+
+ if (loc + sizeof(temp) > maxlen)
+ return(-1);
+ /*bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_long));*/
+ bcopy(st + loc, (char *) &temp, sizeof(temp));
+ *dat = ntohl(temp); /* convert to network order */
+ return sizeof(temp);
+}
+
+static int
+stv_char(st, dat, loc, maxlen)
+ u_char *st; /* a base pointer to the stream */
+ u_char *dat; /* the attributes field */
+ int loc; /* offset into the stream for current data */
+ int maxlen;
+{
+ if (loc + 1 > maxlen)
+ return(-1);
+ *dat = *(st + loc);
+ return 1;
+}
+
+/*
+vals_to_stream
+ recieves : kadm_vals *, u_char *
+ returns : a realloced and filled in u_char *
+
+this function creates a byte-stream representation of the kadm_vals structure
+*/
+int
+vals_to_stream(dt_in, dt_out)
+ Kadm_vals *dt_in;
+ u_char **dt_out;
+{
+ int vsloop, stsize; /* loop counter, stream size */
+
+ stsize = build_field_header(dt_in->fields, dt_out);
+ for (vsloop=31; vsloop>=0; vsloop--)
+ if (IS_FIELD(vsloop,dt_in->fields)) {
+ switch (vsloop) {
+ case KADM_NAME:
+ stsize+=vts_string(dt_in->name, dt_out, stsize);
+ break;
+ case KADM_INST:
+ stsize+=vts_string(dt_in->instance, dt_out, stsize);
+ break;
+ case KADM_EXPDATE:
+ stsize+=vts_long(dt_in->exp_date, dt_out, stsize);
+ break;
+ case KADM_ATTR:
+ stsize+=vts_short(dt_in->attributes, dt_out, stsize);
+ break;
+ case KADM_MAXLIFE:
+ stsize+=vts_char(dt_in->max_life, dt_out, stsize);
+ break;
+ case KADM_DESKEY:
+ stsize+=vts_long(dt_in->key_high, dt_out, stsize);
+ stsize+=vts_long(dt_in->key_low, dt_out, stsize);
+ break;
+ default:
+ break;
+ }
+}
+ return(stsize);
+}
+
+/*
+stream_to_vals
+ recieves : u_char *, kadm_vals *
+ returns : a kadm_vals filled in according to u_char *
+
+this decodes a byte stream represntation of a vals struct into kadm_vals
+*/
+int
+stream_to_vals(dt_in, dt_out, maxlen)
+ u_char *dt_in;
+ Kadm_vals *dt_out;
+ int maxlen; /* max length to use */
+{
+ register int vsloop, stsize; /* loop counter, stream size */
+ register int status;
+
+ bzero((char *) dt_out, sizeof(*dt_out));
+
+ stsize = check_field_header(dt_in, dt_out->fields, maxlen);
+ if (stsize < 0)
+ return(-1);
+ for (vsloop=31; vsloop>=0; vsloop--)
+ if (IS_FIELD(vsloop,dt_out->fields))
+ switch (vsloop) {
+ case KADM_NAME:
+ if ((status = stv_string(dt_in, dt_out->name, stsize,
+ sizeof(dt_out->name), maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_INST:
+ if ((status = stv_string(dt_in, dt_out->instance, stsize,
+ sizeof(dt_out->instance), maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_EXPDATE:
+ if ((status = stv_long(dt_in, &dt_out->exp_date, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_ATTR:
+ if ((status = stv_short(dt_in, &dt_out->attributes, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_MAXLIFE:
+ if ((status = stv_char(dt_in, &dt_out->max_life, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_DESKEY:
+ if ((status = stv_long(dt_in, &dt_out->key_high, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ if ((status = stv_long(dt_in, &dt_out->key_low, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ default:
+ break;
+ }
+ return stsize;
+}
diff --git a/kerberosIV/kadm/kadm_supp.c b/kerberosIV/kadm/kadm_supp.c
new file mode 100644
index 00000000000..8882b06d422
--- /dev/null
+++ b/kerberosIV/kadm/kadm_supp.c
@@ -0,0 +1,126 @@
+/* $Id: kadm_supp.c,v 1.1 1995/12/14 06:52:46 tholo Exp $ */
+
+/*-
+ * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Support functions for Kerberos administration server & clients
+ */
+
+/*
+ kadm_supp.c
+ this holds the support routines for the kerberos administration server
+
+ error: prints out a kadm error message, returns
+ fatal: prints out a kadm fatal error message, exits
+ prin_vals: prints out data associated with a Principal in the vals
+ structure
+*/
+
+#include "kadm_local.h"
+
+/*
+prin_vals:
+ recieves : a vals structure
+*/
+void
+prin_vals(vals)
+ Kadm_vals *vals;
+{
+ printf("Info in Database for %s.%s:\n", vals->name, vals->instance);
+ printf(" Max Life: %d (%s) Exp Date: %s\n",
+ vals->max_life,
+ krb_life_to_atime(vals->max_life),
+ asctime(k_localtime(&vals->exp_date)));
+ printf(" Attribs: %.2x key: %lu %lu\n",
+ vals->attributes,
+ (long)vals->key_low, (long)vals->key_high);
+}
+
+#ifdef notdef
+nierror(s)
+int s;
+{
+ printf("Kerberos admin server loses..... %s\n",error_message(s));
+ return(s);
+}
+#endif
+
+/* kadm_prin_to_vals takes a fields arguments, a Kadm_vals and a Principal,
+ it copies the fields in Principal specified by fields into Kadm_vals,
+ i.e from old to new */
+
+void
+kadm_prin_to_vals(fields, new, old)
+ u_char *fields;
+ Kadm_vals *new;
+ Principal *old;
+{
+ bzero((char *)new, sizeof(*new));
+ if (IS_FIELD(KADM_NAME,fields)) {
+ (void) strncpy(new->name, old->name, ANAME_SZ);
+ SET_FIELD(KADM_NAME, new->fields);
+ }
+ if (IS_FIELD(KADM_INST,fields)) {
+ (void) strncpy(new->instance, old->instance, INST_SZ);
+ SET_FIELD(KADM_INST, new->fields);
+ }
+ if (IS_FIELD(KADM_EXPDATE,fields)) {
+ new->exp_date = old->exp_date;
+ SET_FIELD(KADM_EXPDATE, new->fields);
+ }
+ if (IS_FIELD(KADM_ATTR,fields)) {
+ new->attributes = old->attributes;
+ SET_FIELD(KADM_ATTR, new->fields);
+ }
+ if (IS_FIELD(KADM_MAXLIFE,fields)) {
+ new->max_life = old->max_life;
+ SET_FIELD(KADM_MAXLIFE, new->fields);
+ }
+ if (IS_FIELD(KADM_DESKEY,fields)) {
+ new->key_low = old->key_low;
+ new->key_high = old->key_high;
+ SET_FIELD(KADM_DESKEY, new->fields);
+ }
+}
+
+void
+kadm_vals_to_prin(fields, new, old)
+ u_char *fields;
+ Principal *new;
+ Kadm_vals *old;
+{
+
+ bzero((char *)new, sizeof(*new));
+ if (IS_FIELD(KADM_NAME,fields))
+ (void) strncpy(new->name, old->name, ANAME_SZ);
+ if (IS_FIELD(KADM_INST,fields))
+ (void) strncpy(new->instance, old->instance, INST_SZ);
+ if (IS_FIELD(KADM_EXPDATE,fields))
+ new->exp_date = old->exp_date;
+ if (IS_FIELD(KADM_ATTR,fields))
+ new->attributes = old->attributes;
+ if (IS_FIELD(KADM_MAXLIFE,fields))
+ new->max_life = old->max_life;
+ if (IS_FIELD(KADM_DESKEY,fields)) {
+ new->key_low = old->key_low;
+ new->key_high = old->key_high;
+ }
+}
diff --git a/kerberosIV/kadm/shlib_version b/kerberosIV/kadm/shlib_version
new file mode 100644
index 00000000000..d9961ea9fef
--- /dev/null
+++ b/kerberosIV/kadm/shlib_version
@@ -0,0 +1,2 @@
+major=4
+minor=0