summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2svn <cvs2svn@FreeBSD.org>1995-09-15 20:15:11 +0000
committercvs2svn <cvs2svn@FreeBSD.org>1995-09-15 20:15:11 +0000
commitbfbc580797babffd502df152b40ad384c9638c2c (patch)
treed1b8ea42f49e396daa8df631fbbd15a1973c8fdc
parent93ecce1be0f50592ae4f2c3dc798a862c4fae52c (diff)
Notes
-rw-r--r--eBones/Makefile48
-rw-r--r--eBones/Makefile.inc65
-rw-r--r--eBones/des/3cbc_enc.c60
-rw-r--r--eBones/des/3ecb_enc.c35
-rw-r--r--eBones/des/Makefile27
-rw-r--r--eBones/des/enc_read.c150
-rw-r--r--eBones/des/enc_writ.c99
-rw-r--r--eBones/des/new_rnd_key.c207
-rw-r--r--eBones/des/rand_key.c49
-rw-r--r--eBones/include/Makefile19
-rw-r--r--eBones/include/des.h181
-rw-r--r--eBones/include/kparse.h91
-rw-r--r--eBones/include/krb.h504
-rw-r--r--eBones/include/krb_db.h110
-rw-r--r--eBones/include/rkinit.h42
-rw-r--r--eBones/include/rkinit_private.h106
-rw-r--r--eBones/lib/Makefile6
-rw-r--r--eBones/lib/Makefile.inc4
-rw-r--r--eBones/lib/libacl/Makefile12
-rw-r--r--eBones/lib/libacl/acl_files.c555
-rw-r--r--eBones/lib/libkadm/Makefile23
-rw-r--r--eBones/lib/libkadm/kadm.h164
-rw-r--r--eBones/lib/libkadm/kadm_cli_wrap.c509
-rw-r--r--eBones/lib/libkadm/kadm_err.et53
-rw-r--r--eBones/lib/libkadm/kadm_stream.c286
-rw-r--r--eBones/lib/libkadm/kadm_supp.c118
-rw-r--r--eBones/lib/libkdb/Makefile8
-rw-r--r--eBones/lib/libkdb/krb_cache.c181
-rw-r--r--eBones/lib/libkdb/krb_dbm.c789
-rw-r--r--eBones/lib/libkdb/krb_kdb_utils.c148
-rw-r--r--eBones/lib/libkdb/krb_lib.c242
-rw-r--r--eBones/lib/libkdb/print_princ.c51
-rw-r--r--eBones/lib/libkrb/Makefile53
-rw-r--r--eBones/lib/libkrb/add_ticket.c91
-rw-r--r--eBones/lib/libkrb/create_auth_reply.c118
-rw-r--r--eBones/lib/libkrb/create_ciph.c112
-rw-r--r--eBones/lib/libkrb/create_death_packet.c65
-rw-r--r--eBones/lib/libkrb/create_ticket.c132
-rw-r--r--eBones/lib/libkrb/debug_decl.c20
-rw-r--r--eBones/lib/libkrb/decomp_ticket.c126
-rw-r--r--eBones/lib/libkrb/des_rw.c262
-rw-r--r--eBones/lib/libkrb/dest_tkt.c92
-rw-r--r--eBones/lib/libkrb/extract_ticket.c61
-rw-r--r--eBones/lib/libkrb/fgetst.c42
-rw-r--r--eBones/lib/libkrb/get_ad_tkt.c237
-rw-r--r--eBones/lib/libkrb/get_admhst.c82
-rw-r--r--eBones/lib/libkrb/get_cred.c63
-rw-r--r--eBones/lib/libkrb/get_in_tkt.c286
-rw-r--r--eBones/lib/libkrb/get_krbhst.c87
-rw-r--r--eBones/lib/libkrb/get_krbrlm.c62
-rw-r--r--eBones/lib/libkrb/get_phost.c55
-rw-r--r--eBones/lib/libkrb/get_pw_tkt.c75
-rw-r--r--eBones/lib/libkrb/get_request.c55
-rw-r--r--eBones/lib/libkrb/get_svc_in_tkt.c77
-rw-r--r--eBones/lib/libkrb/get_tf_fullname.c69
-rw-r--r--eBones/lib/libkrb/get_tf_realm.c37
-rw-r--r--eBones/lib/libkrb/getrealm.c106
-rw-r--r--eBones/lib/libkrb/getst.c41
-rw-r--r--eBones/lib/libkrb/in_tkt.c146
-rw-r--r--eBones/lib/libkrb/k_gethostname.c71
-rw-r--r--eBones/lib/libkrb/klog.c110
-rw-r--r--eBones/lib/libkrb/kname_parse.c239
-rw-r--r--eBones/lib/libkrb/kntoln.c63
-rw-r--r--eBones/lib/libkrb/kparse.c776
-rw-r--r--eBones/lib/libkrb/krb.3462
-rw-r--r--eBones/lib/libkrb/krb_err.et257
-rw-r--r--eBones/lib/libkrb/krb_err_txt.c280
-rw-r--r--eBones/lib/libkrb/krb_get_in_tkt.c301
-rw-r--r--eBones/lib/libkrb/krb_realmofhost.3161
-rw-r--r--eBones/lib/libkrb/krb_sendauth.3348
-rw-r--r--eBones/lib/libkrb/krbglue.c258
-rw-r--r--eBones/lib/libkrb/kuserok.c199
-rw-r--r--eBones/lib/libkrb/log.c125
-rw-r--r--eBones/lib/libkrb/mk_err.c65
-rw-r--r--eBones/lib/libkrb/mk_priv.c207
-rw-r--r--eBones/lib/libkrb/mk_req.c198
-rw-r--r--eBones/lib/libkrb/mk_safe.c171
-rw-r--r--eBones/lib/libkrb/month_sname.c33
-rw-r--r--eBones/lib/libkrb/netread.c50
-rw-r--r--eBones/lib/libkrb/netwrite.c46
-rw-r--r--eBones/lib/libkrb/one.c22
-rw-r--r--eBones/lib/libkrb/pkt_cipher.c40
-rw-r--r--eBones/lib/libkrb/pkt_clen.c58
-rw-r--r--eBones/lib/libkrb/rd_err.c82
-rw-r--r--eBones/lib/libkrb/rd_priv.c207
-rw-r--r--eBones/lib/libkrb/rd_req.c331
-rw-r--r--eBones/lib/libkrb/rd_safe.c183
-rw-r--r--eBones/lib/libkrb/read_service_key.c124
-rw-r--r--eBones/lib/libkrb/recvauth.c290
-rw-r--r--eBones/lib/libkrb/save_credentials.c56
-rw-r--r--eBones/lib/libkrb/send_to_kdc.c391
-rw-r--r--eBones/lib/libkrb/sendauth.c259
-rw-r--r--eBones/lib/libkrb/stime.c43
-rw-r--r--eBones/lib/libkrb/tf_shm.c176
-rw-r--r--eBones/lib/libkrb/tf_util.c581
-rw-r--r--eBones/lib/libkrb/tkt_string.c80
-rw-r--r--eBones/lib/libkrb/util.c75
-rw-r--r--eBones/lib/librkinit/Makefile19
-rw-r--r--eBones/lib/librkinit/rk_krb.c316
-rw-r--r--eBones/lib/librkinit/rk_lib.c100
-rw-r--r--eBones/lib/librkinit/rk_rpc.c387
-rw-r--r--eBones/lib/librkinit/rk_util.c214
-rw-r--r--eBones/lib/librkinit/rkinit.3167
-rw-r--r--eBones/lib/librkinit/rkinit_err.et32
-rw-r--r--eBones/libexec/Makefile6
-rw-r--r--eBones/libexec/Makefile.inc5
-rw-r--r--eBones/libexec/kpropd/Makefile10
-rw-r--r--eBones/libexec/kpropd/kpropd.c453
-rw-r--r--eBones/libexec/registerd/Makefile18
-rw-r--r--eBones/libexec/registerd/registerd.c355
-rw-r--r--eBones/libexec/rkinitd/Makefile12
-rw-r--r--eBones/libexec/rkinitd/krb.c388
-rw-r--r--eBones/libexec/rkinitd/rkinitd.842
-rw-r--r--eBones/libexec/rkinitd/rkinitd.c137
-rw-r--r--eBones/libexec/rkinitd/rkinitd.h34
-rw-r--r--eBones/libexec/rkinitd/rpc.c222
-rw-r--r--eBones/libexec/rkinitd/util.c49
-rw-r--r--eBones/man/Makefile10
-rw-r--r--eBones/usr.bin/Makefile6
-rw-r--r--eBones/usr.bin/Makefile.inc5
-rw-r--r--eBones/usr.bin/kadmin/Makefile16
-rw-r--r--eBones/usr.bin/kadmin/kadmin.c636
-rw-r--r--eBones/usr.bin/kadmin/kadmin_cmds.ct41
-rw-r--r--eBones/usr.bin/kdestroy/Makefile10
-rw-r--r--eBones/usr.bin/kdestroy/kdestroy.c83
-rw-r--r--eBones/usr.bin/kinit/Makefile10
-rw-r--r--eBones/usr.bin/kinit/kinit.c224
-rw-r--r--eBones/usr.bin/klist/Makefile10
-rw-r--r--eBones/usr.bin/klist/klist.c288
-rw-r--r--eBones/usr.bin/ksrvtgt/Makefile10
-rw-r--r--eBones/usr.bin/ksrvtgt/ksrvtgt.c62
-rw-r--r--eBones/usr.bin/passwd/kpasswd.c223
-rw-r--r--eBones/usr.bin/register/Makefile11
-rw-r--r--eBones/usr.bin/register/register.c316
-rw-r--r--eBones/usr.bin/rkinit/Makefile11
-rw-r--r--eBones/usr.bin/rkinit/rkinit.1206
-rw-r--r--eBones/usr.bin/rkinit/rkinit.c216
-rw-r--r--eBones/usr.sbin/Makefile7
-rw-r--r--eBones/usr.sbin/Makefile.inc5
-rw-r--r--eBones/usr.sbin/ext_srvtab/Makefile10
-rw-r--r--eBones/usr.sbin/ext_srvtab/ext_srvtab.c176
-rw-r--r--eBones/usr.sbin/kadmind/Makefile10
-rw-r--r--eBones/usr.sbin/kadmind/admin_server.c474
-rw-r--r--eBones/usr.sbin/kadmind/kadm_funcs.c381
-rw-r--r--eBones/usr.sbin/kadmind/kadm_ser_wrap.c213
-rw-r--r--eBones/usr.sbin/kadmind/kadm_server.c167
-rw-r--r--eBones/usr.sbin/kadmind/kadm_server.h70
-rw-r--r--eBones/usr.sbin/kdb_destroy/Makefile8
-rw-r--r--eBones/usr.sbin/kdb_destroy/kdb_destroy.c66
-rw-r--r--eBones/usr.sbin/kdb_edit/Makefile11
-rw-r--r--eBones/usr.sbin/kdb_edit/kdb_edit.c477
-rw-r--r--eBones/usr.sbin/kdb_edit/maketime.c85
-rw-r--r--eBones/usr.sbin/kdb_init/Makefile10
-rw-r--r--eBones/usr.sbin/kdb_init/kdb_init.c180
-rw-r--r--eBones/usr.sbin/kdb_util/Makefile12
-rw-r--r--eBones/usr.sbin/kdb_util/kdb_util.c523
-rw-r--r--eBones/usr.sbin/kerberos/Makefile11
-rw-r--r--eBones/usr.sbin/kerberos/cr_err_reply.c97
-rw-r--r--eBones/usr.sbin/kerberos/kerberos.c816
-rw-r--r--eBones/usr.sbin/kprop/Makefile9
-rw-r--r--eBones/usr.sbin/kprop/kprop.c637
-rw-r--r--eBones/usr.sbin/kprop/kprop.h55
-rw-r--r--eBones/usr.sbin/ksrvutil/Makefile10
-rw-r--r--eBones/usr.sbin/ksrvutil/ksrvutil.c582
-rw-r--r--eBones/usr.sbin/kstash/Makefile10
-rw-r--r--eBones/usr.sbin/kstash/kstash.c94
-rw-r--r--eBones/usr.sbin/make_keypair/Makefile10
-rw-r--r--eBones/usr.sbin/make_keypair/make_keypair.c134
-rw-r--r--share/doc/FAQ/Makefile6
-rw-r--r--share/doc/handbook/Makefile12
-rw-r--r--share/doc/handbook/boothelp.sgml50
-rw-r--r--share/doc/handbook/contrib.sgml300
-rw-r--r--share/doc/handbook/hw.sgml319
-rw-r--r--share/doc/handbook/mirrors.sgml410
-rw-r--r--share/doc/handbook/sections.sgml38
-rwxr-xr-xshare/examples/startslip/sldown.sh3
-rwxr-xr-xshare/examples/startslip/slip.sh4
-rwxr-xr-xshare/examples/startslip/slup.sh16
-rw-r--r--share/man/man4/man4.i386/asc.4179
-rw-r--r--share/man/man4/man4.i386/meteor.4771
-rw-r--r--share/mk/bsd.sgml.mk151
-rw-r--r--sys/gnu/i386/isa/dgb.c2076
-rw-r--r--sys/gnu/i386/isa/dgbios.h175
-rw-r--r--sys/gnu/i386/isa/dgfep.h516
-rw-r--r--sys/gnu/i386/isa/dgreg.h366
-rw-r--r--sys/i386/include/asc_ioctl.h52
-rw-r--r--sys/i386/include/si.h525
-rw-r--r--sys/i386/isa/asc.c862
-rw-r--r--sys/i386/isa/ascreg.h96
-rw-r--r--sys/pci/meteor.c1245
-rw-r--r--usr.bin/ee/nls/fr_FR.ISO_8859-1/ee.msg170
191 files changed, 34064 insertions, 0 deletions
diff --git a/eBones/Makefile b/eBones/Makefile
new file mode 100644
index 0000000000000..8b0b6187903c7
--- /dev/null
+++ b/eBones/Makefile
@@ -0,0 +1,48 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id$
+
+SUBDIR= des include lib libexec usr.bin usr.sbin
+
+SDIR= ${.CURDIR}/..
+
+CODAI= ${MAKE} ${MFLAGS} cleandir; \
+ ${MAKE} ${MFLAGS} obj; \
+ ${MAKE} ${MFLAGS} depend all install
+
+CODAD= ${MAKE} ${MFLAGS} MAKE_EBONES=yes cleandir; \
+ ${MAKE} ${MFLAGS} MAKE_EBONES=yes obj; \
+ ${MAKE} ${MFLAGS} MAKE_EBONES=yes depend all distribute
+
+# These are the programs which depend on kerberos
+kprog:
+ cd ${SDIR}/bin/rcp; ${CODAI}
+ cd ${SDIR}/libexec/rlogind; ${CODAI}
+ cd ${SDIR}/libexec/rshd; ${CODAI}
+ cd ${SDIR}/sbin/mount_nfs; ${CODAI}
+ cd ${SDIR}/sbin/nfsd; ${CODAI}
+ cd ${SDIR}/usr.bin/login; ${CODAI}
+ cd ${SDIR}/usr.bin/passwd; ${CODAI}
+ cd ${SDIR}/usr.bin/rlogin; ${CODAI}
+ cd ${SDIR}/usr.bin/rsh; ${CODAI}
+ cd ${SDIR}/usr.bin/su; ${CODAI}
+
+bootstrap:
+ ( cd include; ${MAKE} ${MFLAGS} install )
+ ( cd des; ${MAKE} ${MFLAGS} depend all install )
+ ${MAKE} ${MFLAGS} cleandir
+ ${MAKE} ${MFLAGS} obj
+ ${MAKE} ${MFLAGS} depend all install kprog
+
+help-distribute: distribute
+ cd ${SDIR}/bin/rcp; ${CODAD}
+ cd ${SDIR}/libexec/rlogind; ${CODAD}
+ cd ${SDIR}/libexec/rshd; ${CODAD}
+ cd ${SDIR}/sbin/mount_nfs; ${CODAD}
+ cd ${SDIR}/sbin/nfsd; ${CODAD}
+ cd ${SDIR}/usr.bin/login; ${CODAD}
+ cd ${SDIR}/usr.bin/passwd; ${CODAD}
+ cd ${SDIR}/usr.bin/rlogin; ${CODAD}
+ cd ${SDIR}/usr.bin/rsh; ${CODAD}
+ cd ${SDIR}/usr.bin/su; ${CODAD}
+
+.include <bsd.subdir.mk>
diff --git a/eBones/Makefile.inc b/eBones/Makefile.inc
new file mode 100644
index 0000000000000..1dc84372bfe00
--- /dev/null
+++ b/eBones/Makefile.inc
@@ -0,0 +1,65 @@
+# From: @(#)Makefile.inc 5.1 (Berkeley) 6/25/90
+# $Id: Makefile.inc,v 1.8 1995/09/14 18:16:08 gibbs Exp $
+
+DISTRIBUTION= krb
+
+INCLUDEDIR= ${.CURDIR}/../../include
+
+.if exists(${.CURDIR}/../../des/obj)
+DESOBJDIR= ${.CURDIR}/../../des/obj
+.else
+DESOBJDIR= ${.CURDIR}/../../des
+.endif
+
+.if exists(${.CURDIR}/../../lib/libkrb/obj)
+KRBOBJDIR= ${.CURDIR}/../../lib/libkrb/obj
+.else
+KRBOBJDIR= ${.CURDIR}/../../lib/libkrb
+.endif
+
+.if exists(${.CURDIR}/../../lib/libkdb/obj)
+KDBOBJDIR= ${.CURDIR}/../../lib/libkdb/obj
+.else
+KDBOBJDIR= ${.CURDIR}/../../lib/libkdb
+.endif
+
+.if exists(${.CURDIR}/../../lib/libacl/obj)
+ACLOBJDIR= ${.CURDIR}/../../lib/libacl/obj
+.else
+ACLOBJDIR= ${.CURDIR}/../../lib/libacl
+.endif
+
+.if exists(${.CURDIR}/../../lib/libkadm/obj)
+KADMOBJDIR= ${.CURDIR}/../../lib/libkadm/obj
+.else
+KADMOBJDIR= ${.CURDIR}/../../lib/libkadm
+.endif
+
+.if exists(${.CURDIR}/../../lib/librkinit/obj)
+RKINITOBJDIR= ${.CURDIR}/../../lib/librkinit/obj
+.else
+RKINITOBJDIR= ${.CURDIR}/../../lib/librkinit
+.endif
+
+CFLAGS+= -I${INCLUDEDIR} -Wall
+
+COMPILE_ET= compile_et
+
+${KRBOBJDIR}/krb_err.h: ${.CURDIR}/../../lib/libkrb/krb_err.et
+ test -e ${KRBOBJDIR}/krb_err.et || ln -s ${.ALLSRC} ${KRBOBJDIR}
+ cd ${KRBOBJDIR}; compile_et krb_err.et
+
+CLEANFILES+=${KRBOBJDIR}/krb_err.h ${KRBOBJDIR}/krb_err.c
+
+${KADMOBJDIR}/kadm_err.h: ${.CURDIR}/../../lib/libkadm/kadm_err.et
+ test -e ${KADMOBJDIR}/kadm_err.et || ln -s ${.ALLSRC} ${KADMOBJDIR}
+ cd ${KADMOBJDIR}; compile_et kadm_err.et
+
+CLEANFILES+=${KADMOBJDIR}/kadm_err.h ${KADMOBJDIR}/kadm_err.c
+
+${RKINITOBJDIR}/rkinit_err.h: ${.CURDIR}/../../lib/librkinit/rkinit_err.et
+ test -e ${RKINITOBJDIR}/rkinit_err.et || \
+ ln -s ${.ALLSRC} ${RKINITOBJDIR}
+ cd ${RKINITOBJDIR}; compile_et rkinit_err.et
+
+CLEANFILES+=${RKINITOBJDIR}/rkinit_err.h ${RKINITOBJDIR}/rkinit_err.c
diff --git a/eBones/des/3cbc_enc.c b/eBones/des/3cbc_enc.c
new file mode 100644
index 0000000000000..1f64502e99541
--- /dev/null
+++ b/eBones/des/3cbc_enc.c
@@ -0,0 +1,60 @@
+/* 3cbc_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: 3cbc_enc.c,v 1.1.1.1 1994/09/30 14:49:50 csgr Exp $
+ */
+
+#include "des_locl.h"
+
+void
+xp(a)
+unsigned char *a;
+{ int i; for(i=0; i<8; i++) printf("%02X",a[i]);printf("\n");}
+
+int des_3cbc_encrypt(input,output,length,ks1,ks2,iv1,iv2,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule ks1,ks2;
+des_cblock *iv1,*iv2;
+int encrypt;
+ {
+ int off=length/8-1;
+ des_cblock niv1,niv2;
+
+printf("3cbc\n");
+xp(iv1);
+xp(iv1);
+xp(iv2);
+xp(input);
+ if (encrypt == DES_ENCRYPT)
+ {
+ des_cbc_encrypt(input,output,length,ks1,iv1,encrypt);
+ if (length >= sizeof(des_cblock))
+ bcopy(output[off],niv1,sizeof(des_cblock));
+ des_cbc_encrypt(output,output,length,ks2,iv1,!encrypt);
+ des_cbc_encrypt(output,output,length,ks1,iv2, encrypt);
+ if (length >= sizeof(des_cblock))
+ bcopy(output[off],niv2,sizeof(des_cblock));
+ bcopy(niv1,*iv1,sizeof(des_cblock));
+ }
+ else
+ {
+ if (length >= sizeof(des_cblock))
+ bcopy(input[off],niv1,sizeof(des_cblock));
+ des_cbc_encrypt(input,output,length,ks1,iv1,encrypt);
+ des_cbc_encrypt(output,output,length,ks2,iv2,!encrypt);
+ if (length >= sizeof(des_cblock))
+ bcopy(output[off],niv2,sizeof(des_cblock));
+ des_cbc_encrypt(output,output,length,ks1,iv2, encrypt);
+ }
+ bcopy(niv1,iv1,sizeof(des_cblock));
+ bcopy(niv2,iv2,sizeof(des_cblock));
+xp(iv1);
+xp(iv1);
+xp(iv2);
+xp(output);
+ return(0);
+ }
+
diff --git a/eBones/des/3ecb_enc.c b/eBones/des/3ecb_enc.c
new file mode 100644
index 0000000000000..4bd22865c6a9d
--- /dev/null
+++ b/eBones/des/3ecb_enc.c
@@ -0,0 +1,35 @@
+/* 3ecb_enc.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: 3ecb_enc.c,v 1.1.1.1 1994/09/30 14:49:50 csgr Exp $
+ */
+
+#include "des_locl.h"
+
+int des_3ecb_encrypt(input,output,ks1,ks2,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule ks1,ks2;
+int encrypt;
+ {
+ register unsigned long l0,l1;
+ register unsigned char *in,*out;
+ unsigned long ll[2];
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ c2l(in,l0);
+ c2l(in,l1);
+ ll[0]=l0;
+ ll[1]=l1;
+ des_encrypt(ll,ll,ks1,encrypt);
+ des_encrypt(ll,ll,ks2,!encrypt);
+ des_encrypt(ll,ll,ks1,encrypt);
+ l0=ll[0];
+ l1=ll[1];
+ l2c(l0,out);
+ l2c(l1,out);
+ return(0);
+ }
+
diff --git a/eBones/des/Makefile b/eBones/des/Makefile
new file mode 100644
index 0000000000000..af0859192d5dc
--- /dev/null
+++ b/eBones/des/Makefile
@@ -0,0 +1,27 @@
+# @(#)Makefile 5.4 (Berkeley) 5/7/91
+# $Id: Makefile,v 1.4 1995/09/14 18:16:11 gibbs Exp $
+
+LIB= des
+SRCS= cbc_cksm.c cbc_enc.c ecb_enc.c enc_read.c enc_writ.c pcbc_enc.c \
+ qud_cksm.c rand_key.c read_pwd.c set_key.c str2key.c \
+ cfb_enc.c 3ecb_enc.c ofb_enc.c 3cbc_enc.c new_rnd_key.c
+#MAN1= des.1
+#MAN3= des.3
+
+#LINKS= crypt
+CFLAGS+= -DDES_ENCRYPT -DKRBDES_ENCRYPT
+
+# Kerberos 4?
+#CFLAGS+=-DKRB4
+#SRCS+= kerberos.c
+
+# Kerberos 5?
+#CFLAGS+= -DKRB5
+#SRCS+= kerberos5.c
+
+CFLAGS+= -I${.CURDIR}/include -I${.CURDIR}/../include -DAUTHENTICATE
+SHLIB_MAJOR?= 2
+SHLIB_MINOR?= 0
+
+.include "/usr/src/lib/Makefile.inc"
+.include <bsd.lib.mk>
diff --git a/eBones/des/enc_read.c b/eBones/des/enc_read.c
new file mode 100644
index 0000000000000..ffd3ba977549c
--- /dev/null
+++ b/eBones/des/enc_read.c
@@ -0,0 +1,150 @@
+/* enc_read.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: enc_read.c,v 1.2 1995/05/30 06:40:11 rgrimes Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <errno.h>
+#include "des_locl.h"
+
+/* This has some uglies in it but it works - even over sockets. */
+extern int errno;
+int des_rw_mode=DES_PCBC_MODE;
+
+int des_enc_read(fd,buf,len,sched,iv)
+int fd;
+char *buf;
+int len;
+des_key_schedule sched;
+des_cblock *iv;
+ {
+ /* data to be unencrypted */
+ int net_num=0;
+ unsigned char net[BSIZE];
+ /* extra unencrypted data
+ * for when a block of 100 comes in but is des_read one byte at
+ * a time. */
+ static char unnet[BSIZE];
+ static int unnet_start=0;
+ static int unnet_left=0;
+ int i;
+ long num=0,rnum;
+ unsigned char *p;
+
+ /* left over data from last decrypt */
+ if (unnet_left != 0)
+ {
+ if (unnet_left < len)
+ {
+ /* we still still need more data but will return
+ * with the number of bytes we have - should always
+ * check the return value */
+ bcopy(&(unnet[unnet_start]),buf,unnet_left);
+ /* eay 26/08/92 I had the next 2 lines
+ * reversed :-( */
+ i=unnet_left;
+ unnet_start=unnet_left=0;
+ }
+ else
+ {
+ bcopy(&(unnet[unnet_start]),buf,len);
+ unnet_start+=len;
+ unnet_left-=len;
+ i=len;
+ }
+ return(i);
+ }
+
+ /* We need to get more data. */
+ if (len > MAXWRITE) len=MAXWRITE;
+
+ /* first - get the length */
+ net_num=0;
+ while (net_num < HDRSIZE)
+ {
+ i=read(fd,&(net[net_num]),HDRSIZE-net_num);
+ if ((i == -1) && (errno == EINTR)) continue;
+ if (i <= 0) return(0);
+ net_num+=i;
+ }
+
+ /* we now have at net_num bytes in net */
+ p=net;
+ num=0;
+ n2l(p,num);
+ /* num should be rounded up to the next group of eight
+ * we make sure that we have read a multiple of 8 bytes from the net.
+ */
+ if ((num > MAXWRITE) || (num < 0)) /* error */
+ return(-1);
+ rnum=(num < 8)?8:((num+7)/8*8);
+
+ net_num=0;
+ while (net_num < rnum)
+ {
+ i=read(fd,&(net[net_num]),rnum-net_num);
+ if ((i == -1) && (errno == EINTR)) continue;
+ if (i <= 0) return(0);
+ net_num+=i;
+ }
+
+ /* Check if there will be data left over. */
+ if (len < num)
+ {
+ if (des_rw_mode & DES_PCBC_MODE)
+ pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
+ num,sched,iv,DES_DECRYPT);
+ else
+ cbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
+ num,sched,iv,DES_DECRYPT);
+ bcopy(unnet,buf,len);
+ unnet_start=len;
+ unnet_left=num-len;
+
+ /* The following line is done because we return num
+ * as the number of bytes read. */
+ num=len;
+ }
+ else
+ {
+ /* >output is a multiple of 8 byes, if len < rnum
+ * >we must be careful. The user must be aware that this
+ * >routine will write more bytes than he asked for.
+ * >The length of the buffer must be correct.
+ * FIXED - Should be ok now 18-9-90 - eay */
+ if (len < rnum)
+ {
+ char tmpbuf[BSIZE];
+
+ if (des_rw_mode & DES_PCBC_MODE)
+ pcbc_encrypt((des_cblock *)net,
+ (des_cblock *)tmpbuf,
+ num,sched,iv,DES_DECRYPT);
+ else
+ cbc_encrypt((des_cblock *)net,
+ (des_cblock *)tmpbuf,
+ num,sched,iv,DES_DECRYPT);
+
+ /* eay 26/08/92 fix a bug that returned more
+ * bytes than you asked for (returned len bytes :-( */
+ bcopy(tmpbuf,buf,num);
+ }
+ else
+ {
+ if (des_rw_mode & DES_PCBC_MODE)
+ pcbc_encrypt((des_cblock *)net,
+ (des_cblock *)buf,num,sched,iv,
+ DES_DECRYPT);
+ else
+ cbc_encrypt((des_cblock *)net,
+ (des_cblock *)buf,num,sched,iv,
+ DES_DECRYPT);
+ }
+ }
+ return(num);
+ }
+
diff --git a/eBones/des/enc_writ.c b/eBones/des/enc_writ.c
new file mode 100644
index 0000000000000..e820e1fd3cb49
--- /dev/null
+++ b/eBones/des/enc_writ.c
@@ -0,0 +1,99 @@
+/* enc_writ.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: enc_writ.c,v 1.2 1995/05/30 06:40:12 rgrimes Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+#include "des_locl.h"
+
+int des_enc_write(fd,buf,len,sched,iv)
+int fd;
+char *buf;
+int len;
+des_key_schedule sched;
+des_cblock *iv;
+ {
+ long rnum;
+ int i,j,k,outnum;
+ char outbuf[BSIZE+HDRSIZE];
+ char shortbuf[8];
+ char *p;
+ static int start=1;
+
+ /* If we are sending less than 8 bytes, the same char will look
+ * the same if we don't pad it out with random bytes */
+ if (start)
+ {
+ start=0;
+ srandom(time(NULL));
+ }
+
+ /* lets recurse if we want to send the data in small chunks */
+ if (len > MAXWRITE)
+ {
+ j=0;
+ for (i=0; i<len; i+=k)
+ {
+ k=des_enc_write(fd,&(buf[i]),
+ ((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv);
+ if (k < 0)
+ return(k);
+ else
+ j+=k;
+ }
+ return(j);
+ }
+
+ /* write length first */
+ p=outbuf;
+ l2n(len,p);
+
+ /* pad short strings */
+ if (len < 8)
+ {
+ p=shortbuf;
+ bcopy(buf,shortbuf,len);
+ for (i=len; i<8; i++)
+ shortbuf[i]=random();
+ rnum=8;
+ }
+ else
+ {
+ p=buf;
+ rnum=((len+7)/8*8); /* round up to nearest eight */
+ }
+
+ if (des_rw_mode & DES_PCBC_MODE)
+ pcbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]),
+ (long)((len<8)?8:len),sched,iv,DES_ENCRYPT);
+ else
+ cbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]),
+ (long)((len<8)?8:len),sched,iv,DES_ENCRYPT);
+
+ /* output */
+ outnum=rnum+HDRSIZE;
+
+ for (j=0; j<outnum; j+=i)
+ {
+ /* eay 26/08/92 I was not doing writing from where we
+ * got upto. */
+ i=write(fd,&(outbuf[j]),(int)(outnum-j));
+ if (i == -1)
+ {
+ if (errno == EINTR)
+ i=0;
+ else /* This is really a bad error - very bad
+ * It will stuff-up both ends. */
+ return(-1);
+ }
+ }
+
+ return(len);
+ }
diff --git a/eBones/des/new_rnd_key.c b/eBones/des/new_rnd_key.c
new file mode 100644
index 0000000000000..18335289b4faf
--- /dev/null
+++ b/eBones/des/new_rnd_key.c
@@ -0,0 +1,207 @@
+/*
+ * $Source: /home/ncvs/src/eBones/des/new_rnd_key.c,v $
+ * $Author: rgrimes $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * New pseudo-random key generator, using DES encryption to make the
+ * pseudo-random cycle as hard to break as DES.
+ *
+ * Written by Mark Lillibridge, MIT Project Athena
+ *
+ * Under U.S. law, this software may not be exported outside the US
+ * without license from the U.S. Commerce department.
+ */
+
+#ifndef lint
+static char rcsid_new_rnd_key_c[] =
+"$Header: /home/ncvs/src/eBones/des/new_rnd_key.c,v 1.1.1.1 1994/05/27 05:12:12 rgrimes Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+
+#include <des.h>
+#include "des_locl.h"
+
+void des_set_random_generator_seed(), des_set_sequence_number();
+void des_generate_random_block();
+
+/*
+ * des_new_random_key: create a random des key
+ *
+ * Requires: des_set_random_number_generater_seed must be at called least
+ * once before this routine is called.
+ *
+ * Notes: the returned key has correct parity and is guarenteed not
+ * to be a weak des key. Des_generate_random_block is used to
+ * provide the random bits.
+ */
+int
+des_new_random_key(key)
+ des_cblock *key;
+{
+ do {
+ des_generate_random_block(key);
+ des_fixup_key_parity(key);
+ } while (des_is_weak_key(key));
+
+ return(0);
+}
+
+/*
+ * des_init_random_number_generator:
+ *
+ * This routine takes a secret key possibly shared by a number
+ * of servers and uses it to generate a random number stream that is
+ * not shared by any of the other servers. It does this by using the current
+ * process id, host id, and the current time to the nearest second. The
+ * resulting stream seed is not useful information for cracking the secret
+ * key. Moreover, this routine keeps no copy of the secret key.
+ * This routine is used for example, by the kerberos server(s) with the
+ * key in question being the kerberos master key.
+ *
+ * Note: this routine calls des_set_random_generator_seed.
+ */
+#if NOTBSDUNIX
+ you lose... (aka, you get to implement an analog of this for your
+ system...)
+#else
+
+#include <sys/time.h>
+
+void des_init_random_number_generator(key)
+ des_cblock *key;
+{
+ struct { /* This must be 64 bits exactly */
+ long process_id;
+ long host_id;
+ } seed;
+ struct timeval time; /* this must also be 64 bits exactly */
+ des_cblock new_key;
+ long gethostid();
+
+ /*
+ * use a host id and process id in generating the seed to ensure
+ * that different servers have different streams:
+ */
+ seed.host_id = gethostid();
+ seed.process_id = getpid();
+
+ /*
+ * Generate a tempory value that depends on the key, host_id, and
+ * process_id such that it gives no useful information about the key:
+ */
+ des_set_random_generator_seed(key);
+ des_set_sequence_number((unsigned char *)&seed);
+ des_new_random_key(&new_key);
+
+ /*
+ * use it to select a random stream:
+ */
+ des_set_random_generator_seed(&new_key);
+
+ /*
+ * use a time stamp to ensure that a server started later does not reuse
+ * an old stream:
+ */
+ gettimeofday(&time, (struct timezone *)0);
+ des_set_sequence_number((unsigned char *)&time);
+
+ /*
+ * use the time stamp finally to select the final seed using the
+ * current random number stream:
+ */
+ des_new_random_key(&new_key);
+ des_set_random_generator_seed(&new_key);
+}
+
+#endif /* ifdef BSDUNIX */
+
+/*
+ * This module implements a random number generator faculty such that the next
+ * number in any random number stream is very hard to predict without knowing
+ * the seed for that stream even given the preceeding random numbers.
+ */
+
+/*
+ * The secret des key schedule for the current stream of random numbers:
+ */
+static des_key_schedule random_sequence_key;
+
+/*
+ * The sequence # in the current stream of random numbers:
+ */
+static unsigned char sequence_number[8];
+
+/*
+ * des_set_random_generator_seed: this routine is used to select a random
+ * number stream. The stream that results is
+ * totally determined by the passed in key.
+ * (I.e., calling this routine again with the
+ * same key allows repeating a sequence of
+ * random numbers)
+ *
+ * Requires: key is a valid des key. I.e., has correct parity and is not a
+ * weak des key.
+ */
+void
+des_set_random_generator_seed(key)
+ des_cblock *key;
+{
+ register int i;
+
+ /* select the new stream: (note errors are not possible here...) */
+ des_key_sched(key, random_sequence_key);
+
+ /* "seek" to the start of the stream: */
+ for (i=0; i<8; i++)
+ sequence_number[i] = 0;
+}
+
+/*
+ * des_set_sequence_number: this routine is used to set the sequence number
+ * of the current random number stream. This routine
+ * may be used to "seek" within the current random
+ * number stream.
+ *
+ * Note that des_set_random_generator_seed resets the sequence number to 0.
+ */
+void
+des_set_sequence_number(new_sequence_number)
+ des_cblock new_sequence_number;
+{
+ bcopy((char *)new_sequence_number, (char *)sequence_number,
+ sizeof(sequence_number));
+}
+
+/*
+ * des_generate_random_block: routine to return the next random number
+ * from the current random number stream.
+ * The returned number is 64 bits long.
+ *
+ * Requires: des_set_random_generator_seed must have been called at least once
+ * before this routine is called.
+ */
+void des_generate_random_block(block)
+ des_cblock *block;
+{
+ int i;
+
+ /*
+ * Encrypt the sequence number to get the new random block:
+ */
+ des_ecb_encrypt(&sequence_number, block, random_sequence_key, 1);
+
+ /*
+ * Increment the sequence number as an 8 byte unsigned number with wrap:
+ * (using LSB here)
+ */
+ for (i=0; i<8; i++) {
+ sequence_number[i] = (sequence_number[i] + 1) & 0xff;
+ if (sequence_number[i])
+ break;
+ }
+}
diff --git a/eBones/des/rand_key.c b/eBones/des/rand_key.c
new file mode 100644
index 0000000000000..30369febd1f8c
--- /dev/null
+++ b/eBones/des/rand_key.c
@@ -0,0 +1,49 @@
+/* rand_key.c */
+/* Copyright (C) 1993 Eric Young - see README for more details */
+
+/*-
+ * $Id: rand_key.c,v 1.2 1995/05/09 18:05:15 wollman Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include "des_locl.h"
+
+int des_random_key(ret)
+des_cblock ret;
+ {
+ des_key_schedule ks;
+ static unsigned long c=0;
+ static unsigned short pid=0;
+ static des_cblock data={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+ des_cblock key;
+ unsigned char *p;
+ unsigned long t;
+
+#ifdef MSDOS
+ pid=1;
+#else
+ if (!pid) pid=getpid();
+#endif
+ p=key;
+ t=(unsigned long)time(NULL);
+ l2c(t,p);
+ t=(unsigned long)((pid)|((c++)<<16));
+ l2c(t,p);
+
+ des_set_odd_parity((des_cblock *)data);
+ des_set__key((des_cblock *)data,ks);
+ des_cbc_cksum((des_cblock *)key,(des_cblock *)key,
+ (long)sizeof(key),ks,(des_cblock *)data);
+ des_set_odd_parity((des_cblock *)key);
+ des_cbc_cksum((des_cblock *)key,(des_cblock *)key,
+ (long)sizeof(key),ks,(des_cblock *)data);
+ des_set_odd_parity((des_cblock *)key);
+
+ bcopy(key,ret,sizeof(key));
+ bzero(key,sizeof(key));
+ bzero(ks,sizeof(ks));
+ t=0;
+ return(0);
+ }
diff --git a/eBones/include/Makefile b/eBones/include/Makefile
new file mode 100644
index 0000000000000..0e95002dd3a79
--- /dev/null
+++ b/eBones/include/Makefile
@@ -0,0 +1,19 @@
+# from: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:23:44 markm Exp $
+
+FILES= kparse.h krb.h krb_db.h des.h
+
+# mit-copyright.h kadm_err.h krb_err.h
+
+NOOBJ= noobj
+NOMAN= noman
+
+all include clean cleandir depend lint tags:
+
+beforeinstall:
+ -cd ${.CURDIR}; for file in ${FILES}; do \
+ cmp -s $$file ${DESTDIR}/usr/include/kerberosIV/$$file || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 $$file \
+ ${DESTDIR}/usr/include/kerberosIV; done
+
+.include <bsd.prog.mk>
diff --git a/eBones/include/des.h b/eBones/include/des.h
new file mode 100644
index 0000000000000..7a44374b428bc
--- /dev/null
+++ b/eBones/include/des.h
@@ -0,0 +1,181 @@
+/* des.h */
+/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
+ * All rights reserved.
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * See the COPYRIGHT file in the libdes distribution for more details.
+ */
+
+#ifndef HEADER_DES_H
+#define HEADER_DES_H
+
+#include <stdio.h>
+
+typedef unsigned char des_cblock[8];
+typedef struct des_ks_struct { des_cblock _; } des_key_schedule[16];
+
+#define DES_KEY_SZ (sizeof(des_cblock))
+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
+
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+#define DES_CBC_MODE 0
+#define DES_PCBC_MODE 1
+
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define set_key des_set_key
+#define key_sched des_key_sched
+#define ecb_encrypt des_ecb_encrypt
+#define cbc_encrypt des_cbc_encrypt
+#define ncbc_encrypt des_ncbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define quad_cksum des_quad_cksum
+
+/* For compatibility with the MIT lib - eay 20/05/92 */
+typedef struct des_ks_struct bit_64;
+#define des_fixup_key_parity des_set_odd_parity
+#define des_check_key_parity check_parity
+
+extern int des_check_key; /* defaults to false */
+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
+
+/* The next line is used to disable full ANSI prototypes, if your
+ * compiler has problems with the prototypes, make sure this line always
+ * evaluates to true :-) */
+#if defined(MSDOS) && defined(__STDC__)
+#undef PROTO
+#define PROTO
+#endif
+
+/* markm - dirty hack */
+#define PROTO
+
+#ifdef PROTO
+int des_2ecb_encrypt(des_cblock *input,des_cblock *output,
+ des_key_schedule ks1,des_key_schedule ks2,int enc);
+int des_3ecb_encrypt(des_cblock *input,des_cblock *output,
+ des_key_schedule ks1,des_key_schedule ks2, int enc);
+unsigned long des_cbc_cksum(des_cblock *input,des_cblock *output,
+ long length,des_key_schedule schedule,des_cblock *ivec);
+int des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
+ des_key_schedule schedule,des_cblock *ivec,int enc);
+int des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
+ des_key_schedule schedule,des_cblock *ivec,int enc);
+int des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,
+ des_key_schedule sk1,des_key_schedule sk2,
+ des_cblock *ivec1,des_cblock *ivec2,int enc);
+int des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
+ long length,des_key_schedule schedule,des_cblock *ivec,int enc);
+int des_ecb_encrypt(des_cblock *input,des_cblock *output,
+ des_key_schedule ks,int enc);
+int des_encrypt(unsigned long *input,unsigned long *output,
+ des_key_schedule ks, int enc);
+int des_encrypt2(unsigned long *input,unsigned long *output,
+ des_key_schedule ks, int enc);
+int des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
+ long length, des_key_schedule ks1, des_key_schedule ks2,
+ des_key_schedule ks3, des_cblock *ivec, int enc);
+int des_ede2_cbc_encrypt(des_cblock *input, des_cblock *output,
+ long length, des_key_schedule ks1, des_key_schedule ks2,
+ des_cblock *ivec, int enc);
+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
+ des_cblock *iv);
+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
+ des_cblock *iv);
+#if 0
+#ifdef PERL5
+char *des_crypt(const char *buf,const char *salt);
+#else
+/* some stupid compilers complain because I have declared char instead
+ * of const char */
+#ifdef HEADER_DES_LOCL_H
+char *crypt(const char *buf,const char *salt);
+#else
+char *crypt();
+#endif /* HEADER_DES_LOCL_H */
+#endif /* PERL5 */
+#endif /* 0 */
+
+int des_ofb_encrypt(unsigned char *in,unsigned char *out,
+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
+int des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
+ des_key_schedule schedule,des_cblock *ivec,int enc);
+unsigned long des_quad_cksum(des_cblock *input,des_cblock *output,
+ long length,int out_count,des_cblock *seed);
+void des_random_seed(des_cblock key);
+int des_random_key(des_cblock ret);
+int des_read_password(des_cblock *key,char *prompt,int verify);
+int des_read_2passwords(des_cblock *key1,des_cblock *key2,
+ char *prompt,int verify);
+int des_read_pw_string(char *buf,int length,char *prompt,int verify);
+void des_set_odd_parity(des_cblock *key);
+int des_is_weak_key(des_cblock *key);
+int des_set_key(des_cblock *key,des_key_schedule schedule);
+int des_key_sched(des_cblock *key,des_key_schedule schedule);
+int des_string_to_key(char *str,des_cblock *key);
+int des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
+int des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+ des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
+int des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+ des_key_schedule schedule, des_cblock *ivec, int *num);
+void des_cblock_print_file(des_cblock *cb, FILE *fp);
+int des_new_random_key(des_cblock *key);
+void des_init_random_number_generator(des_cblock *key);
+void des_set_random_generator_seed(des_cblock *key);
+void des_set_sequence_number(des_cblock new_sequence_number);
+void des_generate_random_block(des_cblock *block);
+
+#else
+
+int des_2ecb_encrypt();
+int des_3ecb_encrypt();
+unsigned long des_cbc_cksum();
+int des_cbc_encrypt();
+int des_ncbc_encrypt();
+int des_3cbc_encrypt();
+int des_cfb_encrypt();
+int des_ecb_encrypt();
+int des_encrypt();
+int des_encrypt2();
+int des_ede3_cbc_encrypt();
+int des_ede2_cbc_encrypt();
+int des_enc_read();
+int des_enc_write();
+#ifdef PERL5
+char *des_crypt();
+#else
+char *crypt();
+#endif
+int des_ofb_encrypt();
+int des_pcbc_encrypt();
+unsigned long des_quad_cksum();
+void des_random_seed();
+int des_random_key();
+int des_read_password();
+int des_read_2passwords();
+int des_read_pw_string();
+void des_set_odd_parity();
+int des_is_weak_key();
+int des_set_key();
+int des_key_sched();
+int des_string_to_key();
+int des_string_to_2keys();
+int des_cfb64_encrypt();
+int des_ofb64_encrypt();
+void des_cblock_print_file();
+int des_new_random_key();
+void des_init_random_number_generator();
+void des_set_random_generator_seed();
+void des_set_sequence_number();
+void des_generate_random_block();
+#endif
+#endif
diff --git a/eBones/include/kparse.h b/eBones/include/kparse.h
new file mode 100644
index 0000000000000..d506d9dc3b312
--- /dev/null
+++ b/eBones/include/kparse.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for kparse routines.
+ *
+ * from: kparse.h,v 4.5 89/01/11 12:05:53 steiner Exp $
+ * $Id: kparse.h,v 1.4 1995/09/07 20:50:34 mark Exp $
+ */
+
+#ifndef KPARSE_DEFS
+#define KPARSE_DEFS
+
+/*
+ * values returned by fGetParameterSet()
+ */
+
+#define PS_BAD_KEYWORD -2 /* unknown or duplicate keyword */
+#define PS_SYNTAX -1 /* syntax error */
+#define PS_OKAY 0 /* got a complete parameter set */
+#define PS_EOF 1 /* nothing more in the file */
+
+/*
+ * values returned by fGetKeywordValue()
+ */
+
+#define KV_SYNTAX -2 /* syntax error */
+#define KV_EOF -1 /* nothing more in the file */
+#define KV_OKAY 0 /* got a keyword/value pair */
+#define KV_EOL 1 /* nothing more on this line */
+
+/*
+ * values returned by fGetToken()
+ */
+
+#define GTOK_BAD_QSTRING -1 /* newline found in quoted string */
+#define GTOK_EOF 0 /* end of file encountered */
+#define GTOK_QSTRING 1 /* quoted string */
+#define GTOK_STRING 2 /* unquoted string */
+#define GTOK_NUMBER 3 /* one or more digits */
+#define GTOK_PUNK 4 /* punks are punctuation, newline,
+ * etc. */
+#define GTOK_WHITE 5 /* one or more whitespace chars */
+
+/*
+ * extended character classification macros
+ */
+
+#define ISOCTAL(CH) ( (CH>='0') && (CH<='7') )
+#define ISQUOTE(CH) ( (CH=='\"') || (CH=='\'') || (CH=='`') )
+#define ISWHITESPACE(C) ( (C==' ') || (C=='\t') )
+#define ISLINEFEED(C) ( (C=='\n') || (C=='\r') || (C=='\f') )
+
+/*
+ * tokens consist of any printable charcacter except comma, equal, or
+ * whitespace
+ */
+
+#define ISTOKENCHAR(C) ((C>040) && (C<0177) && (C != ',') && (C != '='))
+
+/*
+ * the parameter table defines the keywords that will be recognized by
+ * fGetParameterSet, and their default values if not specified.
+ */
+
+typedef struct {
+ char *keyword;
+ char *defvalue;
+ char *value;
+} parmtable;
+
+#define PARMCOUNT(P) (sizeof(P)/sizeof(P[0]))
+
+extern int LineNbr; /* current line # in parameter file */
+
+extern char ErrorMsg[]; /*
+ * meaningful only when KV_SYNTAX,
+ * PS_SYNTAX, or PS_BAD_KEYWORD is
+ * returned by fGetKeywordValue or
+ * fGetParameterSet
+ */
+
+extern char *strsave(char *p); /* defined in this module */
+extern char *strutol(char *p); /* defined in this module */
+
+int fGetParameterSet(FILE *fp, parmtable parm[], int parmcount);
+int fGetKeywordValue(FILE *fp, char *keyword, int klen, char *value, int vlen);
+int fGetToken(FILE *fp, char *dest, int maxlen);
+
+#endif /* KPARSE_DEFS */
diff --git a/eBones/include/krb.h b/eBones/include/krb.h
new file mode 100644
index 0000000000000..0b1ae090a2ab1
--- /dev/null
+++ b/eBones/include/krb.h
@@ -0,0 +1,504 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Include file for the Kerberos library.
+ *
+ * from: krb.h,v 4.26 89/08/08 17:55:25 jtkohl Exp $
+ * $Id: krb.h,v 1.7 1995/09/07 20:50:36 mark Exp $
+ */
+
+/* Only one time, please */
+#ifndef KRB_DEFS
+#define KRB_DEFS
+
+/* Need some defs from des.h */
+#include <stdio.h>
+#include <kerberosIV/des.h>
+#include <netinet/in.h>
+
+/* Text describing error codes */
+#define MAX_KRB_ERRORS 256
+extern char *krb_err_txt[MAX_KRB_ERRORS];
+
+/* These are not defined for at least SunOS 3.3 and Ultrix 2.2 */
+#if defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)
+#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
+#define FD_SET(n, p) ((p)->fds_bits[0] |= (1 << (n)))
+#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1 << (n)))
+#endif /* ULTRIX022 || SunOS */
+
+/* General definitions */
+#define KSUCCESS 0
+#define KFAILURE 255
+
+#ifdef NO_UIDGID_T
+typedef unsigned short uid_t;
+typedef unsigned short gid_t;
+#endif /* NO_UIDGID_T */
+
+/*
+ * Kerberos specific definitions
+ *
+ * KRBLOG is the log file for the kerberos master server. KRB_CONF is
+ * the configuration file where different host machines running master
+ * and slave servers can be found. KRB_MASTER is the name of the
+ * machine with the master database. The admin_server runs on this
+ * machine, and all changes to the db (as opposed to read-only
+ * requests, which can go to slaves) must go to it. KRB_HOST is the
+ * default machine * when looking for a kerberos slave server. Other
+ * possibilities are * in the KRB_CONF file. KRB_REALM is the name of
+ * the realm.
+ */
+
+#ifdef notdef
+this is server - only, does not belong here;
+#define KRBLOG "/etc/kerberosIV/kerberos.log"
+are these used anyplace '?';
+#define VX_KRB_HSTFILE "/etc/krbhst"
+#define PC_KRB_HSTFILE "\\kerberos\\krbhst"
+#endif
+
+#define KRB_CONF "/etc/kerberosIV/krb.conf"
+#define KRB_RLM_TRANS "/etc/kerberosIV/krb.realms"
+#define KRB_MASTER "kerberos"
+#define KRB_HOST KRB_MASTER
+#define KRB_REALM "ATHENA.MIT.EDU"
+
+/* The maximum sizes for aname, realm, sname, and instance +1 */
+#define ANAME_SZ 40
+#define REALM_SZ 40
+#define SNAME_SZ 40
+#define INST_SZ 40
+/* include space for '.' and '@' */
+#define MAX_K_NAME_SZ (ANAME_SZ + INST_SZ + REALM_SZ + 2)
+#define KKEY_SZ 100
+#define VERSION_SZ 1
+#define MSG_TYPE_SZ 1
+#define DATE_SZ 26 /* RTI date output */
+
+#define MAX_HSTNM 100
+
+#ifndef DEFAULT_TKT_LIFE /* allow compile-time override */
+#define DEFAULT_TKT_LIFE 96 /* default lifetime for krb_mk_req
+ & co., 8 hrs */
+#endif
+
+/* Definition of text structure used to pass text around */
+#define MAX_KTXT_LEN 1250
+
+struct ktext {
+ int length; /* Length of the text */
+ unsigned char dat[MAX_KTXT_LEN]; /* The data itself */
+ unsigned long mbz; /* zero to catch runaway strings */
+};
+
+typedef struct ktext *KTEXT;
+typedef struct ktext KTEXT_ST;
+
+
+/* Definitions for send_to_kdc */
+#define CLIENT_KRB_TIMEOUT 4 /* time between retries */
+#define CLIENT_KRB_RETRY 5 /* retry this many times */
+#define CLIENT_KRB_BUFLEN 512 /* max unfragmented packet */
+
+/* Definitions for ticket file utilities */
+#define R_TKT_FIL 0
+#define W_TKT_FIL 1
+
+/* Definitions for cl_get_tgt */
+#ifdef PC
+#define CL_GTGT_INIT_FILE "\\kerberos\\k_in_tkts"
+#else
+#define CL_GTGT_INIT_FILE "/etc/k_in_tkts"
+#endif PC
+
+/* Parameters for rd_ap_req */
+/* Maximum alloable clock skew in seconds */
+#define CLOCK_SKEW 5*60
+/* Filename for readservkey */
+#define KEYFILE "/etc/kerberosIV/srvtab"
+
+/* Structure definition for rd_ap_req */
+
+struct auth_dat {
+ unsigned char k_flags; /* Flags from ticket */
+ char pname[ANAME_SZ]; /* Principal's name */
+ char pinst[INST_SZ]; /* His Instance */
+ char prealm[REALM_SZ]; /* His Realm */
+ unsigned long checksum; /* Data checksum (opt) */
+ C_Block session; /* Session Key */
+ int life; /* Life of ticket */
+ unsigned long time_sec; /* Time ticket issued */
+ unsigned long address; /* Address in ticket */
+ KTEXT_ST reply; /* Auth reply (opt) */
+};
+
+typedef struct auth_dat AUTH_DAT;
+
+/* Structure definition for credentials returned by get_cred */
+
+struct credentials {
+ char service[ANAME_SZ]; /* Service name */
+ char instance[INST_SZ]; /* Instance */
+ char realm[REALM_SZ]; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT_ST ticket_st; /* The ticket itself */
+ long issue_date; /* The issue time */
+ char pname[ANAME_SZ]; /* Principal's name */
+ char pinst[INST_SZ]; /* Principal's instance */
+};
+
+typedef struct credentials CREDENTIALS;
+
+/* Structure definition for rd_private_msg and rd_safe_msg */
+
+struct msg_dat {
+ unsigned char *app_data; /* pointer to appl data */
+ unsigned long app_length; /* length of appl data */
+ unsigned long hash; /* hash to lookup replay */
+ int swap; /* swap bytes? */
+ long time_sec; /* msg timestamp seconds */
+ unsigned char time_5ms; /* msg timestamp 5ms units */
+};
+
+typedef struct msg_dat MSG_DAT;
+
+
+/* Location of ticket file for save_cred and get_cred */
+#ifdef PC
+#define TKT_FILE "\\kerberos\\ticket.ses"
+#else
+#define TKT_FILE tkt_string()
+#define TKT_ROOT "/tmp/tkt"
+#endif PC
+
+/* Error codes returned from the KDC */
+#define KDC_OK 0 /* Request OK */
+#define KDC_NAME_EXP 1 /* Principal expired */
+#define KDC_SERVICE_EXP 2 /* Service expired */
+#define KDC_AUTH_EXP 3 /* Auth expired */
+#define KDC_PKT_VER 4 /* Protocol version unknown */
+#define KDC_P_MKEY_VER 5 /* Wrong master key version */
+#define KDC_S_MKEY_VER 6 /* Wrong master key version */
+#define KDC_BYTE_ORDER 7 /* Byte order unknown */
+#define KDC_PR_UNKNOWN 8 /* Principal unknown */
+#define KDC_PR_N_UNIQUE 9 /* Principal not unique */
+#define KDC_NULL_KEY 10 /* Principal has null key */
+#define KDC_GEN_ERR 20 /* Generic error from KDC */
+
+
+/* Values returned by get_credentials */
+#define GC_OK 0 /* Retrieve OK */
+#define RET_OK 0 /* Retrieve OK */
+#define GC_TKFIL 21 /* Can't read ticket file */
+#define RET_TKFIL 21 /* Can't read ticket file */
+#define GC_NOTKT 22 /* Can't find ticket or TGT */
+#define RET_NOTKT 22 /* Can't find ticket or TGT */
+
+
+/* Values returned by mk_ap_req */
+#define MK_AP_OK 0 /* Success */
+#define MK_AP_TGTEXP 26 /* TGT Expired */
+
+/* Values returned by rd_ap_req */
+#define RD_AP_OK 0 /* Request authentic */
+#define RD_AP_UNDEC 31 /* Can't decode authenticator */
+#define RD_AP_EXP 32 /* Ticket expired */
+#define RD_AP_NYV 33 /* Ticket not yet valid */
+#define RD_AP_REPEAT 34 /* Repeated request */
+#define RD_AP_NOT_US 35 /* The ticket isn't for us */
+#define RD_AP_INCON 36 /* Request is inconsistent */
+#define RD_AP_TIME 37 /* delta_t too big */
+#define RD_AP_BADD 38 /* Incorrect net address */
+#define RD_AP_VERSION 39 /* protocol version mismatch */
+#define RD_AP_MSG_TYPE 40 /* invalid msg type */
+#define RD_AP_MODIFIED 41 /* message stream modified */
+#define RD_AP_ORDER 42 /* message out of order */
+#define RD_AP_UNAUTHOR 43 /* unauthorized request */
+
+/* Values returned by get_pw_tkt */
+#define GT_PW_OK 0 /* Got password changing tkt */
+#define GT_PW_NULL 51 /* Current PW is null */
+#define GT_PW_BADPW 52 /* Incorrect current password */
+#define GT_PW_PROT 53 /* Protocol Error */
+#define GT_PW_KDCERR 54 /* Error returned by KDC */
+#define GT_PW_NULLTKT 55 /* Null tkt returned by KDC */
+
+
+/* Values returned by send_to_kdc */
+#define SKDC_OK 0 /* Response received */
+#define SKDC_RETRY 56 /* Retry count exceeded */
+#define SKDC_CANT 57 /* Can't send request */
+
+/*
+ * Values returned by get_intkt
+ * (can also return SKDC_* and KDC errors)
+ */
+
+#define INTK_OK 0 /* Ticket obtained */
+#define INTK_W_NOTALL 61 /* Not ALL tickets returned */
+#define INTK_BADPW 62 /* Incorrect password */
+#define INTK_PROT 63 /* Protocol Error */
+#define INTK_ERR 70 /* Other error */
+
+/* Values returned by get_adtkt */
+#define AD_OK 0 /* Ticket Obtained */
+#define AD_NOTGT 71 /* Don't have tgt */
+
+/* Error codes returned by ticket file utilities */
+#define NO_TKT_FIL 76 /* No ticket file found */
+#define TKT_FIL_ACC 77 /* Couldn't access tkt file */
+#define TKT_FIL_LCK 78 /* Couldn't lock ticket file */
+#define TKT_FIL_FMT 79 /* Bad ticket file format */
+#define TKT_FIL_INI 80 /* tf_init not called first */
+
+/* Error code returned by kparse_name */
+#define KNAME_FMT 81 /* Bad Kerberos name format */
+
+/* Error code returned by krb_mk_safe */
+#define SAFE_PRIV_ERROR -1 /* syscall error */
+
+/*
+ * macros for byte swapping; also scratch space
+ * u_quad 0-->7, 1-->6, 2-->5, 3-->4, 4-->3, 5-->2, 6-->1, 7-->0
+ * u_long 0-->3, 1-->2, 2-->1, 3-->0
+ * u_short 0-->1, 1-->0
+ */
+
+#define swap_u_16(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab(((char *) x) +0, ((char *) _krb_swap_tmp) +14 ,2); \
+ swab(((char *) x) +2, ((char *) _krb_swap_tmp) +12 ,2); \
+ swab(((char *) x) +4, ((char *) _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +6, ((char *) _krb_swap_tmp) +8 ,2); \
+ swab(((char *) x) +8, ((char *) _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +10,((char *) _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +12,((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +14,((char *) _krb_swap_tmp) +0 ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,16);\
+ }
+
+#define swap_u_12(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab(( char *) x, ((char *) _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +2, ((char *) _krb_swap_tmp) +8 ,2); \
+ swab(((char *) x) +4, ((char *) _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +6, ((char *) _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +8, ((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +10,((char *) _krb_swap_tmp) +0 ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,12);\
+ }
+
+#define swap_C_Block(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab(( char *) x, ((char *) _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +2,((char *) _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +4,((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +6,((char *) _krb_swap_tmp) ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,8);\
+ }
+#define swap_u_quad(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab(( char *) &x, ((char *) _krb_swap_tmp) +6 ,2); \
+ swab(((char *) &x) +2,((char *) _krb_swap_tmp) +4 ,2); \
+ swab(((char *) &x) +4,((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +6,((char *) _krb_swap_tmp) ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)&x,8);\
+ }
+
+#define swap_u_long(x) {\
+ unsigned long _krb_swap_tmp[4];\
+ swab((char *) &x, ((char *) _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +2,((char *) _krb_swap_tmp),2); \
+ x = _krb_swap_tmp[0]; \
+ }
+
+#define swap_u_short(x) {\
+ unsigned short _krb_swap_sh_tmp; \
+ swab((char *) &x, ( &_krb_swap_sh_tmp) ,2); \
+ x = (unsigned short) _krb_swap_sh_tmp; \
+ }
+
+/* Kerberos ticket flag field bit definitions */
+#define K_FLAG_ORDER 0 /* bit 0 --> lsb */
+#define K_FLAG_1 /* reserved */
+#define K_FLAG_2 /* reserved */
+#define K_FLAG_3 /* reserved */
+#define K_FLAG_4 /* reserved */
+#define K_FLAG_5 /* reserved */
+#define K_FLAG_6 /* reserved */
+#define K_FLAG_7 /* reserved, bit 7 --> msb */
+
+#ifndef PC
+char *tkt_string();
+#endif PC
+
+#ifdef OLDNAMES
+#define krb_mk_req mk_ap_req
+#define krb_rd_req rd_ap_req
+#define krb_kntoln an_to_ln
+#define krb_set_key set_serv_key
+#define krb_get_cred get_credentials
+#define krb_mk_priv mk_private_msg
+#define krb_rd_priv rd_private_msg
+#define krb_mk_safe mk_safe_msg
+#define krb_rd_safe rd_safe_msg
+#define krb_mk_err mk_appl_err_msg
+#define krb_rd_err rd_appl_err_msg
+#define krb_ck_repl check_replay
+#define krb_get_pw_in_tkt get_in_tkt
+#define krb_get_svc_in_tkt get_svc_in_tkt
+#define krb_get_pw_tkt get_pw_tkt
+#define krb_realmofhost krb_getrealm
+#define krb_get_phost get_phost
+#define krb_get_krbhst get_krbhst
+#define krb_get_lrealm get_krbrlm
+#endif OLDNAMES
+
+/* Defines for krb_sendauth and krb_recvauth */
+
+#define KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */
+#define KOPT_DO_MUTUAL 0x00000002 /* do mutual auth */
+
+#define KOPT_DONT_CANON 0x00000004 /*
+ * don't canonicalize inst as
+ * a hostname
+ */
+
+#define KRB_SENDAUTH_VLEN 8 /* length for version strings */
+
+#ifdef ATHENA_COMPAT
+#define KOPT_DO_OLDSTYLE 0x00000008 /* use the old-style protocol */
+#endif ATHENA_COMPAT
+
+/* libacl */
+void acl_canonicalize_principal __P((char *principal, char *buf));
+int acl_check __P((char *acl, char *principal));
+int acl_exact_match __P((char *acl, char *principal));
+int acl_add __P((char *acl, char *principal));
+int acl_delete __P((char *acl, char *principal));
+int acl_initialize __P((char *acl_file, int mode));
+
+/* libkrb - krb.3 */
+int krb_mk_req __P((KTEXT authent, char *service, char *instance, char *realm,
+ long checksum);
+int krb_rd_req __P((KTEXT authent, char *service, char *instance,
+ long from_addr, AUTH_DAT *ad, char *fn));
+int krb_kntoln __P((AUTH_DAT *ad, char *lname));
+int krb_set_key __P((char *key, int cvt));
+int krb_get_cred __P((char *service, char *instance, char *realm,
+ CREDENTIALS *c));
+long krb_mk_priv __P((u_char *in, u_char *out, u_long in_length,
+ des_key_schedule schedule, des_cblock key, struct sockaddr_in *sender,
+ struct sockaddr_in *receiver));
+long krb_rd_priv __P((u_char *in, u_long in_length, Key_schedule schedule,
+ des_cblock key, struct sockaddr_in *sender, struct sockaddr_in *receiver,
+ MSG_DAT *msg_data));
+long krb_mk_safe __P((u_char *in, u_char *out, u_long in_length,
+ des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver));
+long krb_rd_safe __P((u_char *in, u_long length, des_cblock *key,
+ struct sockaddr_in *sender, struct sockaddr_in *receiver,
+ MSG_DAT *msg_data));
+long krb_mk_err __P((u_char *out, long code, char *string));
+int krb_rd_err __P((u_char *in, u_long in_length, long *code, MSG_DAT *m_data));
+
+/* libkrb - krb_sendauth.3 */
+int krb_sendauth __P((long options, int fd, KTEXT ticket, char *service,
+ char *inst, char *realm, u_long checksum, MSG_DAT *msg_data,
+ CREDENTIALS *cred, Key_schedule schedule, struct sockaddr_in *laddr,
+ struct sockaddr_in *faddr, char *version));
+int krb_recvauth __P((long options, int fd, KTEXT ticket, char *service,
+ char *instance, struct sockaddr_in *faddr, struct sockaddr_in *laddr,
+ AUTH_DAT *kdata, char *filename, Key_schedule schedule, char *version));
+int krb_net_write __P((int fd, char *buf, int len));
+int krb_net_read __P((int fd, char *buf, int len));
+
+/* libkrb - krb_realmofhost.3 */
+char *krb_realmofhost __P((char *host));
+char *krb_get_phost __P((char *alias));
+int krb_get_krbhst __P((char *h, char *r, int n));
+int krb_get_admhst __P((char *h, char *r, int n));
+int krb_get_lrealm __P((char *r, int n));
+
+/* libkrb - krb_set_tkt_string.3 */
+void krb_set_tkt_string(char *val);
+
+/* libkrb - kuserok.3 */
+int kuserok __P((AUTH_DAT *authdata, char *localuser));
+
+/* libkrb - tf_util.3 */
+int tf_init __P((char *tf_name, int rw));
+int tf_get_pname __P((char *p));
+int tf_get_pinst __P((char *inst));
+int tf_get_cred __P((CREDENTIALS *c));
+void tf_close __P((void));
+
+/* Internal routines */
+int des_read __P((int fd, char *buf, int len));
+int des_write __P((int fd, char *buf, int len));
+int krb_get_tf_realm __P((char *ticket_file, char *realm));
+int krb_get_in_tkt __P((char *user, char *instance, char *realm, char *service,
+ char *sinstance, int life, int (*key_proc)(), int (*decrypt_proc)(),
+ char *arg));
+int krb_get_pw_in_tkt __P((char *user, char *instance, char *realm,
+ char *service, char *sinstance, int life, char *password));
+int krb_get_svc_in_tkt __P((char *user, char *instance, char *realm,
+ char *service, char *sinstance, int life, char *srvtab));
+int krb_get_tf_fullname __P((char *ticket_file, char *name, char *instance,
+ char *realm));
+int save_credentials __P((char *service, char *instance, char *realm,
+ des_cblock session, int lifetime, int kvno, KTEXT ticket, long issue_date));
+int read_service_key __P((char *service, char *instance, char *realm, int kvno,
+ char *file, char *key));
+int get_ad_tkt __P((char *service, char *sinstance, char *realm, int lifetime));
+int send_to_kdc __P((KTEXT pkt, KTEXT rpkt, char *realm));
+int krb_create_ticket __P((KTEXT tkt, unsigned char flags, char *pname,
+ char *pinstance, char *prealm, long paddress, char *session, short life,
+ long time_sec, char *sname, char *sinstance, C_Block key));
+int decomp_ticket __P((KTEXT tkt, unsigned char *flags, char *pname,
+ char *pinstance, char *prealm, unsigned long *paddress, des_cblock session,
+ int *life, unsigned long *time_sec, char *sname, char *sinstance,
+ des_cblock key, des_key_schedule key_s));
+int create_ciph __P((KTEXT c, C_Block session, char *service, char *instance,
+ char *realm, unsigned long life, int kvno, KTEXT tkt,
+ unsigned long kdc_time, C_Block key));
+int kname_parse __P((char *np, char *ip, char *rp, char *fullname));
+int tf_save_cred __P((char *service, char *instance, char *realm,
+ des_cblock session, int lifetime, int kvno, KTEXT ticket, long issue_date));
+int getst(int fd, char *s, int n));
+int pkt_clen __P((KTEXT pkt));
+int in_tkt __P((char *pname, char *pinst));
+int dest_tkt __P((void));
+char *month_sname __P((int n));
+void log __P(()); /* Actually VARARGS - markm */
+void kset_logfile __P((char *filename));
+void set_logfile __P((char *filename));
+int k_isinst __P((char *s));
+int k_isrealm __P((char *s));
+int k_isname __P((char *s));
+int k_gethostname __P((char *name, int namelen));
+int kerb_init __P((void));
+void kerb_fini __P((void));
+int kerb_db_set_name __P((char *name));
+int kerb_db_set_lockmode __P((int mode));
+int kerb_db_create __P((char *db_name));
+int kerb_db_iterate __P((int (*func)(), char *arg));
+int kerb_db_rename __P((char *from, char *to));
+long kerb_get_db_age __P((void));
+char * stime __P((long *t));
+
+long kdb_get_master_key __P((int prompt, C_Block master_key,
+ Key_schedule master_key_sched));
+long kdb_verify_master_key __P((C_Block master_key,
+ Key_schedule master_key_sched, FILE *out));
+void kdb_encrypt_key __P((C_Block in, C_Block out, C_Block master_key,
+ Key_schedule master_key_sched, int e_d_flag));
+
+extern int krb_ap_req_debug;
+extern int krb_debug;
+
+#endif KRB_DEFS
diff --git a/eBones/include/krb_db.h b/eBones/include/krb_db.h
new file mode 100644
index 0000000000000..d6d125a3551f4
--- /dev/null
+++ b/eBones/include/krb_db.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * spm Project Athena 8/85
+ *
+ * This file defines data structures for the kerberos
+ * authentication/authorization database.
+ *
+ * They MUST correspond to those defined in *.rel
+ *
+ * from: krb_db.h,v 4.9 89/01/24 17:55:39 jon Exp $
+ * $Id: krb_db.h,v 1.4 1995/08/25 21:25:12 mark Exp $
+ */
+
+#ifndef KRB_DB_DEFS
+#define KRB_DB_DEFS
+
+#define KERB_M_NAME "K" /* Kerberos */
+#define KERB_M_INST "M" /* Master */
+#define KERB_DEFAULT_NAME "default"
+#define KERB_DEFAULT_INST ""
+#define DBM_FILE "/etc/kerberosIV/principal"
+
+/* this also defines the number of queue headers */
+#define KERB_DB_HASH_MODULO 64
+
+
+/* Arguments to kerb_dbl_lock() */
+
+#define KERB_DBL_EXCLUSIVE 1
+#define KERB_DBL_SHARED 0
+
+/* arguments to kerb_db_set_lockmode() */
+
+#define KERB_DBL_BLOCKING 0
+#define KERB_DBL_NONBLOCKING 1
+
+/* Principal defines the structure of a principal's name */
+
+typedef struct {
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+
+ unsigned long key_low;
+ unsigned long key_high;
+ unsigned long exp_date;
+ char exp_date_txt[DATE_SZ];
+ unsigned long mod_date;
+ char mod_date_txt[DATE_SZ];
+ unsigned short attributes;
+ unsigned char max_life;
+ unsigned char kdc_key_ver;
+ unsigned char key_version;
+
+ char mod_name[ANAME_SZ];
+ char mod_instance[INST_SZ];
+ char *old; /* cast to (Principal *); not in db,
+ * ptr to old vals */
+}
+ Principal;
+
+typedef struct {
+ long cpu;
+ long elapsed;
+ long dio;
+ long pfault;
+ long t_stamp;
+ long n_retrieve;
+ long n_replace;
+ long n_append;
+ long n_get_stat;
+ long n_put_stat;
+}
+ DB_stat;
+
+/* Dba defines the structure of a database administrator */
+
+typedef struct {
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+ unsigned short attributes;
+ unsigned long exp_date;
+ char exp_date_txt[DATE_SZ];
+ char *old; /*
+ * cast to (Dba *); not in db, ptr to
+ * old vals
+ */
+}
+ Dba;
+
+extern int kerb_get_principal(char *name, char *inst, Principal *principal,
+ unsigned int max, int *more);
+extern int kerb_put_principal(Principal *principal, unsigned int n);
+extern void kerb_db_get_stat(DB_stat *s);
+extern void kerb_db_put_stat(DB_stat *s);
+extern int kerb_get_dba(char *name, char *inst, Dba *dba, unsigned int max,
+ int *more);
+extern int kerb_db_get_dba(char *dba_name, char *dba_inst, Dba *dba,
+ unsigned int max, int *more);
+
+extern void krb_print_principal(Principal *p);
+extern int kerb_db_get_principal(char *name, char *inst, Principal *principal,
+ unsigned int max, int *more);
+extern int kerb_db_put_principal(Principal *principal, unsigned int max);
+extern int kerb_db_init(void);
+extern void kerb_db_fini(void);
+
+#endif /* KRB_DB_DEFS */
diff --git a/eBones/include/rkinit.h b/eBones/include/rkinit.h
new file mode 100644
index 0000000000000..8be12029cd8e6
--- /dev/null
+++ b/eBones/include/rkinit.h
@@ -0,0 +1,42 @@
+/*
+ * $Id: rkinit.h,v 1.2 1993/12/23 16:47:27 dglo Exp $
+ * $Source: /usr/sww/share/src/kerberosIV.BSD/include/RCS/rkinit.h,v $
+ * $Author: dglo $
+ *
+ * Main header file for rkinit library users
+ */
+
+#ifndef __RKINIT_H__
+#define __RKINIT_H__
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid_rkinit_h = "$Id: rkinit.h,v 1.2 1993/12/23 16:47:27 dglo Exp $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <krb.h>
+#include <sys/param.h>
+
+#ifdef __STDC__
+#define RK_PROTO(x) x
+#else
+#define RK_PROTO(x) ()
+#endif /* __STDC__ */
+
+typedef struct {
+ char aname[ANAME_SZ + 1];
+ char inst[INST_SZ + 1];
+ char realm[REALM_SZ + 1];
+ char sname[ANAME_SZ + 1];
+ char sinst[INST_SZ + 1];
+ char username[9]; /* max local name length + 1 */
+ char tktfilename[MAXPATHLEN + 1];
+ u_int lifetime;
+} rkinit_info;
+
+#define RKINIT_SUCCESS 0
+
+/* Function declarations */
+extern int rkinit RK_PROTO((char *, char *, rkinit_info *, int));
+extern char *rkinit_errmsg RK_PROTO((char *));
+
+#endif /* __RKINIT_H__ */
diff --git a/eBones/include/rkinit_private.h b/eBones/include/rkinit_private.h
new file mode 100644
index 0000000000000..7784b6e51d0a6
--- /dev/null
+++ b/eBones/include/rkinit_private.h
@@ -0,0 +1,106 @@
+/*
+ * $Id: rkinit_private.h,v 1.4 1993/12/23 16:47:39 dglo Exp $
+ * $Source: /usr/sww/share/src/kerberosIV.BSD/include/RCS/rkinit_private.h,v $
+ * $Author: dglo $
+ *
+ * Header file for rkinit library and server internal use
+ */
+
+#ifndef __RKINIT_PRIVATE_H__
+#define __RKINIT_PRIVATE_H__
+
+#if !defined(lint) && !defined(SABER)
+static const char *rcsid_rkinit_private_h = "$Id: rkinit_private.h,v 1.4 1993/12/23 16:47:39 dglo Exp $";
+#endif /* lint || SABER */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#ifdef __STDC__
+#define RK_PROTO(x) x
+#else
+#define RK_PROTO(x) ()
+#define const
+#endif /* __STDC__ */
+
+/* Lowest and highest versions supported */
+#define RKINIT_LVERSION 3
+#define RKINIT_HVERSION 3
+
+/* Service to be used; port number to fall back on if service isn't found */
+#define SERVENT "rkinit"
+#define PORT 2108
+
+/* Key for kerberos authentication */
+#define KEY "rcmd"
+
+/* Packet format information */
+#define PKT_TYPE 0
+#define PKT_LEN 1
+#define PKT_DATA (PKT_LEN + sizeof(u_int32_t))
+
+/* Number of retries during message reads */
+#define RETRIES 15
+
+/*
+ * Message types for packets. Make sure that rki_mt_to_string is right in
+ * rk_util.c
+ */
+#define MT_STATUS 0
+#define MT_CVERSION 1
+#define MT_SVERSION 2
+#define MT_RKINIT_INFO 3
+#define MT_SKDC 4
+#define MT_CKDC 5
+#define MT_AUTH 6
+#define MT_DROP 7
+
+/* Miscellaneous protocol constants */
+#define VERSION_INFO_SIZE 2
+
+/* Useful definitions */
+#define BCLEAR(a) bzero((char *)(a), sizeof(a))
+#define SBCLEAR(a) bzero((char *)&(a), sizeof(a))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifdef _JBLEN
+#define SETJMP_TYPEDEFED
+#endif
+
+/* Function declarations */
+int rki_key_proc RK_PROTO((char *, char *, char *, char *, des_cblock *));
+int rki_get_tickets RK_PROTO((int, char *, char *, rkinit_info *));
+int rki_send_packet RK_PROTO((int, char, u_int32_t, const char *));
+int rki_get_packet RK_PROTO((int, u_char, u_int32_t *, char *));
+int rki_setup_rpc RK_PROTO((char *));
+int rki_rpc_exchange_version_info RK_PROTO((int, int, int *, int *));
+int rki_rpc_send_rkinit_info RK_PROTO((rkinit_info *));
+int rki_rpc_get_status RK_PROTO((void));
+int rki_rpc_get_ktext RK_PROTO((int, KTEXT, u_char));
+int rki_rpc_sendauth RK_PROTO((KTEXT));
+int rki_rpc_get_skdc RK_PROTO((KTEXT));
+int rki_rpc_send_ckdc RK_PROTO((MSG_DAT *));
+int rki_get_csaddr RK_PROTO((struct sockaddr_in *, struct sockaddr_in *));
+void rki_drop_server RK_PROTO((void));
+void rki_cleanup_rpc RK_PROTO((void));
+void rki_dmsg RK_PROTO((char *));
+const char *rki_mt_to_string RK_PROTO((int));
+int rki_choose_version RK_PROTO((int *));
+int rki_send_rkinit_info RK_PROTO((int, rkinit_info *));
+#ifdef SETJMP_TYPEDEFED
+void (*rki_setup_timer RK_PROTO((jmp_buf env))) RK_PROTO((int));
+#endif
+void rki_restore_timer RK_PROTO((void (*old_alrm)(int)));
+void rki_cleanup_rpc RK_PROTO((void));
+
+
+#endif /* __RKINIT_PRIVATE_H__ */
diff --git a/eBones/lib/Makefile b/eBones/lib/Makefile
new file mode 100644
index 0000000000000..3ca4918934345
--- /dev/null
+++ b/eBones/lib/Makefile
@@ -0,0 +1,6 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.1 1995/09/13 17:23:48 markm Exp $
+
+SUBDIR= libacl libkadm libkdb libkrb librkinit
+
+.include <bsd.subdir.mk>
diff --git a/eBones/lib/Makefile.inc b/eBones/lib/Makefile.inc
new file mode 100644
index 0000000000000..b0b4ed25a2904
--- /dev/null
+++ b/eBones/lib/Makefile.inc
@@ -0,0 +1,4 @@
+SHLIB_MAJOR?= 2
+SHLIB_MINOR?= 0
+
+.include "../Makefile.inc"
diff --git a/eBones/lib/libacl/Makefile b/eBones/lib/libacl/Makefile
new file mode 100644
index 0000000000000..7fa05c06a09cc
--- /dev/null
+++ b/eBones/lib/libacl/Makefile
@@ -0,0 +1,12 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:23:49 markm Exp $
+
+LIB= acl
+CFLAGS+=-DDEBUG -DKERBEROS
+SRCS= acl_files.c
+MAN3= acl_check.3
+MLINKS= acl_check.3 acl_canonicalize_principal.3 \
+ acl_check.3 acl_exact_match.3 acl_check.3 acl_add.3 \
+ acl_check.3 acl_delete.3 acl_check.3 acl_initialize.3
+
+.include <bsd.lib.mk>
diff --git a/eBones/lib/libacl/acl_files.c b/eBones/lib/libacl/acl_files.c
new file mode 100644
index 0000000000000..7670f2aa22aac
--- /dev/null
+++ b/eBones/lib/libacl/acl_files.c
@@ -0,0 +1,555 @@
+/*
+ *
+ * Copyright 1987,1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * from: acl_files.c,v 4.4 89/12/19 13:30:53 jtkohl Exp $
+ * $Id: acl_files.c,v 1.5 1995/09/07 20:50:26 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: acl_files.c,v 1.5 1995/09/07 20:50:26 mark Exp $";
+#endif lint
+#endif
+
+
+/*** Routines for manipulating access control list files ***/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <ctype.h>
+#include "krb.h"
+
+__BEGIN_DECLS
+static int acl_abort __P((char *, FILE *));
+__END_DECLS
+
+#ifndef KRB_REALM
+#define KRB_REALM "ATHENA.MIT.EDU"
+#endif
+
+/* "aname.inst@realm" */
+#define MAX_PRINCIPAL_SIZE (ANAME_SZ + INST_SZ + REALM_SZ + 3)
+#define INST_SEP '.'
+#define REALM_SEP '@'
+
+#define LINESIZE 2048 /* Maximum line length in an acl file */
+
+#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */
+#define WAIT_TIME 300 /* Maximum time allowed write acl file */
+
+#define CACHED_ACLS 8 /* How many acls to cache */
+ /* Each acl costs 1 open file descriptor */
+#define ACL_LEN 16 /* Twice a reasonable acl length */
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+#define COR(a,b) ((a!=NULL)?(a):(b))
+
+/* Canonicalize a principal name */
+/* If instance is missing, it becomes "" */
+/* If realm is missing, it becomes the local realm */
+/* Canonicalized form is put in canon, which must be big enough to hold
+ MAX_PRINCIPAL_SIZE characters */
+void
+acl_canonicalize_principal(principal, canon)
+char *principal;
+char *canon;
+{
+ char *dot, *atsign, *end;
+ int len;
+
+ dot = index(principal, INST_SEP);
+ atsign = index(principal, REALM_SEP);
+
+ /* Maybe we're done already */
+ if(dot != NULL && atsign != NULL) {
+ if(dot < atsign) {
+ /* It's for real */
+ /* Copy into canon */
+ strncpy(canon, principal, MAX_PRINCIPAL_SIZE);
+ canon[MAX_PRINCIPAL_SIZE-1] = '\0';
+ return;
+ } else {
+ /* Nope, it's part of the realm */
+ dot = NULL;
+ }
+ }
+
+ /* No such luck */
+ end = principal + strlen(principal);
+
+ /* Get the principal name */
+ len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal);
+ strncpy(canon, principal, len);
+ canon += len;
+
+ /* Add INST_SEP */
+ *canon++ = INST_SEP;
+
+ /* Get the instance, if it exists */
+ if(dot != NULL) {
+ ++dot;
+ len = MIN(INST_SZ, COR(atsign, end) - dot);
+ strncpy(canon, dot, len);
+ canon += len;
+ }
+
+ /* Add REALM_SEP */
+ *canon++ = REALM_SEP;
+
+ /* Get the realm, if it exists */
+ /* Otherwise, default to local realm */
+ if(atsign != NULL) {
+ ++atsign;
+ len = MIN(REALM_SZ, end - atsign);
+ strncpy(canon, atsign, len);
+ canon += len;
+ *canon++ = '\0';
+ } else if(krb_get_lrealm(canon, 1) != KSUCCESS) {
+ strcpy(canon, KRB_REALM);
+ }
+}
+
+/* Get a lock to modify acl_file */
+/* Return new FILE pointer */
+/* or NULL if file cannot be modified */
+/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */
+static FILE *
+acl_lock_file(acl_file)
+char *acl_file;
+{
+ struct stat s;
+ char new[LINESIZE];
+ int nfd;
+ FILE *nf;
+ int mode;
+
+ if(stat(acl_file, &s) < 0) return(NULL);
+ mode = s.st_mode;
+ sprintf(new, NEW_FILE, acl_file);
+ for(;;) {
+ /* Open the new file */
+ if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) {
+ if(errno == EEXIST) {
+ /* Maybe somebody got here already, maybe it's just old */
+ if(stat(new, &s) < 0) return(NULL);
+ if(time(0) - s.st_ctime > WAIT_TIME) {
+ /* File is stale, kill it */
+ unlink(new);
+ continue;
+ } else {
+ /* Wait and try again */
+ sleep(1);
+ continue;
+ }
+ } else {
+ /* Some other error, we lose */
+ return(NULL);
+ }
+ }
+
+ /* If we got to here, the lock file is ours and ok */
+ /* Reopen it under stdio */
+ if((nf = fdopen(nfd, "w")) == NULL) {
+ /* Oops, clean up */
+ unlink(new);
+ }
+ return(nf);
+ }
+}
+
+/* Commit changes to acl_file written onto FILE *f */
+/* Returns zero if successful */
+/* Returns > 0 if lock was broken */
+/* Returns < 0 if some other error occurs */
+/* Closes f */
+static int
+acl_commit(acl_file, f)
+char *acl_file;
+FILE *f;
+{
+ char new[LINESIZE];
+ int ret;
+ struct stat s;
+
+ sprintf(new, NEW_FILE, acl_file);
+ if(fflush(f) < 0
+ || fstat(fileno(f), &s) < 0
+ || s.st_nlink == 0) {
+ acl_abort(acl_file, f);
+ return(-1);
+ }
+
+ ret = rename(new, acl_file);
+ fclose(f);
+ return(ret);
+}
+
+/*
+ * Abort changes to acl_file written onto FILE *f
+ * Returns 0 if successful, < 0 otherwise
+ * Closes f
+ */
+static int
+acl_abort(acl_file, f)
+char *acl_file;
+FILE *f;
+{
+ char new[LINESIZE];
+ int ret;
+ struct stat s;
+
+ /* make sure we aren't nuking someone else's file */
+ if(fstat(fileno(f), &s) < 0 || s.st_nlink == 0) {
+ fclose(f);
+ return(-1);
+ } else {
+ sprintf(new, NEW_FILE, acl_file);
+ ret = unlink(new);
+ fclose(f);
+ return(ret);
+ }
+}
+
+/* Initialize an acl_file */
+/* Creates the file with permissions perm if it does not exist */
+/* Erases it if it does */
+/* Returns return value of acl_commit */
+int
+acl_initialize(acl_file, perm)
+char *acl_file;
+int perm;
+{
+ FILE *new;
+ int fd;
+
+ /* Check if the file exists already */
+ if((new = acl_lock_file(acl_file)) != NULL) {
+ return(acl_commit(acl_file, new));
+ } else {
+ /* File must be readable and writable by owner */
+ if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) {
+ return(-1);
+ } else {
+ close(fd);
+ return(0);
+ }
+ }
+}
+
+/* Eliminate all whitespace character in buf */
+/* Modifies its argument */
+static void
+nuke_whitespace(buf)
+char *buf;
+{
+ register char *pin, *pout;
+
+ for(pin = pout = buf; *pin != '\0'; pin++)
+ if(!isspace(*pin)) *pout++ = *pin;
+ *pout = '\0'; /* Terminate the string */
+}
+
+/* Hash table stuff */
+
+struct hashtbl {
+ int size; /* Max number of entries */
+ int entries; /* Actual number of entries */
+ char **tbl; /* Pointer to start of table */
+};
+
+/* Make an empty hash table of size s */
+static struct hashtbl *
+make_hash(size)
+int size;
+{
+ struct hashtbl *h;
+
+ if(size < 1) size = 1;
+ h = (struct hashtbl *) malloc(sizeof(struct hashtbl));
+ h->size = size;
+ h->entries = 0;
+ h->tbl = (char **) calloc(size, sizeof(char *));
+ return(h);
+}
+
+/* Destroy a hash table */
+static void
+destroy_hash(h)
+struct hashtbl *h;
+{
+ int i;
+
+ for(i = 0; i < h->size; i++) {
+ if(h->tbl[i] != NULL) free(h->tbl[i]);
+ }
+ free(h->tbl);
+ free(h);
+}
+
+/* Compute hash value for a string */
+static unsigned
+hashval(s)
+register char *s;
+{
+ register unsigned hv;
+
+ for(hv = 0; *s != '\0'; s++) {
+ hv ^= ((hv << 3) ^ *s);
+ }
+ return(hv);
+}
+
+/* Add an element to a hash table */
+static void
+add_hash(h, el)
+struct hashtbl *h;
+char *el;
+{
+ unsigned hv;
+ char *s;
+ char **old;
+ int i;
+
+ /* Make space if it isn't there already */
+ if(h->entries + 1 > (h->size >> 1)) {
+ old = h->tbl;
+ h->tbl = (char **) calloc(h->size << 1, sizeof(char *));
+ for(i = 0; i < h->size; i++) {
+ if(old[i] != NULL) {
+ hv = hashval(old[i]) % (h->size << 1);
+ while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1);
+ h->tbl[hv] = old[i];
+ }
+ }
+ h->size = h->size << 1;
+ free(old);
+ }
+
+ hv = hashval(el) % h->size;
+ while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size;
+ s = malloc(strlen(el)+1);
+ strcpy(s, el);
+ h->tbl[hv] = s;
+ h->entries++;
+}
+
+/* Returns nonzero if el is in h */
+static int
+check_hash(h, el)
+struct hashtbl *h;
+char *el;
+{
+ unsigned hv;
+
+ for(hv = hashval(el) % h->size;
+ h->tbl[hv] != NULL;
+ hv = (hv + 1) % h->size) {
+ if(!strcmp(h->tbl[hv], el)) return(1);
+ }
+ return(0);
+}
+
+struct acl {
+ char filename[LINESIZE]; /* Name of acl file */
+ int fd; /* File descriptor for acl file */
+ struct stat status; /* File status at last read */
+ struct hashtbl *acl; /* Acl entries */
+};
+
+static struct acl acl_cache[CACHED_ACLS];
+
+static int acl_cache_count = 0;
+static int acl_cache_next = 0;
+
+/* Returns < 0 if unsuccessful in loading acl */
+/* Returns index into acl_cache otherwise */
+/* Note that if acl is already loaded, this is just a lookup */
+static int
+acl_load(name)
+char *name;
+{
+ int i;
+ FILE *f;
+ struct stat s;
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ /* See if it's there already */
+ for(i = 0; i < acl_cache_count; i++) {
+ if(!strcmp(acl_cache[i].filename, name)
+ && acl_cache[i].fd >= 0) goto got_it;
+ }
+
+ /* It isn't, load it in */
+ /* maybe there's still room */
+ if(acl_cache_count < CACHED_ACLS) {
+ i = acl_cache_count++;
+ } else {
+ /* No room, clean one out */
+ i = acl_cache_next;
+ acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS;
+ close(acl_cache[i].fd);
+ if(acl_cache[i].acl) {
+ destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = (struct hashtbl *) 0;
+ }
+ }
+
+ /* Set up the acl */
+ strcpy(acl_cache[i].filename, name);
+ if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+ /* Force reload */
+ acl_cache[i].acl = (struct hashtbl *) 0;
+
+ got_it:
+ /*
+ * See if the stat matches
+ *
+ * Use stat(), not fstat(), as the file may have been re-created by
+ * acl_add or acl_delete. If this happens, the old inode will have
+ * no changes in the mod-time and the following test will fail.
+ */
+ if(stat(acl_cache[i].filename, &s) < 0) return(-1);
+ if(acl_cache[i].acl == (struct hashtbl *) 0
+ || s.st_nlink != acl_cache[i].status.st_nlink
+ || s.st_mtime != acl_cache[i].status.st_mtime
+ || s.st_ctime != acl_cache[i].status.st_ctime) {
+ /* Gotta reload */
+ if(acl_cache[i].fd >= 0) close(acl_cache[i].fd);
+ if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+ if((f = fdopen(acl_cache[i].fd, "r")) == NULL) return(-1);
+ if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = make_hash(ACL_LEN);
+ while(fgets(buf, sizeof(buf), f) != NULL) {
+ nuke_whitespace(buf);
+ acl_canonicalize_principal(buf, canon);
+ add_hash(acl_cache[i].acl, canon);
+ }
+ fclose(f);
+ acl_cache[i].status = s;
+ }
+ return(i);
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Principal is not canonicalized, and no wildcarding is done */
+int
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+
+ return((idx = acl_load(acl)) >= 0
+ && check_hash(acl_cache[idx].acl, principal));
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Recognizes wildcards in acl of the form
+ name.*@realm, *.*@realm, and *.*@* */
+int
+acl_check(acl, principal)
+char *acl;
+char *principal;
+{
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+ char *realm;
+
+ acl_canonicalize_principal(principal, canon);
+
+ /* Is it there? */
+ if(acl_exact_match(acl, canon)) return(1);
+
+ /* Try the wildcards */
+ realm = index(canon, REALM_SEP);
+ *index(canon, INST_SEP) = '\0'; /* Chuck the instance */
+
+ sprintf(buf, "%s.*%s", canon, realm);
+ if(acl_exact_match(acl, buf)) return(1);
+
+ sprintf(buf, "*.*%s", realm);
+ if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1);
+
+ return(0);
+}
+
+/* Adds principal to acl */
+/* Wildcards are interpreted literally */
+int
+acl_add(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+ int i;
+ FILE *new;
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ acl_canonicalize_principal(principal, canon);
+
+ if((new = acl_lock_file(acl)) == NULL) return(-1);
+ if((acl_exact_match(acl, canon))
+ || (idx = acl_load(acl)) < 0) {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ /* It isn't there yet, copy the file and put it in */
+ for(i = 0; i < acl_cache[idx].acl->size; i++) {
+ if(acl_cache[idx].acl->tbl[i] != NULL) {
+ if(fputs(acl_cache[idx].acl->tbl[i], new) == NULL
+ || putc('\n', new) != '\n') {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ }
+ }
+ fputs(canon, new);
+ putc('\n', new);
+ return(acl_commit(acl, new));
+}
+
+/* Removes principal from acl */
+/* Wildcards are interpreted literally */
+int
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+{
+ int idx;
+ int i;
+ FILE *new;
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ acl_canonicalize_principal(principal, canon);
+
+ if((new = acl_lock_file(acl)) == NULL) return(-1);
+ if((!acl_exact_match(acl, canon))
+ || (idx = acl_load(acl)) < 0) {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ /* It isn't there yet, copy the file and put it in */
+ for(i = 0; i < acl_cache[idx].acl->size; i++) {
+ if(acl_cache[idx].acl->tbl[i] != NULL
+ && strcmp(acl_cache[idx].acl->tbl[i], canon)) {
+ fputs(acl_cache[idx].acl->tbl[i], new);
+ putc('\n', new);
+ }
+ }
+ return(acl_commit(acl, new));
+}
+
diff --git a/eBones/lib/libkadm/Makefile b/eBones/lib/libkadm/Makefile
new file mode 100644
index 0000000000000..dc822b38fb1a7
--- /dev/null
+++ b/eBones/lib/libkadm/Makefile
@@ -0,0 +1,23 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.7 1995/09/14 19:52:28 gibbs Exp $
+
+LIB= kadm
+
+SRCS= kadm_err.c kadm_stream.c kadm_supp.c kadm_cli_wrap.c
+CFLAGS+= -I. -I${.CURDIR} -I${KRBOBJDIR} -DPOSIX
+
+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>
+
+kadm_err.c: ${KADMOBJDIR}/kadm_err.h
+
+kadm_cli_wrap.o: ${KRBOBJDIR}/krb_err.h
diff --git a/eBones/lib/libkadm/kadm.h b/eBones/lib/libkadm/kadm.h
new file mode 100644
index 0000000000000..21a23bb8f8d92
--- /dev/null
+++ b/eBones/lib/libkadm/kadm.h
@@ -0,0 +1,164 @@
+/*
+ * $Source: /usr/cvs/src/eBones/libkadm/kadm.h,v $
+ * $Author: mark $
+ * 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 <stdlib.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <krb.h>
+#include <krb_db.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
+
+/* XXX This doesn't belong here!!! */
+#ifdef POSIX
+typedef void sigtype;
+#else
+typedef int sigtype;
+#endif
+
+int vals_to_stream(Kadm_vals *dt_in, u_char **dt_out);
+int stream_to_vals(u_char *dt_in, Kadm_vals *dt_out, int maxlen);
+
+int build_field_header(u_char *cont, u_char **st);
+int check_field_header(u_char *st, u_char *cont, int maxlen);
+
+int stv_string(u_char *st, char *dat, int loc, int stlen, int maxlen);
+int stv_short(u_char *st, u_short *dat, int loc, int maxlen);
+int stv_long(u_char *st, u_long *dat, int loc, int maxlen);
+int stv_char(u_char *st, u_char *dat, int loc, int maxlen);
+
+int vts_string(char *dat, u_char **st, int loc);
+int vts_short(u_short dat, u_char **st, int loc);
+int vts_long(u_long dat, u_char **st, int loc);
+int vts_char(u_char dat, u_char **st, int loc);
+
+int kadm_cli_conn(void);
+void kadm_cli_disconn(void);
+int kadm_cli_send(u_char *st_dat, int st_siz, u_char **ret_dat, int *ret_siz);
+int kadm_cli_out(u_char *dat, int dat_len, u_char **ret_dat, int *ret_siz);
+int kadm_cli_keyd(des_cblock s_k, des_key_schedule s_s);
+
+int kadm_get(Kadm_vals *vals, u_char fl[4]);
+int kadm_mod(Kadm_vals *vals1, Kadm_vals *vals2);
+int kadm_add(Kadm_vals *vals);
+int kadm_change_pw(des_cblock newkey);
+int kadm_init_link(char n[], char i[], char r[]);
+void prin_vals(Kadm_vals *vals);
+void kadm_vals_to_prin(u_char fields[FLDSZ], Principal *new, Kadm_vals *old);
+void kadm_prin_to_vals(u_char fields[FLDSZ], Kadm_vals *new, Principal *old);
+
+#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 0000000000000..e25439dbba2b3
--- /dev/null
+++ b/eBones/lib/libkadm/kadm_cli_wrap.c
@@ -0,0 +1,509 @@
+/*
+ * 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
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_kadm_cli_wrap_c[] =
+"from: Id: kadm_cli_wrap.c,v 4.6 89/12/30 20:09:45 qjb Exp";
+static const char rcsid[] =
+ "$Id: kadm_cli_wrap.c,v 1.1 1995/07/18 16:40:23 mark Exp $";
+#endif lint
+#endif
+
+/*
+ * kadm_cli_wrap.c the client side wrapping of the calls to the admin server
+ */
+
+#include <unistd.h>
+#include <string.h>
+#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 void
+clear_secrets()
+{
+ bzero((char *)sess_key, sizeof(sess_key));
+ bzero((char *)sess_sched, sizeof(sess_sched));
+}
+
+/*
+ * kadm_init_link
+ * receives : name, inst, realm
+ *
+ * initializes client parm, the Kadm_Client structure which holds the
+ * data about the connection between the server and client, the services
+ * used, the locations and other fun things
+ */
+int
+kadm_init_link(n, i, r)
+char n[];
+char i[];
+char r[];
+{
+ struct servent *sep; /* service we will talk to */
+ struct hostent *hop; /* host we will talk to */
+ char adm_hostname[MAXHOSTNAMELEN];
+
+ (void) init_kadm_err_tbl();
+ (void) init_krb_err_tbl();
+ (void) strcpy(client_parm.sname, n);
+ (void) strcpy(client_parm.sinst, i);
+ (void) strcpy(client_parm.krbrlm, r);
+ client_parm.admin_fd = -1;
+
+ /* set up the admin_addr - fetch name of admin host */
+ if (krb_get_admhst(adm_hostname, client_parm.krbrlm, 1) != KSUCCESS)
+ return KADM_NO_HOST;
+ if ((hop = gethostbyname(adm_hostname)) == NULL)
+ return KADM_UNK_HOST; /* couldnt find the admin servers
+ * address */
+ if ((sep = getservbyname(KADM_SNAME, "tcp")) == NULL)
+ return KADM_NO_SERV; /* couldnt find the admin service */
+ bzero((char *) &client_parm.admin_addr,
+ sizeof(client_parm.admin_addr));
+ client_parm.admin_addr.sin_family = hop->h_addrtype;
+ bcopy((char *) hop->h_addr, (char *) &client_parm.admin_addr.sin_addr,
+ hop->h_length);
+ client_parm.admin_addr.sin_port = sep->s_port;
+
+ return KADM_SUCCESS;
+} /* procedure kadm_init_link */
+
+/*
+ * kadm_change_pw
+ * recieves : key
+ *
+ * Replaces the password (i.e. des key) of the caller with that specified in
+ * key. Returns no actual data from the master server, since this is called
+ * by a user
+ */
+int
+kadm_change_pw(newkey)
+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
+ */
+int
+kadm_add(vals)
+Kadm_vals *vals;
+{
+ u_char *st, *st2; /* st will hold the stream of values */
+ int st_len; /* st2 the final stream with opcode */
+ int retc; /* return code from call */
+ u_char *ret_st;
+ int ret_sz;
+
+ if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+ return(retc);
+ st_len = vals_to_stream(vals, &st);
+ st2 = (u_char *) malloc((unsigned)(1 + st_len));
+ *st2 = (u_char) ADD_ENT; /* here's the opcode */
+ bcopy((char *) st, (char *) st2 + 1, st_len); /* append st on */
+ retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz);
+ free((char *)st);
+ free((char *)st2);
+ if (retc == KADM_SUCCESS) {
+ /* ret_st has vals */
+ if (stream_to_vals(ret_st, vals, ret_sz) < 0)
+ retc = KADM_LENGTH_ERROR;
+ free((char *)ret_st);
+ }
+ kadm_cli_disconn();
+ return(retc);
+}
+
+/*
+ * kadm_mod
+ * receives : KTEXT, {values, values}
+ * returns : CKSUM, RETCODE, {values}
+ * acl : su, sms (as register or dealloc)
+ *
+ * Modifies all entries corresponding to the first values so they match the
+ * second values. returns the values for the changed entries in vals2
+ */
+int
+kadm_mod(vals1, vals2)
+Kadm_vals *vals1;
+Kadm_vals *vals2;
+{
+ u_char *st, *st2; /* st will hold the stream of values */
+ int st_len, nlen; /* st2 the final stream with opcode */
+ u_char *ret_st;
+ int ret_sz;
+
+ /* nlen is the length of second vals */
+ int retc; /* return code from call */
+
+ if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+ return(retc);
+
+ st_len = vals_to_stream(vals1, &st);
+ st2 = (u_char *) malloc((unsigned)(1 + st_len));
+ *st2 = (u_char) MOD_ENT; /* here's the opcode */
+ bcopy((char *) st, (char *) st2 + 1, st_len++); /* append st on */
+ free((char *)st);
+ nlen = vals_to_stream(vals2, &st);
+ st2 = (u_char *) realloc((char *) st2, (unsigned)(st_len + nlen));
+ bcopy((char *) st, (char *) st2 + st_len, nlen); /* append st on */
+ retc = kadm_cli_send(st2, st_len + nlen, &ret_st, &ret_sz);
+ free((char *)st);
+ free((char *)st2);
+ if (retc == KADM_SUCCESS) {
+ /* ret_st has vals */
+ if (stream_to_vals(ret_st, vals2, ret_sz) < 0)
+ retc = KADM_LENGTH_ERROR;
+ free((char *)ret_st);
+ }
+ kadm_cli_disconn();
+ return(retc);
+}
+
+/*
+ * kadm_get
+ * receives : KTEXT, {values, flags}
+ * returns : CKSUM, RETCODE, {count, values, values, values}
+ * acl : su
+ *
+ * gets the fields requested by flags from all entries matching values returns
+ * this data for each matching recipient, after a count of how many such
+ * matches there were
+ */
+int
+kadm_get(vals, fl)
+Kadm_vals *vals;
+u_char fl[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.
+ */
+int
+kadm_cli_send(st_dat, st_siz, ret_dat, ret_siz)
+u_char *st_dat; /* the actual data */
+int st_siz; /* length of said data */
+u_char **ret_dat; /* to give return info */
+int *ret_siz; /* length of returned info */
+{
+ int act_len, retdat; /* current offset into packet, return
+ * data */
+ KTEXT_ST authent; /* the authenticator we will build */
+ u_char *act_st; /* the pointer to the complete packet */
+ u_char *priv_pak; /* private version of the packet */
+ int priv_len; /* length of private packet */
+ u_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((des_cblock *)priv_pak, (des_cblock *)0,
+ (long)priv_len, 0, (des_cblock *)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 */
+int
+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((des_cblock *)s_k,s_s)))
+ return(stat+krb_err_base);
+#endif
+ return KADM_SUCCESS;
+} /* This code "works" */
+
+static sigtype (*opipe)();
+
+int
+kadm_cli_conn()
+{ /* this connects and sets my_addr */
+ int on = 1;
+
+ if ((client_parm.admin_fd =
+ socket(client_parm.admin_addr.sin_family, SOCK_STREAM,0)) < 0)
+ return KADM_NO_SOCK; /* couldnt create the socket */
+ if (connect(client_parm.admin_fd,
+ (struct sockaddr *) & client_parm.admin_addr,
+ sizeof(client_parm.admin_addr))) {
+ (void) close(client_parm.admin_fd);
+ client_parm.admin_fd = -1;
+ return KADM_NO_CONN; /* couldnt get the connect */
+ }
+ opipe = signal(SIGPIPE, SIG_IGN);
+ client_parm.my_addr_len = sizeof(client_parm.my_addr);
+ if (getsockname(client_parm.admin_fd,
+ (struct sockaddr *) & client_parm.my_addr,
+ &client_parm.my_addr_len) < 0) {
+ (void) close(client_parm.admin_fd);
+ client_parm.admin_fd = -1;
+ (void) signal(SIGPIPE, opipe);
+ return KADM_NO_HERE; /* couldnt find out who we are */
+ }
+ if (setsockopt(client_parm.admin_fd, SOL_SOCKET, SO_KEEPALIVE, &on,
+ sizeof(on)) < 0) {
+ (void) close(client_parm.admin_fd);
+ client_parm.admin_fd = -1;
+ (void) signal(SIGPIPE, opipe);
+ return KADM_NO_CONN; /* XXX */
+ }
+ return KADM_SUCCESS;
+}
+
+void
+kadm_cli_disconn()
+{
+ (void) close(client_parm.admin_fd);
+ (void) signal(SIGPIPE, opipe);
+}
+
+int
+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 0000000000000..e45a9c24cb7f6
--- /dev/null
+++ b/eBones/lib/libkadm/kadm_err.et
@@ -0,0 +1,53 @@
+# $Source: /usr/cvs/src/eBones/libkadm/kadm_err.et,v $
+# $Author: mark $
+# $Header: /usr/cvs/src/eBones/libkadm/kadm_err.et,v 1.1 1995/07/18 16:40:25 mark 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: /usr/cvs/src/eBones/libkadm/kadm_err.et,v 1.1 1995/07/18 16:40:25 mark 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 0000000000000..58a625a464b1d
--- /dev/null
+++ b/eBones/lib/libkadm/kadm_stream.c
@@ -0,0 +1,286 @@
+/*
+ * 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
+ */
+
+#if 0
+#ifndef lint
+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 ";
+static const char rcsid[] =
+ "$Id: kadm_stream.c,v 1.1 1995/07/18 16:40:27 mark Exp $";
+#endif lint
+#endif
+
+/*
+ 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 <string.h>
+#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
+*/
+
+int
+vals_to_stream(dt_in, dt_out)
+Kadm_vals *dt_in;
+u_char **dt_out;
+{
+ int vsloop, stsize; /* loop counter, stream size */
+
+ stsize = build_field_header(dt_in->fields, dt_out);
+ for (vsloop=31; vsloop>=0; vsloop--)
+ if (IS_FIELD(vsloop,dt_in->fields)) {
+ switch (vsloop) {
+ case KADM_NAME:
+ stsize+=vts_string(dt_in->name, dt_out, stsize);
+ break;
+ case KADM_INST:
+ stsize+=vts_string(dt_in->instance, dt_out, stsize);
+ break;
+ case KADM_EXPDATE:
+ stsize+=vts_long(dt_in->exp_date, dt_out, stsize);
+ break;
+ case KADM_ATTR:
+ stsize+=vts_short(dt_in->attributes, dt_out, stsize);
+ break;
+ case KADM_MAXLIFE:
+ stsize+=vts_char(dt_in->max_life, dt_out, stsize);
+ break;
+ case KADM_DESKEY:
+ stsize+=vts_long(dt_in->key_high, dt_out, stsize);
+ stsize+=vts_long(dt_in->key_low, dt_out, stsize);
+ break;
+ default:
+ break;
+ }
+}
+ return(stsize);
+}
+
+int
+build_field_header(cont, st)
+u_char *cont; /* container for fields data */
+u_char **st; /* stream */
+{
+ *st = (u_char *) malloc (4);
+ bcopy((char *) cont, (char *) *st, 4);
+ return 4; /* return pointer to current stream location */
+}
+
+int
+vts_string(dat, st, loc)
+char *dat; /* a string to put on the stream */
+u_char **st; /* base pointer to the stream */
+int loc; /* offset into the stream for current data */
+{
+ *st = (u_char *) realloc ((char *)*st, (unsigned) (loc + strlen(dat) + 1));
+ bcopy(dat, (char *)(*st + loc), strlen(dat)+1);
+ return strlen(dat)+1;
+}
+
+int
+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);
+}
+
+int
+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);
+}
+
+int
+vts_char(dat, st, loc)
+u_char dat; /* the attributes field */
+u_char **st; /* a base pointer to the stream */
+int loc; /* offset into the stream for current data */
+{
+ *st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_char)));
+ (*st)[loc] = (u_char) dat;
+ return 1;
+}
+
+/*
+stream_to_vals
+ recieves : u_char *, kadm_vals *
+ returns : a kadm_vals filled in according to u_char *
+
+this decodes a byte stream represntation of a vals struct into kadm_vals
+*/
+int
+stream_to_vals(dt_in, dt_out, maxlen)
+u_char *dt_in;
+Kadm_vals *dt_out;
+int maxlen; /* max length to use */
+{
+ register int vsloop, stsize; /* loop counter, stream size */
+ register int status;
+
+ bzero((char *) dt_out, sizeof(*dt_out));
+
+ stsize = check_field_header(dt_in, dt_out->fields, maxlen);
+ if (stsize < 0)
+ return(-1);
+ for (vsloop=31; vsloop>=0; vsloop--)
+ if (IS_FIELD(vsloop,dt_out->fields))
+ switch (vsloop) {
+ case KADM_NAME:
+ if ((status = stv_string(dt_in, dt_out->name, stsize,
+ sizeof(dt_out->name), maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_INST:
+ if ((status = stv_string(dt_in, dt_out->instance, stsize,
+ sizeof(dt_out->instance), maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_EXPDATE:
+ if ((status = stv_long(dt_in, &dt_out->exp_date, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_ATTR:
+ if ((status = stv_short(dt_in, &dt_out->attributes, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_MAXLIFE:
+ if ((status = stv_char(dt_in, &dt_out->max_life, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ case KADM_DESKEY:
+ if ((status = stv_long(dt_in, &dt_out->key_high, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ if ((status = stv_long(dt_in, &dt_out->key_low, stsize,
+ maxlen)) < 0)
+ return(-1);
+ stsize += status;
+ break;
+ default:
+ break;
+ }
+ return stsize;
+}
+
+int
+check_field_header(st, cont, maxlen)
+u_char *st; /* stream */
+u_char *cont; /* container for fields data */
+int maxlen;
+{
+ if (4 > maxlen)
+ return(-1);
+ bcopy((char *) st, (char *) cont, 4);
+ return 4; /* return pointer to current stream location */
+}
+
+int
+stv_string(st, dat, loc, stlen, maxlen)
+register u_char *st; /* base pointer to the stream */
+char *dat; /* a string to read from the stream */
+register int loc; /* offset into the stream for current data */
+int stlen; /* max length of string to copy in */
+int maxlen; /* max length of input stream */
+{
+ int maxcount; /* max count of chars to copy */
+
+ maxcount = min(maxlen - loc, stlen);
+
+ (void) strncpy(dat, (char *)st + loc, maxcount);
+
+ if (dat[maxcount-1]) /* not null-term --> not enuf room */
+ return(-1);
+ return strlen(dat)+1;
+}
+
+int
+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);
+}
+
+int
+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);
+}
+
+int
+stv_char(st, dat, loc, maxlen)
+u_char *st; /* a base pointer to the stream */
+u_char *dat; /* the attributes field */
+int loc; /* offset into the stream for current data */
+int maxlen;
+{
+ if (loc + 1 > maxlen)
+ return(-1);
+ *dat = *(st + loc);
+ return 1;
+}
+
diff --git a/eBones/lib/libkadm/kadm_supp.c b/eBones/lib/libkadm/kadm_supp.c
new file mode 100644
index 0000000000000..353fed0ed9b33
--- /dev/null
+++ b/eBones/lib/libkadm/kadm_supp.c
@@ -0,0 +1,118 @@
+/*
+ * 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
+ */
+
+#if 0
+#ifndef lint
+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 ";
+static const char rcsid[] =
+ "$Id: kadm_supp.c,v 1.1 1995/07/18 16:40:28 mark Exp $";
+#endif lint
+#endif
+
+/*
+ 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 <string.h>
+#include <time.h>
+#include <kadm.h>
+#include <krb_db.h>
+
+/*
+prin_vals:
+ recieves : a vals structure
+*/
+void
+prin_vals(vals)
+Kadm_vals *vals;
+{
+ printf("Info in Database for %s.%s:\n", vals->name, vals->instance);
+ printf(" Max Life: %d Exp Date: %s\n",vals->max_life,
+ asctime(localtime((long *)&vals->exp_date)));
+ printf(" Attribs: %.2x key: %lu %lu\n",vals->attributes,
+ vals->key_low, vals->key_high);
+}
+
+#ifdef notdef
+nierror(s)
+int s;
+{
+ printf("Kerberos admin server loses..... %s\n",error_message(s));
+ return(s);
+}
+#endif
+
+/* kadm_prin_to_vals takes a fields arguments, a Kadm_vals and a Principal,
+ it copies the fields in Principal specified by fields into Kadm_vals,
+ i.e from old to new */
+
+void
+kadm_prin_to_vals(fields, new, old)
+u_char fields[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);
+ }
+}
+
+void
+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/lib/libkdb/Makefile b/eBones/lib/libkdb/Makefile
new file mode 100644
index 0000000000000..29beb2401b309
--- /dev/null
+++ b/eBones/lib/libkdb/Makefile
@@ -0,0 +1,8 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:23:53 markm Exp $
+
+LIB= kdb
+CFLAGS+=-DKERBEROS -DDEBUG
+SRCS= krb_cache.c krb_dbm.c krb_kdb_utils.c krb_lib.c print_princ.c
+
+.include <bsd.lib.mk>
diff --git a/eBones/lib/libkdb/krb_cache.c b/eBones/lib/libkdb/krb_cache.c
new file mode 100644
index 0000000000000..1c7c9ce3d7f27
--- /dev/null
+++ b/eBones/lib/libkdb/krb_cache.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This is where a cache would be implemented, if it were necessary.
+ *
+ * from: krb_cache.c,v 4.5 89/01/24 18:12:34 jon Exp $
+ * $Id: krb_cache.c,v 1.3 1995/07/18 16:37:12 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_cache.c,v 1.3 1995/07/18 16:37:12 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#ifdef DEBUG
+extern int debug;
+extern long kerb_debug;
+#endif
+static init = 0;
+
+/*
+ * initialization routine for cache
+ */
+
+int
+kerb_cache_init()
+{
+ init = 1;
+ return (0);
+}
+
+/*
+ * look up a principal in the cache returns number of principals found
+ */
+
+int
+kerb_cache_get_principal(serv, inst, principal, max)
+ char *serv; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+
+{
+ int found = 0;
+
+ if (!init)
+ kerb_cache_init();
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ fprintf(stderr, "cache_get_principal for %s %s max = %d\n",
+ serv, inst, max);
+ if (found) {
+ fprintf(stderr, "cache get %s %s found %s %s\n",
+ serv, inst, principal->name, principal->instance);
+ } else {
+ fprintf(stderr, "cache %s %s not found\n", serv,
+ inst);
+ }
+ }
+#endif
+ return (found);
+}
+
+/*
+ * insert/replace a principal in the cache returns number of principals
+ * inserted
+ */
+
+int
+kerb_cache_put_principal(principal, max)
+ Principal *principal;
+ unsigned int max; /* max number of principal structs to
+ * insert */
+
+{
+ u_long i;
+ int count = 0;
+
+ if (!init)
+ kerb_cache_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ fprintf(stderr, "kerb_cache_put_principal max = %d",
+ max);
+ }
+#endif
+
+ for (i = 0; i < max; i++) {
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "\n %s %s",
+ principal->name, principal->instance);
+#endif
+ /* DO IT */
+ count++;
+ principal++;
+ }
+ return count;
+}
+
+/*
+ * look up a dba in the cache returns number of dbas found
+ */
+
+int
+kerb_cache_get_dba(serv, inst, dba, max)
+ char *serv; /* could have wild card */
+ char *inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+
+{
+ int found = 0;
+
+ if (!init)
+ kerb_cache_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ fprintf(stderr, "cache_get_dba for %s %s max = %d\n",
+ serv, inst, max);
+ if (found) {
+ fprintf(stderr, "cache get %s %s found %s %s\n",
+ serv, inst, dba->name, dba->instance);
+ } else {
+ fprintf(stderr, "cache %s %s not found\n", serv, inst);
+ }
+ }
+#endif
+ return (found);
+}
+
+/*
+ * insert/replace a dba in the cache returns number of dbas inserted
+ */
+
+int
+kerb_cache_put_dba(dba, max)
+ Dba *dba;
+ unsigned int max; /* max number of dba structs to insert */
+
+{
+ u_long i;
+ int count = 0;
+
+ if (!init)
+ kerb_cache_init();
+#ifdef DEBUG
+ if (kerb_debug & 2) {
+ fprintf(stderr, "kerb_cache_put_dba max = %d", max);
+ }
+#endif
+ for (i = 0; i < max; i++) {
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "\n %s %s",
+ dba->name, dba->instance);
+#endif
+ /* DO IT */
+ count++;
+ dba++;
+ }
+ return count;
+}
+
diff --git a/eBones/lib/libkdb/krb_dbm.c b/eBones/lib/libkdb/krb_dbm.c
new file mode 100644
index 0000000000000..760bd6f6bd37d
--- /dev/null
+++ b/eBones/lib/libkdb/krb_dbm.c
@@ -0,0 +1,789 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krb_dbm.c,v 4.9 89/04/18 16:15:13 wesommer Exp $
+ * $Id: krb_dbm.c,v 1.4 1995/08/03 17:15:42 mark Exp $
+*/
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_dbm.c,v 1.4 1995/08/03 17:15:42 mark Exp $";
+#endif lint
+#endif
+
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+#define _NDBM_
+#endif
+
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+#define _DBM_
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/errno.h>
+#include <strings.h>
+#include <des.h>
+#include <sys/file.h>
+#ifdef _NDBM_
+#include <ndbm.h>
+#else /*_NDBM_*/
+#include <dbm.h>
+#endif /*_NDBM_*/
+/* before krb_db.h */
+#include <krb.h>
+#include <krb_db.h>
+
+#ifdef dbm_pagfno
+#define DB
+#endif
+
+#define KERB_DB_MAX_RETRY 5
+
+#ifdef DEBUG
+extern int debug;
+extern long kerb_debug;
+extern char *progname;
+#endif
+
+static init = 0;
+static char default_db_name[] = DBM_FILE;
+static char *current_db_name = default_db_name;
+static void encode_princ_key(datum *key, char *name, char *instance);
+static void decode_princ_key(datum *key, char *name, char *instance);
+static void encode_princ_contents(datum *contents, Principal *principal);
+static void decode_princ_contents(datum *contents, Principal *principal);
+static void kerb_dbl_fini(void);
+static int kerb_dbl_lock(int mode);
+static void kerb_dbl_unlock(void);
+static long kerb_start_update(char *db_name);
+static long kerb_end_update(char *db_name, long age);
+
+static struct timeval timestamp;/* current time of request */
+static int non_blocking = 0;
+
+/*
+ * This module contains all of the code which directly interfaces to
+ * the underlying representation of the Kerberos database; this
+ * implementation uses a DBM or NDBM indexed "file" (actually
+ * implemented as two separate files) to store the relations, plus a
+ * third file as a semaphore to allow the database to be replaced out
+ * from underneath the KDC server.
+ */
+
+/*
+ * Locking:
+ *
+ * There are two distinct locking protocols used. One is designed to
+ * lock against processes (the admin_server, for one) which make
+ * incremental changes to the database; the other is designed to lock
+ * against utilities (kdb_util, kpropd) which replace the entire
+ * database in one fell swoop.
+ *
+ * The first locking protocol is implemented using flock() in the
+ * krb_dbl_lock() and krb_dbl_unlock routines.
+ *
+ * The second locking protocol is necessary because DBM "files" are
+ * actually implemented as two separate files, and it is impossible to
+ * atomically rename two files simultaneously. It assumes that the
+ * database is replaced only very infrequently in comparison to the time
+ * needed to do a database read operation.
+ *
+ * A third file is used as a "version" semaphore; the modification
+ * time of this file is the "version number" of the database.
+ * At the start of a read operation, the reader checks the version
+ * number; at the end of the read operation, it checks again. If the
+ * version number changed, or if the semaphore was nonexistant at
+ * either time, the reader sleeps for a second to let things
+ * stabilize, and then tries again; if it does not succeed after
+ * KERB_DB_MAX_RETRY attempts, it gives up.
+ *
+ * On update, the semaphore file is deleted (if it exists) before any
+ * update takes place; at the end of the update, it is replaced, with
+ * a version number strictly greater than the version number which
+ * existed at the start of the update.
+ *
+ * If the system crashes in the middle of an update, the semaphore
+ * file is not automatically created on reboot; this is a feature, not
+ * a bug, since the database may be inconsistant. Note that the
+ * absence of a semaphore file does not prevent another _update_ from
+ * taking place later. Database replacements take place automatically
+ * only on slave servers; a crash in the middle of an update will be
+ * fixed by the next slave propagation. A crash in the middle of an
+ * update on the master would be somewhat more serious, but this would
+ * likely be noticed by an administrator, who could fix the problem and
+ * retry the operation.
+ */
+
+/* Macros to convert ndbm names to dbm names.
+ * Note that dbm_nextkey() cannot be simply converted using a macro, since
+ * it is invoked giving the database, and nextkey() needs the previous key.
+ *
+ * Instead, all routines call "dbm_next" instead.
+ */
+
+#ifndef _NDBM_
+typedef char DBM;
+
+#define dbm_open(file, flags, mode) ((dbminit(file) == 0)?"":((char *)0))
+#define dbm_fetch(db, key) fetch(key)
+#define dbm_store(db, key, content, flag) store(key, content)
+#define dbm_firstkey(db) firstkey()
+#define dbm_next(db,key) nextkey(key)
+#define dbm_close(db) dbmclose()
+#else
+#define dbm_next(db,key) dbm_nextkey(db)
+#endif
+
+/*
+ * Utility routine: generate name of database file.
+ */
+
+static char *gen_dbsuffix(db_name, sfx)
+ char *db_name;
+ char *sfx;
+{
+ char *dbsuffix;
+
+ if (sfx == NULL)
+ sfx = ".ok";
+
+ dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1);
+ strcpy(dbsuffix, db_name);
+ strcat(dbsuffix, sfx);
+ return dbsuffix;
+}
+
+/*
+ * initialization for data base routines.
+ */
+
+int
+kerb_db_init()
+{
+ init = 1;
+ return (0);
+}
+
+/*
+ * gracefully shut down database--must be called by ANY program that does
+ * a kerb_db_init
+ */
+
+void
+kerb_db_fini()
+{
+}
+
+/*
+ * Set the "name" of the current database to some alternate value.
+ *
+ * Passing a null pointer as "name" will set back to the default.
+ * If the alternate database doesn't exist, nothing is changed.
+ */
+
+int
+kerb_db_set_name(name)
+ char *name;
+{
+ DBM *db;
+
+ if (name == NULL)
+ name = default_db_name;
+ db = dbm_open(name, 0, 0);
+ if (db == NULL)
+ return errno;
+ dbm_close(db);
+ kerb_dbl_fini();
+ current_db_name = name;
+ return 0;
+}
+
+/*
+ * Return the last modification time of the database.
+ */
+
+long
+kerb_get_db_age()
+{
+ struct stat st;
+ char *okname;
+ long age;
+
+ okname = gen_dbsuffix(current_db_name, ".ok");
+
+ if (stat (okname, &st) < 0)
+ age = 0;
+ else
+ age = st.st_mtime;
+
+ free (okname);
+ return age;
+}
+
+/*
+ * Remove the semaphore file; indicates that database is currently
+ * under renovation.
+ *
+ * This is only for use when moving the database out from underneath
+ * the server (for example, during slave updates).
+ */
+
+static long
+kerb_start_update(db_name)
+ char *db_name;
+{
+ char *okname = gen_dbsuffix(db_name, ".ok");
+ long age = kerb_get_db_age();
+
+ if (unlink(okname) < 0
+ && errno != ENOENT) {
+ age = -1;
+ }
+ free (okname);
+ return age;
+}
+
+static long
+kerb_end_update(db_name, age)
+ char *db_name;
+ long age;
+{
+ int fd;
+ int retval = 0;
+ char *new_okname = gen_dbsuffix(db_name, ".ok#");
+ char *okname = gen_dbsuffix(db_name, ".ok");
+
+ fd = open (new_okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+ if (fd < 0)
+ retval = errno;
+ else {
+ struct stat st;
+ struct timeval tv[2];
+ /* make sure that semaphore is "after" previous value. */
+ if (fstat (fd, &st) == 0
+ && st.st_mtime <= age) {
+ tv[0].tv_sec = st.st_atime;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = age;
+ tv[1].tv_usec = 0;
+ /* set times.. */
+ utimes (new_okname, tv);
+ fsync(fd);
+ }
+ close(fd);
+ if (rename (new_okname, okname) < 0)
+ retval = errno;
+ }
+
+ free (new_okname);
+ free (okname);
+
+ return retval;
+}
+
+static long
+kerb_start_read()
+{
+ return kerb_get_db_age();
+}
+
+static long
+kerb_end_read(age)
+ u_long age;
+{
+ if (kerb_get_db_age() != age || age == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Create the database, assuming it's not there.
+ */
+
+int
+kerb_db_create(db_name)
+ char *db_name;
+{
+ char *okname = gen_dbsuffix(db_name, ".ok");
+ int fd;
+ register int ret = 0;
+#ifdef _NDBM_
+ DBM *db;
+
+ db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (db == NULL)
+ ret = errno;
+ else
+ dbm_close(db);
+#else
+ char *dirname = gen_dbsuffix(db_name, ".dir");
+ char *pagname = gen_dbsuffix(db_name, ".pag");
+
+ fd = open(dirname, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (fd < 0)
+ ret = errno;
+ else {
+ close(fd);
+ fd = open (pagname, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (fd < 0)
+ ret = errno;
+ else
+ close(fd);
+ }
+ if (dbminit(db_name) < 0)
+ ret = errno;
+#endif
+ if (ret == 0) {
+ fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+ if (fd < 0)
+ ret = errno;
+ close(fd);
+ }
+ return ret;
+}
+
+/*
+ * "Atomically" rename the database in a way that locks out read
+ * access in the middle of the rename.
+ *
+ * Not perfect; if we crash in the middle of an update, we don't
+ * necessarily know to complete the transaction the rename, but...
+ */
+
+int
+kerb_db_rename(from, to)
+ char *from;
+ char *to;
+{
+#ifdef _DBM_
+ char *fromdb = gen_dbsuffix (from, ".db");
+ char *todb = gen_dbsuffix (to, ".db");
+#else
+ char *fromdir = gen_dbsuffix (from, ".dir");
+ char *todir = gen_dbsuffix (to, ".dir");
+ char *frompag = gen_dbsuffix (from , ".pag");
+ char *topag = gen_dbsuffix (to, ".pag");
+#endif
+ char *fromok = gen_dbsuffix(from, ".ok");
+ long trans = kerb_start_update(to);
+ int ok = 0;
+
+#ifdef _DBM_
+ if (rename (fromdb, todb) == 0) {
+#else
+ if ((rename (fromdir, todir) == 0)
+ && (rename (frompag, topag) == 0)) {
+#endif
+ (void) unlink (fromok);
+ ok = 1;
+ }
+
+ free (fromok);
+#ifdef _DBM_
+ free (fromdb);
+ free (todb);
+#else
+ free (fromdir);
+ free (todir);
+ free (frompag);
+ free (topag);
+#endif
+ if (ok)
+ return kerb_end_update(to, trans);
+ else
+ return -1;
+}
+
+/*
+ * look up a principal in the data base returns number of principals
+ * found , and whether there were more than requested.
+ */
+
+int
+kerb_db_get_principal(name, inst, principal, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* where there more than 'max' tuples? */
+
+{
+ int found = 0, code;
+ extern int errorproc();
+ int wildp, wildi;
+ datum key, contents;
+ char testname[ANAME_SZ], testinst[INST_SZ];
+ u_long trans;
+ int try;
+ DBM *db;
+
+ if (!init)
+ kerb_db_init(); /* initialize database routines */
+
+ for (try = 0; try < KERB_DB_MAX_RETRY; try++) {
+ trans = kerb_start_read();
+
+ if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
+ return -1;
+
+ db = dbm_open(current_db_name, O_RDONLY, 0600);
+
+ *more = 0;
+
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr,
+ "%s: db_get_principal for %s %s max = %d",
+ progname, name, inst, max);
+#endif
+
+ wildp = !strcmp(name, "*");
+ wildi = !strcmp(inst, "*");
+
+ if (!wildi && !wildp) { /* nothing's wild */
+ encode_princ_key(&key, name, inst);
+ contents = dbm_fetch(db, key);
+ if (contents.dptr == NULL) {
+ found = 0;
+ goto done;
+ }
+ decode_princ_contents(&contents, principal);
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ fprintf(stderr, "\t found %s %s p_n length %d t_n length %d\n",
+ principal->name, principal->instance,
+ strlen(principal->name),
+ strlen(principal->instance));
+ }
+#endif
+ found = 1;
+ goto done;
+ }
+ /* process wild cards by looping through entire database */
+
+ for (key = dbm_firstkey(db); key.dptr != NULL;
+ key = dbm_next(db, key)) {
+ decode_princ_key(&key, testname, testinst);
+ if ((wildp || !strcmp(testname, name)) &&
+ (wildi || !strcmp(testinst, inst))) { /* have a match */
+ if (found >= max) {
+ *more = 1;
+ goto done;
+ } else {
+ found++;
+ contents = dbm_fetch(db, key);
+ decode_princ_contents(&contents, principal);
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ fprintf(stderr,
+ "\tfound %s %s p_n length %d t_n length %d\n",
+ principal->name, principal->instance,
+ strlen(principal->name),
+ strlen(principal->instance));
+ }
+#endif
+ principal++; /* point to next */
+ }
+ }
+ }
+
+ done:
+ kerb_dbl_unlock(); /* unlock read lock */
+ dbm_close(db);
+ if (kerb_end_read(trans) == 0)
+ break;
+ found = -1;
+ if (!non_blocking)
+ sleep(1);
+ }
+ return (found);
+}
+
+/*
+ * Update a name in the data base. Returns number of names
+ * successfully updated.
+ */
+
+int
+kerb_db_put_principal(principal, max)
+ Principal *principal;
+ unsigned int max; /* number of principal structs to
+ * update */
+
+{
+ int found = 0, code;
+ u_long i;
+ extern int errorproc();
+ datum key, contents;
+ DBM *db;
+
+ gettimeofday(&timestamp, NULL);
+
+ if (!init)
+ kerb_db_init();
+
+ if ((code = kerb_dbl_lock(KERB_DBL_EXCLUSIVE)) != 0)
+ return -1;
+
+ db = dbm_open(current_db_name, O_RDWR, 0600);
+
+#ifdef DEBUG
+ if (kerb_debug & 2)
+ fprintf(stderr, "%s: kerb_db_put_principal max = %d",
+ progname, max);
+#endif
+
+ /* for each one, stuff temps, and do replace/append */
+ for (i = 0; i < max; i++) {
+ encode_princ_contents(&contents, principal);
+ encode_princ_key(&key, principal->name, principal->instance);
+ dbm_store(db, key, contents, DBM_REPLACE);
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ fprintf(stderr, "\n put %s %s\n",
+ principal->name, principal->instance);
+ }
+#endif
+ found++;
+ principal++; /* bump to next struct */
+ }
+
+ dbm_close(db);
+ kerb_dbl_unlock(); /* unlock database */
+ return (found);
+}
+
+static void
+encode_princ_key(key, name, instance)
+ datum *key;
+ char *name, *instance;
+{
+ static char keystring[ANAME_SZ + INST_SZ];
+
+ bzero(keystring, ANAME_SZ + INST_SZ);
+ strncpy(keystring, name, ANAME_SZ);
+ strncpy(&keystring[ANAME_SZ], instance, INST_SZ);
+ key->dptr = keystring;
+ key->dsize = ANAME_SZ + INST_SZ;
+}
+
+static void
+decode_princ_key(key, name, instance)
+ datum *key;
+ char *name, *instance;
+{
+ strncpy(name, key->dptr, ANAME_SZ);
+ strncpy(instance, key->dptr + ANAME_SZ, INST_SZ);
+ name[ANAME_SZ - 1] = '\0';
+ instance[INST_SZ - 1] = '\0';
+}
+
+static void
+encode_princ_contents(contents, principal)
+ datum *contents;
+ Principal *principal;
+{
+ contents->dsize = sizeof(*principal);
+ contents->dptr = (char *) principal;
+}
+
+static void
+decode_princ_contents(contents, principal)
+ datum *contents;
+ Principal *principal;
+{
+ bcopy(contents->dptr, (char *) principal, sizeof(*principal));
+}
+
+void
+kerb_db_get_stat(s)
+ DB_stat *s;
+{
+ gettimeofday(&timestamp, NULL);
+
+
+ s->cpu = 0;
+ s->elapsed = 0;
+ s->dio = 0;
+ s->pfault = 0;
+ s->t_stamp = timestamp.tv_sec;
+ s->n_retrieve = 0;
+ s->n_replace = 0;
+ s->n_append = 0;
+ s->n_get_stat = 0;
+ s->n_put_stat = 0;
+ /* update local copy too */
+}
+
+void
+kerb_db_put_stat(s)
+ DB_stat *s;
+{
+}
+
+void
+delta_stat(a, b, c)
+ DB_stat *a, *b, *c;
+{
+ /* c = a - b then b = a for the next time */
+
+ c->cpu = a->cpu - b->cpu;
+ c->elapsed = a->elapsed - b->elapsed;
+ c->dio = a->dio - b->dio;
+ c->pfault = a->pfault - b->pfault;
+ c->t_stamp = a->t_stamp - b->t_stamp;
+ c->n_retrieve = a->n_retrieve - b->n_retrieve;
+ c->n_replace = a->n_replace - b->n_replace;
+ c->n_append = a->n_append - b->n_append;
+ c->n_get_stat = a->n_get_stat - b->n_get_stat;
+ c->n_put_stat = a->n_put_stat - b->n_put_stat;
+
+ bcopy(a, b, sizeof(DB_stat));
+}
+
+/*
+ * look up a dba in the data base returns number of dbas found , and
+ * whether there were more than requested.
+ */
+
+int
+kerb_db_get_dba(dba_name, dba_inst, dba, max, more)
+ char *dba_name; /* could have wild card */
+ char *dba_inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* where there more than 'max' tuples? */
+
+{
+ *more = 0;
+ return (0);
+}
+
+int
+kerb_db_iterate (func, arg)
+ int (*func)();
+ char *arg; /* void *, really */
+{
+ datum key, contents;
+ Principal *principal;
+ int code;
+ DBM *db;
+
+ kerb_db_init(); /* initialize and open the database */
+ if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
+ return code;
+
+ db = dbm_open(current_db_name, O_RDONLY, 0600);
+
+ for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) {
+ contents = dbm_fetch (db, key);
+ /* XXX may not be properly aligned */
+ principal = (Principal *) contents.dptr;
+ if ((code = (*func)(arg, principal)) != 0)
+ return code;
+ }
+ dbm_close(db);
+ kerb_dbl_unlock();
+ return 0;
+}
+
+static int dblfd = -1;
+static int mylock = 0;
+static int inited = 0;
+
+static void
+kerb_dbl_init()
+{
+ if (!inited) {
+ char *filename = gen_dbsuffix (current_db_name, ".ok");
+ if ((dblfd = open(filename, 0)) < 0) {
+ fprintf(stderr, "kerb_dbl_init: couldn't open %s\n", filename);
+ fflush(stderr);
+ perror("open");
+ exit(1);
+ }
+ free(filename);
+ inited++;
+ }
+}
+
+static void
+kerb_dbl_fini()
+{
+ close(dblfd);
+ dblfd = -1;
+ inited = 0;
+ mylock = 0;
+}
+
+static int
+kerb_dbl_lock(mode)
+ int mode;
+{
+ int flock_mode;
+
+ if (!inited)
+ kerb_dbl_init();
+ if (mylock) { /* Detect lock call when lock already
+ * locked */
+ fprintf(stderr, "Kerberos locking error (mylock)\n");
+ fflush(stderr);
+ exit(1);
+ }
+ switch (mode) {
+ case KERB_DBL_EXCLUSIVE:
+ flock_mode = LOCK_EX;
+ break;
+ case KERB_DBL_SHARED:
+ flock_mode = LOCK_SH;
+ break;
+ default:
+ fprintf(stderr, "invalid lock mode %d\n", mode);
+ abort();
+ }
+ if (non_blocking)
+ flock_mode |= LOCK_NB;
+
+ if (flock(dblfd, flock_mode) < 0)
+ return errno;
+ mylock++;
+ return 0;
+}
+
+static void
+kerb_dbl_unlock()
+{
+ if (!mylock) { /* lock already unlocked */
+ fprintf(stderr, "Kerberos database lock not locked when unlocking.\n");
+ fflush(stderr);
+ exit(1);
+ }
+ if (flock(dblfd, LOCK_UN) < 0) {
+ fprintf(stderr, "Kerberos database lock error. (unlocking)\n");
+ fflush(stderr);
+ perror("flock");
+ exit(1);
+ }
+ mylock = 0;
+}
+
+int
+kerb_db_set_lockmode(mode)
+ int mode;
+{
+ int old = non_blocking;
+ non_blocking = mode;
+ return old;
+}
diff --git a/eBones/lib/libkdb/krb_kdb_utils.c b/eBones/lib/libkdb/krb_kdb_utils.c
new file mode 100644
index 0000000000000..0256348e2b77b
--- /dev/null
+++ b/eBones/lib/libkdb/krb_kdb_utils.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Utility routines for Kerberos programs which directly access
+ * the database. This code was duplicated in too many places
+ * before I gathered it here.
+ *
+ * Jon Rochlis, MIT Telecom, March 1988
+ *
+ * from: krb_kdb_utils.c,v 4.1 89/07/26 11:01:12 jtkohl Exp $
+ * $Id: krb_kdb_utils.c,v 1.3 1995/07/18 16:37:15 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_kdb_utils.c,v 1.3 1995/07/18 16:37:15 mark Exp $";
+#endif lint
+#endif
+
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+#include <kdc.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/file.h>
+
+long
+kdb_get_master_key(prompt, master_key, master_key_sched)
+ int prompt;
+ C_Block master_key;
+ Key_schedule master_key_sched;
+{
+ int kfile;
+
+ if (prompt) {
+#ifdef NOENCRYPTION
+ placebo_read_password(master_key,
+ "\nEnter Kerberos master key: ", 0);
+#else
+ des_read_password((des_cblock *)master_key,
+ "\nEnter Kerberos master key: ", 0);
+#endif
+ printf ("\n");
+ }
+ else {
+ kfile = open(MKEYFILE, O_RDONLY, 0600);
+ if (kfile < 0) {
+ /* oh, for com_err_ */
+ return (-1);
+ }
+ if (read(kfile, (char *) master_key, 8) != 8) {
+ return (-1);
+ }
+ close(kfile);
+ }
+
+#ifndef NOENCRYPTION
+ key_sched((des_cblock *)master_key,master_key_sched);
+#endif
+ return (0);
+}
+
+/* The caller is reasponsible for cleaning up the master key and sched,
+ even if we can't verify the master key */
+
+/* Returns master key version if successful, otherwise -1 */
+
+long
+kdb_verify_master_key (master_key, master_key_sched, out)
+ C_Block master_key;
+ Key_schedule master_key_sched;
+ FILE *out; /* setting this to non-null be do output */
+{
+ C_Block key_from_db;
+ Principal principal_data[1];
+ int n, more = 0;
+ long master_key_version;
+
+ /* lookup the master key version */
+ n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
+ 1 /* only one please */, &more);
+ if ((n != 1) || more) {
+ if (out != (FILE *) NULL)
+ fprintf(out,
+ "verify_master_key: %s, %d found.\n",
+ "Kerberos error on master key version lookup",
+ n);
+ return (-1);
+ }
+
+ master_key_version = (long) principal_data[0].key_version;
+
+ /* set up the master key */
+ if (out != (FILE *) NULL) /* should we punt this? */
+ fprintf(out, "Current Kerberos master key version is %d.\n",
+ principal_data[0].kdc_key_ver);
+
+ /*
+ * now use the master key to decrypt the key in the db, had better
+ * be the same!
+ */
+ bcopy(&principal_data[0].key_low, key_from_db, 4);
+ bcopy(&principal_data[0].key_high, ((long *) key_from_db) + 1, 4);
+ kdb_encrypt_key (key_from_db, key_from_db,
+ master_key, master_key_sched, DECRYPT);
+
+ /* the decrypted database key had better equal the master key */
+ n = bcmp((char *) master_key, (char *) key_from_db,
+ sizeof(master_key));
+ /* this used to zero the master key here! */
+ bzero(key_from_db, sizeof(key_from_db));
+ bzero(principal_data, sizeof (principal_data));
+
+ if (n && (out != (FILE *) NULL)) {
+ fprintf(out, "\n\07\07verify_master_key: Invalid master key; ");
+ fprintf(out, "does not match database.\n");
+ return (-1);
+ }
+ if (out != (FILE *) NULL) {
+ fprintf(out, "\nMaster key entered. BEWARE!\07\07\n");
+ fflush(out);
+ }
+
+ return (master_key_version);
+}
+
+/* The old algorithm used the key schedule as the initial vector which
+ was byte order depedent ... */
+
+void
+kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag)
+ C_Block in, out, master_key;
+ Key_schedule master_key_sched;
+ int e_d_flag;
+{
+
+#ifdef NOENCRYPTION
+ bcopy(in, out, sizeof(C_Block));
+#else
+ pcbc_encrypt((des_cblock*)in,(des_cblock*)out,(long)sizeof(C_Block),
+ master_key_sched,(des_cblock*)master_key,e_d_flag);
+#endif
+}
diff --git a/eBones/lib/libkdb/krb_lib.c b/eBones/lib/libkdb/krb_lib.c
new file mode 100644
index 0000000000000..2cf4fb8723d6e
--- /dev/null
+++ b/eBones/lib/libkdb/krb_lib.c
@@ -0,0 +1,242 @@
+/*
+ * $Source: /usr/cvs/src/eBones/kdb/krb_lib.c,v $
+ * $Author: mark $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_lib.c,v 1.3 1995/07/18 16:37:17 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#ifdef DEBUG
+extern int debug;
+extern char *progname;
+long kerb_debug;
+#endif
+
+static init = 0;
+
+/*
+ * initialization routine for data base
+ */
+
+int
+kerb_init()
+{
+#ifdef DEBUG
+ if (!init) {
+ char *dbg = getenv("KERB_DBG");
+ if (dbg)
+ sscanf(dbg, "%ld", &kerb_debug);
+ init = 1;
+ }
+#endif
+ kerb_db_init();
+
+#ifdef CACHE
+ kerb_cache_init();
+#endif
+
+ /* successful init, return 0, else errcode */
+ return (0);
+}
+
+/*
+ * finalization routine for database -- NOTE: MUST be called by any
+ * program using kerb_init. ALSO will have to be modified to finalize
+ * caches, if they're ever really implemented.
+ */
+
+void
+kerb_fini()
+{
+ kerb_db_fini();
+}
+
+/*
+ * look up a principal in the cache or data base returns number of
+ * principals found
+ */
+
+int
+kerb_get_principal(name, inst, principal, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Principal *principal;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* more tuples than room for */
+
+{
+ int found = 0;
+#ifdef CACHE
+ static int wild = 0;
+#endif
+ if (!init)
+ kerb_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_get_principal for %s %s max = %d\n",
+ progname, name, inst, max);
+#endif
+
+ /*
+ * if this is a request including a wild card, have to go to db
+ * since the cache may not be exhaustive.
+ */
+
+ /* clear the principal area */
+ bzero((char *) principal, max * sizeof(Principal));
+
+#ifdef CACHE
+ /*
+ * so check to see if the name contains a wildcard "*" or "?", not
+ * preceeded by a backslash.
+ */
+ wild = 0;
+ if (index(name, '*') || index(name, '?') ||
+ index(inst, '*') || index(inst, '?'))
+ wild = 1;
+
+ if (!wild) {
+ /* try the cache first */
+ found = kerb_cache_get_principal(name, inst, principal, max, more);
+ if (found)
+ return (found);
+ }
+#endif
+ /* If we didn't try cache, or it wasn't there, try db */
+ found = kerb_db_get_principal(name, inst, principal, max, more);
+ /* try to insert principal(s) into cache if it was found */
+#ifdef CACHE
+ if (found) {
+ kerb_cache_put_principal(principal, found);
+ }
+#endif
+ return (found);
+}
+
+/* principals */
+int
+kerb_put_principal(principal, n)
+ Principal *principal;
+ unsigned int n; /* number of principal structs to write */
+{
+ long time();
+ struct tm *tp, *localtime();
+
+ /* set mod date */
+ principal->mod_date = time((long *)0);
+ /* and mod date string */
+
+ tp = localtime(&principal->mod_date);
+ (void) sprintf(principal->mod_date_txt, "%4d-%2d-%2d",
+ tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+ tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+#ifdef DEBUG
+ if (kerb_debug & 1) {
+ int i;
+ fprintf(stderr, "\nkerb_put_principal...");
+ for (i = 0; i < n; i++) {
+ krb_print_principal(&principal[i]);
+ }
+ }
+#endif
+ /* write database */
+ if (kerb_db_put_principal(principal, n) < 0) {
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_db_put_principal err", progname);
+ /* watch out for cache */
+#endif
+ return -1;
+ }
+#ifdef CACHE
+ /* write cache */
+ if (!kerb_cache_put_principal(principal, n)) {
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_cache_put_principal err", progname);
+#endif
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+int
+kerb_get_dba(name, inst, dba, max, more)
+ char *name; /* could have wild card */
+ char *inst; /* could have wild card */
+ Dba *dba;
+ unsigned int max; /* max number of name structs to return */
+ int *more; /* more tuples than room for */
+
+{
+ int found = 0;
+#ifdef CACHE
+ static int wild = 0;
+#endif
+ if (!init)
+ kerb_init();
+
+#ifdef DEBUG
+ if (kerb_debug & 1)
+ fprintf(stderr, "\n%s: kerb_get_dba for %s %s max = %d\n",
+ progname, name, inst, max);
+#endif
+ /*
+ * if this is a request including a wild card, have to go to db
+ * since the cache may not be exhaustive.
+ */
+
+ /* clear the dba area */
+ bzero((char *) dba, max * sizeof(Dba));
+
+#ifdef CACHE
+ /*
+ * so check to see if the name contains a wildcard "*" or "?", not
+ * preceeded by a backslash.
+ */
+
+ wild = 0;
+ if (index(name, '*') || index(name, '?') ||
+ index(inst, '*') || index(inst, '?'))
+ wild = 1;
+
+ if (!wild) {
+ /* try the cache first */
+ found = kerb_cache_get_dba(name, inst, dba, max, more);
+ if (found)
+ return (found);
+ }
+#endif
+ /* If we didn't try cache, or it wasn't there, try db */
+ found = kerb_db_get_dba(name, inst, dba, max, more);
+#ifdef CACHE
+ /* try to insert dba(s) into cache if it was found */
+ if (found) {
+ kerb_cache_put_dba(dba, found);
+ }
+#endif
+ return (found);
+}
diff --git a/eBones/lib/libkdb/print_princ.c b/eBones/lib/libkdb/print_princ.c
new file mode 100644
index 0000000000000..64e910660e22c
--- /dev/null
+++ b/eBones/lib/libkdb/print_princ.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: $Header: /usr/cvs/src/eBones/kdb/print_princ.c,v 1.3 1995/07/18 16:37:19 mark Exp $
+ * $Id: print_princ.c,v 1.3 1995/07/18 16:37:19 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: print_princ.c,v 1.3 1995/07/18 16:37:19 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <strings.h>
+#include <krb.h>
+#include <krb_db.h>
+
+extern int debug;
+
+long kerb_debug;
+static struct tm *time_p;
+
+void
+krb_print_principal(a_n)
+ Principal *a_n;
+{
+ /* run-time database does not contain string versions */
+ time_p = localtime(&(a_n->exp_date));
+
+ fprintf(stderr,
+ "\n%s %s expires %4d-%2d-%2d %2d:%2d, max_life %d*5 = %d min attr 0x%02x",
+ a_n->name, a_n->instance,
+ time_p->tm_year > 1900 ? time_p->tm_year : time_p->tm_year + 1900,
+ time_p->tm_mon + 1, time_p->tm_mday,
+ time_p->tm_hour, time_p->tm_min,
+ a_n->max_life, 5 * a_n->max_life, a_n->attributes);
+
+ fprintf(stderr,
+ "\n\tkey_ver %d k_low 0x%08lx k_high 0x%08lx akv %d exists %d\n",
+ a_n->key_version, a_n->key_low, a_n->key_high,
+ a_n->kdc_key_ver, (int)a_n->old);
+
+ fflush(stderr);
+}
diff --git a/eBones/lib/libkrb/Makefile b/eBones/lib/libkrb/Makefile
new file mode 100644
index 0000000000000..eefe1a55d9b37
--- /dev/null
+++ b/eBones/lib/libkrb/Makefile
@@ -0,0 +1,53 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.8 1995/09/13 17:23:55 markm Exp $
+
+LIB= krb
+CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -DBSD42
+SRCS= krb_err.c create_auth_reply.c create_ciph.c \
+ create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \
+ des_rw.c dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c \
+ get_admhst.c get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c \
+ get_phost.c get_pw_tkt.c get_request.c get_svc_in_tkt.c \
+ get_tf_fullname.c get_tf_realm.c getrealm.c getst.c in_tkt.c \
+ k_gethostname.c klog.c kname_parse.c kntoln.c kparse.c \
+ krb_err_txt.c krb_get_in_tkt.c kuserok.c log.c mk_err.c \
+ mk_priv.c mk_req.c mk_safe.c month_sname.c \
+ netread.c netwrite.c one.c pkt_cipher.c pkt_clen.c rd_err.c \
+ rd_priv.c rd_req.c rd_safe.c read_service_key.c recvauth.c \
+ save_credentials.c send_to_kdc.c sendauth.c stime.c tf_util.c \
+ tkt_string.c util.c
+
+LDADD+= -lcom_err
+
+beforeinstall:
+ -cd ${.OBJDIR}; cmp -s krb_err.h \
+ ${DESTDIR}/usr/include/kerberosIV/krb_err.h || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 krb_err.h \
+ ${DESTDIR}/usr/include/kerberosIV
+
+MAN3= krb.3 krb_realmofhost.3 krb_sendauth.3 krb_set_tkt_string.3 \
+ kuserok.3 tf_util.3
+
+MLINKS= krb.3 krb_mk_req.3 krb.3 krb_rd_req.3 krb.3 krb_kntoln.3 \
+ krb.3 krb_set_key.3 krb.3 krb_get_cred.3 krb.3 krb_mk_priv.3 \
+ krb.3 krb_rd_priv.3 krb.3 krb_mk_safe.3 krb.3 krb_rd_safe.3 \
+ krb.3 krb_mk_err.3 krb.3 krb_rd_err.3 krb.3 krb_ck_repl.3
+
+MLINKS+=krb_realmofhost.3 krb_get_phost.3 krb_realmofhost.3 krb_get_krbhst.3 \
+ krb_realmofhost.3 krb_get_admhst.3 krb_realmofhost.3 krb_get_lrealm.3
+
+MLINKS+=krb_realmofhost.3 realm.3
+
+MLINKS+=krb_sendauth.3 krb_recvauth.3 krb_sendauth.3 krb_net_write.3 \
+ krb_sendauth.3 krb_net_read.3
+
+MLINKS+=krb_sendauth.3 ksend.3
+
+MLINKS+=tf_util.3 tf_init.3 tf_util.3 tf_get_pname.3 \
+ tf_util.3 tf_get_pinst.3 tf_util.3 tf_get_cred.3 \
+ tf_util.3 tf_close.3
+
+.include <bsd.lib.mk>
+
+krb_err.c: ${KRBOBJDIR}/krb_err.h
+
diff --git a/eBones/lib/libkrb/add_ticket.c b/eBones/lib/libkrb/add_ticket.c
new file mode 100644
index 0000000000000..14ef47c46a0bd
--- /dev/null
+++ b/eBones/lib/libkrb/add_ticket.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: add_ticket.c,v 4.7 88/10/07 06:06:26 shanzer Exp $
+ * $Id: add_ticket.c,v 1.3 1995/07/18 16:38:04 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: add_ticket.c,v 1.3 1995/07/18 16:38:04 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is now obsolete. It used to be possible to request
+ * more than one ticket at a time from the authentication server, and
+ * it looks like this routine was used by the server to package the
+ * tickets to be returned to the client.
+ */
+
+/*
+ * This routine adds a new ticket to the ciphertext to be returned to
+ * the client. The routine takes the ciphertext (which doesn't get
+ * encrypted till later), the number of the ticket (i.e. 1st, 2nd,
+ * etc) the session key which goes in the ticket and is sent back to
+ * the user, the lifetime for the ticket, the service name, the
+ * instance, the realm, the key version number, and the ticket itself.
+ *
+ * This routine returns 0 (KSUCCESS) on success, and 1 (KFAILURE) on
+ * failure. On failure, which occurs when there isn't enough room
+ * for the ticket, a 0 length ticket is added.
+ *
+ * Notes: This routine must be called with successive values of n.
+ * i.e. the ticket must be added in order. The corresponding routine
+ * on the client side is extract ticket.
+ */
+
+/* XXX they aren't all used; to avoid incompatible changes we will
+ * fool lint for the moment */
+/*ARGSUSED */
+int
+add_ticket(cipher,n,session,lifetime,sname,instance,realm,kvno,ticket)
+ KTEXT cipher; /* Ciphertext info for ticket */
+ char *sname; /* Service name */
+ char *instance; /* Instance */
+ int n; /* Relative position of this ticket */
+ char *session; /* Session key for this tkt */
+ int lifetime; /* Lifetime of this ticket */
+ char *realm; /* Realm in which ticket is valid */
+ int kvno; /* Key version number of service key */
+ KTEXT ticket; /* The ticket itself */
+{
+
+ /* Note, the 42 is a temporary hack; it will have to be changed. */
+
+ /* Begin check of ticket length */
+ if ((cipher->length + ticket->length + 4 + 42 +
+ (*(cipher->dat)+1-n)*(11+strlen(realm))) >
+ MAX_KTXT_LEN) {
+ bcopy(session,(char *)(cipher->dat+cipher->length),8);
+ *(cipher->dat+cipher->length+8) = (char) lifetime;
+ *(cipher->dat+cipher->length+9) = (char) kvno;
+ (void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
+ cipher->length += 11 + strlen(realm);
+ *(cipher->dat+n) = 0;
+ return(KFAILURE);
+ }
+ /* End check of ticket length */
+
+ /* Add the session key, lifetime, kvno, ticket to the ciphertext */
+ bcopy(session,(char *)(cipher->dat+cipher->length),8);
+ *(cipher->dat+cipher->length+8) = (char) lifetime;
+ *(cipher->dat+cipher->length+9) = (char) kvno;
+ (void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
+ cipher->length += 11 + strlen(realm);
+ bcopy((char *)(ticket->dat),(char *)(cipher->dat+cipher->length),
+ ticket->length);
+ cipher->length += ticket->length;
+
+ /* Set the ticket length at beginning of ciphertext */
+ *(cipher->dat+n) = ticket->length;
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/create_auth_reply.c b/eBones/lib/libkrb/create_auth_reply.c
new file mode 100644
index 0000000000000..e304b173628db
--- /dev/null
+++ b/eBones/lib/libkrb/create_auth_reply.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_auth_reply.c,v 4.10 89/01/13 17:47:38 steiner Exp $
+ * $Id: create_auth_reply.c,v 1.3 1995/07/18 16:38:06 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: create_auth_reply.c,v 1.3 1995/07/18 16:38:06 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is called by the Kerberos authentication server
+ * to create a reply to an authentication request. The routine
+ * takes the user's name, instance, and realm, the client's
+ * timestamp, the number of tickets, the user's key version
+ * number and the ciphertext containing the tickets themselves.
+ * It constructs a packet and returns a pointer to it.
+ *
+ * Notes: The packet returned by this routine is static. Thus, if you
+ * intend to keep the result beyond the next call to this routine, you
+ * must copy it elsewhere.
+ *
+ * The packet is built in the following format:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ * unsigned char KRB_PROT_VERSION protocol version number
+ *
+ * unsigned char AUTH_MSG_KDC_REPLY protocol message type
+ *
+ * [least significant HOST_BYTE_ORDER sender's (server's) byte
+ * bit of above field] order
+ *
+ * string pname principal's name
+ *
+ * string pinst principal's instance
+ *
+ * string prealm principal's realm
+ *
+ * unsigned long time_ws client's timestamp
+ *
+ * unsigned char n number of tickets
+ *
+ * unsigned long x_date expiration date
+ *
+ * unsigned char kvno master key version
+ *
+ * short w_1 cipher length
+ *
+ * --- cipher->dat cipher data
+ */
+
+KTEXT
+create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
+ char *pname; /* Principal's name */
+ char *pinst; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long time_ws; /* Workstation time */
+ int n; /* Number of tickets */
+ unsigned long x_date; /* Principal's expiration date */
+ int kvno; /* Principal's key version number */
+ KTEXT cipher; /* Cipher text with tickets and
+ * session keys */
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+ unsigned char *v = pkt->dat; /* Prot vers number */
+ unsigned char *t = (pkt->dat+1); /* Prot message type */
+ short w_l; /* Cipher length */
+
+ /* Create fixed part of packet */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_KDC_REPLY;
+ *t |= HOST_BYTE_ORDER;
+
+ if (n != 0)
+ *v = 3;
+
+ /* Add the basic info */
+ (void) strcpy((char *) (pkt->dat+2), pname);
+ pkt->length = 3 + strlen(pname);
+ (void) strcpy((char *) (pkt->dat+pkt->length),pinst);
+ pkt->length += 1 + strlen(pinst);
+ (void) strcpy((char *) (pkt->dat+pkt->length),prealm);
+ pkt->length += 1 + strlen(prealm);
+ /* Workstation timestamp */
+ bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4);
+ pkt->length += 4;
+ *(pkt->dat+(pkt->length)++) = (unsigned char) n;
+ /* Expiration date */
+ bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4);
+ pkt->length += 4;
+
+ /* Now send the ciphertext and info to help decode it */
+ *(pkt->dat+(pkt->length)++) = (unsigned char) kvno;
+ w_l = (short) cipher->length;
+ bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2);
+ pkt->length += 2;
+ bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length),
+ cipher->length);
+ pkt->length += cipher->length;
+
+ /* And return the packet */
+ return pkt;
+}
diff --git a/eBones/lib/libkrb/create_ciph.c b/eBones/lib/libkrb/create_ciph.c
new file mode 100644
index 0000000000000..7fb93e337d1c5
--- /dev/null
+++ b/eBones/lib/libkrb/create_ciph.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_ciph.c,v 4.8 89/05/18 21:24:26 jis Exp $
+ * $Id: create_ciph.c,v 1.3 1995/07/18 16:38:07 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: create_ciph.c,v 1.3 1995/07/18 16:38:07 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <des.h>
+#include <strings.h>
+
+/*
+ * This routine is used by the authentication server to create
+ * a packet for its client, containing a ticket for the requested
+ * service (given in "tkt"), and some information about the ticket,
+ *
+ * Returns KSUCCESS no matter what.
+ *
+ * The length of the cipher is stored in c->length; the format of
+ * c->dat is as follows:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ *
+ * 8 bytes session session key for client, service
+ *
+ * string service service name
+ *
+ * string instance service instance
+ *
+ * string realm KDC realm
+ *
+ * unsigned char life ticket lifetime
+ *
+ * unsigned char kvno service key version number
+ *
+ * unsigned char tkt->length length of following ticket
+ *
+ * data tkt->dat ticket for service
+ *
+ * 4 bytes kdc_time KDC's timestamp
+ *
+ * <=7 bytes null null pad to 8 byte multiple
+ *
+ */
+
+int
+create_ciph(c, session, service, instance, realm, life, kvno, tkt,
+ kdc_time, key)
+ KTEXT c; /* Text block to hold ciphertext */
+ C_Block session; /* Session key to send to user */
+ char *service; /* Service name on ticket */
+ char *instance; /* Instance name on ticket */
+ char *realm; /* Realm of this KDC */
+ unsigned long life; /* Lifetime of the ticket */
+ int kvno; /* Key version number for service */
+ KTEXT tkt; /* The ticket for the service */
+ unsigned long kdc_time; /* KDC time */
+ C_Block key; /* Key to encrypt ciphertext with */
+{
+ char *ptr;
+ Key_schedule key_s;
+
+ ptr = (char *) c->dat;
+
+ bcopy((char *) session, ptr, 8);
+ ptr += 8;
+
+ (void) strcpy(ptr,service);
+ ptr += strlen(service) + 1;
+
+ (void) strcpy(ptr,instance);
+ ptr += strlen(instance) + 1;
+
+ (void) strcpy(ptr,realm);
+ ptr += strlen(realm) + 1;
+
+ *(ptr++) = (unsigned char) life;
+ *(ptr++) = (unsigned char) kvno;
+ *(ptr++) = (unsigned char) tkt->length;
+
+ bcopy((char *)(tkt->dat),ptr,tkt->length);
+ ptr += tkt->length;
+
+ bcopy((char *) &kdc_time,ptr,4);
+ ptr += 4;
+
+ /* guarantee null padded encrypted data to multiple of 8 bytes */
+ bzero(ptr, 7);
+
+ c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8;
+
+#ifndef NOENCRYPTION
+ key_sched((C_Block *)key,key_s);
+ pcbc_encrypt((C_Block *)c->dat,(C_Block *)c->dat,(long) c->length,key_s,
+ (C_Block *)key,ENCRYPT);
+#endif /* NOENCRYPTION */
+
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/create_death_packet.c b/eBones/lib/libkrb/create_death_packet.c
new file mode 100644
index 0000000000000..bdc0e347bf15c
--- /dev/null
+++ b/eBones/lib/libkrb/create_death_packet.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_death_packet.c,v 4.9 89/01/17 16:05:59 rfrench Exp $
+ * $Id: create_death_packet.c,v 1.3 1995/07/18 16:38:09 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: create_death_packet.c,v 1.3 1995/07/18 16:38:09 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine creates a packet to type AUTH_MSG_DIE which is sent to
+ * the Kerberos server to make it shut down. It is used only in the
+ * development environment.
+ *
+ * It takes a string "a_name" which is sent in the packet. A pointer
+ * to the packet is returned.
+ *
+ * The format of the killer packet is:
+ *
+ * type variable data
+ * or constant
+ * ---- ----------- ----
+ *
+ * unsigned char KRB_PROT_VERSION protocol version number
+ *
+ * unsigned char AUTH_MSG_DIE message type
+ *
+ * [least significant HOST_BYTE_ORDER byte order of sender
+ * bit of above field]
+ *
+ * string a_name presumably, name of
+ * principal sending killer
+ * packet
+ */
+
+#ifdef DEBUG
+KTEXT
+krb_create_death_packet(a_name)
+ char *a_name;
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+
+ unsigned char *v = pkt->dat;
+ unsigned char *t = (pkt->dat+1);
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_DIE;
+ *t |= HOST_BYTE_ORDER;
+ (void) strcpy((char *) (pkt->dat+2),a_name);
+ pkt->length = 3 + strlen(a_name);
+ return pkt;
+}
+#endif /* DEBUG */
diff --git a/eBones/lib/libkrb/create_ticket.c b/eBones/lib/libkrb/create_ticket.c
new file mode 100644
index 0000000000000..e1d697419e1bc
--- /dev/null
+++ b/eBones/lib/libkrb/create_ticket.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: create_ticket.c,v 4.11 89/03/22 14:43:23 jtkohl Exp $
+ * $Id: create_ticket.c,v 1.3 1995/07/18 16:38:12 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: create_ticket.c,v 1.3 1995/07/18 16:38:12 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * Create ticket takes as arguments information that should be in a
+ * ticket, and the KTEXT object in which the ticket should be
+ * constructed. It then constructs a ticket and returns, leaving the
+ * newly created ticket in tkt.
+ * The length of the ticket is a multiple of
+ * eight bytes and is in tkt->length.
+ *
+ * If the ticket is too long, the ticket will contain nulls.
+ * The return value of the routine is undefined.
+ *
+ * The corresponding routine to extract information from a ticket it
+ * decomp_ticket. When changes are made to this routine, the
+ * corresponding changes should also be made to that file.
+ *
+ * The packet is built in the following format:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ * tkt->length length of ticket (multiple of 8 bytes)
+ *
+ * tkt->dat:
+ *
+ * unsigned char flags namely, HOST_BYTE_ORDER
+ *
+ * string pname client's name
+ *
+ * string pinstance client's instance
+ *
+ * string prealm client's realm
+ *
+ * 4 bytes paddress client's address
+ *
+ * 8 bytes session session key
+ *
+ * 1 byte life ticket lifetime
+ *
+ * 4 bytes time_sec KDC timestamp
+ *
+ * string sname service's name
+ *
+ * string sinstance service's instance
+ *
+ * <=7 bytes null null pad to 8 byte multiple
+ *
+ */
+
+int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, key)
+ KTEXT tkt; /* Gets filled in by the ticket */
+ unsigned char flags; /* Various Kerberos flags */
+ char *pname; /* Principal's name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long paddress; /* Net address of requesting entity */
+ char *session; /* Session key inserted in ticket */
+ short life; /* Lifetime of the ticket */
+ long time_sec; /* Issue time and date */
+ char *sname; /* Service Name */
+ char *sinstance; /* Instance Name */
+ C_Block key; /* Service's secret key */
+{
+ Key_schedule key_s;
+ register char *data; /* running index into ticket */
+
+ tkt->length = 0; /* Clear previous data */
+ flags |= HOST_BYTE_ORDER; /* ticket byte order */
+ bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags));
+ data = ((char *)tkt->dat) + sizeof(flags);
+ (void) strcpy(data, pname);
+ data += 1 + strlen(pname);
+ (void) strcpy(data, pinstance);
+ data += 1 + strlen(pinstance);
+ (void) strcpy(data, prealm);
+ data += 1 + strlen(prealm);
+ bcopy((char *) &paddress, data, 4);
+ data += 4;
+
+ bcopy((char *) session, data, 8);
+ data += 8;
+ *(data++) = (char) life;
+ /* issue time */
+ bcopy((char *) &time_sec, data, 4);
+ data += 4;
+ (void) strcpy(data, sname);
+ data += 1 + strlen(sname);
+ (void) strcpy(data, sinstance);
+ data += 1 + strlen(sinstance);
+
+ /* guarantee null padded ticket to multiple of 8 bytes */
+ bzero(data, 7);
+ tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
+
+ /* Check length of ticket */
+ if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
+ bzero(tkt->dat, tkt->length);
+ tkt->length = 0;
+ return KFAILURE /* XXX */;
+ }
+
+#ifndef NOENCRYPTION
+ key_sched((C_Block *)key,key_s);
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
+ key_s,(C_Block *)key,ENCRYPT);
+#endif
+ return 0;
+}
diff --git a/eBones/lib/libkrb/debug_decl.c b/eBones/lib/libkrb/debug_decl.c
new file mode 100644
index 0000000000000..f548e2a0bfa97
--- /dev/null
+++ b/eBones/lib/libkrb/debug_decl.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: debug_decl.c,v 4.5 88/10/07 06:07:49 shanzer Exp $
+ * $Id: debug_decl.c,v 1.3 1995/07/18 16:38:14 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: debug_decl.c,v 1.3 1995/07/18 16:38:14 mark Exp $";
+#endif lint
+#endif
+
+/* Declare global debugging variables. */
+
+int krb_ap_req_debug = 0;
+int krb_debug = 0;
diff --git a/eBones/lib/libkrb/decomp_ticket.c b/eBones/lib/libkrb/decomp_ticket.c
new file mode 100644
index 0000000000000..04316ad405770
--- /dev/null
+++ b/eBones/lib/libkrb/decomp_ticket.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: decomp_ticket.c,v 4.12 89/05/16 18:44:46 jtkohl Exp $
+ * $Id: decomp_ticket.c,v 1.3 1995/07/18 16:38:15 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: decomp_ticket.c,v 1.3 1995/07/18 16:38:15 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine takes a ticket and pointers to the variables that
+ * should be filled in based on the information in the ticket. It
+ * fills in values for its arguments.
+ *
+ * Note: if the client realm field in the ticket is the null string,
+ * then the "prealm" variable is filled in with the local realm (as
+ * defined by KRB_REALM).
+ *
+ * If the ticket byte order is different than the host's byte order
+ * (as indicated by the byte order bit of the "flags" field), then
+ * the KDC timestamp "time_sec" is byte-swapped. The other fields
+ * potentially affected by byte order, "paddress" and "session" are
+ * not byte-swapped.
+ *
+ * The routine returns KFAILURE if any of the "pname", "pinstance",
+ * or "prealm" fields is too big, otherwise it returns KSUCCESS.
+ *
+ * The corresponding routine to generate tickets is create_ticket.
+ * When changes are made to this routine, the corresponding changes
+ * should also be made to that file.
+ *
+ * See create_ticket.c for the format of the ticket packet.
+ */
+
+int
+decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session,
+ life, time_sec, sname, sinstance, key, key_s)
+ KTEXT tkt; /* The ticket to be decoded */
+ unsigned char *flags; /* Kerberos ticket flags */
+ char *pname; /* Authentication name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ unsigned long *paddress; /* Net address of entity
+ * requesting ticket */
+ C_Block session; /* Session key inserted in ticket */
+ int *life; /* Lifetime of the ticket */
+ unsigned long *time_sec; /* Issue time and date */
+ char *sname; /* Service name */
+ char *sinstance; /* Service instance */
+ C_Block key; /* Service's secret key
+ * (to decrypt the ticket) */
+ Key_schedule key_s; /* The precomputed key schedule */
+{
+ static int tkt_swap_bytes;
+ unsigned char *uptr;
+ char *ptr = (char *)tkt->dat;
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
+ key_s,(C_Block *)key,DECRYPT);
+#endif /* ! NOENCRYPTION */
+
+ *flags = *ptr; /* get flags byte */
+ ptr += sizeof(*flags);
+ tkt_swap_bytes = 0;
+ if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
+ tkt_swap_bytes++;
+
+ if (strlen(ptr) > ANAME_SZ)
+ return(KFAILURE);
+ (void) strcpy(pname,ptr); /* pname */
+ ptr += strlen(pname) + 1;
+
+ if (strlen(ptr) > INST_SZ)
+ return(KFAILURE);
+ (void) strcpy(pinstance,ptr); /* instance */
+ ptr += strlen(pinstance) + 1;
+
+ if (strlen(ptr) > REALM_SZ)
+ return(KFAILURE);
+ (void) strcpy(prealm,ptr); /* realm */
+ ptr += strlen(prealm) + 1;
+ /* temporary hack until realms are dealt with properly */
+ if (*prealm == 0)
+ (void) strcpy(prealm,KRB_REALM);
+
+ bcopy(ptr,(char *)paddress,4); /* net address */
+ ptr += 4;
+
+ bcopy(ptr,(char *)session,8); /* session key */
+ ptr+= 8;
+#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */
+ if (tkt_swap_bytes)
+ swap_C_Block(session);
+#endif
+
+ /* get lifetime, being certain we don't get negative lifetimes */
+ uptr = (unsigned char *) ptr++;
+ *life = (int) *uptr;
+
+ bcopy(ptr,(char *) time_sec,4); /* issue time */
+ ptr += 4;
+ if (tkt_swap_bytes)
+ swap_u_long(*time_sec);
+
+ (void) strcpy(sname,ptr); /* service name */
+ ptr += 1 + strlen(sname);
+
+ (void) strcpy(sinstance,ptr); /* instance */
+ ptr += 1 + strlen(sinstance);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/des_rw.c b/eBones/lib/libkrb/des_rw.c
new file mode 100644
index 0000000000000..5b339ee3238e3
--- /dev/null
+++ b/eBones/lib/libkrb/des_rw.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University
+ * All rights reserved.
+ *
+ * This code is derived from a specification based on software
+ * which forms part of the 4.4BSD-Lite distribution, which was developed
+ * by the University of California and its contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the entire comment,
+ * including the above copyright notice, this list of conditions
+ * and the following disclaimer, verbatim, at the beginning of
+ * the source file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Geoffrey M. Rehmet
+ * 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: des_rw.c,v 1.6 1995/07/18 16:38:17 mark Exp $
+ */
+
+/*
+ *
+ * NB: THESE ROUTINES WILL FAIL IF NON-BLOCKING I/O IS USED.
+ *
+ */
+
+/*
+ * Routines for reading and writing DES encrypted messages onto sockets.
+ * (These routines will fail if non-blocking I/O is used.)
+ *
+ * When a message is written, its length is first transmitted as an int,
+ * in network byte order. The encrypted message is then transmitted,
+ * to a multiple of 8 bytes. Messages shorter than 8 bytes are right
+ * justified into a buffer of length 8 bytes, and the remainder of the
+ * buffer is filled with random garbage (before encryption):
+ *
+ * DDD -------->--+--------+
+ * | |
+ * +--+--+--+--+--+--+--+--+
+ * |x |x |x |x |x |D |D |D |
+ * +--+--+--+--+--+--+--+--+
+ * | garbage | data |
+ * | |
+ * +-----------------------+----> des_pcbc_encrypt() -->
+ *
+ * (Note that the length field sent before the actual message specifies
+ * the number of data bytes, not the length of the entire padded message.
+ *
+ * When data is read, if the message received is longer than the number
+ * of bytes requested, then the remaining bytes are stored until the
+ * following call to des_read(). If the number of bytes received is
+ * less then the number of bytes received, then only the number of bytes
+ * actually received is returned.
+ *
+ * This interface corresponds with the original des_rw.c, except for the
+ * bugs in des_read() in the original 4.4BSD version. (One bug is
+ * normally not visible, due to undocumented behaviour of
+ * des_pcbc_encrypt() in the original MIT libdes.)
+ *
+ * XXX Todo:
+ * 1) Give better error returns on writes
+ * 2) Improve error checking on reads
+ * 3) Get rid of need for extern decl. of krb_net_read()
+ * 4) Tidy garbage generation a bit
+ * 5) Make the above comment more readable
+ */
+
+#ifdef CRYPT
+#ifdef KERBEROS
+
+#ifndef BUFFER_LEN
+#define BUFFER_LEN 10240
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <des.h>
+#include <krb.h>
+
+static des_cblock des_key;
+static des_key_schedule key_schedule;
+
+/*
+ * Buffer for storing extra data when more data is received, then was
+ * actually requested in des_read().
+ */
+static u_char des_buff[BUFFER_LEN];
+static u_char buffer[BUFFER_LEN];
+static unsigned stored = 0;
+static u_char *buff_ptr = buffer;
+
+/*
+ * Set the encryption key for des_read() and des_write().
+ * inkey is the initial vector for the DES encryption, while insched is
+ * the DES key, in unwrapped form.
+ */
+
+int
+des_set_key(inkey, insched)
+ des_cblock *inkey;
+ des_key_schedule insched;
+{
+ bcopy(inkey, des_key, sizeof(des_cblock));
+ bcopy(insched, &key_schedule, sizeof(des_key_schedule));
+ return 0;
+}
+
+/*
+ * Clear the key schedule, and initial vector, which were previously
+ * stored in static vars by des_set_key().
+ */
+void des_clear_key()
+{
+ bzero(&des_key, sizeof(des_cblock));
+ bzero(&key_schedule, sizeof(des_key_schedule));
+}
+
+int
+des_read(fd, buf, len)
+ int fd;
+ register char * buf;
+ int len;
+{
+ int msg_length; /* length of actual message data */
+ int pad_length; /* length of padded message */
+ int nread; /* number of bytes actually read */
+ int nreturned = 0;
+
+ if(stored >= len) {
+ bcopy(buff_ptr, buf, len);
+ stored -= len;
+ buff_ptr += len;
+ return(len);
+ } else {
+ if (stored) {
+ bcopy(buff_ptr, buf, stored);
+ nreturned = stored;
+ len -= stored;
+ stored = 0;
+ buff_ptr = buffer;
+ } else {
+ nreturned = 0;
+ buff_ptr = buffer;
+ }
+ }
+
+ nread = krb_net_read(fd, (char *)&msg_length, sizeof(msg_length));
+ if(nread != (int)(sizeof(msg_length)))
+ return(0);
+
+ msg_length = ntohl(msg_length);
+ pad_length = roundup(msg_length, 8);
+
+ nread = krb_net_read(fd, des_buff, pad_length);
+ if(nread != pad_length)
+ return(0);
+
+ des_pcbc_encrypt((des_cblock*) des_buff, (des_cblock*) buff_ptr,
+ (msg_length < 8 ? 8 : msg_length),
+ key_schedule, (des_cblock*) &des_key, DES_DECRYPT);
+
+
+ if(msg_length < 8)
+ buff_ptr += (8 - msg_length);
+ stored = msg_length;
+
+ if(stored >= len) {
+ bcopy(buff_ptr, buf, len);
+ stored -= len;
+ buff_ptr += len;
+ nreturned += len;
+ } else {
+ bcopy(buff_ptr, buf, stored);
+ nreturned += stored;
+ stored = 0;
+ }
+
+ return(nreturned);
+}
+
+
+/*
+ * Write a message onto a file descriptor (generally a socket), using
+ * DES to encrypt the message.
+ */
+int
+des_write(fd, buf, len)
+ int fd;
+ char * buf;
+ int len;
+{
+ static int seeded = 0;
+ char garbage[8];
+ long rnd;
+ int pad_len;
+ int write_len;
+ int i;
+ char *data;
+
+ if(len < 8) {
+ /*
+ * Right justify the message in 8 bytes of random garbage.
+ */
+ if(!seeded) {
+ seeded = 1;
+ srandom((unsigned)time(NULL));
+ }
+
+ for(i = 0 ; i < 8 ; i+= sizeof(long)) {
+ rnd = random();
+ bcopy(&rnd, garbage+i,
+ (i <= (8 - sizeof(long)))?sizeof(long):(8-i));
+ }
+ bcopy(buf, garbage + 8 - len, len);
+ data = garbage;
+ pad_len = 8;
+ } else {
+ data = buf;
+ pad_len = roundup(len, 8);
+ }
+
+ des_pcbc_encrypt((des_cblock*) data, (des_cblock*) des_buff,
+ (len < 8)?8:len, key_schedule, (des_cblock*) &des_key, DES_ENCRYPT);
+
+
+ write_len = htonl(len);
+ if(write(fd, &write_len, sizeof(write_len)) != sizeof(write_len))
+ return(-1);
+ if(write(fd, des_buff, pad_len) != pad_len)
+ return(-1);
+
+ return(len);
+}
+
+#endif /* KERBEROS */
+#endif /* CRYPT */
diff --git a/eBones/lib/libkrb/dest_tkt.c b/eBones/lib/libkrb/dest_tkt.c
new file mode 100644
index 0000000000000..df04be0d08bd5
--- /dev/null
+++ b/eBones/lib/libkrb/dest_tkt.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: dest_tkt.c,v 4.9 89/10/02 16:23:07 jtkohl Exp $
+ * $Id: dest_tkt.c,v 1.3 1995/07/18 16:38:19 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: dest_tkt.c,v 1.3 1995/07/18 16:38:19 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+#include <errno.h>
+
+/*
+ * dest_tkt() is used to destroy the ticket store upon logout.
+ * If the ticket file does not exist, dest_tkt() returns RET_TKFIL.
+ * Otherwise the function returns RET_OK on success, KFAILURE on
+ * failure.
+ *
+ * The ticket file (TKT_FILE) is defined in "krb.h".
+ */
+
+int
+dest_tkt()
+{
+ char *file = TKT_FILE;
+ int i,fd;
+ extern int errno;
+ struct stat statb;
+ char buf[BUFSIZ];
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+#endif /* TKT_SHMEM */
+
+ errno = 0;
+ if (lstat(file,&statb) < 0)
+ goto out;
+
+ if (!(statb.st_mode & S_IFREG)
+#ifdef notdef
+ || statb.st_mode & 077
+#endif
+ )
+ goto out;
+
+ if ((fd = open(file, O_RDWR, 0)) < 0)
+ goto out;
+
+ bzero(buf, BUFSIZ);
+
+ for (i = 0; i < statb.st_size; i += BUFSIZ)
+ if (write(fd, buf, BUFSIZ) != BUFSIZ) {
+ (void) fsync(fd);
+ (void) close(fd);
+ goto out;
+ }
+
+ (void) fsync(fd);
+ (void) close(fd);
+
+ (void) unlink(file);
+
+out:
+ if (errno == ENOENT) return RET_TKFIL;
+ else if (errno != 0) return KFAILURE;
+#ifdef TKT_SHMEM
+ /*
+ * handle the shared memory case
+ */
+ (void) strcpy(shmidname, file);
+ (void) strcat(shmidname, ".shm");
+ if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
+ return(i);
+#endif /* TKT_SHMEM */
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/extract_ticket.c b/eBones/lib/libkrb/extract_ticket.c
new file mode 100644
index 0000000000000..8ad3097ee9292
--- /dev/null
+++ b/eBones/lib/libkrb/extract_ticket.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: extract_ticket.c,v 4.6 88/10/07 06:08:15 shanzer Exp $
+ * $Id: extract_ticket.c,v 1.3 1995/07/18 16:38:21 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: extract_ticket.c,v 1.3 1995/07/18 16:38:21 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine is obsolete.
+ *
+ * This routine accepts the ciphertext returned by kerberos and
+ * extracts the nth ticket. It also fills in the variables passed as
+ * session, liftime and kvno.
+ */
+
+void
+extract_ticket(cipher,n,session,lifetime,kvno,realm,ticket)
+ KTEXT cipher; /* The ciphertext */
+ int n; /* Which ticket */
+ char *session; /* The session key for this tkt */
+ int *lifetime; /* The life of this ticket */
+ int *kvno; /* The kvno for the service */
+ char *realm; /* Realm in which tkt issued */
+ KTEXT ticket; /* The ticket itself */
+{
+ char *ptr;
+ int i;
+
+ /* Start after the ticket lengths */
+ ptr = (char *) cipher->dat;
+ ptr = ptr + 1 + (int) *(cipher->dat);
+
+ /* Step through earlier tickets */
+ for (i = 1; i < n; i++)
+ ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i);
+ bcopy(ptr, (char *) session, 8); /* Save the session key */
+ ptr += 8;
+ *lifetime = *(ptr++); /* Save the life of the ticket */
+ *kvno = *(ptr++); /* Save the kvno */
+ (void) strcpy(realm,ptr); /* instance */
+ ptr += strlen(realm) + 1;
+
+ /* Save the ticket if its length is non zero */
+ ticket->length = *(cipher->dat+n);
+ if (ticket->length)
+ bcopy(ptr, (char *) (ticket->dat), ticket->length);
+}
diff --git a/eBones/lib/libkrb/fgetst.c b/eBones/lib/libkrb/fgetst.c
new file mode 100644
index 0000000000000..796caca7ff746
--- /dev/null
+++ b/eBones/lib/libkrb/fgetst.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: fgetst.c,v 4.0 89/01/23 10:08:31 jtkohl Exp $
+ * $Id: fgetst.c,v 1.3 1995/07/18 16:38:23 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: fgetst.c,v 1.3 1995/07/18 16:38:23 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+
+/*
+ * fgetst takes a file descriptor, a character pointer, and a count.
+ * It reads from the file it has either read "count" characters, or
+ * until it reads a null byte. When finished, what has been read exists
+ * in "s". If "count" characters were actually read, the last is changed
+ * to a null, so the returned string is always null-terminated. fgetst
+ * returns the number of characters read, including the null terminator.
+ */
+
+int
+fgetst(f, s, n)
+ FILE *f;
+ register char *s;
+ int n;
+{
+ register int count = n;
+ int ch; /* NOT char; otherwise you don't see EOF */
+
+ while ((ch = getc(f)) != EOF && ch && --count) {
+ *s++ = ch;
+ }
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/lib/libkrb/get_ad_tkt.c b/eBones/lib/libkrb/get_ad_tkt.c
new file mode 100644
index 0000000000000..f96644a0a8179
--- /dev/null
+++ b/eBones/lib/libkrb/get_ad_tkt.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_ad_tkt.c,v 4.15 89/07/07 15:18:51 jtkohl Exp $
+ * $Id: get_ad_tkt.c,v 1.3 1995/07/18 16:38:25 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: get_ad_tkt.c,v 1.3 1995/07/18 16:38:25 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <des.h>
+#include <prot.h>
+#include <strings.h>
+
+#include <stdio.h>
+#include <errno.h>
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+extern int krb_debug;
+
+struct timeval tt_local = { 0, 0 };
+
+int swap_bytes;
+unsigned long rep_err_code;
+
+/*
+ * get_ad_tkt obtains a new service ticket from Kerberos, using
+ * the ticket-granting ticket which must be in the ticket file.
+ * It is typically called by krb_mk_req() when the client side
+ * of an application is creating authentication information to be
+ * sent to the server side.
+ *
+ * get_ad_tkt takes four arguments: three pointers to strings which
+ * contain the name, instance, and realm of the service for which the
+ * ticket is to be obtained; and an integer indicating the desired
+ * lifetime of the ticket.
+ *
+ * It returns an error status if the ticket couldn't be obtained,
+ * or AD_OK if all went well. The ticket is stored in the ticket
+ * cache.
+ *
+ * The request sent to the Kerberos ticket-granting service looks
+ * like this:
+ *
+ * pkt->dat
+ *
+ * TEXT original contents of authenticator+ticket
+ * pkt->dat built in krb_mk_req call
+ *
+ * 4 bytes time_ws always 0 (?)
+ * char lifetime lifetime argument passed
+ * string service service name argument
+ * string sinstance service instance arg.
+ *
+ * See "prot.h" for the reply packet layout and definitions of the
+ * extraction macros like pkt_version(), pkt_msg_type(), etc.
+ */
+
+int
+get_ad_tkt(service,sinstance,realm,lifetime)
+ char *service;
+ char *sinstance;
+ char *realm;
+ int lifetime;
+{
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = & pkt_st; /* Packet to KDC */
+ static KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st; /* Returned packet */
+ static KTEXT_ST cip_st;
+ KTEXT cip = &cip_st; /* Returned Ciphertext */
+ static KTEXT_ST tkt_st;
+ KTEXT tkt = &tkt_st; /* Current ticket */
+ C_Block ses; /* Session key for tkt */
+ CREDENTIALS cr;
+ int kvno; /* Kvno for session key */
+ char lrealm[REALM_SZ];
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+ long time_ws = 0;
+
+ char s_name[SNAME_SZ];
+ char s_instance[INST_SZ];
+ int msg_byte_order;
+ int kerror;
+ char rlm[REALM_SZ];
+ char *ptr;
+
+ unsigned long kdc_time; /* KDC time */
+
+ if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
+ return(kerror);
+
+ /* Create skeleton of packet to be sent */
+ (void) gettimeofday(&tt_local,(struct timezone *) 0);
+
+ pkt->length = 0;
+
+ /*
+ * Look for the session key (and other stuff we don't need)
+ * in the ticket file for krbtgt.realm@lrealm where "realm"
+ * is the service's realm (passed in "realm" argument) and
+ * lrealm is the realm of our initial ticket. If we don't
+ * have this, we will try to get it.
+ */
+
+ if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) {
+ /*
+ * If realm == lrealm, we have no hope, so let's not even try.
+ */
+ if ((strncmp(realm, lrealm, REALM_SZ)) == 0)
+ return(AD_NOTGT);
+ else{
+ if ((kerror =
+ get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS)
+ return(kerror);
+ if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS)
+ return(kerror);
+ }
+ }
+
+ /*
+ * Make up a request packet to the "krbtgt.realm@lrealm".
+ * Start by calling krb_mk_req() which puts ticket+authenticator
+ * into "pkt". Then tack other stuff on the end.
+ */
+
+ kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L);
+
+ if (kerror)
+ return(AD_NOTGT);
+
+ /* timestamp */
+ bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ *(pkt->dat+(pkt->length)++) = (char) lifetime;
+ (void) strcpy((char *) (pkt->dat+pkt->length),service);
+ pkt->length += 1 + strlen(service);
+ (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ pkt->length += 1 + strlen(sinstance);
+
+ rpkt->length = 0;
+
+ /* Send the request to the local ticket-granting server */
+ if ((kerror = send_to_kdc(pkt, rpkt, realm))) return(kerror);
+
+ /* check packet version of the returned packet */
+ if (pkt_version(rpkt) != KRB_PROT_VERSION )
+ return(INTK_PROT);
+
+ /* Check byte order */
+ msg_byte_order = pkt_msg_type(rpkt) & 1;
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ switch (pkt_msg_type(rpkt) & ~1) {
+ case AUTH_MSG_KDC_REPLY:
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4);
+ if (swap_bytes)
+ swap_u_long(rep_err_code);
+ return(rep_err_code);
+
+ default:
+ return(INTK_PROT);
+ }
+
+ /* Extract the ciphertext */
+ cip->length = pkt_clen(rpkt); /* let clen do the swap */
+
+ bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length);
+
+#ifndef NOENCRYPTION
+ key_sched((C_Block *)cr.session,key_s);
+ pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,(long)cip->length,
+ key_s,(C_Block *)cr.session,DECRYPT);
+#endif
+ /* Get rid of all traces of key */
+ bzero((char *) cr.session, sizeof(key));
+ bzero((char *) key_s, sizeof(key_s));
+
+ ptr = (char *) cip->dat;
+
+ bcopy(ptr,(char *)ses,8);
+ ptr += 8;
+
+ (void) strcpy(s_name,ptr);
+ ptr += strlen(s_name) + 1;
+
+ (void) strcpy(s_instance,ptr);
+ ptr += strlen(s_instance) + 1;
+
+ (void) strcpy(rlm,ptr);
+ ptr += strlen(rlm) + 1;
+
+ lifetime = (unsigned long) ptr[0];
+ kvno = (unsigned long) ptr[1];
+ tkt->length = (int) ptr[2];
+ ptr += 3;
+ bcopy(ptr,(char *)(tkt->dat),tkt->length);
+ ptr += tkt->length;
+
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+ strcmp(rlm, realm)) /* not what we asked for */
+ return(INTK_ERR); /* we need a better code here XXX */
+
+ /* check KDC time stamp */
+ bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ (void) gettimeofday(&tt_local,(struct timezone *) 0);
+ if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+
+ if ((kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime,
+ kvno,tkt,tt_local.tv_sec)))
+ return(kerror);
+
+ return(AD_OK);
+}
diff --git a/eBones/lib/libkrb/get_admhst.c b/eBones/lib/libkrb/get_admhst.c
new file mode 100644
index 0000000000000..a01a40ff3ea5d
--- /dev/null
+++ b/eBones/lib/libkrb/get_admhst.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_admhst.c,v 4.0 89/01/23 10:08:55 jtkohl Exp $
+ * $Id: get_admhst.c,v 1.3 1995/07/18 16:38:27 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: get_admhst.c,v 1.3 1995/07/18 16:38:27 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <krb.h>
+#include <string.h>
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos database
+ * administration server can be found.
+ *
+ * krb_get_admhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer n, and
+ * returns (in h) the nth administrative host entry from the configuration
+ * file (KRB_CONF, defined in "krb.h") associated with the specified realm.
+ *
+ * On error, get_admhst returns KFAILURE. If all goes well, the routine
+ * returns KSUCCESS.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * a Kerberos admin server. In the long run, this functionality will be
+ * provided by a nameserver.
+ */
+
+int
+krb_get_admhst(h, r, n)
+ char *h;
+ char *r;
+ int n;
+{
+ FILE *cnffile;
+ char tr[REALM_SZ];
+ char linebuf[BUFSIZ];
+ char scratch[64];
+ register int i;
+
+ if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+ return(KFAILURE);
+ }
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ /* error reading */
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ if (!index(linebuf, '\n')) {
+ /* didn't all fit into buffer, punt */
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ for (i = 0; i < n; ) {
+ /* run through the file, looking for admin host */
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ /* need to scan for a token after 'admin' to make sure that
+ admin matched correctly */
+ if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3)
+ continue;
+ if (!strcmp(tr,r))
+ i++;
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/get_cred.c b/eBones/lib/libkrb/get_cred.c
new file mode 100644
index 0000000000000..60233867ebd5e
--- /dev/null
+++ b/eBones/lib/libkrb/get_cred.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_cred.c,v 4.10 89/05/31 17:46:22 jtkohl Exp $
+ * $Id: get_cred.c,v 1.3 1995/07/18 16:38:28 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: get_cred.c,v 1.3 1995/07/18 16:38:28 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <krb.h>
+
+/*
+ * krb_get_cred takes a service name, instance, and realm, and a
+ * structure of type CREDENTIALS to be filled in with ticket
+ * information. It then searches the ticket file for the appropriate
+ * ticket and fills in the structure with the corresponding
+ * information from the file. If successful, it returns KSUCCESS.
+ * On failure it returns a Kerberos error code.
+ */
+
+int
+krb_get_cred(service,instance,realm,c)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ CREDENTIALS *c; /* Credentials struct */
+{
+ int tf_status; /* return value of tf function calls */
+
+ /* Open ticket file and lock it for shared reading */
+ if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ /* Copy principal's name and instance into the CREDENTIALS struc c */
+
+ if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS ||
+ (tf_status = tf_get_pinst(c->pinst)) != KSUCCESS )
+ return (tf_status);
+
+ /* Search for requested service credentials and copy into c */
+
+ while ((tf_status = tf_get_cred(c)) == KSUCCESS) {
+ /* Is this the right ticket? */
+ if ((strcmp(c->service,service) == 0) &&
+ (strcmp(c->instance,instance) == 0) &&
+ (strcmp(c->realm,realm) == 0))
+ break;
+ }
+ (void) tf_close();
+
+ if (tf_status == EOF)
+ return (GC_NOTKT);
+ return(tf_status);
+}
diff --git a/eBones/lib/libkrb/get_in_tkt.c b/eBones/lib/libkrb/get_in_tkt.c
new file mode 100644
index 0000000000000..b95f073280487
--- /dev/null
+++ b/eBones/lib/libkrb/get_in_tkt.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_in_tkt.c,v 4.12 89/07/18 16:32:56 jtkohl Exp $
+ * $Id: get_in_tkt.c,v 1.3 1995/07/18 16:38:30 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: get_in_tkt.c,v 1.3 1995/07/18 16:38:30 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * This file contains two routines: passwd_to_key() converts
+ * a password into a DES key (prompting for the password if
+ * not supplied), and krb_get_pw_in_tkt() gets an initial ticket for
+ * a user.
+ */
+
+/*
+ * passwd_to_key(): given a password, return a DES key.
+ * There are extra arguments here which (used to be?)
+ * used by srvtab_to_key().
+ *
+ * If the "passwd" argument is not null, generate a DES
+ * key from it, using string_to_key().
+ *
+ * If the "passwd" argument is null, call des_read_password()
+ * to prompt for a password and then convert it into a DES key.
+ *
+ * In either case, the resulting key is put in the "key" argument,
+ * and 0 is returned.
+ */
+
+/*ARGSUSED */
+static int passwd_to_key(user,instance,realm,passwd,key)
+ char *user, *instance, *realm, *passwd;
+ C_Block *key;
+{
+#ifdef NOENCRYPTION
+ if (!passwd)
+ placebo_read_password(key, "Password: ", 0);
+#else
+ if (passwd)
+ string_to_key(passwd,key);
+ else
+ des_read_password(key,"Password: ",0);
+#endif
+ return (0);
+}
+
+/*
+ * krb_get_pw_in_tkt() takes the name of the server for which the initial
+ * ticket is to be obtained, the name of the principal the ticket is
+ * for, the desired lifetime of the ticket, and the user's password.
+ * It passes its arguments on to krb_get_in_tkt(), which contacts
+ * Kerberos to get the ticket, decrypts it using the password provided,
+ * and stores it away for future use.
+ *
+ * krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt():
+ * the name of a routine (passwd_to_key()) to be used to get the
+ * password in case the "password" argument is null and NULL for the
+ * decryption procedure indicating that krb_get_in_tkt should use the
+ * default method of decrypting the response from the KDC.
+ *
+ * The result of the call to krb_get_in_tkt() is returned.
+ */
+
+int
+krb_get_pw_in_tkt(user,instance,realm,service,sinstance,life,password)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *password;
+{
+ return(krb_get_in_tkt(user,instance,realm,service,sinstance,life,
+ passwd_to_key, NULL, password));
+}
+
+#ifdef NOENCRYPTION
+/*
+ * $Source: /usr/cvs/src/eBones/krb/get_in_tkt.c,v $
+ * $Author: mark $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine prints the supplied string to standard
+ * output as a prompt, and reads a password string without
+ * echoing.
+ */
+
+#include <des.h>
+#include "conf.h"
+
+#include <stdio.h>
+#ifdef BSDUNIX
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <setjmp.h>
+#else
+/* char *strcpy();
+int strcmp(); */
+#endif
+
+#ifdef BSDUNIX
+static jmp_buf env;
+#endif
+
+#ifdef BSDUNIX
+static void sig_restore();
+static push_signals(), pop_signals();
+int placebo_read_pw_string();
+#endif
+
+/*** Routines ****************************************************** */
+int
+placebo_read_password(k,prompt,verify)
+ des_cblock *k;
+ char *prompt;
+ int verify;
+{
+ int ok;
+ char key_string[BUFSIZ];
+
+#ifdef BSDUNIX
+ if (setjmp(env)) {
+ ok = -1;
+ goto lose;
+ }
+#endif
+
+ ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify);
+ if (ok == 0)
+ bzero(k, sizeof(C_Block));
+
+lose:
+ bzero(key_string, sizeof (key_string));
+ return ok;
+}
+
+/*
+ * This version just returns the string, doesn't map to key.
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+
+int
+placebo_read_pw_string(s,max,prompt,verify)
+ char *s;
+ int max;
+ char *prompt;
+ int verify;
+{
+ int ok = 0;
+ char *ptr;
+
+#ifdef BSDUNIX
+ jmp_buf old_env;
+ struct sgttyb tty_state;
+#endif
+ char key_string[BUFSIZ];
+
+ if (max > BUFSIZ) {
+ return -1;
+ }
+
+#ifdef BSDUNIX
+ bcopy(old_env, env, sizeof(env));
+ if (setjmp(env))
+ goto lose;
+
+ /* save terminal state*/
+ if (ioctl(0,TIOCGETP,&tty_state) == -1)
+ return -1;
+
+ push_signals();
+ /* Turn off echo */
+ tty_state.sg_flags &= ~ECHO;
+ if (ioctl(0,TIOCSETP,&tty_state) == -1)
+ return -1;
+#endif
+ while (!ok) {
+ printf(prompt);
+ fflush(stdout);
+#ifdef CROSSMSDOS
+ h19line(s,sizeof(s),0);
+ if (!strlen(s))
+ continue;
+#else
+ if (!fgets(s, max, stdin)) {
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = index(s, '\n')))
+ *ptr = '\0';
+#endif
+ if (verify) {
+ printf("\nVerifying, please re-enter %s",prompt);
+ fflush(stdout);
+#ifdef CROSSMSDOS
+ h19line(key_string,sizeof(key_string),0);
+ if (!strlen(key_string))
+ continue;
+#else
+ if (!fgets(key_string, sizeof(key_string), stdin)) {
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = index(key_string, '\n')))
+ *ptr = '\0';
+#endif
+ if (strcmp(s,key_string)) {
+ printf("\n\07\07Mismatch - try again\n");
+ fflush(stdout);
+ continue;
+ }
+ }
+ ok = 1;
+ }
+
+#ifdef BSDUNIX
+lose:
+ if (!ok)
+ bzero(s, max);
+ printf("\n");
+ /* turn echo back on */
+ tty_state.sg_flags |= ECHO;
+ if (ioctl(0,TIOCSETP,&tty_state))
+ ok = 0;
+ pop_signals();
+ bcopy(env, old_env, sizeof(env));
+#endif
+ if (verify)
+ bzero(key_string, sizeof (key_string));
+ s[max-1] = 0; /* force termination */
+ return !ok; /* return nonzero if not okay */
+}
+
+#ifdef BSDUNIX
+/*
+ * this can be static since we should never have more than
+ * one set saved....
+ */
+#ifdef POSIX
+static void (*old_sigfunc[NSIG])();
+#else
+static int (*old_sigfunc[NSIG])();
+#endif POSIX
+
+static push_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ old_sigfunc[i] = signal(i,sig_restore);
+}
+
+static pop_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ signal(i,old_sigfunc[i]);
+}
+
+static void sig_restore(sig,code,scp)
+ int sig,code;
+ struct sigcontext *scp;
+{
+ longjmp(env,1);
+}
+#endif
+#endif /* NOENCRYPTION */
diff --git a/eBones/lib/libkrb/get_krbhst.c b/eBones/lib/libkrb/get_krbhst.c
new file mode 100644
index 0000000000000..cfc6e1cb70727
--- /dev/null
+++ b/eBones/lib/libkrb/get_krbhst.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_krbhst.c,v 4.8 89/01/22 20:00:29 rfrench Exp $
+ * $Id: get_krbhst.c,v 1.3 1995/07/18 16:38:32 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: get_krbhst.c,v 1.3 1995/07/18 16:38:32 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * Given a Kerberos realm, find a host on which the Kerberos authenti-
+ * cation server can be found.
+ *
+ * krb_get_krbhst takes a pointer to be filled in, a pointer to the name
+ * of the realm for which a server is desired, and an integer, n, and
+ * returns (in h) the nth entry from the configuration file (KRB_CONF,
+ * defined in "krb.h") associated with the specified realm.
+ *
+ * On end-of-file, krb_get_krbhst returns KFAILURE. If n=1 and the
+ * configuration file does not exist, krb_get_krbhst will return KRB_HOST
+ * (also defined in "krb.h"). If all goes well, the routine returnes
+ * KSUCCESS.
+ *
+ * The KRB_CONF file contains the name of the local realm in the first
+ * line (not used by this routine), followed by lines indicating realm/host
+ * entries. The words "admin server" following the hostname indicate that
+ * the host provides an administrative database server.
+ *
+ * For example:
+ *
+ * ATHENA.MIT.EDU
+ * ATHENA.MIT.EDU kerberos-1.mit.edu admin server
+ * ATHENA.MIT.EDU kerberos-2.mit.edu
+ * LCS.MIT.EDU kerberos.lcs.mit.edu admin server
+ *
+ * This is a temporary hack to allow us to find the nearest system running
+ * kerberos. In the long run, this functionality will be provided by a
+ * nameserver.
+ */
+
+int
+krb_get_krbhst(h,r,n)
+ char *h;
+ char *r;
+ int n;
+{
+ FILE *cnffile;
+ char tr[REALM_SZ];
+ char linebuf[BUFSIZ];
+ register int i;
+
+ if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
+ if (n==1) {
+ (void) strcpy(h,KRB_HOST);
+ return(KSUCCESS);
+ }
+ else
+ return(KFAILURE);
+ }
+ if (fscanf(cnffile,"%s",tr) == EOF)
+ return(KFAILURE);
+ /* run through the file, looking for the nth server for this realm */
+ for (i = 1; i <= n;) {
+ if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ if (sscanf(linebuf, "%s %s", tr, h) != 2)
+ continue;
+ if (!strcmp(tr,r))
+ i++;
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/get_krbrlm.c b/eBones/lib/libkrb/get_krbrlm.c
new file mode 100644
index 0000000000000..a4803e5a20179
--- /dev/null
+++ b/eBones/lib/libkrb/get_krbrlm.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_krbrlm.c,v 4.8 89/01/22 20:02:54 rfrench Exp $
+ * $Id: get_krbrlm.c,v 1.3 1995/07/18 16:38:34 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: get_krbrlm.c,v 1.3 1995/07/18 16:38:34 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * krb_get_lrealm takes a pointer to a string, and a number, n. It fills
+ * in the string, r, with the name of the nth realm specified on the
+ * first line of the kerberos config file (KRB_CONF, defined in "krb.h").
+ * It returns 0 (KSUCCESS) on success, and KFAILURE on failure. If the
+ * config file does not exist, and if n=1, a successful return will occur
+ * with r = KRB_REALM (also defined in "krb.h").
+ *
+ * NOTE: for archaic & compatibility reasons, this routine will only return
+ * valid results when n = 1.
+ *
+ * For the format of the KRB_CONF file, see comments describing the routine
+ * krb_get_krbhst().
+ */
+
+int
+krb_get_lrealm(r,n)
+ char *r;
+ int n;
+{
+ FILE *cnffile, *fopen();
+
+ if (n > 1)
+ return(KFAILURE); /* Temporary restriction */
+
+ if ((cnffile = fopen(KRB_CONF, "r")) == NULL) {
+ if (n == 1) {
+ (void) strcpy(r, KRB_REALM);
+ return(KSUCCESS);
+ }
+ else
+ return(KFAILURE);
+ }
+
+ if (fscanf(cnffile,"%s",r) != 1) {
+ (void) fclose(cnffile);
+ return(KFAILURE);
+ }
+ (void) fclose(cnffile);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/get_phost.c b/eBones/lib/libkrb/get_phost.c
new file mode 100644
index 0000000000000..cd83b2d2a1202
--- /dev/null
+++ b/eBones/lib/libkrb/get_phost.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_phost.c,v 4.6 89/01/23 09:25:40 jtkohl Exp $
+ * $Id: get_phost.c,v 1.3 1995/07/18 16:38:35 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: get_phost.c,v 1.3 1995/07/18 16:38:35 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <netdb.h>
+
+char *index();
+
+/*
+ * This routine takes an alias for a host name and returns the first
+ * field, lower case, of its domain name. For example, if "menel" is
+ * an alias for host officially named "menelaus" (in /etc/hosts), for
+ * the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus"
+ * is returned.
+ *
+ * This is done for historical Athena reasons: the Kerberos name of
+ * rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm"
+ * where "host"is the lowercase for of the host name ("menelaus").
+ * This should go away: the instance should be the domain name
+ * (MENELAUS.MIT.EDU). But for now we need this routine...
+ *
+ * A pointer to the name is returned, if found, otherwise a pointer
+ * to the original "alias" argument is returned.
+ */
+
+char * krb_get_phost(alias)
+ char *alias;
+{
+ struct hostent *h;
+ char *phost = alias;
+ if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) {
+ char *p = index( h->h_name, '.' );
+ if (p)
+ *p = NULL;
+ p = phost = h->h_name;
+ do {
+ if (isupper(*p)) *p=tolower(*p);
+ } while (*p++);
+ }
+ return(phost);
+}
diff --git a/eBones/lib/libkrb/get_pw_tkt.c b/eBones/lib/libkrb/get_pw_tkt.c
new file mode 100644
index 0000000000000..48b6126432f74
--- /dev/null
+++ b/eBones/lib/libkrb/get_pw_tkt.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_pw_tkt.c,v 4.6 89/01/13 18:19:11 steiner Exp $
+ * $Id: get_pw_tkt.c,v 1.3 1995/07/18 16:38:37 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: get_pw_tkt.c,v 1.3 1995/07/18 16:38:37 mark Exp $";
+#endif /* lint */
+#endif
+
+
+#include <krb.h>
+
+/*
+ * Get a ticket for the password-changing server ("changepw.KRB_MASTER").
+ *
+ * Given the name, instance, realm, and current password of the
+ * principal for which the user wants a password-changing-ticket,
+ * return either:
+ *
+ * GT_PW_BADPW if current password was wrong,
+ * GT_PW_NULL if principal had a NULL password,
+ * or the result of the krb_get_pw_in_tkt() call.
+ *
+ * First, try to get a ticket for "user.instance@realm" to use the
+ * "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h").
+ * The requested lifetime for the ticket is "1", and the current
+ * password is the "cpw" argument given.
+ *
+ * If the password was bad, give up.
+ *
+ * If the principal had a NULL password in the Kerberos database
+ * (indicating that the principal is known to Kerberos, but hasn't
+ * got a password yet), try instead to get a ticket for the principal
+ * "default.changepw@realm" to use the "changepw.KRB_MASTER" server.
+ * Use the password "changepwkrb" instead of "cpw". Return GT_PW_NULL
+ * if all goes well, otherwise the error.
+ *
+ * If this routine succeeds, a ticket and session key for either the
+ * principal "user.instance@realm" or "default.changepw@realm" to use
+ * the password-changing server will be in the user's ticket file.
+ */
+
+int
+get_pw_tkt(user,instance,realm,cpw)
+ char *user;
+ char *instance;
+ char *realm;
+ char *cpw;
+{
+ int kerror;
+
+ kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw",
+ KRB_MASTER, 1, cpw);
+
+ if (kerror == INTK_BADPW)
+ return(GT_PW_BADPW);
+
+ if (kerror == KDC_NULL_KEY) {
+ kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw",
+ KRB_MASTER,1,"changepwkrb");
+ if (kerror)
+ return(kerror);
+ return(GT_PW_NULL);
+ }
+
+ return(kerror);
+}
diff --git a/eBones/lib/libkrb/get_request.c b/eBones/lib/libkrb/get_request.c
new file mode 100644
index 0000000000000..c4982bf3283ce
--- /dev/null
+++ b/eBones/lib/libkrb/get_request.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_request.c,v 4.7 88/12/01 14:00:11 jtkohl Exp $
+ * $Id: get_request.c,v 1.3 1995/07/18 16:38:39 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: get_request.c,v 1.3 1995/07/18 16:38:39 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+
+/*
+ * This procedure is obsolete. It is used in the kerberos_slave
+ * code for Version 3 tickets.
+ *
+ * This procedure sets s_name, and instance to point to
+ * the corresponding fields from tne nth request in the packet.
+ * it returns the lifetime requested. Garbage will be returned
+ * if there are less than n requests in the packet.
+ */
+
+int
+get_request(pkt, n, s_name, instance)
+ KTEXT pkt; /* The packet itself */
+ int n; /* Which request do we want */
+ char **s_name; /* Service name to be filled in */
+ char **instance; /* Instance name to be filled in */
+{
+ /* Go to the beginning of the request list */
+ char *ptr = (char *) pkt_a_realm(pkt) + 6 +
+ strlen((char *)pkt_a_realm(pkt));
+
+ /* Read requests until we hit the right one */
+ while (n-- > 1) {
+ ptr++;
+ ptr += 1 + strlen(ptr);
+ ptr += 1 + strlen(ptr);
+ }
+
+ /* Set the arguments to point to the right place */
+ *s_name = 1 + ptr;
+ *instance = 2 + ptr + strlen(*s_name);
+
+ /* Return the requested lifetime */
+ return((int) *ptr);
+}
diff --git a/eBones/lib/libkrb/get_svc_in_tkt.c b/eBones/lib/libkrb/get_svc_in_tkt.c
new file mode 100644
index 0000000000000..f5680db91d8b3
--- /dev/null
+++ b/eBones/lib/libkrb/get_svc_in_tkt.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_svc_in_tkt.c,v 4.9 89/07/18 16:33:34 jtkohl Exp $
+ * $Id: get_svc_in_tkt.c,v 1.3 1995/07/18 16:38:41 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: get_svc_in_tkt.c,v 1.3 1995/07/18 16:38:41 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * This file contains two routines: srvtab_to_key(), which gets
+ * a server's key from a srvtab file, and krb_get_svc_in_tkt() which
+ * gets an initial ticket for a server.
+ */
+
+/*
+ * srvtab_to_key(): given a "srvtab" file (where the keys for the
+ * service on a host are stored), return the private key of the
+ * given service (user.instance@realm).
+ *
+ * srvtab_to_key() passes its arguments on to read_service_key(),
+ * plus one additional argument, the key version number.
+ * (Currently, the key version number is always 0; this value
+ * is treated as a wildcard by read_service_key().)
+ *
+ * If the "srvtab" argument is null, KEYFILE (defined in "krb.h")
+ * is passed in its place.
+ *
+ * It returns the return value of the read_service_key() call.
+ * The service key is placed in "key".
+ */
+
+static int
+srvtab_to_key(user, instance, realm, srvtab, key)
+ char *user, *instance, *realm, *srvtab;
+ C_Block key;
+{
+ if (!srvtab)
+ srvtab = KEYFILE;
+
+ return(read_service_key(user, instance, realm, 0, srvtab,
+ (char *)key));
+}
+
+/*
+ * krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(),
+ * plus two additional arguments: a pointer to the srvtab_to_key()
+ * function to be used to get the key from the key file and a NULL
+ * for the decryption procedure indicating that krb_get_in_tkt should
+ * use the default method of decrypting the response from the KDC.
+ *
+ * It returns the return value of the krb_get_in_tkt() call.
+ */
+
+int
+krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *srvtab;
+{
+ return(krb_get_in_tkt(user, instance, realm, service, sinstance,
+ life, srvtab_to_key, NULL, srvtab));
+}
diff --git a/eBones/lib/libkrb/get_tf_fullname.c b/eBones/lib/libkrb/get_tf_fullname.c
new file mode 100644
index 0000000000000..8d7639992e890
--- /dev/null
+++ b/eBones/lib/libkrb/get_tf_fullname.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_tf_fullname.c,v 4.3 90/03/10 22:40:20 jon Exp $
+ * $Id: get_tf_fullname.c,v 1.3 1995/07/18 16:38:42 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: get_tf_fullname.c,v 1.3 1995/07/18 16:38:42 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <strings.h>
+#include <stdio.h>
+
+/*
+ * This file contains a routine to extract the fullname of a user
+ * from the ticket file.
+ */
+
+/*
+ * krb_get_tf_fullname() takes four arguments: the name of the
+ * ticket file, and variables for name, instance, and realm to be
+ * returned in. Since the realm of a ticket file is not really fully
+ * supported, the realm used will be that of the the first ticket in
+ * the file as this is the one that was obtained with a password by
+ * krb_get_in_tkt().
+ */
+
+int
+krb_get_tf_fullname(ticket_file, name, instance, realm)
+ char *ticket_file;
+ char *name;
+ char *instance;
+ char *realm;
+{
+ int tf_status;
+ CREDENTIALS c;
+
+ if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) ||
+ ((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS))
+ return (tf_status);
+
+ if (name)
+ strcpy(name, c.pname);
+ if (instance)
+ strcpy(instance, c.pinst);
+ if ((tf_status = tf_get_cred(&c)) == KSUCCESS) {
+ if (realm)
+ strcpy(realm, c.realm);
+ }
+ else {
+ if (tf_status == EOF)
+ return(KFAILURE);
+ else
+ return(tf_status);
+ }
+ (void) tf_close();
+
+ return(tf_status);
+}
diff --git a/eBones/lib/libkrb/get_tf_realm.c b/eBones/lib/libkrb/get_tf_realm.c
new file mode 100644
index 0000000000000..8d75a9df82951
--- /dev/null
+++ b/eBones/lib/libkrb/get_tf_realm.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: get_tf_realm.c,v 4.2 90/01/02 13:40:19 jtkohl Exp $
+ * $Id: get_tf_realm.c,v 1.3 1995/07/18 16:38:44 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: get_tf_realm.c,v 1.3 1995/07/18 16:38:44 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * This file contains a routine to extract the realm of a kerberos
+ * ticket file.
+ */
+
+/*
+ * krb_get_tf_realm() takes two arguments: the name of a ticket
+ * and a variable to store the name of the realm in.
+ *
+ */
+
+int
+krb_get_tf_realm(ticket_file, realm)
+ char *ticket_file;
+ char *realm;
+{
+ return(krb_get_tf_fullname(ticket_file, 0, 0, realm));
+}
diff --git a/eBones/lib/libkrb/getrealm.c b/eBones/lib/libkrb/getrealm.c
new file mode 100644
index 0000000000000..dcd4d28a91990
--- /dev/null
+++ b/eBones/lib/libkrb/getrealm.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * routine to convert hostname into realm name.
+ *
+ * from: getrealm.c,v 4.6 90/01/02 13:35:56 jtkohl Exp $
+ * $Id: getrealm.c,v 1.3 1995/07/18 16:38:46 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: getrealm.c,v 1.3 1995/07/18 16:38:46 mark Exp $";
+#endif lint
+#endif
+
+#include <strings.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <krb.h>
+#include <sys/param.h>
+
+/* for Ultrix and friends ... */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+/*
+ * krb_realmofhost.
+ * Given a fully-qualified domain-style primary host name,
+ * return the name of the Kerberos realm for the host.
+ * If the hostname contains no discernable domain, or an error occurs,
+ * return the local realm name, as supplied by get_krbrlm().
+ * If the hostname contains a domain, but no translation is found,
+ * the hostname's domain is converted to upper-case and returned.
+ *
+ * The format of each line of the translation file is:
+ * domain_name kerberos_realm
+ * -or-
+ * host_name kerberos_realm
+ *
+ * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
+ * host names should be in the usual form (e.g. FOO.BAR.BAZ)
+ */
+
+static char ret_realm[REALM_SZ+1];
+
+char *
+krb_realmofhost(host)
+char *host;
+{
+ char *domain;
+ FILE *trans_file;
+ char trans_host[MAXHOSTNAMELEN+1];
+ char trans_realm[REALM_SZ+1];
+ int retval;
+
+ domain = index(host, '.');
+
+ /* prepare default */
+ if (domain) {
+ char *cp;
+
+ strncpy(ret_realm, &domain[1], REALM_SZ);
+ ret_realm[REALM_SZ] = '\0';
+ /* Upper-case realm */
+ for (cp = ret_realm; *cp; cp++)
+ if (islower(*cp))
+ *cp = toupper(*cp);
+ } else {
+ krb_get_lrealm(ret_realm, 1);
+ }
+
+ if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) {
+ /* krb_errno = KRB_NO_TRANS */
+ return(ret_realm);
+ }
+ while (1) {
+ if ((retval = fscanf(trans_file, "%s %s",
+ trans_host, trans_realm)) != 2) {
+ if (retval == EOF) {
+ fclose(trans_file);
+ return(ret_realm);
+ }
+ continue; /* ignore broken lines */
+ }
+ trans_host[MAXHOSTNAMELEN] = '\0';
+ trans_realm[REALM_SZ] = '\0';
+ if (!strcasecmp(trans_host, host)) {
+ /* exact match of hostname, so return the realm */
+ (void) strcpy(ret_realm, trans_realm);
+ fclose(trans_file);
+ return(ret_realm);
+ }
+ if ((trans_host[0] == '.') && domain) {
+ /* this is a domain match */
+ if (!strcasecmp(trans_host, domain)) {
+ /* domain match, save for later */
+ (void) strcpy(ret_realm, trans_realm);
+ continue;
+ }
+ }
+ }
+}
diff --git a/eBones/lib/libkrb/getst.c b/eBones/lib/libkrb/getst.c
new file mode 100644
index 0000000000000..e50e4bb51e19b
--- /dev/null
+++ b/eBones/lib/libkrb/getst.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * form: getst.c,v 4.5 88/11/15 16:31:39 jtkohl Exp $
+ * $Id: getst.c,v 1.3 1995/07/18 16:38:47 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: getst.c,v 1.3 1995/07/18 16:38:47 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <unistd.h>
+
+/*
+ * getst() takes a file descriptor, a string and a count. It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte. When finished, what has been read exists in
+ * the given string "s". If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated. getst() returns the number of characters read, including
+ * the null terminator.
+ */
+
+int
+getst(fd, s, n)
+ int fd;
+ register char *s;
+ int n;
+{
+ register count = n;
+ while (read(fd, s, 1) > 0 && --count)
+ if (*s++ == '\0')
+ return (n - count);
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/lib/libkrb/in_tkt.c b/eBones/lib/libkrb/in_tkt.c
new file mode 100644
index 0000000000000..1f6ee8aa60783
--- /dev/null
+++ b/eBones/lib/libkrb/in_tkt.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kt.c,v 4.9 89/10/25 19:03:35 qjb Exp $
+ * $Id: in_tkt.c,v 1.6 1995/07/18 16:38:49 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: in_tkt.c,v 1.6 1995/07/18 16:38:49 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#endif
+
+extern int krb_debug;
+
+/*
+ * in_tkt() is used to initialize the ticket store. It creates the
+ * file to contain the tickets and writes the given user's name "pname"
+ * and instance "pinst" in the file. in_tkt() returns KSUCCESS on
+ * success, or KFAILURE if something goes wrong.
+ */
+
+int
+in_tkt(pname,pinst)
+ char *pname;
+ char *pinst;
+{
+ int tktfile;
+ uid_t me, metoo;
+ struct stat buf;
+ int count;
+ char *file = TKT_FILE;
+ int fd;
+ register int i;
+ char charbuf[BUFSIZ];
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+#endif /* TKT_SHMEM */
+
+ me = getuid ();
+ metoo = geteuid();
+ if (lstat(file,&buf) == 0) {
+ if (buf.st_uid != me && me == 0) {
+ unlink(file);
+ } else {
+ if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+ buf.st_mode & 077) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",file);
+ return(KFAILURE);
+ }
+ /* file already exists, and permissions appear ok, so nuke it */
+ if ((fd = open(file, O_RDWR, 0)) < 0)
+ goto out; /* can't zero it, but we can still try truncating it */
+
+ bzero(charbuf, sizeof(charbuf));
+
+ for (i = 0; i < buf.st_size; i += sizeof(charbuf))
+ if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
+ (void) fsync(fd);
+ (void) close(fd);
+ goto out;
+ }
+
+ (void) fsync(fd);
+ (void) close(fd);
+ }
+ }
+ out:
+ /* arrange so the file is owned by the ruid
+ (swap real & effective uid if necessary).
+ This isn't a security problem, since the ticket file, if it already
+ exists, has the right uid (== ruid) and mode. */
+ if (me != metoo) {
+ if (setreuid(metoo, me) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("in_tkt: setreuid");
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %ld and %ld\n",metoo,me);
+ }
+ if ((tktfile = open(file,O_CREAT | O_TRUNC | O_WRONLY,0600)) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+ if (me != metoo) {
+ if (setreuid(me, metoo) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("in_tkt: setreuid2");
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %ld and %ld\n",me,metoo);
+ }
+ if (lstat(file,&buf) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+
+ if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
+ buf.st_mode & 077) {
+ if (krb_debug)
+ fprintf(stderr,"Error initializing %s",TKT_FILE);
+ return(KFAILURE);
+ }
+
+ count = strlen(pname)+1;
+ if (write(tktfile,pname,count) != count) {
+ (void) close(tktfile);
+ return(KFAILURE);
+ }
+ count = strlen(pinst)+1;
+ if (write(tktfile,pinst,count) != count) {
+ (void) close(tktfile);
+ return(KFAILURE);
+ }
+ (void) close(tktfile);
+#ifdef TKT_SHMEM
+ (void) strcpy(shmidname, file);
+ (void) strcat(shmidname, ".shm");
+ return(krb_shm_create(shmidname));
+#else /* !TKT_SHMEM */
+ return(KSUCCESS);
+#endif /* TKT_SHMEM */
+}
diff --git a/eBones/lib/libkrb/k_gethostname.c b/eBones/lib/libkrb/k_gethostname.c
new file mode 100644
index 0000000000000..cfb4f922a6df7
--- /dev/null
+++ b/eBones/lib/libkrb/k_gethostname.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: k_gethostname.c,v 4.1 88/12/01 14:04:42 jtkohl Exp $
+ * $Id: k_gethostname.c,v 1.3 1995/07/18 16:38:51 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: k_gethostname.c,v 1.3 1995/07/18 16:38:51 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <unistd.h>
+
+#ifndef PC
+#ifndef BSD42
+/* teach me how to k_gethostname for your system here */
+#endif
+#endif
+
+#ifdef PC
+#include <stdio.h>
+typedef long in_name;
+#include "custom.h" /* where is this file? */
+extern get_custom();
+#define LEN 64 /* just a guess */
+#endif /* PC */
+
+/*
+ * Return the local host's name in "name", up to "namelen" characters.
+ * "name" will be null-terminated if "namelen" is big enough.
+ * The return code is 0 on success, -1 on failure. (The calling
+ * interface is identical to gethostname(2).)
+ *
+ * Currently defined for BSD 4.2 and PC. The BSD version just calls
+ * gethostname(); the PC code was taken from "kinit.c", and may or may
+ * not work.
+ */
+
+int
+k_gethostname(name, namelen)
+ char *name;
+ int namelen;
+{
+#ifdef BSD42
+ return gethostname(name, namelen);
+#endif
+
+#ifdef PC
+ char buf[LEN];
+ char b1, b2, b3, b4;
+ register char *ptr;
+
+ get_custom(); /* should check for errors,
+ * return -1 on failure */
+ ptr = (char *) &(custom.c_me);
+ b1 = *ptr++;
+ b2 = *ptr++;
+ b3 = *ptr++;
+ b4 = *ptr;
+ (void) sprintf(buf,"PC address %d.%d.%d.%d",b1,b2,b3,b4);
+ if (strlen(buf) > namelen)
+ fprintf(stderr, "gethostname: namelen too small; truncating");
+ strnpcy(name, buf, namelen);
+ return 0;
+#endif
+}
diff --git a/eBones/lib/libkrb/klog.c b/eBones/lib/libkrb/klog.c
new file mode 100644
index 0000000000000..7fdc774af3d5e
--- /dev/null
+++ b/eBones/lib/libkrb/klog.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: klog.c,v 4.6 88/12/01 14:06:05 jtkohl Exp $
+ * $Id: klog.c,v 1.3 1995/07/18 16:38:52 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: klog.c,v 1.3 1995/07/18 16:38:52 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <krb.h>
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static int is_open;
+static char logtxt[1000];
+
+/*
+ * This file contains two logging routines: kset_logfile()
+ * to determine the file to which log entries should be written;
+ * and klog() to write log entries to the file.
+ */
+
+/*
+ * klog() is used to add entries to the logfile (see kset_logfile()
+ * below). Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format" string.
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * If the given log type "type" is unknown, or if the log file
+ * cannot be opened, no entry is made to the log file.
+ *
+ * The return value is always a pointer to the formatted log
+ * text string "logtxt".
+ */
+
+char * klog(type,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
+ int type;
+ char *format;
+ int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
+{
+ FILE *logfile;
+ long now;
+ struct tm *tm;
+ static int logtype_array[NLOGTYPE] = {0,0};
+ static int array_initialized;
+
+ if (!(array_initialized++)) {
+ logtype_array[L_NET_ERR] = 1;
+ logtype_array[L_KRB_PERR] = 1;
+ logtype_array[L_KRB_PWARN] = 1;
+ logtype_array[L_APPL_REQ] = 1;
+ logtype_array[L_INI_REQ] = 1;
+ logtype_array[L_DEATH_REQ] = 1;
+ logtype_array[L_NTGT_INTK] = 1;
+ logtype_array[L_ERR_SEXP] = 1;
+ logtype_array[L_ERR_MKV] = 1;
+ logtype_array[L_ERR_NKY] = 1;
+ logtype_array[L_ERR_NUN] = 1;
+ logtype_array[L_ERR_UNK] = 1;
+ }
+
+ (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+
+ if (!logtype_array[type])
+ return(logtxt);
+
+ if ((logfile = fopen(log_name,"a")) == NULL)
+ return(logtxt);
+
+ (void) time(&now);
+ tm = localtime(&now);
+
+ fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ fprintf(logfile,"%s\n",logtxt);
+ (void) fclose(logfile);
+ return(logtxt);
+}
+
+/*
+ * kset_logfile() changes the name of the file to which
+ * messages are logged. If kset_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+void
+kset_logfile(filename)
+ char *filename;
+{
+ log_name = filename;
+ is_open = 0;
+}
diff --git a/eBones/lib/libkrb/kname_parse.c b/eBones/lib/libkrb/kname_parse.c
new file mode 100644
index 0000000000000..da7ec9393c6b8
--- /dev/null
+++ b/eBones/lib/libkrb/kname_parse.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kname_parse.c,v 4.4 88/12/01 14:07:29 jtkohl Exp $
+ * $Id: kname_parse.c,v 1.3 1995/07/18 16:38:54 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kname_parse.c,v 1.3 1995/07/18 16:38:54 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <krb.h>
+#include <strings.h>
+
+/* max size of full name */
+#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ)
+
+#define NAME 0 /* which field are we in? */
+#define INST 1
+#define REALM 2
+
+extern char *krb_err_txt[];
+
+/*
+ * This file contains four routines for handling Kerberos names.
+ *
+ * kname_parse() breaks a Kerberos name into its name, instance,
+ * and realm components.
+ *
+ * k_isname(), k_isinst(), and k_isrealm() check a given string to see if
+ * it's a syntactically legitimate respective part of a Kerberos name,
+ * returning 1 if it is, 0 if it isn't.
+ *
+ * Definition of "syntactically legitimate" names is according to
+ * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying
+ * names", version dated 21 Dec 1987.
+ */
+
+/*
+ * kname_parse() takes a Kerberos name "fullname" of the form:
+ *
+ * username[.instance][@realm]
+ *
+ * and returns the three components ("name", "instance", and "realm"
+ * in the example above) in the given arguments "np", "ip", and "rp".
+ *
+ * If successful, it returns KSUCCESS. If there was an error,
+ * KNAME_FMT is returned.
+ */
+
+int
+kname_parse(np, ip, rp, fullname)
+ char *np, *ip, *rp, *fullname;
+{
+ static char buf[FULL_SZ];
+ char *rnext, *wnext; /* next char to read, write */
+ register char c;
+ int backslash;
+ int field;
+
+ backslash = 0;
+ rnext = buf;
+ wnext = np;
+ field = NAME;
+
+ if (strlen(fullname) > FULL_SZ)
+ return KNAME_FMT;
+ (void) strcpy(buf, fullname);
+
+ while ((c = *rnext++)) {
+ if (backslash) {
+ *wnext++ = c;
+ backslash = 0;
+ continue;
+ }
+ switch (c) {
+ case '\\':
+ backslash++;
+ break;
+ case '.':
+ switch (field) {
+ case NAME:
+ if (wnext == np)
+ return KNAME_FMT;
+ *wnext = '\0';
+ field = INST;
+ wnext = ip;
+ break;
+ case INST:
+ return KNAME_FMT;
+ /* break; */
+ case REALM:
+ *wnext++ = c;
+ break;
+ default:
+ fprintf(stderr, "unknown field value\n");
+ exit(1);
+ }
+ break;
+ case '@':
+ switch (field) {
+ case NAME:
+ if (wnext == np)
+ return KNAME_FMT;
+ *ip = '\0';
+ /* fall through */
+ case INST:
+ *wnext = '\0';
+ field = REALM;
+ wnext = rp;
+ break;
+ case REALM:
+ return KNAME_FMT;
+ default:
+ fprintf(stderr, "unknown field value\n");
+ exit(1);
+ }
+ break;
+ default:
+ *wnext++ = c;
+ }
+ }
+ *wnext = '\0';
+ if ((strlen(np) > ANAME_SZ - 1) ||
+ (strlen(ip) > INST_SZ - 1) ||
+ (strlen(rp) > REALM_SZ - 1))
+ return KNAME_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * k_isname() returns 1 if the given name is a syntactically legitimate
+ * Kerberos name; returns 0 if it's not.
+ */
+
+int
+k_isname(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (!*s)
+ return 0;
+ if (strlen(s) > ANAME_SZ - 1)
+ return 0;
+ while((c = *s++)) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '.':
+ return 0;
+ /* break; */
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
+
+
+/*
+ * k_isinst() returns 1 if the given name is a syntactically legitimate
+ * Kerberos instance; returns 0 if it's not.
+ */
+
+int
+k_isinst(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (strlen(s) > INST_SZ - 1)
+ return 0;
+ while((c = *s++)) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '.':
+ return 0;
+ /* break; */
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
+
+/*
+ * k_isrealm() returns 1 if the given name is a syntactically legitimate
+ * Kerberos realm; returns 0 if it's not.
+ */
+
+int
+k_isrealm(s)
+ char *s;
+{
+ register char c;
+ int backslash = 0;
+
+ if (!*s)
+ return 0;
+ if (strlen(s) > REALM_SZ - 1)
+ return 0;
+ while((c = *s++)) {
+ if (backslash) {
+ backslash = 0;
+ continue;
+ }
+ switch(c) {
+ case '\\':
+ backslash = 1;
+ break;
+ case '@':
+ return 0;
+ /* break; */
+ }
+ }
+ return 1;
+}
diff --git a/eBones/lib/libkrb/kntoln.c b/eBones/lib/libkrb/kntoln.c
new file mode 100644
index 0000000000000..388704c09ff39
--- /dev/null
+++ b/eBones/lib/libkrb/kntoln.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kntoln.c,v 4.7 89/01/23 09:25:15 jtkohl Exp $
+ * $Id: kntoln.c,v 1.3 1995/07/18 16:38:56 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: kntoln.c,v 1.3 1995/07/18 16:38:56 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <strings.h>
+
+/*
+ * krb_kntoln converts an auth name into a local name by looking up
+ * the auth name in the /etc/aname file. The format of the aname
+ * file is:
+ *
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | anl | inl | rll | lnl | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ * | 1by | 1by | 1by | 1by | name | instance | realm | lname |
+ * +-----+-----+-----+-----+------+----------+-------+-------+
+ *
+ * If the /etc/aname file can not be opened it will set the
+ * local name to the auth name. Thus, in this case it performs as
+ * the identity function.
+ *
+ * The name instance and realm are passed to krb_kntoln through
+ * the AUTH_DAT structure (ad).
+ *
+ * Now here's what it *really* does:
+ *
+ * Given a Kerberos name in an AUTH_DAT structure, check that the
+ * instance is null, and that the realm is the same as the local
+ * realm, and return the principal's name in "lname". Return
+ * KSUCCESS if all goes well, otherwise KFAILURE.
+ */
+
+int
+krb_kntoln(ad,lname)
+ AUTH_DAT *ad;
+ char *lname;
+{
+ static char lrealm[REALM_SZ] = "";
+
+ if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE))
+ return(KFAILURE);
+
+ if (strcmp(ad->pinst,""))
+ return(KFAILURE);
+ if (strcmp(ad->prealm,lrealm))
+ return(KFAILURE);
+ (void) strcpy(lname,ad->pname);
+ return(KSUCCESS);
+}
diff --git a/eBones/lib/libkrb/kparse.c b/eBones/lib/libkrb/kparse.c
new file mode 100644
index 0000000000000..5b25ac7264362
--- /dev/null
+++ b/eBones/lib/libkrb/kparse.c
@@ -0,0 +1,776 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Purpose:
+ * This module was developed to parse the "~/.klogin" files for
+ * Kerberos-authenticated rlogin/rcp/rsh services. However, it is
+ * general purpose and can be used to parse any such parameter file.
+ *
+ * The parameter file should consist of one or more entries, with each
+ * entry on a separate line and consisting of zero or more
+ * "keyword=value" combinations. The keyword is case insensitive, but
+ * the value is not. Any string may be enclosed in quotes, and
+ * c-style "\" literals are supported. A comma may be used to
+ * separate the k/v combinations, and multiple commas are ignored.
+ * Whitespace (blank or tab) may be used freely and is ignored.
+ *
+ * Full error processing is available. When PS_BAD_KEYWORD or
+ * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg
+ * contains a meaningful error message.
+ *
+ * Keywords and their default values are programmed by an external
+ * table.
+ *
+ * Routines:
+ * fGetParameterSet() parse one line of the parameter file
+ * fGetKeywordValue() parse one "keyword=value" combo
+ * fGetToken() parse one token
+ *
+ *
+ * from: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $
+ * $Id: kparse.c,v 1.3 1995/07/18 16:38:58 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kparse.c,v 1.3 1995/07/18 16:38:58 mark Exp $";
+#endif lint
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <kparse.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define MAXKEY 80
+#define MAXVALUE 80
+
+int fUngetChar(int ch, FILE *fp);
+int fGetChar(FILE *fp);
+int fGetLiteral(FILE *fp);
+
+int LineNbr=1; /* current line nbr in parameter file */
+char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX,
+ * or PS_BAD_KEYWORD is returned by
+ * fGetKeywordValue or fGetParameterSet */
+
+int
+fGetParameterSet( fp,parm,parmcount )
+ FILE *fp;
+ parmtable parm[];
+ int parmcount;
+{
+ int rc,i;
+ char keyword[MAXKEY];
+ char value[MAXVALUE];
+
+ while (TRUE) {
+ rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE);
+
+ switch (rc) {
+
+ case KV_EOF:
+ return(PS_EOF);
+
+ case KV_EOL:
+ return(PS_OKAY);
+
+ case KV_SYNTAX:
+ return(PS_SYNTAX);
+
+ case KV_OKAY:
+ /*
+ * got a reasonable keyword/value pair. Search the
+ * parameter table to see if we recognize the keyword; if
+ * not, return an error. If we DO recognize it, make sure
+ * it has not already been given. If not already given,
+ * save the value.
+ */
+ for (i=0; i<parmcount; i++) {
+ if (strcmp(strutol(keyword),parm[i].keyword)==0) {
+ if (parm[i].value) {
+ sprintf(ErrorMsg,"duplicate keyword \"%s\" found",
+ keyword);
+ return(PS_BAD_KEYWORD);
+ }
+ parm[i].value = strsave( value );
+ break;
+ }
+ }
+ if (i >= parmcount) {
+ sprintf(ErrorMsg, "unrecognized keyword \"%s\" found",
+ keyword);
+ return(PS_BAD_KEYWORD);
+ }
+ break;
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ break;
+ }
+ }
+}
+
+/*
+ * Routine: ParmCompare
+ *
+ * Purpose:
+ * ParmCompare checks a specified value for a particular keyword.
+ * fails if keyword not found or keyword found but the value was
+ * different. Like strcmp, ParmCompare returns 0 for a match found, -1
+ * otherwise
+ */
+int
+ParmCompare( parm, parmcount, keyword, value )
+ parmtable parm[];
+ int parmcount;
+ char *keyword;
+ char *value;
+{
+ int i;
+
+ for (i=0; i<parmcount; i++) {
+ if (strcmp(parm[i].keyword,keyword)==0) {
+ if (parm[i].value) {
+ return(strcmp(parm[i].value,value));
+ } else {
+ return(strcmp(parm[i].defvalue,value));
+ }
+ }
+ }
+ return(-1);
+}
+
+void
+FreeParameterSet(parm,parmcount)
+ parmtable parm[];
+ int parmcount;
+{
+ int i;
+
+ for (i=0; i<parmcount; i++) {
+ if (parm[i].value) {
+ free(parm[i].value);
+ parm[i].value = (char *)NULL;
+ }
+ }
+}
+
+int
+fGetKeywordValue( fp, keyword, klen, value, vlen )
+ FILE *fp;
+ char *keyword;
+ int klen;
+ char *value;
+ int vlen;
+{
+ int rc;
+ int gotit;
+
+ *keyword = *value = '\0'; /* preset strings to NULL */
+
+ /*
+ * Looking for a keyword.
+ * return an exception for EOF or BAD_QSTRING
+ * ignore leading WHITEspace
+ * ignore any number of leading commas
+ * newline means we have all the parms for this
+ * statement; give an indication that there is
+ * nothing more on this line.
+ * stop looking if we find QSTRING, STRING, or NUMBER
+ * return syntax error for any other PUNKtuation
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,keyword,klen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_EOF:
+ return(KV_EOF);
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,"unterminated string \"%s found",keyword);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("\n",keyword)==0) {
+ return(KV_EOL);
+ } else if (strcmp(",",keyword)!=0) {
+ sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword);
+ }
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ gotit = TRUE;
+ break;
+
+ default:
+ sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while (!gotit);
+
+ /*
+ * now we expect an equal sign.
+ * skip any whitespace
+ * stop looking if we find an equal sign
+ * anything else causes a syntax error
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,value,vlen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,
+ "expecting \'=\', found unterminated string \"%s",
+ value);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("=",value)==0) {
+ gotit = TRUE;
+ } else {
+ if (strcmp("\n",value)==0) {
+ sprintf(ErrorMsg,"expecting \"=\", found newline");
+ fUngetChar('\n',fp);
+ } else {
+ sprintf(ErrorMsg,
+ "expecting rvalue, found \'%s\'",keyword);
+ }
+ return(KV_SYNTAX);
+ }
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value);
+ return(KV_SYNTAX);
+
+ case GTOK_EOF:
+ sprintf(ErrorMsg,"expecting \'=\', found EOF");
+ return(KV_SYNTAX);
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while ( !gotit );
+
+ /*
+ * got the keyword and equal sign, now get a value.
+ * ignore any whitespace
+ * any punctuation is a syntax error
+ */
+ gotit = FALSE;
+ do {
+ rc = fGetToken(fp,value,vlen);
+
+ switch (rc) {
+
+ case GTOK_WHITE:
+ break;
+
+ case GTOK_EOF:
+ sprintf(ErrorMsg,"expecting rvalue, found EOF");
+ return(KV_SYNTAX);
+
+ case GTOK_BAD_QSTRING:
+ sprintf(ErrorMsg,"unterminated quoted string \"%s",value);
+ return(KV_SYNTAX);
+
+ case GTOK_PUNK:
+ if (strcmp("\n",value)==0) {
+ sprintf(ErrorMsg,"expecting rvalue, found newline");
+ fUngetChar('\n',fp);
+ } else {
+ sprintf(ErrorMsg,
+ "expecting rvalue, found \'%s\'",value);
+ }
+ return(KV_SYNTAX);
+ break;
+
+ case GTOK_STRING:
+ case GTOK_QSTRING:
+ case GTOK_NUMBER:
+ gotit = TRUE;
+ return(KV_OKAY);
+
+ default:
+ sprintf(ErrorMsg,
+ "panic: bad return (%d) from fGetToken()",rc);
+ return(KV_SYNTAX);
+ }
+
+ } while ( !gotit );
+ /*NOTREACHED*/
+ return(0); /*just to shut up -Wall MRVM*/
+}
+
+/*
+ * Routine Name: fGetToken
+ *
+ * Function: read the next token from the specified file.
+ * A token is defined as a group of characters
+ * terminated by a white space char (SPACE, CR,
+ * LF, FF, TAB). The token returned is stripped of
+ * both leading and trailing white space, and is
+ * terminated by a NULL terminator. An alternate
+ * definition of a token is a string enclosed in
+ * single or double quotes.
+ *
+ * Explicit Parameters:
+ * fp pointer to the input FILE
+ * dest pointer to destination buffer
+ * maxlen length of the destination buffer. The buffer
+ * length INCLUDES the NULL terminator.
+ *
+ * Implicit Parameters: stderr where the "token too long" message goes
+ *
+ * External Procedures: fgetc
+ *
+ * Side Effects: None
+ *
+ * Return Value: A token classification value, as
+ * defined in kparse.h. Note that the
+ * classification for end of file is
+ * always zero.
+ */
+int
+fGetToken(fp, dest, maxlen)
+ FILE *fp;
+ char *dest;
+ int maxlen;
+{
+ int ch='\0';
+ int len=0;
+ char *p = dest;
+ int digits;
+
+ ch=fGetChar(fp);
+
+ /*
+ * check for a quoted string. If found, take all characters
+ * that fit until a closing quote is found. Note that this
+ * algorithm will not behave well for a string which is too long.
+ */
+ if (ISQUOTE(ch)) {
+ int done = FALSE;
+ do {
+ ch = fGetChar(fp);
+ done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF)
+ ||ISQUOTE(ch));
+ if (ch=='\\')
+ ch = fGetLiteral(fp);
+ if (!done)
+ *p++ = ch;
+ else if ((ch!=EOF) && !ISQUOTE(ch))
+ fUngetChar(ch,fp);
+ } while (!done);
+ *p = '\0';
+ if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING);
+ return(GTOK_QSTRING);
+ }
+
+ /*
+ * Not a quoted string. If its a token character (rules are
+ * defined via the ISTOKENCHAR macro, in kparse.h) take it and all
+ * token chars following it until we run out of space.
+ */
+ digits=TRUE;
+ if (ISTOKENCHAR(ch)) {
+ while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) {
+ if (!isdigit(ch)) digits=FALSE;
+ *p++ = ch;
+ len++;
+ ch = fGetChar(fp);
+ };
+ *p = '\0';
+
+ if (ch!=EOF) {
+ fUngetChar(ch,fp);
+ }
+ if (digits) {
+ return(GTOK_NUMBER);
+ } else {
+ return(GTOK_STRING);
+ }
+ }
+
+ /*
+ * Neither a quoted string nor a token character. Return a string
+ * with just that one character in it.
+ */
+ if (ch==EOF) {
+ return(GTOK_EOF);
+ }
+ if (!ISWHITESPACE(ch)) {
+ *p++ = ch;
+ *p='\0';
+ } else {
+ *p++ = ' '; /* white space is always the
+ * blank character */
+ *p='\0';
+ /*
+ * The character is a white space. Flush all additional white
+ * space.
+ */
+ while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
+ ;
+ if (ch!=EOF) {
+ fUngetChar(ch,fp);
+ }
+ return(GTOK_WHITE);
+ }
+ return(GTOK_PUNK);
+}
+
+/*
+ * fGetLiteral is called after we find a '\' in the input stream. A
+ * string of numbers following the backslash are converted to the
+ * appropriate value; hex (0xn), octal (0n), and decimal (otherwise)
+ * are all supported. If the char after the \ is not a number, we
+ * special case certain values (\n, \f, \r, \b) or return a literal
+ * otherwise (useful for \", for example).
+ */
+int
+fGetLiteral(fp)
+ FILE *fp;
+{
+ int ch;
+ int n=0;
+ int base;
+
+ ch = fGetChar(fp);
+
+ if (!isdigit(ch)) {
+ switch (ch) {
+ case 'n': return('\n');
+ case 'f': return('\f');
+ case 'r': return('\r');
+ case 'b': return('\b');
+ default: return(ch);
+ }
+ }
+
+ /*
+ * got a number. might be decimal (no prefix), octal (prefix 0),
+ * or hexadecimal (prefix 0x). Set the base appropriately.
+ */
+ if (ch!='0') {
+ base=10; /* its a decimal number */
+ } else {
+ /*
+ * found a zero, its either hex or octal
+ */
+ ch = fGetChar(fp);
+ if ((ch!='x') && (ch!='X')) {
+ base=010;
+ } else {
+ ch = fGetChar(fp);
+ base=0x10;
+ }
+ }
+
+ switch (base) {
+
+ case 010: /* octal */
+ while (ISOCTAL(ch)) {
+ n = (n*base) + ch - '0';
+ ch = fGetChar(fp);
+ }
+ break;
+
+ case 10: /* decimal */
+ while (isdigit(ch)) {
+ n = (n*base) + ch - '0';
+ ch = fGetChar(fp);
+ }
+ break;
+ case 0x10: /* hexadecimal */
+ while (isxdigit(ch)) {
+ if (isdigit(ch)) {
+ n = (n*base) + ch - '0';
+ } else {
+ n = (n*base) + toupper(ch) - 'A' + 0xA ;
+ }
+ ch = fGetChar(fp);
+ }
+ break;
+ default:
+ fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c.");
+ exit(1);
+ break;
+ }
+ fUngetChar(ch,fp);
+ return(n);
+}
+
+/*
+ * exactly the same as ungetc(3) except that the line number of the
+ * input file is maintained.
+ */
+int
+fUngetChar(ch,fp)
+ int ch;
+ FILE *fp;
+{
+ if (ch=='\n') LineNbr--;
+ return(ungetc(ch,fp));
+}
+
+
+/*
+ * exactly the same as fgetc(3) except that the line number of the
+ * input file is maintained.
+ */
+int
+fGetChar(fp)
+ FILE *fp;
+{
+ int ch = fgetc(fp);
+ if (ch=='\n') LineNbr++;
+ return(ch);
+}
+
+
+/*
+ * Routine Name: strsave
+ *
+ * Function: return a pointer to a saved copy of the
+ * input string. the copy will be allocated
+ * as large as necessary.
+ *
+ * Explicit Parameters: pointer to string to save
+ *
+ * Implicit Parameters: None
+ *
+ * External Procedures: malloc,strcpy,strlen
+ *
+ * Side Effects: None
+ *
+ * Return Value: pointer to copied string
+ *
+ */
+char *
+strsave(p)
+ char *p;
+{
+ return(strcpy(malloc(strlen(p)+1),p));
+}
+
+
+/*
+ * strutol changes all characters in a string to lower case, in place.
+ * the pointer to the beginning of the string is returned.
+ */
+
+char *
+strutol( start )
+ char *start;
+{
+ char *q;
+ for (q=start; *q; q++)
+ if (isupper(*q))
+ *q=tolower(*q);
+ return(start);
+}
+
+#ifdef GTOK_TEST /* mainline test routine for fGetToken() */
+
+#define MAXTOKEN 100
+
+char *pgm = "gettoken";
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ char *p;
+ int type;
+ FILE *fp;
+
+ if (--argc) {
+ fp = fopen(*++argv,"ra");
+ if (fp == (FILE *)NULL) {
+ fprintf(stderr,"can\'t open \"%s\"\n",*argv);
+ }
+ } else
+ fp = stdin;
+
+ p = malloc(MAXTOKEN);
+ while (type = fGetToken(fp,p,MAXTOKEN)) {
+ switch(type) {
+ case GTOK_BAD_QSTRING:
+ printf("BAD QSTRING!\t");
+ break;
+ case GTOK_EOF:
+ printf("EOF!\t");
+ break;
+ case GTOK_QSTRING:
+ printf("QSTRING\t");
+ break;
+ case GTOK_STRING:
+ printf("STRING\t");
+ break;
+ case GTOK_NUMBER:
+ printf("NUMBER\t");
+ break;
+ case GTOK_PUNK:
+ printf("PUNK\t");
+ break;
+ case GTOK_WHITE:
+ printf("WHITE\t");
+ break;
+ default:
+ printf("HUH?\t");
+ break;
+ }
+ if (*p=='\n')
+ printf("\\n\n");
+ else
+ printf("%s\n",p);
+ }
+ exit(0);
+}
+#endif
+
+#ifdef KVTEST
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ int rc,ch;
+ FILE *fp;
+ char key[MAXKEY],valu[MAXVALUE];
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: test <filename>\n");
+ exit(1);
+ }
+
+ if (!(fp=fopen(*++argv,"r"))) {
+ fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+ exit(1);
+ }
+ filename = *argv;
+
+ while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){
+
+ switch (rc) {
+
+ case KV_EOL:
+ printf("%s, line %d: nada mas.\n",filename,LineNbr-1);
+ break;
+
+ case KV_SYNTAX:
+ printf("%s, line %d: syntax error: %s\n",
+ filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case KV_OKAY:
+ printf("%s, line %d: okay, %s=\"%s\"\n",
+ filename,LineNbr,key,valu);
+ break;
+
+ default:
+ printf("panic: bad return (%d) from fGetKeywordValue\n",rc);
+ break;
+ }
+ }
+ printf("EOF");
+ fclose(fp);
+ exit(0);
+}
+#endif
+
+#ifdef PSTEST
+
+parmtable kparm[] = {
+ /* keyword, default, found value */
+ { "user", "", (char *)NULL },
+ { "realm", "Athena", (char *)NULL },
+ { "instance", "", (char *)NULL }
+};
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ int rc,i,ch;
+ FILE *fp;
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: test <filename>\n");
+ exit(1);
+ }
+
+ if (!(fp=fopen(*++argv,"r"))) {
+ fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
+ exit(1);
+ }
+ filename = *argv;
+
+ while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) {
+
+ switch (rc) {
+
+ case PS_BAD_KEYWORD:
+ printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case PS_SYNTAX:
+ printf("%s, line %d: syntax error: %s\n",
+ filename,LineNbr,ErrorMsg);
+ while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
+ break;
+
+ case PS_OKAY:
+ printf("%s, line %d: valid parameter set found:\n",
+ filename,LineNbr-1);
+ for (i=0; i<PARMCOUNT(kparm); i++) {
+ printf("\t%s = \"%s\"\n",kparm[i].keyword,
+ (kparm[i].value ? kparm[i].value
+ : kparm[i].defvalue));
+ }
+ break;
+
+ default:
+ printf("panic: bad return (%d) from fGetParameterSet\n",rc);
+ break;
+ }
+ FreeParameterSet(kparm,PARMCOUNT(kparm));
+ }
+ printf("EOF");
+ fclose(fp);
+ exit(0);
+}
+#endif
diff --git a/eBones/lib/libkrb/krb.3 b/eBones/lib/libkrb/krb.3
new file mode 100644
index 0000000000000..10e20e9480772
--- /dev/null
+++ b/eBones/lib/libkrb/krb.3
@@ -0,0 +1,462 @@
+.\" $Source: /usr/cvs/src/eBones/krb/krb.3,v $
+.\" $Author: mark $
+.\" $Header: /usr/cvs/src/eBones/krb/krb.3,v 1.2 1995/07/18 16:40:57 mark Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <mit-copyright.h>.
+.\"
+.TH KERBEROS 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_mk_req, krb_rd_req, krb_kntoln, krb_set_key, krb_get_cred,
+krb_mk_priv, krb_rd_priv, krb_mk_safe, krb_rd_safe, krb_mk_err,
+krb_rd_err, krb_ck_repl \- Kerberos authentication library
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <des.h>
+#include <kerberosIV/krb.h>
+.PP
+.ft B
+extern char *krb_err_txt[];
+.PP
+.ft B
+int krb_mk_req(authent,service,instance,realm,checksum)
+KTEXT authent;
+char *service;
+char *instance;
+char *realm;
+u_long checksum;
+.PP
+.ft B
+int krb_rd_req(authent,service,instance,from_addr,ad,fn)
+KTEXT authent;
+char *service;
+char *instance;
+u_long from_addr;
+AUTH_DAT *ad;
+char *fn;
+.PP
+.ft B
+int krb_kntoln(ad,lname)
+AUTH_DAT *ad;
+char *lname;
+.PP
+.ft B
+int krb_set_key(key,cvt)
+char *key;
+int cvt;
+.PP
+.ft B
+int krb_get_cred(service,instance,realm,c)
+char *service;
+char *instance;
+char *realm;
+CREDENTIALS *c;
+.PP
+.ft B
+long krb_mk_priv(in,out,in_length,schedule,key,sender,receiver)
+u_char *in;
+u_char *out;
+u_long in_length;
+des_cblock key;
+des_key_schedule schedule;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+.PP
+.ft B
+long krb_rd_priv(in,in_length,schedule,key,sender,receiver,msg_data)
+u_char *in;
+u_long in_length;
+Key_schedule schedule;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+MSG_DAT *msg_data;
+.PP
+.ft B
+long krb_mk_safe(in,out,in_length,key,sender,receiver)
+u_char *in;
+u_char *out;
+u_long in_length;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+.PP
+.ft B
+long krb_rd_safe(in,length,key,sender,receiver,msg_data)
+u_char *in;
+u_long length;
+des_cblock key;
+struct sockaddr_in *sender;
+struct sockaddr_in *receiver;
+MSG_DAT *msg_data;
+.PP
+.ft B
+long krb_mk_err(out,code,string)
+u_char *out;
+long code;
+char *string;
+.PP
+.ft B
+long krb_rd_err(in,length,code,msg_data)
+u_char *in;
+u_long length;
+long code;
+MSG_DAT *msg_data;
+.fi
+.ft R
+.SH DESCRIPTION
+This library supports network authentication and various related
+operations. The library contains many routines beyond those described
+in this man page, but they are not intended to be used directly.
+Instead, they are called by the routines that are described, the
+authentication server and the login program.
+.PP
+.I krb_err_txt[]
+contains text string descriptions of various Kerberos error codes returned
+by some of the routines below.
+.PP
+.I krb_mk_req
+takes a pointer to a text structure in which an authenticator is to be
+built. It also takes the name, instance, and realm of the service to be
+used and an optional checksum. It is up to the application to decide
+how to generate the checksum.
+.I krb_mk_req
+then retrieves a ticket for the desired service and creates an
+authenticator. The authenticator is built in
+.I authent
+and is accessible
+to the calling procedure.
+.PP
+It is up to the application to get the authenticator to the service
+where it will be read by
+.I krb_rd_req.
+Unless an attacker posesses the session key contained in the ticket, it
+will be unable to modify the authenticator. Thus, the checksum can be
+used to verify the authenticity of the other data that will pass through
+a connection.
+.PP
+.I krb_rd_req
+takes an authenticator of type
+.B KTEXT,
+a service name, an instance, the address of the
+host originating the request, and a pointer to a structure of type
+.B AUTH_DAT
+which is filled in with information obtained from the authenticator.
+It also optionally takes the name of the file in which it will find the
+secret key(s) for the service.
+If the supplied
+.I instance
+contains "*", then the first service key with the same service name
+found in the service key file will be used, and the
+.I instance
+argument will be filled in with the chosen instance. This means that
+the caller must provide space for such an instance name.
+.PP
+It is used to find out information about the principal when a request
+has been made to a service. It is up to the application protocol to get
+the authenticator from the client to the service. The authenticator is
+then passed to
+.I krb_rd_req
+to extract the desired information.
+.PP
+.I krb_rd_req
+returns zero (RD_AP_OK) upon successful authentication. If a packet was
+forged, modified, or replayed, authentication will fail. If the
+authentication fails, a non-zero value is returned indicating the
+particular problem encountered. See
+.I krb.h
+for the list of error codes.
+.PP
+If the last argument is the null string (""), krb_rd_req will use the
+file /etc/kerberosIV/srvtab to find its keys. If the last argument is
+NULL, it will assume that the key has been set by
+.I krb_set_key
+and will not bother looking further.
+.PP
+.I krb_kntoln
+converts a Kerberos name to a local name. It takes a structure
+of type AUTH_DAT and uses the name and instance to look in the database
+/etc/kerberosIV/aname to find the corresponding local name. The local name is
+returned and can be used by an application to change uids, directories,
+or other parameters. It is not an integral part of Kerberos, but is
+instead provided to support the use of Kerberos in existing utilities.
+.PP
+.I krb_set_key
+takes as an argument a des key. It then creates
+a key schedule from it and saves the original key to be used as an
+initialization vector.
+It is used to set the server's key which
+must be used to decrypt tickets.
+.PP
+If called with a non-zero second argument,
+.I krb_set_key
+will first convert the input from a string of arbitrary length to a DES
+key by encrypting it with a one-way function.
+.PP
+In most cases it should not be necessary to call
+.I krb_set_key.
+The necessary keys will usually be obtained and set inside
+.I krb_rd_req. krb_set_key
+is provided for those applications that do not wish to place the
+application keys on disk.
+.PP
+.I krb_get_cred
+searches the caller's ticket file for a ticket for the given service, instance,
+and realm; and, if a ticket is found, fills in the given CREDENTIALS structure
+with the ticket information.
+.PP
+If the ticket was found,
+.I krb_get_cred
+returns GC_OK.
+If the ticket file can't be found, can't be read, doesn't belong to
+the user (other than root), isn't a regular file, or is in the wrong
+mode, the error GC_TKFIL is returned.
+.PP
+.I krb_mk_priv
+creates an encrypted, authenticated
+message from any arbitrary application data, pointed to by
+.I in
+and
+.I in_length
+bytes long.
+The private session key, pointed to by
+.I key
+and the key schedule,
+.I schedule,
+are used to encrypt the data and some header information using
+.I pcbc_encrypt.
+.I sender
+and
+.I receiver
+point to the Internet address of the two parties.
+In addition to providing privacy, this protocol message protects
+against modifications, insertions or replays. The encapsulated message and
+header are placed in the area pointed to by
+.I out
+and the routine returns the length of the output, or -1 indicating
+an error.
+.PP
+.I krb_rd_priv
+decrypts and authenticates a received
+.I krb_mk_priv
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+The private session key, pointed to by
+.I key,
+and the key schedule,
+.I schedule,
+are used to decrypt and verify the received message.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h.
+The routine fills in the
+.I app_data
+field with a pointer to the decrypted application data,
+.I app_length
+with the length of the
+.I app_data
+field,
+.I time_sec
+and
+.I time_5ms
+with the timestamps in the message, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender. (The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of). The
+.I hash
+field returns a value useful as input to the
+.I krb_ck_repl
+routine.
+
+The routine returns zero if ok, or a Kerberos error code. Modified messages
+and old messages cause errors, but it is up to the caller to
+check the time sequence of messages, and to check against recently replayed
+messages using
+.I krb_ck_repl
+if so desired.
+.PP
+.I krb_mk_safe
+creates an authenticated, but unencrypted message from any arbitrary
+application data,
+pointed to by
+.I in
+and
+.I in_length
+bytes long.
+The private session key, pointed to by
+.I key,
+is used to seed the
+.I quad_cksum()
+checksum algorithm used as part of the authentication.
+.I sender
+and
+.I receiver
+point to the Internet address of the two parties.
+This message does not provide privacy, but does protect (via detection)
+against modifications, insertions or replays. The encapsulated message and
+header are placed in the area pointed to by
+.I out
+and the routine returns the length of the output, or -1 indicating
+an error.
+The authentication provided by this routine is not as strong as that
+provided by
+.I krb_mk_priv
+or by computing the checksum using
+.I cbc_cksum
+instead, both of which authenticate via DES.
+.PP
+
+.I krb_rd_safe
+authenticates a received
+.I krb_mk_safe
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+The private session key, pointed to by
+.I key,
+is used to seed the quad_cksum() routine as part of the authentication.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h .
+The routine fills in these
+.I MSG_DAT
+fields:
+the
+.I app_data
+field with a pointer to the application data,
+.I app_length
+with the length of the
+.I app_data
+field,
+.I time_sec
+and
+.I time_5ms
+with the timestamps in the message, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender.
+(The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of). The
+.I hash
+field returns a value useful as input to the
+.I krb_ck_repl
+routine.
+
+The routine returns zero if ok, or a Kerberos error code. Modified messages
+and old messages cause errors, but it is up to the caller to
+check the time sequence of messages, and to check against recently replayed
+messages using
+.I krb_ck_repl
+if so desired.
+.PP
+.I krb_mk_err
+constructs an application level error message that may be used along
+with
+.I krb_mk_priv
+or
+.I krb_mk_safe.
+.I out
+is a pointer to the output buffer,
+.I code
+is an application specific error code, and
+.I string
+is an application specific error string.
+
+.PP
+.I krb_rd_err
+unpacks a received
+.I krb_mk_err
+message.
+.I in
+points to the beginning of the received message, whose length
+is specified in
+.I in_length.
+.I code
+is a pointer to a value to be filled in with the error
+value provided by the application.
+.I msg_data
+is a pointer to a
+.I MSG_DAT
+struct, defined in
+.I krb.h .
+The routine fills in these
+.I MSG_DAT
+fields: the
+.I app_data
+field with a pointer to the application error text,
+.I app_length
+with the length of the
+.I app_data
+field, and
+.I swap
+with a 1 if the byte order of the receiver is different than that of
+the sender. (The application must still determine if it is appropriate
+to byte-swap application data; the Kerberos protocol fields are already taken
+care of).
+
+The routine returns zero if the error message has been successfully received,
+or a Kerberos error code.
+.PP
+The
+.I KTEXT
+structure is used to pass around text of varying lengths. It consists
+of a buffer for the data, and a length. krb_rd_req takes an argument of this
+type containing the authenticator, and krb_mk_req returns the
+authenticator in a structure of this type. KTEXT itself is really a
+pointer to the structure. The actual structure is of type KTEXT_ST.
+.PP
+The
+.I AUTH_DAT
+structure is filled in by krb_rd_req. It must be allocated before
+calling krb_rd_req, and a pointer to it is passed. The structure is
+filled in with data obtained from Kerberos.
+.I MSG_DAT
+structure is filled in by either krb_rd_priv, krb_rd_safe, or
+krb_rd_err. It must be allocated before the call and a pointer to it
+is passed. The structure is
+filled in with data obtained from Kerberos.
+.PP
+.SH FILES
+/usr/include/kerberosIV/krb.h
+.br
+/usr/lib/libkrb.a
+.br
+/usr/include/des.h
+.br
+/usr/lib/libdes.a
+.br
+/etc/kerberosIV/aname
+.br
+/etc/kerberosIV/srvtab
+.br
+/tmp/tkt[uid]
+.SH "SEE ALSO"
+kerberos(1), des_crypt(3)
+.SH DIAGNOSTICS
+.SH BUGS
+The caller of
+.I krb_rd_req, krb_rd_priv, and krb_rd_safe
+must check time order and for replay attempts.
+.I krb_ck_repl
+is not implemented yet.
+.SH AUTHORS
+Clifford Neuman, MIT Project Athena
+.br
+Steve Miller, MIT Project Athena/Digital Equipment Corporation
+.SH RESTRICTIONS
+COPYRIGHT 1985,1986,1989 Massachusetts Institute of Technology
diff --git a/eBones/lib/libkrb/krb_err.et b/eBones/lib/libkrb/krb_err.et
new file mode 100644
index 0000000000000..7d2baef473454
--- /dev/null
+++ b/eBones/lib/libkrb/krb_err.et
@@ -0,0 +1,257 @@
+# Copyright 1987,1988 Massachusetts Institute of Technology
+# For copying and distribution information, see the file
+# "Copyright.MIT".
+#
+# from: krb_err.et,v 4.1 89/09/26 09:24:20 jtkohl Exp $
+# $Id: krb_err.et,v 1.3 1995/07/18 16:39:00 mark Exp $
+#
+ error_table krb
+
+ ec KRBET_KSUCCESS,
+ "Kerberos successful"
+
+ ec KRBET_KDC_NAME_EXP,
+ "Kerberos principal expired"
+
+ ec KRBET_KDC_SERVICE_EXP,
+ "Kerberos service expired"
+
+ ec KRBET_KDC_AUTH_EXP,
+ "Kerberos auth expired"
+
+ ec KRBET_KDC_PKT_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_P_MKEY_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_S_MKEY_VER,
+ "Incorrect kerberos master key version"
+
+ ec KRBET_KDC_BYTE_ORDER,
+ "Kerberos error: byte order unknown"
+
+ ec KRBET_KDC_PR_UNKNOWN,
+ "Kerberos principal unknown"
+
+ ec KRBET_KDC_PR_N_UNIQUE,
+ "Kerberos principal not unique"
+
+ ec KRBET_KDC_NULL_KEY,
+ "Kerberos principal has null key"
+
+ ec KRBET_KRB_RES11,
+ "Reserved 11"
+
+ ec KRBET_KRB_RES12,
+ "Reserved 12"
+
+ ec KRBET_KRB_RES13,
+ "Reserved 13"
+
+ ec KRBET_KRB_RES14,
+ "Reserved 14"
+
+ ec KRBET_KRB_RES15,
+ "Reserved 15"
+
+ ec KRBET_KRB_RES16,
+ "Reserved 16"
+
+ ec KRBET_KRB_RES17,
+ "Reserved 17"
+
+ ec KRBET_KRB_RES18,
+ "Reserved 18"
+
+ ec KRBET_KRB_RES19,
+ "Reserved 19"
+
+ ec KRBET_KDC_GEN_ERR,
+ "Generic error from Kerberos KDC"
+
+ ec KRBET_GC_TKFIL,
+ "Can't read Kerberos ticket file"
+
+ ec KRBET_GC_NOTKT,
+ "Can't find Kerberos ticket or TGT"
+
+ ec KRBET_KRB_RES23,
+ "Reserved 23"
+
+ ec KRBET_KRB_RES24,
+ "Reserved 24"
+
+ ec KRBET_KRB_RES25,
+ "Reserved 25"
+
+ ec KRBET_MK_AP_TGTEXP,
+ "Kerberos TGT Expired"
+
+ ec KRBET_KRB_RES27,
+ "Reserved 27"
+
+ ec KRBET_KRB_RES28,
+ "Reserved 28"
+
+ ec KRBET_KRB_RES29,
+ "Reserved 29"
+
+ ec KRBET_KRB_RES30,
+ "Reserved 30"
+
+ ec KRBET_RD_AP_UNDEC,
+ "Kerberos error: Can't decode authenticator"
+
+ ec KRBET_RD_AP_EXP,
+ "Kerberos ticket expired"
+
+ ec KRBET_RD_AP_NYV,
+ "Kerberos ticket not yet valid"
+
+ ec KRBET_RD_AP_REPEAT,
+ "Kerberos error: Repeated request"
+
+ ec KRBET_RD_AP_NOT_US,
+ "The kerberos ticket isn't for us"
+
+ ec KRBET_RD_AP_INCON,
+ "Kerberos request inconsistent"
+
+ ec KRBET_RD_AP_TIME,
+ "Kerberos error: delta_t too big"
+
+ ec KRBET_RD_AP_BADD,
+ "Kerberos error: incorrect net address"
+
+ ec KRBET_RD_AP_VERSION,
+ "Kerberos protocol version mismatch"
+
+ ec KRBET_RD_AP_MSG_TYPE,
+ "Kerberos error: invalid msg type"
+
+ ec KRBET_RD_AP_MODIFIED,
+ "Kerberos error: message stream modified"
+
+ ec KRBET_RD_AP_ORDER,
+ "Kerberos error: message out of order"
+
+ ec KRBET_RD_AP_UNAUTHOR,
+ "Kerberos error: unauthorized request"
+
+ ec KRBET_KRB_RES44,
+ "Reserved 44"
+
+ ec KRBET_KRB_RES45,
+ "Reserved 45"
+
+ ec KRBET_KRB_RES46,
+ "Reserved 46"
+
+ ec KRBET_KRB_RES47,
+ "Reserved 47"
+
+ ec KRBET_KRB_RES48,
+ "Reserved 48"
+
+ ec KRBET_KRB_RES49,
+ "Reserved 49"
+
+ ec KRBET_KRB_RES50,
+ "Reserved 50"
+
+ ec KRBET_GT_PW_NULL,
+ "Kerberos error: current PW is null"
+
+ ec KRBET_GT_PW_BADPW,
+ "Kerberos error: Incorrect current password"
+
+ ec KRBET_GT_PW_PROT,
+ "Kerberos protocol error"
+
+ ec KRBET_GT_PW_KDCERR,
+ "Error returned by Kerberos KDC"
+
+ ec KRBET_GT_PW_NULLTKT,
+ "Null Kerberos ticket returned by KDC"
+
+ ec KRBET_SKDC_RETRY,
+ "Kerberos error: Retry count exceeded"
+
+ ec KRBET_SKDC_CANT,
+ "Kerberos error: Can't send request"
+
+ ec KRBET_KRB_RES58,
+ "Reserved 58"
+
+ ec KRBET_KRB_RES59,
+ "Reserved 59"
+
+ ec KRBET_KRB_RES60,
+ "Reserved 60"
+
+ ec KRBET_INTK_W_NOTALL,
+ "Kerberos error: not all tickets returned"
+
+ ec KRBET_INTK_BADPW,
+ "Kerberos error: incorrect password"
+
+ ec KRBET_INTK_PROT,
+ "Kerberos error: Protocol Error"
+
+ ec KRBET_KRB_RES64,
+ "Reserved 64"
+
+ ec KRBET_KRB_RES65,
+ "Reserved 65"
+
+ ec KRBET_KRB_RES66,
+ "Reserved 66"
+
+ ec KRBET_KRB_RES67,
+ "Reserved 67"
+
+ ec KRBET_KRB_RES68,
+ "Reserved 68"
+
+ ec KRBET_KRB_RES69,
+ "Reserved 69"
+
+ ec KRBET_INTK_ERR,
+ "Other error"
+
+ ec KRBET_AD_NOTGT,
+ "Don't have Kerberos ticket-granting ticket"
+
+ ec KRBET_KRB_RES72,
+ "Reserved 72"
+
+ ec KRBET_KRB_RES73,
+ "Reserved 73"
+
+ ec KRBET_KRB_RES74,
+ "Reserved 74"
+
+ ec KRBET_KRB_RES75,
+ "Reserved 75"
+
+ ec KRBET_NO_TKT_FIL,
+ "No ticket file found"
+
+ ec KRBET_TKT_FIL_ACC,
+ "Couldn't access ticket file"
+
+ ec KRBET_TKT_FIL_LCK,
+ "Couldn't lock ticket file"
+
+ ec KRBET_TKT_FIL_FMT,
+ "Bad ticket file format"
+
+ ec KRBET_TKT_FIL_INI,
+ "tf_init not called first"
+
+ ec KRBET_KNAME_FMT,
+ "Bad Kerberos name format"
+
+ end
+
diff --git a/eBones/lib/libkrb/krb_err_txt.c b/eBones/lib/libkrb/krb_err_txt.c
new file mode 100644
index 0000000000000..2c8c0cacbe201
--- /dev/null
+++ b/eBones/lib/libkrb/krb_err_txt.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krb_err_txt.c,v 4.7 88/12/01 14:10:14 jtkohl Exp $
+ * $Id: krb_err_txt.c,v 1.3 1995/07/18 16:39:02 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: krb_err_txt.c,v 1.3 1995/07/18 16:39:02 mark Exp $";
+#endif lint
+#endif
+
+/*
+ * This file contains an array of error text strings.
+ * The associated error codes (which are defined in "krb.h")
+ * follow the string in the comments at the end of each line.
+ */
+
+char *krb_err_txt[256] = {
+ "OK", /* 000 */
+ "Principal expired (kerberos)", /* 001 */
+ "Service expired (kerberos)", /* 002 */
+ "Authentication expired (kerberos)", /* 003 */
+ "Unknown protocol version number (kerberos)", /* 004 */
+ "Principal: Incorrect master key version (kerberos)", /* 005 */
+ "Service: Incorrect master key version (kerberos)", /* 006 */
+ "Bad byte order (kerberos)", /* 007 */
+ "Principal unknown (kerberos)", /* 008 */
+ "Principal not unique (kerberos)", /* 009 */
+ "Principal has null key (kerberos)", /* 010 */
+ "Reserved error message 11 (kerberos)", /* 011 */
+ "Reserved error message 12 (kerberos)", /* 012 */
+ "Reserved error message 13 (kerberos)", /* 013 */
+ "Reserved error message 14 (kerberos)", /* 014 */
+ "Reserved error message 15 (kerberos)", /* 015 */
+ "Reserved error message 16 (kerberos)", /* 016 */
+ "Reserved error message 17 (kerberos)", /* 017 */
+ "Reserved error message 18 (kerberos)", /* 018 */
+ "Reserved error message 19 (kerberos)", /* 019 */
+ "Permission Denied (kerberos)", /* 020 */
+ "Can't read ticket file (krb_get_cred)", /* 021 */
+ "Can't find ticket (krb_get_cred)", /* 022 */
+ "Reserved error message 23 (krb_get_cred)", /* 023 */
+ "Reserved error message 24 (krb_get_cred)", /* 024 */
+ "Reserved error message 25 (krb_get_cred)", /* 025 */
+ "Ticket granting ticket expired (krb_mk_req)", /* 026 */
+ "Reserved error message 27 (krb_mk_req)", /* 027 */
+ "Reserved error message 28 (krb_mk_req)", /* 028 */
+ "Reserved error message 29 (krb_mk_req)", /* 029 */
+ "Reserved error message 30 (krb_mk_req)", /* 030 */
+ "Can't decode authenticator (krb_rd_req)", /* 031 */
+ "Ticket expired (krb_rd_req)", /* 032 */
+ "Ticket issue date too far in the future (krb_rd_req)",/* 033 */
+ "Repeat request (krb_rd_req)", /* 034 */
+ "Ticket for wrong server (krb_rd_req)", /* 035 */
+ "Request inconsistent (krb_rd_req)", /* 036 */
+ "Time is out of bounds (krb_rd_req)", /* 037 */
+ "Incorrect network address (krb_rd_req)", /* 038 */
+ "Protocol version mismatch (krb_rd_req)", /* 039 */
+ "Illegal message type (krb_rd_req)", /* 040 */
+ "Message integrity error (krb_rd_req)", /* 041 */
+ "Message duplicate or out of order (krb_rd_req)", /* 042 */
+ "Unauthorized request (krb_rd_req)", /* 043 */
+ "Reserved error message 44 (krb_rd_req)", /* 044 */
+ "Reserved error message 45 (krb_rd_req)", /* 045 */
+ "Reserved error message 46 (krb_rd_req)", /* 046 */
+ "Reserved error message 47 (krb_rd_req)", /* 047 */
+ "Reserved error message 48 (krb_rd_req)", /* 048 */
+ "Reserved error message 49 (krb_rd_req)", /* 049 */
+ "Reserved error message 50 (krb_rd_req)", /* 050 */
+ "Current password is NULL (get_pw_tkt)", /* 051 */
+ "Current password incorrect (get_pw_tkt)", /* 052 */
+ "Protocol error (gt_pw_tkt)", /* 053 */
+ "Error returned by KDC (gt_pw_tkt)", /* 054 */
+ "Null ticket returned by KDC (gt_pw_tkt)", /* 055 */
+ "Retry count exceeded (send_to_kdc)", /* 056 */
+ "Can't send request (send_to_kdc)", /* 057 */
+ "Reserved error message 58 (send_to_kdc)", /* 058 */
+ "Reserved error message 59 (send_to_kdc)", /* 059 */
+ "Reserved error message 60 (send_to_kdc)", /* 060 */
+ "Warning: Not ALL tickets returned", /* 061 */
+ "Password incorrect", /* 062 */
+ "Protocol error (get_intkt)", /* 063 */
+ "Reserved error message 64 (get_in_tkt)", /* 064 */
+ "Reserved error message 65 (get_in_tkt)", /* 065 */
+ "Reserved error message 66 (get_in_tkt)", /* 066 */
+ "Reserved error message 67 (get_in_tkt)", /* 067 */
+ "Reserved error message 68 (get_in_tkt)", /* 068 */
+ "Reserved error message 69 (get_in_tkt)", /* 069 */
+ "Generic error (get_intkt)", /* 070 */
+ "Don't have ticket granting ticket (get_ad_tkt)", /* 071 */
+ "Reserved error message 72 (get_ad_tkt)", /* 072 */
+ "Reserved error message 73 (get_ad_tkt)", /* 073 */
+ "Reserved error message 74 (get_ad_tkt)", /* 074 */
+ "Reserved error message 75 (get_ad_tkt)", /* 075 */
+ "No ticket file (tf_util)", /* 076 */
+ "Can't access ticket file (tf_util)", /* 077 */
+ "Can't lock ticket file; try later (tf_util)", /* 078 */
+ "Bad ticket file format (tf_util)", /* 079 */
+ "Read ticket file before tf_init (tf_util)", /* 080 */
+ "Bad Kerberos name format (kname_parse)", /* 081 */
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "(reserved)",
+ "Generic kerberos error (kfailure)", /* 255 */
+};
diff --git a/eBones/lib/libkrb/krb_get_in_tkt.c b/eBones/lib/libkrb/krb_get_in_tkt.c
new file mode 100644
index 0000000000000..b6ff308a77c01
--- /dev/null
+++ b/eBones/lib/libkrb/krb_get_in_tkt.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: krb_get_in_tkt.c,v 4.19 89/07/18 16:31:31 jtkohl Exp $
+ * $Id: krb_get_in_tkt.c,v 1.3 1995/07/18 16:39:04 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: krb_get_in_tkt.c,v 1.3 1995/07/18 16:39:04 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <des.h>
+#include <prot.h>
+
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+
+/* use the bsd time.h struct defs for PC too! */
+#include <sys/time.h>
+#include <sys/types.h>
+
+int swap_bytes;
+
+/*
+ * decrypt_tkt(): Given user, instance, realm, passwd, key_proc
+ * and the cipher text sent from the KDC, decrypt the cipher text
+ * using the key returned by key_proc.
+ */
+
+static int
+decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ int (*key_proc)();
+ KTEXT *cipp;
+{
+ KTEXT cip = *cipp;
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+
+#ifndef NOENCRYPTION
+ /* Attempt to decrypt it */
+#endif
+
+ /* generate a key */
+
+ {
+ register int rc;
+ rc = (*key_proc)(user,instance,realm,arg,key);
+ if (rc)
+ return(rc);
+ }
+
+#ifndef NOENCRYPTION
+ key_sched(&key,key_s);
+ pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
+ (long) cip->length,key_s,(C_Block *)key,DES_DECRYPT);
+#endif /* !NOENCRYPTION */
+ /* Get rid of all traces of key */
+ bzero((char *)key,sizeof(key));
+ bzero((char *)key_s,sizeof(key_s));
+
+ return(0);
+}
+
+/*
+ * krb_get_in_tkt() gets a ticket for a given principal to use a given
+ * service and stores the returned ticket and session key for future
+ * use.
+ *
+ * The "user", "instance", and "realm" arguments give the identity of
+ * the client who will use the ticket. The "service" and "sinstance"
+ * arguments give the identity of the server that the client wishes
+ * to use. (The realm of the server is the same as the Kerberos server
+ * to whom the request is sent.) The "life" argument indicates the
+ * desired lifetime of the ticket; the "key_proc" argument is a pointer
+ * to the routine used for getting the client's private key to decrypt
+ * the reply from Kerberos. The "decrypt_proc" argument is a pointer
+ * to the routine used to decrypt the reply from Kerberos; and "arg"
+ * is an argument to be passed on to the "key_proc" routine.
+ *
+ * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
+ * returns an error code: If an AUTH_MSG_ERR_REPLY packet is returned
+ * by Kerberos, then the error code it contains is returned. Other
+ * error codes returned by this routine include INTK_PROT to indicate
+ * wrong protocol version, INTK_BADPW to indicate bad password (if
+ * decrypted ticket didn't make sense), INTK_ERR if the ticket was for
+ * the wrong server or the ticket store couldn't be initialized.
+ *
+ * The format of the message sent to Kerberos is as follows:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte KRB_PROT_VERSION protocol version number
+ * 1 byte AUTH_MSG_KDC_REQUEST | message type
+ * HOST_BYTE_ORDER local byte order in lsb
+ * string user client's name
+ * string instance client's instance
+ * string realm client's realm
+ * 4 bytes tlocal.tv_sec timestamp in seconds
+ * 1 byte life desired lifetime
+ * string service service's name
+ * string sinstance service's instance
+ */
+
+int
+krb_get_in_tkt(user, instance, realm, service, sinstance, life,
+ key_proc, decrypt_proc, arg)
+ char *user;
+ char *instance;
+ char *realm;
+ char *service;
+ char *sinstance;
+ int life;
+ int (*key_proc)();
+ int (*decrypt_proc)();
+ char *arg;
+{
+ KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st; /* Packet to KDC */
+ KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st; /* Returned packet */
+ KTEXT_ST cip_st;
+ KTEXT cip = &cip_st; /* Returned Ciphertext */
+ KTEXT_ST tkt_st;
+ KTEXT tkt = &tkt_st; /* Current ticket */
+ C_Block ses; /* Session key for tkt */
+ int kvno; /* Kvno for session key */
+ unsigned char *v = pkt->dat; /* Prot vers no */
+ unsigned char *t = (pkt->dat+1); /* Prot msg type */
+
+ char s_name[SNAME_SZ];
+ char s_instance[INST_SZ];
+ char rlm[REALM_SZ];
+ int lifetime;
+ int msg_byte_order;
+ int kerror;
+ unsigned long exp_date;
+ char *ptr;
+
+ struct timeval t_local;
+
+ unsigned long rep_err_code;
+
+ unsigned long kdc_time; /* KDC time */
+
+ /* BUILD REQUEST PACKET */
+
+ /* Set up the fixed part of the packet */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Now for the variable info */
+ (void) strcpy((char *)(pkt->dat+2),user); /* aname */
+ pkt->length = 3 + strlen(user);
+ (void) strcpy((char *)(pkt->dat+pkt->length),
+ instance); /* instance */
+ pkt->length += 1 + strlen(instance);
+ (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
+ pkt->length += 1 + strlen(realm);
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ /* timestamp */
+ bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4);
+ pkt->length += 4;
+
+ *(pkt->dat+(pkt->length)++) = (char) life;
+ (void) strcpy((char *)(pkt->dat+pkt->length),service);
+ pkt->length += 1 + strlen(service);
+ (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
+ pkt->length += 1 + strlen(sinstance);
+
+ rpkt->length = 0;
+
+ /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
+
+ if ((kerror = send_to_kdc(pkt, rpkt, realm))) return(kerror);
+
+ /* check packet version of the returned packet */
+ if (pkt_version(rpkt) != KRB_PROT_VERSION)
+ return(INTK_PROT);
+
+ /* Check byte order */
+ msg_byte_order = pkt_msg_type(rpkt) & 1;
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER) {
+ swap_bytes++;
+ }
+
+ switch (pkt_msg_type(rpkt) & ~1) {
+ case AUTH_MSG_KDC_REPLY:
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4);
+ if (swap_bytes) swap_u_long(rep_err_code);
+ return((int)rep_err_code);
+ default:
+ return(INTK_PROT);
+ }
+
+ /* EXTRACT INFORMATION FROM RETURN PACKET */
+
+ /* get the principal's expiration date */
+ bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date));
+ if (swap_bytes) swap_u_long(exp_date);
+
+ /* Extract the ciphertext */
+ cip->length = pkt_clen(rpkt); /* let clen do the swap */
+
+ if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
+ return(INTK_ERR); /* no appropriate error code
+ currently defined for INTK_ */
+ /* copy information from return packet into "cip" */
+ bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length);
+
+ /* Attempt to decrypt the reply. */
+ if (decrypt_proc == NULL)
+ decrypt_proc = decrypt_tkt;
+ (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
+
+ ptr = (char *) cip->dat;
+
+ /* extract session key */
+ bcopy(ptr,(char *)ses,8);
+ ptr += 8;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's name */
+ (void) strcpy(s_name,ptr);
+ ptr += strlen(s_name) + 1;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's instance */
+ (void) strcpy(s_instance,ptr);
+ ptr += strlen(s_instance) + 1;
+
+ if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
+ return(INTK_BADPW);
+
+ /* extract server's realm */
+ (void) strcpy(rlm,ptr);
+ ptr += strlen(rlm) + 1;
+
+ /* extract ticket lifetime, server key version, ticket length */
+ /* be sure to avoid sign extension on lifetime! */
+ lifetime = (unsigned char) ptr[0];
+ kvno = (unsigned char) ptr[1];
+ tkt->length = (unsigned char) ptr[2];
+ ptr += 3;
+
+ if ((tkt->length < 0) ||
+ ((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
+ return(INTK_BADPW);
+
+ /* extract ticket itself */
+ bcopy(ptr,(char *)(tkt->dat),tkt->length);
+ ptr += tkt->length;
+
+ if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
+ strcmp(rlm, realm)) /* not what we asked for */
+ return(INTK_ERR); /* we need a better code here XXX */
+
+ /* check KDC time stamp */
+ bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+
+ /* initialize ticket cache */
+ if (in_tkt(user,instance) != KSUCCESS)
+ return(INTK_ERR);
+
+ /* stash ticket, session key, etc. for future use */
+ if ((kerror = save_credentials(s_name, s_instance, rlm, ses,
+ lifetime, kvno, tkt, t_local.tv_sec)))
+ return(kerror);
+
+ return(INTK_OK);
+}
diff --git a/eBones/lib/libkrb/krb_realmofhost.3 b/eBones/lib/libkrb/krb_realmofhost.3
new file mode 100644
index 0000000000000..c3b14cc457882
--- /dev/null
+++ b/eBones/lib/libkrb/krb_realmofhost.3
@@ -0,0 +1,161 @@
+.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $
+.\" $Id: krb_realmofhost.3,v 1.3 1995/07/18 16:41:02 mark Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst,
+krb_get_lrealm \- additional Kerberos utility routines
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <kerberosIV/krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.ft B
+char *krb_realmofhost(host)
+char *host;
+.PP
+.ft B
+char *krb_get_phost(alias)
+char *alias;
+.PP
+.ft B
+krb_get_krbhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_admhst(host,realm,n)
+char *host;
+char *realm;
+int n;
+.PP
+.ft B
+krb_get_lrealm(realm,n)
+char *realm;
+int n;
+.fi
+.ft R
+.SH DESCRIPTION
+.I krb_realmofhost
+returns the Kerberos realm of the host
+.IR host ,
+as determined by the translation table
+.IR /etc/kerberosIV/krb.realms .
+.I host
+should be the fully-qualified domain-style primary host name of the host
+in question. In order to prevent certain security attacks, this routine
+must either have
+.I a priori
+knowledge of a host's realm, or obtain such information securely.
+.PP
+The format of the translation file is described by
+.IR krb.realms (5).
+If
+.I host
+exactly matches a host_name line, the corresponding realm
+is returned.
+Otherwise, if the domain portion of
+.I host
+matches a domain_name line, the corresponding realm
+is returned.
+If
+.I host
+contains a domain, but no translation is found,
+.IR host 's
+domain is converted to upper-case and returned.
+If
+.I host
+contains no discernable domain, or an error occurs,
+the local realm name, as supplied by
+.IR krb_get_lrealm (3),
+is returned.
+.PP
+.I krb_get_phost
+converts the hostname
+.I alias
+(which can be either an official name or an alias) into the instance
+name to be used in obtaining Kerberos tickets for most services,
+including the Berkeley rcmd suite (rlogin, rcp, rsh).
+.br
+The current convention is to return the first segment of the official
+domain-style name after conversion to lower case.
+.PP
+.I krb_get_krbhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos key distribution center (KDC)
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/kerberosIV/krb.conf\fR).
+The configuration file is described by
+.IR krb.conf (5).
+If the host is successfully filled in, the routine
+returns KSUCCESS.
+If the file cannot be opened, and
+.I n
+equals 1, then the value of KRB_HOST as defined in
+.I <krb.h>
+is filled in, and KSUCCESS is returned. If there are fewer than
+.I n
+hosts running a Kerberos KDC for the requested realm, or the
+configuration file is malformed, the routine
+returns KFAILURE.
+.PP
+.I krb_get_admhst
+fills in
+.I host
+with the hostname of the
+.IR n th
+host running a Kerberos KDC database administration server
+for realm
+.IR realm ,
+as specified in the configuration file (\fI/etc/kerberosIV/krb.conf\fR).
+If the file cannot be opened or is malformed, or there are fewer than
+.I n
+hosts running a Kerberos KDC database administration server,
+the routine returns KFAILURE.
+.PP
+The character arrays used as return values for
+.IR krb_get_krbhst ,
+.IR krb_get_admhst ,
+should be large enough to
+hold any hostname (MAXHOSTNAMELEN from <sys/param.h>).
+.PP
+.I krb_get_lrealm
+fills in
+.I realm
+with the
+.IR n th
+realm of the local host, as specified in the configuration file.
+.I realm
+should be at least REALM_SZ (from
+.IR <krb.h>) characters long.
+.PP
+.SH SEE ALSO
+kerberos(3), krb.conf(5), krb.realms(5)
+.SH FILES
+.TP 20n
+/etc/kerberosIV/krb.realms
+translation file for host-to-realm mapping.
+.TP
+/etc/kerberosIV/krb.conf
+local realm-name and realm/server configuration file.
+.SH BUGS
+The current convention for instance names is too limited; the full
+domain name should be used.
+.PP
+.I krb_get_lrealm
+currently only supports
+.I n
+= 1. It should really consult the user's ticket cache to determine the
+user's current realm, rather than consulting a file on the host.
diff --git a/eBones/lib/libkrb/krb_sendauth.3 b/eBones/lib/libkrb/krb_sendauth.3
new file mode 100644
index 0000000000000..5608255009d9d
--- /dev/null
+++ b/eBones/lib/libkrb/krb_sendauth.3
@@ -0,0 +1,348 @@
+.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $
+.\" $Id: krb_sendauth.3,v 1.3 1995/07/18 16:41:03 mark Exp $
+.\" Copyright 1988 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \-
+Kerberos routines for sending authentication via network stream sockets
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <kerberosIV/krb.h>
+#include <des.h>
+#include <netinet/in.h>
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_sendauth(options, fd, ktext, service, inst, realm, checksum,
+msg_data, cred, schedule, laddr, faddr, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst, *realm;
+u_long checksum;
+MSG_DAT *msg_data;
+CREDENTIALS *cred;
+Key_schedule schedule;
+struct sockaddr_in *laddr, *faddr;
+char *version;
+.PP
+.fi
+.HP 1i
+.ft B
+int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr,
+auth_data, filename, schedule, version)
+.nf
+.RS 0
+.ft B
+long options;
+int fd;
+KTEXT ktext;
+char *service, *inst;
+struct sockaddr_in *faddr, *laddr;
+AUTH_DAT *auth_data;
+char *filename;
+Key_schedule schedule;
+char *version;
+.PP
+.ft B
+int krb_net_write(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.PP
+.ft B
+int krb_net_read(fd, buf, len)
+int fd;
+char *buf;
+int len;
+.fi
+.SH DESCRIPTION
+.PP
+These functions,
+which are built on top of the core Kerberos library,
+provide a convenient means for client and server
+programs to send authentication messages
+to one another through network connections.
+The
+.I krb_sendauth
+function sends an authenticated ticket from the client program to
+the server program by writing the ticket to a network socket.
+The
+.I krb_recvauth
+function receives the ticket from the client by
+reading from a network socket.
+
+.SH KRB_SENDAUTH
+.PP
+This function writes the ticket to
+the network socket specified by the
+file descriptor
+.IR fd,
+returning KSUCCESS if the write proceeds successfully,
+and an error code if it does not.
+
+The
+.I ktext
+argument should point to an allocated KTEXT_ST structure.
+The
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments specify the server program's Kerberos principal name,
+instance, and realm.
+If you are writing a client that uses the local realm exclusively,
+you can set the
+.I realm
+argument to NULL.
+
+The
+.I version
+argument allows the client program to pass an application-specific
+version string that the server program can then match against
+its own version string.
+The
+.I version
+string can be up to KSEND_VNO_LEN (see
+.IR <krb.h> )
+characters in length.
+
+The
+.I checksum
+argument can be used to pass checksum information to the
+server program.
+The client program is responsible for specifying this information.
+This checksum information is difficult to corrupt because
+.I krb_sendauth
+passes it over the network in encrypted form.
+The
+.I checksum
+argument is passed as the checksum argument to
+.IR krb_mk_req .
+
+You can set
+.IR krb_sendauth's
+other arguments to NULL unless you want the
+client and server programs to mutually authenticate
+themselves.
+In the case of mutual authentication,
+the client authenticates itself to the server program,
+and demands that the server in turn authenticate itself to
+the client.
+
+.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION
+.PP
+If you want mutual authentication,
+make sure that you read all pending data from the local socket
+before calling
+.IR krb_sendauth.
+Set
+.IR krb_sendauth's
+.I options
+argument to
+.BR KOPT_DO_MUTUAL
+(this macro is defined in the
+.IR krb.h
+file);
+make sure that the
+.I laddr
+argument points to
+the address of the local socket,
+and that
+.I faddr
+points to the foreign socket's network address.
+
+.I Krb_sendauth
+fills in the other arguments--
+.IR msg_data ,
+.IR cred ,
+and
+.IR schedule --before
+sending the ticket to the server program.
+You must, however, allocate space for these arguments
+before calling the function.
+
+.I Krb_sendauth
+supports two other options:
+.BR KOPT_DONT_MK_REQ,
+and
+.BR KOPT_DONT_CANON.
+If called with
+.I options
+set as KOPT_DONT_MK_REQ,
+.I krb_sendauth
+will not use the
+.I krb_mk_req
+function to retrieve the ticket from the Kerberos server.
+The
+.I ktext
+argument must point to an existing ticket and authenticator (such as
+would be created by
+.IR krb_mk_req ),
+and the
+.IR service,
+.IR inst,
+and
+.IR realm
+arguments can be set to NULL.
+
+If called with
+.I options
+set as KOPT_DONT_CANON,
+.I krb_sendauth
+will not convert the service's instance to canonical form using
+.IR krb_get_phost (3).
+
+If you want to call
+.I krb_sendauth
+with a multiple
+.I options
+specification,
+construct
+.I options
+as a bitwise-OR of the options you want to specify.
+
+.SH KRB_RECVAUTH
+.PP
+The
+.I krb_recvauth
+function
+reads a ticket/authenticator pair from the socket pointed to by the
+.I fd
+argument.
+Set the
+.I options
+argument
+as a bitwise-OR of the options desired.
+Currently only KOPT_DO_MUTUAL is useful to the receiver.
+
+The
+.I ktext
+argument
+should point to an allocated KTEXT_ST structure.
+.I Krb_recvauth
+fills
+.I ktext
+with the
+ticket/authenticator pair read from
+.IR fd ,
+then passes it to
+.IR krb_rd_req .
+
+The
+.I service
+and
+.I inst
+arguments
+specify the expected service and instance for which the ticket was
+generated. They are also passed to
+.IR krb_rd_req.
+The
+.I inst
+argument may be set to "*" if the caller wishes
+.I krb_mk_req
+to fill in the instance used (note that there must be space in the
+.I inst
+argument to hold a full instance name, see
+.IR krb_mk_req (3)).
+
+The
+.I faddr
+argument
+should point to the address of the peer which is presenting the ticket.
+It is also passed to
+.IR krb_rd_req .
+
+If the client and server plan to mutually authenticate
+one another,
+the
+.I laddr
+argument
+should point to the local address of the file descriptor.
+Otherwise you can set this argument to NULL.
+
+The
+.I auth_data
+argument
+should point to an allocated AUTH_DAT area.
+It is passed to and filled in by
+.IR krb_rd_req .
+The checksum passed to the corresponding
+.I krb_sendauth
+is available as part of the filled-in AUTH_DAT area.
+
+The
+.I filename
+argument
+specifies the filename
+which the service program should use to obtain its service key.
+.I Krb_recvauth
+passes
+.I filename
+to the
+.I krb_rd_req
+function.
+If you set this argument to "",
+.I krb_rd_req
+looks for the service key in the file
+.IR /etc/kerberosIV/srvtab.
+
+If the client and server are performing mutual authenication,
+the
+.I schedule
+argument
+should point to an allocated Key_schedule.
+Otherwise it is ignored and may be NULL.
+
+The
+.I version
+argument should point to a character array of at least KSEND_VNO_LEN
+characters. It is filled in with the version string passed by the client to
+.IR krb_sendauth.
+.PP
+.SH KRB_NET_WRITE AND KRB_NET_READ
+.PP
+The
+.I krb_net_write
+function
+emulates the write(2) system call, but guarantees that all data
+specified is written to
+.I fd
+before returning, unless an error condition occurs.
+.PP
+The
+.I krb_net_read
+function
+emulates the read(2) system call, but guarantees that the requested
+amount of data is read from
+.I fd
+before returning, unless an error condition occurs.
+.PP
+.SH BUGS
+.IR krb_sendauth,
+.IR krb_recvauth,
+.IR krb_net_write,
+and
+.IR krb_net_read
+will not work properly on sockets set to non-blocking I/O mode.
+
+.SH SEE ALSO
+
+krb_mk_req(3), krb_rd_req(3), krb_get_phost(3)
+
+.SH AUTHOR
+John T. Kohl, MIT Project Athena
+.SH RESTRICTIONS
+Copyright 1988, Massachusetts Instititute of Technology.
+For copying and distribution information,
+please see the file <Copyright.h>.
diff --git a/eBones/lib/libkrb/krbglue.c b/eBones/lib/libkrb/krbglue.c
new file mode 100644
index 0000000000000..f82cf70399f3c
--- /dev/null
+++ b/eBones/lib/libkrb/krbglue.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: krbglue.c,v 4.1 89/01/23 15:51:50 wesommer Exp $
+ * $Id: krbglue.c,v 1.3 1995/07/18 16:39:05 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+$Id: krbglue.c,v 1.3 1995/07/18 16:39:05 mark Exp $";
+#endif lint
+#endif
+
+#ifndef NCOMPAT
+/*
+ * glue together new libraries and old clients
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <des.h>
+#include "krb.h"
+
+/* These definitions should be in krb.h, no? */
+/*
+#if defined(__HIGHC__)
+#undef __STDC__
+#endif
+#ifdef __STDC__
+extern int krb_mk_req (KTEXT, char *, char *, char *, long);
+extern int krb_rd_req (KTEXT, char *, char *, long, AUTH_DAT *, char *);
+extern int krb_kntoln (AUTH_DAT *, char *);
+extern int krb_set_key (char *, int);
+extern int krb_get_cred (char *, char *, char *, CREDENTIALS *);
+extern long krb_mk_priv (u_char *, u_char *, u_long, Key_schedule,
+ C_Block, struct sockaddr_in *,
+ struct sockaddr_in *);
+extern long krb_rd_priv (u_char *, u_long, Key_schedule,
+ C_Block, struct sockaddr_in *,
+ struct sockaddr_in *, MSG_DAT *);
+extern long krb_mk_safe (u_char *, u_char *, u_long, C_Block *,
+ struct sockaddr_in *, struct sockaddr_in *);
+extern long krb_rd_safe (u_char *, u_long, C_Block *,
+ struct sockaddr_in *, struct sockaddr_in *,
+ MSG_DAT *);
+extern long krb_mk_err (u_char *, long, char *);
+extern int krb_rd_err (u_char *, u_long, long *, MSG_DAT *);
+extern int krb_get_pw_in_tkt (char *, char *, char *, char *, char *, int,
+ char *);
+extern int krb_get_svc_in_tkt (char *, char *, char *, char *, char *, int,
+ char *);
+extern int krb_get_pw_tkt (char *, char *, char *, char *);
+extern int krb_get_lrealm (char *, char *);
+extern int krb_realmofhost (char *);
+extern char *krb_get_phost (char *);
+extern int krb_get_krbhst (char *, char *, int);
+#ifdef DEBUG
+extern KTEXT krb_create_death_packet (char *);
+#endif
+#else
+extern int krb_mk_req ();
+extern int krb_rd_req ();
+extern int krb_kntoln ();
+extern int krb_set_key ();
+extern int krb_get_cred ();
+extern long krb_mk_priv ();
+extern long krb_rd_priv ();
+extern long krb_mk_safe ();
+extern long krb_rd_safe ();
+extern long krb_mk_err ();
+extern int krb_rd_err ();
+extern int krb_get_pw_in_tkt ();
+extern int krb_get_svc_in_tkt ();
+extern int krb_get_pw_tkt ();
+extern int krb_get_lrealm ();
+extern int krb_realmofhost ();
+extern char *krb_get_phost ();
+extern int krb_get_krbhst ();
+#ifdef DEBUG
+extern KTEXT krb_create_death_packet ();
+#endif
+#endif
+*/
+
+
+int mk_ap_req(authent, service, instance, realm, checksum)
+ KTEXT authent;
+ char *service, *instance, *realm;
+ u_long checksum;
+{
+ return krb_mk_req(authent,service,instance,realm,checksum);
+}
+
+int rd_ap_req(authent, service, instance, from_addr, ad, fn)
+ KTEXT authent;
+ char *service, *instance;
+ u_long from_addr;
+ AUTH_DAT *ad;
+ char *fn;
+{
+ return krb_rd_req(authent,service,instance,from_addr,ad,fn);
+}
+
+int an_to_ln(ad, lname)
+ AUTH_DAT *ad;
+ char *lname;
+{
+ return krb_kntoln (ad,lname);
+}
+
+int set_serv_key (key, cvt)
+ char *key;
+ int cvt;
+{
+ return krb_set_key(key,cvt);
+}
+
+int get_credentials (svc,inst,rlm,cred)
+ char *svc, *inst, *rlm;
+ CREDENTIALS *cred;
+{
+ return krb_get_cred (svc, inst, rlm, cred);
+}
+
+long mk_private_msg (in,out,in_length,schedule,key,sender,receiver)
+ u_char *in, *out;
+ u_long in_length;
+ Key_schedule schedule;
+ C_Block key;
+ struct sockaddr_in *sender, *receiver;
+{
+ return krb_mk_priv (in,out,in_length,schedule,key,sender,receiver);
+}
+
+long rd_private_msg (in,in_length,schedule,key,sender,receiver,msg_data)
+ u_char *in;
+ u_long in_length;
+ Key_schedule schedule;
+ C_Block key;
+ struct sockaddr_in *sender, *receiver;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_priv (in,in_length,schedule,key,sender,receiver,msg_data);
+}
+
+long mk_safe_msg (in,out,in_length,key,sender,receiver)
+ u_char *in, *out;
+ u_long in_length;
+ C_Block *key;
+ struct sockaddr_in *sender, *receiver;
+{
+ return krb_mk_safe (in,out,in_length,key,sender,receiver);
+}
+
+long rd_safe_msg (in,length,key,sender,receiver,msg_data)
+ u_char *in;
+ u_long length;
+ C_Block *key;
+ struct sockaddr_in *sender, *receiver;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_safe (in,length,key,sender,receiver,msg_data);
+}
+
+long mk_appl_err_msg (out,code,string)
+ u_char *out;
+ long code;
+ char *string;
+{
+ return krb_mk_err (out,code,string);
+}
+
+long rd_appl_err_msg (in,length,code,msg_data)
+ u_char *in;
+ u_long length;
+ long *code;
+ MSG_DAT *msg_data;
+{
+ return krb_rd_err (in,length,code,msg_data);
+}
+
+int get_in_tkt(user,instance,realm,service,sinstance,life,password)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *password;
+{
+ return krb_get_pw_in_tkt(user,instance,realm,service,sinstance,
+ life,password);
+}
+
+int get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
+ char *user, *instance, *realm, *service, *sinstance;
+ int life;
+ char *srvtab;
+{
+ return krb_get_svc_in_tkt(user, instance, realm, service, sinstance,
+ life, srvtab);
+}
+
+int get_pw_tkt(user,instance,realm,cpw)
+ char *user;
+ char *instance;
+ char *realm;
+ char *cpw;
+{
+ return krb_get_pw_tkt(user,instance,realm,cpw);
+}
+
+int
+get_krbrlm (r, n)
+char *r;
+int n;
+{
+ return krb_get_lream(r,n);
+}
+
+int
+krb_getrealm (host)
+{
+ return krb_realmofhost(host);
+}
+
+char *
+get_phost (host)
+char *host
+{
+ return krb_get_phost(host);
+}
+
+int
+get_krbhst (h, r, n)
+char *h;
+char *r;
+int n;
+{
+ return krb_get_krbhst(h,r,n);
+}
+#ifdef DEBUG
+struct ktext *create_death_packet(a_name)
+ char *a_name;
+{
+ return krb_create_death_packet(a_name);
+}
+#endif /* DEBUG */
+
+#if 0
+extern int krb_ck_repl ();
+
+int check_replay ()
+{
+ return krb_ck_repl ();
+}
+#endif
+#endif /* NCOMPAT */
diff --git a/eBones/lib/libkrb/kuserok.c b/eBones/lib/libkrb/kuserok.c
new file mode 100644
index 0000000000000..8e5d18ab1e317
--- /dev/null
+++ b/eBones/lib/libkrb/kuserok.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * kuserok: check if a kerberos principal has
+ * access to a local account
+ *
+ * from: kuserok.c,v 4.5 89/01/23 09:25:21 jtkohl Exp $
+ * $Id: kuserok.c,v 1.3 1995/07/18 16:39:07 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kuserok.c,v 1.3 1995/07/18 16:39:07 mark Exp $";
+#endif lint
+#endif
+
+#include <krb.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <strings.h>
+
+#define OK 0
+#define NOTOK 1
+#define MAX_USERNAME 10
+
+/*
+ * Given a Kerberos principal "kdata", and a local username "luser",
+ * determine whether user is authorized to login according to the
+ * authorization file ("~luser/.klogin" by default). Returns OK
+ * if authorized, NOTOK if not authorized.
+ *
+ * If there is no account for "luser" on the local machine, returns
+ * NOTOK. If there is no authorization file, and the given Kerberos
+ * name "kdata" translates to the same name as "luser" (using
+ * krb_kntoln()), returns OK. Otherwise, if the authorization file
+ * can't be accessed, returns NOTOK. Otherwise, the file is read for
+ * a matching principal name, instance, and realm. If one is found,
+ * returns OK, if none is found, returns NOTOK.
+ *
+ * The file entries are in the format:
+ *
+ * name.instance@realm
+ *
+ * one entry per line.
+ *
+ * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin
+ * file entries. See the file "kparse.c".
+ */
+
+#ifdef ATHENA_COMPAT
+
+#include <kparse.h>
+
+/*
+ * The parmtable defines the keywords we will recognize with their
+ * default values, and keeps a pointer to the found value. The found
+ * value should be filled in with strsave(), since FreeParameterSet()
+ * will release memory for all non-NULL found strings.
+ *
+*** NOTE WELL! ***
+ *
+ * The table below is very nice, but we cannot hard-code a default for the
+ * realm: we have to get the realm via krb_get_lrealm(). Even though the
+ * default shows as "from krb_get_lrealm, below", it gets changed in
+ * kuserok to whatever krb_get_lrealm() tells us. That code assumes that
+ * the realm will be the entry number in the table below, so if you
+ * change the order of the entries below, you have to change the
+ * #definition of REALM_SCRIPT to reflect it.
+ */
+#define REALM_SUBSCRIPT 1
+parmtable kparm[] = {
+
+/* keyword default found value */
+{"user", "", (char *) NULL},
+{"realm", "see krb_get_lrealm, below", (char *) NULL},
+{"instance", "", (char *) NULL},
+};
+#define KPARMS kparm,PARMCOUNT(kparm)
+#endif ATHENA_COMPAT
+
+int
+kuserok(kdata, luser)
+ AUTH_DAT *kdata;
+ char *luser;
+{
+ struct stat sbuf;
+ struct passwd *pwd;
+ char pbuf[MAXPATHLEN];
+ int isok = NOTOK, rc;
+ FILE *fp;
+ char kuser[MAX_USERNAME];
+ char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
+ char linebuf[BUFSIZ];
+ char *newline;
+ int gobble;
+#ifdef ATHENA_COMPAT
+ char local_realm[REALM_SZ];
+#endif ATHENA_COMPAT
+
+ /* no account => no access */
+ if ((pwd = getpwnam(luser)) == NULL) {
+ return(NOTOK);
+ }
+ (void) strcpy(pbuf, pwd->pw_dir);
+ (void) strcat(pbuf, "/.klogin");
+
+ if (access(pbuf, F_OK)) { /* not accessible */
+ /*
+ * if he's trying to log in as himself, and there is no .klogin file,
+ * let him. To find out, call
+ * krb_kntoln to convert the triple in kdata to a name which we can
+ * string compare.
+ */
+ if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) {
+ return(OK);
+ }
+ }
+ /* open ~/.klogin */
+ if ((fp = fopen(pbuf, "r")) == NULL) {
+ return(NOTOK);
+ }
+ /*
+ * security: if the user does not own his own .klogin file,
+ * do not grant access
+ */
+ if (fstat(fileno(fp), &sbuf)) {
+ fclose(fp);
+ return(NOTOK);
+ }
+ if (sbuf.st_uid != pwd->pw_uid) {
+ fclose(fp);
+ return(NOTOK);
+ }
+
+#ifdef ATHENA_COMPAT
+ /* Accept old-style .klogin files */
+
+ /*
+ * change the default realm from the hard-coded value to the
+ * accepted realm that Kerberos specifies.
+ */
+ rc = krb_get_lrealm(local_realm, 1);
+ if (rc == KSUCCESS)
+ kparm[REALM_SUBSCRIPT].defvalue = local_realm;
+ else
+ return (rc);
+
+ /* check each line */
+ while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) {
+ switch (rc) {
+ case PS_BAD_KEYWORD:
+ case PS_SYNTAX:
+ while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n'));
+ break;
+
+ case PS_OKAY:
+ isok = (ParmCompare(KPARMS, "user", kdata->pname) ||
+ ParmCompare(KPARMS, "instance", kdata->pinst) ||
+ ParmCompare(KPARMS, "realm", kdata->prealm));
+ break;
+
+ default:
+ break;
+ }
+ FreeParameterSet(kparm, PARMCOUNT(kparm));
+ }
+ /* reset the stream for parsing new-style names, if necessary */
+ rewind(fp);
+#endif ATHENA_COMPAT
+
+ /* check each line */
+ while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
+ /* null-terminate the input string */
+ linebuf[BUFSIZ-1] = '\0';
+ newline = NULL;
+ /* nuke the newline if it exists */
+ if ((newline = index(linebuf, '\n')))
+ *newline = '\0';
+ rc = kname_parse(principal, inst, realm, linebuf);
+ if (rc == KSUCCESS) {
+ isok = (strncmp(kdata->pname, principal, ANAME_SZ) ||
+ strncmp(kdata->pinst, inst, INST_SZ) ||
+ strncmp(kdata->prealm, realm, REALM_SZ));
+ }
+ /* clean up the rest of the line if necessary */
+ if (!newline)
+ while (((gobble = getc(fp)) != EOF) && gobble != '\n');
+ }
+ fclose(fp);
+ return(isok);
+}
diff --git a/eBones/lib/libkrb/log.c b/eBones/lib/libkrb/log.c
new file mode 100644
index 0000000000000..e33477f5cf54f
--- /dev/null
+++ b/eBones/lib/libkrb/log.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: log.c,v 4.7 88/12/01 14:15:14 jtkohl Exp $
+ * $Id: log.c,v 1.3 1995/07/18 16:39:09 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: log.c,v 1.3 1995/07/18 16:39:09 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <krb.h>
+#include <klog.h>
+
+static char *log_name = KRBLOG;
+static is_open;
+
+/*
+ * This file contains three logging routines: set_logfile()
+ * to determine the file that log entries should be written to;
+ * and log() and new_log() to write log entries to the file.
+ */
+
+/*
+ * log() is used to add entries to the logfile (see set_logfile()
+ * below). Note that it is probably not portable since it makes
+ * assumptions about what the compiler will do when it is called
+ * with less than the correct number of arguments which is the
+ * way it is usually called.
+ *
+ * The log entry consists of a timestamp and the given arguments
+ * printed according to the given "format".
+ *
+ * The log file is opened and closed for each log entry.
+ *
+ * The return value is undefined.
+ */
+
+__BEGIN_DECLS
+char *month_sname __P((int));
+__END_DECLS
+
+
+/*VARARGS1 */
+void log(format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
+ char *format;
+ int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
+{
+ FILE *logfile, *fopen();
+ long time(),now;
+ struct tm *tm;
+
+ if ((logfile = fopen(log_name,"a")) == NULL)
+ return;
+
+ (void) time(&now);
+ tm = localtime(&now);
+
+ fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
+ fprintf(logfile,"\n");
+ (void) fclose(logfile);
+ return;
+}
+
+/*
+ * set_logfile() changes the name of the file to which
+ * messages are logged. If set_logfile() is not called,
+ * the logfile defaults to KRBLOG, defined in "krb.h".
+ */
+
+void
+set_logfile(filename)
+ char *filename;
+{
+ log_name = filename;
+ is_open = 0;
+}
+
+/*
+ * new_log() appends a log entry containing the give time "t" and the
+ * string "string" to the logfile (see set_logfile() above). The file
+ * is opened once and left open. The routine returns 1 on failure, 0
+ * on success.
+ */
+
+int
+new_log(t,string)
+ long t;
+ char *string;
+{
+ static FILE *logfile;
+
+ long time();
+ struct tm *tm;
+
+ if (!is_open) {
+ if ((logfile = fopen(log_name,"a")) == NULL) return(1);
+ is_open = 1;
+ }
+
+ if (t) {
+ tm = localtime(&t);
+
+ fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d %s",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec, string);
+ }
+ else {
+ fprintf(logfile,"\n%20s%s","",string);
+ }
+
+ (void) fflush(logfile);
+ return(0);
+}
diff --git a/eBones/lib/libkrb/mk_err.c b/eBones/lib/libkrb/mk_err.c
new file mode 100644
index 0000000000000..86002403bccf9
--- /dev/null
+++ b/eBones/lib/libkrb/mk_err.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: mk_err.c,v 4.4 88/11/15 16:33:36 jtkohl Exp $
+ * $Id: mk_err.c,v 1.3 1995/07/18 16:39:11 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: mk_err.c,v 1.3 1995/07/18 16:39:11 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <sys/types.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+/*
+ * This routine creates a general purpose error reply message. It
+ * doesn't use KTEXT because application protocol may have long
+ * messages, and may want this part of buffer contiguous to other
+ * stuff.
+ *
+ * The error reply is built in "p", using the error code "e" and
+ * error text "e_string" given. The length of the error reply is
+ * returned.
+ *
+ * The error reply is in the following format:
+ *
+ * unsigned char KRB_PROT_VERSION protocol version no.
+ * unsigned char AUTH_MSG_APPL_ERR message type
+ * (least significant
+ * bit of above) HOST_BYTE_ORDER local byte order
+ * 4 bytes e given error code
+ * string e_string given error text
+ */
+
+long krb_mk_err(p,e,e_string)
+ u_char *p; /* Where to build error packet */
+ long e; /* Error code */
+ char *e_string; /* Text of error */
+{
+ u_char *start;
+
+ start = p;
+
+ /* Create fixed part of packet */
+ *p++ = (unsigned char) KRB_PROT_VERSION;
+ *p = (unsigned char) AUTH_MSG_APPL_ERR;
+ *p++ |= HOST_BYTE_ORDER;
+
+ /* Add the basic info */
+ bcopy((char *)&e,(char *)p,4); /* err code */
+ p += sizeof(e);
+ (void) strcpy((char *)p,e_string); /* err text */
+ p += strlen(e_string);
+
+ /* And return the length */
+ return p-start;
+}
diff --git a/eBones/lib/libkrb/mk_priv.c b/eBones/lib/libkrb/mk_priv.c
new file mode 100644
index 0000000000000..d45d734c6f170
--- /dev/null
+++ b/eBones/lib/libkrb/mk_priv.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine constructs a Kerberos 'private msg', i.e.
+ * cryptographically sealed with a private session key.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT.
+ *
+ * Note-- It's too bad that it did a long int compare on the RT before.
+ *
+ * Returns either < 0 ===> error, or resulting size of message
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: mk_priv.c,v 4.13 89/03/22 14:48:59 jtkohl Exp $
+ * $Id: mk_priv.c,v 1.3 1995/07/18 16:39:13 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: mk_priv.c,v 1.3 1995/07/18 16:39:13 mark Exp $";
+#endif /* lint */
+#endif
+
+/* system include files */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+
+static u_long c_length;
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes
+ * some user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address.
+#ifndef NOENCRYTION
+ * The packet is encrypted by pcbc_encrypt(), using the given
+ * "key" and "schedule".
+#endif
+ * The length of the resulting packet "out" is
+ * returned.
+ *
+ * It is similar to krb_mk_safe() except for the additional key
+ * schedule argument "schedule" and the fact that the data is encrypted
+ * rather than appended with a checksum. Also, the protocol version
+ * number is "private_msg_ver", defined in krb_rd_priv.c, rather than
+ * KRB_PROT_VERSION, defined in "krb.h".
+ *
+ * The "out" packet consists of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte private_msg_ver protocol version number
+ * 1 byte AUTH_MSG_PRIVATE | message type plus local
+ * HOST_BYTE_ORDER byte order in low bit
+ *
+ * 4 bytes c_length length of data
+#ifndef NOENCRYPT
+ * we encrypt from here with pcbc_encrypt
+#endif
+ *
+ * 4 bytes length length of user data
+ * length in user data
+ * 1 byte msg_time_5ms timestamp milliseconds
+ * 4 bytes sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes msg_time_sec or timestamp seconds with
+ * -msg_time_sec direction in sign bit
+ *
+ * 0<=n<=7 bytes pad to 8 byte multiple zeroes
+ */
+
+long krb_mk_priv(in,out,length,schedule,key,sender,receiver)
+ u_char *in; /* application data */
+ u_char *out; /* put msg here, leave room for
+ * header! breaks if in and out
+ * (header stuff) overlap */
+ u_long length; /* of in data */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender address */
+ struct sockaddr_in *receiver; /* receiver address */
+{
+ register u_char *p,*q;
+ static u_char *c_length_ptr;
+ extern int private_msg_ver; /* in krb_rd_priv.c */
+
+ /*
+ * get the current time to use instead of a sequence #, since
+ * process lifetime may be shorter than the lifetime of a session
+ * key.
+ */
+ if (gettimeofday(&msg_time,(struct timezone *)0)) {
+ return -1;
+ }
+ msg_time_sec = (long) msg_time.tv_sec;
+ msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+ p = out;
+
+ *p++ = private_msg_ver;
+ *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER;
+
+ /* calculate cipher length */
+ c_length_ptr = p;
+ p += sizeof(c_length);
+
+ q = p;
+
+ /* stuff input length */
+ bcopy((char *)&length,(char *)p,sizeof(length));
+ p += sizeof(length);
+
+#ifdef NOENCRYPTION
+ /* make all the stuff contiguous for checksum */
+#else
+ /* make all the stuff contiguous for checksum and encryption */
+#endif
+ bcopy((char *)in,(char *)p,(int) length);
+ p += length;
+
+ /* stuff time 5ms */
+ bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+ p += sizeof(msg_time_5ms);
+
+ /* stuff source address */
+ bcopy((char *)&sender->sin_addr.s_addr,(char *)p,
+ sizeof(sender->sin_addr.s_addr));
+ p += sizeof(sender->sin_addr.s_addr);
+
+ /*
+ * direction bit is the sign bit of the timestamp. Ok
+ * until 2038??
+ */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
+ receiver->sin_addr.s_addr)==-1)
+ msg_time_sec = -msg_time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
+ msg_time_sec = -msg_time_sec;
+ /* stuff time sec */
+ bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+ p += sizeof(msg_time_sec);
+
+ /*
+ * All that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+#ifdef notdef
+ /*
+ * calculate the checksum of the length, address, sequence, and
+ * inp data
+ */
+ cksum = quad_cksum(q,NULL,p-q,0,key);
+ if (krb_debug)
+ printf("\ncksum = %u",cksum);
+ /* stuff checksum */
+ bcopy((char *) &cksum,(char *) p,sizeof(cksum));
+ p += sizeof(cksum);
+#endif
+
+ /*
+ * All the data have been assembled, compute length
+ */
+
+ c_length = p - q;
+ c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) *
+ sizeof(C_Block);
+ /* stuff the length */
+ bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length));
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)(p-q),schedule,(C_Block *)key,
+ ENCRYPT);
+#endif /* NOENCRYPTION */
+
+ return (q - out + c_length); /* resulting size */
+}
diff --git a/eBones/lib/libkrb/mk_req.c b/eBones/lib/libkrb/mk_req.c
new file mode 100644
index 0000000000000..a27c1c0d556b6
--- /dev/null
+++ b/eBones/lib/libkrb/mk_req.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: mk_req.c,v 4.17 89/07/07 15:20:35 jtkohl Exp $
+ * $Id: mk_req.c,v 1.3 1995/07/18 16:39:15 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: mk_req.c,v 1.3 1995/07/18 16:39:15 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+#include <des.h>
+#include <sys/time.h>
+#include <strings.h>
+
+extern int krb_ap_req_debug;
+static struct timeval tv_local = { 0, 0 };
+static int lifetime = DEFAULT_TKT_LIFE;
+
+/*
+ * krb_mk_req takes a text structure in which an authenticator is to
+ * be built, the name of a service, an instance, a realm,
+ * and a checksum. It then retrieves a ticket for
+ * the desired service and creates an authenticator in the text
+ * structure passed as the first argument. krb_mk_req returns
+ * KSUCCESS on success and a Kerberos error code on failure.
+ *
+ * The peer procedure on the other end is krb_rd_req. When making
+ * any changes to this routine it is important to make corresponding
+ * changes to krb_rd_req.
+ *
+ * The authenticator consists of the following:
+ *
+ * authent->dat
+ *
+ * unsigned char KRB_PROT_VERSION protocol version no.
+ * unsigned char AUTH_MSG_APPL_REQUEST message type
+ * (least significant
+ * bit of above) HOST_BYTE_ORDER local byte ordering
+ * unsigned char kvno from ticket server's key version
+ * string realm server's realm
+ * unsigned char tl ticket length
+ * unsigned char idl request id length
+ * text ticket->dat ticket for server
+ * text req_id->dat request id
+ *
+ * The ticket information is retrieved from the ticket cache or
+ * fetched from Kerberos. The request id (called the "authenticator"
+ * in the papers on Kerberos) contains the following:
+ *
+ * req_id->dat
+ *
+ * string cr.pname {name, instance, and
+ * string cr.pinst realm of principal
+ * string myrealm making this request}
+ * 4 bytes checksum checksum argument given
+ * unsigned char tv_local.tf_usec time (milliseconds)
+ * 4 bytes tv_local.tv_sec time (seconds)
+ *
+ * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time,
+ * all rounded up to multiple of 8.
+ */
+
+int
+krb_mk_req(authent,service,instance,realm,checksum)
+ register KTEXT authent; /* Place to build the authenticator */
+ char *service; /* Name of the service */
+ char *instance; /* Service instance */
+ char *realm; /* Authentication domain of service */
+ long checksum; /* Checksum of data (optional) */
+{
+ static KTEXT_ST req_st; /* Temp storage for req id */
+ register KTEXT req_id = &req_st;
+ unsigned char *v = authent->dat; /* Prot version number */
+ unsigned char *t = (authent->dat+1); /* Message type */
+ unsigned char *kv = (authent->dat+2); /* Key version no */
+ unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */
+ unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */
+ CREDENTIALS cr; /* Credentials used by retr */
+ register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
+ int retval; /* Returned by krb_get_cred */
+ static Key_schedule key_s;
+ char myrealm[REALM_SZ];
+
+ /* The fixed parts of the authenticator */
+ *v = (unsigned char) KRB_PROT_VERSION;
+ *t = (unsigned char) AUTH_MSG_APPL_REQUEST;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Get the ticket and move it into the authenticator */
+ if (krb_ap_req_debug)
+ printf("Realm: %s\n",realm);
+ /*
+ * Determine realm of these tickets. We will send this to the
+ * KDC from which we are requesting tickets so it knows what to
+ * with our session key.
+ */
+ if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS)
+ return(retval);
+
+ retval = krb_get_cred(service,instance,realm,&cr);
+
+ if (retval == RET_NOTKT) {
+ if ((retval = get_ad_tkt(service,instance,realm,lifetime)))
+ return(retval);
+ if ((retval = krb_get_cred(service,instance,realm,&cr)))
+ return(retval);
+ }
+
+ if (retval != KSUCCESS) return (retval);
+
+ if (krb_ap_req_debug)
+ printf("%s %s %s %s %s\n", service, instance, realm,
+ cr.pname, cr.pinst);
+ *kv = (unsigned char) cr.kvno;
+ (void) strcpy((char *)(authent->dat+3),realm);
+ *tl = (unsigned char) ticket->length;
+ bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)),
+ ticket->length);
+ authent->length = 6 + strlen(realm) + ticket->length;
+ if (krb_ap_req_debug)
+ printf("Ticket->length = %d\n",ticket->length);
+ if (krb_ap_req_debug)
+ printf("Issue date: %ld\n",cr.issue_date);
+
+ /* Build request id */
+ (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */
+ req_id->length = strlen(cr.pname)+1;
+ /* Principal's instance */
+ (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst);
+ req_id->length += strlen(cr.pinst)+1;
+ /* Authentication domain */
+ (void) strcpy((char *)(req_id->dat+req_id->length),myrealm);
+ req_id->length += strlen(myrealm)+1;
+ /* Checksum */
+ bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4);
+ req_id->length += 4;
+
+ /* Fill in the times on the request id */
+ (void) gettimeofday(&tv_local,(struct timezone *) 0);
+ *(req_id->dat+(req_id->length)++) =
+ (unsigned char) tv_local.tv_usec;
+ /* Time (coarse) */
+ bcopy((char *)&(tv_local.tv_sec),
+ (char *)(req_id->dat+req_id->length), 4);
+ req_id->length += 4;
+
+ /* Fill to a multiple of 8 bytes for DES */
+ req_id->length = ((req_id->length+7)/8)*8;
+
+#ifndef NOENCRYPTION
+ key_sched((C_Block *)cr.session,key_s);
+ pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
+ (long)req_id->length,key_s,(C_Block *)cr.session,ENCRYPT);
+ bzero((char *) key_s, sizeof(key_s));
+#endif /* NOENCRYPTION */
+
+ /* Copy it into the authenticator */
+ bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length),
+ req_id->length);
+ authent->length += req_id->length;
+ /* And set the id length */
+ *idl = (unsigned char) req_id->length;
+ /* clean up */
+ bzero((char *)req_id, sizeof(*req_id));
+
+ if (krb_ap_req_debug)
+ printf("Authent->length = %d\n",authent->length);
+ if (krb_ap_req_debug)
+ printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl);
+
+ return(KSUCCESS);
+}
+
+/*
+ * krb_set_lifetime sets the default lifetime for additional tickets
+ * obtained via krb_mk_req().
+ *
+ * It returns the previous value of the default lifetime.
+ */
+
+int
+krb_set_lifetime(newval)
+int newval;
+{
+ int olife = lifetime;
+
+ lifetime = newval;
+ return(olife);
+}
diff --git a/eBones/lib/libkrb/mk_safe.c b/eBones/lib/libkrb/mk_safe.c
new file mode 100644
index 0000000000000..e5490bcd2e9be
--- /dev/null
+++ b/eBones/lib/libkrb/mk_safe.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine constructs a Kerberos 'safe msg', i.e. authenticated
+ * using a private session key to seed a checksum. Msg is NOT
+ * encrypted.
+ *
+ * Note-- bcopy is used to avoid alignment problems on IBM RT
+ *
+ * Returns either <0 ===> error, or resulting size of message
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: mk_safe.c,v 4.12 89/03/22 14:50:49 jtkohl Exp $
+ * $Id: mk_safe.c,v 1.3 1995/07/18 16:39:17 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: mk_safe.c,v 1.3 1995/07/18 16:39:17 mark Exp $";
+#endif /* lint */
+#endif
+
+/* system include files */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static u_long cksum;
+static C_Block big_cksum[2];
+static struct timeval msg_time;
+static u_char msg_time_5ms;
+static long msg_time_sec;
+
+/*
+ * krb_mk_safe() constructs an AUTH_MSG_SAFE message. It takes some
+ * user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address, followed by a checksum computed on the above, using the
+ * given "key". The length of the resulting packet is returned.
+ *
+ * The "out" packet consists of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 1 byte KRB_PROT_VERSION protocol version number
+ * 1 byte AUTH_MSG_SAFE | message type plus local
+ * HOST_BYTE_ORDER byte order in low bit
+ *
+ * ===================== begin checksum ================================
+ *
+ * 4 bytes length length of user data
+ * length in user data
+ * 1 byte msg_time_5ms timestamp milliseconds
+ * 4 bytes sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes msg_time_sec or timestamp seconds with
+ * -msg_time_sec direction in sign bit
+ *
+ * ======================= end checksum ================================
+ *
+ * 16 bytes big_cksum quadratic checksum of
+ * above using "key"
+ */
+
+long krb_mk_safe(in,out,length,key,sender,receiver)
+ u_char *in; /* application data */
+ u_char *out; /*
+ * put msg here, leave room for header!
+ * breaks if in and out (header stuff)
+ * overlap
+ */
+ u_long length; /* of in data */
+ C_Block *key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender address */
+ struct sockaddr_in *receiver; /* receiver address */
+{
+ register u_char *p,*q;
+
+ /*
+ * get the current time to use instead of a sequence #, since
+ * process lifetime may be shorter than the lifetime of a session
+ * key.
+ */
+ if (gettimeofday(&msg_time,(struct timezone *)0)) {
+ return -1;
+ }
+ msg_time_sec = (long) msg_time.tv_sec;
+ msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
+
+ p = out;
+
+ *p++ = KRB_PROT_VERSION;
+ *p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER;
+
+ q = p; /* start for checksum stuff */
+ /* stuff input length */
+ bcopy((char *)&length,(char *)p,sizeof(length));
+ p += sizeof(length);
+
+ /* make all the stuff contiguous for checksum */
+ bcopy((char *)in,(char *)p,(int) length);
+ p += length;
+
+ /* stuff time 5ms */
+ bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
+ p += sizeof(msg_time_5ms);
+
+ /* stuff source address */
+ bcopy((char *) &sender->sin_addr.s_addr,(char *)p,
+ sizeof(sender->sin_addr.s_addr));
+ p += sizeof(sender->sin_addr.s_addr);
+
+ /*
+ * direction bit is the sign bit of the timestamp. Ok until
+ * 2038??
+ */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
+ receiver->sin_addr.s_addr)==-1)
+ msg_time_sec = -msg_time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
+ msg_time_sec = -msg_time_sec;
+ /*
+ * all that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+ /* stuff time sec */
+ bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
+ p += sizeof(msg_time_sec);
+
+#ifdef NOENCRYPTION
+ cksum = 0;
+ bzero(big_cksum, sizeof(big_cksum));
+#else
+ cksum=quad_cksum((C_Block *)q,big_cksum,p-q,2,key);
+#endif
+ if (krb_debug)
+ printf("\ncksum = %lu",cksum);
+
+ /* stuff checksum */
+ bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum));
+ p += sizeof(big_cksum);
+
+ return ((long)(p - out)); /* resulting size */
+
+}
diff --git a/eBones/lib/libkrb/month_sname.c b/eBones/lib/libkrb/month_sname.c
new file mode 100644
index 0000000000000..f4ef33994bc9a
--- /dev/null
+++ b/eBones/lib/libkrb/month_sname.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: month_sname.c,v 4.4 88/11/15 16:39:32 jtkohl Exp $
+ * $Id: month_sname.c,v 1.3 1995/07/18 16:39:19 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: month_sname.c,v 1.3 1995/07/18 16:39:19 mark Exp $";
+#endif /* lint */
+#endif
+
+
+/*
+ * Given an integer 1-12, month_sname() returns a string
+ * containing the first three letters of the corresponding
+ * month. Returns 0 if the argument is out of range.
+ */
+
+char *month_sname(n)
+ int n;
+{
+ static char *name[] = {
+ "Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"
+ };
+ return((n < 1 || n > 12) ? 0 : name [n-1]);
+}
diff --git a/eBones/lib/libkrb/netread.c b/eBones/lib/libkrb/netread.c
new file mode 100644
index 0000000000000..628004e251853
--- /dev/null
+++ b/eBones/lib/libkrb/netread.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: netread.c,v 4.1 88/11/15 16:47:21 jtkohl Exp $
+ * $Id: netread.c,v 1.3 1995/07/18 16:39:20 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: netread.c,v 1.3 1995/07/18 16:39:20 mark Exp $";
+#endif lint
+#endif
+
+#include <unistd.h>
+
+/*
+ * krb_net_read() reads from the file descriptor "fd" to the buffer
+ * "buf", until either 1) "len" bytes have been read or 2) cannot
+ * read anymore from "fd". It returns the number of bytes read
+ * or a read() error. (The calling interface is identical to
+ * read(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_read(fd, buf, len)
+int fd;
+register char *buf;
+register int len;
+{
+ int cc, len2 = 0;
+
+ do {
+ cc = read(fd, buf, len);
+ if (cc < 0)
+ return(cc); /* errno is already set */
+ else if (cc == 0) {
+ return(len2);
+ } else {
+ buf += cc;
+ len2 += cc;
+ len -= cc;
+ }
+ } while (len > 0);
+ return(len2);
+}
diff --git a/eBones/lib/libkrb/netwrite.c b/eBones/lib/libkrb/netwrite.c
new file mode 100644
index 0000000000000..f85f7ba5efd77
--- /dev/null
+++ b/eBones/lib/libkrb/netwrite.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: netwrite.c,v 4.1 88/11/15 16:48:58 jtkohl Exp $";
+ * $Id: netwrite.c,v 1.3 1995/07/18 16:39:22 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: netwrite.c,v 1.3 1995/07/18 16:39:22 mark Exp $";
+#endif lint
+#endif
+
+#include <unistd.h>
+
+/*
+ * krb_net_write() writes "len" bytes from "buf" to the file
+ * descriptor "fd". It returns the number of bytes written or
+ * a write() error. (The calling interface is identical to
+ * write(2).)
+ *
+ * XXX must not use non-blocking I/O
+ */
+
+int
+krb_net_write(fd, buf, len)
+int fd;
+register char *buf;
+int len;
+{
+ int cc;
+ register int wrlen = len;
+ do {
+ cc = write(fd, buf, wrlen);
+ if (cc < 0)
+ return(cc);
+ else {
+ buf += cc;
+ wrlen -= cc;
+ }
+ } while (wrlen > 0);
+ return(len);
+}
diff --git a/eBones/lib/libkrb/one.c b/eBones/lib/libkrb/one.c
new file mode 100644
index 0000000000000..ef02ae1c878a9
--- /dev/null
+++ b/eBones/lib/libkrb/one.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * form: one.c,v 4.1 88/11/15 16:51:41 jtkohl Exp $
+ * $Id: one.c,v 1.3 1995/07/18 16:39:24 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: one.c,v 1.3 1995/07/18 16:39:24 mark Exp $";
+#endif lint
+#endif
+
+/*
+ * definition of variable set to 1.
+ * used in krb_conf.h to determine host byte order.
+ */
+
+int krbONE = 1;
diff --git a/eBones/lib/libkrb/pkt_cipher.c b/eBones/lib/libkrb/pkt_cipher.c
new file mode 100644
index 0000000000000..9c32b72b0fe96
--- /dev/null
+++ b/eBones/lib/libkrb/pkt_cipher.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: pkt_cipher.c,v 4.8 89/01/13 17:46:14 steiner Exp $
+ * $Id: pkt_cipher.c,v 1.3 1995/07/18 16:39:25 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: pkt_cipher.c,v 1.3 1995/07/18 16:39:25 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+
+
+/*
+ * This routine takes a reply packet from the Kerberos ticket-granting
+ * service and returns a pointer to the beginning of the ciphertext in it.
+ *
+ * See "prot.h" for packet format.
+ */
+
+KTEXT
+pkt_cipher(packet)
+ KTEXT packet;
+{
+ unsigned char *ptr = pkt_a_realm(packet) + 6
+ + strlen((char *)pkt_a_realm(packet));
+ /* Skip a few more fields */
+ ptr += 3 + 4; /* add 4 for exp_date */
+
+ /* And return the pointer */
+ return((KTEXT) ptr);
+}
diff --git a/eBones/lib/libkrb/pkt_clen.c b/eBones/lib/libkrb/pkt_clen.c
new file mode 100644
index 0000000000000..f8dacae34faa2
--- /dev/null
+++ b/eBones/lib/libkrb/pkt_clen.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: pkt_clen.c,v 4.7 88/11/15 16:56:36 jtkohl Exp $
+ * $Id: pkt_clen.c,v 1.3 1995/07/18 16:39:27 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: pkt_clen.c,v 1.3 1995/07/18 16:39:27 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <string.h>
+
+#include <krb.h>
+#include <prot.h>
+
+extern int krb_debug;
+extern int swap_bytes;
+
+/*
+ * Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of
+ * its ciphertext portion. The external variable "swap_bytes" is assumed
+ * to have been set to indicate whether or not the packet is in local
+ * byte order. pkt_clen() takes this into account when reading the
+ * ciphertext length out of the packet.
+ */
+
+int
+pkt_clen(pkt)
+ KTEXT pkt;
+{
+ static unsigned short temp,temp2;
+ int clen = 0;
+
+ /* Start of ticket list */
+ unsigned char *ptr = pkt_a_realm(pkt) + 10
+ + strlen((char *)pkt_a_realm(pkt));
+
+ /* Finally the length */
+ bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */
+ if (swap_bytes) {
+ /* assume a short is 2 bytes?? */
+ swab((char *)&temp,(char *)&temp2,2);
+ temp = temp2;
+ }
+
+ clen = (int) temp;
+
+ if (krb_debug)
+ printf("Clen is %d\n",clen);
+ return(clen);
+}
diff --git a/eBones/lib/libkrb/rd_err.c b/eBones/lib/libkrb/rd_err.c
new file mode 100644
index 0000000000000..e46dc6678f0db
--- /dev/null
+++ b/eBones/lib/libkrb/rd_err.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'safe msg',
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_err.c,v 4.5 89/01/13 17:26:38 steiner Exp $
+ * $Id: rd_err.c,v 1.3 1995/07/18 16:39:29 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: rd_err.c,v 1.3 1995/07/18 16:39:29 mark Exp $";
+#endif /* lint */
+#endif
+
+/* system include files */
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <krb.h>
+#include <prot.h>
+
+/*
+ * Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length",
+ * return the error code from the message in "code" and the text in
+ * "m_data" as follows:
+ *
+ * m_data->app_data points to the error text
+ * m_data->app_length points to the length of the error text
+ *
+ * If all goes well, return RD_AP_OK. If the version number
+ * is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR
+ * type message, return RD_AP_MSG_TYPE.
+ *
+ * The AUTH_MSG_APPL_ERR message format can be found in mk_err.c
+ */
+
+int
+krb_rd_err(in,in_length,code,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* of in msg */
+ long *code; /* received error code */
+ MSG_DAT *m_data;
+{
+ register u_char *p;
+ int swap_bytes = 0;
+ p = in; /* beginning of message */
+
+ if (*p++ != KRB_PROT_VERSION)
+ return(RD_AP_VERSION);
+ if (((*p) & ~1) != AUTH_MSG_APPL_ERR)
+ return(RD_AP_MSG_TYPE);
+ if ((*p++ & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* safely get code */
+ bcopy((char *)p,(char *)code,sizeof(*code));
+ if (swap_bytes)
+ swap_u_long(*code);
+ p += sizeof(*code); /* skip over */
+
+ m_data->app_data = p; /* we're now at the error text
+ * message */
+ m_data->app_length = in_length;
+
+ return(RD_AP_OK); /* OK == 0 */
+}
diff --git a/eBones/lib/libkrb/rd_priv.c b/eBones/lib/libkrb/rd_priv.c
new file mode 100644
index 0000000000000..0c21a1d463b11
--- /dev/null
+++ b/eBones/lib/libkrb/rd_priv.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'private msg', decrypting it,
+ * checking its integrity, and returning a pointer to the application
+ * data contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If
+ * the return value is RD_AP_TIME, then either the times are too far
+ * out of synch, OR the packet was modified.
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $
+ * $Id: rd_priv.c,v 1.3 1995/07/18 16:39:31 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[]=
+"$Id: rd_priv.c,v 1.3 1995/07/18 16:39:31 mark Exp $";
+#endif /* lint */
+#endif
+
+/* system include files */
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern int krb_debug;
+
+/* static storage */
+
+static u_long c_length;
+static int swap_bytes;
+static struct timeval local_time;
+static long delta_t;
+int private_msg_ver = KRB_PROT_VERSION;
+
+/*
+#ifdef NOENCRPYTION
+ * krb_rd_priv() checks the integrity of an
+#else
+ * krb_rd_priv() decrypts and checks the integrity of an
+#endif
+ * AUTH_MSG_PRIVATE message. Given the message received, "in",
+ * the length of that message, "in_length", the key "schedule"
+ * and "key", and the network addresses of the
+ * "sender" and "receiver" of the message, krb_rd_safe() returns
+ * RD_AP_OK if the message is okay, otherwise some error code.
+ *
+ * The message data retrieved from "in" are returned in the structure
+ * "m_data". The pointer to the application data
+ * (m_data->app_data) refers back to the appropriate place in "in".
+ *
+ * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
+ * message. The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+long
+krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* length of "in" msg */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender;
+ struct sockaddr_in *receiver;
+ MSG_DAT *m_data; /*various input/output data from msg */
+{
+ register u_char *p,*q;
+ static u_long src_addr; /* Can't send structs since no
+ * guarantees on size */
+
+ if (gettimeofday(&local_time,(struct timezone *)0))
+ return -1;
+
+ p = in; /* beginning of message */
+ swap_bytes = 0;
+
+ if (*p++ != KRB_PROT_VERSION && *(p-1) != 3)
+ return RD_AP_VERSION;
+ private_msg_ver = *(p-1);
+ if (((*p) & ~1) != AUTH_MSG_PRIVATE)
+ return RD_AP_MSG_TYPE;
+ if ((*p++ & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* get cipher length */
+ bcopy((char *)p,(char *)&c_length,sizeof(c_length));
+ if (swap_bytes)
+ swap_u_long(c_length);
+ p += sizeof(c_length);
+ /* check for rational length so we don't go comatose */
+ if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
+ return RD_AP_MODIFIED;
+
+
+ q = p; /* mark start of encrypted stuff */
+
+#ifndef NOENCRYPTION
+ pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)c_length,schedule,
+ (C_Block *)key,DECRYPT);
+#endif
+
+ /* safely get application data length */
+ bcopy((char *) p,(char *)&(m_data->app_length),
+ sizeof(m_data->app_length));
+ if (swap_bytes)
+ swap_u_long(m_data->app_length);
+ p += sizeof(m_data->app_length); /* skip over */
+
+ if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
+ sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) +
+ sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ
+ > in_length)
+ return RD_AP_MODIFIED;
+
+#ifndef NOENCRYPTION
+ /* we're now at the decrypted application data */
+#endif
+ m_data->app_data = p;
+
+ p += m_data->app_length;
+
+ /* safely get time_5ms */
+ bcopy((char *) p, (char *)&(m_data->time_5ms),
+ sizeof(m_data->time_5ms));
+ /* don't need to swap-- one byte for now */
+ p += sizeof(m_data->time_5ms);
+
+ /* safely get src address */
+ bcopy((char *) p,(char *)&src_addr,sizeof(src_addr));
+ /* don't swap, net order always */
+ p += sizeof(src_addr);
+
+ if (src_addr != (u_long) sender->sin_addr.s_addr)
+ return RD_AP_MODIFIED;
+
+ /* safely get time_sec */
+ bcopy((char *) p, (char *)&(m_data->time_sec),
+ sizeof(m_data->time_sec));
+ if (swap_bytes) swap_u_long(m_data->time_sec);
+
+ p += sizeof(m_data->time_sec);
+
+ /* check direction bit is the sign bit */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ /*
+ * all that for one tiny bit!
+ * Heaven help those that talk to themselves.
+ */
+
+ /* check the time integrity of the msg */
+ delta_t = abs((int)((long) local_time.tv_sec
+ - m_data->time_sec));
+ if (delta_t > CLOCK_SKEW)
+ return RD_AP_TIME;
+ if (krb_debug)
+ printf("\ndelta_t = %ld",delta_t);
+
+ /*
+ * caller must check timestamps for proper order and
+ * replays, since server might have multiple clients
+ * each with its own timestamps and we don't assume
+ * tightly synchronized clocks.
+ */
+
+#ifdef notdef
+ bcopy((char *) p,(char *)&cksum,sizeof(cksum));
+ if (swap_bytes) swap_u_long(cksum)
+ /*
+ * calculate the checksum of the length, sequence,
+ * and input data, on the sending byte order!!
+ */
+ calc_cksum = quad_cksum(q,NULL,p-q,0,key);
+
+ if (krb_debug)
+ printf("\ncalc_cksum = %u, received cksum = %u",
+ calc_cksum, cksum);
+ if (cksum != calc_cksum)
+ return RD_AP_MODIFIED;
+#endif
+ return RD_AP_OK; /* OK == 0 */
+}
diff --git a/eBones/lib/libkrb/rd_req.c b/eBones/lib/libkrb/rd_req.c
new file mode 100644
index 0000000000000..60ee9483d30c7
--- /dev/null
+++ b/eBones/lib/libkrb/rd_req.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: der: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp $
+ * $Id: rd_req.c,v 1.3 1995/07/18 16:39:33 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: rd_req.c,v 1.3 1995/07/18 16:39:33 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include <sys/time.h>
+#include <strings.h>
+
+extern int krb_ap_req_debug;
+
+static struct timeval t_local = { 0, 0 };
+
+/*
+ * Keep the following information around for subsequent calls
+ * to this routine by the same server using the same key.
+ */
+
+static Key_schedule serv_key; /* Key sched to decrypt ticket */
+static C_Block ky; /* Initialization vector */
+static int st_kvno; /* version number for this key */
+static char st_rlm[REALM_SZ]; /* server's realm */
+static char st_nam[ANAME_SZ]; /* service name */
+static char st_inst[INST_SZ]; /* server's instance */
+
+/*
+ * This file contains two functions. krb_set_key() takes a DES
+ * key or password string and returns a DES key (either the original
+ * key, or the password converted into a DES key) and a key schedule
+ * for it.
+ *
+ * krb_rd_req() reads an authentication request and returns information
+ * about the identity of the requestor, or an indication that the
+ * identity information was not authentic.
+ */
+
+/*
+ * krb_set_key() takes as its first argument either a DES key or a
+ * password string. The "cvt" argument indicates how the first
+ * argument "key" is to be interpreted: if "cvt" is null, "key" is
+ * taken to be a DES key; if "cvt" is non-null, "key" is taken to
+ * be a password string, and is converted into a DES key using
+ * string_to_key(). In either case, the resulting key is returned
+ * in the external static variable "ky". A key schedule is
+ * generated for "ky" and returned in the external static variable
+ * "serv_key".
+ *
+ * This routine returns the return value of des_key_sched.
+ *
+ * krb_set_key() needs to be in the same .o file as krb_rd_req() so that
+ * the key set by krb_set_key() is available in private storage for
+ * krb_rd_req().
+ */
+
+int
+krb_set_key(key,cvt)
+ char *key;
+ int cvt;
+{
+#ifdef NOENCRYPTION
+ bzero(ky, sizeof(ky));
+ return KSUCCESS;
+#else
+ if (cvt)
+ string_to_key(key,(C_Block *)ky);
+ else
+ bcopy(key,(char *)ky,8);
+ return(des_key_sched((C_Block *)ky,serv_key));
+#endif
+}
+
+
+/*
+ * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
+ * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
+ * checks its integrity and returns a judgement as to the requestor's
+ * identity.
+ *
+ * The "authent" argument is a pointer to the received message.
+ * The "service" and "instance" arguments name the receiving server,
+ * and are used to get the service's ticket to decrypt the ticket
+ * in the message, and to compare against the server name inside the
+ * ticket. "from_addr" is the network address of the host from which
+ * the message was received; this is checked against the network
+ * address in the ticket. If "from_addr" is zero, the check is not
+ * performed. "ad" is an AUTH_DAT structure which is
+ * filled in with information about the sender's identity according
+ * to the authenticator and ticket sent in the message. Finally,
+ * "fn" contains the name of the file containing the server's key.
+ * (If "fn" is NULL, the server's key is assumed to have been set
+ * by krb_set_key(). If "fn" is the null string ("") the default
+ * file KEYFILE, defined in "krb.h", is used.)
+ *
+ * krb_rd_req() returns RD_AP_OK if the authentication information
+ * was genuine, or one of the following error codes (defined in
+ * "krb.h"):
+ *
+ * RD_AP_VERSION - wrong protocol version number
+ * RD_AP_MSG_TYPE - wrong message type
+ * RD_AP_UNDEC - couldn't decipher the message
+ * RD_AP_INCON - inconsistencies found
+ * RD_AP_BADD - wrong network address
+ * RD_AP_TIME - client time (in authenticator)
+ * too far off server time
+ * RD_AP_NYV - Kerberos time (in ticket) too
+ * far off server time
+ * RD_AP_EXP - ticket expired
+ *
+ * For the message format, see krb_mk_req().
+ *
+ * Mutual authentication is not implemented.
+ */
+
+int
+krb_rd_req(authent,service,instance,from_addr,ad,fn)
+ register KTEXT authent; /* The received message */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ long from_addr; /* Net address of originating host */
+ AUTH_DAT *ad; /* Structure to be filled in */
+ char *fn; /* Filename to get keys from */
+{
+ static KTEXT_ST ticket; /* Temp storage for ticket */
+ static KTEXT tkt = &ticket;
+ static KTEXT_ST req_id_st; /* Temp storage for authenticator */
+ register KTEXT req_id = &req_id_st;
+
+ char realm[REALM_SZ]; /* Realm of issuing kerberos */
+ static Key_schedule seskey_sched; /* Key sched for session key */
+ unsigned char skey[KKEY_SZ]; /* Session key from ticket */
+ char sname[SNAME_SZ]; /* Service name from ticket */
+ char iname[INST_SZ]; /* Instance name from ticket */
+ char r_aname[ANAME_SZ]; /* Client name from authenticator */
+ char r_inst[INST_SZ]; /* Client instance from authenticator */
+ char r_realm[REALM_SZ]; /* Client realm from authenticator */
+ unsigned int r_time_ms; /* Fine time from authenticator */
+ unsigned long r_time_sec; /* Coarse time from authenticator */
+ register char *ptr; /* For stepping through */
+ unsigned long delta_t; /* Time in authenticator - local time */
+ long tkt_age; /* Age of ticket */
+ static int swap_bytes; /* Need to swap bytes? */
+ static int mutual; /* Mutual authentication requested? */
+ static unsigned char s_kvno;/* Version number of the server's key
+ * Kerberos used to encrypt ticket */
+ int status;
+
+ if (authent->length <= 0)
+ return(RD_AP_MODIFIED);
+
+ ptr = (char *) authent->dat;
+
+ /* get msg version, type and byte order, and server key version */
+
+ /* check version */
+ if (KRB_PROT_VERSION != (unsigned int) *ptr++)
+ return(RD_AP_VERSION);
+
+ /* byte order */
+ swap_bytes = 0;
+ if ((*ptr & 1) != HOST_BYTE_ORDER)
+ swap_bytes++;
+
+ /* check msg type */
+ mutual = 0;
+ switch (*ptr++ & ~1) {
+ case AUTH_MSG_APPL_REQUEST:
+ break;
+ case AUTH_MSG_APPL_REQUEST_MUTUAL:
+ mutual++;
+ break;
+ default:
+ return(RD_AP_MSG_TYPE);
+ }
+
+#ifdef lint
+ /* XXX mutual is set but not used; why??? */
+ /* this is a crock to get lint to shut up */
+ if (mutual)
+ mutual = 0;
+#endif /* lint */
+ s_kvno = *ptr++; /* get server key version */
+ (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
+ ptr += strlen(ptr) + 1; /* skip the realm "hint" */
+
+ /*
+ * If "fn" is NULL, key info should already be set; don't
+ * bother with ticket file. Otherwise, check to see if we
+ * already have key info for the given server and key version
+ * (saved in the static st_* variables). If not, go get it
+ * from the ticket file. If "fn" is the null string, use the
+ * default ticket file.
+ */
+ if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) ||
+ strcmp(st_rlm,realm) || (st_kvno != s_kvno))) {
+ if (*fn == 0) fn = KEYFILE;
+ st_kvno = s_kvno;
+#ifndef NOENCRYPTION
+ if (read_service_key(service,instance,realm,s_kvno,fn,(char *)skey))
+ return(RD_AP_UNDEC);
+ if ((status=krb_set_key((char *)skey,0))) return(status);
+#endif
+ (void) strcpy(st_rlm,realm);
+ (void) strcpy(st_nam,service);
+ (void) strcpy(st_inst,instance);
+ }
+
+ /* Get ticket from authenticator */
+ tkt->length = (int) *ptr++;
+ if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length)
+ return(RD_AP_MODIFIED);
+ bcopy(ptr+1,(char *)(tkt->dat),tkt->length);
+
+ if (krb_ap_req_debug)
+ log("ticket->length: %d",tkt->length);
+
+#ifndef NOENCRYPTION
+ /* Decrypt and take apart ticket */
+#endif
+
+ if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm,
+ &(ad->address),ad->session, &(ad->life),
+ &(ad->time_sec),sname,iname,ky,serv_key))
+ return(RD_AP_UNDEC);
+
+ if (krb_ap_req_debug) {
+ log("Ticket Contents.");
+ log(" Aname: %s.%s",ad->pname,
+ ((int)*(ad->prealm) ? ad->prealm : "Athena"));
+ log(" Service: %s%s%s",sname,((int)*iname ? "." : ""),iname);
+ }
+
+ /* Extract the authenticator */
+ req_id->length = (int) *(ptr++);
+ if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) >
+ authent->length)
+ return(RD_AP_MODIFIED);
+ bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length);
+
+#ifndef NOENCRYPTION
+ key_sched((C_Block *)ad->session,seskey_sched);
+ pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
+ (long)req_id->length,seskey_sched,(C_Block *)ad->session,DES_DECRYPT);
+#endif /* NOENCRYPTION */
+
+#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
+
+ ptr = (char *) req_id->dat;
+ (void) strcpy(r_aname,ptr); /* Authentication name */
+ ptr += strlen(r_aname)+1;
+ check_ptr();
+ (void) strcpy(r_inst,ptr); /* Authentication instance */
+ ptr += strlen(r_inst)+1;
+ check_ptr();
+ (void) strcpy(r_realm,ptr); /* Authentication name */
+ ptr += strlen(r_realm)+1;
+ check_ptr();
+ bcopy(ptr,(char *)&ad->checksum,4); /* Checksum */
+ ptr += 4;
+ check_ptr();
+ if (swap_bytes) swap_u_long(ad->checksum);
+ r_time_ms = *(ptr++); /* Time (fine) */
+#ifdef lint
+ /* XXX r_time_ms is set but not used. why??? */
+ /* this is a crock to get lint to shut up */
+ if (r_time_ms)
+ r_time_ms = 0;
+#endif /* lint */
+ check_ptr();
+ /* assume sizeof(r_time_sec) == 4 ?? */
+ bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */
+ if (swap_bytes) swap_u_long(r_time_sec);
+
+ /* Check for authenticity of the request */
+ if (krb_ap_req_debug)
+ log("Pname: %s %s",ad->pname,r_aname);
+ if (strcmp(ad->pname,r_aname) != 0)
+ return(RD_AP_INCON);
+ if (strcmp(ad->pinst,r_inst) != 0)
+ return(RD_AP_INCON);
+ if (krb_ap_req_debug)
+ log("Realm: %s %s",ad->prealm,r_realm);
+ if ((strcmp(ad->prealm,r_realm) != 0))
+ return(RD_AP_INCON);
+
+ if (krb_ap_req_debug)
+ log("Address: %d %d",ad->address,from_addr);
+ if (from_addr && (ad->address != from_addr))
+ return(RD_AP_BADD);
+
+ (void) gettimeofday(&t_local,(struct timezone *) 0);
+ delta_t = abs((int)(t_local.tv_sec - r_time_sec));
+ if (delta_t > CLOCK_SKEW) {
+ if (krb_ap_req_debug)
+ log("Time out of range: %d - %d = %d",
+ t_local.tv_sec,r_time_sec,delta_t);
+ return(RD_AP_TIME);
+ }
+
+ /* Now check for expiration of ticket */
+
+ tkt_age = t_local.tv_sec - ad->time_sec;
+ if (krb_ap_req_debug)
+ log("Time: %d Issue Date: %d Diff: %d Life %x",
+ t_local.tv_sec,ad->time_sec,tkt_age,ad->life);
+
+ if (t_local.tv_sec < ad->time_sec) {
+ if ((ad->time_sec - t_local.tv_sec) > CLOCK_SKEW)
+ return(RD_AP_NYV);
+ }
+ else if ((t_local.tv_sec - ad->time_sec) > 5 * 60 * ad->life)
+ return(RD_AP_EXP);
+
+ /* All seems OK */
+ ad->reply.length = 0;
+
+ return(RD_AP_OK);
+}
diff --git a/eBones/lib/libkrb/rd_safe.c b/eBones/lib/libkrb/rd_safe.c
new file mode 100644
index 0000000000000..4d3e8d6735aeb
--- /dev/null
+++ b/eBones/lib/libkrb/rd_safe.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine dissects a a Kerberos 'safe msg', checking its
+ * integrity, and returning a pointer to the application data
+ * contained and its length.
+ *
+ * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
+ *
+ * Steve Miller Project Athena MIT/DEC
+ *
+ * from: rd_safe.c,v 4.12 89/01/23 15:16:16 steiner Exp $
+ * $Id: rd_safe.c,v 1.3 1995/07/18 16:39:34 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: rd_safe.c,v 1.3 1995/07/18 16:39:34 mark Exp $";
+#endif /* lint */
+#endif
+
+/* system include files */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+/* application include files */
+#include <des.h>
+#include <krb.h>
+#include <prot.h>
+#include "lsb_addr_comp.h"
+
+extern char *errmsg();
+extern int errno;
+extern int krb_debug;
+
+/* static storage */
+
+static C_Block calc_cksum[2];
+static C_Block big_cksum[2];
+static int swap_bytes;
+static struct timeval local_time;
+static u_long delta_t;
+
+/*
+ * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message.
+ * Given the message received, "in", the length of that message,
+ * "in_length", the "key" to compute the checksum with, and the
+ * network addresses of the "sender" and "receiver" of the message,
+ * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise
+ * some error code.
+ *
+ * The message data retrieved from "in" is returned in the structure
+ * "m_data". The pointer to the application data (m_data->app_data)
+ * refers back to the appropriate place in "in".
+ *
+ * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE
+ * message. The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+long krb_rd_safe(in,in_length,key,sender,receiver,m_data)
+ u_char *in; /* pointer to the msg received */
+ u_long in_length; /* length of "in" msg */
+ C_Block *key; /* encryption key for seed and ivec */
+ struct sockaddr_in *sender; /* sender's address */
+ struct sockaddr_in *receiver; /* receiver's address -- me */
+ MSG_DAT *m_data; /* where to put message information */
+{
+ register u_char *p,*q;
+ static u_long src_addr; /* Can't send structs since no
+ * guarantees on size */
+ /* Be very conservative */
+ if (sizeof(u_long) != sizeof(struct in_addr)) {
+ fprintf(stderr,"\n\
+krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
+ exit(-1);
+ }
+
+ if (gettimeofday(&local_time,(struct timezone *)0))
+ return -1;
+
+ p = in; /* beginning of message */
+ swap_bytes = 0;
+
+ if (*p++ != KRB_PROT_VERSION) return RD_AP_VERSION;
+ if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE;
+ if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++;
+
+ q = p; /* mark start of cksum stuff */
+
+ /* safely get length */
+ bcopy((char *)p,(char *)&(m_data->app_length),
+ sizeof(m_data->app_length));
+ if (swap_bytes) swap_u_long(m_data->app_length);
+ p += sizeof(m_data->app_length); /* skip over */
+
+ if (m_data->app_length + sizeof(in_length)
+ + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms)
+ + sizeof(big_cksum) + sizeof(src_addr)
+ + VERSION_SZ + MSG_TYPE_SZ > in_length)
+ return(RD_AP_MODIFIED);
+
+ m_data->app_data = p; /* we're now at the application data */
+
+ /* skip app data */
+ p += m_data->app_length;
+
+ /* safely get time_5ms */
+ bcopy((char *)p, (char *)&(m_data->time_5ms),
+ sizeof(m_data->time_5ms));
+
+ /* don't need to swap-- one byte for now */
+ p += sizeof(m_data->time_5ms);
+
+ /* safely get src address */
+ bcopy((char *)p,(char *)&src_addr,sizeof(src_addr));
+
+ /* don't swap, net order always */
+ p += sizeof(src_addr);
+
+ if (src_addr != (u_long) sender->sin_addr.s_addr)
+ return RD_AP_MODIFIED;
+
+ /* safely get time_sec */
+ bcopy((char *)p, (char *)&(m_data->time_sec),
+ sizeof(m_data->time_sec));
+ if (swap_bytes)
+ swap_u_long(m_data->time_sec);
+ p += sizeof(m_data->time_sec);
+
+ /* check direction bit is the sign bit */
+ /* For compatibility with broken old code, compares are done in VAX
+ byte order (LSBFIRST) */
+ if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+ else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
+ receiver->sin_addr.s_addr)==0)
+ if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
+ /* src < recv */
+ m_data->time_sec = - m_data->time_sec;
+
+ /*
+ * All that for one tiny bit! Heaven help those that talk to
+ * themselves.
+ */
+
+ /* check the time integrity of the msg */
+ delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec));
+ if (delta_t > CLOCK_SKEW) return RD_AP_TIME;
+
+ /*
+ * caller must check timestamps for proper order and replays, since
+ * server might have multiple clients each with its own timestamps
+ * and we don't assume tightly synchronized clocks.
+ */
+
+ bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum));
+ if (swap_bytes) swap_u_16(big_cksum);
+
+#ifdef NOENCRYPTION
+ bzero(calc_cksum, sizeof(calc_cksum));
+#else
+ quad_cksum((C_Block *)q,calc_cksum,p-q,2,key);
+#endif
+
+ if (krb_debug)
+ printf("\ncalc_cksum = %lu, received cksum = %lu",
+ (long) calc_cksum[0], (long) big_cksum[0]);
+ if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum)))
+ return(RD_AP_MODIFIED);
+
+ return(RD_AP_OK); /* OK == 0 */
+}
diff --git a/eBones/lib/libkrb/read_service_key.c b/eBones/lib/libkrb/read_service_key.c
new file mode 100644
index 0000000000000..6064292d96cfd
--- /dev/null
+++ b/eBones/lib/libkrb/read_service_key.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: _service_key.c,v 4.10 90/03/10 19:06:56 jon Exp $
+ * $Id: read_service_key.c,v 1.3 1995/07/18 16:39:36 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: read_service_key.c,v 1.3 1995/07/18 16:39:36 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+
+/*
+ * The private keys for servers on a given host are stored in a
+ * "srvtab" file (typically "/etc/srvtab"). This routine extracts
+ * a given server's key from the file.
+ *
+ * read_service_key() takes the server's name ("service"), "instance",
+ * and "realm" and a key version number "kvno", and looks in the given
+ * "file" for the corresponding entry, and if found, returns the entry's
+ * key field in "key".
+ *
+ * If "instance" contains the string "*", then it will match
+ * any instance, and the chosen instance will be copied to that
+ * string. For this reason it is important that the there is enough
+ * space beyond the "*" to receive the entry.
+ *
+ * If "kvno" is 0, it is treated as a wild card and the first
+ * matching entry regardless of the "vno" field is returned.
+ *
+ * This routine returns KSUCCESS on success, otherwise KFAILURE.
+ *
+ * The format of each "srvtab" entry is as follows:
+ *
+ * Size Variable Field in file
+ * ---- -------- -------------
+ * string serv server name
+ * string inst server instance
+ * string realm server realm
+ * 1 byte vno server key version #
+ * 8 bytes key server's key
+ * ... ... ...
+ */
+
+
+/*ARGSUSED */
+int
+read_service_key(service,instance,realm,kvno,file,key)
+ char *service; /* Service Name */
+ char *instance; /* Instance name or "*" */
+ char *realm; /* Realm */
+ int kvno; /* Key version number */
+ char *file; /* Filename */
+ char *key; /* Pointer to key to be filled in */
+{
+ char serv[SNAME_SZ];
+ char inst[INST_SZ];
+ char rlm[REALM_SZ];
+ unsigned char vno; /* Key version number */
+ int wcard;
+
+ int stab, open();
+
+ if ((stab = open(file, 0, 0)) < NULL)
+ return(KFAILURE);
+
+ wcard = (instance[0] == '*') && (instance[1] == '\0');
+
+ while(getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */
+ (void) getst(stab,inst,INST_SZ); /* Instance */
+ (void) getst(stab,rlm,REALM_SZ); /* Realm */
+ /* Vers number */
+ if (read(stab,(char *)&vno,1) != 1) {
+ close(stab);
+ return(KFAILURE);
+ }
+ /* Key */
+ if (read(stab,key,8) != 8) {
+ close(stab);
+ return(KFAILURE);
+ }
+ /* Is this the right service */
+ if (strcmp(serv,service))
+ continue;
+ /* How about instance */
+ if (!wcard && strcmp(inst,instance))
+ continue;
+ if (wcard)
+ (void) strncpy(instance,inst,INST_SZ);
+ /* Is this the right realm */
+#ifdef ATHENA_COMPAT
+ /* XXX For backward compatibility: if keyfile says "Athena"
+ and caller wants "ATHENA.MIT.EDU", call it a match */
+ if (strcmp(rlm,realm) &&
+ (strcmp(rlm,"Athena") ||
+ strcmp(realm,"ATHENA.MIT.EDU")))
+ continue;
+#else /* ! ATHENA_COMPAT */
+ if (strcmp(rlm,realm))
+ continue;
+#endif /* ATHENA_COMPAT */
+
+ /* How about the key version number */
+ if (kvno && kvno != (int) vno)
+ continue;
+
+ (void) close(stab);
+ return(KSUCCESS);
+ }
+
+ /* Can't find the requested service */
+ (void) close(stab);
+ return(KFAILURE);
+}
diff --git a/eBones/lib/libkrb/recvauth.c b/eBones/lib/libkrb/recvauth.c
new file mode 100644
index 0000000000000..45d68ee750799
--- /dev/null
+++ b/eBones/lib/libkrb/recvauth.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: recvauth.c,v 4.4 90/03/10 19:03:08 jon Exp $";
+ * $Id: recvauth.c,v 1.3 1995/07/18 16:39:38 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: recvauth.c,v 1.3 1995/07/18 16:39:38 mark Exp $";
+#endif lint
+#endif
+
+#include <krb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <strings.h>
+
+
+#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
+ chars */
+
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_sendauth.c
+ * be sure to support old versions of krb_sendauth!
+ */
+
+extern int errno;
+
+/*
+ * krb_recvauth() reads (and optionally responds to) a message sent
+ * using krb_sendauth(). The "options" argument is a bit-field of
+ * selected options (see "sendauth.c" for options description).
+ * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL
+ * (mutual authentication requested). The "fd" argument supplies
+ * a file descriptor to read from (and write to, if mutual authenti-
+ * cation is requested).
+ *
+ * Part of the received message will be a Kerberos ticket sent by the
+ * client; this is read into the "ticket" argument. The "service" and
+ * "instance" arguments supply the server's Kerberos name. If the
+ * "instance" argument is the string "*", it is treated as a wild card
+ * and filled in during the krb_rd_req() call (see read_service_key()).
+ *
+ * The "faddr" and "laddr" give the sending (client) and receiving
+ * (local server) network addresses. ("laddr" may be left NULL unless
+ * mutual authentication is requested, in which case it must be set.)
+ *
+ * The authentication information extracted from the message is returned
+ * in "kdata". The "filename" argument indicates the file where the
+ * server's key can be found. (It is passed on to krb_rd_req().) If
+ * left null, the default "/etc/srvtab" will be used.
+ *
+ * If mutual authentication is requested, the session key schedule must
+ * be computed in order to reply; this schedule is returned in the
+ * "schedule" argument. A string containing the application version
+ * number from the received message is returned in "version", which
+ * should be large enough to hold a KRB_SENDAUTH_VLEN-character string.
+ *
+ * See krb_sendauth() for the format of the received client message.
+ *
+ * This routine supports another client format, for backward
+ * compatibility, consisting of:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * string tmp_buf, tkt_len length of ticket, in
+ * ascii
+ *
+ * char ' ' (space char) separator
+ *
+ * tkt_len ticket->dat the ticket
+ *
+ * This old-style version does not support mutual authentication.
+ *
+ * krb_recvauth() first reads the protocol version string from the
+ * given file descriptor. If it doesn't match the current protocol
+ * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In
+ * that case, the string of characters up to the first space is read
+ * and interpreted as the ticket length, then the ticket is read.
+ *
+ * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth()
+ * next reads the application protocol version string. Then the
+ * ticket length and ticket itself are read.
+ *
+ * The ticket is decrypted and checked by the call to krb_rd_req().
+ * If no mutual authentication is required, the result of the
+ * krb_rd_req() call is retured by this routine. If mutual authenti-
+ * cation is required, a message in the following format is returned
+ * on "fd":
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * 4 bytes tkt_len length of ticket or -1
+ * if error occurred
+ *
+ * priv_len tmp_buf "private" message created
+ * by krb_mk_priv() which
+ * contains the incremented
+ * checksum sent by the client
+ * encrypted in the session
+ * key. (This field is not
+ * present in case of error.)
+ *
+ * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some
+ * other error code is returned.
+ */
+
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* max */
+
+int
+krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
+ filename, schedule, version)
+long options; /* bit-pattern of options */
+int fd; /* file descr. to read from */
+KTEXT ticket; /* storage for client's ticket */
+char *service; /* service expected */
+char *instance; /* inst expected (may be filled in) */
+struct sockaddr_in *faddr; /* address of foreign host on fd */
+struct sockaddr_in *laddr; /* local address */
+AUTH_DAT *kdata; /* kerberos data (returned) */
+char *filename; /* name of file with service keys */
+Key_schedule schedule; /* key schedule (return) */
+char *version; /* version string (filled in) */
+{
+
+ int i, cc, old_vers = 0;
+ char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */
+ char *cp;
+ int rem;
+ long tkt_len, priv_len;
+ u_long cksum;
+ u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)];
+
+ /* read the protocol version number */
+ if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) !=
+ KRB_SENDAUTH_VLEN)
+ return(errno);
+ krb_vers[KRB_SENDAUTH_VLEN] = '\0';
+
+ /* check version string */
+ if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) {
+ /* Assume the old version of sendkerberosdata: send ascii
+ length, ' ', and ticket. */
+ if (options & KOPT_DO_MUTUAL)
+ return(KFAILURE); /* XXX can't do old style with mutual auth */
+ old_vers = 1;
+
+ /* copy what we have read into tmp_buf */
+ (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN);
+
+ /* search for space, and make it a null */
+ for (i = 0; i < KRB_SENDAUTH_VLEN; i++)
+ if (tmp_buf[i]== ' ') {
+ tmp_buf[i] = '\0';
+ /* point cp to the beginning of the real ticket */
+ cp = (char *) &tmp_buf[i+1];
+ break;
+ }
+
+ if (i == KRB_SENDAUTH_VLEN)
+ /* didn't find the space, keep reading to find it */
+ for (; i<20; i++) {
+ if (read(fd, (char *)&tmp_buf[i], 1) != 1) {
+ return(KFAILURE);
+ }
+ if (tmp_buf[i] == ' ') {
+ tmp_buf[i] = '\0';
+ /* point cp to the beginning of the real ticket */
+ cp = (char *) &tmp_buf[i+1];
+ break;
+ }
+ }
+
+ tkt_len = (long) atoi((char *) tmp_buf);
+
+ /* sanity check the length */
+ if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN))
+ return(KFAILURE);
+
+ if (i < KRB_SENDAUTH_VLEN) {
+ /* since we already got the space, and part of the ticket,
+ we read fewer bytes to get the rest of the ticket */
+ if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
+ (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ return(errno);
+ } else {
+ if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
+ (int) tkt_len)
+ return(errno);
+ }
+ ticket->length = tkt_len;
+ /* copy the ticket into the struct */
+ (void) bcopy(cp, (char *) ticket->dat, ticket->length);
+
+ } else {
+ /* read the application version string */
+ if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) !=
+ KRB_SENDAUTH_VLEN)
+ return(errno);
+ version[KRB_SENDAUTH_VLEN] = '\0';
+
+ /* get the length of the ticket */
+ if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) !=
+ sizeof(tkt_len))
+ return(errno);
+
+ /* sanity check */
+ ticket->length = ntohl((unsigned long)tkt_len);
+ if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) {
+ if (options & KOPT_DO_MUTUAL) {
+ rem = KFAILURE;
+ goto mutual_fail;
+ } else
+ return(KFAILURE); /* XXX there may still be junk on the fd? */
+ }
+
+ /* read the ticket */
+ if (krb_net_read(fd, (char *) ticket->dat, ticket->length)
+ != ticket->length)
+ return(errno);
+ }
+ /*
+ * now have the ticket. decrypt it to get the authenticated
+ * data.
+ */
+ rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr,
+ kdata,filename);
+
+ if (old_vers) return(rem); /* XXX can't do mutual with old client */
+
+ /* if we are doing mutual auth, compose a response */
+ if (options & KOPT_DO_MUTUAL) {
+ if (rem != KSUCCESS)
+ /* the krb_rd_req failed */
+ goto mutual_fail;
+
+ /* add one to the (formerly) sealed checksum, and re-seal it
+ for return to the client */
+ cksum = kdata->checksum + 1;
+ cksum = htonl(cksum);
+#ifndef NOENCRYPTION
+ key_sched((C_Block *)kdata->session,schedule);
+#endif
+ priv_len = krb_mk_priv((unsigned char *)&cksum,
+ tmp_buf,
+ (unsigned long) sizeof(cksum),
+ schedule,
+ kdata->session,
+ laddr,
+ faddr);
+ if (priv_len < 0) {
+ /* re-sealing failed; notify the client */
+ rem = KFAILURE; /* XXX */
+mutual_fail:
+ priv_len = -1;
+ tkt_len = htonl((unsigned long) priv_len);
+ /* a length of -1 is interpreted as an authentication
+ failure by the client */
+ if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+ != sizeof(tkt_len))
+ return(cc);
+ return(rem);
+ } else {
+ /* re-sealing succeeded, send the private message */
+ tkt_len = htonl((unsigned long)priv_len);
+ if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+ != sizeof(tkt_len))
+ return(cc);
+ if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len))
+ != (int) priv_len)
+ return(cc);
+ }
+ }
+ return(rem);
+}
diff --git a/eBones/lib/libkrb/save_credentials.c b/eBones/lib/libkrb/save_credentials.c
new file mode 100644
index 0000000000000..268bb77a1c4da
--- /dev/null
+++ b/eBones/lib/libkrb/save_credentials.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: save_credentials.c,v 4.9 89/05/31 17:45:43 jtkohl Exp $
+ * $Id: save_credentials.c,v 1.3 1995/07/18 16:39:40 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: save_credentials.c,v 1.3 1995/07/18 16:39:40 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdio.h>
+#include <krb.h>
+
+/*
+ * This routine takes a ticket and associated info and calls
+ * tf_save_cred() to store them in the ticket cache. The peer
+ * routine for extracting a ticket and associated info from the
+ * ticket cache is krb_get_cred(). When changes are made to
+ * this routine, the corresponding changes should be made
+ * in krb_get_cred() as well.
+ *
+ * Returns KSUCCESS if all goes well, otherwise an error returned
+ * by the tf_init() or tf_save_cred() routines.
+ */
+
+int
+save_credentials(service, instance, realm, session, lifetime, kvno,
+ ticket, issue_date)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT ticket; /* The ticket itself */
+ long issue_date; /* The issue time */
+{
+ int tf_status; /* return values of the tf_util calls */
+
+ /* Open and lock the ticket file for writing */
+ if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS)
+ return(tf_status);
+
+ /* Save credentials by appending to the ticket file */
+ tf_status = tf_save_cred(service, instance, realm, session,
+ lifetime, kvno, ticket, issue_date);
+ (void) tf_close();
+ return (tf_status);
+}
diff --git a/eBones/lib/libkrb/send_to_kdc.c b/eBones/lib/libkrb/send_to_kdc.c
new file mode 100644
index 0000000000000..eae06d575ac8b
--- /dev/null
+++ b/eBones/lib/libkrb/send_to_kdc.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: send_to_kdc.c,v 4.20 90/01/02 13:40:37 jtkohl Exp $
+ * $Id: send_to_kdc.c,v 1.7 1995/09/07 21:38:31 markm Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_send_to_kdc_c[] =
+"$Id: send_to_kdc.c,v 1.1 1994/03/21 17:35:39 piero Exp ";
+#endif /* lint */
+#endif
+
+#include <krb.h>
+#include <prot.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef lint
+#include <sys/uio.h> /* struct iovec to make lint happy */
+#endif /* lint */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <strings.h>
+
+#define S_AD_SZ sizeof(struct sockaddr_in)
+
+extern int errno;
+extern int krb_debug;
+
+extern char *malloc(), *calloc(), *realloc();
+
+int krb_udp_port = 0;
+
+/* CLIENT_KRB_TIMEOUT indicates the time to wait before
+ * retrying a server. It's defined in "krb.h".
+ */
+static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0};
+static char *prog = "send_to_kdc";
+static send_recv();
+
+/*
+ * This file contains two routines, send_to_kdc() and send_recv().
+ * send_recv() is a static routine used by send_to_kdc().
+ */
+
+/*
+ * send_to_kdc() sends a message to the Kerberos authentication
+ * server(s) in the given realm and returns the reply message.
+ * The "pkt" argument points to the message to be sent to Kerberos;
+ * the "rpkt" argument will be filled in with Kerberos' reply.
+ * The "realm" argument indicates the realm of the Kerberos server(s)
+ * to transact with. If the realm is null, the local realm is used.
+ *
+ * If more than one Kerberos server is known for a given realm,
+ * different servers will be queried until one of them replies.
+ * Several attempts (retries) are made for each server before
+ * giving up entirely.
+ *
+ * If an answer was received from a Kerberos host, KSUCCESS is
+ * returned. The following errors can be returned:
+ *
+ * SKDC_CANT - can't get local realm
+ * - can't find "kerberos" in /etc/services database
+ * - can't open socket
+ * - can't bind socket
+ * - all ports in use
+ * - couldn't find any Kerberos host
+ *
+ * SKDC_RETRY - couldn't get an answer from any Kerberos server,
+ * after several retries
+ */
+
+int
+send_to_kdc(pkt,rpkt,realm)
+ KTEXT pkt;
+ KTEXT rpkt;
+ char *realm;
+{
+ int i, f;
+ int no_host; /* was a kerberos host found? */
+ int retry;
+ int n_hosts;
+ int retval;
+ int addr_count;
+ struct sockaddr_in to;
+ struct hostent *host, *hostlist;
+ char krbhst[MAX_HSTNM];
+ char lrealm[REALM_SZ];
+
+ /*
+ * If "realm" is non-null, use that, otherwise get the
+ * local realm.
+ */
+ if (realm)
+ (void) strcpy(lrealm, realm);
+ else
+ if (krb_get_lrealm(lrealm,1)) {
+ if (krb_debug)
+ fprintf(stderr, "%s: can't get local realm\n", prog);
+ return(SKDC_CANT);
+ }
+ if (krb_debug)
+ printf("lrealm is %s\n", lrealm);
+ if (krb_udp_port == 0) {
+ register struct servent *sp;
+ if ((sp = getservbyname("kerberos","udp")) == 0) {
+ if (krb_debug)
+ fprintf(stderr, "%s: Can't get kerberos/udp service\n",
+ prog);
+ return(SKDC_CANT);
+ }
+ krb_udp_port = sp->s_port;
+ if (krb_debug)
+ printf("krb_udp_port is %d\n", krb_udp_port);
+ }
+ bzero((char *)&to, S_AD_SZ);
+ hostlist = (struct hostent *) malloc(sizeof(struct hostent));
+ if (!hostlist)
+ return (/*errno */SKDC_CANT);
+ if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ if (krb_debug)
+ fprintf(stderr,"%s: Can't open socket\n", prog);
+ return(SKDC_CANT);
+ }
+ /* from now on, exit through rtn label for cleanup */
+
+ no_host = 1;
+ /* get an initial allocation */
+ n_hosts = 0;
+ for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) {
+ if (krb_debug) {
+ printf("Getting host entry for %s...",krbhst);
+ (void) fflush(stdout);
+ }
+ host = gethostbyname(krbhst);
+ if (krb_debug) {
+ printf("%s.\n",
+ host ? "Got it" : "Didn't get it");
+ (void) fflush(stdout);
+ }
+ if (!host)
+ continue;
+ no_host = 0; /* found at least one */
+ n_hosts++;
+ /*
+ * Preserve host network addresses to check against later
+ */
+ hostlist = (struct hostent *)
+ realloc((char *)hostlist,
+ (unsigned)
+ sizeof(struct hostent)*(n_hosts+1));
+ if (!hostlist) {
+ fprintf(stderr, "Could not grow hostlist\n");
+ return /*errno */SKDC_CANT;
+ }
+ bcopy((char *)host, (char *)&hostlist[n_hosts-1],
+ sizeof(struct hostent));
+ host = &hostlist[n_hosts-1];
+/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2
+ (or worse) only return one address ... */
+#if (defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ {
+ char *cp = malloc((unsigned)host->h_length);
+ if (!cp) {
+ retval = /*errno */SKDC_CANT;
+ goto rtn;
+ }
+ bcopy((char *)host->h_addr, cp, host->h_length);
+ host->h_addr = cp;
+ }
+#else /* !(ULTRIX022 || (SunOS < 40)) */
+ /*
+ * Make a copy of the entire h_addr_list.
+ */
+ {
+ char *addr;
+ char **old_addr_list;
+ addr_count = 0;
+ old_addr_list = host->h_addr_list;
+ while(old_addr_list[addr_count++])
+ ;
+ host->h_addr_list = (char **)malloc(addr_count+1 * sizeof(char *));
+ if (host->h_addr_list == NULL) {
+ fprintf(stderr, "Could not allocate host->h_addr_list\n");
+ retval = SKDC_CANT;
+ goto rtn;
+ }
+ if (krb_debug) {
+ printf("h_length = %d\n", host->h_length);
+ printf("Number of addresses = %d\n", addr_count);
+ }
+ for (addr_count = 0; old_addr_list[addr_count]; addr_count++) {
+ if (krb_debug)
+ printf ("addr[%d] = %s\n", addr_count,
+ inet_ntoa(*(struct in_addr *)old_addr_list[addr_count]));
+ addr = (char *)malloc(host->h_length);
+ if (addr == NULL) {
+ fprintf(stderr, "Could not allocate address\n");
+ retval = SKDC_CANT;
+ goto rtn;
+ }
+ bcopy(old_addr_list[addr_count], addr, host->h_length);
+ host->h_addr_list[addr_count] = addr;
+ }
+ host->h_addr_list[addr_count] = NULL;
+ }
+#endif /* !(ULTRIX022 || (SunOS < 40)) */
+
+ bzero((char *)&hostlist[n_hosts],
+ sizeof(struct hostent));
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr, (char *)&to.sin_addr,
+ host->h_length);
+ to.sin_port = krb_udp_port;
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+ if (krb_debug) {
+ printf("Timeout, error, or wrong descriptor\n");
+ (void) fflush(stdout);
+ }
+ }
+ if (no_host) {
+ if (krb_debug)
+ fprintf(stderr, "%s: can't find any Kerberos host.\n", prog);
+ retval = SKDC_CANT;
+ goto rtn;
+ }
+ /*
+ * retry each host in sequence. Some addresses may be unreachable
+ * from where we are, so loop through them as well.
+ */
+ for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) {
+ for (host = hostlist; host->h_name != (char *)NULL; host++) {
+#if (defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr_list[addr_count], (char *)&to.sin_addr,
+ host->h_length);
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+#else /* !(ULTRIX022 || (SunOS < 40)) */
+ for (addr_count = 0; host->h_addr_list[addr_count]; addr_count++) {
+ to.sin_family = host->h_addrtype;
+ bcopy(host->h_addr_list[addr_count], (char *)&to.sin_addr,
+ host->h_length);
+ if (send_recv(pkt, rpkt, f, &to, hostlist)) {
+ retval = KSUCCESS;
+ goto rtn;
+ }
+ }
+#endif /* !(ULTRIX022 || (SunOS < 40)) */
+ }
+ }
+ retval = SKDC_RETRY;
+rtn:
+ (void) close(f);
+ if (hostlist) {
+ if(!no_host) {
+ register struct hostent *hp;
+ for (hp = hostlist; hp->h_name; hp++)
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ if (hp->h_addr_list) {
+#endif /* ULTRIX022 || SunOS */
+ if (hp->h_addr)
+ free(hp->h_addr);
+#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ free((char *)hp->h_addr_list);
+ }
+#endif /* ULTRIX022 || SunOS */
+ }
+ free((char *)hostlist);
+ }
+ return(retval);
+}
+
+/*
+ * try to send out and receive message.
+ * return 1 on success, 0 on failure
+ */
+
+static int
+send_recv(pkt,rpkt,f,_to,addrs)
+ KTEXT pkt;
+ KTEXT rpkt;
+ int f;
+ struct sockaddr_in *_to;
+ struct hostent *addrs;
+{
+ fd_set readfds;
+ register struct hostent *hp;
+ struct sockaddr_in from;
+ int sin_size;
+ int numsent;
+ int addr_count;
+
+ if (krb_debug) {
+ if (_to->sin_family == AF_INET)
+ printf("Sending message to %s...",
+ inet_ntoa(_to->sin_addr));
+ else
+ printf("Sending message...");
+ (void) fflush(stdout);
+ }
+ if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0,
+ (struct sockaddr *)_to,
+ S_AD_SZ)) != pkt->length) {
+ if (krb_debug)
+ printf("sent only %d/%d\n",numsent, pkt->length);
+ return 0;
+ }
+ if (krb_debug) {
+ printf("Sent\nWaiting for reply...");
+ (void) fflush(stdout);
+ }
+ FD_ZERO(&readfds);
+ FD_SET(f, &readfds);
+ errno = 0;
+ /* select - either recv is ready, or timeout */
+ /* see if timeout or error or wrong descriptor */
+ if (select(f + 1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1
+ || !FD_ISSET(f, &readfds)) {
+ if (krb_debug) {
+ fprintf(stderr, "select failed: readfds=%x",
+ readfds);
+ perror("");
+ }
+ return 0;
+ }
+ sin_size = sizeof(from);
+ if (recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0,
+ (struct sockaddr *)&from, &sin_size)
+ < 0) {
+ if (krb_debug)
+ perror("recvfrom");
+ return 0;
+ }
+ if (krb_debug) {
+ printf("received packet from %s\n", inet_ntoa(from.sin_addr));
+ fflush(stdout);
+ }
+/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2
+ (or worse) only return one address ... */
+#if (defined(ULTRIX022) || (defined(SunOS) && SunOS < 40))
+ for (hp = addrs; hp->h_name != (char *)NULL; hp++) {
+ if (!bcmp(hp->h_addr, (char *)&from.sin_addr.s_addr,
+ hp->h_length)) {
+ if (krb_debug) {
+ printf("Received it\n");
+ (void) fflush(stdout);
+ }
+ return 1;
+ }
+ if (krb_debug)
+ fprintf(stderr, "packet not from %s\n",
+ inet_ntoa(*(struct in_addr *)hp->h_addr));
+ }
+#else /* !(ULTRIX022 || (SunOS < 40)) */
+ for (hp = addrs; hp->h_name != (char *)NULL; hp++) {
+ for (addr_count = 0; hp->h_addr_list[addr_count]; addr_count++) {
+ if (!bcmp(hp->h_addr_list[addr_count],
+ (char *)&from.sin_addr.s_addr, hp->h_length)) {
+ if (krb_debug) {
+ printf("Received it\n");
+ (void) fflush(stdout);
+ }
+ return 1;
+ }
+ if (krb_debug)
+ fprintf(stderr, "packet not from %s\n",
+ inet_ntoa(*(struct in_addr *)hp->h_addr_list[addr_count]));
+ }
+ }
+#endif /* !(ULTRIX022 || (SunOS < 40)) */
+ if (krb_debug)
+ fprintf(stderr, "%s: received packet from wrong host! (%ls)\n",
+ "send_to_kdc(send_rcv)", inet_ntoa(from.sin_addr));
+ return 0;
+}
diff --git a/eBones/lib/libkrb/sendauth.c b/eBones/lib/libkrb/sendauth.c
new file mode 100644
index 0000000000000..a1d79e772bc06
--- /dev/null
+++ b/eBones/lib/libkrb/sendauth.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: sendauth.c,v 4.6 90/03/10 23:18:28 jon Exp $
+ * $Id: sendauth.c,v 1.3 1995/07/18 16:39:44 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: sendauth.c,v 1.3 1995/07/18 16:39:44 mark Exp $";
+#endif lint
+#endif
+
+#include <krb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */
+/*
+ * If the protocol changes, you will need to change the version string
+ * and make appropriate changes in krb_recvauth.c
+ */
+
+extern int errno;
+
+extern char *krb_get_phost();
+
+/*
+ * This file contains two routines: krb_sendauth() and krb_sendsrv().
+ *
+ * krb_sendauth() transmits a ticket over a file descriptor for a
+ * desired service, instance, and realm, doing mutual authentication
+ * with the server if desired.
+ *
+ * krb_sendsvc() sends a service name to a remote knetd server.
+ */
+
+/*
+ * The first argument to krb_sendauth() contains a bitfield of
+ * options (the options are defined in "krb.h"):
+ *
+ * KOPT_DONT_CANON Don't canonicalize instance as a hostname.
+ * (If this option is not chosen, krb_get_phost()
+ * is called to canonicalize it.)
+ *
+ * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos.
+ * A ticket must be supplied in the "ticket"
+ * argument.
+ * (If this option is not chosen, and there
+ * is no ticket for the given server in the
+ * ticket cache, one will be fetched using
+ * krb_mk_req() and returned in "ticket".)
+ *
+ * KOPT_DO_MUTUAL Do mutual authentication, requiring that the
+ * receiving server return the checksum+1 encrypted
+ * in the session key. The mutual authentication
+ * is done using krb_mk_priv() on the other side
+ * (see "recvauth.c") and krb_rd_priv() on this
+ * side.
+ *
+ * The "fd" argument is a file descriptor to write to the remote
+ * server on. The "ticket" argument is used to store the new ticket
+ * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is
+ * chosen, the ticket must be supplied in the "ticket" argument.
+ * The "service", "inst", and "realm" arguments identify the ticket.
+ * If "realm" is null, the local realm is used.
+ *
+ * The following arguments are only needed if the KOPT_DO_MUTUAL option
+ * is chosen:
+ *
+ * The "checksum" argument is a number that the server will add 1 to
+ * to authenticate itself back to the client; the "msg_data" argument
+ * holds the returned mutual-authentication message from the server
+ * (i.e., the checksum+1); the "cred" structure is used to hold the
+ * session key of the server, extracted from the ticket file, for use
+ * in decrypting the mutual authentication message from the server;
+ * and "schedule" holds the key schedule for that decryption. The
+ * the local and server addresses are given in "laddr" and "faddr".
+ *
+ * The application protocol version number (of up to KRB_SENDAUTH_VLEN
+ * characters) is passed in "version".
+ *
+ * If all goes well, KSUCCESS is returned, otherwise some error code.
+ *
+ * The format of the message sent to the server is:
+ *
+ * Size Variable Field
+ * ---- -------- -----
+ *
+ * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol
+ * bytes version number
+ *
+ * KRB_SENDAUTH_VLEN version application protocol
+ * bytes version number
+ *
+ * 4 bytes ticket->length length of ticket
+ *
+ * ticket->length ticket->dat ticket itself
+ */
+
+/*
+ * XXX: Note that krb_rd_priv() is coded in such a way that
+ * "msg_data->app_data" will be pointing into "priv_buf", which
+ * will disappear when krb_sendauth() returns.
+ */
+
+int
+krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
+ msg_data, cred, schedule, laddr, faddr, version)
+long options; /* bit-pattern of options */
+int fd; /* file descriptor to write onto */
+KTEXT ticket; /* where to put ticket (return); or
+ * supplied in case of KOPT_DONT_MK_REQ */
+char *service, *inst, *realm; /* service name, instance, realm */
+u_long checksum; /* checksum to include in request */
+MSG_DAT *msg_data; /* mutual auth MSG_DAT (return) */
+CREDENTIALS *cred; /* credentials (return) */
+Key_schedule schedule; /* key schedule (return) */
+struct sockaddr_in *laddr; /* local address */
+struct sockaddr_in *faddr; /* address of foreign host on fd */
+char *version; /* version string */
+{
+ int rem, i, cc;
+ char srv_inst[INST_SZ];
+ char krb_realm[REALM_SZ];
+ char buf[BUFSIZ];
+ long tkt_len;
+ u_char priv_buf[1024];
+ u_long cksum;
+
+ rem=KSUCCESS;
+
+ /* get current realm if not passed in */
+ if (!realm) {
+ rem = krb_get_lrealm(krb_realm,1);
+ if (rem != KSUCCESS)
+ return(rem);
+ realm = krb_realm;
+ }
+
+ /* copy instance into local storage, canonicalizing if desired */
+ if (options & KOPT_DONT_CANON)
+ (void) strncpy(srv_inst, inst, INST_SZ);
+ else
+ (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ);
+
+ /* get the ticket if desired */
+ if (!(options & KOPT_DONT_MK_REQ)) {
+ rem = krb_mk_req(ticket, service, srv_inst, realm, checksum);
+ if (rem != KSUCCESS)
+ return(rem);
+ }
+
+#ifdef ATHENA_COMPAT
+ /* this is only for compatibility with old servers */
+ if (options & KOPT_DO_OLDSTYLE) {
+ (void) sprintf(buf,"%d ",ticket->length);
+ (void) write(fd, buf, strlen(buf));
+ (void) write(fd, (char *) ticket->dat, ticket->length);
+ return(rem);
+ }
+#endif ATHENA_COMPAT
+ /* if mutual auth, get credentials so we have service session
+ keys for decryption below */
+ if (options & KOPT_DO_MUTUAL)
+ if ((cc = krb_get_cred(service, srv_inst, realm, cred)))
+ return(cc);
+
+ /* zero the buffer */
+ (void) bzero(buf, BUFSIZ);
+
+ /* insert version strings */
+ (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
+ (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN);
+
+ /* increment past vers strings */
+ i = 2*KRB_SENDAUTH_VLEN;
+
+ /* put ticket length into buffer */
+ tkt_len = htonl((unsigned long) ticket->length);
+ (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len));
+ i += sizeof(tkt_len);
+
+ /* put ticket into buffer */
+ (void) bcopy((char *) ticket->dat, buf+i, ticket->length);
+ i += ticket->length;
+
+ /* write the request to the server */
+ if ((cc = krb_net_write(fd, buf, i)) != i)
+ return(cc);
+
+ /* mutual authentication, if desired */
+ if (options & KOPT_DO_MUTUAL) {
+ /* get the length of the reply */
+ if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) !=
+ sizeof(tkt_len))
+ return(errno);
+ tkt_len = ntohl((unsigned long)tkt_len);
+
+ /* if the length is negative, the server failed to recognize us. */
+ if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf)))
+ return(KFAILURE); /* XXX */
+ /* read the reply... */
+ if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len)
+ return(errno);
+
+ /* ...and decrypt it */
+#ifndef NOENCRYPTION
+ key_sched((C_Block *)cred->session,schedule);
+#endif
+ if ((cc = krb_rd_priv(priv_buf,(unsigned long) tkt_len, schedule,
+ cred->session, faddr, laddr, msg_data)))
+ return(cc);
+
+ /* fetch the (modified) checksum */
+ (void) bcopy((char *)msg_data->app_data, (char *)&cksum,
+ sizeof(cksum));
+ cksum = ntohl(cksum);
+
+ /* if it doesn't match, fail */
+ if (cksum != checksum + 1)
+ return(KFAILURE); /* XXX */
+ }
+ return(KSUCCESS);
+}
+
+#ifdef ATHENA_COMPAT
+/*
+ * krb_sendsvc
+ */
+
+int
+krb_sendsvc(fd, service)
+int fd;
+char *service;
+{
+ /* write the service name length and then the service name to
+ the fd */
+ long serv_length;
+ int cc;
+
+ serv_length = htonl((unsigned long)strlen(service));
+ if ((cc = krb_net_write(fd, (char *) &serv_length,
+ sizeof(serv_length)))
+ != sizeof(serv_length))
+ return(cc);
+ if ((cc = krb_net_write(fd, service, strlen(service)))
+ != strlen(service))
+ return(cc);
+ return(KSUCCESS);
+}
+#endif ATHENA_COMPAT
diff --git a/eBones/lib/libkrb/stime.c b/eBones/lib/libkrb/stime.c
new file mode 100644
index 0000000000000..2da246319eb73
--- /dev/null
+++ b/eBones/lib/libkrb/stime.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: stime.c,v 4.5 88/11/15 16:58:05 jtkohl Exp $
+ * $Id: stime.c,v 1.3 1995/07/18 16:39:46 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: stime.c,v 1.3 1995/07/18 16:39:46 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <sys/time.h>
+#include <stdio.h> /* for sprintf() */
+
+/*
+ * Given a pointer to a long containing the number of seconds
+ * since the beginning of time (midnight 1 Jan 1970 GMT), return
+ * a string containing the local time in the form:
+ *
+ * "25-Jan-88 10:17:56"
+ */
+
+char *
+stime(t)
+ long *t;
+{
+ static char st_data[40];
+ static char *st = st_data;
+ struct tm *tm;
+ char *month_sname();
+
+ tm = localtime(t);
+ (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday,
+ month_sname(tm->tm_mon + 1),tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ return st;
+}
diff --git a/eBones/lib/libkrb/tf_shm.c b/eBones/lib/libkrb/tf_shm.c
new file mode 100644
index 0000000000000..31894cb83983a
--- /dev/null
+++ b/eBones/lib/libkrb/tf_shm.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Shared memory segment functions for session keys. Derived from code
+ * contributed by Dan Kolkowitz (kolk@jessica.stanford.edu).
+ *
+ * from: tf_shm.c,v 4.2 89/10/25 23:26:46 qjb Exp $
+ * $Id: tf_shm.c,v 1.3 1995/07/18 16:39:48 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: tf_shm.c,v 1.3 1995/07/18 16:39:48 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <krb.h>
+#include <des.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define MAX_BUFF sizeof(des_cblock)*1000 /* room for 1k keys */
+
+extern int errno;
+extern int krb_debug;
+
+/*
+ * krb_create_shmtkt:
+ *
+ * create a shared memory segment for session keys, leaving its id
+ * in the specified filename.
+ */
+
+int
+krb_shm_create(file_name)
+char *file_name;
+{
+ int retval;
+ int shmid;
+ struct shmid_ds shm_buf;
+ FILE *sfile;
+ uid_t me, metoo, getuid(), geteuid();
+
+ (void) krb_shm_dest(file_name); /* nuke it if it exists...
+ this cleans up to make sure we
+ don't slowly lose memory. */
+
+ shmid = shmget((long)IPC_PRIVATE,MAX_BUFF, IPC_CREAT);
+ if (shmid == -1) {
+ if (krb_debug)
+ perror("krb_shm_create shmget");
+ return(KFAILURE); /* XXX */
+ }
+ me = getuid();
+ metoo = geteuid();
+ /*
+ * now set up the buffer so that we can modify it
+ */
+ shm_buf.shm_perm.uid = me;
+ shm_buf.shm_perm.gid = getgid();
+ shm_buf.shm_perm.mode = 0600;
+ if (shmctl(shmid,IPC_SET,&shm_buf) < 0) { /*can now map it */
+ if (krb_debug)
+ perror("krb_shm_create shmctl");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ (void) shmctl(shmid, SHM_LOCK, 0); /* attempt to lock-in-core */
+ /* arrange so the file is owned by the ruid
+ (swap real & effective uid if necessary). */
+ if (me != metoo) {
+ if (setreuid(metoo, me) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("krb_shm_create: setreuid");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",metoo,me);
+ }
+ if ((sfile = fopen(file_name,"w")) == 0) {
+ if (krb_debug)
+ perror("krb_shm_create file");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ if (fchmod(fileno(sfile),0600) < 0) {
+ if (krb_debug)
+ perror("krb_shm_create fchmod");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE); /* XXX */
+ }
+ if (me != metoo) {
+ if (setreuid(me, metoo) < 0) {
+ /* can't switch??? barf! */
+ if (krb_debug)
+ perror("krb_shm_create: setreuid2");
+ (void) shmctl(shmid, IPC_RMID, 0);
+ return(KFAILURE);
+ } else
+ if (krb_debug)
+ printf("swapped UID's %d and %d\n",me,metoo);
+ }
+
+ (void) fprintf(sfile,"%d",shmid);
+ (void) fflush(sfile);
+ (void) fclose(sfile);
+ return(KSUCCESS);
+}
+
+
+/*
+ * krb_is_diskless:
+ *
+ * check / to see if file .diskless exists. If so it is diskless.
+ * Do it this way now to avoid dependencies on a particular routine.
+ * Choose root file system since that will be private to the client.
+ */
+
+int krb_is_diskless()
+{
+ struct stat buf;
+ if (stat("/.diskless",&buf) < 0)
+ return(0);
+ else return(1);
+}
+
+/*
+ * krb_shm_dest: destroy shared memory segment with session keys, and remove
+ * file pointing to it.
+ */
+
+int krb_shm_dest(file)
+char *file;
+{
+ int shmid;
+ FILE *sfile;
+ struct stat st_buf;
+
+ if (stat(file,&st_buf) == 0) {
+ /* successful stat */
+ if ((sfile = fopen(file,"r")) == 0) {
+ if (krb_debug)
+ perror("cannot open shared memory file");
+ return(KFAILURE); /* XXX */
+ }
+ if (fscanf(sfile,"%d",&shmid) == 1) {
+ if (shmctl(shmid,IPC_RMID,0) != 0) {
+ if (krb_debug)
+ perror("krb_shm_dest: cannot delete shm segment");
+ (void) fclose(sfile);
+ return(KFAILURE); /* XXX */
+ }
+ } else {
+ if (krb_debug)
+ fprintf(stderr, "bad format in shmid file\n");
+ (void) fclose(sfile);
+ return(KFAILURE); /* XXX */
+ }
+ (void) fclose(sfile);
+ (void) unlink(file);
+ return(KSUCCESS);
+ } else
+ return(RET_TKFIL); /* XXX */
+}
+
+
+
diff --git a/eBones/lib/libkrb/tf_util.c b/eBones/lib/libkrb/tf_util.c
new file mode 100644
index 0000000000000..e939c38e9da86
--- /dev/null
+++ b/eBones/lib/libkrb/tf_util.c
@@ -0,0 +1,581 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: tf_util.c,v 4.9 90/03/10 19:19:45 jon Exp $
+ * $Id: tf_util.c,v 1.3 1995/07/18 16:39:50 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: tf_util.c,v 1.3 1995/07/18 16:39:50 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <krb.h>
+
+#ifdef TKT_SHMEM
+#include <sys/param.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* TKT_SHMEM */
+
+#define TOO_BIG -1
+#define TF_LCK_RETRY ((unsigned)2) /* seconds to sleep before
+ * retry if ticket file is
+ * locked */
+extern int krb_debug;
+
+#ifdef TKT_SHMEM
+char *krb_shm_addr = 0;
+static char *tmp_shm_addr = 0;
+static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0};
+
+#endif /* TKT_SHMEM */
+
+/*
+ * fd must be initialized to something that won't ever occur as a real
+ * file descriptor. Since open(2) returns only non-negative numbers as
+ * valid file descriptors, and tf_init always stuffs the return value
+ * from open in here even if it is an error flag, we must
+ * a. Initialize fd to a negative number, to indicate that it is
+ * not initially valid.
+ * b. When checking for a valid fd, assume that negative values
+ * are invalid (ie. when deciding whether tf_init has been
+ * called.)
+ * c. In tf_close, be sure it gets reinitialized to a negative
+ * number.
+ */
+static fd = -1;
+static curpos; /* Position in tfbfr */
+static lastpos; /* End of tfbfr */
+static char tfbfr[BUFSIZ]; /* Buffer for ticket data */
+
+static int tf_read(char *s, int n);
+static int tf_gets(char *s, int n);
+
+/*
+ * This file contains routines for manipulating the ticket cache file.
+ *
+ * The ticket file is in the following format:
+ *
+ * principal's name (null-terminated string)
+ * principal's instance (null-terminated string)
+ * CREDENTIAL_1
+ * CREDENTIAL_2
+ * ...
+ * CREDENTIAL_n
+ * EOF
+ *
+ * Where "CREDENTIAL_x" consists of the following fixed-length
+ * fields from the CREDENTIALS structure (see "krb.h"):
+ *
+ * char service[ANAME_SZ]
+ * char instance[INST_SZ]
+ * char realm[REALM_SZ]
+ * C_Block session
+ * int lifetime
+ * int kvno
+ * KTEXT_ST ticket_st
+ * long issue_date
+ *
+ * Short description of routines:
+ *
+ * tf_init() opens the ticket file and locks it.
+ *
+ * tf_get_pname() returns the principal's name.
+ *
+ * tf_get_pinst() returns the principal's instance (may be null).
+ *
+ * tf_get_cred() returns the next CREDENTIALS record.
+ *
+ * tf_save_cred() appends a new CREDENTIAL record to the ticket file.
+ *
+ * tf_close() closes the ticket file and releases the lock.
+ *
+ * tf_gets() returns the next null-terminated string. It's an internal
+ * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred().
+ *
+ * tf_read() reads a given number of bytes. It's an internal routine
+ * used by tf_get_cred().
+ */
+
+/*
+ * tf_init() should be called before the other ticket file routines.
+ * It takes the name of the ticket file to use, "tf_name", and a
+ * read/write flag "rw" as arguments.
+ *
+ * It tries to open the ticket file, checks the mode, and if everything
+ * is okay, locks the file. If it's opened for reading, the lock is
+ * shared. If it's opened for writing, the lock is exclusive.
+ *
+ * Returns KSUCCESS if all went well, otherwise one of the following:
+ *
+ * NO_TKT_FIL - file wasn't there
+ * TKT_FIL_ACC - file was in wrong mode, etc.
+ * TKT_FIL_LCK - couldn't lock the file, even after a retry
+ */
+
+int
+tf_init(tf_name, rw)
+ char *tf_name;
+ int rw;
+{
+ int wflag;
+ uid_t me, getuid();
+ struct stat stat_buf;
+#ifdef TKT_SHMEM
+ char shmidname[MAXPATHLEN];
+ FILE *sfp;
+ int shmid;
+#endif
+
+ switch (rw) {
+ case R_TKT_FIL:
+ wflag = 0;
+ break;
+ case W_TKT_FIL:
+ wflag = 1;
+ break;
+ default:
+ if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n");
+ return TKT_FIL_ACC;
+ }
+ if (lstat(tf_name, &stat_buf) < 0)
+ switch (errno) {
+ case ENOENT:
+ return NO_TKT_FIL;
+ default:
+ return TKT_FIL_ACC;
+ }
+ me = getuid();
+ if ((stat_buf.st_uid != me && me != 0) ||
+ ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+ return TKT_FIL_ACC;
+#ifdef TKT_SHMEM
+ (void) strcpy(shmidname, tf_name);
+ (void) strcat(shmidname, ".shm");
+ if (stat(shmidname,&stat_buf) < 0)
+ return(TKT_FIL_ACC);
+ if ((stat_buf.st_uid != me && me != 0) ||
+ ((stat_buf.st_mode & S_IFMT) != S_IFREG))
+ return TKT_FIL_ACC;
+#endif /* TKT_SHMEM */
+
+ /*
+ * If "wflag" is set, open the ticket file in append-writeonly mode
+ * and lock the ticket file in exclusive mode. If unable to lock
+ * the file, sleep and try again. If we fail again, return with the
+ * proper error message.
+ */
+
+ curpos = sizeof(tfbfr);
+
+#ifdef TKT_SHMEM
+ sfp = fopen(shmidname, "r"); /* only need read/write on the
+ actual tickets */
+ if (sfp == 0)
+ return TKT_FIL_ACC;
+ shmid = -1;
+ {
+ char buf[BUFSIZ];
+ int val; /* useful for debugging fscanf */
+ /* We provide our own buffer here since some STDIO libraries
+ barf on unbuffered input with fscanf() */
+
+ setbuf(sfp, buf);
+ if ((val = fscanf(sfp,"%d",&shmid)) != 1) {
+ (void) fclose(sfp);
+ return TKT_FIL_ACC;
+ }
+ if (shmid < 0) {
+ (void) fclose(sfp);
+ return TKT_FIL_ACC;
+ }
+ (void) fclose(sfp);
+ }
+ /*
+ * global krb_shm_addr is initialized to 0. Ultrix bombs when you try and
+ * attach the same segment twice so we need this check.
+ */
+ if (!krb_shm_addr) {
+ if ((krb_shm_addr = shmat(shmid,0,0)) == -1){
+ if (krb_debug)
+ fprintf(stderr,
+ "cannot attach shared memory for segment %d\n",
+ shmid);
+ krb_shm_addr = 0; /* reset so we catch further errors */
+ return TKT_FIL_ACC;
+ }
+ }
+ tmp_shm_addr = krb_shm_addr;
+#endif /* TKT_SHMEM */
+
+ if (wflag) {
+ fd = open(tf_name, O_RDWR, 0600);
+ if (fd < 0) {
+ return TKT_FIL_ACC;
+ }
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ sleep(TF_LCK_RETRY);
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ (void) close(fd);
+ fd = -1;
+ return TKT_FIL_LCK;
+ }
+ }
+ return KSUCCESS;
+ }
+ /*
+ * Otherwise "wflag" is not set and the ticket file should be opened
+ * for read-only operations and locked for shared access.
+ */
+
+ fd = open(tf_name, O_RDONLY, 0600);
+ if (fd < 0) {
+ return TKT_FIL_ACC;
+ }
+ if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+ sleep(TF_LCK_RETRY);
+ if (flock(fd, LOCK_SH | LOCK_NB) < 0) {
+ (void) close(fd);
+ fd = -1;
+ return TKT_FIL_LCK;
+ }
+ }
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_pname() reads the principal's name from the ticket file. It
+ * should only be called after tf_init() has been called. The
+ * principal's name is filled into the "p" parameter. If all goes well,
+ * KSUCCESS is returned. If tf_init() wasn't called, TKT_FIL_INI is
+ * returned. If the name was null, or EOF was encountered, or the name
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned.
+ */
+
+int
+tf_get_pname(p)
+ char *p;
+{
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_pname called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if (tf_gets(p, ANAME_SZ) < 2) /* can't be just a null */
+ return TKT_FIL_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_pinst() reads the principal's instance from a ticket file.
+ * It should only be called after tf_init() and tf_get_pname() have been
+ * called. The instance is filled into the "inst" parameter. If all
+ * goes well, KSUCCESS is returned. If tf_init() wasn't called,
+ * TKT_FIL_INI is returned. If EOF was encountered, or the instance
+ * was longer than ANAME_SZ, TKT_FIL_FMT is returned. Note that the
+ * instance may be null.
+ */
+
+int
+tf_get_pinst(inst)
+ char *inst;
+{
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_pinst called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if (tf_gets(inst, INST_SZ) < 1)
+ return TKT_FIL_FMT;
+ return KSUCCESS;
+}
+
+/*
+ * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills
+ * in the given structure "c". It should only be called after tf_init(),
+ * tf_get_pname(), and tf_get_pinst() have been called. If all goes well,
+ * KSUCCESS is returned. Possible error codes are:
+ *
+ * TKT_FIL_INI - tf_init wasn't called first
+ * TKT_FIL_FMT - bad format
+ * EOF - end of file encountered
+ */
+
+int
+tf_get_cred(c)
+ CREDENTIALS *c;
+{
+ KTEXT ticket = &c->ticket_st; /* pointer to ticket */
+ int k_errno;
+
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_get_cred called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2)
+ switch (k_errno) {
+ case TOO_BIG:
+ case 1: /* can't be just a null */
+ tf_close();
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1)
+ switch (k_errno) {
+ case TOO_BIG:
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2)
+ switch (k_errno) {
+ case TOO_BIG:
+ case 1: /* can't be just a null */
+ tf_close();
+ return TKT_FIL_FMT;
+ case 0:
+ return EOF;
+ }
+ if (
+ tf_read((char *) (c->session), KEY_SZ) < 1 ||
+ tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 ||
+ tf_read((char *) &(c->kvno), sizeof(c->kvno)) < 1 ||
+ tf_read((char *) &(ticket->length), sizeof(ticket->length))
+ < 1 ||
+ /* don't try to read a silly amount into ticket->dat */
+ ticket->length > MAX_KTXT_LEN ||
+ tf_read((char *) (ticket->dat), ticket->length) < 1 ||
+ tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1
+ ) {
+ tf_close();
+ return TKT_FIL_FMT;
+ }
+#ifdef TKT_SHMEM
+ bcopy(tmp_shm_addr,c->session,KEY_SZ);
+ tmp_shm_addr += KEY_SZ;
+#endif /* TKT_SHMEM */
+ return KSUCCESS;
+}
+
+/*
+ * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is
+ * not a valid file descriptor, it just returns. It also clears the
+ * buffer used to read tickets.
+ *
+ * The return value is not defined.
+ */
+
+void
+tf_close()
+{
+ if (!(fd < 0)) {
+#ifdef TKT_SHMEM
+ if (shmdt(krb_shm_addr)) {
+ /* what kind of error? */
+ if (krb_debug)
+ fprintf(stderr, "shmdt 0x%x: errno %d",krb_shm_addr, errno);
+ } else {
+ krb_shm_addr = 0;
+ }
+#endif TKT_SHMEM
+ (void) flock(fd, LOCK_UN);
+ (void) close(fd);
+ fd = -1; /* see declaration of fd above */
+ }
+ bzero(tfbfr, sizeof(tfbfr));
+}
+
+/*
+ * tf_gets() is an internal routine. It takes a string "s" and a count
+ * "n", and reads from the file until either it has read "n" characters,
+ * or until it reads a null byte. When finished, what has been read exists
+ * in "s". If it encounters EOF or an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n the number of bytes read (including null terminator)
+ * when all goes well
+ *
+ * 0 end of file or read error
+ *
+ * TOO_BIG if "count" characters are read and no null is
+ * encountered. This is an indication that the ticket
+ * file is seriously ill.
+ */
+
+static int
+tf_gets(s, n)
+ register char *s;
+ int n;
+{
+ register count;
+
+ if (fd < 0) {
+ if (krb_debug)
+ fprintf(stderr, "tf_gets called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ for (count = n - 1; count > 0; --count) {
+ if (curpos >= sizeof(tfbfr)) {
+ lastpos = read(fd, tfbfr, sizeof(tfbfr));
+ curpos = 0;
+ }
+ if (curpos == lastpos) {
+ tf_close();
+ return 0;
+ }
+ *s = tfbfr[curpos++];
+ if (*s++ == '\0')
+ return (n - count);
+ }
+ tf_close();
+ return TOO_BIG;
+}
+
+/*
+ * tf_read() is an internal routine. It takes a string "s" and a count
+ * "n", and reads from the file until "n" bytes have been read. When
+ * finished, what has been read exists in "s". If it encounters EOF or
+ * an error, it closes the ticket file.
+ *
+ * Possible return values are:
+ *
+ * n the number of bytes read when all goes well
+ *
+ * 0 on end of file or read error
+ */
+
+static int
+tf_read(s, n)
+ register char *s;
+ register int n;
+{
+ register count;
+
+ for (count = n; count > 0; --count) {
+ if (curpos >= sizeof(tfbfr)) {
+ lastpos = read(fd, tfbfr, sizeof(tfbfr));
+ curpos = 0;
+ }
+ if (curpos == lastpos) {
+ tf_close();
+ return 0;
+ }
+ *s++ = tfbfr[curpos++];
+ }
+ return n;
+}
+
+/*
+ * tf_save_cred() appends an incoming ticket to the end of the ticket
+ * file. You must call tf_init() before calling tf_save_cred().
+ *
+ * The "service", "instance", and "realm" arguments specify the
+ * server's name; "session" contains the session key to be used with
+ * the ticket; "kvno" is the server key version number in which the
+ * ticket is encrypted, "ticket" contains the actual ticket, and
+ * "issue_date" is the time the ticket was requested (local host's time).
+ *
+ * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't
+ * called previously, and KFAILURE for anything else that went wrong.
+ */
+
+int
+tf_save_cred(service, instance, realm, session, lifetime, kvno,
+ ticket, issue_date)
+ char *service; /* Service name */
+ char *instance; /* Instance */
+ char *realm; /* Auth domain */
+ C_Block session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ KTEXT ticket; /* The ticket itself */
+ long issue_date; /* The issue time */
+{
+
+ off_t lseek();
+ int count; /* count for write */
+#ifdef TKT_SHMEM
+ int *skey_check;
+#endif /* TKT_SHMEM */
+
+ if (fd < 0) { /* fd is ticket file as set by tf_init */
+ if (krb_debug)
+ fprintf(stderr, "tf_save_cred called before tf_init.\n");
+ return TKT_FIL_INI;
+ }
+ /* Find the end of the ticket file */
+ (void) lseek(fd, 0L, 2);
+#ifdef TKT_SHMEM
+ /* scan to end of existing keys: pick first 'empty' slot.
+ we assume that no real keys will be completely zero (it's a weak
+ key under DES) */
+
+ skey_check = (int *) krb_shm_addr;
+
+ while (*skey_check && *(skey_check+1))
+ skey_check += 2;
+ tmp_shm_addr = (char *)skey_check;
+#endif /* TKT_SHMEM */
+
+ /* Write the ticket and associated data */
+ /* Service */
+ count = strlen(service) + 1;
+ if (write(fd, service, count) != count)
+ goto bad;
+ /* Instance */
+ count = strlen(instance) + 1;
+ if (write(fd, instance, count) != count)
+ goto bad;
+ /* Realm */
+ count = strlen(realm) + 1;
+ if (write(fd, realm, count) != count)
+ goto bad;
+ /* Session key */
+#ifdef TKT_SHMEM
+ bcopy(session,tmp_shm_addr,8);
+ tmp_shm_addr+=8;
+ if (write(fd,krb_dummy_skey,8) != 8)
+ goto bad;
+#else /* ! TKT_SHMEM */
+ if (write(fd, (char *) session, 8) != 8)
+ goto bad;
+#endif /* TKT_SHMEM */
+ /* Lifetime */
+ if (write(fd, (char *) &lifetime, sizeof(int)) != sizeof(int))
+ goto bad;
+ /* Key vno */
+ if (write(fd, (char *) &kvno, sizeof(int)) != sizeof(int))
+ goto bad;
+ /* Tkt length */
+ if (write(fd, (char *) &(ticket->length), sizeof(int)) !=
+ sizeof(int))
+ goto bad;
+ /* Ticket */
+ count = ticket->length;
+ if (write(fd, (char *) (ticket->dat), count) != count)
+ goto bad;
+ /* Issue date */
+ if (write(fd, (char *) &issue_date, sizeof(long))
+ != sizeof(long))
+ goto bad;
+
+ /* Actually, we should check each write for success */
+ return (KSUCCESS);
+bad:
+ return (KFAILURE);
+}
diff --git a/eBones/lib/libkrb/tkt_string.c b/eBones/lib/libkrb/tkt_string.c
new file mode 100644
index 0000000000000..d944833a33aa6
--- /dev/null
+++ b/eBones/lib/libkrb/tkt_string.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: tkt_string.c,v 4.6 89/01/05 12:31:51 raeburn Exp $
+ * $Id: tkt_string.c,v 1.3 1995/07/18 16:39:52 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid =
+"$Id: tkt_string.c,v 1.3 1995/07/18 16:39:52 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <krb.h>
+#include <string.h>
+#include <sys/param.h>
+
+/*
+ * This routine is used to generate the name of the file that holds
+ * the user's cache of server tickets and associated session keys.
+ *
+ * If it is set, krb_ticket_string contains the ticket file name.
+ * Otherwise, the filename is constructed as follows:
+ *
+ * If it is set, the environment variable "KRBTKFILE" will be used as
+ * the ticket file name. Otherwise TKT_ROOT (defined in "krb.h") and
+ * the user's uid are concatenated to produce the ticket file name
+ * (e.g., "/tmp/tkt123"). A pointer to the string containing the ticket
+ * file name is returned.
+ */
+
+static char krb_ticket_string[MAXPATHLEN] = "";
+
+char *tkt_string()
+{
+ char *env;
+ uid_t getuid();
+
+ if (!*krb_ticket_string) {
+ if ((env = getenv("KRBTKFILE"))) {
+ (void) strncpy(krb_ticket_string, env,
+ sizeof(krb_ticket_string)-1);
+ krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+ } else {
+ /* 32 bits of signed integer will always fit in 11 characters
+ (including the sign), so no need to worry about overflow */
+ (void) sprintf(krb_ticket_string, "%s%ld",TKT_ROOT,getuid());
+ }
+ }
+ return krb_ticket_string;
+}
+
+/*
+ * This routine is used to set the name of the file that holds the user's
+ * cache of server tickets and associated session keys.
+ *
+ * The value passed in is copied into local storage.
+ *
+ * NOTE: This routine should be called during initialization, before other
+ * Kerberos routines are called; otherwise tkt_string() above may be called
+ * and return an undesired ticket file name until this routine is called.
+ */
+
+void
+krb_set_tkt_string(val)
+char *val;
+{
+
+ (void) strncpy(krb_ticket_string, val, sizeof(krb_ticket_string)-1);
+ krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
+
+ return;
+}
diff --git a/eBones/lib/libkrb/util.c b/eBones/lib/libkrb/util.c
new file mode 100644
index 0000000000000..68c0dbc1eb4b8
--- /dev/null
+++ b/eBones/lib/libkrb/util.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Miscellaneous debug printing utilities
+ *
+ * from: util.c,v 4.8 89/01/17 22:02:08 wesommer Exp $
+ * $Id: util.c,v 1.3 1995/07/18 16:39:54 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: util.c,v 1.3 1995/07/18 16:39:54 mark Exp $";
+#endif lint
+#endif
+
+#include <krb.h>
+#include <des.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+/*
+ * Print some of the contents of the given authenticator structure
+ * (AUTH_DAT defined in "krb.h"). Fields printed are:
+ *
+ * pname, pinst, prealm, netaddr, flags, cksum, timestamp, session
+ */
+
+void
+ad_print(x)
+AUTH_DAT *x;
+{
+ struct in_addr in;
+
+ /* Print the contents of an auth_dat struct. */
+ in.s_addr = x->address;
+ printf("\n%s %s %s %s flags %u cksum 0x%lX\n\ttkt_tm 0x%lX sess_key",
+ x->pname, x->pinst, x->prealm, inet_ntoa(in), x->k_flags,
+ x->checksum, x->time_sec);
+
+ printf("[8] =");
+#ifdef NOENCRYPTION
+ placebo_cblock_print(x->session);
+#else
+ des_cblock_print_file((C_Block *)x->session,stdout);
+#endif
+ /* skip reply for now */
+}
+
+/*
+ * Print in hex the 8 bytes of the given session key.
+ *
+ * Printed format is: " 0x { x, x, x, x, x, x, x, x }"
+ */
+
+#ifdef NOENCRYPTION
+placebo_cblock_print(x)
+ des_cblock x;
+{
+ unsigned char *y = (unsigned char *) x;
+ register int i = 0;
+
+ printf(" 0x { ");
+
+ while (i++ <8) {
+ printf("%x",*y++);
+ if (i<8) printf(", ");
+ }
+ printf(" }");
+}
+#endif
diff --git a/eBones/lib/librkinit/Makefile b/eBones/lib/librkinit/Makefile
new file mode 100644
index 0000000000000..7d4b4ca246b27
--- /dev/null
+++ b/eBones/lib/librkinit/Makefile
@@ -0,0 +1,19 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+
+LIB= rkinit
+CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -I${RKINITOBJDIR}
+SRCS= rkinit_err.c rk_lib.c rk_rpc.c rk_util.c rk_krb.c rkinit_err.c
+
+LDADD+= -lcom_err
+
+beforeinstall:
+ -cd ${.OBJDIR}; cmp -s rkinit_err.h \
+ ${DESTDIR}/usr/include/kerberosIV/rkinit_err.h || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 rkinit_err.h \
+ ${DESTDIR}/usr/include/kerberosIV
+
+MAN3= rkinit.3
+
+.include <bsd.lib.mk>
+
+rkinit_err.c: ${RKINITOBJDIR}/rkinit_err.h
diff --git a/eBones/lib/librkinit/rk_krb.c b/eBones/lib/librkinit/rk_krb.c
new file mode 100644
index 0000000000000..ad8a6537b2d45
--- /dev/null
+++ b/eBones/lib/librkinit/rk_krb.c
@@ -0,0 +1,316 @@
+/*
+ * $Id: rk_krb.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/librkinit/RCS/rk_krb.c,v $
+ * $Author: dglo $
+ *
+ * This file contains the kerberos parts of the rkinit library.
+ * See the comment at the top of rk_lib.c for a description of the naming
+ * conventions used within the rkinit library.
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: rk_krb.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <krb.h>
+#include <des.h>
+
+#include <signal.h>
+#include <setjmp.h>
+
+#ifdef POSIX
+#include <termios.h>
+#else
+#include <sgtty.h>
+#endif
+
+#include <rkinit.h>
+#include <rkinit_err.h>
+#include <rkinit_private.h>
+
+static jmp_buf env;
+static void sig_restore();
+static void push_signals();
+static void pop_signals();
+
+/* Information to be passed around within client get_in_tkt */
+typedef struct {
+ KTEXT scip; /* Server KDC packet */
+ char *username;
+ char *host;
+} rkinit_intkt_info;
+
+static char errbuf[BUFSIZ];
+
+/* The compiler complains if this is declared static. */
+#ifdef __STDC__
+int rki_key_proc(char *user, char *instance, char *realm, char *arg,
+ des_cblock *key)
+#else
+int rki_key_proc(user, instance, realm, arg, key)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ des_cblock *key;
+#endif /* __STDC__ */
+
+{
+ rkinit_intkt_info *rii = (rkinit_intkt_info *)arg;
+ char password[BUFSIZ];
+ int ok = 0;
+#ifdef POSIX
+ struct termios ttyb;
+#else
+ struct sgttyb ttyb; /* For turning off echo */
+#endif
+
+ SBCLEAR(ttyb);
+ BCLEAR(password);
+
+ /*
+ * If the username does not match the aname in the ticket,
+ * we will print that too. Otherwise, we won't.
+ */
+
+ printf("Kerberos initialization (%s)", rii->host);
+ if (strcmp(rii->username, user))
+ printf(": tickets will be owned by %s", rii->username);
+
+ printf("\nPassword for %s%s%s@%s: ", user,
+ (instance[0]) ? "." : "", instance, realm);
+
+ fflush(stdout);
+
+ push_signals();
+ if (setjmp(env)) {
+ ok = -1;
+ goto lose;
+ }
+
+#ifndef POSIX
+ ioctl(0, TIOCGETP, &ttyb);
+ ttyb.sg_flags &= ~ECHO;
+ ioctl(0, TIOCSETP, &ttyb);
+#else
+ (void) tcgetattr(0, &ttyb);
+ ttyb.c_lflag &= ~ECHO;
+ (void) tcsetattr(0, TCSAFLUSH, &ttyb);
+#endif
+
+ bzero(password, sizeof(password));
+ if (read(0, password, sizeof(password)) == -1) {
+ perror("read");
+ ok = -1;
+ goto lose;
+ }
+
+ if (password[strlen(password)-1] == '\n')
+ password[strlen(password)-1] = 0;
+
+ /* Generate the key from the password and destroy the password */
+
+ des_string_to_key(password, key);
+
+lose:
+ BCLEAR(password);
+
+#ifndef POSIX
+ ttyb.sg_flags |= ECHO;
+ ioctl(0, TIOCSETP, &ttyb);
+#else
+ ttyb.c_lflag |= ECHO;
+ (void) tcsetattr(0, TCSAFLUSH, &ttyb);
+#endif
+
+ pop_signals();
+ printf("\n");
+
+ return(ok);
+}
+
+#ifdef __STDC__
+static int rki_decrypt_tkt(char *user, char *instance, char *realm,
+ char *arg, int (*key_proc)(), KTEXT *cipp)
+#else
+static int rki_decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ int (*key_proc)();
+ KTEXT *cipp;
+#endif /* __STDC__ */
+{
+ KTEXT cip = *cipp;
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+ KTEXT scip = 0; /* cipher from rkinit server */
+
+ rkinit_intkt_info *rii = (rkinit_intkt_info *)arg;
+
+ /* generate a key */
+ {
+ register int rc;
+ rc = (*key_proc)(user, instance, realm, arg, key);
+ if (rc)
+ return(rc);
+ }
+
+ des_key_sched(&key, key_s);
+
+ /* Decrypt information from KDC */
+ des_pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
+ (long) cip->length, key_s, &key, 0);
+
+ /* DescrYPT rkinit server's information from KDC */
+ scip = rii->scip;
+ des_pcbc_encrypt((C_Block *)scip->dat,(C_Block *)scip->dat,
+ (long) scip->length, key_s, &key, 0);
+
+ /* Get rid of all traces of key */
+ bzero((char *)key, sizeof(key));
+ bzero((char *)key_s, sizeof(key_s));
+
+ return(0);
+}
+
+#ifdef __STDC__
+int rki_get_tickets(int version, char *host, char *r_krealm, rkinit_info *info)
+#else
+int rki_get_tickets(version, host, r_krealm, info)
+ int version;
+ char *host;
+ char *r_krealm;
+ rkinit_info *info;
+#endif /* __STDC__ */
+{
+ int status = RKINIT_SUCCESS;
+ KTEXT_ST auth;
+ char phost[MAXHOSTNAMELEN];
+ KTEXT_ST scip; /* server's KDC packet */
+ des_cblock key;
+ des_key_schedule sched;
+ struct sockaddr_in caddr;
+ struct sockaddr_in saddr;
+ CREDENTIALS cred;
+ MSG_DAT msg_data;
+ u_char enc_data[MAX_KTXT_LEN];
+
+ rkinit_intkt_info rii;
+
+ SBCLEAR(auth);
+ BCLEAR(phost);
+ SBCLEAR(rii);
+ SBCLEAR(scip);
+ SBCLEAR(caddr);
+ SBCLEAR(saddr);
+ SBCLEAR(cred);
+ SBCLEAR(msg_data);
+ BCLEAR(enc_data);
+
+ if ((status = rki_send_rkinit_info(version, info)) != RKINIT_SUCCESS)
+ return(status);
+
+ if ((status = rki_rpc_get_skdc(&scip)) != RKINIT_SUCCESS)
+ return(status);
+
+ rii.scip = &scip;
+ rii.host = host;
+ rii.username = info->username;
+
+ if ((status = krb_get_in_tkt(info->aname, info->inst, info->realm,
+ "krbtgt", info->realm, 1,
+ rki_key_proc, rki_decrypt_tkt, (char *)&rii))) {
+ strcpy(errbuf, krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_KERBEROS);
+ }
+
+ /* Create an authenticator */
+ strcpy(phost, krb_get_phost(host));
+ if ((status = krb_mk_req(&auth, KEY, phost, r_krealm, 0))) {
+ sprintf(errbuf, "krb_mk_req: %s", krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_KERBEROS);
+ }
+
+ /* Re-encrypt server KDC packet in session key */
+ /* Get credentials from ticket file */
+ if ((status = krb_get_cred(KEY, phost, r_krealm, &cred))) {
+ sprintf(errbuf, "krb_get_cred: %s", krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_KERBEROS);
+ }
+
+ /* Exctract the session key and make the schedule */
+ bcopy(cred.session, key, sizeof(key));
+ if ((status = des_key_sched(&key, sched))) {
+ sprintf(errbuf, "des_key_sched: %s", krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_DES);
+ }
+
+ /* Get client and server addresses */
+ if ((status = rki_get_csaddr(&caddr, &saddr)) != RKINIT_SUCCESS)
+ return(status);
+
+ /*
+ * scip was passed to krb_get_in_tkt, where it was decrypted.
+ * Now re-encrypt in the session key.
+ */
+
+ msg_data.app_data = enc_data;
+ if ((msg_data.app_length =
+ krb_mk_priv(scip.dat, msg_data.app_data, scip.length, sched, key,
+ &caddr, &saddr)) == -1) {
+ sprintf(errbuf, "krb_mk_priv failed.");
+ rkinit_errmsg(errbuf);
+ return(RKINIT_KERBEROS);
+ }
+
+ /* Destroy tickets, which we no longer need */
+ dest_tkt();
+
+ if ((status = rki_rpc_send_ckdc(&msg_data)) != RKINIT_SUCCESS)
+ return(status);
+
+ if ((status = rki_rpc_sendauth(&auth)) != RKINIT_SUCCESS)
+ return(status);
+
+ if ((status = rki_rpc_get_status()))
+ return(status);
+
+ return(RKINIT_SUCCESS);
+}
+
+
+static void (*old_sigfunc[NSIG])(int);
+
+static void push_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ old_sigfunc[i] = signal(i,sig_restore);
+}
+
+static void pop_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ signal(i,old_sigfunc[i]);
+}
+
+static void sig_restore(sig,code,scp)
+ int sig,code;
+ struct sigcontext *scp;
+{
+ longjmp(env,1);
+}
diff --git a/eBones/lib/librkinit/rk_lib.c b/eBones/lib/librkinit/rk_lib.c
new file mode 100644
index 0000000000000..06b8f392e0d6f
--- /dev/null
+++ b/eBones/lib/librkinit/rk_lib.c
@@ -0,0 +1,100 @@
+/*
+ * $Id: rk_lib.c,v 1.1 1993/12/10 19:32:01 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/librkinit/RCS/rk_lib.c,v $
+ * $Author: dglo $
+ *
+ * This file contains the non-rpc top-level rkinit library routines.
+ * The routines in the rkinit library that should be called from clients
+ * are exactly those defined in this file.
+ *
+ * The naming convetions used within the rkinit library are as follows:
+ * Functions intended for general client use start with rkinit_
+ * Functions intended for use only inside the library or server start with
+ * rki_
+ * Functions that do network communcation start with rki_rpc_
+ * Static functions can be named in any fashion.
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: rk_lib.c,v 1.1 1993/12/10 19:32:01 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <setjmp.h>
+#include <krb.h>
+
+#include <rkinit.h>
+#include <rkinit_private.h>
+#include <rkinit_err.h>
+
+#ifdef __STDC__
+char *rkinit_errmsg(char *string)
+#else
+char *rkinit_errmsg(string)
+ char *string;
+#endif /* __STDC__ */
+{
+ static char errmsg[BUFSIZ];
+
+ if (string) {
+ BCLEAR(errmsg);
+ strncpy(errmsg, string, sizeof(errmsg) - 1);
+ }
+
+ return(errmsg);
+}
+
+#ifdef __STDC__
+int rkinit(char *host, char *r_krealm, rkinit_info *info, int timeout)
+#else
+int rkinit(host, r_krealm, info, timeout)
+ char *host;
+ char *r_krealm;
+ rkinit_info *info;
+ int timeout;
+#endif /* __STDC__ */
+{
+ int status = RKINIT_SUCCESS;
+ int version = 0;
+ char phost[MAXHOSTNAMELEN];
+ jmp_buf timeout_env;
+ void (*old_alrm)(int) = NULL;
+ char origtktfilename[MAXPATHLEN]; /* original ticket file name */
+ char tktfilename[MAXPATHLEN]; /* temporary client ticket file */
+
+ BCLEAR(phost);
+ BCLEAR(origtktfilename);
+ BCLEAR(tktfilename);
+ BCLEAR(timeout_env);
+
+ init_rkin_err_tbl();
+
+ if ((status = rki_setup_rpc(host)))
+ return(status);
+
+ if (timeout)
+ old_alrm = rki_setup_timer(timeout_env);
+
+ /* The alarm handler longjmps us to here. */
+ if ((status = setjmp(timeout_env)) == 0) {
+
+ strcpy(origtktfilename, tkt_string());
+ sprintf(tktfilename, "/tmp/tkt_rkinit.%ld", getpid());
+ krb_set_tkt_string(tktfilename);
+
+ if ((status = rki_choose_version(&version)) == RKINIT_SUCCESS)
+ status = rki_get_tickets(version, host, r_krealm, info);
+ }
+
+ if (timeout)
+ rki_restore_timer(old_alrm);
+
+ dest_tkt();
+ krb_set_tkt_string(origtktfilename);
+
+ rki_cleanup_rpc();
+
+ return(status);
+}
diff --git a/eBones/lib/librkinit/rk_rpc.c b/eBones/lib/librkinit/rk_rpc.c
new file mode 100644
index 0000000000000..dd6132779461c
--- /dev/null
+++ b/eBones/lib/librkinit/rk_rpc.c
@@ -0,0 +1,387 @@
+/*
+ * $Id: rk_rpc.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/librkinit/RCS/rk_rpc.c,v $
+ * $Author: dglo $
+ *
+ * This file contains functions that are used for network communication.
+ * See the comment at the top of rk_lib.c for a description of the naming
+ * conventions used within the rkinit library.
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: rk_rpc.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+
+#include <rkinit.h>
+#include <rkinit_err.h>
+#include <rkinit_private.h>
+
+extern int errno;
+
+static int sock;
+struct sockaddr_in saddr;
+
+static char errbuf[BUFSIZ];
+
+char *calloc();
+
+#ifdef __STDC__
+int rki_send_packet(int sock, char type, u_int32_t length, const char *data)
+#else
+int rki_send_packet(sock, type, length, data)
+ int sock;
+ char type;
+ u_int32_t length;
+ const char *data;
+#endif /* __STDC__ */
+{
+ int len;
+ u_char *packet;
+ u_int32_t pkt_len;
+ u_int32_t net_pkt_len;
+
+ pkt_len = length + PKT_DATA;
+
+ if ((packet = (u_char *)calloc(pkt_len, sizeof(u_char))) == NULL) {
+ sprintf(errbuf, "rki_send_packet: failure allocating %d bytes",
+ pkt_len * sizeof(u_char));
+ rkinit_errmsg(errbuf);
+ return(RKINIT_MEMORY);
+ }
+
+ net_pkt_len = htonl(pkt_len);
+
+ packet[PKT_TYPE] = type;
+ bcopy((char *)&net_pkt_len, packet + PKT_LEN, sizeof(u_int32_t));
+ bcopy(data, packet + PKT_DATA, length);
+
+ if ((len = write(sock, packet, pkt_len)) != pkt_len) {
+ if (len == -1)
+ sprintf(errbuf, "write: %s", sys_errlist[errno]);
+ else
+ sprintf(errbuf, "write: %d bytes written; %d bytes actually sent",
+ pkt_len, len);
+ rkinit_errmsg(errbuf);
+ free(packet);
+ return(RKINIT_WRITE);
+ }
+
+ free(packet);
+ return(RKINIT_SUCCESS);
+}
+
+#ifdef __STDC__
+int rki_get_packet(int sock, u_char type, u_int32_t *length, char *data)
+#else
+int rki_get_packet(sock, type, length, data)
+ int sock;
+ u_char type;
+ u_int32_t *length;
+ char *data;
+#endif /* __STDC__ */
+{
+ int len;
+ int len_sofar = 0;
+ u_int32_t expected_length = 0;
+ int got_full_packet = FALSE;
+ int tries = 0;
+ u_char *packet;
+
+ u_int32_t max_pkt_len;
+
+ max_pkt_len = *length + PKT_DATA;
+
+ if ((packet = (u_char *)calloc(max_pkt_len, sizeof(u_char))) == NULL) {
+ sprintf(errbuf, "rki_get_packet: failure allocating %d bytes",
+ max_pkt_len * sizeof(u_char));
+ rkinit_errmsg(errbuf);
+ return(RKINIT_MEMORY);
+ }
+
+ /* Read the packet type and length */
+ while ((len_sofar < PKT_DATA) && (tries < RETRIES)) {
+ if ((len = read(sock, packet + len_sofar, PKT_DATA - len_sofar)) < 0) {
+ sprintf(errbuf, "read: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_READ);
+ }
+ len_sofar += len;
+ tries++;
+ }
+ if (len_sofar < PKT_DATA) {
+ sprintf(errbuf,
+ "read: expected to receive at least %d bytes; received %d",
+ PKT_DATA, len_sofar);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_PACKET);
+ }
+ bcopy(packet + PKT_LEN, (char *)&expected_length, sizeof(u_int32_t));
+ expected_length = ntohl(expected_length);
+ if (expected_length > max_pkt_len) {
+ sprintf(errbuf, "%s %d %s %d",
+ "rki_get_packet: incoming message of size",
+ expected_length,
+ "is larger than message buffer of size",
+ max_pkt_len);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_PACKET);
+ }
+ tries = 0;
+ while (!got_full_packet && (tries < RETRIES)) {
+ if ((len = read(sock, packet + len_sofar,
+ expected_length - len_sofar)) < 0) {
+ sprintf(errbuf, "read: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_READ);
+ }
+ len_sofar += len;
+ if (expected_length == len_sofar)
+ got_full_packet = TRUE;
+ }
+ if (len_sofar < expected_length) {
+ sprintf(errbuf,
+ "read: expected to receive at least %d bytes; received %d",
+ expected_length, len_sofar);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_PACKET);
+ }
+ if (packet[PKT_TYPE] == MT_DROP) {
+ BCLEAR(errbuf);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_DROPPED);
+ }
+
+ if (packet[PKT_TYPE] != type) {
+ sprintf(errbuf, "Expected packet type of %s; got %s",
+ rki_mt_to_string(type),
+ rki_mt_to_string(packet[PKT_TYPE]));
+ rkinit_errmsg(errbuf);
+ return(RKINIT_PACKET);
+ }
+
+ *length = len_sofar - PKT_DATA;
+ bcopy(packet + PKT_DATA, data, *length);
+
+ free(packet);
+
+ return(RKINIT_SUCCESS);
+}
+
+#ifdef __STDC__
+int rki_setup_rpc(char *host)
+#else
+int rki_setup_rpc(host)
+ char *host;
+#endif /* __STDC__ */
+{
+ struct hostent *hp;
+ struct servent *sp;
+ int port;
+
+ SBCLEAR(saddr);
+ SBCLEAR(hp);
+ SBCLEAR(sp);
+
+ if ((hp = gethostbyname(host)) == NULL) {
+ sprintf(errbuf, "%s: unknown host.", host);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_HOST);
+ }
+
+ if ((sp = getservbyname(SERVENT, "tcp")))
+ port = sp->s_port;
+ else
+ /* Fall back on known port number */
+ port = htons(PORT);
+
+ saddr.sin_family = hp->h_addrtype;
+ bcopy(hp->h_addr, (char *)&saddr.sin_addr, hp->h_length);
+ saddr.sin_port = port;
+
+ if ((sock = socket(hp->h_addrtype, SOCK_STREAM, IPPROTO_IP)) < 0) {
+ sprintf(errbuf, "socket: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_SOCKET);
+ }
+
+ if (connect(sock, (struct sockaddr *)&saddr, sizeof (saddr)) < 0) {
+ sprintf(errbuf, "connect: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ close(sock);
+ return(RKINIT_CONNECT);
+ }
+
+ return(RKINIT_SUCCESS);
+}
+
+#ifdef __STDC__
+int rki_rpc_exchange_version_info(int c_lversion, int c_hversion,
+ int *s_lversion, int *s_hversion)
+#else
+int rki_rpc_exchange_version_info(c_lversion, c_hversion,
+ s_lversion, s_hversion)
+ int c_lversion;
+ int c_hversion;
+ int *s_lversion;
+ int *s_hversion;
+#endif /* __STDC__ */
+{
+ int status = RKINIT_SUCCESS;
+ u_char version_info[VERSION_INFO_SIZE];
+ u_int32_t length = sizeof(version_info);
+
+ version_info[0] = (u_char) c_lversion;
+ version_info[1] = (u_char) c_hversion;
+
+ if ((status = rki_send_packet(sock, MT_CVERSION, length,
+ (char *)version_info)) != RKINIT_SUCCESS)
+ return(status);
+
+ if ((status = rki_get_packet(sock, MT_SVERSION, &length,
+ (char *)version_info)) != RKINIT_SUCCESS)
+ return(status);
+
+ *s_lversion = (int) version_info[0];
+ *s_hversion = (int) version_info[1];
+
+ return(RKINIT_SUCCESS);
+}
+
+#ifdef __STDC__
+int rki_rpc_send_rkinit_info(rkinit_info *info)
+#else
+int rki_rpc_send_rkinit_info(info)
+ rkinit_info *info;
+#endif /* __STDC__ */
+{
+ rkinit_info info_copy;
+
+ bcopy(info, &info_copy, sizeof(rkinit_info));
+ info_copy.lifetime = htonl(info_copy.lifetime);
+ return(rki_send_packet(sock, MT_RKINIT_INFO, sizeof(rkinit_info),
+ (char *)&info_copy));
+}
+
+#ifdef __STDC__
+int rki_rpc_get_status(void)
+#else
+int rki_rpc_get_status()
+#endif /* __STDC__ */
+{
+ char msg[BUFSIZ];
+ int status = RKINIT_SUCCESS;
+ u_int32_t length = sizeof(msg);
+
+ if ((status = rki_get_packet(sock, MT_STATUS, &length, msg)))
+ return(status);
+
+ if (length == 0)
+ return(RKINIT_SUCCESS);
+ else {
+ rkinit_errmsg(msg);
+ return(RKINIT_DAEMON);
+ }
+}
+
+#ifdef __STDC__
+int rki_rpc_get_ktext(int sock, KTEXT auth, u_char type)
+#else
+int rki_rpc_get_ktext(sock, auth, type)
+ int sock;
+ KTEXT auth;
+ u_char type;
+#endif /* __STDC__ */
+{
+ int status = RKINIT_SUCCESS;
+ u_int32_t length = MAX_KTXT_LEN;
+
+ if ((status = rki_get_packet(sock, type, &length, (char *)auth->dat)))
+ return(status);
+
+ auth->length = length;
+
+ return(RKINIT_SUCCESS);
+}
+
+#ifdef __STDC__
+int rki_rpc_sendauth(KTEXT auth)
+#else
+int rki_rpc_sendauth(auth)
+ KTEXT auth;
+#endif /* __STDC__ */
+{
+ return(rki_send_packet(sock, MT_AUTH, auth->length, (char *)auth->dat));
+}
+
+
+#ifdef __STDC__
+int rki_rpc_get_skdc(KTEXT scip)
+#else
+int rki_rpc_get_skdc(scip)
+ KTEXT scip;
+#endif /* __STDC__ */
+{
+ return(rki_rpc_get_ktext(sock, scip, MT_SKDC));
+}
+
+#ifdef __STDC__
+int rki_rpc_send_ckdc(MSG_DAT *scip)
+#else
+int rki_rpc_send_ckdc(scip)
+ MSG_DAT *scip;
+#endif /* __STDC__ */
+{
+ return(rki_send_packet(sock, MT_CKDC, scip->app_length,
+ (char *)scip->app_data));
+}
+
+#ifdef __STDC__
+int rki_get_csaddr(struct sockaddr_in *caddrp, struct sockaddr_in *saddrp)
+#else
+int rki_get_csaddr(caddrp, saddrp)
+ struct sockaddr_in *caddrp;
+ struct sockaddr_in *saddrp;
+#endif /* __STDC__ */
+{
+ int addrlen = sizeof(struct sockaddr_in);
+
+ bcopy((char *)&saddr, (char *)saddrp, addrlen);
+
+ if (getsockname(sock, (struct sockaddr *)caddrp, &addrlen) < 0) {
+ sprintf(errbuf, "getsockname: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_GETSOCK);
+ }
+
+ return(RKINIT_SUCCESS);
+}
+
+#ifdef __STDC__
+void rki_drop_server(void)
+#else
+void rki_drop_server()
+#endif /* __STDC__ */
+{
+ (void) rki_send_packet(sock, MT_DROP, 0, "");
+}
+
+#ifdef __STDC__
+void rki_cleanup_rpc(void)
+#else
+void rki_cleanup_rpc()
+#endif /* __STDC__ */
+{
+ rki_drop_server();
+ (void) close(sock);
+}
diff --git a/eBones/lib/librkinit/rk_util.c b/eBones/lib/librkinit/rk_util.c
new file mode 100644
index 0000000000000..4333d38d306f9
--- /dev/null
+++ b/eBones/lib/librkinit/rk_util.c
@@ -0,0 +1,214 @@
+/*
+ * $Id: rk_util.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/librkinit/RCS/rk_util.c,v $
+ * $Author: dglo $
+ *
+ * This file contains internal routines for general use by the rkinit
+ * library and server.
+ *
+ * See the comment at the top of rk_lib.c for a description of the naming
+ * conventions used within the rkinit library.
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: rk_util.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/time.h>
+
+#ifdef DEBUG
+#include <syslog.h>
+#endif /* DEBUG */
+
+#include <rkinit.h>
+#include <rkinit_private.h>
+#include <rkinit_err.h>
+
+#define RKINIT_TIMEOUTVAL 60
+
+static char errbuf[BUFSIZ];
+static jmp_buf timeout_env;
+
+#ifdef DEBUG
+static int _rkinit_server_ = FALSE;
+
+#ifdef __STDC__
+void rki_dmsg(char *string)
+#else
+void rki_dmsg(string)
+ char *string;
+#endif /* __STDC__ */
+{
+ if (_rkinit_server_)
+ syslog(LOG_NOTICE, string);
+ else
+ printf("%s\n", string);
+}
+
+#ifdef __STDC__
+void rki_i_am_server(void)
+#else
+void rki_i_am_server()
+#endif /* __STDC__ */
+{
+ _rkinit_server_ = TRUE;
+}
+#else /* DEBUG */
+#ifdef __STDC__
+void rki_dmsg(char *string)
+#else
+void rki_dmsg(string)
+ char *string;
+#endif /* __STDC__ */
+{
+ return;
+}
+
+#endif /* DEBUG */
+
+#ifdef __STDC__
+const char *rki_mt_to_string(int mt)
+#else
+const char *rki_mt_to_string(mt)
+ int mt;
+#endif /* __STDC__ */
+{
+ char *string = 0;
+
+ switch(mt) {
+ case MT_STATUS:
+ string = "Status message";
+ break;
+ case MT_CVERSION:
+ string = "Client version";
+ break;
+ case MT_SVERSION:
+ string = "Server version";
+ break;
+ case MT_RKINIT_INFO:
+ string = "Rkinit information";
+ break;
+ case MT_SKDC:
+ string = "Server kdc packet";
+ break;
+ case MT_CKDC:
+ string = "Client kdc packet";
+ break;
+ case MT_AUTH:
+ string = "Authenticator";
+ break;
+ case MT_DROP:
+ string = "Drop server";
+ break;
+ default:
+ string = "Unknown message type";
+ break;
+ }
+
+ return(string);
+}
+
+#ifdef __STDC__
+int rki_choose_version(int *version)
+#else
+int rki_choose_version(version)
+ int *version;
+#endif /* __STDC__ */
+{
+ int s_lversion; /* lowest version number server supports */
+ int s_hversion; /* highest version number server supports */
+ int status = RKINIT_SUCCESS;
+
+ if ((status =
+ rki_rpc_exchange_version_info(RKINIT_LVERSION, RKINIT_HVERSION,
+ &s_lversion,
+ &s_hversion)) != RKINIT_SUCCESS)
+ return(status);
+
+ *version = min(RKINIT_HVERSION, s_hversion);
+ if (*version < max(RKINIT_LVERSION, s_lversion)) {
+ sprintf(errbuf,
+ "Can't run version %d client against version %d server.",
+ RKINIT_HVERSION, s_hversion);
+ rkinit_errmsg(errbuf);
+ status = RKINIT_VERSION;
+ }
+
+ return(status);
+}
+
+#ifdef __STDC__
+int rki_send_rkinit_info(int version, rkinit_info *info)
+#else
+int rki_send_rkinit_info(version, info)
+ int version;
+ rkinit_info *info;
+#endif /* __STDC__ */
+{
+ int status = 0;
+
+ if ((status = rki_rpc_send_rkinit_info(info)) != RKINIT_SUCCESS)
+ return(status);
+
+ return(rki_rpc_get_status());
+}
+
+#ifdef __STDC__
+static void rki_timeout(int signal)
+#else
+static void rki_timeout(signal)
+ int signal;
+#endif /* __STDC__ */
+{
+ sprintf(errbuf, "%d seconds exceeded.", RKINIT_TIMEOUTVAL);
+ rkinit_errmsg(errbuf);
+ longjmp(timeout_env, RKINIT_TIMEOUT);
+ return;
+}
+
+#ifdef __STDC__
+static void set_timer(int secs)
+#else
+static void set_timer(secs)
+ int secs;
+#endif /* __STDC__ */
+{
+ struct itimerval timer; /* Time structure for timeout */
+
+ /* Set up an itimer structure to send an alarm signal after TIMEOUT
+ seconds. */
+ timer.it_interval.tv_sec = secs;
+ timer.it_interval.tv_usec = 0;
+ timer.it_value = timer.it_interval;
+
+ (void) setitimer (ITIMER_REAL, &timer, (struct itimerval *)0);
+}
+
+
+#ifdef __STDC__
+void (*rki_setup_timer(jmp_buf env))(int)
+#else
+void (*rki_setup_timer(env))(int)
+ jmp_buf env;
+#endif /* __STDC__ */
+{
+ bcopy((char *)env, (char *)timeout_env, sizeof(jmp_buf));
+ set_timer(RKINIT_TIMEOUTVAL);
+ return(signal(SIGALRM, rki_timeout));
+}
+
+#ifdef __STDC__
+void rki_restore_timer(void (*old_alrm)(int))
+#else
+void rki_restore_timer(old_alrm)
+ void (*old_alrm)(int);
+#endif /* __STDC__ */
+{
+ set_timer(0);
+ (void) signal(SIGALRM, old_alrm);
+}
diff --git a/eBones/lib/librkinit/rkinit.3 b/eBones/lib/librkinit/rkinit.3
new file mode 100644
index 0000000000000..fe6bdf7a1fb65
--- /dev/null
+++ b/eBones/lib/librkinit/rkinit.3
@@ -0,0 +1,167 @@
+.\"
+.\" $Header: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinit.3,v 1.1 1991/12/03 23:21:29 eichin Exp $
+.\" $Source: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinit.3,v $
+.\" $Author: eichin $
+.\"
+.\"
+.TH RKINIT 3 "November 12, 1989"
+.SH NAME
+rkinit, rkinit_errmsg
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <rkinit.h>
+#include <rkinit_err.h>
+.PP
+.ft B
+int rkinit(host, r_krealm, info, timeout)
+ char *host;
+ char *r_krealm;
+ rkinit_info *info;
+ int timeout;
+.PP
+.ft B
+char *rkinit_errmsg(string)
+ char *string;
+.fi
+.ft R
+.SH DESCRIPTION
+This library contains the calls necessary to interface with the
+.I rkinit
+system of remote ticket establishment. See
+.IR rkinit (1)
+for more information on
+.I rkinit
+.PP
+.I rkinit.h
+is the header file that contains information that all clients
+will need to use.
+.PP
+.I rkinit_err.h
+is the
+.I com_err
+error table header file. See
+.IR com_err (3)
+for more information about
+.I com_err.
+.PP
+.IR rkinit ()
+takes as arguments the name of the host on which you wish to
+establish tickets, the kerberos realm of the remote host, a
+fully initialized rkinit_info structure, and a boolean value
+telling
+whether or not
+.IR rkinit ()
+should time out if the transaction
+fails to complete after a certain about of time.
+This call does not know about about default values, so
+something must be filled in for everything except for the ticket
+filename in the rkinit_info structure described below.
+
+.nf
+.nj
+.ft B
+This is the rkinit_info type:
+
+typedef struct {
+ char aname[ANAME_SZ + 1];
+ char inst[INST_SZ + 1];
+ char realm[REALM_SZ + 1];
+ char sname[ANAME_SZ + 1];
+ char sinst[INST_SZ + 1];
+ char username[9]; /* max local name length + 1 */
+ char tktfilename[MAXPATHLEN + 1];
+ long lifetime;
+} rkinit_info;
+.fi
+.ft R
+
+.I aname
+is the name part of the kerberos principal for which tickets are
+being requested.
+
+.I inst
+is the instance part.
+
+.I realm
+is the realm part.
+
+.I sname
+is the service name of the key that will appear in the remote
+initial ticket (for example, "krbtgt").
+
+.I sname
+is the service instance.
+
+.I username
+is the name of the local user on the remote host who will own
+the ticket file.
+
+.I tktfilename
+is the name of the file on the remote host in which the
+tickets will be stored. This is the only field in the structure
+for which a blank value is filled in. If this value is left
+blank, the server will figure out what to call the ticket file
+by using the kerberos library default as determined by
+.I TKT_FILE
+as defined in
+.IR krb.h .
+
+.I lifetime
+is the lifetime of the tickets in the usual five minute
+intervals. It is possible with this routine, as with
+.IR krb_get_in_tkt (3)
+to request tickets with zero lifetime.
+
+.IR rkinit (),
+while it is running, opens a socket, changes the name
+of the default kerberos ticket file, and changes the signal
+handler for the ALRM signal (if timeout != 0). rkinit()
+restores all these values when it exits whether it exits with
+an error or not, so clients using the rkinit library need not
+worry about this information.
+
+.IR rkinit_errmsg ()
+takes a string as its only argument. Passing
+other than NULL to this routine should be done
+by only the rkinit library and server.
+Doing this sets the current rkinit
+error message. Calling
+.IR rkinit_errmsg ()
+with NULL as the argument returns the current rkinit error
+message.
+Although the rkinit library uses
+.IR com_err (3)
+for error handling, the error messages returned by
+.IR com_err ()
+may not be specific enough. A client could report the error
+message returned by rkinit as follows:
+
+
+.nf
+.nj
+.ft B
+if (status = rkinit(host, r_krealm, &info, timeout)) {
+ com_err(argv[0], status, "while obtaining remote tickets:");
+ fprintf(stderr, "%s\\n", rkinit_errmsg(0));
+ exit(1);
+}
+.fi
+.ft R
+
+.SH SEE ALSO
+kerberos(1), kerberos(3), rkinit(1), rkinitd(8)
+
+.SH DIAGNOSTICS
+.IR rkinit ()
+is usually good about reporting error messages to the client.
+It will probably not handle uninitialized variables well,
+however. Make sure that things like the realm of the remote
+host and the lifetime of the tickets have been properly
+initialized before calling
+.IR rkinit ().
+
+
+.SH AUTHOR
+Emanuel Jay Berkenbilt (MIT-Project Athena)
diff --git a/eBones/lib/librkinit/rkinit_err.et b/eBones/lib/librkinit/rkinit_err.et
new file mode 100644
index 0000000000000..d0ade5ba11cbc
--- /dev/null
+++ b/eBones/lib/librkinit/rkinit_err.et
@@ -0,0 +1,32 @@
+#
+# $Header: /local/cvsfiles/kerberos/src/appl/rkinit/lib/rkinit_err.et,v 1.1 1991/12/03 23:20:58 eichin Exp $
+# $Source: /local/cvsfiles/kerberos/src/appl/rkinit/lib/rkinit_err.et,v $
+# $Author: eichin $
+#
+# These error messages will probably not be printed by com_err.
+# Instead, a better error message (with specific information)
+# will be obtained by a call to rkinit_errmsg().
+#
+
+et rkin
+
+ec RKINIT_RCSID, "$Header: /local/cvsfiles/kerberos/src/appl/rkinit/lib/rkinit_err.et,v 1.1 1991/12/03 23:20:58 eichin Exp $"
+ec RKINIT_VERSION, "Version mismatch"
+ec RKINIT_HOST, "Failure getting host information"
+ec RKINIT_SERV, "Failure getting service information (/etc/services)"
+ec RKINIT_SOCKET, "Failure setting up socket"
+ec RKINIT_CONNECT, "Failure connecting"
+ec RKINIT_PACKET, "Bad packet type"
+ec RKINIT_WRITE, "Failure writing"
+ec RKINIT_READ, "Failure reading"
+ec RKINIT_DAEMON, "Error reported by rkinitd"
+ec RKINIT_KERBEROS, "Kerberos error"
+ec RKINIT_DES, "Des error"
+ec RKINIT_GETPEER, "Failure in getpeername"
+ec RKINIT_GETSOCK, "Failure in getsockname"
+ec RKINIT_MEMORY, "Out of memory"
+ec RKINIT_TIMEOUT, "Timed out"
+ec RKINIT_DROPPED, "Connection dropped"
+
+ec RKINIT_LAST, "Last error message"
+end
diff --git a/eBones/libexec/Makefile b/eBones/libexec/Makefile
new file mode 100644
index 0000000000000..b7193e672228e
--- /dev/null
+++ b/eBones/libexec/Makefile
@@ -0,0 +1,6 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.1 1995/09/13 17:23:59 markm Exp $
+
+SUBDIR= kpropd registerd rkinitd
+
+.include <bsd.subdir.mk>
diff --git a/eBones/libexec/Makefile.inc b/eBones/libexec/Makefile.inc
new file mode 100644
index 0000000000000..d694f9b03653d
--- /dev/null
+++ b/eBones/libexec/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+BINDIR?= /usr/libexec
+
+.include "../Makefile.inc"
diff --git a/eBones/libexec/kpropd/Makefile b/eBones/libexec/kpropd/Makefile
new file mode 100644
index 0000000000000..0f1f420eda8b2
--- /dev/null
+++ b/eBones/libexec/kpropd/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:02 markm Exp $
+
+PROG= kpropd
+CFLAGS+=-I${.CURDIR}/../../usr.sbin/kprop
+DPADD+= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/libexec/kpropd/kpropd.c b/eBones/libexec/kpropd/kpropd.c
new file mode 100644
index 0000000000000..1b232dfc0ded5
--- /dev/null
+++ b/eBones/libexec/kpropd/kpropd.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright 1987 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * MIT.Copyright.
+ *
+ * kprop/kpropd have been abandonded by Project Athena (for good reason)
+ * however they still form the basis for one of the better ways for
+ * distributing kerberos databases. This version of kpropd has been
+ * adapted from the MIT distribution to work properly in a 4.4BSD
+ * environment.
+ *
+ * $Revision: 1.1.1.1 $ $Date: 1995/08/03 07:37:19 $ $State: Exp $
+ * $Source: /usr/cvs/src/eBones/kpropd/kpropd.c,v $
+ *
+ * Log: kpropd.c,v
+ * Revision 4.5 92/10/23 15:45:46 tytso Make it possible
+ * to specify the location of the kdb_util program.
+ *
+ * Revision 4.4 91/06/15 03:20:51 probe Fixed <sys/types.h> inclusion
+ *
+ * Revision 4.3 89/05/16 15:06:04 wesommer Fix operator precedence stuff.
+ * Programmer: John Kohl.
+ *
+ * Revision 4.2 89/03/23 10:24:00 jtkohl NOENCRYPTION changes
+ *
+ * Revision 4.1 89/01/24 20:33:48 root name change
+ *
+ * Revision 4.0 89/01/24 18:45:06 wesommer Original version; programmer:
+ * wesommer auditor: jon
+ *
+ * Revision 4.5 88/01/08 18:07:46 jon formatting and rcs header changes */
+
+/*
+ * This program is run on slave servers, to catch updates "pushed" from the
+ * master kerberos server in a realm.
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_kpropd_c[] =
+"$Header: /usr/cvs/src/eBones/kpropd/kpropd.c,v 1.1.1.1 1995/08/03 07:37:19 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <syslog.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#include "kprop.h"
+
+static char kprop_version[KPROP_PROT_VERSION_LEN] = KPROP_PROT_VERSION;
+
+int debug = 0;
+
+int pause_int = 300; /* 5 minutes in seconds */
+unsigned long get_data_checksum(int fd, Key_schedule key_sched);
+void recv_auth(int in, int out, int private,
+ struct sockaddr_in *remote, struct sockaddr_in *local,
+ AUTH_DAT *ad);
+static void SlowDeath(void);
+void recv_clear(int in, int out);
+ /* leave room for private msg overhead */
+static char buf[KPROP_BUFSIZ + 64];
+
+static void
+usage()
+{
+ fprintf(stderr, "\nUsage: kpropd [-r realm] [-s srvtab] [-P kdb_util] fname\n");
+ exit(2);
+}
+
+void
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct sockaddr_in from;
+ struct sockaddr_in sin;
+ int s2, fd, n, fdlock;
+ int from_len;
+ char local_file[256];
+ char local_temp[256];
+ struct hostent *hp;
+ char hostname[256];
+ char from_str[128];
+ long kerror;
+ AUTH_DAT auth_dat;
+ KTEXT_ST ticket;
+ char my_instance[INST_SZ];
+ char my_realm[REALM_SZ];
+ char cmd[1024];
+ short net_transfer_mode, transfer_mode;
+ Key_schedule session_sched;
+ char version[9];
+ int c;
+ extern char *optarg;
+ extern int optind;
+ int rflag = 0;
+ char *srvtab = "";
+ char *local_db = DBM_FILE;
+ char *kdb_util = KPROP_KDB_UTIL;
+
+ if (argv[argc - 1][0] == 'k' && isdigit(argv[argc - 1][1])) {
+ argc--; /* ttys file hack */
+ }
+ while ((c = getopt(argc, argv, "r:s:d:P:")) != EOF) {
+ switch (c) {
+ case 'r':
+ rflag++;
+ strcpy(my_realm, optarg);
+ break;
+ case 's':
+ srvtab = optarg;
+ break;
+ case 'd':
+ local_db = optarg;
+ break;
+ case 'P':
+ kdb_util = optarg;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+ if (optind != argc - 1)
+ usage();
+
+ openlog("kpropd", LOG_PID, LOG_AUTH);
+
+ strcpy(local_file, argv[optind]);
+ strcat(strcpy(local_temp, argv[optind]), ".tmp");
+
+#ifdef STANDALONE
+
+ if ((sp = getservbyname("krb_prop", "tcp")) == NULL) {
+ syslog(LOG_ERR, "tcp/krb_prop: unknown service.");
+ SlowDeath();
+ }
+ bzero(&sin, sizeof sin);
+ sin.sin_port = sp->s_port;
+ sin.sin_family = AF_INET;
+
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ syslog(LOG_ERR, "socket: %m");
+ SlowDeath();
+ }
+ if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) {
+ syslog(LOG_ERR, "bind: %m");
+ SlowDeath();
+ }
+
+#endif /* STANDALONE */
+
+ if (!rflag) {
+ kerror = krb_get_lrealm(my_realm, 1);
+ if (kerror != KSUCCESS) {
+ syslog(LOG_ERR, "can't get local realm. %s",
+ krb_err_txt[kerror]);
+ SlowDeath();
+ }
+ }
+ if (gethostname(my_instance, sizeof(my_instance)) != 0) {
+ syslog(LOG_ERR, "gethostname: %m");
+ SlowDeath();
+ }
+
+#ifdef STANDALONE
+ listen(s, 5);
+ for (;;) {
+ from_len = sizeof from;
+ if ((s2 = accept(s, (struct sockaddr *)&from, &from_len)) < 0) {
+ syslog(LOG_ERR, "accept: %m");
+ continue;
+ }
+#else /* !STANDALONE */
+
+ s2 = 0;
+ from_len = sizeof from;
+ if (getpeername(0, (struct sockaddr *)&from, &from_len) < 0) {
+ syslog(LOG_ERR, "getpeername: %m");
+ SlowDeath();
+ }
+
+#endif /* !STANDALONE */
+
+ strcpy(from_str, inet_ntoa(from.sin_addr));
+
+ if ((hp = gethostbyaddr((char *) &(from.sin_addr.s_addr),
+ from_len, AF_INET)) == NULL) {
+ strcpy(hostname, "UNKNOWN");
+ } else {
+ strcpy(hostname, hp->h_name);
+ }
+
+ syslog(LOG_INFO, "connection from %s, %s", hostname, from_str);
+
+ /* for krb_rd_{priv, safe} */
+ n = sizeof sin;
+ if (getsockname(s2, (struct sockaddr *)&sin, &n) != 0) {
+ syslog(LOG_ERR, "can't get socketname: %m");
+ SlowDeath();
+ }
+ if (n != sizeof(sin)) {
+ syslog(LOG_ERR, "can't get socketname (length)");
+ SlowDeath();
+ }
+ if ((fdlock = open(local_temp, O_WRONLY | O_CREAT, 0600)) < 0) {
+ syslog(LOG_ERR, "open: %m");
+ SlowDeath();
+ }
+ if (flock(fdlock, LOCK_EX | LOCK_NB)) {
+ syslog(LOG_ERR, "flock: %m");
+ SlowDeath();
+ }
+ if ((fd = creat(local_temp, 0600)) < 0) {
+ syslog(LOG_ERR, "creat: %m");
+ SlowDeath();
+ }
+ if ((n = read(s2, buf, sizeof(kprop_version)))
+ != sizeof(kprop_version)) {
+ syslog(LOG_ERR,
+ "can't read protocol version (%d bytes)", n);
+ SlowDeath();
+ }
+ if (strncmp(buf, kprop_version, sizeof(kprop_version)) != 0) {
+ syslog(LOG_ERR, "unsupported version %s", buf);
+ SlowDeath();
+ }
+ if ((n = read(s2, &net_transfer_mode,
+ sizeof(net_transfer_mode)))
+ != sizeof(net_transfer_mode)) {
+ syslog(LOG_ERR, "can't read transfer mode");
+ SlowDeath();
+ }
+ transfer_mode = ntohs(net_transfer_mode);
+ kerror = krb_recvauth(KOPT_DO_MUTUAL, s2, &ticket,
+ KPROP_SERVICE_NAME,
+ my_instance,
+ &from,
+ &sin,
+ &auth_dat,
+ srvtab,
+ session_sched,
+ version);
+ if (kerror != KSUCCESS) {
+ syslog(LOG_ERR, "%s calling getkdata",
+ krb_err_txt[kerror]);
+ SlowDeath();
+ }
+ syslog(LOG_INFO, "connection from %s.%s@%s",
+ auth_dat.pname, auth_dat.pinst, auth_dat.prealm);
+
+ /*
+ * AUTHORIZATION is done here. We might want to expand this
+ * to read an acl file at some point, but allowing for now
+ * KPROP_SERVICE_NAME.KRB_MASTER@local-realm is fine ...
+ */
+
+ if ((strcmp(KPROP_SERVICE_NAME, auth_dat.pname) != 0) ||
+ (strcmp(KRB_MASTER, auth_dat.pinst) != 0) ||
+ (strcmp(my_realm, auth_dat.prealm) != 0)) {
+ syslog(LOG_NOTICE, "authorization denied");
+ SlowDeath();
+ }
+ switch (transfer_mode) {
+ case KPROP_TRANSFER_PRIVATE:
+ recv_auth(s2, fd, 1 /* private */ , &from, &sin, &auth_dat);
+ break;
+ case KPROP_TRANSFER_SAFE:
+ recv_auth(s2, fd, 0 /* safe */ , &from, &sin, &auth_dat);
+ break;
+ case KPROP_TRANSFER_CLEAR:
+ recv_clear(s2, fd);
+ break;
+ default:
+ syslog(LOG_ERR, "bad transfer mode %d", transfer_mode);
+ SlowDeath();
+ }
+
+ if (transfer_mode != KPROP_TRANSFER_PRIVATE) {
+ syslog(LOG_ERR, "non-private transfers not supported\n");
+ SlowDeath();
+#ifdef doesnt_work_yet
+ lseek(fd, (long) 0, L_SET);
+ if (auth_dat.checksum != get_data_checksum(fd, session_sched)) {
+ syslog(LOG_ERR, "checksum doesn't match");
+ SlowDeath();
+ }
+#endif
+ } else {
+ struct stat st;
+ fstat(fd, &st);
+ if (st.st_size != auth_dat.checksum) {
+ syslog(LOG_ERR, "length doesn't match");
+ SlowDeath();
+ }
+ }
+ close(fd);
+ close(s2);
+
+ if (rename(local_temp, local_file) < 0) {
+ syslog(LOG_ERR, "rename: %m");
+ SlowDeath();
+ }
+
+ if (flock(fdlock, LOCK_UN)) {
+ syslog(LOG_ERR, "flock (unlock): %m");
+ SlowDeath();
+ }
+ close(fdlock);
+ sprintf(cmd, "%s load %s %s\n", kdb_util, local_file, local_db);
+ if (system(cmd) != 0) {
+ syslog(LOG_ERR, "couldn't load database");
+ SlowDeath();
+ }
+
+#ifdef STANDALONE
+ }
+#endif
+
+}
+
+void
+recv_auth(in, out, private, remote, local, ad)
+ int in, out;
+ int private;
+ struct sockaddr_in *remote, *local;
+ AUTH_DAT *ad;
+{
+ u_long length;
+ long kerror;
+ int n;
+ MSG_DAT msg_data;
+ Key_schedule session_sched;
+
+ if (private)
+#ifdef NOENCRYPTION
+ bzero((char *) session_sched, sizeof(session_sched));
+#else
+ if (key_sched((C_Block *)ad->session, session_sched)) {
+ syslog(LOG_ERR, "can't make key schedule");
+ SlowDeath();
+ }
+#endif
+
+ while (1) {
+ n = krb_net_read(in, (char *)&length, sizeof length);
+ if (n == 0)
+ break;
+ if (n < 0) {
+ syslog(LOG_ERR, "read: %m");
+ SlowDeath();
+ }
+ length = ntohl(length);
+ if (length > sizeof buf) {
+ syslog(LOG_ERR, "read length %d, bigger than buf %d",
+ length, sizeof buf);
+ SlowDeath();
+ }
+ n = krb_net_read(in, buf, length);
+ if (n < 0) {
+ syslog(LOG_ERR, "kpropd: read: %m");
+ SlowDeath();
+ }
+ if (private)
+ kerror = krb_rd_priv(buf, n, session_sched, ad->session,
+ remote, local, &msg_data);
+ else
+ kerror = krb_rd_safe(buf, n, (C_Block *)ad->session,
+ remote, local, &msg_data);
+ if (kerror != KSUCCESS) {
+ syslog(LOG_ERR, "%s: %s",
+ private ? "krb_rd_priv" : "krb_rd_safe",
+ krb_err_txt[kerror]);
+ SlowDeath();
+ }
+ if (write(out, msg_data.app_data, msg_data.app_length) !=
+ msg_data.app_length) {
+ syslog(LOG_ERR, "write: %m");
+ SlowDeath();
+ }
+ }
+}
+
+void
+recv_clear(in, out)
+ int in, out;
+{
+ int n;
+
+ while (1) {
+ n = read(in, buf, sizeof buf);
+ if (n == 0)
+ break;
+ if (n < 0) {
+ syslog(LOG_ERR, "read: %m");
+ SlowDeath();
+ }
+ if (write(out, buf, n) != n) {
+ syslog(LOG_ERR, "write: %m");
+ SlowDeath();
+ }
+ }
+}
+
+static void
+SlowDeath()
+{
+#ifdef STANDALONE
+ sleep(pause_int);
+#endif
+ exit(1);
+}
+
+#ifdef doesnt_work_yet
+unsigned long
+get_data_checksum(fd, key_sched)
+ int fd;
+ Key_schedule key_sched;
+{
+ unsigned long cksum = 0;
+ unsigned long cbc_cksum();
+ int n;
+ char buf[BUFSIZ];
+ char obuf[8];
+
+ while (n = read(fd, buf, sizeof buf)) {
+ if (n < 0) {
+ syslog(LOG_ERR, "read (in checksum test): %m");
+ SlowDeath();
+ }
+#ifndef NOENCRYPTION
+ cksum += cbc_cksum(buf, obuf, n, key_sched, key_sched);
+#endif
+ }
+ return cksum;
+}
+#endif
diff --git a/eBones/libexec/registerd/Makefile b/eBones/libexec/registerd/Makefile
new file mode 100644
index 0000000000000..af9e2cab5ef7a
--- /dev/null
+++ b/eBones/libexec/registerd/Makefile
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 1990 The Regents of the University of California.
+# All rights reserved.
+#
+# %sccs.include.redist.sh
+#
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+#
+# $Id: Makefile,v 1.4 1995/09/13 17:24:03 markm Exp $
+
+PROG= registerd
+SRCS= registerd.c
+CFLAGS+=-DCRYPT -DKERBEROS -I${.CURDIR}/../../usr.bin/register
+DPADD+= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN8= registerd.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/libexec/registerd/registerd.c b/eBones/libexec/registerd/registerd.c
new file mode 100644
index 0000000000000..36c7a742ac467
--- /dev/null
+++ b/eBones/libexec/registerd/registerd.c
@@ -0,0 +1,355 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+static char sccsid[] = "@(#)registerd.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <sys/resource.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <syslog.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "register_proto.h"
+#include "pathnames.h"
+
+#define KBUFSIZ (sizeof(struct keyfile_data))
+#define RCRYPT 0x00
+#define CLEAR 0x01
+
+char *progname, msgbuf[BUFSIZ];
+
+void cleanup(void);
+void die(int);
+void send_packet(char *msg, int flag);
+int net_get_principal(char *pname, char *iname, C_Block *keyp);
+int do_append(struct sockaddr_in *sinp);
+
+void
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ static Key_schedule schedule;
+ static struct rlimit rl = { 0, 0 };
+ struct keyfile_data *kfile;
+ u_char code;
+ int kf, retval, sval;
+ struct sockaddr_in sin;
+ char keyfile[MAXPATHLEN], keybuf[KBUFSIZ];
+
+ progname = argv[0]; /* for the library routines */
+
+ openlog("registerd", LOG_PID, LOG_AUTH);
+
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTSTP, SIG_IGN);
+ signal(SIGPIPE, die);
+
+ if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+ syslog(LOG_ERR, "setrlimit: %m");
+ exit(1);
+ }
+
+
+ /* figure out who we are talking to */
+
+ sval = sizeof(sin);
+ if (getpeername(0, (struct sockaddr *) &sin, &sval) < 0) {
+ syslog(LOG_ERR, "getpeername: %m");
+ exit(1);
+ }
+
+ /* get encryption key */
+
+ (void) sprintf(keyfile, "%s/%s%s",
+ SERVER_KEYDIR,
+ KEYFILE_BASE,
+ inet_ntoa(sin.sin_addr));
+
+ if ((kf = open(keyfile, O_RDONLY)) < 0) {
+ syslog(LOG_ERR,
+ "error opening Kerberos update keyfile (%s): %m", keyfile);
+ sprintf(msgbuf,
+ "couldn't open session keyfile for your host");
+ send_packet(msgbuf, CLEAR);
+ exit(1);
+ }
+
+ if (read(kf, keybuf, KBUFSIZ) != KBUFSIZ) {
+ syslog(LOG_ERR, "wrong read size of Kerberos update keyfile");
+ sprintf(msgbuf,
+ "couldn't read session key from your host's keyfile");
+ send_packet(msgbuf, CLEAR);
+ exit(1);
+ }
+ sprintf(msgbuf, GOTKEY_MSG);
+ send_packet(msgbuf, CLEAR);
+ kfile = (struct keyfile_data *) keybuf;
+ key_sched((C_Block *)kfile->kf_key, schedule);
+ des_set_key((des_cblock *)kfile->kf_key, schedule);
+
+ /* read the command code byte */
+
+ if (des_read(0, &code, 1) == 1) {
+
+ switch(code) {
+ case APPEND_DB:
+ retval = do_append(&sin);
+ break;
+ case ABORT:
+ cleanup();
+ close(0);
+ exit(0);
+ default:
+ retval = KFAILURE;
+ syslog(LOG_NOTICE,
+ "invalid command code on db update (0x%x)",
+ code);
+ }
+
+ } else {
+ retval = KFAILURE;
+ syslog(LOG_ERR,
+ "couldn't read command code on Kerberos update");
+ }
+
+ code = (u_char) retval;
+ if (code != KSUCCESS) {
+ sprintf(msgbuf, "%s", krb_err_txt[code]);
+ send_packet(msgbuf, RCRYPT);
+ } else {
+ sprintf(msgbuf, "Update complete.");
+ send_packet(msgbuf, RCRYPT);
+ }
+ cleanup();
+ close(0);
+ exit(0);
+}
+
+#define MAX_PRINCIPAL 10
+static Principal principal_data[MAX_PRINCIPAL];
+static C_Block key, master_key;
+static Key_schedule master_key_schedule;
+
+int
+do_append(sinp)
+ struct sockaddr_in *sinp;
+{
+ Principal default_princ;
+ char input_name[ANAME_SZ];
+ char input_instance[INST_SZ];
+ int j,n, more;
+ long mkeyversion;
+
+
+
+ /* get master key from MKEYFILE */
+ if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) {
+ syslog(LOG_ERR, "couldn't get master key");
+ return(KFAILURE);
+ }
+
+ mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL);
+ if (mkeyversion < 0) {
+ syslog(LOG_ERR, "couldn't validate master key");
+ return(KFAILURE);
+ }
+
+ n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+
+ if (n != 1) {
+ syslog(LOG_ERR, "couldn't get default principal");
+ return(KFAILURE);
+ }
+
+ /*
+ * get principal name, instance, and password from network.
+ * convert password to key and store it
+ */
+
+ if (net_get_principal(input_name, input_instance, (C_Block *)key) != 0) {
+ return(KFAILURE);
+ }
+
+
+ j = kerb_get_principal(
+ input_name,
+ input_instance,
+ principal_data,
+ MAX_PRINCIPAL,
+ &more
+ );
+
+ if (j != 0) {
+ /* already in database, no update */
+ syslog(LOG_NOTICE,
+ "attempt to add duplicate entry for principal %s.%s",
+ input_name, input_instance);
+ return(KDC_PR_N_UNIQUE);
+ }
+
+ /*
+ * set up principal's name, instance
+ */
+
+ strcpy(principal_data[0].name, input_name);
+ strcpy(principal_data[0].instance, input_instance);
+ principal_data[0].old = NULL;
+
+
+ /* and the expiration date and version #s */
+
+ principal_data[0].exp_date = default_princ.exp_date;
+ strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt);
+ principal_data[0].max_life = default_princ.max_life;
+ principal_data[0].attributes = default_princ.attributes;
+ principal_data[0].kdc_key_ver = default_princ.kdc_key_ver;
+
+
+ /* and the key */
+
+ kdb_encrypt_key(key, key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(key, &principal_data[0].key_low, 4);
+ bcopy(((long *) key) + 1, &principal_data[0].key_high,4);
+ bzero(key, sizeof(key));
+
+ principal_data[0].key_version = 1; /* 1st entry */
+
+ /* and write it to the database */
+
+ if (kerb_put_principal(&principal_data[0], 1)) {
+ syslog(LOG_INFO, "Kerberos update failure: put_principal failed");
+ return(KFAILURE);
+ }
+
+ syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s",
+ principal_data[0].name,
+ principal_data[0].instance,
+ inet_ntoa(sinp->sin_addr)
+ );
+
+ return(KSUCCESS);
+
+}
+
+void
+send_packet(msg,flag)
+ char *msg;
+ int flag;
+{
+ int len = strlen(msg);
+ msg[len++] = '\n';
+ msg[len] = '\0';
+ if (len > sizeof(msgbuf)) {
+ syslog(LOG_ERR, "send_packet: invalid msg size");
+ return;
+ }
+ if (flag == RCRYPT) {
+ if (des_write(0, msg, len) != len)
+ syslog(LOG_ERR, "couldn't write reply message");
+ } else if (flag == CLEAR) {
+ if (write(0, msg, len) != len)
+ syslog(LOG_ERR, "couldn't write reply message");
+ } else
+ syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag);
+
+}
+
+int
+net_get_principal(pname, iname, keyp)
+ char *pname, *iname;
+ C_Block *keyp;
+{
+ int cc;
+ static char password[255];
+
+ cc = des_read(0, pname, ANAME_SZ);
+ if (cc != ANAME_SZ) {
+ syslog(LOG_ERR, "couldn't get principal name");
+ return(-1);
+ }
+
+ cc = des_read(0, iname, INST_SZ);
+ if (cc != INST_SZ) {
+ syslog(LOG_ERR, "couldn't get instance name");
+ return(-1);
+ }
+
+ cc = des_read(0, password, 255);
+ if (cc != 255) {
+ syslog(LOG_ERR, "couldn't get password");
+ bzero(password, 255);
+ return(-1);
+ }
+
+ string_to_key(password, (des_cblock *)*keyp);
+ bzero(password, 255);
+ return(0);
+}
+
+void
+cleanup()
+{
+ bzero(master_key, sizeof(master_key));
+ bzero(key, sizeof(key));
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+}
+
+void
+die(sig)
+ int sig;
+{
+ syslog(LOG_ERR, "remote end died (SIGPIPE)");
+ cleanup();
+ exit(1);
+}
diff --git a/eBones/libexec/rkinitd/Makefile b/eBones/libexec/rkinitd/Makefile
new file mode 100644
index 0000000000000..3872644163897
--- /dev/null
+++ b/eBones/libexec/rkinitd/Makefile
@@ -0,0 +1,12 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+
+PROG= rkinitd
+SRCS= ${RKINITOBJDIR}/rkinit_err.h rkinitd.c util.c rpc.c krb.c
+CFLAGS+=-I${KRBOBJDIR} -I${RKINITOBJDIR}
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${RKINITOBJDIR} -lrkinit -L${KRBOBJDIR} -lkrb \
+ -L${DESOBJDIR} -ldes
+
+MAN8= rkinitd.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/libexec/rkinitd/krb.c b/eBones/libexec/rkinitd/krb.c
new file mode 100644
index 0000000000000..23734db4307d4
--- /dev/null
+++ b/eBones/libexec/rkinitd/krb.c
@@ -0,0 +1,388 @@
+/*
+ * $Id: krb.c,v 1.1 1993/07/29 22:45:19 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/rkinitd/RCS/krb.c,v $
+ * $Author: dglo $
+ *
+ * This file contains all of the kerberos part of rkinitd.
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: krb.c,v 1.1 1993/07/29 22:45:19 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <syslog.h>
+#include <netinet/in.h>
+#include <setjmp.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <krb.h>
+#include <des.h>
+
+#include <rkinit.h>
+#include <rkinit_private.h>
+#include <rkinit_err.h>
+
+#include "rkinitd.h"
+
+#define FAILURE (!RKINIT_SUCCESS)
+
+extern int errno;
+
+static char errbuf[BUFSIZ];
+
+typedef struct {
+ jmp_buf env;
+} rkinitd_intkt_info;
+
+
+#if defined(_AIX) && defined(_IBMR2)
+
+#include <sys/id.h>
+
+/*
+ * The RIOS has bizzarre ideas about changing uids around. They are
+ * such that the seteuid and setruid calls here fail. For this reason
+ * we are replacing the seteuid and setruid calls.
+ *
+ * The bizzarre ideas are as follows:
+ *
+ * The effective ID may be changed only to the current real or
+ * saved IDs.
+ *
+ * The saved uid may be set only if the real and effective
+ * uids are being set to the same value.
+ *
+ * The real uid may be set only if the effective
+ * uid is being set to the same value.
+ */
+
+#ifdef __STDC__
+static int setruid(uid_t ruid)
+#else
+static int setruid(ruid)
+ uid_t ruid;
+#endif /* __STDC__ */
+{
+ uid_t euid;
+
+ euid = geteuid();
+
+ if (setuidx(ID_REAL | ID_EFFECTIVE, ruid) == -1)
+ return (-1);
+
+ return (setuidx(ID_EFFECTIVE, euid));
+}
+
+
+#ifdef __STDC__
+static int seteuid(uid_t euid)
+#else
+static int seteuid(euid)
+ uid_t euid;
+#endif /* __STDC__ */
+{
+ uid_t ruid;
+
+ ruid = getuid();
+
+ if (setuidx(ID_SAVED | ID_REAL | ID_EFFECTIVE, euid) == -1)
+ return (-1);
+
+ return (setruid(ruid));
+}
+
+
+#ifdef __STDC__
+static int setreuid(uid_t ruid, uid_t euid)
+#else
+static int setreuid(ruid, euid)
+ uid_t ruid;
+ uid_t euid;
+#endif /* __STDC__ */
+{
+ if (seteuid(euid) == -1)
+ return (-1);
+
+ return (setruid(ruid));
+}
+
+
+#ifdef __STDC__
+static int setuid(uid_t uid)
+#else
+static int setuid(uid)
+ uid_t uid;
+#endif /* __STDC__ */
+{
+ return (setreuid(uid, uid));
+}
+
+#endif /* RIOS */
+
+
+#ifdef __STDC__
+static void this_phost(char *host, int hostlen)
+#else
+static void this_phost(host, hostlen)
+ char *host;
+ int hostlen;
+#endif /* __STDC__ */
+{
+ char this_host[MAXHOSTNAMELEN + 1];
+
+ BCLEAR(this_host);
+
+ if (gethostname(this_host, sizeof(this_host)) < 0) {
+ sprintf(errbuf, "gethostname: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ error();
+ exit(1);
+ }
+
+ strncpy(host, krb_get_phost(this_host), hostlen - 1);
+}
+
+#ifdef __STDC__
+static int decrypt_tkt(char *user, char *instance, char *realm, char *arg,
+ int (*key_proc)(), KTEXT *cipp)
+#else
+static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ int (*key_proc)();
+ KTEXT *cipp;
+#endif /* __STDC__ */
+{
+ MSG_DAT msg_data; /* Message data containing decrypted data */
+ KTEXT_ST auth; /* Authenticator */
+ AUTH_DAT auth_dat; /* Authentication data */
+ KTEXT cip = *cipp;
+ MSG_DAT scip;
+ int status = 0;
+ des_cblock key;
+ des_key_schedule sched;
+ char phost[MAXHOSTNAMELEN + 1];
+ struct sockaddr_in caddr; /* client internet address */
+ struct sockaddr_in saddr; /* server internet address */
+
+ rkinitd_intkt_info *rii = (rkinitd_intkt_info *)arg;
+
+ u_char enc_data[MAX_KTXT_LEN];
+
+ SBCLEAR(auth);
+ SBCLEAR(auth_dat);
+ SBCLEAR(scip);
+ BCLEAR(enc_data);
+
+ scip.app_data = enc_data;
+
+ /*
+ * Exchange with the client our response from the KDC (ticket encrypted
+ * in user's private key) for the same ticket encrypted in our
+ * (not yet known) session key.
+ */
+
+ rpc_exchange_tkt(cip, &scip);
+
+ /*
+ * Get the authenticator
+ */
+
+ SBCLEAR(auth);
+
+ rpc_getauth(&auth, &caddr, &saddr);
+
+ /*
+ * Decode authenticator and extract session key. The first zero
+ * means we don't care what host this comes from. This needs to
+ * be done with euid of root so that /etc/srvtab can be read.
+ */
+
+ BCLEAR(phost);
+ this_phost(phost, sizeof(phost));
+
+ /*
+ * This function has to use longjmp to return to the caller
+ * because the kerberos library routine that calls it doesn't
+ * pay attention to the return value it gives. That means that
+ * if any of these routines failed, the error returned to the client
+ * would be "password incorrect".
+ */
+
+ if ((status = krb_rd_req(&auth, KEY, phost, caddr.sin_addr.s_addr,
+ &auth_dat, KEYFILE))) {
+ sprintf(errbuf, "krb_rd_req: %s", krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ longjmp(rii->env, status);
+ }
+
+ bcopy(auth_dat.session, key, sizeof(key));
+ if (des_key_sched(&key, sched)) {
+ sprintf(errbuf, "Error in des_key_sched");
+ rkinit_errmsg(errbuf);
+ longjmp(rii->env, RKINIT_DES);
+ }
+
+ /* Decrypt the data. */
+ if ((status =
+ krb_rd_priv((u_char *)scip.app_data, scip.app_length,
+ sched, key, &caddr, &saddr, &msg_data)) == KSUCCESS) {
+ cip->length = msg_data.app_length;
+ bcopy(msg_data.app_data, cip->dat, msg_data.app_length);
+ cip->dat[cip->length] = 0;
+ }
+ else {
+ sprintf(errbuf, "krb_rd_priv: %s", krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ longjmp(rii->env, status);
+ }
+
+ return(status);
+}
+
+#ifdef __STDC__
+static int validate_user(char *aname, char *inst, char *realm,
+ char *username, char *errmsg)
+#else
+static int validate_user(aname, inst, realm, username, errmsg)
+ char *aname;
+ char *inst;
+ char *realm;
+ char *username;
+ char *errmsg;
+#endif /* __STDC__ */
+{
+ struct passwd *pwnam; /* For access_check and uid */
+ AUTH_DAT auth_dat;
+ int kstatus = KSUCCESS;
+
+ SBCLEAR(auth_dat);
+
+ if ((pwnam = getpwnam(username)) == NULL) {
+ sprintf(errmsg, "%s does not exist on the remote host.", username);
+ return(FAILURE);
+ }
+
+ strcpy(auth_dat.pname, aname);
+ strcpy(auth_dat.pinst, inst);
+ strcpy(auth_dat.prealm, realm);
+
+ if (seteuid(pwnam->pw_uid) < 0) {
+ sprintf(errmsg, "Failure setting euid to %d: %s\n", pwnam->pw_uid,
+ sys_errlist[errno]);
+ strcpy(errbuf, errmsg);
+ error();
+ return(FAILURE);
+ }
+ kstatus = kuserok(&auth_dat, username);
+ if (seteuid(0) < 0) {
+ sprintf(errmsg, "Failure setting euid to 0: %s\n",
+ sys_errlist[errno]);
+ strcpy(errbuf, errmsg);
+ error();
+ return(FAILURE);
+ }
+
+ if (kstatus != KSUCCESS) {
+ sprintf(errmsg, "%s has not allowed you to log in with", username);
+ if (strlen(auth_dat.pinst))
+ sprintf(errmsg, "%s %s.%s", errmsg, auth_dat.pname,
+ auth_dat.pinst);
+ else
+ sprintf(errmsg, "%s %s", errmsg, auth_dat.pname);
+ sprintf(errmsg, "%s@%s tickets.", errmsg, auth_dat.prealm);
+ return(FAILURE);
+ }
+
+ /*
+ * Set real uid to owner of ticket file. The library takes care
+ * of making the appropriate change.
+ */
+ if (setruid(pwnam->pw_uid) < 0) {
+ sprintf(errmsg, "Failure setting ruid to %d: %s\n", pwnam->pw_uid,
+ sys_errlist[errno]);
+ strcpy(errbuf, errmsg);
+ error();
+ return(FAILURE);
+ }
+
+ return(RKINIT_SUCCESS);
+}
+
+#ifdef __STDC__
+int get_tickets(int version)
+#else
+int get_tickets(version)
+ int version;
+#endif /* __STDC__ */
+{
+ rkinit_info info;
+ AUTH_DAT auth_dat;
+
+ int status;
+ char errmsg[BUFSIZ]; /* error message for client */
+
+ rkinitd_intkt_info rii;
+
+ SBCLEAR(info);
+ SBCLEAR(auth_dat);
+ BCLEAR(errmsg);
+ SBCLEAR(rii);
+
+ rpc_get_rkinit_info(&info);
+
+ /*
+ * The validate_user routine makes sure that the principal in question
+ * is allowed to log in as username, and if so, does a setuid(localuid).
+ * If there is an access violation or an error in setting the uid,
+ * an error is returned and the string errmsg is initialized with
+ * an error message that will be sent back to the client.
+ */
+ if ((status = validate_user(info.aname, info.inst, info.realm,
+ info.username, errmsg)) != RKINIT_SUCCESS) {
+ rpc_send_error(errmsg);
+ exit(0);
+ }
+ else
+ rpc_send_success();
+
+ /*
+ * If the name of a ticket file was specified, set it; otherwise,
+ * just use the default.
+ */
+ if (strlen(info.tktfilename))
+ krb_set_tkt_string(info.tktfilename);
+
+ /*
+ * Call internal kerberos library routine so that we can supply
+ * our own ticket decryption routine.
+ */
+
+ /*
+ * We need a setjmp here because krb_get_in_tkt ignores the
+ * return value of decrypt_tkt. Thus if we want any of its
+ * return values to reach the client, we have to jump out of
+ * the routine.
+ */
+
+ if (setjmp(rii.env) == 0) {
+ if ((status = krb_get_in_tkt(info.aname, info.inst, info.realm,
+ info.sname, info.sinst, info.lifetime,
+ NULL, decrypt_tkt, (char *)&rii))) {
+ strcpy(errmsg, krb_err_txt[status]);
+ rpc_send_error(errmsg);
+ }
+ else
+ rpc_send_success();
+ }
+ else
+ rpc_send_error(errbuf);
+
+ return(RKINIT_SUCCESS);
+}
diff --git a/eBones/libexec/rkinitd/rkinitd.8 b/eBones/libexec/rkinitd/rkinitd.8
new file mode 100644
index 0000000000000..cce921e90866f
--- /dev/null
+++ b/eBones/libexec/rkinitd/rkinitd.8
@@ -0,0 +1,42 @@
+.\"
+.\" $Header: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinitd.8,v 1.1 1991/12/03 23:21:32 eichin Exp $
+.\" $Source: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinitd.8,v $
+.\" $Author: eichin $
+.\"
+.\"
+.TH RKINITD 8 "November 12, 1989"
+.UC 4
+.SH NAME
+rkinitd \- server for
+.I rkinit,
+a remote kerberos ticket establishment utility
+.SH SYNOPSIS
+.B rkinitd
+.SH DESCRIPTION
+.I rkinitd
+is the server for
+.I rkinit.
+See
+.IR rkinit (1)
+for information about
+.I rkinit.
+.I rkinitd
+is started from inetd and must be run as root or be installed
+setuid(root) as it needs to be able to read /etc/athena/srvtab and
+change its uid to create tickets.
+
+.I rkinitd
+times out in 60 seconds if the transaction is not completed.
+
+.I rkinitd
+must be running on a machine that is registered for rlogin
+service; that is, the host must have a srvtab containing an rcmd.<host>
+key where <host> is the value returned by the
+.IR krb_get_phost (3)
+kerberos library call.
+
+.SH SEE ALSO
+rkinit(1), inetd(8), kerberos(1), kerberos(3)
+
+.SH AUTHOR
+Emanuel Jay Berkenbilt (MIT-Project Athena)
diff --git a/eBones/libexec/rkinitd/rkinitd.c b/eBones/libexec/rkinitd/rkinitd.c
new file mode 100644
index 0000000000000..724414977c24f
--- /dev/null
+++ b/eBones/libexec/rkinitd/rkinitd.c
@@ -0,0 +1,137 @@
+/*
+ * $Id: rkinitd.c,v 1.1 1993/12/10 18:54:19 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/rkinitd/RCS/rkinitd.c,v $
+ * $Author: dglo $
+ *
+ * This is the main source file for rkinit
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: rkinitd.c,v 1.1 1993/12/10 18:54:19 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <strings.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <krb.h>
+#include <des.h>
+#include <syslog.h>
+
+#include <rkinit.h>
+#include <rkinit_err.h>
+#include <rkinit_private.h>
+
+#include "rkinitd.h"
+
+extern int errno;
+
+static int inetd = TRUE; /* True if we were started by inetd */
+
+#ifdef __STDC__
+static void usage(void)
+#else
+static void usage()
+#endif /* __STDC__ */
+{
+ syslog(LOG_ERR, "rkinitd usage: rkinitd [-notimeout]\n");
+ exit(1);
+}
+
+#ifdef __STDC__
+void error(void)
+#else
+void error()
+#endif /* __STDC__ */
+{
+ char errbuf[BUFSIZ];
+
+ strcpy(errbuf, rkinit_errmsg(0));
+ if (strlen(errbuf)) {
+ if (inetd)
+ syslog(LOG_ERR, "rkinitd: %s", errbuf);
+ else
+ fprintf(stderr, "rkinitd: %s\n", errbuf);
+ }
+}
+
+int
+#ifdef __STDC__
+main(int argc, char *argv[])
+#else
+main(argc, argv)
+ int argc;
+ char *argv[];
+#endif /* __STDC__ */
+{
+ int version; /* Version of the transaction */
+
+ int notimeout = FALSE; /* Should we not timeout? */
+
+ static char *envinit[1]; /* Empty environment */
+ extern char **environ; /* This process's environment */
+
+ int status = 0; /* General error code */
+
+ /*
+ * Clear the environment so that this process does not inherit
+ * kerberos ticket variable information from the person who started
+ * the process (if a person started it...).
+ */
+ environ = envinit;
+
+ /* Initialize com_err error table */
+ init_rkin_err_tbl();
+
+#ifdef DEBUG
+ /* This only works if the library was compiled with DEBUG defined */
+ rki_i_am_server();
+#endif /* DEBUG */
+
+ /*
+ * Make sure that we are running as root or can arrange to be
+ * running as root. We need both to be able to read /etc/srvtab
+ * and to be able to change uid to create tickets.
+ */
+
+ (void) setuid(0);
+ if (getuid() != 0) {
+ syslog(LOG_ERR, "rkinitd: not running as root.\n");
+ exit(1);
+ }
+
+ /* Determine whether to time out */
+ if (argc == 2) {
+ if (strcmp(argv[1], "-notimeout"))
+ usage();
+ else
+ notimeout = TRUE;
+ }
+ else if (argc != 1)
+ usage();
+
+ inetd = setup_rpc(notimeout);
+
+ if ((status = choose_version(&version) != RKINIT_SUCCESS)) {
+ error();
+ exit(1);
+ }
+
+ if ((status = get_tickets(version) != RKINIT_SUCCESS)) {
+ error();
+ exit(1);
+ }
+
+ exit(0);
+}
+
+
diff --git a/eBones/libexec/rkinitd/rkinitd.h b/eBones/libexec/rkinitd/rkinitd.h
new file mode 100644
index 0000000000000..1a65cba24ae36
--- /dev/null
+++ b/eBones/libexec/rkinitd/rkinitd.h
@@ -0,0 +1,34 @@
+/*
+ * $Id: rkinitd.h,v 1.1 1993/12/10 19:02:10 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/rkinitd/RCS/rkinitd.h,v $
+ * $Author: dglo $
+ *
+ * This header file contains function declarations for use for rkinitd
+ */
+
+#ifndef __RKINITD_H__
+#define __RKINITD_H__
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid_rkinitd_h = "$Id: rkinitd.h,v 1.1 1993/12/10 19:02:10 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#ifdef __STDC__
+#define RK_PROTO(x) x
+#else
+#define RK_PROTO(x) ()
+#endif /* __STDC__ */
+
+int get_tickets RK_PROTO((int));
+void error RK_PROTO((void));
+int setup_rpc RK_PROTO((int)) ;
+void rpc_exchange_version_info RK_PROTO((int *, int *, int, int));
+void rpc_get_rkinit_info RK_PROTO((rkinit_info *));
+void rpc_send_error RK_PROTO((char *));
+void rpc_send_success RK_PROTO((void));
+void rpc_exchange_tkt RK_PROTO((KTEXT, MSG_DAT *));
+void rpc_getauth RK_PROTO((KTEXT, struct sockaddr_in *, struct sockaddr_in *));
+int choose_version RK_PROTO((int *));
+
+
+#endif /* __RKINITD_H__ */
diff --git a/eBones/libexec/rkinitd/rpc.c b/eBones/libexec/rkinitd/rpc.c
new file mode 100644
index 0000000000000..97d4f9f85c4e4
--- /dev/null
+++ b/eBones/libexec/rkinitd/rpc.c
@@ -0,0 +1,222 @@
+/*
+ * $Id: rpc.c,v 1.1 1993/12/10 18:59:29 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/rkinitd/RCS/rpc.c,v $
+ * $Author: dglo $
+ *
+ * This file contains the network parts of the rkinit server.
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: rpc.c,v 1.1 1993/12/10 18:59:29 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <syslog.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+
+#include <rkinit.h>
+#include <rkinit_err.h>
+#include <rkinit_private.h>
+
+#include "rkinitd.h"
+
+#define RKINITD_TIMEOUT 60
+
+extern int errno;
+
+static int in; /* sockets */
+static int out;
+
+static char errbuf[BUFSIZ];
+
+void error();
+
+#ifdef __STDC__
+static void timeout(int signal)
+#else
+static void timeout(signal)
+ int signal;
+#endif /* __STDC__ */
+{
+ syslog(LOG_WARNING, "rkinitd timed out.\n");
+ exit(1);
+
+ return;
+}
+
+/*
+ * This function does all the network setup for rkinitd.
+ * It returns true if we were started from inetd, or false if
+ * we were started from the commandline.
+ * It causes the program to exit if there is an error.
+ */
+#ifdef __STDC__
+int setup_rpc(int notimeout)
+#else
+int setup_rpc(notimeout)
+ int notimeout; /* True if we should not timeout */
+#endif /* __STDC__ */
+{
+ struct itimerval timer; /* Time structure for timeout */
+
+ /* For now, support only inetd. */
+ in = 0;
+ out = 1;
+
+ if (! notimeout) {
+ SBCLEAR(timer);
+
+ /* Set up an itimer structure to send an alarm signal after timeout
+ seconds. */
+ timer.it_interval.tv_sec = RKINITD_TIMEOUT;
+ timer.it_interval.tv_usec = 0;
+ timer.it_value = timer.it_interval;
+
+ /* Start the timer. */
+ if (setitimer (ITIMER_REAL, &timer, (struct itimerval *)0) < 0) {
+ sprintf(errbuf, "setitimer: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ error();
+ exit(1);
+ }
+
+ signal(SIGALRM, timeout);
+ }
+
+ return(TRUE);
+}
+
+#ifdef __STDC__
+void rpc_exchange_version_info(int *c_lversion, int *c_hversion,
+ int s_lversion, int s_hversion)
+#else
+void rpc_exchange_version_info(c_lversion, c_hversion, s_lversion, s_hversion)
+ int *c_lversion;
+ int *c_hversion;
+ int s_lversion;
+ int s_hversion;
+#endif /* __STDC__ */
+{
+ u_char version_info[VERSION_INFO_SIZE];
+ u_int32_t length = sizeof(version_info);
+
+ if (rki_get_packet(in, MT_CVERSION, &length, (char *)version_info) !=
+ RKINIT_SUCCESS) {
+ error();
+ exit(1);
+ }
+
+ *c_lversion = version_info[0];
+ *c_hversion = version_info[1];
+
+ version_info[0] = s_lversion;
+ version_info[1] = s_hversion;
+
+ if (rki_send_packet(out, MT_SVERSION, length, (char *)version_info) !=
+ RKINIT_SUCCESS) {
+ error();
+ exit(1);
+ }
+}
+
+#ifdef __STDC__
+void rpc_get_rkinit_info(rkinit_info *info)
+#else
+void rpc_get_rkinit_info(info)
+ rkinit_info *info;
+#endif /* __STDC__ */
+{
+ u_int32_t length = sizeof(rkinit_info);
+
+ if (rki_get_packet(in, MT_RKINIT_INFO, &length, (char *)info)) {
+ error();
+ exit(1);
+ }
+
+ info->lifetime = ntohl(info->lifetime);
+}
+
+#ifdef __STDC__
+void rpc_send_error(char *errmsg)
+#else
+void rpc_send_error(errmsg)
+ char *errmsg;
+#endif /* __STDC__ */
+{
+ if (rki_send_packet(out, MT_STATUS, strlen(errmsg), errmsg)) {
+ error();
+ exit(1);
+ }
+}
+
+#ifdef __STDC__
+void rpc_send_success(void)
+#else
+void rpc_send_success()
+#endif /* __STDC__ */
+{
+ if (rki_send_packet(out, MT_STATUS, 0, "")) {
+ error();
+ exit(1);
+ }
+}
+
+#ifdef __STDC__
+void rpc_exchange_tkt(KTEXT cip, MSG_DAT *scip)
+#else
+void rpc_exchange_tkt(cip, scip)
+ KTEXT cip;
+ MSG_DAT *scip;
+#endif /* __STDC__ */
+{
+ u_int32_t length = MAX_KTXT_LEN;
+
+ if (rki_send_packet(out, MT_SKDC, cip->length, (char *)cip->dat)) {
+ error();
+ exit(1);
+ }
+
+ if (rki_get_packet(in, MT_CKDC, &length, (char *)scip->app_data)) {
+ error();
+ exit(1);
+ }
+ scip->app_length = length;
+}
+
+#ifdef __STDC__
+void rpc_getauth(KTEXT auth, struct sockaddr_in *caddr,
+ struct sockaddr_in *saddr)
+#else
+void rpc_getauth(auth, caddr, saddr)
+ KTEXT auth;
+ struct sockaddr_in *caddr;
+ struct sockaddr_in *saddr;
+#endif /* __STDC__ */
+{
+ int addrlen = sizeof(struct sockaddr_in);
+
+ if (rki_rpc_get_ktext(in, auth, MT_AUTH)) {
+ error();
+ exit(1);
+ }
+
+ if (getpeername(in, (struct sockaddr *)caddr, &addrlen) < 0) {
+ sprintf(errbuf, "getpeername: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ error();
+ exit(1);
+ }
+
+ if (getsockname(out, (struct sockaddr *)saddr, &addrlen) < 0) {
+ sprintf(errbuf, "getsockname: %s", sys_errlist[errno]);
+ rkinit_errmsg(errbuf);
+ error();
+ exit(1);
+ }
+}
diff --git a/eBones/libexec/rkinitd/util.c b/eBones/libexec/rkinitd/util.c
new file mode 100644
index 0000000000000..20812051dc48f
--- /dev/null
+++ b/eBones/libexec/rkinitd/util.c
@@ -0,0 +1,49 @@
+/*
+ * $Id: util.c,v 1.1 1993/12/10 18:59:29 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/rkinitd/RCS/util.c,v $
+ * $Author: dglo $
+ *
+ * This file contains general rkinit server utilities.
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: util.c,v 1.1 1993/12/10 18:59:29 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <rkinit.h>
+#include <rkinit_err.h>
+#include <rkinit_private.h>
+
+#include "rkinitd.h"
+
+static char errbuf[BUFSIZ];
+
+void rpc_exchange_version_info();
+void error();
+
+#ifdef __STDC__
+int choose_version(int *version)
+#else
+int choose_version(version)
+ int *version;
+#endif /* __STDC__ */
+{
+ int c_lversion; /* lowest version number client supports */
+ int c_hversion; /* highest version number client supports */
+ int status = RKINIT_SUCCESS;
+
+ rpc_exchange_version_info(&c_lversion, &c_hversion,
+ RKINIT_LVERSION, RKINIT_HVERSION);
+
+ *version = min(RKINIT_HVERSION, c_hversion);
+ if (*version < max(RKINIT_LVERSION, c_lversion)) {
+ sprintf(errbuf,
+ "Can't run version %d client against version %d server.",
+ c_hversion, RKINIT_HVERSION);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_VERSION);
+ }
+
+ return(status);
+}
diff --git a/eBones/man/Makefile b/eBones/man/Makefile
new file mode 100644
index 0000000000000..526ca8ef76de4
--- /dev/null
+++ b/eBones/man/Makefile
@@ -0,0 +1,10 @@
+# from: @(#)Makefile 5.4 (Berkeley) 7/25/90
+# $Id: Makefile,v 1.3 1995/07/18 16:40:32 mark Exp $
+
+MAN1= kerberos.1
+MAN3= des_crypt.3
+MAN5= krb.conf.5 krb.realms.5
+
+MLINKS+=des_crypt.3 des.3
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/Makefile b/eBones/usr.bin/Makefile
new file mode 100644
index 0000000000000..fa796caeb8f59
--- /dev/null
+++ b/eBones/usr.bin/Makefile
@@ -0,0 +1,6 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.1 1995/09/13 17:24:05 markm Exp $
+
+SUBDIR= kadmin kdestroy kinit klist ksrvtgt register rkinit
+
+.include <bsd.subdir.mk>
diff --git a/eBones/usr.bin/Makefile.inc b/eBones/usr.bin/Makefile.inc
new file mode 100644
index 0000000000000..5506596ac57e0
--- /dev/null
+++ b/eBones/usr.bin/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/6/93
+
+BINDIR?= /usr/bin
+
+.include "../Makefile.inc"
diff --git a/eBones/usr.bin/kadmin/Makefile b/eBones/usr.bin/kadmin/Makefile
new file mode 100644
index 0000000000000..7660270bb3c41
--- /dev/null
+++ b/eBones/usr.bin/kadmin/Makefile
@@ -0,0 +1,16 @@
+# $Id: Makefile,v 1.6 1995/09/14 04:05:59 gibbs Exp $
+
+PROG= kadmin
+SRCS= ${KRBOBJDIR}/krb_err.h kadmin.c kadmin_cmds.c
+CLEANFILES+= kadmin_cmds.c krb_err.c
+CFLAGS+= -DPOSIX -I${.CURDIR}/../../lib/libkadm
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD+= -lkadm -lkrb -ldes
+LDADD+= -lss -lcom_err
+MAN8= kadmin.8
+
+kadmin_cmds.c: kadmin_cmds.ct
+ test -e kadmin_cmds.ct || ln -s ${.CURDIR}/kadmin_cmds.ct .
+ mk_cmds kadmin_cmds.ct
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/kadmin/kadmin.c b/eBones/usr.bin/kadmin/kadmin.c
new file mode 100644
index 0000000000000..67e0e1fb2b41c
--- /dev/null
+++ b/eBones/usr.bin/kadmin/kadmin.c
@@ -0,0 +1,636 @@
+/*
+ * $Source: /usr/cvs/src/eBones/kadmin/kadmin.c,v $
+ * $Author: mark $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Kerberos database administrator's tool.
+ *
+ * The default behavior of kadmin is if the -m option is given
+ * on the commandline, multiple requests are allowed to be given
+ * with one entry of the admin password (until the tickets expire).
+ * If you do not want this to be an available option, compile with
+ * NO_MULTIPLE defined.
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_kadmin_c[] =
+"BonesHeader: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadmin.c,v 4.5 89/09/26 14:17:54 qjb Exp ";
+#endif lint
+#endif
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/param.h>
+#include <pwd.h>
+#include <ss/ss.h>
+#include <com_err.h>
+#include <kerberosIV/krb_err.h>
+#include <kadm.h>
+
+#define BAD_PW 1
+#define GOOD_PW 0
+#define FUDGE_VALUE 15 /* for ticket expiration time */
+#define PE_NO 0
+#define PE_YES 1
+#define PE_UNSURE 2
+
+/* for get_password, whether it should do the swapping...necessary for
+ using vals structure, unnecessary for change_pw requests */
+#define DONTSWAP 0
+#define SWAP 1
+
+static void do_init(int argc, char *argv[]);
+void clean_up(void);
+int get_password(unsigned long *low, unsigned long *high, char *prompt,
+ int byteswap);
+int get_admin_password(void);
+int princ_exists(char *name, char *instance, char *realm);
+
+extern ss_request_table admin_cmds;
+
+static char myname[ANAME_SZ];
+static char default_realm[REALM_SZ]; /* default kerberos realm */
+static char krbrlm[REALM_SZ]; /* current realm being administered */
+#ifndef NO_MULTIPLE
+static int multiple = 0; /* Allow multiple requests per ticket */
+#endif
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int sci_idx;
+ int code;
+ char tktstring[MAXPATHLEN];
+
+ void quit();
+
+ sci_idx = ss_create_invocation("admin", "2.0", (char *) NULL,
+ &admin_cmds, &code);
+ if (code) {
+ ss_perror(sci_idx, code, "creating invocation");
+ exit(1);
+ }
+ (void) sprintf(tktstring, "/tmp/tkt_adm_%d",getpid());
+ krb_set_tkt_string(tktstring);
+
+ do_init(argc, argv);
+
+ printf("Welcome to the Kerberos Administration Program, version 2\n");
+ printf("Type \"help\" if you need it.\n");
+ ss_listen(sci_idx, &code);
+ printf("\n");
+ quit();
+ exit(0);
+}
+
+int
+setvals(vals, string)
+ Kadm_vals *vals;
+ char *string;
+{
+ char realm[REALM_SZ];
+ int status = KADM_SUCCESS;
+
+ bzero(vals, sizeof(*vals));
+ bzero(realm, sizeof(realm));
+
+ SET_FIELD(KADM_NAME,vals->fields);
+ SET_FIELD(KADM_INST,vals->fields);
+ if ((status = kname_parse(vals->name, vals->instance, realm, string))) {
+ printf("kerberos error: %s\n", krb_err_txt[status]);
+ return status;
+ }
+ if (!realm[0])
+ strcpy(realm, default_realm);
+ if (strcmp(realm, krbrlm)) {
+ strcpy(krbrlm, realm);
+ if ((status = kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm))
+ != KADM_SUCCESS)
+ printf("kadm error for realm %s: %s\n",
+ krbrlm, error_message(status));
+ }
+ if (status)
+ return 1;
+ else
+ return KADM_SUCCESS;
+}
+
+void
+change_password(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Kadm_vals old, new;
+ int status;
+ char pw_prompt[BUFSIZ];
+
+ if (argc != 2) {
+ printf("Usage: change_password loginname\n");
+ return;
+ }
+
+ if (setvals(&old, argv[1]) != KADM_SUCCESS)
+ return;
+
+ new = old;
+
+ SET_FIELD(KADM_DESKEY,new.fields);
+
+ if (princ_exists(old.name, old.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ /* get the new password */
+ (void) sprintf(pw_prompt, "New password for %s:", argv[1]);
+
+ if (get_password(&new.key_low, &new.key_high,
+ pw_prompt, SWAP) == GOOD_PW) {
+ status = kadm_mod(&old, &new);
+ if (status == KADM_SUCCESS) {
+ printf("Password changed for %s.\n", argv[1]);
+ } else {
+ printf("kadmin: %s\nwhile changing password for %s",
+ error_message(status), argv[1]);
+ }
+ } else
+ printf("Error reading password; password unchanged\n");
+ bzero((char *)&new, sizeof(new));
+#ifndef NO_MULTIPLE
+ if (!multiple)
+ clean_up();
+#endif
+ }
+ else
+ printf("kadmin: Principal does not exist.\n");
+ return;
+}
+
+/*ARGSUSED*/
+void
+change_admin_password(argc, argv)
+ int argc;
+ char *argv[];
+{
+ des_cblock newkey;
+ unsigned long low, high;
+ int status;
+ char prompt_pw[BUFSIZ];
+
+ if (argc != 1) {
+ printf("Usage: change_admin_password\n");
+ return;
+ }
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ (void) sprintf(prompt_pw, "New password for %s.admin:",myname);
+ if (get_password(&low, &high, prompt_pw, DONTSWAP) == GOOD_PW) {
+ bcopy((char *)&low,(char *) newkey,4);
+ bcopy((char *)&high, (char *)(((long *) newkey) + 1),4);
+ low = high = 0L;
+ if ((status = kadm_change_pw(newkey)) == KADM_SUCCESS)
+ printf("Admin password changed\n");
+ else
+ printf("kadm error: %s\n",error_message(status));
+ bzero((char *)newkey, sizeof(newkey));
+ } else
+ printf("Error reading password; password unchanged\n");
+#ifndef NO_MULTIPLE
+ if (!multiple)
+ clean_up();
+#endif
+ return;
+}
+
+void
+add_new_key(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Kadm_vals new;
+ char pw_prompt[BUFSIZ];
+ int status;
+
+ if (argc != 2) {
+ printf("Usage: add_new_key user_name.\n");
+ return;
+ }
+ if (setvals(&new, argv[1]) != KADM_SUCCESS)
+ return;
+
+ SET_FIELD(KADM_DESKEY,new.fields);
+
+ if (princ_exists(new.name, new.instance, krbrlm) != PE_YES) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ /* get the new password */
+ (void) sprintf(pw_prompt, "Password for %s:", argv[1]);
+
+ if (get_password(&new.key_low, &new.key_high,
+ pw_prompt, SWAP) == GOOD_PW) {
+ status = kadm_add(&new);
+ if (status == KADM_SUCCESS) {
+ printf("%s added to database.\n", argv[1]);
+ } else {
+ printf("kadm error: %s\n",error_message(status));
+ }
+ } else
+ printf("Error reading password; %s not added\n",argv[1]);
+ bzero((char *)&new, sizeof(new));
+#ifndef NO_MULTIPLE
+ if (!multiple)
+ clean_up();
+#endif
+ }
+ else
+ printf("kadmin: Principal already exists.\n");
+ return;
+}
+
+void
+get_entry(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int status;
+ u_char fields[4];
+ Kadm_vals vals;
+
+ if (argc != 2) {
+ printf("Usage: get_entry username\n");
+ return;
+ }
+
+ bzero(fields, sizeof(fields));
+
+ SET_FIELD(KADM_NAME,fields);
+ SET_FIELD(KADM_INST,fields);
+ SET_FIELD(KADM_EXPDATE,fields);
+ SET_FIELD(KADM_ATTR,fields);
+ SET_FIELD(KADM_MAXLIFE,fields);
+
+ if (setvals(&vals, argv[1]) != KADM_SUCCESS)
+ return;
+
+
+ if (princ_exists(vals.name, vals.instance, krbrlm) != PE_NO) {
+ /* get the admin's password */
+ if (get_admin_password() != GOOD_PW)
+ return;
+
+ if ((status = kadm_get(&vals, fields)) == KADM_SUCCESS)
+ prin_vals(&vals);
+ else
+ printf("kadm error: %s\n",error_message(status));
+
+#ifndef NO_MULTIPLE
+ if (!multiple)
+ clean_up();
+#endif
+ }
+ else
+ printf("kadmin: Principal does not exist.\n");
+ return;
+}
+
+
+void
+help(argc, argv)
+ int argc;
+ char *argv[];
+{
+ if (argc == 1) {
+ printf("Welcome to the Kerberos administration program.");
+ printf("Type \"?\" to get\n");
+ printf("a list of requests that are available. You can");
+ printf(" get help on each of\n");
+ printf("the commands by typing \"help command_name\".");
+ printf(" Some functions of this\n");
+ printf("program will require an \"admin\" password");
+ printf(" from you. This is a password\n");
+ printf("private to you, that is used to authenticate");
+ printf(" requests from this\n");
+ printf("program. You can change this password with");
+ printf(" the \"change_admin_password\"\n");
+ printf("(or short form \"cap\") command. Good Luck! \n");
+ } else if (!strcmp(argv[1], "change_password") ||
+ !strcmp(argv[1], "cpw")) {
+ printf("Usage: change_password user_name.\n");
+ printf("\n");
+ printf("user_name is the name of the user whose password");
+ printf(" you wish to change. \n");
+ printf("His/her password is changed in the kerberos database\n");
+ printf("When this command is issued, first the \"Admin\"");
+ printf(" password will be prompted\n");
+ printf("for and if correct the user's new password will");
+ printf(" be prompted for (twice with\n");
+ printf("appropriate comparison). Note: No minimum password");
+ printf(" length restrictions apply, but\n");
+ printf("longer passwords are more secure.\n");
+ } else if (!strcmp(argv[1], "change_admin_password") ||
+ !strcmp(argv[1], "cap")) {
+ printf("Usage: change_admin_password.\n");
+ printf("\n");
+ printf("This command takes no arguments and is used");
+ printf(" to change your private\n");
+ printf("\"Admin\" password. It will first prompt for");
+ printf(" the (current) \"Admin\"\n");
+ printf("password and then ask for the new password");
+ printf(" by prompting:\n");
+ printf("\n");
+ printf("New password for <Your User Name>.admin:\n");
+ printf("\n");
+ printf("Enter the new admin password that you desire");
+ printf(" (it will be asked for\n");
+ printf("twice to avoid errors).\n");
+ } else if (!strcmp(argv[1], "add_new_key") ||
+ !strcmp(argv[1], "ank")) {
+ printf("Usage: add_new_key user_name.\n");
+ printf("\n");
+ printf("user_name is the name of a new user to put");
+ printf(" in the kerberos database. Your\n");
+ printf("\"Admin\" password and the user's password");
+ printf(" are prompted for. The user's\n");
+ printf("password will be asked for");
+ printf(" twice to avoid errors.\n");
+ } else if (!strcmp(argv[1], "get_entry") ||
+ !strcmp(argv[1], "get")) {
+ printf("Usage: get_entry user_name.\n");
+ printf("\n");
+ printf("user_name is the name of a user whose");
+ printf(" entry you wish to review. Your\n");
+ printf("\"Admin\" password is prompted for. ");
+ printf(" The key field is not filled in, for\n");
+ printf("security reasons.\n");
+ } else if (!strcmp(argv[1], "destroy_tickets") ||
+ !strcmp(argv[1], "dest")) {
+ printf("Usage: destroy_tickets\n");
+ printf("\n");
+ printf("Destroy your admin tickets. This will");
+ printf(" cause you to be prompted for your\n");
+ printf("admin password on your next request.\n");
+ } else if (!strcmp(argv[1], "list_requests") ||
+ !strcmp(argv[1], "lr") ||
+ !strcmp(argv[1], "?")) {
+ printf("Usage: list_requests\n");
+ printf("\n");
+ printf("This command lists what other commands are");
+ printf(" currently available.\n");
+ } else if (!strcmp(argv[1], "exit") ||
+ !strcmp(argv[1], "quit") ||
+ !strcmp(argv[1], "q")) {
+ printf("Usage: quit\n");
+ printf("\n");
+ printf("This command exits this program.\n");
+ } else {
+ printf("Sorry there is no such command as %s.", argv[1]);
+ printf(" Type \"help\" for more information. \n");
+ }
+ return;
+}
+
+void
+go_home(str,x)
+char *str;
+int x;
+{
+ fprintf(stderr, "%s: %s\n", str, error_message(x));
+ clean_up();
+ exit(1);
+}
+
+static int inited = 0;
+
+void
+usage()
+{
+ fprintf(stderr, "Usage: kadmin [-u admin_name] [-r default_realm]");
+#ifndef NO_MULTIPLE
+ fprintf(stderr, " [-m]");
+#endif
+ fprintf(stderr, "\n");
+#ifndef NO_MULTIPLE
+ fprintf(stderr, " -m allows multiple admin requests to be ");
+ fprintf(stderr, "serviced with one entry of admin\n");
+ fprintf(stderr, " password.\n");
+#endif
+ exit(1);
+}
+
+static void
+do_init(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct passwd *pw;
+ extern char *optarg;
+ extern int optind;
+ int c;
+#ifndef NO_MULTIPLE
+#define OPTION_STRING "u:r:m"
+#else
+#define OPTION_STRING "u:r:"
+#endif
+
+ bzero(myname, sizeof(myname));
+
+ if (!inited) {
+ /*
+ * This is only as a default/initial realm; we don't care
+ * about failure.
+ */
+ if (krb_get_lrealm(default_realm, 1) != KSUCCESS)
+ strcpy(default_realm, KRB_REALM);
+
+ /*
+ * If we can reach the local realm, initialize to it. Otherwise,
+ * don't initialize.
+ */
+ if (kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm) != KADM_SUCCESS)
+ bzero(krbrlm, sizeof(krbrlm));
+ else
+ strcpy(krbrlm, default_realm);
+
+ while ((c = getopt(argc, argv, OPTION_STRING)) != EOF)
+ switch (c) {
+ case 'u':
+ strncpy(myname, optarg, sizeof(myname) - 1);
+ break;
+ case 'r':
+ bzero(default_realm, sizeof(default_realm));
+ strncpy(default_realm, optarg, sizeof(default_realm) - 1);
+ break;
+#ifndef NO_MULTIPLE
+ case 'm':
+ multiple++;
+ break;
+#endif
+ default:
+ usage();
+ break;
+ }
+ if (optind < argc)
+ usage();
+ if (!myname[0]) {
+ pw = getpwuid((int) getuid());
+ if (!pw) {
+ fprintf(stderr,
+ "You aren't in the password file. Who are you?\n");
+ exit(1);
+ }
+ (void) strcpy(myname, pw->pw_name);
+ }
+ inited = 1;
+ }
+}
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else
+#define read_long_pw_string des_read_pw_string
+#endif
+extern int read_long_pw_string();
+
+int
+get_admin_password()
+{
+ int status;
+ char admin_passwd[MAX_KPW_LEN]; /* Admin's password */
+ int ticket_life = 1; /* minimum ticket lifetime */
+#ifndef NO_MULTIPLE
+ CREDENTIALS c;
+
+ if (multiple) {
+ /* If admin tickets exist and are valid, just exit. */
+ bzero(&c, sizeof(c));
+ if (krb_get_cred(PWSERV_NAME, KADM_SINST, krbrlm, &c) == KSUCCESS)
+ /*
+ * If time is less than lifetime - FUDGE_VALUE after issue date,
+ * tickets will probably last long enough for the next
+ * transaction.
+ */
+ if (time(0) < (c.issue_date + (5 * 60 * c.lifetime) - FUDGE_VALUE))
+ return(KADM_SUCCESS);
+ ticket_life = DEFAULT_TKT_LIFE;
+ }
+#endif
+
+ if (princ_exists(myname, "admin", krbrlm) != PE_NO) {
+ if (read_long_pw_string(admin_passwd, sizeof(admin_passwd)-1,
+ "Admin password:", 0)) {
+ fprintf(stderr, "Error reading admin password.\n");
+ goto bad;
+ }
+ status = krb_get_pw_in_tkt(myname, "admin", krbrlm, PWSERV_NAME,
+ KADM_SINST, ticket_life, admin_passwd);
+ bzero(admin_passwd, sizeof(admin_passwd));
+ }
+ else
+ status = KDC_PR_UNKNOWN;
+
+ switch(status) {
+ case GT_PW_OK:
+ return(GOOD_PW);
+ case KDC_PR_UNKNOWN:
+ printf("Principal %s.admin@%s does not exist.\n", myname, krbrlm);
+ goto bad;
+ case GT_PW_BADPW:
+ printf("Incorrect admin password.\n");
+ goto bad;
+ default:
+ com_err("kadmin", status+krb_err_base,
+ "while getting password tickets");
+ goto bad;
+ }
+
+ bad:
+ bzero(admin_passwd, sizeof(admin_passwd));
+ (void) dest_tkt();
+ return(BAD_PW);
+}
+
+void
+clean_up()
+{
+ (void) dest_tkt();
+ return;
+}
+
+void
+quit()
+{
+ printf("Cleaning up and exiting.\n");
+ clean_up();
+ exit(0);
+}
+
+int
+princ_exists(name, instance, realm)
+ char *name;
+ char *instance;
+ char *realm;
+{
+ int status;
+
+ status = krb_get_pw_in_tkt(name, instance, realm, "krbtgt", realm, 1, "");
+
+ if ((status == KSUCCESS) || (status == INTK_BADPW))
+ return(PE_YES);
+ else if (status == KDC_PR_UNKNOWN)
+ return(PE_NO);
+ else
+ return(PE_UNSURE);
+}
+
+int
+get_password(low, high, prompt, byteswap)
+unsigned long *low, *high;
+char *prompt;
+int byteswap;
+{
+ char new_passwd[MAX_KPW_LEN]; /* new password */
+ des_cblock newkey;
+
+ do {
+ if (read_long_pw_string(new_passwd, sizeof(new_passwd)-1, prompt, 1))
+ return(BAD_PW);
+ if (strlen(new_passwd) == 0)
+ printf("Null passwords are not allowed; try again.\n");
+ } while (strlen(new_passwd) == 0);
+
+#ifdef NOENCRYPTION
+ bzero((char *) newkey, sizeof(newkey));
+#else
+ des_string_to_key(new_passwd, &newkey);
+#endif
+ bzero(new_passwd, sizeof(new_passwd));
+
+ bcopy((char *) newkey,(char *)low,4);
+ bcopy((char *)(((long *) newkey) + 1), (char *)high,4);
+
+ bzero((char *) newkey, sizeof(newkey));
+
+#ifdef NOENCRYPTION
+ *low = 1;
+#endif
+
+ if (byteswap != DONTSWAP) {
+ *low = htonl(*low);
+ *high = htonl(*high);
+ }
+ return(GOOD_PW);
+}
diff --git a/eBones/usr.bin/kadmin/kadmin_cmds.ct b/eBones/usr.bin/kadmin/kadmin_cmds.ct
new file mode 100644
index 0000000000000..141ac154e1f13
--- /dev/null
+++ b/eBones/usr.bin/kadmin/kadmin_cmds.ct
@@ -0,0 +1,41 @@
+# $Source: /usr/cvs/src/eBones/kadmin/kadmin_cmds.ct,v $
+# $Author: mark $
+# $Header: /usr/cvs/src/eBones/kadmin/kadmin_cmds.ct,v 1.1 1995/07/18 16:36:56 mark Exp $
+#
+# Copyright 1988 by the Massachusetts Institute of Technology.
+#
+# For copying and distribution information, please see the file
+# <mit-copyright.h>.
+#
+# Command table for Kerberos administration tool
+#
+ command_table admin_cmds;
+
+ request change_password,
+ "Change a user's password",
+ change_password, cpw;
+
+ request change_admin_password, "Change your admin password",
+ change_admin_password, cap;
+
+ request add_new_key, "Add new user to kerberos database",
+ add_new_key, ank;
+
+ request get_entry, "Get entry from kerberos database",
+ get_entry, get;
+
+ request clean_up, "Destroy admin tickets",
+ destroy_tickets, dest;
+
+ request help,"Request help with this program",
+ help;
+
+# list_requests is generic -- unrelated to Kerberos
+
+ request ss_list_requests, "List available requests.",
+ list_requests, lr, "?";
+
+ request quit, "Exit program.",
+ quit, exit, q;
+
+ end;
diff --git a/eBones/usr.bin/kdestroy/Makefile b/eBones/usr.bin/kdestroy/Makefile
new file mode 100644
index 0000000000000..19a157a1fb3ae
--- /dev/null
+++ b/eBones/usr.bin/kdestroy/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:09 markm Exp $
+
+PROG= kdestroy
+CFLAGS+=-DKERBEROS -DDEBUG -DBSD42
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+MAN1= kdestroy.1
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/kdestroy/kdestroy.c b/eBones/usr.bin/kdestroy/kdestroy.c
new file mode 100644
index 0000000000000..926eea52da956
--- /dev/null
+++ b/eBones/usr.bin/kdestroy/kdestroy.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This program causes Kerberos tickets to be destroyed.
+ * Options are:
+ *
+ * -q[uiet] - no bell even if tickets not destroyed
+ * -f[orce] - no message printed at all
+ *
+ * from: kdestroy.c,v 4.5 88/03/18 15:16:02 steiner Exp $
+ * $Id: kdestroy.c,v 1.3 1995/07/18 16:37:44 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kdestroy.c,v 1.3 1995/07/18 16:37:44 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <krb.h>
+#ifdef BSD42
+#include <strings.h>
+#endif BSD42
+
+
+static char *pname;
+
+static void
+usage()
+{
+ fprintf(stderr, "Usage: %s [-f] [-q]\n", pname);
+ exit(1);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int fflag=0, qflag=0, k_errno;
+ register char *cp;
+
+ cp = rindex (argv[0], '/');
+ if (cp == NULL)
+ pname = argv[0];
+ else
+ pname = cp+1;
+
+ if (argc > 2)
+ usage();
+ else if (argc == 2) {
+ if (!strcmp(argv[1], "-f"))
+ ++fflag;
+ else if (!strcmp(argv[1], "-q"))
+ ++qflag;
+ else usage();
+ }
+
+ k_errno = dest_tkt();
+
+ if (fflag) {
+ if (k_errno != 0 && k_errno != RET_TKFIL)
+ exit(1);
+ else
+ exit(0);
+ } else {
+ if (k_errno == 0)
+ printf("Tickets destroyed.\n");
+ else if (k_errno == RET_TKFIL)
+ fprintf(stderr, "No tickets to destroy.\n");
+ else {
+ fprintf(stderr, "Tickets NOT destroyed.\n");
+ if (!qflag)
+ fprintf(stderr, "\007");
+ exit(1);
+ }
+ }
+ exit(0);
+}
diff --git a/eBones/usr.bin/kinit/Makefile b/eBones/usr.bin/kinit/Makefile
new file mode 100644
index 0000000000000..f17237c8e39d4
--- /dev/null
+++ b/eBones/usr.bin/kinit/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:10 markm Exp $
+
+PROG= kinit
+CFLAGS+=-DKERBEROS -DDEBUG -DBSD42
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+MAN1= kinit.1
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/kinit/kinit.c b/eBones/usr.bin/kinit/kinit.c
new file mode 100644
index 0000000000000..3b47c7cfb6bb4
--- /dev/null
+++ b/eBones/usr.bin/kinit/kinit.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Routine to initialize user to Kerberos. Prompts optionally for
+ * user, instance and realm. Authenticates user and gets a ticket
+ * for the Kerberos ticket-granting service for future use.
+ *
+ * Options are:
+ *
+ * -i[instance]
+ * -r[realm]
+ * -v[erbose]
+ * -l[ifetime]
+ *
+ * from: kinit.c,v 4.12 90/03/20 16:11:15 jon Exp $
+ * $Id: kinit.c,v 1.4 1995/08/03 17:16:00 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kinit.c,v 1.4 1995/08/03 17:16:00 mark Exp $";
+#endif lint
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <krb.h>
+
+#ifndef ORGANIZATION
+#define ORGANIZATION "MIT Project Athena"
+#endif /*ORGANIZATION*/
+
+#ifdef PC
+#define LEN 64 /* just guessing */
+#endif PC
+
+#if defined(BSD42) || defined(__FreeBSD__) || defined(__NetBSD__)
+#include <strings.h>
+#include <sys/param.h>
+#if defined(ultrix) || defined(sun)
+#define LEN 64
+#else
+#define LEN MAXHOSTNAMELEN
+#endif /* defined(ultrix) || defined(sun) */
+#endif /* BSD42 */
+
+#define LIFE 96 /* lifetime of ticket in 5-minute units */
+
+char *progname;
+
+void usage(void);
+
+void
+get_input(s, size, stream)
+char *s;
+int size;
+FILE *stream;
+{
+ char *p;
+
+ if (fgets(s, size, stream) == NULL)
+ exit(1);
+ if ((p = index(s, '\n')) != NULL)
+ *p = '\0';
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char aname[ANAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ char buf[LEN];
+ char *username = NULL;
+ int iflag, rflag, vflag, lflag, lifetime, k_errno;
+ register char *cp;
+ register i;
+
+ *inst = *realm = '\0';
+ iflag = rflag = vflag = lflag = 0;
+ lifetime = LIFE;
+ progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ while (--argc) {
+ if ((*++argv)[0] != '-') {
+ if (username)
+ usage();
+ username = *argv;
+ continue;
+ }
+ for (i = 1; (*argv)[i] != '\0'; i++)
+ switch ((*argv)[i]) {
+ case 'i': /* Instance */
+ ++iflag;
+ continue;
+ case 'r': /* Realm */
+ ++rflag;
+ continue;
+ case 'v': /* Verbose */
+ ++vflag;
+ continue;
+ case 'l':
+ ++lflag;
+ continue;
+ default:
+ usage();
+ exit(1);
+ }
+ }
+ if (username &&
+ (k_errno = kname_parse(aname, inst, realm, username))
+ != KSUCCESS) {
+ fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]);
+ iflag = rflag = 1;
+ username = NULL;
+ }
+ if (k_gethostname(buf, LEN)) {
+ fprintf(stderr, "%s: k_gethostname failed\n", progname);
+ exit(1);
+ }
+ printf("%s (%s)\n", ORGANIZATION, buf);
+ if (username) {
+ printf("Kerberos Initialization for \"%s", aname);
+ if (*inst)
+ printf(".%s", inst);
+ if (*realm)
+ printf("@%s", realm);
+ printf("\"\n");
+ } else {
+ if (iflag) {
+ printf("Kerberos Initialization\n");
+ printf("Kerberos name: ");
+ get_input(aname, sizeof(aname), stdin);
+ } else {
+ int uid = getuid();
+ char *getenv();
+ struct passwd *pwd;
+
+ /* default to current user name unless running as root */
+ if (uid == 0 && (username = getenv("USER")) &&
+ strcmp(username, "root") != 0) {
+ strncpy(aname, username, sizeof(aname));
+ strncpy(inst, "root", sizeof(inst));
+ } else {
+ pwd = getpwuid(uid);
+
+ if (pwd == (struct passwd *) NULL) {
+ fprintf(stderr, "Unknown name for your uid\n");
+ printf("Kerberos name: ");
+ gets(aname);
+ } else
+ strncpy(aname, pwd->pw_name, sizeof(aname));
+ }
+ }
+
+ if (!*aname)
+ exit(0);
+ if (!k_isname(aname)) {
+ fprintf(stderr, "%s: bad Kerberos name format\n",
+ progname);
+ exit(1);
+ }
+ }
+ /* optional instance */
+ if (iflag) {
+ printf("Kerberos instance: ");
+ get_input(inst, sizeof(inst), stdin);
+ if (!k_isinst(inst)) {
+ fprintf(stderr, "%s: bad Kerberos instance format\n",
+ progname);
+ exit(1);
+ }
+ }
+ if (rflag) {
+ printf("Kerberos realm: ");
+ get_input(realm, sizeof(realm), stdin);
+ if (!k_isrealm(realm)) {
+ fprintf(stderr, "%s: bad Kerberos realm format\n",
+ progname);
+ exit(1);
+ }
+ }
+ if (lflag) {
+ printf("Kerberos ticket lifetime (minutes): ");
+ get_input(buf, sizeof(buf), stdin);
+ lifetime = atoi(buf);
+ if (lifetime < 5)
+ lifetime = 1;
+ else
+ lifetime /= 5;
+ /* This should be changed if the maximum ticket lifetime */
+ /* changes */
+ if (lifetime > 255)
+ lifetime = 255;
+ }
+ if (!*realm && krb_get_lrealm(realm, 1)) {
+ fprintf(stderr, "%s: krb_get_lrealm failed\n", progname);
+ exit(1);
+ }
+ k_errno = krb_get_pw_in_tkt(aname, inst, realm, "krbtgt", realm,
+ lifetime, 0);
+ if (vflag) {
+ printf("Kerberos realm %s:\n", realm);
+ printf("%s\n", krb_err_txt[k_errno]);
+ } else if (k_errno) {
+ fprintf(stderr, "%s: %s\n", progname, krb_err_txt[k_errno]);
+ exit(1);
+ }
+ return 0;
+}
+
+void
+usage()
+{
+ fprintf(stderr, "Usage: %s [-irvl] [name]\n", progname);
+ exit(1);
+}
diff --git a/eBones/usr.bin/klist/Makefile b/eBones/usr.bin/klist/Makefile
new file mode 100644
index 0000000000000..f77bf20af818e
--- /dev/null
+++ b/eBones/usr.bin/klist/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:11 markm Exp $
+
+PROG= klist
+CFLAGS+=-DKERBEROS -DDEBUG
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+MAN1= klist.1
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/klist/klist.c b/eBones/usr.bin/klist/klist.c
new file mode 100644
index 0000000000000..0927dcb7f58f2
--- /dev/null
+++ b/eBones/usr.bin/klist/klist.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Lists your current Kerberos tickets.
+ * Written by Bill Sommerfeld, MIT Project Athena.
+ *
+ * from: klist.c,v 4.15 89/08/30 11:19:16 jtkohl Exp $
+ * $Id: klist.c,v 1.3 1995/07/18 16:37:59 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: klist.c,v 1.3 1995/07/18 16:37:59 mark Exp $";
+#endif lint
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/file.h>
+#include <krb.h>
+#include <prot.h>
+#include <time.h>
+
+int ok_getst(int fd, char *s, int n);
+void display_srvtab(char *file);
+char *short_date(long *dp);
+void usage(void);
+void display_tktfile(char *file, int tgt_test, int long_form);
+
+char *whoami; /* What was I invoked as?? */
+
+extern char *krb_err_txt[];
+
+/* ARGSUSED */
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int long_form = 1;
+ int tgt_test = 0;
+ int do_srvtab = 0;
+ char *tkt_file = NULL;
+ char *cp;
+
+ whoami = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ while (*(++argv)) {
+ if (!strcmp(*argv, "-s")) {
+ long_form = 0;
+ continue;
+ }
+ if (!strcmp(*argv, "-t")) {
+ tgt_test = 1;
+ long_form = 0;
+ continue;
+ }
+ if (!strcmp(*argv, "-l")) { /* now default */
+ continue;
+ }
+ if (!strcmp(*argv, "-file")) {
+ if (*(++argv)) {
+ tkt_file = *argv;
+ continue;
+ } else
+ usage();
+ }
+ if (!strcmp(*argv, "-srvtab")) {
+ if (tkt_file == NULL) /* if no other file spec'ed,
+ set file to default srvtab */
+ tkt_file = KEYFILE;
+ do_srvtab = 1;
+ continue;
+ }
+ usage();
+ }
+
+ if (do_srvtab)
+ display_srvtab(tkt_file);
+ else
+ display_tktfile(tkt_file, tgt_test, long_form);
+ exit(0);
+}
+
+void
+display_tktfile(file, tgt_test, long_form)
+char *file;
+int tgt_test, long_form;
+{
+ char pname[ANAME_SZ];
+ char pinst[INST_SZ];
+ char prealm[REALM_SZ];
+ char buf1[20], buf2[20];
+ int k_errno;
+ CREDENTIALS c;
+ int header = 1;
+
+ if ((file == NULL) && ((file = getenv("KRBTKFILE")) == NULL))
+ file = TKT_FILE;
+
+ if (long_form)
+ printf("Ticket file: %s\n", file);
+
+ /*
+ * Since krb_get_tf_realm will return a ticket_file error,
+ * we will call tf_init and tf_close first to filter out
+ * things like no ticket file. Otherwise, the error that
+ * the user would see would be
+ * klist: can't find realm of ticket file: No ticket file (tf_util)
+ * instead of
+ * klist: No ticket file (tf_util)
+ */
+
+ /* Open ticket file */
+ if ((k_errno = tf_init(file, R_TKT_FIL))) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+ /* Close ticket file */
+ (void) tf_close();
+
+ /*
+ * We must find the realm of the ticket file here before calling
+ * tf_init because since the realm of the ticket file is not
+ * really stored in the principal section of the file, the
+ * routine we use must itself call tf_init and tf_close.
+ */
+ if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: can't find realm of ticket file: %s\n",
+ whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+
+ /* Open ticket file */
+ if ((k_errno = tf_init(file, R_TKT_FIL))) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+ /* Get principal name and instance */
+ if ((k_errno = tf_get_pname(pname)) ||
+ (k_errno = tf_get_pinst(pinst))) {
+ if (!tgt_test)
+ fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
+ exit(1);
+ }
+
+ /*
+ * You may think that this is the obvious place to get the
+ * realm of the ticket file, but it can't be done here as the
+ * routine to do this must open the ticket file. This is why
+ * it was done before tf_init.
+ */
+
+ if (!tgt_test && long_form)
+ printf("Principal:\t%s%s%s%s%s\n\n", pname,
+ (pinst[0] ? "." : ""), pinst,
+ (prealm[0] ? "@" : ""), prealm);
+ while ((k_errno = tf_get_cred(&c)) == KSUCCESS) {
+ if (!tgt_test && long_form && header) {
+ printf("%-15s %-15s %s\n",
+ " Issued", " Expires", " Principal");
+ header = 0;
+ }
+ if (tgt_test) {
+ c.issue_date += ((unsigned char) c.lifetime) * 5 * 60;
+ if (!strcmp(c.service, TICKET_GRANTING_TICKET) &&
+ !strcmp(c.instance, prealm)) {
+ if (time(0) < c.issue_date)
+ exit(0); /* tgt hasn't expired */
+ else
+ exit(1); /* has expired */
+ }
+ continue; /* not a tgt */
+ }
+ if (long_form) {
+ (void) strcpy(buf1, short_date(&c.issue_date));
+ c.issue_date += ((unsigned char) c.lifetime) * 5 * 60;
+ (void) strcpy(buf2, short_date(&c.issue_date));
+ printf("%s %s ", buf1, buf2);
+ }
+ printf("%s%s%s%s%s\n",
+ c.service, (c.instance[0] ? "." : ""), c.instance,
+ (c.realm[0] ? "@" : ""), c.realm);
+ }
+ if (tgt_test)
+ exit(1); /* no tgt found */
+ if (header && long_form && k_errno == EOF) {
+ printf("No tickets in file.\n");
+ }
+}
+
+char *
+short_date(dp)
+ long *dp;
+{
+ register char *cp;
+ extern char *ctime();
+ cp = ctime(dp) + 4;
+ cp[15] = '\0';
+ return (cp);
+}
+
+void
+usage()
+{
+ fprintf(stderr,
+ "Usage: %s [ -s | -t ] [ -file filename ] [ -srvtab ]\n", whoami);
+ exit(1);
+}
+
+void
+display_srvtab(file)
+char *file;
+{
+ int stab;
+ char serv[SNAME_SZ];
+ char inst[INST_SZ];
+ char rlm[REALM_SZ];
+ unsigned char key[8];
+ unsigned char vno;
+ int count;
+
+ printf("Server key file: %s\n", file);
+
+ if ((stab = open(file, O_RDONLY, 0400)) < 0) {
+ perror(file);
+ exit(1);
+ }
+ printf("%-15s %-15s %-10s %s\n","Service","Instance","Realm",
+ "Key Version");
+ printf("------------------------------------------------------\n");
+
+ /* argh. getst doesn't return error codes, it silently fails */
+ while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0)
+ && ((count = ok_getst(stab, inst, INST_SZ)) > 0)
+ && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) {
+ if (((count = read(stab,(char *) &vno,1)) != 1) ||
+ ((count = read(stab,(char *) key,8)) != 8)) {
+ if (count < 0)
+ perror("reading from key file");
+ else
+ fprintf(stderr, "key file truncated\n");
+ exit(1);
+ }
+ printf("%-15s %-15s %-15s %d\n",serv,inst,rlm,vno);
+ }
+ if (count < 0)
+ perror(file);
+ (void) close(stab);
+}
+
+/* adapted from getst() in librkb */
+/*
+ * ok_getst() takes a file descriptor, a string and a count. It reads
+ * from the file until either it has read "count" characters, or until
+ * it reads a null byte. When finished, what has been read exists in
+ * the given string "s". If "count" characters were actually read, the
+ * last is changed to a null, so the returned string is always null-
+ * terminated. ok_getst() returns the number of characters read, including
+ * the null terminator.
+ *
+ * If there is a read error, it returns -1 (like the read(2) system call)
+ */
+
+int
+ok_getst(fd, s, n)
+ int fd;
+ register char *s;
+ int n;
+{
+ register count = n;
+ int err;
+ while ((err = read(fd, s, 1)) > 0 && --count)
+ if (*s++ == '\0')
+ return (n - count);
+ if (err < 0)
+ return(-1);
+ *s = '\0';
+ return (n - count);
+}
diff --git a/eBones/usr.bin/ksrvtgt/Makefile b/eBones/usr.bin/ksrvtgt/Makefile
new file mode 100644
index 0000000000000..0fc63fd71ba55
--- /dev/null
+++ b/eBones/usr.bin/ksrvtgt/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:12 markm Exp $
+
+PROG= ksrvtgt
+CFLAGS+=-DKERBEROS -DDEBUG
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+MAN1= ksrvtgt.1
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/ksrvtgt/ksrvtgt.c b/eBones/usr.bin/ksrvtgt/ksrvtgt.c
new file mode 100644
index 0000000000000..0f92394b6bbd3
--- /dev/null
+++ b/eBones/usr.bin/ksrvtgt/ksrvtgt.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Get a ticket-granting-ticket given a service key file (srvtab)
+ * The lifetime is the shortest allowed [1 five-minute interval]
+ *
+ * from: ksrvtgt.c,v 4.3 89/07/28 10:17:28 jtkohl Exp $
+ * $Id: ksrvtgt.c,v 1.3 1995/07/18 16:40:07 mark Exp $
+ */
+
+#ifndef lint
+const char rcsid[] =
+"$Id: ksrvtgt.c,v 1.3 1995/07/18 16:40:07 mark Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <krb.h>
+#include <conf.h>
+
+int
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ char realm[REALM_SZ + 1];
+ register int code;
+ char srvtab[MAXPATHLEN + 1];
+
+ bzero(realm, sizeof(realm));
+ bzero(srvtab, sizeof(srvtab));
+
+ if (argc < 3 || argc > 5) {
+ fprintf(stderr, "Usage: %s name instance [[realm] srvtab]\n",
+ argv[0]);
+ exit(1);
+ }
+
+ if (argc == 4)
+ (void) strncpy(srvtab, argv[3], sizeof(srvtab) -1);
+
+ if (argc == 5) {
+ (void) strncpy(realm, argv[3], sizeof(realm) - 1);
+ (void) strncpy(srvtab, argv[4], sizeof(srvtab) -1);
+ }
+
+ if (srvtab[0] == 0)
+ (void) strcpy(srvtab, KEYFILE);
+
+ if (realm[0] == 0)
+ if (krb_get_lrealm(realm, 1) != KSUCCESS)
+ (void) strcpy(realm, KRB_REALM);
+
+ code = krb_get_svc_in_tkt(argv[1], argv[2], realm,
+ "krbtgt", realm, 1, srvtab);
+ if (code)
+ fprintf(stderr, "%s\n", krb_err_txt[code]);
+ exit(code);
+}
diff --git a/eBones/usr.bin/passwd/kpasswd.c b/eBones/usr.bin/passwd/kpasswd.c
new file mode 100644
index 0000000000000..56e76a3d762f7
--- /dev/null
+++ b/eBones/usr.bin/passwd/kpasswd.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * change your password with kerberos
+ */
+
+#ifndef lint
+#if 0
+static char rcsid_kpasswd_c[] =
+ "BonesHeader: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kpasswd.c,v 4.3 89/09/26 09:33:02 jtkohl Exp ";
+#endif
+static const char rcsid[] =
+ "$Id: kpasswd.c,v 1.1 1995/07/18 16:41:20 mark Exp $";
+#endif lint
+
+/*
+ * kpasswd
+ * change your password with kerberos
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <pwd.h>
+#include "kadm.h"
+
+#include "extern.h"
+
+extern void krb_set_tkt_string();
+static void go_home(char *, int);
+
+
+int krb_passwd(char *uname, char *iflag, char *rflag, char *uflag)
+{
+ char name[ANAME_SZ]; /* name of user */
+ char inst[INST_SZ]; /* instance of user */
+ char realm[REALM_SZ]; /* realm of user */
+ char default_name[ANAME_SZ];
+ char default_inst[INST_SZ];
+ char default_realm[REALM_SZ];
+ int realm_given = 0; /* True if realm was give on cmdline */
+ int use_default = 1; /* True if we should use default name */
+ struct passwd *pw;
+ int status; /* return code */
+ des_cblock new_key;
+ int c;
+ extern char *optarg;
+ extern int optind;
+ char tktstring[MAXPATHLEN];
+
+ void get_pw_new_key();
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else
+#define read_long_pw_string des_read_pw_string
+#endif
+ int read_long_pw_string();
+
+ bzero(name, sizeof(name));
+ bzero(inst, sizeof(inst));
+ bzero(realm, sizeof(realm));
+
+ if (krb_get_tf_fullname(TKT_FILE, default_name, default_inst,
+ default_realm) != KSUCCESS) {
+ pw = getpwuid((int) getuid());
+ if (pw) {
+ strcpy(default_name, pw->pw_name);
+ } else {
+ /* seems like a null name is kinda silly */
+ strcpy(default_name, "");
+ }
+ strcpy(default_inst, "");
+ if (krb_get_lrealm(default_realm, 1) != KSUCCESS)
+ strcpy(default_realm, KRB_REALM);
+ }
+
+ if(uflag) {
+ if (status = kname_parse(name, inst, realm, uflag)) {
+ errx(2, "Kerberos error: %s", krb_err_txt[status]);
+ }
+ if (realm[0])
+ realm_given++;
+ else
+ if (krb_get_lrealm(realm, 1) != KSUCCESS)
+ strcpy(realm, KRB_REALM);
+ }
+
+ if(uname) {
+ if (k_isname(uname)) {
+ strncpy(name, uname, sizeof(name) - 1);
+ } else {
+ errx(1, "bad name: %s", uname);
+ }
+ }
+
+ if(iflag) {
+ if (k_isinst(iflag)) {
+ strncpy(inst, iflag, sizeof(inst) - 1);
+ } else {
+ errx(1, "bad instance: %s", iflag);
+ }
+ }
+
+ if(rflag) {
+ if (k_isrealm(rflag)) {
+ strncpy(realm, rflag, sizeof(realm) - 1);
+ realm_given++;
+ } else {
+ errx(1, "bad realm: %s", rflag);
+ }
+ }
+
+ if(uname || iflag || rflag || uflag) use_default = 0;
+
+ if (use_default) {
+ strcpy(name, default_name);
+ strcpy(inst, default_inst);
+ strcpy(realm, default_realm);
+ } else {
+ if (!name[0])
+ strcpy(name, default_name);
+ if (!realm[0])
+ strcpy(realm, default_realm);
+ }
+
+ (void) sprintf(tktstring, "/tmp/tkt_cpw_%d",getpid());
+ krb_set_tkt_string(tktstring);
+
+ get_pw_new_key(new_key, name, inst, realm, realm_given);
+
+ if ((status = kadm_init_link("changepw", KRB_MASTER, realm))
+ != KADM_SUCCESS)
+ com_err("kpasswd", status, "while initializing");
+ else if ((status = kadm_change_pw(new_key)) != KADM_SUCCESS)
+ com_err("kpasswd", status, " attempting to change password.");
+
+ if (status != KADM_SUCCESS)
+ fprintf(stderr,"Password NOT changed.\n");
+ else
+ printf("Password changed.\n");
+
+ (void) dest_tkt();
+ if (status)
+ exit(2);
+ else
+ exit(0);
+}
+
+void get_pw_new_key(new_key, name, inst, realm, print_realm)
+ des_cblock new_key;
+ char *name;
+ char *inst;
+ char *realm;
+ int print_realm; /* True if realm was give on cmdline */
+{
+ char ppromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
+ char pword[MAX_KPW_LEN]; /* storage for the password */
+ char npromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
+
+ char local_realm[REALM_SZ];
+ int status;
+
+ /*
+ * We don't care about failure; this is to determine whether or
+ * not to print the realm in the prompt for a new password.
+ */
+ (void) krb_get_lrealm(local_realm, 1);
+
+ if (strcmp(local_realm, realm))
+ print_realm++;
+
+ (void) sprintf(ppromp,"Old password for %s%s%s%s%s:",
+ name, *inst ? "." : "", inst,
+ print_realm ? "@" : "", print_realm ? realm : "");
+ if (read_long_pw_string(pword, sizeof(pword)-1, ppromp, 0)) {
+ fprintf(stderr, "Error reading old password.\n");
+ exit(1);
+ }
+
+ if ((status = krb_get_pw_in_tkt(name, inst, realm, PWSERV_NAME,
+ KADM_SINST, 1, pword)) != KSUCCESS) {
+ if (status == INTK_BADPW) {
+ printf("Incorrect old password.\n");
+ exit(0);
+ }
+ else {
+ fprintf(stderr, "Kerberos error: %s\n", krb_err_txt[status]);
+ exit(1);
+ }
+ }
+ bzero(pword, sizeof(pword));
+ do {
+ (void) sprintf(npromp,"New Password for %s%s%s%s%s:",
+ name, *inst ? "." : "", inst,
+ print_realm ? "@" : "", print_realm ? realm : "");
+ if (read_long_pw_string(pword, sizeof(pword)-1, npromp, 1))
+ go_home("Error reading new password, password unchanged.\n",0);
+ if (strlen(pword) == 0)
+ printf("Null passwords are not allowed; try again.\n");
+ } while (strlen(pword) == 0);
+
+#ifdef NOENCRYPTION
+ bzero((char *) new_key, sizeof(des_cblock));
+ new_key[0] = (unsigned char) 1;
+#else
+ (void) des_string_to_key(pword, new_key);
+#endif
+ bzero(pword, sizeof(pword));
+}
+
+static void
+go_home(str,x)
+ char *str;
+ int x;
+{
+ fprintf(stderr, str, x);
+ (void) dest_tkt();
+ exit(1);
+}
diff --git a/eBones/usr.bin/register/Makefile b/eBones/usr.bin/register/Makefile
new file mode 100644
index 0000000000000..82a411cfc31a4
--- /dev/null
+++ b/eBones/usr.bin/register/Makefile
@@ -0,0 +1,11 @@
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+# $Id: Makefile,v 1.4 1995/09/13 17:24:14 markm Exp $
+
+PROG= register
+CFLAGS+=-DCRYPT -DDEBUG -DKERBEROS
+DPADD= ${LIBKRB} ${LIBDES} ${LIBCRYPT}
+LDADD= -lkrb -ldes -lcrypt
+BINOWN= root
+BINMODE=4555
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/register/register.c b/eBones/usr.bin/register/register.c
new file mode 100644
index 0000000000000..7050cca1284b6
--- /dev/null
+++ b/eBones/usr.bin/register/register.c
@@ -0,0 +1,316 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+static char sccsid[] = "@(#)register.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <des.h>
+#include <krb.h>
+#include "pathnames.h"
+#include "register_proto.h"
+
+#define SERVICE "krbupdate" /* service to add to KDC's database */
+#define PROTOCOL "tcp"
+
+void die(int);
+void type_info(void);
+void setup_key(struct sockaddr_in local);
+void cleanup(void);
+int get_user_info(void);
+
+char realm[REALM_SZ];
+char krbhst[MAX_HSTNM];
+
+static char pname[ANAME_SZ];
+static char iname[INST_SZ];
+static char password[_PASSWORD_LEN];
+
+void
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct servent *se;
+ struct hostent *host;
+ struct sockaddr_in sin, local;
+ int rval;
+ int sock, llen;
+ u_char code;
+ static struct rlimit rl = { 0, 0 };
+
+ signal(SIGPIPE, die);
+
+ if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+ perror("rlimit");
+ exit(1);
+ }
+
+ if ((se = getservbyname(SERVICE, PROTOCOL)) == NULL) {
+ fprintf(stderr, "couldn't find entry for service %s\n",
+ SERVICE);
+ exit(1);
+ }
+ if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) {
+ fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
+ krb_err_txt[rval]);
+ exit(1);
+ }
+
+ if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
+ fprintf(stderr, "couldn't get Kerberos host: %s\n",
+ krb_err_txt[rval]);
+ exit(1);
+ }
+
+ if ((host = gethostbyname(krbhst)) == NULL) {
+ fprintf(stderr, "couldn't get host entry for host %s\n",
+ krbhst);
+ exit(1);
+ }
+
+ sin.sin_family = host->h_addrtype;
+ (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
+ sin.sin_port = se->s_port;
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+ perror("connect");
+ (void)close(sock);
+ exit(1);
+ }
+
+ llen = sizeof(local);
+ if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
+ perror("getsockname");
+ (void)close(sock);
+ exit(1);
+ }
+
+ setup_key(local);
+
+ type_info();
+
+ if (!get_user_info()) {
+ code = ABORT;
+ (void)des_write(sock, &code, 1);
+ cleanup();
+ exit(1);
+ }
+
+ code = APPEND_DB;
+ if (des_write(sock, &code, 1) != 1) {
+ perror("write 1");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
+ perror("write principal name");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, iname, INST_SZ) != INST_SZ) {
+ perror("write instance name");
+ cleanup();
+ exit(1);
+ }
+
+ if (des_write(sock, password, 255) != 255) {
+ perror("write password");
+ cleanup();
+ exit(1);
+ }
+
+ /* get return message */
+
+ {
+ int cc;
+ char msgbuf[BUFSIZ];
+
+ cc = read(sock, msgbuf, BUFSIZ);
+ if (cc <= 0) {
+ fprintf(stderr, "protocol error during key verification\n");
+ cleanup();
+ exit(1);
+ }
+ if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
+ fprintf(stderr, "%s: %s", krbhst, msgbuf);
+ cleanup();
+ exit(1);
+ }
+
+ cc = des_read(sock, msgbuf, BUFSIZ);
+ if (cc <= 0) {
+ fprintf(stderr, "protocol error during read\n");
+ cleanup();
+ exit(1);
+ } else {
+ printf("%s: %s", krbhst, msgbuf);
+ }
+ }
+
+ cleanup();
+ close(sock);
+}
+
+void
+cleanup()
+{
+ bzero(password, 255);
+}
+
+extern char *crypt();
+extern char *getpass();
+
+int
+get_user_info()
+{
+ int uid = getuid();
+ int valid = 0, i;
+ struct passwd *pw;
+ char *pas, *namep;
+
+ /* NB: we must run setuid-root to get at the real pw file */
+
+ if ((pw = getpwuid(uid)) == NULL) {
+ fprintf(stderr, "Who are you?\n");
+ return(0);
+ }
+ (void)seteuid(uid);
+ (void)strcpy(pname, pw->pw_name); /* principal name */
+
+ for (i = 1; i < 3; i++) {
+ pas = getpass("login password:");
+ namep = crypt(pas, pw->pw_passwd);
+ if (strcmp(namep, pw->pw_passwd)) {
+ fprintf(stderr, "Password incorrect\n");
+ continue;
+ } else {
+ valid = 1;
+ break;
+ }
+ }
+ if (!valid)
+ return(0);
+ pas = getpass("Kerberos password (may be the same):");
+ while (*pas == NULL) {
+ printf("<NULL> password not allowed\n");
+ pas = getpass("Kerberos password (may be the same):");
+ }
+ (void)strcpy(password, pas); /* password */
+ pas = getpass("Retype Kerberos password:");
+ if (strcmp(password, pas)) {
+ fprintf(stderr, "Password mismatch -- aborted\n");
+ return(0);
+ }
+
+ iname[0] = NULL; /* null instance name */
+ return(1);
+}
+
+void
+setup_key(local)
+ struct sockaddr_in local;
+{
+ static struct keyfile_data kdata;
+ static Key_schedule schedule;
+ int fd;
+ char namebuf[MAXPATHLEN];
+
+ (void) sprintf(namebuf, "%s%s",
+ CLIENT_KEYFILE,
+ inet_ntoa(local.sin_addr));
+
+ fd = open(namebuf, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "couldn't open key file %s for local host: ",
+ namebuf);
+ perror("");
+ exit(1);
+ }
+
+ if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
+ fprintf(stderr,"size error reading key file for local host %s\n",
+ inet_ntoa(local.sin_addr));
+ exit(1);
+ }
+ key_sched((des_cblock *)kdata.kf_key, schedule);
+ des_set_key((des_cblock *)kdata.kf_key, schedule);
+ return;
+}
+
+void
+type_info()
+{
+ printf("Kerberos user registration (realm %s)\n\n", realm);
+ printf("Please enter your login password followed by your new Kerberos password.\n");
+ printf("The Kerberos password you enter now will be used in the future\n");
+ printf("as your Kerberos password for all machines in the %s realm.\n", realm);
+ printf("You will only be allowed to perform this operation once, although you may run\n");
+ printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD);
+}
+
+void
+die(sig)
+ int sig;
+{
+ fprintf(stderr, "\nServer no longer listening\n");
+ fflush(stderr);
+ cleanup();
+ exit(1);
+}
diff --git a/eBones/usr.bin/rkinit/Makefile b/eBones/usr.bin/rkinit/Makefile
new file mode 100644
index 0000000000000..b910742fe1b05
--- /dev/null
+++ b/eBones/usr.bin/rkinit/Makefile
@@ -0,0 +1,11 @@
+# Makefile,v 1.2 1995/01/20 22:08:14 wollman Exp
+
+PROG= rkinit
+SRCS= ${RKINITOBJDIR}/rkinit_err.h rkinit.c
+CFLAGS+= -I${KRBOBJDIR} -I${RKINITOBJDIR}
+LDADD+= -L${RKINITOBJDIR} -lrkinit -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+LDADD+= -lss -lcom_err
+
+MAN1= rkinit.1
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.bin/rkinit/rkinit.1 b/eBones/usr.bin/rkinit/rkinit.1
new file mode 100644
index 0000000000000..5634d2b7483c9
--- /dev/null
+++ b/eBones/usr.bin/rkinit/rkinit.1
@@ -0,0 +1,206 @@
+.\"
+.\" $Header: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinit.1,v 1.1 1991/12/03 23:21:25 eichin Exp $
+.\" $Source: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinit.1,v $
+.\" $Author: eichin $
+.\"
+.\"
+.TH RKINIT 1 "November 12, 1989"
+.UC 4
+.SH NAME
+rkinit \- establish kerberos tickets safely on a remote host
+.SH SYNOPSIS
+.B rkinit [ host ]
+[ -p
+.B principal
+] [ -l
+.B username
+] [ -k
+.B kerberos_realm
+] [ -f
+.B ticket_file
+] [ -h
+.B remote_host
+] [ -t
+.B ticket_lifetime
+] [
+.B \-notimeout
+]
+
+A host name must be specified either as the first command line
+argument or following a \-h flag. If redundant command line
+arguments are given, the last one to appear takes precedence.
+
+.SH DESCRIPTION
+.I rkinit
+is a program that allows a user to establish kerberos tickets on
+a remote host registered for
+rlogin service. This can be done without the user's kerberos
+password ever leaving the client machine.
+
+In order to establish tickets remotely
+without the use of something like
+.I rkinit,
+one would have to log in to the
+remote host and run
+.IR kinit (1).
+.I rkinit
+followed by
+.I rlogin
+can be thought of as a safe substitute for
+.I rlogin
+followed
+.I kinit.
+
+.I rkinit
+uses the same access checking mechanism as
+.I rlogin.
+That means that
+.I rkinit
+can be used to create any tickets for user
+.I A
+on remote host
+.I B
+if and only if
+.IR A 's
+tickets would entitle a login to
+.I B.
+This means that one can create remote tickets for himself or for
+another user if he is in that user's .klogin file.
+
+.I rkinit
+understands the following command line options:
+
+.TP 4
+.B \-p \fIprincipal\fR
+If
+.I principal,
+in the format
+.I name[.inst][@realm]
+is specified, the tickets created on the remote host will be the
+tickets indicated by the
+.I principal
+field. If this option is not given, the following defaults are
+used: If the user running
+.I rkinit
+does not have tickets on the client machine,
+.I rkinit
+will prompt for a password and behave effectively as if the user
+had invoked
+.I kinit
+on the specified
+remote host; i.e.,
+the tickets established will be owned on the remote host
+by the user who invoked
+.I rkinit
+and will be for the local realm of the
+remote host.
+If the user running
+.I rkinit
+already has tickets,
+.I rkinit
+will prompt for a password and create tickets whose principal
+matches that of the
+tickets that the user already has.
+
+
+.TP
+.B \-l \fIusername\fR
+If
+.I username
+is specified, the ticket file on the remote host will be owned by the
+user
+.I username.
+If it is not specified, the tickets will be owned by
+the remote user whose login name matches that of the user invoking
+.I rkinit.
+
+.TP
+.B \-r \fIrealm\fR
+.I realm
+is used to tell
+.I rkinit
+what realm the remote host is in. This
+option should not usually have to be used since
+.I rkinit
+uses
+.IR krb_realmofhost (3)
+to determine the remote host's kerberos realm. Note that this
+is distinct from realm as specified in
+.I principal,
+which refers to the realm of the remote tickets.
+
+.TP
+.B \-f \fIticket_file\fR
+This option is used to specify the name of the ticket file that
+should be used on the remote host. Note that if you
+specify a location for the ticket file that is other
+than the default, you will have to set the environment variable
+KRBTKFILE to that filename once you get to the remote host in
+order for you to use the tickets.
+If a ticket file is not specified, the tickets will
+be placed in the
+default location as specified by
+.IR tkt_file (3).
+On a UNIX host, this is /tmp/tkt<uid>, where
+<uid> is the user id of the person who owns the remote ticket file.
+
+.TP
+.B \-h \fIremote_host\fR
+.I remote host
+is the host on which remote tickets are being obtained. This
+option can be used in place of specifying the host as the first
+command line argument.
+
+.TP
+.B \-t \fIticket_lifetime\fR
+.I ticket lifetime
+is the lifetime in minutes of the remote tickets. If it is not
+specified, the default ticket life time (as defined in krb.h) is
+used.
+
+.TP
+.B \-notimeout
+prevents the client from timing out. This is mainly useful only
+for debugging since the rkinit server also times out.
+
+.SH EXAMPLES
+
+In the following examples,
+.B tabetha
+and
+.B soup
+are machines in the
+.B ATHENA.MIT.EDU
+kerberos realm and
+.B local
+is a user who can log in
+to
+.B soup
+and has
+.B qjb.root@ATHENA.MIT.EDU
+in his .klogin file.
+
+
+% rkinit tabetha
+.br
+Kerberos initialization (tabetha)
+.br
+Password for qjb@ATHENA.MIT.EDU:
+.br
+%
+.br
+
+.br
+% rkinit soup -p qjb.root -l local
+.br
+Kerberos initialization (soup): tickets will be owned by local
+.br
+Password for qjb.root@ATHENA.MIT.EDU:
+.br
+%
+
+.SH SEE ALSO
+rkinitd(8), kerberos(1), kerberos(3), kinit(1)
+
+.SH AUTHOR
+Emanuel Jay Berkenbilt (MIT-Project Athena)
diff --git a/eBones/usr.bin/rkinit/rkinit.c b/eBones/usr.bin/rkinit/rkinit.c
new file mode 100644
index 0000000000000..35a0eebfaa101
--- /dev/null
+++ b/eBones/usr.bin/rkinit/rkinit.c
@@ -0,0 +1,216 @@
+/*
+ * $Id: rkinit.c,v 1.1 1993/12/10 18:41:00 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/rkinit/RCS/rkinit.c,v $
+ * $Author: dglo $
+ *
+ * This is an rkinit client
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: rkinit.c,v 1.1 1993/12/10 18:41:00 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <krb.h>
+#include <des.h>
+#include <com_err.h>
+
+#include <rkinit.h>
+#include <rkinit_err.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifdef __STDC__
+static void usage(void)
+#else
+static void usage()
+#endif /* __STDC__ */
+{
+ fprintf(stderr,"Usage: rkinit [host] options\n");
+ fprintf(stderr,
+ "Options: [-l username] [-k krb_realm] [-p principal] [-f tktfile]\n");
+ fprintf(stderr, " [-t lifetime] [-h host] [-notimeout]\n");
+ fprintf(stderr, "A host must be specified either with the -h option ");
+ fprintf(stderr, "or as the first argument.\n");
+
+ exit(1);
+}
+
+int
+#ifdef __STDC__
+main(int argc, char *argv[])
+#else
+main(argc, argv)
+ int argc;
+ char *argv[];
+#endif /* __STDC__ */
+{
+ char *whoami; /* Name of this program */
+
+ char principal[MAX_K_NAME_SZ]; /* Principal for which to get tickets */
+ char *host = NULL; /* Remote host */
+ char *username = 0; /* Username of owner of ticket */
+ char r_krealm[REALM_SZ]; /* Kerberos realm of remote host */
+ char aname[ANAME_SZ]; /* Aname of remote ticket file */
+ char inst[INST_SZ]; /* Instance of remote ticket file */
+ char realm[REALM_SZ]; /* Realm of remote ticket file */
+ char *tktfilename = NULL; /* Name of ticket file on remote host */
+ u_long lifetime = DEFAULT_TKT_LIFE; /* Lifetime of remote tickets */
+ int timeout = TRUE; /* Should we time out? */
+ rkinit_info info; /* Information needed by rkinit */
+
+ struct passwd *localid; /* To determine local id */
+
+ int status = 0; /* general error number */
+
+ int i;
+
+ bzero(r_krealm, sizeof(r_krealm));
+ bzero(principal, sizeof(principal));
+ bzero(aname, sizeof(aname));
+ bzero(inst, sizeof(inst));
+ bzero(realm, sizeof(realm));
+
+ /* Parse commandline arguements. */
+ if ((whoami = rindex(argv[0], '/')) == 0)
+ whoami = argv[0];
+ else
+ whoami++;
+
+ if (argc < 2) usage();
+
+ if (argv[1][0] != '-') {
+ host = argv[1];
+ i = 2;
+ }
+ else
+ i = 1;
+
+ for (/* i initialized above */; i < argc; i++) {
+ if (strcmp(argv[i], "-h") == NULL) {
+ if (++i >= argc)
+ usage();
+ else
+ host = argv[i];
+ }
+ else if (strcmp(argv[i], "-l") == NULL) {
+ if (++i >= argc)
+ usage();
+ else
+ username = argv[i];
+ }
+ else if (strcmp(argv[i], "-k") == NULL) {
+ if (++i >= argc)
+ usage();
+ else
+ strncpy(r_krealm, argv[i], sizeof(r_krealm) - 1);
+ }
+ else if (strcmp(argv[i], "-p") == NULL) {
+ if (++i >= argc)
+ usage();
+ else
+ strncpy(principal, argv[i], sizeof(principal) - 1);
+ }
+ else if (strcmp(argv[i], "-f") == NULL) {
+ if (++i >= argc)
+ usage();
+ else
+ tktfilename = argv[i];
+ }
+ else if (strcmp(argv[i], "-t") == NULL) {
+ if (++i >= argc)
+ usage();
+ else {
+ lifetime = atoi(argv[i])/5;
+ if (lifetime == 0)
+ lifetime = 1;
+ else if (lifetime > 255)
+ lifetime = 255;
+ }
+ }
+ else if (strcmp(argv[i], "-notimeout") == NULL)
+ timeout = FALSE;
+ else
+ usage();
+ }
+
+ if (host == NULL)
+ usage();
+
+ /* Initialize the realm of the remote host if necessary */
+ if (r_krealm[0] == 0) {
+ /*
+ * Try to figure out the realm of the remote host. If the
+ * remote host is unknown, don't worry about it; the library
+ * will handle the error better and print a good error message.
+ */
+ struct hostent *hp;
+ if ((hp = gethostbyname(host)))
+ strcpy(r_krealm, krb_realmofhost(hp->h_name));
+ }
+
+ /* If no username was specified, use local id on client host */
+ if (username == 0) {
+ if ((localid = getpwuid(getuid())) == 0) {
+ fprintf(stderr, "You can not be found in the password file.\n");
+ exit(1);
+ }
+ username = localid->pw_name;
+ }
+
+ /* Find out who will go in the ticket file */
+ if (! principal[0]) {
+ if ((status = krb_get_tf_fullname(TKT_FILE, aname, inst, realm))
+ != KSUCCESS) {
+ /*
+ * If user has no ticket file and principal was not specified,
+ * we will try to get tickets for username@remote_realm
+ */
+ strcpy(aname, username);
+ strcpy(realm, r_krealm);
+ }
+ }
+ else {
+ if ((status = kname_parse(aname, inst, realm, principal))
+ != KSUCCESS) {
+ fprintf(stderr, "%s\n", krb_err_txt[status]);
+ exit(1);
+ }
+ if (strlen(realm) == 0) {
+ if (krb_get_lrealm(realm, 1) != KSUCCESS)
+ strcpy(realm, KRB_REALM);
+ }
+ }
+
+ bzero((char *)&info, sizeof(info));
+
+ strcpy(info.aname, aname);
+ strcpy(info.inst, inst);
+ strcpy(info.realm, realm);
+ strcpy(info.sname, "krbtgt");
+ strcpy(info.sinst, realm);
+ strncpy(info.username, username, sizeof(info.username) - 1);
+ if (tktfilename)
+ strncpy(info.tktfilename, tktfilename, sizeof(info.tktfilename) - 1);
+ info.lifetime = lifetime;
+
+ if ((status = rkinit(host, r_krealm, &info, timeout))) {
+ com_err(whoami, status, "while obtaining remote tickets:");
+ fprintf(stderr, "%s\n", rkinit_errmsg(0));
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/eBones/usr.sbin/Makefile b/eBones/usr.sbin/Makefile
new file mode 100644
index 0000000000000..4d583fc0282fa
--- /dev/null
+++ b/eBones/usr.sbin/Makefile
@@ -0,0 +1,7 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id$
+
+SUBDIR= ext_srvtab kadmind kdb_destroy kdb_edit kdb_init kdb_util \
+ kerberos kprop ksrvutil kstash make_keypair
+
+.include <bsd.subdir.mk>
diff --git a/eBones/usr.sbin/Makefile.inc b/eBones/usr.sbin/Makefile.inc
new file mode 100644
index 0000000000000..a3ace61925937
--- /dev/null
+++ b/eBones/usr.sbin/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/6/93
+
+BINDIR?= /usr/sbin
+
+.include "../Makefile.inc"
diff --git a/eBones/usr.sbin/ext_srvtab/Makefile b/eBones/usr.sbin/ext_srvtab/Makefile
new file mode 100644
index 0000000000000..e1ee1d512eb33
--- /dev/null
+++ b/eBones/usr.sbin/ext_srvtab/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:16 markm Exp $
+
+PROG= ext_srvtab
+CFLAGS+=-DKERBEROS
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD+= -lkdb -lkrb -ldes
+MAN8= ext_srvtab.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/ext_srvtab/ext_srvtab.c b/eBones/usr.sbin/ext_srvtab/ext_srvtab.c
new file mode 100644
index 0000000000000..6f250138cf940
--- /dev/null
+++ b/eBones/usr.sbin/ext_srvtab/ext_srvtab.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * from: ext_srvtab.c,v 4.1 89/07/18 16:49:30 jtkohl Exp $
+ * $Id: ext_srvtab.c,v 1.3 1995/07/18 16:35:55 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: ext_srvtab.c,v 1.3 1995/07/18 16:35:55 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#define TRUE 1
+#define FALSE 0
+
+static C_Block master_key;
+static C_Block session_key;
+static Key_schedule master_key_schedule;
+char progname[] = "ext_srvtab";
+char realm[REALM_SZ];
+
+void FWrite(char *p, int size, int n, FILE *f);
+void StampOutSecrets(void);
+void usage(void);
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ FILE *fout;
+ char fname[1024];
+ int fopen_errs = 0;
+ int arg;
+ Principal princs[40];
+ int more;
+ int prompt = TRUE;
+ register int n, i;
+
+ bzero(realm, sizeof(realm));
+
+ /* Parse commandline arguments */
+ if (argc < 2)
+ usage();
+ else {
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-n") == 0)
+ prompt = FALSE;
+ else if (strcmp(argv[i], "-r") == 0) {
+ if (++i >= argc)
+ usage();
+ else {
+ strcpy(realm, argv[i]);
+ /*
+ * This is to humor the broken way commandline
+ * argument parsing is done. Later, this
+ * program ignores everything that starts with -.
+ */
+ argv[i][0] = '-';
+ }
+ }
+ else if (argv[i][0] == '-')
+ usage();
+ else
+ if (!k_isinst(argv[i])) {
+ fprintf(stderr, "%s: bad instance name: %s\n",
+ progname, argv[i]);
+ usage();
+ }
+ }
+ }
+
+ if (kdb_get_master_key (prompt, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "Couldn't read master key.\n");
+ fflush (stderr);
+ exit(1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ exit(1);
+ }
+
+ /* For each arg, search for instances of arg, and produce */
+ /* srvtab file */
+ if (!realm[0])
+ if (krb_get_lrealm(realm, 1) != KSUCCESS) {
+ fprintf(stderr, "%s: couldn't get local realm\n", progname);
+ exit(1);
+ }
+ (void) umask(077);
+
+ for (arg = 1; arg < argc; arg++) {
+ if (argv[arg][0] == '-')
+ continue;
+ sprintf(fname, "%s-new-srvtab", argv[arg]);
+ if ((fout = fopen(fname, "w")) == NULL) {
+ fprintf(stderr, "Couldn't create file '%s'.\n", fname);
+ fopen_errs++;
+ continue;
+ }
+ printf("Generating '%s'....\n", fname);
+ n = kerb_get_principal("*", argv[arg], &princs[0], 40, &more);
+ if (more)
+ fprintf(stderr, "More than 40 found...\n");
+ for (i = 0; i < n; i++) {
+ FWrite(princs[i].name, strlen(princs[i].name) + 1, 1, fout);
+ FWrite(princs[i].instance, strlen(princs[i].instance) + 1,
+ 1, fout);
+ FWrite(realm, strlen(realm) + 1, 1, fout);
+ FWrite(&princs[i].key_version,
+ sizeof(princs[i].key_version), 1, fout);
+ bcopy(&princs[i].key_low, session_key, sizeof(long));
+ bcopy(&princs[i].key_high, session_key + sizeof(long),
+ sizeof(long));
+ kdb_encrypt_key (session_key, session_key,
+ master_key, master_key_schedule, DES_DECRYPT);
+ FWrite(session_key, sizeof session_key, 1, fout);
+ }
+ fclose(fout);
+ }
+
+ StampOutSecrets();
+
+ exit(fopen_errs); /* 0 errors if successful */
+
+}
+
+void
+Die()
+{
+ StampOutSecrets();
+ exit(1);
+}
+
+void
+FWrite(p, size, n, f)
+ char *p;
+ int size;
+ int n;
+ FILE *f;
+{
+ if (fwrite(p, size, n, f) != n) {
+ printf("Error writing output file. Terminating.\n");
+ Die();
+ }
+}
+
+void
+StampOutSecrets()
+{
+ bzero(master_key, sizeof master_key);
+ bzero(session_key, sizeof session_key);
+ bzero(master_key_schedule, sizeof master_key_schedule);
+}
+
+void
+usage()
+{
+ fprintf(stderr,
+ "Usage: %s [-n] [-r realm] instance [instance ...]\n", progname);
+ exit(1);
+}
diff --git a/eBones/usr.sbin/kadmind/Makefile b/eBones/usr.sbin/kadmind/Makefile
new file mode 100644
index 0000000000000..37222ef002500
--- /dev/null
+++ b/eBones/usr.sbin/kadmind/Makefile
@@ -0,0 +1,10 @@
+# $Id: Makefile,v 1.4 1995/09/13 17:24:18 markm Exp $
+
+PROG= kadmind
+SRCS= admin_server.c kadm_funcs.c kadm_ser_wrap.c kadm_server.c
+CFLAGS+=-DPOSIX -I${.CURDIR}/../../lib/libkadm
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD+= -lkadm -lkdb -lkrb -ldes -lacl -lcom_err
+MAN8= kadmind.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kadmind/admin_server.c b/eBones/usr.sbin/kadmind/admin_server.c
new file mode 100644
index 0000000000000..6f8c7f78b2675
--- /dev/null
+++ b/eBones/usr.sbin/kadmind/admin_server.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Top-level loop of the kerberos Administration server
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_admin_server_c[] =
+"Id: admin_server.c,v 4.8 90/01/02 13:50:38 jtkohl Exp ";
+static const char rcsid[] =
+ "$Id";
+#endif lint
+#endif
+
+/*
+ admin_server.c
+ this holds the main loop and initialization and cleanup code for the server
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#ifndef sigmask
+#define sigmask(m) (1 <<((m)-1))
+#endif
+#include <sys/wait.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <syslog.h>
+#include <com_err.h>
+#include <kadm.h>
+#include <kerberosIV/kadm_err.h>
+#include <krb_db.h>
+#include "kadm_server.h"
+
+/* Almost all procs and such need this, so it is global */
+admin_params prm; /* The command line parameters struct */
+
+char prog[32]; /* WHY IS THIS NEEDED??????? */
+char *progname = prog;
+char *acldir = DEFAULT_ACL_DIR;
+char krbrlm[REALM_SZ];
+extern Kadm_Server server_parm;
+
+void cleanexit(int val);
+void process_client(int fd, struct sockaddr_in *who);
+void kill_children(void);
+static void clear_secrets(void);
+void byebye(void);
+void close_syslog(void);
+int kadm_listen(void);
+
+/*
+** Main does the logical thing, it sets up the database and RPC interface,
+** as well as handling the creation and maintenance of the syslog file...
+*/
+void
+main(argc, argv) /* admin_server main routine */
+int argc;
+char *argv[];
+{
+ int errval;
+ int c;
+ extern char *optarg;
+
+ prog[sizeof(prog)-1]='\0'; /* Terminate... */
+ (void) strncpy(prog, argv[0], sizeof(prog)-1);
+
+ /* initialize the admin_params structure */
+ prm.sysfile = KADM_SYSLOG; /* default file name */
+ prm.inter = 1;
+
+ bzero(krbrlm, sizeof(krbrlm));
+
+ while ((c = getopt(argc, argv, "f:hnd:a:r:")) != EOF)
+ switch(c) {
+ case 'f': /* Syslog file name change */
+ prm.sysfile = optarg;
+ break;
+ case 'n':
+ prm.inter = 0;
+ break;
+ case 'a': /* new acl directory */
+ acldir = optarg;
+ break;
+ case 'd':
+ /* put code to deal with alt database place */
+ if ((errval = kerb_db_set_name(optarg))) {
+ fprintf(stderr, "opening database %s: %s",
+ optarg, error_message(errval));
+ exit(1);
+ }
+ break;
+ case 'r':
+ (void) strncpy(krbrlm, optarg, sizeof(krbrlm) - 1);
+ break;
+ case 'h': /* get help on using admin_server */
+ default:
+ printf("Usage: admin_server [-h] [-n] [-r realm] [-d dbname] [-f filename] [-a acldir]\n");
+ exit(-1); /* failure */
+ }
+
+ if (krbrlm[0] == 0)
+ if (krb_get_lrealm(krbrlm, 0) != KSUCCESS) {
+ fprintf(stderr,
+ "Unable to get local realm. Fix krb.conf or use -r.\n");
+ exit(1);
+ }
+
+ printf("KADM Server %s initializing\n",KADM_VERSTR);
+ printf("Please do not use 'kill -9' to kill this job, use a\n");
+ printf("regular kill instead\n\n");
+
+ set_logfile(prm.sysfile);
+ log("Admin server starting");
+
+ (void) kerb_db_set_lockmode(KERB_DBL_NONBLOCKING);
+ errval = kerb_init(); /* Open the Kerberos database */
+ if (errval) {
+ fprintf(stderr, "error: kerb_init() failed");
+ close_syslog();
+ byebye();
+ }
+ /* set up the server_parm struct */
+ if ((errval = kadm_ser_init(prm.inter, krbrlm))==KADM_SUCCESS) {
+ kerb_fini(); /* Close the Kerberos database--
+ will re-open later */
+ errval = kadm_listen(); /* listen for calls to server from
+ clients */
+ }
+ if (errval != KADM_SUCCESS) {
+ fprintf(stderr,"error: %s\n",error_message(errval));
+ kerb_fini(); /* Close if error */
+ }
+ close_syslog(); /* Close syslog file, print
+ closing note */
+ byebye(); /* Say bye bye on the terminal
+ in use */
+} /* procedure main */
+
+
+/* close the system log file */
+void
+close_syslog()
+{
+ log("Shutting down admin server");
+}
+
+void
+byebye() /* say goodnight gracie */
+{
+ printf("Admin Server (kadm server) has completed operation.\n");
+}
+
+static void
+clear_secrets()
+{
+ bzero((char *)server_parm.master_key, sizeof(server_parm.master_key));
+ bzero((char *)server_parm.master_key_schedule,
+ sizeof(server_parm.master_key_schedule));
+ server_parm.master_key_version = 0L;
+}
+
+static exit_now = 0;
+
+sigtype
+doexit()
+{
+ exit_now = 1;
+#ifdef POSIX
+ return;
+#else /* !POSIX */
+ return(0);
+#endif /* POSIX */
+}
+
+unsigned pidarraysize = 0;
+int *pidarray = (int *)0;
+
+/*
+kadm_listen
+listen on the admin servers port for a request
+*/
+int
+kadm_listen()
+{
+ extern int errno;
+ int found;
+ int admin_fd;
+ int peer_fd;
+ fd_set mask, readfds;
+ struct sockaddr_in peer;
+ int addrlen;
+ int pid;
+ sigtype do_child();
+
+ (void) signal(SIGINT, doexit);
+ (void) signal(SIGTERM, doexit);
+ (void) signal(SIGHUP, doexit);
+ (void) signal(SIGQUIT, doexit);
+ (void) signal(SIGPIPE, SIG_IGN); /* get errors on write() */
+ (void) signal(SIGALRM, doexit);
+ (void) signal(SIGCHLD, do_child);
+
+ if ((admin_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ return KADM_NO_SOCK;
+ if (bind(admin_fd, (struct sockaddr *)&server_parm.admin_addr,
+ sizeof(struct sockaddr_in)) < 0)
+ return KADM_NO_BIND;
+ (void) listen(admin_fd, 1);
+ FD_ZERO(&mask);
+ FD_SET(admin_fd, &mask);
+
+ for (;;) { /* loop nearly forever */
+ if (exit_now) {
+ clear_secrets();
+ kill_children();
+ return(0);
+ }
+ readfds = mask;
+ if ((found = select(admin_fd+1,&readfds,(fd_set *)0,
+ (fd_set *)0, (struct timeval *)0)) == 0)
+ continue; /* no things read */
+ if (found < 0) {
+ if (errno != EINTR)
+ log("select: %s",error_message(errno));
+ continue;
+ }
+ if (FD_ISSET(admin_fd, &readfds)) {
+ /* accept the conn */
+ addrlen = sizeof(peer);
+ if ((peer_fd = accept(admin_fd, (struct sockaddr *)&peer,
+ &addrlen)) < 0) {
+ log("accept: %s",error_message(errno));
+ continue;
+ }
+ addrlen = sizeof(server_parm.admin_addr);
+ if (getsockname(peer_fd, (struct sockaddr *)&server_parm.admin_addr,
+ &addrlen)) {
+ log("getsockname: %s",error_message(errno));
+ continue;
+ }
+#ifdef DEBUG
+ printf("Connection recieved on %s\n",
+ inet_ntoa(server_parm.admin_addr.sin_addr));
+#endif /* DEBUG */
+#ifndef DEBUG
+ /* if you want a sep daemon for each server */
+ if ((pid = fork())) {
+ /* parent */
+ if (pid < 0) {
+ log("fork: %s",error_message(errno));
+ (void) close(peer_fd);
+ continue;
+ }
+ /* fork succeded: keep tabs on child */
+ (void) close(peer_fd);
+ if (pidarray) {
+ pidarray = (int *)realloc((char *)pidarray, ++pidarraysize);
+ pidarray[pidarraysize-1] = pid;
+ } else {
+ pidarray = (int *)malloc(pidarraysize = 1);
+ pidarray[0] = pid;
+ }
+ } else {
+ /* child */
+ (void) close(admin_fd);
+#endif /* DEBUG */
+ /* do stuff */
+ process_client (peer_fd, &peer);
+#ifndef DEBUG
+ }
+#endif
+ } else {
+ log("something else woke me up!");
+ return(0);
+ }
+ }
+ /*NOTREACHED*/
+ return(0); /* Shut -Wall up - markm */
+}
+
+#ifdef DEBUG
+#define cleanexit(code) {kerb_fini(); return;}
+#endif
+
+void
+process_client(fd, who)
+int fd;
+struct sockaddr_in *who;
+{
+ u_char *dat;
+ int dat_len;
+ u_short dlen;
+ int retval;
+ int on = 1;
+ Principal service;
+ des_cblock skey;
+ int more;
+ int status;
+
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
+ log("setsockopt keepalive: %d",errno);
+
+ server_parm.recv_addr = *who;
+
+ if (kerb_init()) { /* Open as client */
+ log("can't open krb db");
+ cleanexit(1);
+ }
+ /* need to set service key to changepw.KRB_MASTER */
+
+ status = kerb_get_principal(server_parm.sname, server_parm.sinst, &service,
+ 1, &more);
+ if (status == -1) {
+ /* db locked */
+ u_long retcode = KADM_DB_INUSE;
+ char *pdat;
+
+ dat_len = KADM_VERSIZE + sizeof(u_long);
+ dat = (u_char *) malloc((unsigned)dat_len);
+ pdat = (char *) dat;
+ retcode = htonl((u_long) KADM_DB_INUSE);
+ (void) strncpy(pdat, KADM_ULOSE, KADM_VERSIZE);
+ bcopy((char *)&retcode, &pdat[KADM_VERSIZE], sizeof(u_long));
+ goto out;
+ } else if (!status) {
+ log("no service %s.%s",server_parm.sname, server_parm.sinst);
+ cleanexit(2);
+ }
+
+ bcopy((char *)&service.key_low, (char *)skey, 4);
+ bcopy((char *)&service.key_high, (char *)(((long *) skey) + 1), 4);
+ bzero((char *)&service, sizeof(service));
+ kdb_encrypt_key (skey, skey, server_parm.master_key,
+ server_parm.master_key_schedule, DECRYPT);
+ (void) krb_set_key((char *)skey, 0); /* if error, will show up when
+ rd_req fails */
+ bzero((char *)skey, sizeof(skey));
+
+ while (1) {
+ if ((retval = krb_net_read(fd, (char *)&dlen, sizeof(u_short))) !=
+ sizeof(u_short)) {
+ if (retval < 0)
+ log("dlen read: %s",error_message(errno));
+ else if (retval)
+ log("short dlen read: %d",retval);
+ (void) close(fd);
+ cleanexit(retval ? 3 : 0);
+ }
+ if (exit_now) {
+ cleanexit(0);
+ }
+ dat_len = (int) ntohs(dlen);
+ dat = (u_char *) malloc((unsigned)dat_len);
+ if (!dat) {
+ log("malloc: No memory");
+ (void) close(fd);
+ cleanexit(4);
+ }
+ if ((retval = krb_net_read(fd, (char *)dat, dat_len)) != dat_len) {
+ if (retval < 0)
+ log("data read: %s",error_message(errno));
+ else
+ log("short read: %d vs. %d", dat_len, retval);
+ (void) close(fd);
+ cleanexit(5);
+ }
+ if (exit_now) {
+ cleanexit(0);
+ }
+ if ((retval = kadm_ser_in(&dat,&dat_len)) != KADM_SUCCESS)
+ log("processing request: %s", error_message(retval));
+
+ /* kadm_ser_in did the processing and returned stuff in
+ dat & dat_len , return the appropriate data */
+
+ out:
+ dlen = (u_short) dat_len;
+
+ if (dat_len != (int)dlen) {
+ clear_secrets();
+ abort(); /* XXX */
+ }
+ dlen = htons(dlen);
+
+ if (krb_net_write(fd, (char *)&dlen, sizeof(u_short)) < 0) {
+ log("writing dlen to client: %s",error_message(errno));
+ (void) close(fd);
+ cleanexit(6);
+ }
+
+ if (krb_net_write(fd, (char *)dat, dat_len) < 0) {
+ log(LOG_ERR, "writing to client: %s",error_message(errno));
+ (void) close(fd);
+ cleanexit(7);
+ }
+ free((char *)dat);
+ }
+ /*NOTREACHED*/
+}
+
+sigtype
+do_child()
+{
+ /* SIGCHLD brings us here */
+ int pid;
+ register int i, j;
+
+#ifdef POSIX
+ int status;
+#else
+ union wait status;
+#endif
+
+ pid = wait(&status);
+
+ for (i = 0; i < pidarraysize; i++)
+ if (pidarray[i] == pid) {
+ /* found it */
+ for (j = i; j < pidarraysize-1; j++)
+ /* copy others down */
+ pidarray[j] = pidarray[j+1];
+ pidarraysize--;
+ if (WEXITSTATUS(status) || WCOREDUMP(status) || WIFSIGNALED(status))
+ log("child %d: termsig %d, coredump %d, retcode %d", pid,
+ WTERMSIG(status), WCOREDUMP(status), WEXITSTATUS(status));
+#ifdef POSIX
+ return;
+#else /* !POSIX */
+ return(0);
+#endif /* POSIX */
+ }
+ log("child %d not in list: termsig %d, coredump %d, retcode %d", pid,
+ WTERMSIG(status), WCOREDUMP(status), WEXITSTATUS(status));
+#ifdef POSIX
+ return;
+#else /* !POSIX */
+ return(0);
+#endif /* POSIX */
+}
+
+#ifndef DEBUG
+void
+cleanexit(val)
+ int val;
+{
+ kerb_fini();
+ clear_secrets();
+ exit(val);
+}
+#endif
+
+void
+kill_children()
+{
+ register int i;
+ int osigmask;
+
+ osigmask = sigblock(sigmask(SIGCHLD));
+
+ for (i = 0; i < pidarraysize; i++) {
+ kill(pidarray[i], SIGINT);
+ log("killing child %d", pidarray[i]);
+ }
+ sigsetmask(osigmask);
+ return;
+}
diff --git a/eBones/usr.sbin/kadmind/kadm_funcs.c b/eBones/usr.sbin/kadmind/kadm_funcs.c
new file mode 100644
index 0000000000000..b20a5666ac6be
--- /dev/null
+++ b/eBones/usr.sbin/kadmind/kadm_funcs.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT
+ *
+ * Kerberos administration server-side database manipulation routines
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_kadm_funcs_c[] =
+"Id: kadm_funcs.c,v 4.3 90/03/20 01:39:51 jon Exp ";
+static const char rcsid[] =
+ "$Id: kadm_funcs.c,v 1.2 1995/09/07 20:50:48 mark Exp $";
+#endif lint
+#endif
+
+/*
+kadm_funcs.c
+the actual database manipulation code
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <com_err.h>
+#include <sys/param.h>
+#include <kadm.h>
+#include <kerberosIV/kadm_err.h>
+#include <krb_db.h>
+#include "kadm_server.h"
+
+extern Kadm_Server server_parm;
+
+int
+check_access(pname, pinst, prealm, acltype)
+char *pname;
+char *pinst;
+char *prealm;
+enum acl_types acltype;
+{
+ char checkname[MAX_K_NAME_SZ];
+ char filename[MAXPATHLEN];
+ extern char *acldir;
+
+ sprintf(checkname, "%s.%s@%s", pname, pinst, prealm);
+
+ switch (acltype) {
+ case ADDACL:
+ sprintf(filename, "%s%s", acldir, ADD_ACL_FILE);
+ break;
+ case GETACL:
+ sprintf(filename, "%s%s", acldir, GET_ACL_FILE);
+ break;
+ case MODACL:
+ sprintf(filename, "%s%s", acldir, MOD_ACL_FILE);
+ break;
+ }
+ return(acl_check(filename, checkname));
+}
+
+int
+wildcard(str)
+char *str;
+{
+ if (!strcmp(str, WILDCARD_STR))
+ return(1);
+ return(0);
+}
+
+#define failadd(code) { (void) log("FAILED addding '%s.%s' (%s)", valsin->name, valsin->instance, error_message(code)); return code; }
+
+int
+kadm_add_entry (rname, rinstance, rrealm, valsin, valsout)
+char *rname; /* requestors name */
+char *rinstance; /* requestors instance */
+char *rrealm; /* requestors realm */
+Kadm_vals *valsin;
+Kadm_vals *valsout;
+{
+ long numfound; /* check how many we get written */
+ int more; /* pointer to more grabbed records */
+ Principal data_i, data_o; /* temporary principal */
+ u_char flags[4];
+ des_cblock newpw;
+ Principal default_princ;
+
+ if (!check_access(rname, rinstance, rrealm, ADDACL)) {
+ (void) log("WARNING: '%s.%s@%s' tried to add an entry for '%s.%s'",
+ rname, rinstance, rrealm, valsin->name, valsin->instance);
+ return KADM_UNAUTH;
+ }
+
+ /* Need to check here for "legal" name and instance */
+ if (wildcard(valsin->name) || wildcard(valsin->instance)) {
+ failadd(KADM_ILL_WILDCARD);
+ }
+
+ (void) log("request to add an entry for '%s.%s' from '%s.%s@%s'",
+ valsin->name, valsin->instance, rname, rinstance, rrealm);
+
+ numfound = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+ if (numfound == -1) {
+ failadd(KADM_DB_INUSE);
+ } else if (numfound != 1) {
+ failadd(KADM_UK_RERROR);
+ }
+
+ kadm_vals_to_prin(valsin->fields, &data_i, valsin);
+ (void) strncpy(data_i.name, valsin->name, ANAME_SZ);
+ (void) strncpy(data_i.instance, valsin->instance, INST_SZ);
+
+ if (!IS_FIELD(KADM_EXPDATE,valsin->fields))
+ data_i.exp_date = default_princ.exp_date;
+ if (!IS_FIELD(KADM_ATTR,valsin->fields))
+ data_i.attributes = default_princ.attributes;
+ if (!IS_FIELD(KADM_MAXLIFE,valsin->fields))
+ data_i.max_life = default_princ.max_life;
+
+ bzero((char *)&default_princ, sizeof(default_princ));
+
+ /* convert to host order */
+ data_i.key_low = ntohl(data_i.key_low);
+ data_i.key_high = ntohl(data_i.key_high);
+
+
+ bcopy(&data_i.key_low,newpw,4);
+ bcopy(&data_i.key_high,(char *)(((long *) newpw) + 1),4);
+
+ /* encrypt new key in master key */
+ kdb_encrypt_key (newpw, newpw, server_parm.master_key,
+ server_parm.master_key_schedule, ENCRYPT);
+ bcopy(newpw,&data_i.key_low,4);
+ bcopy((char *)(((long *) newpw) + 1), &data_i.key_high,4);
+ bzero((char *)newpw, sizeof(newpw));
+
+ data_o = data_i;
+ numfound = kerb_get_principal(valsin->name, valsin->instance,
+ &data_o, 1, &more);
+ if (numfound == -1) {
+ failadd(KADM_DB_INUSE);
+ } else if (numfound) {
+ failadd(KADM_INUSE);
+ } else {
+ data_i.key_version++;
+ data_i.kdc_key_ver = server_parm.master_key_version;
+ (void) strncpy(data_i.mod_name, rname, sizeof(data_i.mod_name)-1);
+ (void) strncpy(data_i.mod_instance, rinstance,
+ sizeof(data_i.mod_instance)-1);
+
+ numfound = kerb_put_principal(&data_i, 1);
+ if (numfound == -1) {
+ failadd(KADM_DB_INUSE);
+ } else if (numfound) {
+ failadd(KADM_UK_SERROR);
+ } else {
+ numfound = kerb_get_principal(valsin->name, valsin->instance,
+ &data_o, 1, &more);
+ if ((numfound!=1) || (more!=0)) {
+ failadd(KADM_UK_RERROR);
+ }
+ bzero((char *)flags, sizeof(flags));
+ SET_FIELD(KADM_NAME,flags);
+ SET_FIELD(KADM_INST,flags);
+ SET_FIELD(KADM_EXPDATE,flags);
+ SET_FIELD(KADM_ATTR,flags);
+ SET_FIELD(KADM_MAXLIFE,flags);
+ kadm_prin_to_vals(flags, valsout, &data_o);
+ (void) log("'%s.%s' added.", valsin->name, valsin->instance);
+ return KADM_DATA; /* Set all the appropriate fields */
+ }
+ }
+}
+#undef failadd
+
+#define failget(code) { (void) log("FAILED retrieving '%s.%s' (%s)", valsin->name, valsin->instance, error_message(code)); return code; }
+
+int
+kadm_get_entry (rname, rinstance, rrealm, valsin, flags, valsout)
+char *rname; /* requestors name */
+char *rinstance; /* requestors instance */
+char *rrealm; /* requestors realm */
+Kadm_vals *valsin; /* what they wannt to get */
+u_char *flags; /* which fields we want */
+Kadm_vals *valsout; /* what data is there */
+{
+ long numfound; /* check how many were returned */
+ int more; /* To point to more name.instances */
+ Principal data_o; /* Data object to hold Principal */
+
+
+ if (!check_access(rname, rinstance, rrealm, GETACL)) {
+ (void) log("WARNING: '%s.%s@%s' tried to get '%s.%s's entry",
+ rname, rinstance, rrealm, valsin->name, valsin->instance);
+ return KADM_UNAUTH;
+ }
+
+ if (wildcard(valsin->name) || wildcard(valsin->instance)) {
+ failget(KADM_ILL_WILDCARD);
+ }
+
+ (void) log("retrieve '%s.%s's entry for '%s.%s@%s'",
+ valsin->name, valsin->instance, rname, rinstance, rrealm);
+
+ /* Look up the record in the database */
+ numfound = kerb_get_principal(valsin->name, valsin->instance,
+ &data_o, 1, &more);
+ if (numfound == -1) {
+ failget(KADM_DB_INUSE);
+ } else if (numfound) { /* We got the record, let's return it */
+ kadm_prin_to_vals(flags, valsout, &data_o);
+ (void) log("'%s.%s' retrieved.", valsin->name, valsin->instance);
+ return KADM_DATA; /* Set all the appropriate fields */
+ } else {
+ failget(KADM_NOENTRY); /* Else whimper and moan */
+ }
+}
+#undef failget
+
+#define failmod(code) { (void) log("FAILED modifying '%s.%s' (%s)", valsin1->name, valsin1->instance, error_message(code)); return code; }
+
+int
+kadm_mod_entry (rname, rinstance, rrealm, valsin1, valsin2, valsout)
+char *rname; /* requestors name */
+char *rinstance; /* requestors instance */
+char *rrealm; /* requestors realm */
+Kadm_vals *valsin1, *valsin2; /* holds the parameters being
+ passed in */
+Kadm_vals *valsout; /* the actual record which is returned */
+{
+ long numfound;
+ int more;
+ Principal data_o, temp_key;
+ u_char fields[4];
+ des_cblock newpw;
+
+ if (wildcard(valsin1->name) || wildcard(valsin1->instance)) {
+ failmod(KADM_ILL_WILDCARD);
+ }
+
+ if (!check_access(rname, rinstance, rrealm, MODACL)) {
+ (void) log("WARNING: '%s.%s@%s' tried to change '%s.%s's entry",
+ rname, rinstance, rrealm, valsin1->name, valsin1->instance);
+ return KADM_UNAUTH;
+ }
+
+ (void) log("request to modify '%s.%s's entry from '%s.%s@%s' ",
+ valsin1->name, valsin1->instance, rname, rinstance, rrealm);
+
+ numfound = kerb_get_principal(valsin1->name, valsin1->instance,
+ &data_o, 1, &more);
+ if (numfound == -1) {
+ failmod(KADM_DB_INUSE);
+ } else if (numfound) {
+ kadm_vals_to_prin(valsin2->fields, &temp_key, valsin2);
+ (void) strncpy(data_o.name, valsin1->name, ANAME_SZ);
+ (void) strncpy(data_o.instance, valsin1->instance, INST_SZ);
+ if (IS_FIELD(KADM_EXPDATE,valsin2->fields))
+ data_o.exp_date = temp_key.exp_date;
+ if (IS_FIELD(KADM_ATTR,valsin2->fields))
+ data_o.attributes = temp_key.attributes;
+ if (IS_FIELD(KADM_MAXLIFE,valsin2->fields))
+ data_o.max_life = temp_key.max_life;
+ if (IS_FIELD(KADM_DESKEY,valsin2->fields)) {
+ data_o.key_version++;
+ data_o.kdc_key_ver = server_parm.master_key_version;
+
+
+ /* convert to host order */
+ temp_key.key_low = ntohl(temp_key.key_low);
+ temp_key.key_high = ntohl(temp_key.key_high);
+
+
+ bcopy(&temp_key.key_low,newpw,4);
+ bcopy(&temp_key.key_high,(char *)(((long *) newpw) + 1),4);
+
+ /* encrypt new key in master key */
+ kdb_encrypt_key (newpw, newpw, server_parm.master_key,
+ server_parm.master_key_schedule, ENCRYPT);
+ bcopy(newpw,&data_o.key_low,4);
+ bcopy((char *)(((long *) newpw) + 1), &data_o.key_high,4);
+ bzero((char *)newpw, sizeof(newpw));
+ }
+ bzero((char *)&temp_key, sizeof(temp_key));
+
+ (void) strncpy(data_o.mod_name, rname, sizeof(data_o.mod_name)-1);
+ (void) strncpy(data_o.mod_instance, rinstance,
+ sizeof(data_o.mod_instance)-1);
+ more = kerb_put_principal(&data_o, 1);
+
+ bzero((char *)&data_o, sizeof(data_o));
+
+ if (more == -1) {
+ failmod(KADM_DB_INUSE);
+ } else if (more) {
+ failmod(KADM_UK_SERROR);
+ } else {
+ numfound = kerb_get_principal(valsin1->name, valsin1->instance,
+ &data_o, 1, &more);
+ if ((more!=0)||(numfound!=1)) {
+ failmod(KADM_UK_RERROR);
+ }
+ bzero((char *) fields, sizeof(fields));
+ SET_FIELD(KADM_NAME,fields);
+ SET_FIELD(KADM_INST,fields);
+ SET_FIELD(KADM_EXPDATE,fields);
+ SET_FIELD(KADM_ATTR,fields);
+ SET_FIELD(KADM_MAXLIFE,fields);
+ kadm_prin_to_vals(fields, valsout, &data_o);
+ (void) log("'%s.%s' modified.", valsin1->name, valsin1->instance);
+ return KADM_DATA; /* Set all the appropriate fields */
+ }
+ }
+ else {
+ failmod(KADM_NOENTRY);
+ }
+}
+#undef failmod
+
+#define failchange(code) { (void) log("FAILED changing key for '%s.%s@%s' (%s)", rname, rinstance, rrealm, error_message(code)); return code; }
+
+int
+kadm_change (rname, rinstance, rrealm, newpw)
+char *rname;
+char *rinstance;
+char *rrealm;
+des_cblock newpw;
+{
+ long numfound;
+ int more;
+ Principal data_o;
+ des_cblock local_pw;
+
+ if (strcmp(server_parm.krbrlm, rrealm)) {
+ (void) log("change key request from wrong realm, '%s.%s@%s'!\n",
+ rname, rinstance, rrealm);
+ return(KADM_WRONG_REALM);
+ }
+
+ if (wildcard(rname) || wildcard(rinstance)) {
+ failchange(KADM_ILL_WILDCARD);
+ }
+ (void) log("'%s.%s@%s' wants to change its password",
+ rname, rinstance, rrealm);
+
+ bcopy(newpw, local_pw, sizeof(local_pw));
+
+ /* encrypt new key in master key */
+ kdb_encrypt_key (local_pw, local_pw, server_parm.master_key,
+ server_parm.master_key_schedule, ENCRYPT);
+
+ numfound = kerb_get_principal(rname, rinstance,
+ &data_o, 1, &more);
+ if (numfound == -1) {
+ failchange(KADM_DB_INUSE);
+ } else if (numfound) {
+ bcopy(local_pw,&data_o.key_low,4);
+ bcopy((char *)(((long *) local_pw) + 1), &data_o.key_high,4);
+ data_o.key_version++;
+ data_o.kdc_key_ver = server_parm.master_key_version;
+ (void) strncpy(data_o.mod_name, rname, sizeof(data_o.mod_name)-1);
+ (void) strncpy(data_o.mod_instance, rinstance,
+ sizeof(data_o.mod_instance)-1);
+ more = kerb_put_principal(&data_o, 1);
+ bzero((char *) local_pw, sizeof(local_pw));
+ bzero((char *) &data_o, sizeof(data_o));
+ if (more == -1) {
+ failchange(KADM_DB_INUSE);
+ } else if (more) {
+ failchange(KADM_UK_SERROR);
+ } else {
+ (void) log("'%s.%s@%s' password changed.", rname, rinstance, rrealm);
+ return KADM_SUCCESS;
+ }
+ }
+ else {
+ failchange(KADM_NOENTRY);
+ }
+}
+#undef failchange
diff --git a/eBones/usr.sbin/kadmind/kadm_ser_wrap.c b/eBones/usr.sbin/kadmind/kadm_ser_wrap.c
new file mode 100644
index 0000000000000..b6f47827b53eb
--- /dev/null
+++ b/eBones/usr.sbin/kadmind/kadm_ser_wrap.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Kerberos administration server-side support functions
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_module_c[] =
+"BonesHeader: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_ser_wrap.c,v 4.4 89/09/26 09:29:36 jtkohl Exp ";
+#endif lint
+#endif
+
+/*
+kadm_ser_wrap.c
+unwraps wrapped packets and calls the appropriate server subroutine
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <kadm.h>
+#include <kerberosIV/kadm_err.h>
+#include <kerberosIV/krb_err.h>
+#include "kadm_server.h"
+
+Kadm_Server server_parm;
+
+/*
+kadm_ser_init
+set up the server_parm structure
+*/
+int
+kadm_ser_init(inter, realm)
+int inter; /* interactive or from file */
+char realm[];
+{
+ struct servent *sep;
+ struct hostent *hp;
+ char hostname[MAXHOSTNAMELEN];
+
+ init_kadm_err_tbl();
+ init_krb_err_tbl();
+ if (gethostname(hostname, sizeof(hostname)))
+ return KADM_NO_HOSTNAME;
+
+ strcpy(server_parm.sname, PWSERV_NAME);
+ strcpy(server_parm.sinst, KRB_MASTER);
+ strcpy(server_parm.krbrlm, realm);
+
+ server_parm.admin_fd = -1;
+ /* setting up the addrs */
+ if ((sep = getservbyname(KADM_SNAME, "tcp")) == NULL)
+ return KADM_NO_SERV;
+ bzero((char *)&server_parm.admin_addr,sizeof(server_parm.admin_addr));
+ server_parm.admin_addr.sin_family = AF_INET;
+ if ((hp = gethostbyname(hostname)) == NULL)
+ return KADM_NO_HOSTNAME;
+ server_parm.admin_addr.sin_addr.s_addr = INADDR_ANY;
+ server_parm.admin_addr.sin_port = sep->s_port;
+ /* setting up the database */
+ if (kdb_get_master_key((inter==1),server_parm.master_key,
+ server_parm.master_key_schedule) != 0)
+ return KADM_NO_MAST;
+ if ((server_parm.master_key_version =
+ kdb_verify_master_key(server_parm.master_key,
+ server_parm.master_key_schedule,stderr))<0)
+ return KADM_NO_VERI;
+ return KADM_SUCCESS;
+}
+
+static void
+errpkt(dat, dat_len, code)
+u_char **dat;
+int *dat_len;
+int code;
+{
+ u_long retcode;
+ char *pdat;
+
+ free((char *)*dat); /* free up req */
+ *dat_len = KADM_VERSIZE + sizeof(u_long);
+ *dat = (u_char *) malloc((unsigned)*dat_len);
+ pdat = (char *) *dat;
+ retcode = htonl((u_long) code);
+ (void) strncpy(pdat, KADM_ULOSE, KADM_VERSIZE);
+ bcopy((char *)&retcode, &pdat[KADM_VERSIZE], sizeof(u_long));
+ return;
+}
+
+/*
+kadm_ser_in
+unwrap the data stored in dat, process, and return it.
+*/
+int
+kadm_ser_in(dat,dat_len)
+u_char **dat;
+int *dat_len;
+{
+ u_char *in_st; /* pointer into the sent packet */
+ int in_len,retc; /* where in packet we are, for
+ returns */
+ u_long r_len; /* length of the actual packet */
+ KTEXT_ST authent; /* the authenticator */
+ AUTH_DAT ad; /* who is this, klink */
+ u_long ncksum; /* checksum of encrypted data */
+ des_key_schedule sess_sched; /* our schedule */
+ MSG_DAT msg_st;
+ u_char *retdat, *tmpdat;
+ int retval, retlen;
+
+ if (strncmp(KADM_VERSTR, (char *)*dat, KADM_VERSIZE)) {
+ errpkt(dat, dat_len, KADM_BAD_VER);
+ return KADM_BAD_VER;
+ }
+ in_len = KADM_VERSIZE;
+ /* get the length */
+ if ((retc = stv_long(*dat, &r_len, in_len, *dat_len)) < 0)
+ return KADM_LENGTH_ERROR;
+ in_len += retc;
+ authent.length = *dat_len - r_len - KADM_VERSIZE - sizeof(u_long);
+ bcopy((char *)(*dat) + in_len, (char *)authent.dat, authent.length);
+ authent.mbz = 0;
+ /* service key should be set before here */
+ if ((retc = krb_rd_req(&authent, server_parm.sname, server_parm.sinst,
+ server_parm.recv_addr.sin_addr.s_addr, &ad, (char *)0)))
+ {
+ errpkt(dat, dat_len,retc + krb_err_base);
+ return retc + krb_err_base;
+ }
+
+#define clr_cli_secrets() {bzero((char *)sess_sched, sizeof(sess_sched)); bzero((char *)ad.session, sizeof(ad.session));}
+
+ in_st = *dat + *dat_len - r_len;
+#ifdef NOENCRYPTION
+ ncksum = 0;
+#else
+ ncksum = quad_cksum((des_cblock *)in_st, (des_cblock *)0, (long) r_len,
+ 0, (des_cblock *)ad.session);
+#endif
+ if (ncksum!=ad.checksum) { /* yow, are we correct yet */
+ clr_cli_secrets();
+ errpkt(dat, dat_len,KADM_BAD_CHK);
+ return KADM_BAD_CHK;
+ }
+#ifdef NOENCRYPTION
+ bzero(sess_sched, sizeof(sess_sched));
+#else
+ des_key_sched((des_cblock *)ad.session, sess_sched);
+#endif
+ if ((retc = (int) krb_rd_priv(in_st, r_len, sess_sched, ad.session,
+ &server_parm.recv_addr,
+ &server_parm.admin_addr, &msg_st))) {
+ clr_cli_secrets();
+ errpkt(dat, dat_len,retc + krb_err_base);
+ return retc + krb_err_base;
+ }
+ switch (msg_st.app_data[0]) {
+ case CHANGE_PW:
+ retval = kadm_ser_cpw(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+ &retdat, &retlen);
+ break;
+ case ADD_ENT:
+ retval = kadm_ser_add(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+ &retdat, &retlen);
+ break;
+ case GET_ENT:
+ retval = kadm_ser_get(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+ &retdat, &retlen);
+ break;
+ case MOD_ENT:
+ retval = kadm_ser_mod(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+ &retdat, &retlen);
+ break;
+ default:
+ clr_cli_secrets();
+ errpkt(dat, dat_len, KADM_NO_OPCODE);
+ return KADM_NO_OPCODE;
+ }
+ /* Now seal the response back into a priv msg */
+ free((char *)*dat);
+ tmpdat = (u_char *) malloc((unsigned)(retlen + KADM_VERSIZE +
+ sizeof(u_long)));
+ (void) strncpy((char *)tmpdat, KADM_VERSTR, KADM_VERSIZE);
+ retval = htonl((u_long)retval);
+ bcopy((char *)&retval, (char *)tmpdat + KADM_VERSIZE, sizeof(u_long));
+ if (retlen) {
+ bcopy((char *)retdat, (char *)tmpdat + KADM_VERSIZE + sizeof(u_long),
+ retlen);
+ free((char *)retdat);
+ }
+ /* slop for mk_priv stuff */
+ *dat = (u_char *) malloc((unsigned) (retlen + KADM_VERSIZE +
+ sizeof(u_long) + 200));
+ if ((*dat_len = krb_mk_priv(tmpdat, *dat,
+ (u_long) (retlen + KADM_VERSIZE +
+ sizeof(u_long)),
+ sess_sched,
+ ad.session, &server_parm.admin_addr,
+ &server_parm.recv_addr)) < 0) {
+ clr_cli_secrets();
+ errpkt(dat, dat_len, KADM_NO_ENCRYPT);
+ return KADM_NO_ENCRYPT;
+ }
+ clr_cli_secrets();
+ return KADM_SUCCESS;
+}
diff --git a/eBones/usr.sbin/kadmind/kadm_server.c b/eBones/usr.sbin/kadmind/kadm_server.c
new file mode 100644
index 0000000000000..c53af7b883368
--- /dev/null
+++ b/eBones/usr.sbin/kadmind/kadm_server.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * Kerberos administration server-side subroutines
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_kadm_server_c[] =
+"Header: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_server.c,v 4.2 89/09/26 09:30:23 jtkohl Exp ";
+#endif lint
+#endif
+
+#include <string.h>
+#include <kadm.h>
+#include <kerberosIV/kadm_err.h>
+#include "kadm_server.h"
+
+/*
+kadm_ser_cpw - the server side of the change_password routine
+ recieves : KTEXT, {key}
+ returns : CKSUM, RETCODE
+ acl : caller can change only own password
+
+Replaces the password (i.e. des key) of the caller with that specified in key.
+Returns no actual data from the master server, since this is called by a user
+*/
+int
+kadm_ser_cpw(dat, len, ad, datout, outlen)
+u_char *dat;
+int len;
+AUTH_DAT *ad;
+u_char **datout;
+int *outlen;
+{
+ unsigned long keylow, keyhigh;
+ des_cblock newkey;
+ int stvlen;
+
+ /* take key off the stream, and change the database */
+
+ if ((stvlen = stv_long(dat, &keyhigh, 0, len)) < 0)
+ return(KADM_LENGTH_ERROR);
+ if (stv_long(dat, &keylow, stvlen, len) < 0)
+ return(KADM_LENGTH_ERROR);
+
+ keylow = ntohl(keylow);
+ keyhigh = ntohl(keyhigh);
+ bcopy((char *)&keyhigh, (char *)(((long *)newkey) + 1), 4);
+ bcopy((char *)&keylow, (char *)newkey, 4);
+ *datout = 0;
+ *outlen = 0;
+
+ return(kadm_change(ad->pname, ad->pinst, ad->prealm, newkey));
+}
+
+/*
+kadm_ser_add - the server side of the add_entry routine
+ recieves : KTEXT, {values}
+ returns : CKSUM, RETCODE, {values}
+ acl : su, sms (as alloc)
+
+Adds and entry containing values to the database
+returns the values of the entry, so if you leave certain fields blank you will
+ be able to determine the default values they are set to
+*/
+int
+kadm_ser_add(dat,len,ad, datout, outlen)
+u_char *dat;
+int len;
+AUTH_DAT *ad;
+u_char **datout;
+int *outlen;
+{
+ Kadm_vals values, retvals;
+ int status;
+
+ if ((status = stream_to_vals(dat, &values, len)) < 0)
+ return(KADM_LENGTH_ERROR);
+ if ((status = kadm_add_entry(ad->pname, ad->pinst, ad->prealm,
+ &values, &retvals)) == KADM_DATA) {
+ *outlen = vals_to_stream(&retvals,datout);
+ return KADM_SUCCESS;
+ } else {
+ *outlen = 0;
+ return status;
+ }
+}
+
+/*
+kadm_ser_mod - the server side of the mod_entry routine
+ recieves : 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
+*/
+int
+kadm_ser_mod(dat,len,ad, datout, outlen)
+u_char *dat;
+int len;
+AUTH_DAT *ad;
+u_char **datout;
+int *outlen;
+{
+ Kadm_vals vals1, vals2, retvals;
+ int wh;
+ int status;
+
+ if ((wh = stream_to_vals(dat, &vals1, len)) < 0)
+ return KADM_LENGTH_ERROR;
+ if ((status = stream_to_vals(dat+wh,&vals2, len-wh)) < 0)
+ return KADM_LENGTH_ERROR;
+ if ((status = kadm_mod_entry(ad->pname, ad->pinst, ad->prealm, &vals1,
+ &vals2, &retvals)) == KADM_DATA) {
+ *outlen = vals_to_stream(&retvals,datout);
+ return KADM_SUCCESS;
+ } else {
+ *outlen = 0;
+ return status;
+ }
+}
+
+/*
+kadm_ser_get
+ recieves : KTEXT, {values, flags}
+ returns : CKSUM, RETCODE, {count, values, values, values}
+ acl : su
+
+gets the fields requested by flags from all entries matching values
+returns this data for each matching recipient, after a count of how many such
+ matches there were
+*/
+int
+kadm_ser_get(dat,len,ad, datout, outlen)
+u_char *dat;
+int len;
+AUTH_DAT *ad;
+u_char **datout;
+int *outlen;
+{
+ Kadm_vals values, retvals;
+ u_char fl[FLDSZ];
+ int loop,wh;
+ int status;
+
+ if ((wh = stream_to_vals(dat, &values, len)) < 0)
+ return KADM_LENGTH_ERROR;
+ if (wh + FLDSZ > len)
+ return KADM_LENGTH_ERROR;
+ for (loop=FLDSZ-1; loop>=0; loop--)
+ fl[loop] = dat[wh++];
+ if ((status = kadm_get_entry(ad->pname, ad->pinst, ad->prealm,
+ &values, fl, &retvals)) == KADM_DATA) {
+ *outlen = vals_to_stream(&retvals,datout);
+ return KADM_SUCCESS;
+ } else {
+ *outlen = 0;
+ return status;
+ }
+}
+
diff --git a/eBones/usr.sbin/kadmind/kadm_server.h b/eBones/usr.sbin/kadmind/kadm_server.h
new file mode 100644
index 0000000000000..1708107029a83
--- /dev/null
+++ b/eBones/usr.sbin/kadmind/kadm_server.h
@@ -0,0 +1,70 @@
+/*
+ * $Source: /usr/cvs/src/eBones/kadmind/kadm_server.h,v $
+ * $Author: mark $
+ * Header: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_server.h,v 4.1 89/12/21 17:46:51 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_SERVER_DEFS
+#define KADM_SERVER_DEFS
+
+/*
+ * kadm_server.h
+ * Header file for the fourth attempt at an admin server
+ * Doug Church, December 28, 1989, MIT Project Athena
+ * ps. Yes that means this code belongs to athena etc...
+ * as part of our ongoing attempt to copyright all greek names
+ */
+
+#include <sys/types.h>
+#include <krb.h>
+#include <des.h>
+
+typedef struct {
+ struct sockaddr_in admin_addr;
+ struct sockaddr_in recv_addr;
+ int recv_addr_len;
+ int admin_fd; /* our link to clients */
+ char sname[ANAME_SZ];
+ char sinst[INST_SZ];
+ char krbrlm[REALM_SZ];
+ C_Block master_key;
+ C_Block session_key;
+ Key_schedule master_key_schedule;
+ long master_key_version;
+} Kadm_Server;
+
+/* the default syslog file */
+#define KADM_SYSLOG "/var/log/kadmind.syslog"
+
+#define DEFAULT_ACL_DIR "/etc/kerberosIV"
+#define ADD_ACL_FILE "/admin_acl.add"
+#define GET_ACL_FILE "/admin_acl.get"
+#define MOD_ACL_FILE "/admin_acl.mod"
+
+int kadm_ser_in(unsigned char **dat, int *dat_len);
+int kadm_ser_init(int inter, char realm[]);
+int kadm_ser_cpw(u_char *dat, int len, AUTH_DAT *ad, u_char **datout,
+ int *outlen);
+int kadm_ser_add(u_char *dat, int len, AUTH_DAT *ad, u_char **datout,
+ int *outlen);
+int kadm_ser_mod(u_char *dat, int len, AUTH_DAT *ad, u_char **datout,
+ int *outlen);
+int kadm_ser_get(u_char *dat, int len, AUTH_DAT *ad, u_char **datout,
+ int *outlen);
+int kadm_change (char *rname, char *rinstance, char *rrealm,
+ des_cblock newpw);
+int kadm_add_entry(char *rname, char *rinstance, char *rrealm,
+ Kadm_vals *valsin, Kadm_vals *valsout);
+int kadm_mod_entry(char *rname, char *rinstance, char *rrealm,
+ Kadm_vals *valsin1, Kadm_vals *valsin2, Kadm_vals *valsout);
+int kadm_get_entry(char *rname, char *rinstance, char *rrealm,
+ Kadm_vals *valsin, u_char *flags, Kadm_vals *valsout);
+
+#endif KADM_SERVER_DEFS
diff --git a/eBones/usr.sbin/kdb_destroy/Makefile b/eBones/usr.sbin/kdb_destroy/Makefile
new file mode 100644
index 0000000000000..f92eb0e2b8e10
--- /dev/null
+++ b/eBones/usr.sbin/kdb_destroy/Makefile
@@ -0,0 +1,8 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:23 markm Exp $
+
+PROG= kdb_destroy
+CFLAGS+=-DKERBEROS -DDEBUG
+MAN8= kdb_destroy.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_destroy/kdb_destroy.c b/eBones/usr.sbin/kdb_destroy/kdb_destroy.c
new file mode 100644
index 0000000000000..57e1a80a6b9c9
--- /dev/null
+++ b/eBones/usr.sbin/kdb_destroy/kdb_destroy.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kdb_destroy.c,v 4.0 89/01/24 21:49:02 jtkohl Exp $
+ * $Id: kdb_destroy.c,v 1.5 1995/08/04 06:35:45 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_destroy.c,v 1.5 1995/08/04 06:35:45 mark Exp $";
+#endif lint
+#endif
+
+#include <unistd.h>
+#include <strings.h>
+#include <stdio.h>
+#include <krb.h>
+#include <krb_db.h>
+
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+#define _DBM_
+#endif
+
+void
+main()
+{
+ char answer[10]; /* user input */
+#ifdef _DBM_
+ char dbm[256]; /* database path and name */
+ char *file; /* database file names */
+#else
+ char dbm[256]; /* database path and name */
+ char dbm1[256]; /* database path and name */
+ char *file1, *file2; /* database file names */
+#endif
+
+ strcpy(dbm, DBM_FILE);
+#ifdef _DBM_
+ file = strcat(dbm, ".db");
+#else
+ strcpy(dbm1, DBM_FILE);
+ file1 = strcat(dbm, ".dir");
+ file2 = strcat(dbm1, ".pag");
+#endif
+
+ printf("You are about to destroy the Kerberos database ");
+ printf("on this machine.\n");
+ printf("Are you sure you want to do this (y/n)? ");
+ fgets(answer, sizeof(answer), stdin);
+
+ if (answer[0] == 'y' || answer[0] == 'Y') {
+#ifdef _DBM_
+ if (unlink(file) == 0)
+#else
+ if (unlink(file1) == 0 && unlink(file2) == 0)
+#endif
+ fprintf(stderr, "Database deleted at %s\n", DBM_FILE);
+ else
+ fprintf(stderr, "Database cannot be deleted at %s\n",
+ DBM_FILE);
+ } else
+ fprintf(stderr, "Database not deleted.\n");
+}
diff --git a/eBones/usr.sbin/kdb_edit/Makefile b/eBones/usr.sbin/kdb_edit/Makefile
new file mode 100644
index 0000000000000..7a05577c4a8af
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.2 (Berkeley) 2/14/91
+# $Id: Makefile,v 1.4 1995/09/13 17:24:24 markm Exp $
+
+PROG= kdb_edit
+CFLAGS+=-DKERBEROS -DDEBUG -I.
+SRCS= kdb_edit.c maketime.c
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN8= kdb_edit.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.c b/eBones/usr.sbin/kdb_edit/kdb_edit.c
new file mode 100644
index 0000000000000..82bf9a4e99722
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/kdb_edit.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine changes the Kerberos encryption keys for principals,
+ * i.e., users or services.
+ *
+ * from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $
+ * $Id: kdb_edit.c,v 1.5 1995/08/03 17:15:54 mark Exp $
+ */
+
+/*
+ * exit returns 0 ==> success -1 ==> error
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_edit.c,v 1.5 1995/08/03 17:15:54 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include "time.h"
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+/* MKEYFILE is now defined in kdc.h */
+#include <kdc.h>
+
+void Usage(void);
+void cleanup(void);
+void sig_exit(int sig, int code, struct sigcontext *scp);
+void no_core_dumps(void);
+int change_principal(void);
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+char prog[32];
+char *progname = prog;
+int nflag = 0;
+int cflag;
+int lflag;
+int uflag;
+int debug;
+extern kerb_debug;
+
+Key_schedule KS;
+C_Block new_key;
+unsigned char *input;
+
+unsigned char *ivec;
+int i, j;
+int more;
+
+char *in_ptr;
+char input_name[ANAME_SZ];
+char input_instance[INST_SZ];
+char input_string[ANAME_SZ];
+
+#define MAX_PRINCIPAL 10
+Principal principal_data[MAX_PRINCIPAL];
+
+static Principal old_principal;
+static Principal default_princ;
+
+static C_Block master_key;
+static C_Block session_key;
+static Key_schedule master_key_schedule;
+static char pw_str[255];
+static long master_key_version;
+
+/*
+ * gets replacement
+ */
+static char * s_gets(char * str, int len)
+{
+ int i;
+ char *s;
+
+ if((s = fgets(str, len, stdin)) == NULL)
+ return(s);
+ if(str[i = (strlen(str)-1)] == '\n')
+ str[i] = '\0';
+ return(s);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+
+{
+ /* Local Declarations */
+
+ long n;
+
+ prog[sizeof prog - 1] = '\0'; /* make sure terminated */
+ strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking
+ * program */
+
+ /* Assume a long is four bytes */
+ if (sizeof(long) != 4) {
+ fprintf(stdout, "%s: size of long is %d.\n", prog, sizeof(long));
+ exit(-1);
+ }
+ /* Assume <=32 signals */
+ if (NSIG > 32) {
+ fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
+ exit(-1);
+ }
+ while (--argc > 0 && (*++argv)[0] == '-')
+ for (i = 1; argv[0][i] != '\0'; i++) {
+ switch (argv[0][i]) {
+
+ /* debug flag */
+ case 'd':
+ debug = 1;
+ continue;
+
+ /* debug flag */
+ case 'l':
+ kerb_debug |= 1;
+ continue;
+
+ case 'n': /* read MKEYFILE for master key */
+ nflag = 1;
+ continue;
+
+ default:
+ fprintf(stderr, "%s: illegal flag \"%c\"\n",
+ progname, argv[0][i]);
+ Usage(); /* Give message and die */
+ }
+ };
+
+ fprintf(stdout, "Opening database...\n");
+ fflush(stdout);
+ kerb_init();
+ if (argc > 0) {
+ if (kerb_db_set_name(*argv) != 0) {
+ fprintf(stderr, "Could not open altername database name\n");
+ exit(1);
+ }
+ }
+
+#ifdef notdef
+ no_core_dumps(); /* diddle signals to avoid core dumps! */
+
+ /* ignore whatever is reasonable */
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTSTP, SIG_IGN);
+
+#endif
+
+ if (kdb_get_master_key ((nflag == 0),
+ master_key, master_key_schedule) != 0) {
+ fprintf (stdout, "Couldn't read master key.\n");
+ fflush (stdout);
+ exit (-1);
+ }
+
+ if ((master_key_version = kdb_verify_master_key(master_key,
+ master_key_schedule,
+ stdout)) < 0)
+ exit (-1);
+
+ /* lookup the default values */
+ n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+ if (n != 1) {
+ fprintf(stderr,
+ "%s: Kerberos error on default value lookup, %ld found.\n",
+ progname, n);
+ exit(-1);
+ }
+ fprintf(stdout, "Previous or default values are in [brackets] ,\n");
+ fprintf(stdout, "enter return to leave the same, or new value.\n");
+
+ while (change_principal()) {
+ }
+
+ cleanup();
+ return(0); /* make -Wall shut up - MRVM */
+}
+
+int
+change_principal()
+{
+ static char temp[255];
+ int creating = 0;
+ int editpw = 0;
+ int changed = 0;
+ long temp_long;
+ int n;
+ struct tm *tp, edate, *localtime();
+ long maketime();
+
+ fprintf(stdout, "\nPrincipal name: ");
+ fflush(stdout);
+ if (!s_gets(input_name, ANAME_SZ-1) || *input_name == '\0')
+ return 0;
+ fprintf(stdout, "Instance: ");
+ fflush(stdout);
+ /* instance can be null */
+ s_gets(input_instance, INST_SZ-1);
+ j = kerb_get_principal(input_name, input_instance, principal_data,
+ MAX_PRINCIPAL, &more);
+ if (!j) {
+ fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
+ s_gets(temp, sizeof(temp)-1); /* Default case should work, it didn't */
+ if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
+ return -1;
+ /* make a new principal, fill in defaults */
+ j = 1;
+ creating = 1;
+ strcpy(principal_data[0].name, input_name);
+ strcpy(principal_data[0].instance, input_instance);
+ principal_data[0].old = NULL;
+ principal_data[0].exp_date = default_princ.exp_date;
+ principal_data[0].max_life = default_princ.max_life;
+ principal_data[0].attributes = default_princ.attributes;
+ principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
+ principal_data[0].key_version = 0; /* bumped up later */
+ }
+ tp = localtime(&principal_data[0].exp_date);
+ (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
+ tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+ tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+ for (i = 0; i < j; i++) {
+ for (;;) {
+ fprintf(stdout,
+ "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
+ principal_data[i].name, principal_data[i].instance,
+ principal_data[i].kdc_key_ver);
+ editpw = 1;
+ changed = 0;
+ if (!creating) {
+ /*
+ * copy the existing data so we can use the old values
+ * for the qualifier clause of the replace
+ */
+ principal_data[i].old = (char *) &old_principal;
+ bcopy(&principal_data[i], &old_principal,
+ sizeof(old_principal));
+ printf("\nChange password [n] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (strcmp("y", temp) && strcmp("Y", temp))
+ editpw = 0;
+ }
+ /* password */
+ if (editpw) {
+#ifdef NOENCRYPTION
+ placebo_read_pw_string(pw_str, sizeof pw_str,
+ "\nNew Password: ", TRUE);
+#else
+ des_read_pw_string(pw_str, sizeof pw_str,
+ "\nNew Password: ", TRUE);
+#endif
+ if (pw_str[0] == '\0' || !strcmp(pw_str, "RANDOM")) {
+ printf("\nRandom password [y] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (!strcmp("n", temp) || !strcmp("N", temp)) {
+ /* no, use literal */
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, &new_key);
+#endif
+ bzero(pw_str, sizeof pw_str); /* "RANDOM" */
+ } else {
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ random_key(new_key);
+#endif
+ bzero(pw_str, sizeof pw_str);
+ }
+ } else if (!strcmp(pw_str, "NULL")) {
+ printf("\nNull Key [y] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (!strcmp("n", temp) || !strcmp("N", temp)) {
+ /* no, use literal */
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, &new_key);
+#endif
+ bzero(pw_str, sizeof pw_str); /* "NULL" */
+ } else {
+
+ principal_data[i].key_low = 0;
+ principal_data[i].key_high = 0;
+ goto null_key;
+ }
+ } else {
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, &new_key);
+#endif
+ bzero(pw_str, sizeof pw_str);
+ }
+
+ /* seal it under the kerberos master key */
+ kdb_encrypt_key (new_key, new_key,
+ master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal_data[i].key_low, 4);
+ bcopy(((long *) new_key) + 1,
+ &principal_data[i].key_high, 4);
+ bzero(new_key, sizeof(new_key));
+ null_key:
+ /* set master key version */
+ principal_data[i].kdc_key_ver =
+ (unsigned char) master_key_version;
+ /* bump key version # */
+ principal_data[i].key_version++;
+ fprintf(stdout,
+ "\nPrincipal's new key version = %d\n",
+ principal_data[i].key_version);
+ fflush(stdout);
+ changed = 1;
+ }
+ /* expiration date */
+ fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+ principal_data[i].exp_date_txt);
+ zaptime(&edate);
+ while (s_gets(temp, sizeof(temp)-1) && ((n = strlen(temp)) >
+ sizeof(principal_data[0].exp_date_txt))) {
+ bad_date:
+ fprintf(stdout, "\07\07Date Invalid\n");
+ fprintf(stdout,
+ "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+ principal_data[i].exp_date_txt);
+ zaptime(&edate);
+ }
+
+ if (*temp) {
+ if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
+ &edate.tm_mon, &edate.tm_mday) != 3)
+ goto bad_date;
+ (void) strcpy(principal_data[i].exp_date_txt, temp);
+ edate.tm_mon--; /* January is 0, not 1 */
+ edate.tm_hour = 23; /* nearly midnight at the end of the */
+ edate.tm_min = 59; /* specified day */
+ if (!(principal_data[i].exp_date = maketime(&edate, 1)))
+ goto bad_date;
+ changed = 1;
+ }
+
+ /* maximum lifetime */
+ fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+ principal_data[i].max_life);
+ while (s_gets(temp, sizeof(temp)-1) && *temp) {
+ if (sscanf(temp, "%ld", &temp_long) != 1)
+ goto bad_life;
+ if (temp_long > 255 || (temp_long < 0)) {
+ bad_life:
+ fprintf(stdout, "\07\07Invalid, choose 0-255\n");
+ fprintf(stdout,
+ "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+ principal_data[i].max_life);
+ continue;
+ }
+ changed = 1;
+ /* dont clobber */
+ principal_data[i].max_life = (unsigned short) temp_long;
+ break;
+ }
+
+ /* attributes */
+ fprintf(stdout, "Attributes [ %d ] ? ",
+ principal_data[i].attributes);
+ while (s_gets(temp, sizeof(temp)-1) && *temp) {
+ if (sscanf(temp, "%ld", &temp_long) != 1)
+ goto bad_att;
+ if (temp_long > 65535 || (temp_long < 0)) {
+ bad_att:
+ fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
+ fprintf(stdout, "Attributes [ %d ] ? ",
+ principal_data[i].attributes);
+ continue;
+ }
+ changed = 1;
+ /* dont clobber */
+ principal_data[i].attributes =
+ (unsigned short) temp_long;
+ break;
+ }
+
+ /*
+ * remaining fields -- key versions and mod info, should
+ * not be directly manipulated
+ */
+ if (changed) {
+ if (kerb_put_principal(&principal_data[i], 1)) {
+ fprintf(stdout,
+ "\nError updating Kerberos database");
+ } else {
+ fprintf(stdout, "Edit O.K.");
+ }
+ } else {
+ fprintf(stdout, "Unchanged");
+ }
+
+
+ bzero(&principal_data[i].key_low, 4);
+ bzero(&principal_data[i].key_high, 4);
+ fflush(stdout);
+ break;
+ }
+ }
+ if (more) {
+ fprintf(stdout, "\nThere were more tuples found ");
+ fprintf(stdout, "than there were space for");
+ }
+ return 1;
+}
+
+void
+no_core_dumps()
+{
+
+ signal(SIGQUIT, (sig_t)sig_exit);
+ signal(SIGILL, (sig_t)sig_exit);
+ signal(SIGTRAP, (sig_t)sig_exit);
+ signal(SIGIOT, (sig_t)sig_exit);
+ signal(SIGEMT, (sig_t)sig_exit);
+ signal(SIGFPE, (sig_t)sig_exit);
+ signal(SIGBUS, (sig_t)sig_exit);
+ signal(SIGSEGV, (sig_t)sig_exit);
+ signal(SIGSYS, (sig_t)sig_exit);
+}
+
+void
+sig_exit(sig, code, scp)
+ int sig, code;
+ struct sigcontext *scp;
+{
+ cleanup();
+ fprintf(stderr,
+ "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
+ sig, code, scp->sc_pc);
+ exit(-1);
+}
+
+void
+cleanup()
+{
+
+ bzero(master_key, sizeof(master_key));
+ bzero(session_key, sizeof(session_key));
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+ bzero(principal_data, sizeof(principal_data));
+ bzero(new_key, sizeof(new_key));
+ bzero(pw_str, sizeof(pw_str));
+}
+
+void
+Usage()
+{
+ fprintf(stderr, "Usage: %s [-n]\n", progname);
+ exit(1);
+}
diff --git a/eBones/usr.sbin/kdb_edit/maketime.c b/eBones/usr.sbin/kdb_edit/maketime.c
new file mode 100644
index 0000000000000..5e0ee00ee0e4a
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/maketime.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Convert a struct tm * to a UNIX time.
+ *
+ * from: maketime.c,v 4.2 90/01/09 15:54:51 raeburn Exp $
+ * $Id: maketime.c,v 1.3 1995/07/18 16:37:29 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: maketime.c,v 1.1 1994/03/21 16:23:54 piero Exp ";
+#endif lint
+#endif
+
+#include <sys/time.h>
+
+#define daysinyear(y) (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
+
+#define SECSPERDAY 24*60*60
+#define SECSPERHOUR 60*60
+#define SECSPERMIN 60
+
+static int cumdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
+ 365};
+
+static int leapyear[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static int nonleapyear[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+long
+maketime(tp, local)
+register struct tm *tp;
+int local;
+{
+ register long retval;
+ int foo;
+ int *marray;
+
+ if (tp->tm_mon < 0 || tp->tm_mon > 11 ||
+ tp->tm_hour < 0 || tp->tm_hour > 23 ||
+ tp->tm_min < 0 || tp->tm_min > 59 ||
+ tp->tm_sec < 0 || tp->tm_sec > 59) /* out of range */
+ return 0;
+
+ retval = 0;
+ if (tp->tm_year < 1900)
+ foo = tp->tm_year + 1900;
+ else
+ foo = tp->tm_year;
+
+ if (foo < 1901 || foo > 2038) /* year is too small/large */
+ return 0;
+
+ if (daysinyear(foo) == 366) {
+ if (tp->tm_mon > 1)
+ retval+= SECSPERDAY; /* add leap day */
+ marray = leapyear;
+ } else
+ marray = nonleapyear;
+
+ if (tp->tm_mday < 0 || tp->tm_mday > marray[tp->tm_mon])
+ return 0; /* out of range */
+
+ while (--foo >= 1970)
+ retval += daysinyear(foo) * SECSPERDAY;
+
+ retval += cumdays[tp->tm_mon] * SECSPERDAY;
+ retval += (tp->tm_mday-1) * SECSPERDAY;
+ retval += tp->tm_hour * SECSPERHOUR + tp->tm_min * SECSPERMIN + tp->tm_sec;
+
+ if (local) {
+ /* need to use local time, so we retrieve timezone info */
+ struct timezone tz;
+ struct timeval tv;
+ if (gettimeofday(&tv, &tz) < 0) {
+ /* some error--give up? */
+ return(retval);
+ }
+ retval += tz.tz_minuteswest * SECSPERMIN;
+ }
+ return(retval);
+}
diff --git a/eBones/usr.sbin/kdb_init/Makefile b/eBones/usr.sbin/kdb_init/Makefile
new file mode 100644
index 0000000000000..cc1b778013f13
--- /dev/null
+++ b/eBones/usr.sbin/kdb_init/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:25 markm Exp $
+
+PROG= kdb_init
+CFLAGS+=-DKERBEROS -DDEBUG
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN8= kdb_init.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_init/kdb_init.c b/eBones/usr.sbin/kdb_init/kdb_init.c
new file mode 100644
index 0000000000000..de99181d5c3ba
--- /dev/null
+++ b/eBones/usr.sbin/kdb_init/kdb_init.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * program to initialize the database, reports error if database file
+ * already exists.
+ *
+ * from: kdb_init.c,v 4.0 89/01/24 21:50:45 jtkohl Exp $
+ * $Id: kdb_init.c,v 1.4 1995/07/18 16:37:35 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_init.c,v 1.4 1995/07/18 16:37:35 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+#include <string.h>
+
+#define TRUE 1
+
+enum ap_op {
+ NULL_KEY, /* setup null keys */
+ MASTER_KEY, /* use master key as new key */
+ RANDOM_KEY, /* choose a random key */
+};
+
+int add_principal(char *name, char *instance, enum ap_op aap_op);
+
+int debug = 0;
+char *progname;
+C_Block master_key;
+Key_schedule master_key_schedule;
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char realm[REALM_SZ];
+ char *cp;
+ int code;
+ char *database;
+
+ progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
+
+ if (argc > 3) {
+ fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]);
+ exit(1);
+ }
+ if (argc == 3) {
+ database = argv[2];
+ --argc;
+ } else
+ database = DBM_FILE;
+
+ /* Do this first, it'll fail if the database exists */
+ if ((code = kerb_db_create(database)) != 0) {
+ fprintf(stderr, "Couldn't create database: %s\n",
+ sys_errlist[code]);
+ exit(1);
+ }
+ kerb_db_set_name(database);
+
+ if (argc == 2)
+ strncpy(realm, argv[1], REALM_SZ);
+ else {
+ fprintf(stderr, "Realm name [default %s ]: ", KRB_REALM);
+ if (fgets(realm, sizeof(realm), stdin) == NULL) {
+ fprintf(stderr, "\nEOF reading realm\n");
+ exit(1);
+ }
+ if ((cp = index(realm, '\n')))
+ *cp = '\0';
+ if (!*realm) /* no realm given */
+ strcpy(realm, KRB_REALM);
+ }
+ if (!k_isrealm(realm)) {
+ fprintf(stderr, "%s: Bad kerberos realm name \"%s\"\n",
+ progname, realm);
+ exit(1);
+ }
+ printf("You will be prompted for the database Master Password.\n");
+ printf("It is important that you NOT FORGET this password.\n");
+ fflush(stdout);
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "Couldn't read master key.\n");
+ exit (-1);
+ }
+
+ if (
+ add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY) ||
+ add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY) ||
+ add_principal("krbtgt", realm, RANDOM_KEY) ||
+ add_principal("changepw", KRB_MASTER, RANDOM_KEY)
+ ) {
+ fprintf(stderr, "\n%s: couldn't initialize database.\n",
+ progname);
+ exit(1);
+ }
+
+ /* play it safe */
+ bzero (master_key, sizeof (C_Block));
+ bzero (master_key_schedule, sizeof (Key_schedule));
+ exit(0);
+}
+
+/* use a return code to indicate success or failure. check the return */
+/* values of the routines called by this routine. */
+
+int
+add_principal(name, instance, aap_op)
+ char *name, *instance;
+ enum ap_op aap_op;
+{
+ Principal principal;
+ struct tm *tm;
+ C_Block new_key;
+
+ bzero(&principal, sizeof(principal));
+ strncpy(principal.name, name, ANAME_SZ);
+ strncpy(principal.instance, instance, INST_SZ);
+ switch (aap_op) {
+ case NULL_KEY:
+ principal.key_low = 0;
+ principal.key_high = 0;
+ break;
+ case RANDOM_KEY:
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ random_key(new_key);
+#endif
+ kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal.key_low, 4);
+ bcopy(((long *) new_key) + 1, &principal.key_high, 4);
+ break;
+ case MASTER_KEY:
+ bcopy (master_key, new_key, sizeof (C_Block));
+ kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal.key_low, 4);
+ bcopy(((long *) new_key) + 1, &principal.key_high, 4);
+ break;
+ }
+ principal.exp_date = 946702799; /* Happy new century */
+ strncpy(principal.exp_date_txt, "12/31/99", DATE_SZ);
+ principal.mod_date = time(0);
+
+ tm = localtime(&principal.mod_date);
+ principal.attributes = 0;
+ principal.max_life = 255;
+
+ principal.kdc_key_ver = 1;
+ principal.key_version = 1;
+
+ strncpy(principal.mod_name, "db_creation", ANAME_SZ);
+ strncpy(principal.mod_instance, "", INST_SZ);
+ principal.old = 0;
+
+ kerb_db_put_principal(&principal, 1);
+
+ /* let's play it safe */
+ bzero (new_key, sizeof (C_Block));
+ bzero (&principal.key_low, 4);
+ bzero (&principal.key_high, 4);
+ return 0;
+}
diff --git a/eBones/usr.sbin/kdb_util/Makefile b/eBones/usr.sbin/kdb_util/Makefile
new file mode 100644
index 0000000000000..1f211a134843b
--- /dev/null
+++ b/eBones/usr.sbin/kdb_util/Makefile
@@ -0,0 +1,12 @@
+# From: @(#)Makefile 5.2 (Berkeley) 2/14/91
+# $Id: Makefile,v 1.4 1995/09/13 17:24:27 markm Exp $
+
+PROG= kdb_util
+CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../../kdb_edit
+SRCS= kdb_util.c maketime.c
+.PATH: ${.CURDIR}/../kdb_edit
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN8= kdb_util.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_util/kdb_util.c b/eBones/usr.sbin/kdb_util/kdb_util.c
new file mode 100644
index 0000000000000..5dbe509e1afe2
--- /dev/null
+++ b/eBones/usr.sbin/kdb_util/kdb_util.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Kerberos database manipulation utility. This program allows you to
+ * dump a kerberos database to an ascii readable file and load this
+ * file into the database. Read locking of the database is done during a
+ * dump operation. NO LOCKING is done during a load operation. Loads
+ * should happen with other processes shutdown.
+ *
+ * Written July 9, 1987 by Jeffrey I. Schiller
+ *
+ * from: kdb_util.c,v 4.4 90/01/09 15:57:20 raeburn Exp $
+ * $Id: kdb_util.c,v 1.5 1995/08/03 17:15:57 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_util.c,v 1.5 1995/08/03 17:15:57 mark Exp $";
+#endif lint
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <time.h>
+#include <strings.h>
+#include <des.h>
+#include <krb.h>
+#include <sys/file.h>
+#include <krb_db.h>
+
+#define TRUE 1
+
+Principal aprinc;
+
+static des_cblock master_key, new_master_key;
+static des_key_schedule master_key_schedule, new_master_key_schedule;
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+char * progname;
+
+void convert_old_format_db (char *db_file, FILE *out);
+void convert_new_master_key (char *db_file, FILE *out);
+void update_ok_file (char *file_name);
+void print_time(FILE *file, unsigned long timeval);
+void load_db (char *db_file, FILE *input_file);
+int dump_db (char *db_file, FILE *output_file, void (*cv_key)());
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ FILE *file;
+ enum {
+ OP_LOAD,
+ OP_DUMP,
+ OP_SLAVE_DUMP,
+ OP_NEW_MASTER,
+ OP_CONVERT_OLD_DB,
+ } op;
+ char *file_name;
+ char *prog = argv[0];
+ char *db_name;
+
+ progname = prog;
+
+ if (argc != 3 && argc != 4) {
+ fprintf(stderr, "Usage: %s operation file-name [database name].\n",
+ argv[0]);
+ exit(1);
+ }
+ if (argc == 3)
+ db_name = DBM_FILE;
+ else
+ db_name = argv[3];
+
+ if (kerb_db_set_name (db_name) != 0) {
+ perror("Can't open database");
+ exit(1);
+ }
+
+ if (!strcmp(argv[1], "load"))
+ op = OP_LOAD;
+ else if (!strcmp(argv[1], "dump"))
+ op = OP_DUMP;
+ else if (!strcmp(argv[1], "slave_dump"))
+ op = OP_SLAVE_DUMP;
+ else if (!strcmp(argv[1], "new_master_key"))
+ op = OP_NEW_MASTER;
+ else if (!strcmp(argv[1], "convert_old_db"))
+ op = OP_CONVERT_OLD_DB;
+ else {
+ fprintf(stderr,
+ "%s: %s is an invalid operation.\n", prog, argv[1]);
+ fprintf(stderr,
+ "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]);
+ fprintf(stderr,
+ "\"load\", \"new_master_key\", and \"convert_old_db\".\n");
+ exit(1);
+ }
+
+ file_name = argv[2];
+ file = fopen(file_name, op == OP_LOAD ? "r" : "w");
+ if (file == NULL) {
+ fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]);
+ (void) fflush(stderr);
+ perror("open");
+ exit(1);
+ }
+
+ switch (op) {
+ case OP_DUMP:
+ if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
+ (fclose(file) == EOF)) {
+ fprintf(stderr, "error on file %s:", file_name);
+ perror("");
+ exit(1);
+ }
+ break;
+ case OP_SLAVE_DUMP:
+ if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
+ (fclose(file) == EOF)) {
+ fprintf(stderr, "error on file %s:", file_name);
+ perror("");
+ exit(1);
+ }
+ update_ok_file (file_name);
+ break;
+ case OP_LOAD:
+ load_db (db_name, file);
+ break;
+ case OP_NEW_MASTER:
+ convert_new_master_key (db_name, file);
+ printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
+ break;
+ case OP_CONVERT_OLD_DB:
+ convert_old_format_db (db_name, file);
+ printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
+ break;
+ }
+ exit(0);
+ }
+
+void
+clear_secrets ()
+{
+ bzero((char *)master_key, sizeof (des_cblock));
+ bzero((char *)master_key_schedule, sizeof (Key_schedule));
+ bzero((char *)new_master_key, sizeof (des_cblock));
+ bzero((char *)new_master_key_schedule, sizeof (Key_schedule));
+}
+
+/* cv_key is a procedure which takes a principle and changes its key,
+ either for a new method of encrypting the keys, or a new master key.
+ if cv_key is null no transformation of key is done (other than net byte
+ order). */
+
+struct callback_args {
+ void (*cv_key)();
+ FILE *output_file;
+};
+
+static int dump_db_1(arg, principal)
+ char *arg;
+ Principal *principal;
+{ /* replace null strings with "*" */
+ struct callback_args *a = (struct callback_args *)arg;
+
+ if (principal->instance[0] == '\0') {
+ principal->instance[0] = '*';
+ principal->instance[1] = '\0';
+ }
+ if (principal->mod_name[0] == '\0') {
+ principal->mod_name[0] = '*';
+ principal->mod_name[1] = '\0';
+ }
+ if (principal->mod_instance[0] == '\0') {
+ principal->mod_instance[0] = '*';
+ principal->mod_instance[1] = '\0';
+ }
+ if (a->cv_key != NULL) {
+ (*a->cv_key) (principal);
+ }
+ fprintf(a->output_file, "%s %s %d %d %d %d %lx %lx",
+ principal->name,
+ principal->instance,
+ principal->max_life,
+ principal->kdc_key_ver,
+ principal->key_version,
+ principal->attributes,
+ htonl (principal->key_low),
+ htonl (principal->key_high));
+ print_time(a->output_file, principal->exp_date);
+ print_time(a->output_file, principal->mod_date);
+ fprintf(a->output_file, " %s %s\n",
+ principal->mod_name,
+ principal->mod_instance);
+ return 0;
+}
+
+int
+dump_db (db_file, output_file, cv_key)
+ char *db_file;
+ FILE *output_file;
+ void (*cv_key)();
+{
+ struct callback_args a;
+
+ a.cv_key = cv_key;
+ a.output_file = output_file;
+
+ kerb_db_iterate (dump_db_1, (char *)&a);
+ return fflush(output_file);
+}
+
+void
+load_db (db_file, input_file)
+ char *db_file;
+ FILE *input_file;
+{
+ char exp_date_str[50];
+ char mod_date_str[50];
+ int temp1, temp2, temp3;
+ long time_explode();
+ int code;
+ char *temp_db_file;
+ temp1 = strlen(db_file)+2;
+ temp_db_file = malloc (temp1);
+ strcpy(temp_db_file, db_file);
+ strcat(temp_db_file, "~");
+
+ /* Create the database */
+ if ((code = kerb_db_create(temp_db_file)) != 0) {
+ fprintf(stderr, "Couldn't create temp database %s: %s\n",
+ temp_db_file, sys_errlist[code]);
+ exit(1);
+ }
+ kerb_db_set_name(temp_db_file);
+ for (;;) { /* explicit break on eof from fscanf */
+ bzero((char *)&aprinc, sizeof(aprinc));
+ if (fscanf(input_file,
+ "%s %s %d %d %d %hd %lx %lx %s %s %s %s\n",
+ aprinc.name,
+ aprinc.instance,
+ &temp1,
+ &temp2,
+ &temp3,
+ &aprinc.attributes,
+ &aprinc.key_low,
+ &aprinc.key_high,
+ exp_date_str,
+ mod_date_str,
+ aprinc.mod_name,
+ aprinc.mod_instance) == EOF)
+ break;
+ aprinc.key_low = ntohl (aprinc.key_low);
+ aprinc.key_high = ntohl (aprinc.key_high);
+ aprinc.max_life = (unsigned char) temp1;
+ aprinc.kdc_key_ver = (unsigned char) temp2;
+ aprinc.key_version = (unsigned char) temp3;
+ aprinc.exp_date = time_explode(exp_date_str);
+ aprinc.mod_date = time_explode(mod_date_str);
+ if (aprinc.instance[0] == '*')
+ aprinc.instance[0] = '\0';
+ if (aprinc.mod_name[0] == '*')
+ aprinc.mod_name[0] = '\0';
+ if (aprinc.mod_instance[0] == '*')
+ aprinc.mod_instance[0] = '\0';
+ if (kerb_db_put_principal(&aprinc, 1) != 1) {
+ fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n",
+ aprinc.name, aprinc.instance,
+ sys_errlist[errno]);
+ exit(1);
+ };
+ }
+ if ((code = kerb_db_rename(temp_db_file, db_file)) != 0)
+ perror("database rename failed");
+ (void) fclose(input_file);
+ free(temp_db_file);
+}
+
+void
+print_time(file, timeval)
+ FILE *file;
+ unsigned long timeval;
+{
+ struct tm *tm;
+ struct tm *gmtime();
+ tm = gmtime((long *)&timeval);
+ fprintf(file, " %04d%02d%02d%02d%02d",
+ tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min);
+}
+
+/*ARGSUSED*/
+void
+update_ok_file (file_name)
+ char *file_name;
+{
+ /* handle slave locking/failure stuff */
+ char *file_ok;
+ int fd;
+ static char ok[]=".dump_ok";
+
+ if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1))
+ == NULL) {
+ fprintf(stderr, "kdb_util: out of memory.\n");
+ (void) fflush (stderr);
+ perror ("malloc");
+ exit (1);
+ }
+ strcpy(file_ok, file_name);
+ strcat(file_ok, ok);
+ if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) {
+ fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok);
+ perror("");
+ (void) fflush (stderr);
+ exit (1);
+ }
+ free(file_ok);
+ close(fd);
+}
+
+void
+convert_key_new_master (p)
+ Principal *p;
+{
+ des_cblock key;
+
+ /* leave null keys alone */
+ if ((p->key_low == 0) && (p->key_high == 0)) return;
+
+ /* move current key to des_cblock for encryption, special case master key
+ since that's changing */
+ if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) &&
+ (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) {
+ bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock));
+ (p->key_version)++;
+ } else {
+ bcopy((char *)&(p->key_low), (char *)key, 4);
+ bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4);
+ kdb_encrypt_key (key, key, master_key, master_key_schedule, DECRYPT);
+ }
+
+ kdb_encrypt_key (key, key, new_master_key, new_master_key_schedule, ENCRYPT);
+
+ bcopy((char *)key, (char *)&(p->key_low), 4);
+ bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
+ bzero((char *)key, sizeof (key)); /* a little paranoia ... */
+
+ (p->kdc_key_ver)++;
+}
+
+void
+convert_new_master_key (db_file, out)
+ char *db_file;
+ FILE *out;
+{
+
+ printf ("\n\nEnter the CURRENT master key.");
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "get_master_key: Couldn't get master key.\n");
+ clear_secrets ();
+ exit (-1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ clear_secrets ();
+ exit (-1);
+ }
+
+ printf ("\n\nNow enter the NEW master key. Do not forget it!!");
+ if (kdb_get_master_key (TRUE, new_master_key, new_master_key_schedule) != 0) {
+ fprintf (stderr, "get_master_key: Couldn't get new master key.\n");
+ clear_secrets ();
+ exit (-1);
+ }
+
+ dump_db (db_file, out, convert_key_new_master);
+}
+
+void
+convert_key_old_db (p)
+ Principal *p;
+{
+ des_cblock key;
+
+ /* leave null keys alone */
+ if ((p->key_low == 0) && (p->key_high == 0)) return;
+
+ bcopy((char *)&(p->key_low), (char *)key, 4);
+ bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4);
+
+#ifndef NOENCRYPTION
+ des_pcbc_encrypt((des_cblock *)key,(des_cblock *)key,
+ (long)sizeof(des_cblock),master_key_schedule,
+ (des_cblock *)master_key_schedule,DECRYPT);
+#endif
+
+ /* make new key, new style */
+ kdb_encrypt_key (key, key, master_key, master_key_schedule, ENCRYPT);
+
+ bcopy((char *)key, (char *)&(p->key_low), 4);
+ bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
+ bzero((char *)key, sizeof (key)); /* a little paranoia ... */
+}
+
+void
+convert_old_format_db (db_file, out)
+ char *db_file;
+ FILE *out;
+{
+ des_cblock key_from_db;
+ Principal principal_data[1];
+ int n, more;
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0L) {
+ fprintf (stderr, "verify_master_key: Couldn't get master key.\n");
+ clear_secrets();
+ exit (-1);
+ }
+
+ /* can't call kdb_verify_master_key because this is an old style db */
+ /* lookup the master key version */
+ n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
+ 1 /* only one please */, &more);
+ if ((n != 1) || more) {
+ fprintf(stderr, "verify_master_key: "
+ "Kerberos error on master key lookup, %d found.\n",
+ n);
+ exit (-1);
+ }
+
+ /* set up the master key */
+ fprintf(stderr, "Current Kerberos master key version is %d.\n",
+ principal_data[0].kdc_key_ver);
+
+ /*
+ * now use the master key to decrypt (old style) the key in the db, had better
+ * be the same!
+ */
+ bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4);
+ bcopy((char *)&principal_data[0].key_high,
+ (char *)(((long *) key_from_db) + 1), 4);
+#ifndef NOENCRYPTION
+ des_pcbc_encrypt((des_cblock *)key_from_db,(des_cblock *)key_from_db,
+ (long)sizeof(key_from_db),master_key_schedule,
+ (des_cblock *)master_key_schedule,DECRYPT);
+#endif
+ /* the decrypted database key had better equal the master key */
+ n = bcmp((char *) master_key, (char *) key_from_db,
+ sizeof(master_key));
+ bzero((char *)key_from_db, sizeof(key_from_db));
+
+ if (n) {
+ fprintf(stderr, "\n\07\07verify_master_key: Invalid master key, ");
+ fprintf(stderr, "does not match database.\n");
+ exit (-1);
+ }
+
+ fprintf(stderr, "Master key verified.\n");
+ (void) fflush(stderr);
+
+ dump_db (db_file, out, convert_key_old_db);
+}
+
+long
+time_explode(cp)
+register char *cp;
+{
+ char wbuf[5];
+ struct tm tp;
+ long maketime();
+ int local;
+
+ zaptime(&tp); /* clear out the struct */
+
+ if (strlen(cp) > 10) { /* new format */
+ (void) strncpy(wbuf, cp, 4);
+ wbuf[4] = 0;
+ tp.tm_year = atoi(wbuf);
+ cp += 4; /* step over the year */
+ local = 0; /* GMT */
+ } else { /* old format: local time,
+ year is 2 digits, assuming 19xx */
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ wbuf[2] = 0;
+ tp.tm_year = 1900 + atoi(wbuf);
+ local = 1; /* local */
+ }
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ wbuf[2] = 0;
+ tp.tm_mon = atoi(wbuf)-1;
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_mday = atoi(wbuf);
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_hour = atoi(wbuf);
+
+ wbuf[0] = *cp++;
+ wbuf[1] = *cp++;
+ tp.tm_min = atoi(wbuf);
+
+
+ return(maketime(&tp, local));
+}
diff --git a/eBones/usr.sbin/kerberos/Makefile b/eBones/usr.sbin/kerberos/Makefile
new file mode 100644
index 0000000000000..224b3350fdb45
--- /dev/null
+++ b/eBones/usr.sbin/kerberos/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.5 1995/09/13 17:24:28 markm Exp $
+
+PROG= kerberos
+SRCS= kerberos.c cr_err_reply.c
+CFLAGS+=-DKERBEROS -DDEBUG
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kerberos/cr_err_reply.c b/eBones/usr.sbin/kerberos/cr_err_reply.c
new file mode 100644
index 0000000000000..89ee5f6cbfdba
--- /dev/null
+++ b/eBones/usr.sbin/kerberos/cr_err_reply.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: cr_err_reply.c,v 4.10 89/01/10 11:34:42 steiner Exp $
+ * $Id: cr_err_reply.c,v 1.2 1995/07/18 16:37:49 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: cr_err_reply.c,v 1.2 1995/07/18 16:37:49 mark Exp $";
+#endif /* lint */
+#endif
+
+#include <sys/types.h>
+#include <krb.h>
+#include <prot.h>
+#include <strings.h>
+
+extern int req_act_vno; /* this is defined in the kerberos
+ * server code */
+
+/*
+ * This routine is used by the Kerberos authentication server to
+ * create an error reply packet to send back to its client.
+ *
+ * It takes a pointer to the packet to be built, the name, instance,
+ * and realm of the principal, the client's timestamp, an error code
+ * and an error string as arguments. Its return value is undefined.
+ *
+ * The packet is built in the following format:
+ *
+ * type variable data
+ * or constant
+ * ---- ----------- ----
+ *
+ * unsigned char req_ack_vno protocol version number
+ *
+ * unsigned char AUTH_MSG_ERR_REPLY protocol message type
+ *
+ * [least significant HOST_BYTE_ORDER sender's (server's) byte
+ * bit of above field] order
+ *
+ * string pname principal's name
+ *
+ * string pinst principal's instance
+ *
+ * string prealm principal's realm
+ *
+ * unsigned long time_ws client's timestamp
+ *
+ * unsigned long e error code
+ *
+ * string e_string error text
+ */
+
+void
+cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string)
+ KTEXT pkt;
+ char *pname; /* Principal's name */
+ char *pinst; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ u_long time_ws; /* Workstation time */
+ u_long e; /* Error code */
+ char *e_string; /* Text of error */
+{
+ u_char *v = (u_char *) pkt->dat; /* Prot vers number */
+ u_char *t = (u_char *)(pkt->dat+1); /* Prot message type */
+
+ /* Create fixed part of packet */
+ *v = (unsigned char) req_act_vno; /* KRB_PROT_VERSION; */
+ *t = (unsigned char) AUTH_MSG_ERR_REPLY;
+ *t |= HOST_BYTE_ORDER;
+
+ /* Add the basic info */
+ (void) strcpy((char *) (pkt->dat+2),pname);
+ pkt->length = 3 + strlen(pname);
+ (void) strcpy((char *)(pkt->dat+pkt->length),pinst);
+ pkt->length += 1 + strlen(pinst);
+ (void) strcpy((char *)(pkt->dat+pkt->length),prealm);
+ pkt->length += 1 + strlen(prealm);
+ /* ws timestamp */
+ bcopy((char *) &time_ws,(char *)(pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ /* err code */
+ bcopy((char *) &e,(char *)(pkt->dat+pkt->length),4);
+ pkt->length += 4;
+ /* err text */
+ (void) strcpy((char *)(pkt->dat+pkt->length),e_string);
+ pkt->length += 1 + strlen(e_string);
+
+ /* And return */
+ return;
+}
diff --git a/eBones/usr.sbin/kerberos/kerberos.c b/eBones/usr.sbin/kerberos/kerberos.c
new file mode 100644
index 0000000000000..236bbbdc116d8
--- /dev/null
+++ b/eBones/usr.sbin/kerberos/kerberos.c
@@ -0,0 +1,816 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kerberos.c,v 4.19 89/11/01 17:18:07 qjb Exp $
+ * $Id: kerberos.c,v 1.4 1995/07/18 16:37:51 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kerberos.c,v 1.4 1995/07/18 16:37:51 mark Exp $";
+#endif lint
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <ctype.h>
+
+#include <krb.h>
+#include <des.h>
+#include <klog.h>
+#include <prot.h>
+#include <krb_db.h>
+#include <kdc.h>
+
+void cr_err_reply(KTEXT pkt, char *pname, char *pinst, char *prealm,
+ u_long time_ws, u_long e, char *e_string);
+void kerb_err_reply(struct sockaddr_in *client, KTEXT pkt, long err,
+ char *string);
+void setup_disc(void);
+void kerberos(struct sockaddr_in *client, KTEXT pkt);
+int check_princ(char *p_name, char *instance, unsigned lifetime, Principal *p);
+int set_tgtkey(char *r);
+
+struct sockaddr_in s_in = {AF_INET};
+int f;
+
+/* XXX several files in libkdb know about this */
+char *progname;
+
+static Key_schedule master_key_schedule;
+static C_Block master_key;
+
+static struct timeval kerb_time;
+static Principal a_name_data; /* for requesting user */
+static Principal s_name_data; /* for services requested */
+static C_Block session_key;
+static u_char master_key_version;
+static char k_instance[INST_SZ];
+static char *lt;
+static int more;
+
+static int mflag; /* Are we invoked manually? */
+static int lflag; /* Have we set an alterate log file? */
+static char *log_file; /* name of alt. log file */
+static int nflag; /* don't check max age */
+static int rflag; /* alternate realm specified */
+
+/* fields within the received request packet */
+static u_char req_msg_type;
+static u_char req_version;
+static char *req_name_ptr;
+static char *req_inst_ptr;
+static char *req_realm_ptr;
+static u_long req_time_ws;
+
+int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */
+
+static char local_realm[REALM_SZ];
+
+/* statistics */
+static long q_bytes; /* current bytes remaining in queue */
+static long q_n; /* how many consecutive non-zero
+ * q_bytes */
+static long max_q_bytes;
+static long max_q_n;
+static long n_auth_req;
+static long n_appl_req;
+static long n_packets;
+
+static long max_age = -1;
+static long pause_int = -1;
+
+static void check_db_age();
+static void hang();
+
+/*
+ * Print usage message and exit.
+ */
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname,
+ " [-a max_age] [-l log_file] [-r realm]"
+ ," [database_pathname]"
+ );
+ exit(1);
+}
+
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct sockaddr_in from;
+ register int n;
+ int on = 1;
+ int child;
+ struct servent *sp;
+ int fromlen;
+ static KTEXT_ST pkt_st;
+ KTEXT pkt = &pkt_st;
+ int kerror;
+ int c;
+ extern char *optarg;
+ extern int optind;
+
+ progname = argv[0];
+
+ while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) {
+ switch(c) {
+ case 's':
+ /*
+ * Set parameters to slave server defaults.
+ */
+ if (max_age == -1 && !nflag)
+ max_age = ONE_DAY; /* 24 hours */
+ if (pause_int == -1)
+ pause_int = FIVE_MINUTES; /* 5 minutes */
+ if (lflag == 0) {
+ log_file = KRBSLAVELOG;
+ lflag++;
+ }
+ break;
+ case 'n':
+ max_age = -1; /* don't check max age. */
+ nflag++;
+ break;
+ case 'm':
+ mflag++; /* running manually; prompt for master key */
+ break;
+ case 'p':
+ /* Set pause interval. */
+ if (!isdigit(optarg[0]))
+ usage();
+ pause_int = atoi(optarg);
+ if ((pause_int < 5) || (pause_int > ONE_HOUR)) {
+ fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n");
+ usage();
+ }
+ break;
+ case 'a':
+ /* Set max age. */
+ if (!isdigit(optarg[0]))
+ usage();
+ max_age = atoi(optarg);
+ if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) {
+ fprintf(stderr, "max_age must be between one hour and three days, in seconds\n");
+ usage();
+ }
+ break;
+ case 'l':
+ /* Set alternate log file */
+ lflag++;
+ log_file = optarg;
+ break;
+ case 'r':
+ /* Set realm name */
+ rflag++;
+ strcpy(local_realm, optarg);
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (optind == (argc-1)) {
+ if (kerb_db_set_name(argv[optind]) != 0) {
+ fprintf(stderr, "Could not set alternate database name\n");
+ exit(1);
+ }
+ optind++;
+ }
+
+ if (optind != argc)
+ usage();
+
+ printf("Kerberos server starting\n");
+
+ if ((!nflag) && (max_age != -1))
+ printf("\tMaximum database age: %ld seconds\n", max_age);
+ if (pause_int != -1)
+ printf("\tSleep for %ld seconds on error\n", pause_int);
+ else
+ printf("\tSleep forever on error\n");
+ if (mflag)
+ printf("\tMaster key will be entered manually\n");
+
+ printf("\tLog file is %s\n", lflag ? log_file : KRBLOG);
+
+ if (lflag)
+ kset_logfile(log_file);
+
+ /* find our hostname, and use it as the instance */
+ if (gethostname(k_instance, INST_SZ)) {
+ fprintf(stderr, "%s: gethostname error\n", progname);
+ exit(1);
+ }
+
+ if ((sp = getservbyname("kerberos", "udp")) == 0) {
+ fprintf(stderr, "%s: udp/kerberos unknown service\n", progname);
+ exit(1);
+ }
+ s_in.sin_port = sp->s_port;
+
+ if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ fprintf(stderr, "%s: Can't open socket\n", progname);
+ exit(1);
+ }
+ if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+ fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname);
+
+ if (bind(f, (struct sockaddr *) &s_in, S_AD_SZ) < 0) {
+ fprintf(stderr, "%s: Can't bind socket\n", progname);
+ exit(1);
+ }
+ /* do all the database and cache inits */
+ if ((n = kerb_init())) {
+ if (mflag) {
+ printf("Kerberos db and cache init ");
+ printf("failed = %d ...exiting\n", n);
+ exit(-1);
+ } else {
+ klog(L_KRB_PERR,
+ "Kerberos db and cache init failed = %d ...exiting", n);
+ hang();
+ }
+ }
+
+ /* Make sure database isn't stale */
+ check_db_age();
+
+ /* setup master key */
+ if (kdb_get_master_key (mflag, master_key, master_key_schedule) != 0) {
+ klog (L_KRB_PERR, "kerberos: couldn't get master key.\n");
+ exit (-1);
+ }
+ kerror = kdb_verify_master_key (master_key, master_key_schedule, stdout);
+ if (kerror < 0) {
+ klog (L_KRB_PERR, "Can't verify master key.");
+ bzero (master_key, sizeof (master_key));
+ bzero (master_key_schedule, sizeof (master_key_schedule));
+ exit (-1);
+ }
+
+ master_key_version = (u_char) kerror;
+
+ fprintf(stdout, "\nCurrent Kerberos master key version is %d\n",
+ master_key_version);
+
+ if (!rflag) {
+ /* Look up our local realm */
+ krb_get_lrealm(local_realm, 1);
+ }
+ fprintf(stdout, "Local realm: %s\n", local_realm);
+ fflush(stdout);
+
+ if (set_tgtkey(local_realm)) {
+ /* Ticket granting service unknown */
+ klog(L_KRB_PERR, "Ticket granting ticket service unknown");
+ fprintf(stderr, "Ticket granting ticket service unknown\n");
+ exit(1);
+ }
+ if (mflag) {
+ if ((child = fork()) != 0) {
+ printf("Kerberos started, PID=%d\n", child);
+ exit(0);
+ }
+ setup_disc();
+ }
+ /* receive loop */
+ for (;;) {
+ fromlen = S_AD_SZ;
+ n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, (struct sockaddr *) &from,
+ &fromlen);
+ if (n > 0) {
+ pkt->length = n;
+ pkt->mbz = 0; /* force zeros to catch runaway strings */
+ /* see what is left in the input queue */
+ ioctl(f, FIONREAD, &q_bytes);
+ gettimeofday(&kerb_time, NULL);
+ q_n++;
+ max_q_n = max(max_q_n, q_n);
+ n_packets++;
+ klog(L_NET_INFO,
+ "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d",
+ q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0);
+ max_q_bytes = max(max_q_bytes, q_bytes);
+ if (!q_bytes)
+ q_n = 0; /* reset consecutive packets */
+ kerberos(&from, pkt);
+ } else
+ klog(L_NET_ERR,
+ "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0);
+ }
+}
+
+void
+kerberos(client, pkt)
+ struct sockaddr_in *client;
+ KTEXT pkt;
+{
+ static KTEXT_ST rpkt_st;
+ KTEXT rpkt = &rpkt_st;
+ static KTEXT_ST ciph_st;
+ KTEXT ciph = &ciph_st;
+ static KTEXT_ST tk_st;
+ KTEXT tk = &tk_st;
+ static KTEXT_ST auth_st;
+ KTEXT auth = &auth_st;
+ AUTH_DAT ad_st;
+ AUTH_DAT *ad = &ad_st;
+
+
+ static struct in_addr client_host;
+ static int msg_byte_order;
+ static int swap_bytes;
+ static u_char k_flags;
+ u_long lifetime;
+ int i;
+ C_Block key;
+ Key_schedule key_s;
+ char *ptr;
+
+
+
+ ciph->length = 0;
+
+ client_host = client->sin_addr;
+
+ /* eval macros and correct the byte order and alignment as needed */
+ req_version = pkt_version(pkt); /* 1 byte, version */
+ req_msg_type = pkt_msg_type(pkt); /* 1 byte, Kerberos msg type */
+
+ req_act_vno = req_version;
+
+ /* check packet version */
+ if (req_version != KRB_PROT_VERSION) {
+ lt = klog(L_KRB_PERR,
+ "KRB prot version mismatch: KRB =%d request = %d",
+ KRB_PROT_VERSION, req_version, 0);
+ /* send an error reply */
+ kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
+ return;
+ }
+ msg_byte_order = req_msg_type & 1;
+
+ swap_bytes = 0;
+ if (msg_byte_order != HOST_BYTE_ORDER) {
+ swap_bytes++;
+ }
+ klog(L_KRB_PINFO,
+ "Prot version: %d, Byte order: %d, Message type: %d",
+ req_version, msg_byte_order, req_msg_type);
+
+ switch (req_msg_type & ~1) {
+
+ case AUTH_MSG_KDC_REQUEST:
+ {
+ u_long req_life; /* Requested liftime */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ n_auth_req++;
+ tk->length = 0;
+ k_flags = 0; /* various kerberos flags */
+
+
+ /* set up and correct for byte order and alignment */
+ req_name_ptr = (char *) pkt_a_name(pkt);
+ req_inst_ptr = (char *) pkt_a_inst(pkt);
+ req_realm_ptr = (char *) pkt_a_realm(pkt);
+ bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws));
+ /* time has to be diddled */
+ if (swap_bytes) {
+ swap_u_long(req_time_ws);
+ }
+ ptr = (char *) pkt_time_ws(pkt) + 4;
+
+ req_life = (u_long) (*ptr++);
+
+ service = ptr;
+ instance = ptr + strlen(service) + 1;
+
+ rpkt = &rpkt_st;
+ klog(L_INI_REQ,
+ "Initial ticket request Host: %s User: \"%s\" \"%s\"",
+ inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
+
+ if ((i = check_princ(req_name_ptr, req_inst_ptr, 0,
+ &a_name_data))) {
+ kerb_err_reply(client, pkt, i, lt);
+ return;
+ }
+ tk->length = 0; /* init */
+ if (strcmp(service, "krbtgt"))
+ klog(L_NTGT_INTK,
+ "INITIAL request from %s.%s for %s.%s",
+ req_name_ptr, req_inst_ptr, service, instance, 0);
+ /* this does all the checking */
+ if ((i = check_princ(service, instance, lifetime,
+ &s_name_data))) {
+ kerb_err_reply(client, pkt, i, lt);
+ return;
+ }
+ /* Bound requested lifetime with service and user */
+ lifetime = min(req_life, ((u_long) s_name_data.max_life));
+ lifetime = min(lifetime, ((u_long) a_name_data.max_life));
+
+#ifdef NOENCRYPTION
+ bzero(session_key, sizeof(C_Block));
+#else
+ random_key(session_key);
+#endif
+ /* unseal server's key from master key */
+ bcopy(&s_name_data.key_low, key, 4);
+ bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ /* construct and seal the ticket */
+ krb_create_ticket(tk, k_flags, a_name_data.name,
+ a_name_data.instance, local_realm,
+ client_host.s_addr, session_key, lifetime, kerb_time.tv_sec,
+ s_name_data.name, s_name_data.instance, key);
+ bzero(key, sizeof(key));
+ bzero(key_s, sizeof(key_s));
+
+ /*
+ * get the user's key, unseal it from the server's key, and
+ * use it to seal the cipher
+ */
+
+ /* a_name_data.key_low a_name_data.key_high */
+ bcopy(&a_name_data.key_low, key, 4);
+ bcopy(&a_name_data.key_high, ((long *) key) + 1, 4);
+
+ /* unseal the a_name key from the master key */
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+
+ create_ciph(ciph, session_key, s_name_data.name,
+ s_name_data.instance, local_realm, lifetime,
+ s_name_data.key_version, tk, kerb_time.tv_sec, key);
+
+ /* clear session key */
+ bzero(session_key, sizeof(session_key));
+
+ bzero(key, sizeof(key));
+
+
+
+ /* always send a reply packet */
+ rpkt = create_auth_reply(req_name_ptr, req_inst_ptr,
+ req_realm_ptr, req_time_ws, 0, a_name_data.exp_date,
+ a_name_data.key_version, ciph);
+ sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+ bzero(&a_name_data, sizeof(a_name_data));
+ bzero(&s_name_data, sizeof(s_name_data));
+ break;
+ }
+ case AUTH_MSG_APPL_REQUEST:
+ {
+ u_long time_ws; /* Workstation time */
+ u_long req_life; /* Requested liftime */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ int kerno; /* Kerberos error number */
+ char tktrlm[REALM_SZ];
+
+ n_appl_req++;
+ tk->length = 0;
+ k_flags = 0; /* various kerberos flags */
+
+ auth->length = 4 + strlen(pkt->dat + 3);
+ auth->length += (int) *(pkt->dat + auth->length) +
+ (int) *(pkt->dat + auth->length + 1) + 2;
+
+ bcopy(pkt->dat, auth->dat, auth->length);
+
+ strncpy(tktrlm, auth->dat + 3, REALM_SZ);
+ if (set_tgtkey(tktrlm)) {
+ lt = klog(L_ERR_UNK,
+ "FAILED realm %s unknown. Host: %s ",
+ tktrlm, inet_ntoa(client_host));
+ kerb_err_reply(client, pkt, kerno, lt);
+ return;
+ }
+ kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr,
+ ad, 0);
+
+ if (kerno) {
+ klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s",
+ inet_ntoa(client_host), krb_err_txt[kerno]);
+ kerb_err_reply(client, pkt, kerno, "krb_rd_req failed");
+ return;
+ }
+ ptr = (char *) pkt->dat + auth->length;
+
+ bcopy(ptr, &time_ws, 4);
+ ptr += 4;
+
+ req_life = (u_long) (*ptr++);
+
+ service = ptr;
+ instance = ptr + strlen(service) + 1;
+
+ klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s",
+ ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host),
+ service, instance, 0);
+
+ if (strcmp(ad->prealm, tktrlm)) {
+ kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+ "Can't hop realms");
+ return;
+ }
+ if (!strcmp(service, "changepw")) {
+ kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+ "Can't authorize password changed based on TGT");
+ return;
+ }
+ kerno = check_princ(service, instance, req_life,
+ &s_name_data);
+ if (kerno) {
+ kerb_err_reply(client, pkt, kerno, lt);
+ return;
+ }
+ /* Bound requested lifetime with service and user */
+ lifetime = min(req_life,
+ (ad->life - ((kerb_time.tv_sec - ad->time_sec) / 300)));
+ lifetime = min(lifetime, ((u_long) s_name_data.max_life));
+
+ /* unseal server's key from master key */
+ bcopy(&s_name_data.key_low, key, 4);
+ bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ /* construct and seal the ticket */
+
+#ifdef NOENCRYPTION
+ bzero(session_key, sizeof(C_Block));
+#else
+ random_key(session_key);
+#endif
+
+ krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
+ ad->prealm, client_host.s_addr,
+ session_key, lifetime, kerb_time.tv_sec,
+ s_name_data.name, s_name_data.instance,
+ key);
+ bzero(key, sizeof(key));
+ bzero(key_s, sizeof(key_s));
+
+ create_ciph(ciph, session_key, service, instance,
+ local_realm,
+ lifetime, s_name_data.key_version, tk,
+ kerb_time.tv_sec, ad->session);
+
+ /* clear session key */
+ bzero(session_key, sizeof(session_key));
+
+ bzero(ad->session, sizeof(ad->session));
+
+ rpkt = create_auth_reply(ad->pname, ad->pinst,
+ ad->prealm, time_ws,
+ 0, 0, 0, ciph);
+ sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+ bzero(&s_name_data, sizeof(s_name_data));
+ break;
+ }
+
+
+#ifdef notdef_DIE
+ case AUTH_MSG_DIE:
+ {
+ lt = klog(L_DEATH_REQ,
+ "Host: %s User: \"%s\" \"%s\" Kerberos killed",
+ inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
+ exit(0);
+ }
+#endif notdef_DIE
+
+ default:
+ {
+ lt = klog(L_KRB_PERR,
+ "Unknown message type: %d from %s port %u",
+ req_msg_type, inet_ntoa(client_host),
+ ntohs(client->sin_port));
+ break;
+ }
+ }
+}
+
+
+/*
+ * setup_disc
+ *
+ * disconnect all descriptors, remove ourself from the process
+ * group that spawned us.
+ */
+
+void
+setup_disc()
+{
+
+ int s;
+
+ for (s = 0; s < 3; s++) {
+ (void) close(s);
+ }
+
+ (void) open("/dev/null", 0);
+ (void) dup2(0, 1);
+ (void) dup2(0, 2);
+
+ s = open("/dev/tty", 2);
+
+ if (s >= 0) {
+ ioctl(s, TIOCNOTTY, (struct sgttyb *) 0);
+ (void) close(s);
+ }
+ (void) chdir("/tmp");
+}
+
+
+/*
+ * kerb_er_reply creates an error reply packet and sends it to the
+ * client.
+ */
+
+void
+kerb_err_reply(client, pkt, err, string)
+ struct sockaddr_in *client;
+ KTEXT pkt;
+ long err;
+ char *string;
+
+{
+ static KTEXT_ST e_pkt_st;
+ KTEXT e_pkt = &e_pkt_st;
+ static char e_msg[128];
+
+ strcpy(e_msg, "\nKerberos error -- ");
+ strcat(e_msg, string);
+ cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr,
+ req_time_ws, err, e_msg);
+ sendto(f, e_pkt->dat, e_pkt->length, 0, (struct sockaddr *) client,
+ S_AD_SZ);
+
+}
+
+/*
+ * Make sure that database isn't stale.
+ *
+ * Exit if it is; we don't want to tell lies.
+ */
+
+static void check_db_age()
+{
+ long age;
+
+ if (max_age != -1) {
+ /* Requires existance of kerb_get_db_age() */
+ gettimeofday(&kerb_time, 0);
+ age = kerb_get_db_age();
+ if (age == 0) {
+ klog(L_KRB_PERR, "Database currently being updated!");
+ hang();
+ }
+ if ((age + max_age) < kerb_time.tv_sec) {
+ klog(L_KRB_PERR, "Database out of date!");
+ hang();
+ /* NOTREACHED */
+ }
+ }
+}
+
+int
+check_princ(p_name, instance, lifetime, p)
+ char *p_name;
+ char *instance;
+ unsigned lifetime;
+
+ Principal *p;
+{
+ static int n;
+ static int more;
+
+ n = kerb_get_principal(p_name, instance, p, 1, &more);
+ klog(L_ALL_REQ,
+ "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d",
+ p_name, instance, lifetime, n, 0);
+
+ if (n < 0) {
+ lt = klog(L_KRB_PERR, "Database unavailable!");
+ hang();
+ }
+
+ /*
+ * if more than one p_name, pick one, randomly create a session key,
+ * compute maximum lifetime, lookup authorizations if applicable,
+ * and stuff into cipher.
+ */
+ if (n == 0) {
+ /* service unknown, log error, skip to next request */
+ lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name,
+ instance, 0);
+ return KERB_ERR_PRINCIPAL_UNKNOWN;
+ }
+ if (more) {
+ /* not unique, log error */
+ lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"",
+ p_name, instance, 0);
+ return KERB_ERR_PRINCIPAL_NOT_UNIQUE;
+ }
+ /* If the user's key is null, we want to return an error */
+ if ((p->key_low == 0) && (p->key_high == 0)) {
+ /* User has a null key */
+ lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name,
+ instance, 0);
+ return KERB_ERR_NULL_KEY;
+ }
+ if (master_key_version != p->kdc_key_ver) {
+ /* log error reply */
+ lt = klog(L_ERR_MKV,
+ "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d",
+ master_key_version, p->name, p->instance, p->kdc_key_ver,
+ 0);
+ return KERB_ERR_NAME_MAST_KEY_VER;
+ }
+ /* make sure the service hasn't expired */
+ if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) {
+ /* service did expire, log it */
+ lt = klog(L_ERR_SEXP,
+ "EXPIRED \"%s\" \"%s\" %s", p->name, p->instance,
+ stime(&(p->exp_date)), 0);
+ return KERB_ERR_NAME_EXP;
+ }
+ /* ok is zero */
+ return 0;
+}
+
+
+/* Set the key for krb_rd_req so we can check tgt */
+int
+set_tgtkey(r)
+ char *r; /* Realm for desired key */
+{
+ int n;
+ static char lastrealm[REALM_SZ];
+ Principal p_st;
+ Principal *p = &p_st;
+ C_Block key;
+
+ if (!strcmp(lastrealm, r))
+ return (KSUCCESS);
+
+ log("Getting key for %s", r);
+
+ n = kerb_get_principal("krbtgt", r, p, 1, &more);
+ if (n == 0)
+ return (KFAILURE);
+
+ /* unseal tgt key from master key */
+ bcopy(&p->key_low, key, 4);
+ bcopy(&p->key_high, ((long *) key) + 1, 4);
+ kdb_encrypt_key(key, key, master_key,
+ master_key_schedule, DECRYPT);
+ krb_set_key(key, 0);
+ strcpy(lastrealm, r);
+ return (KSUCCESS);
+}
+
+static void
+hang()
+{
+ if (pause_int == -1) {
+ klog(L_KRB_PERR, "Kerberos will pause so as not to loop init");
+ for (;;)
+ pause();
+ } else {
+ char buf[256];
+ sprintf(buf, "Kerberos will wait %ld seconds before dying so as not to loop init", pause_int);
+ klog(L_KRB_PERR, buf);
+ sleep(pause_int);
+ klog(L_KRB_PERR, "Do svedania....\n");
+ exit(1);
+ }
+}
diff --git a/eBones/usr.sbin/kprop/Makefile b/eBones/usr.sbin/kprop/Makefile
new file mode 100644
index 0000000000000..d6063a6b08379
--- /dev/null
+++ b/eBones/usr.sbin/kprop/Makefile
@@ -0,0 +1,9 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id: Makefile,v 1.4 1995/09/13 17:24:29 markm Exp $
+
+PROG= kprop
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -lkrb -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kprop/kprop.c b/eBones/usr.sbin/kprop/kprop.c
new file mode 100644
index 0000000000000..23bb893d2703a
--- /dev/null
+++ b/eBones/usr.sbin/kprop/kprop.c
@@ -0,0 +1,637 @@
+/*
+ *
+ * Copyright 1987 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information,
+ * please see the file <mit-copyright.h>.
+ *
+ * $Revision: 1.1.1.1 $
+ * $Date: 1995/08/03 07:36:18 $
+ * $State: Exp $
+ * $Source: /usr/cvs/src/eBones/kprop/kprop.c,v $
+ * $Author: mark $
+ * $Locker: $
+ *
+ * $Log: kprop.c,v $
+ * Revision 1.1.1.1 1995/08/03 07:36:18 mark
+ * Import an updated revision of the MIT kprop program for distributing
+ * kerberos databases to slave servers.
+ *
+ * NOTE: This method was abandoned by MIT long ago, this code is close to
+ * garbage, but it is slightly more secure than using rdist.
+ * There is no documentation available on how to use it, and
+ * it should -not- be built by default.
+ *
+ * Obtained from: MIT Project Athena
+ *
+ * Revision 1.1.1.1 1995/08/02 22:11:44 pst
+ * Import an updated revision of the MIT kprop program for distributing
+ * kerberos databases to slave servers.
+ *
+ * NOTE: This method was abandoned by MIT long ago, this code is close to
+ * garbage, but it is slightly more secure than using rdist.
+ * There is no documentation available on how to use it, and
+ * it should -not- be built by default.
+ *
+ * Obtained from: MIT Project Athena
+ *
+ * Revision 4.7 92/11/10 23:01:06 tytso
+ * Removed incompatible #include
+ *
+ * Revision 4.6 91/02/28 22:49:34 probe
+ * Fixed header file inclusion
+ *
+ * Revision 4.5 90/03/20 15:37:57 jon
+ * Stop kpropd port number from being bashed (static buffers)
+ * Programmer: jtkohl
+ * Auditor: jon
+ *
+ * Revision 4.4 90/01/02 13:42:40 jtkohl
+ * add back in accidentally deleted $ in rcsid string
+ *
+ * Revision 4.3 89/12/30 21:22:27 qjb
+ * Added #define MAXHOSTNAMELEN if not already defined for the benifit
+ * of Unixes that don't have this variable in sys/param.h.
+ *
+ * Revision 4.2 89/03/23 10:23:43 jtkohl
+ * fix misuse of mkstemp to use mktemp
+ * NOENCRYPTION changes
+ *
+ * Revision 4.1 89/01/24 20:35:17 root
+ * name change
+ *
+ * Revision 4.0 89/01/24 18:44:38 wesommer
+ * Original version; programmer: wesommer
+ * auditor: jon.
+ *
+ * Revision 4.4 88/01/08 18:05:21 jon
+ * formating changes and rcs header info
+ *
+ *
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_kprop_c[] =
+"$Id: kprop.c,v 1.1.1.1 1995/08/03 07:36:18 mark Exp $";
+#endif lint
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <netdb.h>
+#include <krb.h>
+#include <des.h>
+
+#include "kprop.h"
+
+/* for those broken Unixes without this defined... should be in sys/param.h */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+static char kprop_version[KPROP_PROT_VERSION_LEN] = KPROP_PROT_VERSION;
+
+int debug = 0;
+
+char my_realm[REALM_SZ];
+int princ_data_size = 3 * sizeof(long) + 3 * sizeof(unsigned char);
+short transfer_mode, net_transfer_mode;
+int force_flag;
+static char ok[] = ".dump_ok";
+
+extern char *krb_get_phost(char *);
+
+struct slave_host {
+ u_long net_addr;
+ char *name;
+ char *instance;
+ char *realm;
+ int not_time_yet;
+ int succeeded;
+ struct slave_host *next;
+};
+
+void Death(char *s);
+int get_slaves(struct slave_host **psl, char *file, time_t ok_mtime);
+int prop_to_slaves(struct slave_host *sl, int fd, char *fslv);
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int fd, i;
+ char *floc, *floc_ok;
+ char *fslv;
+ struct stat stbuf, stbuf_ok;
+ long l_init, l_final;
+ char *pc;
+ int l_diff;
+ static struct slave_host *slave_host_list = NULL;
+ struct slave_host *sh;
+
+ transfer_mode = KPROP_TRANSFER_PRIVATE;
+
+ time(&l_init);
+ pc = ctime(&l_init);
+ pc[strlen(pc) - 1] = '\0';
+ printf("\nStart slave propagation: %s\n", pc);
+
+ floc = (char *) NULL;
+ fslv = (char *) NULL;
+
+ if (krb_get_lrealm(my_realm,1) != KSUCCESS)
+ Death ("Getting my kerberos realm. Check krb.conf");
+
+ for (i = 1; i < argc; i++)
+ switch (argv[i][0]) {
+ case '-':
+ if (strcmp (argv[i], "-private") == 0)
+ transfer_mode = KPROP_TRANSFER_PRIVATE;
+#ifdef not_safe_yet
+ else if (strcmp (argv[i], "-safe") == 0)
+ transfer_mode = KPROP_TRANSFER_SAFE;
+ else if (strcmp (argv[i], "-clear") == 0)
+ transfer_mode = KPROP_TRANSFER_CLEAR;
+#endif
+ else if (strcmp (argv[i], "-realm") == 0) {
+ i++;
+ if (i < argc)
+ strcpy(my_realm, argv[i]);
+ else
+ goto usage;
+ } else if (strcmp (argv[i], "-force") == 0)
+ force_flag++;
+ else {
+ fprintf (stderr, "kprop: unknown control argument %s.\n",
+ argv[i]);
+ exit (1);
+ }
+ break;
+ default:
+ /* positional arguments are marginal at best ... */
+ if (floc == (char *) NULL)
+ floc = argv[i];
+ else {
+ if (fslv == (char *) NULL)
+ fslv = argv[i];
+ else {
+ usage:
+ /* already got floc and fslv, what is this? */
+ fprintf(stderr,
+ "\nUsage: kprop [-force] [-realm realm] [-private|-safe|-clear] data_file slaves_file\n\n");
+ exit(1);
+ }
+ }
+ }
+ if ((floc == (char *)NULL) || (fslv == (char *)NULL))
+ goto usage;
+
+ if ((floc_ok = (char *) malloc(strlen(floc) + strlen(ok) + 1))
+ == NULL) {
+ Death(floc);
+ }
+ strcat(strcpy(floc_ok, floc), ok);
+
+ if ((fd = open(floc, O_RDONLY)) < 0) {
+ Death(floc);
+ }
+ if (flock(fd, LOCK_EX | LOCK_NB)) {
+ Death(floc);
+ }
+ if (stat(floc, &stbuf)) {
+ Death(floc);
+ }
+ if (stat(floc_ok, &stbuf_ok)) {
+ Death(floc_ok);
+ }
+ if (stbuf.st_mtime > stbuf_ok.st_mtime) {
+ fprintf(stderr, "kprop: '%s' more recent than '%s'.\n",
+ floc, floc_ok);
+ exit(1);
+ }
+ if (!get_slaves(&slave_host_list, fslv, stbuf_ok.st_mtime)) {
+ fprintf(stderr,
+ "kprop: can't read slave host file '%s'.\n", fslv);
+ exit(1);
+ }
+#ifdef KPROP_DBG
+ {
+ struct slave_host *sh;
+ int i;
+ fprintf(stderr, "\n\n");
+ fflush(stderr);
+ for (sh = slave_host_list; sh; sh = sh->next) {
+ fprintf(stderr, "slave %d: %s, %s", i++, sh->name,
+ inet_ntoa(sh->net_addr));
+ fflush(stderr);
+ }
+ }
+#endif /* KPROP_DBG */
+
+ if (!prop_to_slaves(slave_host_list, fd, fslv)) {
+ fprintf(stderr,
+ "kprop: propagation failed.\n");
+ exit(1);
+ }
+ if (flock(fd, LOCK_UN)) {
+ Death(floc);
+ }
+ fprintf(stderr, "\n\n");
+ for (sh = slave_host_list; sh; sh = sh->next) {
+ fprintf(stderr, "%s:\t\t%s\n", sh->name,
+ (sh->not_time_yet? "Not time yet" : (sh->succeeded ? "Succeeded" : "FAILED")));
+ }
+
+ time(&l_final);
+ l_diff = l_final - l_init;
+ printf("propagation finished, %d:%02d:%02d elapsed\n",
+ l_diff / 3600, (l_diff % 3600) / 60, l_diff % 60);
+
+ exit(0);
+}
+
+void
+Death(s)
+ char *s;
+{
+ fprintf(stderr, "kprop: ");
+ perror(s);
+ exit(1);
+}
+
+/* The master -> slave protocol looks like this:
+ 1) 8 byte version string
+ 2) 2 bytes of "transfer mode" (net byte order of course)
+ 3) ticket/authentication send by sendauth
+ 4) 4 bytes of "block" length (u_long)
+ 5) data
+
+ 4 and 5 repeat til EOF ...
+*/
+
+int
+prop_to_slaves(sl, fd, fslv)
+ struct slave_host *sl;
+ int fd;
+ char *fslv;
+{
+ char buf[KPROP_BUFSIZ];
+ char obuf[KPROP_BUFSIZ + 64 /* leave room for private msg overhead */ ];
+ struct servent *sp;
+ struct sockaddr_in sin, my_sin;
+ int i, n, s;
+ struct slave_host *cs; /* current slave */
+ char path[256], my_host_name[MAXHOSTNAMELEN], *p_my_host_name;
+ char kprop_service_instance[INST_SZ];
+ char *pc;
+ u_long cksum, get_data_checksum();
+ u_long length, nlength;
+ long kerror;
+ KTEXT_ST ticket;
+ CREDENTIALS cred;
+ MSG_DAT msg_dat;
+ static char tkstring[] = "/tmp/kproptktXXXXXX";
+
+ Key_schedule session_sched;
+
+ (void) mktemp(tkstring);
+ krb_set_tkt_string(tkstring);
+
+ if ((sp = getservbyname("krb_prop", "tcp")) == 0) {
+ fprintf(stderr, "tcp/krb_prop: service unknown.\n");
+ exit(1);
+ }
+
+ bzero(&sin, sizeof sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = sp->s_port;
+
+ strcpy(path, fslv);
+ if ((pc = rindex(path, '/'))) {
+ pc += 1;
+ } else {
+ pc = path;
+ }
+
+ for (i = 0; i < 5; i++) { /* try each slave five times max */
+ for (cs = sl; cs; cs = cs->next) {
+ if (!cs->succeeded) {
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ perror("kprop: socket");
+ exit(1);
+ }
+ bcopy(&cs->net_addr, &sin.sin_addr,
+ sizeof cs->net_addr);
+
+ if (connect(s, (struct sockaddr *) &sin, sizeof sin) < 0) {
+ fprintf(stderr, "%s: ", cs->name);
+ perror("connect");
+ close(s);
+ continue; /*** NEXT SLAVE ***/
+ }
+
+ /* for krb_mk_{priv, safe} */
+ bzero (&my_sin, sizeof my_sin);
+ n = sizeof my_sin;
+ if (getsockname (s, (struct sockaddr *) &my_sin, &n) != 0) {
+ fprintf (stderr, "kprop: can't get socketname.");
+ perror ("getsockname");
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+ if (n != sizeof (my_sin)) {
+ fprintf (stderr, "kprop: can't get socketname. len");
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+
+ /* Get ticket */
+ kerror = krb_mk_req (&ticket, KPROP_SERVICE_NAME,
+ cs->instance, cs->realm, (u_long) 0);
+ /* if ticket has expired try to get a new one, but
+ * first get a TGT ...
+ */
+ if (kerror != MK_AP_OK) {
+ if (gethostname (my_host_name, sizeof(my_host_name)) != 0) {
+ fprintf (stderr, "%s:", cs->name);
+ perror ("getting my hostname");
+ close (s);
+ break; /* next one can't work either! */
+ }
+ /* get canonical kerberos service instance name */
+ p_my_host_name = krb_get_phost (my_host_name);
+ /* copy it to make sure gethostbyname static doesn't
+ * screw us. */
+ strcpy (kprop_service_instance, p_my_host_name);
+ kerror = krb_get_svc_in_tkt (KPROP_SERVICE_NAME,
+#if 0
+ kprop_service_instance,
+#else
+ KRB_MASTER,
+#endif
+ my_realm,
+ TGT_SERVICE_NAME,
+ my_realm,
+ 96,
+ KPROP_SRVTAB);
+ if (kerror != INTK_OK) {
+ fprintf (stderr,
+ "%s: %s. While getting initial ticket\n",
+ cs->name, krb_err_txt[kerror]);
+ close (s);
+ goto punt;
+ }
+ kerror = krb_mk_req (&ticket, KPROP_SERVICE_NAME,
+ cs->instance, cs->realm, (u_long) 0);
+ }
+ if (kerror != MK_AP_OK) {
+ fprintf (stderr, "%s: %s. Calling krb_mk_req.",
+ cs->name, krb_err_txt[kerror]);
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+
+ if (write(s, kprop_version, sizeof(kprop_version))
+ != sizeof(kprop_version)) {
+ fprintf (stderr, "%s: ", cs->name);
+ perror ("write (version) error");
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+
+ net_transfer_mode = htons (transfer_mode);
+ if (write(s, &net_transfer_mode, sizeof(net_transfer_mode))
+ != sizeof(net_transfer_mode)) {
+ fprintf (stderr, "%s: ", cs->name);
+ perror ("write (transfer_mode) error");
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+
+ kerror = krb_get_cred (KPROP_SERVICE_NAME, cs->instance,
+ cs->realm, &cred);
+ if (kerror != KSUCCESS) {
+ fprintf (stderr, "%s: %s. Getting session key.",
+ cs->name, krb_err_txt[kerror]);
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+#ifdef NOENCRYPTION
+ bzero((char *)session_sched, sizeof(session_sched));
+#else
+ if (key_sched ((C_Block *)cred.session, session_sched)) {
+ fprintf (stderr, "%s: can't make key schedule.",
+ cs->name);
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+#endif
+ /* SAFE (quad_cksum) and CLEAR are just not good enough */
+ cksum = 0;
+#ifdef not_working_yet
+ if (transfer_mode != KPROP_TRANSFER_PRIVATE) {
+ cksum = get_data_checksum(fd, session_sched);
+ lseek(fd, 0L, 0);
+ }
+ else
+#endif
+ {
+ struct stat st;
+ fstat (fd, &st);
+ cksum = st.st_size;
+ }
+ kerror = krb_sendauth(KOPT_DO_MUTUAL,
+ s,
+ &ticket,
+ KPROP_SERVICE_NAME,
+ cs->instance,
+ cs->realm,
+ cksum,
+ &msg_dat,
+ &cred,
+ session_sched,
+ &my_sin,
+ &sin,
+ KPROP_PROT_VERSION);
+ if (kerror != KSUCCESS) {
+ fprintf (stderr, "%s: %s. Calling krb_sendauth.",
+ cs->name, krb_err_txt[kerror]);
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+
+ while ((n = read(fd, buf, sizeof buf))) {
+ if (n < 0) {
+ perror("input file read error");
+ exit(1);
+ }
+ switch (transfer_mode) {
+ case KPROP_TRANSFER_PRIVATE:
+ case KPROP_TRANSFER_SAFE:
+ if (transfer_mode == KPROP_TRANSFER_PRIVATE)
+ length = krb_mk_priv (buf, obuf, n,
+ session_sched, cred.session,
+ &my_sin, &sin);
+ else
+ length = krb_mk_safe (buf, obuf, n,
+ (C_Block *)cred.session,
+ &my_sin, &sin);
+ if (length == -1) {
+ fprintf (stderr, "%s: %s failed.",
+ cs->name,
+ (transfer_mode == KPROP_TRANSFER_PRIVATE)
+ ? "krb_rd_priv" : "krb_rd_safe");
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+ nlength = htonl(length);
+ if (write(s, &nlength, sizeof nlength)
+ != sizeof nlength) {
+ fprintf (stderr, "%s: ", cs->name);
+ perror ("write error");
+ close (s);
+ continue; /*** NEXT SLAVE ***/
+ }
+ if (write(s, obuf, length) != length) {
+ fprintf(stderr, "%s: ", cs->name);
+ perror("write error");
+ close(s);
+ continue; /*** NEXT SLAVE ***/
+ }
+ break;
+ case KPROP_TRANSFER_CLEAR:
+ if (write(s, buf, n) != n) {
+ fprintf(stderr, "%s: ", cs->name);
+ perror("write error");
+ close(s);
+ continue; /*** NEXT SLAVE ***/
+ }
+ break;
+ }
+ }
+ close(s);
+ cs->succeeded = 1;
+ fprintf(stderr, "%s: success.\n", cs->name);
+ strcat(strcpy(pc, cs->name), "-last-prop");
+ close(creat(path, 0600));
+ }
+ }
+ }
+punt:
+
+ dest_tkt();
+ for (cs = sl; cs; cs = cs->next) {
+ if (!cs->succeeded)
+ return (0); /* didn't get this slave */
+ }
+ return (1);
+}
+
+int
+get_slaves(psl, file, ok_mtime)
+ struct slave_host **psl;
+ char *file;
+ time_t ok_mtime;
+{
+ FILE *fin;
+ char namebuf[128], *inst;
+ char *pc;
+ struct hostent *host;
+ struct slave_host **th;
+ char path[256];
+ char *ppath;
+ struct stat stbuf;
+
+ if ((fin = fopen(file, "r")) == NULL) {
+ fprintf(stderr, "Can't open slave host file, '%s'.\n", file);
+ exit(-1);
+ }
+ strcpy(path, file);
+ if ((ppath = rindex(path, '/'))) {
+ ppath += 1;
+ } else {
+ ppath = path;
+ }
+ for (th = psl; fgets(namebuf, sizeof namebuf, fin); th = &(*th)->next) {
+ if ((pc = index(namebuf, '\n'))) {
+ *pc = '\0';
+ } else {
+ fprintf(stderr, "Host name too long (>= %d chars) in '%s'.\n",
+ sizeof namebuf, file);
+ exit(-1);
+ }
+ host = gethostbyname(namebuf);
+ if (host == NULL) {
+ fprintf(stderr, "Unknown host '%s' in '%s'.\n", namebuf, file);
+ exit(-1);
+ }
+ (*th) = (struct slave_host *) malloc(sizeof(struct slave_host));
+ if (!*th) {
+ fprintf(stderr, "No memory reading host list from '%s'.\n",
+ file);
+ exit(-1);
+ }
+ (*th)->name = malloc(strlen(namebuf) + 1);
+ if (!(*th)->name) {
+ fprintf(stderr, "No memory reading host list from '%s'.\n",
+ file);
+ exit(-1);
+ }
+ /* get kerberos cannonical instance name */
+ strcpy((*th)->name, namebuf);
+ inst = krb_get_phost ((*th)->name);
+ (*th)->instance = malloc(strlen(inst) + 1);
+ if (!(*th)->instance) {
+ fprintf(stderr, "No memory reading host list from '%s'.\n",
+ file);
+ exit(-1);
+ }
+ strcpy((*th)->instance, inst);
+ /* what a concept, slave servers in different realms! */
+ (*th)->realm = my_realm;
+ (*th)->net_addr = *(u_long *) host->h_addr;
+ (*th)->succeeded = 0;
+ (*th)->next = NULL;
+ strcat(strcpy(ppath, (*th)->name), "-last-prop");
+ if (!force_flag && !stat(path, &stbuf) && stbuf.st_mtime > ok_mtime) {
+ (*th)->not_time_yet = 1;
+ (*th)->succeeded = 1; /* no change since last success */
+ }
+ }
+ fclose(fin);
+ return (1);
+}
+
+#ifdef doesnt_work_yet
+u_long get_data_checksum(fd, key_sched)
+ int fd;
+ Key_schedule key_sched;
+{
+ unsigned long cksum = 0;
+ unsigned long cbc_cksum();
+ int n;
+ char buf[BUFSIZ];
+ long obuf[2];
+
+ while (n = read(fd, buf, sizeof buf)) {
+ if (n < 0) {
+ fprintf(stderr, "Input data file read error: ");
+ perror("read");
+ exit(1);
+ }
+ cksum = cbc_cksum(buf, obuf, n, key_sched, key_sched);
+ }
+ return cksum;
+}
+#endif
diff --git a/eBones/usr.sbin/kprop/kprop.h b/eBones/usr.sbin/kprop/kprop.h
new file mode 100644
index 0000000000000..5197276fc0d76
--- /dev/null
+++ b/eBones/usr.sbin/kprop/kprop.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1987 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information,
+ * please see the file <mit-copyright.h>.
+ *
+ * $Revision: 1.1.1.1 $
+ * $Date: 1995/08/03 07:36:18 $
+ * $State: Exp $
+ * $Source: /usr/cvs/src/eBones/kprop/kprop.h,v $
+ * $Author: mark $
+ * $Locker: $
+ *
+ * $Log: kprop.h,v $
+ * Revision 1.1.1.1 1995/08/03 07:36:18 mark
+ * Import an updated revision of the MIT kprop program for distributing
+ * kerberos databases to slave servers.
+ *
+ * NOTE: This method was abandoned by MIT long ago, this code is close to
+ * garbage, but it is slightly more secure than using rdist.
+ * There is no documentation available on how to use it, and
+ * it should -not- be built by default.
+ *
+ * Obtained from: MIT Project Athena
+ *
+ * Revision 1.1.1.1 1995/08/02 22:11:44 pst
+ * Import an updated revision of the MIT kprop program for distributing
+ * kerberos databases to slave servers.
+ *
+ * NOTE: This method was abandoned by MIT long ago, this code is close to
+ * garbage, but it is slightly more secure than using rdist.
+ * There is no documentation available on how to use it, and
+ * it should -not- be built by default.
+ *
+ * Obtained from: MIT Project Athena
+ *
+ * Revision 4.1 92/10/23 15:45:13 tytso
+ * Change the location of KPROP_KDBUTIL to be /kerberos/bin/kdb_util.
+ *
+ * Revision 4.0 89/01/24 18:44:46 wesommer
+ * Original version; programmer: wesommer
+ * auditor: jon
+ *
+ */
+
+#define KPROP_SERVICE_NAME "rcmd"
+#define KPROP_SRVTAB "/etc/kerberosIV/srvtab"
+#define TGT_SERVICE_NAME "krbtgt"
+#define KPROP_PROT_VERSION_LEN 8
+#define KPROP_PROT_VERSION "kprop01"
+#define KPROP_TRANSFER_PRIVATE 1
+#define KPROP_TRANSFER_SAFE 2
+#define KPROP_TRANSFER_CLEAR 3
+#define KPROP_BUFSIZ 32768
+#define KPROP_KDB_UTIL "/usr/sbin/kdb_util"
diff --git a/eBones/usr.sbin/ksrvutil/Makefile b/eBones/usr.sbin/ksrvutil/Makefile
new file mode 100644
index 0000000000000..199cf48b02db1
--- /dev/null
+++ b/eBones/usr.sbin/ksrvutil/Makefile
@@ -0,0 +1,10 @@
+# $Id: Makefile,v 1.4 1995/09/13 17:24:34 markm Exp $
+
+PROG= ksrvutil
+SRCS= ksrvutil.c
+CFLAGS+= -I${.CURDIR}/../../lib/libkadm
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD+= -lkadm -lkrb -ldes -lcom_err
+MAN8= ksrvutil.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/ksrvutil/ksrvutil.c b/eBones/usr.sbin/ksrvutil/ksrvutil.c
new file mode 100644
index 0000000000000..1062ea5cc9380
--- /dev/null
+++ b/eBones/usr.sbin/ksrvutil/ksrvutil.c
@@ -0,0 +1,582 @@
+/*
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * Copyright.MIT.
+ *
+ * list and update contents of srvtab files
+ */
+
+#if 0
+#ifndef lint
+static char rcsid_ksrvutil_c[] =
+"BonesHeader: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/ksrvutil.c,v 4.1 89/09/26 09:33:49 jtkohl Exp ";
+static const char rcsid[] =
+ "$Id: ksrvutil.c,v 1.1 1995/07/18 16:40:11 mark Exp $";
+#endif lint
+#endif
+
+/*
+ * ksrvutil
+ * list and update the contents of srvtab files
+ */
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <kadm.h>
+#include <err.h>
+#include <com_err.h>
+
+#ifdef NOENCRYPTION
+#define read_long_pw_string placebo_read_pw_string
+#else /* NOENCRYPTION */
+#define read_long_pw_string des_read_pw_string
+#endif /* NOENCRYPTION */
+int read_long_pw_string();
+
+#define SRVTAB_MODE 0600 /* rw------- */
+#define PAD " "
+#define VNO_HEADER "Version"
+#define VNO_FORMAT "%4d "
+#define KEY_HEADER " Key " /* 17 characters long */
+#define PRINC_HEADER " Principal\n"
+#define PRINC_FORMAT "%s"
+
+void usage(void);
+void leave(char *str, int x);
+void get_key_from_password(des_cblock key);
+void print_name(char *name, char *inst, char *realm);
+void print_key(des_cblock key);
+unsigned short get_mode(char *filename);
+int get_svc_new_key(des_cblock new_key, char *sname, char *sinst,
+ char *srealm, char *keyfile);
+
+void
+copy_keyfile(progname, keyfile, backup_keyfile)
+ char *progname;
+ char *keyfile;
+ char *backup_keyfile;
+{
+ int keyfile_fd;
+ int backup_keyfile_fd;
+ int keyfile_mode;
+ char buf[BUFSIZ]; /* for copying keyfiles */
+ int rcount; /* for copying keyfiles */
+ int try_again;
+
+ bzero((char *)buf, sizeof(buf));
+
+ do {
+ try_again = FALSE;
+ if ((keyfile_fd = open(keyfile, O_RDONLY, 0)) < 0) {
+ if (errno != ENOENT) {
+ err(1, "unable to read %s", keyfile);
+ }
+ else {
+ try_again = TRUE;
+ if ((keyfile_fd =
+ open(keyfile,
+ O_WRONLY | O_TRUNC | O_CREAT, SRVTAB_MODE)) < 0) {
+ err(1, "unable to create %s", keyfile);
+ }
+ else
+ if (close(keyfile_fd) < 0) {
+ err(1, "failure closing %s", keyfile);
+ }
+ }
+ }
+ } while(try_again);
+
+ keyfile_mode = get_mode(keyfile);
+
+ if ((backup_keyfile_fd =
+ open(backup_keyfile, O_WRONLY | O_TRUNC | O_CREAT,
+ keyfile_mode)) < 0) {
+ err(1, "unable to write %s", backup_keyfile);
+ }
+ do {
+ if ((rcount = read(keyfile_fd, (char *)buf, sizeof(buf))) < 0) {
+ err(1, "error reading %s", keyfile);
+ }
+ if (rcount && (write(backup_keyfile_fd, buf, rcount) != rcount)) {
+ err(1, "error writing %s", backup_keyfile);
+ }
+ } while (rcount);
+ if (close(backup_keyfile_fd) < 0) {
+ err(1, "error closing %s", backup_keyfile);
+ }
+ if (close(keyfile_fd) < 0) {
+ err(1, "error closing %s", keyfile);
+ }
+}
+
+void
+safe_read_stdin(prompt, buf, size)
+ char *prompt;
+ char *buf;
+ int size;
+{
+ printf(prompt);
+ fflush(stdout);
+ bzero(buf, size);
+ if (read(0, buf, size - 1) < 0) {
+ warn("failure reading from stdin");
+ leave((char *)NULL, 1);
+ }
+ fflush(stdin);
+ buf[strlen(buf)-1] = 0;
+}
+
+
+void
+safe_write(progname, filename, fd, buf, len)
+ char *progname;
+ char *filename;
+ int fd;
+ char *buf;
+ int len;
+{
+ if (write(fd, buf, len) != len) {
+ warn("failure writing %s", filename);
+ close(fd);
+ leave("In progress srvtab in this file.", 1);
+ }
+}
+
+int
+yn(string)
+ char *string;
+{
+ char ynbuf[5];
+
+ printf("%s (y,n) [y] ", string);
+ for (;;) {
+ safe_read_stdin("", ynbuf, sizeof(ynbuf));
+
+ if ((ynbuf[0] == 'n') || (ynbuf[0] == 'N'))
+ return(0);
+ else if ((ynbuf[0] == 'y') || (ynbuf[0] == 'Y') || (ynbuf[0] == 0))
+ return(1);
+ else {
+ printf("Please enter 'y' or 'n': ");
+ fflush(stdout);
+ }
+ }
+}
+
+void
+append_srvtab(progname, filename, fd, sname, sinst,
+ srealm, key_vno, key)
+ char *progname;
+ char *filename;
+ int fd;
+ char *sname;
+ char *sinst;
+ char *srealm;
+ unsigned char key_vno;
+ des_cblock key;
+{
+ /* Add one to append null */
+ safe_write(progname, filename, fd, sname, strlen(sname) + 1);
+ safe_write(progname, filename, fd, sinst, strlen(sinst) + 1);
+ safe_write(progname, filename, fd, srealm, strlen(srealm) + 1);
+ safe_write(progname, filename, fd, (char *)&key_vno, 1);
+ safe_write(progname, filename, fd, (char *)key, sizeof(des_cblock));
+ fsync(fd);
+}
+
+unsigned short
+get_mode(filename)
+ char *filename;
+{
+ struct stat statbuf;
+ unsigned short mode;
+
+ bzero((char *)&statbuf, sizeof(statbuf));
+
+ if (stat(filename, &statbuf) < 0)
+ mode = SRVTAB_MODE;
+ else
+ mode = statbuf.st_mode;
+
+ return(mode);
+}
+
+int
+main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ char sname[ANAME_SZ]; /* name of service */
+ char sinst[INST_SZ]; /* instance of service */
+ char srealm[REALM_SZ]; /* realm of service */
+ unsigned char key_vno; /* key version number */
+ int status; /* general purpose error status */
+ des_cblock new_key;
+ des_cblock old_key;
+ char change_tkt[MAXPATHLEN]; /* Ticket to use for key change */
+ char keyfile[MAXPATHLEN]; /* Original keyfile */
+ char work_keyfile[MAXPATHLEN]; /* Working copy of keyfile */
+ char backup_keyfile[MAXPATHLEN]; /* Backup copy of keyfile */
+ unsigned short keyfile_mode; /* Protections on keyfile */
+ int work_keyfile_fd = -1; /* Initialize so that */
+ int backup_keyfile_fd = -1; /* compiler doesn't complain */
+ char local_realm[REALM_SZ]; /* local kerberos realm */
+ int i;
+ int interactive = FALSE;
+ int list = FALSE;
+ int change = FALSE;
+ int add = FALSE;
+ int key = FALSE; /* do we show keys? */
+ int arg_entered = FALSE;
+ int change_this_key = FALSE;
+ char databuf[BUFSIZ];
+ int first_printed = FALSE; /* have we printed the first item? */
+
+ bzero((char *)sname, sizeof(sname));
+ bzero((char *)sinst, sizeof(sinst));
+ bzero((char *)srealm, sizeof(srealm));
+
+ bzero((char *)change_tkt, sizeof(change_tkt));
+ bzero((char *)keyfile, sizeof(keyfile));
+ bzero((char *)work_keyfile, sizeof(work_keyfile));
+ bzero((char *)backup_keyfile, sizeof(backup_keyfile));
+ bzero((char *)local_realm, sizeof(local_realm));
+
+ sprintf(change_tkt, "/tmp/tkt_ksrvutil.%d", getpid());
+ krb_set_tkt_string(change_tkt);
+
+ /* This is used only as a default for adding keys */
+ if (krb_get_lrealm(local_realm, 1) != KSUCCESS)
+ strcpy(local_realm, KRB_REALM);
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-i") == 0)
+ interactive++;
+ else if (strcmp(argv[i], "-k") == 0)
+ key++;
+ else if (strcmp(argv[i], "list") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ list++;
+ }
+ }
+ else if (strcmp(argv[i], "change") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ change++;
+ }
+ }
+ else if (strcmp(argv[i], "add") == 0) {
+ if (arg_entered)
+ usage();
+ else {
+ arg_entered++;
+ add++;
+ }
+ }
+ else if (strcmp(argv[i], "-f") == 0) {
+ if (++i == argc)
+ usage();
+ else
+ strcpy(keyfile, argv[i]);
+ }
+ else
+ usage();
+ }
+
+ if (!arg_entered)
+ usage();
+
+ if (!keyfile[0])
+ strcpy(keyfile, KEYFILE);
+
+ strcpy(work_keyfile, keyfile);
+ strcpy(backup_keyfile, keyfile);
+
+ if (change || add) {
+ strcat(work_keyfile, ".work");
+ strcat(backup_keyfile, ".old");
+
+ copy_keyfile(argv[0], keyfile, backup_keyfile);
+ }
+
+ if (add)
+ copy_keyfile(argv[0], backup_keyfile, work_keyfile);
+
+ keyfile_mode = get_mode(keyfile);
+
+ if (change || list) {
+ if ((backup_keyfile_fd = open(backup_keyfile, O_RDONLY, 0)) < 0) {
+ err(1, "unable to read %s", backup_keyfile);
+ }
+ }
+
+ if (change) {
+ if ((work_keyfile_fd =
+ open(work_keyfile, O_WRONLY | O_CREAT | O_TRUNC,
+ SRVTAB_MODE)) < 0) {
+ err(1, "unable to write %s", work_keyfile);
+ }
+ }
+ else if (add) {
+ if ((work_keyfile_fd =
+ open(work_keyfile, O_APPEND | O_WRONLY, SRVTAB_MODE)) < 0) {
+ err(1, "unable to append to %s", work_keyfile);
+ }
+ }
+
+ if (change || list) {
+ while ((getst(backup_keyfile_fd, sname, SNAME_SZ) > 0) &&
+ (getst(backup_keyfile_fd, sinst, INST_SZ) > 0) &&
+ (getst(backup_keyfile_fd, srealm, REALM_SZ) > 0) &&
+ (read(backup_keyfile_fd, &key_vno, 1) > 0) &&
+ (read(backup_keyfile_fd,(char *)old_key,sizeof(old_key)) > 0)) {
+ if (list) {
+ if (!first_printed) {
+ printf(VNO_HEADER);
+ printf(PAD);
+ if (key) {
+ printf(KEY_HEADER);
+ printf(PAD);
+ }
+ printf(PRINC_HEADER);
+ first_printed = 1;
+ }
+ printf(VNO_FORMAT, key_vno);
+ printf(PAD);
+ if (key) {
+ print_key(old_key);
+ printf(PAD);
+ }
+ print_name(sname, sinst, srealm);
+ printf("\n");
+ }
+ else if (change) {
+ printf("\nPrincipal: ");
+ print_name(sname, sinst, srealm);
+ printf("; version %d\n", key_vno);
+ if (interactive)
+ change_this_key = yn("Change this key?");
+ else if (change)
+ change_this_key = 1;
+ else
+ change_this_key = 0;
+
+ if (change_this_key)
+ printf("Changing to version %d.\n", key_vno + 1);
+ else if (change)
+ printf("Not changing this key.\n");
+
+ if (change_this_key) {
+ /*
+ * Pick a new key and determine whether or not
+ * it is safe to change
+ */
+ if ((status =
+ get_svc_new_key(new_key, sname, sinst,
+ srealm, keyfile)) == KADM_SUCCESS)
+ key_vno++;
+ else {
+ bcopy(old_key, new_key, sizeof(new_key));
+ com_err(argv[0], status, ": key NOT changed");
+ change_this_key = FALSE;
+ }
+ }
+ else
+ bcopy(old_key, new_key, sizeof(new_key));
+ append_srvtab(argv[0], work_keyfile, work_keyfile_fd,
+ sname, sinst, srealm, key_vno, new_key);
+ if (key && change_this_key) {
+ printf("Old key: ");
+ print_key(old_key);
+ printf("; new key: ");
+ print_key(new_key);
+ printf("\n");
+ }
+ if (change_this_key) {
+ if ((status = kadm_change_pw(new_key)) == KADM_SUCCESS) {
+ printf("Key changed.\n");
+ dest_tkt();
+ }
+ else {
+ com_err(argv[0], status,
+ " attempting to change password.");
+ dest_tkt();
+ /* XXX This knows the format of a keyfile */
+ if (lseek(work_keyfile_fd, -9, L_INCR) >= 0) {
+ key_vno--;
+ safe_write(argv[0], work_keyfile,
+ work_keyfile_fd, (char *)&key_vno, 1);
+ safe_write(argv[0], work_keyfile, work_keyfile_fd,
+ (char *)old_key, sizeof(des_cblock));
+ fsync(work_keyfile_fd);
+ fprintf(stderr,"Key NOT changed.\n");
+ }
+ else {
+ warn("unable to revert keyfile");
+ leave("", 1);
+ }
+ }
+ }
+ }
+ bzero((char *)old_key, sizeof(des_cblock));
+ bzero((char *)new_key, sizeof(des_cblock));
+ }
+ }
+ else if (add) {
+ do {
+ do {
+ safe_read_stdin("Name: ", databuf, sizeof(databuf));
+ strncpy(sname, databuf, sizeof(sname) - 1);
+ safe_read_stdin("Instance: ", databuf, sizeof(databuf));
+ strncpy(sinst, databuf, sizeof(sinst) - 1);
+ safe_read_stdin("Realm: ", databuf, sizeof(databuf));
+ strncpy(srealm, databuf, sizeof(srealm) - 1);
+ safe_read_stdin("Version number: ", databuf, sizeof(databuf));
+ key_vno = atoi(databuf);
+ if (!srealm[0])
+ strcpy(srealm, local_realm);
+ printf("New principal: ");
+ print_name(sname, sinst, srealm);
+ printf("; version %d\n", key_vno);
+ } while (!yn("Is this correct?"));
+ get_key_from_password(new_key);
+ if (key) {
+ printf("Key: ");
+ print_key(new_key);
+ printf("\n");
+ }
+ append_srvtab(argv[0], work_keyfile, work_keyfile_fd,
+ sname, sinst, srealm, key_vno, new_key);
+ printf("Key successfully added.\n");
+ } while (yn("Would you like to add another key?"));
+ }
+
+ if (change || list)
+ if (close(backup_keyfile_fd) < 0) {
+ warn("failure closing %s, continuing", backup_keyfile);
+ }
+
+ if (change || add) {
+ if (close(work_keyfile_fd) < 0) {
+ err(1, "failure closing %s", work_keyfile);
+ }
+ if (rename(work_keyfile, keyfile) < 0) {
+ err(1, "failure renaming %s to %s", work_keyfile, keyfile);
+ }
+ chmod(backup_keyfile, keyfile_mode);
+ chmod(keyfile, keyfile_mode);
+ printf("Old keyfile in %s.\n", backup_keyfile);
+ }
+
+ exit(0);
+}
+
+void
+print_key(key)
+ des_cblock key;
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ printf("%02x", key[i]);
+ printf(" ");
+ for (i = 4; i < 8; i++)
+ printf("%02x", key[i]);
+}
+
+void
+print_name(name, inst, realm)
+ char *name;
+ char *inst;
+ char *realm;
+{
+ printf("%s%s%s%s%s", name, inst[0] ? "." : "", inst,
+ realm[0] ? "@" : "", realm);
+}
+
+int
+get_svc_new_key(new_key, sname, sinst, srealm, keyfile)
+ des_cblock new_key;
+ char *sname;
+ char *sinst;
+ char *srealm;
+ char *keyfile;
+{
+ int status = KADM_SUCCESS;
+
+ if (((status = krb_get_svc_in_tkt(sname, sinst, srealm, PWSERV_NAME,
+ KADM_SINST, 1, keyfile)) == KSUCCESS) &&
+ ((status = kadm_init_link("changepw", KRB_MASTER, srealm)) ==
+ KADM_SUCCESS)) {
+#ifdef NOENCRYPTION
+ bzero((char *) new_key, sizeof(des_cblock));
+ new_key[0] = (unsigned char) 1;
+#else /* NOENCRYPTION */
+ des_random_key(new_key);
+#endif /* NOENCRYPTION */
+ return(KADM_SUCCESS);
+ }
+
+ return(status);
+}
+
+void
+get_key_from_password(key)
+ des_cblock key;
+{
+ char password[MAX_KPW_LEN]; /* storage for the password */
+
+ if (read_long_pw_string(password, sizeof(password)-1, "Password: ", 1))
+ leave("Error reading password.", 1);
+
+#ifdef NOENCRYPTION
+ bzero((char *) key, sizeof(des_cblock));
+ key[0] = (unsigned char) 1;
+#else /* NOENCRYPTION */
+ des_string_to_key(password, (des_cblock *)key);
+#endif /* NOENCRYPTION */
+ bzero((char *)password, sizeof(password));
+}
+
+void
+usage()
+{
+ fprintf(stderr, "Usage: ksrvutil [-f keyfile] [-i] [-k] ");
+ fprintf(stderr, "{list | change | add}\n");
+ fprintf(stderr, " -i causes the program to ask for ");
+ fprintf(stderr, "confirmation before changing keys.\n");
+ fprintf(stderr, " -k causes the key to printed for list or ");
+ fprintf(stderr, "change.\n");
+ exit(1);
+}
+
+void
+leave(str,x)
+char *str;
+int x;
+{
+ if (str)
+ fprintf(stderr, "%s\n", str);
+ dest_tkt();
+ exit(x);
+}
diff --git a/eBones/usr.sbin/kstash/Makefile b/eBones/usr.sbin/kstash/Makefile
new file mode 100644
index 0000000000000..cf97f8cedabd4
--- /dev/null
+++ b/eBones/usr.sbin/kstash/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.2 (Berkeley) 3/5/91
+# $Id: Makefile,v 1.5 1995/09/13 17:24:35 markm Exp $
+
+PROG= kstash
+CFLAGS+=-DKERBEROS -DDEBUG
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+MAN8= kstash.8
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kstash/kstash.c b/eBones/usr.sbin/kstash/kstash.c
new file mode 100644
index 0000000000000..ce26a1db34e0a
--- /dev/null
+++ b/eBones/usr.sbin/kstash/kstash.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * from: kstash.c,v 4.0 89/01/23 09:45:43 jtkohl Exp $
+ * $Id: kstash.c,v 1.3 1995/07/18 16:40:16 mark Exp $
+ */
+
+#if 0
+#ifndef lint
+static char rcsid[] =
+"$Id: kstash.c,v 1.3 1995/07/18 16:40:16 mark Exp $";
+#endif lint
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/file.h>
+
+#include <krb.h>
+#include <des.h>
+#include <klog.h>
+#include <prot.h>
+#include <krb_db.h>
+#include <kdc.h>
+
+/* change this later, but krblib_dbm needs it for now */
+char *progname;
+
+static C_Block master_key;
+static Key_schedule master_key_schedule;
+int debug;
+static int kfile;
+static void clear_secrets();
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ long n;
+ if ((n = kerb_init())) {
+ fprintf(stderr, "Kerberos db and cache init failed = %ld\n", n);
+ exit(1);
+ }
+
+ if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "%s: Couldn't read master key.\n", argv[0]);
+ fflush (stderr);
+ clear_secrets();
+ exit (-1);
+ }
+
+ if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
+ clear_secrets();
+ exit (-1);
+ }
+
+ kfile = open(MKEYFILE, O_TRUNC | O_RDWR | O_CREAT, 0600);
+ if (kfile < 0) {
+ clear_secrets();
+ fprintf(stderr, "\n\07\07%s: Unable to open master key file\n",
+ argv[0]);
+ exit(1);
+ }
+ if (write(kfile, (char *) master_key, 8) < 0) {
+ clear_secrets();
+ fprintf(stderr, "\n%s: Write I/O error on master key file\n",
+ argv[0]);
+ exit(1);
+ }
+ (void) close(kfile);
+ clear_secrets();
+ return(0);
+}
+
+static void
+clear_secrets()
+{
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+ bzero(master_key, sizeof(master_key));
+}
diff --git a/eBones/usr.sbin/make_keypair/Makefile b/eBones/usr.sbin/make_keypair/Makefile
new file mode 100644
index 0000000000000..f100cdcb8ddf6
--- /dev/null
+++ b/eBones/usr.sbin/make_keypair/Makefile
@@ -0,0 +1,10 @@
+# @(#)Makefile 8.1 (Berkeley) 6/1/93
+# $id$
+
+PROG= make_keypair
+MAN8= make_keypair.8
+CFLAGS+=-DKERBEROS -I${.CURDIR}/../../usr.bin/register
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -lkdb -lkrb -ldes
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/make_keypair/make_keypair.c b/eBones/usr.sbin/make_keypair/make_keypair.c
new file mode 100644
index 0000000000000..deb67ac60e1fa
--- /dev/null
+++ b/eBones/usr.sbin/make_keypair/make_keypair.c
@@ -0,0 +1,134 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+static char sccsid[] = "@(#)make_keypair.c 8.1 (Berkeley) 6/1/93";
+#endif /* not lint */
+#endif
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <des.h>
+#include <krb.h>
+#include "pathnames.h"
+#include "register_proto.h"
+
+void usage(char *name);
+void make_key(struct in_addr addr);
+
+char * progname;
+
+void
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct hostent *hp;
+ char *addr;
+ int i;
+ struct sockaddr_in sin;
+
+ progname = *argv; /* argv[0] */
+
+ if (argc != 2) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if ((hp = gethostbyname(argv[1])) == NULL) {
+ herror(argv[1]);
+ exit(1);
+ }
+
+ for (i = 0; (addr = hp->h_addr_list[i]); i++) {
+ addr = hp->h_addr_list[i];
+ bcopy(addr, &sin.sin_addr, hp->h_length);
+
+ printf("Making key for host %s (%s)\n",
+ argv[1], inet_ntoa(sin.sin_addr));
+ make_key(sin.sin_addr);
+ }
+ printf("==========\n");
+ printf("One copy of the each key should be put in %s on the\n",
+ SERVER_KEYDIR);
+ printf("Kerberos server machine (mode 600, owner root).\n");
+ printf("Another copy of each key should be put on the named\n");
+ printf("client as %sXXX.XXX.XXX.XXX (same modes as above),\n",
+ CLIENT_KEYFILE);
+ printf("where the X's refer to digits of the host's inet address.\n");
+ (void)fflush(stdout);
+ exit(0);
+}
+
+void
+make_key(addr)
+ struct in_addr addr;
+{
+ struct keyfile_data kfile;
+ char namebuf[255];
+ int fd;
+
+ (void)sprintf(namebuf, "%s%s",
+ CLIENT_KEYFILE,
+ inet_ntoa(addr));
+ fd = open(namebuf, O_WRONLY|O_CREAT, 0600);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ random_key(kfile.kf_key);
+ printf("writing to file -> %s ...", namebuf);
+ if (write(fd, &kfile, sizeof(kfile)) != sizeof(kfile)) {
+ fprintf(stderr, "error writing file %s\n", namebuf);
+ }
+ printf("done.\n");
+ (void)close(fd);
+ return;
+}
+
+void
+usage(name)
+ char *name;
+{
+ fprintf(stderr, "usage: %s host\n", name);
+}
diff --git a/share/doc/FAQ/Makefile b/share/doc/FAQ/Makefile
new file mode 100644
index 0000000000000..40ecc8aa77906
--- /dev/null
+++ b/share/doc/FAQ/Makefile
@@ -0,0 +1,6 @@
+# $Id$
+
+DOC= freebsd-faq
+SRCS= freebsd-faq.sgml
+
+.include <bsd.sgml.mk>
diff --git a/share/doc/handbook/Makefile b/share/doc/handbook/Makefile
new file mode 100644
index 0000000000000..7bf538d5ff81c
--- /dev/null
+++ b/share/doc/handbook/Makefile
@@ -0,0 +1,12 @@
+# $Id$
+
+SRCS= authors.sgml basics.sgml bibliography.sgml boothelp.sgml
+SRCS+= booting.sgml contrib.sgml ctm.sgml current.sgml dialup.sgml
+SRCS+= diskless.sgml eresources.sgml glossary.sgml handbook.sgml
+SRCS+= history.sgml hw.sgml install.sgml kerberos.sgml kerneldebug.sgml
+SRCS+= memoryuse.sgml mirrors.sgml nfs.sgml nutshell.sgml porting.sgml
+SRCS+= ports.sgml ppp.sgml relnotes.sgml scsi.sgml sections.sgml
+SRCS+= slipc.sgml slips.sgml submitters.sgml sup.sgml
+SRCS+= troubleshooting.sgml userppp.sgml
+
+.include <bsd.sgml.mk>
diff --git a/share/doc/handbook/boothelp.sgml b/share/doc/handbook/boothelp.sgml
new file mode 100644
index 0000000000000..fbda261aa6693
--- /dev/null
+++ b/share/doc/handbook/boothelp.sgml
@@ -0,0 +1,50 @@
+<!-- $Id$ -->
+<!-- The FreeBSD Documentation Project -->
+
+<!DOCTYPE linuxdoc PUBLIC "-//FreeBSD//DTD linuxdoc//EN" [
+
+<!-- Conditional flags for this version of the document -->
+<!ENTITY % boothelp.only "INCLUDE">
+<!ENTITY % handbook.only "IGNORE">
+
+<!-- Entity shorthand for authors' names and email addresses -->
+<!ENTITY % authors SYSTEM "authors.sgml">
+%authors;
+
+<!-- Entity definitions for all the parts -->
+<!ENTITY % sections SYSTEM "sections.sgml">
+%sections;
+
+]>
+
+<linuxdoc>
+ <book>
+
+ <title>FreeBSD Installation
+ <author>
+ <name></name>
+ </author>
+
+ <abstract>Welcome to FreeBSD! This guide describes the
+ FreeBSD installation process. To navigate through the
+ sections in this guide using the <bf>up</bf> and
+ <bf>down</bf> arrow keys to select a section you wish to
+ read. Then use the <bf>right arrow</bf> or the <bf>enter
+ key</bf> to view the section. You can backtrack through
+ sections you have read by using the <bf>left arrow</bf>.
+ </abstract>
+
+ <chapt><heading>General information</heading>
+ &nutshell;
+ &history;
+ &relnotes;
+
+ &install;
+ &troubleshooting;
+ &bibliography;
+ &eresources;
+ &hw;
+ &contrib;
+
+ </book>
+</linuxdoc>
diff --git a/share/doc/handbook/contrib.sgml b/share/doc/handbook/contrib.sgml
new file mode 100644
index 0000000000000..b3bd245e4a680
--- /dev/null
+++ b/share/doc/handbook/contrib.sgml
@@ -0,0 +1,300 @@
+<!-- $Id: contrib.sgml,v 1.14 1995/08/31 15:15:17 jkh Exp $ -->
+<!-- The FreeBSD Documentation Project -->
+
+<chapt><heading>FreeBSD contributor list<label id="contrib"></heading>
+
+ <sect><heading>Derived software contributors</heading>
+
+ <p>This software was originally derived from William
+ F. Jolitz's 386BSD release 0.1, though almost none of the
+ original 386BSD specific code remains. This software has
+ been essentially reimplemented from the 4.4 BSD Lite
+ release provided by the Computer Science Research Group
+ (CSRG) at the University of California, Berkeley and
+ associated academic contributors.
+
+ There are also portions of NetBSD that have been integrated
+ into FreeBSD as well, and we would therefore like to thank
+ all the contributors to NetBSD for their work. Despite
+ some occasionally rocky moments in relations between the
+ two groups, we both want essentially the same thing: More
+ BSD based operating systems on people's computers! We wish
+ the NetBSD group every success in their endevors.
+
+ <sect><heading>Hardware contributors</heading>
+
+ <p>A special thank-you to Walnut Creek CDROM for providing
+ the Pentium P5-90 and 486/DX2-66 EISA/VL systems that are
+ being used for our development work, to say nothing of the
+ network access and other donations of hardware resources.
+ It would have been impossible to do this release without
+ their support.
+
+ TRW Financial Systems, Inc. provided 130 PCs, three 68 GB
+ fileservers, twelve ethernets, two routers and an ATM
+ switch for debugging the diskless code. They also keep a
+ couple of FreeBSD hackers alive and busy. Thanks!
+
+ Thanks also to Dermot McDonnell for his donation of a
+ Toshiba XM3401B CDROM drive. It's been most useful!
+
+ Thanks to Chuck Robey &lt;chuckr@eng.umd.edu&gt; who's been
+ contributing his floppy tape streamer for experimental
+ work.
+
+ <sect><heading>The FreeBSD core team<label id="contrib:core"></heading>
+
+ <p>(in alphabetical order by first name):
+
+ <itemize>
+ <item>Andrey A. Chernov &lt;ache@FreeBSD.org&gt;
+ <item>Bruce Evans &lt;bde@FreeBSD.org&gt;
+ <item>David Greenman &lt;davidg@FreeBSD.org&gt;
+ <item>Garrett A. Wollman &lt;wollman@FreeBSD.org&gt;
+ <item>Gary Palmer &lt;gpalmer@FreeBSD.org&gt;
+ <item>J&ouml;rg Wunsch &lt;joerg@FreeBSD.org&gt;
+ <item>John Dyson &lt;dyson@FreeBSD.org&gt;
+ <item>Jordan K. Hubbard &lt;jkh@FreeBSD.org&gt;
+ <item>Justin Gibbs &lt;gibbs@FreeBSD.org&gt;
+ <item>Poul-Henning Kamp &lt;phk@FreeBSD.org&gt;
+ <item>Rich Murphey &lt;rich@FreeBSD.org&gt;
+ <item>Rodney W. Grimes &lt;rgrimes@FreeBSD.org&gt;
+ <item>Satoshi Asami &lt;asami@FreeBSD.org&gt;
+ <item>S&oslash;ren Schmidt &lt;sos@FreeBSD.org&gt;
+ </itemize>
+
+ <sect><heading>Who is responsible for what</heading>
+
+ <p><descrip>
+ <tag/President/ Jordan K. Hubbard &lt;jkh@FreeBSD.org&gt;
+ <tag/Principle Architect/ David Greenman &lt;davidg@FreeBSD.org&gt;
+ <tag/Documentation/ John Fieber &lt;jfieber@FreeBSD.org&gt;
+ <tag/Internationalization/ Andrey A. Chernov &lt;ache@FreeBSD.org&gt;
+ <tag/Networking/ Garrett A. Wollman &lt;wollman@FreeBSD.org&gt;
+ <tag/Postmaster/ Jonathan M. Bresler &lt;jmb@FreeBSD.org&gt;
+ <tag/Public Relations/ Jordan Hubbard &lt;jkh@FreeBSD.org&gt;
+ <tag/Release Coordinator/ Jordan Hubbard &lt;jkh@FreeBSD.org&gt;
+ <tag/System Administration/ Gary Palmer &lt;gpalmer@FreeBSD.org&gt;
+ <tag/Webmasters/ John Fieber &lt;jfieber@FreeBSD.org&gt; and
+ James L. Robinson &lt;jlrobin@FreeBSD.org&gt;
+ <tag/XFree86 Project, Inc. Liason/ Rich Murphey
+ &lt;rich@FreeBSD.org&gt;
+ </descrip>
+
+ <sect><heading>Additional FreeBSD contributors</heading>
+
+ <p>(in alphabetical order by first name):
+
+ <itemize>
+ <item>Adam David &lt;adam@veda.is&gt;
+ <item>Adam Glass &lt;glass@postgres.berkeley.edu&gt;
+ <item>Akito Fujita &lt;fujita@zoo.ncl.omron.co.jp&gt;
+ <item>Alain Kalker &lt;alain@Wit401402.student.utwente.nl&gt;
+ <item>Andras Olah &lt;olah@cs.utwente.nl&gt;
+ <item>Andreas Klemm &lt;andreas@knobel.GUN.de&gt;
+ <item>Andrew Herbert &lt;andrew@werple.apana.org.au&gt;
+ <item>Andrew Moore &lt;alm@FreeBSD.org&gt;
+ <item>Anthony Yee-Hang Chan &lt;yeehang@netcom.com&gt;
+ <item>Atsushi Murai &lt;amurai@spec.co.jp&gt;
+ <item>Bill Fenner &lt;fenner@parc.xerox.com&gt;
+ <item>Bill Paul &lt;wpaul@FreeBSD.org&gt;
+ <item>Bob Wilcox &lt;bob@obiwan.uucp&gt;
+ <item>Brian Tao &lt;taob@gate.sinica.edu.tw&gt;
+ <item>Charles Hannum &lt;mycroft@ai.mit.edu&gt;
+ <item>Chris G. Demetriou &lt;cgd@postgres.berkeley.edu&gt;
+ <item>Chris Provenzano &lt;proven@athena.mit.edu&gt;
+ <item>Chris Stenton &lt;jacs@gnome.co.uk&gt;
+ <item>Chris Torek &lt;torek@ee.lbl.gov&gt;
+ <item>Christian Gusenbauer &lt;cg@fimp01.fim.uni-linz.ac.at&gt;
+ <item>Christoph Robitschko &lt;chmr@edvz.tu-graz.ac.at&gt;
+ <item>Chuck Robey &lt;chuckr@Glue.umd.edu&gt;
+ <item>Cornelis van der Laan &lt;nils@guru.ims.uni-stuttgart.de&gt;
+ <item>Craig Struble &lt;cstruble@vt.edu&gt;
+ <item>Curt Mayer &lt;curt@toad.com&gt;
+ <item>Danny J. Zerkel &lt;dzerkel@feephi.phofarm.com&gt;
+ <item>Dave Burgess &lt;burgess@hrd769.brooks.af.mil&gt;
+ <item>Dave Chapeskie &lt;dchapes@zeus.leitch.com&gt;
+ <item>Dave Rivers &lt;rivers@ponds.uucp&gt;
+ <item>David Dawes &lt;dawes@physics.su.OZ.AU&gt;
+ <item>Dean Huxley &lt;dean@fsa.ca&gt;
+ <item>Don Whiteside &lt;dwhite@anshar.shadow.net&gt;
+ <item>Eric L. Hernes &lt;erich@lodgenet.com&gt;
+ <item>Frank Durda IV &lt;bsdmail@nemesis.lonestar.org&gt;
+ <item>Frank Maclachlan &lt;fpm@crash.cts.com&gt;
+ <item>Frank Nobis &lt;fn@trinity.radio-do.de&gt;
+ <item>Gary A. Browning &lt;gab10@griffcd.amdahl.com&gt;
+ <item>Gary Clark II &lt;gclarkii@FreeBSD.ORG&gt;
+ <item>Gary Jennejohn &lt;gj%pcs.dec.com@inet-gw-1.pa.dec.com&gt;
+ <item>Gene Stark &lt;stark@cs.sunysb.edu&gt;
+ <item>Guido van Rooij &lt;guido@gvr.win.tue.nl&gt;
+ <item>Havard Eidnes &lt;Havard.Eidnes@runit.sintef.no&gt;
+ <item>Holger Veit &lt;Holger.Veit@gmd.de&gt;
+ <item>Ishii Masahiro, R. Kym Horsell
+ <item>J.T. Conklin &lt;jtc@winsey.com&gt;
+ <item>James Clark &lt;jjc@jclark.com&gt;
+ <item>James da Silva &lt;jds@cs.umd.edu&gt; et al
+ <item>Janusz Kokot &lt;janek@gaja.ipan.lublin.pl&gt;
+ <item>Javier Martin Rueda &lt;jmrueda@diatel.upm.es&gt;
+ <item>Jim Wilson &lt;wilson@moria.cygnus.com&gt;
+ <item>Jonathan Bresler &lt; jmb@FreeBSD.ORG&gt;
+ <item>Josh MacDonald &lt;jmacd@uclink.berkeley.edu&gt;
+ <item>Julian Elischer &lt;julian@dialix.oz.au&gt;
+ <item>Julian Stacey &lt;stacey@guug.de&gt;
+ (fallback: &lt;julian@meepmeep.pcs.com&gt)
+ <item>Keith Bostic &lt;bostic@toe.CS.Berkeley.EDU&gt;
+ <item>Keith Moore &lt;?&gt;
+ <item>Kirk McKusick &lt;mckusick@mckusick.com&gt;
+ <item>Kurt Olsen &lt;kurto@tiny.mcs.usu.edu&gt;
+ <item>L Jonas Olsson &lt;ljo@po.cwru.edu&gt;
+ <item>Lars Fredriksen &lt;fredriks@mcs.com&gt;
+ <item>Lucas James &lt;Lucas.James@ldjpc.apana.org.au&gt;
+ <item>Marc Frajola &lt;marc@dev.com&gt;
+ <item>Marc Ramirez &lt;mrami@mramirez.sy.yale.edu
+ <item>Marc van Kempen &lt;wmbfmk@urc.tue.nl&gt;
+ <item>Mark Murray &lt;mark@grondar.za&gt;
+ <item>Mark Tinguely &lt;tinguely@plains.nodak.edu&gt;
+ &lt;tinguely@hookie.cs.ndsu.NoDak.edu&gt;
+ <item>Martin Birgmeier
+ <item>Martin Renters &lt;martin@innovus.com&gt;
+ <item>Matt Thomas &lt;thomas@lkg.dec.com&gt;
+ <item>Michael Smith &lt;msmith@atrad.adelaide.edu.au&gt;
+ <item>Mike Pritchard &lt;mpp@mpp.minn.net&gt;
+ <item>NIIMI Satoshi &lt;sa2c@and.or.jp&gt;
+ <item>Nate Williams &lt;nate@FreeBSD.org&gt;
+ <item>Nobuhiro Yasutomi &lt;nobu@psrc.isac.co.jp&gt;
+ <item>Nobuyuki Koganemaru &lt;kogane@kces.koganemaru.co.jp&gt;
+ <item>Ollivier Robert &lt;roberto@FreeBSD.org&gt;
+ <item>Paul Kranenburg &lt;pk@cs.few.eur.nl&gt;
+ <item>Paul Mackerras &lt;paulus@cs.anu.edu.au&gt;
+ <item>Paul Richards &lt;paul@FreeBSD.org&gt;
+ <item>Paul Traina &lt;pst@cisco.com&gt;
+ <item>Peter Dufault &lt;dufault@hda.com&gt;
+ <item>Peter Wemm &lt;peter@haywire.DIALix.COM&gt;
+ <item>Philippe Charnier &lt;charnier@lirmm.fr&gt;
+ <item>Richard Stallman &lt;rms@gnu.ai.mit.edu&gt;
+ <item>Rob Shady &lt;rls@id.net&gt;
+ <item>Rob Snow &lt;rsnow@txdirect.net&gt;
+ <item>Sascha Wildner &lt;swildner@channelz.GUN.de&gt;
+ <item>Scott Mace &lt;smace@FreeBSD.org&gt;
+ <item>Sean Eric Fagan &lt;sef@kithrup.com&gt;
+ <item>Serge V. Vakulenko &lt;vak@zebub.msk.su&gt;
+ <item>Stefan Esser &lt;se@MI.Uni-Koeln.DE&gt;
+ <item>Stephen McKay &lt;syssgm@devetir.qld.gov.au&gt;
+ <item>Steve Gerakines &lt;steve2@genesis.tiac.net&gt;
+ <item>Steven Wallace &lt;swallace@ece.uci.edu&gt;
+ <item>Tatsumi Hosokawa &lt;hosokawa@mt.cs.keio.ac.jp&gt;
+ <item>Terry Lee &lt;terry@uivlsi.csl.uiuc.edu&gt;
+ <item>Theo Deraadt &lt;deraadt@fsa.ca&gt;
+ <item>Thomas Gellekum &lt;thomas@ghpc8.ihf.rwth-aachen.de&gt;
+ <item>Tom Samplonius &lt;tom@misery.sdf.com&gt;
+ <item>Torbjorn Granlund &lt;tege@matematik.su.se&gt;
+ <item>Torsten Blum &lt;torstenb@FreeBSD.ORG&gt;
+ <item>Ugen J.S.Antsilevich &lt;ugen@NetVision.net.il&gt;
+ <item>Werner Griessl &lt;werner@btp1da.phy.uni-bayreuth.de&gt;
+ <item>Wolfgang Stanglmeier &lt;wolf@kintaro.cologne.de&gt;
+ <item>Wolfram Schneider &lt;wosch@cs.tu-berlin.de&gt;
+ <item>Yuval Yarom &lt;yval@cs.huji.ac.il&gt;
+ <item>Yves Fonk &lt;yves@cpcoup5.tn.tudelft.nl&gt;
+ </itemize>
+
+ <sect><heading>386BSD Patch kit patch contributors</heading>
+
+ <p>(in alphabetical order by first name):
+
+ <itemize>
+ <item>Adam Glass &lt;glass@postgres.berkeley.edu&gt;
+ <item>Adrian Hall &lt;adrian@ibmpcug.co.uk&gt;
+ <item>Andrey A. Chernov &lt;ache@astral.msk.su&gt;
+ <item>Andrew Herbert &lt;andrew@werple.apana.org.au&gt;
+ <item>Andrew Moore &lt;alm@netcom.com&gt;
+ <item>Andy Valencia &lt;ajv@csd.mot.com&gt; &lt;jtk@netcom.com&gt;
+ <item>Arne Henrik Juul &lt;arnej@Lise.Unit.NO&gt;
+ <item>Bakul Shah &lt;bvs@bitblocks.com&gt;
+ <item>Barry Lustig &lt;barry@ictv.com&gt;
+ <item>Bob Wilcox &lt;bob@obiwan.uucp&gt;
+ <item>Branko Lankester
+ <item>Brett Lymn &lt;blymn@mulga.awadi.com.AU&gt;
+ <item>Charles Hannum &lt;mycroft@ai.mit.edu&gt;
+ <item>Chris G. Demetriou &lt;cgd@postgres.berkeley.edu&gt;
+ <item>Chris Torek &lt;torek@ee.lbl.gov&gt;
+ <item>Christoph Robitschko &lt;chmr@edvz.tu-graz.ac.at&gt;
+ <item>Daniel Poirot &lt;poirot@aio.jsc.nasa.gov&gt;
+ <item>Dave Burgess &lt;burgess@hrd769.brooks.af.mil&gt;
+ <item>Dave Rivers &lt;rivers@ponds.uucp&gt;
+ <item>David Dawes &lt;dawes@physics.su.OZ.AU&gt;
+ <item>David Greenman &lt;davidg@Root.COM&gt;
+ <item>Eric J. Haug &lt;ejh@slustl.slu.edu&gt;
+ <item>Felix Gaehtgens &lt;felix@escape.vsse.in-berlin.de&gt;
+ <item>Frank Maclachlan &lt;fpm@crash.cts.com&gt;
+ <item>Gary A. Browning &lt;gab10@griffcd.amdahl.com&gt;
+ <item>Geoff Rehmet &lt;csgr@alpha.ru.ac.za&gt;
+ <item>Goran Hammarback &lt;goran@astro.uu.se&gt;
+ <item>Guido van Rooij &lt;guido@gvr.win.tue.nl&gt;
+ <item>Guy Harris &lt;guy@auspex.com&gt;
+ <item>Havard Eidnes &lt;Havard.Eidnes@runit.sintef.no&gt;
+ <item>Herb Peyerl &lt;hpeyerl@novatel.cuc.ab.ca
+ <item>Holger Veit &lt;Holger.Veit@gmd.de&gt;
+ <item>Ishii Masahiro, R. Kym Horsell
+ <item>J.T. Conklin &lt;jtc@winsey.com&gt;
+ <item>Jagane D Sundar &lt; jagane@netcom.com &gt;
+ <item>James Clark &lt;jjc@jclark.com&gt;
+ <item>James Jegers &lt;jimj@miller.cs.uwm.edu&gt;
+ <item>James W. Dolter
+ <item>James da Silva &lt;jds@cs.umd.edu&gt; et al
+ <item>Jay Fenlason &lt;hack@datacube.com&gt;
+ <item>Jim Wilson &lt;wilson@moria.cygnus.com&gt;
+ <item>Joerg Lohse &lt;lohse@tech7.informatik.uni-hamburg.de&gt;
+ <item>J&ouml;rg Wunsch &lt;joerg_wunsch@uriah.heep.sax.de&gt;
+ <item>John Dyson - &lt;formerly dyson@ref.tfs.com&gt;
+ <item>John Woods &lt;jfw@eddie.mit.edu&gt;
+ <item>Jordan K. Hubbard &lt;jkh@whisker.hubbard.ie&gt;
+ <item>Julian Elischer &lt;julian@dialix.oz.au&gt;
+ <item>Julian Stacey &lt;stacey@guug.de&gt;
+ (fallback: &lt;julian@meepmeep.pcs.com&gt;)
+ <item>Karl Lehenbauer &lt;karl@NeoSoft.com&gt;
+ &lt;karl@one.neosoft.com&gt;
+ <item>Keith Bostic &lt;bostic@toe.CS.Berkeley.EDU&gt;
+ <item>Ken Hughes
+ <item>Kent Talarico &lt;kent@shipwreck.tsoft.net&gt;
+ <item>Kevin Lahey &lt;kml%rokkaku.UUCP@mathcs.emory.edu&gt;
+ &lt;kml@mosquito.cis.ufl.edu&gt;
+ <item>Marc Frajola &lt;marc@dev.com&gt;
+ <item>Mark Tinguely &lt;tinguely@plains.nodak.edu&gt;
+ &lt;tinguely@hookie.cs.ndsu.NoDak.edu&gt;
+ <item>Martin Renters &lt;martin@innovus.com&gt;
+ <item>Michael Galassi &lt;nerd@percival.rain.com&gt;
+ <item>Mike Durkin &lt;mdurkin@tsoft.sf-bay.org&gt;
+ <item>Nate Williams &lt;nate@bsd.coe.montana.edu&gt;
+ <item>Nick Handel &lt;nhandel@NeoSoft.com&gt;
+ &lt;nick@madhouse.neosoft.com&gt;
+ <item>Pace Willisson &lt;pace@blitz.com&gt;
+ <item>Paul Kranenburg &lt;pk@cs.few.eur.nl&gt;
+ <item>Paul Mackerras &lt;paulus@cs.anu.edu.au&gt;
+ <item>Paul Popelka &lt;paulp@uts.amdahl.com&gt;
+ <item>Peter da Silva &lt;peter@NeoSoft.com&gt;
+ <item>Phil Sutherland &lt;philsuth@mycroft.dialix.oz.au&gt;
+ <item>Ralf Friedl &lt;friedl@informatik.uni-kl.de&gt;
+ <item>Rick Macklem &lt;root@snowhite.cis.uoguelph.ca&gt;
+ <item>Robert D. Thrush &lt;rd@phoenix.aii.com&gt;
+ <item>Rodney W. Grimes &lt;rgrimes@cdrom.com&gt;
+ <item>Rog Egge &lt;?&gt;
+ <item>Sascha Wildner &lt;swildner@channelz.GUN.de&gt;
+ <item>Scott Burris &lt;scott@pita.cns.ucla.edu&gt;
+ <item>Scott Reynolds &lt;scott@clmqt.marquette.mi.us&gt;
+ <item>Sean Eric Fagan &lt;sef@kithrup.com&gt;
+ <item>Simon J Gerraty &lt;sjg@melb.bull.oz.au&gt;
+ &lt;sjg@zen.void.oz.au&gt;
+ <item>Stephen McKay &lt;syssgm@devetir.qld.gov.au&gt;
+ <item>Terry Lambert &lt;terry@icarus.weber.edu&gt;
+ <item>Terry Lee &lt;terry@uivlsi.csl.uiuc.edu&gt;
+ <item>Warren Toomey &lt;wkt@csadfa.cs.adfa.oz.au&gt;
+ <item>Wiljo Heinen &lt;wiljo@freeside.ki.open.de&gt;
+ <item>William Jolitz &lt;withheld&gt;
+ <item>Wolfgang Solfrank &lt;ws@tools.de&gt;
+ <item>Wolfgang Stanglmeier &lt;wolf@dentaro.GUN.de&gt;
+ <item>Yuval Yarom &lt;yval@cs.huji.ac.il&gt;
+ </itemize>
+
+ Last, but not least, the release engineer would like to
+ thank: His Wife, for chocolate chip cookies, and some other
+ things. The DGB project @ TFS, for patience and tolerance.
diff --git a/share/doc/handbook/hw.sgml b/share/doc/handbook/hw.sgml
new file mode 100644
index 0000000000000..372997456200f
--- /dev/null
+++ b/share/doc/handbook/hw.sgml
@@ -0,0 +1,319 @@
+<!-- $Id: hw.sgml,v 1.5 1995/08/29 01:42:37 jfieber Exp $ -->
+<!-- The FreeBSD Documentation Project -->
+
+<!--
+<!DOCTYPE linuxdoc PUBLIC "-//FreeBSD//DTD linuxdoc//EN">
+-->
+
+<chapt><heading>PC Hardware compatibility<label id="hw"></heading>
+
+ <p>Issues of hardware compatibility are among the most
+ troublesome in the computer industry today and FreeBSD is by
+ no means immune to trouble. In this respect, FreeBSD's
+ advantage of being able to run on inexpensive commidity PC
+ hardware is also its liability when it comes to support for
+ the amazing variety of components on the market. While it
+ would be impossible to provide a exhaustive listing of
+ hardware that FreeBSD supports, this section serves as a
+ catalog of the device drivers included with FreeBSD and the
+ hardware each drivers supports. Where possible and
+ appropriate, notes about specific products are included.
+
+ As FreeBSD is a volunteer project without a funded testing
+ department, we depend on you, the user, for much of the
+ information contained in this catalog. If you have direct
+ experience of hardware that does or does not work with
+ FreeBSD, please let us know by sending email to
+ <tt>doc@freebsd.org</tt>. Questions about supported hardware
+ should be directed to <tt>questions@freebsd.org</tt> (see
+ <ref id="eresources:mail" name="Mailing Lists"> for more
+ information). When submitting information or asking a
+ question, please remember to specify exactly what version of
+ FreeBSD you are using and include as many details of your
+ hardware as possible.
+
+<sect><heading>Core/Processing<label id="hw:core"></heading>
+
+<sect1><heading>Motherboards, busses, and chipsets</heading>
+ <sect2><heading>* ISA</heading>
+ <sect2><heading>* EISA</heading>
+ <sect2><heading>* VLB</heading>
+ <sect2><heading>PCI</heading>
+
+ <p><em>Contributed by &a.rgrimes;.<newline>25 April 1995.</em></p>
+
+ <p>Of the Intel PCI chip sets the following is a list
+ of brokenness from worst to best and a short
+ description of brokenness.</p>
+
+ <p><descrip>
+
+ <tag>Mercury:</tag> Cache coherency problems,
+ especially if there are ISA bus masters behind
+ the ISA to PCI bridge chip. Hardware flaw, only
+ known work around is to turn the cache
+ off.
+
+ <tag>Saturn-I <em>(ie, 82424ZX at rev 0, 1 or
+ 2)</em>:</tag> write back cache coherency
+ problems. Hardware flaw, only known work around
+ is to set the external cache to write-through
+ mode. Upgrade to Saturn-II.
+
+ <tag>Saturn-II <em>(ie, 82424ZX at rev 3 or
+ 4)</em>:</tag> Works fine, but many MB
+ manufactures leave out the external dirty bit
+ SRAM needed for write back operation. Work
+ arounds are either run it in write through mode,
+ or get the dirty bit SRAM installed. (I have
+ these for the ASUS PCI/I-486SP3G rev 1.6 and
+ later boards).
+
+ <tag>Neptune:</tag> Can not run more than 2 bus
+ master devices. Admitted Intel design flaw.
+ Workarounds include do not run more than 2 bus
+ masters, special hardware design to replace the
+ PCI bus arbiter (appears on Intel Altair board
+ and several other Intel server group MB's). And
+ of course Intel's official answer, move to the
+ Triton chip set, we ``fixed it there''.
+
+ <tag>Triton:</tag> No known cache coherency or bus
+ master problems, chip set does not implement
+ parity checking. Workaround for parity issue.
+ Wait for Triton-II.
+
+ <tag>Triton-II:</tag> Unknown, not yet shipping.
+
+ </descrip>
+ </p>
+
+<sect1><heading>* CPUs/FPUs</heading>
+<sect1><heading>* Memory</heading>
+<sect1><heading>* BIOS</heading>
+
+<sect><heading>Input/Output Devices<label id="hw:io"></heading>
+
+<sect1><heading>* Video cards</heading>
+<sect1><heading>* Sound cards</heading>
+<sect1><heading>Serial ports and multiport cards</heading>
+
+ <p>The <tt>sio</tt> driver provides support for NS8250-,
+ NS16450-, NS16550 and NS16550A-based EIA RS-232C (CCITT
+ V.24) communications interfaces. Several multiport
+ cards are supported as well. See the <tt>sio(4)</tt>
+ manual page for detailed technical documentation.
+
+<sect2><heading>Digiboard PC/8</heading>
+
+ <p><em>Contributed by &a.awebster;.<newline>26 August
+ 1995.</em>
+
+ Here is a config snippet from a machine with
+ digiboard PC/8 with 16550. It has 8 modems connected
+ to these 8 lines, and they work just great. Do not
+ forget to add <tt>options "COM_MULTIPORT"</tt> or it
+ will not work very well!
+
+<tscreen><verb>
+device sio4 at isa? port 0x100 tty flags 0xb05
+device sio5 at isa? port 0x108 tty flags 0xb05
+device sio6 at isa? port 0x110 tty flags 0xb05
+device sio7 at isa? port 0x118 tty flags 0xb05
+device sio8 at isa? port 0x120 tty flags 0xb05
+device sio9 at isa? port 0x128 tty flags 0xb05
+device sio10 at isa? port 0x130 tty flags 0xb05
+device sio11 at isa? port 0x138 tty flags 0xb05 irq 9 vector siointr
+</verb></tscreen>
+
+ The trick in setting this up is that the MSB of the
+ flags represent the last SIO port, in this case 11 so
+ flags are 0xb05.
+
+<sect2><heading>Boca 16</heading>
+
+ <p><em>Contributed by &a.whiteside;.<newline>26 August
+ 1995.</em>
+
+ The procedures to make a Boca 16 pord board with
+ FreeBSD are pretty straighforward, but you will need
+ a couple things to make it work:
+
+ <enum>
+ <item>You either need the kernel sources installed
+ so you can recompile the necessary options or
+ you will need someone else to compile it for you.
+ The 2.0.5 default kernel does <bf>not</bf> come with
+ multiport support enabled and you will need to add
+ a device entry for each port anyways.
+ </item>
+ <item>Two, you will need to know the interrupt and IO
+ setting for your Boca Board so you can set these
+ options properly in the kernel.</item>
+ </enum>
+
+ One important note - the actual UART chips for the
+ Boca 16 are in the connector box, not on the internal
+ board itself. So if you have it unplugged, probes of
+ those ports will fail. I have never tested booting with
+ the box unplugged and plugging it back in, and I
+ suggest you do not either.
+
+ If you do not already have a custom kernel
+ configuration file set up, refer to <ref
+ id="kernelconfig" name="Kernel Configuration"> for
+ general procedurs. The following are the specifics
+ for the Boca 16 board and assume you are using the
+ kernel name MYKERNEL and editing with vi.
+
+ <enum>
+ <item>Add the line
+<tscreen><verb>
+options "COM_MULTIPORT"
+</verb></tscreen>
+to the config file.
+</item>
+
+ <item>Where the current <tt>device sio
+ <em>xxx</em></tt> lines are, you will need to add
+ 16 more devices. <em>Only the last device
+ includes the interrupt vector for the
+ board</em>. (See the <tt>sio(4)</tt> manual page
+ for detail as to why.)
+
+ The following example is for a Boca Board with an
+ interrupt of 3, and a base IO address 100h. The
+ IO address for Each port is +8 hexidecimal from
+ the previous port, thus the 100h, 108h, 110h...
+ addresses.
+
+<tscreen><verb>
+device sio1 at isa? port 0x100 tty flags 0x1005
+device sio2 at isa? port 0x108 tty flags 0x1005
+device sio3 at isa? port 0x110 tty flags 0x1005
+device sio4 at isa? port 0x118 tty flags 0x1005
+...
+device sio15 at isa? port 0x170 tty flags 0x1005
+device sio16 at isa? port 0x178 tty flags 0x1005 irq 3 vector siointr
+</verb></tscreen>
+
+ The flags entry <em>must</em> be changed from
+ this example unless you are using the exact same
+ sio assignments. Flags are set according to
+ 0x<em>MYY</em> where <em>M</em> indicates the
+ minor number of the master port (the last port on
+ a Boca 16) and <em>YY</em> indicates if FIFO is
+ enabled or disabled(enabled), IRQ sharing is
+ used(yes) and if there is an AST/4 compatible IRQ
+ control register(no).
+
+ In this example,
+<tscreen><verb>
+flags 0x1005
+</verb></tscreen>
+
+ indicates that the master port is sio16. If I
+ added another board and assigned sio17 through
+ sio28, the flags for all 16 ports on
+ <em>that</em> board would be 0x1C05, where 1C
+ indicates the minor number of the master port.
+ Do not change the 05 setting.</item>
+
+ <item>Save and complete the kernel configuration,
+ recompile, install and reboot.
+
+ Presuming you have successfully installed the
+ recompiled kernel and have it set to the correct
+ address and IRQ, your boot message should
+ indicate the successful probe of the Boca ports
+ as follows: (obviously the sio numbers, IO and
+ IRQ could be different)
+
+<tscreen><verb>
+sio1 at 0x100-0x107 flags 0x1005 on isa
+sio1: type 16550A (multiport)
+sio2 at 0x108-0x10f flags 0x1005 on isa
+sio2: type 16550A (multiport)
+sio3 at 0x110-0x117 flags 0x1005 on isa
+sio3: type 16550A (multiport)
+sio4 at 0x118-0x11f flags 0x1005 on isa
+sio4: type 16550A (multiport)
+sio5 at 0x120-0x127 flags 0x1005 on isa
+sio5: type 16550A (multiport)
+sio6 at 0x128-0x12f flags 0x1005 on isa
+sio6: type 16550A (multiport)
+sio7 at 0x130-0x137 flags 0x1005 on isa
+sio7: type 16550A (multiport)
+sio8 at 0x138-0x13f flags 0x1005 on isa
+sio8: type 16550A (multiport)
+sio9 at 0x140-0x147 flags 0x1005 on isa
+sio9: type 16550A (multiport)
+sio10 at 0x148-0x14f flags 0x1005 on isa
+sio10: type 16550A (multiport)
+sio11 at 0x150-0x157 flags 0x1005 on isa
+sio11: type 16550A (multiport)
+sio12 at 0x158-0x15f flags 0x1005 on isa
+sio12: type 16550A (multiport)
+sio13 at 0x160-0x167 flags 0x1005 on isa
+sio13: type 16550A (multiport)
+sio14 at 0x168-0x16f flags 0x1005 on isa
+sio14: type 16550A (multiport)
+sio15 at 0x170-0x177 flags 0x1005 on isa
+sio15: type 16550A (multiport)
+sio16 at 0x178-0x17f irq 3 flags 0x1005 on isa
+sio16: type 16550A (multiport master)
+</verb></tscreen>
+
+ If the messages go by too fast to see, <tt>dmesg
+ &gt; more</tt> will show you the boot
+ messages.</item>
+
+ <item>Next, apprepriate entries in <tt>/dev</tt> for the devices
+ must be made using the <tt>/dev/MAKEDEV</tt>
+ script. After becoming root:
+<tscreen>
+cd /dev<newline>
+./MAKEDEV tty1<newline>
+./MAKEDEV cua1<newline>
+<em>.. (everything inbetween)</em><newline>
+./MAKEDEV ttyg<newline>
+./MAKEDEV cuag
+</tscreen>
+
+ If you do not want or need callout devices for some
+ reason, you can dispense with making the <tt>cua*</tt>
+ devices.</item>
+
+ <item>If you want a quick and sloppy way to make
+ sure the devices are working, you can simply plug
+ a modem into each port and (as root) <tt>echo at
+ &gt; ttyd*</tt> for each device you have
+ made. You <em>should</em> see the RX lights flash
+ for each working port.</item>
+ </enum>
+
+
+<sect1><heading>* Parallel ports</heading>
+<sect1><heading>* Modems</heading>
+<sect1><heading>* Network cards</heading>
+<sect1><heading>* Keyboards</heading>
+<sect1><heading>* Mice</heading>
+<sect1><heading>* Other</heading>
+
+<sect><heading>* Storage Devices<label id="hw:storage"></heading>
+
+<sect1><heading>* Disk/tape controllers</heading>
+ <sect2><heading>* SCSI</heading>
+ <sect2><heading>* IDE</heading>
+ <sect2><heading>* Floppy</heading>
+<sect1><heading>* Hard drives</heading>
+<sect1><heading>* Tape drives</heading>
+<sect1><heading>* CD-ROM drives</heading>
+<sect1><heading>* Other</heading>
+
+<sect><heading>* Other<label id="hw:other"></heading>
+
+<sect1><heading>* PCMCIA</heading>
+
+
+
diff --git a/share/doc/handbook/mirrors.sgml b/share/doc/handbook/mirrors.sgml
new file mode 100644
index 0000000000000..bc6cefbfb7702
--- /dev/null
+++ b/share/doc/handbook/mirrors.sgml
@@ -0,0 +1,410 @@
+<!-- $Id:$ -->
+<!-- The FreeBSD Documentation Project -->
+
+<!--
+<!doctype linuxdoc public "-//FreeBSD//DTD linuxdoc//EN">
+-->
+
+<chapt><heading>Obtaining FreeBSD<label id="mirrors"></heading>
+
+<p>The official sources for FreeBSD available via anonymous FTP from:
+<quote>
+<htmlurl url="ftp://ftp.freebsd.org/pub/FreeBSD"
+name="ftp://ftp.FreeBSD.org/pub/FreeBSD">
+</quote>
+and on CD-ROM from Walnut Creek CDROM:
+<quote>
+ Walnut Creek CDROM<newline>
+ 1547 Palos Verdes Mall, Suite 260<newline>
+ Walnut Creek CA 94596 USA<newline>
+ Phone: +1 510 647-0783<newline>
+ Fax: +1 510 647-0821<newline>
+ Email: <htmlurl url="mailto:info@cdrom.com" name="info@cdrom.com"><newline>
+ WWW: <htmlurl url="http://www.cdrom.com/" name="http://www.cdrom.com/">
+</quote>
+
+<p>Additionally, FreeBSD is available via anonymous FTP from the
+ following mirror sites. If you choose to obtain FreeBSD via
+ anonymous FTP, please try to use a site near you.
+
+<descrip>
+<tag>Australia</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.physics.usyd.edu.au/FreeBSD"
+ name="ftp://ftp.physics.usyd.edu.au/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:dawes@xfree86.org"
+ name="dawes@xfree86.org">.
+
+<item>
+<htmlurl url="ftp://minnie.cs.adfa.oz.au/FreeBSD"
+ name="ftp://minnie.cs.adfa.oz.au/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:wkt@dolphin.cs.adfa.oz.au"
+ name="wkt@dolphin.cs.adfa.oz.au">.
+
+</itemize>
+
+<tag>Canada</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.synapse.net/contrib/FreeBSD"
+ name="ftp://ftp.synapse.net/contrib/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:evanc@synapse.net"
+ name="evanc@synapse.net">.
+
+</itemize>
+
+<tag>Finland</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://nic.funet.fi/pub/unix/FreeBSD"
+ name="ftp://nic.funet.fi/pub/unix/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:count@nic.funet.fi"
+ name="count@nic.funet.fi">.
+
+</itemize>
+
+<tag>France</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.ibp.fr/pub/FreeBSD"
+ name="ftp://ftp.ibp.fr/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:Remy.Card@ibp.fr"
+ name="Remy.Card@ibp.fr">.
+
+</itemize>
+
+<tag>Germany</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.fb9dv.uni-duisburg.de/pub/unix/FreeBSD"
+ name="ftp://ftp.fb9dv.uni-duisburg.de/pub/unix/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftp@ftp.fb9dv.uni-duisburg.de"
+ name="ftp@ftp.fb9dv.uni-duisburg.de">.
+
+<item>
+<htmlurl url="ftp://gil.physik.rwth-aachen.de/pub/FreeBSD"
+ name="ftp://gil.physik.rwth-aachen.de/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:kuku@gil.physik.rwth-aachen.de"
+ name="kuku@gil.physik.rwth-aachen.de">.
+
+<item>
+<htmlurl url="ftp://ftp.uni-paderborn.de/freebsd"
+ name="ftp://ftp.uni-paderborn.de/freebsd"><newline>
+ Contact: <htmlurl url="mailto:ftp@uni-paderborn.de"
+ name="ftp@uni-paderborn.de">.
+
+<item>
+<htmlurl url="ftp://ftp.leo.org/pub/comp/os/bsd/FreeBSD"
+ name="ftp://ftp.leo.org/pub/comp/os/bsd/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:bsd@leo.org"
+ name="bsd@leo.org">.
+
+<item>
+<htmlurl url="ftp://ftp.tu-dresden.de/pub/soft/unix/bsd/FreeBSD"
+ name="ftp://ftp.tu-dresden.de/pub/soft/unix/bsd/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:pdsowner@rcs1.urz.tu-dresden.de"
+ name="pdsowner@rcs1.urz.tu-dresden.de">.
+
+</itemize>
+
+<tag>Ireland</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.internet-eireann.ie/pub/FreeBSD"
+ name="ftp://ftp.internet-eireann.ie/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftpadmin@internet-eireann.ie"
+ name="ftpadmin@internet-eireann.ie">.
+
+</itemize>
+
+<tag>Israel</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://orgchem.weizmann.ac.il/pub/FreeBSD"
+ name="ftp://orgchem.weizmann.ac.il/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:serg@klara.weizmann.ac.il"
+ name="serg@klara.weizmann.ac.il">.
+
+</itemize>
+
+<tag>Hong Kong</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.hk.super.net/pub/FreeBSD"
+ name="g ftp://ftp.hk.super.net/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftp-admin@HK.Super.NET"
+ name="ftp-admin@HK.Super.NET">.
+
+</itemize>
+
+<tag>Korea</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.cau.ac.kr/pub/FreeBSD"
+ name="ftp://ftp.cau.ac.kr/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftpadm@ftp.cau.ac.kr"
+ name="ftpadm@ftp.cau.ac.kr">.
+
+</itemize>
+
+<tag>Netherlands</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.nl.net/pub/os/FreeBSD"
+ name="ftp://ftp.nl.net/pub/os/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:archive@nl.net"
+ name="archive@nl.net">.
+
+</itemize>
+
+<tag>Russia</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.kiae.su/FreeBSD"
+ name="ftp://ftp.kiae.su/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftp@ftp.kiae.su"
+ name="ftp@ftp.kiae.su">.
+
+</itemize>
+
+<tag>Sweden</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.luth.se/pub/FreeBSD"
+ name="ftp://ftp.luth.se/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ragge@ludd.luth.se"
+ name="ragge@ludd.luth.se">.
+
+</itemize>
+
+<tag>Taiwan</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://NCTUCCCA.edu.tw/Operating-Systems/FreeBSD"
+ name="ftp://NCTUCCCA.edu.tw/Operating-Systems/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:freebsd@NCTUCCCA.edu.tw"
+ name="freebsd@NCTUCCCA.edu.tw">.
+
+<item>
+<htmlurl url="ftp://netbsd.csie.nctu.edu.tw/pub/FreeBSD"
+ name="ftp://netbsd.csie.nctu.edu.tw/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftp@netbsd.csie.nctu.edu.tw"
+ name="ftp@netbsd.csie.nctu.edu.tw">.
+
+</itemize>
+
+<tag>Thailand</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.nectec.or.th/pub/FreeBSD"
+ name="ftp://ftp.nectec.or.th/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftpadmin@ftp.nectec.or.th"
+ name="ftpadmin@ftp.nectec.or.th">.
+
+</itemize>
+
+<tag>USA</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://gatekeeper.dec.com/pub/BSD/FreeBSD"
+ name="ftp://gatekeeper.dec.com/pub/BSD/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:hubbard@gatekeeper.dec.com"
+ name="hubbard@gatekeeper.dec.com">.
+
+<item>
+<htmlurl url="ftp://ftp.cybernetics.net/pub/FreeBSD"
+ name="ftp://ftp.cybernetics.net/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:michael@Cybernetics.NET"
+ name="michael@Cybernetics.NET">.
+
+<item>
+<htmlurl url="ftp://ftp.neosoft.com/systems/FreeBSD"
+ name="ftp://ftp.neosoft.com/systems/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:smace@NeoSoft.COM"
+ name="smace@NeoSoft.COM">.
+
+<item>
+<htmlurl url="ftp://kryten.atinc.com/pub/FreeBSD"
+ name="ftp://kryten.atinc.com/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:jmb@kryten.atinc.com"
+ name="jmb@kryten.atinc.com">.
+
+<item>
+<htmlurl url="ftp://ftp.dataplex.net/pub/FreeBSD"
+ name="ftp://ftp.dataplex.net/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:rkw@dataplex.net"
+ name="rkw@dataplex.net">.
+
+<item>
+<htmlurl url="ftp://ftp.cps.cmich.edu/pub/ftp.freebsd.org"
+ name="ftp://ftp.cps.cmich.edu/pub/ftp.freebsd.org"><newline>
+ Contact: <htmlurl url="mailto:ftpadmin@cps.cmich.edu"
+ name="ftpadmin@cps.cmich.edu">.
+
+<item>
+<htmlurl url="ftp://ftp.cslab.vt.edu/pub/FreeBSD"
+ name="ftp://ftp.cslab.vt.edu/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftp@ftp.cslab.vt.edu"
+ name="ftp@ftp.cslab.vt.edu">.
+
+</itemize>
+
+<tag>Japan</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.tokyonet.ad.jp/pub/FreeBSD"
+ name="ftp://ftp.tokyonet.ad.jp/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftpadmin@TokyoNet.AD.JP"
+ name="ftpadmin@TokyoNet.AD.JP">.
+
+<item>
+<htmlurl url="ftp://ftp.tut.ac.jp/FreeBSD"
+ name="ftp://ftp.tut.ac.jp/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:<ashida@ftp.tut.ac.jp"
+ name="ashida@ftp.tut.ac.jp">.
+
+<item>
+<htmlurl url="ftp://ftp.sra.co.jp/pub/os/FreeBSD"
+ name="ftp://ftp.sra.co.jp/pub/os/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftp-admin@sra.co.jp"
+ name="ftp-admin@sra.co.jp">.
+
+<item>
+<htmlurl url="ftp://ftp.ee.uec.ac.jp/pub/os/mirror/ftp.freebsd.org"
+ name="ftp://ftp.ee.uec.ac.jp/pub/os/mirror/ftp.freebsd.org"><newline>
+ Contact: <htmlurl url="mailto:ftp-admin@ftp.ee.uec.ac.jp"
+ name="ftp-admin@ftp.ee.uec.ac.jp">.
+
+<item>
+<htmlurl url="ftp://ftp.mei.co.jp/free/PC-UNIX/FreeBSD"
+ name="ftp://ftp.mei.co.jp/free/PC-UNIX/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:tanig@isl.mei.co.jp"
+ name="tanig@isl.mei.co.jp">.
+
+<item>
+<htmlurl url="ftp://ftp.waseda.ac.jp/pub/FreeBSD"
+ name="ftp://ftp.waseda.ac.jp/pub/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftp-admin@waseda.ac.jp"
+ name="ftp-admin@waseda.ac.jp">.
+
+<item>
+<htmlurl url="ftp://ftp.pu-toyama.ac.jp/pub/FreeBSD"
+ name="ftp://ftp.pu-toyama.ac.jp/pub/FreeBSD"><newline>
+ Contact: Yoshihiko USUI <htmlurl url="mailto:usui@pu-toyama.ac.jp"
+ name="usui@pu-toyama.ac.jp">.
+
+<item>
+<htmlurl url="ftp://ftpsv1.u-aizu.ac.jp/pub/os/FreeBSD"
+ name="ftp://ftpsv1.u-aizu.ac.jp/pub/os/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:ftp-admin@u-aizu.ac.jp"
+ name="ftp-admin@u-aizu.ac.jp">.
+
+</itemize>
+
+<tag>UK</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://src.doc.ic.ac.uk/packages/unix/FreeBSD"
+ name="ftp://src.doc.ic.ac.uk/packages/unix/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:wizards@doc.ic.ac.uk"
+ name="wizards@doc.ic.ac.uk">.
+
+<item>
+<htmlurl url="ftp://unix.hensa.ac.uk/pub/walnut.creek/FreeBSD"
+ name="ftp://unix.hensa.ac.uk/pub/walnut.creek/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:archive-admin@unix.hensa.ac.uk"
+ name="archive-admin@unix.hensa.ac.uk">.
+
+<item>
+<htmlurl url="ftp://ftp.demon.co.uk/pub/BSD/FreeBSD"
+ name="ftp://ftp.demon.co.uk/pub/BSD/FreeBSD"><newline>
+ Contact: <htmlurl url="mailto:uploads@demon.net"
+ name="uploads@demon.net">.
+
+</itemize>
+</descrip>
+
+The latest versions of export-restricted code for FreeBSD (2.0C or later)
+(eBones and secure) are being made available at the following locations.
+If you are outside the U.S. or Canada, please get secure (DES) and
+eBones (Kerberos) from one of the following foreign distribution sites:
+
+<descrip>
+
+<tag>SouthAfrica</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://skeleton.mikom.csir.co.za/pub/FreeBSD"
+ name="ftp://skeleton.mikom.csir.co.za/pub/FreeBSD"><newline>
+ Contact: Mark Murray <htmlurl url="mailto:mark@grondar.za"
+ name="mark@grondar.za">.
+
+<item>
+<htmlurl url="ftp://storm.sea.uct.ac.za/pub/FreeBSD"
+ name="ftp://storm.sea.uct.ac.za/pub/FreeBSD"><newline>
+ Contact: Shaun Courtney <htmlurl url="mailto:ftp@storm.sea.uct.ac.za"
+ name="ftp@storm.sea.uct.ac.za">.
+
+</itemize>
+
+<tag>Brazil</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://ftp.iqm.unicamp.br/pub/FreeBSD"
+ name="ftp://ftp.iqm.unicamp.br/pub/FreeBSD"><newline>
+ Contact: Pedro A M Vazquez <htmlurl url="mailto:vazquez@iqm.unicamp.br"
+ name="vazquez@iqm.unicamp.br">.
+
+</itemize>
+
+<tag>Finland</tag>
+
+<itemize>
+
+<item>
+<htmlurl url="ftp://nic.funet.fi/pub/unix/FreeBSD/eurocrypt"
+ name="ftp://nic.funet.fi/pub/unix/FreeBSD/eurocrypt"><newline>
+ Contact: <htmlurl url="mailto:count@nic.funet.fi"
+ name="count@nic.funet.fi">.
+
+</itemize>
+</descrip> \ No newline at end of file
diff --git a/share/doc/handbook/sections.sgml b/share/doc/handbook/sections.sgml
new file mode 100644
index 0000000000000..0c8a2b1b42835
--- /dev/null
+++ b/share/doc/handbook/sections.sgml
@@ -0,0 +1,38 @@
+<!-- $Id$ -->
+<!-- The FreeBSD Documentation Project -->
+
+<!-- Entities containing all the pieces of the handbook are -->
+<!-- defined here -->
+
+<!ENTITY bibliography SYSTEM "bibliography.sgml">
+<!ENTITY basics SYSTEM "basics.sgml">
+<!ENTITY booting SYSTEM "booting.sgml">
+<!ENTITY contrib SYSTEM "contrib.sgml">
+<!ENTITY ctm SYSTEM "ctm.sgml">
+<!ENTITY current SYSTEM "current.sgml">
+<!ENTITY dialup SYSTEM "dialup.sgml">
+<!ENTITY diskless SYSTEM "diskless.sgml">
+<!ENTITY eresources SYSTEM "eresources.sgml">
+<!ENTITY glossary SYSTEM "glossary.sgml">
+<!ENTITY history SYSTEM "history.sgml">
+<!ENTITY hw SYSTEM "hw.sgml">
+<!ENTITY install SYSTEM "install.sgml">
+<!ENTITY kerberos SYSTEM "kerberos.sgml">
+<!ENTITY kernelconfig SYSTEM "kernelconfig.sgml">
+<!ENTITY kerneldebug SYSTEM "kerneldebug.sgml">
+<!ENTITY memoryuse SYSTEM "memoryuse.sgml">
+<!ENTITY mirrors SYSTEM "mirrors.sgml">
+<!ENTITY nfs SYSTEM "nfs.sgml">
+<!ENTITY nutshell SYSTEM "nutshell.sgml">
+<!ENTITY porting SYSTEM "porting.sgml">
+<!ENTITY ports SYSTEM "ports.sgml">
+<!ENTITY ppp SYSTEM "ppp.sgml">
+<!ENTITY relnotes SYSTEM "relnotes.sgml">
+<!ENTITY scsi SYSTEM "scsi.sgml">
+<!ENTITY slipc SYSTEM "slipc.sgml">
+<!ENTITY slips SYSTEM "slips.sgml">
+<!ENTITY submitters SYSTEM "submitters.sgml">
+<!ENTITY sup SYSTEM "sup.sgml">
+<!ENTITY troubleshooting SYSTEM "troubleshooting.sgml">
+<!ENTITY userppp SYSTEM "userppp.sgml">
+
diff --git a/share/examples/startslip/sldown.sh b/share/examples/startslip/sldown.sh
new file mode 100755
index 0000000000000..1f342a47b0c9c
--- /dev/null
+++ b/share/examples/startslip/sldown.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+/sbin/ifconfig $1 $2
+/sbin/route delete default
diff --git a/share/examples/startslip/slip.sh b/share/examples/startslip/slip.sh
new file mode 100755
index 0000000000000..1a0c1ad7f831b
--- /dev/null
+++ b/share/examples/startslip/slip.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+startslip -b 57600 -U ./slup.sh -D ./sldown.sh \
+ -s atd<phone1> -s atd<phone2> -s atd<phone3> \
+ -h -t 60 -w 2 -W 20 /dev/cuaa1 <login> <password>
diff --git a/share/examples/startslip/slup.sh b/share/examples/startslip/slup.sh
new file mode 100755
index 0000000000000..79cded3395585
--- /dev/null
+++ b/share/examples/startslip/slup.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+myname=<my.ip.address>
+gateway=<gateway.ip.address>
+netmask=255.255.255.248
+tune1="link0 -link2" # force headers compression
+tune2="mtu 296" # for FreeBSD 1.x host
+
+case $LINE in
+ 0) tune=$tune1;; # 1st phone connected
+ 1) tune=$tune2;; # 2nd phone connected
+ *) tune=;; # others
+esac
+
+/sbin/ifconfig $1 $2 $tune
+/sbin/ifconfig $1 inet $myname $gateway netmask $netmask
+/sbin/route add default $gateway
diff --git a/share/man/man4/man4.i386/asc.4 b/share/man/man4/man4.i386/asc.4
new file mode 100644
index 0000000000000..fc187f306bb13
--- /dev/null
+++ b/share/man/man4/man4.i386/asc.4
@@ -0,0 +1,179 @@
+.\" asc(4) - manual page for the scanner device driver `asc'
+.\"
+.\"
+.\" Copyright (c) 1995 Gunther Schadow, Luigi Rizzo. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgements:
+.\" This product includes software developed by Gunther Schadow.
+.\" This product includes software developed by Luigi Rizzo.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.TH ASC 4 "January 6, 1995" FreeBSD "FreeBSD Programmer's Manual"
+.SH NAME
+\fBasc\fP - a device driver for a handy scanner
+.SH SYNOPSIS
+.TP
+\fB#include <machine/asc_ioctl.h>\fP
+.TP
+\fBMinor number bits:\fP \fIuu d g p ...\fP
+\fIuu\fP - unit asc0 .. asc3
+\fI d\fP - selects logging of \fIdebug\fP messages
+\fI g\fP - selects \fIbitmap\fP vs. \fIgraymap\fP output
+\fI p\fP - selects \fIraw\fP vs. portable \fIpnm\fP output
+.TP
+\fBdd if=/dev/asc0 of=rawfile bs=(width/8) count=(height)
+.TP
+\fBcat /dev/asc0p > pbmfile\fP
+.PB
+.SH DESCRIPTION
+The \fBasc\fP character device driver currently handles the
+GI1904-based hand scanner (e.g. Trust Amiscan Grey).
+It uses DMA and interrupts. Input data from the scanner are
+buffered, up to 50 scanlines are buffered in the driver.
+.PP
+The device can operate at four different \fIresolutions\fP: 100, 200,
+300 and 400dpi. It produces a simple bitmap with the most significant bit
+at the left side. The driver can optionally output the famous and
+likely simple portable bitmap file format pbm(5) by Jef
+Poskanzer. Thus the scans can easily processed by any graphic package
+around (xpaint, xv, xli only to name some of them ...).
+.PP
+The \fIwidth\fP of the output bitmap is fixed as given by the
+resolution value. However, the \fIheight\fP of the bitmap must be
+supplied in \fIpnm\fP mode since the driver must know at what time the
+'end-of-file' shall be reached. The default is to produce a
+square image, i.e. \fIheight=width\fP. With this feature you are able to
+directly copy the scanner output into a pbm file whith cat(1). Of
+course you can obtain a similar effect by using dd(1) with the driver
+in \fIraw\fP mode.
+.PP
+The \fIgraymap\fP output mode is not yet implemented into the driver.
+It is even questionable if external programs would not do this job
+better thereby not counting to the size of the kernel. Even though, I
+do not know of tools which produce a graymap from a halftone bitmap.
+.SH IOCTL REQUESTS
+The ioctl requests that are served by \fBasc\fP are listed below.
+There is a utility, called sasc(1), that provides access to these
+requests from within shell.
+.TP
+ASC_GRES int
+Get current resolution in dots per inch (dpi).
+.TP
+ASC_GWIDTH int
+Get current width of the bitmap in pixels.
+.TP
+ASC_SHEIGHT int
+Set the \fIheight\fP of the bitmap in \fIpnm\fP mode. This is actually
+a limit on the amount of lines scannable after the first read
+operation. When the limit is reached read will return 0. However, the
+device is turned off only when a close is performed (either
+explicitely or implicitely on exit of the calling process).
+.TP
+ASC_GHEIGHT int
+Get the current height of the bitmap.
+.TP
+ASC_SBLEN int
+Set the length of the buffer used internally to do the DMA transfer.
+The buffer length is supplied in lines of the bitmap. Since the buffer
+size limit is (currently) 0x3000 bytes the maximum number of lines
+allowed will vary with the width of each line. This upper limit is
+checked before it overwrites the current value and pases an ENOMEM in
+the \fBerrno\fP variable. However, since the bitmap width can change
+after a buffer length was selected a read request may fail with ENOMEM
+if the buffer length turns out too high. It is generally wise to
+choose long buffers rather than go save in order to obtain better
+output.
+.TP
+ASC_GBLEN int
+Get the current buffer length in lines.
+.TP
+ASC_SBTIME int
+Set the timeout for the completion of reading one buffer. Since a
+handy scanner is a human/computer interface timeout values are usually
+higher than those of a flat scanner. Default is 15 seconds. After
+timeout is reached the read operation will fail with EBUSY. Note that
+the timeout timer starts anew for each buffer to be read and thus does
+not cause you to scan faster for longer images. BLEN/BTIME is similar
+as MIN/TIME in termios(4).
+.TP
+ASC_GBTIME int
+Get the current buffer timeout.
+.PP
+All ioctl requests that modify a parameter except ASC_SBTIME do not
+have an effect on an ongoing scan process, i.e. after the first read
+request that follows open. You must close the device and open it again
+for the new selections to take effect. Consequently, the selections
+are not reset when you close or open the device.
+.PP
+Similarily, requests that read a value do not report the value that is
+used for the ongoing scan process. The values needed during the scan
+process are saved when it starts and thus are not accessed by ioctl
+requests.
+.PP
+The BTIME value does, however, have an immediate effect on the ongoing
+scan. Thus the timeout can for example be set to long until the user
+starts scanning. It can then be set to a short amount to react
+(nearly) immediately when the user stops. Note that the user should be
+left time to at least fill one buffer without having to haste.
+.PP
+Note that the \fIpbm\fP versus \fIraw\fP mode selection is done by the
+minor number not by ioctl requests. In \fIraw\fP mode the selected
+height of the bitmap will have no effect.
+.SH FILES
+.TP 15
+.BI /dev/asc0
+device node for \fIraw\fP output, has minor number 0.
+.TP
+.BI /dev/asc0d
+device node for \fIraw\fP output emiting \fIdebug\fP messages if the
+ASCDEBUG option was given at compile time, has minor number 32.
+.TP
+.BI /dev/asc0p
+device node for output in \fIpbm\fP file format, has minor number 8.
+.TP
+.BI /dev/asc0pd
+device node for \fIpbm\fP and \fIdebug\fP mode, has minor number 40.
+.PB
+.SH DIAGNOSTICS
+.TP
+\fBASCDEBUG\fP
+When you define this name as an `option' in the kernel configuration
+you can get debug output if you access the driver with a minor number
+whose debug bit (i.e. bit 5 out of 7) is set.
+.SH SEE ALSO
+.nh
+open(2),
+ioctl(2),
+intro(2),
+read(2),
+close(2),
+cat(1),
+dd(1),
+pbm(5),
+pnm(1),
+termios(4).
+.hy
+.SH BUGS
+Ioctl support is not working yet.
+.SH AUTHOR
+Luigi Rizzo <luigi.rizzo@iet.unipi.it>
diff --git a/share/man/man4/man4.i386/meteor.4 b/share/man/man4/man4.i386/meteor.4
new file mode 100644
index 0000000000000..c4c26185e2071
--- /dev/null
+++ b/share/man/man4/man4.i386/meteor.4
@@ -0,0 +1,771 @@
+.Dd August 15, 1995
+.br
+.in +0.5i
+.Dt METEOR 4
+.Os FreeBSD
+.Sh NAME
+.Nm meteor
+.Nd video capture driver
+.Sh SYNOPSIS
+.Nm video meteor
+.Sh DESCRIPTION
+The
+.Xr meteor
+driver provides support for a PCI
+.Em video
+capture. It allows the capture of 24 bit RGB, 16 bit RGB and 16 bit YUV
+output formats.
+
+.Pp
+.Sh Meteor Driver Installation
+To use the Matrox Meteor card in your system, you need a computer
+that support the PCI (preferably the Type 2 or better) interface bus.
+It is recommended that the system has as more than 16 MB of RAM since this
+capture card directly deposits the image to system RAM.
+.Pp
+The files required for Matrox Meteor card are:
+.br
+.in +0.5i
+/sys/pci/meteor.c
+.br
+/sys/i386/include/ioctl_meteor.h (also known as:
+.br
+/usr/include/machine/ioctl_meteor.h)
+.br
+.in -0.5i
+For FreeBSD release versions 2.1 and earlier, the following patch files are also required:
+.br
+.in +0.5i
+meteor/usr/sys/i386/i386/conf.patch
+.br
+meteor/usr/sys/conf/files.patch
+.br
+meteor/sys/i386/conf/LINT.patch
+.br
+These files are available for anonymous ftp at:
+.br
+.in +0.5i
+ftp://joy.cs.ndsu.nodak.edu/pub/meteor.tgz
+.br
+.in -1.0i
+.Pp
+1) In the configuration file, add the line (as shown in
+meteor/usr/sys/i386/conf/LINT.patch):
+.Pp
+.Em device meteor0
+.Pp
+2) There is also a couple of optional parameters you may use
+.Pp
+.Em options "METEOR_ALLOC_PAGES=xxx"
+specifies the number of contiguous pages to allocate when successfully
+probed. The default number of pages allocated by the kernel is 151.
+This means that there are (151*4096) bytes available for use.
+.Pp
+.Em options METEOR_DEALLOC_PAGES
+deallocate all pages when closing the device. Note, the chance of
+contiguously re-allocating new pages are very small. The default
+behavior is to not deallocate pages.
+.Pp
+.Em options "METEOR_DEALLOC_ABOVE=xxx"
+deallocate all pages above the specified number. The default action is
+to not deallocate above any pages.
+.Pp
+3) Make and install the kernel.
+.Pp
+4) Make the special file name:
+.Pp
+.Em mknod /dev/meteor0 c <major> 0
+The major number is determined by the placement of the device in conf.c.
+The patch supplied with the driver will make the major number 67.
+.Pp
+.Sh Meteor Capture Modes
+The Meteor capture driver has three modes of capture operation.
+.Pp
+1) Conventional read(2) interface.
+.in +0.5i
+.Pp
+This mode is the easiest and slowest to use. This mode is great for
+capturing a single field at little programming cost.
+.Pp
+In this mode, the user opens the device, set the capture mode
+and size (See: METEORSETGEO ioctl call), and uses the read system
+call to load the data into a buffer.
+.Pp
+meteor_read.c; read 400x300 RGB24 into a viewable PPM file
+.Pp
+.in -0.5i
+.nf
+#include <sys/fcntl.h>
+#include <machine/ioctl_meteor.h>
+
+extern int errno;
+#define ROWS 300
+#define COLS 400
+#define SIZE (ROWS * COLS * 4)
+main()
+{
+ struct meteor_geomet geo;
+ char buf[SIZE],b[4],header[16],*p;
+ int i,o,c;
+
+ if ((i = open("/dev/meteor0", O_RDONLY)) < 0) {
+ printf("open failed: %d\n", errno);
+ exit(1);
+ }
+ /* set up the capture type and size */
+ geo.rows = ROWS;
+ geo.columns = COLS;
+ geo.frames = 1;
+ geo.oformat = METEOR_GEO_RGB24 ;
+
+ if (ioctl(i, METEORSETGEO, &geo) < 0) {
+ printf("ioctl failed: %d\n", errno);
+ exit(1);
+ }
+
+ c = METEOR_FMT_NTSC;
+
+ if (ioctl(i, METEORSFMT, &c) < 0) {
+ printf("ioctl failed: %d\n", errno);
+ exit(1);
+ }
+
+ c = METEOR_INPUT_DEV0;
+
+ if (ioctl(i, METEORSINPUT, &c) < 0) {
+ printf("ioctl failed: %d\n", errno);
+ exit(1);
+ }
+
+ if ((c=read(i, &buf[0], SIZE)) < SIZE) {
+ printf("read failed %d %d %d\n", c, i, errno);
+ close(i);
+ exit(1);
+ }
+ close(i);
+
+ if ((o = open("rgb24.ppm", O_WRONLY | O_CREAT, 0644)) < 0) {
+ printf("ppm open failed: %d\n", errno);
+ exit(1);
+ }
+
+ /* make PPM header and save to file */
+ strcpy(&header[0], "P6 400 300 255 ");
+ header[2] = header[6] = header[10] = header[14] = '\n';
+ write (o, &header[0], 15);
+ /* save the RGB data to PPM file */
+ for (p = &buf[0]; p < &buf[SIZE]; ) {
+ b[2] = *p++; /* blue */
+ b[1] = *p++; /* green */
+ b[0] = *p++; /* red */
+ *p++; /* NULL byte */
+ write(o,&b[0], 3); /* not very efficient */
+ }
+ close(o);
+ exit(0);
+}
+.if
+.Pp
+ 2) Memory mapped single capture or unsynchronized continuous capture.
+.in +0.5i
+.Pp
+The single capture mode is designed for conferencing tools such as nv.
+These tools need to control the starting of the image capture and also
+need several frames a second. The continuous capture mode is designed
+for applications that want free-running data.
+.Pp
+In this mode, the user opens the device, set the capture mode
+and size (See: METEORSETGEO ioctl call), memory maps the frame buffer
+memory into the user process space, and issues either the
+single-capture or the continuous capture call (See: METEORCAPTUR ioctl
+call) to load the data into the memory mapped buffer.
+.Pp
+As explained in the METEORCAPTUR ioctl call, the single frame capture
+ioctl will block until the capture is complete, the continuous capture
+will return immediately.
+.in -0.5i
+.Pp
+ meteor_mmap_single_continuous.c
+.Pp
+.nf
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/fcntl.h>
+#include <machine/ioctl_meteor.h>
+
+extern int errno;
+#define ROWS 480
+#define COLS 640
+#define SIZE (ROW * COLS * 2)
+main()
+{
+ struct meteor_geomet geo;
+ char buf[SIZE];
+ char *mmbuf;
+ int i,c;
+
+ if ((i = open("/dev/meteor0", O_RDONLY)) < 0) {
+ printf("open failed\n");
+ exit(1);
+ }
+
+ geo.rows = ROWS;
+ geo.columns = COLS;
+ geo.frames = 1;
+ geo.oformat = METEOR_GEO_RGB16 ;
+
+ if (ioctl(i, METEORSETGEO, &geo) < 0) {
+ printf("ioctl failed: %d\n", errno);
+ exit(1);
+ }
+
+ c = METEOR_FMT_NTSC;
+
+ if (ioctl(i, METEORSFMT, &c) < 0) {
+ printf("ioctl failed: %d\n", errno);
+ exit(1);
+ }
+
+ c = METEOR_INPUT_DEV0;
+
+ if (ioctl(i, METEORSINPUT, &c) < 0) {
+ printf("ioctl failed: %d\n", errno);
+ exit(1);
+ }
+
+ mmbuf=(char *)mmap((caddr_t)0, SIZE, PROT_READ, 0, i, (off_t)0);
+
+#ifdef SINGLE_MODE
+ /* single frame capture */
+ c = METEOR_CAP_SINGLE ;
+ ioctl(i, METEORCAPTUR, &c); /* wait for the frame */
+
+ /* directly access the frame buffer array data in mmbuf */
+#else
+ /* continuous frame capture */
+ c = METEOR_CAP_CONTINOUS ;
+ ioctl(i, METEORCAPTUR, &c); /* returns immediately */
+
+ /* directly access the frame buffer array data in mmbuf */
+
+ c = METEOR_CAP_STOP_CONT ;
+ ioctl(i, METEORCAPTUR, &c); /* close will also stop capture */
+#endif
+
+ close(i);
+ exit(0);
+}
+.if
+.Pp
+ 3) Memory mapped, multi-frame ring buffer synchronize capture.
+.Pp
+.in +0.5i
+This continuous capture mode is synchronized with the application that
+processes up to 32 frames. This gives the advantages of both single and
+continuous capture modes.
+.Pp
+The kernel notifies the application of a new data by raising an
+application defined signal. The driver also shares a structure with
+the application that allows them to communicate which frame has been
+written by the kernel and which frame has been read by the application.
+.Pp
+The shared structure starts on the first page after your data. The
+structure address can be found by calculation:
+.in +0.5i
+.Pp
+(number_rows * number_columns * pixel_depth + 4095) & 0xfffff000
+.in -0.5i
+.Pp
+ or
+.in +0.5i
+.Pp
+((number_rows * number_columns * pixel_depth + 4095)/4096) * 4096
+.in -0.5i
+.Pp
+The shared structure is of type struct meteor_mem. The two most
+important fields are called active and num_active_buf. active
+is a bitmap of frames written by the kernel. num_active_bufs is
+a count of frames marked in the active field. When a frame is read
+in by the driver, the num_active_bufs count is tested, if this
+count is below the threshold of number of active frames (value
+in meteor_mem's hiwat variable), the bit representing frame
+number in the buffer is stored in the active variable, the
+num_active_bufs is incremented, the kernel then raises the specified
+signal to activate the user application. The user application's
+responsibility when getting the signal is to check the active bitmap
+to determine the lowest active frame, use the data as the application
+desires, clear the bitmap entry for that frame, and decrement the
+num_active_bufs. If the threshold of number of active frames (hiwat)
+has been exceeded, no new frames or signal from the kernel will occur
+until the num_active_bufs is less than or equal to lowat.
+.Pp
+The driver loads the frames in a round-robin fashion. it is expected
+that the user removes them in the same order. The driver does not
+check to see if the frame is already active.
+.Pp
+The frame_size and number of frames in the buffer are also provided
+to the meteor_mem structure, but changing these fields in the
+application will not change the operation of the driver.
+.Pp
+In programming for this mode, the user opens the device, sets the
+geometry, mmaps the data/common control structure, then starts the
+continuous capture mode. A special signal catcher is required to
+process the frames as they are read by the kernel.
+.Pp
+When specifying the geometry (See: ioctl METEORSETGEO), it
+is important that the number of frames is set greater than 1.
+.in -0.5i
+.Pp
+ skeleton_capture_n.c
+.Pp
+.nf
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/fcntl.h>
+#include <sys/signal.h>
+#include <machine/ioctl_meteor.h>
+
+int video; /* made global if you wish to stop capture in signal handler */
+caddr_t data_frames;
+struct meteor_mem *common_mem;
+extern int errno;
+
+#define FRAME_MAX
+
+void
+usr2_catcher()
+{
+#ifdef SIGNAL_STOP
+ struct meteor_capframe capframe; /* for ioctl */
+#endif
+ char *frame;
+
+ /* find frame */
+ frame = (char *) (data_frames + sig_cnt * common_mem->frame_size) ;
+
+ /* add frame processing here */
+ /* deactivate frame */
+ common_mem->active &= ~(1 << (sig_cnt % 16));
+ common_mem->num_active_bufs--;
+
+ /* process next frame on next interrupt */
+ sig_cnt = ((sig_cnt+1) % FRAME_MAX);
+
+#ifdef SIGNAL_STOP
+ if (some_condition_requiring_stopping) {
+ capframe.command=METEOR_CAP_STOP_FRAMES;
+
+ if (ioctl(i, METEORCAPFRM, &capframe) < 0) {
+ printf("METEORCAPFRM failed %d\n", errno);
+ exit(1);
+ }
+ }
+#endif
+}
+
+main()
+{
+ struct meteor_geomet geo;
+ int height, width, depth, frames, size;
+ struct meteor_capframe capframe;
+
+ if ((i = open("/dev/meteor0", O_RDONLY)) < 0) {
+ printf("open failed\n");
+ exit(1);
+ }
+ printf("test %d %d\n", errno, i);
+
+ height = geo.rows = 120;
+ width= geo.columns = 320;
+ frames = geo.frames = FRAME_MAX;
+ depth = 2; /* 2 bytes per pixel for RGB*/
+
+
+ geo.oformat = METEOR_GEO_RGB16;
+
+ if (ioctl(i, METEORSETGEO, &geo) < 0) {
+ printf("METEORSETGEO failed %d\n", errno);
+ exit(1);
+ }
+
+ c = METEOR_FMT_NTSC;
+
+ if (ioctl(i, METEORSFMT, &c) < 0) {
+ printf("ioctl failed: %d\n", errno);
+ exit(1);
+ }
+
+ c = METEOR_INPUT_DEV0;
+
+ if (ioctl(i, METEORSINPUT, &c) < 0) {
+ printf("ioctl failed: %d\n", errno);
+ exit(1);
+ }
+
+ size = ((width*height*depth*frames+4095)/4096)*4096;
+ /* add one page after data for meteor_mem */
+ data_frames = mmap((caddr_t)0, size + 4096, PROT_READ | PROT_WRITE,
+ 0, i, (off_t)0);
+
+ if (data_frames == (caddr_t) -1) return (0);
+
+ /* common_mem is located at page following data */
+ common_mem = (struct meteor_mem *) (y + size);
+
+ signal(SIGUSR2, usr2_catcher); /* catch new frame message */
+
+ capframe.command=METEOR_CAP_N_FRAMES;
+ capframe.signal=SIGUSR2;
+ capframe.lowat=12; /* must be < hiwat */
+ capframe.hiwat=14; /* must be < FRAME_MAX */
+
+ /* start the sync capture */
+ if (ioctl(i, METEORCAPFRM, &capframe) < 0) {
+ printf("METEORCAPFRM failed %d\n", errno);
+ exit(1);
+ }
+
+ /* this is the background working area, or you can sleep */
+
+
+ /* to stop capture */
+ capframe.command=METEOR_CAP_STOP_FRAMES;
+
+ if (ioctl(i, METEORCAPFRM, &capframe) < 0) {
+ printf("METEORCAPFRM failed %d\n", errno);
+ exit(1);
+ }
+}
+.if
+.Pp
+.Sh Meteor IOCTL Call and Parameters
+.Pp
+The Meteor capture driver has ioctl requests for capturing, reading card
+status, for setting and reading the geometry, and for setting and reading the
+attributes.
+.Pp
+IT IS VERY IMPORTANT TO CHECK FOR ERRORS ON THESE RETURNING IOCTLs.
+Errors indicate that something is very wrong with the ioctl and the
+application should not attempt to proceed further with capturing. The
+meteor capture driver still makes attempts to stop the next capture step if
+an error occurred in a previous step but was ignored by the application
+programmer.
+.Pp
+1) ioctl requests METEORSETGEO and METEORGETGEO
+.in +0.5i
+METEORSETGEO and METEORGETGEO are used to set and read the input
+size, input device, and output format for frame capture.
+.Pp
+These ioctl routines use the meteor_geomet structure that has the
+following entries:
+.Pp
+.Bl -tag -width columns
+.It Dv rows
+number of rows (lines high) in output image
+.It Dv columns
+number of pixels in a row (width) in output image
+.It Dv frames
+number of frames in buffer. Should be 1, unless using
+the multi-framed synchronous capture mode (METEORCAPFRM)
+which REQUIRES frames to be larger than 1.
+.Pp
+Note: if rows, columns or frames is not changed, then
+the existing values are used. The system defaults
+is 640x480x1.
+.It Dv oformat
+you may choose one of the following output format:
+.Bl -tag -width METEOR_GEO_YUV_PACKED
+.It Dv METEOR_GEO_RGB16
+RGB 16 bits xrrrrrgg gggbbbbb default)
+.It Dv METEOR_GEO_RGB24
+(RBG 24 bits packed in 32 bits:
+00000000 rrrrrrrr gggggggg bbbbbbbb)
+.It Dv METEOR_GEO_YUV_PACKED
+(4-2-2 YUV 16 bits packed. byte format:
+u0 y0 v0 y1 u1 y2 v1 y3 ...)
+.It Dv METEOR_GEO_YUV_PLANER
+(4-2-2 YUV 16 bits planer format:
+rows * columns bytes of y
+rows * column / 4 bytes of even u
+rows * column / 4 bytes of even v
+rows * column / 4 bytes of odd u
+rows * column / 4 bytes of odd v)
+.El
+.El
+.Pp
+The METEORSETGEO ioctl will fail if more than one entry from a category
+is selected. It is highly recommended that a METEORSETGEO is done
+before capturing data because you cannot guarantee the initial mode
+the card.
+.Pp
+The METEORSETGEO will also attempt to reallocate a new contiguous
+kernel buffer if the new geometry exceeds the old geometry. On
+other hand, if the new geometry will fit in the existing buffer,
+the existing buffer is used.
+.Pp
+If METEORSETGEO fails the ioctl() will return a value of -1 and the
+external variable errno will be set to:
+.Pp
+.Bl -tag -width EINVAL
+.It Dv EINVAL
+invalid meteor_geomet structure pointer, rows, columns,
+frames were invalid.
+.It Dv ENOMEM
+could not allocate the contigous block.
+.El
+.in -0.5i
+.Pp
+2) ioctl requests METEORSFMT and METEORGFMT
+.in +0.5i
+.Pp
+METEORSFMT and METEORGFMT are used to set and read the camera input
+standard format.
+.Pp
+Possible formats are:
+.Bl -tag -width METEOR_FMT_AUTOMODE
+.It Dv METEOR_FMT_NTSC
+NTSC (default mode)
+.It Dv METEOR_FMT_PAL
+PAL
+.It Dv METEOR_FMT_SECAM
+SECAM
+.It Dv METEOR_FMT_AUTOMODE
+Autodetect.
+.El
+.in -0.5i
+.Pp
+3) ioctl requests METEORSINPUT and METEORGINPUT
+.in +0.5i
+.Pp
+METEORSINPUT and METEORGINPUT are used to set and read the camera
+input device. Using the DB9 connector on the Meteor card, 4 input
+devices can be connected and an input camera can be selected with this
+ioctl.
+.Pp
+Possible formats are:
+.Bl -tag -width METEOR_INPUT_DEV_SVIDEO
+.It Dv METEOR_INPUT_DEV0
+(default if none specified)
+.It Dv METEOR_INPUT_DEV_RCA
+(same as METEOR_INPUT_DEV0)
+.It Dv METEOR_INPUT_DEV1
+.It Dv METEOR_INPUT_DEV2
+.It Dv METEOR_INPUT_DEV_SVIDEO
+(same as METEOR_INPUT_DEV2)
+.El
+.in -0.5i
+.Pp
+4) ioctl request METEORSTATUS
+.in +0.5i
+.Pp
+METEORSTATUS is used to read the status of the Meteor capture card
+and returns the following information:
+.Pp
+.Bl -tag -width METEOR_STATUS_ID_MASK
+.It Dv METEOR_STATUS_ID_MASK
+4 bit ID of the SAA7196 scaler chip.
+.It Dv METEOR_STATUS_DIR
+0 = scaler uses internal source.
+.br
+1 = scaler uses external data of expansion bus.
+.It Dv METEOR_STATUS_OEF
+0 = even field detected.
+.br
+1 = odd field detected.
+.It Dv METEOR_STATUS_SVP
+VRAM Port state:
+.br
+0 = inputs HFL and INCADDR inactive.
+.br
+1 = inputs HFL and INCADDR active.
+.It Dv METEOR_STATUS_STTC
+0 = TV horizontal time constant (slow).
+.br
+1 = VCR horizontal time constant (fast).
+.It Dv METEOR_STATUS_HCLK
+0 = Horizontal Phase Lock Loop locked.
+.br
+1 = Horizontal Phase Lock Loop unlocked.
+.It Dv METEOR_STATUS_FIDT
+0 = 50 Hz Field detected.
+.br
+1 = 60 Hz Field detected.
+.It Dv METEOR_STATUS_ALTD
+0 = no line alternating color burst detected.
+.br
+1 = line alternating color burst detected
+(PAL/SECAM).
+.It Dv METEOR_STATUS_CODE
+0 = no color information detected.
+.br
+1 = color information detected.
+.El
+.in -0.5i
+.Pp
+5) ioctl request METEORCAPTUR
+.in +0.5i
+.Pp
+METEORCAPTUR is used to single frame capture or unsynchronized
+continuous capture.
+.Pp
+The single frame capture ioctl request will return only after a
+frame has been captured and transfered to the frame buffer.
+.Pp
+The unsynchronized continuous capture will return immediately and
+data is directly deposited into the buffer when it is available.
+Since this is unsynchronized, it is possible the data is being
+written by the kernel while being read by the application.
+.Pp
+These ioctl routines use the following settings:
+following entries:
+.Pp
+.Bl -tag -width METEOR_CAP_CONTINOUS
+.It Dv METEOR_CAP_SINGLE
+capture one frame
+.It Dv METEOR_CAP_CONTINOUS
+unsynchronized continuous capture
+.It Dv METEOR_CAP_STOP_CONT
+stop the unsynchronized continuous
+capture
+.El
+.Pp
+If METEORCAPTUR fails the ioctl() will return a value of -1 and the
+external variable errno will be set to:
+.Pp
+.Bl -tag -width EINVAL
+.It Dv EINVAL
+invalid capture command value
+.It Dv ENXIO
+there is not internal buffer to hold the frame.
+this indicates the previous set geometry ioctl failed.
+.It Dv EIO
+card is already capturing.
+.El
+.in -0.5i
+.Pp
+6) ioctl request METEORCAPFRM
+.in +0.5i
+.Pp
+METEORCAPFRM is used for synchronous capture of multiple frames.
+.Pp
+This ioctl routines use the meteor_capture structure that has the
+following entries:
+.Pp
+.Bl -tag -width command
+.It Dv command
+possible values for command are:
+.Bl -tag -width METEOR_CAP_STOP_FRAMES
+.It Dv METEOR_CAP_STOP_FRAMES stop the capture does not use the
+other variable in structure.
+.It Dv METEOR_CAP_N_FRAMES start the capture using the other
+variables in the structure as inputs
+.El
+.It Dv signal
+signal to send to application when a new
+frame has been captured. This signal will
+only be raised if the captured frame is saved.
+.It Dv lowat
+see below
+.It Dv hiwat
+see below
+.El
+.Pp
+When a new frame is completed, the driver checks the current unread
+frame count stored in shared variable (the shared variable are stored
+in the meteor_mem structure) num_active_buf, if the count is larger
+than hiwat, the driver will not store any new frames and will not
+send capture signal to the user application until the num_active_buf
+is lower than lowat.
+.Pp
+If METEORCAPFRM fails the ioctl() will return a value of -1 and the
+external variable errno will be set to:
+.Pp
+.Bl -tag -width EINVAL
+.It Dv EINVAL
+invalid meteor_geomet structure pointer or bad command.
+.It Dv ENXIO
+there is not internal buffer to hold the frame.
+this indicates the previous set geometry ioctl failed.
+.It Dv EIO
+card is already capturing.
+.El
+.in -0.5i
+.Pp
+7) ioctl requests METEORSCHCV and METEORGCHCV
+.in +0.5i
+.Pp
+METEORSCHCV and METEORGCHCV are used to set and get the chrominance
+gain control and effects the UV output amplitude.
+.Pp
+If METEORSCHCV or METEORGCHCV fails the ioctl() will return a value
+of -1 and the external variable errno will be set to:
+.Pp
+.Bl -tag -width EINVAL
+.It Dv EINVAL
+EINVAL
+invalid unsigned char pointer.
+.El
+.in -0.5i
+.Pp
+8) ioctl requests METEORGHUE and METEORSHUE
+.in +0.5i
+.Pp
+METEORGHUE and METEORSHUE are used to get and set the hue. The
+signed character has legal values are from +127 which represent
++178.6 degrees to -128 which represents -180 degrees.
+.Pp
+If METEORGHUE or METEORSHUE fails the ioctl() will return a value of
+-1 and the external variable errno will be set to:
+.Pp
+.Bl -tag -width EINVAL
+.It Dv EINVAL
+invalid signed char pointer.
+.El
+.in -0.5i
+.Pp
+9) ioctl requests METEORSCOUNT and METEORGCOUNT
+.in +0.5i
+.Pp
+METEORGCOUNT is used to get the count of frame errors, DMA errors and
+count of the number of frames captured that have occurred since
+the device was opened. METEORSCOUNT can be used to reinitialize the
+counters.
+.Pp
+This ioctl routines use the meteor_counts structure that has the
+following entries:
+.Pp
+.Bl -tag -width frame_count
+.It Dv fifo_errors
+number of FIFO errors since device was opened.
+.It Dv dma_errors number of DMA errors since device was opened.
+
+.It Dv frame_count number of frames captured since device was opened.
+.El
+.Pp
+If METEORSCOUNT or METEORGCOUNT fails the ioctl() will return a value
+of -1 and the external variable errno will be set to:
+.Bl -tag -width EINVAL
+.It Dv EINVAL
+invalid meteor_counts structure pointer.
+.El
+.in -0.5i
+.Pp
+.Sh Known Bugs:
+.in +0.5i
+.Pp
+1) IIC register is difficult to set. We got around that by adding a long
+wait at each IIC register write.
+.Pp
+2) We had difficulties getting the Meteor capture card to work on systems
+that used NCR chipset SCSI cards. It is possible that the Meteor and NCR SCSI
+could work together using the newer TRITON motherboards.
+.in -0.5i
+.Pp
+.Sh Authors:
+.Pp
+.Bl -tag -width Mark_Tinguely
+.It Dv Jim Lowe
+(james@miller.cs.uwm.edu)
+.It Dv Mark Tinguely
+(tinguely@plains.nodak.edu)
+.El
diff --git a/share/mk/bsd.sgml.mk b/share/mk/bsd.sgml.mk
new file mode 100644
index 0000000000000..799dfdb0c5535
--- /dev/null
+++ b/share/mk/bsd.sgml.mk
@@ -0,0 +1,151 @@
+# bsd.sgml.mk - 8 Sep 1995 John Fieber
+# This file is in the public domain.
+#
+# $Id: bsd.sgml.mk,v 1.1 1995/09/08 19:23:19 jfieber Exp $
+
+.if exists(${.CURDIR}/../Makefile.inc)
+.include "${.CURDIR}/../Makefile.inc"
+.endif
+
+# FORMATS indicates which output formats will be generated. See
+# the sgmlfmt(1) man page for a list of valid formats.
+# If FORMATS is empty, nothing will be built or installed.
+# Use SGMLOPTS to pass extra flags to sgmlfmt(1).
+
+FORMATS?= ascii html
+SGMLFLAGS+= ${SGMLOPTS}
+
+VOLUME?= ${.CURDIR:T}
+DOC?= ${.CURDIR:T}
+BINDIR?= /usr/share/doc
+SRCDIR?= ${.CURDIR}
+DISTRIBUTION?= doc
+SGMLFMT?= sgmlfmt
+LPR?= lpr
+
+DOCS= ${FORMATS:S/^/${DOC}./g}
+
+.MAIN: all
+all: ${DOCS}
+
+# If FORMATS is empty, do nothing
+.if empty(FORMATS)
+${DOC}. install- print- clean-:
+.endif
+
+.if !target(obj)
+.if defined(NOOBJ)
+obj:
+.else
+obj:
+ @cd ${.CURDIR}; rm -f obj; \
+ here=`pwd`; dest=/usr/obj`echo $$here | sed 's,^/usr/src,,'`; \
+ ${ECHO} "$$here -> $$dest"; ln -s $$dest obj; \
+ if test -d /usr/obj -a ! -d $$dest; then \
+ mkdir -p $$dest; \
+ else \
+ true; \
+ fi;
+.endif
+.endif
+
+clean: ${FORMATS:S/^/clean-/g}
+ rm -f [eE]rrs mklog
+
+cleandir: clean
+ cd ${.CURDIR}; rm -rf obj
+
+install: beforeinstall realinstall afterinstall
+
+.if !target(beforeinstall)
+beforeinstall:
+
+.endif
+.if !target(afterinstall)
+afterinstall:
+
+.endif
+.if !target(maninstall)
+maninstall:
+
+.endif
+
+realinstall: ${FORMATS:S/^/install-/g}
+
+.if !target(print)
+print: ${FORMATS:S/^/print-/g}
+
+.endif
+
+spell: ${SRCS}
+ (cd ${.CURDIR}; spell ${SRCS} ) | sort | \
+ comm -23 - ${.CURDIR}/spell.ok > ${DOC}.spell
+
+.if !target(distribute)
+distribute:
+ cd ${.CURDIR} ; $(MAKE) install DESTDIR=${DISTDIR}/${DISTRIBUTION} SHARED=copies
+.endif
+
+.if !target(depend)
+depend:
+
+.endif
+
+
+# For each FORMATS type, define a build, install, clean and print target.
+# Note that there is special case handling for html targets
+# because the number of files generated is generally not possible
+# to predict outside of sgmlfmt(1).
+
+.for _XFORMAT in ${FORMATS}
+
+# XXX This doesn't work:
+# .if ${_FORMAT} == "foobar"
+# but defining another variable does: (?!?!)
+
+_FORMAT = ${_XFORMAT}
+
+.if !target(print-${_FORMAT})
+.if ${_FORMAT} == "html"
+print-${_FORMAT}:
+
+.else
+print-${_FORMAT}: ${DOC}.${_FORMAT}
+ ${LPR} -P${.TARGET:S/print-//} ${DOC}.${_FORMAT}
+
+.endif
+.endif
+
+.if !target(install-${_FORMAT})
+.if ${_FORMAT} == "html"
+install-${_FORMAT}: ${DOC}.${_FORMAT}
+ ${INSTALL} ${COPY} -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} \
+ *.${.TARGET:S/install-//} ${DESTDIR}${BINDIR}/${VOLUME}
+
+.else
+install-${_FORMAT}: ${DOC}.${_FORMAT}
+ ${INSTALL} ${COPY} -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} \
+ ${DOC}.${.TARGET:S/install-//} ${DESTDIR}${BINDIR}/${VOLUME}
+
+.endif
+.endif
+
+.if !target(${DOC}.${_FORMAT})
+${DOC}.${_FORMAT}: ${SRCS}
+ ${SGMLFMT} -f ${.TARGET:S/${DOC}.//} ${SGMLFLAGS} ${.CURDIR}/${DOC}.sgml
+
+.endif
+
+.if !target(clean-${_FORMAT})
+.if ${_FORMAT} == "html"
+clean-${_FORMAT}:
+ rm -f *.${.TARGET:S/clean-//}
+
+.else
+clean-${_FORMAT}:
+ rm -f ${DOC}.${.TARGET:S/clean-//}
+
+.endif
+.endif
+
+.endfor
diff --git a/sys/gnu/i386/isa/dgb.c b/sys/gnu/i386/isa/dgb.c
new file mode 100644
index 0000000000000..3d227355ca821
--- /dev/null
+++ b/sys/gnu/i386/isa/dgb.c
@@ -0,0 +1,2076 @@
+/*-
+ * dgb.c $Id: dgb.c,v 1.1 1995/09/03 19:52:52 jkh Exp $
+ *
+ * Copyright (C) 1995 by Serge Babkin <babkin@hq.icb.chel.su>
+ *
+ * Digiboard driver.
+ *
+ * Stage 1. "Better than nothing".
+ *
+ * Based on sio driver by Bruce Evans and on Linux driver by Troy
+ * De Jongh <troyd@digibd.com> or <troyd@skypoint.com>
+ * which is under GNU General Public License version 2 so this driver
+ * is forced to be under GPL 2 too.
+ *
+ * Serge Babkin does not guarantee that this file is totally correct
+ * for any given task and users of this file must accept responsibility
+ * for any damage that occurs from the application of this file.
+ *
+ * Written by Serge Babkin,
+ * Joint Stock Commercial Bank "Chelindbank"
+ * (Chelyabinsk, Russia)
+ * babkin@hq.icb.chel.su
+ */
+
+#include "dgb.h"
+
+#if NDGB > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/reboot.h>
+#include <sys/ioctl.h>
+#define TTYDEFCHARS /* XXX TK2.0 */
+#include <sys/tty.h>
+#undef TTYDEFCHARS
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/conf.h>
+#include <sys/dkstat.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/syslog.h>
+#include <sys/devconf.h>
+#include <sys/types.h>
+
+#include <machine/clock.h>
+
+#include <i386/isa/icu.h> /* XXX just to get at `imen' */
+#include <i386/isa/isa.h>
+#include <i386/isa/isa_device.h>
+
+#include <vm/vm.h>
+
+#include "dgreg.h"
+#include "dgbios.h"
+#include "dgfep.h"
+
+/*
+ * XXX temporary kludges for 2.0 (XXX TK2.0).
+ */
+#if defined (__FreeBSD__) && __FreeBSD__ < 2
+#define TS_RTS_IFLOW 0
+#define TSA_CARR_ON(tp) ((void *)&(tp)->t_rawq)
+#define TSA_OCOMPLETE(tp) ((void *)&(tp)->t_outq)
+#define TSA_OLOWAT(tp) ((void *)&(tp)->t_outq)
+
+#define TTY_BI TTY_FE /* XXX */
+#define TTY_OE TTY_PE /* XXX */
+#endif
+
+#define CALLOUT_MASK 0x80
+#define CONTROL_MASK 0x60
+#define CONTROL_INIT_STATE 0x20
+#define CONTROL_LOCK_STATE 0x40
+#define UNIT_MASK 0x30000
+#define PORT_MASK 0xF
+#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
+#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
+#define MINOR_TO_UNIT(mynor) (((mynor) & UNIT_MASK)>>16)
+#define MINOR_TO_PORT(mynor) ((mynor) & 0xF)
+
+/*
+ * Input buffer watermarks.
+ * The external device is asked to stop sending when the buffer exactly reaches
+ * high water, or when the high level requests it.
+ * The high level is notified immediately (rather than at a later clock tick)
+ * when this watermark is reached.
+ * The buffer size is chosen so the watermark should almost never be reached.
+ * The low watermark is invisibly 0 since the buffer is always emptied all at
+ * once.
+ */
+#define RS_IHIGHWATER (3 * RS_IBUFSIZE / 4)
+
+/*
+ * com state bits.
+ * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher
+ * than the other bits so that they can be tested as a group without masking
+ * off the low bits.
+ *
+ * The following com and tty flags correspond closely:
+ * CS_BUSY = TS_BUSY (maintained by comstart() and comflush())
+ * CS_TTGO = ~TS_TTSTOP (maintained by comstart() and siostop())
+ * CS_CTS_OFLOW = CCTS_OFLOW (maintained by comparam())
+ * CS_RTS_IFLOW = CRTS_IFLOW (maintained by comparam())
+ * TS_FLUSH is not used.
+ * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON.
+ * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state).
+ */
+#define CS_BUSY 0x80 /* output in progress */
+#define CS_TTGO 0x40 /* output not stopped by XOFF */
+#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
+#define CS_CHECKMSR 1 /* check of MSR scheduled */
+#define CS_CTS_OFLOW 2 /* use CTS output flow control */
+#define CS_DTR_OFF 0x10 /* DTR held off */
+#define CS_ODONE 4 /* output completed */
+#define CS_RTS_IFLOW 8 /* use RTS input flow control */
+
+static char const * const error_desc[] = {
+#define CE_OVERRUN 0
+ "silo overflow",
+#define CE_INTERRUPT_BUF_OVERFLOW 1
+ "interrupt-level buffer overflow",
+#define CE_TTY_BUF_OVERFLOW 2
+ "tty-level buffer overflow",
+};
+
+#define CE_NTYPES 3
+#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
+
+/* types. XXX - should be elsewhere */
+typedef u_int Port_t; /* hardware port */
+typedef u_char bool_t; /* boolean */
+
+/* digiboard port structure */
+struct dgb_p {
+ bool_t status;
+
+ u_char unit; /* board unit number */
+ u_char pnum; /* port number */
+ u_char omodem; /* FEP output modem status */
+ u_char imodem; /* FEP input modem status */
+ u_char modemfake; /* Modem values to be forced */
+ u_char modem; /* Force values */
+ u_char hflow;
+ u_char dsr;
+ u_char dcd;
+ u_char stopc;
+ u_char startc;
+ u_char stopca;
+ u_char startca;
+ u_char fepstopc;
+ u_char fepstartc;
+ u_char fepstopca;
+ u_char fepstartca;
+ u_char txwin;
+ u_char rxwin;
+ ushort fepiflag;
+ ushort fepcflag;
+ ushort fepoflag;
+ ushort txbufhead;
+ ushort txbufsize;
+ ushort rxbufhead;
+ ushort rxbufsize;
+ int close_delay;
+ int count;
+ int blocked_open;
+ int event;
+ int asyncflags;
+ u_long statusflags;
+ u_char *txptr;
+ u_char *rxptr;
+ struct board_chan *brdchan;
+ struct tty *tty;
+
+ bool_t active_out; /* nonzero if the callout device is open */
+ int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
+ u_int wopeners; /* # processes waiting for DCD in open() */
+
+ /*
+ * The high level of the driver never reads status registers directly
+ * because there would be too many side effects to handle conveniently.
+ * Instead, it reads copies of the registers stored here by the
+ * interrupt handler.
+ */
+ u_char last_modem_status; /* last MSR read by intr handler */
+ u_char prev_modem_status; /* last MSR handled by high level */
+
+ struct tty *tp; /* cross reference */
+
+ /* Initial state. */
+ struct termios it_in; /* should be in struct tty */
+ struct termios it_out;
+
+ /* Lock state. */
+ struct termios lt_in; /* should be in struct tty */
+ struct termios lt_out;
+
+ /* flags of state, are used in sleep() too */
+ u_char closing; /* port is being closed now */
+ u_char draining; /* port is being drained now */
+ u_char used; /* port is being used now */
+ u_char mustdrain; /* data must be waited to drain in dgbparam() */
+};
+
+/* Digiboard per-board structure */
+struct dgb_softc {
+ /* struct board_info */
+ u_char status; /* status: DISABLED/ENABLED */
+ u_char unit; /* unit number */
+ u_char type; /* type of card: PCXE, PCXI, PCXEVE */
+ u_char altpin; /* do we need alternate pin setting ? */
+ ushort numports; /* number of ports on card */
+ ushort port; /* I/O port */
+ u_char *vmem; /* virtual memory address */
+ long pmem; /* physical memory address */
+ int mem_seg; /* internal memory segment */
+ struct dgb_p *ports; /* pointer to array of port descriptors */
+ struct tty *ttys; /* pointer to array of TTY structures */
+ volatile struct global_data *mailbox;
+ };
+
+
+struct dgb_softc dgb_softc[NDGB];
+
+/*
+ * The public functions in the com module ought to be declared in a com-driver
+ * system header.
+ */
+
+/* Interrupt handling entry points. */
+void dgbintr __P((int unit));
+void dgbpoll __P((void *unit_c));
+
+/* Device switch entry points. */
+int dgbopen __P((dev_t dev, int oflags, int devtype,
+ struct proc *p));
+int dgbclose __P((dev_t dev, int fflag, int devtype,
+ struct proc *p));
+int dgbread __P((dev_t dev, struct uio *uio, int ioflag));
+int dgbwrite __P((dev_t dev, struct uio *uio, int ioflag));
+int dgbioctl __P((dev_t dev, int cmd, caddr_t data,
+ int fflag, struct proc *p));
+void dgbstop __P((struct tty *tp, int rw));
+#define dgbreset noreset
+int dgbselect __P((dev_t dev, int rw, struct proc *p));
+#define dgbmmap nommap
+#define dgbstrategy nostrategy
+
+static int dgbattach __P((struct isa_device *dev));
+static int dgbprobe __P((struct isa_device *dev));
+
+static void fepcmd(struct dgb_p *port, int cmd, int op1, int op2,
+ int ncmds, int bytecmd);
+
+static void dgbstart __P((struct tty *tp));
+static int dgbparam __P((struct tty *tp, struct termios *t));
+static void dgbhardclose __P((struct dgb_p *port));
+static void dgb_drain_or_flush __P((struct dgb_p *port));
+static int dgbdrain __P((struct dgb_p *port));
+static void dgb_pause __P((void *chan));
+
+
+struct isa_driver dgbdriver = {
+ dgbprobe, dgbattach, "dgb",0
+};
+
+static speed_t dgbdefaultrate = TTYDEF_SPEED;
+static u_int dgb_events; /* input chars + weighted output completions */
+static int dgbmajor;
+
+static struct speedtab dgbspeedtab[] = {
+ 0, 0, /* old (sysV-like) Bx codes */
+ 50, 1,
+ 75, 2,
+ 110, 3,
+ 134, 4,
+ 150, 5,
+ 200, 6,
+ 300, 7,
+ 600, 8,
+ 1200, 9,
+ 1800, 10,
+ 2400, 11,
+ 4800, 12,
+ 9600, 13,
+ 19200, 14,
+ 38400, 15,
+ 57600, (02000 | 1), /* B50 & fast baud table */
+ 115200, (02000 | 2), /* B100 & fast baud table */
+ -1, -1
+};
+
+#ifdef DEBUG
+ int dgbdebug=1;
+#else
+ int dgbdebug=0;
+#endif
+
+static int polltimeout=0;
+
+static int setwin(struct dgb_softc *sc, unsigned addr);
+static int setinitwin(struct dgb_softc *sc, unsigned addr);
+static void hidewin(struct dgb_softc *sc);
+
+static inline int
+setwin(sc,addr)
+ struct dgb_softc *sc;
+ unsigned int addr;
+{
+ if(sc->type==PCXEVE) {
+ outb(sc->port+1, FEPWIN|(addr>>13));
+ DPRINT3("dgb%d: switched to window 0x%x\n",sc->unit,addr>>13);
+ return (addr & 0x1FFF);
+ } else {
+ outb(sc->port,FEPMEM);
+ return addr;
+ }
+}
+
+static inline int
+setinitwin(sc,addr)
+ struct dgb_softc *sc;
+ unsigned int addr;
+{
+ if(sc->type==PCXEVE) {
+ outb(sc->port+1, FEPWIN|(addr>>13));
+ DPRINT3("dgb%d: switched to window 0x%x\n",sc->unit,addr>>13);
+ return (addr & 0x1FFF);
+ } else {
+ outb(sc->port,inb(sc->port)|FEPMEM);
+ return addr;
+ }
+}
+
+static inline void
+hidewin(sc)
+ struct dgb_softc *sc;
+{
+ if(sc->type==PCXEVE)
+ outb(sc->port+1, 0);
+ else
+ outb(sc->port,0);
+}
+
+static inline void
+towin(sc,win)
+ struct dgb_softc *sc;
+ int win;
+{
+ if(sc->type==PCXEVE) {
+ outb(sc->port+1, win);
+ } else {
+ outb(sc->port,FEPMEM);
+ }
+}
+
+static int
+dgbprobe(dev)
+ struct isa_device *dev;
+{
+ struct dgb_softc *sc= &dgb_softc[dev->id_unit];
+ int i, v, t;
+ u_long win_size; /* size of vizible memory window */
+ u_char *mem;
+ int addr;
+ int unit=dev->id_unit;
+
+ sc->unit=dev->id_unit;
+ sc->port=dev->id_iobase;
+
+ if(dev->id_flags & DGBFLAG_ALTPIN)
+ sc->altpin=1;
+ else
+ sc->altpin=0;
+
+ /* left 24 bits only (ISA address) */
+ sc->pmem=((long)dev->id_maddr & 0xFFFFFF);
+
+ DPRINT4("dgb%d: port 0x%x mem 0x%x\n",unit,sc->port,sc->pmem);
+
+ outb(sc->port, FEPRST);
+ sc->status=DISABLED;
+
+ for(i=0; i< 1000; i++) {
+ DELAY(1);
+ if( (inb(sc->port) & FEPMASK) == FEPRST ) {
+ sc->status=ENABLED;
+ DPRINT3("dgb%d: got reset after %d us\n",unit,i);
+ break;
+ }
+ }
+
+ if(sc->status!=ENABLED) {
+ DPRINT2("dgb%d: failed to respond\n",dev->id_unit);
+ return 0;
+ }
+
+ /* check type of card and get internal memory characteristics */
+
+ v=inb(sc->port);
+
+ if( v & 0x1 ) {
+ switch( v&0x30 ) {
+ case 0:
+ sc->mem_seg=0xF000;
+ win_size=0x10000;
+ printf("dgb%d: PC/Xi 64K\n",dev->id_unit);
+ break;
+ case 0x10:
+ sc->mem_seg=0xE000;
+ win_size=0x20000;
+ printf("dgb%d: PC/Xi 128K\n",dev->id_unit);
+ break;
+ case 0x20:
+ sc->mem_seg=0xC000;
+ win_size=0x40000;
+ printf("dgb%d: PC/Xi 256K\n",dev->id_unit);
+ break;
+ default: /* case 0x30: */
+ sc->mem_seg=0x8000;
+ win_size=0x80000;
+ printf("dgb%d: PC/Xi 512K\n",dev->id_unit);
+ break;
+ }
+ sc->type=PCXI;
+ } else {
+ outb(sc->port, 1);
+ v=inb(sc->port);
+
+ if( v & 0x1 ) {
+ printf("dgb%d: PC/Xm isn't supported\n",dev->id_unit);
+ sc->status=DISABLED;
+ return 0;
+ }
+
+ sc->mem_seg=0xF000;
+
+ if(dev->id_flags==DGBFLAG_NOWIN || ( v&0xC0 )==0) {
+ win_size=0x10000;
+ printf("dgb%d: PC/Xe 64K\n",dev->id_unit);
+ sc->type=PCXE;
+ } else {
+ win_size=0x2000;
+ printf("dgb%d: PC/Xe 64/8K (windowed)\n",dev->id_unit);
+ sc->type=PCXEVE;
+ if((u_long)sc->pmem & ~0xFFE000) {
+ printf("dgb%d: warning: address 0x%x truncated to 0x%x\n",
+ dev->id_unit, sc->pmem,
+ (long)sc->pmem & 0xFFE000);
+
+ dev->id_maddr= (u_char *)( (long)sc->pmem & 0xFFE000 );
+ }
+ }
+ }
+
+ /* save size of vizible memory segment */
+ dev->id_msize=win_size;
+
+ /* map memory */
+ dev->id_maddr=sc->vmem=pmap_mapdev(sc->pmem,dev->id_msize);
+
+ outb(sc->port, FEPCLR); /* drop RESET */
+
+ return 4; /* we need I/O space of 4 ports */
+}
+
+static struct kern_devconf kdc_dgb[NDGB] = { {
+ 0, 0, 0, /* filled in by dev_attach */
+ "dgb", 0, { MDDT_ISA, 0, "tty" },
+ isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
+ &kdc_isa0, /* parent */
+ 0, /* parentdata */
+ DC_UNCONFIGURED,
+ "DigiBoard multiport card"
+} };
+
+static void
+dgbregisterdev(id)
+ struct isa_device *id;
+{
+ int unit;
+
+ unit = id->id_unit;
+ if (unit != 0)
+ kdc_dgb[unit] = kdc_dgb[0];
+ kdc_dgb[unit].kdc_unit = unit;
+ kdc_dgb[unit].kdc_isa = id;
+
+ /* now we assume that multiport is always 'open' for simplicity */
+ kdc_dgb[unit].kdc_state = DC_BUSY;
+ dev_attach(&kdc_dgb[unit]);
+}
+
+
+static int
+dgbattach(dev)
+ struct isa_device *dev;
+{
+ int unit=dev->id_unit;
+ struct dgb_softc *sc= &dgb_softc[dev->id_unit];
+ int i, t;
+ u_char *mem;
+ u_char *ptr;
+ int addr;
+ struct dgb_p *port;
+ struct board_chan *bc;
+ struct global_data *gd;
+ int shrinkmem;
+ int nfails;
+ ushort *pstat;
+ int lowwater;
+
+ if(sc->status!=ENABLED) {
+ DPRINT2("dbg%d: try to attach a disabled card\n",unit);
+ return 0;
+ }
+
+ mem=sc->vmem;
+
+ DPRINT3("dgb%d: internal memory segment 0x%x\n",unit,sc->mem_seg);
+
+ outb(sc->port, FEPRST); DELAY(1);
+
+ for(i=0; (inb(sc->port) & FEPMASK) != FEPRST ; i++) {
+ if(i>10000) {
+ printf("dgb%d: 1st reset failed\n",dev->id_unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+ DELAY(1);
+ }
+
+ DPRINT3("dgb%d: got reset after %d us\n",unit,i);
+
+ /* for PCXEVE set up interrupt and base address */
+
+ if(sc->type==PCXEVE) {
+ t=(((u_long)sc->pmem>>8) & 0xFFE0) | 0x10 /* enable windowing */;
+
+ /* IRQ isn't used */
+#if 0
+ switch(dev->id_irq) {
+ case IRQ3:
+ t|=0x1;
+ break;
+ case IRQ5:
+ t|=2;
+ break;
+ case IRQ7:
+ t|=3;
+ break;
+ case IRQ10:
+ t|=4;
+ break;
+ case IRQ11:
+ t|=5;
+ break;
+ case IRQ12:
+ t|=6;
+ break;
+ case IRQ15:
+ t|=7;
+ break;
+ default:
+ printf("dgb%d: wrong IRQ mask 0x%x\n",dev->id_unit,dev->id_irq);
+ sc->status=DISABLED;
+ return 0;
+ }
+#endif
+
+ outb(sc->port+2,t & 0xFF);
+ outb(sc->port+3,t>>8);
+ } else if(sc->type==PCXE) {
+ t=(((u_long)sc->pmem>>8) & 0xFFE0) /* disable windowing */;
+ outb(sc->port+2,t & 0xFF);
+ outb(sc->port+3,t>>8);
+ }
+
+
+ if(sc->type==PCXI || sc->type==PCXE) {
+ outb(sc->port, FEPRST|FEPMEM); DELAY(1);
+
+ for(i=0; (inb(sc->port) & FEPMASK) != (FEPRST|FEPMEM) ; i++) {
+ if(i>10000) {
+ printf("dgb%d: 2nd reset failed\n",dev->id_unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+ DELAY(1);
+ }
+
+ DPRINT3("dgb%d: got memory after %d us\n",unit,i);
+ }
+
+ mem=sc->vmem;
+
+ /* very short memory test */
+
+ addr=setinitwin(sc,BOTWIN);
+ *(u_long *)(mem+addr) = 0xA55A3CC3;
+ if(*(u_long *)(mem+addr)!=0xA55A3CC3) {
+ printf("dgb%d: 1st memory test failed\n",dev->id_unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+
+ addr=setinitwin(sc,TOPWIN);
+ *(u_long *)(mem+addr) = 0x5AA5C33C;
+ if(*(u_long *)(mem+addr)!=0x5AA5C33C) {
+ printf("dgb%d: 2nd memory test failed\n",dev->id_unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+
+ addr=setinitwin(sc,BIOSCODE+((0xF000-sc->mem_seg)<<4));
+ *(u_long *)(mem+addr) = 0x5AA5C33C;
+ if(*(u_long *)(mem+addr)!=0x5AA5C33C) {
+ printf("dgb%d: 3rd (BIOS) memory test failed\n",dev->id_unit);
+ }
+
+ addr=setinitwin(sc,MISCGLOBAL);
+ for(i=0; i<16; i++) {
+ mem[addr+i]=0;
+ }
+
+ if(sc->type==PCXI || sc->type==PCXE) {
+
+ addr=BIOSCODE+((0xF000-sc->mem_seg)<<4);
+
+ DPRINT3("dgb%d: BIOS local address=0x%x\n",unit,addr);
+
+ ptr= mem+addr;
+
+ for(i=0; i<pcxx_nbios; i++, ptr++)
+ *ptr = pcxx_bios[i];
+
+ ptr= mem+addr;
+
+ nfails=0;
+ for(i=0; i<pcxx_nbios; i++, ptr++)
+ if( *ptr != pcxx_bios[i] ) {
+ DPRINT5("dgb%d: wrong code in BIOS at addr 0x%x : \
+0x%x instead of 0x%x\n", unit, ptr-(mem+addr), *ptr, pcxx_bios[i] );
+
+ if(++nfails>=5) {
+ printf("dgb%d: 4th memory test (BIOS load) fails\n",unit);
+ break;
+ }
+ }
+
+ outb(sc->port,FEPMEM);
+
+ for(i=0; (inb(sc->port) & FEPMASK) != FEPMEM ; i++) {
+ if(i>10000) {
+ printf("dgb%d: BIOS start failed\n",dev->id_unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+ DELAY(1);
+ }
+
+ DPRINT3("dgb%d: reset dropped after %d us\n",unit,i);
+
+ for(i=0; i<200000; i++) {
+ if( *((ushort *)(mem+MISCGLOBAL)) == *((ushort *)"GD") )
+ goto load_fep;
+ DELAY(1);
+ }
+ printf("dgb%d: BIOS download failed\n",dev->id_unit);
+ DPRINT4("dgb%d: code=0x%x must be 0x%x\n",
+ dev->id_unit,
+ *((ushort *)(mem+MISCGLOBAL)),
+ *((ushort *)"GD"));
+
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+
+ if(sc->type==PCXEVE) {
+ /* set window 7 */
+ outb(sc->port+1,0xFF);
+
+ ptr= mem+(BIOSCODE & 0x1FFF);
+
+ for(i=0; i<pcxx_nbios; i++)
+ *ptr++ = pcxx_bios[i];
+
+ ptr= mem+(BIOSCODE & 0x1FFF);
+
+ nfails=0;
+ for(i=0; i<pcxx_nbios; i++, ptr++)
+ if( *ptr != pcxx_bios[i] ) {
+ DPRINT5("dgb%d: wrong code in BIOS at addr 0x%x : \
+0x%x instead of 0x%x\n", unit, ptr-(mem+addr), *ptr, pcxx_bios[i] );
+
+ if(++nfails>=5) {
+ printf("dgb%d: 4th memory test (BIOS load) fails\n",unit);
+ break;
+ }
+ }
+
+ outb(sc->port,FEPCLR);
+
+ setwin(sc,0);
+
+ for(i=0; (inb(sc->port) & FEPMASK) != FEPCLR ; i++) {
+ if(i>10000) {
+ printf("dgb%d: BIOS start failed\n",dev->id_unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+ DELAY(1);
+ }
+
+ DPRINT3("dgb%d: reset dropped after %d us\n",unit,i);
+
+ addr=setwin(sc,MISCGLOBAL);
+
+ for(i=0; i<200000; i++) {
+ if(*(ushort *)(mem+addr)== *(ushort *)"GD")
+ goto load_fep;
+ DELAY(1);
+ }
+ printf("dgb%d: BIOS download failed\n",dev->id_unit);
+ DPRINT5("dgb%d: Error#(0x%x,0x%x) code=0x%x\n",
+ dev->id_unit,
+ *(ushort *)(mem+0xC12),
+ *(ushort *)(mem+0xC14),
+ *(ushort *)(mem+MISCGLOBAL));
+
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+
+load_fep:
+ DPRINT2("dgb%d: BIOS loaded\n",dev->id_unit);
+
+ addr=setwin(sc,FEPCODE);
+
+ ptr= mem+addr;
+
+ for(i=0; i<pcxx_ncook; i++)
+ *ptr++ = pcxx_cook[i];
+
+ addr=setwin(sc,MBOX);
+ *(ushort *)(mem+addr+ 0)=2;
+ *(ushort *)(mem+addr+ 2)=sc->mem_seg+FEPCODESEG;
+ *(ushort *)(mem+addr+ 4)=0;
+ *(ushort *)(mem+addr+ 6)=FEPCODESEG;
+ *(ushort *)(mem+addr+ 8)=0;
+ *(ushort *)(mem+addr+10)=pcxx_ncook;
+
+ outb(sc->port,FEPMEM|FEPINT); /* send interrupt to BIOS */
+ outb(sc->port,FEPMEM);
+
+ for(i=0; *(ushort *)(mem+addr)!=0; i++) {
+ if(i>200000) {
+ printf("dgb%d: FEP code download failed\n",unit);
+ DPRINT3("dgb%d: code=0x%x must be 0\n", unit,
+ *(ushort *)(mem+addr));
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+ }
+
+ DPRINT2("dgb%d: FEP code loaded\n",unit);
+
+ *(ushort *)(mem+setwin(sc,FEPSTAT))=0;
+ addr=setwin(sc,MBOX);
+ *(ushort *)(mem+addr+0)=1;
+ *(ushort *)(mem+addr+2)=FEPCODESEG;
+ *(ushort *)(mem+addr+4)=0x4;
+
+ outb(sc->port,FEPINT); /* send interrupt to BIOS */
+ outb(sc->port,FEPCLR);
+
+ addr=setwin(sc,FEPSTAT);
+ for(i=0; *(ushort *)(mem+addr)!= *(ushort *)"OS"; i++) {
+ if(i>200000) {
+ printf("dgb%d: FEP/OS start failed\n",dev->id_unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+ }
+
+ DPRINT2("dgb%d: FEP/OS started\n",dev->id_unit);
+
+ sc->numports= *(ushort *)(mem+setwin(sc,NPORT));
+
+ printf("dgb%d: %d ports\n",unit,sc->numports);
+
+ if(sc->numports > MAX_DGB_PORTS) {
+ printf("dgb%d: too many ports\n",unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+
+ addr=setwin(sc,PORTBASE);
+ pstat=(ushort *)(mem+addr);
+
+ for(i=0; i<32 && pstat[i]; i++);
+
+ if(i!=sc->numports) {
+ printf("dgb%d: %d ports are shown as valid ones\n",unit,i);
+ if(i<sc->numports)
+ sc->numports=i;
+ printf("dgb%d: %d ports will be used\n",unit,sc->numports);
+ }
+
+ MALLOC(sc->ports, struct dgb_p *, sizeof(struct dgb_p)*sc->numports,
+ M_TTYS, M_NOWAIT);
+
+ if(sc->ports==0) {
+ printf("dgb%d: unable to malloc the per port structures\n",unit);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+
+ bzero(sc->ports, sizeof(struct dgb_p)*sc->numports);
+
+ MALLOC(sc->ttys, struct tty *, sizeof(struct tty)*sc->numports,
+ M_TTYS, M_NOWAIT);
+
+ if(sc->ttys==0) {
+ printf("dgb%d: unable to malloc the tty structures\n",unit);
+ FREE(sc->ttys, M_TTYS);
+ sc->status=DISABLED;
+ hidewin(sc);
+ return 0;
+ }
+
+ bzero(sc->ttys, sizeof(struct tty)*sc->numports);
+
+ /* We should now init per-port structures */
+ bc=(struct board_chan *)(mem + CHANSTRUCT);
+ sc->mailbox=(struct global_data *)(mem + FEP_GLOBAL);
+
+ if(sc->numports<3)
+ shrinkmem=1;
+ else
+ shrinkmem=0;
+
+
+ for(i=0; i<sc->numports; i++, bc++) {
+ port= &sc->ports[i];
+
+ port->status=ENABLED;
+
+ port->tty=&sc->ttys[i];
+ port->unit=unit;
+
+ port->brdchan=bc;
+
+ if(sc->altpin) {
+ port->dsr=CD;
+ port->dcd=DSR;
+ } else {
+ port->dcd=CD;
+ port->dsr=DSR;
+ }
+
+ port->pnum=i;
+
+ if(shrinkmem) {
+ DPRINT2("dgb%d: shrinking memory\n",unit);
+ fepcmd(port, SETBUFFER, 32, 0, 0, 0);
+ shrinkmem=0;
+ }
+
+ if(sc->type!=PCXEVE) {
+ port->txptr=mem+((bc->tseg-sc->mem_seg)<<4);
+ port->rxptr=mem+((bc->rseg-sc->mem_seg)<<4);
+ port->txwin=port->rxwin=0;
+ } else {
+ port->txptr=mem+( ((bc->tseg-sc->mem_seg)<<4) & 0x1FFF );
+ port->rxptr=mem+( ((bc->rseg-sc->mem_seg)<<4) & 0x1FFF );
+ port->txwin=FEPWIN | ((bc->tseg-sc->mem_seg)>>9);
+ port->rxwin=FEPWIN | ((bc->rseg-sc->mem_seg)>>9);
+ }
+
+ port->txbufhead=0;
+ port->rxbufhead=0;
+ port->txbufsize=bc->tmax+1;
+ port->rxbufsize=bc->rmax+1;
+
+ lowwater= (port->txbufsize>=2000) ? 1024 : (port->txbufsize/2);
+ fepcmd(port, STXLWATER, lowwater, 0, 10, 0);
+ fepcmd(port, SRXLWATER, port->rxbufsize/4, 0, 10, 0);
+ fepcmd(port, SRXHWATER, 3*port->rxbufsize/4, 0, 10, 0);
+
+ bc->edelay=100;
+ bc->idata=1;
+
+ port->startc=bc->startc;
+ port->startca=bc->startca;
+ port->stopc=bc->stopc;
+ port->stopca=bc->stopca;
+
+ port->close_delay=50;
+
+ /*
+ * We don't use all the flags from <sys/ttydefaults.h> since they
+ * are only relevant for logins. It's important to have echo off
+ * initially so that the line doesn't start blathering before the
+ * echo flag can be turned off.
+ */
+ port->it_in.c_iflag = TTYDEF_IFLAG;
+ port->it_in.c_oflag = TTYDEF_OFLAG;
+ port->it_in.c_cflag = TTYDEF_CFLAG;
+ port->it_in.c_lflag = TTYDEF_LFLAG;
+ termioschars(&port->it_in);
+ port->it_in.c_ispeed = port->it_in.c_ospeed = dgbdefaultrate;
+ port->it_out = port->it_in;
+ }
+
+ hidewin(sc);
+
+ /* register the polling function */
+ timeout(dgbpoll, (void *)unit, hz/25);
+
+ return 1;
+}
+
+/* ARGSUSED */
+int
+dgbopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
+{
+ struct dgb_softc *sc;
+ struct tty *tp;
+ int unit;
+ int mynor;
+ int pnum;
+ struct dgb_p *port;
+ int s;
+ int error;
+ struct board_chan *bc;
+
+ error=0;
+
+ mynor=minor(dev);
+ unit=MINOR_TO_UNIT(mynor);
+ pnum=MINOR_TO_PORT(mynor);
+
+ if(unit >= NDGB) {
+ DPRINT2("dgb%d: try to open a nonexisting card\n",unit);
+ return ENXIO;
+ }
+
+ sc=&dgb_softc[unit];
+
+ if(sc->status!=ENABLED) {
+ DPRINT2("dgb%d: try to open a disabled card\n",unit);
+ return ENXIO;
+ }
+
+ if(pnum>=sc->numports) {
+ DPRINT3("dgb%d: try to open non-existing port %d\n",unit,pnum);
+ return ENXIO;
+ }
+
+ if(mynor & CONTROL_MASK)
+ return 0;
+
+ tp=&sc->ttys[pnum];
+ port=&sc->ports[pnum];
+ bc=port->brdchan;
+
+open_top:
+
+ s=spltty();
+
+ while(port->closing) {
+ error=tsleep(&port->closing, TTOPRI|PCATCH, "dgocl", 0);
+
+ if(error) {
+ DPRINT4("dgb%d: port %d: tsleep(dgocl) error=%d\n",unit,pnum,error);
+ goto out;
+ }
+ }
+
+ if (tp->t_state & TS_ISOPEN) {
+ /*
+ * The device is open, so everything has been initialized.
+ * Handle conflicts.
+ */
+ if (mynor & CALLOUT_MASK) {
+ if (!port->active_out) {
+ error = EBUSY;
+ DPRINT4("dgb%d: port %d: BUSY error=%d\n",unit,pnum,error);
+ goto out;
+ }
+ } else {
+ if (port->active_out) {
+ if (flag & O_NONBLOCK) {
+ error = EBUSY;
+ DPRINT4("dgb%d: port %d: BUSY error=%d\n",unit,pnum,error);
+ goto out;
+ }
+ error = tsleep(&port->active_out,
+ TTIPRI | PCATCH, "dgbi", 0);
+ if (error != 0) {
+ DPRINT4("dgb%d: port %d: tsleep(dgbi) error=%d\n",
+ unit,pnum,error);
+ goto out;
+ }
+ splx(s);
+ goto open_top;
+ }
+ }
+ if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ error = EBUSY;
+ goto out;
+ }
+ } else {
+ /*
+ * The device isn't open, so there are no conflicts.
+ * Initialize it. Initialization is done twice in many
+ * cases: to preempt sleeping callin opens if we are
+ * callout, and to complete a callin open after DCD rises.
+ */
+ tp->t_oproc=dgbstart;
+ tp->t_param=dgbparam;
+ tp->t_dev=dev;
+ tp->t_termios= (mynor & CALLOUT_MASK) ?
+ port->it_out :
+ port->it_in;
+
+ setwin(sc,0);
+ port->imodem=bc->mstat;
+ bc->rout=bc->rin; /* clear input queue */
+ bc->idata=1;
+
+ hidewin(sc);
+
+ port->wopeners++;
+ error=dgbparam(tp, &tp->t_termios);
+ port->wopeners--;
+
+ if(error!=0) {
+ DPRINT4("dgb%d: port %d: dgbparam error=%d\n",unit,pnum,error);
+ goto out;
+ }
+
+ ttsetwater(tp);
+
+ /* handle fake DCD for callout devices */
+ /* and initial DCD */
+
+ if( (port->imodem & port->dcd) || mynor & CALLOUT_MASK )
+ linesw[tp->t_line].l_modem(tp,1);
+
+ }
+
+ /*
+ * Wait for DCD if necessary.
+ */
+ if (!(tp->t_state & TS_CARR_ON) && !(mynor & CALLOUT_MASK)
+ && !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) {
+ ++port->wopeners;
+ error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, "dgdcd", 0);
+ --port->wopeners;
+ if (error != 0) {
+ DPRINT4("dgb%d: port %d: tsleep(dgdcd) error=%d\n",unit,pnum,error);
+ goto out;
+ }
+ splx(s);
+ goto open_top;
+ }
+ error = linesw[tp->t_line].l_open(dev, tp);
+ DPRINT4("dgb%d: port %d: l_open error=%d\n",unit,pnum,error);
+
+ if (tp->t_state & TS_ISOPEN && mynor & CALLOUT_MASK)
+ port->active_out = TRUE;
+
+ port->used=1;
+
+out:
+ splx(s);
+
+ if( !(tp->t_state & TS_ISOPEN) && port->wopeners==0 )
+ dgbhardclose(port);
+
+ DPRINT4("dgb%d: port %d: open() returns %d\n",unit,pnum,error);
+
+ return error;
+}
+
+/*ARGSUSED*/
+int
+dgbclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
+{
+ int mynor;
+ struct tty *tp;
+ int unit, pnum;
+ struct dgb_softc *sc;
+ struct dgb_p *port;
+ int s;
+
+ mynor=minor(dev);
+ unit=MINOR_TO_UNIT(mynor);
+ pnum=MINOR_TO_PORT(mynor);
+
+ sc=&dgb_softc[unit];
+ tp=&sc->ttys[pnum];
+ port=sc->ports+pnum;
+
+ if(mynor & CONTROL_MASK)
+ return 0;
+
+ DPRINT3("dgb%d: port %d: closing\n",unit,pnum);
+
+ s=spltty();
+
+ port->closing=1;
+ linesw[tp->t_line].l_close(tp,flag);
+ dgb_drain_or_flush(port);
+ dgbhardclose(port);
+ ttyclose(tp);
+ port->closing=0; wakeup(&port->closing);
+ port->used=0;
+
+ splx(s);
+
+ wakeup(TSA_CARR_ON(tp));
+ wakeup(&port->active_out);
+ port->active_out=0;
+
+ return 0;
+}
+
+static void
+dgbhardclose(port)
+ struct dgb_p *port;
+{
+ struct dgb_softc *sc=&dgb_softc[port->unit];
+ struct board_chan *bc=port->brdchan;
+ int s;
+
+ setwin(sc,0);
+
+ bc->idata=0; bc->iempty=0; bc->ilow=0;
+ if(port->tty->t_cflag & HUPCL) {
+ port->omodem &= ~(RTS|DTR);
+ fepcmd(port, SETMODEM, 0, DTR|RTS, 0, 1);
+ }
+
+ hidewin(sc);
+
+ timeout(dgb_pause, &port->brdchan, hz/2);
+ tsleep(&port->brdchan, TTIPRI | PCATCH, "dgclo", 0);
+}
+
+static void
+dgb_pause(chan)
+ void *chan;
+{
+wakeup((caddr_t)chan);
+}
+
+
+int
+dgbread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ int mynor;
+ struct tty *tp;
+ int error, unit, pnum;
+
+ mynor=minor(dev);
+ if (mynor & CONTROL_MASK)
+ return (ENODEV);
+ unit=MINOR_TO_UNIT(mynor);
+ pnum=MINOR_TO_PORT(mynor);
+
+ tp=&dgb_softc[unit].ttys[pnum];
+
+ error=linesw[tp->t_line].l_read(tp, uio, flag);
+ DPRINT4("dgb%d: port %d: read() returns %d\n",unit,pnum,error);
+
+ return error;
+}
+
+int
+dgbwrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ int mynor;
+ struct tty *tp;
+ int error, unit, pnum;
+
+ mynor=minor(dev);
+ if (mynor & CONTROL_MASK)
+ return (ENODEV);
+
+ unit=MINOR_TO_UNIT(mynor);
+ pnum=MINOR_TO_PORT(mynor);
+
+ tp=&dgb_softc[unit].ttys[pnum];
+
+ error=linesw[tp->t_line].l_write(tp, uio, flag);
+ DPRINT4("dgb%d: port %d: write() returns %d\n",unit,pnum,error);
+
+ return error;
+}
+
+void dgbpoll(unit_c)
+ void *unit_c;
+{
+ int unit=(int)unit_c;
+ int pnum;
+ struct dgb_p *port;
+ struct dgb_softc *sc=&dgb_softc[unit];
+ int head, tail;
+ u_char *eventbuf;
+ int event, mstat, lstat;
+ struct board_chan *bc;
+ struct tty *tp;
+ int rhead, rtail;
+ int whead, wtail;
+ int wrapmask;
+ int size;
+ int c=0;
+ u_char *ptr;
+ int ocount;
+
+ if(sc->status==DISABLED) {
+ printf("dgb%d: polling of disabled board stopped\n",unit);
+ return;
+ }
+
+ setwin(sc,0);
+
+ head=sc->mailbox->ein;
+ tail=sc->mailbox->eout;
+
+ while(head!=tail) {
+ if(head >= FEP_IMAX-FEP_ISTART
+ || tail >= FEP_IMAX-FEP_ISTART
+ || (head|tail) & 03 ) {
+ printf("dgb%d: event queue's head or tail is wrong!\n", unit);
+ break;
+ }
+
+ eventbuf=sc->vmem+tail+FEP_ISTART;
+ pnum=eventbuf[0];
+ event=eventbuf[1];
+ mstat=eventbuf[2];
+ lstat=eventbuf[3];
+
+ port=&sc->ports[pnum];
+ bc=port->brdchan;
+ tp=&sc->ttys[pnum];
+
+ if(pnum>=sc->numports || port->status==DISABLED) {
+ printf("dgb%d: port %d: got event on nonexisting port\n",unit,pnum);
+ } else if(port->used || port->wopeners>0 ) {
+
+ if( !(event & ALL_IND) )
+ printf("dgb%d: port%d: ? event 0x%x mstat 0x%x lstat 0x%x\n",
+ unit, pnum, event, mstat, lstat);
+
+ if(event & DATA_IND) {
+ DPRINT3("dgb%d: port %d: DATA_IND\n",unit,pnum);
+
+ wrapmask=port->rxbufsize-1;
+
+ rhead=bc->rin & wrapmask;
+ rtail=bc->rout & wrapmask;
+
+ if( !(tp->t_cflag & CREAD) || !port->used ) {
+ bc->rout=rhead;
+ goto end_of_data;
+ }
+
+ if(bc->orun) {
+ printf("dgb%d: port%d: overrun\n", unit, pnum);
+ bc->orun=0;
+ }
+
+ while(rhead!=rtail) {
+ DPRINT5("dgb%d: port %d: p rx head=%d tail=%d\n",
+ unit,pnum,rhead,rtail);
+
+ if(rhead>rtail)
+ size=rhead-rtail;
+ else
+ size=port->rxbufsize-rtail;
+
+ ptr=port->rxptr+rtail;
+
+ for(c=0; c<size; c++) {
+ int chr;
+
+ towin(sc,port->rxwin);
+ chr= *ptr++;
+
+#if 0
+ if(chr>=' ' && chr<127)
+ DPRINT4("dgb%d: port %d: got char '%c'\n",
+ unit,pnum,chr);
+ else
+ DPRINT4("dgb%d: port %d: got char 0x%x\n",
+ unit,pnum,chr);
+#endif
+
+ hidewin(sc);
+ linesw[tp->t_line].l_rint(chr, tp);
+ }
+
+ setwin(sc,0);
+ rtail= (rtail + size) & wrapmask;
+ bc->rout=rtail;
+ rhead=bc->rin & wrapmask;
+ }
+
+ end_of_data:
+ }
+
+ if(event & MODEMCHG_IND) {
+ DPRINT3("dgb%d: port %d: MODEMCHG_IND\n",unit,pnum);
+ port->imodem=mstat;
+ if(mstat & port->dcd) {
+ hidewin(sc);
+ linesw[tp->t_line].l_modem(tp,1);
+ setwin(sc,0);
+ wakeup(TSA_CARR_ON(tp));
+ } else {
+ hidewin(sc);
+ linesw[tp->t_line].l_modem(tp,0);
+ setwin(sc,0);
+ if( port->draining) {
+ port->draining=0;
+ wakeup(&port->draining);
+ }
+ }
+ }
+
+ if(event & BREAK_IND) {
+ DPRINT3("dgb%d: port %d: BREAK_IND\n",unit,pnum);
+ hidewin(sc);
+ linesw[tp->t_line].l_rint(TTY_BI, tp);
+ setwin(sc,0);
+ }
+
+ if(event & (LOWTX_IND | EMPTYTX_IND) ) {
+ DPRINT3("dgb%d: port %d: LOWTX_IND or EMPTYTX_IND\n",unit,pnum);
+
+ if( (event & EMPTYTX_IND ) && tp->t_outq.c_cc==0
+ && port->draining) {
+ port->draining=0;
+ wakeup(&port->draining);
+ bc->ilow=0; bc->iempty=0;
+ }
+
+ wrapmask=port->txbufsize;
+
+ while( tp->t_outq.c_cc!=0 ) {
+#ifndef TS_ASLEEP /* post 2.0.5 FreeBSD */
+ ttwwakeup(tp);
+#else
+ if(tp->t_outq.c_cc <= tp->t_lowat) {
+ if(tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup(TSA_OLOWAT(tp));
+ }
+ selwakeup(&tp->t_wsel);
+ }
+#endif
+ setwin(sc,0);
+
+ whead=bc->tin & wrapmask;
+ wtail=bc->tout & wrapmask;
+
+ DPRINT5("dgb%d: port%d: p tx head=%d tail=%d\n",
+ unit,pnum,whead,wtail);
+
+ if(whead<wtail)
+ size=wtail-whead-1;
+ else {
+ size=port->txbufsize-whead;
+ if(wtail==0)
+ size--;
+ }
+
+ if(size==0) {
+ bc->iempty=1; bc->ilow=1;
+ goto end_of_buffer;
+ }
+
+ towin(sc,port->txwin);
+
+ ocount=q_to_b(&tp->t_outq, port->txptr+whead, size);
+ whead+=ocount;
+
+ setwin(sc,0);
+ bc->tin=whead;
+ }
+#ifndef TS_ASLEEP /* post 2.0.5 FreeBSD */
+ ttwwakeup(tp);
+#else
+ if(tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup(TSA_OLOWAT(tp));
+ }
+ tp->t_state &= ~TS_BUSY;
+#endif
+ end_of_buffer:
+ }
+ } else {
+ DPRINT4("dgb%d: port %d: got event 0x%x on closed port\n",
+ unit,pnum,event);
+ bc->rout=bc->rin;
+ bc->idata=bc->iempty=bc->ilow=0;
+ }
+
+ bc->idata=1;
+
+ tail= (tail+4) & (FEP_IMAX-FEP_ISTART-4);
+ }
+
+ sc->mailbox->eout=tail;
+ hidewin(sc);
+
+ timeout(dgbpoll, unit_c, hz/25);
+}
+
+void
+dgbintr(unit)
+ int unit;
+{
+}
+
+int
+dgbioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ struct dgb_softc *sc;
+ int unit, pnum;
+ struct dgb_p *port;
+ int mynor;
+ struct tty *tp;
+ struct board_chan *bc;
+ int error;
+ int s;
+ int tiocm_xxx;
+
+ mynor=minor(dev);
+ unit=MINOR_TO_UNIT(mynor);
+ pnum=MINOR_TO_PORT(mynor);
+
+ sc=&dgb_softc[unit];
+ port=&sc->ports[pnum];
+ tp=&sc->ttys[pnum];
+ bc=port->brdchan;
+
+ if (mynor & CONTROL_MASK) {
+ struct termios *ct;
+
+ switch (mynor & CONTROL_MASK) {
+ case CONTROL_INIT_STATE:
+ ct = mynor & CALLOUT_MASK ? &port->it_out : &port->it_in;
+ break;
+ case CONTROL_LOCK_STATE:
+ ct = mynor & CALLOUT_MASK ? &port->lt_out : &port->lt_in;
+ break;
+ default:
+ return (ENODEV); /* /dev/nodev */
+ }
+ switch (cmd) {
+ case TIOCSETA:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error != 0)
+ return (error);
+ *ct = *(struct termios *)data;
+ return (0);
+ case TIOCGETA:
+ *(struct termios *)data = *ct;
+ return (0);
+ case TIOCGETD:
+ *(int *)data = TTYDISC;
+ return (0);
+ case TIOCGWINSZ:
+ bzero(data, sizeof(struct winsize));
+ return (0);
+ default:
+ return (ENOTTY);
+ }
+ }
+
+ if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
+ int cc;
+ struct termios *dt = (struct termios *)data;
+ struct termios *lt = mynor & CALLOUT_MASK
+ ? &port->lt_out : &port->lt_in;
+
+ dt->c_iflag = (tp->t_iflag & lt->c_iflag)
+ | (dt->c_iflag & ~lt->c_iflag);
+ dt->c_oflag = (tp->t_oflag & lt->c_oflag)
+ | (dt->c_oflag & ~lt->c_oflag);
+ dt->c_cflag = (tp->t_cflag & lt->c_cflag)
+ | (dt->c_cflag & ~lt->c_cflag);
+ dt->c_lflag = (tp->t_lflag & lt->c_lflag)
+ | (dt->c_lflag & ~lt->c_lflag);
+ for (cc = 0; cc < NCCS; ++cc)
+ if (lt->c_cc[cc] != 0)
+ dt->c_cc[cc] = tp->t_cc[cc];
+ if (lt->c_ispeed != 0)
+ dt->c_ispeed = tp->t_ispeed;
+ if (lt->c_ospeed != 0)
+ dt->c_ospeed = tp->t_ospeed;
+ }
+
+ if(cmd==TIOCSTOP) {
+ setwin(sc,0);
+ fepcmd(port, PAUSETX, 0, 0, 0, 0);
+ hidewin(sc);
+ return 0;
+ } else if(cmd==TIOCSTART) {
+ setwin(sc,0);
+ fepcmd(port, RESUMETX, 0, 0, 0, 0);
+ hidewin(sc);
+ return 0;
+ }
+
+ if(cmd==TIOCSETAW || cmd==TIOCSETAF)
+ port->mustdrain=1;
+
+ error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p);
+
+ if (error >= 0)
+ return error;
+ error = ttioctl(tp, cmd, data, flag);
+
+ port->mustdrain=0;
+
+ if (error >= 0)
+ return error;
+ s = spltty();
+ switch (cmd) {
+ case TIOCSBRK:
+ error=dgbdrain(port);
+
+ if(error!=0) {
+ splx(s);
+ return error;
+ }
+
+ setwin(sc,0);
+
+ /* now it sends 250 millisecond break because I don't know */
+ /* how to send an infinite break */
+
+ fepcmd(port, SENDBREAK, 250, 0, 10, 0);
+ hidewin(sc);
+ break;
+ case TIOCCBRK:
+ /* now it's empty */
+ break;
+ case TIOCSDTR:
+ DPRINT3("dgb%d: port %d: set DTR\n",unit,pnum);
+ port->omodem |= DTR;
+ setwin(sc,0);
+ fepcmd(port, SETMODEM, port->omodem, RTS, 0, 1);
+
+ if( !(bc->mstat & DTR) ) {
+ DPRINT3("dgb%d: port %d: DTR is off\n",unit,pnum);
+ }
+
+ hidewin(sc);
+ break;
+ case TIOCCDTR:
+ DPRINT3("dgb%d: port %d: reset DTR\n",unit,pnum);
+ port->omodem &= ~DTR;
+ setwin(sc,0);
+ fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1);
+
+ if( bc->mstat & DTR ) {
+ DPRINT3("dgb%d: port %d: DTR is on\n",unit,pnum);
+ }
+
+ hidewin(sc);
+ break;
+ case TIOCMSET:
+ if(*(int *)data & TIOCM_DTR)
+ port->omodem |=DTR;
+ else
+ port->omodem &=~DTR;
+
+ if(*(int *)data & TIOCM_RTS)
+ port->omodem |=RTS;
+ else
+ port->omodem &=~RTS;
+
+ setwin(sc,0);
+ fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1);
+ hidewin(sc);
+ break;
+ case TIOCMBIS:
+ if(*(int *)data & TIOCM_DTR)
+ port->omodem |=DTR;
+
+ if(*(int *)data & TIOCM_RTS)
+ port->omodem |=RTS;
+
+ setwin(sc,0);
+ fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1);
+ hidewin(sc);
+ break;
+ case TIOCMBIC:
+ if(*(int *)data & TIOCM_DTR)
+ port->omodem &=~DTR;
+
+ if(*(int *)data & TIOCM_RTS)
+ port->omodem &=~RTS;
+
+ setwin(sc,0);
+ fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1);
+ hidewin(sc);
+ break;
+ case TIOCMGET:
+ setwin(sc,0);
+ port->imodem=bc->mstat;
+ hidewin(sc);
+
+ tiocm_xxx = TIOCM_LE; /* XXX - always enabled while open */
+
+ DPRINT3("dgb%d: port %d: modem stat -- ",unit,pnum);
+
+ if (port->imodem & DTR) {
+ DPRINT1("DTR ");
+ tiocm_xxx |= TIOCM_DTR;
+ }
+ if (port->imodem & RTS) {
+ DPRINT1("RTS ");
+ tiocm_xxx |= TIOCM_RTS;
+ }
+ if (port->imodem & CTS) {
+ DPRINT1("CTS ");
+ tiocm_xxx |= TIOCM_CTS;
+ }
+ if (port->imodem & port->dcd) {
+ DPRINT1("DCD ");
+ tiocm_xxx |= TIOCM_CD;
+ }
+ if (port->imodem & port->dsr) {
+ DPRINT1("DSR ");
+ tiocm_xxx |= TIOCM_DSR;
+ }
+ if (port->imodem & RI) {
+ DPRINT1("RI ");
+ tiocm_xxx |= TIOCM_RI;
+ }
+ *(int *)data = tiocm_xxx;
+ DPRINT1("--\n");
+ break;
+ default:
+ splx(s);
+ return ENOTTY;
+ }
+ splx(s);
+ return 0;
+}
+
+static void
+wakeflush(p)
+ void *p;
+{
+ struct dgb_p *port=p;
+
+ wakeup(&port->draining);
+}
+
+/* wait for the output to drain */
+
+static int
+dgbdrain(port)
+ struct dgb_p *port;
+{
+ struct tty *tp=port->tty;
+ struct dgb_softc *sc=&dgb_softc[port->unit];
+ struct board_chan *bc=port->brdchan;
+ int error;
+ int head, tail;
+
+ setwin(sc,0);
+
+ bc->iempty=1;
+ tail=bc->tout;
+ head=bc->tin;
+
+ while(tail!=head) {
+ DPRINT5("dgb%d: port %d: drain: head=%d tail=%d\n",
+ port->unit, port->pnum, head, tail);
+
+ hidewin(sc);
+ port->draining=1;
+ timeout(wakeflush,port, hz);
+ error=tsleep(&port->draining, TTIPRI | PCATCH, "dgdrn", 0);
+ port->draining=0;
+ setwin(sc,0);
+
+ if (error != 0) {
+ DPRINT4("dgb%d: port %d: tsleep(dgdrn) error=%d\n",
+ port->unit,port->pnum,error);
+
+ bc->iempty=0;
+ hidewin(sc);
+ return error;
+ }
+
+ tail=bc->tout;
+ head=bc->tin;
+ }
+ DPRINT5("dgb%d: port %d: drain: head=%d tail=%d\n",
+ port->unit, port->pnum, head, tail);
+
+ return 0;
+}
+
+/* wait for the output to drain */
+/* or simply clear the buffer it it's stopped */
+
+static void
+dgb_drain_or_flush(port)
+ struct dgb_p *port;
+{
+ struct tty *tp=port->tty;
+ struct dgb_softc *sc=&dgb_softc[port->unit];
+ struct board_chan *bc=port->brdchan;
+ int error;
+ int lasttail;
+ int head, tail;
+
+ setwin(sc,0);
+
+ lasttail=-1;
+ bc->iempty=1;
+ tail=bc->tout;
+ head=bc->tin;
+
+ while(tail!=head /* && tail!=lasttail */ ) {
+ DPRINT5("dgb%d: port %d: flush: head=%d tail=%d\n",
+ port->unit, port->pnum, head, tail);
+
+ /* if there is no carrier simply clean the buffer */
+ if( !(tp->t_state & TS_CARR_ON) ) {
+ bc->tout=bc->tin=0;
+ bc->iempty=0;
+ hidewin(sc);
+ return;
+ }
+
+ hidewin(sc);
+ port->draining=1;
+ timeout(wakeflush,port, hz);
+ error=tsleep(&port->draining, TTIPRI | PCATCH, "dgfls", 0);
+ port->draining=0;
+ setwin(sc,0);
+
+ if (error != 0) {
+ DPRINT4("dgb%d: port %d: tsleep(dgfls) error=%d\n",
+ port->unit,port->pnum,error);
+
+ /* silently clean the buffer */
+
+ bc->tout=bc->tin=0;
+ bc->iempty=0;
+ hidewin(sc);
+ return;
+ }
+
+ lasttail=tail;
+ tail=bc->tout;
+ head=bc->tin;
+ }
+ DPRINT5("dgb%d: port %d: flush: head=%d tail=%d\n",
+ port->unit, port->pnum, head, tail);
+}
+
+static int
+dgbparam(tp, t)
+ struct tty *tp;
+ struct termios *t;
+{
+ int dev=tp->t_dev;
+ int mynor=minor(dev);
+ int unit=MINOR_TO_UNIT(dev);
+ int pnum=MINOR_TO_PORT(dev);
+ struct dgb_softc *sc=&dgb_softc[unit];
+ struct dgb_p *port=&sc->ports[pnum];
+ struct board_chan *bc=port->brdchan;
+ int cflag;
+ int head;
+ int mval;
+ int iflag;
+ int hflow;
+ int s;
+
+ DPRINT3("dgb%d: port%d: setting parameters\n",unit,pnum);
+
+ if(port->mustdrain) {
+ DPRINT3("dgb%d: port%d: must call dgbdrain()\n",unit,pnum);
+ dgbdrain(port);
+ }
+
+ cflag=ttspeedtab(t->c_ospeed, dgbspeedtab);
+
+ if (t->c_ispeed == 0)
+ t->c_ispeed = t->c_ospeed;
+
+ if (cflag < 0 || cflag > 0 && t->c_ispeed != t->c_ospeed)
+ return (EINVAL);
+
+ s=spltty();
+
+ setwin(sc,0);
+
+ if(cflag==0) { /* hangup */
+ DPRINT3("dgb%d: port%d: hangup\n",unit,pnum);
+ head=bc->rin;
+ bc->rout=head;
+ head=bc->tin;
+ fepcmd(port, STOUT, head, 0, 0, 0);
+ mval= port->omodem & ~(DTR|RTS);
+ } else {
+ DPRINT4("dgb%d: port%d: CBAUD=%d\n",unit,pnum,cflag);
+
+ /* convert flags to sysV-style values */
+ if(t->c_cflag & PARODD)
+ cflag|=01000;
+ if(t->c_cflag & PARENB)
+ cflag|=00400;
+ if(t->c_cflag & CSTOPB)
+ cflag|=00100;
+
+ cflag|= (t->c_cflag & CSIZE) >> 4;
+ DPRINT4("dgb%d: port%d: CFLAG=0x%x\n",unit,pnum,cflag);
+
+ if(cflag!=port->fepcflag) {
+ DPRINT3("dgb%d: port%d: set cflag\n",unit,pnum);
+ port->fepcflag=cflag;
+ fepcmd(port, SETCTRLFLAGS, (unsigned)cflag, 0, 0, 0);
+ }
+ mval= port->omodem | (DTR|RTS) ;
+ }
+
+ iflag=t->c_iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP);
+ if(t->c_cflag & IXON)
+ cflag|=002000;
+ if(t->c_cflag & IXANY)
+ cflag|=004000;
+ if(t->c_cflag & IXOFF)
+ cflag|=010000;
+
+ if(iflag!=port->fepiflag) {
+ DPRINT3("dgb%d: port%d: set iflag\n",unit,pnum);
+ port->fepiflag=iflag;
+ fepcmd(port, SETIFLAGS, (unsigned)iflag, 0, 0, 0);
+ }
+
+ bc->mint=port->dcd;
+
+ if(t->c_cflag & CRTSCTS)
+ hflow=(CTS|RTS);
+ else
+ hflow=0;
+
+ if(hflow!=port->hflow) {
+ DPRINT3("dgb%d: port%d: set hflow\n",unit,pnum);
+ port->hflow=hflow;
+ fepcmd(port, SETHFLOW, (unsigned)hflow, 0xff, 0, 1);
+ }
+
+ if(port->omodem != mval) {
+ DPRINT4("dgb%d: port %d: setting modem parameters 0x%x\n",
+ unit,pnum,mval);
+ port->omodem=mval;
+ fepcmd(port, SETMODEM, (unsigned)mval, RTS|DTR, 0, 1);
+ }
+
+ if(port->fepstartc!=t->c_cc[VSTART] || port->fepstopc!=t->c_cc[VSTOP]) {
+ DPRINT3("dgb%d: port%d: set startc, stopc\n",unit,pnum);
+ port->fepstartc=t->c_cc[VSTART];
+ port->fepstopc=t->c_cc[VSTOP];
+ fepcmd(port, SONOFFC, port->fepstartc, port->fepstopc, 0, 1);
+ }
+
+ hidewin(sc);
+ splx(s);
+
+ return 0;
+
+}
+
+static void
+dgbstart(tp)
+ struct tty *tp;
+{
+ int unit;
+ int pnum;
+ struct dgb_p *port;
+ struct dgb_softc *sc;
+ struct board_chan *bc;
+ int head, tail;
+ int size, ocount;
+ int s;
+ int wmask;
+
+ unit=MINOR_TO_UNIT(minor(tp->t_dev));
+ pnum=MINOR_TO_PORT(minor(tp->t_dev));
+ sc=&dgb_softc[unit];
+ port=&sc->ports[pnum];
+ bc=port->brdchan;
+
+ wmask=port->txbufsize-1;
+
+ s=spltty();
+
+ while( tp->t_outq.c_cc!=0 ) {
+#ifndef TS_ASLEEP /* post 2.0.5 FreeBSD */
+ ttwwakeup(tp);
+#else
+ if(tp->t_outq.c_cc <= tp->t_lowat) {
+ if(tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup(TSA_OLOWAT(tp));
+ }
+ selwakeup(&tp->t_wsel);
+ }
+#endif
+ setwin(sc,0);
+
+ head=bc->tin & wmask;
+ tail=bc->tout & wmask;
+
+ DPRINT5("dgb%d: port%d: s tx head=%d tail=%d\n",unit,pnum,head,tail);
+
+ if(tail>head)
+ size=tail-head-1;
+ else {
+ size=port->txbufsize-head;
+ if(tail==0)
+ size--;
+ }
+
+ if(size==0) {
+ bc->iempty=1; bc->ilow=1;
+ hidewin(sc);
+ tp->t_state|=TS_BUSY;
+ splx(s);
+ return;
+ }
+
+ towin(sc,port->txwin);
+
+ ocount=q_to_b(&tp->t_outq, port->txptr+head, size);
+ head+=ocount;
+
+ setwin(sc,0);
+ bc->tin=head;
+ }
+
+#ifndef TS_ASLEEP /* post 2.0.5 FreeBSD */
+ ttwwakeup(tp);
+#else
+ if(tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup(TSA_OLOWAT(tp));
+ }
+ tp->t_state&=~TS_BUSY;
+#endif
+ hidewin(sc);
+ splx(s);
+}
+
+void
+dgbstop(tp, rw)
+ struct tty *tp;
+ int rw;
+{
+}
+
+int
+dgbselect(dev, rw, p)
+ dev_t dev;
+ int rw;
+ struct proc *p;
+{
+ if (minor(dev) & CONTROL_MASK)
+ return (ENODEV);
+ return (ttselect(dev & ~MINOR_MAGIC_MASK, rw, p));
+}
+
+static void
+fepcmd(port, cmd, op1, op2, ncmds, bytecmd)
+ struct dgb_p *port;
+ int cmd, op1, op2, ncmds, bytecmd;
+{
+ struct dgb_softc *sc=&dgb_softc[port->unit];
+ u_char *mem=sc->vmem;
+ unsigned tail, head;
+ int count, n;
+
+ if(port->status==DISABLED) {
+ printf("dgb%d(%d): FEP command on disabled port\n",
+ port->unit, port->pnum);
+ return;
+ }
+
+ setwin(sc,0);
+ head=sc->mailbox->cin;
+
+ if(head>=(FEP_CMAX-FEP_CSTART) || (head & 3)) {
+ printf("dgb%d(%d): wrong pointer head of command queue : 0x%x\n",
+ port->unit, port->pnum, head);
+ return;
+ }
+
+ if(bytecmd) {
+ mem[head+FEP_CSTART+0]=cmd;
+ mem[head+FEP_CSTART+1]=port->pnum;
+ mem[head+FEP_CSTART+2]=op1;
+ mem[head+FEP_CSTART+3]=op2;
+ } else {
+ mem[head+FEP_CSTART+0]=cmd;
+ mem[head+FEP_CSTART+1]=port->pnum;
+ *(ushort *)(mem+head+FEP_CSTART+2)=op1;
+ }
+
+ head=(head+4) & (FEP_CMAX-FEP_CSTART-4);
+ sc->mailbox->cin=head;
+
+ for(count=FEPTIMEOUT; count>0; count--) {
+ head=sc->mailbox->cin;
+ tail=sc->mailbox->cout;
+ n=(head-tail) & (FEP_CMAX-FEP_CSTART-4);
+
+ if(n <= ncmds * 4)
+ return;
+ }
+
+ printf("dgb%d(%d): timeout on FEP command\n",
+ port->unit, port->pnum);
+}
+
+#endif /* NDGB > 0 */
diff --git a/sys/gnu/i386/isa/dgbios.h b/sys/gnu/i386/isa/dgbios.h
new file mode 100644
index 0000000000000..b6e916e583810
--- /dev/null
+++ b/sys/gnu/i386/isa/dgbios.h
@@ -0,0 +1,175 @@
+static unsigned char pcxx_bios[] = {
+ 0x28,0x43,0x29,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,
+ 0x74,0x20,0x31,0x39,0x39,0x34,0x2C,0x20,0x44,0x69,0x67,0x69,
+ 0x42,0x6F,0x61,0x72,0x64,0x20,0x49,0x6E,0x63,0x2E,0x00,0x00,
+ 0x8A,0xF8,0x8A,0xF8,0x15,0xF9,0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,
+ 0x8A,0xF8,0x8A,0xF8,0xBC,0xF8,0x8A,0xF8,0x96,0xF8,0x96,0xF8,
+ 0x96,0xF8,0x96,0xF8,0x96,0xF8,0x96,0xF8,0x8A,0xF8,0x8A,0xF8,
+ 0x96,0xF8,0x96,0xF8,0x8A,0xF8,0xAD,0xF8,0xB0,0xF8,0x8A,0xF8,
+ 0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,
+ 0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,0x04,0x02,0x00,0x02,0x14,0x02,
+ 0x10,0x02,0x24,0x02,0x20,0x02,0x34,0x02,0x30,0x02,0x44,0x02,
+ 0x40,0x02,0x54,0x02,0x50,0x02,0x64,0x02,0x60,0x02,0x74,0x02,
+ 0x70,0x02,0x04,0x01,0x00,0x01,0x1E,0x2E,0x8E,0x1E,0x22,0xF8,
+ 0xFE,0x06,0x70,0x00,0x1F,0xCF,0x1E,0x50,0x52,0x2E,0x8E,0x1E,
+ 0x22,0xF8,0xFE,0x06,0x71,0x00,0xB8,0x00,0x80,0xBA,0x22,0xFF,
+ 0xEF,0x5A,0x58,0x1F,0xCF,0xB4,0x80,0xCF,0x1E,0x2E,0x8E,0x1E,
+ 0x22,0xF8,0xFE,0x06,0x2B,0x00,0x1F,0xCF,0x1E,0x52,0x50,0x2E,
+ 0x8E,0x1E,0x22,0xF8,0xCD,0x16,0xFE,0x06,0x2A,0x00,0x80,0x3E,
+ 0x2A,0x00,0x12,0x72,0x39,0xC6,0x06,0x2A,0x00,0x00,0xFE,0x06,
+ 0x29,0x00,0x80,0x3E,0x29,0x00,0x3C,0x72,0x29,0xC6,0x06,0x29,
+ 0x00,0x00,0xFE,0x06,0x28,0x00,0x80,0x3E,0x28,0x00,0x3C,0x72,
+ 0x19,0xC6,0x06,0x28,0x00,0x00,0xFE,0x06,0x27,0x00,0x80,0x3E,
+ 0x27,0x00,0x18,0x72,0x09,0xC6,0x06,0x27,0x00,0x00,0xFF,0x06,
+ 0x25,0x00,0xBA,0x22,0xFF,0xB8,0x00,0x80,0xEF,0x58,0x5A,0x1F,
+ 0xCF,0x60,0x1E,0x06,0xFC,0x2E,0x8E,0x06,0x22,0xF8,0x2E,0x8E,
+ 0x1E,0x22,0xF8,0x8D,0x36,0x40,0x00,0xAD,0x3C,0x3F,0x7F,0x22,
+ 0x3C,0x1F,0x7F,0x22,0x32,0xE4,0xD1,0xE0,0x3D,0x16,0x00,0x90,
+ 0x73,0x14,0xBB,0x56,0xF9,0x03,0xD8,0x2E,0xFF,0x17,0x8D,0x36,
+ 0x40,0x00,0xB0,0x00,0x89,0x04,0x07,0x1F,0x61,0xCF,0xB4,0x80,
+ 0xEB,0xF0,0xCD,0x15,0xEB,0xEC,0x6C,0xF9,0x79,0xF9,0xB9,0xF9,
+ 0xD3,0xF9,0xD8,0xF9,0xE1,0xF9,0xE9,0xF9,0xF2,0xF9,0xFA,0xF9,
+ 0xFD,0xF9,0x2A,0xFA,0xE4,0x00,0x24,0xF7,0xE6,0x00,0x0C,0x08,
+ 0xE6,0x00,0xB4,0x00,0xC3,0x1E,0xAD,0x8B,0xD8,0xAD,0x8E,0xDB,
+ 0x8B,0xF0,0x33,0xDB,0x8B,0x07,0x3D,0x4F,0x53,0x75,0x2A,0x8A,
+ 0x47,0x02,0x32,0xE4,0x86,0xC4,0x8B,0xC8,0x32,0xC0,0x02,0x07,
+ 0x43,0xE2,0xFB,0x0A,0xC0,0x75,0x16,0x8C,0xD9,0x1F,0x89,0x0E,
+ 0x2E,0x00,0x89,0x36,0x2C,0x00,0x8D,0x1E,0x02,0x00,0xC7,0x07,
+ 0x45,0x4D,0x32,0xE4,0xC3,0x1F,0xB4,0x80,0xC3,0xAD,0x8B,0xD8,
+ 0xAD,0x8B,0xD0,0xAD,0x8E,0xC0,0xAD,0x8B,0xF8,0xAD,0x8B,0xC8,
+ 0x8B,0xF2,0x1E,0x8E,0xDB,0xF3,0xA4,0x1F,0x32,0xE4,0xC3,0xEA,
+ 0xF0,0xFF,0x00,0xF0,0xAD,0x8B,0xD0,0xEC,0x88,0x04,0x32,0xE4,
+ 0xC3,0xAD,0x8B,0xD0,0xAC,0xEE,0x32,0xE4,0xC3,0xAD,0x8B,0xD0,
+ 0xED,0x89,0x04,0x32,0xE4,0xC3,0xAD,0x8B,0xD0,0xAD,0xEF,0x32,
+ 0xE4,0xC3,0xB4,0x80,0xC3,0xAC,0x3C,0x12,0x7F,0x25,0xFE,0xC8,
+ 0x32,0xE4,0xD1,0xE0,0x8D,0x1E,0x66,0xF8,0x03,0xD8,0x2E,0x8B,
+ 0x17,0xEC,0xAC,0x3C,0x0F,0x7F,0x10,0x3C,0x00,0x74,0x03,0xEE,
+ 0x90,0x90,0xEC,0x8B,0xFE,0x1E,0x07,0xAA,0x32,0xE4,0xC3,0xB4,
+ 0x80,0xC3,0xAC,0x3C,0x12,0x7F,0x1F,0xFE,0xC8,0x32,0xE4,0xD1,
+ 0xE0,0x8D,0x1E,0x66,0xF8,0x03,0xD8,0x2E,0x8B,0x17,0xEC,0xAC,
+ 0x3C,0x0F,0x7F,0x0A,0x3C,0x00,0x74,0x01,0xEE,0xAC,0xEE,0x32,
+ 0xE4,0xC3,0xB4,0x80,0xC3,0xFC,0x8E,0xC0,0xB8,0xFF,0xFF,0x8B,
+ 0xCB,0x33,0xFF,0xF3,0xAB,0x8B,0xCB,0x33,0xFF,0xF3,0xAF,0xE3,
+ 0x01,0xC3,0x8B,0xCB,0xBF,0x00,0x00,0x26,0x89,0x3D,0x83,0xC7,
+ 0x02,0xE2,0xF8,0xBE,0x00,0x00,0x8B,0xCB,0x26,0x8B,0x3C,0x3B,
+ 0xFE,0x74,0x01,0xC3,0x83,0xC6,0x02,0x83,0xC7,0x02,0xE2,0xF0,
+ 0x33,0xC0,0x8B,0xCB,0x33,0xFF,0xF3,0xAB,0x8B,0xCB,0x33,0xFF,
+ 0xF3,0xAF,0xC3,0x32,0xC0,0x26,0x80,0x3E,0x23,0x00,0x00,0x74,
+ 0x02,0x0C,0x01,0x26,0xF7,0x06,0x20,0x00,0x0F,0x00,0x74,0x02,
+ 0x0C,0x02,0x26,0xF7,0x06,0x20,0x00,0xF0,0x00,0x74,0x02,0x0C,
+ 0x04,0x26,0xF7,0x06,0x20,0x00,0x00,0xFF,0x74,0x02,0x0C,0x08,
+ 0x26,0xA2,0x24,0x00,0xB8,0x00,0x40,0xBA,0x5E,0xFF,0xEF,0xBA,
+ 0x66,0xFF,0xEF,0xBA,0x52,0xFF,0xB8,0x63,0x0E,0xEF,0xBA,0x56,
+ 0xFF,0xB8,0x05,0xE0,0xEF,0xBA,0x28,0xFF,0xB8,0xFC,0x00,0xEF,
+ 0xB8,0x00,0x02,0x26,0xA3,0x2E,0x00,0xB8,0x04,0x00,0x26,0xA3,
+ 0x2C,0x00,0xB0,0xC3,0xE6,0x08,0x8A,0xD8,0xE4,0x08,0x3A,0xC3,
+ 0x75,0x06,0x26,0xC6,0x06,0xB4,0x00,0x01,0xFC,0x8D,0x3E,0x00,
+ 0x00,0xB8,0x47,0x44,0xAB,0xB8,0xFF,0xFF,0xAB,0xAB,0xAB,0xB8,
+ 0x42,0x49,0xAB,0xB8,0x4F,0x53,0xAB,0xB8,0x58,0x69,0x26,0x80,
+ 0x3E,0x10,0x00,0x04,0x74,0x0E,0xB8,0x58,0x65,0x26,0x80,0x3E,
+ 0x10,0x00,0x03,0x74,0x03,0xB8,0x58,0x74,0xAB,0x8D,0x36,0xFE,
+ 0xFF,0x8A,0x04,0x8D,0x36,0xFF,0xFF,0x8A,0x24,0xAB,0xFB,0x26,
+ 0x81,0x0E,0x12,0x00,0x00,0x08,0x06,0x1F,0xA1,0x00,0x00,0x8B,
+ 0x1E,0x02,0x00,0x3D,0x44,0x47,0x75,0x0B,0x26,0x81,0x0E,0x12,
+ 0x00,0x00,0x10,0xFF,0x2E,0x2C,0x00,0x81,0xFB,0x45,0x4D,0x75,
+ 0xE3,0x26,0x81,0x0E,0x12,0x00,0x00,0x20,0xFF,0x2E,0x2C,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFA,0xBA,0xA8,0xFF,0xB8,0xBA,0x81,0xEF,
+ 0xBA,0xA4,0xFF,0xB8,0x3A,0x00,0xEF,0x90,0xE4,0x00,0xA8,0x60,
+ 0x75,0x0C,0x24,0x06,0x74,0x14,0x3C,0x02,0x74,0x1C,0x3C,0x04,
+ 0x74,0x24,0xBB,0x38,0xC0,0xBE,0xF8,0x81,0xBF,0xBA,0xA0,0xEB,
+ 0x22,0x90,0xBB,0x38,0xF0,0xBE,0xF8,0x41,0xBF,0xBA,0x81,0xEB,
+ 0x16,0x90,0xBB,0x38,0xF0,0xBE,0xF8,0xE1,0xBF,0xBA,0x88,0xEB,
+ 0x0A,0x90,0xBB,0x38,0xC0,0xBE,0xF8,0x41,0xBF,0xBA,0x81,0xBA,
+ 0xA0,0xFF,0x8B,0xC3,0xEF,0xBA,0xA2,0xFF,0xB8,0xF8,0x0F,0xEF,
+ 0xBA,0xA6,0xFF,0x8B,0xC6,0xEF,0xBA,0xA8,0xFF,0x8B,0xC7,0xEF,
+ 0x8C,0xC8,0x8E,0xD8,0xE4,0x00,0x24,0x06,0x74,0x17,0xBB,0x00,
+ 0x80,0xBD,0xC0,0xE0,0x3C,0x02,0x74,0x5A,0xBD,0xC0,0xC0,0x3C,
+ 0x04,0x74,0x53,0xBD,0xC0,0x80,0xEB,0x4E,0x90,0xB9,0x08,0x00,
+ 0xB8,0x00,0x80,0x8E,0xC0,0x26,0xA3,0x00,0x00,0x05,0x00,0x10,
+ 0xE2,0xF5,0xBD,0xC0,0xF0,0xBB,0x00,0x7C,0xB8,0x00,0xE0,0x8E,
+ 0xC0,0x26,0x8B,0x0E,0x00,0x00,0x3B,0xC8,0x75,0x28,0xBB,0x00,
+ 0x80,0xBD,0xC0,0xE0,0xB8,0x00,0xC0,0x8E,0xC0,0x26,0x8B,0x0E,
+ 0x00,0x00,0x3B,0xC8,0x75,0x14,0xBD,0xC0,0xC0,0xB8,0x00,0x80,
+ 0x8E,0xC0,0x26,0x8B,0x0E,0x00,0x00,0x3B,0xC8,0x75,0x03,0xBD,
+ 0xC0,0x80,0x8C,0xC8,0x8E,0xD0,0xBC,0xED,0xFC,0x8B,0xC5,0x25,
+ 0x00,0xF0,0xE9,0x6C,0xFD,0xB4,0x00,0x74,0x06,0xB4,0xFF,0xEB,
+ 0x02,0xE5,0xFC,0x8E,0xC5,0x2E,0x89,0x2E,0x22,0xF8,0xE4,0x00,
+ 0x24,0x16,0x26,0xA2,0x11,0x00,0x26,0x83,0x0E,0x12,0x00,0x01,
+ 0x80,0xFC,0x00,0x74,0x06,0x26,0x83,0x0E,0x14,0x00,0x01,0x26,
+ 0xC7,0x06,0x18,0x00,0x40,0x00,0x26,0xC6,0x06,0x10,0x00,0x03,
+ 0xA8,0x10,0x74,0x06,0x26,0xC6,0x06,0x10,0x00,0x04,0xB8,0x00,
+ 0x00,0x8E,0xC0,0xB8,0xAA,0x55,0x26,0xA3,0x00,0x00,0x26,0xC7,
+ 0x06,0x02,0x00,0x00,0x00,0x26,0xC7,0x06,0x04,0x00,0x00,0x00,
+ 0x8B,0xCD,0x81,0xE1,0x00,0xF0,0x8E,0xC1,0x26,0x8B,0x1E,0x00,
+ 0x00,0x3B,0xC3,0x75,0x13,0x8E,0xC5,0x26,0xC6,0x06,0x10,0x00,
+ 0x05,0xB8,0x40,0x00,0x8E,0xD0,0xBC,0x00,0x04,0xE9,0x99,0x00,
+ 0x8C,0xC8,0x8E,0xD0,0xBC,0x7C,0xFD,0xB8,0x00,0x00,0xBB,0x00,
+ 0x20,0xE9,0xDD,0xFC,0xB4,0x00,0x74,0x06,0xB4,0xFF,0xEB,0x02,
+ 0x74,0xFD,0x8E,0xC5,0x80,0xFC,0x00,0x74,0x08,0x26,0x83,0x0E,
+ 0x14,0x00,0x02,0xEB,0x0D,0x26,0xC7,0x06,0x16,0x00,0x10,0x00,
+ 0x26,0x83,0x0E,0x12,0x00,0x02,0xB8,0x40,0x00,0x8E,0xD0,0xBC,
+ 0x00,0x04,0xE4,0x00,0xA8,0x60,0x75,0x07,0xBA,0xA2,0xFF,0xB8,
+ 0xFC,0x0F,0xEF,0xB8,0x00,0x04,0x8E,0xC0,0xB8,0xAA,0x55,0x26,
+ 0xA3,0x00,0x00,0x26,0xC7,0x06,0x02,0x00,0x00,0x00,0x26,0xC7,
+ 0x06,0x04,0x00,0x00,0x00,0xB9,0x00,0x00,0x8E,0xC1,0x26,0x8B,
+ 0x1E,0x00,0x00,0x3B,0xC3,0x75,0x02,0xEB,0x24,0x8E,0xC5,0x26,
+ 0x83,0x0E,0x12,0x00,0x04,0xB8,0x00,0x04,0xBB,0x00,0x60,0x06,
+ 0xE8,0x66,0xFC,0x07,0x75,0x09,0x26,0xC7,0x06,0x16,0x00,0x40,
+ 0x00,0xEB,0x06,0x26,0x83,0x0E,0x14,0x00,0x04,0x8E,0xC5,0x8C,
+ 0xC0,0x3D,0xC0,0xF0,0x75,0x03,0xE9,0x9F,0x00,0x3D,0xC0,0x80,
+ 0x74,0x62,0x3D,0xC0,0xC0,0x74,0x23,0x26,0x83,0x0E,0x12,0x00,
+ 0x08,0xB8,0x00,0xF0,0xBB,0x00,0x7C,0x06,0xE8,0x2E,0xFC,0x07,
+ 0x75,0x08,0x26,0x83,0x06,0x18,0x00,0x40,0xEB,0x06,0x26,0x83,
+ 0x0E,0x14,0x00,0x08,0xEB,0x72,0xB9,0x03,0x00,0xB8,0x00,0xD0,
+ 0xBA,0x08,0x00,0xBB,0x00,0x80,0x3D,0x00,0xF0,0x75,0x03,0xBB,
+ 0x00,0x7C,0x26,0x09,0x16,0x12,0x00,0x06,0x50,0x51,0xE8,0xFC,
+ 0xFB,0x59,0x58,0x07,0x75,0x0F,0x26,0x83,0x06,0x18,0x00,0x40,
+ 0xD1,0xE2,0x05,0x00,0x10,0xE2,0xD8,0xEB,0x05,0x26,0x09,0x16,
+ 0x14,0x00,0xEB,0x38,0xB9,0x07,0x00,0xB8,0x00,0x90,0xBA,0x08,
+ 0x00,0xBB,0x00,0x80,0x3D,0x00,0xF0,0x75,0x03,0xBB,0x00,0x7C,
+ 0x26,0x09,0x16,0x12,0x00,0x06,0x50,0x51,0xE8,0xC2,0xFB,0x59,
+ 0x58,0x07,0x75,0x0F,0x26,0x83,0x06,0x18,0x00,0x40,0xD1,0xE2,
+ 0x05,0x00,0x10,0xE2,0xD8,0xEB,0x05,0x26,0x09,0x16,0x14,0x00,
+ 0x26,0xA1,0x18,0x00,0x2D,0x10,0x00,0x26,0xA3,0x1A,0x00,0x06,
+ 0xFC,0x33,0xFF,0x8E,0xC7,0xB9,0x00,0x02,0xB8,0x00,0xF0,0xF3,
+ 0xAB,0x33,0xFF,0xBE,0x24,0xF8,0xB9,0x20,0x00,0xA5,0x47,0x47,
+ 0xE2,0xFB,0xBE,0x64,0xF8,0xB9,0xE0,0x00,0x8B,0x1C,0x26,0x89,
+ 0x1D,0x83,0xC7,0x04,0xE2,0xF8,0x07,0xBA,0x28,0xFF,0xB8,0xFD,
+ 0x00,0xEF,0xBA,0x32,0xFF,0xB8,0x0D,0x00,0xEF,0xBA,0x34,0xFF,
+ 0xB8,0x0F,0x00,0xEF,0xBA,0x36,0xFF,0xB8,0x0E,0x00,0xEF,0xBA,
+ 0x38,0xFF,0xB8,0x19,0x00,0xEF,0xBA,0x3A,0xFF,0xB8,0x18,0x00,
+ 0xEF,0xBA,0x3C,0xFF,0xB8,0x0B,0x00,0xEF,0xBA,0x3E,0xFF,0xB8,
+ 0x1A,0x00,0xEF,0x8D,0x3E,0x90,0x00,0x8D,0x36,0x66,0xF8,0xB9,
+ 0x10,0x00,0xF3,0xA5,0x8D,0x3E,0xB0,0x00,0x8D,0x36,0x86,0xF8,
+ 0xB9,0x02,0x00,0xF3,0xA5,0xB9,0x10,0x00,0x8D,0x36,0x90,0x00,
+ 0x83,0xC6,0x1E,0x26,0x8B,0x14,0xB3,0x10,0x32,0xC0,0xEC,0xB0,
+ 0x0C,0xEE,0x8A,0xC3,0x8A,0xC3,0xEE,0x83,0xEE,0x02,0x26,0x8B,
+ 0x14,0xFE,0xCB,0xE2,0xEB,0xB9,0x10,0x00,0x8D,0x36,0x90,0x00,
+ 0x26,0x8B,0x14,0xB3,0x01,0xBF,0x00,0x80,0xB0,0x0C,0xEE,0xF6,
+ 0xE8,0xEC,0x3A,0xC3,0x75,0x0E,0xD1,0xC7,0x26,0x09,0x3E,0x20,
+ 0x00,0x26,0xFE,0x06,0x22,0x00,0xEB,0x07,0x33,0xC0,0x26,0x89,
+ 0x04,0xD1,0xC7,0x83,0xC6,0x02,0x26,0x8B,0x14,0xFE,0xC3,0xE2,
+ 0xD7,0x26,0xC6,0x06,0x23,0x00,0x01,0x8D,0x36,0xB0,0x00,0x26,
+ 0x8B,0x14,0x32,0xC0,0xEE,0xB0,0x0C,0xEE,0xB0,0x5A,0xEE,0xB0,
+ 0x0C,0xEE,0xF6,0xE8,0xEC,0x3C,0x5A,0x74,0x14,0x26,0xC7,0x06,
+ 0xB0,0x00,0x00,0x00,0x26,0xC7,0x06,0xB2,0x00,0x00,0x00,0x26,
+ 0xC6,0x06,0x23,0x00,0x00,0xE9,0xD3,0xFA,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xEA,0x00,0xFC,0x00,0xF0,0x4D,0x2F,0x50,
+ 0x43,0x2F,0x58,0x2A,0x39,0x34,0x34,0x30
+};
+
+static unsigned pcxx_nbios=sizeof(pcxx_bios);
diff --git a/sys/gnu/i386/isa/dgfep.h b/sys/gnu/i386/isa/dgfep.h
new file mode 100644
index 0000000000000..c60c66afec902
--- /dev/null
+++ b/sys/gnu/i386/isa/dgfep.h
@@ -0,0 +1,516 @@
+static unsigned char pcxx_cook[] = {
+ 0x4F,0x53,0x18,0x85,0xE9,0xBF,0x15,0x00,0x40,0x28,0x23,0x29,
+ 0x46,0x45,0x50,0x4F,0x53,0x20,0x37,0x2E,0x30,0x37,0x20,0x31,
+ 0x2F,0x31,0x30,0x2F,0x39,0x35,0x00,0x40,0x28,0x23,0x29,0x28,
+ 0x43,0x29,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,
+ 0x31,0x39,0x38,0x39,0x2D,0x31,0x39,0x39,0x35,0x20,0x44,0x69,
+ 0x67,0x69,0x42,0x6F,0x61,0x72,0x64,0x20,0x49,0x6E,0x63,0x2E,
+ 0x00,0xCB,0x0C,0xCB,0x0C,0xE2,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,
+ 0x0C,0xCB,0x0C,0xCB,0x0C,0x57,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,
+ 0x0C,0x53,0x0B,0xCB,0x0C,0xCB,0x0C,0x42,0x0B,0xCB,0x0C,0xCB,
+ 0x0C,0x12,0x0D,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,
+ 0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,
+ 0x0C,0xCB,0x0C,0xCB,0x0C,0x00,0x10,0x80,0x10,0x00,0x11,0x80,
+ 0x11,0x00,0x12,0x80,0x12,0x00,0x13,0x80,0x13,0x00,0x14,0x80,
+ 0x14,0x00,0x15,0x80,0x15,0x00,0x16,0x80,0x16,0x00,0x17,0x80,
+ 0x17,0x78,0x0B,0xB9,0x0B,0x50,0x0C,0xB9,0x0B,0x8D,0x0B,0x8D,
+ 0x0B,0x8D,0x0B,0x8D,0x0B,0xC0,0x0B,0xC0,0x0B,0xC0,0x0B,0xC0,
+ 0x0B,0x8D,0x0B,0x8D,0x0B,0x8D,0x0B,0x8D,0x0B,0x50,0x0C,0xB9,
+ 0x0B,0x50,0x0C,0xB9,0x0B,0x8D,0x0B,0x8D,0x0B,0x8D,0x0B,0x8D,
+ 0x0B,0xC0,0x0B,0xC0,0x0B,0xC0,0x0B,0xC0,0x0B,0x8D,0x0B,0x8D,
+ 0x0B,0x8D,0x0B,0x8D,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,
+ 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,
+ 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,
+ 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,
+ 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,
+ 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x16,0x00,0xFE,
+ 0x11,0xFE,0x0B,0x2C,0x08,0xB5,0x06,0xFE,0x05,0x7E,0x04,0xFE,
+ 0x02,0x7E,0x01,0xBE,0x00,0x7E,0x00,0x5E,0x00,0x2E,0x00,0x16,
+ 0x00,0x0A,0x00,0x04,0x00,0x16,0x00,0x02,0x00,0x01,0x00,0x00,
+ 0x00,0x0E,0x00,0x06,0x00,0x7E,0x04,0xFE,0x02,0x7E,0x01,0xBE,
+ 0x00,0x7E,0x00,0x5E,0x00,0x2E,0x00,0x16,0x00,0x0A,0x00,0x04,
+ 0x00,0x18,0x00,0x86,0x13,0x03,0x0D,0xDF,0x08,0x41,0x07,0x81,
+ 0x06,0xE0,0x04,0x3F,0x03,0x9F,0x01,0xCE,0x00,0x89,0x00,0x66,
+ 0x00,0x32,0x00,0x18,0x00,0x0B,0x00,0x0B,0x00,0x18,0x00,0x0B,
+ 0x00,0x0B,0x00,0x0B,0x00,0x41,0x07,0x81,0x06,0xE0,0x04,0x3F,
+ 0x03,0x9F,0x01,0xCE,0x00,0x89,0x00,0x66,0x00,0x32,0x00,0x18,
+ 0x00,0x0B,0x00,0x0B,0x00,0x00,0x80,0x40,0xC0,0x1F,0x3F,0x7F,
+ 0xFF,0x00,0x04,0x02,0x06,0x08,0x0C,0x0A,0x0E,0x00,0x04,0x02,
+ 0x06,0x08,0x0C,0x0A,0x0E,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0x1E,0x06,0x3E,
+ 0x06,0xEF,0x06,0xF8,0x05,0x0E,0x06,0x55,0x07,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,
+ 0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,
+ 0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,
+ 0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,
+ 0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x5B,0x05,0xEA,0x05,0xEA,0x05,0xEA,
+ 0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,
+ 0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,
+ 0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,
+ 0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0x69,
+ 0x05,0x77,0x05,0x85,0x05,0x93,0x05,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,
+ 0x08,0x00,0x00,0xFA,0x8A,0x5C,0x50,0xF6,0xC3,0x0E,0x75,0x3C,
+ 0xF6,0xC3,0x40,0x75,0x16,0xF6,0xC3,0x10,0x74,0x26,0xF6,0xC3,
+ 0x01,0x75,0x13,0xF6,0xC3,0x20,0x75,0x15,0xC7,0x04,0xB6,0x04,
+ 0xE9,0xCF,0x00,0x8B,0x44,0x02,0x89,0x04,0xFF,0xE0,0xC7,0x04,
+ 0x03,0x05,0xE9,0x0E,0x01,0xC7,0x04,0x66,0x08,0xE9,0x6A,0x04,
+ 0xF6,0xC3,0x20,0x74,0x1A,0xC7,0x04,0xB3,0x08,0xE9,0xAB,0x04,
+ 0x8B,0x54,0x20,0xEC,0x8A,0xC8,0xF6,0xC3,0x02,0x75,0x42,0xF6,
+ 0xC3,0x08,0x75,0x0E,0xEB,0x69,0x90,0xC7,0x04,0x20,0x04,0xFB,
+ 0x81,0xC6,0x80,0x00,0xFF,0x24,0xF6,0xC1,0x04,0x74,0x27,0x80,
+ 0x64,0x50,0xF7,0xF6,0x44,0x51,0x02,0x74,0x13,0xF6,0x44,0x29,
+ 0x10,0x74,0x0D,0x8A,0x44,0x5D,0x83,0xC2,0x02,0xEE,0x83,0xEA,
+ 0x02,0xE9,0x49,0x04,0x8A,0x44,0x5C,0x83,0xC2,0x02,0xEE,0x83,
+ 0xEA,0x02,0xE9,0x3C,0x04,0xF6,0x44,0x50,0x04,0x75,0x28,0x83,
+ 0x7C,0x24,0xFF,0x74,0x1F,0xA1,0x00,0x0E,0x2B,0x44,0x26,0x3D,
+ 0x64,0x00,0x77,0x14,0xB0,0x05,0xEE,0x8A,0x44,0x75,0x24,0xEF,
+ 0x88,0x44,0x75,0xEE,0x80,0x64,0x50,0xFD,0x80,0x64,0x4B,0xFD,
+ 0xE9,0x0E,0x04,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0xA8,0x01,
+ 0x74,0x25,0xB0,0x05,0xEE,0x8A,0x44,0x75,0x0C,0x10,0x88,0x44,
+ 0x75,0xEE,0xA1,0x00,0x0E,0x03,0x44,0x24,0x89,0x44,0x26,0x80,
+ 0x64,0x50,0xFB,0x80,0x64,0x4B,0xFB,0x80,0x4C,0x50,0x02,0x80,
+ 0x4C,0x4B,0x02,0xE9,0xDB,0x03,0xFA,0x8B,0x54,0x20,0xEC,0x8A,
+ 0xC8,0x22,0x44,0x52,0x3A,0x44,0x53,0x75,0x19,0x8B,0x7C,0x0C,
+ 0x3B,0x7C,0x0A,0x74,0x18,0x8E,0x44,0x08,0x26,0x8A,0x05,0x47,
+ 0x23,0x7C,0x0E,0x89,0x7C,0x0C,0x83,0xC2,0x02,0xEE,0xFB,0x81,
+ 0xC6,0x80,0x00,0xFF,0x24,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,
+ 0xA8,0x01,0x74,0x0C,0x80,0x64,0x50,0xEF,0x80,0x64,0x4B,0xEF,
+ 0xC7,0x04,0xC3,0x03,0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,0xFA,
+ 0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,0x3A,0x44,0x53,
+ 0x75,0x3A,0x8B,0x7C,0x0C,0x3B,0x7C,0x0A,0x74,0x1B,0x8E,0x44,
+ 0x08,0x26,0x8A,0x05,0x47,0x23,0x7C,0x0E,0x89,0x7C,0x0C,0x8A,
+ 0xD8,0x22,0x5C,0x62,0x32,0xFF,0x03,0xDB,0x2E,0xFF,0xA7,0xC1,
+ 0x01,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0xA8,0x01,0x74,0x0C,
+ 0x80,0x64,0x50,0xEF,0x80,0x64,0x4B,0xEF,0xC7,0x04,0xC3,0x03,
+ 0xF6,0xC1,0x01,0x75,0x07,0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,
+ 0xE9,0x61,0x03,0xF6,0x44,0x2A,0x01,0x75,0x03,0xE9,0x39,0x03,
+ 0xB0,0x27,0xEB,0x42,0x90,0xF6,0x44,0x2A,0x01,0x75,0x03,0xE9,
+ 0x2B,0x03,0xB0,0x28,0xEB,0x34,0x90,0xF6,0x44,0x2A,0x01,0x75,
+ 0x03,0xE9,0x1D,0x03,0xB0,0x21,0xEB,0x26,0x90,0xF6,0x44,0x2A,
+ 0x01,0x75,0x03,0xE9,0x0F,0x03,0xB0,0x29,0xEB,0x18,0x90,0xF6,
+ 0x44,0x2A,0x01,0x75,0x03,0xE9,0x01,0x03,0xB0,0x5E,0xEB,0x0A,
+ 0x90,0xF6,0x44,0x2A,0x01,0x75,0x03,0xE9,0xF3,0x02,0x88,0x44,
+ 0x61,0xB0,0x5C,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x80,0x4C,
+ 0x50,0x40,0xC7,0x04,0xC6,0x05,0xC7,0x44,0x02,0xC6,0x05,0xE9,
+ 0xCB,0x02,0xFA,0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,
+ 0x3A,0x44,0x53,0x75,0x12,0x80,0x64,0x50,0xBF,0xC7,0x04,0x03,
+ 0x05,0x83,0x44,0x30,0x02,0x8A,0x44,0x61,0xE9,0xB9,0x02,0xE9,
+ 0xA7,0x02,0xF6,0x44,0x2A,0x02,0x75,0x03,0xE9,0xAA,0x02,0x2C,
+ 0x20,0xE9,0xA5,0x02,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xF6,
+ 0x44,0x2B,0x40,0x75,0x03,0xE9,0x89,0x02,0xB8,0x7F,0x00,0xE9,
+ 0x9B,0x01,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xF6,0x44,0x2B,
+ 0x80,0x75,0xED,0xE9,0x73,0x02,0x83,0xC2,0x02,0xEE,0x83,0xEA,
+ 0x02,0xF7,0x44,0x30,0xFF,0xFF,0x74,0x03,0xFF,0x4C,0x30,0xF6,
+ 0x44,0x2B,0x20,0x75,0x03,0xE9,0x59,0x02,0xB8,0x02,0x00,0xE9,
+ 0x6B,0x01,0xB3,0x18,0x22,0x5C,0x2B,0x75,0x16,0x83,0xC2,0x02,
+ 0xEE,0x83,0xEA,0x02,0x8B,0x44,0x30,0x05,0x08,0x00,0x25,0xF8,
+ 0xFF,0x89,0x44,0x30,0xE9,0x36,0x02,0x80,0xFB,0x18,0x75,0x57,
+ 0xB0,0x20,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x8B,0x44,0x30,
+ 0x8B,0xD8,0x05,0x08,0x00,0x25,0xF8,0xFF,0x89,0x44,0x30,0x2B,
+ 0xC3,0x48,0x74,0x38,0x89,0x44,0x32,0x80,0x4C,0x50,0x40,0xC7,
+ 0x44,0x02,0x8F,0x06,0xC7,0x04,0x8F,0x06,0xE9,0x02,0x02,0xFA,
+ 0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,0x3A,0x44,0x53,
+ 0x75,0x16,0xB0,0x20,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xFF,
+ 0x4C,0x32,0x75,0x08,0x80,0x64,0x50,0xBF,0xC7,0x04,0x03,0x05,
+ 0xE9,0xDA,0x01,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x80,0xFB,
+ 0x08,0x75,0x18,0x8B,0x44,0x30,0x8B,0xD8,0x05,0x08,0x00,0x25,
+ 0xF8,0xFF,0x89,0x44,0x30,0x2B,0xC3,0x3D,0x05,0x00,0x7C,0xDC,
+ 0xE9,0xCE,0x00,0x8B,0x44,0x30,0x8B,0xD8,0x05,0x08,0x00,0x25,
+ 0xF8,0xFF,0x89,0x44,0x30,0xB8,0x02,0x00,0xE9,0xBA,0x00,0xF6,
+ 0x44,0x2A,0x20,0x75,0x43,0xF6,0x44,0x2A,0x04,0x74,0x42,0xF6,
+ 0x44,0x2A,0x10,0x74,0x07,0xF7,0x44,0x30,0xFF,0xFF,0x74,0x30,
+ 0xB0,0x0D,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x80,0x4C,0x50,
+ 0x40,0xC7,0x04,0x21,0x07,0xC7,0x44,0x02,0x21,0x07,0xE9,0x70,
+ 0x01,0xFA,0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,0x3A,
+ 0x44,0x53,0x75,0x1C,0x80,0x64,0x50,0xBF,0xC7,0x04,0x03,0x05,
+ 0xB0,0x0A,0xEB,0x2B,0x90,0xB0,0x0A,0x83,0xC2,0x02,0xEE,0x83,
+ 0xEA,0x02,0xF6,0x44,0x2B,0x01,0x75,0x03,0xE9,0x42,0x01,0xB8,
+ 0x05,0x00,0xEB,0x55,0x90,0xF6,0x44,0x2A,0x08,0x75,0xE2,0xF6,
+ 0x44,0x2A,0x10,0x74,0x06,0x83,0x7C,0x30,0x00,0x74,0x13,0x83,
+ 0xC2,0x02,0xEE,0x83,0xEA,0x02,0xB3,0x06,0x22,0x5C,0x2B,0x75,
+ 0x08,0xC7,0x44,0x30,0x00,0x00,0xE9,0x14,0x01,0x80,0xFB,0x02,
+ 0x75,0x14,0x8B,0x44,0x30,0xC1,0xE8,0x04,0x05,0x03,0x00,0x3D,
+ 0x06,0x00,0x72,0x14,0xB8,0x06,0x00,0xEB,0x0F,0x90,0x80,0xFB,
+ 0x04,0x75,0x06,0xB8,0x05,0x00,0xEB,0x04,0x90,0xB8,0x09,0x00,
+ 0xC7,0x44,0x30,0x00,0x00,0xF6,0x44,0x2A,0x40,0x74,0x45,0x3D,
+ 0x20,0x00,0x77,0x40,0xBB,0x01,0x00,0x3D,0x03,0x00,0x7E,0x03,
+ 0xBB,0x02,0x00,0x89,0x5C,0x32,0x80,0x4C,0x50,0x40,0xC7,0x44,
+ 0x02,0xD2,0x07,0xC7,0x04,0xD2,0x07,0xE9,0xBF,0x00,0xFA,0x8B,
+ 0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,0x3A,0x44,0x53,0x75,
+ 0x10,0x8A,0x44,0x60,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x83,
+ 0x6C,0x32,0x01,0x7E,0x50,0xE9,0x9D,0x00,0x05,0x06,0x00,0x03,
+ 0xC0,0x89,0x44,0x32,0x80,0x4C,0x50,0x40,0xC7,0x44,0x02,0x0C,
+ 0x08,0xC7,0x04,0x0C,0x08,0xE9,0x85,0x00,0xFA,0x8B,0x54,0x20,
+ 0xEC,0x8A,0xC8,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0xA8,0x01,
+ 0x74,0x0F,0xA1,0x00,0x0E,0x01,0x44,0x32,0xC7,0x44,0x02,0x30,
+ 0x08,0xC7,0x04,0x30,0x08,0xEB,0x62,0x90,0x8B,0x54,0x20,0xEC,
+ 0x8A,0xC8,0xA1,0x00,0x0E,0x2B,0x44,0x32,0x3D,0xE8,0x03,0x77,
+ 0xEC,0x80,0x64,0x50,0xBF,0xC7,0x04,0x03,0x05,0xEB,0x46,0x90,
+ 0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0xA8,0x01,0x74,0x3A,0x80,
+ 0x64,0x50,0xEF,0x80,0x64,0x4B,0xEF,0xC7,0x04,0xB3,0x08,0xEB,
+ 0x2C,0x90,0xFA,0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,
+ 0x3A,0x44,0x53,0x75,0x1C,0x8B,0x7C,0x0C,0x3B,0x7C,0x0A,0x74,
+ 0xCF,0x8E,0x44,0x08,0x26,0x8A,0x05,0x47,0x23,0x7C,0x0E,0x89,
+ 0x7C,0x0C,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xF6,0xC1,0x01,
+ 0x75,0x26,0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,0xFF,0x44,0x30,
+ 0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xF6,0xC1,0x01,0x75,0x10,
+ 0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,0xFA,0x8B,0x54,0x20,0xEC,
+ 0xA8,0x01,0x74,0xDA,0xC6,0x44,0x49,0x02,0x8B,0x7C,0x12,0x8E,
+ 0x44,0x10,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0x8A,0xE0,0x90,
+ 0xB0,0x30,0xEE,0x83,0xC2,0x02,0x90,0xEC,0x83,0xEA,0x02,0x23,
+ 0x44,0x34,0xFF,0x64,0x06,0xB3,0x1C,0x22,0x5C,0x51,0x75,0x1A,
+ 0xF6,0x44,0x29,0x04,0x74,0x21,0xF6,0x44,0x29,0x20,0x75,0x2B,
+ 0x80,0x7C,0x5E,0x00,0x75,0x1D,0xC7,0x44,0x06,0x58,0x0A,0xE9,
+ 0x56,0x01,0xF6,0xC3,0x10,0x75,0x2E,0xF6,0xC3,0x04,0x75,0x74,
+ 0xEB,0x6B,0x90,0xC7,0x44,0x06,0x62,0x0A,0xE9,0x4B,0x01,0xC7,
+ 0x44,0x06,0x53,0x0A,0xE9,0x34,0x01,0x80,0x7C,0x5E,0x00,0x75,
+ 0x08,0xC7,0x44,0x06,0xCA,0x09,0xE9,0x9D,0x00,0xC7,0x44,0x06,
+ 0xC5,0x09,0xE9,0x90,0x00,0x0A,0xC0,0x74,0x2A,0xFE,0x4C,0x63,
+ 0x74,0x1A,0x80,0xE3,0xEF,0x75,0xC4,0xF6,0x44,0x29,0x04,0x74,
+ 0x21,0xF6,0x44,0x29,0x20,0x75,0x21,0x80,0x7C,0x5E,0x00,0x75,
+ 0x18,0xE9,0x00,0x01,0x80,0x64,0x51,0xEF,0x80,0xE3,0xEF,0x75,
+ 0xA6,0xEB,0x85,0x80,0x64,0x51,0xEF,0xE9,0x06,0x01,0xE9,0xF5,
+ 0x00,0xE9,0xE3,0x00,0x80,0x7C,0x5E,0x00,0x75,0x4F,0xEB,0x52,
+ 0x90,0x80,0x64,0x51,0xF7,0xE9,0xE2,0x00,0x80,0x64,0x53,0x3F,
+ 0x80,0x64,0x54,0xFE,0x80,0x4C,0x58,0x01,0x80,0x64,0x51,0xFB,
+ 0xF6,0x44,0x29,0x40,0x75,0x2C,0x3A,0x44,0x5D,0x74,0x27,0x3A,
+ 0x44,0x5C,0x74,0x22,0xF6,0x44,0x29,0x20,0x74,0x0A,0x3A,0x44,
+ 0x5A,0x74,0x17,0x3A,0x44,0x5B,0x74,0x12,0xF6,0x44,0x5E,0xFF,
+ 0x74,0x09,0x3A,0x44,0x5E,0x75,0x04,0x80,0x4C,0x51,0x08,0xE9,
+ 0xA0,0x00,0xE9,0xAB,0x00,0x3A,0x44,0x5E,0x74,0x7D,0x3A,0x44,
+ 0x5C,0x74,0x3D,0x3A,0x44,0x5D,0x74,0x55,0x3A,0x44,0x5A,0x74,
+ 0x08,0x3A,0x44,0x5B,0x74,0x18,0xE9,0x81,0x00,0xF6,0x44,0x53,
+ 0x40,0x74,0x07,0x80,0x64,0x53,0xBF,0xE9,0x82,0x00,0x3A,0x44,
+ 0x5B,0x74,0x03,0xEB,0x7B,0x90,0x80,0x4C,0x53,0x40,0xF6,0x44,
+ 0x29,0x08,0x74,0x70,0x80,0x4C,0x51,0x04,0xC7,0x44,0x06,0xE1,
+ 0x08,0xEB,0x65,0x90,0xF6,0x44,0x53,0x80,0x74,0x0F,0x80,0x64,
+ 0x53,0x7F,0x80,0x64,0x54,0xFE,0x80,0x4C,0x58,0x01,0xEB,0x50,
+ 0x90,0x3A,0x44,0x5D,0x74,0x03,0xEB,0x48,0x90,0x80,0x4C,0x53,
+ 0x80,0x80,0x4C,0x54,0x01,0x80,0x4C,0x58,0x01,0xF6,0x44,0x29,
+ 0x08,0x74,0x35,0x80,0x4C,0x51,0x04,0xC7,0x44,0x06,0xE1,0x08,
+ 0xEB,0x2A,0x90,0x80,0x4C,0x51,0x08,0xC7,0x44,0x06,0xE1,0x08,
+ 0xEB,0x10,0x90,0x3A,0x44,0x5E,0x74,0xEF,0x3A,0x44,0x5C,0x74,
+ 0xAF,0x3A,0x44,0x5D,0x74,0xC7,0x3D,0xFF,0x00,0x73,0x26,0xAA,
+ 0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x4F,0xEC,0xA8,0x01,0x74,
+ 0x03,0xE9,0x4E,0xFE,0x89,0x7C,0x12,0x2B,0x7C,0x14,0x23,0x7C,
+ 0x16,0x3B,0x7C,0x1C,0x73,0x46,0xFB,0x81,0xC6,0x80,0x00,0xFF,
+ 0x24,0x0A,0xE4,0x75,0x1E,0xB3,0x0C,0x22,0x5C,0x28,0x80,0xFB,
+ 0x08,0x75,0xCC,0xAA,0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x1B,
+ 0xAA,0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x12,0xEB,0xC1,0xF6,
+ 0x44,0x28,0x04,0x75,0xBB,0xF6,0x44,0x28,0x08,0x75,0x50,0x32,
+ 0xC0,0xEB,0xA8,0x4F,0x23,0x7C,0x16,0x89,0x7C,0x12,0xC6,0x44,
+ 0x59,0x01,0xEB,0xA4,0xF6,0x44,0x51,0x02,0x74,0x07,0xFB,0x81,
+ 0xC6,0x80,0x00,0xFF,0x24,0x80,0x4C,0x51,0x02,0xB0,0x05,0xEE,
+ 0xB0,0x82,0x22,0x44,0x5F,0xF6,0xD0,0x22,0x44,0x75,0x88,0x44,
+ 0x75,0xEE,0xF6,0x44,0x29,0x10,0x74,0x10,0x80,0x4C,0x54,0x04,
+ 0x80,0x4C,0x58,0x04,0x80,0x74,0x50,0x08,0xC7,0x04,0xC3,0x03,
+ 0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,0x26,0xC6,0x05,0xFF,0x47,
+ 0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0xA7,0x32,0xFF,0xF6,0x44,
+ 0x29,0x80,0x74,0x0A,0x8A,0xDC,0xC0,0xEB,0x04,0x2E,0x8A,0xBF,
+ 0xB1,0x01,0x26,0x88,0x3D,0x47,0x23,0x7C,0x16,0x3B,0x7C,0x14,
+ 0x74,0x89,0xAA,0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x80,0xE9,
+ 0x2E,0xFF,0x1E,0x2E,0x8E,0x1E,0xC1,0x03,0xFF,0x06,0x1C,0x0E,
+ 0x60,0xBE,0x00,0x14,0xEB,0x0F,0x90,0x1E,0x2E,0x8E,0x1E,0xC1,
+ 0x03,0xFF,0x06,0x1A,0x0E,0x60,0xBE,0x00,0x10,0xB9,0x08,0x00,
+ 0x8B,0x54,0x20,0xB0,0x03,0xEE,0x90,0x90,0x32,0xFF,0xEC,0x8A,
+ 0xD8,0x02,0xD8,0x2E,0xFF,0xA7,0xA9,0x00,0x81,0xC6,0x00,0x01,
+ 0x8B,0x54,0x20,0x0B,0xD2,0xE0,0xE4,0xB8,0x00,0x80,0xBA,0x22,
+ 0xFF,0xEF,0x61,0x1F,0xCF,0x81,0xCE,0x80,0x00,0x8B,0x54,0x20,
+ 0xFF,0x06,0x20,0x0E,0xB0,0x01,0xEE,0x8A,0x44,0x71,0x24,0xE7,
+ 0x88,0x44,0x71,0xEE,0xC6,0x44,0x49,0x02,0x80,0x4C,0x50,0x20,
+ 0xC7,0x04,0xC3,0x03,0x81,0xE6,0x7F,0xFF,0x8B,0x54,0x20,0xEB,
+ 0xAE,0x81,0xCE,0x80,0x00,0x8B,0x54,0x20,0xFF,0x06,0x22,0x0E,
+ 0xEC,0x0A,0xC0,0x79,0x7A,0x80,0x4C,0x51,0x10,0xC7,0x44,0x06,
+ 0xE1,0x08,0xC6,0x44,0x63,0x04,0xF6,0x44,0x51,0x04,0x74,0x08,
+ 0x80,0x64,0x51,0xFB,0x80,0x64,0x53,0x3F,0xF6,0x44,0x28,0x01,
+ 0x75,0x59,0xF6,0x44,0x28,0x02,0x75,0x4F,0x8B,0x7C,0x12,0x8C,
+ 0xC3,0x8E,0x44,0x10,0xF6,0x44,0x28,0x08,0x74,0x1E,0xB0,0xFF,
+ 0xAA,0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x26,0x32,0xC0,0xF6,
+ 0x44,0x29,0x80,0x74,0x02,0xB0,0x10,0xAA,0x23,0x7C,0x16,0x3B,
+ 0x7C,0x14,0x74,0x13,0x32,0xC0,0xAA,0x23,0x7C,0x16,0x3B,0x7C,
+ 0x14,0x74,0x08,0x8E,0xC3,0x89,0x7C,0x12,0xEB,0x15,0x90,0x8E,
+ 0xC3,0x4F,0x23,0x7C,0x16,0x89,0x7C,0x12,0xC6,0x44,0x59,0x01,
+ 0xEB,0x05,0x90,0x80,0x4C,0x4F,0x01,0xB0,0x10,0xEE,0x81,0xE6,
+ 0x7F,0xFF,0x8B,0x54,0x20,0xE9,0x17,0xFF,0xFF,0x06,0x1E,0x0E,
+ 0xE9,0x10,0xFF,0x1E,0x2E,0x8E,0x1E,0xC1,0x03,0x50,0x52,0x55,
+ 0x8B,0xEC,0x8B,0x46,0x08,0xA3,0x12,0x0E,0x32,0xE4,0xA0,0x22,
+ 0x0C,0xA3,0x10,0x0E,0xFF,0x06,0x00,0x0E,0x83,0x06,0x0E,0x0E,
+ 0x0A,0x83,0x3E,0x04,0x0E,0x00,0x74,0x31,0x8B,0x16,0x00,0x0E,
+ 0x2B,0x16,0x02,0x0E,0x3B,0x16,0x04,0x0E,0x72,0x23,0x8B,0x16,
+ 0x00,0x0E,0x89,0x16,0x02,0x0E,0x8B,0x16,0x18,0x0D,0x3B,0x16,
+ 0x1A,0x0D,0x74,0x11,0x80,0x3E,0x10,0x0C,0x01,0x74,0x16,0xB0,
+ 0x00,0x90,0xE6,0x00,0x0C,0x08,0x90,0xE6,0x00,0xB8,0x00,0x80,
+ 0xBA,0x22,0xFF,0xEF,0x5D,0x5A,0x58,0x1F,0xCF,0xB0,0x80,0xE6,
+ 0x00,0xA0,0x11,0x0C,0x0C,0x10,0xA2,0x11,0x0C,0xEB,0xE6,0x1E,
+ 0x2E,0x8E,0x1E,0xC1,0x03,0xFF,0x06,0x28,0x0E,0x55,0x8B,0xEC,
+ 0x8B,0x6E,0x02,0x89,0x2E,0x16,0x0E,0x5D,0x1F,0xCF,0x1E,0x2E,
+ 0x8E,0x1E,0xC1,0x03,0xFF,0x06,0x24,0x0E,0x55,0x8B,0xEC,0x8B,
+ 0x6E,0x02,0x89,0x2E,0x14,0x0E,0x5D,0x80,0x3E,0x10,0x0C,0x01,
+ 0x75,0x12,0x50,0xA0,0x11,0x0C,0x0C,0x01,0xA2,0x11,0x0C,0xE4,
+ 0x00,0x90,0x90,0x24,0x7F,0xE6,0x00,0x58,0x1F,0xCF,0x1E,0x06,
+ 0x60,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x2E,0x8E,0x1E,0xC1,
+ 0x03,0x2E,0x8E,0x06,0xC1,0x03,0x2E,0xFF,0x06,0x30,0x0D,0xFC,
+ 0xFF,0x26,0x2E,0x0E,0x00,0x00,0xFB,0x40,0x43,0x41,0x42,0x46,
+ 0x47,0x45,0xEB,0xF6,0xC3,0x00,0x00,0x8F,0x06,0x2E,0x0E,0x2E,
+ 0xFF,0x06,0x3D,0x0D,0xB8,0x00,0x00,0xBA,0x58,0xFF,0xEF,0xB8,
+ 0x00,0xE0,0xBA,0x5E,0xFF,0xEF,0x61,0x07,0x1F,0xCF,0xC2,0xFE,
+ 0xFF,0x8B,0x7C,0x0A,0x2B,0x7C,0x0C,0x23,0x7C,0x0E,0x3B,0x7C,
+ 0x18,0x77,0x2E,0xC6,0x44,0x4D,0x00,0x80,0x4C,0x4F,0x02,0xEB,
+ 0x5A,0x90,0x8B,0x7C,0x0A,0x3B,0x7C,0x0C,0x75,0x1B,0x8B,0x3E,
+ 0x10,0x0D,0x3B,0x3E,0x12,0x0D,0x75,0x53,0xF6,0x44,0x4B,0xFF,
+ 0x75,0x4D,0xC6,0x44,0x4C,0x00,0x80,0x4C,0x4F,0x04,0xEB,0x43,
+ 0x90,0xF6,0x44,0x50,0x10,0x75,0x3C,0xEB,0x09,0x90,0x8B,0x7C,
+ 0x0A,0x2B,0x7C,0x0C,0x74,0x31,0x80,0x4C,0x50,0x10,0x80,0x4C,
+ 0x4B,0x10,0xC7,0x04,0xC3,0x03,0xEB,0x23,0x90,0xFA,0x8B,0x36,
+ 0x08,0x0E,0x8B,0x54,0x20,0xEC,0x8A,0xF8,0x8A,0x5C,0x54,0x32,
+ 0xFB,0xF6,0x44,0x4D,0xFF,0x75,0x8E,0xF6,0x44,0x4C,0xFF,0x75,
+ 0xA1,0xF6,0x44,0x50,0x10,0x74,0xC7,0xEC,0x32,0xC3,0x22,0xF8,
+ 0x83,0x2E,0x10,0x0E,0x01,0x78,0x05,0xD0,0x6C,0x49,0x72,0x45,
+ 0x8B,0x7C,0x12,0x2B,0x7C,0x14,0x74,0x22,0x80,0x7C,0x4E,0x00,
+ 0x74,0x1C,0x23,0x7C,0x16,0x03,0xFF,0x3B,0x7C,0x16,0x73,0x43,
+ 0x8B,0x0E,0x0E,0x0E,0x2B,0x4C,0x6E,0x3B,0x4C,0x22,0x73,0x37,
+ 0x80,0x7C,0x49,0x00,0x74,0x31,0xF6,0x44,0x51,0x02,0x75,0x3C,
+ 0xEC,0x32,0xC3,0x22,0xF8,0x80,0xE7,0x38,0xFB,0x89,0x1E,0x30,
+ 0x0E,0xBE,0x00,0x10,0xFF,0x14,0xEB,0x61,0x90,0xB0,0x01,0xEE,
+ 0x8A,0x44,0x71,0x0C,0x10,0x88,0x44,0x71,0xEE,0x80,0x64,0x50,
+ 0xDF,0xC7,0x04,0xC3,0x03,0xEB,0xA5,0xC6,0x44,0x4E,0x00,0x8B,
+ 0x0E,0x0E,0x0E,0x89,0x4C,0x6E,0x80,0x4C,0x4F,0x08,0xEB,0xBE,
+ 0x8B,0x7C,0x12,0x2B,0x7C,0x14,0x23,0x7C,0x16,0x3B,0x7C,0x1A,
+ 0x73,0xB6,0x80,0x64,0x51,0xFD,0xF6,0x44,0x29,0x10,0x74,0x10,
+ 0x80,0x64,0x54,0xFB,0x80,0x4C,0x58,0x04,0x80,0x74,0x50,0x08,
+ 0xC7,0x04,0xC3,0x03,0xB0,0x05,0xEE,0xB0,0x82,0x22,0x44,0x5F,
+ 0x0A,0x44,0x75,0x88,0x44,0x75,0xEE,0xEB,0x8B,0xFA,0x8B,0x36,
+ 0x08,0x0E,0x8B,0x1E,0x30,0x0E,0x8A,0xCB,0xE5,0x80,0x23,0x44,
+ 0x2E,0x74,0x02,0xF6,0xD1,0x80,0xE1,0x40,0x0A,0xF9,0x8A,0xDF,
+ 0x22,0x5C,0x55,0x30,0x5C,0x54,0x32,0xFB,0x88,0x7C,0x55,0x0A,
+ 0x5C,0x58,0x88,0x5C,0x58,0x22,0x5C,0x56,0x75,0x24,0x80,0x7C,
+ 0x4F,0x00,0x75,0x22,0xFB,0x03,0x74,0x1E,0x89,0x36,0x08,0x0E,
+ 0xFF,0x06,0x26,0x0E,0x8B,0x3E,0x12,0x0D,0x3B,0x3E,0x10,0x0D,
+ 0x75,0x46,0xBE,0x00,0x10,0xFF,0x14,0xE9,0xD3,0xFE,0x80,0x4C,
+ 0x4F,0x20,0x8B,0x3E,0x18,0x0D,0x8A,0x44,0x48,0x8A,0x64,0x4F,
+ 0x89,0x85,0x00,0x08,0x8A,0x44,0x54,0x8A,0x64,0x57,0x89,0x85,
+ 0x02,0x08,0x83,0xC7,0x04,0x81,0xE7,0xFC,0x03,0x3B,0x3E,0x1A,
+ 0x0D,0x74,0x13,0x88,0x44,0x57,0xC6,0x44,0x4F,0x00,0x8A,0x44,
+ 0x56,0xF6,0xD0,0x20,0x44,0x58,0x89,0x3E,0x18,0x0D,0xEB,0xA4,
+ 0xFF,0x06,0x2C,0x0E,0xBE,0x00,0x10,0xFF,0x14,0xFA,0x8B,0x3E,
+ 0x12,0x0D,0x81,0xC7,0x00,0x04,0x8A,0x5D,0x01,0x83,0xE3,0x0F,
+ 0x03,0xDB,0x2E,0x8B,0xB7,0x89,0x00,0x8B,0x54,0x20,0x0B,0xD2,
+ 0x74,0x0D,0x8A,0x1D,0x83,0xE3,0x1F,0x03,0xDB,0xFA,0x2E,0xFF,
+ 0xA7,0x9C,0x0F,0xFF,0x06,0x2A,0x0E,0x8B,0x3E,0x12,0x0D,0x8B,
+ 0x36,0x18,0x0D,0x8B,0x9D,0x00,0x04,0x89,0x9C,0x00,0x08,0x8B,
+ 0x9D,0x02,0x04,0x89,0x9C,0x02,0x08,0x83,0xC6,0x04,0x81,0xE6,
+ 0xFC,0x03,0x3B,0x36,0x1A,0x0D,0x74,0x04,0x89,0x36,0x18,0x0D,
+ 0xFB,0x8B,0x3E,0x12,0x0D,0x83,0xC7,0x04,0x81,0xE7,0xFC,0x03,
+ 0x89,0x3E,0x12,0x0D,0xBE,0x00,0x10,0xFF,0x14,0xE9,0x1D,0xFE,
+ 0xDC,0x0F,0xE4,0x0F,0xEC,0x0F,0x0D,0x10,0x1C,0x10,0x57,0x0F,
+ 0x2F,0x10,0x57,0x0F,0x3B,0x10,0x54,0x10,0x83,0x10,0xCF,0x10,
+ 0xDB,0x10,0xE4,0x10,0xEB,0x10,0x35,0x11,0x7D,0x11,0x83,0x11,
+ 0xA1,0x11,0xB9,0x11,0xF2,0x11,0x38,0x12,0x03,0x13,0x0C,0x13,
+ 0x57,0x0F,0x57,0x0F,0x57,0x0F,0x57,0x0F,0x57,0x0F,0x57,0x0F,
+ 0x57,0x0F,0x57,0x0F,0x8B,0x45,0x02,0x89,0x44,0x1A,0xEB,0xA0,
+ 0x8B,0x45,0x02,0x89,0x44,0x1C,0xEB,0x98,0x8B,0x45,0x02,0x8B,
+ 0x5C,0x0A,0x2B,0x5C,0x0C,0x23,0x5C,0x0E,0x8B,0x4C,0x0A,0x2B,
+ 0xC8,0x23,0x4C,0x0E,0x3B,0xD9,0x76,0x06,0x23,0x44,0x0E,0x89,
+ 0x44,0x0C,0xE9,0x77,0xFF,0x80,0x4C,0x53,0x80,0x80,0x4C,0x54,
+ 0x01,0x80,0x4C,0x58,0x01,0xE9,0x68,0xFF,0x80,0x64,0x53,0x3F,
+ 0x80,0x64,0x54,0xFE,0x80,0x4C,0x58,0x01,0x80,0x64,0x51,0xFB,
+ 0xE9,0x55,0xFF,0x8B,0x45,0x02,0x88,0x44,0x5A,0x88,0x64,0x5B,
+ 0xE9,0x49,0xFF,0x8B,0x45,0x02,0x0B,0xC0,0x74,0x03,0x89,0x44,
+ 0x24,0x80,0x4C,0x50,0x04,0x80,0x4C,0x4B,0x04,0xC7,0x04,0xC3,
+ 0x03,0xE9,0x30,0xFF,0x8B,0x5D,0x02,0xF6,0xD7,0x22,0x7C,0x54,
+ 0x0A,0xDF,0x8A,0x44,0x54,0x32,0xC3,0x24,0x82,0x30,0x44,0x54,
+ 0xB0,0x05,0xEE,0x8A,0x44,0x75,0x32,0xD8,0x8A,0x7C,0x5F,0xF6,
+ 0xD7,0x22,0xDF,0x80,0xE3,0x82,0x32,0xC3,0x88,0x44,0x75,0xEE,
+ 0xE9,0x01,0xFF,0x8B,0x5D,0x02,0xF6,0xC7,0x04,0x75,0x08,0x80,
+ 0x64,0x53,0x3F,0x80,0x64,0x51,0xFB,0x8A,0x44,0x29,0x32,0xC7,
+ 0xA8,0x10,0x74,0x0E,0xF6,0x44,0x51,0x02,0x74,0x08,0x80,0x74,
+ 0x50,0x08,0xC7,0x04,0xC3,0x03,0x88,0x5C,0x28,0x88,0x7C,0x29,
+ 0xB4,0x60,0xF6,0xC3,0x10,0x74,0x03,0x80,0xCC,0x10,0x8A,0x44,
+ 0x62,0xF6,0xC3,0x20,0x74,0x02,0x24,0x7F,0x89,0x44,0x34,0xC7,
+ 0x44,0x06,0xE1,0x08,0xE9,0xB5,0xFE,0x8B,0x45,0x02,0x88,0x44,
+ 0x5C,0x88,0x64,0x5D,0xE9,0xA9,0xFE,0x8B,0x45,0x02,0x89,0x44,
+ 0x18,0xE9,0xA0,0xFE,0xFF,0x1E,0x24,0x0D,0xE9,0x99,0xFE,0xF6,
+ 0x44,0x51,0x02,0x75,0x41,0x8B,0x44,0x12,0x2B,0x44,0x14,0x23,
+ 0x44,0x16,0x3B,0x44,0x1A,0x72,0x33,0x80,0x4C,0x51,0x02,0xF6,
+ 0x44,0x29,0x10,0x74,0x10,0x80,0x4C,0x54,0x04,0x80,0x4C,0x58,
+ 0x04,0x80,0x74,0x50,0x08,0xC7,0x04,0xC3,0x03,0xF6,0x44,0x5F,
+ 0x82,0x74,0x13,0xB0,0x05,0xEE,0x8A,0x44,0x75,0xB4,0x82,0x22,
+ 0x64,0x5F,0xF6,0xD4,0x22,0xC4,0x88,0x44,0x75,0xEE,0xE9,0x4F,
+ 0xFE,0xF6,0x44,0x51,0x02,0x74,0x3F,0x8B,0x44,0x12,0x2B,0x44,
+ 0x14,0x23,0x44,0x16,0x3B,0x44,0x1C,0x73,0xE9,0x80,0x64,0x51,
+ 0xFD,0xF6,0x44,0x29,0x10,0x74,0x10,0x80,0x64,0x54,0xFB,0x80,
+ 0x4C,0x58,0x04,0x80,0x74,0x50,0x08,0xC7,0x04,0xC3,0x03,0xF6,
+ 0x44,0x5F,0x02,0x74,0x11,0xB0,0x05,0xEE,0x8A,0x44,0x75,0xB4,
+ 0x82,0x22,0x64,0x5F,0x0A,0xC4,0x88,0x44,0x75,0xEE,0xE9,0x07,
+ 0xFE,0xE8,0x8A,0x02,0xE9,0x01,0xFE,0x8B,0x45,0x02,0xBB,0x10,
+ 0x27,0xF7,0xE3,0xBB,0x0F,0x00,0xF7,0xF3,0xA3,0x06,0x0E,0xBA,
+ 0x52,0xFF,0xEF,0xBA,0x50,0xFF,0xB8,0x00,0x00,0xEF,0xE9,0xE3,
+ 0xFD,0x8B,0x45,0x02,0x3A,0x06,0x22,0x0C,0x72,0x0C,0x3B,0x06,
+ 0x1A,0x0C,0x77,0x06,0xE8,0xAB,0x01,0xE9,0xCE,0xFD,0xE9,0x9E,
+ 0xFD,0x8B,0x45,0x02,0x88,0x44,0x2A,0x88,0x64,0x2B,0x0B,0xC0,
+ 0x75,0x07,0x80,0x64,0x50,0xFE,0xEB,0x10,0x90,0xF6,0x44,0x50,
+ 0x01,0x75,0x09,0x80,0x4C,0x50,0x01,0xC7,0x44,0x30,0x00,0x00,
+ 0xA8,0x80,0x75,0x07,0xC6,0x44,0x60,0x00,0xEB,0x05,0x90,0xC6,
+ 0x44,0x60,0x7F,0xC7,0x04,0xC3,0x03,0xE9,0x92,0xFD,0x8B,0x5D,
+ 0x02,0xF6,0xD7,0x22,0x7C,0x5F,0x0A,0xDF,0x8A,0xFB,0x88,0x5C,
+ 0x5F,0x8A,0x44,0x52,0x8A,0x64,0x53,0x8B,0xCB,0x33,0xC8,0x81,
+ 0xE1,0x38,0x38,0x33,0xC1,0x88,0x44,0x52,0x88,0x64,0x53,0xB0,
+ 0x05,0xEE,0xF6,0xD3,0x22,0x5C,0x54,0xF6,0x44,0x51,0x02,0x75,
+ 0x02,0x0A,0xDF,0x8A,0x44,0x75,0x32,0xD8,0x80,0xE3,0x82,0x32,
+ 0xC3,0x88,0x44,0x75,0xEE,0xE9,0x4C,0xFD,0x8B,0x5D,0x02,0x88,
+ 0x5C,0x2C,0x88,0x7C,0x2D,0x8B,0xCB,0x83,0xE3,0x0F,0x03,0xDB,
+ 0x80,0x3E,0x10,0x0C,0x01,0x75,0x1F,0xA1,0x0E,0x0C,0x86,0xE0,
+ 0x3D,0x32,0x31,0x73,0x15,0xF6,0xC5,0x04,0x75,0x08,0x2E,0x8B,
+ 0x9F,0x69,0x01,0xEB,0x1B,0x90,0x2E,0x8B,0x9F,0x89,0x01,0xEB,
+ 0x13,0x90,0xF6,0xC5,0x04,0x75,0x08,0x2E,0x8B,0x9F,0x29,0x01,
+ 0xEB,0x06,0x90,0x2E,0x8B,0x9F,0x49,0x01,0xB0,0x0C,0xEE,0x8A,
+ 0xC3,0x88,0x44,0x7C,0xEE,0xB0,0x0D,0x90,0x90,0xEE,0x8A,0xC7,
+ 0x88,0x44,0x7D,0xEE,0xB0,0x04,0xEE,0xB0,0x44,0xF6,0xC1,0x40,
+ 0x74,0x0C,0xF6,0xC1,0x80,0x74,0x05,0x04,0x04,0xEB,0x03,0x90,
+ 0x0C,0x08,0xF6,0xC5,0x01,0x74,0x09,0x0C,0x01,0xF6,0xC5,0x02,
+ 0x75,0x02,0x0C,0x02,0x88,0x44,0x74,0xEE,0xB0,0x03,0x90,0x90,
+ 0xEE,0x8A,0xD9,0x80,0xE3,0x30,0xC0,0xEB,0x04,0x32,0xFF,0x2E,
+ 0x8A,0xA7,0xA9,0x01,0x8A,0x44,0x73,0x24,0x3F,0x0A,0xC4,0x88,
+ 0x44,0x73,0xEE,0x90,0x90,0xB0,0x05,0xEE,0xD0,0xEC,0x8A,0x44,
+ 0x75,0x24,0x9F,0x0A,0xC4,0x88,0x44,0x75,0xEE,0x2E,0x8A,0x87,
+ 0xAD,0x01,0x88,0x44,0x62,0xF6,0x44,0x28,0x20,0x74,0x02,0x24,
+ 0x7F,0x88,0x44,0x34,0xE9,0x81,0xFC,0x8A,0x45,0x02,0x88,0x44,
+ 0x5E,0xE9,0x78,0xFC,0x8B,0x45,0x02,0xBA,0x5A,0xFF,0xEF,0x9C,
+ 0xFF,0x36,0x26,0x0D,0xFF,0x36,0x24,0x0D,0x1E,0x06,0x60,0x8B,
+ 0x36,0x0A,0x0E,0xC7,0x04,0x3F,0x0D,0xE9,0x5A,0xFC,0xB8,0x00,
+ 0x00,0x8E,0xC0,0x8B,0xF0,0x8B,0xF8,0x2E,0x8B,0x9C,0x49,0x00,
+ 0x83,0xC6,0x02,0x26,0x89,0x1D,0x26,0x8C,0x4D,0x02,0x83,0xC7,
+ 0x04,0x81,0xFF,0x80,0x00,0x72,0xE8,0x26,0xC7,0x05,0xCB,0x0C,
+ 0x26,0x8C,0x4D,0x02,0x83,0xC7,0x04,0x81,0xFF,0x00,0x04,0x72,
+ 0xEE,0xC3,0xC1,0xE0,0x06,0x8B,0xD8,0x8C,0xDA,0x81,0xC2,0x00,
+ 0x04,0x8B,0xFA,0x8A,0x0E,0x22,0x0C,0xB5,0x00,0xBE,0x00,0x10,
+ 0x33,0xC0,0x89,0x44,0x0A,0x89,0x44,0x0C,0x89,0x44,0x12,0x89,
+ 0x44,0x14,0x81,0xC6,0x80,0x00,0xE2,0xEE,0x89,0x36,0x0A,0x0E,
+ 0xB8,0x01,0x00,0x8B,0xD0,0xB3,0x00,0x8A,0x0E,0x22,0x0C,0xB5,
+ 0x00,0xBE,0x00,0x10,0x2B,0xDA,0x72,0x29,0x89,0x44,0x16,0x81,
+ 0xC6,0x80,0x00,0xE2,0xF3,0x8A,0x0E,0x22,0x0C,0xB5,0x00,0xBE,
+ 0x00,0x10,0x2B,0xDA,0x72,0x13,0x89,0x44,0x0E,0x81,0xC6,0x80,
+ 0x00,0xE2,0xF3,0x8B,0xD0,0x03,0xC0,0x81,0xFA,0x00,0x02,0x72,
+ 0xCA,0x8A,0x0E,0x22,0x0C,0xB5,0x00,0xBE,0x00,0x10,0x89,0x7C,
+ 0x10,0x8B,0x44,0x16,0x03,0xF8,0x8B,0xD7,0xC1,0xE0,0x04,0x48,
+ 0x89,0x44,0x16,0x81,0xC6,0x80,0x00,0xE2,0xE9,0x8A,0x0E,0x22,
+ 0x0C,0xB5,0x00,0xBE,0x00,0x10,0x89,0x7C,0x08,0x8B,0x44,0x0E,
+ 0x03,0xF8,0x8B,0xD7,0xC1,0xE0,0x04,0x48,0x89,0x44,0x0E,0x81,
+ 0xC6,0x80,0x00,0xE2,0xE9,0xC3,0xC7,0x04,0x20,0x04,0xC7,0x44,
+ 0x06,0xE1,0x08,0x8B,0xC6,0x2D,0x00,0x10,0xB1,0x80,0xF6,0xF1,
+ 0x88,0x44,0x48,0xC7,0x44,0x0A,0x00,0x00,0xC7,0x44,0x0C,0x00,
+ 0x00,0xC7,0x44,0x12,0x00,0x00,0xC7,0x44,0x14,0x00,0x00,0xC7,
+ 0x44,0x18,0x00,0x00,0xC7,0x44,0x1A,0x00,0x00,0xC7,0x44,0x1C,
+ 0xFF,0xFF,0x8A,0x5C,0x48,0x83,0xE3,0x0F,0x03,0xDB,0x8B,0x97,
+ 0x90,0x0C,0x89,0x54,0x20,0xB8,0x01,0x00,0x8A,0x4C,0x48,0xD3,
+ 0xE0,0x89,0x44,0x2E,0xC7,0x44,0x24,0x19,0x00,0xC7,0x44,0x26,
+ 0x00,0x00,0xC6,0x44,0x4A,0x00,0xC7,0x44,0x30,0x00,0x00,0xC7,
+ 0x44,0x32,0x00,0x00,0xC6,0x44,0x4C,0x00,0xC6,0x44,0x4D,0x00,
+ 0xC6,0x44,0x4E,0x00,0xC6,0x44,0x4F,0x00,0xC6,0x44,0x50,0x00,
+ 0xC6,0x44,0x4B,0x00,0xC6,0x44,0x51,0x00,0xC6,0x44,0x28,0x00,
+ 0xC6,0x44,0x29,0x00,0xC6,0x44,0x2A,0x00,0xC6,0x44,0x2B,0x00,
+ 0xC6,0x44,0x54,0x00,0xC6,0x44,0x57,0x00,0xC6,0x44,0x55,0x00,
+ 0xC6,0x44,0x56,0x00,0xC6,0x44,0x58,0x00,0xC6,0x44,0x52,0x04,
+ 0xC6,0x44,0x53,0x04,0xC6,0x44,0x5F,0x00,0xC6,0x44,0x2C,0x3D,
+ 0xC6,0x44,0x2D,0x00,0xC7,0x44,0x34,0xFF,0x60,0xC6,0x44,0x62,
+ 0xFF,0xC6,0x44,0x5D,0x13,0xC6,0x44,0x5C,0x11,0xC6,0x44,0x5E,
+ 0x00,0xC6,0x44,0x60,0x23,0xC6,0x44,0x61,0x23,0x0B,0xD2,0x75,
+ 0x03,0xE9,0xD9,0x00,0xB0,0x09,0xEE,0x8A,0x4C,0x48,0xB0,0x80,
+ 0xD2,0xE8,0xEE,0xC6,0x44,0x70,0x00,0xB0,0x01,0xEE,0xB0,0x11,
+ 0x88,0x44,0x71,0xEE,0xB0,0x02,0x90,0x90,0xEE,0x8A,0x44,0x48,
+ 0xC0,0xE0,0x03,0x24,0xF0,0x88,0x44,0x72,0xEE,0xB0,0x03,0x90,
+ 0x90,0xEE,0xB0,0xC0,0x88,0x44,0x73,0xEE,0xB0,0x04,0x90,0x90,
+ 0xEE,0xB0,0x44,0x88,0x44,0x74,0xEE,0xB0,0x05,0x90,0xEE,0xB0,
+ 0x60,0x88,0x44,0x75,0xEE,0xC6,0x44,0x76,0x00,0xC6,0x44,0x77,
+ 0x00,0xC6,0x44,0x78,0x00,0xB0,0x09,0xEE,0xB0,0x09,0x88,0x44,
+ 0x79,0xEE,0xC6,0x44,0x7A,0x00,0xB0,0x0B,0xEE,0xB0,0x52,0x88,
+ 0x44,0x7B,0xEE,0x80,0x3E,0x10,0x0C,0x01,0x75,0x21,0xA1,0x0E,
+ 0x0C,0x86,0xE0,0x3D,0x32,0x31,0x73,0x17,0xB0,0x0C,0xEE,0xB0,
+ 0x18,0x88,0x44,0x7C,0xEE,0xB0,0x0D,0x90,0x90,0xEE,0xB0,0x00,
+ 0x88,0x44,0x7D,0xEE,0xEB,0x15,0x90,0xB0,0x0C,0xEE,0xB0,0x16,
+ 0x88,0x44,0x7C,0xEE,0xB0,0x0D,0x90,0x90,0xEE,0xB0,0x00,0x88,
+ 0x44,0x7D,0xEE,0xB0,0x0E,0x90,0x90,0xEE,0xB0,0x03,0x88,0x44,
+ 0x7E,0xEE,0xB0,0x0F,0x90,0x90,0xEE,0xB0,0x80,0x88,0x44,0x7F,
+ 0xEE,0xB0,0x03,0x90,0x90,0xEE,0x8A,0x44,0x73,0x0C,0x01,0x88,
+ 0x44,0x73,0xEE,0x90,0x90,0xB0,0x05,0xEE,0x8A,0x44,0x75,0x0C,
+ 0x08,0x88,0x44,0x75,0xEE,0xC3,0xFA,0x8C,0xD8,0x25,0x00,0xF0,
+ 0x8E,0xD0,0xBC,0xFE,0x1F,0x8C,0xD8,0x25,0x00,0xF0,0x8E,0xD8,
+ 0x80,0x3E,0x40,0x0D,0x01,0x75,0x51,0xA1,0x0E,0x0C,0x86,0xE0,
+ 0x3D,0x30,0x32,0x73,0x47,0x8B,0x1E,0x20,0x0C,0x8A,0x16,0x23,
+ 0x0C,0xC6,0x06,0x23,0x0C,0x00,0x83,0xFB,0x00,0x74,0x07,0xFE,
+ 0xCA,0xC6,0x06,0x23,0x0C,0x01,0x88,0x16,0x22,0x0C,0xBE,0x10,
+ 0x0C,0xBF,0x90,0x0C,0xB9,0x08,0x00,0x1E,0x07,0xFC,0xF3,0xA5,
+ 0xBF,0xA0,0x0C,0xB8,0x00,0x00,0xB9,0x08,0x00,0xF3,0xAB,0xC7,
+ 0x06,0x1A,0x0C,0x70,0x00,0xA0,0x40,0x0D,0xA2,0x10,0x0C,0xC6,
+ 0x06,0x11,0x0C,0x00,0x2E,0x8C,0x1E,0xC1,0x03,0xC7,0x06,0x18,
+ 0x0E,0x02,0x00,0xE8,0xEC,0xFC,0xC7,0x06,0x24,0x0D,0x5A,0x0D,
+ 0x8C,0x0E,0x26,0x0D,0xC7,0x06,0x18,0x0E,0x06,0x00,0xA1,0x1A,
+ 0x0C,0xE8,0x0A,0xFD,0xC7,0x06,0x18,0x0E,0x0A,0x00,0xBE,0x00,
+ 0x10,0xC7,0x44,0x1E,0x80,0x00,0xE8,0xA5,0xFD,0x81,0xC6,0x80,
+ 0x00,0x81,0xFE,0x00,0x18,0x72,0xEE,0xA0,0x22,0x0C,0xB4,0x80,
+ 0xF6,0xE4,0xBE,0x00,0x10,0x03,0xF0,0x89,0x36,0x0A,0x0E,0x29,
+ 0x44,0x9E,0xC7,0x06,0x00,0x0E,0x00,0x00,0xC7,0x06,0x02,0x0E,
+ 0x00,0x00,0xC7,0x06,0x04,0x0E,0x00,0x00,0xC7,0x06,0x06,0x0E,
+ 0x9A,0x02,0xBA,0x52,0xFF,0xA1,0x06,0x0E,0xEF,0xBA,0x50,0xFF,
+ 0xB8,0x00,0x00,0xEF,0xBA,0x56,0xFF,0xB8,0x05,0xE0,0xEF,0xBA,
+ 0x5E,0xFF,0xB8,0x00,0x40,0xEF,0xBA,0x66,0xFF,0xB8,0x00,0x40,
+ 0xEF,0xC7,0x06,0x10,0x0D,0x00,0x00,0xC7,0x06,0x12,0x0D,0x00,
+ 0x00,0xC7,0x06,0x14,0x0D,0x00,0x04,0xC7,0x06,0x16,0x0D,0xFC,
+ 0x03,0xC7,0x06,0x18,0x0D,0x00,0x00,0xC7,0x06,0x1A,0x0D,0x00,
+ 0x00,0xC7,0x06,0x1C,0x0D,0x00,0x08,0xC7,0x06,0x1E,0x0D,0xFC,
+ 0x03,0xB0,0x00,0x90,0xE6,0x00,0xC7,0x06,0x18,0x0E,0x32,0x00,
+ 0xBA,0x38,0xFF,0xB8,0x11,0x00,0xEF,0xBA,0x3A,0xFF,0xB8,0x08,
+ 0x00,0xEF,0xBA,0x3C,0xFF,0xB8,0x08,0x00,0xEF,0xBA,0x3E,0xFF,
+ 0xB8,0x08,0x00,0x80,0x3E,0x22,0x0C,0x08,0x76,0x03,0xB8,0x12,
+ 0x00,0xEF,0xBA,0x32,0xFF,0xB8,0x05,0x00,0xEF,0xBA,0x28,0xFF,
+ 0xB8,0x6C,0x00,0xEF,0xBA,0x22,0xFF,0xB8,0x00,0x80,0xEF,0xC7,
+ 0x06,0x18,0x0E,0x33,0x00,0xC7,0x06,0x20,0x0D,0x4F,0x00,0xC7,
+ 0x06,0x21,0x0D,0x53,0x00,0x8B,0x36,0x0A,0x0E,0xC7,0x04,0x3C,
+ 0x0D,0xC7,0x06,0x08,0x0E,0x00,0x10,0xE9,0x63,0xF6,0x40,0x28,
+ 0x23,0x29,0x20,0x24,0x49,0x64,0x3A,0x20,0x78,0x61,0x63,0x6F,
+ 0x6F,0x6B,0x2E,0x61,0x73,0x6D,0x2C,0x76,0x20,0x37,0x2E,0x32,
+ 0x35,0x20,0x31,0x39,0x39,0x35,0x2F,0x30,0x31,0x2F,0x31,0x32,
+ 0x20,0x32,0x30,0x3A,0x35,0x39,0x3A,0x32,0x31,0x20,0x6D,0x69,
+ 0x6C,0x74,0x20,0x45,0x78,0x70,0x20,0x24,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+
+static unsigned pcxx_ncook=sizeof(pcxx_cook);
diff --git a/sys/gnu/i386/isa/dgreg.h b/sys/gnu/i386/isa/dgreg.h
new file mode 100644
index 0000000000000..3c322133d43ef
--- /dev/null
+++ b/sys/gnu/i386/isa/dgreg.h
@@ -0,0 +1,366 @@
+/*-
+ * dgreg.h $Id: dgreg.h,v 1.4 1995/07/13 08:07:46 root Exp root $
+ *
+ * Copyright (C) 1995 by Serge Babkin <babkin@hq.icb.chel.su>
+ *
+ * Digiboard driver.
+ *
+ * Stage 1. "Better than nothing".
+ *
+ * Based on sio driver by Bruce Evans and on Linux driver by Troy
+ * De Jongh <troyd@digibd.com> or <troyd@skypoint.com>
+ * which is under GNU General Public License version 2 so this driver
+ * is forced to be under GPL 2 too.
+ *
+ * Serge Babkin does not guarantee that this file is totally correct
+ * for any given task and users of this file must accept responsibility
+ * for any damage that occurs from the application of this file.
+ *
+ * Written by Serge Babkin,
+ * Joint Stock Commercial Bank "Chelindbank"
+ * (Chelyabinsk, Russia)
+ * babkin@hq.icb.chel.su
+ */
+
+#define DEBUG
+
+#define MAX_DGB_PORTS 32
+
+/* digi.h */
+/* Definitions for DigiBoard ditty(1) command. */
+
+#if !defined(TIOCMODG)
+#define TIOCMODG ('d'<<8) | 250 /* get modem ctrl state */
+#define TIOCMODS ('d'<<8) | 251 /* set modem ctrl state */
+#endif
+
+#if !defined(TIOCMSET)
+#define TIOCMSET ('d'<<8) | 252 /* set modem ctrl state */
+#define TIOCMGET ('d'<<8) | 253 /* set modem ctrl state */
+#endif
+
+#if !defined(TIOCMBIC)
+#define TIOCMBIC ('d'<<8) | 254 /* set modem ctrl state */
+#define TIOCMBIS ('d'<<8) | 255 /* set modem ctrl state */
+#endif
+
+#if !defined(TIOCSDTR)
+#define TIOCSDTR ('e'<<8) | 0 /* set DTR */
+#define TIOCCDTR ('e'<<8) | 1 /* clear DTR */
+#endif
+
+/************************************************************************
+ * Ioctl command arguments for DIGI parameters.
+ ************************************************************************/
+#define DIGI_GETA ('e'<<8) | 94 /* Read params */
+
+#define DIGI_SETA ('e'<<8) | 95 /* Set params */
+#define DIGI_SETAW ('e'<<8) | 96 /* Drain & set params */
+#define DIGI_SETAF ('e'<<8) | 97 /* Drain, flush & set params */
+
+#define DIGI_GETFLOW ('e'<<8) | 99 /* Get startc/stopc flow */
+ /* control characters */
+#define DIGI_SETFLOW ('e'<<8) | 100 /* Set startc/stopc flow */
+ /* control characters */
+#define DIGI_GETAFLOW ('e'<<8) | 101 /* Get Aux. startc/stopc */
+ /* flow control chars */
+#define DIGI_SETAFLOW ('e'<<8) | 102 /* Set Aux. startc/stopc */
+ /* flow control chars */
+
+struct digiflow_struct {
+ unsigned char startc; /* flow cntl start char */
+ unsigned char stopc; /* flow cntl stop char */
+};
+
+typedef struct digiflow_struct digiflow_t;
+
+
+/************************************************************************
+ * Values for digi_flags
+ ************************************************************************/
+#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
+#define DIGI_FAST 0x0002 /* Fast baud rates */
+#define RTSPACE 0x0004 /* RTS input flow control */
+#define CTSPACE 0x0008 /* CTS output flow control */
+#define DSRPACE 0x0010 /* DSR output flow control */
+#define DCDPACE 0x0020 /* DCD output flow control */
+#define DTRPACE 0x0040 /* DTR input flow control */
+#define DIGI_FORCEDCD 0x0100 /* Force carrier */
+#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
+#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
+
+
+/************************************************************************
+ * Structure used with ioctl commands for DIGI parameters.
+ ************************************************************************/
+struct digi_struct {
+ unsigned short digi_flags; /* Flags (see above) */
+};
+
+typedef struct digi_struct digi_t;
+
+/* fep.h */
+
+#define FEP_CSTART 0x400L
+#define FEP_CMAX 0x800L
+#define FEP_ISTART 0x800L
+#define FEP_IMAX 0xC00L
+#define FEP_CIN 0xD10L
+#define FEP_GLOBAL 0xD10L
+#define FEP_EIN 0xD18L
+#define FEPSTAT 0xD20L
+#define CHANSTRUCT 0x1000L
+#define RXTXBUF 0x4000L
+
+
+struct global_data {
+ volatile ushort cin;
+ volatile ushort cout;
+ volatile ushort cstart;
+ volatile ushort cmax;
+ volatile ushort ein;
+ volatile ushort eout;
+ volatile ushort istart;
+ volatile ushort imax;
+};
+
+
+struct board_chan {
+ int filler1;
+ int filler2;
+ volatile ushort tseg;
+ volatile ushort tin;
+ volatile ushort tout;
+ volatile ushort tmax;
+
+ volatile ushort rseg;
+ volatile ushort rin;
+ volatile ushort rout;
+ volatile ushort rmax;
+
+ volatile ushort tlow;
+ volatile ushort rlow;
+ volatile ushort rhigh;
+ volatile ushort incr;
+
+ volatile ushort etime;
+ volatile ushort edelay;
+ volatile u_char *dev;
+
+ volatile ushort iflag;
+ volatile ushort oflag;
+ volatile ushort cflag;
+ volatile ushort gmask;
+
+ volatile ushort col;
+ volatile ushort delay;
+ volatile ushort imask;
+ volatile ushort tflush;
+
+ int filler3;
+ int filler4;
+ int filler5;
+ int filler6;
+
+ volatile u_char num;
+ volatile u_char ract;
+ volatile u_char bstat;
+ volatile u_char tbusy;
+ volatile u_char iempty;
+ volatile u_char ilow;
+ volatile u_char idata;
+ volatile u_char eflag;
+
+ volatile u_char tflag;
+ volatile u_char rflag;
+ volatile u_char xmask;
+ volatile u_char xval;
+ volatile u_char mstat;
+ volatile u_char mchange;
+ volatile u_char mint;
+ volatile u_char lstat;
+
+ volatile u_char mtran;
+ volatile u_char orun;
+ volatile u_char startca;
+ volatile u_char stopca;
+ volatile u_char startc;
+ volatile u_char stopc;
+ volatile u_char vnext;
+ volatile u_char hflow;
+
+ volatile u_char fillc;
+ volatile u_char ochar;
+ volatile u_char omask;
+
+ u_char filler7;
+ u_char filler8[28];
+};
+
+
+#define SRXLWATER 0xE0
+#define SRXHWATER 0xE1
+#define STOUT 0xE2
+#define PAUSETX 0xE3
+#define RESUMETX 0xE4
+#define SAUXONOFFC 0xE6
+#define SENDBREAK 0xE8
+#define SETMODEM 0xE9
+#define SETIFLAGS 0xEA
+#define SONOFFC 0xEB
+#define STXLWATER 0xEC
+#define PAUSERX 0xEE
+#define RESUMERX 0xEF
+#define SETBUFFER 0xF2
+#define SETCOOKED 0xF3
+#define SETHFLOW 0xF4
+#define SETCTRLFLAGS 0xF5
+#define SETVNEXT 0xF6
+
+
+
+#define BREAK_IND 0x01
+#define LOWTX_IND 0x02
+#define EMPTYTX_IND 0x04
+#define DATA_IND 0x08
+#define MODEMCHG_IND 0x20
+
+#define ALL_IND (BREAK_IND|LOWTX_IND|EMPTYTX_IND|DATA_IND|MODEMCHG_IND)
+
+
+#define RTS 0x02
+#define CD 0x08
+#define DSR 0x10
+#define CTS 0x20
+#define RI 0x40
+#define DTR 0x80
+
+/* pcxx.h */
+
+#define FEPCODESEG 0x0200L
+#define FEPCODE 0x2000L
+#define BIOSCODE 0xf800L
+
+#define MISCGLOBAL 0x0C00L
+#define NPORT 0x0C22L
+#define MBOX 0x0C40L
+#define PORTBASE 0x0C90L
+#define BOTWIN 0x100L
+#define TOPWIN 0xFF00L
+
+#define FEPCLR 0x00
+#define FEPMEM 0x02
+#define FEPRST 0x04
+#define FEPINT 0x08
+#define FEPMASK 0x0e
+#define FEPWIN 0x80
+
+#define PCXI 0
+#define PCXE 1
+#define PCXEVE 2
+
+static char *board_desc[] = {
+ "PC/Xi (64K)",
+ "PC/Xe (64K)",
+ "PC/Xe (8K) ",
+};
+
+#define STARTC 021
+#define STOPC 023
+#define IAIXON 0x2000
+
+
+struct board_info {
+ u_char status;
+ u_char type;
+ u_char altpin;
+ ushort numports;
+ ushort port;
+ u_long membase;
+};
+
+
+#define TXSTOPPED 0x1
+#define LOWWAIT 0x2
+#define EMPTYWAIT 0x4
+
+#define DISABLED 0
+#define ENABLED 1
+#define OFF 0
+#define ON 1
+
+#define FEPTIMEOUT 200000
+#define SERIAL_TYPE_NORMAL 1
+#define SERIAL_TYPE_CALLOUT 2
+#define PCXE_EVENT_HANGUP 1
+
+struct channel {
+ u_char unit; /* board unit number */
+ u_char omodem; /* FEP output modem status */
+ u_char imodem; /* FEP input modem status */
+ u_char modemfake; /* Modem values to be forced */
+ u_char modem; /* Force values */
+ u_char hflow;
+ u_char dsr;
+ u_char dcd;
+ u_char stopc;
+ u_char startc;
+ u_char stopca;
+ u_char startca;
+ u_char fepstopc;
+ u_char fepstartc;
+ u_char fepstopca;
+ u_char fepstartca;
+ u_char txwin;
+ u_char rxwin;
+ ushort fepiflag;
+ ushort fepcflag;
+ ushort fepoflag;
+ ushort txbufhead;
+ ushort txbufsize;
+ ushort rxbufhead;
+ ushort rxbufsize;
+ int close_delay;
+ int count;
+ int blocked_open;
+ int event;
+ int asyncflags;
+ uint dev;
+ long session;
+ long pgrp;
+ u_long statusflags;
+ u_long c_iflag;
+ u_long c_cflag;
+ u_long c_lflag;
+ u_long c_oflag;
+ u_char *txptr;
+ u_char *rxptr;
+ struct board_info *board;
+ struct board_chan *brdchan;
+ struct digi_struct digiext;
+ struct tty *tty;
+ struct termios normal_termios;
+ struct termios callout_termios;
+ volatile struct global_data *mailbox;
+};
+
+/* flags for configuring */
+
+#define DGBFLAG_ALTPIN 0x0001 /* chande DCD and DCD */
+#define DGBFLAG_NOWIN 0x0002 /* use windowed PC/Xe as non-windowed */
+
+/* debugging printout */
+
+#ifdef DEBUG
+# define DPRINT1(a1) (dgbdebug ? printf(a1) : 0)
+# define DPRINT2(a1,a2) (dgbdebug ? printf(a1,a2) : 0)
+# define DPRINT3(a1,a2,a3) (dgbdebug ? printf(a1,a2,a3) : 0)
+# define DPRINT4(a1,a2,a3,a4) (dgbdebug ? printf(a1,a2,a3,a4) : 0)
+# define DPRINT5(a1,a2,a3,a4,a5) (dgbdebug ? printf(a1,a2,a3,a4,a5) : 0)
+#else
+# define DPRINT1(a1)
+# define DPRINT2(a1,a2)
+# define DPRINT3(a1,a2,a3)
+# define DPRINT4(a1,a2,a3,a4)
+# define DPRINT5(a1,a2,a3,a4,a5)
+#endif
diff --git a/sys/i386/include/asc_ioctl.h b/sys/i386/include/asc_ioctl.h
new file mode 100644
index 0000000000000..6d33429933301
--- /dev/null
+++ b/sys/i386/include/asc_ioctl.h
@@ -0,0 +1,52 @@
+/* asc.h - programming interface to the scanner device driver `asc'
+ *
+ *
+ * Copyright (c) 1995 Gunther Schadow. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gunther Schadow.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _I386_ASC_IOCTL_H_
+#define _I386_ASC_IOCTL_H_
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#define ASC_GRES _IOR('S', 1, int) /* get resolution / dpi */
+#define ASC_SRES _IOW('S', 2, int) /* set resolution / dpi */
+#define ASC_GWIDTH _IOR('S', 3, int) /* get width / pixels */
+#define ASC_SWIDTH _IOW('S', 4, int) /* set width / pixels */
+#define ASC_GHEIGHT _IOR('S', 5, int) /* get height / pixels */
+#define ASC_SHEIGHT _IOW('S', 6, int) /* set height / pixels */
+
+#define ASC_GBLEN _IOR('S', 7, int) /* get buffer length / lines */
+#define ASC_SBLEN _IOW('S', 8, int) /* set buffer length / lines */
+#define ASC_GBTIME _IOR('S', 9, int) /* get buffer timeout / s */
+#define ASC_SBTIME _IOW('S', 10, int) /* set buffer timeout / s */
+
+#define ASC_SRESSW _IO('S', 11) /* set resolution by switch */
+
+#endif
diff --git a/sys/i386/include/si.h b/sys/i386/include/si.h
new file mode 100644
index 0000000000000..9770fb63eb52e
--- /dev/null
+++ b/sys/i386/include/si.h
@@ -0,0 +1,525 @@
+/*
+ * Device driver for Specialix range (SLXOS) of serial line multiplexors.
+ * 'C' definitions for Specialix serial multiplex driver.
+ *
+ * Copyright (C) 1990, 1992 Specialix International,
+ * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk>
+ * Copyright (C) 1995, Peter Wemm <peter@haywire.dialix.com>
+ *
+ * Derived from: SunOS 4.x version
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notices, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notices, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Andy Rutter of
+ * Advanced Methods and Tools Ltd. based on original information
+ * from Specialix International.
+ * 4. Neither the name of Advanced Methods and Tools, nor Specialix
+ * International may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE.
+ *
+ * $Id: si.h,v 1.3 1995/08/22 00:42:07 peter Exp $
+ */
+
+/*
+ * Macro to turn a device number into various parameters, and test for
+ * CONTROL device.
+ * max of 4 controllers with up to 32 ports per controller.
+ * minor device allocation is:
+ * adapter port
+ * 0 0-31
+ * 1 32-63
+ * 2 64-95
+ * 3 96-127
+ */
+#define SI_MAXPORTPERCARD 32
+#define SI_MAXCONTROLLER 4
+
+
+/*
+ * breakup of minor device number:
+ * lowest 5 bits: port number on card 0x1f
+ * next 2 bits: card number 0x60
+ * top bit: callout 0x80
+ * next 8 bits is the major number
+ * next 2 bits select initial/lock states
+ * next 1 bit selects the master control device
+ */
+
+#define SI_PORT_MASK 0x1f
+#define SI_CARD_MASK 0x60
+#define SI_TTY_MASK 0x7f
+#define SI_CALLOUT_MASK 0x80
+#define SI_INIT_STATE_MASK 0x10000
+#define SI_LOCK_STATE_MASK 0x20000
+#define SI_STATE_MASK 0x30000
+#define SI_CONTROLDEV_MASK 0x40000
+#define SI_SPECIAL_MASK 0x70000
+
+#define SI_PORT(m) (m & SI_PORT_MASK)
+#define SI_CARD(m) ((m & SI_CARD_MASK) >> 5)
+#define SI_TTY(m) (m & SI_TTY_MASK)
+
+#define IS_CALLOUT(m) (m & SI_CALLOUT_MASK)
+#define IS_STATE(m) (m & SI_STATE_MASK)
+#define IS_CONTROLDEV(m) (m & SI_CONTROLDEV_MASK)
+#define IS_SPECIAL(m) (m & SI_SPECIAL_MASK)
+
+#define MINOR2SC(m) (&si_softc[SI_CARD(m)])
+#define MINOR2PP(m) (MINOR2SC((m))->sc_ports + SI_PORT((m)))
+#define MINOR2TP(m) (MINOR2PP((m))->sp_tty)
+#define TP2PP(tp) (MINOR2PP(SI_TTY(minor((tp)->t_dev))))
+
+/* Adapter types */
+#define SIEMPTY 0
+#define SIHOST 1
+#define SI2 2
+#define SIHOST2 3
+#define SIEISA 4
+
+/* Buffer parameters */
+#define SLXOS_BUFFERSIZE 256
+
+typedef unsigned char BYTE; /* Type cast for unsigned 8 bit */
+typedef unsigned short WORD; /* Type cast for unsigned 16 bit */
+
+
+/*
+ * Hardware `registers', stored in the shared memory.
+ * These are related to the firmware running on the Z280.
+ */
+
+struct si_reg {
+ BYTE initstat;
+ BYTE memsize;
+ WORD int_count;
+ WORD revision;
+ BYTE rx_int_count;
+ BYTE spare;
+ WORD int_pending;
+ WORD int_counter;
+ BYTE int_scounter;
+ BYTE res[0x80 - 13];
+};
+
+/*
+ * Per module control structure, stored in shared memory.
+ */
+struct si_module {
+ WORD sm_next; /* Next module */
+ BYTE sm_type; /* Number of channels */
+ BYTE sm_number; /* Module number on cable */
+ BYTE sm_dsr; /* Private dsr copy */
+ BYTE sm_res[0x80 - 5]; /* Reserve space to 128 bytes */
+};
+
+/*
+ * The 'next' pointer & with 0x7fff + SI base addres give
+ * the address of the next module block if fitted. (else 0)
+ * Note that next points to the TX buffer so 0x60 must be
+ * subtracted to find the true base.
+ *
+ * Type is a bit field as follows: The bottom 5 bits are the
+ * number of channels on this module, the top 3 bits are
+ * as the module type thus:
+ *
+ * 000 2698 RS232 module (4 port or 8 port)
+ * 001 Reserved for 2698 RS422 module
+ * 010 Reserved for 8530 based sync module
+ * 011 Reserved for parallel printer module
+ * 100 Reserved for network module
+ * 101-111 Reserved for expansion.
+ *
+ * The number field is the cable position of the module.
+ */
+#define M232 0x00
+#define M422 0x20 /* not supported */
+#define MSYNC 0x40 /* this is the Telebit Netblazer module */
+#define MCENT 0x60 /* not supported */
+#define MNET 0x80 /* not supported */
+#define MMASK 0x1F
+
+/*
+ * Per channel(port) control structure, stored in shared memory.
+ */
+struct si_channel {
+ /*
+ * Generic stuff
+ */
+ WORD next; /* Next Channel */
+ WORD addr_uart; /* Uart address */
+ WORD module; /* address of module struct */
+ BYTE type; /* Uart type */
+ BYTE fill;
+ /*
+ * Uart type specific stuff
+ */
+ BYTE x_status; /* XON / XOFF status */
+ BYTE c_status; /* cooking status */
+ BYTE hi_rxipos; /* stuff into rx buff */
+ BYTE hi_rxopos; /* stuff out of rx buffer */
+ BYTE hi_txopos; /* Stuff into tx ptr */
+ BYTE hi_txipos; /* ditto out */
+ BYTE hi_stat; /* Command register */
+ BYTE dsr_bit; /* Magic bit for DSR */
+ BYTE txon; /* TX XON char */
+ BYTE txoff; /* ditto XOFF */
+ BYTE rxon; /* RX XON char */
+ BYTE rxoff; /* ditto XOFF */
+ BYTE hi_mr1; /* mode 1 image */
+ BYTE hi_mr2; /* mode 2 image */
+ BYTE hi_csr; /* clock register */
+ BYTE hi_op; /* Op control */
+ BYTE hi_ip; /* Input pins */
+ BYTE hi_state; /* status */
+ BYTE hi_prtcl; /* Protocol */
+ BYTE hi_txon; /* host copy tx xon stuff */
+ BYTE hi_txoff;
+ BYTE hi_rxon;
+ BYTE hi_rxoff;
+ BYTE close_prev; /* Was channel previously closed */
+ BYTE hi_break; /* host copy break process */
+ BYTE break_state; /* local copy ditto */
+ BYTE hi_mask; /* Mask for CS7 etc. */
+ BYTE mask_z280; /* Z280's copy */
+ BYTE res[0x60 - 36];
+ BYTE hi_txbuf[SLXOS_BUFFERSIZE];
+ BYTE hi_rxbuf[SLXOS_BUFFERSIZE];
+ BYTE res1[0xA0];
+};
+
+/*
+ * Register definitions
+ */
+
+/*
+ * Break input control register definitions
+ */
+#define BR_IGN 0x01 /* Ignore any received breaks */
+#define BR_INT 0x02 /* Interrupt on received break */
+#define BR_PARMRK 0x04 /* Enable parmrk parity error processing */
+#define BR_PARIGN 0x08 /* Ignore chars with parity errors */
+
+/*
+ * Protocol register provided by host for XON/XOFF and cooking
+ */
+#define SP_TANY 0x01 /* Tx XON any char */
+#define SP_TXEN 0x02 /* Tx XON/XOFF enabled */
+#define SP_CEN 0x04 /* Cooking enabled */
+#define SP_RXEN 0x08 /* Rx XON/XOFF enabled */
+#define SP_DCEN 0x20 /* DCD / DTR check */
+#define SP_PAEN 0x80 /* Parity checking enabled */
+
+/*
+ * HOST STATUS / COMMAND REGISTER
+ */
+#define IDLE_OPEN 0x00 /* Default mode, TX and RX polled
+ buffer updated etc */
+#define LOPEN 0x02 /* Local open command (no modem ctl */
+#define MOPEN 0x04 /* Open and monitor modem lines (blocks
+ for DCD */
+#define MPEND 0x06 /* Wating for DCD */
+#define CONFIG 0x08 /* Channel config has changed */
+#define CLOSE 0x0A /* Close channel */
+#define SBREAK 0x0C /* Start break */
+#define EBREAK 0x0E /* End break */
+#define IDLE_CLOSE 0x10 /* Closed channel */
+#define IDLE_BREAK 0x12 /* In a break */
+#define FCLOSE 0x14 /* Force a close */
+#define RESUME 0x16 /* Clear a pending xoff */
+#define WFLUSH 0x18 /* Flush output buffer */
+#define RFLUSH 0x1A /* Flush input buffer */
+
+/*
+ * Host status register
+ */
+#define ST_BREAK 0x01 /* Break received (clear with config) */
+
+/*
+ * OUTPUT PORT REGISTER
+ */
+#define OP_CTS 0x01 /* Enable CTS */
+#define OP_DSR 0x02 /* Enable DSR */
+/*
+ * INPUT PORT REGISTER
+ */
+#define IP_DCD 0x04 /* DCD High */
+#define IP_DTR 0x20 /* DTR High */
+#define IP_RTS 0x02 /* RTS High */
+#define IP_RI 0x40 /* RI High */
+
+/*
+ * Mode register and uart specific stuff
+ */
+/*
+ * MODE REGISTER 1
+ */
+#define MR1_5_BITS 0x00
+#define MR1_6_BITS 0x01
+#define MR1_7_BITS 0x02
+#define MR1_8_BITS 0x03
+/*
+ * Parity
+ */
+#define MR1_ODD 0x04
+#define MR1_EVEN 0x00
+/*
+ * Parity mode
+ */
+#define MR1_WITH 0x00
+#define MR1_FORCE 0x08
+#define MR1_NONE 0x10
+#define MR1_SPECIAL 0x18
+/*
+ * Error mode
+ */
+#define MR1_CHAR 0x00
+#define MR1_BLOCK 0x20
+/*
+ * Request to send line automatic control
+ */
+#define MR1_CTSCONT 0x80
+
+/*
+ * MODE REGISTER 2
+ */
+/*
+ * Number of stop bits
+ */
+#define MR2_1_STOP 0x07
+#define MR2_2_STOP 0x0F
+/*
+ * Clear to send automatic testing before character sent
+ */
+#define MR2_RTSCONT 0x10
+/*
+ * Reset RTS automatically after sending character?
+ */
+#define MR2_CTSCONT 0x20
+/*
+ * Channel mode
+ */
+#define MR2_NORMAL 0x00
+#define MR2_AUTO 0x40
+#define MR2_LOCAL 0x80
+#define MR2_REMOTE 0xC0
+
+/*
+ * CLOCK SELECT REGISTER - this and the code assumes ispeed == ospeed
+ */
+/*
+ * Clocking rates are in lower and upper nibbles.. R = upper, T = lower
+ */
+#define CLK75 0x0
+#define CLK110 0x1 /* 110 on XIO!! */
+#define CLK38400 0x2 /* out of sequence */
+#define CLK150 0x3
+#define CLK300 0x4
+#define CLK600 0x5
+#define CLK1200 0x6
+#define CLK2000 0x7
+#define CLK2400 0x8
+#define CLK4800 0x9
+#define CLK7200 0xa /* unchecked */
+#define CLK9600 0xb
+#define CLK19200 0xc
+#define CLK57600 0xd
+
+/*
+ * Per-port (channel) soft information structure, stored in the driver.
+ * This is visible via ioctl()'s.
+ */
+struct si_port {
+ volatile struct si_channel *sp_ccb;
+ struct tty *sp_tty;
+ int sp_pend; /* pending command */
+ int sp_last_hi_ip; /* cached DCD */
+ int sp_state;
+ int sp_active_out; /* callout is open */
+ int sp_flags;
+ int sp_dtr_wait; /* DTR holddown in hz */
+ u_int sp_wopeners; /* # procs waiting DCD */
+ u_char sp_hotchar; /* ldisc specific ASAP char */
+ /* Initial state. */
+ struct termios sp_iin;
+ struct termios sp_iout;
+ /* Lock state. */
+ struct termios sp_lin;
+ struct termios sp_lout;
+#ifdef SI_DEBUG
+ int sp_debug; /* debug mask */
+#endif
+};
+
+/* sp_state */
+#define SS_CLOSED 0x0000
+#define SS_OPEN 0x0001 /* Port is active */
+/* 0x0002 -- */
+/* 0x0004 -- */
+/* 0x0008 -- */
+/* 0x0010 -- */
+/* 0x0020 -- */
+/* 0x0040 -- */
+/* 0x0080 -- */
+#define SS_LSTART 0x0100 /* lstart timeout pending */
+#define SS_INLSTART 0x0200 /* running an lstart induced t_oproc */
+#define SS_CLOSING 0x0400 /* in the middle of a siclose() */
+/* 0x0800 -- */
+#define SS_WAITWRITE 0x1000
+#define SS_BLOCKWRITE 0x2000
+#define SS_DTR_OFF 0x4000 /* DTR held off */
+
+/* sp_flags */
+#define SPF_COOKMODE 0x0003
+#define SPFC_WELL 0
+#define SPFC_MEDIUM 1
+#define SPFC_RAW 2
+#define spfc_clear(pp) (pp)->sp_flags &= ~SPF_COOKMODE
+#define SPF_COOK_WELL(pp) spfc_clear(pp)
+#define SPF_COOK_MEDIUM(pp) {spfc_clear(pp);(pp)->sp_flags|=SPFC_MEDIUM;}
+#define SPF_COOK_RAW(pp) {spfc_clear(pp);(pp)->sp_flags|=SPFC_RAW;}
+#define SPF_SETCOOK(pp, c) {spfc_clear(pp);(pp)->sp_flags|=(c);}
+#define SPF_ISCOOKWELL(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_WELL)
+#define SPF_ISCOOKMEDIUM(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_MEDIUM)
+#define SPF_ISCOOKRAW(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_RAW)
+#define SPF_COOKWELL_ALWAYS 0x0004 /* always use line disc */
+/* 0x0008 */
+#define SPF_IXANY 0x0020 /* IXANY enable/disable flag */
+#define SPF_CTSOFLOW 0x0040 /* use CTS to handle o/p flow */
+#define SPF_RTSIFLOW 0x0080 /* use RTS to handle i/p flow */
+#define SPF_PPP 0x0100 /* special handling for upper
+ * level protocol code */
+
+/*
+ * Command post flags
+ */
+#define SI_NOWAIT 0x00 /* Don't wait for command */
+#define SI_WAIT 0x01 /* Wait for complete */
+
+/*
+ * Extensive debugging stuff - manipulated using siconfig(8)
+ */
+#define DBG_ENTRY 0x00000001
+#define DBG_DRAIN 0x00000002
+#define DBG_OPEN 0x00000004
+#define DBG_CLOSE 0x00000008
+#define DBG_READ 0x00000010
+#define DBG_WRITE 0x00000020
+#define DBG_PARAM 0x00000040
+#define DBG_INTR 0x00000080
+#define DBG_IOCTL 0x00000100
+/* 0x00000200 */
+#define DBG_SELECT 0x00000400
+#define DBG_OPTIM 0x00000800
+#define DBG_START 0x00001000
+#define DBG_EXIT 0x00002000
+#define DBG_FAIL 0x00004000
+#define DBG_STOP 0x00008000
+#define DBG_AUTOBOOT 0x00010000
+#define DBG_MODEM 0x00020000
+#define DBG_DOWNLOAD 0x00040000
+#define DBG_LSTART 0x00080000
+#define DBG_POLL 0x00100000
+#define DBG_ALL 0xffffffff
+
+/*
+ * SI ioctls
+ */
+/*
+ * struct for use by Specialix ioctls - used by siconfig(8)
+ */
+typedef struct {
+ unsigned char
+ sid_port:5, /* 0 - 31 ports per card */
+ sid_card:2, /* 0 - 3 cards */
+ sid_control:1; /* controlling device (all cards) */
+} sidev_t;
+struct si_tcsi {
+ sidev_t tc_dev;
+ union {
+ int x_int;
+ int x_dbglvl;
+ } tc_action;
+#define tc_card tc_dev.sid_card
+#define tc_port tc_dev.sid_port
+#define tc_int tc_action.x_int
+#define tc_dbglvl tc_action.x_dbglvl
+};
+
+struct si_pstat {
+ sidev_t tc_dev;
+ union {
+ struct si_port x_siport;
+ struct si_channel x_ccb;
+ struct tty x_tty;
+ } tc_action;
+#define tc_siport tc_action.x_siport
+#define tc_ccb tc_action.x_ccb
+#define tc_tty tc_action.x_tty
+};
+
+#define IOCTL_MIN 96
+#define TCSIDEBUG _IOW('S', 96, struct si_tcsi) /* Toggle debug */
+#define TCSIRXIT _IOW('S', 97, struct si_tcsi) /* RX int throttle */
+#define TCSIIT _IOW('S', 98, struct si_tcsi) /* TX int throttle */
+ /* 99 defunct */
+ /* 100 defunct */
+ /* 101 defunct */
+ /* 102 defunct */
+ /* 103 defunct */
+#define TCSIIXANY _IOW('S', 103, struct si_tcsi) /* enable ixany */
+ /* 104 defunct */
+#define TCSISTATE _IOWR('S', 105, struct si_tcsi) /* get current state of RTS
+ DCD and DTR pins */
+ /* Set/reset/enquire cook mode, 1 = always use line disc
+ * -1 = enquire current setting */
+#define TCSICOOKMODE _IOWR('S', 106, struct si_tcsi)
+#define TCSIPORTS _IOR('S', 107, int) /* Number of ports found */
+#define TCSISDBG_LEVEL _IOW('S', 108, struct si_tcsi) /* equivalent of TCSIDEBUG which sets a
+ * particular debug level (DBG_??? bit
+ * mask), default is 0xffff */
+#define TCSIGDBG_LEVEL _IOWR('S', 109, struct si_tcsi)
+#define TCSIGRXIT _IOWR('S', 110, struct si_tcsi)
+#define TCSIGIT _IOWR('S', 111, struct si_tcsi)
+ /* 112 defunct */
+ /* 113 defunct */
+ /* 114 defunct */
+ /* 115 defunct */
+ /* 116 defunct */
+#define TCSIMODEM _IOWR('S', 117, struct si_tcsi) /* set/clear/query the modem bit */
+
+#define TCSISDBG_ALL _IOW('S', 118, int) /* set global debug level */
+#define TCSIGDBG_ALL _IOR('S', 119, int) /* get global debug level */
+
+#define TCSIFLOW _IOWR('S', 120, struct si_tcsi) /* set/get h/w flow state */
+ /* 121 defunct */
+ /* 122 defunct */
+
+
+#define TCSIPPP _IOWR('S', 123, struct si_tcsi) /* set/get PPP flag bit */
+#define TCSIMODULES _IOR('S', 124, int) /* Number of modules found */
+
+/* Various stats and monitoring hooks per tty device */
+#define TCSI_PORT _IOWR('S', 125, struct si_pstat) /* get si_port */
+#define TCSI_CCB _IOWR('S', 126, struct si_pstat) /* get si_ccb */
+#define TCSI_TTY _IOWR('S', 127, struct si_pstat) /* get tty struct */
+
+#define IOCTL_MAX 127
+
+#define IS_SI_IOCTL(cmd) ((u_int)((cmd)&0xff00) == ('S'<<8) && \
+ (u_int)((cmd)&0xff) >= IOCTL_MIN && \
+ (u_int)((cmd)&0xff) <= IOCTL_MAX)
+
+#define CONTROLDEV "/dev/si_control"
diff --git a/sys/i386/isa/asc.c b/sys/i386/isa/asc.c
new file mode 100644
index 0000000000000..4e994d9a98ffc
--- /dev/null
+++ b/sys/i386/isa/asc.c
@@ -0,0 +1,862 @@
+/* asc.c - device driver for hand scanners
+ *
+ * Current version supports:
+ *
+ * - Trust AmiScan BW (GI1904 chipset)
+ *
+ * Copyright (c) 1995 Gunther Schadow. All rights reserved.
+ * Copyright (c) 1995 Luigi Rizzo. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gunther Schadow
+ * and Luigi Rizzo.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * $Id: asc.c,v 1.4 1995/09/08 18:30:33 julian Exp $
+ */
+
+#include "asc.h"
+#if NASC > 0
+#ifdef FREEBSD_1_X
+#include "param.h"
+#include "systm.h"
+#include "proc.h"
+#include "user.h"
+#include "buf.h"
+#include "malloc.h"
+#include "kernel.h"
+#include "ioctl.h"
+#include "tty.h"
+#include "uio.h"
+#include "syslog.h"
+
+#include "i386/isa/isa.h"
+#include "i386/isa/isa_device.h"
+#include "i386/isa/ascreg.h"
+
+#include "machine/asc_ioctl.h"
+#else
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/uio.h>
+#include <sys/syslog.h>
+
+#include <machine/asc_ioctl.h>
+
+#include <sys/devconf.h>
+#include <i386/isa/isa.h>
+#include <i386/isa/isa_device.h>
+#include <i386/isa/ascreg.h>
+#ifdef DEVFS
+#include <sys/devfsext.h>
+
+extern d_open_t ascopen;
+#endif
+
+#endif /* FREEBSD_1_X */
+
+/***
+ *** CONSTANTS & DEFINES
+ ***
+ ***/
+
+#define PROBE_FAIL 0
+#define PROBE_SUCCESS 5 /* number of io ports... */
+#define SUCCESS 0
+#define FAIL -1
+#define INVALID FAIL
+
+#define DMA1_READY 0x08
+#define ASCDEBUG
+#ifdef ASCDEBUG
+# define lprintf if(scu->flags & DEBUG) printf
+#else
+# define lprintf (void)
+#endif
+
+#define TIMEOUT (hz*15) /* timeout while reading a buffer - default value */
+#define ASCPRI PRIBIO /* priority while reading a buffer */
+
+/***
+ *** LAYOUT OF THE MINOR NUMBER
+ ***/
+
+#define UNIT_MASK 0xc0 /* unit asc0 .. asc3 */
+#define UNIT(x) (x >> 6)
+#define DBUG_MASK 0x20
+#define FRMT_MASK 0x18 /* output format */
+#define FRMT_RAW 0x00 /* output bits as read from scanner */
+#define FRMT_GRAY 0x10 /* output graymap (not implemented yet) */
+#define FRMT_PBM 0x08 /* output pbm format */
+#define FRMT_PGM 0x18
+
+/***
+ *** THE GEMOMETRY TABLE
+ ***/
+
+static const struct asc_geom {
+ int dpi; /* dots per inch */
+ int dpl; /* dots per line */
+ int bpl; /* bytes per line */
+ int g_res; /* get resolution value (ASC_STAT) */
+} geomtab[] = {
+ { 800, 3312, 414, ASC_RES_800},
+ { 700, 2896, 362, ASC_RES_700},
+ { 600, 2480, 310, ASC_RES_600},
+ { 500, 1656, 258, ASC_RES_500},
+ { 400, 1656, 207, ASC_RES_400},
+ { 300, 1240, 155, ASC_RES_300},
+ { 200, 832, 104, ASC_RES_200},
+ { 100, 416, 52, ASC_RES_100},
+ { INVALID, 416, 52, INVALID } /* terminator */
+};
+
+/***
+ *** THE TABLE OF UNITS
+ ***/
+
+struct _sbuf {
+ size_t size;
+ size_t rptr;
+ size_t wptr; /* only changed in ascintr */
+ size_t count;
+ char *base;
+};
+
+struct asc_unit {
+ int base; /* base address */
+ int dma_num; /* dma number */
+ char dma_byte; /* mask of byte for setting DMA value */
+ char int_byte; /* mask of byte for setting int value */
+ char cfg_byte; /* mirror of byte written to config reg (ASC_CFG). */
+ char cmd_byte; /* mirror of byte written to cmd port (ASC_CMD)*/
+ int flags;
+#define ATTACHED 0x01
+#define OPEN 0x02
+#define READING 0x04
+#define DMA_ACTIVE 0x08
+#define SLEEPING 0x10
+#define SEL_COLL 0x20
+#define PBM_MODE 0x40
+#define DEBUG 0x80
+ int geometry; /* resolution as geomtab index */
+ int linesize; /* length of one scan line (from geom.table) */
+ int blen; /* length of buffer in lines */
+ int btime; /* timeout of buffer in seconds/hz */
+ struct _sbuf sbuf;
+ long icnt; /* interrupt count XXX for debugging */
+#ifdef FREEBSD_1_X
+ pid_t selp; /* select pointer... */
+#else
+ struct selinfo selp;
+#endif
+ int height; /* height, for pnm modes */
+ size_t bcount; /* bytes to read, for pnm modes */
+} unittab[NASC];
+
+/*** I could not find a reasonable buffer size limit other than by
+ *** experiments. MAXPHYS is obviously too much, while DEV_BSIZE and
+ *** PAGE_SIZE are really too small. There must be something wrong
+ *** with isa_dmastart/isa_dmarangecheck HELP!!!
+ ***/
+#define MAX_BUFSIZE 0x3000
+#define DEFAULT_BLEN 20
+
+/***
+ *** THE PER-DRIVER RECORD FOR ISA.C
+ ***/
+int ascprobe (struct isa_device *isdp);
+int ascattach(struct isa_device *isdp);
+struct isa_driver ascdriver = { ascprobe, ascattach, "asc" };
+
+#ifndef FREEBSD_1_X
+struct asc_softc {
+ struct isa_device *dev;
+} asc_softc[NASC];
+
+static struct kern_devconf kdc_asc[NASC] = { {
+ 0, 0, 0, /* filled in by dev_attach */
+ "asc", 0, { MDDT_ISA, 0, "tty" },
+ isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
+ &kdc_isa0, /* parent */
+ 0, /* parentdata */
+ DC_UNCONFIGURED, /* state */
+ "GI1904 Hand scanner",
+ DC_CLS_MISC
+} };
+
+static inline void
+asc_registerdev(struct isa_device *id)
+{
+ if(id->id_unit)
+ kdc_asc[id->id_unit] = kdc_asc[0];
+ kdc_asc[id->id_unit].kdc_unit = id->id_unit;
+ kdc_asc[id->id_unit].kdc_isa = id;
+ dev_attach(&kdc_asc[id->id_unit]);
+}
+#endif /* ! FREEBSD_1_X */
+
+/***
+ *** LOCALLY USED SUBROUTINES
+ ***
+ ***/
+
+/***
+ *** get_resolution
+ *** read resolution from the scanner
+ ***/
+static void
+get_resolution(struct asc_unit *scu)
+{
+ int res, i, delay;
+
+ res=0;
+ scu->cmd_byte = ASC_STANDBY;
+ outb(ASC_CMD, scu->cmd_byte);
+ tsleep((caddr_t)scu, ASCPRI | PCATCH, "ascres", hz/10);
+ for(delay= 100; (res=inb(ASC_STAT)) & ASC_RDY_FLAG; delay--)
+ {
+ i = tsleep((caddr_t)scu, ASCPRI | PCATCH, "ascres0", 1);
+ if ( ( i == 0 ) || ( i == EWOULDBLOCK ) )
+ i = SUCCESS;
+ else
+ break;
+ }
+ if (delay==0) {
+ lprintf("asc.get_resolution: timeout completing command\n");
+ return /* -1 */;
+ }
+ /* ... actual read resolution... */
+ res &= ASC_RES_MASK;
+ for (i=0; geomtab[i].dpi != INVALID; i++) {
+ if (geomtab[i].g_res == res) break;
+ }
+ if (geomtab[i].dpi==INVALID) {
+ scu->geometry= i; /* INVALID; */
+ lprintf("asc.get_resolution: wrong resolution\n");
+ } else {
+ lprintf("asc.get_resolution: %d dpi\n",geomtab[i].dpi);
+ scu->geometry = i;
+ }
+ scu->linesize = geomtab[scu->geometry].bpl;
+ scu->height = geomtab[scu->geometry].dpl; /* default... */
+}
+
+/***
+ *** buffer_allocate
+ *** allocate/reallocate a buffer
+ ***/
+
+static int
+buffer_allocate(struct asc_unit *scu)
+{
+ size_t size, size1;
+
+ size = scu->blen * scu->linesize;
+
+ lprintf("asc.buffer_allocate: need 0x%x bytes\n", size);
+
+ if ( size > MAX_BUFSIZE ) {
+ size1=size;
+ size= ( (MAX_BUFSIZE+scu->linesize-1) / scu->linesize)*scu->linesize;
+ lprintf("asc.buffer_allocate: 0x%x bytes are too much, try 0x%x\n",
+ size1, size);
+ /* return ENOMEM; */
+ }
+
+ if ( scu->sbuf.base != NULL )
+ if ( scu->sbuf.size == size ) {
+ lprintf("asc.buffer_allocate: keep old buffer\n");
+ return SUCCESS;
+ } else {
+ lprintf("asc.buffer_allocate: release old buffer\n");
+ free( scu->sbuf.base, M_DEVBUF );
+ }
+
+ scu->sbuf.base = (char *)malloc(size, M_DEVBUF, M_WAITOK);
+
+ if ( scu->sbuf.base == NULL ) {
+ lprintf("asc.buffer_allocate: "
+ "buffer allocatation failed for size = 0x%x\n",
+ scu->sbuf.size);
+ return ENOMEM;
+ }
+
+ scu->sbuf.size = size;
+ scu->sbuf.rptr = 0;
+ scu->sbuf.wptr = 0;
+ scu->sbuf.count = 0; /* available data for reading */
+
+ lprintf("asc.buffer_allocate: ok\n");
+
+ return SUCCESS;
+}
+
+/*** dma_restart
+ *** invoked locally to start dma. Must run in a critical section
+ ***/
+static void
+dma_restart(struct asc_unit *scu)
+{
+ unsigned char al=scu->cmd_byte;
+ isa_dmastart(B_READ, scu->sbuf.base+scu->sbuf.wptr,
+ scu->linesize, scu->dma_num);
+ /*** this is done in sub_20, after dmastart ? ***/
+#if 0
+ outb( ASC_CMD, al |= 4 );
+ outb( ASC_CMD, al |= 8 ); /* ??? seems useless */
+ outb( ASC_CMD, al &= 0xfb );
+ scu->cmd_byte = al;
+#else
+ outb( ASC_CMD, ASC_OPERATE);
+#endif
+ scu->flags |= DMA_ACTIVE;
+}
+
+/***
+ *** the main functions
+ ***/
+
+/*** asc_reset
+ *** resets the scanner and the config bytes...
+ ***/
+void
+asc_reset(struct asc_unit *scu)
+{
+ scu->cfg_byte = 0 ; /* clear... */
+ scu->cmd_byte = 0 ; /* clear... */
+
+ outb(ASC_CFG,scu->cfg_byte); /* for safety, do this here */
+ outb(ASC_CMD,scu->cmd_byte); /* probably not needed */
+ tsleep((caddr_t)scu, ASCPRI | PCATCH, "ascres", hz/10); /* sleep .1 sec */
+
+ scu->blen = DEFAULT_BLEN;
+ scu->btime = TIMEOUT;
+ scu->height = 0 ; /* don't know better... */
+}
+/**************************************************************************
+ ***
+ *** ascprobe
+ *** read status port and check for proper configuration:
+ *** - if address group matches (status byte has reasonable value)
+ *** cannot check interrupt/dma, only clear the config byte.
+ ***/
+int
+ascprobe (struct isa_device *isdp)
+{
+ int unit = isdp->id_unit;
+ struct asc_unit *scu = unittab + unit;
+ int stb;
+
+ scu->base = isdp->id_iobase; /*** needed by the following macros ***/
+ scu->flags = DEBUG;
+
+ if ( isdp->id_iobase < 0 ) {
+ lprintf("asc%d.probe: no iobase given\n", unit);
+ return PROBE_FAIL;
+ }
+
+ if ((stb=inb(ASC_PROBE)) != ASC_PROBE_VALUE) {
+ lprintf("asc%d.probe: failed, got 0x%02x instead of 0x%02x\n",
+ unit, stb, ASC_PROBE_VALUE);
+ return PROBE_FAIL;
+ }
+
+ switch(ffs(isdp->id_irq) - 1) {
+ case 3:
+ scu->int_byte = ASC_CNF_IRQ3;
+ break;
+ case 5:
+ scu->int_byte = ASC_CNF_IRQ5;
+ break;
+ case 10:
+ scu->int_byte = ASC_CNF_IRQ10;
+ break;
+#if 0
+ case -1:
+ scu->int_byte = 0;
+ lprintf("asc%d.probe: warning - going interruptless\n", unit);
+ break;
+#endif
+ default:
+ lprintf("asc%d.probe: unsupported INT %d (only 3, 5, 10)\n",
+ unit, isdp->id_irq);
+ return PROBE_FAIL;
+ }
+ scu->dma_num = isdp->id_drq;
+ switch(scu->dma_num) {
+ case 1:
+ scu->dma_byte = ASC_CNF_DMA1;
+ break;
+ case 3:
+ scu->dma_byte = ASC_CNF_DMA3;
+ break;
+ default:
+ lprintf("asc%d.probe: unsupported DMA %d (only 1 or 3)\n", scu->dma_num);
+ return PROBE_FAIL;
+ }
+ asc_reset(scu);
+/* lprintf("asc%d.probe: ok\n", unit); */
+
+ scu->flags &= ~DEBUG;
+ scu->icnt = 0;
+
+ return PROBE_SUCCESS;
+}
+
+/**************************************************************************
+ ***
+ *** ascattach
+ *** finish initialization of unit structure, get geometry value (?)
+ ***/
+
+int
+ascattach(struct isa_device *isdp)
+{
+ int unit = isdp->id_unit;
+ struct asc_unit *scu = unittab + unit;
+#ifdef DEVFS
+ char buf[32];
+ void *x;
+#endif
+
+ scu->flags |= DEBUG;
+ printf("asc%d: [GI1904/Trust Ami-Scan Grey, type S2]\n", unit);
+
+ /* initialize buffer structure */
+ scu->sbuf.base = NULL;
+ scu->sbuf.size = INVALID;
+ scu->sbuf.rptr = INVALID;
+
+ scu->flags |= ATTACHED;
+/* lprintf("asc%d.attach: ok\n", unit); */
+ scu->flags &= ~DEBUG;
+
+#ifdef FREEBSD_1_X
+ scu->selp = (pid_t)0;
+#else
+ scu->selp.si_flags=0;
+ scu->selp.si_pid=(pid_t)0;
+ kdc_asc[isdp->id_unit].kdc_state = DC_BUSY; /* XXX don't know better */
+ asc_registerdev(isdp);
+#endif
+#ifdef DEVFS
+ sprintf(buf,"asc%d",unit);
+/* path name devsw minor type uid gid perm*/
+ x=dev_add("/misc", buf, ascopen, unit<<6, DV_CHR, 0, 0, 0666);
+ sprintf(buf,"asc%dp",unit);
+ x=dev_add("/misc", buf, ascopen, ((unit<<6) + FRMT_PBM),
+ DV_CHR, 0, 0, 0666);
+ sprintf(buf,"asc%dd",unit);
+ x=dev_add("/misc", buf, ascopen, ((unit<<6) + DBUG_MASK),
+ DV_CHR, 0, 0, 0666);
+ sprintf(buf,"asc%dpd",unit);
+ x=dev_add("/misc", buf, ascopen, ((unit<<6) + DBUG_MASK + FRMT_PBM),
+ DV_CHR, 0, 0, 0666);
+#endif /*DEVFS*/
+ return 1; /* attach must not fail */
+}
+
+/**************************************************************************
+ ***
+ *** ascintr
+ *** the interrupt routine, at the end of DMA...
+ ***/
+void
+ascintr(int unit)
+{
+ struct asc_unit *scu = unittab + unit;
+ int chan_bit = 0x01 << scu->dma_num;
+
+ scu->icnt++;
+ /* ignore stray interrupts... */
+ if ( scu->flags & (OPEN |READING) != (OPEN | READING) ) {
+ /* must be after closing... */
+ scu->flags &= ~(OPEN | READING | DMA_ACTIVE | SLEEPING | SEL_COLL);
+ return;
+ }
+ if ( (scu->flags & DMA_ACTIVE) && (inb(DMA1_READY) & chan_bit) != 0) {
+ outb( ASC_CMD, ASC_STANDBY);
+ scu->flags &= ~DMA_ACTIVE;
+ /* bounce buffers... */
+ isa_dmadone(B_READ, scu->sbuf.base+scu->sbuf.wptr,
+ scu->linesize, scu->dma_num);
+ scu->sbuf.wptr += scu->linesize;
+ if (scu->sbuf.wptr >= scu->sbuf.size) scu->sbuf.wptr=0;
+ scu->sbuf.count += scu->linesize;
+ if (scu->flags & SLEEPING) {
+ scu->flags &= ~SLEEPING;
+ wakeup((caddr_t)scu);
+ }
+ if (scu->sbuf.size - scu->sbuf.count >= scu->linesize) {
+ dma_restart(scu);
+ }
+#ifdef FREEBSD_1_X
+ if (scu->selp) {
+ selwakeup(&scu->selp, scu->flags & SEL_COLL );
+ scu->selp=(pid_t)0;
+ scu->flags &= ~SEL_COLL;
+ }
+#else
+ if (scu->selp.si_pid) {
+ selwakeup(&scu->selp);
+ scu->selp.si_pid=(pid_t)0;
+ scu->selp.si_flags = 0;
+ }
+#endif
+ }
+}
+
+/**************************************************************************
+ ***
+ *** ascopen
+ *** set open flag, set modes according to minor number
+ *** FOR RELEASE:
+ *** don't switch scanner on, wait until first read or ioctls go before
+ ***/
+
+int
+ascopen(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ int unit = UNIT(minor(dev)) & UNIT_MASK;
+ struct asc_unit *scu = unittab + unit;
+
+ lprintf("asc%d.open: minor %d icnt %d\n", unit, minor(dev), scu->icnt);
+
+ if ( unit >= NASC || !( scu->flags & ATTACHED ) ) {
+ lprintf("asc%d.open: unit was not attached successfully, flags 0x%04x\n",
+ unit, scu->flags);
+ return ENXIO;
+ }
+
+ if ( scu->flags & OPEN ) {
+ lprintf("asc%d.open: already open", unit);
+ return EBUSY;
+ }
+ scu->flags = ATTACHED | OPEN;
+
+ if ( minor(dev) & DBUG_MASK ) scu->flags |= DEBUG;
+
+ switch(minor(dev) & FRMT_MASK) {
+ case FRMT_PBM:
+ scu->flags |= PBM_MODE;
+ lprintf("asc%d.open: pbm mode\n", unit);
+ break;
+ case FRMT_RAW:
+ lprintf("asc%d.open: raw mode\n", unit);
+ scu->flags &= ~PBM_MODE;
+ break;
+ default:
+ lprintf("asc%d.open: gray maps are not yet supported", unit);
+ return ENXIO;
+ }
+
+ asc_reset(scu);
+ get_resolution(scu);
+ return SUCCESS;
+}
+
+int
+asc_startread(struct asc_unit *scu)
+{
+ /*** from here on, things can be delayed to the first read/ioctl ***/
+ /*** this was done in sub_12... ***/
+ scu->cfg_byte= scu->cmd_byte=0; /* init scanner */
+ outb(ASC_CMD, scu->cmd_byte);
+ /*** this was done in sub_16, set scan len... ***/
+ outb(ASC_BOH, 0 );
+ scu->cmd_byte = 0x90 ;
+ outb(ASC_CMD, scu->cmd_byte);
+ outb(ASC_LEN_L, scu->linesize & 0xff /* len_low */);
+ outb(ASC_LEN_H, (scu->linesize >>8) & 0xff /* len_high */);
+ /*** this was done in sub_21, config DMA ... ***/
+ scu->cfg_byte |= scu->dma_byte;
+ outb(ASC_CFG, scu->cfg_byte);
+ /*** sub_22: enable int on the scanner ***/
+ scu->cfg_byte |= scu->int_byte;
+ outb(ASC_CFG, scu->cfg_byte);
+ /*** sub_28: light on etc...***/
+ scu->cmd_byte = ASC_STANDBY;
+ outb(ASC_CMD, scu->cmd_byte);
+ tsleep((caddr_t)scu, ASCPRI | PCATCH, "ascstrd", hz/10); /* sleep .1 sec */
+ return SUCCESS;
+}
+
+/**************************************************************************
+ ***
+ *** ascclose
+ *** turn off scanner, release the buffer
+ *** should probably terminate dma ops, release int and dma. lr 12mar95
+ ***/
+
+int
+ascclose(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ int unit = UNIT(minor(dev));
+ struct asc_unit *scu = unittab + unit;
+
+ lprintf("asc%d.close: minor %d\n",
+ unit, minor(dev));
+
+ if ( unit >= NASC || !( scu->flags & ATTACHED ) ) {
+ lprintf("asc%d.close: unit was not attached successfully 0x%04x\n",
+ unit, scu->flags);
+ return ENXIO;
+ }
+ /* all this is in sub_29... */
+ /* cli(); */
+ outb(ASC_CFG, 0 ); /* don't save in CFG byte!!! */
+ scu->cmd_byte &= ~ASC_LIGHT_ON;
+ outb(ASC_CMD, scu->cmd_byte);/* light off */
+ tsleep((caddr_t)scu, ASCPRI | PCATCH, "ascclo", hz/2); /* sleep 1/2 sec */
+ scu->cfg_byte &= ~ scu->dma_byte ; /* disable scanner dma */
+ scu->cfg_byte &= ~ scu->int_byte ; /* disable scanner int */
+ outb(ASC_CFG, scu->cfg_byte);
+ /* --- disable dma controller ? --- */
+ /* --- disable interrupts on the controller (sub_24) --- */
+
+ if ( scu->sbuf.base != NULL ) free( scu->sbuf.base, M_DEVBUF );
+
+ scu->sbuf.base = NULL;
+ scu->sbuf.size = INVALID;
+ scu->sbuf.rptr = INVALID;
+
+ scu->flags &= ~(DEBUG | OPEN | READING);
+
+ return SUCCESS;
+}
+
+static void
+pbm_init(struct asc_unit *scu)
+{
+ int width = geomtab[scu->geometry].dpl;
+ int l= sprintf(scu->sbuf.base,"P4 %d %d\n", width, scu->height);
+ char *p;
+
+ scu->bcount = scu->height * width / 8 + l;
+
+ /* move header to end of sbuf */
+ scu->sbuf.rptr=scu->sbuf.size-l;
+ bcopy(scu->sbuf.base, scu->sbuf.base+scu->sbuf.rptr,l);
+ scu->sbuf.count = l;
+ for(p = scu->sbuf.base + scu->sbuf.rptr; l; p++, l--)
+ *p = ~*p;
+}
+/**************************************************************************
+ ***
+ *** ascread
+ ***/
+
+int
+ascread(dev_t dev, struct uio *uio, int ioflag)
+{
+ int unit = UNIT(minor(dev));
+ struct asc_unit *scu = unittab + unit;
+ size_t nbytes;
+ int sps, res;
+ unsigned char *p;
+
+ lprintf("asc%d.read: minor %d icnt %d\n", unit, minor(dev), scu->icnt);
+
+ if ( unit >= NASC || !( scu->flags & ATTACHED ) ) {
+ lprintf("asc%d.read: unit was not attached successfully 0x%04x\n",
+ unit, scu->flags);
+ return ENXIO;
+ }
+
+ if ( !(scu->flags & READING) ) { /*** first read... ***/
+ /* allocate a buffer for reading data and init things */
+ if ( (res = buffer_allocate(scu)) == SUCCESS ) scu->flags |= READING;
+ else return res;
+ asc_startread(scu);
+ if ( scu->flags & PBM_MODE ) { /* initialize for pbm mode */
+ pbm_init(scu);
+ }
+ }
+
+ lprintf("asc%d.read(before): "
+ "sz 0x%x, rptr 0x%x, wptr 0x%x, cnt 0x%x bcnt 0x%x flags 0x%x icnt %d\n",
+ unit, scu->sbuf.size, scu->sbuf.rptr,
+ scu->sbuf.wptr, scu->sbuf.count, scu->bcount,scu->flags,
+ scu->icnt);
+
+ sps=spltty();
+ if ( scu->sbuf.count == 0 ) { /* no data avail., must wait */
+ if (!(scu->flags & DMA_ACTIVE)) dma_restart(scu);
+ scu->flags |= SLEEPING;
+ res = tsleep((caddr_t)scu, ASCPRI | PCATCH, "ascread", 0);
+ scu->flags &= ~SLEEPING;
+ if ( res == 0 ) res = SUCCESS;
+ }
+ splx(sps); /* lower priority... */
+ if (scu->flags & DEBUG)
+ tsleep((caddr_t)scu, ASCPRI | PCATCH, "ascdly",hz);
+ lprintf("asc%d.read(after): "
+ "sz 0x%x, rptr 0x%x, wptr 0x%x, cnt 0x%x bcnt 0x%x flags 0x%x icnt %d\n",
+ unit, scu->sbuf.size, scu->sbuf.rptr,
+ scu->sbuf.wptr, scu->sbuf.count, scu->bcount,scu->flags,scu->icnt);
+
+ /* first, not more than available... */
+ nbytes = min( uio->uio_resid, scu->sbuf.count );
+ /* second, contiguous data... */
+ nbytes = min( nbytes, (scu->sbuf.size - scu->sbuf.rptr) );
+ /* third, one line (will remove this later, XXX) */
+ nbytes = min( nbytes, scu->linesize );
+ if ( (scu->flags & PBM_MODE) )
+ nbytes = min( nbytes, scu->bcount );
+ lprintf("asc%d.read: transferring 0x%x bytes\n", unit, nbytes);
+
+ lprintf("asc%d.read: invert buffer\n",unit);
+ for(p = scu->sbuf.base + scu->sbuf.rptr, res=nbytes; res; p++, res--)
+ *p = ~*p;
+ res = uiomove(scu->sbuf.base + scu->sbuf.rptr, nbytes, uio);
+ if ( res != SUCCESS ) {
+ lprintf("asc%d.read: uiomove failed %d", unit, res);
+ return res;
+ }
+
+ sps=spltty();
+ scu->sbuf.rptr += nbytes;
+ if (scu->sbuf.rptr >= scu->sbuf.size) scu->sbuf.rptr=0;
+ scu->sbuf.count -= nbytes;
+ /* having moved some data, can read mode */
+ if (!(scu->flags & DMA_ACTIVE)) dma_restart(scu);
+ splx(sps); /* lower priority... */
+ if ( scu->flags & PBM_MODE ) scu->bcount -= nbytes;
+
+ lprintf("asc%d.read: size 0x%x, pointer 0x%x, bcount 0x%x, ok\n",
+ unit, scu->sbuf.size, scu->sbuf.rptr, scu->bcount);
+
+ return SUCCESS;
+}
+
+/**************************************************************************
+ ***
+ *** ascioctl
+ ***/
+
+int
+ascioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *p)
+{
+ int unit = UNIT(minor(dev));
+ struct asc_unit *scu = unittab + unit;
+
+ lprintf("asc%d.ioctl: minor %d\n",
+ unit, minor(dev));
+
+ if ( unit >= NASC || !( scu->flags & ATTACHED ) ) {
+ lprintf("asc%d.ioctl: unit was not attached successfully 0x04x\n",
+ unit, scu->flags);
+ return ENXIO;
+ }
+ switch(cmd) {
+ case ASC_GRES:
+ asc_reset(scu);
+ get_resolution(scu);
+ *(int *)data=geomtab[scu->geometry].dpi;
+ lprintf("asc%d.ioctl:ASC_GRES %ddpi\n", unit, *(int *)data);
+ return SUCCESS;
+ case ASC_GWIDTH:
+ *(int *)data=geomtab[scu->geometry].dpl;
+ lprintf("asc%d.ioctl:ASC_GWIDTH %d\n", unit, *(int *)data);
+ return SUCCESS;
+ case ASC_GHEIGHT:
+ *(int *)data=scu->height;
+ lprintf("asc%d.ioctl:ASC_GHEIGHT %d\n", unit, *(int *)data);
+ return SUCCESS;
+ case ASC_SHEIGHT:
+ lprintf("asc%d.ioctl:ASC_SHEIGHT %d\n", unit, *(int *)data);
+ if ( scu->flags & READING ) {
+ lprintf("asc%d:ioctl on already reading unit\n", unit);
+ return EBUSY;
+ }
+ scu->height=*(int *)data;
+ return SUCCESS;
+#if 0
+ case ASC_GBLEN:
+ *(int *)data=scu->blen;
+ lprintf("asc%d.ioctl:ASC_GBLEN %d\n", unit, *(int *)data);
+ return SUCCESS;
+ case ASC_SBLEN:
+ lprintf("asc%d.ioctl:ASC_SBLEN %d\n", unit, *(int *)data);
+ if (*(int *)data * geomtab[scu->geometry].dpl / 8 > MAX_BUFSIZE)
+ {
+ lprintf("asc%d:ioctl buffer size too high\n", unit);
+ return ENOMEM;
+ }
+ scu->blen=*(int *)data;
+ return SUCCESS;
+ case ASC_GBTIME:
+ *(int *)data = scu->btime / hz;
+ lprintf("asc%d.ioctl:ASC_GBTIME %d\n", unit, *(int *)data);
+ return SUCCESS;
+ case ASC_SBTIME:
+ scu->btime = *(int *)data * hz;
+ lprintf("asc%d.ioctl:ASC_SBTIME %d\n", unit, *(int *)data);
+ return SUCCESS;
+#endif
+ default: return ENOTTY;
+ }
+ return SUCCESS;
+}
+
+int
+ascselect(dev_t dev, int rw, struct proc *p)
+{
+ int unit = UNIT(minor(dev));
+ struct asc_unit *scu = unittab + unit;
+ int sps=spltty();
+ struct proc *p1;
+
+ if (scu->sbuf.count >0) {
+ splx(sps);
+ return 1;
+ }
+ if (!(scu->flags & DMA_ACTIVE)) dma_restart(scu);
+#ifdef FREEBSD_1_X
+ if (scu->selp== (pid_t)0) {
+ scu->selp= p->p_pid;
+ } else {
+ scu->flags |= SEL_COLL;
+ }
+#else
+
+ if (scu->selp.si_pid && (p1=pfind(scu->selp.si_pid))
+ && p1->p_wchan == (caddr_t)&selwait)
+ scu->selp.si_flags = SI_COLL;
+ else
+ scu->selp.si_pid = p->p_pid;
+#endif
+ splx(sps);
+ return 0;
+}
+#endif /* NASC > 0 */
diff --git a/sys/i386/isa/ascreg.h b/sys/i386/isa/ascreg.h
new file mode 100644
index 0000000000000..a1a7393de651a
--- /dev/null
+++ b/sys/i386/isa/ascreg.h
@@ -0,0 +1,96 @@
+/* ascreg.h - port and bit definitions for the GI-1904 interface
+ *
+ * Copyright (c) 1995 Gunther Schadow. All rights reserved.
+ * Copyright (c) 1995 Luigi Rizzo. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gunther Schadow.
+ * and Luigi Rizzo
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * $Id:$
+ */
+
+ /*** Registers (base=3EB): ************/
+#define ASC_CFG (scu->base)
+ /*** ASC_CFG 3EB: configuration register. Write only, mirror in RAM
+ *** 7 6 5 4 3 2 1 0
+ *** - - I_5 I_3 I10 D_3 - D_1
+ ***/
+ /*** #define ASC_CNF_MASK 0x3D */ /* was 0x5a */
+#define ASC_CNF_DMA1 0x01 /* was (~0x02 & ASC_CNF_MASK) */
+#define ASC_CNF_DMA3 0x04 /* was (~0x08 & ASC_CNF_MASK) */
+#define ASC_CNF_IRQ3 0x10 /* was (~0x10 & ASC_CNF_MASK) */
+#define ASC_CNF_IRQ5 0x20 /* was (~0x40 & ASC_CNF_MASK) */
+#define ASC_CNF_IRQ10 0x08 /* was (~0x40 & ASC_CNF_MASK) */
+
+ /*** ASC_STAT 3EC: command/status; rw, mirror in ram
+ *** 7 6 5 4 3 2 1 0
+ *** BSY - - - - - - -
+ *** [<-- Resolution -->] 13h,10h,0eh,0ch,09h, 07h, 04h, 02h
+ ***/
+#define ASC_STAT (scu->base + 1)
+
+#define ASC_RDY_FLAG 0x80
+#define ASC_RES_MASK 0x3f
+#define ASC_RES_800 0x13
+#define ASC_RES_700 0x10
+#define ASC_RES_600 0x0e
+#define ASC_RES_500 0x0c
+#define ASC_RES_400 0x09 /* 0x00 */
+#define ASC_RES_300 0x07 /* 0x04 */
+#define ASC_RES_200 0x04 /* 0x20 */
+#define ASC_RES_100 0x02 /* 0x24 */
+
+ /*** ASC_CMD 3EC: command/status; rw, mirror in ram
+ *** W: 7 6 5 4 3 2 1 0
+ *** . - - . . . . .
+ *** b0: 1: light on & get resolution, 0: light off
+ *** b1: 0: load scan len (sub_16, with b4=1, b7=1)
+ *** b2: 1/0 : dma stuff
+ *** b3: 0/1 : dma stuff
+ *** b4: 1 : load scan len (sub_16, with b1=0, b7=1)
+ *** b5: ?
+ *** b6: ?
+ *** b7: ? : set at beginning of sub_16
+ ***/
+#define ASC_CMD (scu->base + 1)
+
+#define ASC_LIGHT_ON 0x01
+#define ASC_SET_B2 0x04
+#define ASC_OPERATE 0x91 /* from linux driver... */
+#define ASC_STANDBY 0x05 /* from linux driver... */
+
+ /*** ASC_LEN_L, ASC_LEN_H 3ED, 3EE: transfer length, lsb first ***/
+#define ASC_LEN_L ((scu->base)+2)
+#define ASC_LEN_H ((scu->base)+3)
+
+ /*** 3EE ASC_PROBE (must read ASC_PROBE_VALUE) ***/
+#define ASC_PROBE ((scu->base)+3)
+#define ASC_PROBE_VALUE 0xA5
+
+ /*** ASC_BOH 3EF: always write 0 at the moment, read some values ? ***/
+#define ASC_BOH ((scu->base)+4)
diff --git a/sys/pci/meteor.c b/sys/pci/meteor.c
new file mode 100644
index 0000000000000..dac5eab12ce2d
--- /dev/null
+++ b/sys/pci/meteor.c
@@ -0,0 +1,1245 @@
+/*
+ * Copyright (c) 1995 Mark Tinguely and Jim Lowe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Tinguely and Jim Lowe
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Change History:
+ 8/21/95 Release
+ 8/23/95 On advice from Stefan Esser, added volatile to PCI
+ memory pointers to remove PCI caching .
+ 8/29/95 Fixes suggested by Bruce Evans.
+ meteor_mmap should return -1 on error rather than 0.
+ unit # > NMETEOR should be unit # >= NMETEOR.
+*/
+
+#include "meteor.h"
+
+#if NMETEOR > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/devconf.h>
+#include <sys/mman.h>
+#include <machine/clock.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_param.h>
+
+#include <pci.h>
+#if NPCI > 0
+#include <pci/pcivar.h>
+#endif
+#include <machine/ioctl_meteor.h>
+
+ /* enough memory for 640x48 RGB16, or YUV (16 storage bits/pixel) or
+ 450x340 RGB24 (32 storage bits/pixel)
+ options "METEOR_ALLOC_PAGES="
+ */
+#ifndef METEOR_ALLOC_PAGES
+#define METEOR_ALLOC_PAGES 151
+#endif
+#define METEOR_ALLOC (METEOR_ALLOC_PAGES * PAGE_SIZE)
+
+#define NUM_SAA7116_PCI_REGS 37
+#define NUM_SAA7196_I2C_REGS 49
+
+typedef struct {
+ vm_offset_t virt_baseaddr; /* saa7116 register virtual address */
+ vm_offset_t phys_baseaddr; /* saa7116 register physical address */
+ vm_offset_t capt_cntrl; /* capture control register offset 0x40 */
+ vm_offset_t stat_reg; /* status register offset 0x60 */
+ vm_offset_t iic_virt_addr; /* ICC bus register offset 0x64 */
+ pcici_t tag; /* PCI tag, for doing PCI commands */
+ vm_offset_t bigbuf; /* buffer that holds the captured image */
+ int alloc_pages; /* number of pages in bigbuf */
+ struct proc *proc; /* process to receive raised signal */
+ struct meteor_mem *mem; /* used to control sync. multi-frame output */
+ u_long hiwat_cnt; /* mark and count frames lost due to hiwat */
+ short ecurrent; /* even frame number in buffer (1-frames) */
+ short ocurrent; /* odd frame number in buffer (1-frames) */
+ short rows; /* number of rows in a frame */
+ short cols; /* number of columns in a frame */
+ short depth; /* number of byte per pixel */
+ short frames; /* number of frames allocated */
+ int frame_size; /* number of bytes in a frame */
+ u_long fifo_errors; /* number of fifo capture errors since open */
+ u_long dma_errors; /* number of DMA capture errors since open */
+ u_long frames_captured;/* number of frames captured since open */
+ unsigned flags;
+#define METEOR_INITALIZED 0x00000001
+#define METEOR_OPEN 0x00000002
+#define METEOR_MMAP 0x00000004
+#define METEOR_INTR 0x00000008
+#define METEOR_READ 0x00000010
+#define METEOR_SINGLE 0x00000020
+#define METEOR_CONTIN 0x00000040
+#define METEOR_SYNCAP 0x00000080
+#define METEOR_CAP_MASK 0x000000f0
+#define METEOR_NTSC 0x00000100
+#define METEOR_PAL 0x00000200
+#define METEOR_SECAM 0x00000400
+#define METEOR_AUTOMODE 0x00000800
+#define METEOR_FORM_MASK 0x00000f00
+#define METEOR_DEV0 0x00001000
+#define METEOR_DEV1 0x00002000
+#define METEOR_DEV2 0x00004000
+#define METEOR_DEV3 0x00008000
+#define METEOR_DEV_MASK 0x0000f000
+#define METEOR_RGB16 0x00010000
+#define METEOR_RGB24 0x00020000
+#define METEOR_YUV_PACKED 0x00040000
+#define METEOR_YUV_PLANER 0x00080000
+#define METEOR_PRO_MASK 0x000f0000
+#define METEOR_SINGLE_EVEN 0x00100000
+#define METEOR_SINGLE_ODD 0x00200000
+#define METEOR_SINGLE_MASK 0x00300000
+ u_char saa7196_i2c[NUM_SAA7196_I2C_REGS]; /* saa7196 register values */
+} meteor_reg_t;
+
+meteor_reg_t meteor[NMETEOR];
+
+u_long read_intr_wait;
+#define METPRI (PZERO+8)|PCATCH
+
+/*---------------------------------------------------------
+**
+** Meteor PCI probe and initialization routines
+**
+**---------------------------------------------------------
+*/
+
+static char* met_probe (pcici_t tag, pcidi_t type);
+static void met_attach(pcici_t tag, int unit);
+static u_long met_count;
+
+struct pci_device met_device = {
+ "meteor",
+ met_probe,
+ met_attach,
+ &met_count
+};
+
+DATA_SET (pcidevice_set, met_device);
+
+static u_long saa7116_pci_default[NUM_SAA7116_PCI_REGS] = {
+ /* PCI Memory registers */
+ /* BITS Type Description */
+/* 0x00 */ 0x00000000, /* 31:1 e*RW DMA 1 (Even)
+ 0 RO 0x0 */
+/* 0x04 */ 0x00000000, /* 31:2 e*RW DMA 2 (Even)
+ 1:0 RO 0x0 */
+/* 0x08 */ 0x00000000, /* 31:2 e*RW DMA 3 (Even)
+ 1:0 RO 0x0 */
+/* 0x0c */ 0x00000000, /* 31:1 o*RW DMA 1 (Odd)
+ 0 RO 0x0 */
+/* 0x10 */ 0x00000000, /* 31:2 o*RW DMA 2 (Odd)
+ 1:0 RO 0x0 */
+/* 0x14 */ 0x00000000, /* 31:2 o*RW DMA 3 (Odd)
+ 1:0 RO 0x0 */
+/* 0x18 */ 0x00000500, /* 15:2 e*RW Stride 1 (Even)
+ 1:0 RO 0x0 */
+/* 0x1c */ 0x00000000, /* 15:2 e*RW Stride 2 (Even)
+ 1:0 RO 0x0 */
+/* 0x20 */ 0x00000000, /* 15:2 e*RW Stride 3 (Even)
+ 1:0 RO 0x0 */
+/* 0x24 */ 0x00000500, /* 15:2 o*RW Stride 1 (Odd)
+ 1:0 RO 0x0 */
+/* 0x28 */ 0x00000000, /* 15:2 o*RW Stride 2 (Odd)
+ 1:0 RO 0x0 */
+/* 0x2c */ 0x00000000, /* 15:2 o*RW Stride 3 (Odd)
+ 1:0 RO 0x0 */
+/* 0x30 */ 0xeeeeee01, /* 31:8 *RW Route (Even)
+ 7:0 *RW Mode (Even) */
+/* 0x34 */ 0xeeeeee01, /* 31:8 *RW Route (Odd)
+ 7:0 *RW Mode (Odd) */
+/* 0x38 */ 0x00200020, /* 22:16 *RW FIFO Trigger Planer Mode,
+ 6:0 *RW FIFO Trigger Packed Mode */
+/* 0x3c */ 0x00000103, /* 9:8 *RW Reserved (0x0)
+ 2 *RW Field Toggle
+ 1 *RW Reserved (0x1)
+ 0 *RW Reserved (0x1) */
+/* 0x40 */ 0x000000c0, /* 15 *RW Range Enable
+ 14 *RW Corrupt Disable
+ 11 *RR Address Error (Odd)
+ 10 *RR Address Error (Even)
+ 9 *RR Field Corrupt (Odd)
+ 8 *RR Field Corrupt (Even)
+ 7 *RW Fifo Enable
+ 6 *RW VRSTN#
+ 5 *RR Field Done (Odd)
+ 4 *RR Field Done (Even)
+ 3 *RS Single Field Capture (Odd)
+ 2 *RS Single Field Capture (Even)
+ 1 *RW Capture (ODD) Continous
+ 0 *RW Capture (Even) Continous */
+
+/* 0x44 */ 0x00000000, /* 7:0 *RW Retry Wait Counter */
+/* 0x48 */ 0x00000307, /* 10 *RW Interrupt mask, start of field
+ 9 *RW Interrupt mask, end odd field
+ 8 *RW Interrupt mask, end even field
+ 2 *RR Interrupt status, start of field
+ 1 *RR Interrupt status, end of odd
+ 0 *RR Interrupt status, end of even */
+/* 0x4c */ 0x00000001, /* 31:0 *RW Field Mask (Even) continous */
+/* 0x50 */ 0x00000001, /* 31:0 *RW Field Mask (Odd) continous */
+/* 0x54 */ 0x00000000, /* 20:16 *RW Mask Length (Odd)
+ 4:0 *RW Mask Length (Even) */
+/* 0x58 */ 0x0005007c, /* 22:16 *RW FIFO almost empty
+ 6:0 *RW FIFO almost full */
+/* 0x5c */ 0x461e1e0f, /* 31:24 *RW I2C Phase 4
+ 23:16 *RW I2C Phase 3
+ 15:8 *RW I2C Phase 2
+ 7:0 *RW I2C Phase 1 */
+/* 0x60 */ 0x00000300, /* 31:24 *RO I2C Read Data
+ 23:16 **RW I2C Auto Address
+ 11 RO I2C SCL Input
+ 10 RO I2C SDA Input
+ 9 RR I2C Direct Abort
+ 8 RR I2C Auto Abort
+ 3 RW I2C SCL Output
+ 2 RW I2C SDA Output
+ 1 RW I2C Bypass
+ 0 RW I2C Auto Enable */
+/* 0x64 */ 0x00000000, /* 24 RS I2C New Cycle
+ 23:16 **RW I2C Direct Address
+ 15:8 **RW I2C Direct Sub-address
+ 7:0 **RW I2C Direct Write Address */
+/* 0x68 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 1 (Even)
+ 23:16 **RW I2C Auto Data 1 (Even)
+ 15:8 **RW I2C Auto Sub-address 0 (Even)
+ 7:0 **RW I2C Auto Data 0 (Even) */
+/* 0x6c */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 3 (Even)
+ 23:16 **RW I2C Auto Data 3 (Even)
+ 15:8 **RW I2C Auto Sub-address 2 (Even)
+ 7:0 **RW I2C Auto Data 2 (Even) */
+/* 0x70 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 5 (Even)
+ 23:16 **RW I2C Auto Data 5 (Even)
+ 15:8 **RW I2C Auto Sub-address 4 (Even)
+ 7:0 **RW I2C Auto Data 4 (Even) */
+/* 0x74 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 7 (Even)
+ 23:16 **RW I2C Auto Data 7 (Even)
+ 15:8 **RW I2C Auto Sub-address 6 (Even)
+ 7:0 **RW I2C Auto Data 6 (Even) */
+/* 0x78 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 1 (Odd)
+ 23:16 **RW I2C Auto Data 1 (Odd)
+ 15:8 **RW I2C Auto Sub-address 0 (Odd)
+ 7:0 **RW I2C Auto Data 0 (Odd) */
+/* 0x7c */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 3 (Odd)
+ 23:16 **RW I2C Auto Data 3 (Odd)
+ 15:8 **RW I2C Auto Sub-address 2 (Odd)
+ 7:0 **RW I2C Auto Data 2 (Odd) */
+/* 0x80 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 5 (Odd)
+ 23:16 **RW I2C Auto Data 5 (Odd)
+ 15:8 **RW I2C Auto Sub-address 4 (Odd)
+ 7:0 **RW I2C Auto Data 4 (Odd) */
+/* 0x84 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 7 (Odd)
+ 23:16 **RW I2C Auto Data 7 (Odd)
+ 15:8 **RW I2C Auto Sub-address 6 (Odd)
+ 7:0 **RW I2C Auto Data 6 (Odd) */
+/* 0x88 */ 0x00000000, /* 23:16 **RW I2C Register Enable (Odd)
+ 7:0 **RW I2C Register Enable (Even) */
+/* 0x8c */ 0x00000000, /* 23:2 e*RW DMA End (Even)
+ 1:0 RO 0x0 */
+/* 0x90 */ 0x00000000 /* 23:2 e*RW DMA End (Odd)
+ 1:0 RO 0x0 */
+};
+
+static u_char saa7196_i2c_default[NUM_SAA7196_I2C_REGS] = {
+ /* SAA7196 I2C bus control */
+ /* BITS Function */
+/* 00 */ 0x50, /* 7:0 Increment Delay */
+/* 01 */ 0x7f, /* 7:0 Horizontal Sync Begin for 50hz */
+/* 02 */ 0x53, /* 7:0 Horizontal Sync Stop for 50hz */
+/* 03 */ 0x43, /* 7:0 Horizontal Sync Clamp Start for 50hz */
+/* 04 */ 0x19, /* 7:0 Horizontal Sync Clamp Stop for 50hz */
+/* 05 */ 0x00, /* 7:0 Horizontal Sync Start after PH1 for 50hz */
+/* 06 */ 0x46, /* 7 Input mode =0 CVBS, =1 S-Video
+ 6 Pre filter
+ 5:4 Aperture Bandpass characteristics
+ 3:2 Coring range for high freq
+ 1:0 Aperture bandpass filter weights */
+/* 07 */ 0x00, /* 7:0 Hue */
+/* 08 */ 0x7f, /* 7:3 Colour-killer threshold QAM (PAL, NTSC) */
+/* 09 */ 0x7f, /* 7:3 Colour-killer threshold SECAM */
+/* 0a */ 0x7f, /* 7:0 PAL switch sensitivity */
+/* 0b */ 0x7f, /* 7:0 SECAM switch sensitivity */
+/* 0c */ 0x40, /* 7 Colour-on bit
+ 6:5 AGC filter */
+/* 0d */ 0x84, /* 7 VTR/TV mode bit = 1->VTR mode
+ 3 Realtime output mode select bit
+ 2 HREF position select
+ 1 Status byte select
+ 0 SECAM mode bit */
+/* 0e */ 0x38, /* 7 Horizontal clock PLL
+ 5 Select interal/external clock source
+ 4 Output enable of Horizontal/Vertical sync
+ 3 Data output YUV enable
+ 2 S-VHS bit
+ 1 GPSW2
+ 0 GPSW1 */
+/* 0f */ 0x50, /* 7 Automatic Field detection
+ 6 Field Select 0 = 50hz, 1=60hz
+ 5 SECAM cross-colour reduction
+ 4 Enable sync and clamping pulse
+ 3:1 Luminance delay compensation */
+/* 10 */ 0x00, /* 2 Select HREF Position
+ 1:0 Vertical noise reduction */
+/* 11 */ 0x2c, /* 7:0 Chrominance gain conrtol for QAM */
+/* 12 */ 0x40, /* 7:0 Chrominance saturation control for VRAM port */
+/* 13 */ 0x40, /* 7:0 Luminance contract control for VRAM port */
+/* 14 */ 0x34, /* 7:0 Horizontal sync begin for 60hz */
+/* 15 */ 0x0c, /* 7:0 Horizontal sync stop for 60hz */
+/* 16 */ 0xfb, /* 7:0 Horizontal clamp begin for 60hz */
+/* 17 */ 0xd4, /* 7:0 Horizontal clamp stop for 60hz */
+/* 18 */ 0xec, /* 7:0 Horizontal sync start after PH1 for 60hz */
+/* 19 */ 0x80, /* 7:0 Luminance brightness control for VRAM port */
+/* 1a */ 0x00,
+/* 1b */ 0x00,
+/* 1c */ 0x00,
+/* 1d */ 0x00,
+/* 1e */ 0x00,
+/* 1f */ 0x00,
+/* 20 */ 0x90, /* 7 ROM table bypass switch
+ 6:5 Set output field mode
+ 4 VRAM port outputs enable
+ 3:2 First pixel position in VRO data
+ 1:0 FIFO output register select */
+/* 21 */ 0x80, /* 7:0 [7:0] Pixel number per line on output */
+/* 22 */ 0x80, /* 7:0 [7:0] Pixel number per line on input */
+/* 23 */ 0x03, /* 7:0 [7:0] Horizontal start position of scaling win*/
+/* 24 */ 0x8a, /* 7:5 Horizontal decimation filter
+ 4 [8] Horizontal start position of scaling win
+ 3:2 [9:8] Pixel number per line on input
+ 1:0 [9:8] Pixel number per line on output */
+/* 25 */ 0xf0, /* 7:0 [7:0] Line number per output field */
+/* 26 */ 0xf0, /* 7:0 [7:0] Line number per input field */
+/* 27 */ 0x0f, /* 7:0 [7:0] Vertical start of scaling window */
+/* 28 */ 0x80, /* 7 Adaptive filter switch
+ 6:5 Vertical luminance data processing
+ 4 [8] Vertical start of scaling window
+ 3:2 [9:8] Line number per input field
+ 1:0 [9:8] Line number per output field */
+/* 29 */ 0x16, /* 7:0 [7:0] Vertical bypass start */
+/* 2a */ 0x00, /* 7:0 [7:0] Vertical bypass count */
+/* 2b */ 0x00, /* 4 [8] Vertical bypass start
+ 2 [8] Vertical bypass count
+ 0 Polarity, internally detected odd even flag */
+/* 2c */ 0x80, /* 7:0 Set lower limit V for colour-keying */
+/* 2d */ 0x7f, /* 7:0 Set upper limit V for colour-keying */
+/* 2e */ 0x80, /* 7:0 Set lower limit U for colour-keying */
+/* 2f */ 0x7f, /* 7:0 Set upper limit U for colour-keying */
+/* 30 */ 0xbf /* 7 VRAM bus output format
+ 6 Adaptive geometrical filter
+ 5 Luminance limiting value
+ 4 Monochrome and two's complement output data sel
+ 3 Line quailifier flag
+ 2 Pixel qualifier flag
+ 1 Transparent data transfer
+ 0 Extended formats enable bit */
+};
+
+/*
+ * i2c_write:
+ * Returns 0 Succesful completion.
+ * Returns 1 If transfer aborted or timeout occured.
+ *
+ */
+#define SAA7196_I2C_ADDR 0x40
+#define I2C_WRITE 0x00
+#define I2C_READ 0x01
+#define SAA7116_IIC_NEW_CYCLE 0x1000000L
+#define IIC_DIRECT_TRANSFER_ABORTED 0x0000200L
+
+#define SAA7196_WRITE(mtr, reg, data) \
+ i2c_write(mtr, SAA7196_I2C_ADDR, I2C_WRITE, reg, data); \
+ mtr->saa7196_i2c[reg] = data
+#define SAA7196_REG(mtr, reg) mtr->saa7196_i2c[reg]
+#define SAA7196_READ(mtr) \
+ i2c_write(mtr, SAA7196_I2C_ADDR, I2C_READ, 0x0, 0x0)
+
+static int
+i2c_write(meteor_reg_t * mtr, u_char slave, u_char rw, u_char reg, u_char data)
+{
+register unsigned long wait_counter = 0x0001ffff;
+register volatile u_long *iic_write_loc = (volatile u_long *)mtr->iic_virt_addr;
+register int err = 0;
+
+ /* Write the data the the i2c write register */
+ *iic_write_loc = SAA7116_IIC_NEW_CYCLE |
+ (((u_long)slave|(u_long)rw) << 16) |
+ ((u_long)reg << 8) | (u_long)data;
+
+ /* Wait until the i2c cycle is compeleted */
+ while((*iic_write_loc & SAA7116_IIC_NEW_CYCLE)) {
+ if(!wait_counter) break;
+ wait_counter--;
+ }
+
+/*#ifdef notdef*/
+ /* it seems the iic_write_loc is cached, until we can
+ figure out how to uncache the pci registers, then we
+ will just ignore the timeout. Hopefully 1ffff will
+ be enough delay time for the i2c cycle to complete */
+ if(!wait_counter) {
+ printf("meteor: saa7116 i2c %s transfer timeout 0x%x",
+ rw ? "read" : "write", *iic_write_loc);
+
+ err=1;
+ }
+/*#endif*/
+
+ /* Check for error on direct write, clear if any */
+ if((*((volatile u_long *)mtr->stat_reg)) & IIC_DIRECT_TRANSFER_ABORTED) {
+ printf("meteor: saa7116 i2c %s tranfer aborted",
+ rw ? "read" : "write" );
+ err= 1;
+ }
+
+ if(err) {
+ printf(" - reg=0x%x, value=0x%x.\n", reg, data);
+ }
+
+ return err;
+}
+
+
+static char*
+met_probe (pcici_t tag, pcidi_t type)
+{
+ switch (type) {
+
+ case 0x12238086ul: /* meteor */
+ return ("Matrox Meteor");
+
+ };
+ return ((char*)0);
+}
+
+ /* interrupt handling routine
+ complete meteor_read() if using interrupts
+ */
+int
+meteor_intr( void *arg)
+{
+ register meteor_reg_t *mtr = (meteor_reg_t *) arg;
+
+ register volatile u_long *cap, *base, *status, cap_err;
+ struct meteor_mem *mm;
+
+ base = (volatile u_long *) mtr->virt_baseaddr;
+ cap = (volatile u_long *) mtr->capt_cntrl; /* capture control ptr */
+ status = base + 18; /* mtr->virt_base + 0x48 save a dereference */
+
+ /* the even field has to make the decision of whether the high water
+ has been reached. If hiwat has been reach do not advance the buffer.
+ continue to save frames on this buffer until we can advance again */
+ if (*status & 0x1) { /* even field */
+ if (mtr->flags & METEOR_SYNCAP) {
+ mm = mtr->mem; /* shared SYNCAP struct */
+ if ((!mtr->hiwat_cnt && mm->num_active_bufs < mm->hiwat) ||
+ (mm->num_active_bufs <= mm->lowat)) {
+ mtr->hiwat_cnt = 0;
+ if (++mtr->ecurrent > mtr->frames) {
+ *base = mtr->bigbuf;
+ mtr->ecurrent = 1;
+ } else {
+ *base = *base + mtr->frame_size;
+ }
+ }
+ else {
+ mtr->hiwat_cnt++;
+ }
+ } else if(mtr->flags & METEOR_SINGLE) {
+ *cap &= 0x0ffe;
+ mtr->flags &= ~METEOR_SINGLE_EVEN;
+ if(!(mtr->flags & METEOR_SINGLE_MASK)) {
+ mtr->frames_captured++ ;
+ wakeup((caddr_t) &read_intr_wait);
+ }
+ }
+ } else { /* odd field */
+ if (mtr->flags & METEOR_SINGLE) {
+ *cap &= 0x0ffd;
+ mtr->flags &= ~ METEOR_SINGLE_ODD;
+ if(!(mtr->flags & METEOR_SINGLE_MASK)) {
+ mtr->frames_captured++ ;
+ wakeup((caddr_t) &read_intr_wait);
+ }
+ } else if (mtr->flags & METEOR_SYNCAP) {
+ mm = mtr->mem; /* shared SYNCAP struct */
+ /* even field decided to advance or not, we
+ simply add stride to that decision */
+ *(base+3) = *base + *(base + 6);
+ if (mtr->ecurrent != mtr->ocurrent) {
+ mm->active |= (1 << (mtr->ocurrent-1));
+ mtr->ocurrent = mtr->ecurrent;
+ mm->num_active_bufs++;
+ if (mtr->proc && mm->signal) {
+ mtr->frames_captured++ ;
+ psignal(mtr->proc, mm->signal);
+ }
+ }
+ }
+ }
+ if (cap_err = (*cap & 0xf00)) {
+ if (cap_err & 0x3)
+ mtr->fifo_errors++ ; /* incrememnt fifo capture errors cnt */
+ if (cap_err & 0xc)
+ mtr->dma_errors++ ; /* increment DMA capture errors cnt */
+ }
+
+ *cap |= 0xf30; /* clear error and field done */
+ *status |= 0xf; /* clear interrupt status */
+
+ return(1);
+}
+
+/*
+ * Initialize the capture card to NTSC RGB 16 640x480
+ */
+static void
+meteor_init ( meteor_reg_t *mtr )
+{
+ volatile u_long *vbase_addr;
+ int i;
+
+ *((volatile u_long *)(mtr->capt_cntrl)) = 0x00000040L;
+
+ vbase_addr = (volatile u_long *) mtr->virt_baseaddr;
+ for (i= 0 ; i < NUM_SAA7116_PCI_REGS; i++)
+ *vbase_addr++ = saa7116_pci_default[i];
+
+ for (i = 0; i < NUM_SAA7196_I2C_REGS; i++) {
+ SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]);
+ }
+
+}
+
+static void met_attach(pcici_t tag, int unit)
+{
+#ifdef METEOR_IRQ /* from the meteor.h file */
+ u_long old_irq,new_irq;
+
+#endif METEOR_IRQ /* from the meteor.h file */
+ meteor_reg_t *mtr;
+ vm_offset_t buf;
+
+ if (unit >= NMETEOR) {
+ printf("meteor_attach: mx%d: invalid unit number\n");
+ return ;
+ }
+
+ mtr = &meteor[unit];
+ pci_map_mem(tag, 0x10, &(mtr->virt_baseaddr),
+ &(mtr->phys_baseaddr));
+ /* IIC addres at 0x64 offset bytes */
+ mtr->capt_cntrl = mtr->virt_baseaddr + 0x40;
+ mtr->stat_reg = mtr->virt_baseaddr + 0x60;
+ mtr->iic_virt_addr = mtr->virt_baseaddr + 0x64;
+
+#ifdef METEOR_IRQ /* from the meteor.h file */
+ old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
+ pci_conf_write(tag, PCI_INTERRUPT_REG, METEOR_IRQ);
+ new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
+ printf("meteor_attach: irq changed from %d to %d\n", (old_irq & 0xff),
+ (new_irq & 0xff));
+#endif METEOR_IRQ
+
+ meteor_init( mtr ); /* set up saa7116 and saa7196 chips */
+ mtr->tag = tag;
+ /* setup the interrupt handling routine */
+ pci_map_int (tag, meteor_intr, (void*) mtr, &net_imask);
+
+ /* 640*240*3 round up to nearest pag e*/
+ buf = vm_page_alloc_contig(METEOR_ALLOC, 0x100000, 0xffffffff, PAGE_SIZE);
+ if (buf == NULL) {
+ printf("meteor_attach: big buffer allocation failed\n");
+ return;
+ }
+ mtr->bigbuf = buf;
+ mtr->alloc_pages = METEOR_ALLOC_PAGES;
+
+ bzero((caddr_t) buf, METEOR_ALLOC);
+
+ buf = vtophys(buf);
+ *((volatile u_long *) mtr->virt_baseaddr) = buf;
+
+ /* 640x480 RGB 16 */
+ *((volatile u_long *) mtr->virt_baseaddr + 3) = buf + 0x500;
+
+ *((volatile u_long *) mtr->virt_baseaddr + 36) =
+ *((volatile u_long *) mtr->virt_baseaddr + 35) = buf + METEOR_ALLOC;
+ mtr->flags = METEOR_INITALIZED | METEOR_NTSC | METEOR_DEV0 |
+ METEOR_RGB16;
+ /* 1 frame of 640x480 RGB 16 */
+ mtr->cols = 640;
+ mtr->rows = 480;
+ mtr->depth = 2; /* two bytes per pixel */
+ mtr->frames = 1; /* one frame */
+}
+
+static void
+meteor_reset(meteor_reg_t * const sc)
+{
+
+}
+
+/*---------------------------------------------------------
+**
+** Meteor character device driver routines
+**
+**---------------------------------------------------------
+*/
+
+#define UNIT(x) ((x) & 0x07)
+
+int
+meteor_open(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ meteor_reg_t *mtr;
+ int unit;
+ int i;
+
+ unit = UNIT(minor(dev));
+ if (unit >= NMETEOR) /* unit out of range */
+ return(ENXIO);
+
+ mtr = &(meteor[unit]);
+
+ if (!(mtr->flags & METEOR_INITALIZED)) /* device not found */
+ return(ENXIO);
+
+ if (mtr->flags & METEOR_OPEN) /* device is busy */
+ return(EBUSY);
+
+ mtr->flags |= METEOR_OPEN;
+ /*
+ * Make sure that the i2c regs are set the same for each open.
+ */
+ for(i=0; i< NUM_SAA7196_I2C_REGS; i++) {
+ SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]);
+ }
+
+ mtr->fifo_errors = 0;
+ mtr->dma_errors = 0;
+ mtr->frames_captured = 0;
+
+ return(0);
+}
+
+int
+meteor_close(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ meteor_reg_t *mtr;
+ int unit;
+ int temp;
+
+ unit = UNIT(minor(dev));
+ if (unit >= NMETEOR) /* unit out of range */
+ return(ENXIO);
+
+ mtr = &(meteor[unit]);
+ mtr->flags &= ~METEOR_OPEN;
+
+ /* XXX stop any capture modes running */
+ switch (mtr->flags & METEOR_CAP_MASK) {
+ case METEOR_SINGLE: /* this should not happen, the read capture
+ should have completed or in the very least
+ recieved a signal before close is called. */
+ mtr->flags &= ~(METEOR_SINGLE|METEOR_SINGLE_MASK);
+ wakeup((caddr_t) &read_intr_wait); /* continue read */
+ break;
+
+ case METEOR_CONTIN: /* continous unsync-ed reading, we can
+ simply turn off the capture */
+ mtr->flags &= ~METEOR_CONTIN;
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff0; /* turn off capture */
+ break;
+ case METEOR_SYNCAP:
+ mtr->flags &= ~METEOR_SYNCAP;
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff0; /* turn off capture */
+ mtr->proc = NULL;
+ mtr->mem = NULL;
+ mtr->ecurrent = mtr->ocurrent = 1;
+ /* re-initalize the even/odd DMA positions to top of buffer */
+ *((volatile u_long *) mtr->virt_baseaddr) = mtr->bigbuf;
+ *((volatile u_long *) mtr->virt_baseaddr +3) =
+ *((volatile u_long *) mtr->virt_baseaddr) +
+ *((volatile u_long *) mtr->virt_baseaddr+6);
+ break;
+ case 0:
+ break;
+ default:
+ printf("meteor_close: bad capture state on close %d\n",
+ mtr->flags & METEOR_CAP_MASK);
+ }
+#ifdef METEOR_DEALLOC_PAGES
+ if (mtr->bigbuf) {
+ kmem_free(kernel_map,mtr->bigbuf,(mtr->alloc_pages*PAGE_SIZE));
+ mtr->bigbuf = NULL;
+ mtr->alloc_pages = 0;
+ }
+#else
+#ifdef METEOR_DEALLOC_ABOVE
+ if (mtr->bigbuf && mtr->alloc_pages > METEOR_DEALLOC_ABOVE) {
+ temp = METEOR_DEALLOC_ABOVE - mtr->alloc_pages;
+ kmem_free(kernel_map,
+ mtr->bigbuf+((mtr->alloc_pages - temp) * PAGE_SIZE),
+ (temp * PAGE_SIZE));
+ mtr->alloc_pages = METEOR_DEALLOC_ABOVE;
+ }
+#endif
+#endif
+ return(0);
+}
+
+int
+meteor_read(dev_t dev, struct uio *uio, int ioflag)
+{
+ meteor_reg_t *mtr;
+ int unit;
+ int status;
+ int count;
+
+ unit = UNIT(minor(dev));
+ if (unit >= NMETEOR) /* unit out of range */
+ return(ENXIO);
+
+ mtr = &(meteor[unit]);
+ if (!mtr->bigbuf) /* no frame buffer allocated (ioctl failed) */
+ return(ENXIO);
+
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EIO); /* already capturing */
+
+ count = mtr->rows * mtr->cols * mtr->depth;
+ if (uio->uio_iov->iov_len < count)
+ return(EINVAL);
+
+ mtr->flags |= METEOR_SINGLE | METEOR_SINGLE_MASK;
+
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff3; /* capture */
+
+ status = tsleep((caddr_t) &read_intr_wait, METPRI, "capturing", 0);
+
+ if (!status) /* successful capture */
+ status = uiomove((caddr_t)mtr->bigbuf, count, uio);
+
+ else
+ printf ("meteor_read: bad tsleep\n");
+ mtr->flags &= ~(METEOR_SINGLE | METEOR_SINGLE_MASK);
+ return(status);
+}
+
+int
+meteor_write(dev_t dev, struct uio *uio, int ioflag)
+{
+ return(0);
+}
+
+int
+meteor_ioctl(dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr)
+{
+ int error;
+ int unit;
+ int temp;
+ meteor_reg_t *mtr;
+ struct meteor_counts *cnt;
+ struct meteor_geomet *geo;
+ struct meteor_mem *mem;
+ struct meteor_capframe *frame;
+ volatile u_long *p;
+ vm_offset_t buf;
+
+ error = 0;
+
+ if (!arg) return(EINVAL);
+ unit = UNIT(minor(dev));
+ if (unit >= NMETEOR) /* unit out of range */
+ return(ENXIO);
+
+ mtr = &(meteor[unit]);
+
+ switch (cmd) {
+ case METEORSTATUS: /* get 7196 status */
+ temp = 0;
+ SAA7196_WRITE(mtr, 0x0d, SAA7196_REG(mtr, 0x0d) | 0x02);
+ SAA7196_READ(mtr);
+ temp |= ((*((volatile u_long *)mtr->stat_reg)) & 0xff000000L) >> 24;
+ SAA7196_WRITE(mtr, 0x0d, SAA7196_REG(mtr, 0x0d) & 0x02);
+ SAA7196_READ(mtr);
+ temp |= ((*((volatile u_long *)mtr->stat_reg)) & 0xff000000L) >> 16;
+ *(u_short *)arg = temp;
+ break;
+ case METEORSHUE: /* set hue */
+ SAA7196_WRITE(mtr, 0x07, *(char *)arg);
+ break;
+ case METEORGHUE: /* get hue */
+ *(char *)arg = SAA7196_REG(mtr, 0x07);
+ break;
+ case METEORSCHCV: /* set chrominance gain */
+ SAA7196_WRITE(mtr, 0x11, *(char *)arg);
+ break;
+ case METEORGCHCV: /* get chrominance gain */
+ *(char *)arg = SAA7196_REG(mtr, 0x11);
+ break;
+ case METEORSINPUT: /* set input device */
+ switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
+ case 0: /* default */
+ case METEOR_INPUT_DEV0:
+ mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV0;
+
+ SAA7196_WRITE(mtr, 0x0e,
+ (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x0);
+ break;
+ case METEOR_INPUT_DEV1:
+ mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV1;
+ SAA7196_WRITE(mtr, 0x0e,
+ (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x1);
+ break;
+ case METEOR_INPUT_DEV2:
+ mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV2;
+ SAA7196_WRITE(mtr, 0x0e,
+ (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x2);
+ break;
+ case METEOR_INPUT_DEV3:
+ mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV3;
+ SAA7196_WRITE(mtr, 0x0e,
+ (SAA7196_REG(mtr, 0x0e) | 0x3));
+ break;
+ default:
+ return EINVAL;
+ }
+ break;
+ case METEORGINPUT: /* get input device */
+ *(u_long *)arg = mtr->flags & METEOR_DEV_MASK;
+ break;
+ case METEORSFMT: /* set input format */
+ switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
+ case 0: /* default */
+ case METEOR_FMT_NTSC:
+ mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
+ METEOR_NTSC;
+ SAA7196_WRITE(mtr, 0x0d,
+ (SAA7196_REG(mtr, 0x0d) & ~0x01));
+ SAA7196_WRITE(mtr, 0x0f,
+ (SAA7196_REG(mtr, 0x0f) & ~0xc0) | 0x40);
+ SAA7196_WRITE(mtr, 0x22, 0x80);
+ SAA7196_WRITE(mtr, 0x24,
+ (SAA7196_REG(mtr, 0x24) & ~0x0c) | 0x08);
+ SAA7196_WRITE(mtr, 0x26, 0xf0);
+ SAA7196_WRITE(mtr, 0x28,
+ (SAA7196_REG(mtr, 0x28) & ~0x0c)) ;
+ break;
+ case METEOR_FMT_PAL:
+ mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
+ METEOR_PAL;
+ SAA7196_WRITE(mtr, 0x0d,
+ (SAA7196_REG(mtr, 0x0d) & ~0x01));
+ SAA7196_WRITE(mtr, 0x0f,
+ (SAA7196_REG(mtr, 0x0f) & ~0xc0));
+ SAA7196_WRITE(mtr, 0x22, 0x00);
+ SAA7196_WRITE(mtr, 0x24,
+ (SAA7196_REG(mtr, 0x24) | 0x0c));
+ SAA7196_WRITE(mtr, 0x26, 0x20);
+ SAA7196_WRITE(mtr, 0x28,
+ (SAA7196_REG(mtr, 0x28) & ~0x0c) | 0x01) ;
+ break;
+ case METEOR_FMT_SECAM:
+ mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
+ METEOR_SECAM;
+ SAA7196_WRITE(mtr, 0x0d,
+ (SAA7196_REG(mtr, 0x0d) & ~0x01) | 0x1);
+ SAA7196_WRITE(mtr, 0x0f,
+ (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0xe0);
+ SAA7196_WRITE(mtr, 0x22, 0x00);
+ SAA7196_WRITE(mtr, 0x24,
+ (SAA7196_REG(mtr, 0x24) | 0x0c));
+ SAA7196_WRITE(mtr, 0x26, 0x20);
+ SAA7196_WRITE(mtr, 0x28,
+ (SAA7196_REG(mtr, 0x28) & ~0x0c) | 0x01) ;
+ break;
+ case METEOR_FMT_AUTOMODE:
+ mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
+ METEOR_AUTOMODE;
+ SAA7196_WRITE(mtr, 0x0d,
+ (SAA7196_REG(mtr, 0x0d) & ~0x01));
+ SAA7196_WRITE(mtr, 0x0f,
+ (SAA7196_REG(mtr, 0x0f) & ~0xc0) | 0xc0);
+ break;
+ default:
+ return EINVAL;
+ }
+ break;
+ case METEORGFMT: /* get input format */
+ *(u_long *)arg = mtr->flags & METEOR_FORM_MASK;
+ break;
+ case METEORCAPTUR:
+ switch (*(int *) arg) {
+ case METEOR_CAP_SINGLE:
+ if (!mtr->bigbuf) /* no frame buffer allocated */
+ return(ENXIO);
+
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EIO); /* already capturing */
+
+ mtr->flags |= METEOR_SINGLE | METEOR_SINGLE_MASK;
+
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff3; /* capture */
+
+ error = tsleep((caddr_t) &read_intr_wait, METPRI,
+ "capturing", 0);
+ mtr->flags &= ~(METEOR_SINGLE| METEOR_SINGLE_MASK);
+ break;
+ case METEOR_CAP_CONTINOUS:
+ if (!mtr->bigbuf) /* no frame buffer allocated */
+ return(ENXIO);
+
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EIO); /* already capturing */
+
+ mtr->flags |= METEOR_CONTIN;
+
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff3; /* capture */
+ break;
+ case METEOR_CAP_STOP_CONT:
+ if (mtr->flags & METEOR_CONTIN) {
+ mtr->flags &= ~METEOR_CONTIN;
+ /* turn off capture */
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff0;
+ }
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+ case METEORCAPFRM:
+ frame = (struct meteor_capframe *) arg;
+ if (!frame)
+ return(EINVAL);
+ switch (frame->command) {
+ case METEOR_CAP_N_FRAMES:
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EIO);
+ if (mtr->flags & METEOR_YUV_PLANER)
+ return(EINVAL);
+ if (!mtr->bigbuf)
+ return(ENOMEM);
+ if ((mtr->frames < 2) ||
+ (frame->lowat < 1 || frame->lowat >= mtr->frames) ||
+ (frame->hiwat < 1 || frame->hiwat >= mtr->frames))
+ return(EINVAL);
+ mtr->flags |= METEOR_SYNCAP;
+ mtr->proc = pr;
+ /* meteor_mem structure is on the page after the data */
+ mem = mtr->mem = (struct meteor_mem *) (mtr->bigbuf +
+ ((mtr->rows*mtr->cols * mtr->depth *
+ mtr->frames+PAGE_SIZE-1)/PAGE_SIZE)*PAGE_SIZE);
+ mtr->ecurrent = mtr->ocurrent = 1;
+ mem->signal = frame->signal;
+ mem->num_bufs = mtr->frames;
+ mem->frame_size=
+ mtr->frame_size = mtr->rows * mtr->cols * mtr->depth;
+ /* user and kernel change these */
+ mem->lowat = frame->lowat;
+ mem->hiwat = frame->hiwat;
+ mem->active = 0;
+ mem->num_active_bufs = 0;
+ *((u_long *) mtr->capt_cntrl) = 0x0ff3;
+ break;
+ case METEOR_CAP_STOP_FRAMES:
+ if (mtr->flags & METEOR_SYNCAP) {
+ mtr->flags &= ~METEOR_SYNCAP;
+ /* turn off capture */
+ *((u_long *) mtr->capt_cntrl) = 0x0ff0;
+ mtr->proc = NULL;
+ mtr->mem = NULL;
+ mtr->ecurrent = mtr->ocurrent = 0;
+
+ /* re-initalize the even/odd DMA positions to top of buffer*/
+ /* XXX if a capture is in progress, this may be trouble */
+
+ *((volatile u_long *) mtr->virt_baseaddr) = mtr->bigbuf;
+ *((volatile u_long *) mtr->virt_baseaddr +3) =
+ *((volatile u_long *) mtr->virt_baseaddr) +
+ *((volatile u_long *) mtr->virt_baseaddr+6);
+ }
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+
+ case METEORSETGEO:
+ geo = (struct meteor_geomet *) arg;
+ /* can't change parameters while capturing */
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EBUSY);
+
+ if ((geo->columns & 0x3fe) != geo->columns) {
+ printf("meteor ioctl: column too large or not even\n");
+ error = EINVAL;
+ }
+ if ((geo->rows & 0x7fe) != geo->rows) {
+ printf("meteor ioctl: rows too large or not even\n");
+ error = EINVAL;
+ }
+ if (geo->frames > 32) {
+ printf("meteor ioctl: frames too large\n");
+ error = EINVAL;
+ }
+ if (!error && (temp=geo->rows*geo->columns * geo->frames *2)) {
+ if (geo->oformat & METEOR_GEO_RGB24)
+ temp = temp * 2;
+
+ /* meteor_mem structure for SYNC Capture */
+ if (geo->frames > 1)
+ temp += PAGE_SIZE;
+
+ temp = (temp + PAGE_SIZE -1)/PAGE_SIZE;
+ if (temp > mtr->alloc_pages) {
+ if (mtr->bigbuf)
+ kmem_free(kernel_map, mtr->bigbuf,
+ (mtr->alloc_pages * PAGE_SIZE));
+ mtr->bigbuf = vm_page_alloc_contig((temp*PAGE_SIZE),
+ 0x100000, 0xffffffff, PAGE_SIZE);
+ mtr->alloc_pages = temp;
+ }
+ if (mtr->bigbuf) {
+ mtr->rows = geo->rows;
+ mtr->cols = geo->columns;
+ mtr->frames = geo->frames;
+ }
+ else {
+ mtr->alloc_pages = 0;
+ printf("meteor_ioctl: buffer allocation failed\n");
+ error = ENOMEM;
+ }
+ }
+
+ p = (volatile u_long *) mtr->virt_baseaddr;
+ if (mtr->bigbuf)
+ buf = vtophys(mtr->bigbuf);
+ else
+ buf = 0;
+ *p++ = buf; /* even y or even RGB */
+ /* set end of buffer location */
+ *(p+36) = *(p+35) = buf + mtr->alloc_pages * PAGE_SIZE;
+
+ switch (geo->oformat & METEOR_PRO_MASK) {
+ case 0: /* default */
+ case METEOR_GEO_RGB16:
+ mtr->depth = 2;
+ if (mtr->flags & METEOR_RGB16 == 0) {
+ mtr->flags = (mtr->flags & ~(METEOR_RGB24 |
+ METEOR_YUV_PACKED |
+ METEOR_YUV_PLANER))
+ | METEOR_RGB16;
+ }
+ if (error == 0) {
+ /* recal stride and odd starting point */
+
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = buf + mtr->cols * 2;
+ *p++ = 0;
+ *p++ = 0;
+ /* stride */
+ *p = *(p+3) = mtr->cols * 2;
+ *(p+6) = *(p+7) = 0xeeeeee01;
+ /* set up the saa7196 */
+ SAA7196_WRITE(mtr, 0x20, 0x90);
+ }
+ break;
+ case METEOR_GEO_RGB24:
+ mtr->depth = 4;
+ if (mtr->flags & METEOR_RGB24 == 0) {
+ mtr->flags = (mtr->flags & ~(METEOR_RGB16 |
+ METEOR_YUV_PACKED |
+ METEOR_YUV_PLANER))
+ | METEOR_RGB24;
+ }
+ if (error == 0 ) {
+ /* recal stride and odd starting point */
+
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = buf + mtr->cols * 4;
+ /* routes */
+ *p++ = 0;
+ *p++ = 0;
+ /* stride */
+ *p = *(p+3) = mtr->cols * 4;
+ /* routes */
+ *(p+6) = *(p+7) = 0x39393900;
+ /* set up the saa7196 */
+ SAA7196_WRITE(mtr, 0x20, 0x92);
+ }
+ break;
+ case METEOR_GEO_YUV_PLANER:
+ mtr->depth = 2;
+ if (mtr->flags & METEOR_YUV_PLANER == 0) {
+ mtr->flags = (mtr->flags & ~(METEOR_RGB16 |
+ METEOR_RGB24 |
+ METEOR_YUV_PACKED))
+ | METEOR_YUV_PLANER;
+ }
+ if (error == 0 ) {
+ /* recal stride and odd starting point */
+
+ temp = mtr->rows * mtr->cols;
+ /* even u */
+ *p++ = buf + temp;
+ /* even v */
+ *p++ = buf + temp + (temp >> 2);
+ /* odd y */
+ *p++ = buf + mtr->cols;
+ /* odd u */
+ *p++ = buf + temp + (temp >> 1);
+ /* odd v */
+ *p++ = buf + temp + (temp >> 1)
+ + (temp >> 2);
+ /* stride */
+ *p = *(p+3) = mtr->cols;
+ /* routes */
+ *(p+6) = *(p+7) = 0xaaaaffc1;
+ /* set up the saa7196 */
+ SAA7196_WRITE(mtr, 0x20, 0x91);
+ }
+ break;
+ case METEOR_GEO_YUV_PACKED:
+ mtr->depth = 2;
+ if (mtr->flags & METEOR_YUV_PACKED == 0) {
+ mtr->flags = (mtr->flags & ~(METEOR_RGB16 |
+ METEOR_RGB24 |
+ METEOR_YUV_PLANER))
+ | METEOR_YUV_PACKED;
+ }
+ if (error == 0 ) {
+ /* recal stride and odd starting point */
+
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = buf + mtr->cols * 2;
+ *p++ = 0;
+ *p++ = 0;
+ /* stride */
+ *p = *(p+3) = mtr->cols * 2;
+ /* routes */
+ *(p+6) = *(p+7) = 0xeeeeee41;
+ /* set up the saa7196 */
+ SAA7196_WRITE(mtr, 0x20, 0x91);
+ }
+ break;
+ default:
+ error = EINVAL; /* invalid arguement */
+ printf("meteor_ioctl: invalid output format\n");
+ break;
+ }
+ if (error == 0 ) {
+ /* set cols */
+ SAA7196_WRITE(mtr, 0x21, mtr->cols & 0xff);
+ SAA7196_WRITE(mtr, 0x24,
+ ((SAA7196_REG(mtr, 0x24) & ~0x03) |
+ ((mtr->cols >> 8) & 0x03)));
+ /* set rows */
+ SAA7196_WRITE(mtr, 0x25, ((mtr->rows >> 1) & 0xff));
+ SAA7196_WRITE(mtr, 0x28,
+ ((SAA7196_REG(mtr, 0x28) & ~0x03) |
+ ((mtr->rows >> 9) & 0x03)));
+ }
+ break;
+ case METEORGETGEO:
+ geo = (struct meteor_geomet *) arg;
+ geo->rows = mtr->rows;
+ geo->columns = mtr->cols;
+ geo->frames = mtr->frames;
+ geo->oformat = mtr->flags & METEOR_PRO_MASK;
+ break;
+ case METEORSCOUNT: /* (re)set error counts */
+ cnt = (struct meteor_counts *) arg;
+ mtr->fifo_errors = cnt->fifo_errors;
+ mtr->dma_errors = cnt->dma_errors;
+ mtr->frames_captured = cnt->frames_captured;
+ break;
+ case METEORGCOUNT: /* get error counts */
+ cnt = (struct meteor_counts *) arg;
+ cnt->fifo_errors = mtr->fifo_errors;
+ cnt->dma_errors = mtr->dma_errors;
+ cnt->frames_captured = mtr->frames_captured;
+ break;
+ default:
+ printf("meteor_ioctl: invalid ioctl request\n");
+ error = ENOTTY;
+ break;
+ }
+ return(error);
+}
+
+int
+meteor_mmap(dev_t dev, int offset, int nprot)
+{
+
+ int unit;
+ meteor_reg_t *mtr;
+
+ unit = UNIT(minor(dev));
+ if (unit >= NMETEOR)
+ return(-1);
+
+ mtr = &(meteor[unit]);
+
+
+ if(nprot & PROT_EXEC)
+ return -1;
+
+ if(offset >= mtr->alloc_pages * PAGE_SIZE)
+ return -1;
+
+ return i386_btop((vtophys(mtr->bigbuf) + offset));
+}
+
+#endif /* NMETEOR > 0 */
diff --git a/usr.bin/ee/nls/fr_FR.ISO_8859-1/ee.msg b/usr.bin/ee/nls/fr_FR.ISO_8859-1/ee.msg
new file mode 100644
index 0000000000000..1901d8e8835da
--- /dev/null
+++ b/usr.bin/ee/nls/fr_FR.ISO_8859-1/ee.msg
@@ -0,0 +1,170 @@
+$ This file contains the messages for ee ("easy editor"). See the file
+$ ee.i18n.guide for more information
+$
+$ For ee patchlevel 3
+$
+$ $Id$
+$
+$set 1
+$quote "
+1 "menu de configuration "
+2 "tabulation -> espaces "
+3 "recherche sensible aux maj/min "
+4 "respect des marges "
+5 "formattage automatique des paragraphes"
+6 "caractères 8 bits "
+7 "fenêtre d'informations "
+8 "marge de droite "
+9 "menu de sortie"
+10 "enregistrer les modifications"
+11 "ne pas enregistrer"
+12 "menu fichiers"
+13 "lire un fichier"
+14 "écrire un fichier"
+15 "enregistrer un fichier"
+16 "imprimer le contenu de l'éditeur"
+17 "menu recherche"
+18 "recherche de..."
+19 "rechercher"
+20 "menu correcteur orthographique"
+21 "utiliser 'spell'"
+22 "utiliser 'ispell'"
+23 "menu divers"
+24 "formatter le paragraphe"
+25 "commande du shell"
+26 "vérifier l'orthographe"
+27 "menu principal"
+28 "quitter l'éditeur"
+29 "aide"
+30 "opérations sur les fichiers"
+31 "rafraîchir l'écran"
+32 "configuration"
+33 "recherche"
+34 "divers"
+35 "Contrôle + touche: "
+36 "^a code ascii ^i tabulation ^r droite "
+37 "^b fin du texte ^j nouvelle ligne ^t début du texte "
+38 "^c commande ^k effacer caractère ^u haut "
+39 "^d bas ^l gauche ^v annuler effacement mot "
+40 "^e entrer recherche ^m nouvelle ligne ^w effacer un mot "
+41 "^f annuler eff. caract. ^n page suivante ^x recherche "
+42 "^g début de ligne ^o fin de ligne ^y effacer ligne "
+43 "^h arrière ^p page précédente ^z annuler effacement ligne"
+44 "^[ (échappement) menu "
+45 " "
+46 "Commandes: "
+47 "aide : pour cet écran d'info fichier: donne le nom du fichier "
+48 "lire : lire un fichier caract : code ascii d'un caractère"
+49 "ecrire : créer un fichier minmaj : recherche sensible aux maj/Min"
+50 "fin : quitter et enregistrer pasmin : recherche insensible aux maj/Min"
+51 "quitter: quitter, ne pas enregistrer !cmd : exécute \"cmd\" par le shell"
+52 "ligne : indique le nunéro de ligne 0-9 : aller à la ligne \"#\" "
+53 "tabs : étendre les tabulations pastabs: ne pas étendre les tabulations"
+54 " "
+55 " ee [-i] [-e] [-h] [fichier(s)] "
+56 " -i : pas de fenêtre d'info -e : ne pas étendre les tabs -h : pas de surbrillance"
+57 "^[ (echap.) menu ^e rechercher... ^y efface ligne ^u haut ^p page préc."
+58 "^a code ascii ^x rechercher ^z annul. eff. ligne ^d bas ^n page suiv."
+59 "^b fin du texte ^g début de ligne ^w efface mot ^l gauche "
+60 "^t début du texte ^o fin de ligne ^v annul. eff. mot ^r droite "
+61 "^c commande ^k efface caract. ^f annul. eff. caract. "
+62 "aide: fenêtre d'aide |fichier: nom du fichier |ligne: numéro de ligne"
+63 "lire: lecture fichier|caract : code ascii du car. |0-9: aller ligne \"#\""
+64 "ecrire: crée un fich. |minmaj: rech. sensible min/maj|fin: quitte et sauve"
+65 "!cmd: shell \"cmd\" |pasmin: rech. insens. min/maj |quitte: quitte sans sauver"
+66 "tabs: étend les tabs |pastabs: n'étend pas les tabulations"
+67 " presser sur Esc (^[) pour le menu"
+68 "pas de fichier"
+69 "code ascii: "
+70 "le contenu du buffer est imprimé sur \"%s\" "
+71 "commande: "
+72 "nom du fichier à créer: "
+73 "nom du fichier à lire: "
+74 "caractère = %d"
+75 "commande inconnue : \"%s\""
+76 "la commande tapée est ambiguë"
+77 "ligne %d "
+78 "longueur = %d"
+79 "le fichier courant est \"%s\" "
+80 "utilisation: %s [-i] [-e] [-h] [+numero_de_ligne] [fichier(s)]\n"
+81 " -i supprime la fenêtre d'informations\n"
+82 " -e ne convertit pas les tabs en espaces\n"
+83 " -h n'utilise pas de surbrillance\n"
+84 "le fichier \"%s\" est un répertoire"
+85 "nouveau fichier \"%s\""
+86 "impossible de d'ouvrir \"%s\""
+87 "fichier \"%s\", %d lignes"
+88 "le fichier \"%s\" a été lu"
+89 "lecture du fichier \"%s\""
+90 ", lecture seule"
+91 "fichier \"%s\", %d lignes"
+92 "entrer un nom de fichier : "
+93 "pas de nom de fichier donné : fichier non enregistré"
+94 "des changements ont été effectués, êtes vous sûr ? (o/n [n]) "
+95 "o"
+96 "le fichier existe déjà, réécrire ? (o/n) [n] "
+97 "impossible de créer le fichier \"%s\""
+98 "écriture du fichier \"%s\""
+99 "\"%s\" %d lignes, %d caractères"
+100 " ...recherche"
+101 "chaîne \"%s\" non trouvée"
+102 "rechercher: "
+103 "impossible d'exécuter %s\n"
+104 "taper return pour continuer "
+105 "presser sur echap pour annuler"
+106 "menu trop grand pour la fenêtre"
+107 "appuyer sur une touche pour continuer "
+108 "commande du shell: "
+109 "...formattage du paragraphe..."
+110 "<!echo 'liste des mots non reconnus'; echo -=-=-=-=-=-"
+111 "envoi du contenu du buffer à 'spell'"
+112 "colonne de la marge de droite : "
+113 "mode restreint: impossible d'effectuer l'opération demandée"
+114 "OUI"
+115 "NON"
+116 "AIDE"
+117 "ECRIRE"
+118 "LIRE"
+119 "LIGNE"
+120 "FICHIER"
+121 "CARACTERE"
+122 "RAFRAICHIR"
+23 "menu divers"
+124 "AUTEUR"
+125 "VERSION"
+126 "MINMAJ"
+127 "PASMINMAJ"
+128 "TABS"
+129 "PASTABS"
+130 "FIN"
+131 "QUITTE"
+132 "INFO"
+133 "PASINFO"
+134 "MARGES"
+135 "PASMARGES"
+136 "AUTOFORMAT"
+137 "PASAUTOFORMAT"
+138 "ECHO"
+139 "COMMANDEIMPRESSION"
+140 "MARGEDROITE"
+141 "SURBRILLANT"
+142 "PASSURBRILLANT"
+143 "8BIT"
+144 "PAS8BIT"
+145 "caractères de contrôle comme emacs "
+146 "^a début de ligne ^i tabulation ^r annule effacement mot "
+147 "^b arrière ^j annule eff. caract. ^t début du texte "
+148 "^c commande ^k efface ligne ^u fin du texte "
+149 "^d efface caractère ^l annule eff. ligne ^v page suivante "
+150 "^e fin de ligne ^m nouvelle ligne ^w effacer un mot "
+151 "^f caractère suivant ^n ligne suivante ^x recherche "
+152 "^g page précédente ^o insère caract. ascii ^y rechercher... "
+153 "^h efface en arrière ^p ligne précédente ^z mot suivant "
+154 "^[ (escape) menu ^y rechercher... ^k efface ligne ^p ligne prec ^g page prec"
+155 "^o code ascii ^x recherche ^l annul. eff.li ^n ligne suiv ^v page suiv"
+156 "^u fin du fichier ^a début de ligne ^w efface mot ^b arrière "
+157 "^t début du texte ^e fin de ligne ^r annul.eff.mot ^f avance 1 caractère "
+158 "^c commande ^d efface caract. ^j annul.eff.car ^z mot suivant "
+159 "EMACS"
+160 "PASEMACS"
+161 " +# positionne le curseur sur la ligne #\n"