summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Traina <pst@FreeBSD.org>1995-08-02 22:14:27 +0000
committerPaul Traina <pst@FreeBSD.org>1995-08-02 22:14:27 +0000
commitf97a38cd650d66f5bf12266eb6cf0bac07cd9485 (patch)
tree5daa6b0d933d2673aa37d383a2dbed938ab90492
parentfa84c420257565aa0181fbccea613e2c3d2c7775 (diff)
downloadsrc-test2-f97a38cd650d66f5bf12266eb6cf0bac07cd9485.tar.gz
src-test2-f97a38cd650d66f5bf12266eb6cf0bac07cd9485.zip
Notes
-rw-r--r--eBones/kpropd/Makefile11
-rw-r--r--eBones/kpropd/kpropd.c445
-rw-r--r--eBones/libexec/kpropd/Makefile11
-rw-r--r--eBones/libexec/kpropd/kpropd.c445
4 files changed, 912 insertions, 0 deletions
diff --git a/eBones/kpropd/Makefile b/eBones/kpropd/Makefile
new file mode 100644
index 000000000000..74d774fe5ef5
--- /dev/null
+++ b/eBones/kpropd/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id$
+
+PROG= kpropd
+CFLAGS+=-I${.CURDIR}/../include -I${.CURDIR}/../kprop
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/libexec
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/kpropd/kpropd.c b/eBones/kpropd/kpropd.c
new file mode 100644
index 000000000000..db99ae0b5964
--- /dev/null
+++ b/eBones/kpropd/kpropd.c
@@ -0,0 +1,445 @@
+/*
+ * 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: 4.5 $ $Date: 92/10/23 15:45:46 $ $State: Exp $
+ * $Source$
+ *
+ * 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.
+ */
+
+#ifndef lint
+static char rcsid_kpropd_c[] =
+"$Header: /afs/net.mit.edu/project/krb4/src/slave/RCS/kpropd.c,v 4.5 92/10/23 15:45:46 tytso Exp $";
+#endif /* lint */
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <stdio.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;
+
+extern int errno;
+int debug = 0;
+
+int pause_int = 300; /* 5 minutes in seconds */
+unsigned long get_data_checksum();
+static void SlowDeath();
+ /* 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);
+}
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct sockaddr_in from;
+ struct sockaddr_in sin;
+ struct servent *sp;
+ int s, s2, fd, n, fdlock;
+ int from_len;
+ char local_file[256];
+ char local_temp[256];
+ struct hostent *hp;
+ char hostname[256];
+ unsigned long cksum_read;
+ unsigned long cksum_calc;
+ char from_str[128];
+ u_long length;
+ 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;
+ 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
+
+}
+
+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(ad->session, session_sched)) {
+ syslog(LOG_ERR, "can't make key schedule");
+ SlowDeath();
+ }
+#endif
+
+ while (1) {
+ n = krb_net_read(in, &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, 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();
+ }
+ }
+}
+
+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/kpropd/Makefile b/eBones/libexec/kpropd/Makefile
new file mode 100644
index 000000000000..74d774fe5ef5
--- /dev/null
+++ b/eBones/libexec/kpropd/Makefile
@@ -0,0 +1,11 @@
+# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
+# $Id$
+
+PROG= kpropd
+CFLAGS+=-I${.CURDIR}/../include -I${.CURDIR}/../kprop
+DPADD= ${LIBKRB} ${LIBDES}
+LDADD= -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+BINDIR= /usr/libexec
+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 000000000000..db99ae0b5964
--- /dev/null
+++ b/eBones/libexec/kpropd/kpropd.c
@@ -0,0 +1,445 @@
+/*
+ * 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: 4.5 $ $Date: 92/10/23 15:45:46 $ $State: Exp $
+ * $Source$
+ *
+ * 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.
+ */
+
+#ifndef lint
+static char rcsid_kpropd_c[] =
+"$Header: /afs/net.mit.edu/project/krb4/src/slave/RCS/kpropd.c,v 4.5 92/10/23 15:45:46 tytso Exp $";
+#endif /* lint */
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <stdio.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;
+
+extern int errno;
+int debug = 0;
+
+int pause_int = 300; /* 5 minutes in seconds */
+unsigned long get_data_checksum();
+static void SlowDeath();
+ /* 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);
+}
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct sockaddr_in from;
+ struct sockaddr_in sin;
+ struct servent *sp;
+ int s, s2, fd, n, fdlock;
+ int from_len;
+ char local_file[256];
+ char local_temp[256];
+ struct hostent *hp;
+ char hostname[256];
+ unsigned long cksum_read;
+ unsigned long cksum_calc;
+ char from_str[128];
+ u_long length;
+ 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;
+ 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
+
+}
+
+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(ad->session, session_sched)) {
+ syslog(LOG_ERR, "can't make key schedule");
+ SlowDeath();
+ }
+#endif
+
+ while (1) {
+ n = krb_net_read(in, &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, 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();
+ }
+ }
+}
+
+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