diff options
author | wollman <wollman@FreeBSD.org> | 1995-01-20 02:02:54 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1995-01-20 02:02:54 +0000 |
commit | c0e71984712cdfdc2d3befb12d640aea2c027f22 (patch) | |
tree | 2d4c68484fd0d5e51fe6f8e98eb79c47832b43ee /eBones | |
parent | 97daf1a19a1c37bb4730ac42ab08ca48e8d24a32 (diff) | |
download | FreeBSD-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/EXPORTABLE | 4 | ||||
-rw-r--r-- | eBones/lib/libkadm/Makefile | 23 | ||||
-rw-r--r-- | eBones/lib/libkadm/kadm.h | 140 | ||||
-rw-r--r-- | eBones/lib/libkadm/kadm_cli_wrap.c | 499 | ||||
-rw-r--r-- | eBones/lib/libkadm/kadm_err.et | 53 | ||||
-rw-r--r-- | eBones/lib/libkadm/kadm_stream.c | 273 | ||||
-rw-r--r-- | eBones/lib/libkadm/kadm_supp.c | 114 | ||||
-rw-r--r-- | eBones/libkadm/EXPORTABLE | 4 | ||||
-rw-r--r-- | eBones/libkadm/Makefile | 23 | ||||
-rw-r--r-- | eBones/libkadm/kadm.h | 140 | ||||
-rw-r--r-- | eBones/libkadm/kadm_cli_wrap.c | 499 | ||||
-rw-r--r-- | eBones/libkadm/kadm_err.et | 53 | ||||
-rw-r--r-- | eBones/libkadm/kadm_stream.c | 273 | ||||
-rw-r--r-- | eBones/libkadm/kadm_supp.c | 114 |
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; + } +} |