summaryrefslogtreecommitdiffstats
path: root/eBones
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1995-01-20 02:02:54 +0000
committerwollman <wollman@FreeBSD.org>1995-01-20 02:02:54 +0000
commitc0e71984712cdfdc2d3befb12d640aea2c027f22 (patch)
tree2d4c68484fd0d5e51fe6f8e98eb79c47832b43ee /eBones
parent97daf1a19a1c37bb4730ac42ab08ca48e8d24a32 (diff)
downloadFreeBSD-src-c0e71984712cdfdc2d3befb12d640aea2c027f22.zip
FreeBSD-src-c0e71984712cdfdc2d3befb12d640aea2c027f22.tar.gz
Add the library used by `kadmin' and `kadmind'. Oddly enough, this
little library is actually exportable (we think) even though it's pretty useless iwithout the (non-exportable) clients.
Diffstat (limited to 'eBones')
-rw-r--r--eBones/lib/libkadm/EXPORTABLE4
-rw-r--r--eBones/lib/libkadm/Makefile23
-rw-r--r--eBones/lib/libkadm/kadm.h140
-rw-r--r--eBones/lib/libkadm/kadm_cli_wrap.c499
-rw-r--r--eBones/lib/libkadm/kadm_err.et53
-rw-r--r--eBones/lib/libkadm/kadm_stream.c273
-rw-r--r--eBones/lib/libkadm/kadm_supp.c114
-rw-r--r--eBones/libkadm/EXPORTABLE4
-rw-r--r--eBones/libkadm/Makefile23
-rw-r--r--eBones/libkadm/kadm.h140
-rw-r--r--eBones/libkadm/kadm_cli_wrap.c499
-rw-r--r--eBones/libkadm/kadm_err.et53
-rw-r--r--eBones/libkadm/kadm_stream.c273
-rw-r--r--eBones/libkadm/kadm_supp.c114
14 files changed, 2212 insertions, 0 deletions
diff --git a/eBones/lib/libkadm/EXPORTABLE b/eBones/lib/libkadm/EXPORTABLE
new file mode 100644
index 0000000..e478483
--- /dev/null
+++ b/eBones/lib/libkadm/EXPORTABLE
@@ -0,0 +1,4 @@
+The files in this directory are believed to be exportable.
+
+-GAWollman
+
diff --git a/eBones/lib/libkadm/Makefile b/eBones/lib/libkadm/Makefile
new file mode 100644
index 0000000..f587d5c
--- /dev/null
+++ b/eBones/lib/libkadm/Makefile
@@ -0,0 +1,23 @@
+# $Id$
+
+LIB= kadm
+
+SRCS= kadm_err.c kadm_stream.c kadm_supp.c kadm_cli_wrap.c
+CFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/../include -I${KRBOBJDIR} -DPOSIX
+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
+
+beforeinstall:
+ -cd ${.CURDIR}; cmp -s kadm.h \
+ ${DESTDIR}/usr/include/kerberosIV/kadm.h || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 kadm.h \
+ ${DESTDIR}/usr/include/kerberosIV
+ -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/eBones/lib/libkadm/kadm.h b/eBones/lib/libkadm/kadm.h
new file mode 100644
index 0000000..66284f4
--- /dev/null
+++ b/eBones/lib/libkadm/kadm.h
@@ -0,0 +1,140 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/include/RCS/kadm.h,v $
+ * $Author: jtkohl $
+ * Header: /afs/athena.mit.edu/astaff/project/kerberos/src/include/RCS/kadm.h,v 4.2 89/09/26 09:15:20 jtkohl Exp
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Definitions for Kerberos administration server & client
+ */
+
+#ifndef KADM_DEFS
+#define KADM_DEFS
+
+/*
+ * kadm.h
+ * Header file for the fourth attempt at an admin server
+ * Doug Church, December 28, 1989, MIT Project Athena
+ */
+
+/* for those broken Unixes without this defined... should be in sys/param.h */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <krb.h>
+#include <des.h>
+
+/* The global structures for the client and server */
+typedef struct {
+ struct sockaddr_in admin_addr;
+ struct sockaddr_in my_addr;
+ int my_addr_len;
+ int admin_fd; /* file descriptor for link to admin server */
+ char sname[ANAME_SZ]; /* the service name */
+ char sinst[INST_SZ]; /* the services instance */
+ char krbrlm[REALM_SZ];
+} Kadm_Client;
+
+typedef struct { /* status of the server, i.e the parameters */
+ int inter; /* Space for command line flags */
+ char *sysfile; /* filename of server */
+} admin_params; /* Well... it's the admin's parameters */
+
+/* Largest password length to be supported */
+#define MAX_KPW_LEN 128
+
+/* Largest packet the admin server will ever allow itself to return */
+#define KADM_RET_MAX 2048
+
+/* That's right, versions are 8 byte strings */
+#define KADM_VERSTR "KADM0.0A"
+#define KADM_ULOSE "KYOULOSE" /* sent back when server can't
+ decrypt client's msg */
+#define KADM_VERSIZE strlen(KADM_VERSTR)
+
+/* the lookups for the server instances */
+#define PWSERV_NAME "changepw"
+#define KADM_SNAME "kerberos_master"
+#define KADM_SINST "kerberos"
+
+/* Attributes fields constants and macros */
+#define ALLOC 2
+#define RESERVED 3
+#define DEALLOC 4
+#define DEACTIVATED 5
+#define ACTIVE 6
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ 4
+
+typedef struct {
+ u_char fields[FLDSZ]; /* The active fields in this struct */
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+ unsigned long key_low;
+ unsigned long key_high;
+ unsigned long exp_date;
+ unsigned short attributes;
+ unsigned char max_life;
+} Kadm_vals; /* The basic values structure in Kadm */
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ 4
+
+/* Need to define fields types here */
+#define KADM_NAME 31
+#define KADM_INST 30
+#define KADM_EXPDATE 29
+#define KADM_ATTR 28
+#define KADM_MAXLIFE 27
+#define KADM_DESKEY 26
+
+/* To set a field entry f in a fields structure d */
+#define SET_FIELD(f,d) (d[3-(f/8)]|=(1<<(f%8)))
+
+/* To set a field entry f in a fields structure d */
+#define CLEAR_FIELD(f,d) (d[3-(f/8)]&=(~(1<<(f%8))))
+
+/* Is field f in fields structure d */
+#define IS_FIELD(f,d) (d[3-(f/8)]&(1<<(f%8)))
+
+/* Various return codes */
+#define KADM_SUCCESS 0
+
+#define WILDCARD_STR "*"
+
+enum acl_types {
+ADDACL,
+GETACL,
+MODACL
+};
+
+/* Various opcodes for the admin server's functions */
+#define CHANGE_PW 2
+#define ADD_ENT 3
+#define MOD_ENT 4
+#define GET_ENT 5
+
+extern long kdb_get_master_key(); /* XXX should be in krb_db.h */
+extern long kdb_verify_master_key(); /* XXX ditto */
+
+extern long krb_mk_priv(), krb_rd_priv(); /* XXX should be in krb.h */
+extern void krb_set_tkt_string(); /* XXX ditto */
+
+extern unsigned long quad_cksum(); /* XXX should be in des.h */
+
+/* XXX This doesn't belong here!!! */
+char *malloc(), *realloc();
+#ifdef POSIX
+typedef void sigtype;
+#else
+typedef int sigtype;
+#endif
+
+#endif KADM_DEFS
diff --git a/eBones/lib/libkadm/kadm_cli_wrap.c b/eBones/lib/libkadm/kadm_cli_wrap.c
new file mode 100644
index 0000000..ca20601
--- /dev/null
+++ b/eBones/lib/libkadm/kadm_cli_wrap.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Kerberos administration server client-side routines
+ */
+
+#ifndef lint
+#if 0
+static char rcsid_kadm_cli_wrap_c[] =
+"from: Id: kadm_cli_wrap.c,v 4.6 89/12/30 20:09:45 qjb Exp";
+#endif
+static const char rcsid[] =
+ "$Id$";
+#endif lint
+
+/*
+ * kadm_cli_wrap.c the client side wrapping of the calls to the admin server
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <kadm.h>
+#include <kadm_err.h>
+#include <krb_err.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 Key_schedule sess_sched;
+
+static
+clear_secrets()
+{
+ bzero((char *)sess_key, sizeof(sess_key));
+ bzero((char *)sess_sched, sizeof(sess_sched));
+ 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
+ */
+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 */
+
+/*
+ * 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
+ */
+kadm_change_pw(newkey)
+des_cblock 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_long 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
+ */
+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
+ */
+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
+ */
+kadm_get(vals, fl)
+Kadm_vals *vals;
+u_char fl[4];
+
+{
+ 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);
+}
+
+/*
+ * 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.
+ */
+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_long 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_long)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_long) (for the size indication) from total size */
+
+ act_len += vts_long((u_long) priv_len, &act_st, act_len);
+#ifdef NOENCRYPTION
+ cksum = 0;
+#else
+ cksum = quad_cksum(priv_pak, (u_long *)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_long errcode;
+ /* it's a youlose packet */
+ if (*ret_siz < KADM_VERSIZE + sizeof(u_long))
+ RET_N_FREE2(KADM_BAD_VER);
+ bcopy((char *)(*ret_dat) + KADM_VERSIZE, (char *)&errcode,
+ sizeof(u_long));
+ retdat = (int) ntohl(errcode);
+ RET_N_FREE2(retdat);
+ }
+ /* need to decode the ret_dat */
+ if (retdat = krb_rd_priv(*ret_dat, (u_long)*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_long));
+ retdat = ntohl((u_long)retdat);
+ if (!(return_dat = (u_char *)malloc((unsigned)(mdat.app_length -
+ KADM_VERSIZE - sizeof(u_long)))))
+ RET_N_FREE2(KADM_NOMEM);
+ bcopy((char *) mdat.app_data + KADM_VERSIZE + sizeof(u_long),
+ (char *)return_dat,
+ (int)mdat.app_length - KADM_VERSIZE - sizeof(u_long));
+ free((char *)*ret_dat);
+ clear_secrets();
+ *ret_dat = return_dat;
+ *ret_siz = mdat.app_length - KADM_VERSIZE - sizeof(u_long);
+ return retdat;
+}
+
+/* takes in the sess_key and key_schedule and sets them appropriately */
+kadm_cli_keyd(s_k, s_s)
+des_cblock s_k; /* session key */
+des_key_schedule 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 = key_sched(s_k,s_s))
+ return(stat+krb_err_base);
+#endif
+ return KADM_SUCCESS;
+} /* This code "works" */
+
+static sigtype (*opipe)();
+
+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;
+}
+
+kadm_cli_disconn()
+{
+ (void) close(client_parm.admin_fd);
+ (void) signal(SIGPIPE, opipe);
+ return;
+}
+
+kadm_cli_out(dat, dat_len, ret_dat, ret_siz)
+u_char *dat;
+int dat_len;
+u_char **ret_dat;
+int *ret_siz;
+{
+ extern int errno;
+ 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;
+}
diff --git a/eBones/lib/libkadm/kadm_err.et b/eBones/lib/libkadm/kadm_err.et
new file mode 100644
index 0000000..9a04851
--- /dev/null
+++ b/eBones/lib/libkadm/kadm_err.et
@@ -0,0 +1,53 @@
+# $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v $
+# $Author: jtkohl $
+# $Header: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v 4.0 89/01/24 15:16:10 jtkohl 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: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v 4.0 89/01/24 15:16:10 jtkohl 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/eBones/lib/libkadm/kadm_stream.c b/eBones/lib/libkadm/kadm_stream.c
new file mode 100644
index 0000000..c5990a0
--- /dev/null
+++ b/eBones/lib/libkadm/kadm_stream.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Stream conversion functions for Kerberos administration server
+ */
+
+#ifndef lint
+#if 0
+static char rcsid_kadm_stream_c[] =
+"Header: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/kadm/RCS/kadm_stream.c,v 4.2 89/09/26 09:20:48 jtkohl Exp ";
+#endif
+static const char rcsid[] =
+ "$Id$";
+#endif lint
+
+/*
+ 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.h"
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+/*
+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
+*/
+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);
+}
+
+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 */
+}
+
+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;
+}
+
+vts_short(dat, st, loc)
+u_short dat; /* the attributes field */
+u_char **st; /* a base pointer to the stream */
+int loc; /* offset into the stream for current data */
+{
+ u_short temp; /* to hold the net order short */
+
+ temp = htons(dat); /* convert to network order */
+ *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_short)));
+ bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_short));
+ return sizeof(u_short);
+}
+
+vts_long(dat, st, loc)
+u_long dat; /* the attributes field */
+u_char **st; /* a base pointer to the stream */
+int loc; /* offset into the stream for current data */
+{
+ u_long temp; /* to hold the net order short */
+
+ temp = htonl(dat); /* convert to network order */
+ *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_long)));
+ bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_long));
+ return sizeof(u_long);
+}
+
+
+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;
+}
+
+/*
+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
+*/
+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;
+}
+
+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 */
+}
+
+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;
+}
+
+stv_short(st, dat, loc, maxlen)
+u_char *st; /* a base pointer to the stream */
+u_short *dat; /* the attributes field */
+int loc; /* offset into the stream for current data */
+int maxlen;
+{
+ u_short temp; /* to hold the net order short */
+
+ if (loc + sizeof(u_short) > maxlen)
+ return(-1);
+ bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_short));
+ *dat = ntohs(temp); /* convert to network order */
+ return sizeof(u_short);
+}
+
+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; /* to hold the net order short */
+
+ if (loc + sizeof(u_long) > maxlen)
+ return(-1);
+ bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_long));
+ *dat = ntohl(temp); /* convert to network order */
+ return sizeof(u_long);
+}
+
+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;
+}
+
diff --git a/eBones/lib/libkadm/kadm_supp.c b/eBones/lib/libkadm/kadm_supp.c
new file mode 100644
index 0000000..df97f17
--- /dev/null
+++ b/eBones/lib/libkadm/kadm_supp.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Support functions for Kerberos administration server & clients
+ */
+
+#ifndef lint
+#if 0
+static char rcsid_kadm_supp_c[] =
+"Header: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/kadm/RCS/kadm_supp.c,v 4.1 89/09/26 09:21:07 jtkohl Exp ";
+#endif
+static const char rcsid[] =
+ "$Id$";
+#endif lint
+
+/*
+ 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.h"
+#include "krb_db.h"
+
+/*
+prin_vals:
+ recieves : a vals structure
+*/
+prin_vals(vals)
+Kadm_vals *vals;
+{
+ printf("Info in Database for %s.%s:\n", vals->name, vals->instance);
+ printf(" Max Life: %d Exp Date: %s\n",vals->max_life,
+ asctime(localtime((long *)&vals->exp_date)));
+ printf(" Attribs: %.2x key: %u %u\n",vals->attributes,
+ vals->key_low, vals->key_high);
+}
+
+#ifdef notdef
+nierror(s)
+int s;
+{
+ extern char *error_message();
+ 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 */
+
+kadm_prin_to_vals(fields, new, old)
+u_char fields[FLDSZ];
+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_MAXLIFE, 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);
+ }
+}
+
+kadm_vals_to_prin(fields, new, old)
+u_char fields[FLDSZ];
+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/eBones/libkadm/EXPORTABLE b/eBones/libkadm/EXPORTABLE
new file mode 100644
index 0000000..e478483
--- /dev/null
+++ b/eBones/libkadm/EXPORTABLE
@@ -0,0 +1,4 @@
+The files in this directory are believed to be exportable.
+
+-GAWollman
+
diff --git a/eBones/libkadm/Makefile b/eBones/libkadm/Makefile
new file mode 100644
index 0000000..f587d5c
--- /dev/null
+++ b/eBones/libkadm/Makefile
@@ -0,0 +1,23 @@
+# $Id$
+
+LIB= kadm
+
+SRCS= kadm_err.c kadm_stream.c kadm_supp.c kadm_cli_wrap.c
+CFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/../include -I${KRBOBJDIR} -DPOSIX
+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
+
+beforeinstall:
+ -cd ${.CURDIR}; cmp -s kadm.h \
+ ${DESTDIR}/usr/include/kerberosIV/kadm.h || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 kadm.h \
+ ${DESTDIR}/usr/include/kerberosIV
+ -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/eBones/libkadm/kadm.h b/eBones/libkadm/kadm.h
new file mode 100644
index 0000000..66284f4
--- /dev/null
+++ b/eBones/libkadm/kadm.h
@@ -0,0 +1,140 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/include/RCS/kadm.h,v $
+ * $Author: jtkohl $
+ * Header: /afs/athena.mit.edu/astaff/project/kerberos/src/include/RCS/kadm.h,v 4.2 89/09/26 09:15:20 jtkohl Exp
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Definitions for Kerberos administration server & client
+ */
+
+#ifndef KADM_DEFS
+#define KADM_DEFS
+
+/*
+ * kadm.h
+ * Header file for the fourth attempt at an admin server
+ * Doug Church, December 28, 1989, MIT Project Athena
+ */
+
+/* for those broken Unixes without this defined... should be in sys/param.h */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <krb.h>
+#include <des.h>
+
+/* The global structures for the client and server */
+typedef struct {
+ struct sockaddr_in admin_addr;
+ struct sockaddr_in my_addr;
+ int my_addr_len;
+ int admin_fd; /* file descriptor for link to admin server */
+ char sname[ANAME_SZ]; /* the service name */
+ char sinst[INST_SZ]; /* the services instance */
+ char krbrlm[REALM_SZ];
+} Kadm_Client;
+
+typedef struct { /* status of the server, i.e the parameters */
+ int inter; /* Space for command line flags */
+ char *sysfile; /* filename of server */
+} admin_params; /* Well... it's the admin's parameters */
+
+/* Largest password length to be supported */
+#define MAX_KPW_LEN 128
+
+/* Largest packet the admin server will ever allow itself to return */
+#define KADM_RET_MAX 2048
+
+/* That's right, versions are 8 byte strings */
+#define KADM_VERSTR "KADM0.0A"
+#define KADM_ULOSE "KYOULOSE" /* sent back when server can't
+ decrypt client's msg */
+#define KADM_VERSIZE strlen(KADM_VERSTR)
+
+/* the lookups for the server instances */
+#define PWSERV_NAME "changepw"
+#define KADM_SNAME "kerberos_master"
+#define KADM_SINST "kerberos"
+
+/* Attributes fields constants and macros */
+#define ALLOC 2
+#define RESERVED 3
+#define DEALLOC 4
+#define DEACTIVATED 5
+#define ACTIVE 6
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ 4
+
+typedef struct {
+ u_char fields[FLDSZ]; /* The active fields in this struct */
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+ unsigned long key_low;
+ unsigned long key_high;
+ unsigned long exp_date;
+ unsigned short attributes;
+ unsigned char max_life;
+} Kadm_vals; /* The basic values structure in Kadm */
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ 4
+
+/* Need to define fields types here */
+#define KADM_NAME 31
+#define KADM_INST 30
+#define KADM_EXPDATE 29
+#define KADM_ATTR 28
+#define KADM_MAXLIFE 27
+#define KADM_DESKEY 26
+
+/* To set a field entry f in a fields structure d */
+#define SET_FIELD(f,d) (d[3-(f/8)]|=(1<<(f%8)))
+
+/* To set a field entry f in a fields structure d */
+#define CLEAR_FIELD(f,d) (d[3-(f/8)]&=(~(1<<(f%8))))
+
+/* Is field f in fields structure d */
+#define IS_FIELD(f,d) (d[3-(f/8)]&(1<<(f%8)))
+
+/* Various return codes */
+#define KADM_SUCCESS 0
+
+#define WILDCARD_STR "*"
+
+enum acl_types {
+ADDACL,
+GETACL,
+MODACL
+};
+
+/* Various opcodes for the admin server's functions */
+#define CHANGE_PW 2
+#define ADD_ENT 3
+#define MOD_ENT 4
+#define GET_ENT 5
+
+extern long kdb_get_master_key(); /* XXX should be in krb_db.h */
+extern long kdb_verify_master_key(); /* XXX ditto */
+
+extern long krb_mk_priv(), krb_rd_priv(); /* XXX should be in krb.h */
+extern void krb_set_tkt_string(); /* XXX ditto */
+
+extern unsigned long quad_cksum(); /* XXX should be in des.h */
+
+/* XXX This doesn't belong here!!! */
+char *malloc(), *realloc();
+#ifdef POSIX
+typedef void sigtype;
+#else
+typedef int sigtype;
+#endif
+
+#endif KADM_DEFS
diff --git a/eBones/libkadm/kadm_cli_wrap.c b/eBones/libkadm/kadm_cli_wrap.c
new file mode 100644
index 0000000..ca20601
--- /dev/null
+++ b/eBones/libkadm/kadm_cli_wrap.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Kerberos administration server client-side routines
+ */
+
+#ifndef lint
+#if 0
+static char rcsid_kadm_cli_wrap_c[] =
+"from: Id: kadm_cli_wrap.c,v 4.6 89/12/30 20:09:45 qjb Exp";
+#endif
+static const char rcsid[] =
+ "$Id$";
+#endif lint
+
+/*
+ * kadm_cli_wrap.c the client side wrapping of the calls to the admin server
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <kadm.h>
+#include <kadm_err.h>
+#include <krb_err.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 Key_schedule sess_sched;
+
+static
+clear_secrets()
+{
+ bzero((char *)sess_key, sizeof(sess_key));
+ bzero((char *)sess_sched, sizeof(sess_sched));
+ 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
+ */
+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 */
+
+/*
+ * 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
+ */
+kadm_change_pw(newkey)
+des_cblock 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_long 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
+ */
+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
+ */
+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
+ */
+kadm_get(vals, fl)
+Kadm_vals *vals;
+u_char fl[4];
+
+{
+ 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);
+}
+
+/*
+ * 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.
+ */
+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_long 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_long)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_long) (for the size indication) from total size */
+
+ act_len += vts_long((u_long) priv_len, &act_st, act_len);
+#ifdef NOENCRYPTION
+ cksum = 0;
+#else
+ cksum = quad_cksum(priv_pak, (u_long *)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_long errcode;
+ /* it's a youlose packet */
+ if (*ret_siz < KADM_VERSIZE + sizeof(u_long))
+ RET_N_FREE2(KADM_BAD_VER);
+ bcopy((char *)(*ret_dat) + KADM_VERSIZE, (char *)&errcode,
+ sizeof(u_long));
+ retdat = (int) ntohl(errcode);
+ RET_N_FREE2(retdat);
+ }
+ /* need to decode the ret_dat */
+ if (retdat = krb_rd_priv(*ret_dat, (u_long)*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_long));
+ retdat = ntohl((u_long)retdat);
+ if (!(return_dat = (u_char *)malloc((unsigned)(mdat.app_length -
+ KADM_VERSIZE - sizeof(u_long)))))
+ RET_N_FREE2(KADM_NOMEM);
+ bcopy((char *) mdat.app_data + KADM_VERSIZE + sizeof(u_long),
+ (char *)return_dat,
+ (int)mdat.app_length - KADM_VERSIZE - sizeof(u_long));
+ free((char *)*ret_dat);
+ clear_secrets();
+ *ret_dat = return_dat;
+ *ret_siz = mdat.app_length - KADM_VERSIZE - sizeof(u_long);
+ return retdat;
+}
+
+/* takes in the sess_key and key_schedule and sets them appropriately */
+kadm_cli_keyd(s_k, s_s)
+des_cblock s_k; /* session key */
+des_key_schedule 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 = key_sched(s_k,s_s))
+ return(stat+krb_err_base);
+#endif
+ return KADM_SUCCESS;
+} /* This code "works" */
+
+static sigtype (*opipe)();
+
+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;
+}
+
+kadm_cli_disconn()
+{
+ (void) close(client_parm.admin_fd);
+ (void) signal(SIGPIPE, opipe);
+ return;
+}
+
+kadm_cli_out(dat, dat_len, ret_dat, ret_siz)
+u_char *dat;
+int dat_len;
+u_char **ret_dat;
+int *ret_siz;
+{
+ extern int errno;
+ 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;
+}
diff --git a/eBones/libkadm/kadm_err.et b/eBones/libkadm/kadm_err.et
new file mode 100644
index 0000000..9a04851
--- /dev/null
+++ b/eBones/libkadm/kadm_err.et
@@ -0,0 +1,53 @@
+# $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v $
+# $Author: jtkohl $
+# $Header: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v 4.0 89/01/24 15:16:10 jtkohl 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: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v 4.0 89/01/24 15:16:10 jtkohl 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/eBones/libkadm/kadm_stream.c b/eBones/libkadm/kadm_stream.c
new file mode 100644
index 0000000..c5990a0
--- /dev/null
+++ b/eBones/libkadm/kadm_stream.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Stream conversion functions for Kerberos administration server
+ */
+
+#ifndef lint
+#if 0
+static char rcsid_kadm_stream_c[] =
+"Header: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/kadm/RCS/kadm_stream.c,v 4.2 89/09/26 09:20:48 jtkohl Exp ";
+#endif
+static const char rcsid[] =
+ "$Id$";
+#endif lint
+
+/*
+ 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.h"
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+/*
+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
+*/
+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);
+}
+
+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 */
+}
+
+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;
+}
+
+vts_short(dat, st, loc)
+u_short dat; /* the attributes field */
+u_char **st; /* a base pointer to the stream */
+int loc; /* offset into the stream for current data */
+{
+ u_short temp; /* to hold the net order short */
+
+ temp = htons(dat); /* convert to network order */
+ *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_short)));
+ bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_short));
+ return sizeof(u_short);
+}
+
+vts_long(dat, st, loc)
+u_long dat; /* the attributes field */
+u_char **st; /* a base pointer to the stream */
+int loc; /* offset into the stream for current data */
+{
+ u_long temp; /* to hold the net order short */
+
+ temp = htonl(dat); /* convert to network order */
+ *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_long)));
+ bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_long));
+ return sizeof(u_long);
+}
+
+
+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;
+}
+
+/*
+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
+*/
+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;
+}
+
+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 */
+}
+
+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;
+}
+
+stv_short(st, dat, loc, maxlen)
+u_char *st; /* a base pointer to the stream */
+u_short *dat; /* the attributes field */
+int loc; /* offset into the stream for current data */
+int maxlen;
+{
+ u_short temp; /* to hold the net order short */
+
+ if (loc + sizeof(u_short) > maxlen)
+ return(-1);
+ bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_short));
+ *dat = ntohs(temp); /* convert to network order */
+ return sizeof(u_short);
+}
+
+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; /* to hold the net order short */
+
+ if (loc + sizeof(u_long) > maxlen)
+ return(-1);
+ bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_long));
+ *dat = ntohl(temp); /* convert to network order */
+ return sizeof(u_long);
+}
+
+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;
+}
+
diff --git a/eBones/libkadm/kadm_supp.c b/eBones/libkadm/kadm_supp.c
new file mode 100644
index 0000000..df97f17
--- /dev/null
+++ b/eBones/libkadm/kadm_supp.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Support functions for Kerberos administration server & clients
+ */
+
+#ifndef lint
+#if 0
+static char rcsid_kadm_supp_c[] =
+"Header: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/kadm/RCS/kadm_supp.c,v 4.1 89/09/26 09:21:07 jtkohl Exp ";
+#endif
+static const char rcsid[] =
+ "$Id$";
+#endif lint
+
+/*
+ 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.h"
+#include "krb_db.h"
+
+/*
+prin_vals:
+ recieves : a vals structure
+*/
+prin_vals(vals)
+Kadm_vals *vals;
+{
+ printf("Info in Database for %s.%s:\n", vals->name, vals->instance);
+ printf(" Max Life: %d Exp Date: %s\n",vals->max_life,
+ asctime(localtime((long *)&vals->exp_date)));
+ printf(" Attribs: %.2x key: %u %u\n",vals->attributes,
+ vals->key_low, vals->key_high);
+}
+
+#ifdef notdef
+nierror(s)
+int s;
+{
+ extern char *error_message();
+ 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 */
+
+kadm_prin_to_vals(fields, new, old)
+u_char fields[FLDSZ];
+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_MAXLIFE, 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);
+ }
+}
+
+kadm_vals_to_prin(fields, new, old)
+u_char fields[FLDSZ];
+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;
+ }
+}
OpenPOWER on IntegriCloud