summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorGravatar Greg Hudson <ghudson@mit.edu>1997-09-14 17:50:06 +0000
committerGravatar Greg Hudson <ghudson@mit.edu>1997-09-14 17:50:06 +0000
commitac16f380e349fa39ec7e26bccb5456cb300006a5 (patch)
treec07ca88af97b4f6b77d28a2dc723d2e4621ed302 /server
parentd33e482744fad80d95cdd89ed380c5b8401e49bf (diff)
Pull in sources from zephyr locker. See /mit/zephyr/repository for
detailed change information.
Diffstat (limited to 'server')
-rw-r--r--server/BUGS2
-rw-r--r--server/Imakefile76
-rw-r--r--server/Makefile.in67
-rw-r--r--server/access.c314
-rw-r--r--server/access.h42
-rw-r--r--server/acl.h27
-rw-r--r--server/acl_files.c589
-rw-r--r--server/bdump.c2139
-rw-r--r--server/class.c562
-rw-r--r--server/client.c302
-rw-r--r--server/common.c108
-rw-r--r--server/dispatch.c1712
-rw-r--r--server/dispatch.c.auth1078
-rw-r--r--server/hostm.c1045
-rw-r--r--server/kopt.c440
-rw-r--r--server/kopt.c.auth631
-rw-r--r--server/kopt.c.old594
-rw-r--r--server/kstuff.c532
-rw-r--r--server/kstuff.c.auth363
-rw-r--r--server/main.c946
-rw-r--r--server/main.c.auth804
-rw-r--r--server/main.c.old803
-rw-r--r--server/realm.c1086
-rw-r--r--server/server.c2444
-rw-r--r--server/subscr.c2025
-rw-r--r--server/subscr.c.old1384
-rw-r--r--server/timer.c300
-rw-r--r--server/timer.h42
-rw-r--r--server/uloc.c1853
-rw-r--r--server/unix.h110
-rw-r--r--server/version.c18
-rw-r--r--server/version.h1
-rw-r--r--server/zalloc.c175
-rw-r--r--server/zalloc.h22
-rw-r--r--server/zserver.h585
-rw-r--r--server/zserver.h.auth425
-rw-r--r--server/zserver.h.old424
-rw-r--r--server/zsrv_conf.h38
-rw-r--r--server/zsrv_conf.h.auth63
-rw-r--r--server/zsrv_err.et4
-rw-r--r--server/zstring.c253
-rw-r--r--server/zstring.h39
42 files changed, 8933 insertions, 15534 deletions
diff --git a/server/BUGS b/server/BUGS
deleted file mode 100644
index ba58741..0000000
--- a/server/BUGS
+++ /dev/null
@@ -1,2 +0,0 @@
-* race conditions may still exist...
-* two renegade servers won't find each other.
diff --git a/server/Imakefile b/server/Imakefile
deleted file mode 100644
index fcf0232..0000000
--- a/server/Imakefile
+++ /dev/null
@@ -1,76 +0,0 @@
-/**/# Copyright 1988 Massachusetts Institute of Technology.
-/**/#
-/**/# For copying and distribution information, see the file
-/**/# "mit-copyright.h".
-/**/#
-/**/# $Source$
-/**/# $Author$
-/**/# $Header$
-/**/#
-
-#if defined(SYSLOG_COMPAT42)
-SYSLOG_OBJ= ../clients/syslogd/syslog.o
-SYSLOG_DEF= -I../clients/syslogd
-#else
-SYSLOG_OBJ=
-SYSLOG_DEF=
-#endif
-
-#ifdef __NetBSD__
-OSLIBS=-lcompat /* for insque() */
-#endif
-
-XDEFS = $(SYSLOG_DEF) -DCONCURRENT
-
-SRCS= access.c \
- bdump.c \
- class.c \
- client.c \
- common.c \
- dispatch.c \
- hostm.c \
- kopt.c \
- kstuff.c \
- main.c \
- server.c \
- subscr.c \
- timer.c \
- uloc.c \
- version.c \
- zsrv_err.c \
- zstring.c
-
-OBJS= access.o \
- bdump.o \
- class.o \
- client.o \
- common.o \
- dispatch.o \
- hostm.o \
- kopt.o \
- kstuff.o \
- main.o \
- server.o \
- subscr.o \
- timer.o \
- uloc.o \
- zsrv_err.o \
- zstring.o
-
-error_table(zsrv_err)
-SimpleProgram(zephyrd,$(OBJS) $(SYSLOG_OBJ) version.o $(ZLIB) $(ZLIBDES), $(ZLIBS) $(OSLIBS), $(ATHETCDIR))
-install_man(zephyrd.8,zephyrd.8)
-install_file(default.subscriptions,$(ZETCDIR))
-
-create_dir($(ZACLDIR))
-install::
- $(RM) $(DESTDIR)$(ZACLDIR)/?*.acl
- $(CP) acl/?* $(DESTDIR)$(ZACLDIR)
-
-depend:: zsrv_err.h version.h
-$(OBJS): zsrv_err.h
-
-version.o: version.h
-version.h: $(SRCS)
- $(RM) version.h
- sh new_vers.sh
diff --git a/server/Makefile.in b/server/Makefile.in
new file mode 100644
index 0000000..9a4cf56
--- /dev/null
+++ b/server/Makefile.in
@@ -0,0 +1,67 @@
+SHELL = /bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+datadir=@datadir@
+confdir=@confdir@
+sbindir=@sbindir@
+lsbindir=@lsbindir@
+
+includedir=${prefix}/include
+mandir=${prefix}/man
+libdir=${exec_prefix}/lib
+
+srcdir=@srcdir@
+top_srcdir=@top_srcdir@
+BUILDTOP=..
+VPATH=@srcdir@
+CC=@CC@
+INSTALL=@INSTALL@
+COMPILE_ET=@COMPILE_ET@
+
+DEBUG=-O
+CFLAGS=${DEBUG} -DCONFDIR=\"${confdir}\" -I${top_srcdir}/h -I${BUILDTOP}/h \
+ -I. @CPPFLAGS@
+LDFLAGS=${DEBUG} -L${BUILDTOP}/lib/zephyr @ET_LDFLAGS@ @LDFLAGS@
+LIBS=-lzephyr @LIBS@ -lcom_err
+
+OBJS= zsrv_err.o access.o acl_files.o bdump.o class.o client.o common.o \
+ dispatch.o kopt.o kstuff.o main.o server.o subscr.o timer.o uloc.o \
+ zstring.o realm.o version.o
+
+all: zephyrd
+
+zephyrd: ${OBJS} ${BUILDTOP}/lib/zephyr/libzephyr.a @ETDEP@
+ ${CC} ${LDFLAGS} -o $@ ${OBJS} ${LIBS}
+
+zsrv_err.c zsrv_err.h: zsrv_err.et
+ ${COMPILE_ET} ${srcdir}/zsrv_err.et
+
+version.o: version.h
+
+version.h: always
+ sh ${srcdir}/new_vers.sh
+
+check:
+
+# No dependency on zephyrd, to avoid rebuilding version.o.
+install:
+ ${INSTALL} -m 755 -s zephyrd ${DESTDIR}${sbindir}
+ ${INSTALL} -m 644 ${srcdir}/zephyrd.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL} -m 644 ${srcdir}/default.subscriptions ${DESTDIR}${confdir}
+ rm -f ${DESTDIR}${confdir}/acl/?*.acl
+ cp ${srcdir}/acl/?*.acl ${DESTDIR}${confdir}/acl
+ chmod 644 ${DESTDIR}${confdir}/acl/*
+
+clean:
+ rm -f ${OBJS} zephyrd zsrv_err.[ch]
+
+always:
+
+${OBJS}: zserver.h zsrv_err.h timer.h zsrv_conf.h zstring.h access.h acl.h
+${OBJS}: ${top_srcdir}/h/internal.h ${top_srcdir}/h/sysdep.h
+${OBJS}: ${BUILDTOP}/h/config.h ${BUILDTOP}/h/zephyr/zephyr.h
+${OBJS}: ${BUILDTOP}/h/zephyr/zephyr_err.h
+
+.PHONY: all check install clean always
+
diff --git a/server/access.c b/server/access.c
index 9550904..325b911 100644
--- a/server/access.c
+++ b/server/access.c
@@ -12,9 +12,11 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
+#include <com_err.h>
#if !defined (lint) && !defined (SABER)
-static char rcsid_access_c[] =
+static const char rcsid_access_c[] =
"$Id$";
#endif
@@ -24,8 +26,8 @@ static char rcsid_access_c[] =
*
* int access_check(notice, acl, accesstype)
* ZNotice_t *notice;
- * ZAcl_t *acl;
- * ZAccess_t accesstype;
+ * Acl *acl;
+ * Access accesstype;
*
* void access_init();
*
@@ -39,14 +41,8 @@ static char rcsid_access_c[] =
* routines and the support needed by the Zephyr server.
*/
-#include <sys/param.h>
-#ifdef SOLARIS
-#include <sys/filio.h>
-#endif
-#include "zserver.h"
-
/*
- * Our private types for the acl_types field in the ZAcl_t structure.
+ * Our private types for the acl_types field in the Acl structure.
* -TYT 8/14/90
*/
#define ACL_XMT 1
@@ -54,18 +50,9 @@ static char rcsid_access_c[] =
#define ACL_IWS 4
#define ACL_IUI 8
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static void check_acl P((ZAcl_t *acl));
-static void check_acl_type P((ZAcl_t *acl, ZAccess_t accesstype,
- int typeflag));
-static void access_setup P((int first));
-
-#undef P
+static void check_acl __P((Acl *acl));
+static void check_acl_type __P((Acl *acl, Access accesstype, int typeflag));
+static void access_setup __P((int first));
/*
* check access. return 1 if ok, 0 if not ok.
@@ -73,195 +60,176 @@ static void access_setup P((int first));
int
access_check(sender, acl, accesstype)
- char *sender;
- ZAcl_t *acl;
- ZAccess_t accesstype;
+ char *sender;
+ Acl *acl;
+ Access accesstype;
{
- char buf[MAXPATHLEN]; /* holds the real acl name */
- char *prefix;
- int flag;
- int retval;
-
- switch (accesstype) {
- case TRANSMIT:
- prefix = "xmt";
- flag = ACL_XMT;
- break;
- case SUBSCRIBE:
- prefix = "sub";
- flag = ACL_SUB;
- break;
- case INSTWILD:
- prefix = "iws";
- flag = ACL_IWS;
- break;
- case INSTUID:
- prefix = "iui";
- flag = ACL_IUI;
- break;
- default:
- syslog(LOG_ERR, "unknown access type %d", (int) accesstype);
- return(0);
- }
- if (!(acl->acl_types) & flag) /* no acl ==> no restriction
- ==> thumbs up */
- return (1);
- (void) sprintf(buf, "%s%s-%s.acl",
- ZEPHYR_ACL_DIR,
- prefix,
- acl->acl_filename);
- /*
- * If we can't load it (because it probably doesn't exist),
- * we deny access.
- */
+ char buf[MAXPATHLEN]; /* holds the real acl name */
+ char *prefix;
+ int flag;
+ int retval;
+
+ switch (accesstype) {
+ case TRANSMIT:
+ prefix = "xmt";
+ flag = ACL_XMT;
+ break;
+ case SUBSCRIBE:
+ prefix = "sub";
+ flag = ACL_SUB;
+ break;
+ case INSTWILD:
+ prefix = "iws";
+ flag = ACL_IWS;
+ break;
+ case INSTUID:
+ prefix = "iui";
+ flag = ACL_IUI;
+ break;
+ default:
+ syslog(LOG_ERR, "unknown access type %d", (int) accesstype);
+ return 0;
+ }
+ if (!(acl->acl_types & flag)) /* no acl ==> no restriction */
+ return 1;
+ sprintf(buf, "%s/%s-%s.acl", acl_dir, prefix, acl->acl_filename);
+ /*
+ * If we can't load it (because it probably doesn't exist),
+ * we deny access.
+ */
#if 0
- zdbug ((LOG_DEBUG, "checking %s for %s", buf, sender));
+ zdbug ((LOG_DEBUG, "checking %s for %s", buf, sender));
#endif
- retval = acl_load(buf);
- if (retval < 0) {
- syslog(LOG_DEBUG, "Error in acl_load of %s for %s", buf, sender);
- return(0);
- }
- return (acl_check(buf, sender));
+ retval = acl_load(buf);
+ if (retval < 0) {
+ syslog(LOG_DEBUG, "Error in acl_load of %s for %s", buf, sender);
+ return 0;
+ }
+ return acl_check(buf, sender);
}
static void
check_acl(acl)
- ZAcl_t *acl;
+ Acl *acl;
{
- acl->acl_types = 0;
- check_acl_type (acl, TRANSMIT, ACL_XMT);
- check_acl_type (acl, SUBSCRIBE, ACL_SUB);
- check_acl_type (acl, INSTWILD, ACL_IWS);
- check_acl_type (acl, INSTUID, ACL_IUI);
+ acl->acl_types = 0;
+ check_acl_type(acl, TRANSMIT, ACL_XMT);
+ check_acl_type(acl, SUBSCRIBE, ACL_SUB);
+ check_acl_type(acl, INSTWILD, ACL_IWS);
+ check_acl_type(acl, INSTUID, ACL_IUI);
}
static void
check_acl_type(acl, accesstype, typeflag)
- ZAcl_t *acl;
- ZAccess_t accesstype;
- int typeflag;
+ Acl *acl;
+ Access accesstype;
+ int typeflag;
{
- char buf[MAXPATHLEN]; /* holds the real acl name */
- char *prefix;
-
- switch (accesstype) {
- case TRANSMIT:
- prefix = "xmt";
- break;
- case SUBSCRIBE:
- prefix = "sub";
- break;
- case INSTWILD:
- prefix = "iws";
- break;
- case INSTUID:
- prefix = "iui";
- break;
- default:
- syslog(LOG_ERR, "unknown access type %d", (int) accesstype);
- return;
- }
- (void) sprintf(buf, "%s%s-%s.acl",
- ZEPHYR_ACL_DIR,
- prefix,
- acl->acl_filename);
- if (!access(buf, F_OK))
- acl->acl_types |= typeflag;
+ char buf[MAXPATHLEN]; /* holds the real acl name */
+ char *prefix;
+
+ switch (accesstype) {
+ case TRANSMIT:
+ prefix = "xmt";
+ break;
+ case SUBSCRIBE:
+ prefix = "sub";
+ break;
+ case INSTWILD:
+ prefix = "iws";
+ break;
+ case INSTUID:
+ prefix = "iui";
+ break;
+ default:
+ syslog(LOG_ERR, "unknown access type %d", (int) accesstype);
+ return;
+ }
+ sprintf(buf, "%s/%s-%s.acl", acl_dir, prefix, acl->acl_filename);
+ if (!access(buf, F_OK))
+ acl->acl_types |= typeflag;
}
-
+
/*
* Re-init code written by TYT, 8/14/90.
*
* General plan of action; we reread the registry list, and add any
* new restricted classes. If any restricted classes disappear (this
- * should be rarely) the ZAcl_t structure is not deallocated; rather,
+ * should be rarely) the Acl structure is not deallocated; rather,
* the acl_types field will be left at zero, since there will be no
* acl files for the (non-)restricted class.
*/
static void
-#ifdef __STDC__
-access_setup (int first)
-#else
access_setup(first)
- int first;
-#endif
+ int first;
{
- char buf[MAXPATHLEN];
- char class_name[512]; /* assume class names <= 511 bytes */
- FILE *registry;
- ZAcl_t *acl;
- register int len;
- register char *colon_idx;
- Code_t retval = 0;
-
- (void) sprintf(buf, "%s%s", ZEPHYR_ACL_DIR, ZEPHYR_CLASS_REGISTRY);
-
- if ((registry = fopen(buf, "r")) == (FILE *) NULL) {
- syslog(LOG_ERR, "no registry available, all classes are free");
- return;
+ char buf[MAXPATHLEN];
+ char class_name[512]; /* assume class names <= 511 bytes */
+ FILE *registry;
+ Acl *acl;
+ int len;
+ char *colon_idx;
+ Code_t retval = 0;
+
+ sprintf(buf, "%s/%s", acl_dir, ZEPHYR_CLASS_REGISTRY);
+ registry = fopen(buf, "r");
+ if (!registry) {
+ syslog(LOG_ERR, "no registry available, all classes are free");
+ return;
+ }
+ while (fgets(class_name, 512, registry)) {
+ colon_idx = strchr(class_name, ':');
+ if (colon_idx != NULL)
+ *colon_idx = '\0';
+ else if ((len = strlen(class_name)) != 0)
+ class_name[len - 1] = '\0';
+ acl = 0;
+ if (!first) {
+ String *z;
+
+ z = make_string(class_name,1);
+ acl = class_get_acl(z);
+ free_string(z);
}
- while (fgets(class_name, 512, registry) != NULL) {
- if ((colon_idx = (char *) strchr(class_name, ':')) != NULL)
- *colon_idx = '\0';
- else if ((len = strlen(class_name)) != 0)
- class_name[len - 1] = '\0';
- acl = 0;
- if (!first) {
- ZSTRING *z;
- z = make_zstring(class_name,1);
- acl = class_get_acl(z);
- free_zstring(z);
- }
- if (!acl) {
- acl = (ZAcl_t *) xmalloc(sizeof(ZAcl_t));
- if (!acl) {
- syslog(LOG_ERR, "no mem acl alloc");
- abort();
- }
- acl->acl_filename = strsave(class_name);
- check_acl(acl);
+ if (!acl) {
+ acl = (Acl *) malloc(sizeof(Acl));
+ if (!acl) {
+ syslog(LOG_ERR, "no mem acl alloc");
+ abort();
+ }
+ acl->acl_filename = strsave(class_name);
+ check_acl(acl);
- if (!first) {
- /* Try to restrict already existing class */
- retval = class_restrict (class_name, acl);
- if (retval == ZSRV_NOCLASS)
- retval = class_setup_restricted (class_name, acl);
- }
- else
- retval = class_setup_restricted (class_name, acl);
- }
- if (retval) {
- syslog(LOG_ERR, "can't restrict %s: %s",
- class_name, error_message(retval));
- continue;
- }
- zdbug((LOG_DEBUG, "restricted %s", class_name));
+ if (!first) {
+ /* Try to restrict already existing class */
+ retval = class_restrict(class_name, acl);
+ if (retval == ZSRV_NOCLASS)
+ retval = class_setup_restricted(class_name, acl);
+ } else {
+ retval = class_setup_restricted(class_name, acl);
+ }
}
- (void) fclose(registry);
-
- return;
+ if (retval) {
+ syslog(LOG_ERR, "can't restrict %s: %s",
+ class_name, error_message(retval));
+ continue;
+ }
+ zdbug((LOG_DEBUG, "restricted %s", class_name));
+ }
+ fclose(registry);
}
void
-#ifdef __STDC__
-access_init (void)
-#else
access_init()
-#endif
{
- access_setup (1);
+ access_setup(1);
}
void
-#ifdef __STDC__
-access_reinit (void)
-#else
access_reinit()
-#endif
{
- acl_cache_reset ();
- access_setup (0);
+ acl_cache_reset();
+ access_setup(0);
}
diff --git a/server/access.h b/server/access.h
index df1201d..32507e3 100644
--- a/server/access.h
+++ b/server/access.h
@@ -17,36 +17,28 @@
#include <zephyr/mit-copyright.h>
-#include <zephyr/acl.h>
+#include "acl.h"
#include "zstring.h"
-#include "unix.h"
-
-typedef enum _ZAccess_t {
- TRANSMIT, /* use transmission acl */
- SUBSCRIBE, /* use subscription acl */
- INSTWILD, /* use instance wildcard acl */
- INSTUID /* use instance UID identity acl */
-} ZAccess_t;
-
-typedef struct _ZAcl_t {
- char *acl_filename;
- int acl_types; /* Flag field indcating which acls
- are present. Used ONLY in access.c */
-} ZAcl_t;
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
+
+typedef enum _Access {
+ TRANSMIT, /* use transmission acl */
+ SUBSCRIBE, /* use subscription acl */
+ INSTWILD, /* use instance wildcard acl */
+ INSTUID /* use instance UID identity acl */
+} Access;
+
+typedef struct _Acl {
+ char *acl_filename;
+ int acl_types; /* Internal; access fields present. */
+} Acl;
/* found in access.c */
-extern void access_init P((void)), access_reinit P((void));
+void access_init __P((void));
+void access_reinit __P((void));
/* found in acl_files.c */
-extern int acl_load P((char *));
-
-#undef P
+int acl_load __P((char *));
/* external data relevant */
extern int zdebug;
+
diff --git a/server/acl.h b/server/acl.h
new file mode 100644
index 0000000..679cd95
--- /dev/null
+++ b/server/acl.h
@@ -0,0 +1,27 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains definitions for the ACL library
+ *
+ * Created by: John T. Kohl
+ *
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, see the file
+ * "mit-copyright.h".
+ */
+
+#include <zephyr/mit-copyright.h>
+
+#ifndef __ACL__
+#define __ACL__
+
+int acl_add __P((char *, char *));
+int acl_check __P((char *, char *));
+int acl_delete __P((char *, char *));
+int acl_initialize __P((char *, int));
+void acl_cache_reset __P((void));
+
+#endif /* __ACL__ */
+
diff --git a/server/acl_files.c b/server/acl_files.c
new file mode 100644
index 0000000..27c7f63
--- /dev/null
+++ b/server/acl_files.c
@@ -0,0 +1,589 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains functions for maintaining Access Control Lists.
+ *
+ * Created by: John T. Kohl
+ *
+ * $Source$
+ * $Author$
+ *
+ * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, see the file
+ * "mit-copyright.h".
+ */
+
+/* Define this if you really want the ACL-writing code included. */
+/* #define WRITE_ACL */
+
+/*
+ * Stolen from lib/acl_files.c because acl_load needs to be externally
+ * declared and not statically declared.
+ */
+
+#include <zephyr/mit-copyright.h>
+#include "zserver.h"
+
+
+#ifndef SABER
+#ifndef lint
+static const char rcsid_acl_files_c[] = "$Id$";
+#endif /* lint */
+#endif /* SABER */
+
+/*** Routines for manipulating access control list files ***/
+
+/* "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 64 /* How many acls to cache */
+#define ACL_LEN 256 /* 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))
+
+extern int errno;
+
+extern time_t time();
+
+/* 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 *end;
+ char *dot, *atsign;
+ int len;
+
+ dot = strchr(principal, INST_SEP);
+ atsign = strchr(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';
+ }
+#ifdef ZEPHYR_USES_KERBEROS
+ else if (krb_get_lrealm(canon, 1) != KSUCCESS) {
+ strcpy(canon, KRB_REALM);
+ }
+#endif
+}
+
+#ifdef notdef
+/* 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;
+{
+#ifdef WRITE_ACL
+ 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);
+#else
+ abort ();
+#endif
+}
+
+/* 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;
+{
+#ifdef WRITE_ACL
+ 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);
+ }
+#else
+ abort ();
+#endif
+}
+
+/* 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);
+ }
+ }
+}
+
+#endif /* notdef */
+
+/* Eliminate all whitespace character in buf */
+/* Modifies its argument */
+static void nuke_whitespace(buf)
+ char *buf;
+{
+ 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 int
+hashval(s)
+ char *s;
+{
+ 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;
+
+#if 0
+ fprintf (stderr, "adding %s to acl hash %08X\n", el, h);
+#endif
+ /* 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 = (char *) 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;
+
+#if 0
+ fprintf (stderr, "looking for %s in acl %08X\n", el, h);
+#endif
+ for (hv = hashval(el) % h->size; h->tbl[hv]; hv = (hv + 1) % h->size) {
+#if 0
+ fprintf (stderr, "\tstrcmp (%s,...)\n", h->tbl[hv]);
+#endif
+ if (!strcmp(h->tbl[hv], el)) {
+#if 0
+ fprintf (stderr, "success!\n");
+#endif
+ return 1;
+ }
+ }
+#if 0
+ fprintf (stderr, "failure\n");
+#endif
+ return 0;
+}
+
+struct acl {
+ char filename[LINESIZE]; /* Name of acl file */
+ 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 */
+int acl_load(name)
+ char *name;
+{
+ int i;
+ FILE *f;
+ 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))
+ 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;
+ 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);
+ /* Force reload */
+ acl_cache[i].acl = (struct hashtbl *) 0;
+
+ got_it:
+ /*
+ * See if we need to reload the ACL
+ */
+ if (acl_cache[i].acl == (struct hashtbl *) 0) {
+ /* Gotta reload */
+#if 0
+ fprintf (stderr, "attempting to load %s\n", name);
+#endif
+ if ((f = fopen(name, "r")) == NULL) {
+#if 0
+ perror (name);
+#endif
+ 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);
+ }
+ return(i);
+}
+
+/*
+ * This destroys all cached ACL's so that new ones will be loaded in
+ * the next time they are requested.
+ */
+void
+acl_cache_reset()
+{
+ int i;
+
+ /* See if it's there already */
+ for (i = 0; i < acl_cache_count; i++)
+ if (acl_cache[i].acl) {
+ destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = (struct hashtbl *) 0;
+ }
+ acl_cache_count = 0;
+ acl_cache_next = 0;
+ }
+
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Principal is not canonicalized, and no wildcarding is done */
+acl_exact_match(acl, principal)
+ char *acl;
+ char *principal;
+{
+ int idx;
+
+#if 0
+ fprintf (stderr, "checking for %s in %s\n", principal, acl);
+#endif
+ 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. */
+int
+acl_check(acl, principal)
+ char *acl;
+ char *principal;
+{
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+ char *instance, *realm;
+ int p, i, r;
+
+ /* Parse into principal, instance, and realm. */
+ acl_canonicalize_principal(principal, canon);
+ instance = (char *) strchr(canon, INST_SEP);
+ *instance++ = 0;
+ realm = (char *) strchr(instance, REALM_SEP);
+ *realm++ = 0;
+
+ for (p = 0; p <= 1; p++) {
+ for (i = 0; i <= 1; i++) {
+ for (r = 0; r <= 1; r++) {
+ sprintf(buf, "%s%c%s%c%s", (p) ? canon : "*", INST_SEP,
+ (i) ? instance : "*", REALM_SEP, (r) ? realm : "*");
+ if (acl_exact_match(acl, buf))
+ return 1;
+ }
+ }
+ }
+
+ return(0);
+}
+
+#ifdef notdef
+/* 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));
+}
+#endif /* notdef */
diff --git a/server/bdump.c b/server/bdump.c
index e304933..17f99db 100644
--- a/server/bdump.c
+++ b/server/bdump.c
@@ -11,27 +11,15 @@
* For copying and distribution information, see the file
* "mit-copyright.h".
*/
-
+
#include <zephyr/mit-copyright.h>
-
-#ifndef lint
-#ifndef SABER
-static char rcsid_bdump_c[] = "$Id$";
-#endif /* SABER */
-#endif /* lint */
-
#include "zserver.h"
#include <sys/socket.h>
-#include <signal.h>
-#include <sys/param.h> /* for BSD */
-
-/* inconsistent header files... */
-#ifdef SignalIgnore
-#undef SIG_IGN
-#define SIG_IGN SignalIgnore
-#undef SIG_DFL
-#define SIG_DFL SignalDefault
-#endif
+#include <com_err.h>
+
+#ifndef lint
+static const char rcsid_bdump_c[] = "$Id$";
+#endif /* lint */
/*
* External functions are:
@@ -45,7 +33,7 @@ static char rcsid_bdump_c[] = "$Id$";
* ZNotice_t *notice;
* int auth;
* struct sockaddr_in *who;
- * ZServerDesc_t *server;
+ * Server *server;
*
* Code_t bdump_send_list_tcp(kind, port, class, inst, opcode,
* sender, recip, lyst, num)
@@ -55,42 +43,30 @@ static char rcsid_bdump_c[] = "$Id$";
* char *lyst[];
* int num;
*/
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-static void close_bdump P((void* arg));
-static Code_t bdump_send_loop P((register ZServerDesc_t *server, char *vers)),
- bdump_ask_for P((char *inst)),
- bdump_recv_loop P((ZServerDesc_t *server));
-static void bdump_get_v1 P((ZNotice_t *, int, struct sockaddr_in *,
- ZServerDesc_t *));
-static void bdump_get_v1a P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who, ZServerDesc_t *server));
-static Code_t get_packet P((caddr_t packet, int len, int *retlen));
-static Code_t extract_sin P((ZNotice_t *notice, struct sockaddr_in *target));
-static Code_t send_done P((void));
-static Code_t send_list P((ZNotice_Kind_t kind, int port, char *class_name,
- char *inst, char *opcode, char *sender, char *recip,
- char **lyst, int num));
-static Code_t send_host_register P((ZHostList_t *host));
-static Code_t sbd_loop P((struct sockaddr_in *from));
-static Code_t gbd_loop P((ZServerDesc_t *server));
-static Code_t send_normal_tcp P((ZNotice_Kind_t kind, int port,
- char *class_name,
- char *inst, char *opcode, char *sender,
- char *recip, char *message, int len));
-static int net_read P((FILE *f, register char *buf, register int len));
-static int net_write P((FILE *f, register char *buf, int len));
-static int setup_file_pointers P((void));
-static void shutdown_file_pointers P((void));
-static void cleanup P((ZServerDesc_t *server));
-
-#ifdef KERBEROS
-static int get_tgt P((void));
+static void close_bdump __P((void* arg));
+static Code_t bdump_send_loop __P((Server *server)),
+bdump_ask_for __P((char *inst)),
+bdump_recv_loop __P((Server *server));
+static void bdump_get_v12 __P((ZNotice_t *, int, struct sockaddr_in *,
+ Server *));
+static Code_t get_packet __P((void *packet, int len, int *retlen));
+static Code_t extract_sin __P((ZNotice_t *notice, struct sockaddr_in *target));
+static Code_t send_done __P((void));
+static Code_t send_list __P((ZNotice_Kind_t kind, int port, char *class_name,
+ char *inst, char *opcode, char *sender,
+ char *recip, char **lyst, int num));
+static Code_t send_normal_tcp __P((ZNotice_Kind_t kind, int port,
+ char *class_name,
+ char *inst, char *opcode, char *sender,
+ char *recip, char *message, int len));
+static int net_read __P((FILE *f, char *buf, int len));
+static int net_write __P((FILE *f, char *buf, int len));
+static int setup_file_pointers __P((void));
+static void shutdown_file_pointers __P((void));
+static void cleanup __P((Server *server));
+
+#ifdef ZEPHYR_USES_KERBEROS
static long ticket_time;
static char my_realm[REALM_SZ];
@@ -98,15 +74,12 @@ static char my_realm[REALM_SZ];
#define tkt_lifetime(val) ((long) val * 5L * 60L)
#ifndef NOENCRYPTION
-C_Block serv_key;
-Sched serv_ksched;
+extern C_Block serv_key;
+extern Sched serv_ksched;
#endif
-#endif /* KERBEROS */
+#endif /* ZEPHYR_USES_KERBEROS */
-#undef P
-
-static timer bdump_timer;
-static int bdump_inited;
+static Timer *bdump_timer;
static int live_socket = -1;
static FILE *input, *output;
static struct sockaddr_in bdump_sin;
@@ -115,668 +88,575 @@ static int cancel_outgoing_dump;
#endif
int bdumping;
+int bdump_concurrent;
extern char *bdump_version;
-
+
/*
* Functions for performing a brain dump between servers.
*/
-
+
/*
* offer the brain dump to another server
*/
-
+
void
bdump_offer(who)
- struct sockaddr_in *who;
+ struct sockaddr_in *who;
{
- Code_t retval;
- char buf[512], *addr, *lyst[2];
-#ifndef KERBEROS
- int bdump_port = IPPORT_RESERVED - 1;
-#endif /* !KERBEROS */
+ Code_t retval;
+ char buf[512], *addr, *lyst[2];
+#ifndef ZEPHYR_USES_KERBEROS
+ int bdump_port = IPPORT_RESERVED - 1;
+#endif /* !ZEPHYR_USES_KERBEROS */
#if 1
- zdbug((LOG_DEBUG, "bdump_offer"));
+ zdbug((LOG_DEBUG, "bdump_offer"));
#endif
-#ifdef KERBEROS
- /*
- * when using Kerberos server-server authentication, we can
- * use any random local address
- */
- if ((bdump_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- syslog(LOG_ERR,"bdump_offer: socket: %m");
- bdump_socket = -1;
- return;
- }
- (void) memset((caddr_t) &bdump_sin, 0, sizeof(bdump_sin));
- /* a port field of 0 makes the UNIX
- * kernel choose an appropriate port/address pair */
-
- bdump_sin.sin_port = 0;
- bdump_sin.sin_addr = my_addr;
- bdump_sin.sin_family = AF_INET;
- if ((retval = bind(bdump_socket, (struct sockaddr *) &bdump_sin, sizeof(bdump_sin))) < 0) {
- syslog(LOG_ERR, "bdump_offer: bind: %m");
- (void) close(bdump_socket);
- bdump_socket = -1;
- return;
- }
- if (!bdump_sin.sin_port) {
- int len = sizeof(bdump_sin);
- if (getsockname(bdump_socket,
- (struct sockaddr *)&bdump_sin, &len)) {
- syslog(LOG_ERR, "bdump_offer: getsockname: %m");
- (void) close(bdump_socket);
- bdump_socket = -1;
- return;
- }
- }
-#else /* !KERBEROS */
- /*
- * when not using Kerberos, we can't use any old port, we use
- * Internet reserved ports instead (rresvport)
- */
- if ((bdump_socket = rresvport(&bdump_port)) < 0) {
- syslog(LOG_ERR,"bdump_offer: socket: %m");
- bdump_socket = -1;
- return;
+#ifdef ZEPHYR_USES_KERBEROS
+ /*
+ * when using ZEPHYR_USES_KERBEROS server-server authentication, we can
+ * use any random local address
+ */
+ bdump_socket = socket(AF_INET, SOCK_STREAM, 0);
+ if (bdump_socket < 0) {
+ syslog(LOG_ERR,"bdump_offer: socket: %m");
+ bdump_socket = -1;
+ return;
+ }
+ memset(&bdump_sin, 0, sizeof(bdump_sin));
+ /* a port field of 0 makes the UNIX
+ * kernel choose an appropriate port/address pair */
+
+ bdump_sin.sin_port = 0;
+ bdump_sin.sin_addr = my_addr;
+ bdump_sin.sin_family = AF_INET;
+ retval = bind(bdump_socket, (struct sockaddr *) &bdump_sin,
+ sizeof(bdump_sin));
+ if (retval < 0) {
+ syslog(LOG_ERR, "bdump_offer: bind: %m");
+ close(bdump_socket);
+ bdump_socket = -1;
+ return;
+ }
+ if (!bdump_sin.sin_port) {
+ int len = sizeof(bdump_sin);
+
+ if (getsockname(bdump_socket,
+ (struct sockaddr *) &bdump_sin, &len) < 0) {
+ syslog(LOG_ERR, "bdump_offer: getsockname: %m");
+ close(bdump_socket);
+ bdump_socket = -1;
+ return;
}
- (void) memset((caddr_t) &bdump_sin, 0, sizeof(bdump_sin));
- bdump_sin.sin_port = htons((unsigned short)bdump_port);
- bdump_sin.sin_addr = my_addr;
- bdump_sin.sin_family = AF_INET;
-
-#endif /* KERBEROS */
- (void) listen(bdump_socket, 1);
-
- bdump_timer = timer_set_rel(20L, close_bdump, (void *) 0);
- FD_SET(bdump_socket, &interesting);
- nfildes = max(bdump_socket, srv_socket) + 1;
-
-
- addr = inet_ntoa(bdump_sin.sin_addr);
- (void) sprintf(buf, "%d", ntohs(bdump_sin.sin_port));
- lyst[0] = addr;
- lyst[1] = buf;
+ }
+#else /* !ZEPHYR_USES_KERBEROS */
+ /*
+ * when not using ZEPHYR_USES_KERBEROS, we can't use any old port, we use
+ * Internet reserved ports instead (rresvport)
+ */
+ bdump_socket = rresvport(&bdump_port);
+ if (bdump_socket < 0) {
+ syslog(LOG_ERR,"bdump_offer: socket: %m");
+ bdump_socket = -1;
+ return;
+ }
+ memset(&bdump_sin, 0, sizeof(bdump_sin));
+ bdump_sin.sin_port = htons((unsigned short) bdump_port);
+ bdump_sin.sin_addr = my_addr;
+ bdump_sin.sin_family = AF_INET;
+#endif /* ZEPHYR_USES_KERBEROS */
+
+ listen(bdump_socket, 1);
- if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "bdump_offer: ZSetDestAddr: %s",
- error_message(retval));
- return;
- }
+ bdump_timer = timer_set_rel(20L, close_bdump, NULL);
+ FD_SET(bdump_socket, &interesting);
+ nfds = max(bdump_socket, srv_socket) + 1;
+
+ addr = inet_ntoa(bdump_sin.sin_addr);
+ sprintf(buf, "%d", ntohs(bdump_sin.sin_port));
+ lyst[0] = addr;
+ lyst[1] = buf;
+
+ retval = ZSetDestAddr(who);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "bdump_offer: ZSetDestAddr: %s",
+ error_message(retval));
+ return;
+ }
- /* myname is the hostname */
- /* the class instance is the version number, here it is */
- /* bdump_version, which is set in main */
- (void) send_list(ACKED, sock_sin.sin_port, ZEPHYR_ADMIN_CLASS,
- bdump_version, ADMIN_BDUMP, myname, "", lyst, 2);
+ /* myname is the hostname */
+ /* the class instance is the version number, here it is */
+ /* bdump_version, which is set in main */
+ send_list(ACKED, srv_addr.sin_port, ZEPHYR_ADMIN_CLASS, bdump_version,
+ ADMIN_BDUMP, myname, "", lyst, 2);
#if 1
- zdbug((LOG_DEBUG,"bdump_offer: address is %s/%d\n",
- inet_ntoa(bdump_sin.sin_addr),
- ntohs(bdump_sin.sin_port)));
+ zdbug((LOG_DEBUG,"bdump_offer: address is %s/%d\n",
+ inet_ntoa(bdump_sin.sin_addr),
+ ntohs(bdump_sin.sin_port)));
#endif
- return;
+ return;
}
-
+
/*
* Accept a connection, and send the brain dump to the other server
*/
-
+
void
-#ifdef __STDC__
-bdump_send(void)
-#else
bdump_send()
-#endif
{
- struct sockaddr_in from;
- ZServerDesc_t *server;
- Code_t retval;
- int fromlen = sizeof(from);
- int on = 1;
-#ifdef POSIX
- struct sigaction action;
+ struct sockaddr_in from;
+ Server *server;
+ Code_t retval;
+ int fromlen = sizeof(from);
+ int on = 1;
+#ifdef _POSIX_VERSION
+ struct sigaction action;
#endif
-#ifdef KERBEROS
- KTEXT_ST ticket;
- AUTH_DAT kdata;
+#ifdef ZEPHYR_USES_KERBEROS
+ KTEXT_ST ticket;
+ AUTH_DAT kdata;
#else
- unsigned short fromport;
-#endif /* KERBEROS */
+ unsigned short fromport;
+#endif /* ZEPHYR_USES_KERBEROS */
#if 1
- zdbug((LOG_DEBUG, "bdump_send"));
+ zdbug((LOG_DEBUG, "bdump_send"));
#endif
- /* accept the connection, and send the brain dump */
- if ((live_socket = accept(bdump_socket, (struct sockaddr *)&from,
- &fromlen)) < 0) {
- syslog(LOG_ERR,"bdump_send: accept: %m");
- return;
- }
- if (setsockopt(live_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
- sizeof (on)) < 0)
- syslog(LOG_WARNING,
- "bdump_send: setsockopt (SO_KEEPALIVE): %m");
+ /* accept the connection, and send the brain dump */
+ live_socket = accept(bdump_socket, (struct sockaddr *) &from, &fromlen);
+ if (live_socket < 0) {
+ syslog(LOG_ERR,"bdump_send: accept: %m");
+ return;
+ }
+ if (setsockopt(live_socket, SOL_SOCKET, SO_KEEPALIVE, (char *) &on,
+ sizeof(on)) < 0)
+ syslog(LOG_WARNING, "bdump_send: setsockopt (SO_KEEPALIVE): %m");
-#ifndef KERBEROS
- fromport = ntohs(from.sin_port);
+#ifndef ZEPHYR_USES_KERBEROS
+ fromport = ntohs(from.sin_port);
#endif
-#ifdef POSIX
- (void) sigemptyset(&action.sa_mask);
- action.sa_flags = 0;
- action.sa_handler = SIG_IGN;
- (void) sigaction(SIGPIPE, &action, NULL);
+#ifdef _POSIX_VERSION
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
- START_CRITICAL_CODE;
#else
- (void) signal(SIGPIPE, SIG_IGN); /* so we can detect failures */
+ signal(SIGPIPE, SIG_IGN); /* so we can detect failures */
#endif
- from.sin_port = sock_sin.sin_port; /* we don't care what port
- it came from, and we need to
- fake out server_which_server() */
- server = server_which_server(&from);
- if (!server) {
- syslog(LOG_ERR, "bdump_send: unknown server?");
- server = limbo_server;
- }
+ from.sin_port = srv_addr.sin_port; /* we don't care what port
+ * it came from, and we need to
+ * fake out server_which_server() */
+ server = server_which_server(&from);
+ if (!server) {
+ syslog(LOG_ERR, "bdump_send: unknown server?");
+ server = limbo_server;
+ }
#if 1
- zdbug((LOG_DEBUG, "bdump_send: connection from %s/%d",
- inet_ntoa (from.sin_addr), ntohs (from.sin_port)));
+ zdbug((LOG_DEBUG, "bdump_send: connection from %s/%d",
+ inet_ntoa(from.sin_addr), ntohs(from.sin_port)));
#endif
-#ifdef notdef
- if (bdumping) {
- /* Already bdumping; punt one of the two. If this is a
- new host, punt this connection. If it's one we're
- already trying to talk to... arbitrary decision: The
- connection with the listener at the lower IP address
- will be punted. */
- if (!server->zs_dumping) {
- zdbug ((LOG_INFO,
-"bdump_send: already dumping; breaking new bdump connection from %s",
- inet_ntoa (from.sin_addr)));
- (void) close (live_socket);
- return;
- }
- /* Should be safe now to get rid of listener socket. */
- (void) close (bdump_socket);
- FD_CLR (bdump_socket, &interesting);
- bdump_socket = -1;
- timer_reset(bdump_timer);
- if (ntohl (bdump_sin.sin_addr.s_addr) < ntohl (from.sin_addr.s_addr)) {
- /* My address is lower; punt incoming connection. */
- (void) close (live_socket);
- return;
- }
- else
- cancel_outgoing_dump = 1;
- }
-#endif
+ bdumping = 1;
+ server->dumping = 1;
- bdumping = 1;
- server->zs_dumping = 1;
-
- if (bdump_socket >= 0) {
- /* shut down the listening socket and the timer */
- FD_CLR(bdump_socket, &interesting);
- (void) close(bdump_socket);
- nfildes = srv_socket + 1;
- bdump_socket = -1;
- timer_reset(bdump_timer);
- }
+ if (bdump_socket >= 0) {
+ /* shut down the listening socket and the timer. */
+ FD_CLR(bdump_socket, &interesting);
+ close(bdump_socket);
+ nfds = srv_socket + 1;
+ bdump_socket = -1;
+ timer_reset(bdump_timer);
+ }
- /* Now begin the brain dump. */
+ /* Now begin the brain dump. */
-#ifdef KERBEROS
- /* receive the authenticator */
- if ((retval = GetKerberosData(live_socket, from.sin_addr, &kdata,
- SERVER_SERVICE, ZEPHYR_SRVTAB))
- != KSUCCESS)
- {
- syslog(LOG_ERR, "bdump_send: getkdata: %s",
- krb_err_txt[retval]);
- cleanup(server);
- return;
- }
- if (get_tgt()) {
- cleanup(server);
- return;
- }
- if (strcmp(kdata.pname,SERVER_SERVICE) ||
- strcmp(kdata.pinst, SERVER_INSTANCE) ||
- strcmp(kdata.prealm, my_realm))
- {
- syslog(LOG_ERR, "bdump_send: peer not zephyr: %s.%s@%s",
- kdata.pname, kdata.pinst, kdata.prealm);
- cleanup(server);
- return;
- }
- /* authenticate back */
- if ((retval = SendKerberosData(live_socket, &ticket,
- SERVER_SERVICE, SERVER_INSTANCE)) != 0)
- {
- syslog(LOG_ERR,"bdump_send: SendKerberosData: %s",
- error_message (retval));
- cleanup(server);
- return;
- }
-#else /* !KERBEROS */
- if ((fromport > IPPORT_RESERVED) ||
- (fromport < (IPPORT_RESERVED / 2))) {
- syslog(LOG_ERR, "bdump_send: bad port from peer: %d",
- fromport);
- cleanup(server);
- return;
- }
-#endif /* KERBEROS */
+#ifdef ZEPHYR_USES_KERBEROS
+ /* receive the authenticator */
+ retval = GetKerberosData(live_socket, from.sin_addr, &kdata,
+ SERVER_SERVICE, srvtab_file);
+ if (retval != KSUCCESS) {
+ syslog(LOG_ERR, "bdump_send: getkdata: %s",
+ krb_get_err_text(retval));
+ cleanup(server);
+ return;
+ }
+ if (get_tgt()) {
+ cleanup(server);
+ return;
+ }
+ if (strcmp(kdata.pname, SERVER_SERVICE) ||
+ strcmp(kdata.pinst, SERVER_INSTANCE) ||
+ strcmp(kdata.prealm, ZGetRealm())) {
+ syslog(LOG_ERR, "bdump_send: peer not zephyr: %s.%s@%s",
+ kdata.pname, kdata.pinst, kdata.prealm);
+ cleanup(server);
+ return;
+ }
+ /* authenticate back */
+ retval = SendKerberosData(live_socket, &ticket, SERVER_SERVICE,
+ SERVER_INSTANCE);
+ if (retval != 0) {
+ syslog(LOG_ERR,"bdump_send: SendKerberosData: %s",
+ error_message (retval));
+ cleanup(server);
+ return;
+ }
+#else /* !ZEPHYR_USES_KERBEROS */
+ if (fromport > IPPORT_RESERVED || fromport < IPPORT_RESERVED / 2) {
+ syslog(LOG_ERR, "bdump_send: bad port from peer: %d", fromport);
+ cleanup(server);
+ return;
+ }
+#endif /* ZEPHYR_USES_KERBEROS */
- if ((retval = setup_file_pointers()) != 0) {
- syslog (LOG_WARNING, "bdump_send: can't set up file pointers: %s",
- error_message (retval));
- cleanup(server);
- return;
- }
- if ((retval = sbd_loop(&from)) != ZERR_NONE) {
- syslog(LOG_WARNING, "bdump_send: sbd_loop failed: %s",
- error_message(retval));
- cleanup(server);
- return;
- }
- if ((retval = gbd_loop(server)) != ZERR_NONE) {
- syslog(LOG_WARNING, "bdump_send: gbd_loop failed: %s",
- error_message(retval));
- cleanup(server);
- return;
- }
+ retval = setup_file_pointers();
+ if (retval != 0) {
+ syslog (LOG_WARNING, "bdump_send: can't set up file pointers: %s",
+ error_message(retval));
+ cleanup(server);
+ return;
+ }
+ retval = bdump_send_loop(server);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "bdump_send: bdump_send_loop failed: %s",
+ error_message(retval));
+ cleanup(server);
+ return;
+ }
+ retval = bdump_recv_loop(server);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "bdump_send: bdump_recv_loop failed: %s",
+ error_message(retval));
+ cleanup(server);
+ return;
+ }
#if 1
- zdbug((LOG_DEBUG, "bdump_send: finished"));
+ zdbug((LOG_DEBUG, "bdump_send: finished"));
#endif
- if (server != limbo_server) {
- /* set this guy to be up, and schedule a hello */
- server->zs_state = SERV_UP;
- timer_reset(server->zs_timer);
- server->zs_timer = timer_set_rel(0L, server_timo, (void *) server);
- }
+ if (server != limbo_server) {
+ /* set this guy to be up, and schedule a hello */
+ server->state = SERV_UP;
+ timer_reset(server->timer);
+ server->timer = timer_set_rel(0L, server_timo, server);
+ }
#if 0
- zdbug((LOG_DEBUG,"cleanup sbd"));
+ zdbug((LOG_DEBUG,"cleanup sbd"));
#endif
- shutdown_file_pointers ();
+ shutdown_file_pointers();
-#ifdef POSIX
- action.sa_handler = SIG_DFL;
- sigaction(SIGPIPE, &action, NULL);
+#ifdef _POSIX_VERSION
+ action.sa_handler = SIG_DFL;
+ sigaction(SIGPIPE, &action, NULL);
#else
- (void) signal(SIGPIPE, SIG_DFL);
-#endif
- bdump_inited = 1;
- bdumping = 0;
- server->zs_dumping = 0;
-#ifdef CONCURRENT
- /* Now that we are finished dumping, send all the queued packets */
- server_send_queue(server);
+ signal(SIGPIPE, SIG_DFL);
#endif
- END_CRITICAL_CODE;
- return;
+ bdumping = 0;
+ server->dumping = 0;
+ /* Now that we are finished dumping, send all the queued packets */
+ server_send_queue(server);
+ return;
}
/*ARGSUSED*/
static void
-bdump_get_v1_guts (notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
+bdump_get_v12 (notice, auth, who, server)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
{
- struct sockaddr_in from;
- Code_t retval;
- int on = 1;
-#ifdef POSIX
- struct sigaction action;
+ struct sockaddr_in from;
+ Code_t retval;
+ int on = 1;
+#ifdef _POSIX_VERSION
+ struct sigaction action;
#endif
-#ifdef KERBEROS
- KTEXT_ST ticket;
- AUTH_DAT kdata;
-#else /* !KERBEROS */
- int reserved_port = IPPORT_RESERVED - 1;
-#endif /* KERBEROS */
+#ifdef ZEPHYR_USES_KERBEROS
+ KTEXT_ST ticket;
+ AUTH_DAT kdata;
+#else /* !ZEPHYR_USES_KERBEROS */
+ int reserved_port = IPPORT_RESERVED - 1;
+#endif /* ZEPHYR_USES_KERBEROS */
- bdumping = 1;
- server->zs_dumping = 1;
+ bdumping = 1;
+ server->dumping = 1;
-#ifdef POSIX
- action.sa_flags = 0;
- sigemptyset(&action.sa_mask);
- action.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &action, NULL);
+#ifdef _POSIX_VERSION
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
#else
- (void) signal(SIGPIPE, SIG_IGN); /* so we can detect problems */
-#endif /* POSIX */
+ signal(SIGPIPE, SIG_IGN); /* so we can detect problems */
+#endif /* _POSIX_VRESION */
- if (bdump_socket >= 0) {
- /* We cannot go get a brain dump when someone may
- potentially be connecting to us (if that other
- server is the server to whom we are connecting,
- we will deadlock. so we shut down the listening
- socket and the timer */
- FD_CLR(bdump_socket, &interesting);
- (void) close(bdump_socket);
- nfildes = srv_socket+1;
- bdump_socket = -1;
- timer_reset(bdump_timer);
- }
+ if (bdump_socket >= 0) {
+ /* We cannot go get a brain dump when someone may
+ potentially be connecting to us (if that other
+ server is the server to whom we are connecting,
+ we will deadlock. so we shut down the listening
+ socket and the timer. */
+ FD_CLR(bdump_socket, &interesting);
+ close(bdump_socket);
+ nfds = srv_socket+1;
+ bdump_socket = -1;
+ timer_reset(bdump_timer);
+ }
- if ((retval = extract_sin(notice, &from)) != ZERR_NONE) {
- syslog(LOG_ERR, "bdump_get: sin: %s", error_message(retval));
-#ifdef POSIX
- action.sa_handler = SIG_DFL;
- sigaction(SIGPIPE, &action, NULL);
+ retval = extract_sin(notice, &from);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "bdump_get: sin: %s", error_message(retval));
+#ifdef _POSIX_VERSION
+ action.sa_handler = SIG_DFL;
+ sigaction(SIGPIPE, &action, NULL);
#else
- (void) signal(SIGPIPE, SIG_DFL);
+ signal(SIGPIPE, SIG_DFL);
#endif
- bdumping = 0;
- server->zs_dumping = 0;
- return;
- }
- START_CRITICAL_CODE;
-#ifndef KERBEROS
- if (ntohs(from.sin_port) > IPPORT_RESERVED ||
- ntohs(from.sin_port) < IPPORT_RESERVED / 2) {
- syslog(LOG_ERR, "bdump_get: port not reserved: %d",
- ntohs(from.sin_port));
- cleanup(server);
- return;
- }
- live_socket = rresvport(&reserved_port);
-#else /* !KERBEROS */
- live_socket = socket(AF_INET, SOCK_STREAM, 0);
-#endif /* KERBEROS */
- if (live_socket < 0) {
- syslog(LOG_ERR, "bdump_get: socket: %m");
- cleanup(server);
- return;
- }
- if (connect(live_socket, (struct sockaddr *) &from, sizeof(from))) {
- syslog(LOG_ERR, "bdump_get: connect: %m");
- cleanup(server);
- return;
- }
- if (setsockopt(live_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
- sizeof (on)) < 0)
- syslog(LOG_WARNING,
- "bdump_get: setsockopt (SO_KEEPALIVE): %m");
+ bdumping = 0;
+ server->dumping = 0;
+ return;
+ }
+#ifndef ZEPHYR_USES_KERBEROS
+ if (ntohs(from.sin_port) > IPPORT_RESERVED ||
+ ntohs(from.sin_port) < IPPORT_RESERVED / 2) {
+ syslog(LOG_ERR, "bdump_get: port not reserved: %d",
+ ntohs(from.sin_port));
+ cleanup(server);
+ return;
+ }
+ live_socket = rresvport(&reserved_port);
+#else /* !ZEPHYR_USES_KERBEROS */
+ live_socket = socket(AF_INET, SOCK_STREAM, 0);
+#endif /* ZEPHYR_USES_KERBEROS */
+ if (live_socket < 0) {
+ syslog(LOG_ERR, "bdump_get: socket: %m");
+ cleanup(server);
+ return;
+ }
+ if (connect(live_socket, (struct sockaddr *) &from, sizeof(from))) {
+ syslog(LOG_ERR, "bdump_get: connect: %m");
+ cleanup(server);
+ return;
+ }
+ if (setsockopt(live_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
+ sizeof(on)) < 0)
+ syslog(LOG_WARNING, "bdump_get: setsockopt (SO_KEEPALIVE): %m");
#if 1
- zdbug((LOG_DEBUG, "bdump_get: connected"));
+ zdbug((LOG_DEBUG, "bdump_get: connected"));
#endif
- /* Now begin the brain dump. */
+ /* Now begin the brain dump. */
-#ifdef KERBEROS
- /* send an authenticator */
- if (get_tgt()) {
- cleanup(server);
- return;
- }
- if ((retval = SendKerberosData(live_socket, &ticket,
- SERVER_SERVICE, SERVER_INSTANCE)) != 0)
- {
- syslog(LOG_ERR,"bdump_get: %s",
- error_message (retval));
- cleanup(server);
- return;
- }
+#ifdef ZEPHYR_USES_KERBEROS
+ /* send an authenticator */
+ if (get_tgt()) {
+ cleanup(server);
+ return;
+ }
+ retval = SendKerberosData(live_socket, &ticket, SERVER_SERVICE,
+ SERVER_INSTANCE);
+ if (retval != 0) {
+ syslog(LOG_ERR,"bdump_get: %s", error_message(retval));
+ cleanup(server);
+ return;
+ }
#if 1
- zdbug((LOG_DEBUG, "bdump_get: SendKerberosData ok"));
+ zdbug((LOG_DEBUG, "bdump_get: SendKerberosData ok"));
#endif
- /* get his authenticator */
- if ((retval = GetKerberosData(live_socket, from.sin_addr, &kdata,
- SERVER_SERVICE, ZEPHYR_SRVTAB))
- != KSUCCESS)
- {
- syslog(LOG_ERR, "bdump_get getkdata: %s",krb_err_txt[retval]);
- cleanup(server);
- return;
- }
- /* my_realm is filled in inside get_tgt() */
- if (strcmp(kdata.pname, SERVER_SERVICE) ||
- strcmp(kdata.pinst, SERVER_INSTANCE) ||
- strcmp(kdata.prealm, my_realm))
- {
- syslog(LOG_ERR,
- "bdump_get: peer not zephyr in lrealm: %s.%s@%s",
- kdata.pname, kdata.pinst,kdata.prealm);
- cleanup(server);
- return;
- }
-#endif /* KERBEROS */
- if ((retval = setup_file_pointers()) != 0) {
- syslog (LOG_WARNING, "bdump_get: can't set up file pointers: %s",
- error_message (retval));
- cleanup(server);
- return;
- }
- if ((retval = gbd_loop(server)) != ZERR_NONE) {
- syslog(LOG_WARNING, "bdump_get: gbd_loop failed: %s",
- error_message(retval));
- cleanup(server);
- return;
- }
+ /* get his authenticator */
+ retval = GetKerberosData(live_socket, from.sin_addr, &kdata,
+ SERVER_SERVICE, srvtab_file);
+ if (retval != KSUCCESS) {
+ syslog(LOG_ERR, "bdump_get getkdata: %s",krb_get_err_text(retval));
+ cleanup(server);
+ return;
+ }
+ /* my_realm is filled in inside get_tgt() */
+ if (strcmp(kdata.pname, SERVER_SERVICE) ||
+ strcmp(kdata.pinst, SERVER_INSTANCE) ||
+ strcmp(kdata.prealm, my_realm)) {
+ syslog(LOG_ERR, "bdump_get: peer not zephyr in lrealm: %s.%s@%s",
+ kdata.pname, kdata.pinst,kdata.prealm);
+ cleanup(server);
+ return;
+ }
+#endif /* ZEPHYR_USES_KERBEROS */
+ retval = setup_file_pointers();
+ if (retval != 0) {
+ syslog(LOG_WARNING, "bdump_get: can't set up file pointers: %s",
+ error_message (retval));
+ cleanup(server);
+ return;
+ }
+ retval = bdump_recv_loop(server);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "bdump_get: bdump_recv_loop failed: %s",
+ error_message(retval));
+ cleanup(server);
+ return;
+ }
#if 1
- zdbug((LOG_DEBUG,"bdump_get: gbdl ok"));
+ zdbug((LOG_DEBUG,"bdump_get: gbdl ok"));
#endif
- if ((retval = sbd_loop(&from)) != ZERR_NONE) {
- syslog(LOG_WARNING, "sbd_loop failed: %s",
- error_message(retval));
- cleanup(server);
- return;
- }
+ retval = bdump_send_loop(server);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "bdump_send_loop failed: %s",
+ error_message(retval));
+ cleanup(server);
+ return;
+ }
#if 1
- zdbug((LOG_DEBUG, "bdump_get: gbd finished"));
+ zdbug((LOG_DEBUG, "bdump_get: gbd finished"));
#endif
- /* set this guy to be up, and schedule a hello */
- server->zs_state = SERV_UP;
- timer_reset(server->zs_timer);
- server->zs_timer = timer_set_rel(0L, server_timo, (void *) server);
+ /* set this guy to be up, and schedule a hello */
+ server->state = SERV_UP;
+ timer_reset(server->timer);
+ server->timer = timer_set_rel(0L, server_timo, server);
#if 1
- zdbug((LOG_DEBUG,"cleanup gbd"));
-#endif
- shutdown_file_pointers ();
-#ifdef POSIX
- action.sa_handler = SIG_DFL;
- sigaction(SIGPIPE, &action, NULL);
-#else
- (void) signal(SIGPIPE, SIG_DFL);
+ zdbug((LOG_DEBUG,"cleanup gbd"));
#endif
- bdump_inited = 1;
- bdumping = 0;
- server->zs_dumping = 0;
-#ifdef CONCURRENT
- /* Now that we are finished dumping, send all the queued packets */
- server_send_queue(server);
-#endif
-
- END_CRITICAL_CODE;
- return;
-}
-
-static void
-#ifdef __STDC__
-bdump_get_v1(ZNotice_t *notice, int auth, struct sockaddr_in *who,
- ZServerDesc_t *server)
+ shutdown_file_pointers();
+#ifdef _POSIX_VERSION
+ action.sa_handler = SIG_DFL;
+ sigaction(SIGPIPE, &action, NULL);
#else
-bdump_get_v1(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
+ signal(SIGPIPE, SIG_DFL);
#endif
-{
- if (bdump_socket >= 0) {
- /* We cannot go get a brain dump when someone may
- potentially be connecting to us (if that other
- server is the server to whom we are connecting,
- we will deadlock. so we shut down the listening
- socket and the timer */
- FD_CLR(bdump_socket, &interesting);
- (void) close(bdump_socket);
- nfildes = srv_socket + 1;
- bdump_socket = -1;
- timer_reset(bdump_timer);
- }
-
- bdump_get_v1_guts (notice, auth, who, server);
-}
+ bdumping = 0;
+ server->dumping = 0;
+ /* Now that we are finished dumping, send all the queued packets */
+ server_send_queue(server);
-static void
-#ifdef __STDC__
-bdump_get_v1a( ZNotice_t *notice, int auth, struct sockaddr_in *who,
- ZServerDesc_t *server)
-#else
-bdump_get_v1a(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
-#endif
-{
- /* In version 1A, leave the listening file descriptor open; if we
- get a connection while we're dumping, one of the two will be
- punted. */
- bdump_get_v1_guts (notice, auth, who, server);
+ return;
}
void
bdump_get(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
{
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
+ void (*proc) __P((ZNotice_t *, int, struct sockaddr_in *, Server *));
- void (*proc) P((ZNotice_t *, int, struct sockaddr_in *, ZServerDesc_t *));
-
-#undef P
- proc = NULL;
+ proc = NULL;
#if 1
- if (zdebug)
- syslog(LOG_DEBUG, "bdump_get: bdump v%s avail %s",
- notice->z_class_inst, inet_ntoa(who->sin_addr));
+ if (zdebug) {
+ syslog(LOG_DEBUG, "bdump_get: bdump v%s avail %s",
+ notice->z_class_inst, inet_ntoa(who->sin_addr));
+ }
#endif
- /*
- * We do not listen to version "1" or "1A" because they are a
- * security threat (they send the CBlock in clear-text).
- */
- if (!strcmp (notice->z_class_inst, "1.1")
- || !strcmp (notice->z_class_inst, ""))
- proc = bdump_get_v1;
- if (!strcmp (notice->z_class_inst, "1.1A"))
- proc = bdump_get_v1a;
-
- if (proc)
- (*proc) (notice, auth, who, server);
- else
- syslog(LOG_WARNING,
- "bdump_get: Incompatible bdump version '%s' from %s",
- notice->z_class_inst,
- inet_ntoa(who->sin_addr));
+ if (strcmp (notice->z_class_inst, "1.2") == 0)
+ proc = bdump_get_v12;
+
+ if (proc) {
+ (*proc)(notice, auth, who, server);
+ } else {
+ syslog(LOG_WARNING,
+ "bdump_get: Incompatible bdump version '%s' from %s",
+ notice->z_class_inst,
+ inet_ntoa(who->sin_addr));
+ }
}
/*
* Send a list off as the specified notice
*/
-
-int
-bdump_send_list_tcp(kind, port, class_name, inst, opcode, sender, recip,
- lyst, num)
- ZNotice_Kind_t kind;
- int port;
- char *class_name;
- char *inst;
- char *opcode;
- char *sender;
- char *recip;
- char **lyst;
- int num;
+
+Code_t
+bdump_send_list_tcp(kind, addr, class_name, inst, opcode, sender, recip, lyst,
+ num)
+ ZNotice_Kind_t kind;
+ struct sockaddr_in *addr;
+ int num;
+ char *class_name, *inst, *opcode, *sender, *recip, **lyst;
{
- ZNotice_t notice;
- register ZNotice_t *pnotice = &notice; /* speed hack */
- char *pack;
- int packlen, count;
- Code_t retval;
- u_short length;
-
- pnotice->z_kind = kind;
-
- pnotice->z_port = port;
- pnotice->z_class = class_name;
- pnotice->z_class_inst = inst;
- pnotice->z_opcode = opcode;
- pnotice->z_sender = sender;
- pnotice->z_recipient = recip;
- pnotice->z_default_format = "";
- pnotice->z_num_other_fields = 0;
-
- if ((retval = ZFormatNoticeList(pnotice, (char **) lyst, num, &pack, &packlen, ZNOAUTH)) != ZERR_NONE)
- return(retval);
+ ZNotice_t notice;
+ char *pack, addrbuf[100];
+ int packlen, count;
+ Code_t retval;
+ u_short length;
+
+ retval = ZMakeAscii(addrbuf, sizeof(addrbuf),
+ (unsigned char *) &addr->sin_addr,
+ sizeof(struct in_addr));
+ if (retval != ZERR_NONE)
+ return retval;
+ notice.z_kind = kind;
+
+ notice.z_port = addr->sin_port;
+ notice.z_class = class_name;
+ notice.z_class_inst = inst;
+ notice.z_opcode = opcode;
+ notice.z_sender = sender;
+ notice.z_recipient = recip;
+ notice.z_default_format = "";
+ notice.z_num_other_fields = 1;
+ notice.z_other_fields[0] = addrbuf;
+
+ retval = ZFormatNoticeList(&notice, lyst, num, &pack, &packlen, ZNOAUTH);
+ if (retval != ZERR_NONE)
+ return retval;
- length = htons((u_short) packlen);
+ length = htons((u_short) packlen);
- if ((count = net_write(output, (caddr_t) &length, sizeof(length))) != sizeof(length))
- if (count < 0) {
- xfree(pack); /* free allocated storage */
- return(errno);
- } else {
- syslog(LOG_WARNING, "slt (length) xmit: %d vs %d",
- sizeof(length),count);
- xfree(pack); /* free allocated storage */
- return(ZSRV_PKSHORT);
- }
+ count = net_write(output, (char *) &length, sizeof(length));
+ if (count != sizeof(length)) {
+ if (count < 0) {
+ free(pack);
+ return(errno);
+ } else {
+ syslog(LOG_WARNING, "slt (length) xmit: %d vs %d",
+ sizeof(length), count);
+ free(pack);
+ return(ZSRV_PKSHORT);
+ }
+ }
- if ((count = net_write(output, pack, packlen)) != packlen)
- if (count < 0) {
- xfree(pack); /* free allocated storage */
- return(errno);
- } else {
- syslog(LOG_WARNING, "slt (packet) xmit: %d vs %d",
- packlen, count);
- xfree(pack); /* free allocated storage */
- return(ZSRV_PKSHORT);
- }
- xfree(pack); /* free allocated storage */
- return(ZERR_NONE);
+ count = net_write(output, pack, packlen);
+ if (count != packlen) {
+ if (count < 0) {
+ free(pack);
+ return(errno);
+ } else {
+ syslog(LOG_WARNING, "slt (packet) xmit: %d vs %d",
+ packlen, count);
+ free(pack);
+ return(ZSRV_PKSHORT);
+ }
+ }
+ free(pack);
+ return(ZERR_NONE);
}
-
+
static void
-shutdown_file_pointers () {
+shutdown_file_pointers() {
if (input) {
- (void) fclose (input);
+ fclose(input);
input = 0;
}
if (output) {
- (void) fclose (output);
+ fclose(output);
output = 0;
}
if (live_socket >= 0) {
- (void) close (live_socket);
+ close(live_socket);
live_socket = -1;
}
}
static void
cleanup(server)
- ZServerDesc_t *server;
+ Server *server;
{
-#ifdef POSIX
+#ifdef _POSIX_VERSION
struct sigaction action;
#endif
@@ -784,226 +664,86 @@ cleanup(server)
zdbug((LOG_DEBUG, "bdump cleanup"));
#endif
if (server != limbo_server) {
- server->zs_state = SERV_DEAD;
- timer_reset(server->zs_timer);
- server->zs_timer =
- timer_set_rel(0L, server_timo, (void *) server);
+ server->state = SERV_DEAD;
+ timer_reset(server->timer);
+ server->timer = timer_set_rel(0L, server_timo, server);
}
shutdown_file_pointers ();
-#ifdef POSIX
+#ifdef _POSIX_VERSION
action.sa_flags = 0;
sigemptyset(&action.sa_mask);
action.sa_handler = SIG_DFL;
sigaction(SIGPIPE,&action, NULL);
#else
- (void) signal(SIGPIPE, SIG_DFL);
-#endif /* POSIX */
+ signal(SIGPIPE, SIG_DFL);
+#endif /* _POSIX_VERSION */
bdumping = 0;
- server->zs_dumping = 0;
-#ifdef CONCURRENT
- /* XXX need to flush the server and the updates to it */
-#endif
- END_CRITICAL_CODE;
- return;
+ server->dumping = 0;
}
-
-#ifdef KERBEROS
-static int
+
+#ifdef ZEPHYR_USES_KERBEROS
+int
get_tgt()
{
- int retval;
+ /* MIT Kerberos 4 get_svc_in_tkt() requires instance to be writable and
+ * at least INST_SZ bytes long. */
+ static char buf[INST_SZ + 1] = SERVER_INSTANCE;
+ int retval = 0;
+ CREDENTIALS cred;
#ifndef NOENCRYPTION
- Sched *s;
+ Sched *s;
#endif
- if (!*my_realm)
- if ((retval = krb_get_lrealm(my_realm, 1)) != KSUCCESS) {
- syslog(LOG_ERR,"krb_get_lrealm: %s",
- krb_err_txt[retval]);
- *my_realm = '\0';
- return(1);
- }
- /* have they expired ? */
- if (ticket_time < NOW - tkt_lifetime(TKTLIFETIME) + 15L) {
- /* +15 for leeway */
+ if (!*my_realm) {
+ retval = krb_get_lrealm(my_realm, 1);
+ if (retval != KSUCCESS) {
+ syslog(LOG_ERR,"krb_get_lrealm: %s", krb_get_err_text(retval));
+ *my_realm = '\0';
+ return(1);
+ }
+ }
+ /* have they expired ? */
+ if (ticket_time < NOW - tkt_lifetime(TKTLIFETIME) + 15L) {
+ /* +15 for leeway */
#if 0
- zdbug((LOG_DEBUG,"get new tickets: %d %d %d",
- ticket_time, NOW,
- NOW - tkt_lifetime(TKTLIFETIME) + 15L));
+ zdbug((LOG_DEBUG,"get new tickets: %d %d %d", ticket_time, NOW,
+ NOW - tkt_lifetime(TKTLIFETIME) + 15L));
#endif
- (void) dest_tkt();
-
- {
- /*
- * XXX One version of krb_get_svc_in_tkt wants
- * this argument writable and at least INST_SZ
- * bytes long.
- */
- static char buf[INST_SZ+1] = SERVER_INSTANCE;
-
- retval = krb_get_svc_in_tkt (SERVER_SERVICE, buf/*XXX*/,
- my_realm,
- SERVER_SERVICE, SERVER_INSTANCE,
- TKTLIFETIME, ZEPHYR_SRVTAB);
- }
- if (retval != KSUCCESS) {
- syslog(LOG_ERR,"get_tgt: krb_get_svc_in_tkt: %s",
- krb_err_txt[retval]);
- ticket_time = 0L;
- return(1);
- } else
- ticket_time = NOW;
+ dest_tkt();
-#ifndef NOENCRYPTION
- retval = read_service_key(SERVER_SERVICE, SERVER_INSTANCE,
- my_realm, 0 /*kvno*/,
- ZEPHYR_SRVTAB, serv_key);
- if (retval != KSUCCESS) {
- syslog(LOG_ERR, "get_tgt: read_service_key: %s",
- krb_err_txt[retval]);
- return 1;
- }
- s = (Sched *)check_key_sched_cache(serv_key);
- if (s) {
- serv_ksched = *s;
- } else {
- des_key_sched(serv_key, serv_ksched.s);
- add_to_key_sched_cache(serv_key, &serv_ksched);
- }
-#endif /* !NOENCRYPTION */
- }
- return(0);
-}
-#endif /* KERBEROS */
-
-static Code_t
-sbd_loop(from)
- struct sockaddr_in *from;
-{
- ZNotice_t bd_notice;
- ZPacket_t pack;
- ZServerDesc_t *server;
- int packlen = sizeof(pack);
- Code_t retval;
- struct sockaddr_in bogus_from;
- char *zeph_version = NULL;
-
- bogus_from = *from;
- bogus_from.sin_port = sock_sin.sin_port;
-
- while (1) {
- packlen = sizeof(pack);
- if ((retval = get_packet(pack, packlen, &packlen)) != ZERR_NONE) {
- syslog(LOG_ERR, "sbd_loop: notice get: %s",
- error_message(retval));
- return(retval);
- }
- if ((retval = ZParseNotice(pack, packlen, &bd_notice)) != ZERR_NONE) {
- syslog(LOG_ERR, "sbd notice parse: %s",
- error_message(retval));
- return(retval);
- }
- if (!zeph_version) {
- zeph_version = strsave(bd_notice.z_version);
- }
-#ifdef DEBUG
- if (zdebug) {
- char buf[4096];
-
- (void) sprintf(buf,
- "bdump:%s '%s' '%s' '%s' '%s' '%s'",
- ZNoticeKinds[(int) bd_notice.z_kind],
- bd_notice.z_class,
- bd_notice.z_class_inst,
- bd_notice.z_opcode,
- bd_notice.z_sender,
- bd_notice.z_recipient);
- syslog(LOG_DEBUG, buf);
- }
-#endif /* DEBUG */
- if (!strcmp(bd_notice.z_class_inst, ADMIN_LIMBO)) {
- /* he wants limbo */
-#if 1
- zdbug((LOG_DEBUG, "limbo req"));
-#endif
- if ((retval = bdump_send_loop(limbo_server,
- zeph_version))
- != ZERR_NONE)
- return(retval);
- continue;
- } else if (!strcmp(bd_notice.z_class_inst, ADMIN_ME)) {
- /* he wants his state */
-#if 1
- zdbug((LOG_DEBUG, "his state req"));
-#endif
- if ((server = server_which_server(&bogus_from)) !=
- NULLZSDT) {
- if ((retval = bdump_send_loop(server,
- zeph_version))
- != ZERR_NONE)
- return(retval);
- } else {
- syslog(LOG_ERR,"sbd_loop: no state");
- if ((retval = send_done()) != ZERR_NONE)
- return(retval);
- }
- continue;
- } else if (!strcmp(bd_notice.z_class_inst, ADMIN_YOU)) {
- /* he wants my state */
-#if 1
- zdbug((LOG_DEBUG, "my state req"));
-#endif
- if ((retval = bdump_send_loop(me_server, zeph_version))
- != ZERR_NONE)
- return(retval);
- break;
- } else if (!strcmp(bd_notice.z_class_inst, ADMIN_DONE)) {
- break;
- } else {
- /* what does he want? */
-#if 1
- zdbug((LOG_DEBUG, "unknown req"));
-#endif
- break;
- }
- }
- if (zeph_version)
- xfree(zeph_version);
- return(ZERR_NONE);
-}
-
-static Code_t
-gbd_loop(server)
- ZServerDesc_t *server;
-{
- Code_t retval;
-
- /*
- * if we have no hosts in the 'limbo' state (on the limbo server),
- * ask for the other server to send us the limbo state.
- * Thus we keep track of all the hosts which haven't spoken in a while,
- * even in the face of server failure.
- */
- if (otherservers[limbo_server_idx()].zs_hosts->q_forw ==
- otherservers[limbo_server_idx()].zs_hosts) {
- if ((retval = bdump_ask_for(ADMIN_LIMBO)) != ZERR_NONE)
- return(retval);
- if ((retval = bdump_recv_loop(&otherservers[limbo_server_idx()])) != ZERR_NONE)
- return(retval);
+ retval = krb_get_svc_in_tkt(SERVER_SERVICE, buf, ZGetRealm(),
+ "krbtgt", ZGetRealm(),
+ TKTLIFETIME, srvtab_file);
+ if (retval != KSUCCESS) {
+ syslog(LOG_ERR,"get_tgt: krb_get_svc_in_tkt: %s",
+ krb_get_err_text(retval));
+ ticket_time = 0;
+ return(1);
+ } else {
+ ticket_time = NOW;
}
- /* Have I been given my own startup info yet? */
- if (!bdump_inited) {
- if ((retval = bdump_ask_for(ADMIN_ME)) != ZERR_NONE)
- return(retval);
- if ((retval = bdump_recv_loop(me_server)) != ZERR_NONE)
- return(retval);
+#ifndef NOENCRYPTION
+ retval = read_service_key(SERVER_SERVICE, SERVER_INSTANCE,
+ ZGetRealm(), 0 /*kvno*/,
+ srvtab_file, serv_key);
+ if (retval != KSUCCESS) {
+ syslog(LOG_ERR, "get_tgt: read_service_key: %s",
+ krb_get_err_text(retval));
+ return 1;
+ }
+ s = (Sched *) check_key_sched_cache(serv_key);
+ if (s) {
+ serv_ksched = *s;
+ } else {
+ des_key_sched(serv_key, serv_ksched.s);
+ add_to_key_sched_cache(serv_key, &serv_ksched);
}
- if ((retval = bdump_ask_for(ADMIN_YOU)) != ZERR_NONE)
- return(retval);
- retval = bdump_recv_loop(server);
- return(retval);
+#endif /* !NOENCRYPTION */
+ }
+ return(0);
}
+#endif /* ZEPHYR_USES_KERBEROS */
/*
* The braindump offer wasn't taken, so we retract it.
@@ -1012,40 +752,22 @@ gbd_loop(server)
/*ARGSUSED*/
static void
close_bdump(arg)
- void * arg;
+ void * arg;
{
- if (bdump_socket >= 0) {
- FD_CLR(bdump_socket, &interesting);
- (void) close(bdump_socket);
- nfildes = srv_socket + 1;
- bdump_socket = -1;
+ if (bdump_socket >= 0) {
+ FD_CLR(bdump_socket, &interesting);
+ close(bdump_socket);
+ nfds = srv_socket + 1;
+ bdump_socket = -1;
#if 1
- zdbug((LOG_DEBUG, "bdump not used"));
+ zdbug((LOG_DEBUG, "bdump not used"));
#endif
- } else {
+ } else {
#if 1
- zdbug((LOG_DEBUG, "bdump not open"));
+ zdbug((LOG_DEBUG, "bdump not open"));
#endif
- }
- return;
-}
-
-/*
- * Ask the other server to send instruction packets for class instance
- * inst
- */
-
-static Code_t
-bdump_ask_for(inst)
- char *inst;
-{
- Code_t retval;
-
- /* myname is the hostname */
- retval = send_normal_tcp(ACKED, bdump_sin.sin_port, ZEPHYR_ADMIN_CLASS,
- inst, ADMIN_BDUMP, myname, "",
- (char *) NULL, 0);
- return(retval);
+ }
+ return;
}
/*
@@ -1054,535 +776,376 @@ bdump_ask_for(inst)
static Code_t
bdump_recv_loop(server)
- ZServerDesc_t *server;
+ Server *server;
{
- ZNotice_t notice;
- ZPacket_t packet;
- int len;
- Code_t retval;
- ZClient_t *client = NULLZCNT;
- struct sockaddr_in current_who;
- int who_valid = 0;
- int flushing_subs = 0;
-#ifdef KERBEROS
- register char *cp;
- C_Block cblock;
-#endif /* KERBEROS */
-#ifdef CONCURRENT
- fd_set readable, initial;
- int fd_ready;
- struct timeval tv;
-#endif /* CONCURRENT */
+ ZNotice_t notice;
+ ZPacket_t packet;
+ int len;
+ Code_t retval;
+ Client *client = NULL;
+ struct sockaddr_in who;
+#ifdef ZEPHYR_USES_KERBEROS
+ char *cp;
+ C_Block cblock;
+#endif /* ZEPHYR_USES_KERBEROS */
+ Realm *realm = NULL;
#if 1
- zdbug((LOG_DEBUG, "bdump recv loop"));
+ zdbug((LOG_DEBUG, "bdump recv loop"));
#endif
-#ifdef CONCURRENT
- FD_ZERO(&initial);
- FD_SET(srv_socket, &initial);
-#endif /* CONCURRENT */
-
- /* do the inverse of bdump_send_loop, registering stuff on the fly */
- while (1) {
-#ifdef CONCURRENT
- readable = initial;
- tv.tv_sec = tv.tv_usec = 0;
-
- if (msgs_queued()) {
-#if 1
- zdbug((LOG_DEBUG, "brl msgqued"));
-#endif
- fd_ready = 1;
- } else
- fd_ready = select(srv_socket + 1, &readable,
- (fd_set *)0,
- (fd_set *)0, &tv);
- /*
- * if there are packets to be processed, do them.
- * We needn't worry about locking since we don't
- * know what's coming our way.
- */
- if (fd_ready > 0) {
-#if 1
- zdbug((LOG_DEBUG, "brl fdready"));
-#endif
- handle_packet();
-#ifdef notdef
- if (cancel_outgoing_dump) {
- cancel_outgoing_dump = 0;
- return EWOULDBLOCK; /* maybe in a warped sort
- of way */
- }
-#endif
- } else if (fd_ready < 0)
- syslog(LOG_ERR, "brl select: %m");
-#endif /* CONCURRENT */
- len = sizeof(packet);
- if ((retval = get_packet(packet, len, &len)) != ZERR_NONE) {
- syslog(LOG_ERR, "brl get pkt: %s",
- error_message(retval));
- return(retval);
- }
+ /* do the inverse of bdump_send_loop, registering stuff on the fly */
+ while (1) {
+ if (packets_waiting()) {
+ /* A non-braindump packet is waiting; handle it. */
+ bdumping = 0;
+ bdump_concurrent = 1;
+ handle_packet();
+ bdump_concurrent = 0;
+ bdumping = 1;
+ }
+ len = sizeof(packet);
+ retval = get_packet(packet, len, &len);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "brl get pkt: %s", error_message(retval));
+ return retval;
+ }
- if ((retval = ZParseNotice(packet, len, &notice)) != ZERR_NONE) {
- syslog(LOG_ERR, "brl notice parse: %s",
- error_message(retval));
- return(retval);
- }
+ retval = ZParseNotice(packet, len, &notice);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "brl notice parse: %s", error_message(retval));
+ return retval;
+ }
#if defined (DEBUG)
- if (zdebug) {
- char buf[4096];
-
- (void) sprintf(buf,
- "bdump:%s '%s' '%s' '%s' '%s' '%s'",
- ZNoticeKinds[(int) notice.z_kind],
- notice.z_class,
- notice.z_class_inst,
- notice.z_opcode,
- notice.z_sender,
- notice.z_recipient);
- syslog(LOG_DEBUG, buf);
- }
+ if (zdebug) {
+ char buf[4096];
+
+ sprintf(buf, "bdump:%s '%s' '%s' '%s' '%s' '%s'",
+ ZNoticeKinds[(int) notice.z_kind], notice.z_class,
+ notice.z_class_inst, notice.z_opcode, notice.z_sender,
+ notice.z_recipient);
+ syslog(LOG_DEBUG, buf);
+ }
#endif /* DEBUG */
- if (notice.z_kind == HMCTL) {
- /* host register */
- if ((retval = extract_sin(&notice, &current_who)) !=
- ZERR_NONE) {
- syslog(LOG_ERR, "brl hmctl sin: %s",
- error_message(retval));
- return(retval);
- }
- who_valid = 1;
- /* 1 = tell it we are authentic */
- if ((retval = hostm_dispatch(&notice, 1,
- &current_who, server))
- != ZERR_NONE) {
- syslog(LOG_ERR,"brl hm_disp failed: %s",
- error_message(retval));
- return(retval);
- }
- } else if (!strcmp(notice.z_opcode, ADMIN_DONE)) {
- /* end of brain dump */
- return(ZERR_NONE);
- } else if (!who_valid) {
- syslog(LOG_ERR, "brl: no current host");
- return(ZSRV_HNOTFOUND);
- } else if (!strcmp(notice.z_class, LOGIN_CLASS)) {
- /* 1 = tell it we are authentic */
- if ((retval = ulogin_dispatch(&notice, 1,
- &current_who, server))
- != ZERR_NONE) {
- syslog(LOG_ERR, "brl ul_disp failed: %s",
- error_message(retval));
- return(retval);
- }
- } else if (!strcmp(notice.z_opcode, ADMIN_NEWCLT)) {
- /* register a new client */
- notice.z_port = htons((u_short)atoi(notice.z_message));
- if (ntohs(notice.z_port) == 0) {
- /* this is a bogus client from an older rev.
- server, so we just flush it. */
- syslog(LOG_ERR, "brl flushing %s/0",
- inet_ntoa(current_who.sin_addr));
- flushing_subs = 1;
- continue; /* while loop */
- }
- flushing_subs = 0;
- if ((retval = client_register(&notice,
- &current_who,
- &client,
- server,
- 0)) != ZERR_NONE) {
- syslog(LOG_ERR,"brl register failed: %s",
- error_message(retval));
- return(retval);
- }
-#ifdef KERBEROS
- (void) memset((caddr_t) client->zct_cblock, 0,
- sizeof(C_Block));
- if (*notice.z_class_inst) {
- /* a C_Block is there */
- cp = notice.z_message +
- strlen(notice.z_message) + 1;
- retval = ZReadAscii(cp,strlen(cp),
- cblock, sizeof(C_Block));
- if (retval != ZERR_NONE) {
- syslog(LOG_ERR,"brl bad cblk read: %s (%s)",
- error_message(retval),
- cp);
- } else {
+ if (notice.z_num_other_fields >= 1) {
+ retval = ZReadAscii(notice.z_other_fields[0],
+ strlen(notice.z_other_fields[0]),
+ (unsigned char *) &who.sin_addr,
+ sizeof(struct in_addr));
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "brl zreadascii failed: %s",
+ error_message(retval));
+ return retval;
+ }
+ } else {
+ who.sin_addr.s_addr = notice.z_sender_addr.s_addr;
+ }
+ who.sin_family = AF_INET;
+ who.sin_port = notice.z_port;
+
+ if (strcmp(notice.z_opcode, ADMIN_DONE) == 0) {
+ /* end of brain dump */
+ return ZERR_NONE;
+ } else if (strcmp(notice.z_opcode, ADMIN_NEWREALM) == 0) {
+ /* get a realm from the message */
+ realm = realm_get_realm_by_name(notice.z_message);
+ if (!realm)
+ return(ZERR_NONE);
+ } else if (strcmp(notice.z_class, LOGIN_CLASS) == 0) {
+ /* 1 = tell it we are authentic */
+ retval = ulogin_dispatch(&notice, 1, &who, server);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "brl ul_disp failed: %s",
+ error_message(retval));
+ return retval;
+ }
+ } else if (strcmp(notice.z_opcode, ADMIN_NEWCLT) == 0) {
+ /* a new client */
+ notice.z_port = htons((u_short) atoi(notice.z_message));
+ retval = client_register(&notice, &who.sin_addr, &client, 0);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR,"brl failed: %s", error_message(retval));
+ return retval;
+ }
+#ifdef ZEPHYR_USES_KERBEROS
+ memset(client->session_key, 0, sizeof(C_Block));
+ if (*notice.z_class_inst) {
+ /* a C_Block is there */
+ cp = notice.z_message + strlen(notice.z_message) + 1;
+ retval = ZReadAscii(cp, strlen(cp), cblock, sizeof(C_Block));
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR,"brl bad cblk read: %s (%s)",
+ error_message(retval), cp);
+ } else {
#ifdef NOENCRYPTION
- memcpy((caddr_t)cblock,
- (caddr_t)client->zct_cblock,
- sizeof(C_Block));
+ memcpy(cblock, client->session_key, sizeof(C_Block));
#else
- des_ecb_encrypt(cblock, client->zct_cblock,
- serv_ksched.s, DES_DECRYPT);
+ des_ecb_encrypt(cblock, client->session_key, serv_ksched.s,
+ DES_DECRYPT);
#endif
- }
- }
-#endif /* KERBEROS */
- } else if (!strcmp(notice.z_opcode, CLIENT_SUBSCRIBE)) {
- if (flushing_subs)
- continue; /* while loop */
- /* a subscription packet */
- if (!client) {
- syslog(LOG_ERR, "brl no client");
- return(ZSRV_NOCLT);
- }
- if ((retval = subscr_subscribe(client, &notice)) != ZERR_NONE) {
- syslog(LOG_WARNING, "brl subscr failed: %s",
- error_message(retval));
- return(retval);
- }
- } else {
- syslog(LOG_ERR, "brl bad opcode %s",notice.z_opcode);
- return(ZSRV_UNKNOWNOPCODE);
}
+ }
+#endif /* ZEPHYR_USES_KERBEROS */
+ } else if (strcmp(notice.z_opcode, CLIENT_SUBSCRIBE) == 0) {
+ /* a subscription packet */
+ if (!client) {
+ syslog(LOG_ERR, "brl no client");
+ return ZSRV_NOCLT;
+ }
+ retval = subscr_subscribe(client, &notice);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "brl subscr failed: %s",
+ error_message(retval));
+ return retval;
+ }
+ } else if (strcmp(notice.z_opcode, REALM_SUBSCRIBE) == 0) {
+ /* add a subscription for a realm */
+ if (!realm) {
+ syslog(LOG_ERR, "brl no realm");
+ return(ZSRV_NORLM);
+ }
+ retval = subscr_realm(realm, &notice);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "brl subscr failed: %s",
+ error_message(retval));
+ return retval;
+ }
+ } else {
+ syslog(LOG_ERR, "brl bad opcode %s",notice.z_opcode);
+ return ZSRV_UNKNOWNOPCODE;
}
+ }
}
-
+
/*
- * Send all the state from server to the peer.
+ * Send all the state to the peer.
*/
-
+
static Code_t
-bdump_send_loop(server, vers)
- ZServerDesc_t *server;
- char *vers;
+bdump_send_loop(server)
+ Server *server;
{
- register ZHostList_t *host;
- register ZClientList_t *clist;
- Code_t retval;
-#ifdef CONCURRENT
- fd_set readable, initial;
- int fd_ready;
- struct timeval tv;
-#endif /* CONCURRENT */
-
+ Code_t retval;
+
#if 1
- zdbug((LOG_DEBUG, "bdump send loop"));
-#endif
-
-
-#ifdef CONCURRENT
- FD_ZERO(&initial);
- FD_SET(srv_socket, &initial);
-#endif /* CONCURRENT */
-
- for (host = server->zs_hosts->q_forw;
- host != server->zs_hosts;
- host = host->q_forw) {
- /* for each host */
-#ifdef CONCURRENT
- host->zh_locked = 1;
-
- readable = initial;
- tv.tv_sec = tv.tv_usec = 0;
-
- if (msgs_queued())
- fd_ready = 1;
- else
- fd_ready = select(srv_socket + 1, &readable,
- (fd_set *)0,
- (fd_set *)0, &tv);
- /*
- * if there are packets to be processed, do them.
- * locking the host above insures nothing we are working on
- * gets trashed.
- */
- if (fd_ready > 0) {
- handle_packet();
-#ifdef notdef
- if (cancel_outgoing_dump) {
- cancel_outgoing_dump = 0;
- return EWOULDBLOCK;
- }
-#endif
- } else if (fd_ready < 0)
- syslog(LOG_ERR, "bsl select: %m");
-
-#endif /* CONCURRENT */
- if ((retval = send_host_register(host)) != ZERR_NONE) {
- host->zh_locked = 0;
- return(retval);
- }
- if ((retval = uloc_send_locations(host, vers)) != ZERR_NONE) {
- host->zh_locked = 0;
- return(retval);
- }
- if (!host->zh_clients) {
- host->zh_locked = 0;
- continue;
- }
- for (clist = host->zh_clients->q_forw;
- clist != host->zh_clients;
- clist = clist->q_forw) {
- /* for each client */
- if (!clist->zclt_client->zct_subs) {
- host->zh_locked = 0;
- continue;
- }
- if ((retval = subscr_send_subs(clist->zclt_client,
- vers)) != ZERR_NONE) {
- host->zh_locked = 0;
- return(retval);
- }
- }
- host->zh_locked = 0;
- }
- retval = send_done();
- return(retval);
-}
-
-/*
- * Send a host boot packet to the other server
- */
-
-static Code_t
-send_host_register(host)
- ZHostList_t *host;
-{
- char buf[512], *addr, *lyst[2];
- Code_t retval;
-
-#if 0
- zdbug((LOG_DEBUG, "bdump_host_register"));
+ zdbug((LOG_DEBUG, "bdump send loop"));
#endif
- addr = inet_ntoa(host->zh_addr.sin_addr);
- (void) sprintf(buf, "%d", ntohs(host->zh_addr.sin_port));
- lyst[0] = addr;
- lyst[1] = buf;
-
- /* myname is the hostname */
- retval = bdump_send_list_tcp (HMCTL, (int) bdump_sin.sin_port,
- ZEPHYR_CTL_CLASS, ZEPHYR_CTL_HM,
- HM_BOOT, myname, "", lyst, 2);
- if (retval != ZERR_NONE)
- syslog(LOG_ERR, "shr send: %s",error_message(retval));
- return(retval);
+
+ retval = uloc_send_locations();
+ if (retval != ZERR_NONE)
+ return retval;
+ retval = client_send_clients();
+ if (retval != ZERR_NONE)
+ return retval;
+ retval = realm_send_realms();
+ if (retval != ZERR_NONE)
+ return retval;
+ return send_done();
}
-
+
/*
* Send a sync indicating end of this host
*/
-
+
static Code_t
send_done()
{
- Code_t retval;
+ Code_t retval;
#if 1
- zdbug((LOG_DEBUG, "send_done"));
+ zdbug((LOG_DEBUG, "send_done"));
#endif
- retval = send_normal_tcp(SERVACK, bdump_sin.sin_port,
- ZEPHYR_ADMIN_CLASS, "", ADMIN_DONE, myname,
- "", (char *) NULL, 0);
- return(retval);
+ retval = send_normal_tcp(SERVACK, bdump_sin.sin_port, ZEPHYR_ADMIN_CLASS,
+ "", ADMIN_DONE, myname, "", NULL, 0);
+ return retval;
}
-
-
+
+
/*
* Send a list off as the specified notice
*/
-
+
static Code_t
send_list(kind, port, class_name, inst, opcode, sender, recip, lyst, num)
- ZNotice_Kind_t kind;
- int port;
- char *class_name;
- char *inst;
- char *opcode;
- char *sender;
- char *recip;
- char **lyst;
- int num;
+ ZNotice_Kind_t kind;
+ int port, num;
+ char *class_name, *inst, *opcode, *sender, *recip, **lyst;
{
- ZNotice_t notice;
- register ZNotice_t *pnotice; /* speed hack */
- char *pack;
- int packlen;
- Code_t retval;
-
- pnotice = &notice;
-
- pnotice->z_kind = kind;
-
- pnotice->z_port = port;
- pnotice->z_class = class_name;
- pnotice->z_class_inst = inst;
- pnotice->z_opcode = opcode;
- pnotice->z_sender = sender;
- pnotice->z_recipient = recip;
- pnotice->z_default_format = "";
- pnotice->z_num_other_fields = 0;
+ ZNotice_t notice;
+ char *pack;
+ int packlen;
+ Code_t retval;
+
+ notice.z_kind = kind;
+ notice.z_port = port;
+ notice.z_class = class_name;
+ notice.z_class_inst = inst;
+ notice.z_opcode = opcode;
+ notice.z_sender = sender;
+ notice.z_recipient = recip;
+ notice.z_default_format = "";
+ notice.z_num_other_fields = 0;
- if ((retval = ZFormatNoticeList(pnotice, lyst, num, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
- syslog(LOG_WARNING, "sl format: %s", error_message(retval));
- return(retval);
- }
+ retval = ZFormatNoticeList(&notice, lyst, num, &pack, &packlen, ZNOAUTH);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "sl format: %s", error_message(retval));
+ return retval;
+ }
- if ((retval = ZSendPacket(pack, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "sl xmit: %s", error_message(retval));
- xfree(pack); /* free allocated storage */
- return(retval);
- }
- xfree(pack); /* free allocated storage */
- return(ZERR_NONE);
+ retval = ZSendPacket(pack, packlen, 0);
+ if (retval != ZERR_NONE)
+ syslog(LOG_WARNING, "sl xmit: %s", error_message(retval));
+ free(pack);
+ return retval;
}
-
+
/*
* Send a message off as the specified notice, via TCP
*/
-
+
static Code_t
send_normal_tcp(kind, port, class_name, inst, opcode, sender, recip,
message, len)
- ZNotice_Kind_t kind;
- int port;
- char *class_name;
- char *inst;
- char *opcode;
- char *sender;
- char *recip;
- char *message;
- int len;
+ ZNotice_Kind_t kind;
+ int port, len;
+ char *class_name, *inst, *opcode, *sender, *recip, *message;
{
- ZNotice_t notice;
- register ZNotice_t *pnotice; /* speed hack */
- char *pack;
- int packlen, count;
- Code_t retval;
- u_short length;
-
- pnotice = &notice;
-
- pnotice->z_kind = kind;
+ ZNotice_t notice;
+ char *pack;
+ int packlen, count;
+ Code_t retval;
+ u_short length;
+
+ notice.z_kind = kind;
+ notice.z_port = port;
+ notice.z_class = class_name;
+ notice.z_class_inst = inst;
+ notice.z_opcode = opcode;
+ notice.z_sender = sender;
+ notice.z_recipient = recip;
+ notice.z_default_format = "";
+ notice.z_message = message;
+ notice.z_message_len = len;
+ notice.z_num_other_fields = 0;
+
+ retval = ZFormatNotice(&notice, &pack, &packlen, ZNOAUTH);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "sn format: %s", error_message(retval));
+ return retval;
+ }
- pnotice->z_port = port;
- pnotice->z_class = class_name;
- pnotice->z_class_inst = inst;
- pnotice->z_opcode = opcode;
- pnotice->z_sender = sender;
- pnotice->z_recipient = recip;
- pnotice->z_default_format = "";
- pnotice->z_message = message;
- pnotice->z_message_len = len;
- pnotice->z_num_other_fields = 0;
+ length = htons((u_short) packlen);
- if ((retval = ZFormatNotice(pnotice, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
- syslog(LOG_WARNING, "sn format: %s", error_message(retval));
- return(retval);
+ count = net_write(output, (char *) &length, sizeof(length));
+ if (count != sizeof(length)) {
+ if (count < 0) {
+ syslog(LOG_WARNING, "snt xmit/len: %m");
+ free(pack);
+ return errno;
+ } else {
+ syslog(LOG_WARNING, "snt xmit: %d vs %d",sizeof(length),count);
+ free(pack);
+ return ZSRV_LEN;
}
-
- length = htons((u_short) packlen);
-
- if ((count = net_write(output, (caddr_t) &length, sizeof(length))) != sizeof(length)) {
- if (count < 0) {
- syslog(LOG_WARNING, "snt xmit/len: %m");
- xfree(pack); /* free allocated storage */
- return(errno);
- } else {
- syslog(LOG_WARNING, "snt xmit: %d vs %d",sizeof(length),count);
- xfree(pack); /* free allocated storage */
- return(ZSRV_LEN);
- }
+ }
+ count = net_write(output, pack, packlen);
+ if (count != packlen) {
+ if (count < 0) {
+ syslog(LOG_WARNING, "snt xmit: %m");
+ free(pack);
+ return errno;
+ } else {
+ syslog(LOG_WARNING, "snt xmit: %d vs %d",packlen, count);
+ free(pack);
+ return ZSRV_LEN;
}
- if ((count = net_write(output, pack, packlen)) != packlen)
- if (count < 0) {
- syslog(LOG_WARNING, "snt xmit: %m");
- xfree(pack); /* free allocated storage */
- return(errno);
- } else {
- syslog(LOG_WARNING, "snt xmit: %d vs %d",packlen, count);
- xfree(pack); /* free allocated storage */
- return(ZSRV_LEN);
- }
- xfree(pack); /* free allocated storage */
- return(ZERR_NONE);
+ }
+ free(pack);
+ return ZERR_NONE;
}
-
+
/*
* get a packet from the TCP socket
* return 0 if successful, error code else
*/
-
+
static Code_t
get_packet(packet, len, retlen)
- caddr_t packet;
- int len;
- int *retlen;
+ void *packet;
+ int len;
+ int *retlen;
{
- u_short length;
- int result;
+ u_short length;
+ int result;
- if ((result = net_read(input, (caddr_t) &length, sizeof(u_short))) < sizeof(short)) {
- if (result < 0)
- return(errno);
- else {
- syslog(LOG_ERR, "get_pkt len: %d vs %d (%m)", result, sizeof(short));
- return(ZSRV_LEN);
- }
+ result = net_read(input, (char *) &length, sizeof(u_short));
+ if (result < sizeof(short)) {
+ if (result < 0) {
+ return errno;
+ } else {
+ syslog(LOG_ERR, "get_pkt len: %d vs %d (%m)", result,
+ sizeof(short));
+ return ZSRV_LEN;
}
+ }
- length = ntohs(length);
- if (len < length)
- return(ZSRV_BUFSHORT);
- if ((result = net_read(input, packet, (int) length)) < length) {
- if (result < 0)
- return(errno);
- else {
- syslog(LOG_ERR, "get_pkt: %d vs %d (%m)",result, length);
- return(ZSRV_LEN);
- }
+ length = ntohs(length);
+ if (len < length)
+ return ZSRV_BUFSHORT;
+ result = net_read(input, packet, (int) length);
+ if (result < length) {
+ if (result < 0) {
+ return errno;
+ } else {
+ syslog(LOG_ERR, "get_pkt: %d vs %d (%m)", result, length);
+ return ZSRV_LEN;
}
- *retlen = (int) length;
- return(ZERR_NONE);
+ }
+ *retlen = length;
+ return ZERR_NONE;
}
-
+
static Code_t
extract_sin(notice, target)
- ZNotice_t *notice;
- struct sockaddr_in *target;
+ ZNotice_t *notice;
+ struct sockaddr_in *target;
{
- register char *cp = notice->z_message;
- char *buf;
+ char *cp = notice->z_message;
+ char *buf;
- buf = cp;
- if (!notice->z_message_len || *buf == '\0') {
+ buf = cp;
+ if (!notice->z_message_len || *buf == '\0') {
#if 0
- zdbug((LOG_DEBUG,"no addr"));
+ zdbug((LOG_DEBUG,"no addr"));
#endif
- return(ZSRV_PKSHORT);
- }
- target->sin_addr.s_addr = inet_addr(cp);
+ return ZSRV_PKSHORT;
+ }
+ target->sin_addr.s_addr = inet_addr(cp);
- cp += (strlen(cp) + 1); /* past the null */
- if ((cp >= notice->z_message + notice->z_message_len)
- || (*cp == '\0')) {
+ cp += (strlen(cp) + 1); /* past the null */
+ if ((cp >= notice->z_message + notice->z_message_len) || (*cp == '\0')) {
#if 0
- zdbug((LOG_DEBUG, "no port"));
+ zdbug((LOG_DEBUG, "no port"));
#endif
- return(ZSRV_PKSHORT);
- }
- target->sin_port = htons((u_short) atoi(cp));
- target->sin_family = AF_INET;
- return(ZERR_NONE);
+ return(ZSRV_PKSHORT);
+ }
+ target->sin_port = htons((u_short) atoi(cp));
+ target->sin_family = AF_INET;
+ return ZERR_NONE;
}
-
+
static int
net_read(f, buf, len)
- FILE *f;
- register char *buf;
- register int len;
+ FILE *f;
+ char *buf;
+ int len;
{
int cc, len2 = 0;
fflush (output);
do {
errno = 0;
- cc = fread (buf, 1, len, f);
+ cc = fread(buf, 1, len, f);
if (cc == 0)
return -1;
buf += cc;
@@ -1591,15 +1154,15 @@ net_read(f, buf, len)
} while (len > 0);
return len2;
}
-
+
static int
net_write(f, buf, len)
- FILE *f;
- register char *buf;
- int len;
+ FILE *f;
+ char *buf;
+ int len;
{
int cc;
- register int wrlen = len;
+ int wrlen = len;
do {
cc = fwrite (buf, 1, wrlen, f);
if (cc == 0)
@@ -1613,7 +1176,7 @@ net_write(f, buf, len)
static int
setup_file_pointers ()
{
- int fd;
+ int fd;
input = fdopen (live_socket, "r");
if (!input)
diff --git a/server/class.c b/server/class.c
index b70bf4e..b4c46d8 100644
--- a/server/class.c
+++ b/server/class.c
@@ -12,41 +12,40 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h" /* includes zephyr/zephyr.h */
+#include <assert.h>
#if !defined (lint) && !defined (SABER)
-static char rcsid_class_c[] =
- "$Id$";
+static const char rcsid_class_c[] =
+"$Id$";
#endif
-#include "zserver.h" /* includes zephyr/zephyr.h */
-
-#include <ctype.h> /* for isupper, tolower */
-
/*
* Class manager subsystem.
*
*
* External functions are:
*
- * Code_t triplet_register(client, subs)
+ * Code_t triplet_register(client, subs, realm)
*
- * Code_t triplet_deregister(client, subs)
+ * Code_t triplet_deregister(client, subs, realm)
*
- * ZClientList_t *triplet_lookup(subs)
- * ZClient_t *client;
- * ZSubscr_t *subs;
+ * Client *triplet_lookup(subs)
+ * Client *client;
+ * Destlist *subs;
*
- * ZAcl_t *class_get_acl(ZString class_name)
+ * Acl *class_get_acl(class_name)
+ * String *class_name;
*
* Code_t class_restrict(class_name, acl)
* char *class_name;
- * ZAcl_t *acl;
+ * Acl *acl;
*
* Code_t class_setup_restricted(class_name, acl)
* char *class_name;
- * ZAcl_t *acl;
+ * Acl *acl;
*
- * and several ZDestination methods.
+ * and several Destination methods.
*/
/*
@@ -56,7 +55,7 @@ static char rcsid_class_c[] =
* name (which hashes into the bucket associated with this list) and a
* doubly linked list of clients which are interested in this class.
* The data pointed to by these clients is owned by other modules. Care
- * must be taken by the caller not to register a free()'d client
+ * must be taken by the caller not to a free()'d client
* structure.
*
* If any hash bucket is empty, the pointer is null.
@@ -71,26 +70,23 @@ static char rcsid_class_c[] =
/* Private variables */
#define EMPTY_CLASS 2000
+#define ALLOC_OFFSET 8 /* Allocate 32 bytes less than a power of 2. */
+#define ALLOC_INIT 8 /* Initial number of subscriptions. */
+
#define HASHSIZE 1023
#define HASHVAL(c, i, r) (((c)->hash_val ^ (i)->hash_val ^ (r)->hash_val) \
% HASHSIZE)
#define DEST_HASHVAL(dest) HASHVAL((dest).classname, (dest).inst, (dest).recip)
-static ZTriplet_t *class_bucket[HASHSIZE]; /* the hash table of pointers */
-
+static Triplet *triplet_bucket[HASHSIZE]; /* the hash table of pointers */
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static Code_t remove_client P((ZTriplet_t *ptr, ZClient_t *client));
-static Code_t insert_client P((ZTriplet_t *ptr, ZClient_t *client));
-static ZClientList_t *client_alloc P((ZClient_t *client));
-static ZTriplet_t *triplet_alloc P((ZSTRING *classname, ZSTRING *inst,
- ZSTRING *recipient));
-static void free_class P((ZTriplet_t *));
+static Code_t remove_client __P((Triplet *triplet, Client *client,
+ Realm *realm));
+static Code_t insert_client __P((Triplet *triplet, Client *client,
+ Realm *realm));
+static Triplet *triplet_alloc __P((String *classname, String *inst,
+ String *recipient));
+static void free_triplet __P((Triplet *));
/* public routines */
@@ -102,169 +98,112 @@ static void free_class P((ZTriplet_t *));
* been case-sensitive in the recipient string. In most cases, a
* failed match will fail on the classname or instance, and a successful
* match will succeed on the (d1->recip == d2->recip) check, so this
- * shouldn't affect performance. Note that this invalidates the overall
- * hash value check, which was of dubious value to start with.
+ * shouldn't affect performance.
*/
int ZDest_eq(d1, d2)
- ZDestination *d1, *d2;
+ Destination *d1, *d2;
{
- return((d1->classname == d2->classname) &&
- (d1->inst == d2->inst) &&
- (d1->recip == d2->recip ||
- strcasecmp(d1->recip->string, d2->recip->string) == 0));
+ return((d1->classname == d2->classname) &&
+ (d1->inst == d2->inst) &&
+ (d1->recip == d2->recip ||
+ strcasecmp(d1->recip->string, d2->recip->string) == 0));
}
-/* register the client as interested in a triplet */
+/* the client as interested in a triplet */
Code_t
-triplet_register(client, dest)
- ZClient_t *client;
- ZDestination *dest;
+triplet_register(client, dest, realm)
+ Client *client;
+ Destination *dest;
+ Realm *realm;
{
- register ZTriplet_t *ptr, *ptr2;
- unsigned long hashval;
-
- hashval = DEST_HASHVAL(*dest);
-
- if (!(ptr = class_bucket[hashval])) {
- /* not registered */
-
- ptr = triplet_alloc(dest->classname, dest->inst, dest->recip);
- if (!ptr)
- return(ENOMEM);
-
- /* allocate the head of the bucket */
-
- if (!(ptr2 = (ZTriplet_t *) xmalloc(sizeof(ZTriplet_t))))
- return(ENOMEM);
-
- ptr2->zct_clientlist = 0;
- ptr2->zct_acl = 0;
- ptr2->q_forw = ptr;
- ptr2->q_back = ptr;
- ptr->q_forw = ptr2;
- ptr->q_back = ptr2;
-
- class_bucket[hashval] = ptr2;
- return(insert_client(ptr, client));
-
- } else {
- for (ptr2 = ptr->q_forw; ptr2 != ptr; ptr2 = ptr2->q_forw) {
- /* walk down the list, looking for a match */
- if (ZDest_eq(&ptr2->zct_dest,dest))
- return(insert_client(ptr2, client));
- }
+ Triplet *triplet;
+ unsigned long hashval;
- /* fell off the end, no match */
- ptr2 = triplet_alloc(dest->classname, dest->inst, dest->recip);
- if (!ptr2)
- return(ENOMEM);
+ hashval = DEST_HASHVAL(*dest);
+ for (triplet = triplet_bucket[hashval]; triplet; triplet = triplet->next) {
+ if (ZDest_eq(&triplet->dest, dest))
+ return insert_client(triplet, client, realm);
+ }
- xinsque(ptr2, ptr); /* insert new class into hash bucket */
- return(insert_client(ptr2, client));
- }
+ /* Triplet not present in hash table, insert it. */
+ triplet = triplet_alloc(dest->classname, dest->inst, dest->recip);
+ LIST_INSERT(&triplet_bucket[hashval], triplet);
+ return insert_client(triplet, client, realm);
}
/* dissociate client from the class, garbage collecting if appropriate */
Code_t
-triplet_deregister(client, dest)
- ZClient_t *client;
- ZDestination *dest;
+triplet_deregister(client, dest, realm)
+ Client *client;
+ Destination *dest;
+ Realm *realm;
{
- register ZTriplet_t *ptr, *ptr2;
- int retval = -1;
- unsigned long hashval;
+ Triplet *triplet;
+ int retval;
+ unsigned long hashval;
- hashval = DEST_HASHVAL(*dest);
-#if 0
- zdbug((LOG_DEBUG, "class_dereg: %s %s", dest->classname->string,
- dest->inst->string));
-#endif
- ptr = class_bucket[hashval];
- if (!ptr)
- /* no such class to deregister */
- return(ZSRV_BADASSOC);
-
- for (ptr2 = ptr->q_forw; ptr2 != ptr; ptr2 = ptr2->q_forw) {
- /* walk down the list, looking for a match */
- if (ZDest_eq(&ptr2->zct_dest,dest)) {
- retval = remove_client(ptr2, client);
- if (retval == EMPTY_CLASS) {
#if 0
- zdbug((LOG_DEBUG,"empty class"));
+ zdbug((LOG_DEBUG, "class_dereg: %s %s", dest->classname->string,
+ dest->inst->string));
#endif
- /* Don't free up restricted classes. */
- if (ptr2->zct_acl)
- return(ZERR_NONE);
- else {
- xremque(ptr2);
- free_class(ptr2);
- return(ZERR_NONE);
- }
- }
- /* if not EMPTY_CLASS, it's either ZSRV_BADASSOC
- (not found) or ZERR_NONE (found and removed),
- so break */
- break;
- }
+ hashval = DEST_HASHVAL(*dest);
+ for (triplet = triplet_bucket[hashval]; triplet; triplet = triplet->next) {
+ if (ZDest_eq(&triplet->dest, dest)) {
+ retval = remove_client(triplet, client, realm);
+ if (retval != ZERR_NONE)
+ return retval;
+ if (*triplet->clients == NULL && !triplet->acl) {
+ LIST_DELETE(triplet);
+ free_triplet(triplet);
+ }
+ return ZERR_NONE;
}
-
- /* fell off: either client not found or client found
- and removed, retval contains the result */
- return(retval);
+ }
+ return(ZSRV_BADASSOC);
}
-
+
/* return a linked list of what clients are interested in this triplet */
-ZClientList_t *
+Client **
triplet_lookup(dest)
- ZDestination *dest;
+ Destination *dest;
{
- register ZTriplet_t *class, *p;
- unsigned long hashval;
-
- hashval = DEST_HASHVAL(*dest);
- p = class_bucket[hashval];
- if (p == NULLZT)
- return NULLZCLT;
-
- /* Go search the list for the class */
- for (class = p->q_forw; class != p; class = class->q_forw) {
- /* walk down the list, looking for a match */
- if (ZDest_eq(&class->zct_dest,dest))
- return class->zct_clientlist;
- }
- return NULLZCLT;
+ Triplet *triplet;
+ unsigned long hashval;
+
+ hashval = DEST_HASHVAL(*dest);
+ for (triplet = triplet_bucket[hashval]; triplet; triplet = triplet->next) {
+ if (ZDest_eq(&triplet->dest, dest))
+ return triplet->clients;
+ }
+ return NULL;
}
/*
- * return the acl structure associated with class, or NULLZACLT if there is
+ * return the acl structure associated with class, or NULL if there is
* no such acl struct
*/
-ZAcl_t *
+Acl *
class_get_acl(class_name)
- ZSTRING *class_name;
+ String *class_name;
{
- register ZTriplet_t *ptr, *ptr2;
- unsigned long hashval;
-
- hashval = HASHVAL(class_name, empty, empty);
- if (!(ptr = class_bucket[hashval]))
- return(NULLZACLT);
-
- /* walk down the list, looking for a match */
- for (ptr2 = ptr->q_back; ptr2 != ptr; ptr2 = ptr2->q_back)
- if ((ptr2->zct_dest.classname == class_name) &&
- (ptr2->zct_dest.inst == empty) &&
- (ptr2->zct_dest.recip == empty))
- return(ptr2->zct_acl);
-
- /* fell off the end, no match ==> not restricted */
- return(NULLZACLT);
+ Triplet *triplet;
+ unsigned long hashval;
+
+ hashval = HASHVAL(class_name, empty, empty);
+ for (triplet = triplet_bucket[hashval]; triplet; triplet = triplet->next) {
+ if (triplet->dest.classname == class_name &&
+ triplet->dest.inst == empty && triplet->dest.recip == empty)
+ return triplet->acl;
+ }
+
+ /* No acl found, not restricted. */
+ return NULL;
}
/*
@@ -275,35 +214,28 @@ class_get_acl(class_name)
Code_t
class_restrict(class_name, acl)
- char *class_name;
- ZAcl_t *acl;
+ char *class_name;
+ Acl *acl;
{
- register ZTriplet_t *ptr, *ptr2;
- ZSTRING *d;
- unsigned long hashval;
-
- d = make_zstring(class_name,1);
- hashval = HASHVAL(d, empty, empty);
-
- if (!(ptr = class_bucket[hashval])) {
- free_zstring(d);
- return(ZSRV_NOCLASS);
+ Triplet *triplet;
+ String *d;
+ unsigned long hashval;
+
+ d = make_string(class_name,1);
+ hashval = HASHVAL(d, empty, empty);
+ for (triplet = triplet_bucket[hashval]; triplet; triplet = triplet->next) {
+ if (triplet->dest.classname == d && triplet->dest.inst == empty &&
+ triplet->dest.recip == empty) {
+ if (triplet->acl)
+ return ZSRV_CLASSRESTRICTED;
+ triplet->acl = acl;
+ free_string(d);
+ return ZERR_NONE;
}
- for (ptr2 = ptr->q_forw; ptr2 != ptr; ptr2 = ptr2->q_forw)
- /* walk down the list, looking for a match */
- if ((ptr2->zct_dest.classname == d) &&
- (ptr2->zct_dest.inst == empty) &&
- (ptr2->zct_dest.recip == empty)) {
- if (ptr2->zct_acl)
- return ZSRV_CLASSRESTRICTED;
- ptr2->zct_acl = acl;
- free_zstring(d);
- return(ZERR_NONE);
- }
+ }
- /* fell off the end, no match */
- free_zstring(d);
- return(ZSRV_NOCLASS);
+ free_string(d);
+ return ZSRV_NOCLASS;
}
/*
@@ -311,132 +243,100 @@ class_restrict(class_name, acl)
* structure acl. return ZERR_NONE if no error, or ZSRV_CLASSXISTS
* if the class is already registered, or ENOMEM in case of malloc failure.
*/
-
+
Code_t
class_setup_restricted(class_name, acl)
- char *class_name;
- ZAcl_t *acl;
+ char *class_name;
+ Acl *acl;
{
- register ZTriplet_t *ptr, *ptr2;
- ZSTRING *d;
- unsigned long hashval;
-
- d = make_zstring(class_name,1);
- hashval = HASHVAL(d, empty, empty);
-
- if (!(ptr = class_bucket[hashval])) {
- /* not registered */
-
- ptr = triplet_alloc(d,empty,empty);
- if (!ptr)
- return(ENOMEM);
-
- ptr->zct_acl = acl;
-
- /* allocate the head of the bucket */
- ptr2 = (ZTriplet_t *) xmalloc(sizeof(ZTriplet_t));
- if (!ptr2)
- return(ENOMEM);
-
- ptr2->q_forw = ptr;
- ptr2->q_back = ptr;
- ptr->q_forw = ptr2;
- ptr->q_back = ptr2;
-
- class_bucket[hashval] = ptr2;
- free_zstring(d);
- return(ZERR_NONE);
- } else {
- for (ptr2 = ptr->q_forw; ptr2 != ptr; ptr2 = ptr2->q_forw)
- /* walk down the list, looking for a match */
- if ((ptr2->zct_dest.classname == d) &&
- (ptr2->zct_dest.inst == empty) &&
- (ptr2->zct_dest.recip == empty)) {
- free_zstring(d);
- return(ZSRV_CLASSXISTS);
- }
- if (!(ptr2 = triplet_alloc(d,empty,empty))) {
- free_zstring(d);
- return(ENOMEM);
- }
-
- free_zstring(d);
- ptr2->zct_acl = acl;
- xinsque(ptr2, ptr);
- return(ZERR_NONE);
+ Triplet *triplet;
+ String *d;
+ unsigned long hashval;
+
+ d = make_string(class_name,1);
+ hashval = HASHVAL(d, empty, empty);
+ for (triplet = triplet_bucket[hashval]; triplet; triplet = triplet->next) {
+ if (triplet->dest.classname == d && triplet->dest.inst == empty &&
+ triplet->dest.recip == d) {
+ free_string(d);
+ return ZSRV_CLASSXISTS;
}
+ }
+
+ /* Triplet not present in hash table, insert it. */
+ triplet = triplet_alloc(d, empty, empty);
+ free_string(d);
+ if (!triplet)
+ return ENOMEM;
+ triplet->acl = acl;
+ LIST_INSERT(&triplet_bucket[hashval], triplet);
+ return ZERR_NONE;
}
/* private routines */
/* allocate space for a class structure */
-static ZTriplet_t *
+static Triplet *
triplet_alloc(classname,inst,recipient)
- ZSTRING *classname;
- ZSTRING *inst;
- ZSTRING *recipient;
+ String *classname, *inst, *recipient;
{
- register ZTriplet_t *ptr;
- ZClientList_t *clist;
-
- if (!(ptr = (ZTriplet_t *) xmalloc(sizeof(ZTriplet_t))))
- return(NULLZT);
-
- ptr->q_forw = ptr->q_back = ptr;
- ptr->zct_dest.classname = dup_zstring(classname);
- ptr->zct_dest.inst = dup_zstring(inst);
- ptr->zct_dest.recip = dup_zstring(recipient);
-
- if (!(clist = (ZClientList_t *) xmalloc (sizeof (ZClientList_t)))) {
- xfree(ptr);
- return(NULLZT);
- }
- clist->q_forw = clist->q_back = clist;
- ptr->zct_clientlist = clist;
- ptr->zct_acl = NULLZACLT;
+ Triplet *triplet;
+ Client *clist;
- return (ptr);
-}
-
-/* allocate space for a client entry */
-
-static ZClientList_t *
-client_alloc(client)
- ZClient_t *client;
-{
- register ZClientList_t *ptr;
- if (!(ptr = (ZClientList_t *) xmalloc(sizeof(ZClientList_t))))
- return(NULLZCLT);
+ triplet = (Triplet *) malloc(sizeof(Triplet));
+ if (!triplet)
+ return NULL;
- ptr->q_forw = ptr->q_back = ptr;
- ptr->zclt_client = client;
+ triplet->dest.classname = dup_string(classname);
+ triplet->dest.inst = dup_string(inst);
+ triplet->dest.recip = dup_string(recipient);
+ triplet->clients = NULL;
+ triplet->acl = NULL;
- return(ptr);
+ return triplet;
}
/* insert a client into the list associated with the class *ptr */
static Code_t
-insert_client(ptr, client)
- ZTriplet_t *ptr;
- ZClient_t *client;
+insert_client(triplet, client, realm)
+ Triplet *triplet;
+ Client *client;
+ Realm *realm;
{
- register ZClientList_t *listp, *clist;
-
- for (clist = ptr->zct_clientlist->q_forw;
- clist != ptr->zct_clientlist;
- clist = clist->q_forw) {
- /* don't duplicate */
- if (clist->zclt_client == client)
- return(ZSRV_CLASSXISTS);
+ Client **clientp, **newclients;
+ int new_size;
+
+ if (triplet->clients) {
+ /* Avoid duplication. */
+ for (clientp = triplet->clients; *clientp; clientp++) {
+ if (*clientp == client || (realm && (*clientp)->realm == realm))
+ return ZSRV_CLASSXISTS;
}
- if (!(listp = client_alloc(client)))
- return(ENOMEM);
+ if (clientp + 1 - triplet->clients >= triplet->clients_size) {
+ new_size = triplet->clients_size * 2 + ALLOC_OFFSET;
+ newclients = (Client **) realloc(triplet->clients,
+ new_size * sizeof(Client *));
+ if (newclients == NULL)
+ return ENOMEM;
+ clientp = newclients + (clientp - triplet->clients);
+ triplet->clients = newclients;
+ triplet->clients_size = new_size;
+ }
+ } else {
+ /* Allocate an initial list of client pointers. */
+ triplet->clients = (Client **) malloc(ALLOC_INIT * sizeof(Client *));
+ if (triplet->clients == NULL)
+ return ENOMEM;
+ triplet->clients_size = ALLOC_INIT;
+ clientp = triplet->clients;
+ }
- xinsque(listp, ptr->zct_clientlist);
- return(ZERR_NONE);
+ *clientp = client;
+ clientp[1] = NULL;
+ return ZERR_NONE;
}
/*
@@ -444,70 +344,58 @@ insert_client(ptr, client)
* collecting if appropriate
*/
-static Code_t remove_client(ptr, client)
- ZTriplet_t *ptr;
- ZClient_t *client;
+static Code_t remove_client(triplet, client, realm)
+ Triplet *triplet;
+ Client *client;
+ Realm *realm;
{
- register ZClientList_t *listp = ptr->zct_clientlist;
- register ZClientList_t *listp2;
-
- if (!listp)
- return(ZSRV_BADASSOC);
- for (listp2 = listp->q_forw;
- listp2 != listp;
- listp2 = listp2->q_forw)
- /* walk down list, looking for him */
- if (listp2->zclt_client == client) {
- xremque(listp2);
- xfree(listp2);
- if (listp->q_forw == listp)
- return(EMPTY_CLASS);
- else
- return(ZERR_NONE);
- }
- return(ZSRV_BADASSOC);
+ Client **clientp;
+
+ for (clientp = triplet->clients; *clientp; clientp++) {
+ if (*clientp == client || (realm && (*clientp)->realm == realm)) {
+ for (; *clientp; clientp++)
+ *clientp = clientp[1];
+ return ZERR_NONE;
+ }
+ }
+
+ return ZSRV_BADASSOC;
}
-static void free_class(class)
- ZTriplet_t *class;
+static void free_triplet(triplet)
+ Triplet *triplet;
{
- free_zstring(class->zct_dest.classname);
- free_zstring(class->zct_dest.inst);
- free_zstring(class->zct_dest.recip);
- if (class->zct_acl != NULL)
- xfree(class->zct_acl);
- if (class->zct_clientlist != NULL)
- xfree(class->zct_clientlist);
- xfree(class);
+ if (triplet->clients)
+ free(triplet->clients);
+ free_string(triplet->dest.classname);
+ free_string(triplet->dest.inst);
+ free_string(triplet->dest.recip);
+ free(triplet);
}
-
-void class_dump_subs(fp)
- register FILE *fp;
+
+void triplet_dump_subs(fp)
+ FILE *fp;
{
int i;
- ZTriplet_t *trpq, *trp;
- ZClientList_t *cltq, *clt;
+ Triplet *triplet;
+ Client **clientp;
for (i = 0; i < HASHSIZE; i++) {
- trpq = class_bucket[i];
- if (!trpq)
- continue;
- for (trp = trpq->q_forw; trp != trpq; trp = trp->q_forw) {
+ for (triplet = triplet_bucket[i]; triplet; triplet = triplet->next) {
fputs("Triplet '", fp);
- subscr_quote(trp->zct_dest.classname->string, fp);
+ dump_quote(triplet->dest.classname->string, fp);
fputs("' '", fp);
- subscr_quote(trp->zct_dest.inst->string, fp);
+ dump_quote(triplet->dest.inst->string, fp);
fputs("' '", fp);
- subscr_quote(trp->zct_dest.recip->string, fp);
+ dump_quote(triplet->dest.recip->string, fp);
fputs("':\n", fp);
- cltq = trp->zct_clientlist;
- if (!cltq)
- continue;
- for (clt = cltq->q_forw; clt != cltq; clt = clt->q_forw) {
- fprintf(fp, "\t%s %d (%s)\n",
- inet_ntoa(clt->zclt_client->zct_sin.sin_addr),
- ntohs(clt->zclt_client->zct_sin.sin_port),
- clt->zclt_client->zct_principal->string);
+ if (triplet->clients) {
+ for (clientp = triplet->clients; *clientp; clientp++) {
+ fprintf(fp, "\t%s %d (%s)\n",
+ inet_ntoa((*clientp)->addr.sin_addr),
+ ntohs((*clientp)->addr.sin_port),
+ (*clientp)->principal->string);
+ }
}
}
}
diff --git a/server/client.c b/server/client.c
index 4646ac6..4e98f8f 100644
--- a/server/client.c
+++ b/server/client.c
@@ -12,10 +12,12 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
+#include <sys/socket.h>
#if !defined (lint) && !defined (SABER)
-static char rcsid_client_c[] =
- "$Id$";
+static const char rcsid_client_c[] =
+"$Id$";
#endif
/*
@@ -24,29 +26,26 @@ static char rcsid_client_c[] =
* Code_t client_register(notice, who, client, server, wantdefaults)
* ZNotice_t *notice;
* struct sockaddr_in *who;
- * ZClient_t **client; (RETURN)
- * ZServerDesc_t *server;
+ * Client **client; (RETURN)
+ * Server *server;
* int wantdefaults;
*
* Code_t client_deregister(client, host, flush)
- * ZClient_t *client;
- * ZHostList_t *host;
+ * Client *client;
+ * Host *host;
* int flush;
*
- * ZClient_t *client_which_client(who, notice)
+ * Client *client_which_client(who, notice)
* struct sockaddr_in *who;
* ZNotice_t *notice;
*
* void client_dump_clients(fp, clist)
* FILE *fp;
- * ZClientList_t *clist;
+ * Client *clist;
*/
-#include "zserver.h"
-#include <sys/socket.h>
-
/*
- * register a client: allocate space, find or insert the address in the
+ * a client: allocate space, find or insert the address in the
* server's list of hosts, initialize and insert the client into
* the host's list of clients.
*
@@ -54,90 +53,61 @@ static char rcsid_client_c[] =
* The caller should check by calling client_which_client
*/
+#define HASHSIZE 1024
+static Client *client_bucket[HASHSIZE];
+
+#define INET_HASH(host, port) ((htonl((host)->s_addr) + \
+ htons((unsigned short) (port))) % HASHSIZE)
+
+static Client *client_find __P((struct in_addr *host, unsigned int port));
+
Code_t
-client_register(notice, who, client, server, wantdefaults)
- ZNotice_t *notice;
- struct sockaddr_in *who;
- register ZClient_t **client;
- ZServerDesc_t *server;
- int wantdefaults;
+client_register(notice, host, client_p, wantdefaults)
+ ZNotice_t *notice;
+ struct in_addr *host;
+ Client **client_p;
+ int wantdefaults;
{
- register ZHostList_t *hlp = server->zs_hosts;
- register ZHostList_t *hlp2;
- register ZClientList_t *clist;
-
- /* chain the client's host onto this server's host list */
+ Client *client;
+ Code_t retval;
- if (!hlp) { /* bad host list */
- syslog(LOG_ERR, "cl_register: bad server host list");
- abort();
- }
+ /* chain the client's host onto this server's host list */
#if 1
- zdbug ((LOG_DEBUG, "client_register: adding %s at %s/%d",
- notice->z_sender, inet_ntoa (who->sin_addr),
- ntohs (notice->z_port)));
+ zdbug((LOG_DEBUG, "client_register: adding %s at %s/%d",
+ notice->z_sender, inet_ntoa(*host), ntohs(notice->z_port)));
#endif
- if (!notice->z_port) {
- /* must be a non-zero port # */
- return(ZSRV_BADSUBPORT);
- }
- if (!(hlp2 = hostm_find_host(&who->sin_addr))) {
- /* not here */
- return(ZSRV_HNOTFOUND);
- }
+ if (!notice->z_port)
+ return ZSRV_BADSUBPORT;
- /* hlp2 is now pointing to the client's host's address struct */
-
- if (!hlp2->zh_clients) {
- return(EINVAL);
- }
-
- /* allocate a client struct */
- if (!(*client = (ZClient_t *) xmalloc(sizeof(ZClient_t))))
- return(ENOMEM);
-
- (*client)->last_msg = 0;
- (*client)->last_check = 0;
- (*client)->last_send = 0;
-
- if (!(clist = (ZClientList_t *) xmalloc(sizeof(ZClientList_t)))) {
- xfree(*client);
- return(ENOMEM);
- }
-
- clist->q_forw = clist->q_back = clist;
- clist->zclt_client = *client;
-
- /* initialize the struct */
- (void) memset((caddr_t) &(*client)->zct_sin, 0,
- sizeof(struct sockaddr_in));
+ *client_p = client = client_find(host, notice->z_port);
+ if (!client) {
+ *client_p = client = (Client *) malloc(sizeof(Client));
+ if (!client)
+ return ENOMEM;
+ memset(&client->addr, 0, sizeof(struct sockaddr_in));
#ifdef KERBEROS
- (void) memset((caddr_t) &(*client)->zct_cblock, 0,
- sizeof((*client)->zct_cblock));
+ memset(&client->session_key, 0, sizeof(client->session_key));
#endif
- (*client)->zct_sin.sin_addr.s_addr = who->sin_addr.s_addr;
- (*client)->zct_sin.sin_port = notice->z_port;
- (*client)->zct_sin.sin_family = AF_INET;
- (*client)->zct_subs = NULLZST;
- (*client)->zct_principal = make_zstring(notice->z_sender,0);
-
- /* chain him in to the clients list in the host list*/
-
- START_CRITICAL_CODE;
-
- xinsque(clist, hlp2->zh_clients);
-
- END_CRITICAL_CODE;
-
- if (!server->zs_dumping && wantdefaults)
- /* add default subscriptions only if this is not
- resulting from a brain dump, AND this request
- wants defaults */
- return(subscr_def_subs(*client));
- else
- return(ZERR_NONE);
+ client->last_msg = 0;
+ client->last_send = 0;
+ client->addr.sin_family = AF_INET;
+ client->addr.sin_addr.s_addr = host->s_addr;
+ client->addr.sin_port = notice->z_port;
+ client->subs = NULL;
+ client->realm = NULL;
+ client->principal = make_string(notice->z_sender, 0);
+ LIST_INSERT(&client_bucket[INET_HASH(&client->addr.sin_addr,
+ notice->z_port)], client);
+ }
+
+ /* Add default subscriptions only if this is not resulting from a brain
+ * dump, AND this request wants defaults. */
+ if (!bdumping && wantdefaults)
+ return subscr_def_subs(client);
+ else
+ return ZERR_NONE;
}
/*
@@ -147,81 +117,73 @@ client_register(notice, who, client, server, wantdefaults)
*/
void
-client_deregister(client, host, flush)
- ZClient_t *client;
- ZHostList_t *host;
- int flush;
+client_deregister(client, flush)
+ Client *client;
+ int flush;
+{
+ LIST_DELETE(client);
+ nack_release(client);
+ subscr_cancel_client(client);
+ free_string(client->principal);
+ if (flush)
+ uloc_flush_client(&client->addr);
+ free(client);
+}
+
+void
+client_flush_host(host)
+ struct in_addr *host;
{
- ZClientList_t *clients;
-
- START_CRITICAL_CODE;
-
- /* release any not-acked packets in the rexmit queue */
- nack_release(client);
-
- /* release subscriptions */
- (void) subscr_cancel_client(client);
-
- if (flush)
- /* release locations if this is a punted client */
- (void) uloc_flush_client(&client->zct_sin);
-
- /* unthread and release this client */
-
- if (host->zh_clients)
- for (clients = host->zh_clients->q_forw;
- clients != host->zh_clients;
- clients = clients->q_forw)
- if (clients->zclt_client == client) {
- xremque(clients);
- free_zstring(client->zct_principal);
- xfree(client);
- xfree(clients);
- END_CRITICAL_CODE;
- return;
- }
- syslog(LOG_CRIT, "clt_dereg: clt not in host list");
- abort();
- /*NOTREACHED*/
+ int i;
+ Client *client, *next;
+
+ for (i = 0; i < HASHSIZE; i++) {
+ for (client = client_bucket[i]; client; client = next) {
+ next = client->next;
+ if (client->addr.sin_addr.s_addr == host->s_addr)
+ client_deregister(client, 1);
+ }
+ }
+ uloc_hflush(host);
}
/*
* find the client which sent the notice
*/
-ZClient_t *
-client_which_client(who, notice)
- struct sockaddr_in *who;
- ZNotice_t *notice;
+Client *
+client_which_client(host, notice)
+ struct in_addr *host;
+ ZNotice_t *notice;
{
- register ZHostList_t *hlt;
- register ZClientList_t *clients;
+ return client_find(host, notice->z_port);
+}
- if (!(hlt = hostm_find_host(&who->sin_addr))) {
-#if 0
- zdbug((LOG_DEBUG,"cl_wh_clt: host not found"));
-#endif
- return(NULLZCNT);
+Code_t
+client_send_clients()
+{
+ int i;
+ Client *client;
+ Code_t retval;
+
+ for (i = 0; i < HASHSIZE; i++) {
+ /* Allow packets to be processed between rows of the hash table. */
+ if (packets_waiting()) {
+ bdumping = 0;
+ bdump_concurrent = 1;
+ handle_packet();
+ bdump_concurrent = 0;
+ bdumping = 1;
}
-
- if (!hlt->zh_clients) {
-#if 1
- zdbug((LOG_DEBUG,"cl_wh_clt: no clients"));
-#endif
- return(NULLZCNT);
+ for (client = client_bucket[i]; client; client = client->next) {
+ if (client->subs) {
+ retval = subscr_send_subs(client);
+ if (retval != ZERR_NONE)
+ return retval;
+ }
}
-
- for (clients = hlt->zh_clients->q_forw;
- clients != hlt->zh_clients;
- clients = clients->q_forw)
- if (clients->zclt_client->zct_sin.sin_port == notice->z_port) {
- return(clients->zclt_client);
- }
-
-#if 1
- zdbug((LOG_DEBUG, "cl_wh_clt: no port"));
-#endif
- return(NULLZCNT);
+ }
+ return ZERR_NONE;
}
/*
@@ -231,17 +193,35 @@ client_which_client(who, notice)
*/
void
-client_dump_clients(fp, clist)
- FILE *fp;
- ZClientList_t *clist;
+client_dump_clients(fp)
+ FILE *fp;
{
- register ZClientList_t *ptr;
-
- for (ptr = clist->q_forw; ptr != clist; ptr = ptr->q_forw) {
- (void) fprintf(fp, "\t%d (%s):\n",
- ntohs(ptr->zclt_client->zct_sin.sin_port),
- ptr->zclt_client->zct_principal->string);
- subscr_dump_subs(fp, ptr->zclt_client->zct_subs);
+ Client *client;
+ int i;
+
+ for (i = 0; i < HASHSIZE; i++) {
+ for (client = client_bucket[i]; client; client = client->next) {
+ fprintf(fp, "\t%d (%s):\n", ntohs(client->addr.sin_port),
+ client->principal->string);
+ subscr_dump_subs(fp, client->subs);
}
- return;
+ }
}
+
+static Client *
+client_find(host, port)
+ struct in_addr *host;
+ unsigned int port;
+{
+ Client *client;
+ long hashval;
+
+ hashval = INET_HASH(host, port);
+ for (client = client_bucket[hashval]; client; client = client->next) {
+ if (client->addr.sin_addr.s_addr == host->s_addr
+ && client->addr.sin_port == port)
+ return client;
+ }
+ return NULL;
+}
+
diff --git a/server/common.c b/server/common.c
index 87585b9..bff30a9 100644
--- a/server/common.c
+++ b/server/common.c
@@ -12,90 +12,78 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
#ifndef lint
#ifndef SABER
-static char rcsid_common_c[] =
+static const char rcsid_common_c[] =
"$Id$";
#endif /* SABER */
#endif /* lint */
-#include <zephyr/zephyr.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <syslog.h>
-#include <string.h>
-#include "unix.h"
-
/* common routines for the server */
-/* copy the string into newly allocated area */
+/* copy a string into a newly allocated area */
char *
-#ifdef __STDC__
-strsave (Zconst char *sp)
-#else
strsave (sp)
- Zconst char *sp;
-#endif
+ const char *sp;
{
- register char *ret;
+ char *ret;
- if((ret = (char *) xmalloc((unsigned) strlen(sp)+1)) == NULL) {
- syslog(LOG_ERR, "no mem strdup'ing");
- abort();
+ ret = (char *) malloc(strlen(sp) + 1);
+ if (!ret) {
+ syslog(LOG_CRIT, "no mem strdup'ing");
+ abort();
}
- (void) strcpy(ret,sp);
- return(ret);
+ strcpy(ret, sp);
+ return ret;
}
/* The "& 0x5f" provides case-insensitivity for ASCII. */
unsigned long
-#ifdef __STDC__
-hash (Zconst char *string)
-#else
-hash (string)
- Zconst char *string;
-#endif
+hash(string)
+ const char *string;
{
- register unsigned long hval = 0;
- register char cp;
-
- while (1) {
- cp = *string++;
- if (!cp)
- break;
- hval += cp & 0x5f;
-
- cp = *string++;
- if (!cp)
- break;
- hval += (cp & 0x5f) * (3 + (1 << 16));
-
- cp = *string++;
- if (!cp)
- break;
- hval += (cp & 0x5f) * (1 + (1 << 8));
-
- cp = *string++;
- if (!cp)
- break;
- hval += (cp & 0x5f) * (1 + (1 << 12));
-
- cp = *string++;
- if (!cp)
- break;
- hval += (cp & 0x5f) * (1 + (1 << 4));
-
- hval += ((long) hval) >> 18;
- }
- hval &= 0x7fffffff;
- return hval;
+ unsigned long hval = 0;
+ char cp;
+
+ while (1) {
+ cp = *string++;
+ if (!cp)
+ break;
+ hval += cp & 0x5f;
+
+ cp = *string++;
+ if (!cp)
+ break;
+ hval += (cp & 0x5f) * (3 + (1 << 16));
+
+ cp = *string++;
+ if (!cp)
+ break;
+ hval += (cp & 0x5f) * (1 + (1 << 8));
+
+ cp = *string++;
+ if (!cp)
+ break;
+ hval += (cp & 0x5f) * (1 + (1 << 12));
+
+ cp = *string++;
+ if (!cp)
+ break;
+ hval += (cp & 0x5f) * (1 + (1 << 4));
+
+ hval += ((long) hval) >> 18;
+ }
+
+ hval &= 0x7fffffff;
+ return hval;
}
/* Output a name, replacing newlines with \n and single quotes with \q. */
-void subscr_quote(p, fp)
+void dump_quote(p, fp)
char *p;
FILE *fp;
{
diff --git a/server/dispatch.c b/server/dispatch.c
index 2c2fb16..fed2336 100644
--- a/server/dispatch.c
+++ b/server/dispatch.c
@@ -12,21 +12,28 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
+#include <sys/socket.h>
#ifndef lint
#ifndef SABER
-static char rcsid_dispatch_c[] =
- "$Id$";
+static const char rcsid_dispatch_c[] =
+"$Id$";
#endif
#endif
-#include "zserver.h"
-#include <sys/socket.h>
+#define NACKTAB_HASHSIZE 1023
+#define NACKTAB_HASHVAL(sockaddr, uid) (((sockaddr).sin_addr.s_addr ^ \
+ (sockaddr).sin_port ^ \
+ (uid).zuid_addr.s_addr ^ \
+ (uid).tv.tv_sec ^ \
+ (uid).tv.tv_usec) % NACKTAB_HASHSIZE)
+#define HOSTS_SIZE_INIT 256
#ifdef DEBUG
-Zconst char *ZNoticeKinds[9] = {"UNSAFE", "UNACKED", "ACKED", "HMACK",
- "HMCTL", "SERVACK", "SERVNAK", "CLIENTACK",
- "STAT"};
+ZCONST char *ZNoticeKinds[9] = {"UNSAFE", "UNACKED", "ACKED", "HMACK",
+ "HMCTL", "SERVACK", "SERVNAK", "CLIENTACK",
+ "STAT"};
#endif
/*
*
@@ -40,10 +47,10 @@ Zconst char *ZNoticeKinds[9] = {"UNSAFE", "UNACKED", "ACKED", "HMACK",
* void clt_ack(notice, who, sent)
* ZNotice_t *notice;
* struct sockaddr_in *who;
- * ZSentType sent;
+ * Sent_type sent;
*
* void nack_release(client)
- * ZClient_t *client;
+ * Client *client;
*
* void sendit(notice, auth, who)
* ZNotice_t *notice;
@@ -54,69 +61,59 @@ Zconst char *ZNoticeKinds[9] = {"UNSAFE", "UNACKED", "ACKED", "HMACK",
* ZNotice_t *notice;
* struct sockaddr_in *dest;
* int auth;
- * ZClient_t *client;
+ * Client *client;
*/
-/* patchable magic numbers controlling the retransmission rate and count */
-int num_rexmits = NUM_REXMITS;
-long rexmit_secs = REXMIT_SECS;
-long abs_timo = REXMIT_SECS*NUM_REXMITS + 10;
+String *class_control, *class_admin, *class_hm, *class_ulogin, *class_ulocate;
-ZSTRING *class_control, *class_admin, *class_hm, *class_ulogin,
- *class_ulocate;
+int rexmit_times[] = REXMIT_TIMES;
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static void nack_cancel P((register ZNotice_t *, struct sockaddr_in *));
-static void dispatch P((ZNotice_t *, int, struct sockaddr_in *, int));
-static int send_to_dest P((ZNotice_t *, int, ZDestination *dest, int));
+static void nack_cancel __P((ZNotice_t *, struct sockaddr_in *));
+static void dispatch __P((ZNotice_t *, int, struct sockaddr_in *, int));
+static int send_to_dest __P((ZNotice_t *, int, Destination *dest, int, int));
+static void hostm_deathgram __P((struct sockaddr_in *, Server *));
+static char *hm_recipient __P((void));
-#undef P
+Statistic realm_notices = {0, "inter-realm notices"};
+Statistic interserver_notices = {0, "inter-server notices"};
+Statistic hm_packets = {0, "hostmanager packets"};
+Statistic control_notices = {0, "client control notices"};
+Statistic message_notices = {0, "message notices"};
+Statistic login_notices = {0, "login notices"};
+Statistic i_s_ctls = {0, "inter-server control notices"};
+Statistic i_s_logins = {0, "inter-server login notices"};
+Statistic i_s_admins = {0, "inter-server admin notices"};
+Statistic i_s_locates = {0, "inter-server locate notices"};
+Statistic locate_notices = {0, "locate notices"};
+Statistic admin_notices = {0, "admin notices"};
-ZStatistic interserver_notices = {0, "inter-server notices"};
-ZStatistic hm_packets = {0, "hostmanager packets"};
-ZStatistic control_notices = {0, "client control notices"};
-ZStatistic message_notices = {0, "message notices"};
-ZStatistic login_notices = {0, "login notices"};
-ZStatistic i_s_ctls = {0, "inter-server control notices"};
-ZStatistic i_s_logins = {0, "inter-server login notices"};
-ZStatistic i_s_admins = {0, "inter-server admin notices"};
-ZStatistic i_s_locates = {0, "inter-server locate notices"};
-ZStatistic locate_notices = {0, "locate notices"};
-ZStatistic admin_notices = {0, "admin notices"};
+static Unacked *nacktab[NACKTAB_HASHSIZE];
+static struct in_addr *hosts;
+static int hosts_size = 0, num_hosts = 0;
static void
-#ifdef __STDC__
-dump_stats (void *arg)
-#else
dump_stats (arg)
-void *arg;
-#endif
+ void *arg;
{
- syslog(LOG_INFO, "stats: %s: %d", hm_packets.str, hm_packets.val);
- syslog(LOG_INFO, "stats: %s: %d", control_notices.str,
- control_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", message_notices.str,
- message_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", login_notices.str,
- login_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", locate_notices.str,
- locate_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", admin_notices.str,
- admin_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", interserver_notices.str,
- interserver_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", i_s_ctls.str, i_s_ctls.val);
- syslog(LOG_INFO, "stats: %s: %d", i_s_logins.str, i_s_logins.val);
- syslog(LOG_INFO, "stats: %s: %d", i_s_admins.str, i_s_admins.val);
- syslog(LOG_INFO, "stats: %s: %d", i_s_locates.str, i_s_locates.val);
- /* log stuff once an hour */
- (void) timer_set_rel ((long) 6*60*60, dump_stats, arg);
+ syslog(LOG_INFO, "stats: %s: %d", hm_packets.str, hm_packets.val);
+ syslog(LOG_INFO, "stats: %s: %d", control_notices.str,
+ control_notices.val);
+ syslog(LOG_INFO, "stats: %s: %d", message_notices.str,
+ message_notices.val);
+ syslog(LOG_INFO, "stats: %s: %d", login_notices.str, login_notices.val);
+ syslog(LOG_INFO, "stats: %s: %d", locate_notices.str, locate_notices.val);
+ syslog(LOG_INFO, "stats: %s: %d", admin_notices.str, admin_notices.val);
+ syslog(LOG_INFO, "stats: %s: %d", realm_notices.str, realm_notices.val);
+ syslog(LOG_INFO, "stats: %s: %d", interserver_notices.str,
+ interserver_notices.val);
+ syslog(LOG_INFO, "stats: %s: %d", i_s_ctls.str, i_s_ctls.val);
+ syslog(LOG_INFO, "stats: %s: %d", i_s_logins.str, i_s_logins.val);
+ syslog(LOG_INFO, "stats: %s: %d", i_s_admins.str, i_s_admins.val);
+ syslog(LOG_INFO, "stats: %s: %d", i_s_locates.str, i_s_locates.val);
+
+ /* log stuff once an hour */
+ timer_set_rel ((long) 6*60*60, dump_stats, arg);
}
/*
@@ -127,123 +124,104 @@ void *arg;
void
handle_packet()
{
- Code_t status;
- ZPacket_t input_packet; /* from the network */
- ZNotice_t new_notice; /* parsed from input_packet */
- int input_len; /* len of packet */
- struct sockaddr_in input_sin; /* Zconstructed for authent */
- struct sockaddr_in whoisit; /* for holding peer's address */
- int authentic; /* authentic flag */
- ZSrvPending_t *pending; /* pending packet */
- ZHostList_t *host; /* host ptr */
- int from_server; /* packet is from another server */
+ Code_t status;
+ ZPacket_t input_packet; /* from the network */
+ ZNotice_t new_notice; /* parsed from input_packet */
+ int input_len; /* len of packet */
+ struct sockaddr_in input_sin; /* Zconstructed for authent */
+ struct sockaddr_in whoisit; /* for holding peer's address */
+ int authentic; /* authentic flag */
+ Pending *pending; /* pending packet */
+ int from_server; /* packet is from another server */
+ Realm *realm; /* foreign realm ptr */
#ifdef DEBUG
- static int first_time = 1;
+ static int first_time = 1;
#endif
#ifdef DEBUG
- /* Dump statistics five minutes after startup */
- if (first_time) {
- first_time = 0;
- (void) timer_set_rel (5*60, dump_stats, (void *) 0);
- }
-#endif
- /* handle traffic */
-
- if (otherservers[me_server_idx].zs_update_queue) {
- /* something here for me; take care of it */
-#if 1
- zdbug((LOG_DEBUG, "internal queue process"));
+ /* Dump statistics five minutes after startup */
+ if (first_time) {
+ first_time = 0;
+ timer_set_rel(5*60, dump_stats, NULL);
+ }
#endif
+ /* handle traffic */
- pending = otherservers[me_server_idx].zs_update_queue->q_forw;
- host = hostm_find_host(&(pending->pend_who.sin_addr));
- if (host && host->zh_locked) {
- /* can't deal with it now. to preserve ordering,
- we can't process other packets, esp. since we
- may block since we don't really know if there
- are things in the real queue. */
+ if (otherservers[me_server_idx].queue) {
+ /* something here for me; take care of it */
#if 1
- zdbug((LOG_DEBUG,"host %s is locked",
- inet_ntoa(host->zh_addr.sin_addr)));
+ zdbug((LOG_DEBUG, "internal queue process"));
#endif
- return;
- }
- pending = server_dequeue(me_server); /* we can do it, remove */
-
- if ((status = ZParseNotice(pending->pend_packet,
- pending->pend_len,
- &new_notice)) != ZERR_NONE) {
- syslog(LOG_ERR,
- "bad notice parse (%s): %s",
- inet_ntoa(pending->pend_who.sin_addr),
- error_message(status));
- } else
- dispatch(&new_notice, pending->pend_auth,
- &pending->pend_who, 1);
- server_pending_free(pending);
- return;
- }
- /*
- * nothing in internal queue, go to the external library
- * queue/socket
- */
- if ((status = ZReceivePacket(input_packet,
- &input_len,
- &whoisit)) != ZERR_NONE) {
- syslog(LOG_ERR,
- "bad packet receive: %s from %s",
- error_message(status), inet_ntoa(whoisit.sin_addr));
- return;
- }
- npackets++;
- if ((status = ZParseNotice(input_packet,
- input_len,
- &new_notice)) != ZERR_NONE) {
- syslog(LOG_ERR,
- "bad notice parse (%s): %s",
- inet_ntoa(whoisit.sin_addr),
- error_message(status));
- return;
- }
- if (server_which_server(&whoisit)) {
- /* we need to parse twice--once to get
- the source addr, second to check
- authentication */
- (void) memset((caddr_t) &input_sin, 0,
- sizeof(input_sin));
- input_sin.sin_addr.s_addr = new_notice.z_sender_addr.s_addr;
- input_sin.sin_port = new_notice.z_port;
- input_sin.sin_family = AF_INET;
- authentic = ZCheckAuthentication(&new_notice, &input_sin);
- from_server = 1;
+
+ pending = server_dequeue(me_server);
+
+ status = ZParseNotice(pending->packet, pending->len, &new_notice);
+ if (status != ZERR_NONE) {
+ syslog(LOG_ERR, "bad notice parse (%s): %s",
+ inet_ntoa(pending->who.sin_addr), error_message(status));
} else {
- from_server = 0;
- authentic = ZCheckAuthentication(&new_notice, &whoisit);
+ dispatch(&new_notice, pending->auth, &pending->who, 1);
}
- switch (authentic) {
- case ZAUTH_YES:
- authentic = 1;
- break;
- case ZAUTH_FAILED:
- case ZAUTH_NO:
- default:
- authentic = 0;
- break;
+ server_pending_free(pending);
+ return;
+ }
+
+ /*
+ * nothing in internal queue, go to the external library
+ * queue/socket
+ */
+ status = ZReceivePacket(input_packet, &input_len, &whoisit);
+ if (status != ZERR_NONE) {
+ syslog(LOG_ERR, "bad packet receive: %s from %s",
+ error_message(status), inet_ntoa(whoisit.sin_addr));
+ return;
+ }
+ npackets++;
+ status = ZParseNotice(input_packet, input_len, &new_notice);
+ if (status != ZERR_NONE) {
+ syslog(LOG_ERR, "bad notice parse (%s): %s",
+ inet_ntoa(whoisit.sin_addr), error_message(status));
+ return;
+ }
+ if (server_which_server(&whoisit)) {
+ /* we need to parse twice--once to get
+ the source addr, second to check
+ authentication */
+ memset(&input_sin, 0, sizeof(input_sin));
+ input_sin.sin_addr.s_addr = new_notice.z_sender_addr.s_addr;
+ input_sin.sin_port = new_notice.z_port;
+ input_sin.sin_family = AF_INET;
+ realm = realm_which_realm(&input_sin);
+ if (realm) {
+ authentic = ZCheckRealmAuthentication(&new_notice, &input_sin,
+ realm->name);
+ } else {
+ authentic = ZCheckAuthentication(&new_notice, &input_sin);
}
- if (whoisit.sin_port != hm_port &&
- strcasecmp (new_notice.z_class,ZEPHYR_ADMIN_CLASS) &&
- whoisit.sin_port != sock_sin.sin_port &&
- new_notice.z_kind != CLIENTACK) {
- syslog(LOG_ERR,
- "bad port %s/%d",
- inet_ntoa(whoisit.sin_addr),
- ntohs(whoisit.sin_port));
- return;
+ from_server = 1;
+ } else {
+ from_server = 0;
+ realm = realm_which_realm(&whoisit);
+ if (realm) {
+ authentic = ZCheckRealmAuthentication(&new_notice, &whoisit,
+ realm->name);
+ } else {
+ authentic = ZCheckAuthentication(&new_notice, &whoisit);
}
- message_notices.val++;
- dispatch(&new_notice, authentic, &whoisit, from_server);
+ }
+
+ if (whoisit.sin_port != hm_port && whoisit.sin_port != hm_srv_port &&
+ strcasecmp(new_notice.z_class, ZEPHYR_ADMIN_CLASS) != 0 &&
+ whoisit.sin_port != srv_addr.sin_port &&
+ new_notice.z_kind != CLIENTACK) {
+ syslog(LOG_ERR, "bad port %s/%d", inet_ntoa(whoisit.sin_addr),
+ ntohs(whoisit.sin_port));
return;
+ }
+
+ message_notices.val++;
+ dispatch(&new_notice, authentic, &whoisit, from_server);
+ return;
}
/*
* Dispatch a notice.
@@ -251,88 +229,110 @@ handle_packet()
static void
dispatch(notice, auth, who, from_server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- int from_server;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ int from_server;
{
- Code_t status;
- ZSTRING *notice_class;
- struct sockaddr_in who2;
+ Code_t status;
+ String *notice_class;
+ struct sockaddr_in who2;
+ int authflag;
+ Realm *realm;
+ char *cp;
#ifdef DEBUG
- char dbg_buf[BUFSIZ];
+ char dbg_buf[BUFSIZ];
#endif
- if ((int) notice->z_kind < (int) UNSAFE ||
- (int) notice->z_kind > (int) CLIENTACK) {
- syslog(LOG_NOTICE, "bad notice kind 0x%x from %s",
- (int) notice->z_kind,
- inet_ntoa(who->sin_addr));
- return;
- }
+ /* Set "authflag" to 1 or 0 for handler functions. Treat
+ * ZAUTH_CKSUM_FAILED as authentic except for sendit(), which is
+ * handled below. */
+ switch (auth) {
+ case ZAUTH_YES:
+ case ZAUTH_CKSUM_FAILED:
+ authflag = 1;
+ break;
+ case ZAUTH_FAILED:
+ case ZAUTH_NO:
+ default:
+ authflag = 0;
+ break;
+ }
+
+ if ((int) notice->z_kind < (int) UNSAFE ||
+ (int) notice->z_kind > (int) CLIENTACK) {
+ syslog(LOG_NOTICE, "bad notice kind 0x%x from %s", notice->z_kind,
+ inet_ntoa(who->sin_addr));
+ return;
+ }
#if 0
- if (zdebug) {
- (void) sprintf (dbg_buf,
- "disp:%s '%s' '%s' '%s' notice to '%s' from '%s' %s/%d/%d",
- ZNoticeKinds[(int) notice->z_kind],
- notice->z_class,
- notice->z_class_inst,
- notice->z_opcode,
- notice->z_recipient,
- notice->z_sender,
- inet_ntoa(who->sin_addr),
- ntohs(who->sin_port),
- ntohs(notice->z_port));
- syslog (LOG_DEBUG, "%s", dbg_buf);
- }
+ if (zdebug) {
+ sprintf(dbg_buf,
+ "disp:%s '%s' '%s' '%s' notice to '%s' from '%s' %s/%d/%d",
+ ZNoticeKinds[(int) notice->z_kind], notice->z_class,
+ notice->z_class_inst, notice->z_opcode, notice->z_recipient,
+ notice->z_sender, inet_ntoa(who->sin_addr),
+ ntohs(who->sin_port), ntohs(notice->z_port));
+ syslog(LOG_DEBUG, "%s", dbg_buf);
+ }
#endif
- if (notice->z_kind == CLIENTACK) {
- nack_cancel(notice, who);
- return;
- }
+ if (notice->z_kind == CLIENTACK) {
+ nack_cancel(notice, who);
+ return;
+ }
- who2 = *who;
+ who2 = *who;
#if 0
- if (0 && from_server) {
- /* incorporate server_dispatch here */
- }
+ if (0 && from_server) {
+ /* incorporate server_dispatch here */
+ }
#endif
- notice_class = make_zstring(notice->z_class,1);
-
- if (from_server) {
- interserver_notices.val++;
- status = server_dispatch(notice, auth, who);
- } else if (class_is_hm(notice_class)) {
- hm_packets.val++;
- status = hostm_dispatch(notice, auth, who, me_server);
- } else if (class_is_control(notice_class)) {
- control_notices.val++;
- status = control_dispatch(notice, auth, who, me_server);
- } else if (class_is_ulogin(notice_class)) {
- login_notices.val++;
- status = ulogin_dispatch(notice, auth, who, me_server);
- } else if (class_is_ulocate(notice_class)) {
- locate_notices.val++;
- status = ulocate_dispatch(notice, auth, who, me_server);
- } else if (class_is_admin(notice_class)) {
- admin_notices.val++;
- status = server_adispatch(notice, auth, who, me_server);
+ notice_class = make_string(notice->z_class,1);
+
+ if (from_server) {
+ interserver_notices.val++;
+ status = server_dispatch(notice, authflag, who);
+ } else if (class_is_hm(notice_class)) {
+ hm_packets.val++;
+ status = hostm_dispatch(notice, authflag, who, me_server);
+ } else if (realm_which_realm(who) && !(class_is_admin(notice_class))) {
+ realm_notices.val++;
+ status = realm_dispatch(notice, authflag, who, me_server);
+ } else if (class_is_control(notice_class)) {
+ control_notices.val++;
+ status = control_dispatch(notice, authflag, who, me_server);
+ } else if (class_is_ulogin(notice_class)) {
+ login_notices.val++;
+ status = ulogin_dispatch(notice, authflag, who, me_server);
+ } else if (class_is_ulocate(notice_class)) {
+ locate_notices.val++;
+ status = ulocate_dispatch(notice, authflag, who, me_server);
+ } else if (class_is_admin(notice_class)) {
+ admin_notices.val++;
+ status = server_adispatch(notice, authflag, who, me_server);
+ } else {
+ if (auth == ZAUTH_CKSUM_FAILED)
+ authflag = 0;
+ if (!bound_for_local_realm(notice)) {
+ cp = strchr(notice->z_recipient, '@');
+ if (!cp ||
+ !(realm = realm_get_realm_by_name(realm_expand_realm(cp + 1))))
+ sendit(notice, authflag, who, 0);
+ else
+ realm_handoff(notice, authflag, who, realm, 1);
} else {
- sendit (notice, auth, who);
- free_zstring(notice_class);
- return;
+ if (notice->z_recipient[0] == '@')
+ notice->z_recipient = "";
+ sendit(notice, authflag, who, 1);
}
+ free_string(notice_class);
+ return;
+ }
- if (status == ZSRV_REQUEUE) {
-#ifdef CONCURRENT
- server_self_queue(notice, auth, who);
-#else
- syslog(LOG_ERR, "requeue while not concurr");
- abort();
-#endif
- }
- free_zstring(notice_class);
+ if (status == ZSRV_REQUEUE)
+ server_self_queue(notice, authflag, who);
+ free_string(notice_class);
}
/*
@@ -340,101 +340,113 @@ dispatch(notice, auth, who, from_server)
*/
void
-sendit(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+sendit(notice, auth, who, external)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ int external;
{
- static int send_counter = 0;
- int any = 0;
- ZAcl_t *acl;
- ZDestination dest;
- ZSTRING *class;
-
- class = make_zstring(notice->z_class,1);
- if ((acl = class_get_acl(class)) != NULLZACLT) {
- /* if controlled and not auth, fail */
- if (!auth) {
- syslog(LOG_WARNING, "sendit unauthentic %s from %s",
- notice->z_class, notice->z_sender);
- clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
- return;
- }
- /* if not auth to transmit, fail */
- if (!access_check(notice->z_sender, acl, TRANSMIT)) {
- syslog(LOG_WARNING, "sendit unauthorized %s from %s",
- notice->z_class, notice->z_sender);
- clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
- return;
- }
- /* sender != inst and not auth to send to others --> fail */
- if ((strcmp (notice->z_sender, notice->z_class_inst)) &&
- (!access_check(notice->z_sender, acl, INSTUID))) {
- syslog(LOG_WARNING,
- "sendit unauth uid %s %s.%s",
- notice->z_sender,
- notice->z_class,
- notice->z_class_inst);
+ static int send_counter = 0;
+ char recipbuf[ANAME_SZ + INST_SZ + REALM_SZ + 3], *recipp;
+ int any = 0;
+ Acl *acl;
+ Destination dest;
+ String *class;
+
+ class = make_string(notice->z_class, 1);
+ acl = class_get_acl(class);
+ if (acl != NULL) {
+ /* if controlled and not auth, fail */
+ if (!auth) {
+ syslog(LOG_WARNING, "sendit unauthentic %s from %s",
+ notice->z_class, notice->z_sender);
clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
+ free_string(class);
return;
- }
}
+ /* if not auth to transmit, fail */
+ if (!access_check(notice->z_sender, acl, TRANSMIT)) {
+ syslog(LOG_WARNING, "sendit unauthorized %s from %s",
+ notice->z_class, notice->z_sender);
+ clt_ack(notice, who, AUTH_FAILED);
+ free_string(class);
+ return;
+ }
+ /* sender != inst and not auth to send to others --> fail */
+ if (strcmp(notice->z_sender, notice->z_class_inst) != 0 &&
+ !access_check(notice->z_sender, acl, INSTUID)) {
+ syslog(LOG_WARNING, "sendit unauth uid %s %s.%s", notice->z_sender,
+ notice->z_class, notice->z_class_inst);
+ clt_ack(notice, who, AUTH_FAILED);
+ free_string(class);
+ return;
+ }
+ }
+ if (!realm_which_realm(who)) {
if (memcmp(&notice->z_sender_addr.s_addr, &who->sin_addr.s_addr,
sizeof(notice->z_sender_addr.s_addr))) {
/* someone is playing games... */
/* inet_ntoa returns pointer to static area */
/* max size is 255.255.255.255 */
char buffer[16];
- (void) strcpy(buffer, inet_ntoa(who->sin_addr));
+ strcpy(buffer, inet_ntoa(who->sin_addr));
if (!auth) {
- syslog(LOG_WARNING, "sendit unauthentic fake packet: claimed %s, real %s",
+ syslog(LOG_WARNING,
+ "sendit unauthentic fake packet: claimed %s, real %s",
inet_ntoa(notice->z_sender_addr), buffer);
clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
+ free_string(class);
return;
}
if (ntohl(notice->z_sender_addr.s_addr) != 0) {
- syslog(LOG_WARNING, "sendit invalid address: claimed %s, real %s",
+ syslog(LOG_WARNING,
+ "sendit invalid address: claimed %s, real %s",
inet_ntoa(notice->z_sender_addr), buffer);
clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
+ free_string(class);
return;
}
syslog(LOG_WARNING, "sendit addr mismatch: claimed %s, real %s",
inet_ntoa(notice->z_sender_addr), buffer);
}
-
- /* Increment the send counter, used to prevent duplicate sends to
- * clients. On the off-chance that we wrap around to 0, skip over
- * it to prevent missing clients which have never had a packet
- * sent to them. */
- send_counter++;
- if (send_counter == 0)
- send_counter = 1;
-
- /* Send to clients subscribed to the triplet itself. */
- dest.classname = class;
- dest.inst = make_zstring(notice->z_class_inst, 1);
- dest.recip = make_zstring(notice->z_recipient, 0);
- if (send_to_dest(notice, auth, &dest, send_counter))
- any = 1;
-
- /* Send to clients subscribed to the triplet with the instance
- * substituted with the wildcard instance. */
- free_zstring(dest.inst);
- dest.inst = wildcard_instance;
- if (send_to_dest(notice, auth, &dest, send_counter))
- any = 1;
-
- free_zstring(class);
- free_zstring(dest.recip);
- if (any)
- ack(notice, who);
- else
- nack(notice, who);
+ }
+
+ /* Increment the send counter, used to prevent duplicate sends to
+ * clients. On the off-chance that we wrap around to 0, skip over
+ * it to prevent missing clients which have never had a packet
+ * sent to them. */
+ send_counter++;
+ if (send_counter == 0)
+ send_counter = 1;
+
+ /* Send to clients subscribed to the triplet itself. */
+ dest.classname = class;
+ dest.inst = make_string(notice->z_class_inst, 1);
+ if (bound_for_local_realm(notice) && *notice->z_recipient == '@') {
+ dest.recip = make_string("", 0);
+ } else {
+ strncpy(recipbuf, notice->z_recipient, sizeof(recipbuf));
+ recipp = strrchr(&recipbuf, '@');
+ if (recipp)
+ sprintf(recipp + 1, "%s", realm_expand_realm(recipp + 1));
+ dest.recip = make_string(recipbuf, 0);
+ }
+ if (send_to_dest(notice, auth, &dest, send_counter, external))
+ any = 1;
+
+ /* Send to clients subscribed to the triplet with the instance
+ * substituted with the wildcard instance. */
+ free_string(dest.inst);
+ dest.inst = wildcard_instance;
+ if (send_to_dest(notice, auth, &dest, send_counter, external))
+ any = 1;
+
+ free_string(class);
+ free_string(dest.recip);
+ if (any)
+ ack(notice, who);
+ else
+ nack(notice, who);
}
/*
@@ -444,59 +456,59 @@ sendit(notice, auth, who)
*/
static int
-send_to_dest(notice, auth, dest, send_counter)
- ZNotice_t *notice;
- int auth;
- ZDestination *dest;
- int send_counter;
+send_to_dest(notice, auth, dest, send_counter, external)
+ ZNotice_t *notice;
+ int auth;
+ Destination *dest;
+ int send_counter;
+ int external;
{
- register ZClientList_t *list, *p;
- register ZClient_t *client;
- register int any = 0;
-
- list = triplet_lookup(dest);
- if (list != NULLZCLT) {
- for (p = list->q_forw; p != list; p = p->q_forw) {
- client = p->zclt_client;
- if (client->last_send == send_counter)
- continue;
- client->last_send = send_counter;
- xmit(notice, &(client->zct_sin), auth, client);
- any = 1;
- }
- }
- return any;
+ Client **clientp;
+ int any = 0;
+
+ clientp = triplet_lookup(dest);
+ if (!clientp)
+ return 0;
+
+ for (; *clientp; clientp++) {
+ if ((*clientp)->last_send == send_counter)
+ continue;
+ (*clientp)->last_send = send_counter;
+ if ((*clientp)->realm && external)
+ realm_handoff(notice, auth, &clientp[0]->addr, clientp[0]->realm,
+ 1);
+ else
+ xmit(notice, &((*clientp)->addr), auth, *clientp);
+ any = 1;
+ }
+
+ return any;
}
/*
- * Clean up the not-yet-acked queue and release anything destined
- * for the client.
+ * Release anything destined for the client in the not-yet-acked table.
*/
void
nack_release(client)
- ZClient_t *client;
+ Client *client;
{
- register ZNotAcked_t *nacked, *nack2;
-
- /* search the not-yet-acked list for anything destined to him, and
- flush it. */
- for (nacked = nacklist->q_forw;
- nacked != nacklist;)
- if ((nacked->na_addr.sin_addr.s_addr == client->zct_sin.sin_addr.s_addr) &&
- (nacked->na_addr.sin_port == client->zct_sin.sin_port)) {
- /* go back, since remque will change things */
- nack2 = nacked->q_back;
- timer_reset(nacked->na_timer);
- xremque(nacked);
- xfree(nacked->na_packet);
- xfree(nacked);
- /* now that the remque adjusted the linked list,
- we go forward again */
- nacked = nack2->q_forw;
- } else
- nacked = nacked->q_forw;
- return;
+ int i;
+ Unacked *nacked, *next;
+
+ for (i = 0; i < NACKTAB_HASHSIZE; i++) {
+ for (nacked = nacktab[i]; nacked; nacked = next) {
+ next = nacked->next;
+ if (nacked->dest.addr.sin_addr.s_addr ==
+ client->addr.sin_addr.s_addr &&
+ nacked->dest.addr.sin_port == client->addr.sin_port) {
+ timer_reset(nacked->timer);
+ LIST_DELETE(nacked);
+ free(nacked->packet);
+ free(nacked);
+ }
+ }
+ }
}
/*
@@ -508,53 +520,50 @@ nack_release(client)
/*ARGSUSED*/
Code_t
xmit_frag(notice, buf, len, waitforack)
- ZNotice_t *notice;
- char *buf;
- int len;
- int waitforack;
+ ZNotice_t *notice;
+ char *buf;
+ int len;
+ int waitforack;
{
- char *savebuf;
- register ZNotAcked_t *nacked;
- Code_t retval;
-
- if ((retval = ZSendPacket(buf, len, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "xmit_frag send: %s",
- error_message(retval));
- return(retval);
- }
-
- /* now we've sent it, mark it as not ack'ed */
-
- if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) {
- /* no space: just punt */
- syslog(LOG_WARNING, "xmit_frag nack malloc");
- return(ENOMEM);
- }
-
- if (!(savebuf = (char *)xmalloc(len))) {
- /* no space: just punt */
- syslog(LOG_WARNING, "xmit_frag pack malloc");
- return(ENOMEM);
- }
-
- (void) memcpy(savebuf, buf, len);
-
- nacked->na_rexmits = 0;
- nacked->na_packet = savebuf;
- nacked->na_srv_idx = 0;
- nacked->na_addr = ZGetDestAddr();
- nacked->na_packsz = len;
- nacked->na_uid = notice->z_uid;
- nacked->q_forw = nacked->q_back = nacked;
- nacked->na_abstimo = NOW + abs_timo;
-
- /* set a timer to retransmit when done */
- nacked->na_timer = timer_set_rel(rexmit_secs,
- rexmit,
- (void *) nacked);
- /* chain in */
- xinsque(nacked, nacklist);
- return(ZERR_NONE);
+ struct sockaddr_in sin;
+ char *savebuf;
+ Unacked *nacked;
+ Code_t retval;
+ int hashval;
+
+ retval = ZSendPacket(buf, len, 0);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "xmit_frag send: %s", error_message(retval));
+ return retval;
+ }
+
+ /* now we've sent it, mark it as not ack'ed */
+ nacked = (Unacked *) malloc(sizeof(Unacked));
+ if (!nacked) {
+ /* no space: just punt */
+ syslog(LOG_WARNING, "xmit_frag nack malloc");
+ return ENOMEM;
+ }
+
+ savebuf = (char *) malloc(len);
+ if (!savebuf) {
+ /* no space: just punt */
+ syslog(LOG_WARNING, "xmit_frag pack malloc");
+ free(nacked);
+ return ENOMEM;
+ }
+
+ memcpy(savebuf, buf, len);
+
+ sin = ZGetDestAddr();
+ nacked->rexmits = 0;
+ nacked->packet = savebuf;
+ nacked->dest.addr = sin;
+ nacked->packsz = len;
+ nacked->uid = notice->z_uid;
+ nacked->timer = timer_set_rel(rexmit_times[0], rexmit, nacked);
+ LIST_INSERT(&nacktab[NACKTAB_HASHVAL(sin, nacked->uid)], nacked);
+ return(ZERR_NONE);
}
/*
@@ -564,115 +573,97 @@ xmit_frag(notice, buf, len, waitforack)
void
xmit(notice, dest, auth, client)
- ZNotice_t *notice;
- struct sockaddr_in *dest;
- int auth;
- ZClient_t *client;
+ ZNotice_t *notice;
+ struct sockaddr_in *dest;
+ int auth;
+ Client *client;
{
- caddr_t noticepack;
- register ZNotAcked_t *nacked;
- int packlen;
- Code_t retval;
+ char *noticepack;
+ Unacked *nacked;
+ int packlen;
+ Code_t retval;
#if 0
- zdbug((LOG_DEBUG,"xmit"));
+ zdbug((LOG_DEBUG,"xmit"));
#endif
- if (!(noticepack = (caddr_t) xmalloc(sizeof(ZPacket_t)))) {
- syslog(LOG_ERR, "xmit malloc");
- return; /* DON'T put on nack list */
+ noticepack = (char *) malloc(sizeof(ZPacket_t));
+ if (!noticepack) {
+ syslog(LOG_ERR, "xmit malloc");
+ return; /* DON'T put on nack list */
+ }
+
+ packlen = sizeof(ZPacket_t);
+
+ if (auth && client) { /*
+ we are distributing authentic and
+ we have a pointer to auth info
+ */
+#ifdef ZEPHYR_USES_KERBEROS
+ retval = ZFormatAuthenticNotice(notice, noticepack, packlen, &packlen,
+ client->session_key);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "xmit auth format: %s", error_message(retval));
+ free(noticepack);
+ return;
}
-
- packlen = sizeof(ZPacket_t);
-
- if (auth && client) { /*
- we are distributing authentic and
- we have a pointer to auth info
- */
-#ifdef KERBEROS
-
- if ((retval = ZFormatAuthenticNotice(notice,
- noticepack,
- packlen,
- &packlen,
- client->zct_cblock))
- != ZERR_NONE) {
- syslog(LOG_ERR, "xmit auth format: %s",
- error_message(retval));
- xfree(noticepack);
- return;
- }
-#else /* !KERBEROS */
- notice->z_auth = 1;
- if ((retval = ZFormatSmallRawNotice(notice,
- noticepack,
- &packlen))
- != ZERR_NONE) {
- syslog(LOG_ERR, "xmit auth/raw format: %s",
- error_message(retval));
- xfree(noticepack);
- return;
- }
-#endif /* KERBEROS */
- } else {
- notice->z_auth = 0;
- notice->z_authent_len = 0;
- notice->z_ascii_authent = (char *)"";
- if ((retval = ZFormatSmallRawNotice(notice,
- noticepack,
- &packlen)) != ZERR_NONE) {
- syslog(LOG_ERR, "xmit format: %s",
- error_message(retval));
- xfree(noticepack);
- return; /* DON'T put on nack list */
- }
+#else /* !ZEPHYR_USES_KERBEROS */
+ notice->z_auth = 1;
+ retval = ZFormatSmallRawNotice(notice, noticepack, &packlen);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "xmit auth/raw format: %s", error_message(retval));
+ free(noticepack);
+ return;
+ }
+#endif /* ZEPHYR_USES_KERBEROS */
+ } else {
+ notice->z_auth = 0;
+ notice->z_authent_len = 0;
+ notice->z_ascii_authent = (char *)"";
+ retval = ZFormatSmallRawNotice(notice, noticepack, &packlen);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "xmit format: %s", error_message(retval));
+ free(noticepack);
+ return; /* DON'T put on nack list */
}
+ }
#if 0
- zdbug((LOG_DEBUG," to %s/%d",inet_ntoa(dest->sin_addr),
- ntohs(dest->sin_port)));
+ zdbug((LOG_DEBUG," to %s/%d", inet_ntoa(dest->sin_addr),
+ ntohs(dest->sin_port)));
#endif
- if ((retval = ZSetDestAddr(dest)) != ZERR_NONE) {
- syslog(LOG_WARNING, "xmit set addr: %s",
- error_message(retval));
- xfree(noticepack);
- return;
- }
- if ((retval = ZSendPacket(noticepack, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "xmit xmit: (%s/%d) %s",
- inet_ntoa(dest->sin_addr), ntohs(dest->sin_port),
- error_message(retval));
- xfree(noticepack);
- return;
- }
-
- /* now we've sent it, mark it as not ack'ed */
-
- if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) {
- /* no space: just punt */
- syslog(LOG_WARNING, "xmit nack malloc");
- xfree(noticepack);
- return;
- }
+ retval = ZSetDestAddr(dest);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "xmit set addr: %s", error_message(retval));
+ free(noticepack);
+ return;
+ }
+ retval = ZSendPacket(noticepack, packlen, 0);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "xmit xmit: (%s/%d) %s", inet_ntoa(dest->sin_addr),
+ ntohs(dest->sin_port), error_message(retval));
+ free(noticepack);
+ return;
+ }
- nacked->na_rexmits = 0;
- nacked->na_packet = noticepack;
- nacked->na_srv_idx = 0; /* XXX */
- nacked->na_addr = *dest;
- nacked->na_packsz = packlen;
- nacked->na_uid = notice->z_uid;
- nacked->q_forw = nacked->q_back = nacked;
- nacked->na_abstimo = NOW + abs_timo;
-
- /* set a timer to retransmit when done */
- nacked->na_timer = timer_set_rel(rexmit_secs,
- rexmit,
- (void *) nacked);
- /* chain in */
- xinsque(nacked, nacklist);
+ /* now we've sent it, mark it as not ack'ed */
+ nacked = (Unacked *) malloc(sizeof(Unacked));
+ if (!nacked) {
+ /* no space: just punt */
+ syslog(LOG_WARNING, "xmit nack malloc");
+ free(noticepack);
+ return;
+ }
+
+ nacked->rexmits = 0;
+ nacked->packet = noticepack;
+ nacked->dest.addr = *dest;
+ nacked->packsz = packlen;
+ nacked->uid = notice->z_uid;
+ nacked->timer = timer_set_rel(rexmit_times[0], rexmit, nacked);
+ LIST_INSERT(&nacktab[NACKTAB_HASHVAL(*dest, nacked->uid)], nacked);
}
-
/*
* Retransmit the packet specified. If we have timed out or retransmitted
* too many times, punt the packet and initiate the host recovery algorithm
@@ -680,67 +671,59 @@ xmit(notice, dest, auth, client)
*/
void
-#ifdef __STDC__
-rexmit(void *arg)
-#else
rexmit(arg)
- void *arg;
-#endif
+ void *arg;
{
- register ZNotAcked_t *nackpacket = (ZNotAcked_t*) arg;
- int retval;
- ZNotice_t dummy_notice;
- register ZClient_t *client;
+ Unacked *nacked = (Unacked *) arg;
+ int retval;
+ ZNotice_t dummy_notice;
+ Client *client;
#if 1
- zdbug((LOG_DEBUG,"rexmit"));
+ syslog(LOG_DEBUG, "rexmit %s/%d #%d time %d",
+ inet_ntoa(nacked->dest.addr.sin_addr),
+ ntohs(nacked->dest.addr.sin_port), nacked->rexmits + 1, NOW);
#endif
- if (++(nackpacket->na_rexmits) > num_rexmits ||
- NOW > nackpacket->na_abstimo) {
- /* possibly dead client */
-
- dummy_notice.z_port = nackpacket->na_addr.sin_port;
-
- client = client_which_client(&nackpacket->na_addr,
- &dummy_notice);
-
- /* unlink & free packet */
- xremque(nackpacket);
- xfree(nackpacket->na_packet);
- xfree(nackpacket);
-
- /* initiate recovery */
- if (client)
- server_recover(client);
- return;
+ nacked->rexmits++;
+ if (rexmit_times[nacked->rexmits] == -1) {
+ /* Unresponsive client, find it in our database. */
+ dummy_notice.z_port = nacked->dest.addr.sin_port;
+ client = client_which_client(&nacked->dest.addr.sin_addr,
+ &dummy_notice);
+
+ /* unlink & free nacked */
+ LIST_DELETE(nacked);
+ free(nacked->packet);
+ free(nacked);
+
+ /* Kill the client. */
+ if (client) {
+ server_kill_clt(client);
+ client_deregister(client, 1);
}
- /* retransmit the packet */
-
-#if 0
- zdbug((LOG_DEBUG," to %s/%d",
- inet_ntoa(nackpacket->na_addr.sin_addr),
- ntohs(nackpacket->na_addr.sin_port)));
-#endif
- if ((retval = ZSetDestAddr(&nackpacket->na_addr))
- != ZERR_NONE) {
- syslog(LOG_WARNING, "rexmit set addr: %s",
- error_message(retval));
- goto requeue;
-
- }
- if ((retval = ZSendPacket(nackpacket->na_packet,
- nackpacket->na_packsz, 0)) != ZERR_NONE)
- syslog(LOG_WARNING, "rexmit xmit: %s", error_message(retval));
-
-requeue:
- /* reset the timer */
- nackpacket->na_timer = timer_set_rel(rexmit_secs,
- rexmit,
- (void *) nackpacket);
return;
+ }
+ /* retransmit the packet */
+#if 0
+ zdbug((LOG_DEBUG," to %s/%d", inet_ntoa(nacked->dest.addr.sin_addr),
+ ntohs(nacked->dest.addr.sin_port)));
+#endif
+ retval = ZSetDestAddr(&nacked->dest.addr);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "rexmit set addr: %s", error_message(retval));
+ } else {
+ retval = ZSendPacket(nacked->packet, nacked->packsz, 0);
+ if (retval != ZERR_NONE)
+ syslog(LOG_WARNING, "rexmit xmit: %s", error_message(retval));
+ }
+
+ /* reset the timer */
+ nacked->timer = timer_set_rel(rexmit_times[nacked->rexmits], rexmit,
+ nacked);
+ return;
}
/*
@@ -752,93 +735,81 @@ requeue:
void
clt_ack(notice, who, sent)
- ZNotice_t *notice;
- struct sockaddr_in *who;
- ZSentType sent;
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ Sent_type sent;
{
- ZNotice_t acknotice;
- ZPacket_t ackpack;
- int packlen;
- int notme = 0;
- char *sent_name;
- Code_t retval;
-
- if (bdumping) { /* don't ack while dumping */
+ ZNotice_t acknotice;
+ ZPacket_t ackpack;
+ int packlen;
+ int notme = 0;
+ char *sent_name;
+ Code_t retval;
+
+ if (bdumping) { /* don't ack while dumping */
#if 1
- zdbug((LOG_DEBUG,"bdumping, no ack"));
-#endif
- return;
- }
-
- acknotice = *notice;
-
- acknotice.z_kind = SERVACK;
- switch (sent) {
- case SENT:
- acknotice.z_message = ZSRVACK_SENT;
- sent_name = "sent";
- break;
- case NOT_FOUND:
- acknotice.z_message = ZSRVACK_FAIL;
- acknotice.z_kind = SERVNAK;
- sent_name = "fail";
- break;
- case AUTH_FAILED:
- acknotice.z_kind = SERVNAK;
- acknotice.z_message = ZSRVACK_NOTSENT;
- sent_name = "nak/not_sent";
- break;
- case NOT_SENT:
- acknotice.z_message = ZSRVACK_NOTSENT;
- sent_name = "not_sent";
- break;
- default:
- abort ();
- }
-
-#if 0
- zdbug((LOG_DEBUG,"clt_ack type %s for %d to %s/%d",
- sent_name,
- ntohs(notice->z_port),
- inet_ntoa(who->sin_addr),
- ntohs(who->sin_port)));
+ zdbug((LOG_DEBUG,"bdumping, no ack"));
#endif
+ return;
+ }
+
+ acknotice = *notice;
+
+ acknotice.z_kind = SERVACK;
+ switch (sent) {
+ case SENT:
+ acknotice.z_message = ZSRVACK_SENT;
+ sent_name = "sent";
+ break;
+ case NOT_FOUND:
+ acknotice.z_message = ZSRVACK_FAIL;
+ acknotice.z_kind = SERVNAK;
+ sent_name = "fail";
+ break;
+ case AUTH_FAILED:
+ acknotice.z_kind = SERVNAK;
+ acknotice.z_message = ZSRVACK_NOTSENT;
+ sent_name = "nak/not_sent";
+ break;
+ case NOT_SENT:
+ acknotice.z_message = ZSRVACK_NOTSENT;
+ sent_name = "not_sent";
+ break;
+ default:
+ abort ();
+ }
- if (!server_which_server(who) &&
- (hostm_find_server(&who->sin_addr) != me_server)) {
#if 0
- zdbug((LOG_DEBUG,"not me"));
+ zdbug((LOG_DEBUG,"clt_ack type %s for %d to %s/%d", sent_name,
+ ntohs(notice->z_port), inet_ntoa(who->sin_addr),
+ ntohs(who->sin_port)));
#endif
- notme = 1;
- }
- acknotice.z_multinotice = "";
+ acknotice.z_multinotice = "";
- /* leave room for the trailing null */
- acknotice.z_message_len = strlen(acknotice.z_message) + 1;
+ /* leave room for the trailing null */
+ acknotice.z_message_len = strlen(acknotice.z_message) + 1;
- packlen = sizeof(ackpack);
+ packlen = sizeof(ackpack);
- if ((retval = ZFormatSmallRawNotice(&acknotice,
- ackpack,
- &packlen)) != ZERR_NONE) {
- syslog(LOG_ERR, "clt_ack format: %s",error_message(retval));
- return;
- }
- if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "clt_ack set addr: %s",
- error_message(retval));
- return;
- }
- if ((retval = ZSendPacket(ackpack, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "clt_ack xmit: %s", error_message(retval));
- return;
- }
- else
- zdbug ((LOG_DEBUG, "packet sent"));
- if (notme)
- hostm_deathgram(who, me_server);
+ retval = ZFormatSmallRawNotice(&acknotice, ackpack, &packlen);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "clt_ack format: %s", error_message(retval));
return;
+ }
+ retval = ZSetDestAddr(who);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "clt_ack set addr: %s", error_message(retval));
+ return;
+ }
+ retval = ZSendPacket(ackpack, packlen, 0);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "clt_ack xmit: %s", error_message(retval));
+ return;
+ } else {
+ zdbug((LOG_DEBUG, "packet sent"));
+ }
+ return;
}
/*
@@ -848,36 +819,36 @@ clt_ack(notice, who, sent)
static void
nack_cancel(notice, who)
- register ZNotice_t *notice;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
{
- register ZNotAcked_t *nacked;
+ Unacked *nacked;
+ int hashval;
- /* search the not-yet-acked list for this packet, and
- flush it. */
+ /* search the not-yet-acked table for this packet, and flush it. */
#if 0
- zdbug((LOG_DEBUG, "nack_cancel: %s:%08X,%08X",
- inet_ntoa (notice->z_uid.zuid_addr),
- notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
+ zdbug((LOG_DEBUG, "nack_cancel: %s:%08X,%08X",
+ inet_ntoa(notice->z_uid.zuid_addr),
+ notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
#endif
- for (nacked = nacklist->q_forw;
- nacked != nacklist;
- nacked = nacked->q_forw)
- if ((nacked->na_addr.sin_addr.s_addr == who->sin_addr.s_addr) &&
- (nacked->na_addr.sin_port == who->sin_port))
- if (ZCompareUID(&nacked->na_uid, &notice->z_uid)) {
- timer_reset(nacked->na_timer);
- xfree(nacked->na_packet);
- xremque(nacked);
- xfree(nacked);
- return;
- }
+ hashval = NACKTAB_HASHVAL(*who, notice->z_uid);
+ for (nacked = nacktab[hashval]; nacked; nacked = nacked->next) {
+ if (nacked->dest.addr.sin_addr.s_addr == who->sin_addr.s_addr
+ && nacked->dest.addr.sin_port == who->sin_port
+ && ZCompareUID(&nacked->uid, &notice->z_uid)) {
+ timer_reset(nacked->timer);
+ free(nacked->packet);
+ LIST_DELETE(nacked);
+ free(nacked);
+ return;
+ }
+ }
+
#if 1
- zdbug((LOG_DEBUG,"nack_cancel: nack not found %s:%08X,%08X",
- inet_ntoa (notice->z_uid.zuid_addr),
- notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
+ zdbug((LOG_DEBUG,"nack_cancel: nack not found %s:%08X,%08X",
+ inet_ntoa (notice->z_uid.zuid_addr),
+ notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
#endif
- return;
}
/* for compatibility when sending subscription information to old clients */
@@ -885,184 +856,329 @@ nack_cancel(notice, who)
#define OLD_ZEPHYR_VERSION "ZEPH0.0"
#endif /* OLD_COMPAT */
+/* Dispatch an HM_CTL notice. */
+
+Code_t
+hostm_dispatch(notice, auth, who, server)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
+{
+ Server *owner;
+ char *opcode = notice->z_opcode;
+ Code_t retval;
+ int i, add = 0, remove = 0;
+
+#if 0
+ zdbug((LOG_DEBUG,"hm_disp"));
+#endif
+
+ if (notice->z_kind == HMACK) {
+ /* Ignore. */
+ ;
+ } else if (notice->z_kind != HMCTL) {
+#if 0
+ zdbug((LOG_DEBUG, "bogus HM packet"));
+#endif
+ clt_ack(notice, who, AUTH_FAILED);
+ } else if (strcmp(opcode, HM_FLUSH) == 0) {
+ client_flush_host(&who->sin_addr);
+ if (server == me_server)
+ server_forward(notice, auth, who);
+ } else if (strcmp(opcode, HM_BOOT) == 0) {
+ client_flush_host(&who->sin_addr);
+ if (server == me_server) {
+ server_forward(notice, auth, who);
+ ack(notice, who);
+ add = 1;
+ }
+ } else if (strcmp(opcode, HM_ATTACH) == 0) {
+ if (server == me_server) {
+ server_forward(notice, auth, who);
+ ack(notice, who);
+ add = 1;
+ } else {
+ remove = 1;
+ }
+ } else if (strcmp(opcode, HM_DETACH) == 0) {
+ remove = 1;
+ } else {
+ syslog(LOG_WARNING, "hm_dispatch: unknown opcode %s", opcode);
+ }
+
+ if (add) {
+ for (i = 0; i < num_hosts; i++) {
+ if (hosts[i].s_addr == who->sin_addr.s_addr)
+ break;
+ }
+ if (i == num_hosts) {
+ if (hosts_size == 0) {
+ hosts = (struct in_addr *) malloc(HOSTS_SIZE_INIT *
+ sizeof(struct in_addr));
+ if (!hosts)
+ return ENOMEM;
+ hosts_size = HOSTS_SIZE_INIT;
+ } else if (num_hosts == hosts_size) {
+ hosts = (struct in_addr *) realloc(hosts, hosts_size * 2 *
+ sizeof(struct in_addr));
+ if (!hosts)
+ return ENOMEM;
+ hosts_size *= 2;
+ }
+ hosts[num_hosts++] = who->sin_addr;
+ }
+ } else if (remove) {
+ for (i = 0; i < num_hosts; i++) {
+ if (hosts[i].s_addr == who->sin_addr.s_addr) {
+ memmove(&hosts[i], &hosts[i + 1], num_hosts - (i + 1));
+ num_hosts--;
+ break;
+ }
+ }
+ }
+ return ZERR_NONE;
+}
+
/*
* Dispatch a ZEPHYR_CTL notice.
*/
Code_t
control_dispatch(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
{
- register char *opcode = notice->z_opcode;
- ZClient_t *client;
- ZHostList_t *host;
- Code_t retval;
- int wantdefs;
-
- /*
- * ZEPHYR_CTL Opcodes expected are:
- * BOOT (inst HM): host has booted; flush data.
- * CLIENT_SUBSCRIBE: process with the subscription mananger.
- * CLIENT_UNSUBSCRIBE: ""
- * CLIENT_CANCELSUB: ""
- */
-
- zdbug ((LOG_DEBUG, "ctl_disp: opc=%s", opcode));
-
- if (!strcasecmp (notice->z_class_inst, ZEPHYR_CTL_HM))
- return(hostm_dispatch(notice, auth, who, server));
- else if (!strcmp (opcode, CLIENT_GIMMESUBS) ||
- !strcmp (opcode, CLIENT_GIMMEDEFS)) {
- /* this special case is before the auth check so that
- someone who has no subscriptions does NOT get a SERVNAK
- but rather an empty list. Note we must therefore
- check authentication inside subscr_sendlist */
+ char *opcode = notice->z_opcode;
+ Client *client;
+ Code_t retval;
+ int wantdefs;
+ Realm *realm;
+ struct sockaddr_in newwho;
+
+ /*
+ * ZEPHYR_CTL Opcodes expected are:
+ * BOOT (inst HM): host has booted; flush data.
+ * CLIENT_SUBSCRIBE: process with the subscription mananger.
+ * CLIENT_UNSUBSCRIBE: ""
+ * CLIENT_CANCELSUB: ""
+ */
+
+ zdbug((LOG_DEBUG, "ctl_disp: opc=%s", opcode));
+
+ newwho.sin_addr.s_addr = notice->z_sender_addr.s_addr;
+ newwho.sin_port = notice->z_port;
+ realm = realm_which_realm(&newwho);
+ if (realm)
+ return(realm_control_dispatch(notice, auth, who, server, realm));
+
+ if (strcasecmp(notice->z_class_inst, ZEPHYR_CTL_HM) == 0) {
+ return hostm_dispatch(notice, auth, who, server);
+ } else if (strcmp(opcode, CLIENT_GIMMESUBS) == 0 ||
+ strcmp(opcode, CLIENT_GIMMEDEFS) == 0) {
+ /* this special case is before the auth check so that
+ someone who has no subscriptions does NOT get a SERVNAK
+ but rather an empty list. Note we must therefore
+ check authentication inside subscr_sendlist */
#ifdef OLD_COMPAT
- /* only acknowledge if *not* old version; the old version
- acknowledges the packet with the reply */
- if (strcmp (notice->z_version, OLD_ZEPHYR_VERSION))
- ack(notice, who);
+ /* only acknowledge if *not* old version; the old version
+ acknowledges the packet with the reply */
+ if (strcmp(notice->z_version, OLD_ZEPHYR_VERSION) != 0)
+ ack(notice, who);
#else /* !OLD_COMPAT */
- ack(notice, who);
+ ack(notice, who);
#endif /* OLD_COMPAT */
- subscr_sendlist(notice, auth, who);
- return(ZERR_NONE);
- } else if (!auth) {
+ subscr_sendlist(notice, auth, who);
+ return ZERR_NONE;
+ } else if (!auth) {
#if 0
- zdbug((LOG_DEBUG,"unauth ctrl_disp"));
+ zdbug((LOG_DEBUG,"unauth ctrl_disp"));
#endif
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return ZERR_NONE;
+ }
+
+ wantdefs = strcmp(opcode, CLIENT_SUBSCRIBE_NODEFS);
+ if (!wantdefs || strcmp(opcode, CLIENT_SUBSCRIBE) == 0) {
+ /* subscription notice */
+ retval = client_register(notice, &who->sin_addr, &client, wantdefs);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_NOTICE, "subscr %s/%s/%d failed: %s",
+ notice->z_sender, inet_ntoa(who->sin_addr),
+ ntohs(notice->z_port), error_message(retval));
+ if (server == me_server) {
+ if (retval == ZSRV_BADSUBPORT)
+ clt_ack(notice, who, AUTH_FAILED);
+ else
+ nack(notice, who);
+ }
+ return(ZERR_NONE);
}
-
- /* the rest of the expected opcodes modify state; check for
- unlocked host first */
- host = hostm_find_host(&who->sin_addr);
- if (host && host->zh_locked)
- return(ZSRV_REQUEUE);
-
- wantdefs = strcmp (opcode, CLIENT_SUBSCRIBE_NODEFS);
- if (!wantdefs || !strcmp (opcode, CLIENT_SUBSCRIBE)) {
- /* subscription notice */
- if (!(client = client_which_client(who, notice))) {
- if ((retval = client_register(notice,
- who,
- &client,
- server,
- wantdefs)) != ZERR_NONE)
- {
- syslog(LOG_NOTICE,
- "subscr. register %s/%s/%d failed: %s",
- notice->z_sender,
- inet_ntoa(who->sin_addr),
- ntohs(notice->z_port),
- error_message(retval));
- if (server == me_server) {
- if (retval == ZSRV_BADSUBPORT) {
- clt_ack(notice, who, AUTH_FAILED);
- } else
- hostm_deathgram(who, me_server);
- }
- return(ZERR_NONE);
- }
- if (!(client = client_which_client(who, notice))) {
- syslog(LOG_CRIT, "subscr reg. failure");
- abort();
- }
- }
- if (strcmp (client->zct_principal->string, notice->z_sender)) {
- /* you may only subscribe for your own clients */
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
-#ifdef KERBEROS
- /* in case it's changed */
- (void) memcpy((caddr_t) client->zct_cblock, (caddr_t) ZGetSession(),
- sizeof(C_Block));
+ if (strcmp(client->principal->string, notice->z_sender) != 0) {
+ /* you may only subscribe for your own clients */
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return ZERR_NONE;
+ }
+#ifdef ZEPHYR_USES_KERBEROS
+ /* in case it's changed */
+ memcpy(client->session_key, ZGetSession(), sizeof(C_Block));
#endif
- if ((retval = subscr_subscribe(client,notice)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr failed: %s",
- error_message(retval));
- if (server == me_server)
- nack(notice, who);
- return(ZERR_NONE);
- }
- } else if (!strcmp(opcode, CLIENT_UNSUBSCRIBE)) {
- if ((client = client_which_client(who,notice)) != NULLZCNT) {
- if (strcmp(client->zct_principal->string, notice->z_sender)) {
- /* you may only cancel for your own clients */
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
+ retval = subscr_subscribe(client, notice);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr failed: %s", error_message(retval));
+ if (server == me_server)
+ nack(notice, who);
+ return ZERR_NONE;
+ }
+ } else if (strcmp(opcode, CLIENT_UNSUBSCRIBE) == 0) {
+ client = client_which_client(&who->sin_addr, notice);
+ if (client != NULL) {
+ if (strcmp(client->principal->string, notice->z_sender) != 0) {
+ /* you may only cancel for your own clients */
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return ZERR_NONE;
+ }
#if 0
- if (zdebug) {
- if (server == me_server)
- syslog (LOG_DEBUG,
- "subscription cancel for %s/%d\n",
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port));
- else
- syslog (LOG_DEBUG,
- "subscription cancel for %s/%d from %s\n",
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port),
- server->addr);
- }
-#endif
- (void) subscr_cancel(who, notice);
+ if (zdebug) {
+ if (server == me_server) {
+ syslog(LOG_DEBUG, "subscription cancel for %s/%d\n",
+ inet_ntoa(who->sin_addr), ntohs(who->sin_port));
} else {
- nack(notice, who);
- return(ZERR_NONE);
+ syslog(LOG_DEBUG,
+ "subscription cancel for %s/%d from %s\n",
+ inet_ntoa(who->sin_addr), ntohs(who->sin_port),
+ server->addr_str);
}
- } else if (!strcmp(opcode, CLIENT_CANCELSUB)) {
- /* canceling subscriptions implies I can punt info about
- this client */
- if ((client = client_which_client(who,notice)) != NULLZCNT) {
- if (strcmp(client->zct_principal->string, notice->z_sender)) {
- /* you may only cancel for your own clients */
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
- if (host) {
- /* don't flush locations here, let him
- do it explicitly */
+ }
+#endif
+ subscr_cancel(who, notice);
+ } else {
+ nack(notice, who);
+ return ZERR_NONE;
+ }
+ } else if (strcmp(opcode, CLIENT_CANCELSUB) == 0) {
+ /* canceling subscriptions implies I can punt info about this client */
+ client = client_which_client(&who->sin_addr, notice);
+ if (client == NULL) {
#if 0
- zdbug((LOG_DEBUG, "cancelsub clt_dereg %s/%d",
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port)));
+ zdbug((LOG_DEBUG,"can_sub not found client"));
#endif
- hostm_lose_ignore(client);
- (void) client_deregister(client, host, 0);
- }
-
- }
- if (!client || !host) {
+ if (server == me_server)
+ nack(notice, who);
+ return ZERR_NONE;
+ }
+ if (strcmp(client->principal->string, notice->z_sender) != 0) {
+ /* you may only cancel for your own clients */
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return ZERR_NONE;
+ }
+ /* don't flush locations here, let him do it explicitly */
#if 0
- zdbug((LOG_DEBUG,"can_sub not found client"));
+ zdbug((LOG_DEBUG, "cancelsub clt_dereg %s/%d",
+ inet_ntoa(who->sin_addr), ntohs(who->sin_port)));
#endif
- if (server == me_server)
- nack(notice, who);
- return(ZERR_NONE);
- }
+ client_deregister(client, 0);
+ } else {
+ syslog(LOG_WARNING, "unknown ctl opcode %s", opcode);
+ if (server == me_server)
+ nack(notice, who);
+ return ZERR_NONE;
+ }
+
+ if (server == me_server) {
+ ack(notice, who);
+ server_forward(notice, auth, who);
+ }
+ return ZERR_NONE;
+}
+
+void
+hostm_shutdown()
+{
+ int i, s, newserver;
+ struct sockaddr_in sin;
+
+ for (i = 0; i < nservers; i++) {
+ if (i != me_server_idx && otherservers[i].state == SERV_UP)
+ break;
+ }
+ newserver = (i < nservers);
+ for (i = 0; i < num_hosts; i++) {
+ sin.sin_addr = hosts[i];
+ sin.sin_port = hm_port;
+ if (newserver) {
+ while (1) {
+ s = (random() % (nservers - 1)) + 1;
+ if (otherservers[s].state == SERV_UP)
+ break;
+ }
+ hostm_deathgram(&sin, &otherservers[s]);
} else {
- syslog(LOG_WARNING, "unknown ctl opcode %s", opcode);
- if (server == me_server)
- nack(notice, who);
- return(ZERR_NONE);
+ hostm_deathgram(&sin, NULL);
}
+ }
+}
- if (server == me_server) {
- ack(notice, who);
- server_forward(notice, auth, who);
- }
- return(ZERR_NONE);
+static void
+hostm_deathgram(sin, server)
+ struct sockaddr_in *sin;
+ Server *server;
+{
+ Code_t retval;
+ int shutlen;
+ ZNotice_t shutnotice;
+ char *shutpack;
+
+ shutnotice.z_kind = HMCTL;
+ shutnotice.z_port = sin->sin_port; /* we are sending it */
+ shutnotice.z_class = HM_CTL_CLASS;
+ shutnotice.z_class_inst = HM_CTL_SERVER;
+ shutnotice.z_opcode = SERVER_SHUTDOWN;
+ shutnotice.z_sender = HM_CTL_SERVER;
+ shutnotice.z_recipient = hm_recipient();
+ shutnotice.z_default_format = "";
+ shutnotice.z_num_other_fields = 0;
+ shutnotice.z_message = (server) ? server->addr_str : NULL;
+ shutnotice.z_message_len = (server) ? strlen(server->addr_str) + 1 : 0;
+
+ retval = ZFormatNotice(&shutnotice, &shutpack, &shutlen, ZNOAUTH);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "hm_shut format: %s",error_message(retval));
+ return;
+ }
+ retval = ZSetDestAddr(sin);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "hm_shut set addr: %s", error_message(retval));
+ free(shutpack);
+ return;
+ }
+ retval = ZSendPacket(shutpack, shutlen, 0);
+ if (retval != ZERR_NONE)
+ syslog(LOG_WARNING, "hm_shut xmit: %s", error_message(retval));
+ free(shutpack);
+}
+
+static char *
+hm_recipient()
+{
+ static char *recipient;
+ char *realm;
+
+ if (recipient)
+ return recipient;
+
+ realm = ZGetRealm();
+ if (!realm)
+ realm = "???";
+ recipient = (char *) malloc(strlen(realm) + 4);
+ strcpy (recipient, "hm@");
+ strcat (recipient, realm);
+ return recipient;
}
-
diff --git a/server/dispatch.c.auth b/server/dispatch.c.auth
deleted file mode 100644
index 8707c2f..0000000
--- a/server/dispatch.c.auth
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains functions for dispatching a notice.
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- *
- * Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#ifndef lint
-#ifndef SABER
-static char rcsid_dispatch_c[] =
- "$Id$";
-#endif
-#endif
-
-#include "zserver.h"
-#include <sys/socket.h>
-
-#ifdef DEBUG
-Zconst char *ZNoticeKinds[9] = {"UNSAFE", "UNACKED", "ACKED", "HMACK",
- "HMCTL", "SERVACK", "SERVNAK", "CLIENTACK",
- "STAT"};
-#endif
-/*
- *
- * External Routines:
- *
- * void dispatch(notice, auth, who)
- * ZNotice_t *notice;
- * int auth;
- * struct sockaddr_in *who;
- *
- * void clt_ack(notice, who, sent)
- * ZNotice_t *notice;
- * struct sockaddr_in *who;
- * ZSentType sent;
- *
- * void nack_release(client)
- * ZClient_t *client;
- *
- * void sendit(notice, auth, who)
- * ZNotice_t *notice;
- * int auth;
- * struct sockaddr_in *who;
- *
- * void xmit(notice, dest, auth, client)
- * ZNotice_t *notice;
- * struct sockaddr_in *dest;
- * int auth;
- * ZClient_t *client;
- */
-
-
-/* patchable magic numbers controlling the retransmission rate and count */
-int num_rexmits = NUM_REXMITS;
-long rexmit_secs = REXMIT_SECS;
-long abs_timo = REXMIT_SECS*NUM_REXMITS + 10;
-
-ZSTRING *class_control, *class_admin, *class_hm, *class_ulogin,
- *class_ulocate;
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static void nack_cancel P((register ZNotice_t *, struct sockaddr_in *));
-static void dispatch P((ZNotice_t *, int, struct sockaddr_in *, int));
-static int send_to_dest P((ZNotice_t *, int, ZDestination *dest, int));
-
-#undef P
-
-ZStatistic interserver_notices = {0, "inter-server notices"};
-ZStatistic hm_packets = {0, "hostmanager packets"};
-ZStatistic control_notices = {0, "client control notices"};
-ZStatistic message_notices = {0, "message notices"};
-ZStatistic login_notices = {0, "login notices"};
-ZStatistic i_s_ctls = {0, "inter-server control notices"};
-ZStatistic i_s_logins = {0, "inter-server login notices"};
-ZStatistic i_s_admins = {0, "inter-server admin notices"};
-ZStatistic i_s_locates = {0, "inter-server locate notices"};
-ZStatistic locate_notices = {0, "locate notices"};
-ZStatistic admin_notices = {0, "admin notices"};
-
-static void
-#ifdef __STDC__
-dump_stats (void *arg)
-#else
-dump_stats (arg)
-void *arg;
-#endif
-{
- syslog(LOG_INFO, "stats: %s: %d", hm_packets.str, hm_packets.val);
- syslog(LOG_INFO, "stats: %s: %d", control_notices.str,
- control_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", message_notices.str,
- message_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", login_notices.str,
- login_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", locate_notices.str,
- locate_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", admin_notices.str,
- admin_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", interserver_notices.str,
- interserver_notices.val);
- syslog(LOG_INFO, "stats: %s: %d", i_s_ctls.str, i_s_ctls.val);
- syslog(LOG_INFO, "stats: %s: %d", i_s_logins.str, i_s_logins.val);
- syslog(LOG_INFO, "stats: %s: %d", i_s_admins.str, i_s_admins.val);
- syslog(LOG_INFO, "stats: %s: %d", i_s_locates.str, i_s_locates.val);
- /* log stuff once an hour */
- (void) timer_set_rel ((long) 6*60*60, dump_stats, arg);
-}
-
-/*
- * Handle an input packet.
- * Warning: this function may be called from within a brain dump.
- */
-
-void
-handle_packet()
-{
- Code_t status;
- ZPacket_t input_packet; /* from the network */
- ZNotice_t new_notice; /* parsed from input_packet */
- int input_len; /* len of packet */
- struct sockaddr_in input_sin; /* Zconstructed for authent */
- struct sockaddr_in whoisit; /* for holding peer's address */
- int authentic; /* authentic flag */
- ZSrvPending_t *pending; /* pending packet */
- ZHostList_t *host; /* host ptr */
- int from_server; /* packet is from another server */
-#ifdef DEBUG
- static int first_time = 1;
-#endif
-
-#ifdef DEBUG
- /* Dump statistics five minutes after startup */
- if (first_time) {
- first_time = 0;
- (void) timer_set_rel (5*60, dump_stats, (void *) 0);
- }
-#endif
- /* handle traffic */
-
- if (otherservers[me_server_idx].zs_update_queue) {
- /* something here for me; take care of it */
-#if 1
- zdbug((LOG_DEBUG, "internal queue process"));
-#endif
-
- pending = otherservers[me_server_idx].zs_update_queue->q_forw;
- host = hostm_find_host(&(pending->pend_who.sin_addr));
- if (host && host->zh_locked) {
- /* can't deal with it now. to preserve ordering,
- we can't process other packets, esp. since we
- may block since we don't really know if there
- are things in the real queue. */
-#if 1
- zdbug((LOG_DEBUG,"host %s is locked",
- inet_ntoa(host->zh_addr.sin_addr)));
-#endif
- return;
- }
- pending = server_dequeue(me_server); /* we can do it, remove */
-
- if ((status = ZParseNotice(pending->pend_packet,
- pending->pend_len,
- &new_notice)) != ZERR_NONE) {
- syslog(LOG_ERR,
- "bad notice parse (%s): %s",
- inet_ntoa(pending->pend_who.sin_addr),
- error_message(status));
- } else
- dispatch(&new_notice, pending->pend_auth,
- &pending->pend_who, 1);
- server_pending_free(pending);
- return;
- }
- /*
- * nothing in internal queue, go to the external library
- * queue/socket
- */
- if ((status = ZReceivePacket(input_packet,
- &input_len,
- &whoisit)) != ZERR_NONE) {
- syslog(LOG_ERR,
- "bad packet receive: %s from %s",
- error_message(status), inet_ntoa(whoisit.sin_addr));
- return;
- }
- npackets++;
- if ((status = ZParseNotice(input_packet,
- input_len,
- &new_notice)) != ZERR_NONE) {
- syslog(LOG_ERR,
- "bad notice parse (%s): %s",
- inet_ntoa(whoisit.sin_addr),
- error_message(status));
- return;
- }
- if (server_which_server(&whoisit)) {
- /* we need to parse twice--once to get
- the source addr, second to check
- authentication */
- (void) memset((caddr_t) &input_sin, 0,
- sizeof(input_sin));
- input_sin.sin_addr.s_addr = new_notice.z_sender_addr.s_addr;
- input_sin.sin_port = new_notice.z_port;
- input_sin.sin_family = AF_INET;
- authentic = ZCheckAuthentication(&new_notice, &input_sin);
- from_server = 1;
- } else {
- from_server = 0;
- authentic = ZCheckAuthentication(&new_notice, &whoisit);
- }
-
- if (whoisit.sin_port != hm_port &&
- strcasecmp (new_notice.z_class,ZEPHYR_ADMIN_CLASS) &&
- whoisit.sin_port != sock_sin.sin_port &&
- new_notice.z_kind != CLIENTACK) {
- syslog(LOG_ERR,
- "bad port %s/%d",
- inet_ntoa(whoisit.sin_addr),
- ntohs(whoisit.sin_port));
- return;
- }
-
- message_notices.val++;
- dispatch(&new_notice, authentic, &whoisit, from_server);
- return;
-}
-/*
- * Dispatch a notice.
- */
-
-static void
-dispatch(notice, auth, who, from_server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- int from_server;
-{
- Code_t status;
- ZSTRING *notice_class;
- struct sockaddr_in who2;
- int authflag;
-#ifdef DEBUG
- char dbg_buf[BUFSIZ];
-#endif
-
- /* Set "authflag" to 1 or 0 for handler functions. Treat
- * ZAUTH_CKSUM_FAILED as authentic except for sendit(), which is
- * handled below. */
- switch (auth) {
- case ZAUTH_YES:
- case ZAUTH_CKSUM_FAILED:
- authflag = 1;
- break;
- case ZAUTH_FAILED:
- case ZAUTH_NO:
- default:
- authflag = 0;
- break;
- }
-
- if ((int) notice->z_kind < (int) UNSAFE ||
- (int) notice->z_kind > (int) CLIENTACK) {
- syslog(LOG_NOTICE, "bad notice kind 0x%x from %s",
- (int) notice->z_kind,
- inet_ntoa(who->sin_addr));
- return;
- }
-#if 0
- if (zdebug) {
- (void) sprintf (dbg_buf,
- "disp:%s '%s' '%s' '%s' notice to '%s' from '%s' %s/%d/%d",
- ZNoticeKinds[(int) notice->z_kind],
- notice->z_class,
- notice->z_class_inst,
- notice->z_opcode,
- notice->z_recipient,
- notice->z_sender,
- inet_ntoa(who->sin_addr),
- ntohs(who->sin_port),
- ntohs(notice->z_port));
- syslog (LOG_DEBUG, "%s", dbg_buf);
- }
-#endif
-
- if (notice->z_kind == CLIENTACK) {
- nack_cancel(notice, who);
- return;
- }
-
- who2 = *who;
-#if 0
- if (0 && from_server) {
- /* incorporate server_dispatch here */
- }
-#endif
- notice_class = make_zstring(notice->z_class,1);
-
- if (from_server) {
- interserver_notices.val++;
- status = server_dispatch(notice, auth, who);
- } else if (class_is_hm(notice_class)) {
- hm_packets.val++;
- status = hostm_dispatch(notice, auth, who, me_server);
- } else if (class_is_control(notice_class)) {
- control_notices.val++;
- status = control_dispatch(notice, auth, who, me_server);
- } else if (class_is_ulogin(notice_class)) {
- login_notices.val++;
- status = ulogin_dispatch(notice, auth, who, me_server);
- } else if (class_is_ulocate(notice_class)) {
- locate_notices.val++;
- status = ulocate_dispatch(notice, auth, who, me_server);
- } else if (class_is_admin(notice_class)) {
- admin_notices.val++;
- status = server_adispatch(notice, auth, who, me_server);
- } else {
- if (auth == ZAUTH_CKSUM_FAILED)
- authflag = 0;
- sendit (notice, auth, who);
- free_zstring(notice_class);
- return;
- }
-
- if (status == ZSRV_REQUEUE) {
-#ifdef CONCURRENT
- server_self_queue(notice, auth, who);
-#else
- syslog(LOG_ERR, "requeue while not concurr");
- abort();
-#endif
- }
- free_zstring(notice_class);
-}
-
-/*
- * Send a notice off to those clients who have subscribed to it.
- */
-
-void
-sendit(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
-{
- static int send_counter = 0;
- int any = 0;
- ZAcl_t *acl;
- ZDestination dest;
- ZSTRING *class;
-
- class = make_zstring(notice->z_class,1);
- if ((acl = class_get_acl(class)) != NULLZACLT) {
- /* if controlled and not auth, fail */
- if (!auth) {
- syslog(LOG_WARNING, "sendit unauthentic %s from %s",
- notice->z_class, notice->z_sender);
- clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
- return;
- }
- /* if not auth to transmit, fail */
- if (!access_check(notice->z_sender, acl, TRANSMIT)) {
- syslog(LOG_WARNING, "sendit unauthorized %s from %s",
- notice->z_class, notice->z_sender);
- clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
- return;
- }
- /* sender != inst and not auth to send to others --> fail */
- if ((strcmp (notice->z_sender, notice->z_class_inst)) &&
- (!access_check(notice->z_sender, acl, INSTUID))) {
- syslog(LOG_WARNING,
- "sendit unauth uid %s %s.%s",
- notice->z_sender,
- notice->z_class,
- notice->z_class_inst);
- clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
- return;
- }
- }
- if (memcmp(&notice->z_sender_addr.s_addr, &who->sin_addr.s_addr,
- sizeof(notice->z_sender_addr.s_addr))) {
- /* someone is playing games... */
- /* inet_ntoa returns pointer to static area */
- /* max size is 255.255.255.255 */
- char buffer[16];
- (void) strcpy(buffer, inet_ntoa(who->sin_addr));
- if (!auth) {
- syslog(LOG_WARNING, "sendit unauthentic fake packet: claimed %s, real %s",
- inet_ntoa(notice->z_sender_addr), buffer);
- clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
- return;
- }
- if (ntohl(notice->z_sender_addr.s_addr) != 0) {
- syslog(LOG_WARNING, "sendit invalid address: claimed %s, real %s",
- inet_ntoa(notice->z_sender_addr), buffer);
- clt_ack(notice, who, AUTH_FAILED);
- free_zstring(class);
- return;
- }
- syslog(LOG_WARNING, "sendit addr mismatch: claimed %s, real %s",
- inet_ntoa(notice->z_sender_addr), buffer);
- }
-
- /* Increment the send counter, used to prevent duplicate sends to
- * clients. On the off-chance that we wrap around to 0, skip over
- * it to prevent missing clients which have never had a packet
- * sent to them. */
- send_counter++;
- if (send_counter == 0)
- send_counter = 1;
-
- /* Send to clients subscribed to the triplet itself. */
- dest.classname = class;
- dest.inst = make_zstring(notice->z_class_inst, 1);
- dest.recip = make_zstring(notice->z_recipient, 0);
- if (send_to_dest(notice, auth, &dest, send_counter))
- any = 1;
-
- /* Send to clients subscribed to the triplet with the instance
- * substituted with the wildcard instance. */
- free_zstring(dest.inst);
- dest.inst = wildcard_instance;
- if (send_to_dest(notice, auth, &dest, send_counter))
- any = 1;
-
- free_zstring(class);
- free_zstring(dest.recip);
- if (any)
- ack(notice, who);
- else
- nack(notice, who);
-}
-
-/*
- * Send to each client in the list. Avoid duplicates by setting
- * last_send on each client to send_counter, a nonce which is updated
- * by sendit() above.
- */
-
-static int
-send_to_dest(notice, auth, dest, send_counter)
- ZNotice_t *notice;
- int auth;
- ZDestination *dest;
- int send_counter;
-{
- register ZClientList_t *list, *p;
- register ZClient_t *client;
- register int any = 0;
-
- list = triplet_lookup(dest);
- if (list != NULLZCLT) {
- for (p = list->q_forw; p != list; p = p->q_forw) {
- client = p->zclt_client;
- if (client->last_send == send_counter)
- continue;
- client->last_send = send_counter;
- xmit(notice, &(client->zct_sin), auth, client);
- any = 1;
- }
- }
- return any;
-}
-
-/*
- * Clean up the not-yet-acked queue and release anything destined
- * for the client.
- */
-
-void
-nack_release(client)
- ZClient_t *client;
-{
- register ZNotAcked_t *nacked, *nack2;
-
- /* search the not-yet-acked list for anything destined to him, and
- flush it. */
- for (nacked = nacklist->q_forw;
- nacked != nacklist;)
- if ((nacked->na_addr.sin_addr.s_addr == client->zct_sin.sin_addr.s_addr) &&
- (nacked->na_addr.sin_port == client->zct_sin.sin_port)) {
- /* go back, since remque will change things */
- nack2 = nacked->q_back;
- timer_reset(nacked->na_timer);
- xremque(nacked);
- xfree(nacked->na_packet);
- xfree(nacked);
- /* now that the remque adjusted the linked list,
- we go forward again */
- nacked = nack2->q_forw;
- } else
- nacked = nacked->q_forw;
- return;
-}
-
-/*
- * Send one packet of a fragmented message to a client. After transmitting,
- * put it onto the not ack'ed list.
- */
-
-/* the arguments must be the same as the arguments to Z_XmitFragment */
-/*ARGSUSED*/
-Code_t
-xmit_frag(notice, buf, len, waitforack)
- ZNotice_t *notice;
- char *buf;
- int len;
- int waitforack;
-{
- char *savebuf;
- register ZNotAcked_t *nacked;
- Code_t retval;
-
- if ((retval = ZSendPacket(buf, len, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "xmit_frag send: %s",
- error_message(retval));
- return(retval);
- }
-
- /* now we've sent it, mark it as not ack'ed */
-
- if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) {
- /* no space: just punt */
- syslog(LOG_WARNING, "xmit_frag nack malloc");
- return(ENOMEM);
- }
-
- if (!(savebuf = (char *)xmalloc(len))) {
- /* no space: just punt */
- syslog(LOG_WARNING, "xmit_frag pack malloc");
- return(ENOMEM);
- }
-
- (void) memcpy(savebuf, buf, len);
-
- nacked->na_rexmits = 0;
- nacked->na_packet = savebuf;
- nacked->na_srv_idx = 0;
- nacked->na_addr = ZGetDestAddr();
- nacked->na_packsz = len;
- nacked->na_uid = notice->z_uid;
- nacked->q_forw = nacked->q_back = nacked;
- nacked->na_abstimo = NOW + abs_timo;
-
- /* set a timer to retransmit when done */
- nacked->na_timer = timer_set_rel(rexmit_secs,
- rexmit,
- (void *) nacked);
- /* chain in */
- xinsque(nacked, nacklist);
- return(ZERR_NONE);
-}
-
-/*
- * Send the notice to the client. After transmitting, put it onto the
- * not ack'ed list.
- */
-
-void
-xmit(notice, dest, auth, client)
- ZNotice_t *notice;
- struct sockaddr_in *dest;
- int auth;
- ZClient_t *client;
-{
- caddr_t noticepack;
- register ZNotAcked_t *nacked;
- int packlen;
- Code_t retval;
-
-#if 0
- zdbug((LOG_DEBUG,"xmit"));
-#endif
-
- if (!(noticepack = (caddr_t) xmalloc(sizeof(ZPacket_t)))) {
- syslog(LOG_ERR, "xmit malloc");
- return; /* DON'T put on nack list */
- }
-
- packlen = sizeof(ZPacket_t);
-
- if (auth && client) { /*
- we are distributing authentic and
- we have a pointer to auth info
- */
-#ifdef KERBEROS
-
- if ((retval = ZFormatAuthenticNotice(notice,
- noticepack,
- packlen,
- &packlen,
- client->zct_cblock))
- != ZERR_NONE) {
- syslog(LOG_ERR, "xmit auth format: %s",
- error_message(retval));
- xfree(noticepack);
- return;
- }
-#else /* !KERBEROS */
- notice->z_auth = 1;
- if ((retval = ZFormatSmallRawNotice(notice,
- noticepack,
- &packlen))
- != ZERR_NONE) {
- syslog(LOG_ERR, "xmit auth/raw format: %s",
- error_message(retval));
- xfree(noticepack);
- return;
- }
-#endif /* KERBEROS */
- } else {
- notice->z_auth = 0;
- notice->z_authent_len = 0;
- notice->z_ascii_authent = (char *)"";
- if ((retval = ZFormatSmallRawNotice(notice,
- noticepack,
- &packlen)) != ZERR_NONE) {
- syslog(LOG_ERR, "xmit format: %s",
- error_message(retval));
- xfree(noticepack);
- return; /* DON'T put on nack list */
- }
- }
-#if 0
- zdbug((LOG_DEBUG," to %s/%d",inet_ntoa(dest->sin_addr),
- ntohs(dest->sin_port)));
-#endif
- if ((retval = ZSetDestAddr(dest)) != ZERR_NONE) {
- syslog(LOG_WARNING, "xmit set addr: %s",
- error_message(retval));
- xfree(noticepack);
- return;
- }
- if ((retval = ZSendPacket(noticepack, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "xmit xmit: (%s/%d) %s",
- inet_ntoa(dest->sin_addr), ntohs(dest->sin_port),
- error_message(retval));
- xfree(noticepack);
- return;
- }
-
- /* now we've sent it, mark it as not ack'ed */
-
- if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) {
- /* no space: just punt */
- syslog(LOG_WARNING, "xmit nack malloc");
- xfree(noticepack);
- return;
- }
-
- nacked->na_rexmits = 0;
- nacked->na_packet = noticepack;
- nacked->na_srv_idx = 0; /* XXX */
- nacked->na_addr = *dest;
- nacked->na_packsz = packlen;
- nacked->na_uid = notice->z_uid;
- nacked->q_forw = nacked->q_back = nacked;
- nacked->na_abstimo = NOW + abs_timo;
-
- /* set a timer to retransmit when done */
- nacked->na_timer = timer_set_rel(rexmit_secs,
- rexmit,
- (void *) nacked);
- /* chain in */
- xinsque(nacked, nacklist);
-
-}
-
-
-/*
- * Retransmit the packet specified. If we have timed out or retransmitted
- * too many times, punt the packet and initiate the host recovery algorithm
- * Else, increment the count and re-send the notice packet.
- */
-
-void
-#ifdef __STDC__
-rexmit(void *arg)
-#else
-rexmit(arg)
- void *arg;
-#endif
-{
- register ZNotAcked_t *nackpacket = (ZNotAcked_t*) arg;
- int retval;
- ZNotice_t dummy_notice;
- register ZClient_t *client;
-
-#if 1
- zdbug((LOG_DEBUG,"rexmit"));
-#endif
-
- if (++(nackpacket->na_rexmits) > num_rexmits ||
- NOW > nackpacket->na_abstimo) {
- /* possibly dead client */
-
- dummy_notice.z_port = nackpacket->na_addr.sin_port;
-
- client = client_which_client(&nackpacket->na_addr,
- &dummy_notice);
-
- /* unlink & free packet */
- xremque(nackpacket);
- xfree(nackpacket->na_packet);
- xfree(nackpacket);
-
- /* initiate recovery */
- if (client)
- server_recover(client);
- return;
- }
-
- /* retransmit the packet */
-
-#if 0
- zdbug((LOG_DEBUG," to %s/%d",
- inet_ntoa(nackpacket->na_addr.sin_addr),
- ntohs(nackpacket->na_addr.sin_port)));
-#endif
- if ((retval = ZSetDestAddr(&nackpacket->na_addr))
- != ZERR_NONE) {
- syslog(LOG_WARNING, "rexmit set addr: %s",
- error_message(retval));
- goto requeue;
-
- }
- if ((retval = ZSendPacket(nackpacket->na_packet,
- nackpacket->na_packsz, 0)) != ZERR_NONE)
- syslog(LOG_WARNING, "rexmit xmit: %s", error_message(retval));
-
-requeue:
- /* reset the timer */
- nackpacket->na_timer = timer_set_rel(rexmit_secs,
- rexmit,
- (void *) nackpacket);
- return;
-
-}
-
-/*
- * Send an acknowledgement to the sending client, by sending back the
- * header from the original notice with the z_kind field changed to either
- * SERVACK or SERVNAK, and the contents of the message either SENT or
- * NOT_SENT, depending on the value of the sent argument.
- */
-
-void
-clt_ack(notice, who, sent)
- ZNotice_t *notice;
- struct sockaddr_in *who;
- ZSentType sent;
-{
- ZNotice_t acknotice;
- ZPacket_t ackpack;
- int packlen;
- int notme = 0;
- char *sent_name;
- Code_t retval;
-
- if (bdumping) { /* don't ack while dumping */
-#if 1
- zdbug((LOG_DEBUG,"bdumping, no ack"));
-#endif
- return;
- }
-
- acknotice = *notice;
-
- acknotice.z_kind = SERVACK;
- switch (sent) {
- case SENT:
- acknotice.z_message = ZSRVACK_SENT;
- sent_name = "sent";
- break;
- case NOT_FOUND:
- acknotice.z_message = ZSRVACK_FAIL;
- acknotice.z_kind = SERVNAK;
- sent_name = "fail";
- break;
- case AUTH_FAILED:
- acknotice.z_kind = SERVNAK;
- acknotice.z_message = ZSRVACK_NOTSENT;
- sent_name = "nak/not_sent";
- break;
- case NOT_SENT:
- acknotice.z_message = ZSRVACK_NOTSENT;
- sent_name = "not_sent";
- break;
- default:
- abort ();
- }
-
-#if 0
- zdbug((LOG_DEBUG,"clt_ack type %s for %d to %s/%d",
- sent_name,
- ntohs(notice->z_port),
- inet_ntoa(who->sin_addr),
- ntohs(who->sin_port)));
-#endif
-
- if (!server_which_server(who) &&
- (hostm_find_server(&who->sin_addr) != me_server)) {
-#if 0
- zdbug((LOG_DEBUG,"not me"));
-#endif
- notme = 1;
- }
-
- acknotice.z_multinotice = "";
-
- /* leave room for the trailing null */
- acknotice.z_message_len = strlen(acknotice.z_message) + 1;
-
- packlen = sizeof(ackpack);
-
- if ((retval = ZFormatSmallRawNotice(&acknotice,
- ackpack,
- &packlen)) != ZERR_NONE) {
- syslog(LOG_ERR, "clt_ack format: %s",error_message(retval));
- return;
- }
- if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "clt_ack set addr: %s",
- error_message(retval));
- return;
- }
- if ((retval = ZSendPacket(ackpack, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "clt_ack xmit: %s", error_message(retval));
- return;
- }
- else
- zdbug ((LOG_DEBUG, "packet sent"));
- if (notme)
- hostm_deathgram(who, me_server);
- return;
-}
-
-/*
- * An ack has arrived.
- * remove the packet matching this notice from the not-yet-acked queue
- */
-
-static void
-nack_cancel(notice, who)
- register ZNotice_t *notice;
- struct sockaddr_in *who;
-{
- register ZNotAcked_t *nacked;
-
- /* search the not-yet-acked list for this packet, and
- flush it. */
-#if 0
- zdbug((LOG_DEBUG, "nack_cancel: %s:%08X,%08X",
- inet_ntoa (notice->z_uid.zuid_addr),
- notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
-#endif
- for (nacked = nacklist->q_forw;
- nacked != nacklist;
- nacked = nacked->q_forw)
- if ((nacked->na_addr.sin_addr.s_addr == who->sin_addr.s_addr) &&
- (nacked->na_addr.sin_port == who->sin_port))
- if (ZCompareUID(&nacked->na_uid, &notice->z_uid)) {
- timer_reset(nacked->na_timer);
- xfree(nacked->na_packet);
- xremque(nacked);
- xfree(nacked);
- return;
- }
-#if 1
- zdbug((LOG_DEBUG,"nack_cancel: nack not found %s:%08X,%08X",
- inet_ntoa (notice->z_uid.zuid_addr),
- notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
-#endif
- return;
-}
-
-/* for compatibility when sending subscription information to old clients */
-#ifdef OLD_COMPAT
-#define OLD_ZEPHYR_VERSION "ZEPH0.0"
-#endif /* OLD_COMPAT */
-
-/*
- * Dispatch a ZEPHYR_CTL notice.
- */
-
-Code_t
-control_dispatch(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
-{
- register char *opcode = notice->z_opcode;
- ZClient_t *client;
- ZHostList_t *host;
- Code_t retval;
- int wantdefs;
-
- /*
- * ZEPHYR_CTL Opcodes expected are:
- * BOOT (inst HM): host has booted; flush data.
- * CLIENT_SUBSCRIBE: process with the subscription mananger.
- * CLIENT_UNSUBSCRIBE: ""
- * CLIENT_CANCELSUB: ""
- */
-
- zdbug ((LOG_DEBUG, "ctl_disp: opc=%s", opcode));
-
- if (!strcasecmp (notice->z_class_inst, ZEPHYR_CTL_HM))
- return(hostm_dispatch(notice, auth, who, server));
- else if (!strcmp (opcode, CLIENT_GIMMESUBS) ||
- !strcmp (opcode, CLIENT_GIMMEDEFS)) {
- /* this special case is before the auth check so that
- someone who has no subscriptions does NOT get a SERVNAK
- but rather an empty list. Note we must therefore
- check authentication inside subscr_sendlist */
-#ifdef OLD_COMPAT
- /* only acknowledge if *not* old version; the old version
- acknowledges the packet with the reply */
- if (strcmp (notice->z_version, OLD_ZEPHYR_VERSION))
- ack(notice, who);
-#else /* !OLD_COMPAT */
- ack(notice, who);
-#endif /* OLD_COMPAT */
- subscr_sendlist(notice, auth, who);
- return(ZERR_NONE);
- } else if (!auth) {
-#if 0
- zdbug((LOG_DEBUG,"unauth ctrl_disp"));
-#endif
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
-
- /* the rest of the expected opcodes modify state; check for
- unlocked host first */
- host = hostm_find_host(&who->sin_addr);
- if (host && host->zh_locked)
- return(ZSRV_REQUEUE);
-
- wantdefs = strcmp (opcode, CLIENT_SUBSCRIBE_NODEFS);
- if (!wantdefs || !strcmp (opcode, CLIENT_SUBSCRIBE)) {
- /* subscription notice */
- if (!(client = client_which_client(who, notice))) {
- if ((retval = client_register(notice,
- who,
- &client,
- server,
- wantdefs)) != ZERR_NONE)
- {
- syslog(LOG_NOTICE,
- "subscr. register %s/%s/%d failed: %s",
- notice->z_sender,
- inet_ntoa(who->sin_addr),
- ntohs(notice->z_port),
- error_message(retval));
- if (server == me_server) {
- if (retval == ZSRV_BADSUBPORT) {
- clt_ack(notice, who, AUTH_FAILED);
- } else
- hostm_deathgram(who, me_server);
- }
- return(ZERR_NONE);
- }
- if (!(client = client_which_client(who, notice))) {
- syslog(LOG_CRIT, "subscr reg. failure");
- abort();
- }
- }
- if (strcmp (client->zct_principal->string, notice->z_sender)) {
- /* you may only subscribe for your own clients */
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
-#ifdef KERBEROS
- /* in case it's changed */
- (void) memcpy((caddr_t) client->zct_cblock, (caddr_t) ZGetSession(),
- sizeof(C_Block));
-#endif
- if ((retval = subscr_subscribe(client,notice)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr failed: %s",
- error_message(retval));
- if (server == me_server)
- nack(notice, who);
- return(ZERR_NONE);
- }
- } else if (!strcmp(opcode, CLIENT_UNSUBSCRIBE)) {
- if ((client = client_which_client(who,notice)) != NULLZCNT) {
- if (strcmp(client->zct_principal->string, notice->z_sender)) {
- /* you may only cancel for your own clients */
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
-#if 0
- if (zdebug) {
- if (server == me_server)
- syslog (LOG_DEBUG,
- "subscription cancel for %s/%d\n",
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port));
- else
- syslog (LOG_DEBUG,
- "subscription cancel for %s/%d from %s\n",
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port),
- server->addr);
- }
-#endif
- (void) subscr_cancel(who, notice);
- } else {
- nack(notice, who);
- return(ZERR_NONE);
- }
- } else if (!strcmp(opcode, CLIENT_CANCELSUB)) {
- /* canceling subscriptions implies I can punt info about
- this client */
- if ((client = client_which_client(who,notice)) != NULLZCNT) {
- if (strcmp(client->zct_principal->string, notice->z_sender)) {
- /* you may only cancel for your own clients */
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
- if (host) {
- /* don't flush locations here, let him
- do it explicitly */
-#if 0
- zdbug((LOG_DEBUG, "cancelsub clt_dereg %s/%d",
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port)));
-#endif
- hostm_lose_ignore(client);
- (void) client_deregister(client, host, 0);
- }
-
- }
- if (!client || !host) {
-#if 0
- zdbug((LOG_DEBUG,"can_sub not found client"));
-#endif
- if (server == me_server)
- nack(notice, who);
- return(ZERR_NONE);
- }
- } else {
- syslog(LOG_WARNING, "unknown ctl opcode %s", opcode);
- if (server == me_server)
- nack(notice, who);
- return(ZERR_NONE);
- }
-
- if (server == me_server) {
- ack(notice, who);
- server_forward(notice, auth, who);
- }
- return(ZERR_NONE);
-}
-
-
diff --git a/server/hostm.c b/server/hostm.c
deleted file mode 100644
index 4a029ea..0000000
--- a/server/hostm.c
+++ /dev/null
@@ -1,1045 +0,0 @@
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains functions for communicating with the HostManager.
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- *
- * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#ifndef lint
-#ifndef SABER
-static char rcsid_hostm_c[] = "$Id$";
-#endif
-#endif
-
-#include "zserver.h"
-#include <sys/socket.h> /* for AF_INET */
-
-/*
- *
- * External functions:
- *
- * void hostm_dispatch(notice, auth, who, server)
- * ZNotice_t *notice;
- * int auth;
- * struct sockaddr_in *who;
- * ZServerDesc_t *server;
- *
- * void hostm_flush(host, server)
- * ZHostList_t *host;
- * ZServerDesc_t *server;
- *
- * void hostm_transfer(host, server)
- * ZHostList_t *host;
- * ZServerDesc_t *server;
- *
- * ZHostList_t *hostm_find_host(addr)
- * struct in_addr *addr;
- *
- * ZServerDesc_t *hostm_find_server(addr)
- * struct in_addr *addr;
- *
- * void hostm_shutdown()
- *
- * void hostm_losing(client, host)
- * ZClient_t *client;
- * ZHostList_t *host;
- *
- * void hostm_deathgram(sin, server)
- * struct sockaddr_in *sin;
- * ZServerDesc_t *server;
- *
- * void hostm_dump_hosts(fp)
- * FILE *fp;
- */
-
-/*
- * This module maintains two important structures.
- * all_hosts is an array of all currently known hosts, and which server
- * is responsible for that host. This list is kept sorted by IP address
- * so that lookups can be fast (binary search). num_hosts contains the
- * number of hosts to be found in the array.
- *
- * The losing hosts list is a linked list of all the clients (and their hosts)
- * whose existence is in doubt. Any host on this list has already been sent
- * a ping and is expected to reply immediately.
- * As usual, the first element of the list is a placeholder header so we
- * know when the list has been completely scanned.
- */
-
-struct hostlist {
- ZHostList_t *host; /* ptr to host struct */
- int server_index; /* index of server in the table */
-};
-
-typedef struct _losinghost {
- struct _losinghost *q_forw;
- struct _losinghost *q_back;
- struct _ZHostList_t *lh_host;
- timer lh_timer;
- struct _ZClient_t *lh_client;
-} losinghost;
-
-#define NULLHLT ((struct hostlist *) 0)
-
-static struct hostlist *all_hosts;
-
-static int num_hosts = 0; /* number of hosts in all_hosts */
-static long lose_timo = LOSE_TIMO;
-
-static losinghost *losing_hosts; /* queue of pings for hosts we
- doubt are really there */
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static void host_detach P((register ZHostList_t *host, ZServerDesc_t *server)),
- insert_host P((ZHostList_t *host, ZServerDesc_t *server)),
- remove_host P((ZHostList_t *host));
-static void host_not_losing P((struct sockaddr_in *who)),
- host_lost P((void *which)),
- ping P((struct sockaddr_in *sin));
-static Code_t host_attach P((struct sockaddr_in *who, ZServerDesc_t *server));
-
-#undef P
-
-/*
- * We received a HostManager packet. process accordingly.
- */
-
-/*ARGSUSED*/
-Code_t
-hostm_dispatch(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
-{
- ZServerDesc_t *owner;
- ZHostList_t *host = NULLZHLT;
- char *opcode = notice->z_opcode;
- Code_t retval;
-
-#if 0
- zdbug((LOG_DEBUG,"hm_disp"));
-#endif
-
- host = hostm_find_host(&who->sin_addr);
- if (host && host->zh_locked)
- return(ZSRV_REQUEUE);
-
- if (notice->z_kind == HMACK) {
- host_not_losing(who);
- return(ZERR_NONE);
- } else if (notice->z_kind != HMCTL) {
-#if 0
- zdbug((LOG_DEBUG, "bogus HM packet"));
-#endif
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
- owner = hostm_find_server(&who->sin_addr);
- if (!strcmp(opcode, HM_ATTACH)) {
-#if 0
- zdbug((LOG_DEBUG,"attach %s",inet_ntoa(who)));
-#endif
- if (owner == server) {
-#if 0
- zdbug((LOG_DEBUG,"no change"));
-#endif
- /* Same server owns him. do nothing */
- } else if (owner) {
- /* He has switched servers.
- he was lost but has asked server to work for him.
- We need to transfer him to server */
-#if 0
- zdbug((LOG_DEBUG,"hm_disp transfer"));
-#endif
- hostm_transfer(host, server);
- } else {
- /* no owner. attach him to server. */
- if ((retval = host_attach(who, server))
- != ZERR_NONE) {
- syslog(LOG_WARNING, "hattach failed: %s",
- error_message(retval));
- return(retval);
- }
-
- }
- if (server == me_server) {
- server_forward(notice, auth, who);
- ack(notice, who);
- }
- } else if (!strcmp(opcode, HM_BOOT)) {
-#if 0
- zdbug((LOG_DEBUG, "boot %s (server %s)",
- inet_ntoa(who->sin_addr),
- server->addr));
-#endif
- /* Booting is just like flushing and attaching */
- if (owner) /* if owned, flush */
- hostm_flush(host, owner);
- if ((retval = host_attach(who, server)) != ZERR_NONE) {
- syslog(LOG_WARNING, "hattach failed: %s",
- error_message(retval));
- return(retval);
- }
- if (server == me_server) {
- server_forward(notice, auth, who);
- ack(notice, who);
- }
- } else if (!strcmp(opcode, HM_FLUSH)) {
-#if 0
- zdbug((LOG_DEBUG, "hm_flush %s (server %s)",
- inet_ntoa(who->sin_addr),
- server->addr));
-#endif
- if (!owner)
- return(ZERR_NONE);
- /* flush him */
- hostm_flush(host, owner);
- if (server == me_server)
- server_forward(notice, auth, who);
- } else if (!strcmp(opcode, HM_DETACH)) {
-#if 0
- zdbug((LOG_DEBUG, "hm_detach %s",inet_ntoa(who_sin_addr)));
-#endif
- /* ignore it */
- } else {
- syslog(LOG_WARNING, "hm_disp: unknown opcode %s",opcode);
- return(ZERR_NONE);
- }
- return(ZERR_NONE);
-}
-
-/*
- * Flush all information about this host. Remove any losing host entries,
- * deregister all the clients, flush any user locations, and remove the host
- * from its server.
- * The caller is responsible for informing other servers of this flush
- * (if appropriate).
- */
-
-void
-hostm_flush(host, server)
- ZHostList_t *host;
- ZServerDesc_t *server;
-{
- register ZClientList_t *clist = NULLZCLT, *clt;
- losinghost *lhp, *lhp2;
-
- START_CRITICAL_CODE;
-
- if (!host) {
- syslog(LOG_WARNING, "null host flush");
- return;
- }
-
-#if 0
- zdbug ((LOG_DEBUG,"hostm_flush %s", inet_ntoa (host->zh_addr.sin_addr)));
-#endif
-
- if (losing_hosts)
- for (lhp = losing_hosts->q_forw;
- lhp != losing_hosts;)
- if (lhp->lh_host == host) {
- lhp2 = lhp->q_back;
- timer_reset(lhp->lh_timer);
- xremque(lhp);
- xfree(lhp);
- lhp = lhp2->q_forw;
- } else
- lhp = lhp->q_forw;
-
- if ((clist = host->zh_clients) != NULLZCLT) {
- for (clt = clist->q_forw; clt != clist; clt = clist->q_forw) {
- /* client_deregister frees this client & subscriptions
- & locations and remque()s the client */
-#if 0
- if (zdebug)
- syslog (LOG_DEBUG, "hostm_flush clt_dereg %s/%d",
- inet_ntoa(host->zh_addr.sin_addr),
- ntohs (clt->zclt_client->zct_sin.sin_port));
-#endif
- client_deregister(clt->zclt_client, host, 1);
- }
- }
-
- uloc_hflush(&host->zh_addr.sin_addr);
- host_detach(host, server);
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-/*
- * send a shutdown to each of our hosts
- */
-
-void
-hostm_shutdown()
-{
- register ZHostList_t *hosts = otherservers[me_server_idx].zs_hosts;
- register ZHostList_t *host;
- int newserver, i;
-
-#if 0
- zdbug((LOG_DEBUG,"hostm_shutdown"));
-#endif
- if (!hosts)
- return;
-
- for (i = 0; i < nservers; i++){
- if (i == me_server_idx) continue;
- if (otherservers[i].zs_state == SERV_UP)
- break;
- }
- if (i == nservers) /* no other servers are up */
- newserver = 0;
- else
- newserver = 1;
-
- /* kill them all */
- for (host = hosts->q_forw;
- host != hosts;
- host = host->q_forw) {
- /* recommend a random, known up server */
- if (newserver) {
- do
- newserver = (int) (random() % (nservers - 1)) + 1;
- while (newserver == limbo_server_idx() ||
- (otherservers[newserver].zs_state != SERV_UP &&
- otherservers[newserver].zs_state != SERV_TARDY) ||
- newserver == me_server_idx);
- hostm_deathgram(&host->zh_addr, &otherservers[newserver]);
- } else
- hostm_deathgram(&host->zh_addr, NULLZSDT);
- }
- return;
-}
-
-
-/*
- * The client on the host is not acknowledging any packets. Ping the
- * host and set a timeout.
- */
-
-void
-hostm_losing(client, host)
- ZClient_t *client;
- ZHostList_t *host;
-{
- losinghost *newhost;
-
-#if 0
- zdbug((LOG_DEBUG,"losing host"));
-#endif
- if (!losing_hosts) {
- if (!(losing_hosts = (losinghost *)
- xmalloc(sizeof(losinghost)))) {
- syslog(LOG_ERR, "no mem losing host");
- return;
- }
- losing_hosts->q_forw = losing_hosts->q_back = losing_hosts;
- }
- for (newhost = losing_hosts->q_forw;
- newhost != losing_hosts;
- newhost = newhost->q_forw)
- if (newhost->lh_client == client) {
-#if 0
- zdbug((LOG_DEBUG,"clt already losing"));
-#endif
- return;
- }
- if (!(newhost = (losinghost *) xmalloc(sizeof(losinghost)))) {
- syslog(LOG_ERR, "no mem losing host 2");
- return;
- }
-
- /* send a ping */
- ping(&host->zh_addr);
- newhost->lh_host = host;
- newhost->lh_client = client;
- newhost->lh_timer = timer_set_rel(lose_timo, host_lost, (void *) newhost);
- xinsque(newhost, losing_hosts);
- return;
-}
-
-/*
- * The host did not respond to the ping, so we punt him
- */
-
-static void
-host_lost(arg)
- void* arg;
-{
- losinghost *which = (losinghost *) arg;
- ZServerDesc_t *server;
- ZNotice_t notice;
- struct sockaddr_in who;
- Code_t retval;
- char *buffer;
- int len;
-
- START_CRITICAL_CODE;
-
- server = hostm_find_server(&which->lh_host->zh_addr.sin_addr);
-#if 1
- zdbug ((LOG_DEBUG,"lost host %s (server %s)",
- inet_ntoa(which->lh_host->zh_addr.sin_addr),
- server ? server->addr : "<NONE>"));
-#endif
-
- if (!server) {
-#if 1
- zdbug((LOG_DEBUG,"no server"));
-#endif
- xremque(which);
- xfree(which);
- END_CRITICAL_CODE;
- return;
- }
- xremque(which);
- hostm_flush(which->lh_host, server);
-
- (void) memset((caddr_t)&notice, 0, sizeof(notice));
-
- /* tell other servers to flush this host */
- notice.z_kind = HMCTL;
- notice.z_auth = 0;
- notice.z_port = hm_port;
- notice.z_class = ZEPHYR_CTL_CLASS;
- notice.z_class_inst = ZEPHYR_CTL_HM;
- notice.z_opcode = HM_FLUSH;
- notice.z_sender = "HM";
- notice.z_recipient = "";
- notice.z_default_format = "";
- notice.z_num_other_fields = 0;
- notice.z_message_len = 0;
-
- /* generate the other fields */
- retval = ZFormatNotice(&notice, &buffer, &len, ZNOAUTH);
- if (retval != ZERR_NONE)
- return;
- xfree(buffer);
-
- /* forge a from address */
- (void) memset((char *) &who, 0, sizeof(who));
- who.sin_addr.s_addr = which->lh_host->zh_addr.sin_addr.s_addr;
- who.sin_port = hm_port;
- who.sin_family = AF_INET;
-
- server_forward(&notice, 0, &who); /* unauthentic */
-
- xfree(which);
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-/*
- * The host responded to the ping, so we flush the losing clients on this host.
- */
-
-static void
-host_not_losing(who)
- struct sockaddr_in *who;
-{
- losinghost *lhp, *lhp2;
-
- if (!losing_hosts)
- return;
-
- START_CRITICAL_CODE;
-
- for (lhp = losing_hosts->q_forw;
- lhp != losing_hosts;)
- if (lhp->lh_host->zh_addr.sin_addr.s_addr == who->sin_addr.s_addr) {
- /* go back, since remque will change things */
- lhp2 = lhp->q_back;
- timer_reset(lhp->lh_timer);
-#if 1
- if (zdebug || 1)
- syslog (LOG_DEBUG,"lost client %s/%d",
- inet_ntoa(lhp->lh_client->zct_sin.sin_addr),
- ntohs(lhp->lh_client->zct_sin.sin_port));
-#endif
- /* deregister all subscriptions, and flush locations
- associated with the client. */
-#if 0
- if (zdebug)
- syslog(LOG_DEBUG,"h_not_lose clt_dereg");
-#endif
- server_kill_clt(lhp->lh_client);
- client_deregister(lhp->lh_client, lhp->lh_host, 1);
- xremque(lhp);
- xfree(lhp);
- /* now that the remque adjusted the linked list,
- we go forward again */
- lhp = lhp2->q_forw;
- } else
- lhp = lhp->q_forw;
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-/*
- * A client is being de-registered, so remove it from the losing_host list,
- * if it is there.
- */
-
-void
-hostm_lose_ignore(client)
- ZClient_t *client;
-{
- losinghost *lhp, *lhp2;
-
- if (!losing_hosts)
- return;
-
- START_CRITICAL_CODE;
-
- for (lhp = losing_hosts->q_forw;
- lhp != losing_hosts;)
- /* if client matches, remove it */
- if (lhp->lh_client == client) {
- /* go back, since remque will change things */
- lhp2 = lhp->q_back;
- timer_reset(lhp->lh_timer);
-#if 0
- zdbug((LOG_DEBUG,"hm_l_ign client %s/%d",
- inet_ntoa(client->zct_sin),
- ntohs(client->zct_sin.sin_port)));
-#endif
- xremque(lhp);
- xfree(lhp);
- /* now that the remque adjusted the linked list,
- we go forward again */
- lhp = lhp2->q_forw;
- } else
- lhp = lhp->q_forw;
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-/*
- * transfer this host to server's ownership. The caller must update the
- * other servers.
- */
-
-void
-hostm_transfer(host, server)
- ZHostList_t *host;
- ZServerDesc_t *server;
-{
- /* we need to unlink and relink him, and change the table entry */
-#if 1
- if (zdebug)
- syslog (LOG_DEBUG, "hostm_transfer %s to %s",
- inet_ntoa (host->zh_addr.sin_addr), server->addr);
-#endif
-
- /* is this the same server? */
- if (hostm_find_server(&host->zh_addr.sin_addr) == server)
- return;
-
- START_CRITICAL_CODE;
-
- /* remove from old server's queue */
- xremque(host);
-
- /* switch servers in the table */
- remove_host(host);
- insert_host(host, server);
-
- /* insert in our queue */
- xinsque(host, server->zs_hosts);
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-
-/*
- * attach the host with return address in who to the server.
- */
-
-static Code_t
-host_attach(who, server)
- struct sockaddr_in *who;
- ZServerDesc_t *server;
-{
- register ZHostList_t *hlist;
- register ZClientList_t *clist;
-
- START_CRITICAL_CODE;
-
-#if 0
- if (zdebug)
- syslog (LOG_DEBUG, "host_attach %s to %s",
- inet_ntoa (who->sin_addr), server->addr);
-#endif
- /* allocate a header */
- if (!(hlist = (ZHostList_t *) xmalloc(sizeof(ZHostList_t)))) {
- syslog(LOG_WARNING, "hm_attach alloc");
- END_CRITICAL_CODE;
- return(ENOMEM);
- }
- /* set up */
- if (!(clist = (ZClientList_t *)xmalloc(sizeof(ZClientList_t)))) {
- xfree(hlist);
- END_CRITICAL_CODE;
- return(ENOMEM);
- }
- clist->zclt_client = NULLZCNT;
- clist->q_forw = clist->q_back = clist;
-
- hlist->zh_clients = clist;
- hlist->zh_addr = *who;
- hlist->q_forw = hlist->q_back = hlist;
- hlist->zh_locked = 0;
-
- /* add to table */
- insert_host(hlist, server);
-
- /* chain in to the end of the list */
- xinsque(hlist, server->zs_hosts->q_back);
-
- END_CRITICAL_CODE;
-
- return(ZERR_NONE);
-}
-
-/*
- * detach the host at addr from the server
- * Warning: this routine assumes all the clients have already been removed
- * from this host.
- */
-
-static void
-host_detach(host, server)
- register ZHostList_t *host;
- ZServerDesc_t *server;
-{
- ZServerDesc_t *server2;
-
- START_CRITICAL_CODE;
-
- /* undo what we did in host_attach */
- server2 = hostm_find_server (&host->zh_addr.sin_addr);
-
- if (server2 != server) {
- syslog(LOG_WARNING,
- "host_detach: wrong server: %s from %s, found %s",
- inet_ntoa (host->zh_addr.sin_addr),
- server->addr,
- server2->addr);
- END_CRITICAL_CODE;
- return;
- }
-
-
- /* all the clients have already been freed */
- xfree(host->zh_clients);
-
- /* unchain */
- xremque(host);
-
- /* remove from table */
- remove_host(host);
-
- xfree(host);
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-/*
- * Build hostmanager recipient name.
- */
-static char *
-hm_recipient ()
-{
- static char *recipient;
- char *realm;
-
- if (recipient)
- return recipient;
-
- realm = ZGetRealm ();
- if (!realm)
- realm = "???";
- recipient = (char *) xmalloc (strlen (realm) + 4);
- strcpy (recipient, "hm@");
- strcat (recipient, realm);
- return recipient;
-}
-
-/*
- * Send a shutdown message to the HostManager at sin, recommending him to
- * use server
- */
-
-void
-hostm_deathgram(sin, server)
- struct sockaddr_in *sin;
- ZServerDesc_t *server;
-{
- Code_t retval;
- int shutlen;
- ZNotice_t shutnotice;
- char *shutpack;
-
-#if 0
- zdbug((LOG_DEBUG,"deathgram %s",inet_ntoa(*sin)));
-#endif
-
- /* fill in the shutdown notice */
-
- shutnotice.z_kind = HMCTL;
- shutnotice.z_port = sock_sin.sin_port; /* we are sending it */
- shutnotice.z_class = HM_CTL_CLASS;
- shutnotice.z_class_inst = HM_CTL_SERVER;
- shutnotice.z_opcode = SERVER_SHUTDOWN;
- shutnotice.z_sender = HM_CTL_SERVER;
- shutnotice.z_recipient = hm_recipient ();
- shutnotice.z_default_format = "";
- shutnotice.z_num_other_fields = 0;
-
- if (server) {
- shutnotice.z_message = server->addr;
- shutnotice.z_message_len = strlen(shutnotice.z_message) + 1;
-#if 0
- zdbug((LOG_DEBUG, "suggesting %s",shutnotice.z_message));
-#endif
- } else {
- shutnotice.z_message = NULL;
- shutnotice.z_message_len = 0;
- }
-
- if ((retval = ZFormatNotice(&shutnotice,
- &shutpack,
- &shutlen,
- ZNOAUTH)) != ZERR_NONE) {
- syslog(LOG_ERR, "hm_shut format: %s",error_message(retval));
- return;
- }
- if ((retval = ZSetDestAddr(sin)) != ZERR_NONE) {
- syslog(LOG_WARNING, "hm_shut set addr: %s",
- error_message(retval));
- xfree(shutpack); /* free allocated storage */
- return;
- }
- /* don't wait for ack! */
- if ((retval = ZSendPacket(shutpack, shutlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "hm_shut xmit: %s", error_message(retval));
- xfree(shutpack); /* free allocated storage */
- return;
- }
- xfree(shutpack); /* free allocated storage */
- return;
-}
-
-/*
- * Send a ping to the HostManager at sin
- */
-
-static void
-ping(sin)
- struct sockaddr_in *sin;
-{
- Code_t retval;
- int shutlen;
- ZNotice_t shutnotice;
- char *shutpack;
-
-#if 0
- zdbug((LOG_DEBUG,"ping %s",inet_ntoa(*sin)));
-#endif
-
- /* fill in the shutdown notice */
-
- shutnotice.z_kind = HMCTL;
- shutnotice.z_port = sock_sin.sin_port;
- shutnotice.z_class = HM_CTL_CLASS;
- shutnotice.z_class_inst = HM_CTL_SERVER;
- shutnotice.z_opcode = SERVER_PING;
- shutnotice.z_sender = HM_CTL_SERVER;
- shutnotice.z_recipient = hm_recipient ();
- shutnotice.z_message = NULL;
- shutnotice.z_message_len = 0;
- shutnotice.z_default_format = "";
- shutnotice.z_num_other_fields = 0;
-
- if ((retval = ZFormatNotice(&shutnotice,
- &shutpack,
- &shutlen,
- ZNOAUTH)) != ZERR_NONE) {
- syslog(LOG_ERR, "hm_ping format: %s",error_message(retval));
- return;
- }
- if ((retval = ZSetDestAddr(sin)) != ZERR_NONE) {
- syslog(LOG_WARNING, "hm_ping set addr: %s",
- error_message(retval));
- xfree(shutpack); /* free allocated storage */
- return;
- }
- /* don't wait for ack */
- if ((retval = ZSendPacket(shutpack, shutlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "hm_ping xmit: %s", error_message(retval));
- xfree(shutpack); /* free allocated storage */
- return;
- }
- xfree(shutpack); /* free allocated storage */
- return;
-}
-
-/*
- * Routines for maintaining the host array.
- */
-
-/*
- * Binary search on the host table to find this host.
- */
-
-ZHostList_t *
-hostm_find_host(addr)
- struct in_addr *addr;
-{
- register int i, rlo, rhi;
-
- if (!all_hosts)
- return(NULLZHLT);
-
- /* i is the current host we are checking */
- /* rlo is the lowest we will still check, rhi is the highest we will
- still check */
-
- i = num_hosts >> 1; /* start in the middle */
- rlo = 0;
- rhi = num_hosts - 1; /* first index is 0 */
-
- while ((all_hosts[i].host)->zh_addr.sin_addr.s_addr != addr->s_addr) {
- if ((all_hosts[i].host)->zh_addr.sin_addr.s_addr < addr->s_addr)
- rlo = i + 1;
- else
- rhi = i - 1;
- if (rhi - rlo < 0)
- return(NULLZHLT);
- i = (rhi + rlo) >> 1; /* split the diff */
- }
- return(all_hosts[i].host);
-}
-
-/*
- * Binary search on the host table to find this host's server.
- */
-
-ZServerDesc_t *
-hostm_find_server(addr)
- struct in_addr *addr;
-{
- register int i, rlo, rhi;
-
- if (!all_hosts)
- return(NULLZSDT);
-
- /* i is the current host we are checking */
- /* rlo is the lowest we will still check, rhi is the highest we will
- still check */
-
- i = num_hosts >> 1; /* start in the middle */
- rlo = 0;
- rhi = num_hosts - 1; /* first index is 0 */
-
- while ((all_hosts[i].host)->zh_addr.sin_addr.s_addr != addr->s_addr) {
- if ((all_hosts[i].host)->zh_addr.sin_addr.s_addr < addr->s_addr)
- rlo = i + 1;
- else
- rhi = i - 1;
- if (rhi - rlo < 0)
- return(NULLZSDT);
- i = (rhi + rlo) >> 1; /* split the diff */
- }
- return(&otherservers[all_hosts[i].server_index]);
-}
-
-/*
- * Insert the host and server into the sorted array of hosts.
- */
-
-static void
-insert_host(host, server)
- ZHostList_t *host;
- ZServerDesc_t *server;
-{
- struct hostlist *oldlist;
- register int i = 0;
-
-#if 0
- zdbug ((LOG_DEBUG,"insert_host %s %s",
- inet_ntoa(host->zh_addr.sin_addr), server->addr));
-#endif
- if (hostm_find_host(&host->zh_addr.sin_addr))
- return;
-
- START_CRITICAL_CODE;
-
- num_hosts++;
- oldlist = all_hosts;
-
- if (!(all_hosts = (struct hostlist *) xmalloc(num_hosts * sizeof(struct hostlist)))) {
- syslog(LOG_CRIT, "insert_host: nomem");
- abort();
- }
-
- if (!oldlist) { /* this is the first */
- all_hosts[0].host = host;
- all_hosts[0].server_index = server - otherservers;
- END_CRITICAL_CODE;
- return;
- }
-
- /* copy old pointers */
- while ((i < (num_hosts - 1)) &&
- ((oldlist[i].host)->zh_addr.sin_addr.s_addr < host->zh_addr.sin_addr.s_addr)) {
- all_hosts[i] = oldlist[i];
- i++;
- }
- /* add this one */
- all_hosts[i].host = host;
- all_hosts[i++].server_index = server - otherservers;
-
- /* copy the rest */
- while (i < num_hosts) {
- all_hosts[i] = oldlist[i - 1];
- i++;
- }
- xfree(oldlist);
-
- END_CRITICAL_CODE;
-
-#if defined (DEBUG) && 0
- if (zdebug) {
- register int i = 0;
- for (i = 0; i < num_hosts; i++)
- syslog(LOG_DEBUG, "%d: %s %s",i,
- inet_ntoa ((all_hosts[i].host)->zh_addr.sin_addr),
- otherservers[all_hosts[i].server_index]->addr);
- }
-#endif
- return;
-}
-
-/*
- * remove the host from the array of known hosts.
- */
-
-static void
-remove_host(host)
- ZHostList_t *host;
-{
- struct hostlist *oldlist;
- register int i = 0;
-
-#if 0
- zdbug((LOG_DEBUG,"remove_host %s", inet_ntoa(host->zh_addr.sin_addr)));
-#endif
- if (!hostm_find_host(&host->zh_addr.sin_addr))
- return;
-
- START_CRITICAL_CODE;
-
- if (--num_hosts == 0) {
-#if 0
- zdbug((LOG_DEBUG,"last host"));
-#endif
- xfree (all_hosts);
- all_hosts = NULLHLT;
- END_CRITICAL_CODE;
- return;
- }
-
- oldlist = all_hosts;
-
- if (!(all_hosts = (struct hostlist *) xmalloc(num_hosts * sizeof(struct hostlist)))) {
- syslog(LOG_CRIT, "remove_host: nomem");
- abort();
- }
-
- /* copy old pointers */
- while (i < num_hosts && (oldlist[i].host)->zh_addr.sin_addr.s_addr < host->zh_addr.sin_addr.s_addr) {
- all_hosts[i] = oldlist[i];
- i++;
- }
-
- i++; /* skip over this one */
-
- /* copy the rest */
- while (i <= num_hosts) {
- all_hosts[i - 1] = oldlist[i];
- i++;
- }
- xfree (oldlist);
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-/*
- * Assumes that SIGFPE is blocked when called; this is true if called from a
- * signal handler
- */
-
-void
-hostm_dump_hosts(fp)
- FILE *fp;
-{
- register int i;
- for (i = 0; i < num_hosts; i++) {
- (void) fprintf(fp, "%s/%d:\n",
- inet_ntoa((all_hosts[i].host)->zh_addr.sin_addr),
- all_hosts[i].server_index);
- client_dump_clients(fp,(all_hosts[i].host)->zh_clients);
- }
- return;
-}
-
-/*
- * Readjust server-array indices according to the supplied new vector.
- */
-
-void
-hostm_renumber_servers (srv)
- int *srv;
-{
- int i;
- for (i = 0; i < num_hosts; i++) {
- int idx = srv[all_hosts[i].server_index];
- if (idx < 0) {
- syslog (LOG_ERR, "hostm_renumber_servers error: [%d] = %d",
- all_hosts[i].server_index, idx);
- idx = 0;
- }
- all_hosts[i].server_index = idx;
- }
-}
diff --git a/server/kopt.c b/server/kopt.c
index 5d62688..3bcaa57 100644
--- a/server/kopt.c
+++ b/server/kopt.c
@@ -16,24 +16,22 @@
* Kerberos: krb_conf.h,v 4.0 89/01/23 09:59:27 jtkohl Exp
*/
+#include <zephyr/mit-copyright.h>
+#include "zserver.h"
+
#ifndef lint
#ifndef SABER
-static char *rcsid_rd_req_c =
+static const char *rcsid_rd_req_c =
"$Id$";
#endif /* lint */
#endif /* SABER */
-#ifdef KERBEROS
+#ifdef ZEPHYR_USES_KERBEROS
#ifndef NOENCRYPTION
-#include <zephyr/mit-copyright.h>
-#include <zephyr/zephyr.h>
-#include <stdio.h>
-#include <krb.h>
-#include "zserver.h"
-
/* Byte ordering */
-static int krbONE;
+#undef HOST_BYTE_ORDER
+static int krbONE = 1;
#define HOST_BYTE_ORDER (* (char *) &krbONE)
#define KRB_PROT_VERSION 4
@@ -64,9 +62,6 @@ static int krbONE;
#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9
#define KERB_ERR_NULL_KEY 10
-#include <sys/time.h>
-#include <string.h>
-
extern int krb_ap_req_debug;
extern struct timeval t_local;
@@ -97,34 +92,26 @@ typedef struct {
} KeySchedRec;
static KeySchedRec scheds[HASH_SIZE_1][HASH_SIZE_2];
-#ifdef __STDC__
-Sched* check_key_sched_cache (des_cblock key)
-#else
-Sched* check_key_sched_cache (key)
- des_cblock key;
-#endif
+Sched *check_key_sched_cache(key)
+ des_cblock key;
{
unsigned int hash_value = key[0] + key[1] * 256;
KeySchedRec *rec = scheds[hash_value % HASH_SIZE_1];
int i;
- for (i = HASH_SIZE_2 - 1; i >= 0; i--)
- if (rec[i].last_time_used
- && key[0] == rec[i].key[0]
- && !memcmp (key, rec[i].key, sizeof (des_cblock))) {
+ for (i = HASH_SIZE_2 - 1; i >= 0; i--) {
+ if (rec[i].last_time_used && key[0] == rec[i].key[0]
+ && !memcmp(key, rec[i].key, sizeof(des_cblock))) {
rec[i].last_time_used = last_use++;
return &rec[i].schedule;
}
+ }
return 0;
}
-#ifdef __STDC__
-void add_to_key_sched_cache (des_cblock key, Sched* sched)
-#else
-void add_to_key_sched_cache (key, sched)
- des_cblock key;
- Sched* sched;
-#endif
+void add_to_key_sched_cache(key, sched)
+ des_cblock key;
+ Sched *sched;
{
unsigned int hash_value = key[0] + key[1] * 256;
KeySchedRec *rec = scheds[hash_value % HASH_SIZE_1];
@@ -138,7 +125,7 @@ void add_to_key_sched_cache (key, sched)
if (rec[i].last_time_used < rec[oldest].last_time_used)
oldest = i;
}
- (void) memcpy (rec[oldest].key, key, sizeof (des_cblock));
+ memcpy (rec[oldest].key, key, sizeof(des_cblock));
rec[oldest].schedule = *sched;
rec[oldest].last_time_used = last_use++;
}
@@ -178,7 +165,7 @@ krb_set_key(key,cvt)
int cvt;
{
#ifdef NOENCRYPTION
- (void) memset(serv_key, 0, sizeof(serv_key));
+ memset(serv_key, 0, sizeof(serv_key));
return KSUCCESS;
#else /* Encrypt */
Sched *s;
@@ -187,15 +174,15 @@ krb_set_key(key,cvt)
if (cvt)
string_to_key(key,serv_key);
else
- (void) memcpy((char *)serv_key,key,8);
+ memcpy((char *)serv_key,key,8);
s = check_key_sched_cache (serv_key);
if (s) {
serv_ksched = *s;
return 0;
}
- ret = des_key_sched (serv_key, serv_ksched.s);
- add_to_key_sched_cache (serv_key, &serv_ksched);
+ ret = des_key_sched(serv_key, serv_ksched.s);
+ add_to_key_sched_cache(serv_key, &serv_ksched);
return ret;
#endif /* NOENCRYPTION */
}
@@ -242,18 +229,19 @@ krb_set_key(key,cvt)
* 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 */
+ KTEXT authent; /* The received message */
+ char *service; /* Service name */
+ char *instance; /* Service instance */
+ unsigned KRB_INT32 from_addr; /* Net address of originating host */
+ AUTH_DAT *ad; /* Structure to be filled in */
+ char *fn; /* Filename to get keys from */
{
KTEXT_ST ticket; /* Temp storage for ticket */
KTEXT tkt = &ticket;
KTEXT_ST req_id_st; /* Temp storage for authenticator */
- register KTEXT req_id = &req_id_st;
+ KTEXT req_id = &req_id_st;
char realm[REALM_SZ]; /* Realm of issuing kerberos */
Sched seskey_sched, *sched; /* Key sched for session key */
@@ -265,7 +253,7 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
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 */
+ char *ptr; /* For stepping through */
unsigned long delta_t; /* Time in authenticator - local time */
long tkt_age; /* Age of ticket */
int swap_bytes; /* Need to swap bytes? */
@@ -283,7 +271,7 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
/* check version */
if (KRB_PROT_VERSION != (unsigned int) *ptr++)
- return(RD_AP_VERSION);
+ return RD_AP_VERSION;
/* byte order */
swap_bytes = 0;
@@ -293,12 +281,12 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
/* check msg type */
mutual = 0;
switch (*ptr++ & ~1) {
- case AUTH_MSG_APPL_REQUEST:
+ case AUTH_MSG_APPL_REQUEST:
break;
- case AUTH_MSG_APPL_REQUEST_MUTUAL:
+ case AUTH_MSG_APPL_REQUEST_MUTUAL:
mutual++;
break;
- default:
+ default:
return(RD_AP_MSG_TYPE);
}
@@ -309,7 +297,7 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
mutual = 0;
#endif /* lint */
s_kvno = *ptr++; /* get server key version */
- (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
+ strcpy(realm,ptr); /* And the realm of the issuing KDC */
ptr += strlen(ptr) + 1; /* skip the realm "hint" */
/*
@@ -320,85 +308,90 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
* 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;
+ if (fn && (strcmp(st_nam,service) != 0 || strcmp(st_inst,instance) != 0 ||
+ strcmp(st_rlm,realm) != 0 || (st_kvno != s_kvno))) {
+ if (*fn == 0)
+ fn = KEYFILE;
st_kvno = s_kvno;
#ifndef NOENCRYPTION
- if (read_service_key(service,instance,realm,(int) s_kvno,
- fn,(char *)skey))
+ if (read_service_key(service,instance,realm, (int) s_kvno,
+ fn, (char *) skey))
return(RD_AP_UNDEC);
- if ((status = krb_set_key((char *)skey,0)) != 0)
+ status = krb_set_key((char *) skey, 0);
+ if (status != 0)
return(status);
#endif /* !NOENCRYPTION */
- (void) strcpy(st_rlm,realm);
- (void) strcpy(st_nam,service);
- (void) strcpy(st_inst,instance);
+ strcpy(st_rlm,realm);
+ strcpy(st_nam,service);
+ 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);
- (void) memcpy((char *)(tkt->dat),ptr+1,tkt->length);
+ return RD_AP_MODIFIED;
+ memcpy(tkt->dat, ptr + 1, tkt->length);
if (krb_ap_req_debug)
- log("ticket->length: %d",tkt->length);
+ krb_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,serv_key,serv_ksched.s))
- return(RD_AP_UNDEC);
+ if (decomp_ticket(tkt, &ad->k_flags, ad->pname, ad->pinst, ad->prealm,
+ &(ad->address), ad->session, &(ad->life),
+ &(ad->time_sec), sname, iname, serv_key, serv_ksched.s))
+ 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);
+ krb_log("Ticket Contents.");
+ krb_log(" Aname: %s.%s",ad->pname,
+ ((int)*(ad->prealm) ? ad->prealm : "Athena"));
+ krb_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);
- (void) memcpy((char *)(req_id->dat),ptr + tkt->length, req_id->length);
+ return RD_AP_MODIFIED;
+ memcpy(req_id->dat, ptr + tkt->length, req_id->length);
#ifndef NOENCRYPTION
/* And decrypt it with the session key from the ticket */
- if (krb_ap_req_debug) log("About to decrypt authenticator");
- sched = check_key_sched_cache (ad->session);
+ if (krb_ap_req_debug)
+ krb_log("About to decrypt authenticator");
+ sched = check_key_sched_cache(ad->session);
if (!sched) {
sched = &seskey_sched;
- key_sched (ad->session, seskey_sched.s);
- add_to_key_sched_cache (ad->session, &seskey_sched);
+ key_sched(ad->session, seskey_sched.s);
+ add_to_key_sched_cache(ad->session, &seskey_sched);
}
/* can't do much to optimize this... */
- pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
- (long) req_id->length, sched->s, ad->session,DES_DECRYPT);
- if (krb_ap_req_debug) log("Done.");
+ pcbc_encrypt((C_Block *) req_id->dat, (C_Block *) req_id->dat,
+ (long) req_id->length, sched->s, ad->session, DES_DECRYPT);
+ if (krb_ap_req_debug)
+ krb_log("Done.");
#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;
+ 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;
+ 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;
+ strcpy(r_realm,ptr); /* Authentication name */
+ ptr += strlen(r_realm) + 1;
check_ptr();
- (void) memcpy((char *)&ad->checksum,ptr,4); /* Checksum */
+ memcpy(&ad->checksum, ptr, 4); /* Checksum */
ptr += 4;
check_ptr();
- if (swap_bytes) swap_u_long(ad->checksum);
+ 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??? */
@@ -408,61 +401,102 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
#endif /* lint */
check_ptr();
/* assume sizeof(r_time_sec) == 4 ?? */
- (void) memcpy((char *)&r_time_sec,ptr,4); /* Time (coarse) */
- if (swap_bytes) swap_u_long(r_time_sec);
+ memcpy(&r_time_sec,ptr,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);
+ krb_log("Pname: %s %s",ad->pname,r_aname);
if (strcmp(ad->pname,r_aname) != 0)
- return(RD_AP_INCON);
+ return RD_AP_INCON;
if (strcmp(ad->pinst,r_inst) != 0)
- return(RD_AP_INCON);
+ 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);
+ krb_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);
+ krb_log("Address: %d %d", ad->address, from_addr);
if (from_addr && (ad->address != from_addr))
- return(RD_AP_BADD);
+ return RD_AP_BADD;
delta_t = abs((int)(t_local.tv_sec - r_time_sec));
if (delta_t > CLOCK_SKEW) {
- (void) gettimeofday(&t_local, (struct timezone *)0);
+ gettimeofday(&t_local, NULL);
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);
+ if (krb_ap_req_debug) {
+ krb_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 (krb_ap_req_debug) {
+ krb_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);
+ 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;
}
- 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);
+ return RD_AP_OK;
}
#endif /* NOENCRYPTION */
+int
+krb_find_ticket(authent, ticket)
+ KTEXT authent, ticket;
+{
+ char *ptr; /* For stepping through */
+
+ /* Check for bogus length. */
+ if (authent->length <= 0)
+ return RD_AP_MODIFIED;
+
+ ptr = (char *) authent->dat;
+
+ /* check version */
+ if (KRB_PROT_VERSION != (unsigned int) *ptr++)
+ return RD_AP_VERSION;
+
+ /* Make sure msg type is ok. */
+ switch (*ptr++ & ~1) {
+ case AUTH_MSG_APPL_REQUEST:
+ case AUTH_MSG_APPL_REQUEST_MUTUAL:
+ break;
+ default:
+ return RD_AP_MSG_TYPE;
+ }
+
+ *ptr++; /* skip server key version */
+ ptr += strlen(ptr) + 1; /* skip the realm "hint" */
+
+ /* Get ticket from authenticator */
+ ticket->length = (int) *ptr++;
+ if ((ticket->length + (ptr + 1 - (char *) authent->dat)) > authent->length)
+ return RD_AP_MODIFIED;
+ memcpy((char *)(ticket->dat),ptr+1,ticket->length);
+
+ return RD_AP_OK;
+}
+
static char local_realm_buffer[REALM_SZ+1];
+int
krb_get_lrealm(r,n)
char *r;
int n;
@@ -470,125 +504,111 @@ krb_get_lrealm(r,n)
FILE *cnffile, *fopen();
if (n > 1)
- return(KFAILURE); /* Temporary restriction */
+ return KFAILURE; /* Temporary restriction */
+
+ if (my_realm[0]) {
+ strcpy(r, my_realm);
+ return KSUCCESS;
+ }
if (local_realm_buffer[0]) {
- strcpy (r, local_realm_buffer);
+ strcpy(r, local_realm_buffer);
return KSUCCESS;
}
- if ((cnffile = fopen(KRB_CONF, "r")) == NULL) {
+ cnffile = fopen(KRB_CONF, "r");
+ if (cnffile == NULL) {
if (n == 1) {
- (void) strcpy(r, KRB_REALM);
- return(KSUCCESS);
+ strcpy(r, KRB_REALM);
+ return KSUCCESS;
+ } else {
+ return KFAILURE;
}
- else
- return(KFAILURE);
}
if (fscanf(cnffile,"%s",r) != 1) {
- (void) fclose(cnffile);
- return(KFAILURE);
+ fclose(cnffile);
+ return KFAILURE;
}
- (void) fclose(cnffile);
- return(KSUCCESS);
+ fclose(cnffile);
+ return KSUCCESS;
}
-#endif /* KERBEROS */
+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) */
+ des_key_sched key_s; /* The precomputed key schedule */
+{
+ static int tkt_swap_bytes;
+ unsigned char *uptr;
+ char *ptr = (char *)tkt->dat;
-#ifdef ibm032
+#ifndef NOENCRYPTION
+ /* Do the decryption */
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,
+ (long) tkt->length,key_s,(C_Block *) key,0);
+#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);
+ strcpy(pname,ptr); /* pname */
+ ptr += strlen(pname) + 1;
-#if defined (__GNUC__) || defined (__HIGHC__)
-#ifdef __HIGHC__
-#define asm _ASM
-#endif
+ if (strlen(ptr) > INST_SZ)
+ return(KFAILURE);
+ strcpy(pinstance,ptr); /* instance */
+ ptr += strlen(pinstance) + 1;
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted.
- */
+ if (strlen(ptr) > REALM_SZ)
+ return(KFAILURE);
+ strcpy(prealm,ptr); /* realm */
+ ptr += strlen(prealm) + 1;
+ /* temporary hack until realms are dealt with properly */
+ if (*prealm == 0)
+ strcpy(prealm, ZGetRealm());
-void asm_wrapper_kopt_c () {
- /*
- * Multiply routine. The C library routine tries to optimize around
- * the multiply-step instruction, which was slower in earlier versions
- * of the processor; this is no longer useful. Derived from assembly
- * code written by John Carr.
- */
-
- /* data section */
- asm(".data\n.align 2");
- asm(".globl _ulmul$$ \n _ulmul$$:");
- asm(".globl _lmul$$ \n _lmul$$: .long lmul$$");
- /* text section */
- asm(".text \n .align 1");
- asm(".globl lmul$$ \n lmul$$:");
- asm(".globl ulmul$$ \n ulmul$$:");
- asm(".globl _.lmul$$ \n _.lmul$$:");
- asm(".globl _.ulmul$$ \n _.ulmul$$:");
- asm(" s r0,r0 \n mts r10,r2"); /* set up multiply, and go: */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" brx r15 \n mfs r10,r2"); /* return result */
- asm(" .long 0xdf02df00"); /* for debugging */
-
-#ifdef USE_LIBC_STRLEN
- }
-#else
- /* Note- do not use this version of strlen when compiling with -g; -g */
- /* causes extra no-ops to be inserted between instructions, which cause */
- /* the delayed branch instructions to fail. */
+ memcpy((char *)paddress, ptr, 4); /* net address */
+ ptr += 4;
- /*
- * Fast strlen, with optional trapping of null pointers. Also from
- * John Carr.
- */
- /* data */
- asm(".data\n.align 2");
- asm(".globl _strlen \n _strlen: .long _.strlen");
- /* text */
- asm(".text\n.align 1");
- asm(".globl _.strlen \n _.strlen:");
-#if 1
- asm(" ti 2,r2,0"); /* trap if r2 is NULL */
-#endif
- asm(" ls r4,0(r2)");
- asm(" mr r0,r2");
- asm(" nilz r3,r2,3");
- asm(" beqx 0f");
- asm(" nilo r2,r2,0xfffc"); /* clear low bits */
- asm(" sis r3,2"); /* test appropriate bytes of 1st word */
- asm(" jeq 2f"); /* s & 3 == 2 */
- asm(" jm 1f"); /* s & 3 == 1 */
- asm(" j 3f"); /* s & 3 == 3 */
- asm("0: srpi16 r4,8"); /* byte 0 */
- asm(" jeq 4f");
- asm("1: niuz r5,r4,0xff"); /* byte 1 */
- asm(" jeq 5f");
- asm("2: nilz r5,r4,0xff00"); /* byte 2 */
- asm(" jeq 6f");
- asm("3: sli16 r4,8"); /* byte 3 */
- asm(" jeq 7f");
- asm(" ls r4,4(r2)"); /* get next word and continue */
- asm(" bx 0b");
- asm(" inc r2,4");
- asm("4: brx r15"); /* byte 0 is zero */
- asm(" s r2,r0");
- asm("5: s r2,r0"); /* byte 1 is zero */
- asm(" brx r15");
- asm(" inc r2,1");
- asm("6: s r2,r0"); /* byte 2 is zero */
- asm(" brx r15");
- asm(" inc r2,2");
- asm("7: s r2,r0"); /* byte 3 is zero */
- asm(" brx r15");
- asm(" inc r2,3");
- asm(" .long 0xdf02df00"); /* trace table */
+ memcpy((char *)session, ptr, 8); /* session key */
+ ptr+= 8;
+
+ /* get lifetime, being certain we don't get negative lifetimes */
+ uptr = (unsigned char *) ptr++;
+ *life = (int) *uptr;
+
+ memcpy((char *) time_sec, ptr, 4); /* issue time */
+ ptr += 4;
+ if (tkt_swap_bytes)
+ swap_u_long(*time_sec);
+
+ strcpy(sname,ptr); /* service name */
+ ptr += 1 + strlen(sname);
+
+ strcpy(sinstance,ptr); /* instance */
+ ptr += 1 + strlen(sinstance);
+
+ return(KSUCCESS);
}
-#endif /* USE_LIBC_STRLEN */
-#endif /* __GNUC__ || __HIGHC__ */
-#endif /* ibm032 */
+#endif /* ZEPHYR_USES_KERBEROS */
+
diff --git a/server/kopt.c.auth b/server/kopt.c.auth
deleted file mode 100644
index 99fe48e..0000000
--- a/server/kopt.c.auth
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * $Source$
- * $Author$
- *
- * Copyright 1985, 1986, 1987, 1988, 1990, 1991 by the Massachusetts
- * Institute of Technology.
- *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
- */
-
-/*
- * This includes code taken from:
- * Kerberos: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp
- * Kerberos: prot.h,v 4.13 89/01/24 14:27:22 jtkohl Exp
- * Kerberos: krb_conf.h,v 4.0 89/01/23 09:59:27 jtkohl Exp
- */
-
-#ifndef lint
-#ifndef SABER
-static char *rcsid_rd_req_c =
- "$Id$";
-#endif /* lint */
-#endif /* SABER */
-
-#ifdef KERBEROS
-#ifndef NOENCRYPTION
-
-#include <zephyr/mit-copyright.h>
-#include <zephyr/zephyr.h>
-#include <stdio.h>
-#include <krb.h>
-#include "zserver.h"
-
-/* Byte ordering */
-static int krbONE = 1;
-#define HOST_BYTE_ORDER (* (char *) &krbONE)
-
-#define KRB_PROT_VERSION 4
-
-/* Message types , always leave lsb for byte order */
-
-#define AUTH_MSG_KDC_REQUEST 1<<1
-#define AUTH_MSG_KDC_REPLY 2<<1
-#define AUTH_MSG_APPL_REQUEST 3<<1
-#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1
-#define AUTH_MSG_ERR_REPLY 5<<1
-#define AUTH_MSG_PRIVATE 6<<1
-#define AUTH_MSG_SAFE 7<<1
-#define AUTH_MSG_APPL_ERR 8<<1
-#define AUTH_MSG_DIE 63<<1
-
-/* values for kerb error codes */
-
-#define KERB_ERR_OK 0
-#define KERB_ERR_NAME_EXP 1
-#define KERB_ERR_SERVICE_EXP 2
-#define KERB_ERR_AUTH_EXP 3
-#define KERB_ERR_PKT_VER 4
-#define KERB_ERR_NAME_MAST_KEY_VER 5
-#define KERB_ERR_SERV_MAST_KEY_VER 6
-#define KERB_ERR_BYTE_ORDER 7
-#define KERB_ERR_PRINCIPAL_UNKNOWN 8
-#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9
-#define KERB_ERR_NULL_KEY 10
-
-#include <sys/time.h>
-#include <string.h>
-
-extern int krb_ap_req_debug;
-
-extern struct timeval t_local;
-
-/*
- * Keep the following information around for subsequent calls
- * to this routine by the same server using the same key.
- */
-
-static Sched serv_ksched; /* Key sched to decrypt ticket */
-static des_cblock serv_key; /* 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 */
-
-/*
- * Cache of key schedules
- */
-#define HASH_SIZE_1 255 /* not a power of 2 */
-#define HASH_SIZE_2 3
-static unsigned long last_use;
-typedef struct {
- unsigned long last_time_used;
- des_cblock key;
- Sched schedule;
-} KeySchedRec;
-static KeySchedRec scheds[HASH_SIZE_1][HASH_SIZE_2];
-
-#ifdef __STDC__
-Sched* check_key_sched_cache (des_cblock key)
-#else
-Sched* check_key_sched_cache (key)
- des_cblock key;
-#endif
-{
- unsigned int hash_value = key[0] + key[1] * 256;
- KeySchedRec *rec = scheds[hash_value % HASH_SIZE_1];
- int i;
-
- for (i = HASH_SIZE_2 - 1; i >= 0; i--)
- if (rec[i].last_time_used
- && key[0] == rec[i].key[0]
- && !memcmp (key, rec[i].key, sizeof (des_cblock))) {
- rec[i].last_time_used = last_use++;
- return &rec[i].schedule;
- }
- return 0;
-}
-
-#ifdef __STDC__
-void add_to_key_sched_cache (des_cblock key, Sched* sched)
-#else
-void add_to_key_sched_cache (key, sched)
- des_cblock key;
- Sched* sched;
-#endif
-{
- unsigned int hash_value = key[0] + key[1] * 256;
- KeySchedRec *rec = scheds[hash_value % HASH_SIZE_1];
- int i, oldest = HASH_SIZE_2 - 1;
-
- for (i = HASH_SIZE_2 - 1; i >= 0; i--) {
- if (rec[i].last_time_used == 0) {
- oldest = i;
- break;
- }
- if (rec[i].last_time_used < rec[oldest].last_time_used)
- oldest = i;
- }
- (void) memcpy (rec[oldest].key, key, sizeof (des_cblock));
- rec[oldest].schedule = *sched;
- rec[oldest].last_time_used = last_use++;
-}
-
-/*
- * 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 variable "serv_key". A key schedule is
- * generated for "serv_key" and returned in the external variable
- * "serv_ksched".
- *
- * 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
- (void) memset(serv_key, 0, sizeof(serv_key));
- return KSUCCESS;
-#else /* Encrypt */
- Sched *s;
- int ret;
-
- if (cvt)
- string_to_key(key,serv_key);
- else
- (void) memcpy((char *)serv_key,key,8);
-
- s = check_key_sched_cache (serv_key);
- if (s) {
- serv_ksched = *s;
- return 0;
- }
- ret = des_key_sched (serv_key, serv_ksched.s);
- add_to_key_sched_cache (serv_key, &serv_ksched);
- return ret;
-#endif /* NOENCRYPTION */
-}
-
-
-/*
- * 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.
- */
-
-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 */
-{
- KTEXT_ST ticket; /* Temp storage for ticket */
- KTEXT tkt = &ticket;
- KTEXT_ST req_id_st; /* Temp storage for authenticator */
- register KTEXT req_id = &req_id_st;
-
- char realm[REALM_SZ]; /* Realm of issuing kerberos */
- Sched seskey_sched, *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 */
- int swap_bytes; /* Need to swap bytes? */
- int mutual; /* Mutual authentication requested? */
- 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,(int) s_kvno,
- fn,(char *)skey))
- return(RD_AP_UNDEC);
- if ((status = krb_set_key((char *)skey,0)) != 0)
- return(status);
-#endif /* !NOENCRYPTION */
- (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);
- (void) memcpy((char *)(tkt->dat),ptr+1,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,serv_key,serv_ksched.s))
- 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);
- (void) memcpy((char *)(req_id->dat),ptr + tkt->length, req_id->length);
-
-#ifndef NOENCRYPTION
- /* And decrypt it with the session key from the ticket */
- if (krb_ap_req_debug) log("About to decrypt authenticator");
- sched = check_key_sched_cache (ad->session);
- if (!sched) {
- sched = &seskey_sched;
- key_sched (ad->session, seskey_sched.s);
- add_to_key_sched_cache (ad->session, &seskey_sched);
- }
- /* can't do much to optimize this... */
- pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
- (long) req_id->length, sched->s, ad->session,DES_DECRYPT);
- if (krb_ap_req_debug) log("Done.");
-#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();
- (void) memcpy((char *)&ad->checksum,ptr,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 ?? */
- (void) memcpy((char *)&r_time_sec,ptr,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);
-
- delta_t = abs((int)(t_local.tv_sec - r_time_sec));
- if (delta_t > CLOCK_SKEW) {
- (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);
-}
-#endif /* NOENCRYPTION */
-
-int krb_find_ticket(authent, ticket)
- KTEXT authent, ticket;
-{
- register char *ptr; /* For stepping through */
-
- /* Check for bogus length. */
- if (authent->length <= 0)
- return(RD_AP_MODIFIED);
-
- ptr = (char *) authent->dat;
-
- /* check version */
- if (KRB_PROT_VERSION != (unsigned int) *ptr++)
- return(RD_AP_VERSION);
-
- /* Make sure msg type is ok. */
- switch (*ptr++ & ~1) {
- case AUTH_MSG_APPL_REQUEST:
- case AUTH_MSG_APPL_REQUEST_MUTUAL:
- break;
- default:
- return(RD_AP_MSG_TYPE);
- }
-
- *ptr++; /* skip server key version */
- ptr += strlen(ptr) + 1; /* skip the realm "hint" */
-
- /* Get ticket from authenticator */
- ticket->length = (int) *ptr++;
- if ((ticket->length + (ptr+1 - (char *) authent->dat)) > authent->length)
- return(RD_AP_MODIFIED);
- (void) memcpy((char *)(ticket->dat),ptr+1,ticket->length);
-
- return RD_AP_OK;
-}
-
-static char local_realm_buffer[REALM_SZ+1];
-
-krb_get_lrealm(r,n)
- char *r;
- int n;
-{
- FILE *cnffile, *fopen();
-
- if (n > 1)
- return(KFAILURE); /* Temporary restriction */
-
- if (local_realm_buffer[0]) {
- strcpy (r, local_realm_buffer);
- return KSUCCESS;
- }
-
- 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);
-}
-
-#endif /* KERBEROS */
-
-#ifdef ibm032
-
-#if defined (__GNUC__) || defined (__HIGHC__)
-#ifdef __HIGHC__
-#define asm _ASM
-#endif
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted.
- */
-
-void asm_wrapper_kopt_c () {
- /*
- * Multiply routine. The C library routine tries to optimize around
- * the multiply-step instruction, which was slower in earlier versions
- * of the processor; this is no longer useful. Derived from assembly
- * code written by John Carr.
- */
-
- /* data section */
- asm(".data\n.align 2");
- asm(".globl _ulmul$$ \n _ulmul$$:");
- asm(".globl _lmul$$ \n _lmul$$: .long lmul$$");
- /* text section */
- asm(".text \n .align 1");
- asm(".globl lmul$$ \n lmul$$:");
- asm(".globl ulmul$$ \n ulmul$$:");
- asm(".globl _.lmul$$ \n _.lmul$$:");
- asm(".globl _.ulmul$$ \n _.ulmul$$:");
- asm(" s r0,r0 \n mts r10,r2"); /* set up multiply, and go: */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" brx r15 \n mfs r10,r2"); /* return result */
- asm(" .long 0xdf02df00"); /* for debugging */
-
-#ifdef USE_LIBC_STRLEN
- }
-#else
- /* Note- do not use this version of strlen when compiling with -g; -g */
- /* causes extra no-ops to be inserted between instructions, which cause */
- /* the delayed branch instructions to fail. */
-
- /*
- * Fast strlen, with optional trapping of null pointers. Also from
- * John Carr.
- */
- /* data */
- asm(".data\n.align 2");
- asm(".globl _strlen \n _strlen: .long _.strlen");
- /* text */
- asm(".text\n.align 1");
- asm(".globl _.strlen \n _.strlen:");
-#if 1
- asm(" ti 2,r2,0"); /* trap if r2 is NULL */
-#endif
- asm(" ls r4,0(r2)");
- asm(" mr r0,r2");
- asm(" nilz r3,r2,3");
- asm(" beqx 0f");
- asm(" nilo r2,r2,0xfffc"); /* clear low bits */
- asm(" sis r3,2"); /* test appropriate bytes of 1st word */
- asm(" jeq 2f"); /* s & 3 == 2 */
- asm(" jm 1f"); /* s & 3 == 1 */
- asm(" j 3f"); /* s & 3 == 3 */
- asm("0: srpi16 r4,8"); /* byte 0 */
- asm(" jeq 4f");
- asm("1: niuz r5,r4,0xff"); /* byte 1 */
- asm(" jeq 5f");
- asm("2: nilz r5,r4,0xff00"); /* byte 2 */
- asm(" jeq 6f");
- asm("3: sli16 r4,8"); /* byte 3 */
- asm(" jeq 7f");
- asm(" ls r4,4(r2)"); /* get next word and continue */
- asm(" bx 0b");
- asm(" inc r2,4");
- asm("4: brx r15"); /* byte 0 is zero */
- asm(" s r2,r0");
- asm("5: s r2,r0"); /* byte 1 is zero */
- asm(" brx r15");
- asm(" inc r2,1");
- asm("6: s r2,r0"); /* byte 2 is zero */
- asm(" brx r15");
- asm(" inc r2,2");
- asm("7: s r2,r0"); /* byte 3 is zero */
- asm(" brx r15");
- asm(" inc r2,3");
- asm(" .long 0xdf02df00"); /* trace table */
-}
-#endif /* USE_LIBC_STRLEN */
-#endif /* __GNUC__ || __HIGHC__ */
-#endif /* ibm032 */
-
diff --git a/server/kopt.c.old b/server/kopt.c.old
deleted file mode 100644
index 90032f1..0000000
--- a/server/kopt.c.old
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * $Source$
- * $Author$
- *
- * Copyright 1985, 1986, 1987, 1988, 1990, 1991 by the Massachusetts
- * Institute of Technology.
- *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
- */
-
-/*
- * This includes code taken from:
- * Kerberos: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp
- * Kerberos: prot.h,v 4.13 89/01/24 14:27:22 jtkohl Exp
- * Kerberos: krb_conf.h,v 4.0 89/01/23 09:59:27 jtkohl Exp
- */
-
-#ifndef lint
-#ifndef SABER
-static char *rcsid_rd_req_c =
- "$Id$";
-#endif /* lint */
-#endif /* SABER */
-
-#ifdef KERBEROS
-#ifndef NOENCRYPTION
-
-#include <zephyr/mit-copyright.h>
-#include <zephyr/zephyr.h>
-#include <stdio.h>
-#include <krb.h>
-#include "zserver.h"
-
-/* Byte ordering */
-extern int krbONE;
-#define HOST_BYTE_ORDER (* (char *) &krbONE)
-
-#define KRB_PROT_VERSION 4
-
-/* Message types , always leave lsb for byte order */
-
-#define AUTH_MSG_KDC_REQUEST 1<<1
-#define AUTH_MSG_KDC_REPLY 2<<1
-#define AUTH_MSG_APPL_REQUEST 3<<1
-#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1
-#define AUTH_MSG_ERR_REPLY 5<<1
-#define AUTH_MSG_PRIVATE 6<<1
-#define AUTH_MSG_SAFE 7<<1
-#define AUTH_MSG_APPL_ERR 8<<1
-#define AUTH_MSG_DIE 63<<1
-
-/* values for kerb error codes */
-
-#define KERB_ERR_OK 0
-#define KERB_ERR_NAME_EXP 1
-#define KERB_ERR_SERVICE_EXP 2
-#define KERB_ERR_AUTH_EXP 3
-#define KERB_ERR_PKT_VER 4
-#define KERB_ERR_NAME_MAST_KEY_VER 5
-#define KERB_ERR_SERV_MAST_KEY_VER 6
-#define KERB_ERR_BYTE_ORDER 7
-#define KERB_ERR_PRINCIPAL_UNKNOWN 8
-#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9
-#define KERB_ERR_NULL_KEY 10
-
-#include <sys/time.h>
-#include <strings.h>
-
-extern int krb_ap_req_debug;
-
-extern struct timeval t_local;
-
-/*
- * Keep the following information around for subsequent calls
- * to this routine by the same server using the same key.
- */
-
-static Sched serv_ksched; /* Key sched to decrypt ticket */
-static des_cblock serv_key; /* 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 */
-
-/*
- * Cache of key schedules
- */
-#define HASH_SIZE_1 255 /* not a power of 2 */
-#define HASH_SIZE_2 3
-static unsigned long last_use;
-typedef struct {
- unsigned long last_time_used;
- des_cblock key;
- Sched schedule;
-} KeySchedRec;
-static KeySchedRec scheds[HASH_SIZE_1][HASH_SIZE_2];
-
-#ifdef __STDC__
-Sched* check_key_sched_cache (des_cblock key)
-#else
-Sched* check_key_sched_cache (key)
- des_cblock key;
-#endif
-{
- unsigned int hash_value = key[0] + key[1] * 256;
- KeySchedRec *rec = scheds[hash_value % HASH_SIZE_1];
- int i;
-
- for (i = HASH_SIZE_2 - 1; i >= 0; i--)
- if (rec[i].last_time_used
- && key[0] == rec[i].key[0]
- && !memcmp (key, rec[i].key, sizeof (des_cblock))) {
- rec[i].last_time_used = last_use++;
- return &rec[i].schedule;
- }
- return 0;
-}
-
-#ifdef __STDC__
-void add_to_key_sched_cache (des_cblock key, Sched* sched)
-#else
-void add_to_key_sched_cache (key, sched)
- des_cblock key;
- Sched* sched;
-#endif
-{
- unsigned int hash_value = key[0] + key[1] * 256;
- KeySchedRec *rec = scheds[hash_value % HASH_SIZE_1];
- int i, oldest = HASH_SIZE_2 - 1;
-
- for (i = HASH_SIZE_2 - 1; i >= 0; i--) {
- if (rec[i].last_time_used == 0) {
- oldest = i;
- break;
- }
- if (rec[i].last_time_used < rec[oldest].last_time_used)
- oldest = i;
- }
- (void) memcpy (rec[oldest].key, key, sizeof (des_cblock));
- rec[oldest].schedule = *sched;
- rec[oldest].last_time_used = last_use++;
-}
-
-/*
- * 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 variable "serv_key". A key schedule is
- * generated for "serv_key" and returned in the external variable
- * "serv_ksched".
- *
- * 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
- (void) memset(serv_key, 0, sizeof(serv_key));
- return KSUCCESS;
-#else /* Encrypt */
- Sched *s;
- int ret;
-
- if (cvt)
- string_to_key(key,serv_key);
- else
- (void) memcpy((char *)serv_key,key,8);
-
- s = check_key_sched_cache (serv_key);
- if (s) {
- serv_ksched = *s;
- return 0;
- }
- ret = des_key_sched (serv_key, serv_ksched.s);
- add_to_key_sched_cache (serv_key, &serv_ksched);
- return ret;
-#endif /* NOENCRYPTION */
-}
-
-
-/*
- * 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.
- */
-
-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 */
-{
- KTEXT_ST ticket; /* Temp storage for ticket */
- KTEXT tkt = &ticket;
- KTEXT_ST req_id_st; /* Temp storage for authenticator */
- register KTEXT req_id = &req_id_st;
-
- char realm[REALM_SZ]; /* Realm of issuing kerberos */
- Sched seskey_sched, *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 */
- int swap_bytes; /* Need to swap bytes? */
- int mutual; /* Mutual authentication requested? */
- 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,(int) s_kvno,
- fn,(char *)skey))
- return(RD_AP_UNDEC);
- if ((status = krb_set_key((char *)skey,0)) != 0)
- return(status);
-#endif /* !NOENCRYPTION */
- (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);
- (void) memcpy((char *)(tkt->dat),ptr+1,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,serv_key,serv_ksched.s))
- 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);
- (void) memcpy((char *)(req_id->dat),ptr + tkt->length, req_id->length);
-
-#ifndef NOENCRYPTION
- /* And decrypt it with the session key from the ticket */
- if (krb_ap_req_debug) log("About to decrypt authenticator");
- sched = check_key_sched_cache (ad->session);
- if (!sched) {
- sched = &seskey_sched;
- key_sched (ad->session, seskey_sched.s);
- add_to_key_sched_cache (ad->session, &seskey_sched);
- }
- /* can't do much to optimize this... */
- pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
- (long) req_id->length, sched->s, ad->session,DES_DECRYPT);
- if (krb_ap_req_debug) log("Done.");
-#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();
- (void) memcpy((char *)&ad->checksum,ptr,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 ?? */
- (void) memcpy((char *)&r_time_sec,ptr,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);
-
- delta_t = abs((int)(t_local.tv_sec - r_time_sec));
- if (delta_t > CLOCK_SKEW) {
- (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);
-}
-#endif /* NOENCRYPTION */
-
-static char local_realm_buffer[REALM_SZ+1];
-
-krb_get_lrealm(r,n)
- char *r;
- int n;
-{
- FILE *cnffile, *fopen();
-
- if (n > 1)
- return(KFAILURE); /* Temporary restriction */
-
- if (local_realm_buffer[0]) {
- strcpy (r, local_realm_buffer);
- return KSUCCESS;
- }
-
- 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);
-}
-
-#endif /* KERBEROS */
-
-#ifdef ibm032
-
-#if defined (__GNUC__) || defined (__HIGHC__)
-#ifdef __HIGHC__
-#define asm _ASM
-#endif
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted.
- */
-
-void asm_wrapper_kopt_c () {
- /*
- * Multiply routine. The C library routine tries to optimize around
- * the multiply-step instruction, which was slower in earlier versions
- * of the processor; this is no longer useful. Derived from assembly
- * code written by John Carr.
- */
-
- /* data section */
- asm(".data\n.align 2");
- asm(".globl _ulmul$$ \n _ulmul$$:");
- asm(".globl _lmul$$ \n _lmul$$: .long lmul$$");
- /* text section */
- asm(".text \n .align 1");
- asm(".globl lmul$$ \n lmul$$:");
- asm(".globl ulmul$$ \n ulmul$$:");
- asm(".globl _.lmul$$ \n _.lmul$$:");
- asm(".globl _.ulmul$$ \n _.ulmul$$:");
- asm(" s r0,r0 \n mts r10,r2"); /* set up multiply, and go: */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" m r0,r3 \n m r0,r3 \n m r0,r3 \n m r0,r3"); /* execute 4 steps */
- asm(" brx r15 \n mfs r10,r2"); /* return result */
- asm(" .long 0xdf02df00"); /* for debugging */
-
-#ifdef USE_LIBC_STRLEN
- }
-#else
- /* Note- do not use this version of strlen when compiling with -g; -g */
- /* causes extra no-ops to be inserted between instructions, which cause */
- /* the delayed branch instructions to fail. */
-
- /*
- * Fast strlen, with optional trapping of null pointers. Also from
- * John Carr.
- */
- /* data */
- asm(".data\n.align 2");
- asm(".globl _strlen \n _strlen: .long _.strlen");
- /* text */
- asm(".text\n.align 1");
- asm(".globl _.strlen \n _.strlen:");
-#if 1
- asm(" ti 2,r2,0"); /* trap if r2 is NULL */
-#endif
- asm(" ls r4,0(r2)");
- asm(" mr r0,r2");
- asm(" nilz r3,r2,3");
- asm(" beqx 0f");
- asm(" nilo r2,r2,0xfffc"); /* clear low bits */
- asm(" sis r3,2"); /* test appropriate bytes of 1st word */
- asm(" jeq 2f"); /* s & 3 == 2 */
- asm(" jm 1f"); /* s & 3 == 1 */
- asm(" j 3f"); /* s & 3 == 3 */
- asm("0: srpi16 r4,8"); /* byte 0 */
- asm(" jeq 4f");
- asm("1: niuz r5,r4,0xff"); /* byte 1 */
- asm(" jeq 5f");
- asm("2: nilz r5,r4,0xff00"); /* byte 2 */
- asm(" jeq 6f");
- asm("3: sli16 r4,8"); /* byte 3 */
- asm(" jeq 7f");
- asm(" ls r4,4(r2)"); /* get next word and continue */
- asm(" bx 0b");
- asm(" inc r2,4");
- asm("4: brx r15"); /* byte 0 is zero */
- asm(" s r2,r0");
- asm("5: s r2,r0"); /* byte 1 is zero */
- asm(" brx r15");
- asm(" inc r2,1");
- asm("6: s r2,r0"); /* byte 2 is zero */
- asm(" brx r15");
- asm(" inc r2,2");
- asm("7: s r2,r0"); /* byte 3 is zero */
- asm(" brx r15");
- asm(" inc r2,3");
- asm(" .long 0xdf02df00"); /* trace table */
-}
-#endif /* USE_LIBC_STRLEN */
-#endif /* __GNUC__ || __HIGHC__ */
-#endif /* ibm032 */
diff --git a/server/kstuff.c b/server/kstuff.c
index 49089de..ff695f5 100644
--- a/server/kstuff.c
+++ b/server/kstuff.c
@@ -1,4 +1,3 @@
-#ifdef KERBEROS
/* This file is part of the Project Athena Zephyr Notification System.
* It contains functions for dealing with Kerberos functions in the server.
*
@@ -13,40 +12,42 @@
* $Header$
*/
+#include "zserver.h"
+
#ifndef lint
#ifndef SABER
-static char rcsid_kstuff_c[] = "$Id$";
+static const char rcsid_kstuff_c[] = "$Id$";
#endif
#endif
-#include "zserver.h"
+#ifdef ZEPHYR_USES_KERBEROS
-#include <ctype.h>
-#include <netdb.h>
-#include <string.h>
+/* Keep a hash table mapping tickets to session keys, so we can do a fast
+ * check of the cryptographic checksum without doing and DES decryptions.
+ * Also remember the expiry time of the ticket, so that we can sweep the
+ * table periodically. */
-#include <zephyr/zephyr_internal.h>
-#ifdef KERBEROS
-#include <zephyr/krb_err.h>
-#endif
+#define HASHTAB_SIZE 4091
-static char tkt_file[] = ZEPHYR_TKFILE;
+typedef struct hash_entry Hash_entry;
-
-struct AuthEnt {
- Zconst char *data;
- int len;
- ZSTRING *principal;
-#ifndef NOENCRYPTION
+/* The ticket comes at the end, in a variable-length array. */
+struct hash_entry {
C_Block session_key;
-#endif
- long expire_time;
- struct sockaddr_in from;
+ time_t expires;
+ char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
+ Hash_entry *next;
+ int ticket_len;
+ unsigned char ticket[1];
};
-#define HASH_SIZE_1 513
-#define HASH_SIZE_2 3
-static struct AuthEnt auth_cache[HASH_SIZE_1][HASH_SIZE_2];
+Hash_entry *hashtab[HASHTAB_SIZE];
+
+static int hash_ticket __P((unsigned char *, int));
+static void add_session_key __P((KTEXT, C_Block, char *, time_t));
+static int find_session_key __P((KTEXT, C_Block, char *));
+static ZChecksum_t compute_checksum __P((ZNotice_t *, C_Block));
+static ZChecksum_t compute_rlm_checksum __P((ZNotice_t *, C_Block));
/*
* GetKerberosData
@@ -114,7 +115,7 @@ GetKerberosData(fd, haddr, kdata, service, srvtab)
int
SendKerberosData(fd, ticket, service, host)
- int fd; /* file descriptor to write onto */
+ int fd; /* file descriptor to write onto */
KTEXT ticket; /* where to put ticket (return) */
char *service; /* service name, foreign host */
char *host;
@@ -125,242 +126,327 @@ SendKerberosData(fd, ticket, service, host)
int written;
int size_to_write;
- rem = krb_get_lrealm(krb_realm,1);
- if (rem != KSUCCESS)
- return rem + krb_err_base;
-
- rem = krb_mk_req( ticket, service, host, krb_realm, (u_long)0 );
+ rem = krb_mk_req(ticket, service, host, ZGetRealm(), (u_long) 0);
if (rem != KSUCCESS)
return rem + krb_err_base;
(void) sprintf(p,"%d ",ticket->length);
size_to_write = strlen (p);
if ((written = write(fd, p, size_to_write)) != size_to_write)
- if (written < 0)
- return errno;
- else
- return ZSRV_PKSHORT;
- if ((written = write(fd, (caddr_t) (ticket->dat), ticket->length)) != ticket->length)
- if (written < 0)
- return errno;
- else
- return ZSRV_PKSHORT;
+ return (written < 0) ? errno : ZSRV_PKSHORT;
+ if ((written = write(fd, (caddr_t) (ticket->dat), ticket->length))
+ != ticket->length)
+ return (written < 0) ? errno : ZSRV_PKSHORT;
return 0;
}
-/* Hack to replace the kerberos library's idea of the ticket file with
- our idea */
-char *
-tkt_string()
-{
- return tkt_file;
-}
+#endif /* ZEPHYR_USES_KERBEROS */
-/* Check authentication of the notice.
- If it looks authentic but fails the Kerberos check, return -1.
- If it looks authentic and passes the Kerberos check, return 1.
- If it doesn't look authentic, return 0
-
- When not using Kerberos, return (looks-authentic-p)
- */
+int
+ZCheckRealmAuthentication(notice, from, realm)
+ ZNotice_t *notice;
+ struct sockaddr_in *from;
+ char *realm;
+{
+#ifdef ZEPHYR_USES_KERBEROS
+ int result;
+ char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
+ char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
+ KTEXT_ST authent, ticket;
+ AUTH_DAT dat;
+ ZChecksum_t checksum;
+ CREDENTIALS cred;
+ C_Block session_key;
-static void
-ae_expire(ae)
- struct AuthEnt *ae;
-{
- if (ae->data) {
- xfree((void *) ae->data);
- ae->data = 0;
- }
- ae->len = 0;
- ae->expire_time = 0;
- free_zstring(ae->principal);
- ae->principal= 0;
-}
+ if (!notice->z_auth)
+ return ZAUTH_NO;
-static int
-auth_hash (str, len)
- Zconst char *str;
- int len;
-{
- unsigned long hash;
- if (len <= 3)
- return str[0];
- hash = str[len - 1] * 256 + str[len-2] * 16 + str[len-3];
- hash %= HASH_SIZE_1;
- return hash;
-}
+ /* Check for bogus authentication data length. */
+ if (notice->z_authent_len <= 0)
+ return ZAUTH_FAILED;
-static int
-check_cache (notice, from)
- ZNotice_t *notice;
- struct sockaddr_in *from;
- {
- Zconst char *str = notice->z_ascii_authent;
- int len, i;
- unsigned int hash_val = 0;
- unsigned long now = time(0);
- struct AuthEnt *a;
-
- len = strlen (str);
- hash_val = auth_hash (str, len);
- for (i = 0; i < HASH_SIZE_2; i++) {
- a = &auth_cache[hash_val][i];
- if (!a->data) {
- continue;
- }
- if (now > a->expire_time) {
- ae_expire(a);
- continue;
- }
- if (len != a->len) {
- continue;
- }
- if (strcmp (notice->z_ascii_authent, a->data)) {
- continue;
- }
- /* Okay, we know we've got the same authenticator. */
- if (strcmp (notice->z_sender, a->principal->string)) {
- return ZAUTH_FAILED;
- }
- if (from->sin_addr.s_addr != a->from.sin_addr.s_addr) {
- return ZAUTH_FAILED;
- }
-#ifndef NOENCRYPTION
- (void) memcpy (__Zephyr_session, a->session_key, sizeof (C_Block));
-#endif
- return ZAUTH_YES;
+ /* Read in the authentication data. */
+ if (ZReadAscii(notice->z_ascii_authent,
+ strlen(notice->z_ascii_authent)+1,
+ (unsigned char *)authent.dat,
+ notice->z_authent_len) == ZERR_BADFIELD) {
+ return ZAUTH_FAILED;
+ }
+ authent.length = notice->z_authent_len;
+
+ /* Copy the ticket out of the authentication data. */
+ if (krb_find_ticket(&authent, &ticket) != RD_AP_OK)
+ return ZAUTH_FAILED;
+
+ (void) sprintf(rlmprincipal, "%s.%s@%s", SERVER_SERVICE,
+ SERVER_INSTANCE, realm);
+
+ /* Try to do a fast check against the cryptographic checksum. */
+ if (find_session_key(&ticket, session_key, srcprincipal) >= 0) {
+ if (strcmp(srcprincipal, rlmprincipal) != 0)
+ return ZAUTH_FAILED;
+ if (notice->z_time.tv_sec - NOW > CLOCK_SKEW)
+ return ZAUTH_FAILED;
+ checksum = compute_rlm_checksum(notice, session_key);
+
+ /* If checksum matches, packet is authentic. Otherwise, check
+ * the authenticator as if we didn't have the session key cached
+ * and return ZAUTH_CKSUM_FAILED. This is a rare case (since the
+ * ticket isn't cached after a checksum failure), so don't worry
+ * about the extra des_quad_cksum() call. */
+ if (checksum == notice->z_checksum) {
+ memcpy(__Zephyr_session, session_key, sizeof(C_Block));
+ return ZAUTH_YES;
+ }
}
- return ZAUTH_NO;
-}
-void
-add_to_cache (a)
- struct AuthEnt *a;
-{
- int len, i, j;
- struct AuthEnt *entries;
- unsigned int hash_val = 0;
-
- len = a->len;
- hash_val = auth_hash (a->data, len);
- entries = auth_cache[hash_val];
- j = 0;
- for (i = 0; i < HASH_SIZE_2; i++) {
- if (entries[i].data == 0) {
- j = i;
- goto ok;
- }
- if (i == j)
- continue;
- if (entries[i].expire_time < entries[j].expire_time)
- j = i;
+ /* We don't have the session key cached; do it the long way. */
+ result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
+ from->sin_addr.s_addr, &dat, srvtab_file);
+ if (result == RD_AP_OK) {
+ sprintf(srcprincipal, "%s%s%s@%s", dat.pname, dat.pinst[0] ? "." : "",
+ dat.pinst, dat.prealm);
+ if (strcmp(rlmprincipal, srcprincipal))
+ return ZAUTH_FAILED;
+ } else {
+ return ZAUTH_FAILED; /* didn't decode correctly */
}
-ok:
- if (entries[j].data)
- ae_expire(&entries[j]);
- entries[j] = *a;
+
+ /* Check the cryptographic checksum. */
+#ifdef NOENCRYPTION
+ our_checksum = 0;
+#else
+ checksum = compute_rlm_checksum(notice, dat.session);
+#endif
+ if (checksum != notice->z_checksum)
+ return ZAUTH_CKSUM_FAILED;
+
+ /* Record the session key, expiry time, and source principal in the
+ * hash table, so we can do a fast check next time. */
+ add_session_key(&ticket, dat.session, srcprincipal,
+ (time_t)(dat.time_sec + dat.life * 5 * 60));
+
+ return ZAUTH_YES;
+
+#else /* !ZEPHYR_USES_KERBEROS */
+ return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
+#endif
}
int
ZCheckAuthentication(notice, from)
- ZNotice_t *notice;
- struct sockaddr_in *from;
+ ZNotice_t *notice;
+ struct sockaddr_in *from;
{
+#ifdef ZEPHYR_USES_KERBEROS
int result;
char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
- KTEXT_ST authent;
+ KTEXT_ST authent, ticket;
AUTH_DAT dat;
- ZChecksum_t our_checksum;
- CREDENTIALS cred;
- struct AuthEnt a;
- char *s;
- int auth_len = 0;
+ ZChecksum_t checksum;
+ C_Block session_key;
+
+ if (!notice->z_auth)
+ return ZAUTH_NO;
+ /* Check for bogus authentication data length. */
+ if (notice->z_authent_len <= 0)
+ return ZAUTH_FAILED;
- if (!notice->z_auth) {
- return (ZAUTH_NO);
+ /* Read in the authentication data. */
+ if (ZReadAscii(notice->z_ascii_authent,
+ strlen(notice->z_ascii_authent)+1,
+ (unsigned char *)authent.dat,
+ notice->z_authent_len) == ZERR_BADFIELD) {
+ return ZAUTH_FAILED;
}
+ authent.length = notice->z_authent_len;
- if (__Zephyr_server) {
-
- if (notice->z_authent_len <= 0) { /* bogus length */
-#if 0
- syslog (LOG_DEBUG, "z_authent_len = %d -> AUTH_FAILED",
- notice->z_authent_len);
-#endif
- return(ZAUTH_FAILED);
- }
+ /* Copy the ticket out of the authentication data. */
+ if (krb_find_ticket(&authent, &ticket) != RD_AP_OK)
+ return ZAUTH_FAILED;
- auth_len = strlen (notice->z_ascii_authent);
- if (ZReadAscii(notice->z_ascii_authent, auth_len + 1,
- (unsigned char *)authent.dat,
- notice->z_authent_len) == ZERR_BADFIELD) {
- syslog (LOG_DEBUG,
- "ZReadAscii failed (len:%s) -> AUTH_FAILED (from %s)",
- error_message (ZERR_BADFIELD), inet_ntoa (from->sin_addr));
- return (ZAUTH_FAILED);
- }
- authent.length = notice->z_authent_len;
- result = check_cache (notice, from);
- if (result != ZAUTH_NO)
- return result;
-
- /* Well, it's not in the cache... decode it. */
- result = krb_rd_req(&authent, SERVER_SERVICE,
- SERVER_INSTANCE, (int) from->sin_addr.s_addr,
- &dat, SERVER_SRVTAB);
- if (result == RD_AP_OK) {
- (void) memcpy ((void *) a.session_key,(void *) dat.session,
- sizeof(C_Block));
- (void) memcpy((char *)__Zephyr_session, (char *)dat.session,
- sizeof(C_Block));
- (void) sprintf(srcprincipal, "%s%s%s@%s", dat.pname,
- dat.pinst[0]?".":"", dat.pinst, dat.prealm);
- if (strcmp(srcprincipal, notice->z_sender)) {
- syslog (LOG_DEBUG, "principal mismatch->AUTH_FAILED");
- return (ZAUTH_FAILED);
- }
- a.principal = make_zstring(srcprincipal,0);
- a.expire_time = time (0) + 5 * 60; /* add 5 minutes */
- a.from = *from;
- s = (char *) xmalloc (auth_len + 1);
- strcpy (s, notice->z_ascii_authent);
- a.data = s;
- a.len = auth_len;
- add_to_cache (&a);
- return(ZAUTH_YES);
- } else {
- syslog (LOG_DEBUG, "krb_rd_req failed (%s)->AUTH_FAILED (from %s)",
- krb_err_txt [result], inet_ntoa (from->sin_addr));
- return (ZAUTH_FAILED); /* didn't decode correctly */
+ /* Try to do a fast check against the cryptographic checksum. */
+ if (find_session_key(&ticket, session_key, srcprincipal) >= 0) {
+ if (strcmp(srcprincipal, notice->z_sender) != 0)
+ return ZAUTH_FAILED;
+ if (notice->z_time.tv_sec - NOW > CLOCK_SKEW)
+ return ZAUTH_FAILED;
+ checksum = compute_checksum(notice, session_key);
+
+ /* If the checksum matches, the packet is authentic. Otherwise,
+ * check authenticator as if we didn't have the session key cached
+ * and return ZAUTH_CKSUM_FAILED. This is a rare case (since the
+ * ticket isn't cached after a checksum failure), so don't worry
+ * about the extra des_quad_cksum() call. */
+ if (checksum == notice->z_checksum) {
+ memcpy(__Zephyr_session, session_key, sizeof(C_Block));
+ return ZAUTH_YES;
}
}
-
- if ((result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE,
- __Zephyr_realm, &cred)) != KSUCCESS) {
- syslog (LOG_DEBUG, "krb_get_cred failed (%s) ->AUTH_NO (from %s)",
- krb_err_txt [result], inet_ntoa (from->sin_addr));
- return (ZAUTH_NO);
+
+ /* We don't have the session key cached; do it the long way. */
+ result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
+ from->sin_addr.s_addr, &dat, srvtab_file);
+ if (result == RD_AP_OK) {
+ memcpy(__Zephyr_session, dat.session, sizeof(C_Block));
+ sprintf(srcprincipal, "%s%s%s@%s", dat.pname, dat.pinst[0] ? "." : "",
+ dat.pinst, dat.prealm);
+ if (strcmp(srcprincipal, notice->z_sender))
+ return ZAUTH_FAILED;
+ } else {
+ return ZAUTH_FAILED; /* didn't decode correctly */
}
+ /* Check the cryptographic checksum. */
#ifdef NOENCRYPTION
our_checksum = 0;
#else
- our_checksum = (ZChecksum_t)des_quad_cksum(notice->z_packet, NULL,
- notice->z_default_format+
- strlen(notice->z_default_format)+1-
- notice->z_packet, 0, cred.session);
+ checksum = compute_checksum(notice, dat.session);
#endif
- /* if mismatched checksum, then the packet was corrupted */
- if (our_checksum == notice->z_checksum) {
- return ZAUTH_YES;
+ if (checksum != notice->z_checksum)
+ return ZAUTH_CKSUM_FAILED;
+
+ /* Record the session key, expiry time, and source principal in the
+ * hash table, so we can do a fast check next time. */
+ add_session_key(&ticket, dat.session, srcprincipal,
+ (time_t)(dat.time_sec + dat.life * 5 * 60));
+
+ return ZAUTH_YES;
+
+#else /* !ZEPHYR_USES_KERBEROS */
+ return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
+#endif
+}
+
+#ifdef ZEPHYR_USES_KERBEROS
+
+static int hash_ticket(p, len)
+ unsigned char *p;
+ int len;
+{
+ unsigned long hashval = 0, g;
+
+ for (; len > 0; p++, len--) {
+ hashval = (hashval << 4) + *p;
+ g = hashval & 0xf0000000;
+ if (g) {
+ hashval ^= g >> 24;
+ hashval ^= g;
+ }
}
- else {
- syslog (LOG_DEBUG, "checksum mismatch->AUTH_FAILED (from %s)",
- inet_ntoa (from->sin_addr));
- return ZAUTH_FAILED;
+ return hashval % HASHTAB_SIZE;
+}
+
+static void add_session_key(ticket, session_key, srcprincipal, expires)
+ KTEXT ticket;
+ C_Block session_key;
+ char *srcprincipal;
+ time_t expires;
+{
+ Hash_entry *entry;
+ int hashval;
+
+ /* If we can't allocate memory for the hash table entry, just forget
+ * about it. */
+ entry = (Hash_entry *) malloc(sizeof(Hash_entry) - 1 + ticket->length);
+ if (!entry)
+ return;
+
+ /* Initialize the new entry. */
+ memcpy(entry->session_key, session_key, sizeof(entry->session_key));
+ strcpy(entry->srcprincipal, srcprincipal);
+ entry->expires = expires;
+ entry->ticket_len = ticket->length;
+ memcpy(entry->ticket, ticket->dat, ticket->length * sizeof(unsigned char));
+
+ /* Insert the new entry in the hash table. */
+ hashval = hash_ticket(ticket->dat, ticket->length);
+ entry->next = hashtab[hashval];
+ hashtab[hashval] = entry;
+}
+
+static int find_session_key(ticket, key, srcprincipal)
+ KTEXT ticket;
+ C_Block key;
+ char *srcprincipal;
+{
+ unsigned char *dat;
+ int hashval, len;
+ Hash_entry *entry;
+
+ dat = ticket->dat;
+ len = ticket->length;
+ hashval = hash_ticket(dat, len);
+
+ for (entry = hashtab[hashval]; entry; entry = entry->next) {
+ if (entry->ticket_len == len && memcmp(entry->ticket, dat, len) == 0) {
+ memcpy(key, entry->session_key, sizeof(entry->session_key));
+ strcpy(srcprincipal, entry->srcprincipal);
+ return 0;
+ }
}
-}
-#endif /* KERBEROS */
+ return -1;
+}
+
+static ZChecksum_t compute_checksum(notice, session_key)
+ ZNotice_t *notice;
+ C_Block session_key;
+{
+#ifdef NOENCRYPTION
+ return 0;
+#else
+ ZChecksum_t checksum;
+ char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
+
+ cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
+ cend = cstart + strlen(cstart) + 1;
+ checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
+ checksum ^= des_quad_cksum(cend, NULL, hend - cend, 0, session_key);
+ checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len,
+ 0, session_key);
+ return checksum;
+#endif
+}
+
+static ZChecksum_t compute_rlm_checksum(notice, session_key)
+ ZNotice_t *notice;
+ C_Block session_key;
+{
+#ifdef NOENCRYPTION
+ return 0;
+#else
+ ZChecksum_t checksum;
+ char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
+
+ cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
+ cend = cstart + strlen(cstart) + 1;
+ checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
+ return checksum;
+#endif
+}
+
+void sweep_ticket_hash_table(arg)
+ void *arg;
+{
+ int i;
+ Hash_entry **ptr, *entry;
+
+ for (i = 0; i < HASHTAB_SIZE; i++) {
+ ptr = &hashtab[i];
+ while (*ptr) {
+ entry = *ptr;
+ if (entry->expires < NOW) {
+ *ptr = entry->next;
+ free(entry);
+ } else {
+ ptr = &(*ptr)->next;
+ }
+ }
+ }
+ timer_set_rel(SWEEP_INTERVAL, sweep_ticket_hash_table, NULL);
+}
+
+#endif /* ZEPHYR_USES_KERBEROS */
+
diff --git a/server/kstuff.c.auth b/server/kstuff.c.auth
deleted file mode 100644
index f81da75..0000000
--- a/server/kstuff.c.auth
+++ /dev/null
@@ -1,363 +0,0 @@
-#ifdef KERBEROS
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains functions for dealing with Kerberos functions in the server.
- *
- * Created by: John T Kohl
- *
- * Copyright (c) 1988 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-/*
- * $Source$
- * $Header$
- */
-
-#ifndef lint
-#ifndef SABER
-static char rcsid_kstuff_c[] = "$Id$";
-#endif
-#endif
-
-#include "zserver.h"
-
-#include <ctype.h>
-#include <netdb.h>
-#include <string.h>
-
-#include <zephyr/zephyr_internal.h>
-#ifdef KERBEROS
-#include <zephyr/krb_err.h>
-#endif
-
-/* Keep a hash table mapping tickets to session keys, so we can do a fast
- * check of the cryptographic checksum without doing and DES decryptions.
- * Also remember the expiry time of the ticket, so that we can sweep the
- * table periodically. */
-
-#define HASHTAB_SIZE 4091
-
-typedef struct hash_entry Hash_entry;
-
-/* The ticket comes at the end, in a variable-length array. */
-struct hash_entry {
- C_Block session_key;
- time_t expires;
- char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
- Hash_entry *next;
- int ticket_len;
- unsigned char ticket[1];
-};
-
-Hash_entry *hashtab[HASHTAB_SIZE];
-
-static char tkt_file[] = ZEPHYR_TKFILE;
-
-#ifdef __STDC__
-static int hash_ticket(unsigned char *, int);
-static void add_session_key(KTEXT, C_Block, char *, time_t);
-static int find_session_key(KTEXT, C_Block, char *);
-#else
-static int hash_ticket();
-static void add_session_key();
-static int find_session_key();
-#endif
-
-/*
- * GetKerberosData
- *
- * get ticket from file descriptor and decode it.
- * Return KFAILURE if we barf on reading the ticket, else return
- * the value of rd_ap_req() applied to the ticket.
- */
-int
-GetKerberosData(fd, haddr, kdata, service, srvtab)
- int fd; /* file descr. to read from */
- struct in_addr haddr; /* address of foreign host on fd */
- AUTH_DAT *kdata; /* kerberos data (returned) */
- char *service; /* service principal desired */
- char *srvtab; /* file to get keys from */
-{
- char p[20];
- KTEXT_ST ticket; /* will get Kerberos ticket from client */
- int i;
- char instance[INST_SZ];
-
- /*
- * Get the Kerberos ticket. The first few characters, terminated
- * by a blank, should give us a length; then get than many chars
- * which will be the ticket proper.
- */
- for (i=0; i<20; i++) {
- if (read(fd, &p[i], 1) != 1) {
- syslog(LOG_WARNING,"bad read tkt len");
- return(KFAILURE);
- }
- if (p[i] == ' ') {
- p[i] = '\0';
- break;
- }
- }
- ticket.length = atoi(p);
- if ((i==20) || (ticket.length<=0) || (ticket.length>MAX_KTXT_LEN)) {
- syslog(LOG_WARNING,"bad tkt len %d",ticket.length);
- return(KFAILURE);
- }
- for (i=0; i<ticket.length; i++) {
- if (read(fd, (caddr_t) &(ticket.dat[i]), 1) != 1) {
- syslog(LOG_WARNING,"bad tkt read");
- return(KFAILURE);
- }
- }
- /*
- * now have the ticket. use it to get the authenticated
- * data from Kerberos.
- */
- (void) strcpy(instance,"*"); /* let Kerberos fill it in */
-
- return(krb_rd_req(&ticket, service, instance, haddr.s_addr,
- kdata, srvtab ? srvtab : ""));
-}
-
-/*
- * SendKerberosData
- *
- * create and transmit a ticket over the file descriptor for service.host
- * return failure codes if appropriate, or 0 if we
- * get the ticket and write it to the file descriptor
- */
-
-int
-SendKerberosData(fd, ticket, service, host)
- int fd; /* file descriptor to write onto */
- KTEXT ticket; /* where to put ticket (return) */
- char *service; /* service name, foreign host */
- char *host;
-{
- int rem;
- char p[32];
- char krb_realm[REALM_SZ];
- int written;
- int size_to_write;
-
- rem = krb_get_lrealm(krb_realm,1);
- if (rem != KSUCCESS)
- return rem + krb_err_base;
-
- rem = krb_mk_req( ticket, service, host, krb_realm, (u_long)0 );
- if (rem != KSUCCESS)
- return rem + krb_err_base;
-
- (void) sprintf(p,"%d ",ticket->length);
- size_to_write = strlen (p);
- if ((written = write(fd, p, size_to_write)) != size_to_write)
- if (written < 0)
- return errno;
- else
- return ZSRV_PKSHORT;
- if ((written = write(fd, (caddr_t) (ticket->dat), ticket->length)) != ticket->length)
- if (written < 0)
- return errno;
- else
- return ZSRV_PKSHORT;
-
- return 0;
-}
-
-/* Hack to replace the kerberos library's idea of the ticket file with
- our idea */
-char *
-tkt_string()
-{
- return tkt_file;
-}
-
-int
-ZCheckAuthentication(notice, from)
- ZNotice_t *notice;
- struct sockaddr_in *from;
-{
-#ifdef Z_HaveKerberos
- int result, len;
- char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
- KTEXT_ST authent, ticket;
- AUTH_DAT dat;
- ZChecksum_t our_checksum;
- unsigned long cksum;
- CREDENTIALS cred;
- C_Block session_key;
-
- if (!notice->z_auth)
- return (ZAUTH_NO);
-
- /* Check for bogus authentication data length. */
- if (notice->z_authent_len <= 0)
- return(ZAUTH_FAILED);
-
- /* Read in the authentication data. */
- if (ZReadAscii(notice->z_ascii_authent,
- strlen(notice->z_ascii_authent)+1,
- (unsigned char *)authent.dat,
- notice->z_authent_len) == ZERR_BADFIELD) {
- return (ZAUTH_FAILED);
- }
- authent.length = notice->z_authent_len;
-
- /* Copy the ticket out of the authentication data. */
- if (krb_find_ticket(&authent, &ticket) != RD_AP_OK)
- return (ZAUTH_FAILED);
-
- /* Try to do a fast check against the cryptographic checksum. */
- if (find_session_key(&ticket, session_key, srcprincipal) >= 0) {
- if (strcmp(srcprincipal, notice->z_sender) != 0)
- return (ZAUTH_FAILED);
- if (notice->z_time.tv_sec - NOW > CLOCK_SKEW)
- return (ZAUTH_FAILED);
-#ifdef NOENCRYPTION
- our_checksum = 0;
-#else
- len = notice->z_default_format + strlen(notice->z_default_format)
- + 1 - notice->z_packet;
- result = des_quad_cksum(notice->z_packet, NULL, len, 0, session_key);
- result ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len,
- 0, session_key);
- our_checksum = (ZChecksum_t) result;
-#endif
- /* If checksum matches, packet is authentic. Otherwise, check
- * the authenticator as if we didn't have the session key cached
- * and return ZAUTH_CKSUM_FAILED. This is a rare case (since the
- * ticket isn't cached after a checksum failure), so don't worry
- * about the extra des_quad_cksum() call. */
- if (our_checksum == notice->z_checksum)
- return (ZAUTH_YES);
- }
-
- /* We don't have the session key cached; do it the long way. */
- result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
- from->sin_addr.s_addr, &dat, SERVER_SRVTAB);
- if (result == RD_AP_OK) {
- (void) memcpy((char *)__Zephyr_session, (char *)dat.session,
- sizeof(C_Block));
- (void) sprintf(srcprincipal, "%s%s%s@%s", dat.pname,
- dat.pinst[0]?".":"", dat.pinst, dat.prealm);
- if (strcmp(srcprincipal, notice->z_sender))
- return (ZAUTH_FAILED);
- } else {
- return (ZAUTH_FAILED); /* didn't decode correctly */
- }
-
- /* Check the cryptographic checksum. */
-#ifdef NOENCRYPTION
- our_checksum = 0;
-#else
- len = notice->z_default_format + strlen(notice->z_default_format)
- + 1 - notice->z_packet;
- cksum = des_quad_cksum(notice->z_packet, NULL, len, 0, dat.session);
- our_checksum = (ZChecksum_t) cksum;
-#endif
- if (our_checksum != notice->z_checksum)
- return (ZAUTH_CKSUM_FAILED);
-
- /* Record the session key, expiry time, and source principal in the
- * hash table, so we can do a fast check next time. */
- add_session_key(&ticket, dat.session, srcprincipal,
- (time_t)(dat.time_sec + dat.life * 5 * 60));
-
- return (ZAUTH_YES);
-
-#else /* not Z_HaveKerberos */
- return (notice->z_auth ? ZAUTH_YES : ZAUTH_NO);
-#endif
-}
-
-static int hash_ticket(p, len)
- unsigned char *p;
- int len;
-{
- unsigned long hashval = 0, g;
-
- for (; len > 0; p++, len--) {
- hashval = (hashval << 4) + *p;
- g = hashval & 0xf0000000;
- if (g) {
- hashval ^= g >> 24;
- hashval ^= g;
- }
- }
- return hashval % HASHTAB_SIZE;
-}
-
-static void add_session_key(ticket, session_key, srcprincipal, expires)
- KTEXT ticket;
- C_Block session_key;
- char *srcprincipal;
- time_t expires;
-{
- Hash_entry *entry;
- int hashval;
-
- /* If we can't allocate memory for the hash table entry, just forget
- * about it. */
- entry = (Hash_entry *) xmalloc(sizeof(Hash_entry) - 1 + ticket->length);
- if (!entry)
- return;
-
- /* Initialize the new entry. */
- memcpy(entry->session_key, session_key, sizeof(entry->session_key));
- strcpy(entry->srcprincipal, srcprincipal);
- entry->expires = expires;
- entry->ticket_len = ticket->length;
- memcpy(entry->ticket, ticket->dat, ticket->length * sizeof(unsigned char));
-
- /* Insert the new entry in the hash table. */
- hashval = hash_ticket(ticket->dat, ticket->length);
- entry->next = hashtab[hashval];
- hashtab[hashval] = entry;
-}
-
-static int find_session_key(ticket, key, srcprincipal)
- KTEXT ticket;
- C_Block key;
- char *srcprincipal;
-{
- unsigned char *dat;
- int hashval, len;
- Hash_entry *entry;
-
- dat = ticket->dat;
- len = ticket->length;
- hashval = hash_ticket(dat, len);
-
- for (entry = hashtab[hashval]; entry; entry = entry->next) {
- if (entry->ticket_len == len && memcmp(entry->ticket, dat, len) == 0) {
- memcpy(key, entry->session_key, sizeof(entry->session_key));
- strcpy(srcprincipal, entry->srcprincipal);
- return 0;
- }
- }
- return -1;
-}
-
-void sweep_ticket_hash_table(arg)
- void *arg;
-{
- int i;
- Hash_entry **ptr, *entry;
-
- for (i = 0; i < HASHTAB_SIZE; i++) {
- ptr = &hashtab[i];
- while (*ptr) {
- entry = *ptr;
- if (entry->expires < NOW) {
- *ptr = entry->next;
- free(entry);
- } else {
- ptr = &(*ptr)->next;
- }
- }
- }
- timer_set_rel(SWEEP_INTERVAL, sweep_ticket_hash_table, NULL);
-}
-
-#endif /* KERBEROS */
-
diff --git a/server/main.c b/server/main.c
index 3420d06..9978bbd 100644
--- a/server/main.c
+++ b/server/main.c
@@ -12,10 +12,13 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
+#include <sys/socket.h>
+#include <sys/resource.h>
#ifndef lint
#ifndef SABER
-static char rcsid_main_c[] =
+static const char rcsid_main_c[] =
"$Id$";
#endif
#endif
@@ -47,91 +50,58 @@ static char rcsid_main_c[] =
(if the client has not acknowledged a packet after a given timeout).
*/
-#include "zserver.h"
-/* which includes
- zephyr/zephyr.h
- <errno.h>
- <sys/types.h>
- <netinet/in.h>
- <sys/time.h>
- <stdio.h>
- <sys/file.h>
- <syslog.h>
- <strings.h>
- <signal.h>
- timer.h
- zsrv_err.h
- */
-
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#ifdef POSIX
-#include <termios.h>
-#endif
-
-#ifdef POSIX
-#define SIGNAL_RETURN_TYPE void
-#define SIG_RETURN return
-#else
-#define SIGNAL_RETURN_TYPE int
-#define SIG_RETURN return(0)
-#endif
-
-#if !defined(__SABER__) && (defined (vax) || defined (ibm032))
-#define MONCONTROL moncontrol
-#else
-#define MONCONTROL (void)
-#endif
-
#define EVER (;;) /* don't stop looping */
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static int do_net_setup P((void)), initialize P((void));
-static void usage P((void)), do_reset P((void));
-static SIGNAL_RETURN_TYPE bye P((int)),
- dbug_on P((int)), dbug_off P((int)),
- sig_dump_db P((int)), sig_dump_strings P((int)),
- reset P((int)), reap P((int));
-static void read_from_dump P((char *dumpfile));
-static void dump_db P((void)), dump_strings P((void));
+static int do_net_setup __P((void));
+static int initialize __P((void));
+static void usage __P((void));
+static void do_reset __P((void));
+static RETSIGTYPE bye __P((int));
+static RETSIGTYPE dbug_on __P((int));
+static RETSIGTYPE dbug_off __P((int));
+static RETSIGTYPE sig_dump_db __P((int));
+static RETSIGTYPE sig_dump_strings __P((int));
+static RETSIGTYPE reset __P((int));
+static RETSIGTYPE reap __P((int));
+static void read_from_dump __P((char *dumpfile));
+static void dump_db __P((void));
+static void dump_strings __P((void));
#ifndef DEBUG
-static void detach P((void));
+static void detach __P((void));
#endif
-extern void perror P((Zconst char *));
-
-#undef P
-
static short doreset = 0; /* if it becomes 1, perform
reset functions */
+int nfds; /* max file descriptor for select() */
int srv_socket; /* dgram socket for clients
and other servers */
int bdump_socket = -1; /* brain dump socket fd
(closed most of the time) */
fd_set interesting; /* the file descrips we are listening
to right now */
-int nfildes; /* number to look at in select() */
-struct sockaddr_in sock_sin; /* address of the socket */
-struct timeval nexthost_tv; /* time till next timeout for select */
+struct sockaddr_in srv_addr; /* address of the socket */
-ZNotAcked_t *nacklist; /* list of packets waiting for ack's */
+Unacked *nacklist = NULL; /* list of packets waiting for ack's */
-u_short hm_port; /* the port # of the host manager */
+unsigned short hm_port; /* host manager receiver port */
+unsigned short hm_srv_port; /* host manager server sending port */
char *programname; /* set to the basename of argv[0] */
char myname[MAXHOSTNAMELEN]; /* my host name */
+#ifndef ZEPHYR_USES_HESIOD
+char list_file[128];
+#endif
+#ifdef ZEPHYR_USES_KERBEROS
+char srvtab_file[128];
+char my_realm[REALM_SZ];
+static char tkt_file[128];
+#endif
+char acl_dir[128];
+char subs_file[128];
+
int zdebug;
#ifdef DEBUG_MALLOC
int dump_malloc_stats = 0;
@@ -147,259 +117,247 @@ static int dump_db_flag = 0;
static int dump_strings_flag = 0;
u_long npackets; /* number of packets processed */
-long uptime; /* when we started operations */
+time_t uptime; /* when we started operations */
static int nofork;
struct in_addr my_addr;
-char *bdump_version = "1.1";
+char *bdump_version = "1.2";
int
main(argc, argv)
- int argc;
- char **argv;
+ int argc;
+ char **argv;
{
- int nfound; /* #fildes ready on select */
- fd_set readable;
- struct timeval *tvp;
- int init_from_dump = 0;
- char *dumpfile;
-#ifdef POSIX
- struct sigaction action;
-#endif
-
-
- int optchar; /* option processing */
- extern char *optarg;
- extern int optind;
-
- /* set name */
- if (programname = strrchr(argv[0],'/'))
- programname++;
- else programname = argv[0];
-
- /* process arguments */
-
- while ((optchar = getopt(argc, argv, "dsnv:f:")) != EOF) {
- switch(optchar) {
- case 'd':
- zdebug = 1;
- break;
+ int nfound; /* #fildes ready on select */
+ fd_set readable;
+ struct timeval tv;
+ int init_from_dump = 0;
+ char *dumpfile;
+#ifdef _POSIX_VERSION
+ struct sigaction action;
+#endif
+ int optchar; /* option processing */
+ extern char *optarg;
+ extern int optind;
+
+#ifndef ZEPHYR_USES_HESIOD
+ sprintf(list_file, "%s/%s", CONFDIR, SERVER_LIST_FILE);
+#endif
+#ifdef ZEPHYR_USES_KERBEROS
+ sprintf(srvtab_file, "%s/%s", CONFDIR, ZEPHYR_SRVTAB);
+ sprintf(tkt_file, "%s/%s", CONFDIR, ZEPHYR_TKFILE);
+#endif
+ sprintf(acl_dir, "%s/%s", CONFDIR, ZEPHYR_ACL_DIR);
+ sprintf(subs_file, "%s/%s", CONFDIR, DEFAULT_SUBS_FILE);
+
+ /* set name */
+ programname = strrchr(argv[0],'/');
+ programname = (programname) ? programname + 1 : argv[0];
+
+ /* process arguments */
+ while ((optchar = getopt(argc, argv, "dsnv:f:k:")) != EOF) {
+ switch(optchar) {
+ case 'd':
+ zdebug = 1;
+ break;
#ifdef DEBUG
- case 's':
- zalone = 1;
- break;
-#endif
- case 'n':
- nofork = 1;
- break;
- case 'v':
- bdump_version = optarg;
- break;
- case 'f':
- init_from_dump = 0;
- dumpfile = optarg;
- break;
- case '?':
- default:
- usage();
- /*NOTREACHED*/
- }
+ case 's':
+ zalone = 1;
+ break;
+#endif
+ case 'n':
+ nofork = 1;
+ break;
+ case 'k':
+#ifdef ZEPHYR_USES_KERBEROS
+ strncpy(my_realm, optarg, REALM_SZ);
+#endif
+ break;
+ case 'v':
+ bdump_version = optarg;
+ break;
+ case 'f':
+ init_from_dump = 0;
+ dumpfile = optarg;
+ break;
+ case '?':
+ default:
+ usage();
+ /*NOTREACHED*/
}
+ }
-#ifdef KERBEROS
- /* if there is no readable srvtab and we are not standalone, there
- is no possible way we can succeed, so we exit */
+#ifdef ZEPHYR_USES_KERBEROS
+ /* if there is no readable srvtab and we are not standalone, there
+ is no possible way we can succeed, so we exit */
- if (access(ZEPHYR_SRVTAB, R_OK)
+ if (access(srvtab_file, R_OK)
#ifdef DEBUG
- && !zalone
+ && !zalone
#endif /* DEBUG */
- ) {
- fprintf(stderr, "NO ZEPHYR SRVTAB (%s) available; exiting\n",
- ZEPHYR_SRVTAB);
- exit(1);
+ ) {
+ fprintf(stderr, "NO ZEPHYR SRVTAB (%s) available; exiting\n",
+ srvtab_file);
+ exit(1);
+ }
+ /* Use local realm if not specified on command line. */
+ if (!*my_realm) {
+ if (krb_get_lrealm(my_realm, 1) != KSUCCESS) {
+ fputs("Couldn't get local Kerberos realm; exiting.\n", stderr);
+ exit(1);
}
-#endif /* KERBEROS */
+ }
+#endif /* ZEPHYR_USES_KERBEROS */
#ifndef DEBUG
- if (!nofork)
- detach();
+ if (!nofork)
+ detach();
#endif /* DEBUG */
- /* open log */
- OPENLOG(programname, LOG_PID, LOG_LOCAL6);
+ /* open log */
+ OPENLOG(programname, LOG_PID, LOG_LOCAL6);
#if defined (DEBUG) && 0
- if (zalone)
- syslog(LOG_DEBUG, "standalone operation");
+ if (zalone)
+ syslog(LOG_DEBUG, "standalone operation");
#endif
#if 0
- if (zdebug)
- syslog(LOG_DEBUG, "debugging on");
+ if (zdebug)
+ syslog(LOG_DEBUG, "debugging on");
#endif
- /* set up sockets & my_addr and myname,
- find other servers and set up server table, initialize queues
- for retransmits, initialize error tables,
- set up restricted classes */
-
- /* Initialize t_local for other uses */
- (void) gettimeofday(&t_local, (struct timezone *)0);
+ /* set up sockets & my_addr and myname,
+ find other servers and set up server table, initialize queues
+ for retransmits, initialize error tables,
+ set up restricted classes */
- if (initialize())
- exit(1);
+ /* Initialize t_local for other uses */
+ gettimeofday(&t_local, NULL);
- if (init_from_dump)
- read_from_dump(dumpfile);
+ if (initialize())
+ exit(1);
- /* Seed random number set. */
- srandom (getpid () ^ time (0));
+ if (init_from_dump)
+ read_from_dump(dumpfile);
-#ifndef __SABER__
- /* chdir to somewhere where a core dump will survive */
- if (chdir("/usr/tmp") != 0)
- syslog(LOG_ERR,"chdir failed (%m) (execution continuing)");
+ /* Seed random number set. */
+ srandom(getpid() ^ time(0));
-#if 0
- /*
- * Many systems don't implement setpriority() as is done under BSD,
- * and the kernel scheduler will appropriately swap in the processes
- * that are needed.
- */
- if (setpriority(PRIO_PROCESS, getpid(), -10))
- syslog(LOG_ERR,"setpriority failed (%m)");
-#endif
-#endif
+ /* chdir to somewhere where a core dump will survive */
+ if (chdir(TEMP_DIRECTORY) != 0)
+ syslog(LOG_ERR, "chdir failed (%m) (execution continuing)");
- FD_ZERO(&interesting);
- FD_SET(srv_socket, &interesting);
+ FD_ZERO(&interesting);
+ FD_SET(srv_socket, &interesting);
- nfildes = srv_socket + 1;
+ nfds = srv_socket + 1;
-#ifdef POSIX
- action.sa_flags = 0;
- sigemptyset(&action.sa_mask);
+#ifdef _POSIX_VERSION
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
- action.sa_handler = bye;
- sigaction(SIGINT, &action, NULL);
- sigaction(SIGTERM, &action, NULL);
+ action.sa_handler = bye;
+ sigaction(SIGINT, &action, NULL);
+ sigaction(SIGTERM, &action, NULL);
- action.sa_handler = dbug_on;
- sigaction(SIGUSR1, &action, NULL);
+ action.sa_handler = dbug_on;
+ sigaction(SIGUSR1, &action, NULL);
- action.sa_handler = dbug_off;
- sigaction(SIGUSR2, &action, NULL);
+ action.sa_handler = dbug_off;
+ sigaction(SIGUSR2, &action, NULL);
- action.sa_handler = reap;
- sigaction(SIGCHLD, &action, NULL);
+ action.sa_handler = reap;
+ sigaction(SIGCHLD, &action, NULL);
- action.sa_handler = sig_dump_db;
- sigaction(SIGFPE, &action, NULL);
- sigaction(SIGXCPU, &action, NULL);
+ action.sa_handler = sig_dump_db;
+ sigaction(SIGFPE, &action, NULL);
#ifdef SIGEMT
- action.sa_handler = sig_dump_strings;
- sigaction(SIGEMT, &action, NULL);
+ action.sa_handler = sig_dump_strings;
+ sigaction(SIGEMT, &action, NULL);
#endif
- action.sa_handler = reset;
- sigaction(SIGHUP, &action, NULL);
+ action.sa_handler = reset;
+ sigaction(SIGHUP, &action, NULL);
#else /* !posix */
- (void) signal(SIGINT, bye);
- (void) signal(SIGTERM, bye);
- (void) signal(SIGUSR1, dbug_on);
- (void) signal(SIGUSR2, dbug_off);
- (void) signal(SIGCHLD, reap);
- (void) signal(SIGFPE, sig_dump_db);
- (void) signal(SIGXCPU, sig_dump_db);
+ signal(SIGINT, bye);
+ signal(SIGTERM, bye);
+ signal(SIGUSR1, dbug_on);
+ signal(SIGUSR2, dbug_off);
+ signal(SIGCHLD, reap);
+ signal(SIGFPE, sig_dump_db);
#ifdef SIGEMT
- (void) signal(SIGEMT, sig_dump_strings);
+ signal(SIGEMT, sig_dump_strings);
#endif
- (void) signal(SIGHUP, reset);
-#endif /* POSIX */
+ signal(SIGHUP, reset);
+#endif /* _POSIX_VERSION */
- syslog(LOG_NOTICE, "Ready for action");
+ syslog(LOG_NOTICE, "Ready for action");
- /* Reinitialize t_local now that initialization is done. */
- (void) gettimeofday(&t_local, (struct timezone *)0);
- /* GO! */
- uptime = NOW;
+ /* Reinitialize t_local now that initialization is done. */
+ gettimeofday(&t_local, NULL);
+ uptime = NOW;
+#ifdef ZEPHYR_USES_KERBEROS
+ timer_set_rel(SWEEP_INTERVAL, sweep_ticket_hash_table, NULL);
+#endif
#ifdef DEBUG_MALLOC
- malloc_inuse(&m_size);
-#endif
- for EVER {
- if (doreset)
- do_reset();
-
- if (dump_db_flag)
- dump_db();
- if (dump_strings_flag)
- dump_strings();
-
- nexthost_tv.tv_usec = 0;
- tvp = &nexthost_tv;
-
- if (nexttimo != 0L) {
- nexthost_tv.tv_sec = nexttimo - NOW;
- if (nexthost_tv.tv_sec <= 0) {
- /* timeout has passed! */
- /* so we process one timeout, then pop to
- select, polling for input. This way we get
- work done even if swamped with many
- timeouts */
- /* this will reset nexttimo */
- (void) timer_process();
- nexthost_tv.tv_sec = 0;
- }
- } else { /* no timeouts to process */
- nexthost_tv.tv_sec = 15;
- }
- readable = interesting;
- if (msgs_queued()) {
- /* when there is input in the queue, we
- artificially set up to pick up the input */
- nfound = 1;
- FD_ZERO(&readable);
- } else
- nfound = select(nfildes, &readable, (fd_set *) 0,
- (fd_set *) 0, tvp);
-
- /* Initialize t_local for other uses */
- (void) gettimeofday(&t_local, (struct timezone *)0);
+ malloc_inuse(&m_size);
+#endif
+ for EVER {
+ if (doreset)
+ do_reset();
+
+ if (dump_db_flag)
+ dump_db();
+ if (dump_strings_flag)
+ dump_strings();
+
+ readable = interesting;
+ if (msgs_queued()) {
+ /* when there is input in the queue, we
+ artificially set up to pick up the input */
+ nfound = 1;
+ FD_ZERO(&readable);
+ } else {
+ nfound = select(nfds, &readable, NULL, NULL, timer_timeout(&tv));
+ }
+
+ /* Initialize t_local for other uses */
+ gettimeofday(&t_local, (struct timezone *)0);
- /* don't flame about EINTR, since a SIGUSR1 or SIGUSR2
- can generate it by interrupting the select */
- if (nfound < 0) {
- if (errno != EINTR)
- syslog(LOG_WARNING, "select error: %m");
+ /* don't flame about EINTR, since a SIGUSR1 or SIGUSR2
+ can generate it by interrupting the select */
+ if (nfound < 0) {
+ if (errno != EINTR)
+ syslog(LOG_WARNING, "select error: %m");
#ifdef DEBUG_MALLOC
- if (dump_malloc_stats) {
- unsigned long foo,histid2;
- dump_malloc_stats = 0;
- foo = malloc_inuse(&histid2);
- printf("Total inuse: %d\n",foo);
- malloc_list(2,m_size,histid2);
- }
-#endif
- continue;
- }
- if (nfound == 0)
- /* either we timed out or we were just
- polling for input. Either way we want to continue
- the loop, and process the next timeout */
- continue;
- else {
- if ((bdump_socket >= 0) &&
- FD_ISSET(bdump_socket,&readable))
- bdump_send();
- else if (msgs_queued() ||
- FD_ISSET(srv_socket, &readable)) {
- handle_packet();
- } else
- syslog(LOG_ERR, "select weird?!?!");
- }
+ if (dump_malloc_stats) {
+ unsigned long foo,histid2;
+
+ dump_malloc_stats = 0;
+ foo = malloc_inuse(&histid2);
+ printf("Total inuse: %d\n",foo);
+ malloc_list(2,m_size,histid2);
+ }
+#endif
+ continue;
+ }
+
+ if (nfound == 0) {
+ /* either we timed out or we were just
+ polling for input. Either way we want to continue
+ the loop, and process the next timeout */
+ continue;
+ } else {
+ if (bdump_socket >= 0 && FD_ISSET(bdump_socket,&readable))
+ bdump_send();
+ else if (msgs_queued() || FD_ISSET(srv_socket, &readable))
+ handle_packet();
+ else
+ syslog(LOG_ERR, "select weird?!?!");
}
+ }
}
/* Initialize net stuff.
@@ -412,49 +370,35 @@ main(argc, argv)
static int
initialize()
{
- if (do_net_setup())
- return(1);
+ if (do_net_setup())
+ return(1);
- server_init();
+ server_init();
-#if 0
- if (!(nacklist = (ZNotAcked_t *) xmalloc(sizeof(ZNotAcked_t)))) {
- /* unrecoverable */
- syslog(LOG_CRIT, "nacklist malloc");
- abort();
- }
-#else
- {
- static ZNotAcked_t not_acked_head;
- nacklist = &not_acked_head;
- }
+#ifdef ZEPHYR_USES_KERBEROS
+ krb_set_tkt_string(tkt_file);
#endif
- (void) memset((caddr_t) nacklist, 0, sizeof(ZNotAcked_t));
- nacklist->q_forw = nacklist->q_back = nacklist;
-
- nexttimo = 1L; /* trigger the timers when we hit
- the FOR loop */
+ realm_init();
- (void) ZInitialize(); /* set up the library */
- (void) init_zsrv_err_tbl(); /* set up err table */
+ ZSetServerState(1);
+ ZInitialize(); /* set up the library */
+ init_zsrv_err_tbl(); /* set up err table */
- (void) ZSetServerState(1);
- (void) ZSetFD(srv_socket); /* set up the socket as the
- input fildes */
+ ZSetFD(srv_socket); /* set up the socket as the input fildes */
- /* set up default strings */
+ /* set up default strings */
- class_control = make_zstring(ZEPHYR_CTL_CLASS, 1);
- class_admin = make_zstring(ZEPHYR_ADMIN_CLASS, 1);
- class_hm = make_zstring(HM_CTL_CLASS, 1);
- class_ulogin = make_zstring(LOGIN_CLASS, 1);
- class_ulocate = make_zstring(LOCATE_CLASS, 1);
- wildcard_instance = make_zstring(WILDCARD_INSTANCE, 1);
- empty = make_zstring("", 0);
+ class_control = make_string(ZEPHYR_CTL_CLASS, 1);
+ class_admin = make_string(ZEPHYR_ADMIN_CLASS, 1);
+ class_hm = make_string(HM_CTL_CLASS, 1);
+ class_ulogin = make_string(LOGIN_CLASS, 1);
+ class_ulocate = make_string(LOCATE_CLASS, 1);
+ wildcard_instance = make_string(WILDCARD_INSTANCE, 1);
+ empty = make_string("", 0);
- /* restrict certain classes */
- access_init();
- return(0);
+ /* restrict certain classes */
+ access_init();
+ return 0;
}
/*
@@ -464,62 +408,59 @@ initialize()
static int
do_net_setup()
{
- struct servent *sp;
- struct hostent *hp;
- char hostname[MAXHOSTNAMELEN+1];
- int flags;
-
- if (gethostname(hostname, MAXHOSTNAMELEN+1)) {
- syslog(LOG_ERR, "no hostname: %m");
- return(1);
- }
- if (!(hp = gethostbyname(hostname))) {
- syslog(LOG_ERR, "no gethostbyname repsonse");
- (void) strncpy(myname, hostname, MAXHOSTNAMELEN);
- return(1);
- }
- (void) strncpy(myname, hp->h_name, MAXHOSTNAMELEN);
- (void) memcpy((caddr_t) &my_addr, (caddr_t) hp->h_addr,
- sizeof(hp->h_addr));
-
- (void) setservent(1); /* keep file/connection open */
-
- if (!(sp = getservbyname(SERVER_SVCNAME, "udp"))) {
- syslog(LOG_ERR, "%s/udp unknown",SERVER_SVCNAME);
- return(1);
- }
- (void) memset((caddr_t) &sock_sin, 0, sizeof(sock_sin));
- sock_sin.sin_port = sp->s_port;
-
- if (!(sp = getservbyname(HM_SVCNAME, "udp"))) {
- syslog(LOG_ERR, "%s/udp unknown", HM_SVCNAME);
- return(1);
- }
- hm_port = sp->s_port;
+ struct servent *sp;
+ struct hostent *hp;
+ char hostname[MAXHOSTNAMELEN+1];
+ int flags;
+
+ if (gethostname(hostname, MAXHOSTNAMELEN + 1)) {
+ syslog(LOG_ERR, "no hostname: %m");
+ return 1;
+ }
+ hp = gethostbyname(hostname);
+ if (!hp) {
+ syslog(LOG_ERR, "no gethostbyname repsonse");
+ strncpy(myname, hostname, MAXHOSTNAMELEN);
+ return 1;
+ }
+ strncpy(myname, hp->h_name, MAXHOSTNAMELEN);
+ memcpy(&my_addr, hp->h_addr, sizeof(hp->h_addr));
- (void) endservent();
+ setservent(1); /* keep file/connection open */
+
+ memset(&srv_addr, 0, sizeof(srv_addr));
+ srv_addr.sin_family = AF_INET;
+ sp = getservbyname(SERVER_SVCNAME, "udp");
+ srv_addr.sin_port = (sp) ? sp->s_port : SERVER_SVC_FALLBACK;
+
+ sp = getservbyname(HM_SVCNAME, "udp");
+ hm_port = (sp) ? sp->s_port : HM_SVC_FALLBACK;
- if ((srv_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "client_sock failed: %m");
- return(1);
- }
- if (bind(srv_socket, (struct sockaddr *) &sock_sin,
- sizeof(sock_sin)) < 0) {
- syslog(LOG_ERR, "client bind failed: %m");
- return(1);
- }
+ sp = getservbyname(HM_SRV_SVCNAME, "udp");
+ hm_srv_port = (sp) ? sp->s_port : HM_SRV_SVC_FALLBACK;
+
+ srv_socket = socket(AF_INET, SOCK_DGRAM, 0);
+ if (srv_socket < 0) {
+ syslog(LOG_ERR, "client_sock failed: %m");
+ return 1;
+ }
+ if (bind(srv_socket, (struct sockaddr *) &srv_addr,
+ sizeof(srv_addr)) < 0) {
+ syslog(LOG_ERR, "client bind failed: %m");
+ return 1;
+ }
- /* set not-blocking */
-#ifdef POSIX
- flags = fcntl(srv_socket, F_GETFL);
- flags |= O_NONBLOCK;
- (void) fcntl(srv_socket, F_SETFL, flags);
+ /* set not-blocking */
+#ifdef _POSIX_VERSION
+ flags = fcntl(srv_socket, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(srv_socket, F_SETFL, flags);
#else
- flags = 1;
- (void) ioctl(srv_socket, FIONBIO, (caddr_t) &flags);
+ flags = 1;
+ ioctl(srv_socket, FIONBIO, &flags);
#endif
- return(0);
+ return 0;
}
@@ -531,186 +472,160 @@ static void
usage()
{
#ifdef DEBUG
- fprintf(stderr,"Usage: %s [-d] [-s] [-n] [-f dumpfile]\n",programname);
+ fprintf(stderr, "Usage: %s [-d] [-s] [-n] [-k realm] [-f dumpfile]\n",
+ programname);
#else
- fprintf(stderr,"Usage: %s [-d] [-n] [-f dumpfile]\n",programname);
+ fprintf(stderr, "Usage: %s [-d] [-n] [-k realm] [-f dumpfile]\n",
+ programname);
#endif /* DEBUG */
exit(2);
}
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-bye(int sig)
-#else
+int
+packets_waiting()
+{
+ fd_set readable, initial;
+ struct timeval tv;
+
+ if (msgs_queued())
+ return 1;
+ FD_ZERO(&initial);
+ FD_SET(srv_socket, &initial);
+ readable = initial;
+ tv.tv_sec = tv.tv_usec = 0;
+ return (select(srv_socket + 1, &readable, NULL, NULL, &tv) > 0);
+}
+
+static RETSIGTYPE
bye(sig)
- int sig;
-#endif
+ int sig;
{
- server_shutdown(); /* tell other servers */
- hostm_shutdown(); /* tell our hosts */
-#ifdef KERBEROS
- (void) dest_tkt();
+ server_shutdown(); /* tell other servers */
+ hostm_shutdown(); /* tell our hosts */
+#ifdef ZEPHYR_USES_KERBEROS
+ dest_tkt();
#endif
- syslog(LOG_NOTICE, "goodbye (sig %d)",sig);
- exit(0);
- /*NOTREACHED*/
+ syslog(LOG_NOTICE, "goodbye (sig %d)", sig);
+ exit(0);
}
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-dbug_on(int sig)
-#else
+static RETSIGTYPE
dbug_on(sig)
- int sig;
-#endif
+ int sig;
{
- syslog(LOG_DEBUG, "debugging turned on");
+ syslog(LOG_DEBUG, "debugging turned on");
#ifdef DEBUG_MALLOC
- dump_malloc_stats = 1;
+ dump_malloc_stats = 1;
#endif
- zdebug = 1;
- SIG_RETURN;
+ zdebug = 1;
}
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-dbug_off(int sig)
-#else
+static RETSIGTYPE
dbug_off(sig)
- int sig;
-#endif
+ int sig;
{
- syslog(LOG_DEBUG, "debugging turned off");
+ syslog(LOG_DEBUG, "debugging turned off");
#ifdef DEBUG_MALLOC
- malloc_inuse(&m_size);
+ malloc_inuse(&m_size);
#endif
- zdebug = 0;
- SIG_RETURN;
+ zdebug = 0;
}
int fork_for_dump = 0;
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-sig_dump_strings (int sig)
-#else
+static RETSIGTYPE
sig_dump_strings(sig)
- int sig;
-#endif
+ int sig;
{
- dump_strings_flag = 1;
- SIG_RETURN;
+ dump_strings_flag = 1;
}
static void dump_strings()
{
+ char filename[128];
+
FILE *fp;
int oerrno = errno;
- fp = fopen ("/usr/tmp/zephyr.strings", "w");
+
+ sprintf(filename, "%szephyr.strings", TEMP_DIRECTORY);
+ fp = fopen (filename, "w");
if (!fp) {
- syslog (LOG_ERR, "can't open strings dump file: %m");
+ syslog(LOG_ERR, "can't open strings dump file: %m");
errno = oerrno;
dump_strings_flag = 0;
return;
}
- syslog (LOG_INFO, "dumping strings to disk");
- print_zstring_table(fp);
- if (fclose (fp) == EOF)
- syslog (LOG_ERR, "error writing strings dump file");
+ syslog(LOG_INFO, "dumping strings to disk");
+ print_string_table(fp);
+ if (fclose(fp) == EOF)
+ syslog(LOG_ERR, "error writing strings dump file");
else
- syslog (LOG_INFO, "dump done");
+ syslog(LOG_INFO, "dump done");
oerrno = errno;
dump_strings_flag = 0;
return;
}
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-sig_dump_db(int sig)
-#else
+static RETSIGTYPE
sig_dump_db(sig)
- int sig;
-#endif
+ int sig;
{
- dump_db_flag = 1;
- SIG_RETURN;
+ dump_db_flag = 1;
}
static void dump_db()
{
- /* dump the in-core database to human-readable form on disk */
- FILE *fp;
- int oerrno = errno;
- int pid;
+ /* dump the in-core database to human-readable form on disk */
+ FILE *fp;
+ int oerrno = errno;
+ int pid;
+ char filename[128];
-#ifdef __SABER__
- pid = -1;
-#else
- if (fork_for_dump) {
- MONCONTROL (0);
- pid = fork ();
- MONCONTROL (1);
- }
- else
- pid = -1;
-#endif
- if (pid > 0)
- {
- dump_db_flag = 0;
- return;
- }
- if ((fp = fopen("/usr/tmp/zephyr.db", "w")) == (FILE *)0) {
- syslog(LOG_ERR, "can't open dump database");
- errno = oerrno;
- dump_db_flag = 0;
- return;
- }
- syslog(LOG_INFO, "dumping to disk");
- server_dump_servers(fp);
- uloc_dump_locs(fp);
- hostm_dump_hosts(fp);
- class_dump_subs(fp);
- syslog(LOG_INFO, "dump done");
- if (fclose(fp) == EOF) {
- syslog(LOG_ERR, "can't close dump db");
- }
- if (pid == 0)
- exit (0);
+ pid = (fork_for_dump) ? fork() : -1;
+ if (pid > 0) {
+ dump_db_flag = 0;
+ return;
+ }
+ sprintf(filename, "%szephyr.db", TEMP_DIRECTORY);
+ fp = fopen(filename, "w");
+ if (!fp) {
+ syslog(LOG_ERR, "can't open dump database");
errno = oerrno;
dump_db_flag = 0;
return;
+ }
+ syslog(LOG_INFO, "dumping to disk");
+ server_dump_servers(fp);
+ uloc_dump_locs(fp);
+ client_dump_clients(fp);
+ triplet_dump_subs(fp);
+ realm_dump_realms(fp);
+ syslog(LOG_INFO, "dump done");
+ if (fclose(fp) == EOF)
+ syslog(LOG_ERR, "can't close dump db");
+ if (pid == 0)
+ exit(0);
+ errno = oerrno;
+ dump_db_flag = 0;
}
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-reset(int sig)
-#else
+static RETSIGTYPE
reset(sig)
- int sig;
-#endif
+ int sig;
{
#if 1
- zdbug((LOG_DEBUG,"reset()"));
+ zdbug((LOG_DEBUG,"reset()"));
#endif
- doreset = 1;
- SIG_RETURN;
+ doreset = 1;
}
-#ifdef __GNUG__
-#define wait WaitStatus
-#endif
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-reap(int sig)
-#else
+static RETSIGTYPE
reap(sig)
- int sig;
-#endif
+ int sig;
{
int oerrno = errno;
-#ifdef POSIX
+#ifdef _POSIX_VERSION
int waitb;
while (waitpid(-1, &waitb, WNOHANG) == 0) ;
#else
@@ -719,40 +634,39 @@ reap(sig)
#endif
errno = oerrno;
- SIG_RETURN;
}
static void
do_reset()
{
- int oerrno = errno;
-#ifdef POSIX
- sigset_t mask, omask;
+ int oerrno = errno;
+#ifdef _POSIX_VERSION
+ sigset_t mask, omask;
#else
- int omask;
+ int omask;
#endif
#if 0
- zdbug((LOG_DEBUG,"do_reset()"));
+ zdbug((LOG_DEBUG,"do_reset()"));
#endif
-#ifdef POSIX
- sigemptyset(&mask);
- sigaddset(&mask, SIGHUP);
- sigprocmask(SIG_BLOCK, &mask, &omask);
+#ifdef _POSIX_VERSION
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGHUP);
+ sigprocmask(SIG_BLOCK, &mask, &omask);
#else
- omask = sigblock(sigmask(SIGHUP));
+ omask = sigblock(sigmask(SIGHUP));
#endif
- /* reset various things in the server's state */
- subscr_reset();
- server_reset();
- access_reinit();
- syslog (LOG_INFO, "restart completed");
- doreset = 0;
- errno = oerrno;
-#ifdef POSIX
- sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
+ /* reset various things in the server's state */
+ subscr_reset();
+ server_reset();
+ access_reinit();
+ syslog(LOG_INFO, "restart completed");
+ doreset = 0;
+ errno = oerrno;
+#ifdef _POSIX_VERSION
+ sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
#else
- sigsetmask(omask);
+ sigsetmask(omask);
#endif
}
@@ -764,40 +678,42 @@ do_reset()
static void
detach()
{
- /* detach from terminal and fork. */
- register int i;
- register long size;
+ /* detach from terminal and fork. */
+ int i;
+ long size;
-#ifdef POSIX
- size = sysconf(_SC_OPEN_MAX);
+#ifdef _POSIX_VERSION
+ size = sysconf(_SC_OPEN_MAX);
#else
- size = getdtablesize();
-#endif
- /* profiling seems to get confused by fork() */
- MONCONTROL (0);
- i = fork ();
- MONCONTROL (1);
- if (i) {
- if (i < 0)
- perror("fork");
- exit(0);
- }
+ size = getdtablesize();
+#endif
+ /* profiling seems to get confused by fork() */
+ i = fork ();
+ if (i) {
+ if (i < 0)
+ perror("fork");
+ exit(0);
+ }
- for (i = 0; i < size; i++) {
- (void) close(i);
- }
- i = open("/dev/tty", O_RDWR, 666);
- (void) ioctl(i, TIOCNOTTY, (caddr_t) 0);
- (void) close(i);
-#ifdef POSIX
- (void) setsid();
+ for (i = 0; i < size; i++)
+ close(i);
+
+ i = open("/dev/tty", O_RDWR, 666);
+#ifdef TIOCNOTTY /* Only necessary on old systems. */
+ ioctl(i, TIOCNOTTY, NULL);
#endif
-}
+ close(i);
+#ifdef _POSIX_VERSION
+ setsid();
#endif
+}
+#endif /* not DEBUG */
static void
read_from_dump(dumpfile)
- char *dumpfile;
+ char *dumpfile;
{
- return;
+ /* Not yet implemented. */
+ return;
}
+
diff --git a/server/main.c.auth b/server/main.c.auth
deleted file mode 100644
index c0ae1af..0000000
--- a/server/main.c.auth
+++ /dev/null
@@ -1,804 +0,0 @@
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains the main loop of the Zephyr server
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- *
- * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#ifndef lint
-#ifndef SABER
-static char rcsid_main_c[] =
- "$Id$";
-#endif
-#endif
-
-/*
- * Server loop for Zephyr.
- */
-
-/*
- The Zephyr server maintains several linked lists of information.
-
- There is an array of servers (otherservers) initialized and maintained
- by server_s.c.
-
- Each server descriptor contains a pointer to a linked list of hosts
- which are ``owned'' by that server. The first server is the ``limbo''
- server which owns any host which was formerly owned by a dead server.
-
- Each of these host list entries has an IP address and a pointer to a
- linked list of clients on that host.
-
- Each client has a sockaddr_in, a list of subscriptions, and possibly
- a session key.
-
- In addition, the class manager has copies of the pointers to the
- clients which are registered with a particular class, the
- not-yet-acknowledged list has copies of pointers to some clients,
- and the hostm manager may have copies of pointers to some clients
- (if the client has not acknowledged a packet after a given timeout).
-*/
-
-#include "zserver.h"
-/* which includes
- zephyr/zephyr.h
- <errno.h>
- <sys/types.h>
- <netinet/in.h>
- <sys/time.h>
- <stdio.h>
- <sys/file.h>
- <syslog.h>
- <strings.h>
- <signal.h>
- timer.h
- zsrv_err.h
- */
-
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#ifdef POSIX
-#include <termios.h>
-#endif
-
-#ifdef POSIX
-#define SIGNAL_RETURN_TYPE void
-#define SIG_RETURN return
-#else
-#define SIGNAL_RETURN_TYPE int
-#define SIG_RETURN return(0)
-#endif
-
-#if !defined(__SABER__) && (defined (vax) || defined (ibm032))
-#define MONCONTROL moncontrol
-#else
-#define MONCONTROL (void)
-#endif
-
-#define EVER (;;) /* don't stop looping */
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static int do_net_setup P((void)), initialize P((void));
-static void usage P((void)), do_reset P((void));
-static SIGNAL_RETURN_TYPE bye P((int)),
- dbug_on P((int)), dbug_off P((int)),
- sig_dump_db P((int)), sig_dump_strings P((int)),
- reset P((int)), reap P((int));
-static void read_from_dump P((char *dumpfile));
-static void dump_db P((void)), dump_strings P((void));
-
-#ifndef DEBUG
-static void detach P((void));
-#endif
-
-extern void perror P((Zconst char *));
-
-#undef P
-
-static short doreset = 0; /* if it becomes 1, perform
- reset functions */
-
-int srv_socket; /* dgram socket for clients
- and other servers */
-int bdump_socket = -1; /* brain dump socket fd
- (closed most of the time) */
-fd_set interesting; /* the file descrips we are listening
- to right now */
-int nfildes; /* number to look at in select() */
-struct sockaddr_in sock_sin; /* address of the socket */
-struct timeval nexthost_tv; /* time till next timeout for select */
-
-ZNotAcked_t *nacklist; /* list of packets waiting for ack's */
-
-u_short hm_port; /* the port # of the host manager */
-
-char *programname; /* set to the basename of argv[0] */
-char myname[MAXHOSTNAMELEN]; /* my host name */
-
-int zdebug;
-#ifdef DEBUG_MALLOC
-int dump_malloc_stats = 0;
-unsigned long m_size;
-#endif
-#ifdef DEBUG
-int zalone;
-#endif
-
-struct timeval t_local; /* store current time for other uses */
-
-static int dump_db_flag = 0;
-static int dump_strings_flag = 0;
-
-u_long npackets; /* number of packets processed */
-long uptime; /* when we started operations */
-static int nofork;
-struct in_addr my_addr;
-char *bdump_version = "1.1";
-
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- int nfound; /* #fildes ready on select */
- fd_set readable;
- struct timeval *tvp;
- int init_from_dump = 0;
- char *dumpfile;
-#ifdef POSIX
- struct sigaction action;
-#endif
-
-
- int optchar; /* option processing */
- extern char *optarg;
- extern int optind;
-
- /* set name */
- if (programname = strrchr(argv[0],'/'))
- programname++;
- else programname = argv[0];
-
- /* process arguments */
-
- while ((optchar = getopt(argc, argv, "dsnv:f:")) != EOF) {
- switch(optchar) {
- case 'd':
- zdebug = 1;
- break;
-#ifdef DEBUG
- case 's':
- zalone = 1;
- break;
-#endif
- case 'n':
- nofork = 1;
- break;
- case 'v':
- bdump_version = optarg;
- break;
- case 'f':
- init_from_dump = 0;
- dumpfile = optarg;
- break;
- case '?':
- default:
- usage();
- /*NOTREACHED*/
- }
- }
-
-#ifdef KERBEROS
- /* if there is no readable srvtab and we are not standalone, there
- is no possible way we can succeed, so we exit */
-
- if (access(ZEPHYR_SRVTAB, R_OK)
-#ifdef DEBUG
- && !zalone
-#endif /* DEBUG */
- ) {
- fprintf(stderr, "NO ZEPHYR SRVTAB (%s) available; exiting\n",
- ZEPHYR_SRVTAB);
- exit(1);
- }
-#endif /* KERBEROS */
-
-#ifndef DEBUG
- if (!nofork)
- detach();
-#endif /* DEBUG */
-
- /* open log */
- OPENLOG(programname, LOG_PID, LOG_LOCAL6);
-
-#if defined (DEBUG) && 0
- if (zalone)
- syslog(LOG_DEBUG, "standalone operation");
-#endif
-#if 0
- if (zdebug)
- syslog(LOG_DEBUG, "debugging on");
-#endif
-
- /* set up sockets & my_addr and myname,
- find other servers and set up server table, initialize queues
- for retransmits, initialize error tables,
- set up restricted classes */
-
- /* Initialize t_local for other uses */
- (void) gettimeofday(&t_local, (struct timezone *)0);
-
- if (initialize())
- exit(1);
-
- if (init_from_dump)
- read_from_dump(dumpfile);
-
- /* Seed random number set. */
- srandom (getpid () ^ time (0));
-
-#ifndef __SABER__
- /* chdir to somewhere where a core dump will survive */
- if (chdir("/usr/tmp") != 0)
- syslog(LOG_ERR,"chdir failed (%m) (execution continuing)");
-
-#if 0
- /*
- * Many systems don't implement setpriority() as is done under BSD,
- * and the kernel scheduler will appropriately swap in the processes
- * that are needed.
- */
- if (setpriority(PRIO_PROCESS, getpid(), -10))
- syslog(LOG_ERR,"setpriority failed (%m)");
-#endif
-#endif
-
- FD_ZERO(&interesting);
- FD_SET(srv_socket, &interesting);
-
- nfildes = srv_socket + 1;
-
-
-#ifdef POSIX
- action.sa_flags = 0;
- sigemptyset(&action.sa_mask);
-
- action.sa_handler = bye;
- sigaction(SIGINT, &action, NULL);
- sigaction(SIGTERM, &action, NULL);
-
- action.sa_handler = dbug_on;
- sigaction(SIGUSR1, &action, NULL);
-
- action.sa_handler = dbug_off;
- sigaction(SIGUSR2, &action, NULL);
-
- action.sa_handler = reap;
- sigaction(SIGCHLD, &action, NULL);
-
- action.sa_handler = sig_dump_db;
- sigaction(SIGFPE, &action, NULL);
- sigaction(SIGXCPU, &action, NULL);
-
-#ifdef SIGEMT
- action.sa_handler = sig_dump_strings;
- sigaction(SIGEMT, &action, NULL);
-#endif
-
- action.sa_handler = reset;
- sigaction(SIGHUP, &action, NULL);
-#else /* !posix */
- (void) signal(SIGINT, bye);
- (void) signal(SIGTERM, bye);
- (void) signal(SIGUSR1, dbug_on);
- (void) signal(SIGUSR2, dbug_off);
- (void) signal(SIGCHLD, reap);
- (void) signal(SIGFPE, sig_dump_db);
- (void) signal(SIGXCPU, sig_dump_db);
-#ifdef SIGEMT
- (void) signal(SIGEMT, sig_dump_strings);
-#endif
- (void) signal(SIGHUP, reset);
-#endif /* POSIX */
-
- syslog(LOG_NOTICE, "Ready for action");
-
- /* Reinitialize t_local now that initialization is done. */
- (void) gettimeofday(&t_local, (struct timezone *)0);
- timer_set_rel(SWEEP_INTERVAL, sweep_ticket_hash_table, NULL);
- /* GO! */
- uptime = NOW;
-
-#ifdef DEBUG_MALLOC
- malloc_inuse(&m_size);
-#endif
- for EVER {
- if (doreset)
- do_reset();
-
- if (dump_db_flag)
- dump_db();
- if (dump_strings_flag)
- dump_strings();
-
- nexthost_tv.tv_usec = 0;
- tvp = &nexthost_tv;
-
- if (nexttimo != 0L) {
- nexthost_tv.tv_sec = nexttimo - NOW;
- if (nexthost_tv.tv_sec <= 0) {
- /* timeout has passed! */
- /* so we process one timeout, then pop to
- select, polling for input. This way we get
- work done even if swamped with many
- timeouts */
- /* this will reset nexttimo */
- (void) timer_process();
- nexthost_tv.tv_sec = 0;
- }
- } else { /* no timeouts to process */
- nexthost_tv.tv_sec = 15;
- }
- readable = interesting;
- if (msgs_queued()) {
- /* when there is input in the queue, we
- artificially set up to pick up the input */
- nfound = 1;
- FD_ZERO(&readable);
- } else
- nfound = select(nfildes, &readable, (fd_set *) 0,
- (fd_set *) 0, tvp);
-
- /* Initialize t_local for other uses */
- (void) gettimeofday(&t_local, (struct timezone *)0);
-
- /* don't flame about EINTR, since a SIGUSR1 or SIGUSR2
- can generate it by interrupting the select */
- if (nfound < 0) {
- if (errno != EINTR)
- syslog(LOG_WARNING, "select error: %m");
-#ifdef DEBUG_MALLOC
- if (dump_malloc_stats) {
- unsigned long foo,histid2;
- dump_malloc_stats = 0;
- foo = malloc_inuse(&histid2);
- printf("Total inuse: %d\n",foo);
- malloc_list(2,m_size,histid2);
- }
-#endif
- continue;
- }
- if (nfound == 0)
- /* either we timed out or we were just
- polling for input. Either way we want to continue
- the loop, and process the next timeout */
- continue;
- else {
- if ((bdump_socket >= 0) &&
- FD_ISSET(bdump_socket,&readable))
- bdump_send();
- else if (msgs_queued() ||
- FD_ISSET(srv_socket, &readable)) {
- handle_packet();
- } else
- syslog(LOG_ERR, "select weird?!?!");
- }
- }
-}
-
-/* Initialize net stuff.
- Set up the server array.
- Initialize the packet ack queues to be empty.
- Initialize the error tables.
- Restrict certain classes.
- */
-
-static int
-initialize()
-{
- if (do_net_setup())
- return(1);
-
- server_init();
-
-#if 0
- if (!(nacklist = (ZNotAcked_t *) xmalloc(sizeof(ZNotAcked_t)))) {
- /* unrecoverable */
- syslog(LOG_CRIT, "nacklist malloc");
- abort();
- }
-#else
- {
- static ZNotAcked_t not_acked_head;
- nacklist = &not_acked_head;
- }
-#endif
- (void) memset((caddr_t) nacklist, 0, sizeof(ZNotAcked_t));
- nacklist->q_forw = nacklist->q_back = nacklist;
-
- nexttimo = 1L; /* trigger the timers when we hit
- the FOR loop */
-
- (void) ZInitialize(); /* set up the library */
- (void) init_zsrv_err_tbl(); /* set up err table */
-
- (void) ZSetServerState(1);
- (void) ZSetFD(srv_socket); /* set up the socket as the
- input fildes */
-
- /* set up default strings */
-
- class_control = make_zstring(ZEPHYR_CTL_CLASS, 1);
- class_admin = make_zstring(ZEPHYR_ADMIN_CLASS, 1);
- class_hm = make_zstring(HM_CTL_CLASS, 1);
- class_ulogin = make_zstring(LOGIN_CLASS, 1);
- class_ulocate = make_zstring(LOCATE_CLASS, 1);
- wildcard_instance = make_zstring(WILDCARD_INSTANCE, 1);
- empty = make_zstring("", 0);
-
- /* restrict certain classes */
- access_init();
- return(0);
-}
-
-/*
- * Set up the server and client sockets, and initialize my_addr and myname
- */
-
-static int
-do_net_setup()
-{
- struct servent *sp;
- struct hostent *hp;
- char hostname[MAXHOSTNAMELEN+1];
- int flags;
-
- if (gethostname(hostname, MAXHOSTNAMELEN+1)) {
- syslog(LOG_ERR, "no hostname: %m");
- return(1);
- }
- if (!(hp = gethostbyname(hostname))) {
- syslog(LOG_ERR, "no gethostbyname repsonse");
- (void) strncpy(myname, hostname, MAXHOSTNAMELEN);
- return(1);
- }
- (void) strncpy(myname, hp->h_name, MAXHOSTNAMELEN);
- (void) memcpy((caddr_t) &my_addr, (caddr_t) hp->h_addr,
- sizeof(hp->h_addr));
-
- (void) setservent(1); /* keep file/connection open */
-
- if (!(sp = getservbyname(SERVER_SVCNAME, "udp"))) {
- syslog(LOG_ERR, "%s/udp unknown",SERVER_SVCNAME);
- return(1);
- }
- (void) memset((caddr_t) &sock_sin, 0, sizeof(sock_sin));
- sock_sin.sin_port = sp->s_port;
-
- if (!(sp = getservbyname(HM_SVCNAME, "udp"))) {
- syslog(LOG_ERR, "%s/udp unknown", HM_SVCNAME);
- return(1);
- }
- hm_port = sp->s_port;
-
- (void) endservent();
-
- if ((srv_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "client_sock failed: %m");
- return(1);
- }
- if (bind(srv_socket, (struct sockaddr *) &sock_sin,
- sizeof(sock_sin)) < 0) {
- syslog(LOG_ERR, "client bind failed: %m");
- return(1);
- }
-
- /* set not-blocking */
-#ifdef POSIX
- flags = fcntl(srv_socket, F_GETFL);
- flags |= O_NONBLOCK;
- (void) fcntl(srv_socket, F_SETFL, flags);
-#else
- flags = 1;
- (void) ioctl(srv_socket, FIONBIO, (caddr_t) &flags);
-#endif
-
- return(0);
-}
-
-
-/*
- * print out a usage message.
- */
-
-static void
-usage()
-{
-#ifdef DEBUG
- fprintf(stderr,"Usage: %s [-d] [-s] [-n] [-f dumpfile]\n",programname);
-#else
- fprintf(stderr,"Usage: %s [-d] [-n] [-f dumpfile]\n",programname);
-#endif /* DEBUG */
- exit(2);
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-bye(int sig)
-#else
-bye(sig)
- int sig;
-#endif
-{
- server_shutdown(); /* tell other servers */
- hostm_shutdown(); /* tell our hosts */
-#ifdef KERBEROS
- (void) dest_tkt();
-#endif
- syslog(LOG_NOTICE, "goodbye (sig %d)",sig);
- exit(0);
- /*NOTREACHED*/
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-dbug_on(int sig)
-#else
-dbug_on(sig)
- int sig;
-#endif
-{
- syslog(LOG_DEBUG, "debugging turned on");
-#ifdef DEBUG_MALLOC
- dump_malloc_stats = 1;
-#endif
- zdebug = 1;
- SIG_RETURN;
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-dbug_off(int sig)
-#else
-dbug_off(sig)
- int sig;
-#endif
-{
- syslog(LOG_DEBUG, "debugging turned off");
-#ifdef DEBUG_MALLOC
- malloc_inuse(&m_size);
-#endif
- zdebug = 0;
- SIG_RETURN;
-}
-
-int fork_for_dump = 0;
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-sig_dump_strings (int sig)
-#else
-sig_dump_strings(sig)
- int sig;
-#endif
-{
- dump_strings_flag = 1;
- SIG_RETURN;
-}
-
-static void dump_strings()
-{
- FILE *fp;
- int oerrno = errno;
- fp = fopen ("/usr/tmp/zephyr.strings", "w");
- if (!fp) {
- syslog (LOG_ERR, "can't open strings dump file: %m");
- errno = oerrno;
- dump_strings_flag = 0;
- return;
- }
- syslog (LOG_INFO, "dumping strings to disk");
- print_zstring_table(fp);
- if (fclose (fp) == EOF)
- syslog (LOG_ERR, "error writing strings dump file");
- else
- syslog (LOG_INFO, "dump done");
- oerrno = errno;
- dump_strings_flag = 0;
- return;
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-sig_dump_db(int sig)
-#else
-sig_dump_db(sig)
- int sig;
-#endif
-{
- dump_db_flag = 1;
- SIG_RETURN;
-}
-
-static void dump_db()
-{
- /* dump the in-core database to human-readable form on disk */
- FILE *fp;
- int oerrno = errno;
- int pid;
-
-#ifdef __SABER__
- pid = -1;
-#else
- if (fork_for_dump) {
- MONCONTROL (0);
- pid = fork ();
- MONCONTROL (1);
- }
- else
- pid = -1;
-#endif
- if (pid > 0)
- {
- dump_db_flag = 0;
- return;
- }
- if ((fp = fopen("/usr/tmp/zephyr.db", "w")) == (FILE *)0) {
- syslog(LOG_ERR, "can't open dump database");
- errno = oerrno;
- dump_db_flag = 0;
- return;
- }
- syslog(LOG_INFO, "dumping to disk");
- server_dump_servers(fp);
- uloc_dump_locs(fp);
- hostm_dump_hosts(fp);
- class_dump_subs(fp);
- syslog(LOG_INFO, "dump done");
- if (fclose(fp) == EOF) {
- syslog(LOG_ERR, "can't close dump db");
- }
- if (pid == 0)
- exit (0);
- errno = oerrno;
- dump_db_flag = 0;
- return;
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-reset(int sig)
-#else
-reset(sig)
- int sig;
-#endif
-{
-#if 1
- zdbug((LOG_DEBUG,"reset()"));
-#endif
- doreset = 1;
- SIG_RETURN;
-}
-
-#ifdef __GNUG__
-#define wait WaitStatus
-#endif
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-reap(int sig)
-#else
-reap(sig)
- int sig;
-#endif
-{
- int oerrno = errno;
-
-#ifdef POSIX
- int waitb;
- while (waitpid(-1, &waitb, WNOHANG) == 0) ;
-#else
- union wait waitb;
- while (wait3 (&waitb, WNOHANG, (struct rusage*) 0) == 0) ;
-#endif
-
- errno = oerrno;
- SIG_RETURN;
-}
-
-static void
-do_reset()
-{
- int oerrno = errno;
-#ifdef POSIX
- sigset_t mask, omask;
-#else
- int omask;
-#endif
-#if 0
- zdbug((LOG_DEBUG,"do_reset()"));
-#endif
-#ifdef POSIX
- sigemptyset(&mask);
- sigaddset(&mask, SIGHUP);
- sigprocmask(SIG_BLOCK, &mask, &omask);
-#else
- omask = sigblock(sigmask(SIGHUP));
-#endif
-
- /* reset various things in the server's state */
- subscr_reset();
- server_reset();
- access_reinit();
- syslog (LOG_INFO, "restart completed");
- doreset = 0;
- errno = oerrno;
-#ifdef POSIX
- sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
-#else
- sigsetmask(omask);
-#endif
-}
-
-#ifndef DEBUG
-/*
- * detach from the terminal
- */
-
-static void
-detach()
-{
- /* detach from terminal and fork. */
- register int i;
- register long size;
-
-#ifdef POSIX
- size = sysconf(_SC_OPEN_MAX);
-#else
- size = getdtablesize();
-#endif
- /* profiling seems to get confused by fork() */
- MONCONTROL (0);
- i = fork ();
- MONCONTROL (1);
- if (i) {
- if (i < 0)
- perror("fork");
- exit(0);
- }
-
- for (i = 0; i < size; i++) {
- (void) close(i);
- }
- i = open("/dev/tty", O_RDWR, 666);
- (void) ioctl(i, TIOCNOTTY, (caddr_t) 0);
- (void) close(i);
-#ifdef POSIX
- (void) setsid();
-#endif
-}
-#endif
-
-static void
-read_from_dump(dumpfile)
- char *dumpfile;
-{
- return;
-}
diff --git a/server/main.c.old b/server/main.c.old
deleted file mode 100644
index b3ec4e4..0000000
--- a/server/main.c.old
+++ /dev/null
@@ -1,803 +0,0 @@
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains the main loop of the Zephyr server
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- *
- * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#ifndef lint
-#ifndef SABER
-static char rcsid_main_c[] =
- "$Id$";
-#endif
-#endif
-
-/*
- * Server loop for Zephyr.
- */
-
-/*
- The Zephyr server maintains several linked lists of information.
-
- There is an array of servers (otherservers) initialized and maintained
- by server_s.c.
-
- Each server descriptor contains a pointer to a linked list of hosts
- which are ``owned'' by that server. The first server is the ``limbo''
- server which owns any host which was formerly owned by a dead server.
-
- Each of these host list entries has an IP address and a pointer to a
- linked list of clients on that host.
-
- Each client has a sockaddr_in, a list of subscriptions, and possibly
- a session key.
-
- In addition, the class manager has copies of the pointers to the
- clients which are registered with a particular class, the
- not-yet-acknowledged list has copies of pointers to some clients,
- and the hostm manager may have copies of pointers to some clients
- (if the client has not acknowledged a packet after a given timeout).
-*/
-
-#include "zserver.h"
-/* which includes
- zephyr/zephyr.h
- <errno.h>
- <sys/types.h>
- <netinet/in.h>
- <sys/time.h>
- <stdio.h>
- <sys/file.h>
- <syslog.h>
- <strings.h>
- <signal.h>
- timer.h
- zsrv_err.h
- */
-
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#ifdef POSIX
-#include <termios.h>
-#endif
-
-#ifdef POSIX
-#define SIGNAL_RETURN_TYPE void
-#define SIG_RETURN return
-#else
-#define SIGNAL_RETURN_TYPE int
-#define SIG_RETURN return(0)
-#endif
-
-#if !defined(__SABER__) && (defined (vax) || defined (ibm032))
-#define MONCONTROL moncontrol
-#else
-#define MONCONTROL (void)
-#endif
-
-#define EVER (;;) /* don't stop looping */
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static int do_net_setup P((void)), initialize P((void));
-static void usage P((void)), do_reset P((void));
-static SIGNAL_RETURN_TYPE bye P((int)),
- dbug_on P((int)), dbug_off P((int)),
- sig_dump_db P((int)), sig_dump_strings P((int)),
- reset P((int)), reap P((int));
-static void read_from_dump P((char *dumpfile));
-static void dump_db P((void)), dump_strings P((void));
-
-#ifndef DEBUG
-static void detach P((void));
-#endif
-
-extern void perror P((Zconst char *));
-
-#undef P
-
-static short doreset = 0; /* if it becomes 1, perform
- reset functions */
-
-int srv_socket; /* dgram socket for clients
- and other servers */
-int bdump_socket = -1; /* brain dump socket fd
- (closed most of the time) */
-fd_set interesting; /* the file descrips we are listening
- to right now */
-int nfildes; /* number to look at in select() */
-struct sockaddr_in sock_sin; /* address of the socket */
-struct timeval nexthost_tv; /* time till next timeout for select */
-
-ZNotAcked_t *nacklist; /* list of packets waiting for ack's */
-
-u_short hm_port; /* the port # of the host manager */
-
-char *programname; /* set to the basename of argv[0] */
-char myname[MAXHOSTNAMELEN]; /* my host name */
-
-int zdebug;
-#ifdef DEBUG_MALLOC
-int dump_malloc_stats = 0;
-unsigned long m_size;
-#endif
-#ifdef DEBUG
-int zalone;
-#endif
-
-struct timeval t_local; /* store current time for other uses */
-
-static int dump_db_flag = 0;
-static int dump_strings_flag = 0;
-
-u_long npackets; /* number of packets processed */
-long uptime; /* when we started operations */
-static int nofork;
-struct in_addr my_addr;
-char *bdump_version = "1.1";
-
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- int nfound; /* #fildes ready on select */
- fd_set readable;
- struct timeval *tvp;
- int init_from_dump = 0;
- char *dumpfile;
-#ifdef POSIX
- struct sigaction action;
-#endif
-
-
- int optchar; /* option processing */
- extern char *optarg;
- extern int optind;
-
- /* set name */
- if (programname = strrchr(argv[0],'/'))
- programname++;
- else programname = argv[0];
-
- /* process arguments */
-
- while ((optchar = getopt(argc, argv, "dsnv:f:")) != EOF) {
- switch(optchar) {
- case 'd':
- zdebug = 1;
- break;
-#ifdef DEBUG
- case 's':
- zalone = 1;
- break;
-#endif
- case 'n':
- nofork = 1;
- break;
- case 'v':
- bdump_version = optarg;
- break;
- case 'f':
- init_from_dump = 0;
- dumpfile = optarg;
- break;
- case '?':
- default:
- usage();
- /*NOTREACHED*/
- }
- }
-
-#ifdef KERBEROS
- /* if there is no readable srvtab and we are not standalone, there
- is no possible way we can succeed, so we exit */
-
- if (access(ZEPHYR_SRVTAB, R_OK)
-#ifdef DEBUG
- && !zalone
-#endif /* DEBUG */
- ) {
- fprintf(stderr, "NO ZEPHYR SRVTAB (%s) available; exiting\n",
- ZEPHYR_SRVTAB);
- exit(1);
- }
-#endif /* KERBEROS */
-
-#ifndef DEBUG
- if (!nofork)
- detach();
-#endif /* DEBUG */
-
- /* open log */
- OPENLOG(programname, LOG_PID, LOG_LOCAL6);
-
-#if defined (DEBUG) && 0
- if (zalone)
- syslog(LOG_DEBUG, "standalone operation");
-#endif
-#if 0
- if (zdebug)
- syslog(LOG_DEBUG, "debugging on");
-#endif
-
- /* set up sockets & my_addr and myname,
- find other servers and set up server table, initialize queues
- for retransmits, initialize error tables,
- set up restricted classes */
-
- if (initialize())
- exit(1);
-
- if (init_from_dump)
- read_from_dump(dumpfile);
-
- /* Seed random number set. */
- srandom (getpid () ^ time (0));
-
-#ifndef __SABER__
- /* chdir to somewhere where a core dump will survive */
- if (chdir("/usr/tmp") != 0)
- syslog(LOG_ERR,"chdir failed (%m) (execution continuing)");
-
-#if 0
- /*
- * Many systems don't implement setpriority() as is done under BSD,
- * and the kernel scheduler will appropriately swap in the processes
- * that are needed.
- */
- if (setpriority(PRIO_PROCESS, getpid(), -10))
- syslog(LOG_ERR,"setpriority failed (%m)");
-#endif
-#endif
-
- FD_ZERO(&interesting);
- FD_SET(srv_socket, &interesting);
-
- nfildes = srv_socket + 1;
-
-
-#ifdef POSIX
- action.sa_flags = 0;
- sigemptyset(&action.sa_mask);
-
- action.sa_handler = bye;
- sigaction(SIGINT, &action, NULL);
- sigaction(SIGTERM, &action, NULL);
-
- action.sa_handler = dbug_on;
- sigaction(SIGUSR1, &action, NULL);
-
- action.sa_handler = dbug_off;
- sigaction(SIGUSR2, &action, NULL);
-
- action.sa_handler = reap;
- sigaction(SIGCHLD, &action, NULL);
-
- action.sa_handler = sig_dump_db;
- sigaction(SIGFPE, &action, NULL);
- sigaction(SIGXCPU, &action, NULL);
-
- action.sa_handler = sig_dump_strings;
- sigaction(SIGEMT, &action, NULL);
-
- action.sa_handler = reset;
- sigaction(SIGHUP, &action, NULL);
-#else /* !posix */
- (void) signal(SIGINT, bye);
- (void) signal(SIGTERM, bye);
- (void) signal(SIGUSR1, dbug_on);
- (void) signal(SIGUSR2, dbug_off);
- (void) signal(SIGCHLD, reap);
- (void) signal(SIGFPE, sig_dump_db);
- (void) signal(SIGXCPU, sig_dump_db);
- (void) signal(SIGEMT, sig_dump_strings);
- (void) signal(SIGHUP, reset);
-#endif /* POSIX */
-
- syslog(LOG_NOTICE, "Ready for action");
-
- /* Initialize t_local for other uses */
- (void) gettimeofday(&t_local, (struct timezone *)0);
- /* GO! */
- uptime = NOW;
-
-#ifdef DEBUG_MALLOC
- malloc_inuse(&m_size);
-#endif
- for EVER {
- if (doreset)
- do_reset();
-
- if (dump_db_flag)
- dump_db();
- if (dump_strings_flag)
- dump_strings();
-
- nexthost_tv.tv_usec = 0;
- tvp = &nexthost_tv;
-
- if (nexttimo != 0L) {
- nexthost_tv.tv_sec = nexttimo - NOW;
- if (nexthost_tv.tv_sec <= 0) {
- /* timeout has passed! */
- /* so we process one timeout, then pop to
- select, polling for input. This way we get
- work done even if swamped with many
- timeouts */
- /* this will reset nexttimo */
- (void) timer_process();
- nexthost_tv.tv_sec = 0;
- }
- } else { /* no timeouts to process */
- nexthost_tv.tv_sec = 15;
- }
- readable = interesting;
- if (msgs_queued()) {
- /* when there is input in the queue, we
- artificially set up to pick up the input */
- nfound = 1;
- FD_ZERO(&readable);
- } else
- nfound = select(nfildes, &readable, (fd_set *) 0,
- (fd_set *) 0, tvp);
-
- /* Initialize t_local for other uses */
- (void) gettimeofday(&t_local, (struct timezone *)0);
-
- /* don't flame about EINTR, since a SIGUSR1 or SIGUSR2
- can generate it by interrupting the select */
- if (nfound < 0) {
- if (errno != EINTR)
- syslog(LOG_WARNING, "select error: %m");
-#ifdef DEBUG_MALLOC
- if (dump_malloc_stats) {
- unsigned long foo,histid2;
- dump_malloc_stats = 0;
- foo = malloc_inuse(&histid2);
- printf("Total inuse: %d\n",foo);
- malloc_list(2,m_size,histid2);
- }
-#endif
- continue;
- }
- if (nfound == 0)
- /* either we timed out or we were just
- polling for input. Either way we want to continue
- the loop, and process the next timeout */
- continue;
- else {
- if ((bdump_socket >= 0) &&
- FD_ISSET(bdump_socket,&readable))
- bdump_send();
- else if (msgs_queued() ||
- FD_ISSET(srv_socket, &readable)) {
- handle_packet();
- } else
- syslog(LOG_ERR, "select weird?!?!");
- }
- }
-}
-
-/* Initialize net stuff.
- Set up the server array.
- Initialize the packet ack queues to be empty.
- Initialize the error tables.
- Restrict certain classes.
- */
-
-static int
-initialize()
-{
- if (do_net_setup())
- return(1);
-
- server_init();
-
-#if 0
- if (!(nacklist = (ZNotAcked_t *) xmalloc(sizeof(ZNotAcked_t)))) {
- /* unrecoverable */
- syslog(LOG_CRIT, "nacklist malloc");
- abort();
- }
-#else
- {
- static ZNotAcked_t not_acked_head;
- nacklist = &not_acked_head;
- }
-#endif
- (void) memset((caddr_t) nacklist, 0, sizeof(ZNotAcked_t));
- nacklist->q_forw = nacklist->q_back = nacklist;
-
- nexttimo = 1L; /* trigger the timers when we hit
- the FOR loop */
-
- (void) ZInitialize(); /* set up the library */
- (void) init_zsrv_err_tbl(); /* set up err table */
-
- (void) ZSetServerState(1);
- (void) ZSetFD(srv_socket); /* set up the socket as the
- input fildes */
-
- /* set up default strings */
-
- class_control = make_zstring(ZEPHYR_CTL_CLASS, 1);
- class_admin = make_zstring(ZEPHYR_ADMIN_CLASS, 1);
- class_hm = make_zstring(HM_CTL_CLASS, 1);
- class_ulogin = make_zstring(LOGIN_CLASS, 1);
- class_ulocate = make_zstring(LOCATE_CLASS, 1);
- wildcard_class = make_zstring(MATCHALL_CLASS, 1);
- wildcard_instance = make_zstring(WILDCARD_INSTANCE, 1);
- empty = make_zstring("", 0);
-
- matchall_sub.q_forw = &matchall_sub;
- matchall_sub.q_back = &matchall_sub;
- matchall_sub.zst_dest.classname = wildcard_class;
- matchall_sub.zst_dest.inst = dup_zstring(empty);
- matchall_sub.zst_dest.recip = dup_zstring(empty);
-
- set_ZDestination_hash(&matchall_sub.zst_dest);
- /* restrict certain classes */
- access_init();
- return(0);
-}
-
-/*
- * Set up the server and client sockets, and initialize my_addr and myname
- */
-
-static int
-do_net_setup()
-{
- struct servent *sp;
- struct hostent *hp;
- char hostname[MAXHOSTNAMELEN+1];
- int flags;
-
- if (gethostname(hostname, MAXHOSTNAMELEN+1)) {
- syslog(LOG_ERR, "no hostname: %m");
- return(1);
- }
- if (!(hp = gethostbyname(hostname))) {
- syslog(LOG_ERR, "no gethostbyname repsonse");
- (void) strncpy(myname, hostname, MAXHOSTNAMELEN);
- return(1);
- }
- (void) strncpy(myname, hp->h_name, MAXHOSTNAMELEN);
- (void) memcpy((caddr_t) &my_addr, (caddr_t) hp->h_addr,
- sizeof(hp->h_addr));
-
- (void) setservent(1); /* keep file/connection open */
-
- if (!(sp = getservbyname(SERVER_SVCNAME, "udp"))) {
- syslog(LOG_ERR, "%s/udp unknown",SERVER_SVCNAME);
- return(1);
- }
- (void) memset((caddr_t) &sock_sin, 0, sizeof(sock_sin));
- sock_sin.sin_port = sp->s_port;
-
- if (!(sp = getservbyname(HM_SVCNAME, "udp"))) {
- syslog(LOG_ERR, "%s/udp unknown", HM_SVCNAME);
- return(1);
- }
- hm_port = sp->s_port;
-
- (void) endservent();
-
- if ((srv_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "client_sock failed: %m");
- return(1);
- }
- if (bind(srv_socket, (struct sockaddr *) &sock_sin,
- sizeof(sock_sin)) < 0) {
- syslog(LOG_ERR, "client bind failed: %m");
- return(1);
- }
-
- /* set not-blocking */
-#ifdef POSIX
- flags = fcntl(srv_socket, F_GETFL);
- flags |= O_NONBLOCK;
- (void) fcntl(srv_socket, F_SETFL, flags);
-#else
- flags = 1;
- (void) ioctl(srv_socket, FIONBIO, (caddr_t) &flags);
-#endif
-
- return(0);
-}
-
-
-/*
- * print out a usage message.
- */
-
-static void
-usage()
-{
-#ifdef DEBUG
- fprintf(stderr,"Usage: %s [-d] [-s] [-n] [-f dumpfile]\n",programname);
-#else
- fprintf(stderr,"Usage: %s [-d] [-n] [-f dumpfile]\n",programname);
-#endif /* DEBUG */
- exit(2);
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-bye(int sig)
-#else
-bye(sig)
- int sig;
-#endif
-{
- server_shutdown(); /* tell other servers */
- hostm_shutdown(); /* tell our hosts */
-#ifdef KERBEROS
- (void) dest_tkt();
-#endif
- syslog(LOG_NOTICE, "goodbye (sig %d)",sig);
- exit(0);
- /*NOTREACHED*/
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-dbug_on(int sig)
-#else
-dbug_on(sig)
- int sig;
-#endif
-{
- syslog(LOG_DEBUG, "debugging turned on");
-#ifdef DEBUG_MALLOC
- dump_malloc_stats = 1;
-#endif
- zdebug = 1;
- SIG_RETURN;
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-dbug_off(int sig)
-#else
-dbug_off(sig)
- int sig;
-#endif
-{
- syslog(LOG_DEBUG, "debugging turned off");
-#ifdef DEBUG_MALLOC
- malloc_inuse(&m_size);
-#endif
- zdebug = 0;
- SIG_RETURN;
-}
-
-int fork_for_dump = 0;
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-sig_dump_strings (int sig)
-#else
-sig_dump_strings(sig)
- int sig;
-#endif
-{
- dump_strings_flag = 1;
- SIG_RETURN;
-}
-
-static void dump_strings()
-{
- FILE *fp;
- int oerrno = errno;
- fp = fopen ("/usr/tmp/zephyr.strings", "w");
- if (!fp) {
- syslog (LOG_ERR, "can't open strings dump file: %m");
- errno = oerrno;
- dump_strings_flag = 0;
- return;
- }
- syslog (LOG_INFO, "dumping strings to disk");
- print_zstring_table(fp);
- if (fclose (fp) == EOF)
- syslog (LOG_ERR, "error writing strings dump file");
- else
- syslog (LOG_INFO, "dump done");
- oerrno = errno;
- dump_strings_flag = 0;
- return;
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-sig_dump_db(int sig)
-#else
-sig_dump_db(sig)
- int sig;
-#endif
-{
- dump_db_flag = 1;
- SIG_RETURN;
-}
-
-static void dump_db()
-{
- /* dump the in-core database to human-readable form on disk */
- FILE *fp;
- int oerrno = errno;
- int pid;
-
-#ifdef __SABER__
- pid = -1;
-#else
- if (fork_for_dump) {
- MONCONTROL (0);
- pid = fork ();
- MONCONTROL (1);
- }
- else
- pid = -1;
-#endif
- if (pid > 0)
- {
- dump_db_flag = 0;
- return;
- }
- if ((fp = fopen("/usr/tmp/zephyr.db", "w")) == (FILE *)0) {
- syslog(LOG_ERR, "can't open dump database");
- errno = oerrno;
- dump_db_flag = 0;
- return;
- }
- syslog(LOG_INFO, "dumping to disk");
- server_dump_servers(fp);
- uloc_dump_locs(fp);
- hostm_dump_hosts(fp);
- syslog(LOG_INFO, "dump done");
- if (fclose(fp) == EOF) {
- syslog(LOG_ERR, "can't close dump db");
- }
- if (pid == 0)
- exit (0);
- errno = oerrno;
- dump_db_flag = 0;
- return;
-}
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-reset(int sig)
-#else
-reset(sig)
- int sig;
-#endif
-{
-#if 1
- zdbug((LOG_DEBUG,"reset()"));
-#endif
- doreset = 1;
- SIG_RETURN;
-}
-
-#ifdef __GNUG__
-#define wait WaitStatus
-#endif
-
-static SIGNAL_RETURN_TYPE
-#ifdef __STDC__
-reap(int sig)
-#else
-reap(sig)
- int sig;
-#endif
-{
- int oerrno = errno;
-
-#ifdef POSIX
- int waitb;
- while (waitpid(-1, &waitb, WNOHANG) == 0) ;
-#else
- union wait waitb;
- while (wait3 (&waitb, WNOHANG, (struct rusage*) 0) == 0) ;
-#endif
-
- errno = oerrno;
- SIG_RETURN;
-}
-
-static void
-do_reset()
-{
- int oerrno = errno;
-#ifdef POSIX
- sigset_t mask, omask;
-#else
- int omask;
-#endif
-#if 0
- zdbug((LOG_DEBUG,"do_reset()"));
-#endif
-#ifdef POSIX
- sigemptyset(&mask);
- sigaddset(&mask, SIGHUP);
- sigprocmask(SIG_BLOCK, &mask, &omask);
-#else
- omask = sigblock(sigmask(SIGHUP));
-#endif
-
- /* reset various things in the server's state */
- subscr_reset();
- server_reset();
- access_reinit();
- syslog (LOG_INFO, "restart completed");
- doreset = 0;
- errno = oerrno;
-#ifdef POSIX
- sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
-#else
- sigsetmask(omask);
-#endif
-}
-
-#ifndef DEBUG
-/*
- * detach from the terminal
- */
-
-static void
-detach()
-{
- /* detach from terminal and fork. */
- register int i;
- register long size;
-
-#ifdef POSIX
- size = sysconf(_SC_OPEN_MAX);
-#else
- size = getdtablesize();
-#endif
- /* profiling seems to get confused by fork() */
- MONCONTROL (0);
- i = fork ();
- MONCONTROL (1);
- if (i) {
- if (i < 0)
- perror("fork");
- exit(0);
- }
-
- for (i = 0; i < size; i++) {
- (void) close(i);
- }
- i = open("/dev/tty", O_RDWR, 666);
- (void) ioctl(i, TIOCNOTTY, (caddr_t) 0);
- (void) close(i);
-#ifdef POSIX
- (void) setsid();
-#endif
-}
-#endif
-
-static void
-read_from_dump(dumpfile)
- char *dumpfile;
-{
- return;
-}
diff --git a/server/realm.c b/server/realm.c
new file mode 100644
index 0000000..de2dc12
--- /dev/null
+++ b/server/realm.c
@@ -0,0 +1,1086 @@
+#include "zserver.h"
+#include <sys/socket.h>
+
+extern int __My_length;
+extern char *__My_addr;
+
+Unacked *rlm_nacklist = NULL; /* not acked list for realm-realm
+ packets */
+Realm *otherrealms; /* points to an array of the known
+ servers */
+int nrealms = 0; /* number of other realms */
+
+static void get_realm_addrs __P(());
+static void realm_sendit __P((ZNotice_t *notice, struct sockaddr_in *who, int auth, Realm *realm, int ack_to_sender));
+static void realm_sendit_auth __P((ZNotice_t *notice, struct sockaddr_in *who, int auth, Realm *realm, int ack_to_sender));
+static void rlm_ack __P((ZNotice_t *notice, Unacked *nacked));
+static void rlm_nack_cancel __P((ZNotice_t *notice, struct sockaddr_in *who));
+static void rlm_new_ticket __P(());
+static void rlm_rexmit __P((void *arg));
+static Code_t realm_ulocate_dispatch __P((ZNotice_t *notice,int auth,struct sockaddr_in *who,Server *server,Realm *realm));
+#ifdef ZEPHYR_USES_KERBEROS
+static Code_t ticket_retrieve __P((Realm *realm));
+#endif
+
+char *
+realm_expand_realm(realmname)
+char *realmname;
+{
+ static char expand[REALM_SZ];
+ static char krb_realm[REALM_SZ+1];
+ char *cp1, *cp2;
+ int retval;
+ FILE *rlm_file;
+ char list_file[128];
+ char linebuf[BUFSIZ];
+ char scratch[128];
+
+ /* upcase what we got */
+ cp2 = realmname;
+ cp1 = expand;
+ while (*cp2) {
+ *cp1++ = toupper(*cp2++);
+ }
+ *cp1 = '\0';
+
+ sprintf(list_file, "%s/%s", CONFDIR, REALM_LIST_FILE);
+
+ if ((rlm_file = fopen(list_file, "r")) == (FILE *) 0) {
+ return(expand);
+ }
+
+ if (fgets(linebuf, BUFSIZ, rlm_file) == NULL) {
+ /* error reading */
+ (void) fclose(rlm_file);
+ return(expand);
+ }
+
+ while (1) {
+ /* run through the file, looking for admin host */
+ if (fgets(linebuf, BUFSIZ, rlm_file) == NULL) {
+ (void) fclose(rlm_file);
+ return(expand);
+ }
+
+ if (sscanf(linebuf, "%s %s", krb_realm, scratch) < 2)
+ continue;
+ if (!strncmp(krb_realm, expand, strlen(expand))) {
+ (void) fclose(rlm_file);
+ return(krb_realm);
+ }
+ }
+#ifdef KERBEROS
+ if (!strncmp(my_realm, expand, strlen(expand)))
+ return(my_realm);
+#endif
+ return(expand);
+}
+
+Realmname *
+get_realm_lists(file)
+ char *file;
+{
+ Realmname *rlm_list, *rlm;
+ int ii, nused, ntotal;
+ FILE *fp;
+ char buf[REALM_SZ + MAXHOSTNAMELEN + 1]; /* one for newline */
+ char realm[REALM_SZ], server[MAXHOSTNAMELEN + 1];
+
+ nused = 0;
+ if (!(fp = fopen(file, "r")))
+ return((Realmname *)0);
+
+ /* start with 16, realloc if necessary */
+ ntotal = 16;
+ rlm_list = (Realmname *)malloc(ntotal * sizeof(Realmname));
+ if (!rlm_list) {
+ syslog(LOG_CRIT, "get_realm_lists malloc");
+ abort();
+ }
+
+ while (fgets(buf, REALM_SZ + MAXHOSTNAMELEN + 1, fp)) {
+ if (sscanf(buf, "%s %s", realm, server) != 2) {
+ syslog(LOG_CRIT, "bad format in %s", file);
+ abort();
+ }
+ for (ii = 0; ii < nused; ii++) {
+ /* look for this realm */
+ if (!strcmp(rlm_list[ii].name, realm))
+ break;
+ }
+ if (ii < nused) {
+ rlm = &rlm_list[ii];
+ if (rlm->nused +1 >= rlm->nservers) {
+ /* make more space */
+ rlm->servers = (char **)realloc((char *)rlm->servers,
+ (unsigned)rlm->nservers * 2 *
+ sizeof(char *));
+ if (!rlm->servers) {
+ syslog(LOG_CRIT, "get_realm_lists realloc");
+ abort();
+ }
+ rlm->nservers *= 2;
+ }
+ rlm->servers[rlm->nused++] = strsave(server);
+ } else {
+ /* new realm */
+ if (nused + 1 >= ntotal) {
+ /* make more space */
+ rlm_list = (Realmname *)realloc((char *)rlm_list,
+ (unsigned)ntotal * 2 *
+ sizeof(Realmname));
+ if (!rlm_list) {
+ syslog(LOG_CRIT, "get_realm_lists realloc");
+ abort();
+ }
+ ntotal *= 2;
+ }
+ rlm = &rlm_list[nused++];
+ strcpy(rlm->name, realm);
+ rlm->nused = 0;
+ rlm->nservers = 16;
+ rlm->servers = (char **)malloc(rlm->nservers * sizeof(char *));
+ if (!rlm->servers) {
+ syslog(LOG_CRIT, "get_realm_lists malloc");
+ abort();
+ }
+ rlm->servers[rlm->nused++] = strsave(server);
+ }
+ }
+ if (nused + 1 >= ntotal) {
+ rlm_list = (Realmname *)realloc((char *)rlm_list,
+ (unsigned)(ntotal + 1) *
+ sizeof(Realmname));
+ if (!rlm_list) {
+ syslog(LOG_CRIT, "get_realm_lists realloc");
+ abort();
+ }
+ }
+ *rlm_list[nused].name = '\0';
+
+ return(rlm_list);
+}
+
+Code_t
+realm_send_realms()
+{
+ int cnt, retval;
+ for (cnt = 0; cnt < nrealms; cnt++) {
+ if (retval = (subscr_send_realm_subs(&otherrealms[cnt])) != ZERR_NONE)
+ return(retval);
+ }
+}
+
+int
+bound_for_local_realm(notice)
+ ZNotice_t *notice;
+{
+ char *realm;
+
+ realm = strchr(notice->z_recipient, '@');
+
+ if (!realm || !strcmp(realm_expand_realm(realm + 1), ZGetRealm()))
+ return 1;
+
+ return 0;
+}
+
+int
+sender_in_realm(notice)
+ ZNotice_t *notice;
+{
+ char *realm;
+
+ realm = strchr(notice->z_sender, '@');
+
+ if (!realm || !strcmp(realm + 1, ZGetRealm()))
+ return 1;
+
+ return 0;
+}
+
+Realm *
+realm_which_realm(who)
+ struct sockaddr_in *who;
+{
+ Realm *realm;
+ struct sockaddr_in *addr;
+ int a, b;
+
+ /* loop through the realms */
+ for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
+ /* loop through the addresses for the realm */
+ for (addr = realm->addrs, b = 0; b < realm->count; b++, addr++)
+ if (addr->sin_addr.s_addr == who->sin_addr.s_addr)
+ return(realm);
+
+ return 0;
+}
+
+Realm *
+realm_get_realm_by_name(name)
+char *name;
+{
+ int a;
+ Realm *realm;
+
+ for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
+ if (!strcmp(realm->name, name))
+ return(realm);
+
+ return 0;
+}
+
+static void
+rlm_nack_cancel(notice, who)
+ register ZNotice_t *notice;
+ struct sockaddr_in *who;
+{
+ register Realm *which = realm_which_realm(who);
+ register Unacked *nacked, *next;
+ ZNotice_t acknotice;
+ ZPacket_t retval;
+
+#if 0
+ zdbug((LOG_DEBUG, "rlm_nack_cancel: %s:%08X,%08X",
+ inet_ntoa(notice->z_uid.zuid_addr),
+ notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
+#endif
+ if (!which) {
+ syslog(LOG_ERR, "non-realm ack?");
+ return;
+ }
+
+ for (nacked = rlm_nacklist; nacked; nacked = nacked->next) {
+ if (&otherrealms[nacked->dest.rlm.rlm_idx] == which) {
+ if (ZCompareUID(&nacked->uid, &notice->z_uid)) {
+ timer_reset(nacked->timer);
+
+ if (nacked->ack_addr.sin_addr.s_addr)
+ rlm_ack(notice, nacked);
+
+ /* free the data */
+ free(nacked->packet);
+ LIST_DELETE(nacked);
+ free(nacked);
+ return;
+ }
+ }
+ }
+#if 0
+ zdbug((LOG_DEBUG,"nack_cancel: nack not found %s:%08X,%08X",
+ inet_ntoa (notice->z_uid.zuid_addr),
+ notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
+#endif
+ return;
+}
+
+static void
+rlm_ack(notice, nacked)
+ ZNotice_t *notice;
+ Unacked *nacked;
+{
+ ZNotice_t acknotice;
+ ZPacket_t ackpack;
+ int packlen;
+ Code_t retval;
+
+ /* tell the original sender the result */
+ acknotice = *notice;
+ acknotice.z_message_len = strlen(acknotice.z_message) + 1;
+
+ packlen = sizeof(ackpack);
+
+ if ((retval = ZFormatSmallRawNotice(&acknotice, ackpack, &packlen)) != ZERR_NONE) {
+ syslog(LOG_ERR, "rlm_ack format: %s",
+ error_message(retval));
+ return;
+ }
+ zdbug((LOG_DEBUG, "rlm_ack sending to %s/%d",
+ inet_ntoa(nacked->ack_addr.sin_addr),
+ ntohs(nacked->ack_addr.sin_port)));
+ if ((retval = ZSetDestAddr(&nacked->ack_addr)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_ack set addr: %s",
+ error_message(retval));
+ return;
+ }
+ if ((retval = ZSendPacket(ackpack, packlen, 0)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_ack xmit: %s", error_message(retval));
+ return;
+ }
+}
+
+
+Code_t
+realm_dispatch(notice, auth, who, server)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
+{
+ Realm *realm;
+ struct sockaddr_in newwho;
+ Code_t status = ZERR_NONE;
+ char rlm_recipient[REALM_SZ + 1];
+ int external = 0;
+ String *notice_class;
+
+ if (notice->z_kind == SERVACK || notice->z_kind == SERVNAK) {
+ rlm_nack_cancel(notice, who);
+ return(ZERR_NONE);
+ }
+ /* set up a who for the real origin */
+ memset((caddr_t) &newwho, 0, sizeof(newwho));
+ newwho.sin_family = AF_INET;
+ newwho.sin_addr.s_addr = notice->z_sender_addr.s_addr;
+ newwho.sin_port = hm_port;
+
+ /* check if it's a control message */
+ realm = realm_which_realm(who);
+
+ notice_class = make_string(notice->z_class,1);
+
+ if (class_is_admin(notice_class)) {
+ syslog(LOG_WARNING, "%s sending admin opcode %s",
+ realm->name, notice->z_opcode);
+ } else if (class_is_hm(notice_class)) {
+ syslog(LOG_WARNING, "%s sending hm opcode %s",
+ realm->name, notice->z_opcode);
+ } else if (class_is_control(notice_class)) {
+ status = realm_control_dispatch(notice, auth, who,
+ server, realm);
+ } else if (class_is_ulogin(notice_class)) {
+ /* don't need to forward this */
+ if (server == me_server) {
+ sprintf(rlm_recipient, "@%s", realm->name);
+ notice->z_recipient = rlm_recipient;
+
+ sendit(notice, 1, who, 0);
+ }
+ } else if (class_is_ulocate(notice_class)) {
+ status = realm_ulocate_dispatch(notice, auth, who, server, realm);
+ } else {
+ /* redo the recipient */
+ if (*notice->z_recipient == '\0') {
+ sprintf(rlm_recipient, "@%s", realm->name);
+ notice->z_recipient = rlm_recipient;
+ /* only send to our realm */
+ external = 0;
+ } else if (bound_for_local_realm(notice) && *notice->z_recipient
+ == '@')
+ {
+ /* we're responsible for getting this message out */
+ external = 1;
+ notice->z_recipient = "";
+ }
+
+ /* otherwise, send to local subscribers */
+ sendit(notice, auth, who, external);
+ }
+
+ return(status);
+}
+
+void
+realm_init()
+{
+ Client *client;
+ Realmname *rlmnames;
+ Realm *rlm;
+ int ii, jj, found;
+ struct in_addr *addresses;
+ struct hostent *hp;
+ char list_file[128];
+ char rlmprinc[ANAME_SZ+INST_SZ+REALM_SZ+3];
+
+ sprintf(list_file, "%s/%s", CONFDIR, REALM_LIST_FILE);
+ rlmnames = get_realm_lists(list_file);
+ if (!rlmnames) {
+ zdbug((LOG_DEBUG, "No other realms"));
+ nrealms = 0;
+ return;
+ }
+
+ for (nrealms = 0; *rlmnames[nrealms].name; nrealms++);
+
+ otherrealms = (Realm *)malloc(nrealms * sizeof(Realm));
+ if (!otherrealms) {
+ syslog(LOG_CRIT, "malloc failed in get_realm_addrs");
+ abort();
+ }
+
+ for (ii = 0; ii < nrealms; ii++) {
+ rlm = &otherrealms[ii];
+ strcpy(rlm->name, rlmnames[ii].name);
+
+ addresses = (struct in_addr *)malloc(rlmnames[ii].nused * sizeof(struct in_addr));
+ if (!addresses) {
+ syslog(LOG_CRIT, "malloc failed in get_realm_addrs");
+ abort();
+ }
+ /* convert names to addresses */
+ found = 0;
+ for (jj = 0; jj < rlmnames[ii].nused; jj++) {
+ hp = gethostbyname(rlmnames[ii].servers[jj]);
+ if (hp) {
+ memmove((caddr_t) &addresses[found], (caddr_t)hp->h_addr, sizeof(struct in_addr));
+ found++;
+ } else
+ syslog(LOG_WARNING, "hostname failed, %s", rlmnames[ii].servers[jj]);
+ /* free the hostname */
+ free(rlmnames[ii].servers[jj]);
+ }
+ rlm->count = found;
+ rlm->addrs = (struct sockaddr_in *)malloc(found * sizeof (struct sockaddr_in));
+ if (!rlm->addrs) {
+ syslog(LOG_CRIT, "malloc failed in get_realm_addrs");
+ abort();
+ }
+ for (jj = 0; jj < rlm->count; jj++) {
+ rlm->addrs[jj].sin_family = AF_INET;
+ /* use the server port */
+ rlm->addrs[jj].sin_port = srv_addr.sin_port;
+ rlm->addrs[jj].sin_addr = addresses[jj];
+ }
+ client = (Client *) malloc(sizeof(Client));
+ if (!client) {
+ syslog(LOG_CRIT, "malloc failed in get_realm_addrs");
+ abort();
+ }
+ memset(&client->addr, 0, sizeof(struct sockaddr_in));
+#ifdef ZEPHYR_USES_KERBEROS
+ memset(&client->session_key, 0, sizeof(client->session_key));
+#endif
+ sprintf(rlmprinc, "%s.%s@%s", SERVER_SERVICE, SERVER_INSTANCE, rlm->name);
+ client->principal = make_string(rlmprinc, 0);
+ client->last_msg = 0;
+ client->last_check = 0;
+ client->last_send = 0;
+ client->subs = NULL;
+ client->realm = rlm;
+ client->addr.sin_family = 0;
+ client->addr.sin_port = 0;
+ client->addr.sin_addr.s_addr = 0;
+
+ rlm->client = client;
+ rlm->idx = random() % rlm->count;
+ rlm->subs = NULL;
+ rlm->tkt_try = 0;
+ free(rlmnames[ii].servers);
+ free(addresses);
+ }
+ free(rlmnames);
+}
+
+static Code_t
+realm_ulocate_dispatch(notice, auth, who, server, realm)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
+ Realm *realm;
+{
+ register char *opcode = notice->z_opcode;
+ Code_t status;
+
+ if (!auth) {
+ syslog(LOG_WARNING, "unauth locate msg from %s",
+ inet_ntoa(who->sin_addr));
+ clt_ack(notice, who, AUTH_FAILED);
+ return(ZERR_NONE);
+ }
+
+ if (!strcmp(opcode, REALM_REQ_LOCATE)) {
+ ack(notice, who);
+ ulogin_realm_locate(notice, who, realm);
+ } else if (!strcmp(opcode, REALM_ANS_LOCATE)) {
+ ack(notice, who);
+ ulogin_relay_locate(notice, who);
+ } else {
+ syslog(LOG_WARNING, "%s unknown/illegal loc opcode %s",
+ realm->name, opcode);
+ nack(notice, who);
+ }
+
+ return(ZERR_NONE);
+}
+
+
+Code_t
+realm_control_dispatch(notice, auth, who, server, realm)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
+ Realm *realm;
+{
+ register char *opcode = notice->z_opcode;
+ Code_t status;
+
+ if (!auth) {
+ syslog(LOG_WARNING, "unauth ctl msg from %s",
+ inet_ntoa(who->sin_addr));
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return(ZERR_NONE);
+ }
+
+ if (strcmp(notice->z_class_inst, ZEPHYR_CTL_REALM)) {
+ syslog(LOG_WARNING, "Invalid rlm_dispatch instance %s",
+ notice->z_class_inst);
+ return(ZERR_NONE);
+ }
+
+ if (!strcmp(opcode, REALM_REQ_SUBSCRIBE) || !strcmp(opcode, REALM_ADD_SUBSCRIBE)) {
+ /* try to add subscriptions */
+ /* attempts to get defaults are ignored */
+ if ((status = subscr_foreign_user(notice, who, realm)) != ZERR_NONE) {
+ clt_ack(notice, who, AUTH_FAILED);
+ } else if (server == me_server) {
+ server_forward(notice, auth, who);
+ ack(notice, who);
+ }
+ } else if (!strcmp(opcode, REALM_UNSUBSCRIBE)) {
+ /* try to remove subscriptions */
+ if ((status = subscr_realm_cancel(who, notice, realm)) != ZERR_NONE) {
+ clt_ack(notice, who, NOT_FOUND);
+ } else if (server == me_server) {
+ server_forward(notice, auth, who);
+ ack(notice, who);
+ }
+ } else {
+ syslog(LOG_WARNING, "%s unknown/illegal ctl opcode %s",
+ realm->name, opcode);
+ if (server == me_server)
+ nack(notice, who);
+ return(ZERR_NONE);
+ }
+ return(ZERR_NONE);
+}
+
+void
+realm_handoff(notice, auth, who, realm, ack_to_sender)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Realm *realm;
+ int ack_to_sender;
+{
+#ifdef ZEPHYR_USES_KERBEROS
+ Code_t retval;
+
+ if (!auth) {
+ zdbug((LOG_DEBUG, "realm_sendit unauthentic to realm %s", realm->name))
+ realm_sendit(notice, who, auth, realm, ack_to_sender);
+ }
+
+ if (!ticket_lookup(realm->name))
+ if ((retval = ticket_retrieve(realm)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_handoff failed: %s", error_message(retval));
+ return;
+ }
+
+ zdbug((LOG_DEBUG, "realm_sendit to realm %s auth %d", realm->name, auth));
+ /* valid ticket available now, send the message */
+ realm_sendit_auth(notice, who, auth, realm, ack_to_sender);
+#else /* ZEPHYR_USES_KERBEROS */
+ realm_sendit(notice, who, auth, realm, ack_to_sender);
+#endif /* ZEPHYR_USES_KERBEROS */
+}
+
+static void
+realm_sendit(notice, who, auth, realm, ack_to_sender)
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ int auth;
+ Realm *realm;
+ int ack_to_sender;
+{
+ caddr_t pack;
+ int packlen;
+ Code_t retval;
+ Unacked *nacked;
+
+ notice->z_auth = auth;
+
+ /* format the notice */
+ if ((retval = ZFormatRawNotice(notice, &pack, &packlen)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit format: %s",
+ error_message(retval));
+ return;
+ }
+
+ /* now send */
+ if ((retval = ZSetDestAddr(&realm->addrs[realm->idx])) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit set addr: %s",
+ error_message(retval));
+ free(pack);
+ return;
+ }
+ if ((retval = ZSendPacket(pack, packlen, 0)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit xmit: %s", error_message(retval));
+ free(pack);
+ return;
+ }
+
+ /* now we've sent it, mark it as not ack'ed */
+
+ if (!(nacked = (Unacked *)malloc(sizeof(Unacked)))) {
+ /* no space: just punt */
+ syslog(LOG_ERR, "rlm_sendit nack malloc");
+ free(pack);
+ return;
+ }
+
+ nacked->rexmits = 0;
+ nacked->packet = pack;
+ nacked->dest.rlm.rlm_idx = realm - otherrealms;
+ nacked->dest.rlm.rlm_srv_idx = realm->idx;
+ nacked->packsz = packlen;
+ nacked->uid = notice->z_uid;
+ if (ack_to_sender)
+ nacked->ack_addr = *who;
+ else
+ nacked->ack_addr.sin_addr.s_addr = 0;
+
+ /* set a timer to retransmit */
+ nacked->timer = timer_set_rel(rexmit_times[0], rlm_rexmit, nacked);
+ /* chain in */
+ LIST_INSERT(&rlm_nacklist, nacked);
+ return;
+}
+
+static void
+packet_ctl_nack(nackpacket)
+ Unacked *nackpacket;
+{
+ ZNotice_t notice;
+
+ /* extract the notice */
+ ZParseNotice(nackpacket->packet, nackpacket->packsz, &notice);
+ nack(&notice, &nackpacket->ack_addr);
+}
+
+static void
+rlm_rexmit(arg)
+ void *arg;
+{
+ Unacked *nackpacket = (Unacked *) arg;
+ Code_t retval;
+ register Realm *realm;
+ int new_srv_idx;
+
+ zdbug((LOG_DEBUG,"rlm_rexmit"));
+
+ realm = &otherrealms[nackpacket->dest.rlm.rlm_idx];
+
+ zdbug((LOG_DEBUG, "rlm_rexmit: sending to %s", realm->name));
+
+ if (rexmit_times[(nackpacket->rexmits + 1)/(realm->count)] == -1) {
+ /* give a server ack that the packet is lost/realm dead */
+ packet_ctl_nack(nackpacket);
+ LIST_DELETE(nackpacket);
+ free(nackpacket->packet);
+ free(nackpacket);
+
+ zdbug((LOG_DEBUG, "rlm_rexmit: %s appears dead", realm->name));
+ return;
+ }
+
+ /* retransmit the packet, trying each server in the realm multiple times */
+#if 0
+ new_srv_idx = ((nackpacket->rexmits / NUM_REXMIT_TIMES)
+ + nackpacket->rlm.rlm_srv_idx) % realm->count;
+#else
+ new_srv_idx = nackpacket->rexmits % realm->count;
+#endif
+ if (new_srv_idx != realm->idx)
+ realm->idx = new_srv_idx;
+
+ retval = ZSetDestAddr(&realm->addrs[realm->idx]);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_rexmit set addr: %s", error_message(retval));
+ } else {
+ retval = ZSendPacket(nackpacket->packet, nackpacket->packsz, 0);
+ if (retval != ZERR_NONE)
+ syslog(LOG_WARNING, "rlm_rexmit xmit: %s", error_message(retval));
+ }
+ /* reset the timer */
+ if (rexmit_times[(nackpacket->rexmits + 1)/(realm->count)] != -1)
+ nackpacket->rexmits++;
+
+ nackpacket->timer = timer_set_rel(rexmit_times[(nackpacket->rexmits)/(realm->count)], rlm_rexmit, nackpacket);
+ return;
+}
+
+void
+realm_dump_realms(fp)
+ FILE *fp;
+{
+ register int ii, jj;
+
+ for (ii = 0; ii < nrealms; ii++) {
+ (void) fprintf(fp, "%d:%s\n", ii, otherrealms[ii].name);
+ for (jj = 0; jj < otherrealms[ii].count; jj++) {
+ (void) fprintf(fp, "\t%s\n",
+ inet_ntoa(otherrealms[ii].addrs[jj].sin_addr));
+ }
+ /* dump the subs */
+ subscr_dump_subs(fp, otherrealms[ii].subs);
+ }
+}
+
+
+#ifdef ZEPHYR_USES_KERBEROS
+static void
+realm_sendit_auth(notice, who, auth, realm, ack_to_sender)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Realm *realm;
+ int ack_to_sender;
+{
+ char *buffer, *ptr;
+ caddr_t pack;
+ int buffer_len, hdrlen, offset, fragsize, ret_len, message_len;
+ int origoffset, origlen;
+ Code_t retval;
+ Unacked *nacked;
+ char buf[1024], multi[64];
+ CREDENTIALS cred;
+ KTEXT_ST authent;
+ ZNotice_t partnotice, newnotice;
+
+ offset = 0;
+
+ /* first, build an authent */
+ retval = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, realm, &cred);
+ if (retval != GC_OK) {
+ syslog(LOG_WARNING, "rlm_sendit_auth get_cred: %s",
+ error_message(retval+krb_err_base));
+ return;
+ }
+
+ retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE, realm, 1);
+ if (retval != MK_AP_OK) {
+ syslog(LOG_WARNING, "rlm_sendit_auth mk_req: %s",
+ error_message(retval+krb_err_base));
+ return;
+ }
+
+ retval = ZMakeAscii(buf, sizeof(buf), authent.dat, authent.length);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth mk_ascii: %s",
+ error_message(retval));
+ return;
+ }
+
+ /* set the dest addr */
+ retval = ZSetDestAddr(&realm->addrs[realm->idx]);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth set addr: %s", error_message(retval));
+ return;
+ }
+
+ /* now format the notice, refragmenting if needed */
+ newnotice = *notice;
+ newnotice.z_auth = 1;
+ newnotice.z_ascii_authent = buf;
+ newnotice.z_authent_len = authent.length;
+
+ buffer = (char *) malloc(sizeof(ZPacket_t));
+ if (!buffer) {
+ syslog(LOG_ERR, "realm_sendit_auth malloc");
+ return; /* DON'T put on nack list */
+ }
+
+ buffer_len = sizeof(ZPacket_t);
+
+ retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen, &ptr,
+ NULL);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
+ free(buffer);
+ return;
+ }
+
+#ifdef NOENCRYPTION
+ newnotice.z_checksum = 0;
+#else
+ newnotice.z_checksum =
+ (ZChecksum_t)des_quad_cksum(buffer, NULL, ptr - buffer, 0, cred.session);
+#endif
+
+ retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen,
+ NULL, NULL);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
+ free(buffer);
+ return;
+ }
+
+ /* This is not terribly pretty, but it does do its job.
+ * If a packet we get that needs to get sent off to another realm is
+ * too big after we slap on our authent, we refragment it further,
+ * a la Z_SendFragmentedNotice. This obliviates the need for what
+ * used to be done in ZFormatAuthenticRealmNotice, as we do it here.
+ * At some point it should be pulled back out into its own function,
+ * but only the server uses it.
+ */
+
+ if ((newnotice.z_message_len+hdrlen > buffer_len) ||
+ (newnotice.z_message_len+hdrlen > Z_MAXPKTLEN)){
+ /* Deallocate buffer, use a local one */
+ free(buffer);
+
+ partnotice = *notice;
+
+ partnotice.z_auth = 1;
+ partnotice.z_ascii_authent = buf;
+ partnotice.z_authent_len = authent.length;
+
+ origoffset = 0;
+ origlen = notice->z_message_len;
+
+ if (notice->z_multinotice && strcmp(notice->z_multinotice, ""))
+ if (sscanf(notice->z_multinotice, "%d/%d", &origoffset, &origlen) != 2) {
+ syslog(LOG_WARNING, "rlm_sendit_auth frag: parse failed");
+ return;
+ }
+
+#if 0
+ zdbug((LOG_DEBUG,"rlm_send_auth: orig: %d-%d/%d", origoffset, notice->z_message_len, origlen));
+#endif
+
+ fragsize = Z_MAXPKTLEN-hdrlen-Z_FRAGFUDGE;
+
+ while (offset < notice->z_message_len || !notice->z_message_len) {
+ (void) sprintf(multi, "%d/%d", offset+origoffset, origlen);
+ partnotice.z_multinotice = multi;
+ if (offset > 0) {
+ (void) gettimeofday(&partnotice.z_uid.tv, (struct timezone *)0);
+ partnotice.z_uid.tv.tv_sec = htonl((u_long)
+ partnotice.z_uid.tv.tv_sec);
+ partnotice.z_uid.tv.tv_usec = htonl((u_long)
+ partnotice.z_uid.tv.tv_usec);
+ if ((retval = Z_GetMyAddr()) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth addr: %s", error_message(retval));
+ return;
+ }
+ (void) memcpy((char *)&partnotice.z_uid.zuid_addr, __My_addr,
+ __My_length);
+ }
+ message_len = min(notice->z_message_len-offset, fragsize);
+ partnotice.z_message = notice->z_message+offset;
+ partnotice.z_message_len = message_len;
+
+#if 0
+ zdbug((LOG_DEBUG,"rlm_send_auth: new: %d-%d/%d", origoffset+offset, message_len, origlen));
+#endif
+
+ buffer = (char *) malloc(sizeof(ZPacket_t));
+ if (!buffer) {
+ syslog(LOG_ERR, "realm_sendit_auth malloc");
+ return; /* DON'T put on nack list */
+ }
+
+ retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len, &hdrlen,
+ &ptr, NULL);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
+ free(buffer);
+ return;
+ }
+
+#ifdef NOENCRYPTION
+ partnotice.z_checksum = 0;
+#else
+ partnotice.z_checksum =
+ (ZChecksum_t)des_quad_cksum(buffer, NULL, ptr - buffer, 0,
+ cred.session);
+#endif
+
+ retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len, &hdrlen,
+ NULL, NULL);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
+ free(buffer);
+ return;
+ }
+
+ ptr = buffer+hdrlen;
+
+ (void) memcpy(ptr, partnotice.z_message, partnotice.z_message_len);
+
+ buffer_len = hdrlen+partnotice.z_message_len;
+
+ /* now send */
+ if ((retval = ZSendPacket(buffer, buffer_len, 0)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth xmit: %s", error_message(retval));
+ free(buffer);
+ return;
+ }
+
+ offset += fragsize;
+
+ if (!(nacked = (Unacked *)malloc(sizeof(Unacked)))) {
+ /* no space: just punt */
+ syslog(LOG_ERR, "rlm_sendit_auth nack malloc");
+ free(buffer);
+ return;
+ }
+
+ nacked->rexmits = 0;
+ nacked->packet = buffer;
+ nacked->dest.rlm.rlm_idx = realm - otherrealms;
+ nacked->dest.rlm.rlm_srv_idx = realm->idx;
+ nacked->packsz = buffer_len;
+ nacked->uid = partnotice.z_uid;
+
+ /* Do the ack for the last frag, below */
+ if (ack_to_sender)
+ nacked->ack_addr = *who;
+ else
+ nacked->ack_addr.sin_addr.s_addr = 0;
+
+ /* set a timer to retransmit */
+ nacked->timer = timer_set_rel(rexmit_times[0], rlm_rexmit, nacked);
+
+ /* chain in */
+ LIST_INSERT(&rlm_nacklist, nacked);
+
+ if (!notice->z_message_len)
+ break;
+ }
+#if 0
+ zdbug((LOG_DEBUG, "rlm_sendit_auth frag message sent"));
+#endif
+ } else {
+ /* This is easy, no further fragmentation needed */
+ ptr = buffer+hdrlen;
+
+ (void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len);
+
+ buffer_len = hdrlen+newnotice.z_message_len;
+
+ /* now send */
+ if ((retval = ZSendPacket(buffer, buffer_len, 0)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "rlm_sendit_auth xmit: %s", error_message(retval));
+ free(buffer);
+ return;
+ }
+
+#if 0
+ zdbug((LOG_DEBUG, "rlm_sendit_auth message sent"));
+#endif
+ /* now we've sent it, mark it as not ack'ed */
+
+ if (!(nacked = (Unacked *)malloc(sizeof(Unacked)))) {
+ /* no space: just punt */
+ syslog(LOG_ERR, "rlm_sendit_auth nack malloc");
+ free(buffer);
+ return;
+ }
+
+ nacked->rexmits = 0;
+ nacked->packet = buffer;
+ nacked->dest.rlm.rlm_idx = realm - otherrealms;
+ nacked->dest.rlm.rlm_srv_idx = realm->idx;
+ nacked->packsz = buffer_len;
+ nacked->uid = notice->z_uid;
+
+ /* Do the ack for the last frag, below */
+ if (ack_to_sender)
+ nacked->ack_addr = *who;
+ else
+ nacked->ack_addr.sin_addr.s_addr = 0;
+
+ /* set a timer to retransmit */
+ nacked->timer = timer_set_rel(rexmit_times[0], rlm_rexmit, nacked);
+ /* chain in */
+ LIST_INSERT(&rlm_nacklist, nacked);
+ }
+#if 0
+ if (ack_to_sender)
+ nacked->ack_addr = *who;
+#endif
+ return;
+}
+
+int
+ticket_expired(cred)
+CREDENTIALS *cred;
+{
+ /* extra 15 minutes for safety margin */
+#ifdef AFS_LIFETIMES
+ return (krb_life_to_time(cred->issue_date, cred->lifetime) < NOW + 15*60);
+#else /* AFS_LIFETIMES */
+ return (cred->issue_date + cred->lifetime*5*60 < NOW + 15*60);
+#endif /* AFS_LIFETIMES */
+}
+
+int
+ticket_lookup(realm)
+char *realm;
+{
+ CREDENTIALS cred;
+ KTEXT_ST authent;
+ int retval;
+
+ retval = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, realm, &cred);
+ if (retval == GC_OK && !ticket_expired(&cred))
+ /* good ticket */
+ return(1);
+
+ if (!strcmp(realm, ZGetRealm())) {
+ get_tgt();
+
+ /* For Putrify */
+ memset(&authent.dat,0,MAX_KTXT_LEN);
+ authent.mbz=0;
+
+ /* this is local, so try to contact the Kerberos server */
+ retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
+ realm, 0);
+ if (retval != KSUCCESS) {
+ syslog(LOG_ERR, "tkt_lookup: local: %s",
+ krb_err_txt[retval]);
+ return(0);
+ } else {
+ return(1);
+ }
+ }
+
+ return (0);
+}
+
+static Code_t
+ticket_retrieve(realm)
+ Realm *realm;
+{
+ int pid, retval;
+ KTEXT_ST authent;
+
+ get_tgt();
+
+ /* For Putrify */
+ memset(&authent.dat,0,MAX_KTXT_LEN);
+ authent.mbz=0;
+
+ /* Don't lose by trying too often. */
+ if (NOW - realm->tkt_try > 5 * 60) {
+ retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
+ realm->name, 0);
+ realm->tkt_try = NOW;
+ if (retval != KSUCCESS) {
+ syslog(LOG_WARNING, "tkt_rtrv: %s: %s", realm,
+ krb_err_txt[retval]);
+ return (retval+krb_err_base);
+ }
+ return (0);
+ } else {
+ return (1);
+ }
+}
+#endif /* ZEPHYR_USES_KERBEROS */
+
diff --git a/server/server.c b/server/server.c
index cb9b121..70a06b9 100644
--- a/server/server.c
+++ b/server/server.c
@@ -12,18 +12,19 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
+#include <sys/socket.h>
#ifndef lint
#ifndef SABER
-static char rcsid_server_c[] = "$Id$";
+static const char rcsid_server_c[] = "$Id$";
#endif
#endif
-#include "zserver.h"
-#include <sys/socket.h> /* for AF_INET */
-#include <netdb.h> /* for gethostbyname */
-#include <sys/param.h> /* for BSD */
-
+#define SRV_NACKTAB_HASHSIZE 1023
+#define SRV_NACKTAB_HASHVAL(which, uid) (((which) ^ (uid).zuid_addr.s_addr ^ \
+ (uid).tv.tv_sec ^ (uid).tv.tv_usec) \
+ % SRV_NACKTAB_HASHSIZE)
/*
* Server manager. Deal with traffic to and from other servers.
*
@@ -32,7 +33,7 @@ static char rcsid_server_c[] = "$Id$";
* void server_shutdown()
*
* void server_timo(which)
- * ZServerDesc_t *which;
+ * Server *which;
*
* void server_dispatch(notice, auth, who)
* ZNotice_t *notice;
@@ -40,24 +41,24 @@ static char rcsid_server_c[] = "$Id$";
* struct sockaddr_in *who;
*
* void server_recover(client)
- * ZClient_t *client;
+ * Client *client;
*
* void server_adispatch(notice, auth, who, server)
* ZNotice_t *notice;
* int auth;
* struct sockaddr_in *who;
- * ZServerDesc_t *server;
+ * Server *server;
*
* void server_forward(notice, auth, who)
* ZNotice_t *notice;
* int auth;
* struct sockaddr_in *who;
*
- * ZServerDesc_t *server_which_server(who)
+ * Server *server_which_server(who)
* struct sockaddr_in *who;
*
* void server_kill_clt(client);
- * ZClient_t *client;
+ * Client *client;
*
* void server_dump_servers(fp);
* FILE *fp;
@@ -65,68 +66,51 @@ static char rcsid_server_c[] = "$Id$";
* void server_reset();
*/
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static void
- server_flush P((ZServerDesc_t *)),
- hello_respond P((struct sockaddr_in *, int, int)),
- srv_responded P((struct sockaddr_in *)),
- send_msg P((struct sockaddr_in *, char *, int)),
- send_msg_list P((struct sockaddr_in *, char *, char **, int, int, int)),
- srv_nack_cancel P((ZNotice_t *, struct sockaddr_in *)),
- srv_nack_release P((ZServerDesc_t *)),
- srv_nack_renumber P((int *)),
- server_lost P((ZServerDesc_t *)),
- send_stats P((struct sockaddr_in *)),
- server_queue P((ZServerDesc_t *, int, caddr_t, int, struct sockaddr_in *));
-#define STATIC /* should be static, but is friend elsewhere */
-STATIC void
- server_hello P((ZServerDesc_t *, int)),
- setup_server P((ZServerDesc_t *, struct in_addr *)),
- srv_rexmit P((void *)),
- server_forw_reliable P((ZServerDesc_t *, caddr_t, int, ZNotice_t *));
-static Code_t
- admin_dispatch P((ZNotice_t *, int, struct sockaddr_in *,
- ZServerDesc_t *)),
- recover_clt P((ZNotice_t *, ZServerDesc_t *)),
- kill_clt P((ZNotice_t *, ZServerDesc_t *)),
- extract_addr P((ZNotice_t *, struct sockaddr_in *));
-
+static void server_flush __P((Server *));
+static void hello_respond __P((struct sockaddr_in *, int, int));
+static void srv_responded __P((struct sockaddr_in *));
+static void send_msg __P((struct sockaddr_in *, char *, int));
+static void send_msg_list __P((struct sockaddr_in *, char *, char **, int,
+ int));
+static void srv_nack_cancel __P((ZNotice_t *, struct sockaddr_in *));
+static void srv_nack_release __P((Server *));
+static void srv_nack_renumber __P((int *));
+static void send_stats __P((struct sockaddr_in *));
+static void server_queue __P((Server *, int, void *, int,
+ struct sockaddr_in *));
+static void server_hello __P((Server *, int));
+static void setup_server __P((Server *, struct in_addr *));
+static void srv_rexmit __P((void *));
+static void server_forw_reliable __P((Server *, caddr_t, int, ZNotice_t *));
+static Code_t admin_dispatch __P((ZNotice_t *, int, struct sockaddr_in *,
+ Server *));
+static Code_t kill_clt __P((ZNotice_t *, Server *));
+static Code_t extract_addr __P((ZNotice_t *, struct sockaddr_in *));
#ifdef notdef
static Code_t server_register();
#endif
-static struct in_addr *get_server_addrs P((int *number));
-#ifndef HESIOD
-static char **get_server_list P((char *file));
-static void free_server_list P((char **list));
+static struct in_addr *get_server_addrs __P((int *number));
+#ifndef ZEPHYR_USES_HESIOD
+static char **get_server_list __P((char *file));
+static void free_server_list __P((char **list));
#endif
-#undef P
+static Unacked *srv_nacktab[SRV_NACKTAB_HASHSIZE];
+Server *otherservers; /* points to an array of the known
+ servers */
+int nservers; /* number of other servers */
+int me_server_idx; /* # of my entry in the array */
-
-ZNotAcked_t *srv_nacklist; /* not acked list for server-server
- packets */
-ZServerDesc_t *otherservers; /* points to an array of the known
- servers */
-int nservers; /* number of other servers */
-int me_server_idx; /* # of my entry in the array */
-
-#define ADJUST (1) /* adjust timeout on hello input */
-#define DONT_ADJUST (0) /* don't adjust timeout */
+#define ADJUST (1) /* adjust timeout on hello input */
+#define DONT_ADJUST (0) /* don't adjust timeout */
/* parameters controlling the transitions of the FSM's--patchable with adb */
long timo_up = TIMO_UP;
long timo_tardy = TIMO_TARDY;
long timo_dead = TIMO_DEAD;
-long srv_rexmit_secs = REXMIT_SECS;
-
/* counters to measure old protocol use */
#ifdef OLD_COMPAT
int old_compat_count_uloc = 0;
@@ -152,93 +136,85 @@ int zalone;
void
server_init()
{
- register int i;
- struct in_addr *serv_addr, *server_addrs, limbo_addr;
+ int i;
+ struct in_addr *serv_addr, *server_addrs, limbo_addr;
- /* we don't need to mask SIGFPE here since when we are called,
- the signal handler isn't set up yet. */
+ /* we don't need to mask SIGFPE here since when we are called,
+ the signal handler isn't set up yet. */
- /* talk to hesiod here, set nservers */
- if (!(server_addrs = get_server_addrs(&nservers))) {
- syslog(LOG_ERR, "No servers?!?");
- exit(1);
- }
+ /* talk to hesiod here, set nservers */
+ server_addrs = get_server_addrs(&nservers);
+ if (!server_addrs) {
+ syslog(LOG_ERR, "No servers?!?");
+ exit(1);
+ }
#ifdef DEBUG
- if (zalone)
- nservers = 1;
- else
+ if (zalone)
+ nservers = 1;
+ else
#endif /* DEBUG */
- /* increment servers to make room for 'limbo' */
- nservers++;
-
- otherservers = (ZServerDesc_t *) xmalloc(nservers *
- sizeof(ZServerDesc_t));
- me_server_idx = -1;
-
- /* set up limbo */
- limbo_addr.s_addr = (unsigned long) 0;
- setup_server(otherservers, &limbo_addr);
- timer_reset(otherservers[0].zs_timer);
- otherservers[0].zs_timer = (timer) NULL;
- otherservers[0].zs_update_queue = NULLZSPT;
- otherservers[0].zs_dumping = 0;
-
- for (serv_addr = server_addrs, i = 1; i < nservers; serv_addr++, i++) {
- setup_server(&otherservers[i], serv_addr);
- /* is this me? */
- if (serv_addr->s_addr == my_addr.s_addr) {
- me_server_idx = i;
- otherservers[i].zs_state = SERV_UP;
- timer_reset(otherservers[i].zs_timer);
- otherservers[i].zs_timer = (timer) NULL;
- otherservers[i].zs_update_queue = NULLZSPT;
- otherservers[i].zs_dumping = 0;
+ /* increment servers to make room for 'limbo' */
+ nservers++;
+
+ otherservers = (Server *) malloc(nservers * sizeof(Server));
+ me_server_idx = -1;
+
+ /* set up limbo */
+ limbo_addr.s_addr = 0;
+ setup_server(otherservers, &limbo_addr);
+ timer_reset(otherservers[0].timer);
+ otherservers[0].timer = NULL;
+ otherservers[0].queue = NULL;
+ otherservers[0].dumping = 0;
+
+ for (serv_addr = server_addrs, i = 1; i < nservers; serv_addr++, i++) {
+ setup_server(&otherservers[i], serv_addr);
+ /* is this me? */
+ if (serv_addr->s_addr == my_addr.s_addr) {
+ me_server_idx = i;
+ otherservers[i].state = SERV_UP;
+ timer_reset(otherservers[i].timer);
+ otherservers[i].timer = NULL;
+ otherservers[i].queue = NULL;
+ otherservers[i].dumping = 0;
#if 0
- zdbug((LOG_DEBUG,"found myself"));
+ zdbug((LOG_DEBUG,"found myself"));
#endif
- }
}
+ }
- /* free up the addresses */
- xfree(server_addrs);
+ /* free up the addresses */
+ free(server_addrs);
- if (me_server_idx == -1) {
- syslog(LOG_WARNING, "I'm a renegade server!");
- otherservers = (ZServerDesc_t *)realloc((caddr_t) otherservers, (unsigned) (++nservers * sizeof(ZServerDesc_t)));
- if (!otherservers) {
- syslog(LOG_CRIT, "renegade realloc");
- abort();
- }
- setup_server(&otherservers[nservers - 1], &my_addr);
- /* we are up. */
- otherservers[nservers - 1].zs_state = SERV_UP;
-
- /* I don't send hello's to myself--cancel the timer */
- timer_reset(otherservers[nservers - 1].zs_timer);
- otherservers[nservers - 1].zs_timer = (timer) NULL;
-
- /* cancel and reschedule all the timers--pointers need
- adjusting */
- /* don't reschedule limbo's timer, so start i=1 */
- for (i = 1; i < nservers - 1; i++) {
- timer_reset(otherservers[i].zs_timer);
- /* all the HELLO's are due now */
- otherservers[i].zs_timer =
- timer_set_rel(0L, server_timo, (void *)
- &otherservers[i]);
- }
- me_server_idx = nservers - 1;
+ if (me_server_idx == -1) {
+ syslog(LOG_WARNING, "I'm a renegade server!");
+ otherservers = (Server *) realloc(otherservers,
+ ++nservers * sizeof(Server));
+ if (!otherservers) {
+ syslog(LOG_CRIT, "renegade realloc");
+ abort();
}
- if (!(srv_nacklist = (ZNotAcked_t *) xmalloc(sizeof(ZNotAcked_t)))) {
- /* unrecoverable */
- syslog(LOG_CRIT, "srv_nacklist malloc");
- abort();
+ setup_server(&otherservers[nservers - 1], &my_addr);
+ /* we are up. */
+ otherservers[nservers - 1].state = SERV_UP;
+
+ /* I don't send hello's to myself--cancel the timer */
+ timer_reset(otherservers[nservers - 1].timer);
+ otherservers[nservers - 1].timer = NULL;
+
+ /* cancel and reschedule all the timers--pointers need
+ adjusting */
+ /* don't reschedule limbo's timer, so start i=1 */
+ for (i = 1; i < nservers - 1; i++) {
+ timer_reset(otherservers[i].timer);
+ /* all the HELLO's are due now */
+ otherservers[i].timer = timer_set_rel(0L, server_timo,
+ &otherservers[i]);
}
- (void) memset((caddr_t) srv_nacklist, 0, sizeof(ZNotAcked_t));
- srv_nacklist->q_forw = srv_nacklist->q_back = srv_nacklist;
+ me_server_idx = nservers - 1;
+ }
- return;
}
/*
@@ -256,191 +232,193 @@ server_init()
void
server_reset()
{
- int num_servers;
- struct in_addr *server_addrs;
- register struct in_addr *serv_addr;
- register ZServerDesc_t *servers;
- register int i, j;
- int *ok_list_new, *ok_list_old;
- int num_ok, new_num;
+ int num_servers;
+ struct in_addr *server_addrs;
+ struct in_addr *serv_addr;
+ Server *servers;
+ int i, j;
+ int *ok_list_new, *ok_list_old;
+ int num_ok, new_num;
#if 0
- zdbug((LOG_DEBUG, "server_reset"));
+ zdbug((LOG_DEBUG, "server_reset"));
#endif
#ifdef DEBUG
- if (zalone) {
- syslog(LOG_INFO, "server_reset while alone, punt");
- return;
- }
+ if (zalone) {
+ syslog(LOG_INFO, "server_reset while alone, punt");
+ return;
+ }
#endif /* DEBUG */
- /* Find out what servers are supposed to be known. */
- if (!(server_addrs = get_server_addrs(&num_servers))) {
- syslog(LOG_ERR, "server_reset no servers. nothing done.");
- return;
- }
- ok_list_new = (int *) xmalloc (num_servers * sizeof (int));
- if (ok_list_new == (int *) 0) {
- syslog(LOG_ERR, "server_reset no mem new");
- return;
- }
- ok_list_old = (int *) xmalloc (nservers * sizeof (int));
- if (ok_list_old == (int *) 0) {
- syslog(LOG_ERR, "server_reset no mem old");
- xfree(ok_list_new);
- return;
- }
+ /* Find out what servers are supposed to be known. */
+ server_addrs = get_server_addrs(&num_servers);
+ if (!server_addrs) {
+ syslog(LOG_ERR, "server_reset no servers. nothing done.");
+ return;
+ }
+ ok_list_new = (int *) malloc(num_servers * sizeof(int));
+ if (!ok_list_new) {
+ syslog(LOG_ERR, "server_reset no mem new");
+ return;
+ }
+ ok_list_old = (int *) malloc(nservers * sizeof(int));
+ if (!ok_list_old) {
+ syslog(LOG_ERR, "server_reset no mem old");
+ free(ok_list_new);
+ return;
+ }
- (void) memset((char *)ok_list_old, 0, nservers * sizeof(int));
- (void) memset((char *)ok_list_new, 0, num_servers * sizeof(int));
+ memset(ok_list_old, 0, nservers * sizeof(int));
+ memset(ok_list_new, 0, num_servers * sizeof(int));
- /* reset timers--pointers will move */
- for (j = 1; j < nservers; j++) { /* skip limbo */
- if (j == me_server_idx)
- continue;
- timer_reset(otherservers[j].zs_timer);
- otherservers[j].zs_timer = (timer) 0;
+ /* reset timers--pointers will move */
+ for (j = 1; j < nservers; j++) { /* skip limbo */
+ if (j == me_server_idx)
+ continue;
+ timer_reset(otherservers[j].timer);
+ otherservers[j].timer = NULL;
+ }
+
+ /* check off entries on new list which are on old list.
+ check off entries on old list which are on new list. */
+
+ /* count limbo as "OK" */
+ num_ok = 1;
+ ok_list_old[0] = 1; /* limbo is OK */
+
+ for (serv_addr = server_addrs, i = 0; i < num_servers; serv_addr++, i++) {
+ for (j = 1; j < nservers; j++) { /* j = 1 since we skip limbo */
+ if (otherservers[j].addr.sin_addr.s_addr == serv_addr->s_addr) {
+ /* if server is on both lists, mark */
+ ok_list_new[i] = 1;
+ ok_list_old[j] = 1;
+ num_ok++;
+ break; /* for j loop */
+ }
}
+ }
- /* check off entries on new list which are on old list.
- check off entries on old list which are on new list.
- */
-
- /* count limbo as "OK" */
- num_ok = 1;
- ok_list_old[0] = 1; /* limbo is OK */
-
- for (serv_addr = server_addrs, i = 0;
- i < num_servers;
- serv_addr++, i++) /* for each new server */
- for (j = 1; j < nservers; j++) /* j = 1 since we skip limbo */
- if (otherservers[j].zs_addr.sin_addr.s_addr ==
- serv_addr->s_addr) {
- /* if server is on both lists, mark */
- ok_list_new[i] = 1;
- ok_list_old[j] = 1;
- num_ok++;
- break; /* for j loop */
- }
-
- /* remove any dead servers on old list not on new list. */
- if (num_ok < nservers) {
- int *srv;
- new_num = 1; /* limbo */
- /* count number of servers to keep */
- for (j = 1; j < nservers; j++)
- /* since we are never SERV_DEAD, the following
- test prevents removing ourself from the list */
- if (ok_list_old[j] ||
- (otherservers[j].zs_state != SERV_DEAD)) {
- syslog(LOG_INFO, "keeping server %s",
- otherservers[j].addr);
- new_num++;
- }
- if (new_num < nservers) {
- servers = (ZServerDesc_t *) xmalloc(new_num * sizeof(ZServerDesc_t));
- if (!servers) {
- syslog(LOG_CRIT, "server_reset server malloc");
- abort();
- }
- i = 1;
- servers[0] = otherservers[0]; /* copy limbo */
-
- srv = (int*) xmalloc (nservers * sizeof (int));
- (void) memset (srv, 0, nservers * sizeof (int));
-
- /* copy the kept servers */
- for (j = 1; j < nservers; j++) { /* skip limbo */
- if (ok_list_old[j] ||
- otherservers[j].zs_state != SERV_DEAD) {
- servers[i] = otherservers[j];
- srv[j] = i;
- i++;
- } else {
- syslog(LOG_INFO, "flushing server %s",
- otherservers[j].addr);
- server_flush(&otherservers[j]);
- srv[j] = -1;
- }
-
- }
- srv_nack_renumber (srv);
- hostm_renumber_servers (srv);
-
- xfree(srv);
- xfree(otherservers);
- otherservers = servers;
- nservers = new_num;
+ /* remove any dead servers on old list not on new list. */
+ if (num_ok < nservers) {
+ int *srv;
+
+ new_num = 1; /* limbo */
+ /* count number of servers to keep */
+ for (j = 1; j < nservers; j++) {
+ /* since we are never SERV_DEAD, the following
+ test prevents removing ourself from the list */
+ if (ok_list_old[j] || (otherservers[j].state != SERV_DEAD)) {
+ syslog(LOG_INFO, "keeping server %s",
+ otherservers[j].addr_str);
+ new_num++;
+ }
+ }
+ if (new_num < nservers) {
+ servers = (Server *) malloc(new_num * sizeof(Server));
+ if (!servers) {
+ syslog(LOG_CRIT, "server_reset server malloc");
+ abort();
+ }
+ i = 1;
+ servers[0] = otherservers[0]; /* copy limbo */
+
+ srv = (int *) malloc(nservers * sizeof(int));
+ memset(srv, 0, nservers * sizeof(int));
+
+ /* copy the kept servers */
+ for (j = 1; j < nservers; j++) { /* skip limbo */
+ if (ok_list_old[j] ||
+ otherservers[j].state != SERV_DEAD) {
+ servers[i] = otherservers[j];
+ srv[j] = i;
+ i++;
+ } else {
+ syslog(LOG_INFO, "flushing server %s",
+ otherservers[j].addr_str);
+ server_flush(&otherservers[j]);
+ srv[j] = -1;
}
+
+ }
+ srv_nack_renumber(srv);
+
+ free(srv);
+ free(otherservers);
+ otherservers = servers;
+ nservers = new_num;
}
- /* add any new servers on new list not on old list. */
- new_num = 0;
- for (i = 0; i < num_servers; i++)
- if (!ok_list_new[i])
- new_num++;
- /* new_num is number of extras. */
- nservers += new_num;
- otherservers = (ZServerDesc_t *)realloc((caddr_t) otherservers, (unsigned) (nservers * sizeof(ZServerDesc_t)));
- if (!otherservers) {
- syslog(LOG_CRIT, "server_reset realloc");
- abort();
+ }
+
+ /* add any new servers on new list not on old list. */
+ new_num = 0;
+ for (i = 0; i < num_servers; i++) {
+ if (!ok_list_new[i])
+ new_num++;
+ }
+
+ /* new_num is number of extras. */
+ nservers += new_num;
+ otherservers = (Server *) realloc(otherservers, nservers * sizeof(Server));
+ if (!otherservers) {
+ syslog(LOG_CRIT, "server_reset realloc");
+ abort();
+ }
+
+ me_server_idx = 0;
+ for (j = 1; j < nservers - new_num; j++) {
+ if (otherservers[j].addr.sin_addr.s_addr == my_addr.s_addr) {
+ me_server_idx = j;
+ break;
}
+ }
+ if (!me_server_idx) {
+ syslog(LOG_CRIT, "can't find myself");
+ abort();
+ }
- me_server_idx = 0;
- for (j = 1; j < nservers - new_num; j++)
- if (otherservers[j].zs_addr.sin_addr.s_addr ==
- my_addr.s_addr) {
- me_server_idx = j;
- break;
- }
- if (!me_server_idx) {
- syslog(LOG_CRIT, "can't find myself");
- abort();
+ /* fill in otherservers with the new servers */
+ for (i = 0; i < num_servers; i++) {
+ if (!ok_list_new[i]) {
+ setup_server(&otherservers[nservers - (new_num--)],
+ &server_addrs[i]);
+ syslog(LOG_INFO, "adding server %s", inet_ntoa(server_addrs[i]));
}
-
- /* fill in otherservers with the new servers */
- for (i = 0; i < num_servers; i++)
- if (!ok_list_new[i]) {
- setup_server(&otherservers[nservers - (new_num--)],
- &server_addrs[i]);
- syslog(LOG_INFO, "adding server %s",
- inet_ntoa(server_addrs[i]));
- }
- xfree(server_addrs);
- /* reset timers, to go off now.
- We can't get a time-left indication (bleagh!)
- so we expire them all now. This will generally
- be non-destructive. We assume that when this code is
- entered via a SIGHUP trigger that a system wizard
- is watching the goings-on to make sure things straighten
- themselves out.
- */
- for (i = 1; i < nservers; i++) /* skip limbo */
- if (i != me_server_idx && !otherservers[i].zs_timer) {
- otherservers[i].zs_timer =
- timer_set_rel(0L, server_timo,
- (void *) &otherservers[i]);
+ }
+
+ free(server_addrs);
+ /* reset timers, to go off now.
+ We can't get a time-left indication (bleagh!)
+ so we expire them all now. This will generally
+ be non-destructive. We assume that when this code is
+ entered via a SIGHUP trigger that a system wizard
+ is watching the goings-on to make sure things straighten
+ themselves out.
+ */
+ for (i = 1; i < nservers; i++) { /* skip limbo */
+ if (i != me_server_idx && !otherservers[i].timer) {
+ otherservers[i].timer =
+ timer_set_rel(0L, server_timo, &otherservers[i]);
#if 0
- zdbug((LOG_DEBUG, "reset timer for %s",
- otherservers[i].addr));
-#endif
- }
- xfree(ok_list_old);
- xfree(ok_list_new);
+ zdbug((LOG_DEBUG, "reset timer for %s",
+ otherservers[i].addr_str));
+#endif
+ }
+ }
+ free(ok_list_old);
+ free(ok_list_new);
#if 0
- zdbug((LOG_DEBUG, "server_reset: %d servers now", nservers));
+ zdbug((LOG_DEBUG, "server_reset: %d servers now", nservers));
#endif
- return;
}
/* note: these must match the order given in zserver.h */
static char *
srv_states[] = {
- "SERV_UP",
- "SERV_TARDY",
- "SERV_DEAD",
- "SERV_STARTING"
+ "SERV_UP",
+ "SERV_TARDY",
+ "SERV_DEAD",
+ "SERV_STARTING"
};
/*
@@ -453,58 +431,53 @@ srv_states[] = {
*/
void
-#ifdef __STDC__
-server_timo(void* arg)
-#else
server_timo(arg)
- void* arg;
-#endif
+ void *arg;
{
- ZServerDesc_t *which = (ZServerDesc_t *) arg;
- int auth = 0;
+ Server *which = (Server *) arg;
+ int auth = 0;
#if 0
- zdbug((LOG_DEBUG,"srv_timo: %s", which->addr));
+ zdbug((LOG_DEBUG,"srv_timo: %s", which->addr_str));
#endif
- /* change state and reset if appropriate */
- switch(which->zs_state) {
- case SERV_DEAD: /* leave him dead */
- server_flush(which);
- auth = 1;
- break;
- case SERV_UP: /* he's now tardy */
- which->zs_state = SERV_TARDY;
- which->zs_numsent = 0;
- which->zs_timeout = timo_tardy;
- auth = 0;
- break;
- case SERV_TARDY:
- case SERV_STARTING:
- if (which->zs_numsent >= ((which->zs_state == SERV_TARDY) ?
- H_NUM_TARDY :
- H_NUM_STARTING)) {
- /* he hasn't answered, assume DEAD */
- which->zs_state = SERV_DEAD;
- which->zs_numsent = 0;
- which->zs_timeout = timo_dead;
- server_lost(which);
- }
- auth = 0;
- break;
- default:
- syslog(LOG_ERR,"Bad server state, server 0x%x\n",which);
- abort();
+ /* change state and reset if appropriate */
+ switch(which->state) {
+ case SERV_DEAD: /* leave him dead */
+ server_flush(which);
+ auth = 1;
+ break;
+ case SERV_UP: /* he's now tardy */
+ which->state = SERV_TARDY;
+ which->num_hello_sent = 0;
+ which->timeout = timo_tardy;
+ auth = 0;
+ break;
+ case SERV_TARDY:
+ case SERV_STARTING:
+ if (which->num_hello_sent >= ((which->state == SERV_TARDY) ?
+ H_NUM_TARDY :
+ H_NUM_STARTING)) {
+ /* he hasn't answered, assume DEAD */
+ which->state = SERV_DEAD;
+ which->num_hello_sent = 0;
+ which->timeout = timo_dead;
+ srv_nack_release(which);
}
- /* now he's either TARDY, STARTING, or DEAD
- We send a "hello," which increments the counter */
+ auth = 0;
+ break;
+ default:
+ syslog(LOG_ERR,"Bad server state, server 0x%x\n",which);
+ abort();
+ }
+ /* now he's either TARDY, STARTING, or DEAD
+ We send a "hello," which increments the counter */
#if 0
- zdbug((LOG_DEBUG, "srv %s is %s", which->addr,
- srv_states[(int) which->zs_state]));
+ zdbug((LOG_DEBUG, "srv %s is %s", which->addr_str,
+ srv_states[which->state]));
#endif
- server_hello(which, auth);
- /* reschedule the timer */
- which->zs_timer = timer_set_rel(which->zs_timeout, server_timo,
- (void *) which);
+ server_hello(which, auth);
+ /* reschedule the timer */
+ which->timer = timer_set_rel(which->timeout, server_timo, which);
}
/*
@@ -514,67 +487,64 @@ server_timo(arg)
/*ARGSUSED*/
Code_t
server_dispatch(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
{
- ZServerDesc_t *server;
- struct sockaddr_in newwho;
- Code_t status;
- ZSTRING *notice_class;
-
+ Server *server;
+ struct sockaddr_in newwho;
+ Code_t status;
+ String *notice_class;
#if 0
- zdbug((LOG_DEBUG, "server_dispatch"));
+ zdbug((LOG_DEBUG, "server_dispatch"));
#endif
- if (notice->z_kind == SERVACK) {
- srv_nack_cancel(notice, who);
- srv_responded(who);
- return(ZERR_NONE);
- }
- /* set up a who for the real origin */
- (void) memset((caddr_t) &newwho, 0, sizeof(newwho));
- newwho.sin_family = AF_INET;
- newwho.sin_addr.s_addr = notice->z_sender_addr.s_addr;
- newwho.sin_port = notice->z_port;
-
- server = server_which_server(who);
-
- /* we can dispatch to routines safely here, since they will
- return ZSRV_REQUEUE if appropriate. We bounce this back
- to the caller, and the caller will re-queue the message
- for us to process later. */
-
- notice_class = make_zstring(notice->z_class,1);
-
- if (class_is_admin(notice_class)) {
- /* admins don't get acked, else we get a packet loop */
- /* will return requeue if bdump request and dumping */
- i_s_admins.val++;
- return(admin_dispatch(notice, auth, who, server));
- } else if (class_is_control(notice_class)) {
- status = control_dispatch(notice, auth, &newwho, server);
- i_s_ctls.val++;
- }
- else if (class_is_ulogin(notice_class)) {
- status = ulogin_dispatch(notice, auth, &newwho, server);
- i_s_logins.val++;
- }
- else if (class_is_ulocate(notice_class)) {
- status = ulocate_dispatch(notice, auth, &newwho, server);
- i_s_locates.val++;
- }
- else {
- /* shouldn't come from another server */
- syslog(LOG_WARNING, "srv_disp: pkt cls %s",
- notice->z_class);
- status = ZERR_NONE; /* XXX */
- }
- if (status != ZSRV_REQUEUE)
- ack(notice, who); /* acknowledge it if processed */
- free_zstring(notice_class);
- return(status);
+ if (notice->z_kind == SERVACK) {
+ srv_nack_cancel(notice, who);
+ srv_responded(who);
+ return ZERR_NONE;
+ }
+ /* set up a who for the real origin */
+ memset(&newwho, 0, sizeof(newwho));
+ newwho.sin_family = AF_INET;
+ newwho.sin_addr.s_addr = notice->z_sender_addr.s_addr;
+ newwho.sin_port = notice->z_port;
+
+ server = server_which_server(who);
+
+ /* we can dispatch to routines safely here, since they will
+ return ZSRV_REQUEUE if appropriate. We bounce this back
+ to the caller, and the caller will re-queue the message
+ for us to process later. */
+
+ notice_class = make_string(notice->z_class, 1);
+
+ if (realm_which_realm(&newwho))
+ status = realm_dispatch(notice, auth, &newwho, server);
+ else if (class_is_admin(notice_class)) {
+ /* admins don't get acked, else we get a packet loop */
+ /* will return requeue if bdump request and dumping */
+ i_s_admins.val++;
+ return admin_dispatch(notice, auth, who, server);
+ } else if (class_is_control(notice_class)) {
+ status = control_dispatch(notice, auth, &newwho, server);
+ i_s_ctls.val++;
+ } else if (class_is_ulogin(notice_class)) {
+ status = ulogin_dispatch(notice, auth, &newwho, server);
+ i_s_logins.val++;
+ } else if (class_is_ulocate(notice_class)) {
+ status = ulocate_dispatch(notice, auth, &newwho, server);
+ i_s_locates.val++;
+ } else {
+ /* shouldn't come from another server */
+ syslog(LOG_WARNING, "srv_disp: pkt cls %s", notice->z_class);
+ status = ZERR_NONE; /* XXX */
+ }
+ if (status != ZSRV_REQUEUE)
+ ack(notice, who); /* acknowledge it if processed */
+ free_string(notice_class);
+ return status;
}
#ifdef notdef
@@ -585,165 +555,120 @@ server_dispatch(notice, auth, who)
/*ARGSUSED*/
static Code_t
server_register(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
{
- ZServerDesc_t *temp;
- register int i;
- long timerval;
+ Server *temp;
+ int i;
+ long timerval;
- if (who->sin_port != sock_sin.sin_port) {
+ if (who->sin_port != srv_addr.sin_port) {
#if 0
- zdbug((LOG_DEBUG, "srv_register wrong port %d",
- ntohs(who->sin_port)));
+ zdbug((LOG_DEBUG, "srv_wrong port %d", ntohs(who->sin_port)));
#endif
- return 1;
- }
- /* Not yet... talk to ken about authenticators */
+ return 1;
+ }
+ /* Not yet... talk to ken about authenticators */
#ifdef notdef
- if (!auth) {
+ if (!auth) {
#if 0
- zdbug((LOG_DEBUG, "srv_register unauth"));
+ zdbug((LOG_DEBUG, "srv_unauth"));
#endif
- return 1;
- }
+ return 1;
+ }
#endif /* notdef */
- /* OK, go ahead and set him up. */
- temp = (ZServerDesc_t *)xmalloc((unsigned) ((nservers + 1) * sizeof(ZServerDesc_t)));
- if (!temp) {
- syslog(LOG_CRIT, "srv_reg malloc");
- return 1;
- }
+ /* OK, go ahead and set him up. */
+ temp = (Server *) malloc((nservers + 1) * sizeof(Server));
+ if (!temp) {
+ syslog(LOG_CRIT, "srv_reg malloc");
+ return 1;
+ }
- START_CRITICAL_CODE;
-
- (void) memcpy((caddr_t) temp, (caddr_t) otherservers,
- nservers * sizeof(ZServerDesc_t));
- xfree(otherservers);
- otherservers = temp;
- /* don't reschedule limbo's timer, so start i=1 */
- for (i = 1; i < nservers; i++) {
- if (i == me_server_idx) /* don't reset myself */
- continue;
- /* reschedule the timers--we moved otherservers */
- timerval = timer_when(otherservers[i].zs_timer);
- timer_reset(otherservers[i].zs_timer);
- otherservers[i].zs_timer = timer_set_abs(timerval, server_timo, (caddr_t) &otherservers[i]);
- }
- setup_server(&otherservers[nservers], &who->sin_addr);
- otherservers[nservers].zs_state = SERV_STARTING;
- otherservers[nservers].zs_timeout = timo_tardy;
- otherservers[nservers].zs_update_queue = NULLZSPT;
- otherservers[nservers].zs_dumping = 0;
+ memcpy(temp, otherservers, nservers * sizeof(Server));
+ free(otherservers);
+ otherservers = temp;
+ /* don't reschedule limbo's timer, so start i=1 */
+ for (i = 1; i < nservers; i++) {
+ if (i == me_server_idx) /* don't reset myself */
+ continue;
+ /* reschedule the timers--we moved otherservers */
+ timerval = timer_when(otherservers[i].timer);
+ timer_reset(otherservers[i].timer);
+ otherservers[i].timer = timer_set_abs(timerval, server_timo,
+ &otherservers[i]);
+ }
+ setup_server(&otherservers[nservers], &who->sin_addr);
+ otherservers[nservers].state = SERV_STARTING;
+ otherservers[nservers].timeout = timo_tardy;
+ otherservers[nservers].update_queue = NULL;
+ otherservers[nservers].dumping = 0;
- nservers++;
+ nservers++;
#if 0
- zdbug((LOG_DEBUG, "srv %s is %s", otherservers[nservers].addr,
- srv_states[(int) otherservers[nservers].zs_state]));
+ zdbug((LOG_DEBUG, "srv %s is %s", otherservers[nservers].addr_str,
+ srv_states[otherservers[nservers].state]));
#endif
- END_CRITICAL_CODE;
-
- return 0;
+ return 0;
}
#endif
/*
- * Recover a host whose client has stopped responding.
- * The hostm_ module takes care of pings, timeouts, etc.
- */
-
-void
-server_recover(client)
- ZClient_t *client;
-{
- ZServerDesc_t *server;
- char *lyst[2];
- char buf[512];
-
-#if 0
- zdbug((LOG_DEBUG,"server recover"));
-#endif
- if ((server = hostm_find_server(&client->zct_sin.sin_addr)) !=
- NULLZSDT) {
- if (server == limbo_server) {
-#if 0
- zdbug((LOG_DEBUG, "no server to recover"));
-#endif
- return;
- } else if (server == me_server) {
- /* send a ping, set up a timeout, and return */
- hostm_losing(client, hostm_find_host(&client->zct_sin.sin_addr));
- return;
- } else {
- /* some other server */
- lyst[0] = inet_ntoa(client->zct_sin.sin_addr);
- (void) sprintf(buf, "%d", ntohs(client->zct_sin.sin_port));
- lyst[1] = buf;
- send_msg_list(&server->zs_addr, ADMIN_LOST_CLT,
- lyst, 2, 0, server - otherservers);
- return;
- }
- } else
- syslog(LOG_ERR, "srv_recover: no host for client");
- return;
-}
-
-/*
* Tell the other servers that this client died.
*/
void
server_kill_clt(client)
- ZClient_t *client;
+ Client *client;
{
- register int i;
- char buf[512], *lyst[2];
- ZNotice_t notice;
- register ZNotice_t *pnotice; /* speed hack */
- caddr_t pack;
- int packlen, auth;
- Code_t retval;
-
- lyst[0] = inet_ntoa(client->zct_sin.sin_addr),
- (void) sprintf(buf, "%d", ntohs(client->zct_sin.sin_port));
- lyst[1] = buf;
+ int i;
+ char buf[512], *lyst[2];
+ ZNotice_t notice;
+ ZNotice_t *pnotice; /* speed hack */
+ caddr_t pack;
+ int packlen, auth;
+ Code_t retval;
+
+ lyst[0] = inet_ntoa(client->addr.sin_addr),
+ sprintf(buf, "%d", ntohs(client->addr.sin_port));
+ lyst[1] = buf;
#if 0
- zdbug((LOG_DEBUG, "server kill clt %s/%s", lyst[0], lyst[1]));
+ zdbug((LOG_DEBUG, "server kill clt %s/%s", lyst[0], lyst[1]));
#endif
- pnotice = &notice;
+ pnotice = &notice;
- pnotice->z_kind = ACKED;
+ pnotice->z_kind = ACKED;
- pnotice->z_port = sock_sin.sin_port;
- pnotice->z_class = ZEPHYR_ADMIN_CLASS;
- pnotice->z_class_inst = "";
- pnotice->z_opcode = ADMIN_KILL_CLT;
- pnotice->z_sender = myname; /* myname is the hostname */
- pnotice->z_recipient = "";
- pnotice->z_default_format = "";
- pnotice->z_num_other_fields = 0;
+ pnotice->z_port = srv_addr.sin_port;
+ pnotice->z_class = ZEPHYR_ADMIN_CLASS;
+ pnotice->z_class_inst = "";
+ pnotice->z_opcode = ADMIN_KILL_CLT;
+ pnotice->z_sender = myname; /* myname is the hostname */
+ pnotice->z_recipient = "";
+ pnotice->z_default_format = "";
+ pnotice->z_num_other_fields = 0;
- /* XXX */
- auth = 0;
+ /* XXX */
+ auth = 0;
- /* don't tell limbo to flush, start at 1*/
- for (i = 1; i < nservers; i++) {
- if (i == me_server_idx) /* don't xmit to myself */
- continue;
- if (otherservers[i].zs_state == SERV_DEAD)
- continue;
-
- if ((retval = ZFormatNoticeList(pnotice, lyst, 2, &pack, &packlen, auth ? ZAUTH : ZNOAUTH)) != ZERR_NONE) {
- syslog(LOG_WARNING, "kill_clt format: %s",
- error_message(retval));
- return;
- }
- server_forw_reliable(&otherservers[i], pack, packlen, pnotice);
+ /* don't tell limbo to flush, start at 1*/
+ for (i = 1; i < nservers; i++) {
+ if (i == me_server_idx) /* don't xmit to myself */
+ continue;
+ if (otherservers[i].state == SERV_DEAD)
+ continue;
+
+ retval = ZFormatNoticeList(pnotice, lyst, 2, &pack, &packlen,
+ auth ? ZAUTH : ZNOAUTH);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "kill_clt format: %s", error_message(retval));
+ return;
}
+ server_forw_reliable(&otherservers[i], pack, packlen, pnotice);
+ }
}
/*
@@ -752,76 +677,34 @@ server_kill_clt(client)
static Code_t
kill_clt(notice, server)
- ZNotice_t *notice;
- ZServerDesc_t *server;
+ ZNotice_t *notice;
+ Server *server;
{
- struct sockaddr_in who;
- ZHostList_t *host;
- ZClient_t *client;
+ struct sockaddr_in who;
+ Client *client;
#if 0
- zdbug((LOG_DEBUG, "kill_clt"));
+ zdbug((LOG_DEBUG, "kill_clt"));
#endif
- if (extract_addr(notice, &who) != ZERR_NONE)
- return(ZERR_NONE); /* XXX */
- if (!(host = hostm_find_host(&who.sin_addr))) {
- syslog(LOG_NOTICE, "kill_clt: no such host (%s, from %s)",
- inet_ntoa (who.sin_addr), server->addr);
- return(ZERR_NONE); /* XXX */
- }
- if (host->zh_locked)
- return(ZSRV_REQUEUE);
- if (!(client = client_which_client(&who, notice))) {
- syslog(LOG_NOTICE, "kill_clt: no such client (%s/%d) from %s",
- inet_ntoa (who.sin_addr), ntohs (who.sin_port),
- server->addr);
- return(ZERR_NONE); /* XXX */
- }
-#if 0
- if (zdebug || 1)
- syslog(LOG_DEBUG, "kill_clt clt_dereg %s/%d from %s",
- inet_ntoa (who.sin_addr), ntohs (who.sin_port),
- server->addr);
+ if (extract_addr(notice, &who) != ZERR_NONE)
+ return ZERR_NONE; /* XXX */
+ client = client_which_client(&who.sin_addr, notice);
+ if (!client) {
+ syslog(LOG_NOTICE, "kill_clt: no such client (%s/%d) from %s",
+ inet_ntoa(who.sin_addr), ntohs(who.sin_port),
+ server->addr_str);
+ return ZERR_NONE; /* XXX */
+ }
+#if 1
+ if (zdebug || 1) {
+ syslog(LOG_DEBUG, "kill_clt clt_dereg %s/%d from %s",
+ inet_ntoa(who.sin_addr), ntohs(who.sin_port), server->addr_str);
+ }
#endif
- hostm_lose_ignore(client);
- /* remove the locations, too */
- client_deregister(client, host, 1);
- return(ZERR_NONE);
-}
-
-/*
- * Another server asked us to initiate recovery protocol with the hostmanager
- */
-static Code_t
-recover_clt(notice, server)
- register ZNotice_t *notice;
- ZServerDesc_t *server;
-{
- struct sockaddr_in who;
- ZClient_t *client;
- ZHostList_t *host;
- Code_t status;
-
- if ((status = extract_addr(notice, &who)) != ZERR_NONE)
- return(status);
- if (!(host = hostm_find_host(&who.sin_addr))) {
- syslog(LOG_NOTICE,
- "recover_clt: host not found (%s, from %s)",
- inet_ntoa (who.sin_addr), server->addr);
- return(ZERR_NONE); /* XXX */
- }
- if (host->zh_locked)
- return(ZSRV_REQUEUE);
- if (!(client = client_which_client(&who, notice))) {
- syslog(LOG_NOTICE,
- "recover_clt: client not found (%s/%d, from %s)",
- inet_ntoa (who.sin_addr), ntohs (who.sin_port),
- server->addr);
- return(ZERR_NONE); /* XXX */
- }
- hostm_losing(client, host);
- return(ZERR_NONE);
+ /* remove the locations, too */
+ client_deregister(client, 1);
+ return ZERR_NONE;
}
/*
@@ -830,29 +713,29 @@ recover_clt(notice, server)
static Code_t
extract_addr(notice, who)
- ZNotice_t *notice;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
{
- register char *cp = notice->z_message;
+ char *cp = notice->z_message;
- if (!notice->z_message_len) {
- syslog(LOG_WARNING, "bad addr pkt");
- return(ZSRV_PKSHORT);
- }
- who->sin_addr.s_addr = inet_addr(notice->z_message);
+ if (!notice->z_message_len) {
+ syslog(LOG_WARNING, "bad addr pkt");
+ return ZSRV_PKSHORT;
+ }
+ who->sin_addr.s_addr = inet_addr(notice->z_message);
- cp += strlen(cp) + 1;
- if (cp >= notice->z_message + notice->z_message_len) {
- syslog(LOG_WARNING, "short addr pkt");
- return(ZSRV_PKSHORT);
- }
- who->sin_port = notice->z_port = htons((u_short) atoi(cp));
- who->sin_family = AF_INET;
+ cp += strlen(cp) + 1;
+ if (cp >= notice->z_message + notice->z_message_len) {
+ syslog(LOG_WARNING, "short addr pkt");
+ return ZSRV_PKSHORT;
+ }
+ who->sin_port = notice->z_port = htons((u_short) atoi(cp));
+ who->sin_family = AF_INET;
#if 0
- zdbug((LOG_DEBUG,"ext %s/%d", inet_ntoa(who->sin_addr),
- ntohs(who->sin_port)));
+ zdbug((LOG_DEBUG,"ext %s/%d", inet_ntoa(who->sin_addr),
+ ntohs(who->sin_port)));
#endif
- return(ZERR_NONE);
+ return ZERR_NONE;
}
/*
@@ -861,29 +744,13 @@ extract_addr(notice, who)
static void
server_flush(which)
- register ZServerDesc_t *which;
+ Server *which;
{
- register ZHostList_t *hst;
-
#if 0
- if (zdebug)
- syslog (LOG_DEBUG, "server_flush %s", which->addr);
+ if (zdebug)
+ syslog(LOG_DEBUG, "server_flush %s", which->addr_str);
#endif
- if (!which->zs_hosts) /* no data to flush */
- return;
-
- for (hst = which->zs_hosts->q_forw;
- hst != which->zs_hosts;
- hst = which->zs_hosts->q_forw) {
- /* for each host, flush all data */
-#if 0
- if (zdebug)
- syslog (LOG_DEBUG, "... host %s",
- inet_ntoa (hst->zh_addr.sin_addr));
-#endif
- hostm_flush(hst, which);
- }
- srv_nack_release(which);
+ srv_nack_release(which);
}
/*
@@ -891,14 +758,13 @@ server_flush(which)
* Authenticate if auth is set.
*/
-STATIC void
+static void
server_hello(which, auth)
- ZServerDesc_t *which;
- int auth;
+ Server *which;
+ int auth;
{
- send_msg(&which->zs_addr, ADMIN_HELLO, auth);
- (which->zs_numsent)++;
- return;
+ send_msg(&which->addr, ADMIN_HELLO, auth);
+ which->num_hello_sent++;
}
/*
@@ -908,83 +774,54 @@ server_hello(which, auth)
/*ARGSUSED*/
static Code_t
admin_dispatch(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
{
- register char *opcode = notice->z_opcode;
- Code_t status = ZERR_NONE;
+ char *opcode = notice->z_opcode;
+ Code_t status = ZERR_NONE;
#if 0
- zdbug((LOG_DEBUG, "ADMIN received"));
+ zdbug((LOG_DEBUG, "ADMIN received"));
#endif
- if (!strcmp(opcode, ADMIN_HELLO)) {
- hello_respond(who, ADJUST, auth);
- } else if (!strcmp(opcode, ADMIN_IMHERE)) {
- srv_responded(who);
- } else if (!strcmp(opcode, ADMIN_SHUTDOWN)) {
+ if (strcmp(opcode, ADMIN_HELLO) == 0) {
+ hello_respond(who, ADJUST, auth);
+ } else if (strcmp(opcode, ADMIN_IMHERE) == 0) {
+ srv_responded(who);
+ } else if (strcmp(opcode, ADMIN_SHUTDOWN) == 0) {
#if 0
- zdbug((LOG_DEBUG, "server shutdown"));
+ zdbug((LOG_DEBUG, "server shutdown"));
#endif
- /* we need to transfer all of its hosts to limbo */
- if (server) {
- server_lost(server);
- server->zs_state = SERV_DEAD;
- server->zs_timeout = timo_dead;
- /* don't worry about the timer, it will
- be set appropriately on the next send */
+ if (server) {
+ srv_nack_release(server);
+ server->state = SERV_DEAD;
+ server->timeout = timo_dead;
+ /* don't worry about the timer, it will
+ be set appropriately on the next send */
#if 0
- zdbug((LOG_DEBUG, "srv %s is %s", server->addr,
- srv_states[(int) server->zs_state]));
+ zdbug((LOG_DEBUG, "srv %s is %s", server->addr_str,
+ srv_states[server->state]));
#endif
}
- } else if (!strcmp(opcode, ADMIN_BDUMP)) {
-#ifdef CONCURRENT
-#if 0 /* If another dump is in progress, it'll likely not
- finish in time for us to catch the server's
- bdump-waiting period. So don't bother. */
- if (bdumping)
- return(ZSRV_REQUEUE);
-#else
- if (bdumping)
- return ZERR_NONE;
-#endif
-#endif
- bdump_get(notice, auth, who, server);
- } else if (!strcmp(opcode, ADMIN_LOST_CLT)) {
- status = recover_clt(notice, server);
- if (status == ZERR_NONE)
- ack(notice, who);
- } else if (!strcmp(opcode, ADMIN_KILL_CLT)) {
- status = kill_clt(notice, server);
- if (status == ZERR_NONE)
- ack(notice, who);
- } else
- syslog(LOG_WARNING, "ADMIN unknown opcode %s",opcode);
- return(status);
+ } else if (strcmp(opcode, ADMIN_BDUMP) == 0) {
+ /* Ignore a brain dump request if this is a brain dump packet
+ * or a packet being processed concurrently during a brain
+ * dump. */
+ if (bdumping || bdump_concurrent)
+ return ZERR_NONE;
+ bdump_get(notice, auth, who, server);
+ } else if (strcmp(opcode, ADMIN_KILL_CLT) == 0) {
+ status = kill_clt(notice, server);
+ if (status == ZERR_NONE)
+ ack(notice, who);
+ } else {
+ syslog(LOG_WARNING, "ADMIN unknown opcode %s",opcode);
+ }
+ return status;
}
-/*
- * Transfer all the hosts on server to limbo
- */
-
-static void
-server_lost(server)
- ZServerDesc_t *server;
-{
- register ZHostList_t *host, *hishost;
-
- hishost = server->zs_hosts;
- for (host = hishost->q_forw;
- host != hishost;
- host = hishost->q_forw)
- /* hostm transfer remque's the host and
- attaches it to the new server */
- hostm_transfer(host, limbo_server);
- srv_nack_release(server);
-}
/*
* Handle an ADMIN message from some random client.
@@ -995,130 +832,131 @@ server_lost(server)
/*ARGSUSED*/
Code_t
server_adispatch(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
{
- /* this had better be a HELLO message--start of acquisition
- protocol, OR a status req packet */
+ /* this had better be a HELLO message--start of acquisition
+ protocol, OR a status req packet */
+
+ if (strcmp(notice->z_opcode, ADMIN_STATUS) == 0) {
+ /* status packet */
+ send_stats(who);
+ return ZERR_NONE;
+ }
- if (!strcmp(notice->z_opcode, ADMIN_STATUS)) {
- /* status packet */
- send_stats(who);
- return(ZERR_NONE);
- }
#ifdef notdef
- syslog(LOG_INFO, "disp: new server?");
- if (server_register(notice, auth, who) != ZERR_NONE)
- syslog(LOG_INFO, "new server failed");
- else {
- syslog(LOG_INFO, "new server %s, %d",
- inet_ntoa(who->sin_addr),
- ntohs(who->sin_port));
- hello_respond(who, DONT_ADJUST, auth);
- }
+ syslog(LOG_INFO, "disp: new server?");
+ if (server_register(notice, auth, who) != ZERR_NONE) {
+ syslog(LOG_INFO, "new server failed");
+ } else {
+ syslog(LOG_INFO, "new server %s, %d", inet_ntoa(who->sin_addr),
+ ntohs(who->sin_port));
+ hello_respond(who, DONT_ADJUST, auth);
+ }
#else
- syslog(LOG_INFO, "srv_adisp: server attempt from %s",
- inet_ntoa(who->sin_addr));
+ syslog(LOG_INFO, "srv_adisp: server attempt from %s",
+ inet_ntoa(who->sin_addr));
#endif /* notdef */
- return(ZERR_NONE);
+
+ return ZERR_NONE;
}
static void
send_stats(who)
- struct sockaddr_in *who;
+ struct sockaddr_in *who;
{
- register int i;
- char buf[BUFSIZ];
- char **responses;
- int num_resp;
- char *vers, *pkts, *upt;
+ int i;
+ char buf[BUFSIZ];
+ char **responses;
+ int num_resp;
+ char *vers, *pkts, *upt;
#if defined(OLD_COMPAT) || defined(NEW_COMPAT)
- int extrafields = 0;
+ int extrafields = 0;
#endif /* OLD_ or NEW_COMPAT */
#define NUM_FIXED 3 /* 3 fixed fields, plus server info */
/* well, not really...but for
backward compatibility, we gotta
do it this way. */
- vers = get_version();
+ vers = get_version();
- (void) sprintf(buf, "%d pkts", npackets);
- pkts = strsave(buf);
- (void) sprintf(buf, "%d seconds operational",NOW - uptime);
- upt = strsave(buf);
+ sprintf(buf, "%d pkts", npackets);
+ pkts = strsave(buf);
+ sprintf(buf, "%d seconds operational",NOW - uptime);
+ upt = strsave(buf);
#ifdef OLD_COMPAT
- if (old_compat_count_uloc) extrafields++;
- if (old_compat_count_ulocate) extrafields++;
- if (old_compat_count_subscr) extrafields++;
+ if (old_compat_count_uloc)
+ extrafields++;
+ if (old_compat_count_ulocate)
+ extrafields++;
+ if (old_compat_count_subscr)
+ extrafields++;
#endif /* OLD_COMPAT */
#ifdef NEW_COMPAT
- if (new_compat_count_uloc) extrafields++;
- if (new_compat_count_subscr) extrafields++;
+ if (new_compat_count_uloc)
+ extrafields++;
+ if (new_compat_count_subscr)
+ extrafields++;
#endif /* NEW_COMPAT */
#if defined(OLD_COMPAT) || defined(NEW_COMPAT)
- responses = (char **) xmalloc((NUM_FIXED + nservers + extrafields) *
- sizeof(char **));
+ responses = (char **) malloc((NUM_FIXED + nservers + extrafields) *
+ sizeof(char *));
#else
- responses = (char **) xmalloc ((NUM_FIXED + nservers) *
- sizeof(char **));
+ responses = (char **) malloc((NUM_FIXED + nservers) * sizeof(char *));
#endif /* OLD_ or NEW_COMPAT */
- responses[0] = vers;
- responses[1] = pkts;
- responses[2] = upt;
-
- num_resp = NUM_FIXED;
- /* start at 1 and ignore limbo */
- for (i = 1; i < nservers ; i++) {
- (void) sprintf(buf, "%s/%s%s", otherservers[i].addr,
- srv_states[(int) otherservers[i].zs_state],
- otherservers[i].zs_dumping ? " (DUMPING)" : "");
- responses[num_resp++] = strsave (buf);
- }
+ responses[0] = vers;
+ responses[1] = pkts;
+ responses[2] = upt;
+
+ num_resp = NUM_FIXED;
+ /* start at 1 and ignore limbo */
+ for (i = 1; i < nservers ; i++) {
+ sprintf(buf, "%s/%s%s", otherservers[i].addr_str,
+ srv_states[(int) otherservers[i].state],
+ otherservers[i].dumping ? " (DUMPING)" : "");
+ responses[num_resp++] = strsave(buf);
+ }
#ifdef OLD_COMPAT
- if (old_compat_count_uloc) {
- (void) sprintf(buf, "%d old old location requests",
- old_compat_count_uloc);
- responses[num_resp++] = strsave (buf);
- }
- if (old_compat_count_ulocate) {
- (void) sprintf(buf, "%d old old loc lookup requests",
- old_compat_count_ulocate);
- responses[num_resp++] = strsave (buf);
- }
- if (old_compat_count_subscr) {
- (void) sprintf(buf, "%d old old subscr requests",
- old_compat_count_subscr);
- responses[num_resp++] = strsave (buf);
- }
+ if (old_compat_count_uloc) {
+ sprintf(buf, "%d old old location requests", old_compat_count_uloc);
+ responses[num_resp++] = strsave(buf);
+ }
+ if (old_compat_count_ulocate) {
+ sprintf(buf, "%d old old loc lookup requests",
+ old_compat_count_ulocate);
+ responses[num_resp++] = strsave(buf);
+ }
+ if (old_compat_count_subscr) {
+ sprintf(buf, "%d old old subscr requests", old_compat_count_subscr);
+ responses[num_resp++] = strsave(buf);
+ }
#endif /* OLD_COMPAT */
#ifdef NEW_COMPAT
- if (new_compat_count_uloc) {
- (void) sprintf(buf, "%d new old location requests",
- new_compat_count_uloc);
- responses[num_resp++] = strsave (buf);
- }
- if (new_compat_count_subscr) {
- (void) sprintf(buf, "%d new old subscr requests",
- new_compat_count_subscr);
- responses[num_resp++] = strsave (buf);
- }
+ if (new_compat_count_uloc) {
+ sprintf(buf, "%d new old location requests", new_compat_count_uloc);
+ responses[num_resp++] = strsave(buf);
+ }
+ if (new_compat_count_subscr) {
+ sprintf(buf, "%d new old subscr requests", new_compat_count_subscr);
+ responses[num_resp++] = strsave(buf);
+ }
#endif /* NEW_COMPAT */
- send_msg_list(who, ADMIN_STATUS, responses, num_resp, 0, -1);
- /* Start at one; don't try to free static version string */
- for (i = 1; i < num_resp; i++)
- xfree(responses[i]);
- xfree(responses);
- return;
+ send_msg_list(who, ADMIN_STATUS, responses, num_resp, 0);
+
+ /* Start at one; don't try to free static version string */
+ for (i = 1; i < num_resp; i++)
+ free(responses[i]);
+ free(responses);
}
/*
* Get a list of server addresses.
-#ifdef HESIOD
+#ifdef ZEPHYR_USES_HESIOD
* This list is retrieved from Hesiod.
#else
* This list is read from a file.
@@ -1129,46 +967,50 @@ send_stats(who)
static struct in_addr *
get_server_addrs(number)
- int *number; /* RETURN */
+ int *number; /* RETURN */
{
- register int i;
- char **server_hosts;
- register char **cpp;
- struct in_addr *addrs;
- register struct in_addr *addr;
- register struct hostent *hp;
-
-#ifdef HESIOD
- /* get the names from Hesiod */
- if (!(server_hosts = hes_resolve("zephyr","sloc")))
- return((struct in_addr *)NULL);
+ int i;
+ char **server_hosts;
+ char **cpp;
+ struct in_addr *addrs;
+ struct in_addr *addr;
+ struct hostent *hp;
+
+#ifdef ZEPHYR_USES_HESIOD
+ /* get the names from Hesiod */
+ server_hosts = hes_resolve("zephyr","sloc");
+ if (!server_hosts)
+ return NULL;
#else
- if (!(server_hosts = get_server_list(SERVER_LIST_FILE)))
- return((struct in_addr *)NULL);
+ server_hosts = get_server_list(list_file);
+ if (!server_hosts)
+ return NULL;
#endif
- /* count up */
- for (cpp = server_hosts, i = 0; *cpp; cpp++, i++);
+ /* count up */
+ i = 0;
+ for (cpp = server_hosts; *cpp; cpp++)
+ i++;
- addrs = (struct in_addr *) xmalloc(i * sizeof(struct in_addr));
-
- /* Convert to in_addr's */
- for (cpp = server_hosts, addr = addrs, i = 0; *cpp; cpp++) {
- hp = gethostbyname(*cpp);
- if (hp) {
- (void) memcpy((caddr_t) addr, (caddr_t)hp->h_addr,
- sizeof(struct in_addr));
- addr++, i++;
- } else
- syslog(LOG_WARNING, "hostname failed, %s",*cpp);
+ addrs = (struct in_addr *) malloc(i * sizeof(struct in_addr));
+
+ /* Convert to in_addr's */
+ for (cpp = server_hosts, addr = addrs, i = 0; *cpp; cpp++) {
+ hp = gethostbyname(*cpp);
+ if (hp) {
+ memcpy(addr, hp->h_addr, sizeof(struct in_addr));
+ addr++, i++;
+ } else {
+ syslog(LOG_WARNING, "hostname failed, %s", *cpp);
}
- *number = i;
-#ifndef HESIOD
- free_server_list(server_hosts);
+ }
+ *number = i;
+#ifndef ZEPHYR_USES_HESIOD
+ free_server_list(server_hosts);
#endif
- return(addrs);
+ return addrs;
}
-#ifndef HESIOD
+#ifndef ZEPHYR_USES_HESIOD
static int nhosts = 0;
@@ -1179,40 +1021,46 @@ static int nhosts = 0;
static char **
get_server_list(file)
- char *file;
+ char *file;
{
- FILE *fp;
- char buf[MAXHOSTNAMELEN];
- char **ret_list;
- int nused = 0;
- char *newline;
-
- if (!(fp = fopen(file, "r")))
- return((char **)0);
-
- /* start with 16, realloc if necessary */
- nhosts = 16;
- ret_list = (char **)xmalloc(nhosts * sizeof(char *));
-
+ FILE *fp;
+ char buf[MAXHOSTNAMELEN];
+ char **ret_list;
+ int nused = 0;
+ char *newline;
+
+ /* start with 16, realloc if necessary */
+ nhosts = 16;
+ ret_list = (char **) malloc(nhosts * sizeof(char *));
+
+ fp = fopen(file, "r");
+ if (fp) {
while (fgets(buf, MAXHOSTNAMELEN, fp)) {
- /* nuke the newline, being careful not to overrun
- the buffer searching for it with strlen() */
- buf[MAXHOSTNAMELEN - 1] = '\0';
- if (newline = index(buf, '\n'))
- *newline = '\0';
-
- if (nused+1 >= nhosts) {
- /* get more pointer space if necessary */
- /* +1 to leave room for null pointer */
- ret_list = (char **)realloc((char *)ret_list,
- (unsigned) nhosts * 2);
- nhosts = nhosts * 2;
- }
- ret_list[nused++] = strsave (buf);
- }
- (void) fclose(fp);
- ret_list[nused] = (char *)0;
- return(ret_list);
+ /* nuke the newline, being careful not to overrun
+ the buffer searching for it with strlen() */
+ buf[MAXHOSTNAMELEN - 1] = '\0';
+ newline = strchr(buf, '\n');
+ if (newline)
+ *newline = '\0';
+
+ if (nused + 1 >= nhosts) {
+ /* get more pointer space if necessary */
+ /* +1 to leave room for null pointer */
+ ret_list = (char **) realloc(ret_list, nhosts * 2);
+ nhosts = nhosts * 2;
+ }
+ ret_list[nused++] = strsave(buf);
+ }
+ fclose(fp);
+ } else {
+ if (gethostname(buf, sizeof(buf)) < 0) {
+ free(ret_list);
+ return NULL;
+ }
+ ret_list[nused++] = strsave(buf);
+ }
+ ret_list[nused] = NULL;
+ return ret_list;
}
/*
@@ -1220,16 +1068,16 @@ get_server_list(file)
*/
static void
free_server_list(list)
- register char **list;
+ char **list;
{
- char **orig_list = list;
+ char **orig_list = list;
- if (!nhosts) /* nothing allocated */
- return;
- for (; *list; list++)
- xfree(*list);
- xfree(orig_list);
+ if (!nhosts) /* nothing allocated */
return;
+ for (; *list; list++)
+ free(*list);
+ free(orig_list);
+ return;
}
#endif
@@ -1238,37 +1086,22 @@ free_server_list(list)
* to go off immediately to send hello's to other servers.
*/
-STATIC void
+static void
setup_server(server, addr)
- register ZServerDesc_t *server;
- struct in_addr *addr;
+ Server *server;
+ struct in_addr *addr;
{
- register ZHostList_t *host;
-
- server->zs_state = SERV_DEAD;
- server->zs_timeout = timo_dead;
- server->zs_numsent = 0;
- server->zs_addr.sin_family = AF_INET;
- /* he listens to the same port we do */
- server->zs_addr.sin_port = sock_sin.sin_port;
- server->zs_addr.sin_addr = *addr;
- strcpy (server->addr, inet_ntoa (*addr));
-
- /* set up a timer for this server */
- server->zs_timer = timer_set_rel(0L, server_timo, (void *) server);
- host = (ZHostList_t *) xmalloc(sizeof(ZHostList_t));
- if (!host) {
- /* unrecoverable */
- syslog(LOG_CRIT, "zs_host alloc");
- abort();
- }
- host->q_forw = host->q_back = host;
- server->zs_hosts = host;
-
- server->zs_update_queue = NULLZSPT;
- server->zs_dumping = 0;
-
- return;
+ server->state = SERV_DEAD;
+ server->timeout = timo_dead;
+ server->num_hello_sent = 0;
+ server->addr.sin_family = AF_INET;
+ /* he listens to the same port we do */
+ server->addr.sin_port = srv_addr.sin_port;
+ server->addr.sin_addr = *addr;
+ strcpy(server->addr_str, inet_ntoa(*addr));
+ server->timer = timer_set_rel(0L, server_timo, server);
+ server->queue = NULL;
+ server->dumping = 0;
}
/*
@@ -1277,62 +1110,61 @@ setup_server(server, addr)
static void
hello_respond(who, adj, auth)
- struct sockaddr_in *who;
- int adj;
- int auth;
+ struct sockaddr_in *who;
+ int adj;
+ int auth;
{
- register ZServerDesc_t *which;
+ Server *which;
#if 0
- zdbug((LOG_DEBUG, "hello from %s", inet_ntoa(who->sin_addr)));
+ zdbug((LOG_DEBUG, "hello from %s", inet_ntoa(who->sin_addr)));
#endif
- send_msg(who, ADMIN_IMHERE, auth);
- if (adj != ADJUST)
- return;
-
- /* If we think he's down, schedule an immediate HELLO. */
-
- if (!(which = server_which_server(who)))
- return;
-
- switch (which->zs_state) {
- case SERV_DEAD:
- /* he said hello, we thought he was dead.
- reschedule his hello for now. */
- timer_reset(which->zs_timer);
- which->zs_timer = timer_set_rel(0L, server_timo,
- (void *) which);
- break;
- case SERV_STARTING:
- case SERV_TARDY:
- case SERV_UP:
- default:
- break;
- }
+ send_msg(who, ADMIN_IMHERE, auth);
+ if (adj != ADJUST)
+ return;
+
+ /* If we think he's down, schedule an immediate HELLO. */
+
+ which = server_which_server(who);
+ if (!which)
return;
+
+ switch (which->state) {
+ case SERV_DEAD:
+ /* he said hello, we thought he was dead.
+ reschedule his hello for now. */
+ timer_reset(which->timer);
+ which->timer = timer_set_rel(0L, server_timo, which);
+ break;
+ case SERV_STARTING:
+ case SERV_TARDY:
+ case SERV_UP:
+ default:
+ break;
+ }
}
/*
* return the server descriptor for server at who
*/
-ZServerDesc_t *
+Server *
server_which_server(who)
- struct sockaddr_in *who;
+ struct sockaddr_in *who;
{
- register ZServerDesc_t *server;
- register int i;
+ Server *server;
+ int i;
- if (who->sin_port != sock_sin.sin_port)
- return(NULLZSDT);
+ if (who->sin_port != srv_addr.sin_port)
+ return NULL;
- /* don't check limbo */
- for (server = &otherservers[1], i = 1; i < nservers; i++, server++) {
- if (server->zs_addr.sin_addr.s_addr == who->sin_addr.s_addr)
- return(server);
- }
- return(NULLZSDT);
+ /* don't check limbo */
+ for (server = &otherservers[1], i = 1; i < nservers; i++, server++) {
+ if (server->addr.sin_addr.s_addr == who->sin_addr.s_addr)
+ return server;
+ }
+ return NULL;
}
/*
@@ -1341,52 +1173,50 @@ server_which_server(who)
*/
static void
srv_responded(who)
- struct sockaddr_in *who;
+ struct sockaddr_in *who;
{
- register ZServerDesc_t *which = server_which_server(who);
+ Server *which = server_which_server(who);
#if 0
- zdbug((LOG_DEBUG, "srv_responded %s", inet_ntoa(who->sin_addr)));
+ zdbug((LOG_DEBUG, "srv_responded %s", inet_ntoa(who->sin_addr)));
#endif
- if (!which) {
- syslog(LOG_ERR, "hello input from non-server?!");
- return;
- }
+ if (!which) {
+ syslog(LOG_ERR, "hello input from non-server?!");
+ return;
+ }
- switch (which->zs_state) {
- case SERV_DEAD:
- /* he responded, we thought he was dead. mark as starting
- and negotiate */
- which->zs_state = SERV_STARTING;
- which->zs_timeout = timo_tardy;
- timer_reset(which->zs_timer);
- which->zs_timer = timer_set_rel(0L, server_timo,
- (void *) which);
-
- case SERV_STARTING:
- /* here we negotiate and set up a braindump */
- if (bdump_socket < 0) {
- /* XXX offer it to the other server */
- bdump_offer(who);
- }
- break;
- case SERV_TARDY:
- which->zs_state = SERV_UP;
- case SERV_UP:
- /* reset the timer and counts */
- which->zs_numsent = 0;
- which->zs_timeout = timo_up;
- timer_reset(which->zs_timer);
- which->zs_timer = timer_set_rel(which->zs_timeout, server_timo,
- (void *) which);
- break;
- }
+ switch (which->state) {
+ case SERV_DEAD:
+ /* he responded, we thought he was dead. mark as starting
+ and negotiate */
+ which->state = SERV_STARTING;
+ which->timeout = timo_tardy;
+ timer_reset(which->timer);
+ which->timer = timer_set_rel(0L, server_timo, which);
+
+ case SERV_STARTING:
+ /* here we negotiate and set up a braindump */
+ if (bdump_socket < 0)
+ bdump_offer(who);
+ break;
+
+ case SERV_TARDY:
+ which->state = SERV_UP;
+ /* Fall through. */
+
+ case SERV_UP:
+ /* reset the timer and counts */
+ which->num_hello_sent = 0;
+ which->timeout = timo_up;
+ timer_reset(which->timer);
+ which->timer = timer_set_rel(which->timeout, server_timo, which);
+ break;
+ }
#if 0
- zdbug((LOG_DEBUG, "srv %s is %s", which->addr,
- srv_states[(int) which->zs_state]));
+ zdbug((LOG_DEBUG, "srv %s is %s", which->addr_str,
+ srv_states[which->state]));
#endif
- return;
}
/*
@@ -1396,13 +1226,11 @@ srv_responded(who)
void
server_shutdown()
{
- register int i;
+ int i;
- /* don't tell limbo to go away, start at 1*/
- for (i = 1; i < nservers; i++) {
- send_msg(&otherservers[i].zs_addr, ADMIN_SHUTDOWN, 1);
- }
- return;
+ /* don't tell limbo to go away, start at 1*/
+ for (i = 1; i < nservers; i++)
+ send_msg(&otherservers[i].addr, ADMIN_SHUTDOWN, 1);
}
/*
@@ -1412,54 +1240,50 @@ server_shutdown()
static void
send_msg(who, opcode, auth)
- struct sockaddr_in *who;
- char *opcode;
- int auth;
+ struct sockaddr_in *who;
+ char *opcode;
+ int auth;
{
- ZNotice_t notice;
- register ZNotice_t *pnotice; /* speed hack */
- char *pack;
- int packlen;
- Code_t retval;
-
- pnotice = &notice;
-
- pnotice->z_kind = ACKED;
-
- pnotice->z_port = sock_sin.sin_port;
- pnotice->z_class = ZEPHYR_ADMIN_CLASS;
- pnotice->z_class_inst = "";
- pnotice->z_opcode = opcode;
- pnotice->z_sender = myname; /* myname is the hostname */
- pnotice->z_recipient = "";
- pnotice->z_default_format = "";
- pnotice->z_message = (caddr_t) NULL;
- pnotice->z_message_len = 0;
- pnotice->z_num_other_fields = 0;
-
- /* XXX for now, we don't do authentication */
- auth = 0;
-
- if ((retval = ZFormatNotice(pnotice, &pack, &packlen,
- auth ? ZAUTH : ZNOAUTH)) != ZERR_NONE) {
- syslog(LOG_WARNING, "snd_msg format: %s",
- error_message(retval));
- return;
- }
- if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "snd_msg set addr: %s",
- error_message(retval));
- xfree(pack); /* free allocated storage */
- return;
- }
- /* don't wait for ack */
- if ((retval = ZSendPacket(pack, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "snd_msg xmit: %s", error_message(retval));
- xfree(pack); /* free allocated storage */
- return;
- }
- xfree(pack); /* free allocated storage */
+ ZNotice_t notice;
+ ZNotice_t *pnotice; /* speed hack */
+ char *pack;
+ int packlen;
+ Code_t retval;
+
+ pnotice = &notice;
+
+ pnotice->z_kind = ACKED;
+
+ pnotice->z_port = srv_addr.sin_port;
+ pnotice->z_class = ZEPHYR_ADMIN_CLASS;
+ pnotice->z_class_inst = "";
+ pnotice->z_opcode = opcode;
+ pnotice->z_sender = myname; /* myname is the hostname */
+ pnotice->z_recipient = "";
+ pnotice->z_default_format = "";
+ pnotice->z_message = NULL;
+ pnotice->z_message_len = 0;
+ pnotice->z_num_other_fields = 0;
+
+ /* XXX for now, we don't do authentication */
+ auth = 0;
+
+ retval = ZFormatNotice(pnotice, &pack, &packlen, auth ? ZAUTH : ZNOAUTH);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "snd_msg format: %s", error_message(retval));
+ return;
+ }
+ retval = ZSetDestAddr(who);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "snd_msg set addr: %s", error_message(retval));
+ free(pack);
return;
+ }
+ /* don't wait for ack */
+ retval = ZSendPacket(pack, packlen, 0);
+ if (retval != ZERR_NONE)
+ syslog(LOG_WARNING, "snd_msg xmit: %s", error_message(retval));
+ free(pack);
}
/*
@@ -1471,83 +1295,48 @@ send_msg(who, opcode, auth)
*/
static void
-send_msg_list(who, opcode, lyst, num, auth, server_idx)
- struct sockaddr_in *who;
- char *opcode;
- char **lyst;
- int num;
- int auth;
- int server_idx;
+send_msg_list(who, opcode, lyst, num, auth)
+ struct sockaddr_in *who;
+ char *opcode;
+ char **lyst;
+ int num;
+ int auth;
{
- ZNotice_t notice;
- register ZNotice_t *pnotice; /* speed hack */
- char *pack;
- int packlen;
- Code_t retval;
- register ZNotAcked_t *nacked;
-
- pnotice = &notice;
-
- pnotice->z_kind = UNSAFE;
-
- pnotice->z_port = sock_sin.sin_port;
- pnotice->z_class = ZEPHYR_ADMIN_CLASS;
- pnotice->z_class_inst = "";
- pnotice->z_opcode = opcode;
- pnotice->z_sender = myname; /* myname is the hostname */
- pnotice->z_recipient = "";
- pnotice->z_default_format = "";
- pnotice->z_message = (caddr_t) NULL;
- pnotice->z_message_len = 0;
- pnotice->z_num_other_fields = 0;
-
- /* XXX for now, we don't do authentication */
- auth = 0;
-
- retval = ZFormatNoticeList (pnotice, lyst, num, &pack, &packlen,
- auth ? ZAUTH : ZNOAUTH);
- if (retval != ZERR_NONE) {
- syslog(LOG_WARNING, "snd_msg_lst format: %s",
- error_message(retval));
- return;
- }
- if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "snd_msg_lst set addr: %s",
- error_message(retval));
- xfree(pack); /* free allocated storage */
- return;
- }
- if ((retval = ZSendPacket(pack, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "snd_msg_lst xmit: %s", error_message(retval));
- xfree(pack); /* free allocated storage */
- return;
- }
-
- if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) {
- /* no space: just punt */
- syslog(LOG_WARNING, "xmit nack malloc");
- xfree(pack);
- return;
- }
-
- nacked->na_rexmits = 0;
- nacked->na_packet = pack;
- nacked->na_packsz = packlen;
- nacked->na_uid = pnotice->z_uid;
- nacked->q_forw = nacked->q_back = nacked;
- nacked->na_abstimo = NOW + abs_timo;
-
- /* Set the address and chain into the appropriate queue. */
- if (server_idx < 0) {
- nacked->na_addr = *who;
- nacked->na_timer = timer_set_rel(rexmit_secs, rexmit, nacked);
- xinsque(nacked, nacklist);
- } else {
- nacked->na_srv_idx = server_idx;
- nacked->na_timer = timer_set_rel(srv_rexmit_secs, srv_rexmit,
- nacked);
- xinsque(nacked, srv_nacklist);
- }
+ ZNotice_t notice;
+ char *pack;
+ int packlen;
+ Code_t retval;
+ Unacked *nacked;
+
+ notice.z_kind = UNSAFE;
+ notice.z_port = srv_addr.sin_port;
+ notice.z_class = ZEPHYR_ADMIN_CLASS;
+ notice.z_class_inst = "";
+ notice.z_opcode = opcode;
+ notice.z_sender = myname; /* myname is the hostname */
+ notice.z_recipient = "";
+ notice.z_default_format = "";
+ notice.z_message = NULL;
+ notice.z_message_len = 0;
+ notice.z_num_other_fields = 0;
+
+ /* XXX for now, we don't do authentication */
+ auth = 0;
+
+ retval = ZFormatNoticeList(&notice, lyst, num, &pack, &packlen,
+ auth ? ZAUTH : ZNOAUTH);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "snd_msg_lst format: %s", error_message(retval));
+ return;
+ }
+ retval = ZSetDestAddr(who);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "snd_msg_lst set addr: %s", error_message(retval));
+ free(pack);
+ return;
+ }
+ xmit_frag(&notice, pack, packlen, 0);
+ free(pack);
}
/*
@@ -1556,125 +1345,116 @@ send_msg_list(who, opcode, lyst, num, auth, server_idx)
/*ARGSUSED*/
void
server_forward(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
{
- register int i;
- caddr_t pack;
- int packlen;
- Code_t retval;
+ int i;
+ caddr_t pack;
+ int packlen;
+ Code_t retval;
#if 0
- zdbug((LOG_DEBUG, "srv_forw"));
+ zdbug((LOG_DEBUG, "srv_forw"));
#endif
- /* don't send to limbo */
- for (i = 1; i < nservers; i++) {
- if (i == me_server_idx) /* don't xmit to myself */
- continue;
- if (otherservers[i].zs_state == SERV_DEAD &&
- otherservers[i].zs_dumping == 0)
- /* if we are dumping to him, we want to
- queue it, even if he's dead */
- continue;
-
- if (!(pack = (caddr_t) xmalloc(sizeof(ZPacket_t)))) {
- syslog(LOG_CRIT, "srv_fwd malloc");
- abort();
- }
- if ((retval = ZFormatSmallRawNotice(notice, pack, &packlen)) != ZERR_NONE) {
- syslog(LOG_WARNING, "srv_fwd format: %s",
- error_message(retval));
- continue;
- }
- if (otherservers[i].zs_dumping) {
- server_queue(&(otherservers[i]), packlen, pack,
- auth, who);
- continue;
- }
- server_forw_reliable(&otherservers[i], pack, packlen, notice);
+ /* don't send to limbo */
+ for (i = 1; i < nservers; i++) {
+ if (i == me_server_idx) /* don't xmit to myself */
+ continue;
+ if (otherservers[i].state == SERV_DEAD &&
+ otherservers[i].dumping == 0) {
+ /* if we are dumping to him, we want to
+ queue it, even if he's dead */
+ continue;
+ }
+
+ pack = malloc(sizeof(ZPacket_t));
+ if (!pack) {
+ syslog(LOG_CRIT, "srv_fwd malloc");
+ abort();
+ }
+ retval = ZFormatSmallRawNotice(notice, pack, &packlen);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "srv_fwd format: %s", error_message(retval));
+ continue;
}
- return;
+ if (otherservers[i].dumping) {
+ server_queue(&otherservers[i], packlen, pack, auth, who);
+ continue;
+ }
+ server_forw_reliable(&otherservers[i], pack, packlen, notice);
+ }
}
-STATIC void
+static void
server_forw_reliable(server, pack, packlen, notice)
- ZServerDesc_t *server;
- caddr_t pack;
- int packlen;
- ZNotice_t *notice;
+ Server *server;
+ caddr_t pack;
+ int packlen;
+ ZNotice_t *notice;
{
- Code_t retval;
- register ZNotAcked_t *nacked;
-
- if ((retval = ZSetDestAddr(&server->zs_addr)) != ZERR_NONE) {
- syslog(LOG_WARNING, "srv_fwd_rel set addr: %s",
- error_message(retval));
- xfree(pack);
- return;
- }
- if ((retval = ZSendPacket(pack, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "srv_fwd xmit: %s", error_message(retval));
- xfree(pack);
- return;
- }
- /* now we've sent it, mark it as not ack'ed */
+ Code_t retval;
+ Unacked *nacked;
+ int hashval;
+
+ retval = ZSetDestAddr(&server->addr);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "srv_fwd_rel set addr: %s", error_message(retval));
+ free(pack);
+ return;
+ }
+ retval = ZSendPacket(pack, packlen, 0);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "srv_fwd xmit: %s", error_message(retval));
+ free(pack);
+ return;
+ }
+ /* now we've sent it, mark it as not ack'ed */
- if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) {
- /* no space: just punt */
- syslog(LOG_ERR, "srv_forw_rel nack malloc");
- xfree(pack);
- return;
- }
-
- nacked->na_rexmits = 0;
- nacked->na_packet = pack;
- nacked->na_srv_idx = server - otherservers;
- nacked->na_packsz = packlen;
- nacked->na_uid = notice->z_uid;
- nacked->q_forw = nacked->q_back = nacked;
- nacked->na_abstimo = 0;
-
- /* set a timer to retransmit */
- nacked->na_timer = timer_set_rel(srv_rexmit_secs,
- srv_rexmit,
- (void *) nacked);
- /* chain in */
- xinsque(nacked, srv_nacklist);
+ nacked = (Unacked *) malloc(sizeof(Unacked));
+ if (!nacked) {
+ /* no space: just punt */
+ syslog(LOG_ERR, "srv_forw_rel nack malloc");
+ free(pack);
return;
+ }
+
+ nacked->rexmits = 0;
+ nacked->packet = pack;
+ nacked->dest.srv_idx = server - otherservers;
+ nacked->packsz = packlen;
+ nacked->uid = notice->z_uid;
+ nacked->timer = timer_set_rel(rexmit_times[0], srv_rexmit, nacked);
+ hashval = SRV_NACKTAB_HASHVAL(nacked->dest.srv_idx, nacked->uid);
+ LIST_INSERT(&srv_nacktab[hashval], nacked);
}
-#ifdef CONCURRENT
/*
* send the queued message for the server.
*/
void
server_send_queue(server)
- ZServerDesc_t *server;
+ Server *server;
{
- register ZSrvPending_t *pending;
- ZNotice_t notice;
- Code_t status;
-
- while(server->zs_update_queue) {
- pending = server_dequeue(server);
- if ((status = ZParseNotice(pending->pend_packet,
- pending->pend_len,
- &notice)) != ZERR_NONE) {
- syslog(LOG_ERR,
- "ssq bad notice parse (%s): %s",
- inet_ntoa(pending->pend_who.sin_addr),
- error_message(status));
- } else {
- server_forw_reliable(server, pending->pend_packet,
- pending->pend_len, &notice);
- xfree(pending);
- /* ACK handling routines will free the packet */
- }
+ Pending *pending;
+ ZNotice_t notice;
+ Code_t status;
+
+ while (server->queue) {
+ pending = server_dequeue(server);
+ status = ZParseNotice(pending->packet, pending->len, &notice);
+ if (status != ZERR_NONE) {
+ syslog(LOG_ERR, "ssq bad notice parse (%s): %s",
+ inet_ntoa(pending->who.sin_addr), error_message(status));
+ } else {
+ server_forw_reliable(server, pending->packet, pending->len,
+ &notice);
+ free(pending);
+ /* ACK handling routines will free the packet */
}
+ }
}
-#endif
/*
* a server has acknowledged a message we sent to him; remove it from
@@ -1683,82 +1463,75 @@ server_send_queue(server)
static void
srv_nack_cancel(notice, who)
- register ZNotice_t *notice;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
{
- register ZServerDesc_t *which = server_which_server(who);
- register ZNotAcked_t *nacked;
+ Server *server = server_which_server(who);
+ Unacked *nacked;
+ int hashval;
- if (!which) {
- syslog(LOG_ERR, "non-server ack?");
- return;
+ if (!server) {
+ syslog(LOG_ERR, "non-server ack?");
+ return;
+ }
+ hashval = SRV_NACKTAB_HASHVAL(server - otherservers, notice->z_uid);
+ for (nacked = srv_nacktab[hashval]; nacked; nacked = nacked->next) {
+ if (nacked->dest.srv_idx == server - otherservers
+ && ZCompareUID(&nacked->uid, &notice->z_uid)) {
+ timer_reset(nacked->timer);
+ free(nacked->packet);
+ LIST_DELETE(nacked);
+ free(nacked);
+ return;
}
- for (nacked = srv_nacklist->q_forw;
- nacked != srv_nacklist;
- nacked = nacked->q_forw)
- if (&otherservers[nacked->na_srv_idx] == which)
- if (ZCompareUID(&nacked->na_uid, &notice->z_uid)) {
- timer_reset(nacked->na_timer);
- xfree(nacked->na_packet);
- xremque(nacked);
- xfree(nacked);
- return;
- }
+ }
#if 0
- zdbug((LOG_DEBUG, "srv_nack not found"));
+ zdbug((LOG_DEBUG, "srv_nack not found"));
#endif
- return;
}
/*
* retransmit a message to another server
*/
-STATIC void
-#ifdef __STDC__
-srv_rexmit(void *arg)
-#else
+static void
srv_rexmit(arg)
- void *arg;
-#endif
+ void *arg;
{
- ZNotAcked_t *nackpacket = (ZNotAcked_t *) arg;
- Code_t retval;
- /* retransmit the packet */
+ Unacked *packet = (Unacked *) arg;
+ Code_t retval;
+ /* retransmit the packet */
#if 0
- zdbug((LOG_DEBUG,"srv_rexmit to %s/%d",
- otherservers[nackpacket->na_srv_idx].addr,
- ntohs(otherservers[nackpacket->na_srv_idx].zs_addr.sin_port)));
+ zdbug((LOG_DEBUG,"srv_rexmit to %s/%d",
+ otherservers[packet->dest.srv_idx].addr_str,
+ ntohs(otherservers[packet->dest.srv_idx].addr.sin_port)));
#endif
- if (otherservers[nackpacket->na_srv_idx].zs_state == SERV_DEAD) {
+ if (otherservers[packet->dest.srv_idx].state == SERV_DEAD) {
#if 0
- zdbug((LOG_DEBUG, "cancelling send to dead server"));
+ zdbug((LOG_DEBUG, "cancelling send to dead server"));
#endif
- xremque(nackpacket);
- xfree(nackpacket->na_packet);
- srv_nack_release(&otherservers[nackpacket->na_srv_idx]);
- xfree(nackpacket);
- return;
- }
- retval = ZSetDestAddr(&otherservers[nackpacket->na_srv_idx].zs_addr);
- if (retval != ZERR_NONE) {
- syslog(LOG_WARNING, "srv_rexmit set addr: %s",
- error_message(retval));
- goto requeue;
-
- }
- if ((retval = ZSendPacket(nackpacket->na_packet,
- nackpacket->na_packsz, 0)) != ZERR_NONE)
- syslog(LOG_WARNING, "srv_rexmit xmit: %s",
- error_message(retval));
-
-requeue:
- /* reset the timer */
- nackpacket->na_timer = timer_set_rel(srv_rexmit_secs,
- srv_rexmit,
- (void *) nackpacket);
+ LIST_DELETE(packet);
+ free(packet->packet);
+ srv_nack_release(&otherservers[packet->dest.srv_idx]);
+ free(packet);
return;
+ }
+ retval = ZSetDestAddr(&otherservers[packet->dest.srv_idx].addr);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "srv_rexmit set addr: %s", error_message(retval));
+ } else {
+ retval = ZSendPacket(packet->packet, packet->packsz, 0);
+ if (retval != ZERR_NONE)
+ syslog(LOG_WARNING, "srv_rexmit xmit: %s",
+ error_message(retval));
+ }
+
+ /* reset the timer */
+ if (rexmit_times[packet->rexmits + 1] != -1)
+ packet->rexmits++;
+ packet->timer = timer_set_rel(rexmit_times[packet->rexmits], srv_rexmit,
+ packet);
}
/*
@@ -1768,29 +1541,22 @@ requeue:
static void
srv_nack_release(server)
- ZServerDesc_t *server;
+ Server *server;
{
- /* XXX release any private queue for this server */
-
- register ZNotAcked_t *nacked, *nack2;
-
- /* search the not-yet-acked list for anything destined to him, and
- flush it. */
- for (nacked = srv_nacklist->q_forw;
- nacked != srv_nacklist;)
- if (&otherservers[nacked->na_srv_idx] == server) {
- /* go back, since remque will change things */
- nack2 = nacked->q_back;
- timer_reset(nacked->na_timer);
- xremque(nacked);
- xfree(nacked->na_packet);
- xfree(nacked);
- /* now that the remque adjusted the linked list,
- we go forward again */
- nacked = nack2->q_forw;
- } else
- nacked = nacked->q_forw;
- return;
+ int i;
+ Unacked *nacked, *next;
+
+ for (i = 0; i < SRV_NACKTAB_HASHSIZE; i++) {
+ for (nacked = srv_nacktab[i]; nacked; nacked = next) {
+ next = nacked->next;
+ if (nacked->dest.srv_idx == server - otherservers) {
+ timer_reset(nacked->timer);
+ LIST_DELETE(nacked);
+ free(nacked->packet);
+ free(nacked);
+ }
+ }
+ }
}
/*
@@ -1800,23 +1566,24 @@ srv_nack_release(server)
static void
srv_nack_renumber (new_idx)
- register int* new_idx;
+ int *new_idx;
{
/* XXX release any private queue for this server */
-
- register ZNotAcked_t *nacked;
+ Unacked *nacked;
+ int idx, i;
/* search the not-yet-acked list for anything destined to 'from', and
change the index to 'to'. */
- for (nacked = srv_nacklist->q_forw; nacked != srv_nacklist;) {
- int idx = new_idx[nacked->na_srv_idx];
- if (idx < 0) {
- syslog (LOG_ERR,
- "srv_nack_renumber error: [%d]=%d",
- nacked->na_srv_idx, idx);
- idx = 0;
+ for (i = 0; i < SRV_NACKTAB_HASHSIZE; i++) {
+ for (nacked = srv_nacktab[i]; nacked; nacked = nacked->next) {
+ idx = new_idx[nacked->dest.srv_idx];
+ if (idx < 0) {
+ syslog(LOG_ERR, "srv_nack_renumber error: [%d]=%d",
+ nacked->dest.srv_idx, idx);
+ idx = 0;
+ }
+ nacked->dest.srv_idx = idx;
}
- nacked->na_srv_idx = idx;
}
}
@@ -1825,58 +1592,47 @@ srv_nack_renumber (new_idx)
*/
static void
server_queue(server, len, pack, auth, who)
- ZServerDesc_t *server;
- int len;
- caddr_t pack;
- int auth;
- struct sockaddr_in *who;
+ Server *server;
+ int len;
+ void *pack;
+ int auth;
+ struct sockaddr_in *who;
{
- register ZSrvPending_t *pending;
-
- if (!server->zs_update_queue) {
- if (!(pending =
- (ZSrvPending_t *)xmalloc(sizeof(ZSrvPending_t)))) {
- syslog(LOG_CRIT, "zs_update_queue head malloc");
- abort();
- }
- pending->q_forw = pending->q_back = pending;
- server->zs_update_queue = pending;
- }
- if (!(pending = (ZSrvPending_t *)xmalloc(sizeof(ZSrvPending_t)))) {
- syslog(LOG_CRIT, "zs_update_queue malloc");
- abort();
- }
- pending->pend_packet = pack;
- pending->pend_len = len;
- pending->pend_auth = auth;
- pending->pend_who = *who;
+ Pending *pending;
- /* put it on the end of the list */
- xinsque(pending, server->zs_update_queue->q_back);
- return;
+ pending = (Pending *) malloc(sizeof(Pending));
+ if (!pending) {
+ syslog(LOG_CRIT, "update_queue malloc");
+ abort();
+ }
+ pending->packet = pack;
+ pending->len = len;
+ pending->auth = auth;
+ pending->who = *who;
+ pending->next = NULL;
+
+ /* put it on the end of the list */
+ if (server->queue)
+ server->queue_last->next = pending;
+ else
+ server->queue = server->queue_last = pending;
}
/*
* Pull a notice off the hold queue.
*/
-ZSrvPending_t *
+Pending *
server_dequeue(server)
- register ZServerDesc_t *server;
+ Server *server;
{
- ZSrvPending_t *pending;
+ Pending *pending;
- if (!server->zs_update_queue)
- return(NULLZSPT);
- pending = server->zs_update_queue->q_forw;
- /* pull it off */
- xremque(pending);
- if (server->zs_update_queue->q_forw == server->zs_update_queue) {
- /* empty queue now */
- xfree(server->zs_update_queue);
- server->zs_update_queue = NULLZSPT;
- }
- return(pending);
+ if (!server->queue)
+ return NULL;
+ pending = server->queue;
+ server->queue = pending->next;
+ return pending;
}
/*
@@ -1885,38 +1641,34 @@ server_dequeue(server)
void
server_pending_free(pending)
- register ZSrvPending_t *pending;
+ Pending *pending;
{
- xfree(pending->pend_packet);
- xfree(pending);
- return;
+ free(pending->packet);
+ free(pending);
+ return;
}
-#ifdef CONCURRENT
/*
* Queue something to be handled later by this server.
*/
void
server_self_queue(notice, auth, who)
- ZNotice_t* notice;
- int auth;
- struct sockaddr_in * who;
+ ZNotice_t* notice;
+ int auth;
+ struct sockaddr_in * who;
{
- caddr_t pack;
- int packlen;
- Code_t retval;
-
- if ((retval = ZFormatRawNotice(notice, &pack, &packlen))
- != ZERR_NONE) {
- syslog(LOG_CRIT, "srv_self_queue format: %s",
- error_message(retval));
- abort();
- }
- server_queue(me_server, packlen, pack, auth, who);
- return;
+ char *pack;
+ int packlen;
+ Code_t retval;
+
+ retval = ZFormatRawNotice(notice, &pack, &packlen);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_CRIT, "srv_self_queue format: %s", error_message(retval));
+ abort();
+ }
+ server_queue(me_server, packlen, pack, auth, who);
}
-#endif
/*
* dump info about servers onto the fp.
@@ -1925,16 +1677,14 @@ server_self_queue(notice, auth, who)
*/
void
server_dump_servers(fp)
- FILE *fp;
+ FILE *fp;
{
- register int i;
-
- for (i = 0; i < nservers ; i++) {
- (void) fprintf(fp, "%d:%s/%s%s\n",
- i, otherservers[i].addr,
- srv_states[(int) otherservers[i].zs_state],
- otherservers[i].zs_dumping ? " (DUMPING)" : "");
- }
+ int i;
- return;
+ for (i = 0; i < nservers ; i++) {
+ fprintf(fp, "%d:%s/%s%s\n", i, otherservers[i].addr_str,
+ srv_states[otherservers[i].state],
+ otherservers[i].dumping ? " (DUMPING)" : "");
+ }
}
+
diff --git a/server/subscr.c b/server/subscr.c
index 742adda..c305c70 100644
--- a/server/subscr.c
+++ b/server/subscr.c
@@ -12,10 +12,11 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
#ifndef lint
#ifndef SABER
-static char rcsid_subscr_c[] = "$Id$";
+static const char rcsid_subscr_c[] = "$Id$";
#endif
#endif
@@ -25,7 +26,7 @@ static char rcsid_subscr_c[] = "$Id$";
* External functions:
*
* Code_t subscr_subscribe(who, notice)
- * ZClient_t *who;
+ * Client *who;
* ZNotice_t *notice;
*
* Code_t subscr_cancel(sin, notice)
@@ -33,16 +34,16 @@ static char rcsid_subscr_c[] = "$Id$";
* ZNotice_t *notice;
*
* Code_t subscr_cancel_client(client)
- * ZClient_t *client;
+ * Client *client;
*
* Code_t subscr_cancel_host(addr)
* struct in_addr *addr;
*
- * ZClientList_t *subscr_match_list(notice)
+ * Client *subscr_match_list(notice)
* ZNotice_t *notice;
*
* void subscr_free_list(list)
- * ZClientList_t *list;
+ * Client *list;
*
* void subscr_sendlist(notice, auth, who)
* ZNotice_t *notice;
@@ -50,28 +51,17 @@ static char rcsid_subscr_c[] = "$Id$";
* struct sockaddr_in *who;
*
* Code_t subscr_send_subs(client, vers)
- * ZClient_t *client;
+ * Client *client;
* char *vers;
*
* Code_t subscr_def_subs(who)
- * ZClient_t *who;
+ * Client *who;
*
* void subscr_reset();
*
*/
-#include "zserver.h"
-#include <ctype.h>
-#include <strings.h>
-#include <sys/stat.h>
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-#ifdef KERBEROS
+#ifdef ZEPHYR_USES_KERBEROS
#ifndef NOENCRYPTION
C_Block serv_key;
Sched serv_ksched;
@@ -83,36 +73,41 @@ Sched serv_ksched;
#ifdef OLD_COMPAT
#define OLD_ZEPHYR_VERSION "ZEPH0.0"
#define OLD_CLIENT_INCOMPSUBS "INCOMP"
-static void old_compat_subscr_sendlist P((ZNotice_t *notice, int auth,
+static void old_compat_subscr_sendlist __P((ZNotice_t *notice, int auth,
struct sockaddr_in *who));
extern int old_compat_count_subscr; /* counter of old use */
#endif /* OLD_COMPAT */
#ifdef NEW_COMPAT
#define NEW_OLD_ZEPHYR_VERSION "ZEPH0.1"
-static void new_old_compat_subscr_sendlist P((ZNotice_t *notice, int auth,
+static void new_old_compat_subscr_sendlist __P((ZNotice_t *notice, int auth,
struct sockaddr_in *who));
extern int new_compat_count_subscr; /* counter of old use */
#endif /* NEW_COMPAT */
extern char *re_comp(), *re_conv();
-static Code_t add_subscriptions P((ZClient_t *who, ZSubscr_t *subs_queue,
+static Code_t add_subscriptions __P((Client *who, Destlist *subs_queue,
ZNotice_t *notice));
-static ZSubscr_t *extract_subscriptions P((register ZNotice_t *notice));
-static void free_subscriptions P((register ZSubscr_t *subs));
-static char **subscr_marshal_subs P((ZNotice_t *notice, int auth,
+static Destlist *extract_subscriptions __P((ZNotice_t *notice));
+static void free_subscriptions __P((Destlist *subs));
+static char **subscr_marshal_subs __P((ZNotice_t *notice, int auth,
struct sockaddr_in *who,
- register int *found));
-static ZSubscr_t *subscr_copy_def_subs P((char *person));
-static int cl_match P((ZSubscr_t*, ZClient_t *));
+ int *found));
+static Destlist *subscr_copy_def_subs __P((char *person));
+static Code_t subscr_subscribe_realms __P((struct sockaddr_in *who,
+ Destlist *newsubs,
+ ZNotice_t *notice));
+static Code_t subscr_realm_sendit __P((Client *who, Destlist *subs,
+ ZNotice_t *notice, Realm *realm));
+static void subscr_unsub_realms __P((Destlist *newsubs));
+static void subscr_unsub_sendit __P((Destlist *subs, Realm *realm));
+static int cl_match __P((Destlist*, Client *));
static int defaults_read = 0; /* set to 1 if the default subs
are in memory */
static ZNotice_t default_notice; /* contains default subscriptions */
-#undef P
-
-ZSTRING *wildcard_instance;
-ZSTRING *empty;
+String *wildcard_instance;
+String *empty;
/* WARNING: make sure this is the same as the number of strings you */
/* plan to hand back to the user in response to a subscription check, */
@@ -125,105 +120,89 @@ ZSTRING *empty;
Code_t
subscr_subscribe(who, notice)
- ZClient_t *who;
- ZNotice_t *notice;
+ Client *who;
+ ZNotice_t *notice;
{
- ZSubscr_t *subs_queue, *sub;
- Code_t retval;
-
- if (!who->zct_subs) {
- /* allocate a subscription head */
- sub = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t));
- if (!sub)
- return(ENOMEM);
- sub->q_forw = sub->q_back = sub;
- sub->zst_dest.classname = sub->zst_dest.inst =
- sub->zst_dest.recip = NULL;
- who->zct_subs = sub;
- }
+ Destlist *subs;
- subs_queue = extract_subscriptions(notice);
- return(add_subscriptions(who, subs_queue, notice));
+ subs = extract_subscriptions(notice);
+ return add_subscriptions(who, subs, notice);
}
static Code_t
-add_subscriptions(who, subs_queue, notice)
- ZClient_t *who;
- ZSubscr_t *subs_queue;
- ZNotice_t *notice;
+add_subscriptions(who, subs, notice)
+ Client *who;
+ Destlist *subs;
+ ZNotice_t *notice;
{
- ZSubscr_t *sub, *next;
- Code_t retval;
- ZAcl_t *acl;
- ZSTRING *sender;
-
- if (!subs_queue)
- return(ZERR_NONE); /* no subscr -> no error */
+ Destlist *next;
+ Code_t retval;
+ Acl *acl;
+ String *sender;
+ Realm *realm = NULL;
- sender = make_zstring(notice->z_sender,0);
+ if (!subs)
+ return ZERR_NONE; /* no subscr -> no error */
- START_CRITICAL_CODE;
-
- /* Loop over the new subscriptions. */
- next = subs_queue->q_forw;
- while (next != subs_queue) {
- sub = next;
- next = sub->q_forw;
+ sender = make_string(notice->z_sender, 0);
+ /* Loop over the new subscriptions. */
+ for (; subs; subs = next) {
+ next = subs->next;
#if 0
- zdbug ((LOG_DEBUG, "subscr: %s/%s/%s",
- sub->zst_dest.classname->string,
- sub->zst_dest.inst->string,
- sub->zst_dest.recip->string));
+ zdbug ((LOG_DEBUG, "subscr: %s/%s/%s", subs->dest.classname->string,
+ subs->dest.inst->string, subs->dest.recip->string));
#endif
-
- if (!bdumping) {
- if ((sub->zst_dest.recip != empty)
- && (sub->zst_dest.recip != sender)) {
- syslog(LOG_WARNING, "subscr unauth %s recipient %s",
- sender->string,
- sub->zst_dest.recip->string);
+ if (!bdumping) {
+ if (subs->dest.recip != empty && subs->dest.recip != sender
+ && subs->dest.recip->string[0] != '@') {
+ syslog(LOG_WARNING, "subscr unauth %s recipient %s",
+ sender->string, subs->dest.recip->string);
+ continue;
+ }
+ acl = class_get_acl(subs->dest.classname);
+ if (acl) {
+ if (!access_check(sender->string, acl, SUBSCRIBE)) {
+ syslog(LOG_WARNING, "subscr unauth %s class %s",
+ sender->string, subs->dest.classname->string);
+ continue; /* the for loop */
+ }
+ if (wildcard_instance == subs->dest.inst) {
+ if (!access_check(sender->string, acl, INSTWILD)) {
+ syslog(LOG_WARNING,
+ "subscr unauth %s class %s wild inst",
+ sender->string, subs->dest.classname->string);
continue;
}
- acl = class_get_acl(sub->zst_dest.classname);
- if (acl) {
- if (!(access_check(sender->string, acl, SUBSCRIBE))) {
- syslog(LOG_WARNING,
- "subscr unauth %s class %s",
- sender->string,
- sub->zst_dest.classname->string);
- continue; /* the for loop */
- }
- if (wildcard_instance == sub->zst_dest.inst) {
- if (!access_check(sender->string, acl, INSTWILD)) {
- syslog(LOG_WARNING,
- "subscr unauth %s class %s wild inst",
- notice->z_sender,
- sub->zst_dest.classname->string);
- continue;
- }
- }
- }
}
- xremque(sub);
- retval = triplet_register(who, &sub->zst_dest);
- if (retval != ZERR_NONE) {
- xfree(sub);
- if (retval == ZSRV_CLASSXISTS) {
- continue;
- } else {
- free_subscriptions(subs_queue);
- END_CRITICAL_CODE;
- return(retval);
- }
- }
- xinsque(sub, who->zct_subs);
+ }
}
+ /* check the recipient for a realm which isn't ours */
+ realm = NULL;
+ if (subs->dest.recip->string[0] == '@' &&
+ strcmp((subs->dest.recip->string + 1), ZGetRealm()) != 0)
+ realm = realm_get_realm_by_name(subs->dest.recip->string + 1);
+ if (realm) {
+ retval = subscr_realm_sendit(who, subs, notice, realm);
+ if (retval != ZERR_NONE) {
+ free(subs);
+ return(retval);
+ }
+ }
+ retval = triplet_register(who, &subs->dest, realm);
+ if (retval != ZERR_NONE) {
+ free(subs);
+ if (retval == ZSRV_CLASSXISTS) {
+ continue;
+ } else {
+ free_subscriptions(next);
+ return retval;
+ }
+ }
+ LIST_INSERT(&who->subs, subs);
+ }
- END_CRITICAL_CODE;
-
- free_subscriptions(subs_queue);
- return(ZERR_NONE);
+ return ZERR_NONE;
}
/*
@@ -232,126 +211,101 @@ add_subscriptions(who, subs_queue, notice)
Code_t
subscr_def_subs(who)
- ZClient_t *who;
+ Client *who;
{
- ZSubscr_t *subs;
-
- if (!who->zct_subs) {
- /* allocate a subscription head */
- if (!(subs = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_ERR, "no mem subscr_def_subs");
- return(ENOMEM);
- }
- subs->q_forw = subs->q_back = subs;
- subs->zst_dest.classname = subs->zst_dest.inst =
- subs->zst_dest.recip = (ZSTRING *) NULL;
- who->zct_subs = subs;
- }
+ Destlist *subs;
- subs = subscr_copy_def_subs(who->zct_principal->string);
- return(add_subscriptions(who, subs, &default_notice));
+ subs = subscr_copy_def_subs(who->principal->string);
+ return add_subscriptions(who, subs, &default_notice);
}
void
subscr_reset()
{
#if 0
- zdbug((LOG_DEBUG, "subscr_reset()"));
+ zdbug((LOG_DEBUG, "subscr_reset()"));
#endif
- xfree(default_notice.z_message);
- default_notice.z_message = NULL;
- defaults_read = 0;
+ free(default_notice.z_message);
+ default_notice.z_message = NULL;
+ defaults_read = 0;
}
-static ZSubscr_t *
+static Destlist *
subscr_copy_def_subs(person)
- char *person;
+ char *person;
{
- int retval;
- int fd;
- struct stat statbuf;
- char *def_sub_area;
- register char *cp;
- ZSubscr_t *subs;
- register ZSubscr_t *subs2;
-
- if (!defaults_read) {
+ int retval, fd;
+ struct stat statbuf;
+ char *def_sub_area, *cp;
+ Destlist *subs, *sub;
+
+ if (!defaults_read) {
#if 0
- zdbug((LOG_DEBUG, "reading default subscription file"));
+ zdbug((LOG_DEBUG, "reading default subscription file"));
#endif
- fd = open(DEFAULT_SUBS_FILE, O_RDONLY, 0666);
- if (fd < 0) {
- syslog(LOG_ERR, "can't open %s:%m", DEFAULT_SUBS_FILE);
- return((ZSubscr_t *)0);
- }
- retval = fstat(fd, &statbuf);
- if (retval < 0) {
- syslog(LOG_ERR, "fstat failure on %s:%m",
- DEFAULT_SUBS_FILE);
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
- if (!(def_sub_area = (char *) xmalloc(statbuf.st_size + 1))) {
- syslog(LOG_ERR, "no mem copy_def_subs");
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
- retval = read(fd, def_sub_area, (int) statbuf.st_size);
- /*
- "Upon successful completion, read and readv return the number
- of bytes actually read and placed in the buffer. The system
- guarantees to read the number of bytes requested if the
- descriptor references a normal file that has that many bytes
- left before the end-of-file, but in no other case."
- -- read(2)
- Therefore, the following test is valid.
- */
- if (retval != statbuf.st_size) {
- syslog(LOG_ERR, "short read in copy_def_subs");
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
+ fd = open(subs_file, O_RDONLY, 0666);
+ if (fd < 0) {
+ syslog(LOG_ERR, "can't open %s:%m", subs_file);
+ return NULL;
+ }
+ retval = fstat(fd, &statbuf);
+ if (retval < 0) {
+ syslog(LOG_ERR, "fstat failure on %s:%m", subs_file);
+ close(fd);
+ return NULL;
+ }
+ def_sub_area = (char *) malloc(statbuf.st_size + 1);
+ if (!def_sub_area) {
+ syslog(LOG_ERR, "no mem copy_def_subs");
+ close(fd);
+ return NULL;
+ }
+ retval = read(fd, def_sub_area, (size_t) statbuf.st_size);
+ if (retval != statbuf.st_size) {
+ syslog(LOG_ERR, "short read in copy_def_subs");
+ close(fd);
+ return NULL;
+ }
+
+ close(fd);
+ def_sub_area[statbuf.st_size] = '\0'; /* null-terminate it */
+
+ /*
+ def_subs_area now points to a buffer full of subscription info.
+ Each line of the stuff is of the form:
+ class,inst,recipient
- (void) close(fd);
- def_sub_area[statbuf.st_size] = '\0'; /* null-terminate it */
-
- /*
- def_subs_area now points to a buffer full of subscription
- info.
- each line of the stuff is of the form:
- class,inst,recipient
-
- Commas and newlines may not appear as part of the class,
- instance, or recipient. XXX!
- */
-
- /* split up the subscription info */
- for (cp = def_sub_area;
- cp < def_sub_area + statbuf.st_size;
- cp++)
- if ((*cp == '\n') || (*cp == ','))
- *cp = '\0';
- default_notice.z_message = def_sub_area;
- default_notice.z_message_len = (int) statbuf.st_size + 1;
- default_notice.z_auth = 1;
- defaults_read = 1;
+ Commas and newlines may not appear as part of the class,
+ instance, or recipient. XXX!
+ */
+
+ /* split up the subscription info */
+ for (cp = def_sub_area; cp < def_sub_area + statbuf.st_size; cp++) {
+ if (*cp == '\n' || *cp == ',')
+ *cp = '\0';
}
- /* needed later for access_check() */
- default_notice.z_sender = person;
- subs = extract_subscriptions(&default_notice);
- /* replace any non-* recipients with "person" */
-
- for (subs2 = subs->q_forw; subs2 != subs; subs2 = subs2->q_forw) {
- /* if not a wildcard, replace it with person */
- if (strcmp(subs2->zst_dest.recip->string, "*")) {
- free_zstring(subs2->zst_dest.recip);
- subs2->zst_dest.recip = make_zstring(person,0);
- } else { /* replace with null recipient */
- free_zstring(subs2->zst_dest.recip);
- subs2->zst_dest.recip = dup_zstring(empty);
- }
+ default_notice.z_message = def_sub_area;
+ default_notice.z_message_len = statbuf.st_size + 1;
+ default_notice.z_auth = 1;
+ defaults_read = 1;
+ }
+
+ /* needed later for access_check() */
+ default_notice.z_sender = person;
+ subs = extract_subscriptions(&default_notice);
+ /* replace any non-* recipients with "person" */
+
+ for (sub = subs; sub; sub = sub->next) {
+ /* if not a wildcard, replace it with person */
+ if (strcmp(sub->dest.recip->string, "*")) {
+ free_string(sub->dest.recip);
+ sub->dest.recip = make_string(person, 0);
+ } else { /* replace with null recipient */
+ free_string(sub->dest.recip);
+ sub->dest.recip = dup_string(empty);
}
- return(subs);
+ }
+ return subs;
}
/*
@@ -360,161 +314,163 @@ subscr_copy_def_subs(person)
Code_t
subscr_cancel(sin, notice)
- struct sockaddr_in *sin;
- ZNotice_t *notice;
+ struct sockaddr_in *sin;
+ ZNotice_t *notice;
{
- ZClient_t *who;
- register ZSubscr_t *cancel_queue, *cancel, *sub;
- Code_t retval;
- int found = 0;
- int relation;
+ Realm *realm;
+ Client *who;
+ Destlist *cancel_subs, *subs, *cancel_next, *client_subs, *client_next;
+ Code_t retval;
+ int found = 0;
+ int relation;
#if 0
- zdbug((LOG_DEBUG,"subscr_cancel"));
+ zdbug((LOG_DEBUG,"subscr_cancel"));
#endif
- who = client_which_client(sin, notice);
- if (!who)
- return(ZSRV_NOCLT);
-
- if (!who->zct_subs)
- return(ZSRV_NOSUB);
-
- cancel_queue = extract_subscriptions(notice);
- if (!cancel_queue)
- return(ZERR_NONE); /* no subscr -> no error */
-
- START_CRITICAL_CODE;
-
- for (cancel = cancel_queue->q_forw; cancel != cancel_queue;
- cancel = cancel->q_forw) {
- for (sub = who->zct_subs->q_forw; sub != who->zct_subs;
- sub = sub->q_forw) {
- if (ZDest_eq(&cancel->zst_dest, &sub->zst_dest)) {
- xremque(sub);
- triplet_deregister(who, &sub->zst_dest);
- free_zstring(sub->zst_dest.classname);
- free_zstring(sub->zst_dest.inst);
- free_zstring(sub->zst_dest.recip);
- xfree(sub);
- found = 1;
- break;
+ who = client_which_client(&sin->sin_addr, notice);
+ if (!who)
+ return ZSRV_NOCLT;
+
+ if (!who->subs)
+ return ZSRV_NOSUB;
+
+ cancel_subs = extract_subscriptions(notice);
+ if (!cancel_subs)
+ return ZERR_NONE; /* no subscr -> no error */
+
+ for (subs = cancel_subs; subs; subs = cancel_next) {
+ cancel_next = subs->next;
+ for (client_subs = who->subs; client_subs; client_subs = client_next) {
+ client_next = client_subs->next;
+ if (ZDest_eq(&client_subs->dest, &subs->dest)) {
+ LIST_DELETE(client_subs);
+ triplet_deregister(who, &client_subs->dest, NULL);
+ if (retval == ZSRV_EMPTYCLASS &&
+ client_subs->dest.recip->string[0] == '@') {
+ realm =
+ realm_get_realm_by_name(client_subs->dest.recip->string
+ + 1);
+ if (realm)
+ subscr_unsub_sendit(client_subs, realm);
+ realm = NULL;
}
+ free_string(client_subs->dest.classname);
+ free_string(client_subs->dest.inst);
+ free_string(client_subs->dest.recip);
+ free(client_subs);
+ found = 1;
+ break;
}
}
+ }
- END_CRITICAL_CODE;
+ free_subscriptions(cancel_subs);
- free_subscriptions(cancel_queue);
- if (found) {
+ if (found) {
#if 0
- zdbug((LOG_DEBUG, "found & removed"));
+ zdbug((LOG_DEBUG, "found & removed"));
#endif
- return(ZERR_NONE);
- } else {
+ return ZERR_NONE;
+ } else {
#if 0
- zdbug((LOG_DEBUG, "not found"));
+ zdbug((LOG_DEBUG, "not found"));
#endif
- return(ZSRV_NOSUB);
- }
+ return ZSRV_NOSUB;
+ }
}
-/*
- * Cancel all the subscriptions for this client.
- */
-
-void
-subscr_cancel_client(client)
- ZClient_t *client;
+Code_t
+subscr_realm_cancel(sin, notice, realm)
+ struct sockaddr_in *sin;
+ ZNotice_t *notice;
+ Realm *realm;
{
- register ZSubscr_t *subs;
-
+ Client *who;
+ Destlist *cancel_subs, *subs, *client_subs, *next, *next2;
+ Code_t retval;
+ int found = 0;
+
+ if (!realm)
+ return ZSRV_NORLM;
+
+ if (!realm->subs)
+ return ZSRV_NOSUB;
+
+ cancel_subs = extract_subscriptions(notice);
+ if (!cancel_subs)
+ return ZERR_NONE; /* no subscr -> no error */
+
+ for (subs = cancel_subs; subs; subs = next) {
+ next = subs->next;
+ for (client_subs = realm->subs; client_subs; client_subs = next2) {
+ next2 = client_subs->next;
+ if (ZDest_eq(&client_subs->dest, &subs->dest)) {
+ LIST_DELETE(client_subs);
+ retval = triplet_deregister(realm->client, &client_subs->dest, realm);
+ free_string(client_subs->dest.classname);
+ free_string(client_subs->dest.inst);
+ free_string(client_subs->dest.recip);
+ free(client_subs);
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ free_subscriptions(cancel_subs);
+
+ if (found) {
#if 0
- zdbug((LOG_DEBUG,"subscr_cancel_client %s",
- inet_ntoa (client->zct_addr.sin_addr)));
+ zdbug((LOG_DEBUG, "found & removed"));
#endif
- if (!client->zct_subs)
- return;
-
- START_CRITICAL_CODE;
-
- for (subs = client->zct_subs->q_forw;
- subs != client->zct_subs;
- subs = client->zct_subs->q_forw) {
+ return ZERR_NONE;
+ } else {
#if 0
- zdbug((LOG_DEBUG,"sub_can %s",
- subs->zst_dest.classname->string));
+ zdbug((LOG_DEBUG, "not found"));
#endif
- if (triplet_deregister(client, &subs->zst_dest) != ZERR_NONE) {
-#if 0
- zdbug((LOG_DEBUG,"sub_can_clt: not registered!"));
-#endif
- }
- xremque(subs);
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
- }
-
- /* also flush the head of the queue */
- /* subs is now client->zct_subs */
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
- client->zct_subs = NULLZST;
-
- END_CRITICAL_CODE;
-
- return;
+ return ZSRV_NOSUB;
+ }
}
-#ifdef notdef
-/* not used for the moment */
/*
- * Cancel all the subscriptions for clients at this addr.
+ * Cancel all the subscriptions for this client.
*/
-Code_t
-subscr_cancel_host(addr)
-struct in_addr *addr;
+void
+subscr_cancel_client(client)
+ Client *client;
{
- register ZHostList_t *hosts;
- register ZClientList_t *clist = NULLZCLT, *clt;
-
- /* find the host */
- if (!(hosts = hostm_find_host(addr)))
- return(ZSRV_HNOTFOUND);
- clist = hosts->zh_clients;
-
- START_CRITICAL_CODE;
-
- /* flush each one */
- for (clt = clist->q_forw; clt != clist; clt = clt->q_forw)
- (void) subscr_cancel_client(clt->zclt_client);
+ Destlist *subs, *next;
+ Code_t retval;
+ Realm *realm;
- END_CRITICAL_CODE;
-
- return(ZERR_NONE);
-}
+#if 0
+ zdbug((LOG_DEBUG,"subscr_cancel_client %s",
+ inet_ntoa(client->addr.sin_addr)));
#endif
+ if (!client->subs)
+ return;
-/*
- * Free memory used by a list we allocated.
- */
-
-void
-subscr_free_list(list)
- ZClientList_t *list;
-{
- register ZClientList_t *lyst;
-
- for (lyst = list->q_forw; lyst != list; lyst = list->q_forw) {
- xremque(lyst);
- xfree(lyst);
+ for (subs = client->subs; subs; subs = next) {
+ next = subs->next;
+#if 0
+ zdbug((LOG_DEBUG,"sub_can %s", subs->dest.classname->string));
+#endif
+ retval = triplet_deregister(client, &subs->dest, NULL);
+ if (retval == ZSRV_EMPTYCLASS &&
+ subs->dest.recip->string[0] == '@') {
+ realm = realm_get_realm_by_name(subs->dest.recip->string + 1);
+ if (realm)
+ subscr_unsub_sendit(subs, realm);
+ realm = NULL;
}
- xfree(list);
- return;
+ free_string(subs->dest.classname);
+ free_string(subs->dest.inst);
+ free_string(subs->dest.recip);
+ free(subs);
+ }
+
+ client->subs = NULL;
}
/*
@@ -523,359 +479,349 @@ subscr_free_list(list)
void
subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
{
- char **answer;
- int found;
- struct sockaddr_in send_to_who;
- Code_t retval;
+ char **answer;
+ int found;
+ struct sockaddr_in send_to_who;
+ Code_t retval;
#ifdef OLD_COMPAT
- if (!strcmp(notice->z_version, OLD_ZEPHYR_VERSION)) {
- /* we are talking to an old client; use the old-style
- acknowledgement-message */
- old_compat_subscr_sendlist(notice, auth, who);
- return;
- }
+ if (strcmp(notice->z_version, OLD_ZEPHYR_VERSION) == 0) {
+ /* we are talking to an old client; use the old-style
+ acknowledgement-message */
+ old_compat_subscr_sendlist(notice, auth, who);
+ return;
+ }
#endif /* OLD_COMPAT */
#ifdef NEW_COMPAT
- if (!strcmp(notice->z_version, NEW_OLD_ZEPHYR_VERSION)) {
- /* we are talking to a new old client; use the new-old-style
- acknowledgement-message */
- new_old_compat_subscr_sendlist(notice, auth, who);
- return;
- }
+ if (strcmp(notice->z_version, NEW_OLD_ZEPHYR_VERSION) == 0) {
+ /* we are talking to a new old client; use the new-old-style
+ acknowledgement-message */
+ new_old_compat_subscr_sendlist(notice, auth, who);
+ return;
+ }
#endif /* NEW_COMPAT */
- answer = subscr_marshal_subs(notice, auth, who, &found);
- send_to_who = *who;
- send_to_who.sin_port = notice->z_port; /* Return port */
-
- if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
+ answer = subscr_marshal_subs(notice, auth, who, &found);
+ send_to_who = *who;
+ send_to_who.sin_port = notice->z_port; /* Return port */
+
+ retval = ZSetDestAddr(&send_to_who);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
+ error_message(retval));
+ if (answer)
+ free(answer);
+ return;
+ }
- /* XXX for now, don't do authentication */
- auth = 0;
+ /* XXX for now, don't do authentication */
+ auth = 0;
- notice->z_kind = ACKED;
+ notice->z_kind = ACKED;
- /* use xmit_frag() to send each piece of the notice */
+ /* use xmit_frag() to send each piece of the notice */
- if ((retval = ZSrvSendRawList(notice, (char **) answer,
- found*NUM_FIELDS, xmit_frag))
- != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- }
- if (answer)
- xfree(answer);
- return;
+ retval = ZSrvSendRawList(notice, answer, found * NUM_FIELDS, xmit_frag);
+ if (retval != ZERR_NONE)
+ syslog(LOG_WARNING, "subscr_sendlist xmit: %s", error_message(retval));
+ if (answer)
+ free(answer);
}
static char **
subscr_marshal_subs(notice, auth, who, found)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- register int *found;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ int *found;
{
- ZNotice_t reply;
- char **answer = (char **) 0;
- int temp;
- Code_t retval;
- ZClient_t *client;
- register ZSubscr_t *subs, *subs2 = NULLZST;
- register int i;
- int defsubs = 0;
+ ZNotice_t reply;
+ char **answer = NULL;
+ unsigned short temp;
+ Code_t retval;
+ Client *client;
+ Destlist *subs = NULL, *sub;
+ int i;
+ int defsubs = 0;
#if 0
- zdbug((LOG_DEBUG, "subscr_marshal"));
+ zdbug((LOG_DEBUG, "subscr_marshal"));
#endif
- *found = 0;
+ *found = 0;
- /* Note that the following code is an incredible crock! */
+ /* Note that the following code is an incredible crock! */
- /* We cannot send multiple packets as acknowledgements to the client,
- since the hostmanager will ignore the later packets. So we need
- to send directly to the client. */
+ /* We cannot send multiple packets as acknowledgements to the client,
+ since the hostmanager will ignore the later packets. So we need
+ to send directly to the client. */
- /* Make our own copy so we can send directly back to the client */
- /* RSF 11/07/87 */
-
+ /* Make our own copy so we can send directly back to the client */
+ /* RSF 11/07/87 */
- if (!strcmp(notice->z_opcode, CLIENT_GIMMESUBS)) {
- /* If the client has requested his current subscriptions,
- the message field of the notice contains the port number
- of the client for which the sender desires the subscription
- list. The port field is the port of the sender. */
-
- if ((retval = ZReadAscii(notice->z_message,
- notice->z_message_len,
- (unsigned char *)&temp,
- sizeof(u_short))) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_marshal read port num: %s",
- error_message(retval));
- return((char **)0);
- }
+ if (strcmp(notice->z_opcode, CLIENT_GIMMESUBS) == 0) {
+ /* If the client has requested his current subscriptions,
+ the message field of the notice contains the port number
+ of the client for which the sender desires the subscription
+ list. The port field is the port of the sender. */
- /* Blech blech blech */
- reply = *notice;
- reply.z_port = *((u_short *)&temp);
-
- client = client_which_client(who, &reply);
-
- if (client)
- subs2 = client->zct_subs;
- } else if (!strcmp(notice->z_opcode, CLIENT_GIMMEDEFS)) {
-#if 0
- zdbug((LOG_DEBUG, "gimmedefs"));
-#endif
- /* subscr_copy_def_subs allocates new pointer rings, so
- it must be freed when finished.
- the string areas pointed to are static, however.*/
- subs2 = subscr_copy_def_subs(notice->z_sender);
- defsubs = 1;
- } else {
- syslog(LOG_ERR, "subscr_marshal bogus opcode %s",
- notice->z_opcode);
- return((char **) 0);
+ retval = ZReadAscii16(notice->z_message, notice->z_message_len, &temp);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_marshal read port num: %s",
+ error_message(retval));
+ return(NULL);
}
- if (subs2) {
+ reply = *notice;
+ reply.z_port = htons(temp);
- /* check authenticity here. The user must be authentic to get
- a list of subscriptions. If he is not subscribed to
- anything, this if-clause fails, and he gets a response
- indicating no subscriptions.
- if retrieving default subscriptions, don't care about
- authentication. */
+ client = client_which_client(&who->sin_addr, &reply);
- if (!auth && !defsubs) {
- return((char **) 0);
- }
- if (!defsubs) {
- if (client && (strcmp(client->zct_principal->string,
- notice->z_sender) != 0)) {
- zdbug ((LOG_DEBUG,
+ if (client)
+ subs = client->subs;
+ } else if (strcmp(notice->z_opcode, CLIENT_GIMMEDEFS) == 0) {
+#if 0
+ zdbug((LOG_DEBUG, "gimmedefs"));
+#endif
+ /* subscr_copy_def_subs allocates new pointer rings, so
+ it must be freed when finished.
+ the string areas pointed to are static, however.*/
+ subs = subscr_copy_def_subs(notice->z_sender);
+ defsubs = 1;
+ } else {
+ syslog(LOG_ERR, "subscr_marshal bogus opcode %s",
+ notice->z_opcode);
+ return(NULL);
+ }
+
+ if (subs) {
+
+ /* check authenticity here. The user must be authentic to get
+ a list of subscriptions. If he is not subscribed to
+ anything, this if-clause fails, and he gets a response
+ indicating no subscriptions.
+ if retrieving default subscriptions, don't care about
+ authentication. */
+
+ if (!auth && !defsubs)
+ return(NULL);
+ if (!defsubs) {
+ if (client && (strcmp(client->principal->string,
+ notice->z_sender) != 0)) {
+ zdbug ((LOG_DEBUG,
"subscr_marshal: %s requests subs for %s at %s/%d",
- notice->z_sender,
- client->zct_principal->string,
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port)));
- return 0;
- }
- }
+ notice->z_sender, client->principal->string,
+ inet_ntoa(who->sin_addr), ntohs(who->sin_port)));
+ return 0;
+ }
+ }
+
+ for (sub = subs; sub; sub = sub->next)
+ (*found)++;
- for (subs = subs2->q_forw;
- subs != subs2;
- subs = subs->q_forw, (*found)++);
-
- /* found is now the number of subscriptions */
-
- /* coalesce the subscription information into a list of
- char *'s */
- if ((answer = (char **) xmalloc((*found) * NUM_FIELDS * sizeof(char *))) == (char **) 0) {
- syslog(LOG_ERR, "subscr no mem(answer)");
- *found = 0;
- } else
- for (i = 0, subs = subs2->q_forw;
- i < *found ;
- i++, subs = subs->q_forw) {
- answer[i*NUM_FIELDS] = subs->zst_dest.classname->string;
- answer[i*NUM_FIELDS + 1] = subs->zst_dest.inst->string;
- answer[i*NUM_FIELDS + 2] = subs->zst_dest.recip->string;
- }
+ /* found is now the number of subscriptions */
+
+ /* coalesce the subscription information into a list of char *'s */
+ answer = (char **) malloc((*found) * NUM_FIELDS * sizeof(char *));
+ if (answer == NULL) {
+ syslog(LOG_ERR, "subscr no mem(answer)");
+ *found = 0;
+ } else {
+ i = 0;
+ for (sub = subs; sub; sub = sub->next) {
+ answer[i * NUM_FIELDS] = sub->dest.classname->string;
+ answer[i * NUM_FIELDS + 1] = sub->dest.inst->string;
+ answer[i * NUM_FIELDS + 2] = sub->dest.recip->string;
+ i++;
+ }
}
- if (defsubs)
- free_subscriptions(subs2);
- return(answer);
+ }
+ if (defsubs)
+ free_subscriptions(subs);
+ return answer;
}
#ifdef NEW_COMPAT
static void
new_old_compat_subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
{
- Code_t retval;
- ZNotice_t reply;
- ZPacket_t reppacket;
- int packlen, found, count, initfound, zerofound;
- char buf[64];
- Zconst char **answer;
- struct sockaddr_in send_to_who;
- register int i;
-
- new_compat_count_subscr++;
-
- syslog(LOG_INFO, "new old subscr, %s", inet_ntoa(who->sin_addr));
- reply = *notice;
- reply.z_kind = SERVACK;
- reply.z_authent_len = 0; /* save some space */
- reply.z_auth = 0;
-
- send_to_who = *who;
- send_to_who.sin_port = notice->z_port; /* Return port */
-
- if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "new_old_subscr_sendlist set addr: %s",
- error_message(retval));
- return;
- }
+ Code_t retval;
+ ZNotice_t reply;
+ ZPacket_t reppacket;
+ int packlen, found, count, initfound, zerofound;
+ char buf[64];
+ const char **answer;
+ struct sockaddr_in send_to_who;
+ int i;
+
+ new_compat_count_subscr++;
+
+ syslog(LOG_INFO, "new old subscr, %s", inet_ntoa(who->sin_addr));
+ reply = *notice;
+ reply.z_kind = SERVACK;
+ reply.z_authent_len = 0; /* save some space */
+ reply.z_auth = 0;
+
+ send_to_who = *who;
+ send_to_who.sin_port = notice->z_port; /* Return port */
+
+ retval = ZSetDestAddr(&send_to_who);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "new_old_subscr_sendlist set addr: %s",
+ error_message(retval));
+ return;
+ }
- /* retrieve the subscriptions */
- answer = subscr_marshal_subs(notice, auth, who, &found);
+ /* retrieve the subscriptions */
+ answer = subscr_marshal_subs(notice, auth, who, &found);
- /* note that when there are no subscriptions, found == 0, so
- we needn't worry about answer being NULL since
- ZFormatSmallRawNoticeList won't reference the pointer */
+ /* note that when there are no subscriptions, found == 0, so
+ we needn't worry about answer being NULL since
+ ZFormatSmallRawNoticeList won't reference the pointer */
- /* send 5 at a time until we are finished */
- count = found?((found-1) / 5 + 1):1; /* total # to be sent */
- i = 0; /* pkt # counter */
+ /* send 5 at a time until we are finished */
+ count = found?((found-1) / 5 + 1):1; /* total # to be sent */
+ i = 0; /* pkt # counter */
#if 0
- zdbug((LOG_DEBUG,"Found %d subscriptions for %d packets",
- found,count));
+ zdbug((LOG_DEBUG,"Found %d subscriptions for %d packets", found, count));
#endif
- initfound = found;
- zerofound = (found == 0);
- while (found > 0 || zerofound) {
- packlen = sizeof(reppacket);
- (void) sprintf(buf, "%d/%d", ++i, count);
- reply.z_opcode = buf;
- retval = ZFormatSmallRawNoticeList(&reply,
- answer+(initfound-found)*NUM_FIELDS,
- ((found > 5) ? 5 : found)*NUM_FIELDS,
- reppacket,
- &packlen);
- if (retval != ZERR_NONE) {
- syslog(LOG_ERR, "subscr_sendlist format: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- found -= 5;
- zerofound = 0;
+ initfound = found;
+ zerofound = (found == 0);
+ while (found > 0 || zerofound) {
+ packlen = sizeof(reppacket);
+ sprintf(buf, "%d/%d", ++i, count);
+ reply.z_opcode = buf;
+ retval = ZFormatSmallRawNoticeList(&reply,
+ answer + (initfound - found)
+ * NUM_FIELDS,
+ ((found > 5) ? 5 : found)
+ * NUM_FIELDS,
+ reppacket, &packlen);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_sendlist format: %s",
+ error_message(retval));
+ if (answer)
+ free(answer);
+ return;
}
+ retval = ZSendPacket(reppacket, packlen, 0);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
+ error_message(retval));
+ if (answer)
+ free(answer);
+ return;
+ }
+ found -= 5;
+ zerofound = 0;
+ }
#if 0
- zdbug((LOG_DEBUG,"subscr_sendlist acked"));
+ zdbug((LOG_DEBUG,"subscr_sendlist acked"));
#endif
- if (answer)
- xfree(answer);
- return;
+ if (answer)
+ free(answer);
}
#endif /* NEW_COMPAT */
#ifdef OLD_COMPAT
static void
old_compat_subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
{
- ZClient_t *client = client_which_client(who, notice);
- register ZSubscr_t *subs;
- Code_t retval;
- ZNotice_t reply;
- ZPacket_t reppacket;
- int packlen, i, found = 0;
- char **answer = (char **) NULL;
-
- old_compat_count_subscr++;
-
- syslog(LOG_INFO, "old old subscr, %s", inet_ntoa(who->sin_addr));
- if (client && client->zct_subs) {
-
- /* check authenticity here. The user must be authentic to get
- a list of subscriptions. If he is not subscribed to
- anything, the above test fails, and he gets a response
- indicating no subscriptions */
-
- if (!auth) {
- clt_ack(notice, who, AUTH_FAILED);
- return;
- }
-
- for (subs = client->zct_subs->q_forw;
- subs != client->zct_subs;
- subs = subs->q_forw, found++);
-
- /* found is now the number of subscriptions */
-
- /* coalesce the subscription information into a list of
- char *'s */
- if ((answer = (char **) xmalloc(found * NUM_FIELDS * sizeof(char *))) == (char **) 0) {
- syslog(LOG_ERR, "old_subscr_sendlist no mem(answer)");
- found = 0;
- } else
- for (i = 0, subs = client->zct_subs->q_forw;
- i < found ;
- i++, subs = subs->q_forw) {
- answer[i*NUM_FIELDS] = subs->zst_class;
- answer[i*NUM_FIELDS + 1] = subs->zst_classinst;
- answer[i*NUM_FIELDS + 2] = subs->zst_recipient;
- }
+ Client *client = client_which_client(&who->sin_addr, notice);
+ Destlist *subs;
+ Code_t retval;
+ ZNotice_t reply;
+ ZPacket_t reppacket;
+ int packlen, i, found = 0;
+ char **answer = NULL;
+
+ old_compat_count_subscr++;
+
+ syslog(LOG_INFO, "old old subscr, %s", inet_ntoa(who->sin_addr));
+ if (client && client->subs) {
+
+ /* check authenticity here. The user must be authentic to get
+ a list of subscriptions. If he is not subscribed to
+ anything, the above test fails, and he gets a response
+ indicating no subscriptions */
+
+ if (!auth) {
+ clt_ack(notice, who, AUTH_FAILED);
+ return;
}
- /* note that when there are no subscriptions, found == 0, so
- we needn't worry about answer being NULL */
- reply = *notice;
- reply.z_kind = SERVACK;
- reply.z_authent_len = 0; /* save some space */
- reply.z_auth = 0;
-
-
- /* if it's too long, chop off one at a time till it fits */
- while ((retval = ZFormatSmallRawNoticeList(&reply,
- answer,
- found * NUM_FIELDS,
- reppacket,
- &packlen)) == ZERR_PKTLEN) {
- found--;
- reply.z_opcode = OLD_CLIENT_INCOMPSUBS;
- }
- if (retval != ZERR_NONE) {
- syslog(LOG_ERR, "old_subscr_sendlist format: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
+ for (subs = client->subs; subs; subs = subs->next)
+ found++;
+ /* found is now the number of subscriptions */
+
+ /* coalesce the subscription information into a list of char *'s */
+ answer = (char **) malloc(found * NUM_FIELDS * sizeof(char *));
+ if (!answer) {
+ syslog(LOG_ERR, "old_subscr_sendlist no mem(answer)");
+ found = 0;
+ } else {
+ i = 0;
+ for (subs = client->subs; subs; subs = subs->next) {
+ answer[i*NUM_FIELDS] = subs->dest.classname->string;
+ answer[i*NUM_FIELDS + 1] = subs->dest.inst->string;
+ answer[i*NUM_FIELDS + 2] = subs->dest.recip->string;
+ i++;
+ }
}
-#if 0
- zdbug((LOG_DEBUG,"subscr_sendlist acked"));
-#endif
+ }
+
+ /* note that when there are no subscriptions, found == 0, so
+ we needn't worry about answer being NULL */
+
+ reply = *notice;
+ reply.z_kind = SERVACK;
+ reply.z_authent_len = 0; /* save some space */
+ reply.z_auth = 0;
+
+ /* if it's too long, chop off one at a time till it fits */
+ while ((retval = ZFormatSmallRawNoticeList(&reply, answer,
+ found * NUM_FIELDS,
+ reppacket,
+ &packlen)) != ZERR_PKTLEN) {
+ found--;
+ reply.z_opcode = OLD_CLIENT_INCOMPSUBS;
+ }
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "old_subscr_sendlist format: %s",
+ error_message(retval));
if (answer)
- xfree(answer);
+ free(answer);
return;
+ }
+ retval = ZSetDestAddr(who);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
+ error_message(retval));
+ if (answer)
+ free(answer);
+ return;
+ }
+ retval = ZSendPacket(reppacket, packlen, 0);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
+ error_message(retval));
+ if (answer)
+ free(answer);
+ return;
+ }
+#if 0
+ zdbug((LOG_DEBUG,"subscr_sendlist acked"));
+#endif
+ if (answer)
+ free(answer);
}
#endif /* OLD_COMPAT */
@@ -888,99 +834,89 @@ old_compat_subscr_sendlist(notice, auth, who)
/*ARGSUSED*/
Code_t
-subscr_send_subs(client, vers)
- ZClient_t *client;
- char *vers;
+subscr_send_subs(client)
+ Client *client;
{
- register int i = 0;
- register ZSubscr_t *sub;
-#ifdef KERBEROS
- char buf[512];
- C_Block cblock;
-#endif /* KERBEROS */
- char buf2[512];
- char *lyst[7 * NUM_FIELDS];
- int num = 0;
- Code_t retval;
+ int i = 0;
+ Destlist *subs;
+#ifdef ZEPHYR_USES_KERBEROS
+ char buf[512];
+ C_Block cblock;
+#endif /* ZEPHYR_USES_KERBEROS */
+ char buf2[512];
+ char *list[7 * NUM_FIELDS];
+ int num = 0;
+ Code_t retval;
#if 0
- zdbug((LOG_DEBUG, "send_subs"));
+ zdbug((LOG_DEBUG, "send_subs"));
#endif
- (void) sprintf(buf2, "%d",ntohs(client->zct_sin.sin_port));
+ sprintf(buf2, "%d",ntohs(client->addr.sin_port));
- lyst[num++] = buf2;
+ list[num++] = buf2;
-#ifdef KERBEROS
+#ifdef ZEPHYR_USES_KERBEROS
#ifdef NOENCRYPTION
- (void) memcpy((caddr_t)cblock, (caddr_t)client->zct_cblock, sizeof(C_Block));
+ memcpy(cblock, client->session_key, sizeof(C_Block));
#else
- des_ecb_encrypt(client->zct_cblock, cblock, serv_ksched.s, DES_ENCRYPT);
+ des_ecb_encrypt(client->session_key, cblock, serv_ksched.s, DES_ENCRYPT);
#endif
- if ((retval = ZMakeAscii(buf, sizeof(buf), cblock,
- sizeof(C_Block))) != ZERR_NONE) {
+ retval = ZMakeAscii(buf, sizeof(buf), cblock, sizeof(C_Block));
+ if (retval != ZERR_NONE) {
#if 0
- zdbug((LOG_DEBUG,"zmakeascii failed: %s",
- error_message(retval)));
+ zdbug((LOG_DEBUG,"zmakeascii failed: %s", error_message(retval)));
#endif
- } else {
- lyst[num++] = buf;
+ } else {
+ list[num++] = buf;
#if 0
- zdbug((LOG_DEBUG,"cblock %s",buf));
+ zdbug((LOG_DEBUG, "cblock %s", buf));
#endif
- }
-#endif /* KERBEROS */
- if ((retval = bdump_send_list_tcp(SERVACK, client->zct_sin.sin_port,
- ZEPHYR_ADMIN_CLASS,
- num > 1 ? "CBLOCK" : "",
- ADMIN_NEWCLT,
- (char*)client->zct_principal->string,
- "", lyst, num)) != ZERR_NONE ) {
- syslog(LOG_ERR, "subscr_send_subs newclt: %s",
+ }
+#endif /* ZEPHYR_USES_KERBEROS */
+ retval = bdump_send_list_tcp(SERVACK, &client->addr, ZEPHYR_ADMIN_CLASS,
+ num > 1 ? "CBLOCK" : "", ADMIN_NEWCLT,
+ client->principal->string, "", list, num);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_subs newclt: %s", error_message(retval));
+ return retval;
+ }
+
+ if (!client->subs)
+ return ZERR_NONE;
+
+ for (subs = client->subs; subs; subs = subs->next) {
+ /* for each subscription */
+ list[i * NUM_FIELDS] = subs->dest.classname->string;
+ list[i * NUM_FIELDS + 1] = subs->dest.inst->string;
+ list[i * NUM_FIELDS + 2] = subs->dest.recip->string;
+ i++;
+ if (i >= 7) {
+ /* we only put 7 in each packet, so we don't run out of room */
+ retval = bdump_send_list_tcp(ACKED, &client->addr,
+ ZEPHYR_CTL_CLASS, "",
+ CLIENT_SUBSCRIBE, "", "", list,
+ i * NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_subs subs: %s",
error_message(retval));
- return(retval);
- }
-
- if (!client->zct_subs)
- return(ZERR_NONE);
- for (sub = client->zct_subs->q_forw;
- sub != client->zct_subs;
- sub = sub->q_forw) {
- /* for each subscription */
- lyst[i * NUM_FIELDS] = sub->zst_dest.classname->string;
- lyst[i * NUM_FIELDS + 1] = sub->zst_dest.inst->string;
- lyst[i * NUM_FIELDS + 2] = sub->zst_dest.recip->string;
- i++;
- if (i >= 7) {
- /* we only put 7 in each packet, so we don't
- run out of room */
- if ((retval = bdump_send_list_tcp(ACKED,
- client->zct_sin.sin_port,
- ZEPHYR_CTL_CLASS, "",
- CLIENT_SUBSCRIBE, "",
- "", lyst,
- i * NUM_FIELDS))
- != ZERR_NONE) {
- syslog(LOG_ERR, "subscr_send_subs subs: %s",
- error_message(retval));
- return(retval);
- }
- i = 0;
- }
+ return retval;
+ }
+ i = 0;
}
- if (i) {
- if ((retval = bdump_send_list_tcp(ACKED,
- client->zct_sin.sin_port,
- ZEPHYR_CTL_CLASS, "",
- CLIENT_SUBSCRIBE, "", "",
- lyst, i * NUM_FIELDS))
- != ZERR_NONE) {
- syslog(LOG_ERR, "subscr_send_subs subs: %s",
- error_message(retval));
- return(retval);
- }
+ }
+ if (i) {
+ retval = bdump_send_list_tcp(ACKED, &client->addr, ZEPHYR_CTL_CLASS,
+ "", CLIENT_SUBSCRIBE, "", "", list,
+ i * NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_subs subs: %s",
+ error_message(retval));
+ return retval;
}
- return(ZERR_NONE);
+ }
+
+ return ZERR_NONE;
}
/*
@@ -989,85 +925,72 @@ subscr_send_subs(client, vers)
static void
free_subscriptions(subs)
- register ZSubscr_t *subs;
+ Destlist *subs;
{
- register ZSubscr_t *sub;
-
- for (sub = subs->q_forw; sub != subs; sub = subs->q_forw) {
- xremque(sub);
- free_zstring(sub->zst_dest.classname);
- free_zstring(sub->zst_dest.inst);
- free_zstring(sub->zst_dest.recip);
- xfree(sub);
- }
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
-
- return;
+ Destlist *next;
+
+ for (; subs; subs = next) {
+ next = subs->next;
+ free_string(subs->dest.classname);
+ free_string(subs->dest.inst);
+ free_string(subs->dest.recip);
+ free(subs);
+ }
}
#define ADVANCE(xx) { cp += (strlen(cp) + 1); \
if (cp >= notice->z_message + notice->z_message_len) { \
- syslog(LOG_WARNING, "malformed subscription %d", xx); \
- return(subs); \
+ syslog(LOG_WARNING, "malformed subscription %d", \
+ xx); \
+ return subs; \
}}
/*
* Parse the message body, returning a linked list of subscriptions, or
- * NULLZST if there are no subscriptions there.
+ * NULL if there are no subscriptions there.
*/
-static ZSubscr_t *
+static Destlist *
extract_subscriptions(notice)
- register ZNotice_t *notice;
+ ZNotice_t *notice;
{
- register ZSubscr_t *subs = NULLZST, *subs2;
- register char *recip, *class_name, *classinst;
- register char *cp = notice->z_message;
-
- /* parse the data area for the subscriptions */
- while (cp < notice->z_message + notice->z_message_len) {
- class_name = cp;
- if (*cp == '\0')
- /* we've exhausted the subscriptions */
- return(subs);
- ADVANCE(1);
- classinst = cp;
- ADVANCE(2);
- recip = cp;
+ Destlist *subs = NULL, *sub;
+ char *recip, *class_name, *classinst;
+ char *cp = notice->z_message;
+
+ /* parse the data area for the subscriptions */
+ while (cp < notice->z_message + notice->z_message_len) {
+ class_name = cp;
+ if (*cp == '\0') /* we've exhausted the subscriptions */
+ return(subs);
+ ADVANCE(1);
+ classinst = cp;
+ ADVANCE(2);
+ recip = cp;
#if 0
- zdbug((LOG_DEBUG, "ext_sub: CLS %s INST %s RCPT %s",
- class_name, classinst, cp));
+ zdbug((LOG_DEBUG, "ext_sub: CLS %s INST %s RCPT %s",
+ class_name, classinst, cp));
#endif
- cp += (strlen(cp) + 1);
- if (cp > notice->z_message + notice->z_message_len) {
- syslog(LOG_WARNING, "malformed sub 3");
- return(subs);
- }
- if (!subs) {
- if (!(subs = (ZSubscr_t *)
- xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_WARNING, "ex_subs: no mem");
- return(NULLZST);
- }
- subs->q_forw = subs->q_back = subs;
- subs->zst_dest.classname = subs->zst_dest.inst =
- subs->zst_dest.recip = NULL;
- }
- if (!(subs2 = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_WARNING, "ex_subs: no mem 2");
- return(subs);
- }
- subs2->q_forw = subs2->q_back = subs2;
- subs2->zst_dest.classname = make_zstring(class_name,1);
- subs2->zst_dest.inst = make_zstring(classinst,1);
- subs2->zst_dest.recip = make_zstring(recip,0);
-
- xinsque(subs2, subs);
+ cp += (strlen(cp) + 1);
+ if (cp > notice->z_message + notice->z_message_len) {
+ syslog(LOG_WARNING, "malformed sub 3");
+ return subs;
+ }
+ sub = (Destlist *) malloc(sizeof(Destlist));
+ if (!sub) {
+ syslog(LOG_WARNING, "ex_subs: no mem 2");
+ return subs;
}
- return(subs);
+ sub->dest.classname = make_string(class_name, 1);
+ sub->dest.inst = make_string(classinst, 1);
+ /* Nuke @REALM if REALM is us. */
+ if (recip[0] == '@' && !strcmp(recip + 1, ZGetRealm()))
+ sub->dest.recip = make_string("", 0);
+ else
+ sub->dest.recip = make_string(recip, 0);
+ LIST_INSERT(&subs, sub);
+ }
+ return subs;
}
/*
@@ -1078,24 +1001,538 @@ extract_subscriptions(notice)
void
subscr_dump_subs(fp, subs)
- FILE *fp;
- ZSubscr_t *subs;
+ FILE *fp;
+ Destlist *subs;
{
- register ZSubscr_t *ptr;
- register char *p;
+ char *p;
- if (!subs) /* no subscriptions to dump */
- return;
-
- for (ptr = subs->q_forw; ptr != subs; ptr = ptr->q_forw) {
- fputs("\t\t'", fp);
- subscr_quote(ptr->zst_dest.classname->string, fp);
- fputs("' '", fp);
- subscr_quote(ptr->zst_dest.inst->string, fp);
- fputs("' '", fp);
- subscr_quote(ptr->zst_dest.recip->string, fp);
- fputs("'\n", fp);
- }
+ if (!subs) /* no subscriptions to dump */
return;
+
+ for (; subs; subs = subs->next) {
+ fputs("\t\t'", fp);
+ dump_quote(subs->dest.classname->string, fp);
+ fputs("' '", fp);
+ dump_quote(subs->dest.inst->string, fp);
+ fputs("' '", fp);
+ dump_quote(subs->dest.recip->string, fp);
+ fputs("'\n", fp);
+ }
+}
+
+#define I_ADVANCE(xx) { cp += (strlen(cp) + 1); \
+ if (cp >= notice->z_message + notice->z_message_len) { \
+ syslog(LOG_WARNING, "malformed subscription %d", \
+ xx); \
+ return (ZERR_NONE); \
+ }}
+
+/* As it exists, this function expects to take only the first sub from the
+ * Destlist. At some point, it and the calling code should be replaced */
+static Code_t
+subscr_realm_sendit(who, subs, notice, realm)
+ Client *who;
+ Destlist *subs;
+ ZNotice_t *notice;
+ Realm *realm;
+{
+#if 0
+ Destlist *subs2;
+#endif
+ ZNotice_t snotice;
+ char *pack;
+ int packlen;
+ int found = 0, i;
+ char **text;
+ Code_t retval;
+ char addr[16]; /* xxx.xxx.xxx.xxx max */
+ char port[16];
+
+#if 0
+ zdbug((LOG_DEBUG, "subscr_rlm_sendit"));
+#endif
+
+
+#ifdef notdef
+ for (subs2 = subs; subs2; subs2 = subs2->next, found++);
+ /* found is now the number of subscriptions */
+
+ /* coalesce the subscription information into a list of char *'s */
+ /* one extra for client information */
+ if ((text = (char **) malloc((found * NUM_FIELDS + 2)
+ * sizeof(char *))) == (char **) 0)
+ {
+ syslog(LOG_ERR, "subscr_rlm_sendit malloc");
+ return(ENOMEM);
+ }
+#endif /* notdef */
+
+ if ((text=(char **)malloc((NUM_FIELDS + 2)*sizeof(char *))) == (char **)0) {
+ syslog(LOG_ERR, "subscr_rlm_sendit malloc");
+ return(ENOMEM);
+ }
+ /* convert the address to a string of the form x.x.x.x/port */
+ strcpy(addr, inet_ntoa(notice->z_sender_addr));
+ if ((retval = ZMakeAscii(port, sizeof(port), (unsigned char *)
+ &notice->z_port, sizeof(u_short))) != ZERR_NONE)
+ {
+ syslog(LOG_ERR, "subscr_rlm_sendit make ascii: %s",
+ error_message(retval));
+ return(ZERR_NONE);
+ }
+ text[0] = addr;
+ text[1] = port;
+
+#ifdef notdef
+ for (i = 0, subs2 = subs; subs2, i < found ; i++, subs2 = subs2->next) {
+ text[i*NUM_FIELDS + 2] = subs2->dest.classname->string;
+ text[i*NUM_FIELDS + 3] = subs2->dest.inst->string;
+ text[i*NUM_FIELDS + 4] = subs2->dest.recip->string;
+ }
+#endif /* notdef */
+
+ text[2] = subs->dest.classname->string;
+ text[3] = subs->dest.inst->string;
+ text[4] = subs->dest.recip->string;
+
+ /* format snotice */
+ snotice.z_class_inst = ZEPHYR_CTL_REALM;
+ snotice.z_opcode = REALM_REQ_SUBSCRIBE;
+ snotice.z_port = srv_addr.sin_port;
+
+ snotice.z_class = ZEPHYR_CTL_CLASS;
+
+ snotice.z_recipient = "";
+ snotice.z_kind = ACKED;
+ snotice.z_num_other_fields = 0;
+ snotice.z_default_format = "";
+ snotice.z_sender = notice->z_sender;
+ snotice.z_recipient = notice->z_recipient;
+ snotice.z_default_format = notice->z_default_format;
+
+#ifdef notdef
+ if ((retval = ZFormatNoticeList(&snotice, text, found * NUM_FIELDS + 2,
+ &pack, &packlen, ZNOAUTH)) != ZERR_NONE)
+#else
+ if ((retval = ZFormatNoticeList(&snotice, text, NUM_FIELDS + 2,
+ &pack, &packlen, ZNOAUTH)) != ZERR_NONE)
+#endif
+ {
+ syslog(LOG_WARNING, "subscr_rlm_sendit format: %s",
+ error_message(retval));
+ free(text);
+ return(ZERR_NONE);
+ }
+ free(text);
+
+ if ((retval = ZParseNotice(pack, packlen, &snotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_rlm_sendit parse: %s",
+ error_message(retval));
+ free(pack);
+ return(ZERR_NONE);
+ }
+
+#if 0
+ zdbug((LOG_DEBUG,"subscr_rlm_sendit len: %d", snotice.z_message_len));
+#endif
+ realm_handoff(&snotice, 1, &(who->addr), realm, 0);
+ free(pack);
+
+ return(ZERR_NONE);
+}
+
+static Code_t
+subscr_add_raw(client, realm, newsubs)
+ Client *client;
+ Realm *realm;
+ Destlist *newsubs;
+{
+ Destlist *subs, *subs2, *subs3, **head;
+ Code_t retval;
+
+#if 0
+ zdbug((LOG_DEBUG, "subscr_add_raw"));
+#endif
+ head = (realm) ? &realm->subs : &client->subs;
+
+ /* Loop over the new subscriptions. */
+ for (subs = newsubs; subs; subs = subs2) {
+ subs2 = subs->next;
+#ifdef DEBUG
+ zdbug((LOG_DEBUG,"subscr_add_raw: %s/%s/%s", subs->dest.classname->string, subs->dest.inst->string, subs->dest.recip->string));
+ if (realm)
+ zdbug((LOG_DEBUG,"subscr_add_raw: realm is %s", realm->name));
+#endif
+ retval = triplet_register(client, &subs->dest, realm);
+ if (retval != ZERR_NONE) {
+ free(subs);
+ if (retval == ZSRV_CLASSXISTS) {
+ continue;
+ } else {
+ free_subscriptions(subs2);
+ return retval;
+ }
+ }
+ LIST_INSERT(head, subs);
+ }
+ return ZERR_NONE;
+}
+
+Code_t
+subscr_realm(realm, notice)
+ Realm *realm;
+ ZNotice_t *notice;
+{
+ Destlist *newsubs;
+
+ newsubs = extract_subscriptions(notice);
+
+ if (!newsubs) {
+ syslog(LOG_WARNING, "empty subs in subscr_realm");
+ return(ZERR_NONE);
+ }
+
+ return(subscr_add_raw(realm->client, realm, newsubs));
+}
+
+/* Like realm_sendit, this only takes one item from subs */
+static void
+subscr_unsub_sendit(subs, realm)
+ Destlist *subs;
+ Realm *realm;
+{
+ ZNotice_t unotice;
+ Code_t retval;
+#ifdef notdef
+ char *list[7 * NUM_FIELDS];
+#else /* notdef */
+ char *list[NUM_FIELDS];
+#endif /* notdef */
+ char *pack;
+ int packlen;
+ int found = 0;
+ Destlist *subs2;
+
+ unotice.z_class = ZEPHYR_CTL_CLASS;
+ unotice.z_class_inst = ZEPHYR_CTL_REALM;
+ unotice.z_opcode = REALM_UNSUBSCRIBE;
+ unotice.z_recipient = "";
+ unotice.z_kind = ACKED;
+
+ unotice.z_sender = "";
+ unotice.z_port = srv_addr.sin_port;
+ unotice.z_num_other_fields = 0;
+ unotice.z_default_format = "";
+
+#ifdef notdef
+ found = 0;
+ for (subs2 = subs; subs2; subs2 = subs2->next) {
+ list[found * NUM_FIELDS] = subs2->dest.classname->string;
+ list[found * NUM_FIELDS + 1] = subs2->dest.inst->string;
+ list[found * NUM_FIELDS + 2] = "";
+
+ found++;
+
+ if (found >= 7) {
+ if ((retval = ZFormatNoticeList(&unotice, list, found * NUM_FIELDS, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit format: %s",
+ error_message(retval));
+ return;
+ }
+ if ((retval = ZParseNotice(pack, packlen, &unotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit parse: %s",
+ error_message(retval));
+ free(pack);
+ return;
+ }
+ free(pack);
+ realm_handoff(&unotice, 1, (struct sockaddr_in *) 0, realm, 0);
+ found = 0;
+ }
+ }
+
+ if (found == 0)
+ return;
+
+ if ((retval = ZFormatNoticeList(&unotice, list, found * NUM_FIELDS, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit format: %s",
+ error_message(retval));
+ return;
+ }
+#else /* notdef */
+ list[0] = subs->dest.classname->string;
+ list[1] = subs->dest.inst->string;
+ list[2] = "";
+
+ if ((retval = ZFormatNoticeList(&unotice, list, NUM_FIELDS, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit format: %s",
+ error_message(retval));
+ return;
+ }
+#endif /* notdef */
+
+ if ((retval = ZParseNotice(pack, packlen, &unotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit parse: %s",
+ error_message(retval));
+ free(pack);
+ return;
+ }
+ free(pack);
+ realm_handoff(&unotice, 1, (struct sockaddr_in *) 0, realm, 0);
+}
+
+Code_t
+subscr_send_realm_subs(realm)
+ Realm *realm;
+{
+ int i = 0;
+ Destlist *subs, *next;
+ char buf[512];
+ char *list[7 * NUM_FIELDS];
+ int num = 0;
+ Code_t retval;
+
+#if 0
+ zdbug((LOG_DEBUG, "send_realm_subs"));
+#endif
+
+ strcpy(buf, realm->name);
+ list[num++] = buf;
+
+ retval = bdump_send_list_tcp(SERVACK, &srv_addr, ZEPHYR_ADMIN_CLASS,
+ "", ADMIN_NEWREALM, "", "", list, num);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_realm_subs newclt: %s", error_message(retval));
+ return retval;
+ }
+
+ if (!realm->subs)
+ return ZERR_NONE;
+
+ for (subs=realm->subs; subs; subs = next) {
+ next = subs->next;
+#ifdef DEBUG
+ zdbug ((LOG_DEBUG, "send_realm_subs: %s/%s/%s", subs->dest.classname->string,
+ subs->dest.inst->string, subs->dest.recip->string));
+#endif
+ /* for each subscription */
+ list[i * NUM_FIELDS] = subs->dest.classname->string;
+ list[i * NUM_FIELDS + 1] = subs->dest.inst->string;
+ list[i * NUM_FIELDS + 2] = subs->dest.recip->string;
+ i++;
+ if (i >= 7) {
+ /* we only put 7 in each packet, so we don't run out of room */
+ retval = bdump_send_list_tcp(ACKED, &srv_addr,
+ ZEPHYR_CTL_CLASS, "",
+ REALM_SUBSCRIBE, "", "", list,
+ i * NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_realm_subs subs: %s",
+ error_message(retval));
+ return retval;
+ }
+ i = 0;
+ }
+ }
+ if (i) {
+ retval = bdump_send_list_tcp(ACKED, &srv_addr, ZEPHYR_CTL_CLASS,
+ "", REALM_SUBSCRIBE, "", "", list,
+ i * NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_realm_subs subs: %s",
+ error_message(retval));
+ return retval;
+ }
+ }
+
+ return ZERR_NONE;
+}
+
+static Code_t
+subscr_check_foreign_subs(notice, who, realm, newsubs)
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ Realm *realm;
+ Destlist *newsubs;
+{
+ Destlist *subs, *subs2, *next;
+ Acl *acl;
+ char **text;
+ int found = 0;
+ ZNotice_t snotice;
+ char *pack, *cp;
+ int packlen;
+ Code_t retval;
+ String *sender;
+
+ for (subs = newsubs; subs; subs = subs->next)
+ found++;
+
+ if (found == 0)
+ return(ZERR_NONE);
+
+ sender = make_string(notice->z_sender, 0);
+
+ if ((text = (char **)malloc((found * NUM_FIELDS + 2) * sizeof(char *))) == (char **) 0) {
+ syslog(LOG_ERR, "subscr_ck_forn_subs no mem(text)");
+ return(ENOMEM);
+ }
+
+ /* grab the client information from the incoming message */
+ cp = notice->z_message;
+ text[0] = cp;
+
+ I_ADVANCE(2);
+ text[1] = cp;
+
+ I_ADVANCE(3);
+
+ found = 0;
+ for (subs = newsubs; subs; subs = next) {
+ next=subs->next;
+ acl = class_get_acl(subs->dest.classname);
+ if (acl) {
+ if (!access_check(sender->string, acl, SUBSCRIBE)) {
+ syslog(LOG_WARNING, "subscr unauth %s class %s",
+ sender->string, subs->dest.classname->string);
+ continue; /* the for loop */
+ }
+ if (wildcard_instance == subs->dest.inst) {
+ if (!access_check(sender->string, acl, INSTWILD)) {
+ syslog(LOG_WARNING,
+ "subscr unauth %s class %s wild inst",
+ sender->string, subs->dest.classname->string);
+ continue;
+ }
+ }
+ }
+
+ /* okay to subscribe. save for return trip */
+ text[found*NUM_FIELDS + 2] = subs->dest.classname->string;
+ text[found*NUM_FIELDS + 3] = subs->dest.inst->string;
+ text[found*NUM_FIELDS + 4] = "";
+ found++;
+
+ retval = triplet_register(realm->client, &subs->dest, realm);
+#ifdef DEBUG
+ zdbug ((LOG_DEBUG, "ck_frn_subs: %s/%s/%s", subs->dest.classname->string,
+ subs->dest.inst->string, subs->dest.recip->string));
+#endif
+
+ if (retval != ZERR_NONE) {
+ if (retval == ZSRV_CLASSXISTS) {
+ continue;
+ } else {
+ free_subscriptions(subs->next);
+ free(text);
+ return retval;
+ }
+ }
+ LIST_INSERT(&realm->subs, subs);
+ }
+ /* don't send confirmation if we're not the initial server contacted */
+ if (!(server_which_server(who) || found == 0)) {
+ snotice = *notice;
+ snotice.z_opcode = REALM_ADD_SUBSCRIBE;
+ snotice.z_class_inst = ZEPHYR_CTL_REALM;
+ snotice.z_port = srv_addr.sin_port;
+ if ((retval = ZFormatNoticeList(&snotice, text, found * NUM_FIELDS + 2, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_ck_forn_subs format: %s",
+ error_message(retval));
+ free(text);
+ return(ZERR_NONE);
+ }
+ if ((retval = ZParseNotice(pack, packlen, &snotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_ck_forn_subs parse: %s",
+ error_message(retval));
+ free(text);
+ free(pack);
+ return(ZERR_NONE);
+ }
+ realm_handoff(&snotice, 1, who, realm, 0);
+ free(pack);
+ }
+ free(text);
+ return ZERR_NONE;
+}
+
+Code_t subscr_foreign_user(notice, who, realm)
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ Realm *realm;
+{
+ Destlist *newsubs, *temp;
+ Acl *acl;
+ Code_t status;
+ Client *client;
+ ZNotice_t snotice;
+ struct sockaddr_in newwho;
+ char *cp;
+ char rlm_recipient[REALM_SZ + 1];
+
+#if 0
+ zdbug((LOG_DEBUG, "subscr_foreign_user"));
+#endif
+
+ cp = notice->z_message;
+
+ newwho.sin_addr.s_addr = inet_addr(cp);
+ if (newwho.sin_addr.s_addr == -1) {
+ syslog(LOG_ERR, "malformed addr from %s, notice->z_sender");
+ return(ZERR_NONE);
+ }
+
+ I_ADVANCE(0);
+
+ snotice = *notice;
+
+ if ((status = ZReadAscii(cp, strlen(cp), (unsigned char *)&snotice.z_port, sizeof(u_short)))
+ != ZERR_NONE)
+ {
+ syslog(LOG_ERR, "subscr_foreign_user read ascii: %s",
+ error_message(status));
+ return(ZERR_NONE);
+ }
+
+ I_ADVANCE(1);
+
+ snotice.z_message = cp;
+ snotice.z_message_len = notice->z_message_len - (cp - notice->z_message);
+
+ newsubs = extract_subscriptions(&snotice);
+ if (!newsubs) {
+ syslog(LOG_WARNING, "empty subscr for %s", notice->z_sender);
+ return(ZERR_NONE);
+ }
+
+ if (!strcmp(snotice.z_opcode, REALM_ADD_SUBSCRIBE)) {
+ /* this was approved by the other realm, add subscriptions */
+
+ client = client_which_client(&newwho.sin_addr, &snotice);
+ if (client == (Client *)0) {
+ syslog(LOG_WARNING, "no client at %s/%d",
+ inet_ntoa(newwho.sin_addr), ntohs(snotice.z_port));
+ free_subscriptions(newsubs);
+ return(ZERR_NONE);
+ }
+
+ /* translate the recipient to represent the foreign realm */
+ sprintf(rlm_recipient, "@%s", realm->name);
+ for (temp = newsubs; temp; temp = temp->next) {
+#if 0
+ syslog(LOG_DEBUG, "in foreign_user: class is %s", temp->dest.classname->string);
+#endif
+ temp->dest.recip = make_string(rlm_recipient, 0);
+ }
+
+ status = subscr_add_raw(client, (Realm *)0, newsubs);
+ } else if (!strcmp(snotice.z_opcode, REALM_REQ_SUBSCRIBE)) {
+ status = subscr_check_foreign_subs(notice, who, realm, newsubs);
+ } else {
+ syslog(LOG_ERR, "bogus opcode %s in subscr_forn_user",
+ snotice.z_opcode);
+ status = ZERR_NONE;
+ }
+ return(status);
}
diff --git a/server/subscr.c.old b/server/subscr.c.old
deleted file mode 100644
index cb2b110..0000000
--- a/server/subscr.c.old
+++ /dev/null
@@ -1,1384 +0,0 @@
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains functions for managing subscription lists.
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- *
- * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#ifndef lint
-#ifndef SABER
-static char rcsid_subscr_c[] = "$Id$";
-#endif
-#endif
-
-/*
- * The subscription manager.
- *
- * External functions:
- *
- * Code_t subscr_subscribe(who, notice)
- * ZClient_t *who;
- * ZNotice_t *notice;
- *
- * Code_t subscr_cancel(sin, notice)
- * struct sockaddr_in *sin;
- * ZNotice_t *notice;
- *
- * Code_t subscr_cancel_client(client)
- * ZClient_t *client;
- *
- * Code_t subscr_cancel_host(addr)
- * struct in_addr *addr;
- *
- * ZClientList_t *subscr_match_list(notice)
- * ZNotice_t *notice;
- *
- * void subscr_free_list(list)
- * ZClientList_t *list;
- *
- * void subscr_sendlist(notice, auth, who)
- * ZNotice_t *notice;
- * int auth;
- * struct sockaddr_in *who;
- *
- * Code_t subscr_send_subs(client, vers)
- * ZClient_t *client;
- * char *vers;
- *
- * Code_t subscr_def_subs(who)
- * ZClient_t *who;
- *
- * void subscr_reset();
- *
- */
-
-#include "zserver.h"
-#include <ctype.h>
-#include <strings.h>
-#include <sys/stat.h>
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-#ifdef KERBEROS
-#ifndef NOENCRYPTION
-C_Block serv_key;
-Sched serv_ksched;
-#endif
-#endif
-
-/* for compatibility when sending subscription information to old clients */
-
-static void check_sub_order P((ZSubscr_t *subs, int wc));
-#ifdef OLD_COMPAT
-#define OLD_ZEPHYR_VERSION "ZEPH0.0"
-#define OLD_CLIENT_INCOMPSUBS "INCOMP"
-static void old_compat_subscr_sendlist P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern int old_compat_count_subscr; /* counter of old use */
-#endif /* OLD_COMPAT */
-#ifdef NEW_COMPAT
-#define NEW_OLD_ZEPHYR_VERSION "ZEPH0.1"
-static void new_old_compat_subscr_sendlist P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern int new_compat_count_subscr; /* counter of old use */
-#endif /* NEW_COMPAT */
-
-extern char *re_comp(), *re_conv();
-static ZSubscr_t *extract_subscriptions P((register ZNotice_t *notice));
-static int clt_unique P((ZClient_t *clt, ZClientList_t *clist));
-static void free_subscriptions P((register ZSubscr_t *subs));
-static char **subscr_marshal_subs P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- register int *found));
-static Code_t subscr_subscribe_real P((ZClient_t *who, ZSubscr_t *newsubs,
- ZNotice_t *notice));
-static ZSubscr_t *subscr_copy_def_subs P((char *));
-static int cl_match P((ZSubscr_t*, ZClient_t *));
-
-static int defaults_read = 0; /* set to 1 if the default subs
- are in memory */
-static ZNotice_t default_notice; /* contains default subscriptions */
-
-#undef P
-
-ZSTRING *wildcard_class;
-ZSTRING *wildcard_instance;
-ZSTRING *empty;
-ZSubscr_t matchall_sub;
-
-/* WARNING: make sure this is the same as the number of strings you */
-/* plan to hand back to the user in response to a subscription check, */
-/* else you will lose. See subscr_sendlist() */
-#define NUM_FIELDS 3
-
-/*
- * subscribe the client to types described in notice.
- */
-
-Code_t
-subscr_subscribe(who, notice)
- ZClient_t *who;
- ZNotice_t *notice;
-{
- ZSubscr_t *subs;
-
- if (!who->zct_subs) {
- /* allocate a subscription head */
- if (!(subs = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t))))
- return(ENOMEM);
- subs->q_forw = subs->q_back = subs;
- subs->zst_dest.classname = subs->zst_dest.inst =
- subs->zst_dest.recip = NULL;
- subs->zst_dest.hash_value = 0;
- who->zct_subs = subs;
- }
-
- if (!(subs = extract_subscriptions(notice)))
- return(ZERR_NONE); /* no subscr -> no error */
-
- return(subscr_subscribe_real(who, subs, notice));
-}
-
-static Code_t
-subscr_subscribe_real(who, newsubs, notice)
- ZClient_t *who;
- register ZSubscr_t *newsubs;
- ZNotice_t *notice;
-{
- Code_t retval;
- ZAcl_t *acl;
- ZSTRING *sender;
- ZSubscr_t *subs2, *subs3, *subs;
- int relation;
-
- sender = make_zstring(notice->z_sender,0);
-
- START_CRITICAL_CODE;
-
- for (subs = newsubs->q_forw;
- subs != newsubs;
- subs = subs->q_forw) {
- /* for each new subscription */
-
-#if 0
- zdbug ((LOG_DEBUG, "subscr: %s/%s/%s",
- subs->zst_dest.classname->string,
- subs->zst_dest.inst->string,
- subs->zst_dest.recip->string));
-#endif
-
- if (!bdumping
- && (subs->zst_dest.recip != empty)
- && (subs->zst_dest.recip != sender)) {
- syslog(LOG_WARNING, "subscr unauth %s recipient %s",
- sender->string,
- subs->zst_dest.recip->string);
- continue;
- }
- if (!bdumping) {
- acl = class_get_acl(subs->zst_dest.classname);
- if (acl) {
- if (!(access_check(sender->string, acl, SUBSCRIBE))) {
- syslog(LOG_WARNING,
- "subscr unauth %s class %s",
- sender->string,
- subs->zst_dest.classname->string);
- continue; /* the for loop */
- }
- if (wildcard_instance == subs->zst_dest.inst) {
- if (!access_check(sender->string, acl, INSTWILD)) {
- syslog(LOG_WARNING,
- "subscr unauth %s class %s wild inst",
- notice->z_sender,
- subs->zst_dest.classname->string);
- continue;
- }
- }
- }
- }
- /* subscriptions are stored in ascending order by */
- /* subscription hash value */
- /* Scan through list to check for duplicates, and to find */
- /* where to insert these subs */
-
- for (subs2 = who->zct_subs->q_forw;
- subs2 != who->zct_subs;
- subs2 = subs2->q_forw) {
- /* for each existing subscription */
- relation = compare_subs(subs2,subs,0);
- if (relation == 0)
- goto duplicate;
- if (relation > 0) /* we have passed last possible one */
- break;
- if (relation < 0) /* nope... */
- continue;
- }
-
- /* subs2 now points to the first class which is greater
- than the new class. We need to back up so that the
- insertion below goes BEFORE this one (i.e. after the
- previous one) */
- subs2 = subs2->q_back;
-
- /* ok, we are a new subscription. register and chain on. */
-
- if (!(subs3 = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t)))) {
- free_subscriptions(newsubs);
- END_CRITICAL_CODE;
- return(ENOMEM);
- }
-
- subs3->q_forw = subs3->q_back = subs3;
- subs3->zst_dest.classname =
- dup_zstring(subs->zst_dest.classname);
- subs3->zst_dest.inst = dup_zstring(subs->zst_dest.inst);
- subs3->zst_dest.recip = dup_zstring(subs->zst_dest.recip);
- set_ZDestination_hash(&subs3->zst_dest);
-
- if ((retval = class_register(who, subs)) != ZERR_NONE) {
- xfree(subs3);
- free_subscriptions(newsubs);
- END_CRITICAL_CODE;
- return(retval);
- }
-
- /* subs2 was adjusted above */
- xinsque(subs3, subs2);
- duplicate:
- ;
- }
-
- END_CRITICAL_CODE;
-
- free_subscriptions(newsubs);
- return(ZERR_NONE);
-}
-
-/*
- * add default subscriptions to the client's subscription chain.
- */
-
-Code_t
-subscr_def_subs(who)
- ZClient_t *who;
-{
- ZSubscr_t *subs;
-
- if (!who->zct_subs) {
- /* allocate a subscription head */
- if (!(subs = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_ERR, "no mem subscr_def_subs");
- return(ENOMEM);
- }
- subs->q_forw = subs->q_back = subs;
- subs->zst_dest.classname = subs->zst_dest.inst =
- subs->zst_dest.recip = (ZSTRING *) NULL;
- subs->zst_dest.hash_value = 0;
- who->zct_subs = subs;
- }
-
- subs = subscr_copy_def_subs(who->zct_principal->string);
- return(subscr_subscribe_real(who, subs, &default_notice));
-}
-
-void
-subscr_reset()
-{
-#if 0
- zdbug((LOG_DEBUG, "subscr_reset()"));
-#endif
- xfree(default_notice.z_message);
- default_notice.z_message = NULL;
- defaults_read = 0;
-}
-
-static ZSubscr_t *
-subscr_copy_def_subs(person)
- char *person;
-{
- int retval;
- int fd;
- struct stat statbuf;
- char *def_sub_area;
- register char *cp;
- ZSubscr_t *subs;
- register ZSubscr_t *subs2;
-
- if (!defaults_read) {
-#if 0
- zdbug((LOG_DEBUG, "reading default subscription file"));
-#endif
- fd = open(DEFAULT_SUBS_FILE, O_RDONLY, 0666);
- if (fd < 0) {
- syslog(LOG_ERR, "can't open %s:%m", DEFAULT_SUBS_FILE);
- return((ZSubscr_t *)0);
- }
- retval = fstat(fd, &statbuf);
- if (retval < 0) {
- syslog(LOG_ERR, "fstat failure on %s:%m",
- DEFAULT_SUBS_FILE);
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
- if (!(def_sub_area = (char *) xmalloc(statbuf.st_size + 1))) {
- syslog(LOG_ERR, "no mem copy_def_subs");
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
- retval = read(fd, def_sub_area, (int) statbuf.st_size);
- /*
- "Upon successful completion, read and readv return the number
- of bytes actually read and placed in the buffer. The system
- guarantees to read the number of bytes requested if the
- descriptor references a normal file that has that many bytes
- left before the end-of-file, but in no other case."
- -- read(2)
- Therefore, the following test is valid.
- */
- if (retval != statbuf.st_size) {
- syslog(LOG_ERR, "short read in copy_def_subs");
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
-
- (void) close(fd);
- def_sub_area[statbuf.st_size] = '\0'; /* null-terminate it */
-
- /*
- def_subs_area now points to a buffer full of subscription
- info.
- each line of the stuff is of the form:
- class,inst,recipient
-
- Commas and newlines may not appear as part of the class,
- instance, or recipient. XXX!
- */
-
- /* split up the subscription info */
- for (cp = def_sub_area;
- cp < def_sub_area + statbuf.st_size;
- cp++)
- if ((*cp == '\n') || (*cp == ','))
- *cp = '\0';
- default_notice.z_message = def_sub_area;
- default_notice.z_message_len = (int) statbuf.st_size + 1;
- default_notice.z_auth = 1;
- defaults_read = 1;
- }
- /* needed later for access_check() */
- default_notice.z_sender = person;
- subs = extract_subscriptions(&default_notice);
- /* replace any non-* recipients with "person" */
-
- for (subs2 = subs->q_forw; subs2 != subs; subs2 = subs2->q_forw) {
- /* if not a wildcard, replace it with person */
- if (strcmp(subs2->zst_dest.recip->string, "*")) {
- free_zstring(subs2->zst_dest.recip);
- subs2->zst_dest.recip = make_zstring(person,0);
- } else { /* replace with null recipient */
- free_zstring(subs2->zst_dest.recip);
- subs2->zst_dest.recip = dup_zstring(empty);
- }
- set_ZDestination_hash(&(subs2->zst_dest));
- }
- return(subs);
-}
-
-/*
- * Cancel one subscription.
- */
-
-Code_t
-subscr_cancel(sin, notice)
- struct sockaddr_in *sin;
- ZNotice_t *notice;
-{
- ZClient_t *who;
- register ZSubscr_t *subs, *subs2, *subs3, *subs4;
- Code_t retval;
- int found = 0;
- int relation;
-
-#if 0
- zdbug((LOG_DEBUG,"subscr_cancel"));
-#endif
- if (!(who = client_which_client(sin, notice)))
- return(ZSRV_NOCLT);
-
- if (!who->zct_subs)
- return(ZSRV_NOSUB);
-
- if (!(subs = extract_subscriptions(notice)))
- return(ZERR_NONE); /* no subscr -> no error */
-
- START_CRITICAL_CODE;
-
- for (subs4 = subs->q_forw; subs4 != subs; subs4 = subs4->q_forw) {
- for (subs2 = who->zct_subs->q_forw;
- subs2 != who->zct_subs;) {
- /* for each existing subscription */
- /* is this what we are canceling? */
- relation = compare_subs(subs2, subs4,0);
- if (relation < 0) {
- subs2 = subs2->q_forw;
- continue;
- }
- if (relation > 0)
- /* We have passed last possible one */
- break;
-
- /* go back, since remque will change things */
- subs3 = subs2->q_back;
- xremque(subs2);
- (void) class_deregister(who, subs2);
- free_zstring(subs2->zst_dest.classname);
- free_zstring(subs2->zst_dest.inst);
- free_zstring(subs2->zst_dest.recip);
- xfree(subs2);
- found = 1;
- /* now that the remque adjusted the linked
- list, we go forward again */
- subs2 = subs3->q_forw;
- break;
- }
- }
-
- /* make sure we are still registered for all the classes */
- if (found) {
- for (subs2 = who->zct_subs->q_forw;
- subs2 != who->zct_subs;
- subs2 = subs2->q_forw)
- if ((retval = class_register(who, subs2)) != ZERR_NONE) {
- free_subscriptions(subs);
- END_CRITICAL_CODE;
- return(retval);
- }
- }
-
- END_CRITICAL_CODE;
-
- free_subscriptions(subs);
- if (found) {
-#if 0
- zdbug((LOG_DEBUG, "found & removed"));
-#endif
- return(ZERR_NONE);
- } else {
-#if 0
- zdbug((LOG_DEBUG, "not found"));
-#endif
- return(ZSRV_NOSUB);
- }
-}
-
-/*
- * Cancel all the subscriptions for this client.
- */
-
-void
-subscr_cancel_client(client)
- ZClient_t *client;
-{
- register ZSubscr_t *subs;
-
-#if 0
- zdbug((LOG_DEBUG,"subscr_cancel_client %s",
- inet_ntoa (client->zct_addr.sin_addr)));
-#endif
- if (!client->zct_subs)
- return;
-
- START_CRITICAL_CODE;
-
- for (subs = client->zct_subs->q_forw;
- subs != client->zct_subs;
- subs = client->zct_subs->q_forw) {
-#if 0
- zdbug((LOG_DEBUG,"sub_can %s",
- subs->zst_dest.classname->string));
-#endif
- if (class_deregister(client, subs) != ZERR_NONE) {
-#if 0
- zdbug((LOG_DEBUG,"sub_can_clt: not registered!"));
-#endif
- }
- xremque(subs);
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
- }
-
- /* also flush the head of the queue */
- /* subs is now client->zct_subs */
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
- client->zct_subs = NULLZST;
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-#ifdef notdef
-/* not used for the moment */
-/*
- * Cancel all the subscriptions for clients at this addr.
- */
-
-Code_t
-subscr_cancel_host(addr)
-struct in_addr *addr;
-{
- register ZHostList_t *hosts;
- register ZClientList_t *clist = NULLZCLT, *clt;
-
- /* find the host */
- if (!(hosts = hostm_find_host(addr)))
- return(ZSRV_HNOTFOUND);
- clist = hosts->zh_clients;
-
- START_CRITICAL_CODE;
-
- /* flush each one */
- for (clt = clist->q_forw; clt != clist; clt = clt->q_forw)
- (void) subscr_cancel_client(clt->zclt_client);
-
- END_CRITICAL_CODE;
-
- return(ZERR_NONE);
-}
-#endif
-
-/*
- * Here is the bulk of the work in the subscription manager.
- * We grovel over the list of clients possibly interested in this
- * notice, and copy into a list on a match. Make sure we only add any given
- * client once.
- */
-
-ZClientList_t *
-subscr_match_list(notice)
- ZNotice_t *notice;
-{
- register ZClientList_t *hits, *clients, *majik, *clients2, *hit2;
- char *saveclass, *saveclinst;
- ZSTRING *newclass;
- ZSTRING *newclinst;
- ZSubscr_t check_sub;
-
- if (!(hits = (ZClientList_t *) xmalloc(sizeof(ZClientList_t))))
- return(NULLZCLT);
- hits->q_forw = hits->q_back = hits;
-
- saveclass = notice->z_class;
- newclass = make_zstring(notice->z_class, 1);
-
- saveclinst = notice->z_class_inst;
- newclinst = make_zstring(notice->z_class_inst, 1);
-
- check_sub.zst_dest.classname = newclass;
- check_sub.zst_dest.inst = newclinst;
- check_sub.zst_dest.recip = make_zstring(notice->z_recipient, 0);
- set_ZDestination_hash(&check_sub.zst_dest);
- check_sub.q_forw = check_sub.q_back = &check_sub;
-
- clients = class_lookup (&check_sub);
- majik = class_lookup (&matchall_sub);
- if (!clients && !majik)
- return NULLZCLT;
-
- notice->z_class = (char *) newclass->string;
- notice->z_class_inst = (char *) newclinst->string;
- if (clients) {
- for (clients2 = clients->q_forw;
- clients2 != clients;
- clients2 = clients2->q_forw)
- if (cl_match(&check_sub, clients2->zclt_client)) {
- if (!clt_unique(clients2->zclt_client, hits))
- continue;
- /* we hit */
- if (!(hit2 = (ZClientList_t *) xmalloc(sizeof(ZClientList_t)))) {
- syslog(LOG_WARNING,
- "subscr_match: punting/no mem");
- notice->z_class = saveclass;
- notice->z_class_inst = saveclinst;
- free_zstring(newclass);
- free_zstring(newclinst);
- free_zstring(check_sub.zst_dest.recip);
- return(hits);
- }
- hit2->zclt_client = clients2->zclt_client;
- hit2->q_forw = hit2->q_back = hit2;
- xinsque(hit2, hits);
- }
- class_free(clients);
- }
- if (majik) {
- for (clients2 = majik->q_forw;
- clients2 != majik;
- clients2 = clients2->q_forw) {
- if (!clt_unique(clients2->zclt_client, hits))
- continue;
- /* we hit */
- if (!(hit2 = (ZClientList_t *) xmalloc(sizeof(ZClientList_t)))) {
- syslog(LOG_WARNING,
- "subscr_match(majik): punting/no mem");
- notice->z_class = saveclass;
- notice->z_class_inst = saveclinst;
- free_zstring(newclass);
- free_zstring(newclinst);
- free_zstring(check_sub.zst_dest.recip);
- return(hits);
- }
- hit2->zclt_client = clients2->zclt_client;
- hit2->q_forw = hit2->q_back = hit2;
-
- xinsque(hit2, hits);
- }
- class_free(majik);
- }
- notice->z_class = saveclass;
- notice->z_class_inst = saveclinst;
- free_zstring(newclass);
- free_zstring(newclinst);
- free_zstring(check_sub.zst_dest.recip);
- if (hits->q_forw == hits) {
- xfree(hits);
- return(NULLZCLT);
- }
- return(hits);
-}
-
-/*
- * Free memory used by a list we allocated.
- */
-
-void
-subscr_free_list(list)
- ZClientList_t *list;
-{
- register ZClientList_t *lyst;
-
- for (lyst = list->q_forw; lyst != list; lyst = list->q_forw) {
- xremque(lyst);
- xfree(lyst);
- }
- xfree(list);
- return;
-}
-
-/*
- * Send the requester a list of his current subscriptions
- */
-
-void
-subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
-{
- char **answer;
- int found;
- struct sockaddr_in send_to_who;
- Code_t retval;
-
-#ifdef OLD_COMPAT
- if (!strcmp(notice->z_version, OLD_ZEPHYR_VERSION)) {
- /* we are talking to an old client; use the old-style
- acknowledgement-message */
- old_compat_subscr_sendlist(notice, auth, who);
- return;
- }
-#endif /* OLD_COMPAT */
-#ifdef NEW_COMPAT
- if (!strcmp(notice->z_version, NEW_OLD_ZEPHYR_VERSION)) {
- /* we are talking to a new old client; use the new-old-style
- acknowledgement-message */
- new_old_compat_subscr_sendlist(notice, auth, who);
- return;
- }
-#endif /* NEW_COMPAT */
- answer = subscr_marshal_subs(notice, auth, who, &found);
- send_to_who = *who;
- send_to_who.sin_port = notice->z_port; /* Return port */
-
- if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
-
- /* XXX for now, don't do authentication */
- auth = 0;
-
- notice->z_kind = ACKED;
-
- /* use xmit_frag() to send each piece of the notice */
-
- if ((retval = ZSrvSendRawList(notice, (char **) answer,
- found*NUM_FIELDS, xmit_frag))
- != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- }
- if (answer)
- xfree(answer);
- return;
-}
-
-static char **
-subscr_marshal_subs(notice, auth, who, found)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- register int *found;
-{
- ZNotice_t reply;
- char **answer = (char **) 0;
- int temp;
- Code_t retval;
- ZClient_t *client;
- register ZSubscr_t *subs, *subs2 = NULLZST;
- register int i;
- int defsubs = 0;
-
-#if 0
- zdbug((LOG_DEBUG, "subscr_marshal"));
-#endif
- *found = 0;
-
- /* Note that the following code is an incredible crock! */
-
- /* We cannot send multiple packets as acknowledgements to the client,
- since the hostmanager will ignore the later packets. So we need
- to send directly to the client. */
-
- /* Make our own copy so we can send directly back to the client */
- /* RSF 11/07/87 */
-
-
- if (!strcmp(notice->z_opcode, CLIENT_GIMMESUBS)) {
- /* If the client has requested his current subscriptions,
- the message field of the notice contains the port number
- of the client for which the sender desires the subscription
- list. The port field is the port of the sender. */
-
- if ((retval = ZReadAscii(notice->z_message,
- notice->z_message_len,
- (unsigned char *)&temp,
- sizeof(u_short))) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_marshal read port num: %s",
- error_message(retval));
- return((char **)0);
- }
-
- /* Blech blech blech */
- reply = *notice;
- reply.z_port = *((u_short *)&temp);
-
- client = client_which_client(who, &reply);
-
- if (client)
- subs2 = client->zct_subs;
- } else if (!strcmp(notice->z_opcode, CLIENT_GIMMEDEFS)) {
-#if 0
- zdbug((LOG_DEBUG, "gimmedefs"));
-#endif
- /* subscr_copy_def_subs allocates new pointer rings, so
- it must be freed when finished.
- the string areas pointed to are static, however.*/
- subs2 = subscr_copy_def_subs(notice->z_sender);
- defsubs = 1;
- } else {
- syslog(LOG_ERR, "subscr_marshal bogus opcode %s",
- notice->z_opcode);
- return((char **) 0);
- }
-
- if (subs2) {
-
- /* check authenticity here. The user must be authentic to get
- a list of subscriptions. If he is not subscribed to
- anything, this if-clause fails, and he gets a response
- indicating no subscriptions.
- if retrieving default subscriptions, don't care about
- authentication. */
-
- if (!auth && !defsubs) {
- return((char **) 0);
- }
- if (!defsubs) {
- if (client && (strcmp(client->zct_principal->string,
- notice->z_sender) != 0)) {
- zdbug ((LOG_DEBUG,
- "subscr_marshal: %s requests subs for %s at %s/%d",
- notice->z_sender,
- client->zct_principal->string,
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port)));
- return 0;
- }
- }
-
- for (subs = subs2->q_forw;
- subs != subs2;
- subs = subs->q_forw, (*found)++);
-
- /* found is now the number of subscriptions */
-
- /* coalesce the subscription information into a list of
- char *'s */
- if ((answer = (char **) xmalloc((*found) * NUM_FIELDS * sizeof(char *))) == (char **) 0) {
- syslog(LOG_ERR, "subscr no mem(answer)");
- *found = 0;
- } else
- for (i = 0, subs = subs2->q_forw;
- i < *found ;
- i++, subs = subs->q_forw) {
- answer[i*NUM_FIELDS] = subs->zst_dest.classname->string;
- answer[i*NUM_FIELDS + 1] = subs->zst_dest.inst->string;
- answer[i*NUM_FIELDS + 2] = subs->zst_dest.recip->string;
- }
- }
- if (defsubs)
- free_subscriptions(subs2);
- return(answer);
-}
-
-#ifdef NEW_COMPAT
-static void
-new_old_compat_subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
-{
- Code_t retval;
- ZNotice_t reply;
- ZPacket_t reppacket;
- int packlen, found, count, initfound, zerofound;
- char buf[64];
- Zconst char **answer;
- struct sockaddr_in send_to_who;
- register int i;
-
- new_compat_count_subscr++;
-
- syslog(LOG_INFO, "new old subscr, %s", inet_ntoa(who->sin_addr));
- reply = *notice;
- reply.z_kind = SERVACK;
- reply.z_authent_len = 0; /* save some space */
- reply.z_auth = 0;
-
- send_to_who = *who;
- send_to_who.sin_port = notice->z_port; /* Return port */
-
- if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "new_old_subscr_sendlist set addr: %s",
- error_message(retval));
- return;
- }
-
- /* retrieve the subscriptions */
- answer = subscr_marshal_subs(notice, auth, who, &found);
-
- /* note that when there are no subscriptions, found == 0, so
- we needn't worry about answer being NULL since
- ZFormatSmallRawNoticeList won't reference the pointer */
-
- /* send 5 at a time until we are finished */
- count = found?((found-1) / 5 + 1):1; /* total # to be sent */
- i = 0; /* pkt # counter */
-#if 0
- zdbug((LOG_DEBUG,"Found %d subscriptions for %d packets",
- found,count));
-#endif
- initfound = found;
- zerofound = (found == 0);
- while (found > 0 || zerofound) {
- packlen = sizeof(reppacket);
- (void) sprintf(buf, "%d/%d", ++i, count);
- reply.z_opcode = buf;
- retval = ZFormatSmallRawNoticeList(&reply,
- answer+(initfound-found)*NUM_FIELDS,
- ((found > 5) ? 5 : found)*NUM_FIELDS,
- reppacket,
- &packlen);
- if (retval != ZERR_NONE) {
- syslog(LOG_ERR, "subscr_sendlist format: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- found -= 5;
- zerofound = 0;
- }
-#if 0
- zdbug((LOG_DEBUG,"subscr_sendlist acked"));
-#endif
- if (answer)
- xfree(answer);
- return;
-}
-#endif /* NEW_COMPAT */
-
-#ifdef OLD_COMPAT
-static void
-old_compat_subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
-{
- ZClient_t *client = client_which_client(who, notice);
- register ZSubscr_t *subs;
- Code_t retval;
- ZNotice_t reply;
- ZPacket_t reppacket;
- int packlen, i, found = 0;
- char **answer = (char **) NULL;
-
- old_compat_count_subscr++;
-
- syslog(LOG_INFO, "old old subscr, %s", inet_ntoa(who->sin_addr));
- if (client && client->zct_subs) {
-
- /* check authenticity here. The user must be authentic to get
- a list of subscriptions. If he is not subscribed to
- anything, the above test fails, and he gets a response
- indicating no subscriptions */
-
- if (!auth) {
- clt_ack(notice, who, AUTH_FAILED);
- return;
- }
-
- for (subs = client->zct_subs->q_forw;
- subs != client->zct_subs;
- subs = subs->q_forw, found++);
-
- /* found is now the number of subscriptions */
-
- /* coalesce the subscription information into a list of
- char *'s */
- if ((answer = (char **) xmalloc(found * NUM_FIELDS * sizeof(char *))) == (char **) 0) {
- syslog(LOG_ERR, "old_subscr_sendlist no mem(answer)");
- found = 0;
- } else
- for (i = 0, subs = client->zct_subs->q_forw;
- i < found ;
- i++, subs = subs->q_forw) {
- answer[i*NUM_FIELDS] = subs->zst_class;
- answer[i*NUM_FIELDS + 1] = subs->zst_classinst;
- answer[i*NUM_FIELDS + 2] = subs->zst_recipient;
- }
- }
- /* note that when there are no subscriptions, found == 0, so
- we needn't worry about answer being NULL */
-
- reply = *notice;
- reply.z_kind = SERVACK;
- reply.z_authent_len = 0; /* save some space */
- reply.z_auth = 0;
-
-
- /* if it's too long, chop off one at a time till it fits */
- while ((retval = ZFormatSmallRawNoticeList(&reply,
- answer,
- found * NUM_FIELDS,
- reppacket,
- &packlen)) == ZERR_PKTLEN) {
- found--;
- reply.z_opcode = OLD_CLIENT_INCOMPSUBS;
- }
- if (retval != ZERR_NONE) {
- syslog(LOG_ERR, "old_subscr_sendlist format: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
-#if 0
- zdbug((LOG_DEBUG,"subscr_sendlist acked"));
-#endif
- if (answer)
- xfree(answer);
- return;
-}
-#endif /* OLD_COMPAT */
-
-/*
- * Send the client's subscriptions to another server
- */
-
-/* version is currently unused; if necessary later versions may key off it
- to determine what to send to the peer (protocol changes) */
-
-/*ARGSUSED*/
-Code_t
-subscr_send_subs(client, vers)
- ZClient_t *client;
- char *vers;
-{
- register int i = 0;
- register ZSubscr_t *sub;
-#ifdef KERBEROS
- char buf[512];
- C_Block cblock;
-#endif /* KERBEROS */
- char buf2[512];
- char *lyst[7 * NUM_FIELDS];
- int num = 0;
- Code_t retval;
-
-#if 0
- zdbug((LOG_DEBUG, "send_subs"));
-#endif
- (void) sprintf(buf2, "%d",ntohs(client->zct_sin.sin_port));
-
- lyst[num++] = buf2;
-
-#ifdef KERBEROS
-#ifdef NOENCRYPTION
- (void) memcpy((caddr_t)cblock, (caddr_t)client->zct_cblock, sizeof(C_Block));
-#else
- des_ecb_encrypt(client->zct_cblock, cblock, serv_ksched.s, DES_ENCRYPT);
-#endif
-
- if ((retval = ZMakeAscii(buf, sizeof(buf), cblock,
- sizeof(C_Block))) != ZERR_NONE) {
-#if 0
- zdbug((LOG_DEBUG,"zmakeascii failed: %s",
- error_message(retval)));
-#endif
- } else {
- lyst[num++] = buf;
-#if 0
- zdbug((LOG_DEBUG,"cblock %s",buf));
-#endif
- }
-#endif /* KERBEROS */
- if ((retval = bdump_send_list_tcp(SERVACK, client->zct_sin.sin_port,
- ZEPHYR_ADMIN_CLASS,
- num > 1 ? "CBLOCK" : "",
- ADMIN_NEWCLT,
- (char*)client->zct_principal->string,
- "", lyst, num)) != ZERR_NONE ) {
- syslog(LOG_ERR, "subscr_send_subs newclt: %s",
- error_message(retval));
- return(retval);
- }
-
- if (!client->zct_subs)
- return(ZERR_NONE);
- for (sub = client->zct_subs->q_forw;
- sub != client->zct_subs;
- sub = sub->q_forw) {
- /* for each subscription */
- lyst[i * NUM_FIELDS] = sub->zst_dest.classname->string;
- lyst[i * NUM_FIELDS + 1] = sub->zst_dest.inst->string;
- lyst[i * NUM_FIELDS + 2] = sub->zst_dest.recip->string;
- i++;
- if (i >= 7) {
- /* we only put 7 in each packet, so we don't
- run out of room */
- if ((retval = bdump_send_list_tcp(ACKED,
- client->zct_sin.sin_port,
- ZEPHYR_CTL_CLASS, "",
- CLIENT_SUBSCRIBE, "",
- "", lyst,
- i * NUM_FIELDS))
- != ZERR_NONE) {
- syslog(LOG_ERR, "subscr_send_subs subs: %s",
- error_message(retval));
- return(retval);
- }
- i = 0;
- }
- }
- if (i) {
- if ((retval = bdump_send_list_tcp(ACKED,
- client->zct_sin.sin_port,
- ZEPHYR_CTL_CLASS, "",
- CLIENT_SUBSCRIBE, "", "",
- lyst, i * NUM_FIELDS))
- != ZERR_NONE) {
- syslog(LOG_ERR, "subscr_send_subs subs: %s",
- error_message(retval));
- return(retval);
- }
- }
- return(ZERR_NONE);
-}
-
-/*
- * is this client unique to this list? 0 = no, 1 = yes
- */
-
-static int
-clt_unique(clt, clist)
- ZClient_t *clt;
- ZClientList_t *clist;
-{
- register ZClientList_t *client;
-
- for (client = clist->q_forw;
- client != clist;
- client = client->q_forw)
- if (client->zclt_client == clt)
- return(0);
- return(1);
-}
-
-/*
- * is this client listening to this notice? 1=yes, 0=no
- */
-
-static int
-cl_match(notice_subs, client)
- register ZSubscr_t *notice_subs;
- register ZClient_t *client;
-{
- register ZSubscr_t *subs;
- int relation;
-
- if (client->zct_subs == NULLZST) {
- syslog(LOG_WARNING, "cl_match w/ no subs");
- return(0);
- }
-
- for (subs = client->zct_subs->q_forw;
- subs != client->zct_subs;
- subs = subs->q_forw) {
- relation = compare_subs(notice_subs, subs, 1);
-
-/*
- if (relation < 0)
- return(0);
-*/
- if (relation == 0)
- return(1);
- }
- /* fall through */
- return(0);
-}
-
-/*
- * free the memory allocated for the list of subscriptions.
- */
-
-static void
-free_subscriptions(subs)
- register ZSubscr_t *subs;
-{
- register ZSubscr_t *sub;
-
- for (sub = subs->q_forw; sub != subs; sub = subs->q_forw) {
- xremque(sub);
- free_zstring(sub->zst_dest.classname);
- free_zstring(sub->zst_dest.inst);
- free_zstring(sub->zst_dest.recip);
- xfree(sub);
- }
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
-
- return;
-}
-
-#define ADVANCE(xx) { cp += (strlen(cp) + 1); \
- if (cp >= notice->z_message + notice->z_message_len) { \
- syslog(LOG_WARNING, "malformed subscription %d", xx); \
- return(subs); \
- }}
-
-/*
- * Parse the message body, returning a linked list of subscriptions, or
- * NULLZST if there are no subscriptions there.
- */
-
-static ZSubscr_t *
-extract_subscriptions(notice)
- register ZNotice_t *notice;
-{
- register ZSubscr_t *subs = NULLZST, *subs2;
- register char *recip, *class_name, *classinst;
- register char *cp = notice->z_message;
-
- /* parse the data area for the subscriptions */
- while (cp < notice->z_message + notice->z_message_len) {
- class_name = cp;
- if (*cp == '\0')
- /* we've exhausted the subscriptions */
- return(subs);
- ADVANCE(1);
- classinst = cp;
- ADVANCE(2);
- recip = cp;
-#if 0
- zdbug((LOG_DEBUG, "ext_sub: CLS %s INST %s RCPT %s",
- class_name, classinst, cp));
-#endif
- cp += (strlen(cp) + 1);
- if (cp > notice->z_message + notice->z_message_len) {
- syslog(LOG_WARNING, "malformed sub 3");
- return(subs);
- }
- if (!subs) {
- if (!(subs = (ZSubscr_t *)
- xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_WARNING, "ex_subs: no mem");
- return(NULLZST);
- }
- subs->q_forw = subs->q_back = subs;
- subs->zst_dest.classname = subs->zst_dest.inst =
- subs->zst_dest.recip = NULL;
- subs->zst_dest.hash_value = 0;
- }
- if (!(subs2 = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_WARNING, "ex_subs: no mem 2");
- return(subs);
- }
- subs2->q_forw = subs2->q_back = subs2;
- subs2->zst_dest.classname = make_zstring(class_name,1);
- subs2->zst_dest.inst = make_zstring(classinst,1);
- subs2->zst_dest.recip = make_zstring(recip,0);
- set_ZDestination_hash(&subs2->zst_dest);
-
- xinsque(subs2, subs);
- }
- return(subs);
-}
-
-/*
- * print subscriptions in subs onto fp.
- * assumed to be called with SIGFPE blocked
- * (true if called from signal handler)
- */
-
-void
-subscr_dump_subs(fp, subs)
- FILE *fp;
- ZSubscr_t *subs;
-{
- register ZSubscr_t *ptr;
-
- if (!subs) /* no subscriptions to dump */
- return;
-
- for (ptr = subs->q_forw; ptr != subs; ptr = ptr->q_forw) {
- fputs("\t\t'", fp);
- fputs(ptr->zst_dest.classname->string, fp);
- fputs("' '", fp);
- fputs(ptr->zst_dest.inst->string, fp);
- fputs("' '", fp);
- fputs(ptr->zst_dest.recip->string, fp);
- fputs("'\n", fp);
- }
- return;
-}
-
-int
-compare_subs(s1,s2,do_wildcard)
- ZSubscr_t *s1, *s2;
- int do_wildcard;
-{
-
-#if 0
- zdbug((LOG_DEBUG,"compare_subs: %s/%s/%s to %s/%s/%s",
- s1->zst_dest.classname->string, s1->zst_dest.inst->string, s1->zst_dest.recip->string,
- s2->zst_dest.classname->string, s2->zst_dest.inst->string, s2->zst_dest.recip->string));
-#endif
- /* wildcard must be in s2 in order for it to match */
-
- if (do_wildcard && (s1->zst_dest.classname == s2->zst_dest.classname) &&
- (s2->zst_dest.inst == wildcard_instance) &&
- (s1->zst_dest.recip == s2->zst_dest.recip))
- return(0);
-
- if (s1->zst_dest.hash_value > s2->zst_dest.hash_value)
- return 1;
- if (s1->zst_dest.hash_value < s2->zst_dest.hash_value)
- return -1;
-
- if (s1->zst_dest.classname != s2->zst_dest.classname)
- return(strcasecmp(s1->zst_dest.classname->string,
- s2->zst_dest.classname->string));
-
- if (s1->zst_dest.inst != s2->zst_dest.inst)
- return(strcasecmp(s1->zst_dest.inst->string,
- s2->zst_dest.inst->string));
-
- if (s1->zst_dest.recip != s2->zst_dest.recip)
- return(strcasecmp(s1->zst_dest.recip->string,
- s2->zst_dest.recip->string));
-
- return(0);
-}
-
-static void
-check_sub_order(subs,wc)
- ZSubscr_t *subs;
- int wc;
-{
- ZSubscr_t *subs2;
- int relation;
-
- for (subs2 = subs->q_forw;
- subs2->q_forw != subs;
- subs2 = subs2->q_forw) {
-
- /* for each existing subscription */
- relation = compare_subs(subs2,subs2->q_forw,wc);
- if (relation > 0) {
- syslog(LOG_DEBUG, "s_check failed: %s/%s/%s <=> %s/%s/%s = %d",
- subs2->zst_dest.classname->string,
- subs2->zst_dest.inst->string,
- subs2->zst_dest.recip->string,
- subs2->q_forw->zst_dest.classname->string,
- subs2->q_forw->zst_dest.inst->string,
- subs2->q_forw->zst_dest.recip->string,
- relation);
- }
-
- }
-}
diff --git a/server/timer.c b/server/timer.c
index 9d59cba..d23eb82 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -9,10 +9,12 @@
*
*/
+#include "zserver.h"
+
#ifndef SABER
#ifndef lint
-static char rcsid[] =
- "$Id$";
+static const char rcsid[] =
+"$Id$";
#endif /* lint */
#endif /* SABER */
@@ -24,46 +26,43 @@ static char rcsid[] =
* Massachusetts Institute of Technology
*
* written by Ken Raeburn
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of M.I.T. and the Student
-Information Processing Board not be used in
-advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-M.I.T. and the Student Information Processing Board
-make no representations about the suitability of
-this software for any purpose. It is provided "as is"
-without express or implied warranty.
-
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of M.I.T. and the Student
+ Information Processing Board not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+ M.I.T. and the Student Information Processing Board
+ make no representations about the suitability of
+ this software for any purpose. It is provided "as is"
+ without express or implied warranty.
+
*/
/*
* External functions:
*
- * timer timer_set_rel (time_rel, proc, arg)
+ * Timer *timer_set_rel (time_rel, proc, arg)
* long time_rel;
* void (*proc)();
* caddr_t arg;
- * timer timer_set_abs (time_abs, proc, arg)
+ * Timer *timer_set_abs (time_abs, proc, arg)
* long time_abs;
* void (*proc)();
* caddr_t arg;
*
* void timer_reset(tmr)
- * timer tmr;
+ * Timer *tmr;
*
* void timer_process()
*
*/
-#include <stdio.h>
-#include "zserver.h"
-
/* DELTA is just an offset to keep the size a bit less than a power
* of two. It's measured in pointers, so it's 32 bytes on most
* systems. */
@@ -109,180 +108,149 @@ without express or implied warranty.
#define PARENT(i) (((i) - 1) / 2)
#define CHILD1(i) ((i) * 2 + 1)
#define CHILD2(i) ((i) * 2 + 2)
-#define TIME(i) (heap[i]->time)
+#define TIME(i) (heap[i]->abstime)
#define HEAP_ASSIGN(pos, tmr) ((heap[pos] = (tmr))->heap_pos = (pos))
-long nexttimo = 0L; /* the Unix time of the next
- alarm */
-static timer *heap;
+static Timer **heap;
static int num_timers = 0;
static int heap_size = 0;
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static void timer_botch P((void*));
-static timer add_timer P((timer));
-
-/*
- * timer_set_rel(time_rel, proc)
- * time_rel: alarm time relative to now, in seconds
- * proc: subroutine to be called (no args, returns void)
- *
- * creates a "timer" and adds it to the current list, returns "timer"
- */
+static void timer_botch __P((void*));
+static Timer *add_timer __P((Timer *));
-timer timer_set_rel (time_rel, proc, arg)
- long time_rel;
- void (*proc) P((void *));
- void *arg;
+Timer *timer_set_rel(time_rel, proc, arg)
+ long time_rel;
+ void (*proc) __P((void *));
+ void *arg;
{
- timer new_t;
- new_t = (timer) xmalloc(sizeof(*new_t));
- if (new_t == NULL)
- return(NULL);
- new_t->time = time_rel + NOW;
- new_t->func = proc;
- new_t->arg = arg;
- return add_timer(new_t);
+ Timer *new_t;
+
+ new_t = (Timer *) malloc(sizeof(*new_t));
+ if (new_t == NULL)
+ return(NULL);
+ new_t->abstime = time_rel + NOW;
+ new_t->func = proc;
+ new_t->arg = arg;
+ return add_timer(new_t);
}
-/*
- * timer_reset
- *
- * args:
- * tmr: timer to be removed from the list
- *
- * removes any timers matching tmr and reallocates list
- *
- */
-
void
timer_reset(tmr)
- timer tmr;
+ Timer *tmr;
{
- int pos, min;
-
- /* Free the timer, saving its heap position. */
- pos = tmr->heap_pos;
- xfree(tmr);
-
- if (pos != num_timers - 1) {
- /* Replace the timer with the last timer in the heap and
- * restore the heap, propagating the timer either up or
- * down, depending on which way it violates the heap
- * property to insert the last timer in place of the
- * deleted timer. */
- if (pos > 0 && TIME(num_timers - 1) < TIME(PARENT(pos))) {
- do {
- HEAP_ASSIGN(pos, heap[PARENT(pos)]);
- pos = PARENT(pos);
- } while (pos > 0 && TIME(num_timers - 1) < TIME(PARENT(pos)));
- HEAP_ASSIGN(pos, heap[num_timers - 1]);
- } else {
- while (CHILD2(pos) < num_timers) {
- min = num_timers - 1;
- if (TIME(CHILD1(pos)) < TIME(min))
- min = CHILD1(pos);
- if (TIME(CHILD2(pos)) < TIME(min))
- min = CHILD2(pos);
- HEAP_ASSIGN(pos, heap[min]);
- pos = min;
- }
- if (pos != num_timers - 1)
- HEAP_ASSIGN(pos, heap[num_timers - 1]);
+ int pos, min;
+
+ /* Free the timer, saving its heap position. */
+ pos = tmr->heap_pos;
+ free(tmr);
+
+ if (pos != num_timers - 1) {
+ /* Replace the timer with the last timer in the heap and
+ * restore the heap, propagating the timer either up or
+ * down, depending on which way it violates the heap
+ * property to insert the last timer in place of the
+ * deleted timer. */
+ if (pos > 0 && TIME(num_timers - 1) < TIME(PARENT(pos))) {
+ do {
+ HEAP_ASSIGN(pos, heap[PARENT(pos)]);
+ pos = PARENT(pos);
+ } while (pos > 0 && TIME(num_timers - 1) < TIME(PARENT(pos)));
+ HEAP_ASSIGN(pos, heap[num_timers - 1]);
+ } else {
+ while (CHILD2(pos) < num_timers) {
+ min = num_timers - 1;
+ if (TIME(CHILD1(pos)) < TIME(min))
+ min = CHILD1(pos);
+ if (TIME(CHILD2(pos)) < TIME(min))
+ min = CHILD2(pos);
+ HEAP_ASSIGN(pos, heap[min]);
+ pos = min;
}
+ if (pos != num_timers - 1)
+ HEAP_ASSIGN(pos, heap[num_timers - 1]);
}
- num_timers--;
-
- /* Fix up the next timeout. */
- nexttimo = (num_timers == 0) ? 0 : heap[0]->time;
+ }
+ num_timers--;
}
#define set_timeval(t,s) ((t).tv_sec=(s),(t).tv_usec=0,(t))
-/* add_timer(t:timer)
- *
- * args:
- * t: new "timer" to be added
- *
- * returns:
- * 0 if successful
- * -1 if error (errno set) -- old time table may have been destroyed
- *
- */
-static timer
+static Timer *
add_timer(new)
- timer new;
+ Timer *new;
{
- int pos;
-
- /* Create or resize the heap as necessary. */
- if (heap_size == 0) {
- heap_size = INITIAL_HEAP_SIZE;
- heap = (timer *) xmalloc(heap_size * sizeof(timer));
- } else if (num_timers >= heap_size) {
- heap_size = heap_size * 2 + DELTA;
- heap = (timer *) xrealloc(heap, heap_size * sizeof(timer));
- }
- if (!heap) {
- xfree(new);
- return NULL;
- }
-
- /* Insert the timer into the heap. */
- pos = num_timers;
- while (pos > 0 && new->time < TIME(PARENT(pos))) {
- HEAP_ASSIGN(pos, heap[PARENT(pos)]);
- pos = PARENT(pos);
- }
- HEAP_ASSIGN(pos, new);
- num_timers++;
-
- /* Fix up the next timeout. */
- nexttimo = heap[0]->time;
- return new;
+ int pos;
+
+ /* Create or resize the heap as necessary. */
+ if (heap_size == 0) {
+ heap_size = INITIAL_HEAP_SIZE;
+ heap = (Timer **) malloc(heap_size * sizeof(Timer *));
+ } else if (num_timers >= heap_size) {
+ heap_size = heap_size * 2 + DELTA;
+ heap = (Timer **) realloc(heap, heap_size * sizeof(Timer *));
+ }
+ if (!heap) {
+ free(new);
+ return NULL;
+ }
+
+ /* Insert the Timer *into the heap. */
+ pos = num_timers;
+ while (pos > 0 && new->abstime < TIME(PARENT(pos))) {
+ HEAP_ASSIGN(pos, heap[PARENT(pos)]);
+ pos = PARENT(pos);
+ }
+ HEAP_ASSIGN(pos, new);
+ num_timers++;
+
+ return new;
}
-/*
- * timer_process -- checks for next timer execution time
- * and execute
- *
- */
-
void
timer_process()
{
- register timer t;
- timer_proc func;
- void *arg;
- int valid = 0;
-
- if (num_timers == 0 || heap[0]->time > NOW)
- return;
-
- /* Remove the first timer from the heap, remembering it's
- * function and argument. timer_reset() updates nexttimo. */
- t = heap[0];
- func = t->func;
- arg = t->arg;
- t->func = timer_botch;
- t->arg = NULL;
- timer_reset(t);
+ Timer *t;
+ timer_proc func;
+ void *arg;
+ int valid = 0;
+
+ if (num_timers == 0 || heap[0]->abstime > NOW)
+ return;
+
+ /* Remove the first timer from the heap, remembering its
+ * function and argument. */
+ t = heap[0];
+ func = t->func;
+ arg = t->arg;
+ t->func = timer_botch;
+ t->arg = NULL;
+ timer_reset(t);
+
+ /* Run the function. */
+ func(arg);
+}
- /* Run the function. */
- (func)(arg);
+struct timeval *
+timer_timeout(tvbuf)
+ struct timeval *tvbuf;
+{
+ if (num_timers > 0) {
+ tvbuf->tv_sec = heap[0]->abstime - NOW;
+ if (tvbuf->tv_sec < 0)
+ tvbuf->tv_sec = 0;
+ tvbuf->tv_usec = 0;
+ return tvbuf;
+ } else {
+ return NULL;
+ }
}
static void
timer_botch(arg)
- void *arg;
+ void *arg;
{
- syslog(LOG_CRIT, "Timer botch\n");
- abort();
+ syslog(LOG_CRIT, "timer botch\n");
+ abort();
}
diff --git a/server/timer.h b/server/timer.h
index 231208f..42c0081 100644
--- a/server/timer.h
+++ b/server/timer.h
@@ -6,11 +6,12 @@
*
* $Source$
* $Author$
- * $Header: /mit/zephyr/src/server/RCS/timer.h,v 1.9 94/03/15 12:44:40 prob
-e Exp $
+ * $Header$
*
*/
+#ifndef __TIMER_H
+
/*
* timer_manager_ -- routines for handling timers in login_shell
* (and elsewhere)
@@ -36,31 +37,20 @@ without express or implied warranty.
*/
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-typedef struct _timer {
- int heap_pos;
- /* time for timer to go off, absolute time */
- long time;
- /* procedure to call when timer goes off */
- void (*func)P((void*));
- /* argument for that procedure */
- void * arg;
-} *timer;
+typedef void (*timer_proc) __P((void *));
-#define NOW t_local.tv_sec
-typedef void (*timer_proc) P((void *));
-extern timer timer_set_rel P((long, timer_proc, void*));
-extern timer timer_set_abs P((long, timer_proc, void*));
-extern void timer_reset P((timer)), timer_process P((void));
+typedef struct _Timer {
+ int heap_pos; /* Position in timer heap */
+ long abstime;
+ timer_proc func;
+ void *arg;
+} Timer;
-#undef P
+Timer *timer_set_rel __P((long, timer_proc, void *));
+Timer *timer_set_abs __P((long, timer_proc, void *));
+void timer_reset __P((Timer *));
+void timer_process __P((void));
+struct timeval *timer_timeout __P((struct timeval *tvbuf));
-#define timer_when(x) ALARM_TIME(x)
+#endif /* __TIMER_H */
-extern struct timeval t_local;
-extern long nexttimo; /* Unix time of next timout */
diff --git a/server/uloc.c b/server/uloc.c
index 018d657..9bd7a11 100644
--- a/server/uloc.c
+++ b/server/uloc.c
@@ -12,16 +12,16 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
+#include <sys/socket.h>
#ifndef lint
#ifndef SABER
-static char rcsid_uloc_c[] =
- "$Id$";
+static const char rcsid_uloc_c[] =
+"$Id$";
#endif /* SABER */
#endif /* lint */
-#include "zserver.h"
-
/*
* The user locator functions.
*
@@ -31,13 +31,13 @@ static char rcsid_uloc_c[] =
* ZNotice_t *notice;
* int auth;
* struct sockaddr_in *who;
- * ZServerDesc_t *server;
+ * Server *server;
*
* void ulogin_dispatch(notice, auth, who, server)
* ZNotice_t *notice;
* int auth;
* struct sockaddr_in *who;
- * ZServerDesc_t *server;
+ * Server *server;
*
* void uloc_hflush(addr)
* struct in_addr *addr;
@@ -45,9 +45,7 @@ static char rcsid_uloc_c[] =
* void uloc_flush_client(sin)
* struct sockaddr_in *sin;
*
- * Code_t uloc_send_locations(host, version)
- * ZHostList_t *host;
- * char *version;
+ * Code_t uloc_send_locations()
*
* void uloc_dump_locs(fp)
* FILE *fp;
@@ -55,7 +53,7 @@ static char rcsid_uloc_c[] =
/*
* The user locator.
- * We maintain an array of ZLocation_t sorted by user (so we can do
+ * We maintain an array of Location sorted by user (so we can do
* binary searches), growing and shrinking it as necessary.
*/
@@ -64,58 +62,53 @@ static char rcsid_uloc_c[] =
/* else you will lose. See ulogin_locate() and uloc_send_locations() */
#define NUM_FIELDS 3
-typedef enum _exposure_type {
- NONE,
- OPSTAFF_VIS,
- REALM_VIS,
- REALM_ANN,
- NET_VIS,
- NET_ANN
-} exposure_type;
-
-typedef struct _ZLocation_t {
- ZSTRING * zlt_user;
- ZSTRING * zlt_machine;
- char * zlt_time; /* in ctime format */
- ZSTRING * zlt_tty;
- struct in_addr zlt_addr; /* IP addr of this loc */
- unsigned short zlt_port; /* port of registering client--
- for removing old entries */
- exposure_type zlt_exposure;
-} ZLocation_t;
-
-#define NULLZLT ((ZLocation_t *) 0)
+typedef enum _Exposure_type {
+ NONE,
+ OPSTAFF_VIS,
+ REALM_VIS,
+ REALM_ANN,
+ NET_VIS,
+ NET_ANN
+} Exposure_type;
+
+typedef struct _Location {
+ String *user;
+ String *machine;
+ char *time; /* in ctime format */
+ String *tty;
+ struct sockaddr_in addr; /* IP address and port of location */
+ Exposure_type exposure;
+} Location;
+
#define NOLOC 1
#define QUIET -1
#define UNAUTH -2
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-static void ulogin_locate P((ZNotice_t *notice, struct sockaddr_in *who,
- int auth)),
- ulogin_flush_user P((ZNotice_t *notice));
-static ZLocation_t *ulogin_find P((ZNotice_t *notice, int strict));
-static int ulogin_setup P((ZNotice_t *notice, ZLocation_t *locs,
- exposure_type exposure, struct sockaddr_in *who)),
- ulogin_add_user P((ZNotice_t *notice, exposure_type exposure,
- struct sockaddr_in *who)),
- ulogin_parse P((ZNotice_t *notice, ZLocation_t *locs)),
- ulogin_expose_user P((ZNotice_t *notice, exposure_type exposure));
-static exposure_type ulogin_remove_user P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- int *err_return));
-static void login_sendit P((ZNotice_t *notice, int auth, struct sockaddr_in *who));
-static char **ulogin_marshal_locs P((ZNotice_t *notice, int *found, int auth));
-
-static int ul_equiv P((ZLocation_t *l1, ZLocation_t *l2));
-
-static void free_loc P((ZLocation_t *loc));
-
-static ZLocation_t *locations = NULLZLT; /* ptr to first in array */
+static void ulogin_locate __P((ZNotice_t *notice, struct sockaddr_in *who,
+ int auth)),
+ulogin_flush_user __P((ZNotice_t *notice));
+static Location *ulogin_find __P((ZNotice_t *notice, int strict));
+static int ulogin_setup __P((ZNotice_t *notice, Location *locs,
+ Exposure_type exposure, struct sockaddr_in *who)),
+ulogin_add_user __P((ZNotice_t *notice, Exposure_type exposure,
+ struct sockaddr_in *who)),
+ulogin_parse __P((ZNotice_t *notice, Location *locs)),
+ulogin_expose_user __P((ZNotice_t *notice, Exposure_type exposure));
+static Exposure_type ulogin_remove_user __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who,
+ int *err_return));
+static void login_sendit __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who, int external));
+static char **ulogin_marshal_locs __P((ZNotice_t *notice, int *found,
+ int auth));
+
+static int ul_equiv __P((Location *l1, Location *l2));
+
+static void free_loc __P((Location *loc));
+static void ulogin_locate_forward __P((ZNotice_t *notice,
+ struct sockaddr_in *who, Realm *realm));
+
+static Location *locations = NULL; /* ptr to first in array */
static int num_locs = 0; /* number in array */
/*
@@ -124,197 +117,199 @@ static int num_locs = 0; /* number in array */
Code_t
ulogin_dispatch(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
{
- exposure_type retval;
- int err_ret;
- ZHostList_t *host;
+ Exposure_type retval;
+ int err_ret;
#if 0
- zdbug((LOG_DEBUG,
- "ulogin_dispatch: opc=%s from=%s/%d auth=%d who=%s/%d",
- notice->z_opcode, notice->z_sender, ntohs (notice->z_port),
- auth, inet_ntoa (who->sin_addr), ntohs (who->sin_port)));
+ zdbug((LOG_DEBUG,
+ "ulogin_dispatch: opc=%s from=%s/%d auth=%d who=%s/%d",
+ notice->z_opcode, notice->z_sender, ntohs (notice->z_port),
+ auth, inet_ntoa (who->sin_addr), ntohs (who->sin_port)));
#endif
- host = hostm_find_host(&who->sin_addr);
- if (host && host->zh_locked)
- return(ZSRV_REQUEUE);
-
- if (!strcmp(notice->z_opcode, LOGIN_USER_LOGOUT)) {
+ if (strcmp(notice->z_opcode, LOGIN_USER_LOGOUT) == 0) {
#if 0
- zdbug((LOG_DEBUG,"logout"));
+ zdbug((LOG_DEBUG,"logout"));
#endif
- retval = ulogin_remove_user(notice, auth, who, &err_ret);
- switch (retval) {
- case NONE:
- if (err_ret == UNAUTH) {
+ retval = ulogin_remove_user(notice, auth, who, &err_ret);
+ switch (retval) {
+ case NONE:
+ if (err_ret == UNAUTH) {
#if 0
- zdbug((LOG_DEBUG, "unauth logout: %s %d",
- inet_ntoa(who->sin_addr),
- ntohs(notice->z_port)));
+ zdbug((LOG_DEBUG, "unauth logout: %s %d",
+ inet_ntoa(who->sin_addr),
+ ntohs(notice->z_port)));
#endif
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- } else if (err_ret == NOLOC) {
- if (server == me_server)
- clt_ack(notice, who, NOT_FOUND);
- return(ZERR_NONE);
- }
- syslog(LOG_ERR,"bogus location exposure NONE, %s",
- notice->z_sender);
- break;
- case OPSTAFF_VIS:
- case REALM_VIS:
- /* he is not announced to people. Silently ack */
- if (server == me_server)
- ack(notice, who);
- break;
- case REALM_ANN:
- case NET_VIS:
- case NET_ANN:
- /* currently no distinction between these.
- just announce */
- /* we assume that if this user is at a certain
- IP address, we can trust the logout to be
- authentic. ulogin_remove_user checks the
- ip addrs */
- if (server == me_server)
- sendit(notice, 1, who);
- break;
- default:
- syslog(LOG_ERR,"bogus location exposure %d/%s",
- (int) retval, notice->z_sender);
- break;
- }
- if (server == me_server) /* tell the other servers */
- server_forward(notice, auth, who);
- return(ZERR_NONE);
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return ZERR_NONE;
+ } else if (err_ret == NOLOC) {
+ if (server == me_server)
+ clt_ack(notice, who, NOT_FOUND);
+ return ZERR_NONE;
+ }
+ syslog(LOG_ERR,"bogus location exposure NONE, %s",
+ notice->z_sender);
+ break;
+ case OPSTAFF_VIS:
+ case REALM_VIS:
+ /* he is not announced to people. Silently ack */
+ if (server == me_server)
+ ack(notice, who);
+ break;
+ case REALM_ANN:
+ case NET_VIS:
+ if (server == me_server)
+ sendit(notice, 1, who, 0);
+ break;
+ case NET_ANN:
+ /* currently no distinction between these.
+ just announce */
+ /* we assume that if this user is at a certain
+ IP address, we can trust the logout to be
+ authentic. ulogin_remove_user checks the
+ ip addrs */
+ if (server == me_server)
+ sendit(notice, 1, who, 1);
+ break;
+ default:
+ syslog(LOG_ERR,"bogus location exposure %d/%s",
+ (int) retval, notice->z_sender);
+ break;
}
- if (!bdumping &&
- (!auth || strcmp(notice->z_sender, notice->z_class_inst))) {
+ if (server == me_server) /* tell the other servers */
+ server_forward(notice, auth, who);
+ return ZERR_NONE;
+ }
+ if (!bdumping &&
+ (!auth || strcmp(notice->z_sender, notice->z_class_inst) != 0)) {
#if 1
- zdbug((LOG_DEBUG,"unauthentic ulogin: %d %s %s", auth,
- notice->z_sender, notice->z_class_inst));
+ zdbug((LOG_DEBUG,"unauthentic ulogin: %d %s %s", auth,
+ notice->z_sender, notice->z_class_inst));
#endif
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
- if (!strcmp(notice->z_opcode, LOGIN_USER_FLUSH)) {
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return ZERR_NONE;
+ }
+ if (strcmp(notice->z_opcode, LOGIN_USER_FLUSH) == 0) {
#if 0
- zdbug((LOG_DEBUG, "user flush"));
+ zdbug((LOG_DEBUG, "user flush"));
#endif
- ulogin_flush_user(notice);
- if (server == me_server)
- ack(notice, who);
- } else if (!strcmp(notice->z_opcode, EXPOSE_NONE)) {
+ ulogin_flush_user(notice);
+ if (server == me_server)
+ ack(notice, who);
+ } else if (strcmp(notice->z_opcode, EXPOSE_NONE) == 0) {
#if 0
- zdbug((LOG_DEBUG,"no expose"));
+ zdbug((LOG_DEBUG,"no expose"));
#endif
- (void) ulogin_remove_user(notice, auth, who, &err_ret);
- if (err_ret == UNAUTH) {
+ ulogin_remove_user(notice, auth, who, &err_ret);
+ if (err_ret == UNAUTH) {
#if 0
- zdbug((LOG_DEBUG, "unauth noexpose: %s/%d",
- inet_ntoa(who->sin_addr),
- ntohs(notice->z_port)));
+ zdbug((LOG_DEBUG, "unauth noexpose: %s/%d",
+ inet_ntoa(who->sin_addr), ntohs(notice->z_port)));
#endif
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- } else if (err_ret == NOLOC) {
- if (server == me_server)
- clt_ack(notice, who, NOT_FOUND);
- return(ZERR_NONE);
- }
- if (server == me_server) {
- ack(notice, who);
- server_forward(notice, auth, who);
- }
- return(ZERR_NONE);
- } else if (!strcmp(notice->z_opcode, EXPOSE_OPSTAFF)) {
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return ZERR_NONE;
+ } else if (err_ret == NOLOC) {
+ if (server == me_server)
+ clt_ack(notice, who, NOT_FOUND);
+ return ZERR_NONE;
+ }
+ if (server == me_server) {
+ ack(notice, who);
+ server_forward(notice, auth, who);
+ }
+ return ZERR_NONE;
+ } else if (strcmp(notice->z_opcode, EXPOSE_OPSTAFF) == 0) {
#if 0
- zdbug((LOG_DEBUG,"opstaff"));
+ zdbug((LOG_DEBUG,"opstaff"));
#endif
- err_ret = ulogin_add_user(notice, OPSTAFF_VIS, who);
- if (server == me_server)
- if (err_ret)
- nack(notice, who);
- else
- ack(notice, who);
- } else if (!strcmp(notice->z_opcode, EXPOSE_REALMVIS)) {
+ err_ret = ulogin_add_user(notice, OPSTAFF_VIS, who);
+ if (server == me_server) {
+ if (err_ret)
+ nack(notice, who);
+ else
+ ack(notice, who);
+ }
+ } else if (strcmp(notice->z_opcode, EXPOSE_REALMVIS) == 0) {
#if 0
- zdbug((LOG_DEBUG,"realmvis"));
+ zdbug((LOG_DEBUG,"realmvis"));
#endif
- err_ret = ulogin_add_user(notice, REALM_VIS, who);
- if (server == me_server) /* realm vis is not broadcast,
- so we ack it here */
- if (err_ret)
- nack(notice, who);
- else
- ack(notice, who);
- } else if (!strcmp(notice->z_opcode, EXPOSE_REALMANN)) {
+ err_ret = ulogin_add_user(notice, REALM_VIS, who);
+ if (server == me_server) { /* realm vis is not broadcast,
+ so we ack it here */
+ if (err_ret)
+ nack(notice, who);
+ else
+ ack(notice, who);
+ }
+ } else if (!strcmp(notice->z_opcode, EXPOSE_REALMANN)) {
#if 0
- zdbug((LOG_DEBUG,"realmann"));
+ zdbug((LOG_DEBUG,"realmann"));
#endif
- err_ret = ulogin_add_user(notice, REALM_ANN, who);
- if (server == me_server) /* announce to the realm */
- if (err_ret)
- nack(notice, who);
- else
- login_sendit(notice, auth, who);
- } else if (!strcmp(notice->z_opcode, EXPOSE_NETVIS)) {
+ err_ret = ulogin_add_user(notice, REALM_ANN, who);
+ if (server == me_server) { /* announce to the realm */
+ if (err_ret)
+ nack(notice, who);
+ else
+ login_sendit(notice, auth, who, 0);
+ }
+ } else if (!strcmp(notice->z_opcode, EXPOSE_NETVIS)) {
#if 0
- zdbug((LOG_DEBUG,"netvis"));
+ zdbug((LOG_DEBUG,"netvis"));
#endif
- err_ret = ulogin_add_user(notice, NET_VIS, who);
- if (server == me_server) /* announce to the realm */
- if (err_ret)
- nack(notice, who);
- else
- login_sendit(notice, auth, who);
- } else if (!strcmp(notice->z_opcode, EXPOSE_NETANN)) {
+ err_ret = ulogin_add_user(notice, NET_VIS, who);
+ if (server == me_server) { /* announce to the realm */
+ if (err_ret)
+ nack(notice, who);
+ else
+ login_sendit(notice, auth, who, 0);
+ }
+ } else if (!strcmp(notice->z_opcode, EXPOSE_NETANN)) {
#if 0
- zdbug((LOG_DEBUG,"netann"));
+ zdbug((LOG_DEBUG,"netann"));
#endif
- err_ret = ulogin_add_user(notice, NET_ANN, who);
- if (server == me_server) /* tell the world */
- if (err_ret)
- nack(notice, who);
- else
- login_sendit(notice, auth, who);
- } else {
- syslog(LOG_ERR, "unknown ulog opcode %s", notice->z_opcode);
- if (server == me_server)
- nack(notice, who);
- return(ZERR_NONE);
+ err_ret = ulogin_add_user(notice, NET_ANN, who);
+ if (server == me_server) { /* tell the world */
+ if (err_ret)
+ nack(notice, who);
+ else
+ login_sendit(notice, auth, who, 1);
}
+ } else {
+ syslog(LOG_ERR, "unknown ulog opcode %s", notice->z_opcode);
if (server == me_server)
- server_forward(notice, auth, who);
- return(ZERR_NONE);
+ nack(notice, who);
+ return ZERR_NONE;
+ }
+ if (server == me_server)
+ server_forward(notice, auth, who);
+ return ZERR_NONE;
}
static void
-login_sendit(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+login_sendit(notice, auth, who, external)
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ int external;
{
- ZNotice_t log_notice;
+ ZNotice_t log_notice;
- /* we must copy the notice struct here because we need the original
- for forwarding. We needn't copy the private data of the notice,
- since that isn't modified by sendit and its subroutines. */
+ /* we must copy the notice struct here because we need the original
+ for forwarding. We needn't copy the private data of the notice,
+ since that isn't modified by sendit and its subroutines. */
- log_notice = *notice;
+ log_notice = *notice;
- log_notice.z_opcode = LOGIN_USER_LOGIN;
- sendit(&log_notice, auth, who);
- return;
+ log_notice.z_opcode = LOGIN_USER_LOGIN;
+ sendit(&log_notice, auth, who, external);
}
@@ -323,46 +318,53 @@ login_sendit(notice, auth, who)
*/
Code_t
ulocate_dispatch(notice, auth, who, server)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- ZServerDesc_t *server;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ Server *server;
{
+ char *cp;
+ Realm *realm;
+
#if 0
- zdbug((LOG_DEBUG,"ulocate_disp"));
+ zdbug((LOG_DEBUG,"ulocate_disp"));
#endif
-#if 0 /* Now we support unauthentic locate for net-visible. */
- if (!auth) {
+#if 0 /* Now we support unauthentic locate for net-visible. */
+ if (!auth) {
#if 0
- zdbug((LOG_DEBUG,"unauthentic ulocate"));
+ zdbug((LOG_DEBUG,"unauthentic ulocate"));
#endif
- if (server == me_server)
- clt_ack(notice, who, AUTH_FAILED);
- return(ZERR_NONE);
- }
+ if (server == me_server)
+ clt_ack(notice, who, AUTH_FAILED);
+ return ZERR_NONE;
+ }
#endif
- if (!strcmp(notice->z_opcode, LOCATE_LOCATE)) {
+ if (!strcmp(notice->z_opcode, LOCATE_LOCATE)) {
#if 0
- zdbug((LOG_DEBUG,"locate"));
+ zdbug((LOG_DEBUG,"locate"));
#endif
- /* we are talking to a current-rev client; send an ack */
- ack(notice, who);
- ulogin_locate(notice, who, auth);
- return(ZERR_NONE);
- } else {
- syslog(LOG_ERR, "unknown uloc opcode %s", notice->z_opcode);
- if (server == me_server)
- nack(notice, who);
- return(ZERR_NONE);
- }
+ /* we are talking to a current-rev client; send an ack */
+ ack(notice, who);
+ cp = strchr(notice->z_class_inst, '@');
+ if (cp && (realm = realm_get_realm_by_name(cp + 1)))
+ ulogin_locate_forward(notice, who, realm);
+ else
+ ulogin_locate(notice, who, auth);
+ return ZERR_NONE;
+ } else {
+ syslog(LOG_ERR, "unknown uloc opcode %s", notice->z_opcode);
+ if (server == me_server)
+ nack(notice, who);
+ return ZERR_NONE;
+ }
#if 0
- if (server == me_server) {
- server_forward(notice, auth, who);
- ack(notice, who);
- }
+ if (server == me_server) {
+ server_forward(notice, auth, who);
+ ack(notice, who);
+ }
+ return ZERR_NONE;
#endif
- return(ZERR_NONE);
}
/*
@@ -371,135 +373,121 @@ ulocate_dispatch(notice, auth, who, server)
void
uloc_hflush(addr)
- struct in_addr *addr;
+ struct in_addr *addr;
{
- ZLocation_t *loc;
- register int i = 0, new_num = 0;
-
- if (num_locs == 0)
- return; /* none to flush */
-
- START_CRITICAL_CODE;
-
- /* slightly inefficient, assume the worst, and allocate enough space */
- loc = (ZLocation_t *) xmalloc(num_locs *sizeof(ZLocation_t));
- if (!loc) {
- syslog(LOG_CRIT, "uloc_flush alloc");
- abort();
- /*NOTREACHED*/
- }
-
- /* copy entries which don't match */
- while (i < num_locs) {
- if (locations[i].zlt_addr.s_addr != addr->s_addr)
- loc[new_num++] = locations[i];
- else {
+ Location *loc;
+ int i = 0, new_num = 0;
+
+ if (num_locs == 0)
+ return; /* none to flush */
+
+ /* slightly inefficient, assume the worst, and allocate enough space */
+ loc = (Location *) malloc(num_locs *sizeof(Location));
+ if (!loc) {
+ syslog(LOG_CRIT, "uloc_flush alloc");
+ abort();
+ }
+
+ /* copy entries which don't match */
+ while (i < num_locs) {
+ if (locations[i].addr.sin_addr.s_addr != addr->s_addr) {
+ loc[new_num++] = locations[i];
+ } else {
#if 0
- if (zdebug)
- syslog(LOG_DEBUG, "uloc hflushing %s/%s/%s",
- locations[i].zlt_user->string,
- locations[i].zlt_machine->string,
- locations[i].zlt_tty->string);
+ if (zdebug)
+ syslog(LOG_DEBUG, "uloc hflushing %s/%s/%s",
+ locations[i].user->string,
+ locations[i].machine->string,
+ locations[i].tty->string);
#endif
- free_loc(&locations[i]);
- }
- i++;
+ free_loc(&locations[i]);
}
+ i++;
+ }
- xfree(locations);
- locations = NULLZLT;
+ free(locations);
+ locations = NULL;
- if (!new_num) {
+ if (!new_num) {
#if 0
- zdbug((LOG_DEBUG,"no more locs"));
+ zdbug((LOG_DEBUG,"no more locs"));
#endif
- xfree(loc);
- loc = NULLZLT;
- num_locs = new_num;
-
- END_CRITICAL_CODE;
-
- return;
- }
- locations = loc;
+ free(loc);
+ loc = NULL;
num_locs = new_num;
- END_CRITICAL_CODE;
-
- /* all done */
return;
+ }
+ locations = loc;
+ num_locs = new_num;
+
+ /* all done */
+ return;
}
void
uloc_flush_client(sin)
- struct sockaddr_in *sin;
+ struct sockaddr_in *sin;
{
- ZLocation_t *loc;
- register int i = 0, new_num = 0;
-
- if (num_locs == 0)
- return; /* none to flush */
-
- START_CRITICAL_CODE;
-
- /* slightly inefficient, assume the worst, and allocate enough space */
- loc = (ZLocation_t *) xmalloc(num_locs *sizeof(ZLocation_t));
- if (!loc) {
- syslog(LOG_CRIT, "uloc_flush_clt alloc");
- abort();
- /*NOTREACHED*/
- }
-
- /* copy entries which don't match */
- while (i < num_locs) {
- if ((locations[i].zlt_addr.s_addr != sin->sin_addr.s_addr)
- || (locations[i].zlt_port != sin->sin_port))
- loc[new_num++] = locations[i];
- else {
+ Location *loc;
+ int i = 0, new_num = 0;
+
+ if (num_locs == 0)
+ return; /* none to flush */
+
+ /* slightly inefficient, assume the worst, and allocate enough space */
+ loc = (Location *) malloc(num_locs *sizeof(Location));
+ if (!loc) {
+ syslog(LOG_CRIT, "uloc_flush_clt alloc");
+ abort();
+ }
+
+ /* copy entries which don't match */
+ while (i < num_locs) {
+ if ((locations[i].addr.sin_addr.s_addr != sin->sin_addr.s_addr)
+ || (locations[i].addr.sin_port != sin->sin_port)) {
+ loc[new_num++] = locations[i];
+ } else {
#if 0
- if (zdebug)
- syslog(LOG_DEBUG, "uloc cflushing %s/%s/%s",
- locations[i].zlt_user->string,
- locations[i].zlt_machine->string,
- locations[i].zlt_tty->string);
+ if (zdebug)
+ syslog(LOG_DEBUG, "uloc cflushing %s/%s/%s",
+ locations[i].user->string,
+ locations[i].machine->string,
+ locations[i].tty->string);
#endif
- free_loc(&locations[i]);
- }
- i++;
+ free_loc(&locations[i]);
}
+ i++;
+ }
- xfree(locations);
- locations = NULLZLT;
+ free(locations);
+ locations = NULL;
- if (!new_num) {
+ if (!new_num) {
#if 0
- zdbug((LOG_DEBUG,"no more locs"));
+ zdbug((LOG_DEBUG,"no more locs"));
#endif
- xfree(loc);
- loc = NULLZLT;
- num_locs = new_num;
-
- END_CRITICAL_CODE;
-
- return;
- }
- locations = loc;
+ free(loc);
+ loc = NULL;
num_locs = new_num;
- END_CRITICAL_CODE;
+ return;
+ }
+ locations = loc;
+ num_locs = new_num;
#ifdef DEBUG
- if (zdebug) {
- register int i;
+ if (zdebug) {
+ int i;
- for (i = 0; i < num_locs; i++)
- syslog(LOG_DEBUG, "%s/%d",
- locations[i].zlt_user->string,
- (int) locations[i].zlt_exposure);
+ for (i = 0; i < num_locs; i++) {
+ syslog(LOG_DEBUG, "%s/%d", locations[i].user->string,
+ (int) locations[i].exposure);
}
+ }
#endif
- /* all done */
- return;
+ /* all done */
+ return;
}
/*
@@ -508,59 +496,49 @@ uloc_flush_client(sin)
/*ARGSUSED*/
Code_t
-uloc_send_locations(host, vers)
- ZHostList_t *host;
- char *vers;
+uloc_send_locations()
{
- register ZLocation_t *loc;
- register int i;
- register struct in_addr *haddr = &host->zh_addr.sin_addr;
- char *lyst[NUM_FIELDS];
- char *exposure_level;
- Code_t retval;
-
- for (i = 0, loc = locations; i < num_locs; i++, loc++) {
- if (loc->zlt_addr.s_addr != haddr->s_addr)
- continue;
- lyst[0] = (char *) loc->zlt_machine->string;
- lyst[1] = (char *) loc->zlt_time;
- lyst[2] = (char *) loc->zlt_tty->string;
-
- switch (loc->zlt_exposure) {
- case OPSTAFF_VIS:
- exposure_level = EXPOSE_OPSTAFF;
- break;
- case REALM_VIS:
- exposure_level = EXPOSE_REALMVIS;
- break;
- case REALM_ANN:
- exposure_level = EXPOSE_REALMANN;
- break;
- case NET_VIS:
- exposure_level = EXPOSE_NETVIS;
- break;
- case NET_ANN:
- exposure_level = EXPOSE_NETANN;
- break;
- default:
- syslog(LOG_ERR,"broken location state %s/%d",
- loc->zlt_user->string,
- (int) loc->zlt_exposure);
- break;
- }
- retval = bdump_send_list_tcp(ACKED, loc->zlt_port,
- LOGIN_CLASS,
- (char *) loc->zlt_user->string, /* XXX */
- exposure_level,
- myname, "", lyst,
- NUM_FIELDS);
- if (retval != ZERR_NONE) {
- syslog(LOG_ERR, "uloc_send_locs: %s",
- error_message(retval));
- return(retval);
- }
+ Location *loc;
+ int i;
+ char *lyst[NUM_FIELDS];
+ char *exposure_level;
+ Code_t retval;
+
+ for (i = 0, loc = locations; i < num_locs; i++, loc++) {
+ lyst[0] = (char *) loc->machine->string;
+ lyst[1] = (char *) loc->time;
+ lyst[2] = (char *) loc->tty->string;
+
+ switch (loc->exposure) {
+ case OPSTAFF_VIS:
+ exposure_level = EXPOSE_OPSTAFF;
+ break;
+ case REALM_VIS:
+ exposure_level = EXPOSE_REALMVIS;
+ break;
+ case REALM_ANN:
+ exposure_level = EXPOSE_REALMANN;
+ break;
+ case NET_VIS:
+ exposure_level = EXPOSE_NETVIS;
+ break;
+ case NET_ANN:
+ exposure_level = EXPOSE_NETANN;
+ break;
+ default:
+ syslog(LOG_ERR,"broken location state %s/%d",
+ loc->user->string, (int) loc->exposure);
+ break;
+ }
+ retval = bdump_send_list_tcp(ACKED, &loc->addr, LOGIN_CLASS,
+ loc->user->string, exposure_level, myname,
+ "", lyst, NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "uloc_send_locs: %s", error_message(retval));
+ return(retval);
}
- return(ZERR_NONE);
+ }
+ return ZERR_NONE;
}
/*
@@ -569,88 +547,81 @@ uloc_send_locations(host, vers)
static int
ulogin_add_user(notice, exposure, who)
- ZNotice_t *notice;
- exposure_type exposure;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ Exposure_type exposure;
+ struct sockaddr_in *who;
{
- ZLocation_t *oldlocs, newloc;
- register int i;
+ Location *oldlocs, newloc;
+ int i;
- if ((oldlocs = ulogin_find(notice,1)) != NULLZLT) {
+ if ((oldlocs = ulogin_find(notice,1)) != NULL) {
#if 0
- zdbug((LOG_DEBUG,"ul_add: already here"));
+ zdbug((LOG_DEBUG,"ul_add: already here"));
#endif
- (void) ulogin_expose_user(notice, exposure);
- return 0;
- }
-
- oldlocs = locations;
-
- START_CRITICAL_CODE;
-
- locations = (ZLocation_t *) xmalloc((num_locs +1) *
- sizeof(ZLocation_t));
- if (!locations) {
- syslog(LOG_ERR, "zloc mem alloc");
- locations = oldlocs;
- return 1;
- }
-
- if (num_locs == 0) { /* first one */
- if (ulogin_setup(notice, locations, exposure, who)) {
- xfree(locations);
- locations = NULLZLT;
- END_CRITICAL_CODE;
- return 1;
- }
- num_locs = 1;
- goto dprnt;
- }
-
- /* not the first one, insert him */
-
- if (ulogin_setup(notice, &newloc, exposure, who)) {
- xfree(locations);
- locations = oldlocs;
- END_CRITICAL_CODE;
- return 1;
- }
- num_locs++;
+ ulogin_expose_user(notice, exposure);
+ return 0;
+ }
- /* copy old locs */
- i = 0;
- while ((i < num_locs-1) &&
- (comp_zstring(oldlocs[i].zlt_user,newloc.zlt_user) < 0)) {
- locations[i] = oldlocs[i];
- i++;
- }
+ oldlocs = locations;
- /* add him in here */
- locations[i++] = newloc;
+ locations = (Location *) malloc((num_locs + 1) * sizeof(Location));
+ if (!locations) {
+ syslog(LOG_ERR, "zloc mem alloc");
+ locations = oldlocs;
+ return 1;
+ }
- /* copy the rest */
- while (i < num_locs) {
- locations[i] = oldlocs[i - 1];
- i++;
+ if (num_locs == 0) { /* first one */
+ if (ulogin_setup(notice, locations, exposure, who)) {
+ free(locations);
+ locations = NULL;
+ return 1;
}
- if (oldlocs)
- xfree(oldlocs);
-
- dprnt:
+ num_locs = 1;
+ goto dprnt;
+ }
+
+ /* not the first one, insert him */
+
+ if (ulogin_setup(notice, &newloc, exposure, who)) {
+ free(locations);
+ locations = oldlocs;
+ return 1;
+ }
+ num_locs++;
+
+ /* copy old locs */
+ i = 0;
+ while ((i < num_locs-1) &&
+ (comp_string(oldlocs[i].user,newloc.user) < 0)) {
+ locations[i] = oldlocs[i];
+ i++;
+ }
+
+ /* add him in here */
+ locations[i++] = newloc;
+
+ /* copy the rest */
+ while (i < num_locs) {
+ locations[i] = oldlocs[i - 1];
+ i++;
+ }
+ if (oldlocs)
+ free(oldlocs);
+
+ dprnt:
#if 0
- if (zdebug) {
- register int i;
- syslog(LOG_DEBUG, "ul_add: New Locations (%d)", num_locs);
- for (i = 0; i < num_locs; i++)
- syslog(LOG_DEBUG, "%s/%s/%s/%d",
- locations[i].zlt_user->string,
- locations[i].zlt_machine->string,
- locations[i].zlt_tty->string,
- (int) locations[i].zlt_exposure);
+ if (zdebug) {
+ int i;
+ syslog(LOG_DEBUG, "ul_add: New Locations (%d)", num_locs);
+ for (i = 0; i < num_locs; i++) {
+ syslog(LOG_DEBUG, "%s/%s/%s/%d", locations[i].user->string,
+ locations[i].machine->string, locations[i].tty->string,
+ (int) locations[i].exposure);
}
+ }
#endif
- END_CRITICAL_CODE;
- return 0;
+ return 0;
}
/*
@@ -659,41 +630,19 @@ ulogin_add_user(notice, exposure, who)
static int
ulogin_setup(notice, locs, exposure, who)
- ZNotice_t *notice;
- ZLocation_t *locs;
- exposure_type exposure;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ Location *locs;
+ Exposure_type exposure;
+ struct sockaddr_in *who;
{
- if (ulogin_parse(notice, locs))
- return(1);
-
- if (!locs->zlt_user) {
- syslog(LOG_ERR, "zloc bad format: no user");
- return(1);
- }
- if (!locs->zlt_machine) {
- syslog(LOG_ERR, "zloc bad format: no machine");
- free_zstring(locs->zlt_user);
- return(1);
-
- }
- if (!locs->zlt_tty) {
- syslog(LOG_ERR, "zloc bad format: no tty");
- free_zstring(locs->zlt_user);
- free_zstring(locs->zlt_machine);
- return(1);
- }
- if (!locs->zlt_time) {
- syslog(LOG_ERR, "zloc bad format: no time");
- free_zstring(locs->zlt_user);
- free_zstring(locs->zlt_machine);
- free_zstring(locs->zlt_tty);
- return(1);
- }
- locs->zlt_exposure = exposure;
- locs->zlt_addr = who->sin_addr;
- locs->zlt_port = notice->z_port;
- return(0);
+ if (ulogin_parse(notice, locs))
+ return 1;
+
+ locs->exposure = exposure;
+ locs->addr.sin_family = AF_INET;
+ locs->addr.sin_addr.s_addr = who->sin_addr.s_addr;
+ locs->addr.sin_port = notice->z_port;
+ return(0);
}
/*
@@ -702,56 +651,50 @@ ulogin_setup(notice, locs, exposure, who)
static int
ulogin_parse(notice, locs)
- ZNotice_t *notice;
- ZLocation_t *locs;
+ ZNotice_t *notice;
+ Location *locs;
{
- register char *cp, *base;
- register int nulls = 0;
-
- if (!notice->z_message_len) {
- syslog(LOG_ERR, "short ulogin");
- return(1);
- }
-
- base = notice->z_message;
- for (cp = base; cp < base + notice->z_message_len; cp++)
- if (! *cp) nulls++;
- if (nulls < 3) {
- syslog(LOG_ERR, "zloc bad format from user %s (only %d fields)",
- notice->z_sender, nulls);
- return 1;
- }
-
- locs->zlt_user = make_zstring(notice->z_class_inst,0);
-
- cp = base;
- locs->zlt_machine = make_zstring(cp,0);
+ char *cp, *base;
+ int nulls = 0;
+
+ if (!notice->z_message_len) {
+ syslog(LOG_ERR, "short ulogin");
+ return 1;
+ }
+
+ base = notice->z_message;
+ for (cp = base; cp < base + notice->z_message_len; cp++) {
+ if (!*cp)
+ nulls++;
+ }
+ if (nulls < 3) {
+ syslog(LOG_ERR, "zloc bad format from user %s (only %d fields)",
+ notice->z_sender, nulls);
+ return 1;
+ }
+
+ locs->user = make_string(notice->z_class_inst,0);
+
+ cp = base;
+ locs->machine = make_string(cp,0);
#if 0
- zdbug((LOG_DEBUG, "ul_parse: mach %s", cp));
+ zdbug((LOG_DEBUG, "ul_parse: mach %s", cp));
#endif
- cp += (strlen(cp) + 1);
- locs->zlt_time = strsave(cp);
+ cp += (strlen(cp) + 1);
+ locs->time = strsave(cp);
#if 0
- zdbug((LOG_DEBUG, "ul_parse: time %s", cp));
+ zdbug((LOG_DEBUG, "ul_parse: time %s", cp));
#endif
- /* This field might not be null-terminated */
- cp += (strlen(cp) + 1);
-#if 0
- if (nulls == 2) {
- s = (char *)xmalloc(base + notice->z_message_len - cp + 1);
- strncpy(s, cp);
- locs->zlt_tty = make_zstring(s, 0);
- xfree(s);
- } else
-#endif
- locs->zlt_tty = make_zstring(cp,0);
+ /* This field might not be null-terminated */
+ cp += (strlen(cp) + 1);
+ locs->tty = make_string(cp, 0);
#if 0
- zdbug((LOG_DEBUG, "ul_parse: tty %s", locs->zlt_tty->string));
+ zdbug((LOG_DEBUG, "ul_parse: tty %s", locs->tty->string));
#endif
- return 0;
+ return 0;
}
/*
@@ -761,190 +704,178 @@ ulogin_parse(notice, locs)
* in the table.
*/
-static ZLocation_t *
+static Location *
ulogin_find(notice, strict)
- ZNotice_t *notice;
- int strict;
+ ZNotice_t *notice;
+ int strict;
{
- register int i, rlo, rhi;
- ZLocation_t tmploc;
- int compar;
- ZSTRING *inst;
+ int i, rlo, rhi;
+ Location tmploc;
+ int compar;
+ String *inst;
- if (!locations)
- return(NULLZLT);
+ if (!locations)
+ return(NULL);
- inst = make_zstring(notice->z_class_inst,0);
+ inst = make_string(notice->z_class_inst, 0);
- /* i is the current loc we are checking */
- /* rlo is the lowest we will still check, rhi is the highest we will
- still check */
+ /* i is the current loc we are checking */
+ /* rlo is the lowest we will still check, rhi is the highest we will
+ still check */
- i = num_locs >> 1; /* start in the middle */
- rlo = 0;
- rhi = num_locs - 1; /* first index is 0 */
+ i = num_locs >> 1; /* start in the middle */
+ rlo = 0;
+ rhi = num_locs - 1; /* first index is 0 */
- while ((compar = comp_zstring(locations[i].zlt_user, inst)) != 0) {
+ while ((compar = comp_string(locations[i].user, inst)) != 0) {
#if 0
- zdbug ((LOG_DEBUG, "ulogin_find: comparing %s %s %s %d %d",
- notice->z_class_inst,
- locations[i].zlt_user->string,
- locations[i].zlt_tty->string,
- rlo, rhi));
+ zdbug ((LOG_DEBUG, "ulogin_find: comparing %s %s %s %d %d",
+ notice->z_class_inst, locations[i].user->string,
+ locations[i].tty->string, rlo, rhi));
#endif
- if (compar < 0)
- rlo = i + 1;
- else
- rhi = i - 1;
- if (rhi - rlo < 0) {
+ if (compar < 0)
+ rlo = i + 1;
+ else
+ rhi = i - 1;
+ if (rhi - rlo < 0) {
#if 0
- zdbug((LOG_DEBUG,"ul_find: %s not found",
- inst->string));
+ zdbug((LOG_DEBUG,"ul_find: %s not found",
+ inst->string));
#endif
- free_zstring(inst);
- return 0;
- }
- i = (rhi + rlo) >> 1; /* split the diff */
+ free_string(inst);
+ return 0;
}
+ i = (rhi + rlo) >> 1; /* split the diff */
+ }
#if 0
- zdbug((LOG_DEBUG, "ul_find: %s found at loc %d",
- inst->string, i));
+ zdbug((LOG_DEBUG, "ul_find: %s found at loc %d",
+ inst->string, i));
#endif
- if (strict && ulogin_parse(notice, &tmploc)) {
+ if (strict && ulogin_parse(notice, &tmploc)) {
#if 1
- zdbug((LOG_DEBUG,"ul_find bad fmt"));
+ zdbug((LOG_DEBUG,"ul_find bad fmt"));
#endif
- free_zstring(inst);
- return 0;
- }
- /* back up to the first of this guy */
- while (i > 0 && (locations[i-1].zlt_user == inst)) {
- i--;
+ free_string(inst);
+ return 0;
+ }
+ /* back up to the first of this guy */
+ while (i > 0 && (locations[i-1].user == inst)) {
+ i--;
#if 0
- zdbug ((LOG_DEBUG,
- "ulogin_find: backing up: %s %d %s %s",
- inst->string, i,
- locations[i].zlt_user->string,
- locations[i].zlt_tty->string));
+ zdbug((LOG_DEBUG, "ulogin_find: backing up: %s %d %s %s", inst->string,
+ i, locations[i].user->string, locations[i].tty->string));
#endif
- }
- if (strict)
- while (i < num_locs
- && !ul_equiv(&tmploc, &locations[i])
- && (locations[i].zlt_user == inst)) {
- i++;
- }
-
- if ((i == num_locs) || (locations[i].zlt_user != inst)) {
+ }
+ if (strict) {
+ while (i < num_locs && !ul_equiv(&tmploc, &locations[i])
+ && (locations[i].user == inst))
+ i++;
+ }
+ if (strict)
+ free_loc(&tmploc);
+ if (i == num_locs || locations[i].user != inst) {
#if 1
- zdbug((LOG_DEBUG,"ul_find final match loss"));
+ zdbug((LOG_DEBUG,"ul_find final match loss"));
#endif
- free_zstring(inst);
- return 0;
- }
- if (strict)
- free_loc(&tmploc);
- free_zstring(inst);
- return &locations[i];
+ free_string(inst);
+ return 0;
+ }
+ free_string(inst);
+ return &locations[i];
}
static int
ul_equiv(l1, l2)
-register ZLocation_t *l1, *l2;
+ Location *l1, *l2;
{
- if (l1->zlt_machine != l2->zlt_machine)
- return(0);
- if (l1->zlt_tty != l2->zlt_tty)
- return(0);
- return(1);
+ if (l1->machine != l2->machine)
+ return 0;
+ if (l1->tty != l2->tty)
+ return 0;
+ return 1;
}
/*
* remove the user specified in notice from the internal table
*/
-static exposure_type
+static Exposure_type
ulogin_remove_user(notice, auth, who, err_return)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- int *err_return;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ int *err_return;
{
- ZLocation_t *loc, *loc2;
- register int i = 0;
- exposure_type quiet;
+ Location *new_locs, *loc;
+ int i = 0;
+ Exposure_type quiet;
- *err_return = 0;
- if (!(loc2 = ulogin_find(notice, 1))) {
+ *err_return = 0;
+ loc = ulogin_find(notice, 1);
+ if (!loc) {
#if 0
- zdbug((LOG_DEBUG,"ul_rem: not here"));
+ zdbug((LOG_DEBUG,"ul_rem: not here"));
#endif
- *err_return = NOLOC;
- return(NONE);
- }
+ *err_return = NOLOC;
+ return NONE;
+ }
- /* if unauthentic, the sender MUST be the same IP addr
- that registered */
- if (!auth && loc2->zlt_addr.s_addr != who->sin_addr.s_addr) {
- *err_return = UNAUTH;
- return NONE;
- }
+ /* if unauthentic, the sender MUST be the same IP addr that registered */
+ if (!auth && loc->addr.sin_addr.s_addr != who->sin_addr.s_addr) {
+ *err_return = UNAUTH;
+ return NONE;
+ }
- quiet = loc2->zlt_exposure;
+ quiet = loc->exposure;
- START_CRITICAL_CODE;
- if (--num_locs == 0) { /* last one */
+ if (--num_locs == 0) { /* last one */
#if 0
- zdbug((LOG_DEBUG,"last loc"));
+ zdbug((LOG_DEBUG,"last loc"));
#endif
- free_loc(locations);
- xfree(locations);
- locations = NULLZLT;
- END_CRITICAL_CODE;
- return(quiet);
- }
-
- loc = (ZLocation_t *) xmalloc(num_locs * sizeof(ZLocation_t));
- if (!loc) {
- syslog(LOG_CRIT, "ul_rem alloc");
- abort();
- /*NOTREACHED*/
- }
-
- /* copy old entries */
- while (i < num_locs && &locations[i] < loc2) {
- loc[i] = locations[i];
- i++;
- }
-
- /* free up this one */
- free_loc(&locations[i]);
- i++; /* skip over this one */
-
- /* copy the rest */
- while (i <= num_locs) {
- loc[i - 1] = locations[i];
- i++;
- }
-
- xfree(locations);
-
- locations = loc;
-
- END_CRITICAL_CODE;
+ free_loc(locations);
+ free(locations);
+ locations = NULL;
+ return quiet;
+ }
+
+ new_locs = (Location *) malloc(num_locs * sizeof(Location));
+ if (!new_locs) {
+ syslog(LOG_CRIT, "ul_rem alloc");
+ abort();
+ }
+
+ /* copy old entries */
+ while (i < num_locs && &locations[i] < loc) {
+ new_locs[i] = locations[i];
+ i++;
+ }
+
+ /* free up this one */
+ free_loc(&locations[i]);
+ i++; /* skip over this one */
+
+ /* copy the rest */
+ while (i <= num_locs) {
+ new_locs[i - 1] = locations[i];
+ i++;
+ }
+
+ free(locations);
+
+ locations = new_locs;
#if defined(DEBUG) && 0
- if (zdebug) {
- register int i;
+ if (zdebug) {
+ int i;
- for (i = 0; i < num_locs; i++)
- syslog(LOG_DEBUG, "%s/%d",
- locations[i].zlt_user->string,
- (int) locations[i].zlt_exposure);
+ for (i = 0; i < num_locs; i++) {
+ syslog(LOG_DEBUG, "%s/%d", locations[i].user->string,
+ (int) locations[i].exposure);
}
+ }
#endif
- /* all done */
- return(quiet);
+ /* all done */
+ return quiet;
}
/*
@@ -953,89 +884,80 @@ ulogin_remove_user(notice, auth, who, err_return)
static void
ulogin_flush_user(notice)
- ZNotice_t *notice;
+ ZNotice_t *notice;
{
- register ZLocation_t *loc, *loc2;
- register int i, j, num_match, num_left;
+ Location *loc, *loc2;
+ int i, j, num_match, num_left;
- i = num_match = num_left = 0;
+ i = num_match = num_left = 0;
- if (!(loc2 = ulogin_find(notice, 0))) {
+ if (!(loc2 = ulogin_find(notice, 0))) {
#if 0
- zdbug((LOG_DEBUG,"ul_rem: not here"));
+ zdbug((LOG_DEBUG,"ul_rem: not here"));
#endif
- return;
- }
-
- /* compute # locations left in the list, after loc2 (inclusive) */
- num_left = num_locs - (loc2 - locations);
+ return;
+ }
- START_CRITICAL_CODE;
+ /* compute # locations left in the list, after loc2 (inclusive) */
+ num_left = num_locs - (loc2 - locations);
- while (num_left &&
- !strcasecmp(loc2[num_match].zlt_user->string,
+ while (num_left &&
+ !strcasecmp(loc2[num_match].user->string,
notice->z_class_inst)) {
- /* as long as we keep matching, march up the list */
- num_match++;
- num_left--;
- }
- if (num_locs == num_match) { /* no other locations left */
+ /* as long as we keep matching, march up the list */
+ num_match++;
+ num_left--;
+ }
+ if (num_locs == num_match) { /* no other locations left */
#if 0
- zdbug((LOG_DEBUG,"last loc"));
+ zdbug((LOG_DEBUG,"last loc"));
#endif
- for (j = 0; j < num_match; j++)
- free_loc(&locations[j]); /* free storage */
- xfree (locations);
- locations = NULLZLT;
- num_locs = 0;
- END_CRITICAL_CODE;
- return;
- }
-
- loc = (ZLocation_t *) xmalloc((num_locs - num_match) *
- sizeof(ZLocation_t));
- if (!loc) {
- syslog(LOG_CRIT, "ul_rem alloc");
- abort();
- /*NOTREACHED*/
- }
-
- /* copy old entries */
- while (i < num_locs && &locations[i] < loc2) {
- loc[i] = locations[i];
- i++;
- }
+ for (j = 0; j < num_match; j++)
+ free_loc(&locations[j]); /* free storage */
+ free (locations);
+ locations = NULL;
+ num_locs = 0;
+ return;
+ }
+
+ loc = (Location *) malloc((num_locs - num_match) * sizeof(Location));
+ if (!loc) {
+ syslog(LOG_CRIT, "ul_rem alloc");
+ abort();
+ }
+
+ /* copy old entries */
+ while (i < num_locs && &locations[i] < loc2) {
+ loc[i] = locations[i];
+ i++;
+ }
- for(j = 0; j < num_match; j++) {
- free_loc(&locations[i]);
- i++;
- }
+ for(j = 0; j < num_match; j++) {
+ free_loc(&locations[i]);
+ i++;
+ }
- /* copy the rest */
- while (i < num_locs) {
- loc[i - num_match] = locations[i];
- i++;
- }
+ /* copy the rest */
+ while (i < num_locs) {
+ loc[i - num_match] = locations[i];
+ i++;
+ }
- xfree(locations);
+ free(locations);
- locations = loc;
- num_locs -= num_match;
+ locations = loc;
+ num_locs -= num_match;
- END_CRITICAL_CODE;
-
#ifdef DEBUG
- if (zdebug) {
- register int i;
+ if (zdebug) {
+ int i;
- for (i = 0; i < num_locs; i++)
- syslog(LOG_DEBUG, "%s/%d",
- locations[i].zlt_user->string,
- (int) locations[i].zlt_exposure);
+ for (i = 0; i < num_locs; i++) {
+ syslog(LOG_DEBUG, "%s/%d", locations[i].user->string,
+ (int) locations[i].exposure);
}
+ }
#endif
- /* all done */
- return;
}
/*
@@ -1044,86 +966,85 @@ ulogin_flush_user(notice)
static int
ulogin_expose_user(notice, exposure)
- ZNotice_t *notice;
- exposure_type exposure;
+ ZNotice_t *notice;
+ Exposure_type exposure;
{
- ZLocation_t *loc, loc2;
- int idx, notfound = 1;
+ Location *loc, loc2;
+ int idx, notfound = 1;
#if 0
- zdbug((LOG_DEBUG,"ul_expose: %s type %d", notice->z_sender,
- (int) exposure));
+ zdbug((LOG_DEBUG,"ul_expose: %s type %d", notice->z_sender,
+ (int) exposure));
#endif
- if (ulogin_parse(notice, &loc2))
- return(1);
-
- if (!(loc = ulogin_find(notice, 0))) {
+ loc = ulogin_find(notice, 0);
+ if (!loc) {
#if 0
zdbug((LOG_DEBUG,"ul_hide: not here"));
#endif
- return(1);
- }
+ return 1;
+ }
+
+ if (ulogin_parse(notice, &loc2))
+ return 1;
- idx = loc -locations;
-
- while ((idx < num_locs) &&
- locations[idx].zlt_user == loc2.zlt_user) {
-
- /* change exposure and owner for each loc on that host */
- if (locations[idx].zlt_machine == loc2.zlt_machine) {
- notfound = 0;
- locations[idx].zlt_exposure = exposure;
- locations[idx].zlt_port = notice->z_port;
- /* change time for the specific loc */
- if (locations[idx].zlt_tty == loc2.zlt_tty) {
- xfree(locations[idx].zlt_time);
- locations[idx].zlt_time = strsave(loc2.zlt_time);
- }
- }
- idx++;
+ idx = loc -locations;
+
+ while (idx < num_locs && locations[idx].user == loc2.user) {
+
+ /* change exposure and owner for each loc on that host */
+ if (locations[idx].machine == loc2.machine) {
+ notfound = 0;
+ locations[idx].exposure = exposure;
+ locations[idx].addr.sin_port = notice->z_port;
+ /* change time for the specific loc */
+ if (locations[idx].tty == loc2.tty) {
+ free(locations[idx].time);
+ locations[idx].time = strsave(loc2.time);
+ }
}
- return(notfound);
+ idx++;
+ }
+
+ free_loc(&loc2);
+ return notfound;
}
static void
ulogin_locate(notice, who, auth)
- ZNotice_t *notice;
- struct sockaddr_in *who;
- int auth;
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ int auth;
{
- char **answer;
- int found;
- Code_t retval;
- struct sockaddr_in send_to_who;
-
- answer = ulogin_marshal_locs(notice, &found, auth);
-
- send_to_who = *who;
- send_to_who.sin_port = notice->z_port;
-
- if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "ulogin_locate set addr: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
+ char **answer;
+ int found;
+ Code_t retval;
+ struct sockaddr_in send_to_who;
- notice->z_kind = ACKED;
+ answer = ulogin_marshal_locs(notice, &found, auth);
- /* use xmit_frag() to send each piece of the notice */
+ send_to_who = *who;
+ send_to_who.sin_port = notice->z_port;
- if ((retval = ZSrvSendRawList(notice, answer, found*NUM_FIELDS,
- xmit_frag))
- != ZERR_NONE) {
- syslog(LOG_WARNING, "ulog_locate xmit: %s",
- error_message(retval));
- }
+ retval = ZSetDestAddr(&send_to_who);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "ulogin_locate set addr: %s",
+ error_message(retval));
if (answer)
- xfree(answer);
+ free(answer);
return;
+ }
+
+ notice->z_kind = ACKED;
+
+ /* use xmit_frag() to send each piece of the notice */
+
+ retval = ZSrvSendRawList(notice, answer, found * NUM_FIELDS, xmit_frag);
+ if (retval != ZERR_NONE)
+ syslog(LOG_WARNING, "ulog_locate xmit: %s", error_message(retval));
+ if (answer)
+ free(answer);
}
/*
@@ -1133,151 +1054,243 @@ ulogin_locate(notice, who, auth)
static char **
ulogin_marshal_locs(notice, found, auth)
- ZNotice_t *notice;
- register int *found;
- int auth;
+ ZNotice_t *notice;
+ int *found;
+ int auth;
{
- ZLocation_t **matches = (ZLocation_t **) 0;
- ZLocation_t *loc;
- char **answer;
- register int i = 0;
- ZSTRING *inst;
+ Location **matches = (Location **) 0;
+ Location *loc;
+ char **answer;
+ int i = 0;
+ String *inst;
+ int local = sender_in_realm(notice);
- *found = 0; /* # of matches */
+ *found = 0; /* # of matches */
- if (!(loc = ulogin_find(notice, 0)))
- /* not here anywhere */
- return((char **)0);
+ loc = ulogin_find(notice, 0);
+ if (!loc)
+ return(NULL);
- i = loc - locations;
+ i = loc - locations;
- inst = make_zstring(notice->z_class_inst,0);
- while (i < num_locs && (inst == locations[i].zlt_user)) {
- /* these locations match */
+ inst = make_string(notice->z_class_inst,0);
+ while (i < num_locs && (inst == locations[i].user)) {
+ /* these locations match */
#if 0
- zdbug((LOG_DEBUG,"match %s", locations[i].zlt_user->string));
+ zdbug((LOG_DEBUG,"match %s", locations[i].user->string));
#endif
- switch (locations[i].zlt_exposure) {
- case OPSTAFF_VIS:
- i++;
- continue;
- case REALM_VIS:
- case REALM_ANN:
- if (!auth) {
- i++;
- continue;
- }
- case NET_VIS:
- case NET_ANN:
- default:
- break;
- }
- if (!*found) {
- if ((matches = (ZLocation_t **) xmalloc(sizeof(ZLocation_t *))) == (ZLocation_t **) 0) {
- syslog(LOG_ERR, "ulog_loc: no mem");
- break; /* from the while */
- }
- matches[0] = &locations[i];
- (*found)++;
- } else {
- if ((matches = (ZLocation_t **) realloc((caddr_t) matches, (unsigned) ++(*found) * sizeof(ZLocation_t *))) == (ZLocation_t **) 0) {
- syslog(LOG_ERR, "ulog_loc: realloc no mem");
- *found = 0;
- break; /* from the while */
- }
- matches[*found - 1] = &locations[i];
- }
+ switch (locations[i].exposure) {
+ case OPSTAFF_VIS:
+ i++;
+ continue;
+ case REALM_VIS:
+ case REALM_ANN:
+ if (!local) {
i++;
+ continue;
+ }
+ case NET_VIS:
+ case NET_ANN:
+ default:
+ break;
}
- free_zstring(inst);
-
- /* OK, now we have a list of user@host's to return to the client
- in matches */
-
+ if (!*found) {
+ matches = (Location **) malloc(sizeof(Location *));
+ if (!matches) {
+ syslog(LOG_ERR, "ulog_loc: no mem");
+ break; /* from the while */
+ }
+ matches[0] = &locations[i];
+ (*found)++;
+ } else {
+ matches = (Location **) realloc(matches,
+ ++(*found) * sizeof(Location *));
+ if (!matches) {
+ syslog(LOG_ERR, "ulog_loc: realloc no mem");
+ *found = 0;
+ break; /* from the while */
+ }
+ matches[*found - 1] = &locations[i];
+ }
+ i++;
+ }
+ free_string(inst);
+ /* OK, now we have a list of user@host's to return to the client
+ in matches */
+
+
#ifdef DEBUG
- if (zdebug) {
- for (i = 0; i < *found ; i++)
- zdbug((LOG_DEBUG,"found %s",
- matches[i]->zlt_user->string));
- }
+ if (zdebug) {
+ for (i = 0; i < *found ; i++)
+ zdbug((LOG_DEBUG,"found %s",
+ matches[i]->user->string));
+ }
#endif
-
- /* coalesce the location information into a list of char *'s */
- if ((answer = (char **)xmalloc((*found) * NUM_FIELDS * sizeof(char *))) == (char **) 0) {
- syslog(LOG_ERR, "zloc no mem(answer)");
- *found = 0;
- } else
- for (i = 0; i < *found ; i++) {
- answer[i*NUM_FIELDS] = (char *) matches[i]->zlt_machine->string;
- answer[i*NUM_FIELDS + 1] = (char *) matches[i]->zlt_time;
- answer[i*NUM_FIELDS + 2] = (char *) matches[i]->zlt_tty->string;
- }
-
- if (matches)
- xfree(matches);
- return(answer);
+
+ /* coalesce the location information into a list of char *'s */
+ answer = (char **) malloc((*found) * NUM_FIELDS * sizeof(char *));
+ if (!answer) {
+ syslog(LOG_ERR, "zloc no mem(answer)");
+ *found = 0;
+ } else
+ for (i = 0; i < *found ; i++) {
+ answer[i * NUM_FIELDS] = matches[i]->machine->string;
+ answer[i * NUM_FIELDS + 1] = matches[i]->time;
+ answer[i * NUM_FIELDS + 2] = matches[i]->tty->string;
+ }
+
+ if (matches)
+ free(matches);
+ return answer;
}
void
uloc_dump_locs(fp)
- register FILE *fp;
+ FILE *fp;
{
- register int i;
- char buf[BUFSIZ*3];
- static char *bufp;
- static Zconst char *cp;
-
- /* delay using stdio so that we can run FAST! */
- for (i = 0; i < num_locs; i++) {
- bufp = buf;
-#define cpy(str) cp=(str);while(*cp){*bufp++ = *cp++;}
- cpy (locations[i].zlt_user->string);
- *bufp++ = '/';
- cpy (locations[i].zlt_machine->string);
- *bufp++ = '/';
- cpy (locations[i].zlt_time);
- *bufp++ = '/';
- cpy (locations[i].zlt_tty->string);
- switch (locations[i].zlt_exposure) {
- case OPSTAFF_VIS:
- cpy ("/OPSTAFF/");
- break;
- case REALM_VIS:
- cpy ("/RLM_VIS/");
- break;
- case REALM_ANN:
- cpy ("/RLM_ANN/");
- break;
- case NET_VIS:
- cpy ("/NET_VIS/");
- break;
- case NET_ANN:
- cpy ("/NET_ANN/");
- break;
- default:
- sprintf (bufp, "/? %d ?/", locations[i].zlt_exposure);
- while (*bufp)
- bufp++;
- break;
- }
- cpy (inet_ntoa (locations[i].zlt_addr));
- *bufp++ = '/';
- sprintf(bufp, "%d", ntohs(locations[i].zlt_port));
- fputs(buf, fp);
- (void) putc('\n', fp);
-#undef cpy
+ int i;
+
+ for (i = 0; i < num_locs; i++) {
+ fputs("'", fp);
+ dump_quote(locations[i].user->string, fp);
+ fputs("' '", fp);
+ dump_quote(locations[i].machine->string, fp);
+ fputs("' '", fp);
+ dump_quote(locations[i].time, fp);
+ fputs("' ", fp);
+ switch (locations[i].exposure) {
+ case OPSTAFF_VIS:
+ fputs("OPSTAFF", fp);
+ break;
+ case REALM_VIS:
+ fputs("RLM_VIS", fp);
+ break;
+ case REALM_ANN:
+ fputs("RLM_ANN", fp);
+ break;
+ case NET_VIS:
+ fputs("NET_VIS", fp);
+ break;
+ case NET_ANN:
+ fputs("NET_ANN", fp);
+ break;
+ default:
+ fprintf(fp, "? %d ?", locations[i].exposure);
+ break;
}
- return;
+ fprintf(fp, " %s/%d\n", inet_ntoa(locations[i].addr.sin_addr),
+ ntohs(locations[i].addr.sin_port));
+ }
}
static void
free_loc(loc)
- ZLocation_t *loc;
+ Location *loc;
+{
+ free_string(loc->user);
+ free_string(loc->machine);
+ free_string(loc->tty);
+ free(loc->time);
+ return;
+}
+
+static void
+ulogin_locate_forward(notice, who, realm)
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ Realm *realm;
{
- free_zstring(loc->zlt_user);
- free_zstring(loc->zlt_machine);
- free_zstring(loc->zlt_tty);
- xfree(loc->zlt_time);
+ ZNotice_t lnotice;
+
+ lnotice = *notice;
+ lnotice.z_opcode = REALM_REQ_LOCATE;
+
+ realm_handoff(&lnotice, 1, who, realm, 0);
+}
+
+void
+ulogin_realm_locate(notice, who, realm)
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ Realm *realm;
+{
+ char **answer;
+ int found;
+ Code_t retval;
+ ZNotice_t lnotice;
+ char *pack;
+ int packlen;
+
+#ifdef DEBUG
+ if (zdebug)
+ zdbug((LOG_DEBUG, "ulogin_realm_locate"));
+#endif
+
+ answer = ulogin_marshal_locs(notice, &found, 0/*AUTH*/);
+
+ lnotice = *notice;
+ lnotice.z_opcode = REALM_ANS_LOCATE;
+
+ if ((retval = ZFormatRawNoticeList(&lnotice, answer, found * NUM_FIELDS, &pack, &packlen)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "ulog_rlm_loc format: %s",
+ error_message(retval));
+
+ if (answer)
+ free(answer);
+ return;
+ }
+ if (answer)
+ free(answer);
+
+ if ((retval = ZParseNotice(pack, packlen, &lnotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_rlm_sendit parse: %s",
+ error_message(retval));
+ free(pack);
+ return;
+ }
+
+ realm_handoff(&lnotice, 1, who, realm, 0);
+ free(pack);
+
return;
}
+
+void
+ulogin_relay_locate(notice, who)
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+{
+ ZNotice_t lnotice;
+ Code_t retval;
+ struct sockaddr_in newwho;
+ char *pack;
+ int packlen;
+
+ newwho.sin_addr.s_addr = notice->z_sender_addr.s_addr;
+ newwho.sin_port = notice->z_port;
+ newwho.sin_family = AF_INET;
+
+ if ((retval = ZSetDestAddr(&newwho)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "uloc_relay_loc set addr: %s",
+ error_message(retval));
+ return;
+ }
+
+ lnotice = *notice;
+ lnotice.z_opcode = LOCATE_LOCATE;
+ lnotice.z_kind = ACKED;
+
+ if ((retval = ZFormatRawNotice(&lnotice, &pack, &packlen)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "ulog_relay_loc format: %s",
+ error_message(retval));
+ return;
+ }
+
+ if ((retval = ZSendPacket(pack, packlen, 0)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "ulog_relay_loc xmit: %s",
+ error_message(retval));
+ }
+ free(pack);
+}
+
diff --git a/server/unix.h b/server/unix.h
deleted file mode 100644
index 78b6d34..0000000
--- a/server/unix.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains declarations for many standard UNIX library functions,
- * and macros for aiding in interfacing to them.
- *
- * Created by Ken Raeburn.
- *
- * $Source$
- * $Author$
- * $Zephyr: unix.h,v 1.3 91/01/28 15:12:57 raeburn Exp $
- *
- * Copyright (c) 1990,1991 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#ifndef ZSERVER_UNIX_H__
-
-#include <stdio.h>
-#if defined(__STDC__) && !defined(__HIGHC__) && !defined(SABER)
-/* Brain-dead High-C claims to be ANSI but doesn't have the include files.. */
-#include <stdlib.h>
-#endif
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-#ifndef linux /* struct qelem is defined in stdlib.h */
-/*
- * Queue-handling functions. This structure is basically a dummy;
- * as long as the start of another structure looks like this,
- * we're okay.
- */
-struct qelem {
- struct qelem *q_forw;
- struct qelem *q_back;
- char *q_data;
-};
-void insque P((struct qelem*, struct qelem*));
-void remque P((struct qelem *));
-
-#endif /* linux */
-
-/* From the Error table library */
-char *error_message P((long));
-
-#ifdef KERBEROS
-/* Kerberos */
-extern int krb_get_lrealm P((char *, int));
-extern int dest_tkt P((void));
-extern int krb_get_svc_in_tkt P((char *, char *, char *, char *, char *, int,
- char *));
-#ifdef KRB_DEFS /* have we actually got krb.h? */
-extern int krb_mk_req P((KTEXT, char *, char *, char *, unsigned long));
-extern int krb_get_cred P((char *, char *, char *, CREDENTIALS *));
-#endif
-#else
-extern int rresvport P((int *));
-#endif
-
-#ifdef HESIOD
- /* Hesiod */
-extern char ** hes_resolve P((Zconst char *, Zconst char *));
-#endif
-
- /* hacked acl code */
-extern void acl_cache_reset P((void));
-
-#undef P
-
-#ifdef vax
-#define HAVE_ALLOCA
-#endif
-
-#if defined (__GNUC__)
-
-/* GCC/G++ has a built-in function for allocating automatic storage. */
-#define LOCAL_ALLOC(X) __builtin_alloca(X)
-#define LOCAL_FREE(X)
-
-#else /* not gcc or g++ */
-
-#ifdef HAVE_ALLOCA
-#define LOCAL_ALLOC(X) alloca(X)
-#define LOCAL_FREE(X)
-#endif
-#endif
-
-#ifndef LOCAL_ALLOC
-#define LOCAL_ALLOC(X) malloc(X)
-#define LOCAL_FREE(X) free(X)
-#endif
-
-/*
- * Miscellaneous casts, so we don't have to insert these all over the
- * source files...
- */
-
-#define xfree(foo) free((caddr_t) (foo))
-#define xinsque(a,b) insque((struct qelem *)(a), (struct qelem *)(b))
-#define xremque(a) remque((struct qelem *)(a))
-#define xmalloc(a) malloc((unsigned)(a))
-#define xrealloc(foo,a) realloc((caddr_t) (foo), (unsigned) (a))
-
-#define ZSERVER_UNIX_H__
-#endif
diff --git a/server/version.c b/server/version.c
index 587028f..5487000 100644
--- a/server/version.c
+++ b/server/version.c
@@ -13,26 +13,22 @@
#include <zephyr/mit-copyright.h>
-#include <string.h>
-#include <zephyr/zephyr.h>
+#include "zserver.h"
#include "version.h"
+const char zephyr_version[] = "Zephyr system version 2.0";
+
#ifdef DEBUG
-Zconst char version[] = "Zephyr Server (DEBUG) $Revision$";
+const char version[] = "Zephyr server (DEBUG) $Revision$";
#else
-Zconst char version[] = "Zephyr Server $Revision$";
+const char version[] = "Zephyr server $Revision$";
#endif
#if !defined (lint) && !defined (SABER)
-Zconst char rcsid_version_c[] =
+static const char rcsid_version_c[] =
"$Id$";
-Zconst char copyright[] =
+static const char copyright[] =
"Copyright (c) 1987,1988,1989,1990 Massachusetts Institute of Technology.\n";
-#ifdef CONCURRENT
-Zconst char concurrent[] = "Brain-dump concurrency enabled";
-#else
-Zconst char concurrent[] = "no brain-dump concurrency";
-#endif
#endif
char *
diff --git a/server/version.h b/server/version.h
deleted file mode 100644
index 40f1ff3..0000000
--- a/server/version.h
+++ /dev/null
@@ -1 +0,0 @@
-#define ZSERVER_VERSION_STRING "(Fri Nov 19 13:34:58 EST 1993) probe@tardis"
diff --git a/server/zalloc.c b/server/zalloc.c
deleted file mode 100644
index f4e5e23..0000000
--- a/server/zalloc.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Memory allocator for Zephyr server.
- */
-
-#include <stdio.h>
-#include <zephyr/zephyr.h>
-#include "unix.h"
-#include "zalloc.h"
-
-#ifndef MPROF
-/*
- * What's the maximum number of words to expect to allocate through
- * this mechanism? (Larger requests will be fed to malloc.)
- */
-#define MAX_SIZE 32
-
-static void *free_space;
-static unsigned int free_space_size;
-static void *buckets[MAX_SIZE];
-#ifdef ZALLOC_STATS
-enum zalloc_memtype {
- FREE=0, ALLOCATED,
- N_zalloc_memtype
-};
-static int zalloc_count[MAX_SIZE][(int) N_zalloc_memtype];
-#endif
-
-/*
- union misc_types {
- void *void_p;
- int i;
- long l;
- double d;
- };
-*/
-/* SZ = sizeof(misc_types) */
-#define SZ 32
-
-/*
- * Pick some size here that will help keep down the number of calls to
- * malloc, but doesn't waste too much space. To avoid waste of space,
- * we leave some overhead before the next power of two.
- */
-
-
-/* ALLOC_SIZE = ((16384 - 32) / SZ) * SZ */
-#define ALLOC_SIZE 16352
-
-unsigned int round (size)
- unsigned int size;
-{
- size += SZ - 1;
- size -= (size % SZ);
- return size;
-}
-
-#define ROUND(size) (size = round (size))
-int BUCKET (size)
- unsigned int size;
-{
- ROUND (size);
- return size / SZ - 1;
-}
-
-static void
-zmemset (ptr, size, fill)
- void *ptr;
- int size;
- int fill;
-{
-#ifdef ZALLOC_DEBUG
- char *cptr = (char *) ptr;
- while (size--)
- cptr[size] = fill;
-#endif
-}
-
-void *
-zalloc (size)
- unsigned int size;
-{
- int bucket;
- void *ret;
- void **ptr;
-
- ROUND (size);
- bucket = BUCKET (size);
- if (bucket < 0 || bucket >= MAX_SIZE)
- return (void *) malloc (size);
-
- ptr = &buckets[bucket];
-#ifdef ZALLOC_DEBUG_PRINT
- fprintf (stderr, "zalloc(%d); looking in bucket %d, found %08X\n",
- size, bucket, *ptr);
-#endif
- if (*ptr) {
- ret = *ptr;
- *ptr = *(void**)ret;
- goto return_it;
- }
-
- if (free_space_size < size) {
- if (free_space_size > 0) {
- ptr = &buckets[BUCKET (free_space_size)];
- *(void**)free_space = *ptr;
- *ptr = free_space;
-#ifdef ZALLOC_DEBUG_PRINT
- fprintf (stderr, "tossing %08X into bucket %d\n",
- free_space, bucket);
-#endif
-#ifdef ZALLOC_STATS
- zalloc_count[BUCKET (free_space_size)][FREE]++;
-#endif
- }
-
- free_space_size = ALLOC_SIZE;
- free_space = (void *) malloc (free_space_size);
- if (!free_space)
- abort ();
-#ifdef ZALLOC_DEBUG_PRINT
- fprintf (stderr, "grabbing more free store at %08X\n", free_space);
-#endif
- }
-
- ret = free_space;
- free_space = (char *) free_space + size;
- free_space_size -= size;
-return_it:
-#ifdef ZALLOC_DEBUG_PRINT
- fprintf (stderr, "returning %08X\n", ret);
-#endif
- zmemset (ret, size, 0xe5);
-#ifdef ZALLOC_STATS
- zalloc_count[bucket][FREE]--, zalloc_count[bucket][ALLOCATED]++;
-#endif
- return ret;
-}
-
-void zfree (ptr, size)
- void *ptr;
- unsigned int size;
-{
- int bucket;
- void **b;
-
- ROUND (size);
- bucket = BUCKET (size);
- if (bucket < 0 || bucket >= MAX_SIZE) {
- free (ptr);
- return;
- }
-
- b = &buckets[bucket];
- zmemset (ptr, size, 0xe5);
- *(void **) ptr = *b;
- *b = ptr;
-#ifdef ZALLOC_DEBUG
-#ifdef ZALLOC_DEBUG_PRINT
- fprintf (stderr, "putting %08X into bucket %d\n",
- ptr, bucket);
- fprintf (stderr, "bucket %d:");
- for (ptr = buckets[bucket]; ptr; ptr=*(void**)ptr)
- fprintf (stderr, " %X", ptr);
- fprintf (stderr, "\n");
-#else
- for (ptr = buckets[bucket]; ptr; ptr=*(void**)ptr)
- /* do nothing, just read value */;
-#endif
-#endif
-
-#ifdef ZALLOC_STATS
- zalloc_count[bucket][FREE]++, zalloc_count[bucket][ALLOCATED]--;
-#endif
-}
-#endif
diff --git a/server/zalloc.h b/server/zalloc.h
deleted file mode 100644
index a2c60a8..0000000
--- a/server/zalloc.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- */
-
-#ifndef __zalloc_h
-#define __zalloc_h __FILE__
-#ifdef MPROF
-#define zalloc(sz) malloc(sz)
-#define zfree(p,sz) free(p)
-#else
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif /* STDC */
-
-extern void * zalloc P((unsigned int));
-extern void zfree P((void *, unsigned int));
-
-#undef P
-#endif /* MPROF */
-#endif /* __zalloc_h */
diff --git a/server/zserver.h b/server/zserver.h
index 8dede2b..4fe7c2a 100644
--- a/server/zserver.h
+++ b/server/zserver.h
@@ -16,27 +16,9 @@
#include <zephyr/mit-copyright.h>
-#include <zephyr/zephyr.h> /* which includes <errno.h>,
- <sys/types.h>,
- <netinet/in.h>,
- <sys/time.h>,
- <stdio.h>,
- <krb.h> */
+#include <internal.h>
#include <arpa/inet.h>
-#include <zephyr/acl.h>
-#include <sys/file.h>
-#include <fcntl.h>
-
-#include <zephyr/zsyslog.h>
-
-#include <string.h>
-#include <signal.h>
-#ifdef lint
-#include <sys/uio.h> /* so it shuts up about struct iovec */
-#endif /* lint */
-#ifdef _IBMR2
-#include <sys/select.h>
-#endif
+
#include "zsrv_err.h"
#include "timer.h"
@@ -44,277 +26,299 @@
#include "zstring.h"
#include "access.h"
-#include "unix.h"
-#include "zalloc.h"
+#include "acl.h"
-/* definitions for the Zephyr server */
-
-/* structures */
+/* For krb_rd_req prototype and definition. */
+#ifndef KRB_INT32
+#define KRB_INT32 ZEPHYR_INT32
+#endif
-/*
- * ZDestination: Where is this notice going to? This includes class,
- * instance, and recipient at the moment.
- */
+/* These macros are for insertion into and deletion from a singly-linked list
+ * with back pointers to the previous element's next pointer. In order to
+ * make these macros act like expressions, they use the comma operator for
+ * sequenced evaluations of assignment, and "a && b" for "evaluate assignment
+ * b if expression a is true". */
+#define LIST_INSERT(head, elem) \
+ ((elem)->next = *(head), \
+ (*head) && ((*(head))->prev_p = &(elem)->next), \
+ (*head) = (elem), (elem)->prev_p = (head))
+#define LIST_DELETE(elem) \
+ (*(elem)->prev_p = (elem)->next, \
+ (elem)->next && ((elem)->next->prev_p = (elem)->prev_p))
+
+/* Current time as cached by main(); use instead of time(). */
+#define NOW t_local.tv_sec
+
+#ifdef ZEPHYR_USES_KERBEROS
+#ifndef NOENCRYPTION
+/* Kerberos shouldn't stick us with array types... */
+typedef struct {
+ des_key_schedule s;
+} Sched;
+#endif
+#endif
-typedef struct _ZDestination {
- ZSTRING *classname;
- ZSTRING *inst;
- ZSTRING *recip;
-} ZDestination;
-
-/* typedef struct _Notice {
- ZNotice_t *notice;
- struct _ZDestination dest;
- ZSTRING *sender;
- int msg_no;
-} Notice;
-*/
-typedef struct _ZSubscr_t {
- struct _ZSubscr_t *q_forw; /* links in client's subscr. queue */
- struct _ZSubscr_t *q_back;
- struct _ZDestination zst_dest; /* destination of messages */
-} ZSubscr_t;
-
-typedef struct _ZClient_t {
- struct sockaddr_in zct_sin; /* ipaddr/port of client */
- struct _ZSubscr_t *zct_subs; /* subscriptions */
-#ifdef KERBEROS
- C_Block zct_cblock; /* session key for this client */
-#endif /* KERBEROS */
- ZSTRING *zct_principal; /* krb principal of user */
- long last_msg; /* last message sent to this client */
- long last_check; /* actually, last time the other
- server was asked to check... */
- int last_send; /* The send counter value for the
- * last packet sent to the client,
- * used to prevent duplicates. See
- * sendit() in dispatch.c. */
-} ZClient_t;
-
-typedef struct _ZClientList_t {
- struct _ZClientList_t *q_forw;
- struct _ZClientList_t *q_back;
- struct _ZClient_t *zclt_client;
-} ZClientList_t;
-
-typedef struct _ZTriplet_t {
- struct _ZTriplet_t *q_forw;
- struct _ZTriplet_t *q_back;
- ZDestination zct_dest;
- ZAcl_t *zct_acl;
- ZClientList_t *zct_clientlist;
-} ZTriplet_t;
-
-typedef struct _ZHostList_t {
- struct _ZHostList_t *q_forw;
- struct _ZHostList_t *q_back;
- ZClientList_t *zh_clients;
- struct sockaddr_in zh_addr; /* IP addr/port of hostmanager */
- unsigned int zh_locked; /* 1 if this host is locked for
- a braindump */
-} ZHostList_t;
-
-typedef enum _server_state {
- SERV_UP, /* Server is up */
- SERV_TARDY, /* Server due for a hello */
- SERV_DEAD, /* Server is considered dead */
- SERV_STARTING /* Server is between dead and up */
-} server_state;
-
-typedef struct _ZNotAcked_t {
- struct _ZNotAcked_t *q_forw; /* link to next */
- struct _ZNotAcked_t *q_back; /* link to prev */
- timer na_timer; /* timer for retransmit */
- long na_abstimo; /* absolute timeout to drop after */
- short na_rexmits; /* number of retransmits */
- short na_packsz; /* size of packet */
- caddr_t na_packet; /* ptr to packet */
- ZUnique_Id_t na_uid; /* uid of packet */
- union { /* address to send to */
- struct sockaddr_in na_sin; /* client address */
- int srv_idx; /* index of server */
- } dest;
-#define na_addr dest.na_sin
-#define na_srv_idx dest.srv_idx
-} ZNotAcked_t;
-
-typedef struct _ZSrvPending_t {
- struct _ZSrvPending_t *q_forw; /* link to next */
- struct _ZSrvPending_t *q_back; /* link to prev */
- caddr_t pend_packet; /* the notice (in pkt form) */
- short pend_len; /* len of pkt */
- unsigned int pend_auth; /* whether it is authentic */
- struct sockaddr_in pend_who; /* the addr of the sender */
-} ZSrvPending_t;
-
-typedef struct _ZServerDesc_t {
- server_state zs_state; /* server's state */
- struct sockaddr_in zs_addr; /* server's address */
- long zs_timeout; /* Length of timeout in sec */
- timer zs_timer; /* timer struct for this server */
- struct _ZHostList_t *zs_hosts; /* pointer to list of info from this
- server */
- struct _ZSrvPending_t *zs_update_queue; /* queue of packets to send
+typedef struct _Destination Destination;
+typedef struct _Destlist Destlist;
+typedef struct _Realm Realm;
+typedef struct _Realmname Realmname;
+typedef struct _Client Client;
+typedef struct _Triplet Triplet;
+typedef enum _Server_state Server_state;
+typedef struct _Unacked Unacked;
+typedef struct _Pending Pending;
+typedef struct _Server Server;
+typedef enum _Sent_type Sent_type;
+typedef struct _Statistic Statistic;
+
+struct _Destination {
+ String *classname;
+ String *inst;
+ String *recip;
+};
+
+struct _Destlist {
+ Destination dest;
+ struct _Destlist *next, **prev_p;
+};
+
+struct _Realm {
+ char name[REALM_SZ];
+ int count;
+ struct sockaddr_in *addrs;
+ int idx; /* which server we are connected to */
+ Destlist *subs;
+ Client *client;
+ long tkt_try;
+};
+
+struct _Realmname {
+ char name[REALM_SZ];
+ char **servers;
+ int nused;
+ int nservers;
+};
+
+struct _Client {
+ struct sockaddr_in addr; /* ipaddr/port of client */
+ Destlist *subs ; /* subscriptions */
+#ifdef ZEPHYR_USES_KERBEROS
+ C_Block session_key; /* session key for this client */
+#endif /* ZEPHYR_USES_KERBEROS */
+ String *principal; /* krb principal of user */
+ time_t last_check; /* last time the other server was
+ asked to check */
+ long last_msg; /* last message sent to this client */
+ int last_send; /* Counter for last sent packet. */
+ Realm *realm;
+ struct _Client *next, **prev_p;
+};
+
+struct _Triplet {
+ Destination dest;
+ Acl *acl;
+ Client **clients;
+ int clients_size;
+ struct _Triplet *next, **prev_p;
+};
+
+enum _Server_state {
+ SERV_UP, /* Server is up */
+ SERV_TARDY, /* Server due for a hello */
+ SERV_DEAD, /* Server is considered dead */
+ SERV_STARTING /* Server is between dead and up */
+};
+
+struct _Unacked {
+ Timer *timer; /* timer for retransmit */
+ short rexmits; /* number of retransmits */
+ short packsz; /* size of packet */
+ char *packet; /* ptr to packet */
+ ZUnique_Id_t uid; /* uid of packet */
+ struct sockaddr_in ack_addr;
+ union { /* address to send to */
+ struct sockaddr_in addr; /* client address */
+ int srv_idx; /* index of server */
+ struct {
+ int rlm_idx; /* index of realm */
+ int rlm_srv_idx; /* index of server in realm */
+ } rlm;
+ } dest;
+ struct _Unacked *next, **prev_p;
+};
+
+struct _Pending {
+ char *packet; /* the notice (in pkt form) */
+ short len; /* len of pkt */
+ unsigned int auth; /* whether it is authentic */
+ struct sockaddr_in who; /* the addr of the sender */
+ struct _Pending *next;
+};
+
+struct _Server {
+ Server_state state; /* server's state */
+ struct sockaddr_in addr; /* server's address */
+ long timeout; /* Length of timeout in sec */
+ Timer *timer; /* timer for this server */
+ Pending *queue; /* queue of packets to send
to this server when done dumping */
- short zs_numsent; /* number of hello's sent */
- unsigned int zs_dumping; /* 1 if dumping, so we should queue */
- char addr[16]; /* text version of address */
-} ZServerDesc_t;
-
-typedef enum ZSentType {
- NOT_SENT, /* message was not xmitted */
- SENT, /* message was xmitted */
- AUTH_FAILED, /* authentication failed */
- NOT_FOUND /* user not found for uloc */
-} ZSentType;
+ Pending *queue_last; /* last packet on queue */
+ short num_hello_sent; /* number of hello's sent */
+ unsigned int dumping; /* 1 if dumping, so we should queue */
+ char addr_str[16]; /* text version of address */
+};
+
+enum _Sent_type {
+ NOT_SENT, /* message was not xmitted */
+ SENT, /* message was xmitted */
+ AUTH_FAILED, /* authentication failed */
+ NOT_FOUND /* user not found for uloc */
+};
/* statistics gathering */
-typedef struct _ZStatistic_t {
- int val;
- char *str;
-} ZStatistic;
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
+struct _Statistic {
+ int val;
+ char *str;
+};
/* Function declarations */
/* found in bdump.c */
-extern void bdump_get P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
- ZServerDesc_t *server));
-extern void bdump_send P((void));
-extern void bdump_offer P((struct sockaddr_in *who));
-extern Code_t bdump_send_list_tcp P((ZNotice_Kind_t kind, int port,
- char *class_name, char *inst, char *opcode,
- char *sender, char *recip,
- char **lyst, int num));
+void bdump_get __P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
+ Server *server));
+void bdump_send __P((void));
+void bdump_offer __P((struct sockaddr_in *who));
+Code_t bdump_send_list_tcp __P((ZNotice_Kind_t kind, struct sockaddr_in *addr,
+ char *class_name, char *inst, char *opcode,
+ char *sender, char *recip, char **lyst,
+ int num));
+int get_tgt __P((void));
/* found in class.c */
-extern Code_t triplet_register P((ZClient_t *client, ZDestination *dest));
-extern Code_t triplet_deregister P((ZClient_t *client, ZDestination *dest));
-extern Code_t class_restrict P((char *z_class, ZAcl_t *acl));
-extern Code_t class_setup_restricted P((char *z_class, ZAcl_t *acl));
-extern ZClientList_t *triplet_lookup P((ZDestination *dest));
-extern ZAcl_t *class_get_acl P((ZSTRING *z_class));
-extern void class_free P((ZClientList_t *lyst));
-extern ZSTRING *class_control, *class_admin, *class_hm;
-extern ZSTRING *class_ulogin, *class_ulocate;
-extern void set_ZDestination_hash P((ZDestination *zd));
-extern int ZDest_eq P((ZDestination *zd1, ZDestination *zd2));
-extern int order_dest_strings P((ZDestination *zd1, ZDestination *zd2));
-extern void class_dump_subs P((register FILE *fp));
+extern String *class_control, *class_admin, *class_hm;
+extern String *class_ulogin, *class_ulocate;
+int ZDest_eq __P((Destination *d1, Destination *d2));
+Code_t triplet_register __P((Client *client, Destination *dest, Realm *realm));
+Code_t triplet_deregister __P((Client *client, Destination *dest,
+ Realm *realm));
+Code_t class_restrict __P((char *class, Acl *acl));
+Code_t class_setup_restricted __P((char *class, Acl *acl));
+Client **triplet_lookup __P((Destination *dest));
+Acl *class_get_acl __P((String *class));
+int dest_eq __P((Destination *d1, Destination *d2));
+int order_dest_strings __P((Destination *d1, Destination *d2));
+void triplet_dump_subs __P((FILE *fp));
/* found in client.c */
-extern Code_t client_register P((ZNotice_t *notice, struct sockaddr_in *who,
- register ZClient_t **client,
- ZServerDesc_t *server, int wantdefaults));
-extern void client_deregister P((ZClient_t *client, ZHostList_t *host,
- int flush));
-extern void client_dump_clients P((FILE *fp, ZClientList_t *clist));
-extern ZClient_t *client_which_client P((struct sockaddr_in *who,
- ZNotice_t *notice));
+Code_t client_register __P((ZNotice_t *notice, struct in_addr *host,
+ Client **client_p, int wantdefaults));
+void client_deregister __P((Client *client, int flush));
+void client_flush_host __P((struct in_addr *host));
+void client_dump_clients __P((FILE *fp));
+Client *client_which_client __P((struct in_addr *host, ZNotice_t *notice));
+Code_t client_send_clients __P((void));
/* found in common.c */
-extern char *strsave P((Zconst char *str));
-extern unsigned long hash P((Zconst char *));
-extern void subscr_quote P((char *p, FILE *fp));
+char *strsave __P((const char *str));
+unsigned long hash __P((const char *));
+void dump_quote __P((char *p, FILE *fp));
/* found in dispatch.c */
-extern void handle_packet P((void));
-extern void clt_ack P((ZNotice_t *notice, struct sockaddr_in *who,
- ZSentType sent));
-extern void nack_release P((ZClient_t *client));
-extern void sendit P((register ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern void rexmit P((void *));
-extern void xmit P((register ZNotice_t *notice, struct sockaddr_in *dest,
- int auth, ZClient_t *client));
-extern Code_t control_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- ZServerDesc_t *server));
-extern Code_t xmit_frag P((ZNotice_t *notice, char *buf, int len,
- int waitforack));
-
-/* found in hostm.c */
-extern void hostm_flush P((ZHostList_t *host, ZServerDesc_t *server));
-extern void hostm_shutdown P((void));
-extern void hostm_losing P((ZClient_t *client, ZHostList_t *host));
-extern ZHostList_t *hostm_find_host P((struct in_addr *addr));
-extern ZServerDesc_t *hostm_find_server P((struct in_addr *addr));
-extern void hostm_transfer P((ZHostList_t *host, ZServerDesc_t *server));
-extern void hostm_deathgram P((struct sockaddr_in *sin,
- ZServerDesc_t *server));
-extern void hostm_dump_hosts P((FILE *fp));
-extern Code_t hostm_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who, ZServerDesc_t *server));
-extern void hostm_lose_ignore P((ZClient_t *client));
-extern void hostm_renumber_servers P((int *));
+void handle_packet __P((void));
+void clt_ack __P((ZNotice_t *notice, struct sockaddr_in *who, Sent_type sent));
+void nack_release __P((Client *client));
+void sendit __P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
+ int external));
+void rexmit __P((void *));
+void xmit __P((ZNotice_t *notice, struct sockaddr_in *dest, int auth,
+ Client *client));
+Code_t hostm_dispatch __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who, Server *server));
+Code_t control_dispatch __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who, Server *server));
+Code_t xmit_frag __P((ZNotice_t *notice, char *buf, int len, int waitforack));
+void hostm_shutdown __P((void));
/* found in kstuff.c */
-#ifdef KERBEROS
-extern int GetKerberosData P((int, struct in_addr, AUTH_DAT*, char*, char*));
-extern Code_t SendKerberosData P((int, KTEXT, char*, char*));
+#ifdef ZEPHYR_USES_KERBEROS
+int GetKerberosData __P((int, struct in_addr, AUTH_DAT *, char *, char *));
+Code_t SendKerberosData __P((int, KTEXT, char *, char *));
+void sweep_ticket_hash_table __P((void *));
#endif
-/* found in server.c */
-extern void server_timo P((void *which));
-extern void server_recover P((ZClient_t *client)),
- server_dump_servers P((FILE *fp));
-extern void server_init P((void)),
- server_shutdown P((void));
-extern void server_forward P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern void server_kill_clt P((ZClient_t *client));
-extern void server_pending_free P((register ZSrvPending_t *pending));
-extern void server_self_queue P((ZNotice_t*, int, struct sockaddr_in *)),
- server_send_queue P((ZServerDesc_t *)),
- server_reset P((void));
-extern int is_server();
-extern ZServerDesc_t *server_which_server P((struct sockaddr_in *who));
-extern ZSrvPending_t *server_dequeue P((register ZServerDesc_t *server));
-extern Code_t server_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern Code_t server_adispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- ZServerDesc_t *server));
+/* found in kopt.c */
+#ifdef ZEPHYR_USES_KERBEROS
+#ifndef NOENCRYPTION
+Sched *check_key_sched_cache __P((des_cblock key));
+void add_to_key_sched_cache __P((des_cblock key, Sched *sched));
+int krb_set_key __P((char *key, int cvt));
+int krb_rd_req __P((KTEXT authent, char *service, char *instance,
+ unsigned KRB_INT32 from_addr, AUTH_DAT *ad, char *fn));
+int krb_find_ticket __P((KTEXT authent, KTEXT ticket));
+int krb_get_lrealm __P((char *r, int n));
+#endif
+#endif
+/* found in server.c */
+void server_timo __P((void *which));
+void server_dump_servers __P((FILE *fp));
+void server_init __P((void));
+void server_shutdown __P((void));
+void server_forward __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who));
+void server_kill_clt __P((Client *client));
+void server_pending_free __P((Pending *pending));
+void server_self_queue __P((ZNotice_t *, int, struct sockaddr_in *));
+void server_send_queue __P((Server *));
+void server_reset __P((void));
+int is_server();
+Server *server_which_server __P((struct sockaddr_in *who));
+Pending *server_dequeue __P((Server *server));
+Code_t server_dispatch __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who));
+Code_t server_adispatch __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who, Server *server));
/* found in subscr.c */
-extern Code_t subscr_cancel P((struct sockaddr_in *sin, ZNotice_t *notice));
-extern Code_t subscr_subscribe P((ZClient_t *who, ZNotice_t *notice)),
- subscr_send_subs P((ZClient_t *client, char *vers));;
-extern void subscr_free_list P((ZClientList_t *list)),
- subscr_cancel_client P((register ZClient_t *client)),
- subscr_sendlist P((ZNotice_t *notice, int auth, struct sockaddr_in *who));
-extern void subscr_dump_subs P((FILE *fp, ZSubscr_t *subs)),
- subscr_reset P((void));
-extern int compare_subs P((ZSubscr_t *s1, ZSubscr_t *s2, int do_wildcard));
-extern Code_t subscr_def_subs P((ZClient_t *who));
+Code_t subscr_cancel __P((struct sockaddr_in *sin, ZNotice_t *notice));
+Code_t subscr_subscribe __P((Client *who, ZNotice_t *notice));
+Code_t subscr_send_subs __P((Client *client));
+void subscr_cancel_client __P((Client *client));
+void subscr_sendlist __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who));
+void subscr_dump_subs __P((FILE *fp, Destlist *subs));
+void subscr_reset __P((void));
+Code_t subscr_def_subs __P((Client *who));
/* found in uloc.c */
-extern void uloc_hflush P((struct in_addr *addr)),
- uloc_flush_client P((struct sockaddr_in *sin)),
- uloc_dump_locs P((register FILE *fp));
-extern Code_t ulogin_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who, ZServerDesc_t *server)),
- ulocate_dispatch P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
- ZServerDesc_t *server)),
- uloc_send_locations P((ZHostList_t *host, char *vers));
+void uloc_hflush __P((struct in_addr *addr));
+void uloc_flush_client __P((struct sockaddr_in *sin));
+void uloc_dump_locs __P((FILE *fp));
+Code_t ulogin_dispatch __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who, Server *server));
+Code_t ulocate_dispatch __P((ZNotice_t *notice, int auth,
+ struct sockaddr_in *who, Server *server));
+Code_t uloc_send_locations __P((void));
+
+/* found in realm.c */
+Realm *realm_which_realm __P((struct sockaddr_in *who));
+Realm *realm_get_realm_by_name __P((char *name));
+void realm_handoff(ZNotice_t *, int, struct sockaddr_in *, Realm *, int);
+char *realm_expand_realm(char *);
+void realm_init __P((void));
+Code_t ZCheckRealmAuthentication __P((ZNotice_t *, struct sockaddr_in *,
+ char *));
/* found in version.c */
-extern char *get_version P((void));
-
-#undef P
-
+char *get_version __P((void));
/* global identifiers */
/* found in main.c */
-extern struct sockaddr_in sock_sin; /* socket descriptors */
-extern u_short hm_port; /* port # of hostmanagers */
+int packets_waiting __P((void));
+extern struct sockaddr_in srv_addr; /* server socket address */
+extern unsigned short hm_port; /* host manager receiver port */
+extern unsigned short hm_srv_port; /* host manager server sending port */
extern int srv_socket; /* dgram sockets for clients
and other servers */
extern int bdump_socket; /* brain dump socket
@@ -322,31 +326,41 @@ extern int bdump_socket; /* brain dump socket
extern fd_set interesting; /* the file descrips we are listening
to right now */
-extern int nfildes; /* number to look at in select() */
+extern int nfds; /* number to look at in select() */
extern int zdebug;
extern char myname[]; /* domain name of this host */
-extern ZNotAcked_t *nacklist; /* list of not ack'ed packets */
-extern Zconst char version[];
+#ifndef ZEPHYR_USES_HESIOD
+extern char list_file[];
+#endif
+#ifdef ZEPHYR_USES_KERBEROS
+extern char srvtab_file[];
+extern char my_realm[];
+#endif
+extern char acl_dir[];
+extern char subs_file[];
+extern const char version[];
extern u_long npackets; /* num of packets processed */
-extern long uptime; /* time we started */
+extern time_t uptime; /* time we started */
extern struct in_addr my_addr;
+extern struct timeval t_local; /* current time */
/* found in bdump.c */
-extern int bdumping; /* are we dumping right now? */
+extern int bdumping; /* are we processing a bdump packet? */
+extern int bdump_concurrent; /* set while processing a packet
+ * concurrently during a braindump. */
/* found in dispatch.c */
-extern ZStatistic i_s_ctls, i_s_logins, i_s_admins, i_s_locates;
-extern int num_rexmits;
-extern long rexmit_secs, abs_timo;
+extern Statistic i_s_ctls, i_s_logins, i_s_admins, i_s_locates;
+extern int rexmit_times[];
/* found in server.c */
-extern ZServerDesc_t *otherservers; /* array of servers */
+extern Server *otherservers; /* array of servers */
extern int me_server_idx; /* me (in the array of servers) */
extern int nservers; /* number of other servers*/
/* found in subscr.c */
-extern ZSTRING *empty;
-extern ZSTRING *wildcard_instance;
+extern String *empty;
+extern String *wildcard_instance;
extern struct in_addr my_addr; /* my inet address */
@@ -363,24 +377,12 @@ extern struct in_addr my_addr; /* my inet address */
#define ADMIN_DONE "DUMP_DONE" /* Opcode: brain dump for this server
is complete */
#define ADMIN_NEWCLT "NEXT_CLIENT" /* Opcode: this is a new client */
-#define ADMIN_LOST_CLT "LOST_CLIENT" /* Opcode: client not ack'ing */
#define ADMIN_KILL_CLT "KILL_CLIENT" /* Opcode: client is dead, remove */
#define ADMIN_STATUS "STATUS" /* Opcode: please send status */
-#define ADMIN_LIMBO "LIMBO" /* Class inst: please send limbo info*/
-#define ADMIN_YOU "YOUR_STATE" /* Class inst: please send your state*/
-#define ADMIN_ME "MY_STATE" /* Class inst: please send my info */
-
-#define NULLZT ((ZTriplet_t *) 0)
-#define NULLZCNT ((ZClient_t *) 0)
-#define NULLZCLT ((ZClientList_t *) 0)
-#define NULLZST ((ZSubscr_t *) 0)
-#define NULLZHLT ((ZHostList_t *) 0)
-#define NULLZNAT ((ZNotAcked_t *) 0)
-#define NULLZACLT ((ZAcl_t *) 0)
-#define NULLZPT ((ZPacket_t *) 0)
-#define NULLZSDT ((ZServerDesc_t *) 0)
-#define NULLZSPT ((ZSrvPending_t *) 0)
+#define ADMIN_NEWREALM "NEXT_REALM" /* Opcode: this is a new realm */
+#define REALM_REQ_LOCATE "REQ_LOCATE" /* Opcode: request a location */
+#define REALM_ANS_LOCATE "ANS_LOCATE" /* Opcode: answer to location */
/* me_server_idx is the index into otherservers of this server descriptor. */
/* the 'limbo' server is always the first server */
@@ -389,11 +391,12 @@ extern struct in_addr my_addr; /* my inet address */
#define limbo_server_idx() (0)
#define limbo_server (&otherservers[limbo_server_idx()])
-#define msgs_queued() (ZQLength() || otherservers[me_server_idx].zs_update_queue)
+#define msgs_queued() (ZQLength() || otherservers[me_server_idx].queue)
#define ack(a,b) clt_ack(a,b,SENT)
#define nack(a,b) clt_ack(a,b,NOT_SENT)
+#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define START_CRITICAL_CODE
@@ -402,18 +405,6 @@ extern struct in_addr my_addr; /* my inet address */
/* the instance that matches all instances */
#define WILDCARD_INSTANCE "*"
-/* SERVER_SRVTAB is defined in zephyr.h */
-#define ZEPHYR_SRVTAB SERVER_SRVTAB
-
-#ifdef KERBEROS
-#ifndef NOENCRYPTION
-/* Kerberos shouldn't stick us with array types... */
-typedef struct {
- des_key_schedule s;
-} Sched;
-#endif
-#endif
-
/* debugging macros */
#ifdef DEBUG
#define zdbug(s1) if (zdebug) syslog s1;
diff --git a/server/zserver.h.auth b/server/zserver.h.auth
deleted file mode 100644
index 41f6380..0000000
--- a/server/zserver.h.auth
+++ /dev/null
@@ -1,425 +0,0 @@
-#ifndef __ZSERVER_H__
-#define __ZSERVER_H__
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains declarations for use in the server.
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- * $Zephyr: /mit/zephyr/src/server/RCS/zserver.h,v 1.34 91/03/08 12:53:24 raeburn Exp $
- *
- * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#include <zephyr/zephyr.h> /* which includes <errno.h>,
- <sys/types.h>,
- <netinet/in.h>,
- <sys/time.h>,
- <stdio.h>,
- <krb.h> */
-#include <arpa/inet.h>
-#include <zephyr/acl.h>
-#include <sys/file.h>
-#include <fcntl.h>
-
-#include <zephyr/zsyslog.h>
-
-#include <string.h>
-#include <signal.h>
-#ifdef lint
-#include <sys/uio.h> /* so it shuts up about struct iovec */
-#endif /* lint */
-#ifdef _IBMR2
-#include <sys/select.h>
-#endif
-#include "zsrv_err.h"
-
-#include "timer.h"
-#include "zsrv_conf.h" /* configuration params */
-
-#include "zstring.h"
-#include "access.h"
-#include "unix.h"
-#include "zalloc.h"
-
-/* definitions for the Zephyr server */
-
-/* structures */
-
-/*
- * ZDestination: Where is this notice going to? This includes class,
- * instance, and recipient at the moment.
- */
-
-typedef struct _ZDestination {
- ZSTRING *classname;
- ZSTRING *inst;
- ZSTRING *recip;
-} ZDestination;
-
-/* typedef struct _Notice {
- ZNotice_t *notice;
- struct _ZDestination dest;
- ZSTRING *sender;
- int msg_no;
-} Notice;
-*/
-typedef struct _ZSubscr_t {
- struct _ZSubscr_t *q_forw; /* links in client's subscr. queue */
- struct _ZSubscr_t *q_back;
- struct _ZDestination zst_dest; /* destination of messages */
-} ZSubscr_t;
-
-typedef struct _ZClient_t {
- struct sockaddr_in zct_sin; /* ipaddr/port of client */
- struct _ZSubscr_t *zct_subs; /* subscriptions */
-#ifdef KERBEROS
- C_Block zct_cblock; /* session key for this client */
-#endif /* KERBEROS */
- ZSTRING *zct_principal; /* krb principal of user */
- long last_msg; /* last message sent to this client */
- long last_check; /* actually, last time the other
- server was asked to check... */
- int last_send; /* The send counter value for the
- * last packet sent to the client,
- * used to prevent duplicates. See
- * sendit() in dispatch.c. */
-} ZClient_t;
-
-typedef struct _ZClientList_t {
- struct _ZClientList_t *q_forw;
- struct _ZClientList_t *q_back;
- struct _ZClient_t *zclt_client;
-} ZClientList_t;
-
-typedef struct _ZTriplet_t {
- struct _ZTriplet_t *q_forw;
- struct _ZTriplet_t *q_back;
- ZDestination zct_dest;
- ZAcl_t *zct_acl;
- ZClientList_t *zct_clientlist;
-} ZTriplet_t;
-
-typedef struct _ZHostList_t {
- struct _ZHostList_t *q_forw;
- struct _ZHostList_t *q_back;
- ZClientList_t *zh_clients;
- struct sockaddr_in zh_addr; /* IP addr/port of hostmanager */
- unsigned int zh_locked; /* 1 if this host is locked for
- a braindump */
-} ZHostList_t;
-
-typedef enum _server_state {
- SERV_UP, /* Server is up */
- SERV_TARDY, /* Server due for a hello */
- SERV_DEAD, /* Server is considered dead */
- SERV_STARTING /* Server is between dead and up */
-} server_state;
-
-typedef struct _ZNotAcked_t {
- struct _ZNotAcked_t *q_forw; /* link to next */
- struct _ZNotAcked_t *q_back; /* link to prev */
- timer na_timer; /* timer for retransmit */
- long na_abstimo; /* absolute timeout to drop after */
- short na_rexmits; /* number of retransmits */
- short na_packsz; /* size of packet */
- caddr_t na_packet; /* ptr to packet */
- ZUnique_Id_t na_uid; /* uid of packet */
- union { /* address to send to */
- struct sockaddr_in na_sin; /* client address */
- int srv_idx; /* index of server */
- } dest;
-#define na_addr dest.na_sin
-#define na_srv_idx dest.srv_idx
-} ZNotAcked_t;
-
-typedef struct _ZSrvPending_t {
- struct _ZSrvPending_t *q_forw; /* link to next */
- struct _ZSrvPending_t *q_back; /* link to prev */
- caddr_t pend_packet; /* the notice (in pkt form) */
- short pend_len; /* len of pkt */
- unsigned int pend_auth; /* whether it is authentic */
- struct sockaddr_in pend_who; /* the addr of the sender */
-} ZSrvPending_t;
-
-typedef struct _ZServerDesc_t {
- server_state zs_state; /* server's state */
- struct sockaddr_in zs_addr; /* server's address */
- long zs_timeout; /* Length of timeout in sec */
- timer zs_timer; /* timer struct for this server */
- struct _ZHostList_t *zs_hosts; /* pointer to list of info from this
- server */
- struct _ZSrvPending_t *zs_update_queue; /* queue of packets to send
- to this server when done dumping */
- short zs_numsent; /* number of hello's sent */
- unsigned int zs_dumping; /* 1 if dumping, so we should queue */
- char addr[16]; /* text version of address */
-} ZServerDesc_t;
-
-typedef enum ZSentType {
- NOT_SENT, /* message was not xmitted */
- SENT, /* message was xmitted */
- AUTH_FAILED, /* authentication failed */
- NOT_FOUND /* user not found for uloc */
-} ZSentType;
-
-/* statistics gathering */
-typedef struct _ZStatistic_t {
- int val;
- char *str;
-} ZStatistic;
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-/* Function declarations */
-
-/* found in bdump.c */
-extern void bdump_get P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
- ZServerDesc_t *server));
-extern void bdump_send P((void));
-extern void bdump_offer P((struct sockaddr_in *who));
-extern Code_t bdump_send_list_tcp P((ZNotice_Kind_t kind, int port,
- char *class_name, char *inst, char *opcode,
- char *sender, char *recip,
- char **lyst, int num));
-
-/* found in class.c */
-extern Code_t triplet_register P((ZClient_t *client, ZDestination *dest));
-extern Code_t triplet_deregister P((ZClient_t *client, ZDestination *dest));
-extern Code_t class_restrict P((char *z_class, ZAcl_t *acl));
-extern Code_t class_setup_restricted P((char *z_class, ZAcl_t *acl));
-extern ZClientList_t *triplet_lookup P((ZDestination *dest));
-extern ZAcl_t *class_get_acl P((ZSTRING *z_class));
-extern void class_free P((ZClientList_t *lyst));
-extern ZSTRING *class_control, *class_admin, *class_hm;
-extern ZSTRING *class_ulogin, *class_ulocate;
-extern void set_ZDestination_hash P((ZDestination *zd));
-extern int ZDest_eq P((ZDestination *zd1, ZDestination *zd2));
-extern int order_dest_strings P((ZDestination *zd1, ZDestination *zd2));
-extern void class_dump_subs P((register FILE *fp));
-
-/* found in client.c */
-extern Code_t client_register P((ZNotice_t *notice, struct sockaddr_in *who,
- register ZClient_t **client,
- ZServerDesc_t *server, int wantdefaults));
-extern void client_deregister P((ZClient_t *client, ZHostList_t *host,
- int flush));
-extern void client_dump_clients P((FILE *fp, ZClientList_t *clist));
-extern ZClient_t *client_which_client P((struct sockaddr_in *who,
- ZNotice_t *notice));
-
-/* found in common.c */
-extern char *strsave P((Zconst char *str));
-extern unsigned long hash P((Zconst char *));
-extern void subscr_quote P((char *p, FILE *fp));
-
-/* found in dispatch.c */
-extern void handle_packet P((void));
-extern void clt_ack P((ZNotice_t *notice, struct sockaddr_in *who,
- ZSentType sent));
-extern void nack_release P((ZClient_t *client));
-extern void sendit P((register ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern void rexmit P((void *));
-extern void xmit P((register ZNotice_t *notice, struct sockaddr_in *dest,
- int auth, ZClient_t *client));
-extern Code_t control_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- ZServerDesc_t *server));
-extern Code_t xmit_frag P((ZNotice_t *notice, char *buf, int len,
- int waitforack));
-
-/* found in hostm.c */
-extern void hostm_flush P((ZHostList_t *host, ZServerDesc_t *server));
-extern void hostm_shutdown P((void));
-extern void hostm_losing P((ZClient_t *client, ZHostList_t *host));
-extern ZHostList_t *hostm_find_host P((struct in_addr *addr));
-extern ZServerDesc_t *hostm_find_server P((struct in_addr *addr));
-extern void hostm_transfer P((ZHostList_t *host, ZServerDesc_t *server));
-extern void hostm_deathgram P((struct sockaddr_in *sin,
- ZServerDesc_t *server));
-extern void hostm_dump_hosts P((FILE *fp));
-extern Code_t hostm_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who, ZServerDesc_t *server));
-extern void hostm_lose_ignore P((ZClient_t *client));
-extern void hostm_renumber_servers P((int *));
-
-/* found in kstuff.c */
-#ifdef KERBEROS
-extern int GetKerberosData P((int, struct in_addr, AUTH_DAT*, char*, char*));
-extern Code_t SendKerberosData P((int, KTEXT, char*, char*));
-#endif
-void sweep_ticket_hash_table P((void *));
-
-/* found in server.c */
-extern void server_timo P((void *which));
-extern void server_recover P((ZClient_t *client)),
- server_dump_servers P((FILE *fp));
-extern void server_init P((void)),
- server_shutdown P((void));
-extern void server_forward P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern void server_kill_clt P((ZClient_t *client));
-extern void server_pending_free P((register ZSrvPending_t *pending));
-extern void server_self_queue P((ZNotice_t*, int, struct sockaddr_in *)),
- server_send_queue P((ZServerDesc_t *)),
- server_reset P((void));
-extern int is_server();
-extern ZServerDesc_t *server_which_server P((struct sockaddr_in *who));
-extern ZSrvPending_t *server_dequeue P((register ZServerDesc_t *server));
-extern Code_t server_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern Code_t server_adispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- ZServerDesc_t *server));
-
-
-/* found in subscr.c */
-extern Code_t subscr_cancel P((struct sockaddr_in *sin, ZNotice_t *notice));
-extern Code_t subscr_subscribe P((ZClient_t *who, ZNotice_t *notice)),
- subscr_send_subs P((ZClient_t *client, char *vers));;
-extern void subscr_free_list P((ZClientList_t *list)),
- subscr_cancel_client P((register ZClient_t *client)),
- subscr_sendlist P((ZNotice_t *notice, int auth, struct sockaddr_in *who));
-extern void subscr_dump_subs P((FILE *fp, ZSubscr_t *subs)),
- subscr_reset P((void));
-extern int compare_subs P((ZSubscr_t *s1, ZSubscr_t *s2, int do_wildcard));
-extern Code_t subscr_def_subs P((ZClient_t *who));
-
-/* found in uloc.c */
-extern void uloc_hflush P((struct in_addr *addr)),
- uloc_flush_client P((struct sockaddr_in *sin)),
- uloc_dump_locs P((register FILE *fp));
-extern Code_t ulogin_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who, ZServerDesc_t *server)),
- ulocate_dispatch P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
- ZServerDesc_t *server)),
- uloc_send_locations P((ZHostList_t *host, char *vers));
-
-/* found in version.c */
-extern char *get_version P((void));
-
-#undef P
-
-
-/* global identifiers */
-
-/* found in main.c */
-extern struct sockaddr_in sock_sin; /* socket descriptors */
-extern u_short hm_port; /* port # of hostmanagers */
-extern int srv_socket; /* dgram sockets for clients
- and other servers */
-extern int bdump_socket; /* brain dump socket
- (closed most of the time) */
-
-extern fd_set interesting; /* the file descrips we are listening
- to right now */
-extern int nfildes; /* number to look at in select() */
-extern int zdebug;
-extern char myname[]; /* domain name of this host */
-extern ZNotAcked_t *nacklist; /* list of not ack'ed packets */
-extern Zconst char version[];
-extern u_long npackets; /* num of packets processed */
-extern long uptime; /* time we started */
-extern struct in_addr my_addr;
-
-/* found in bdump.c */
-extern int bdumping; /* are we dumping right now? */
-
-/* found in dispatch.c */
-extern ZStatistic i_s_ctls, i_s_logins, i_s_admins, i_s_locates;
-extern int num_rexmits;
-extern long rexmit_secs, abs_timo;
-
-/* found in server.c */
-extern ZServerDesc_t *otherservers; /* array of servers */
-extern int me_server_idx; /* me (in the array of servers) */
-extern int nservers; /* number of other servers*/
-
-/* found in subscr.c */
-extern ZSTRING *empty;
-extern ZSTRING *wildcard_instance;
-
-extern struct in_addr my_addr; /* my inet address */
-
-#define class_is_control(classname) (classname == class_control)
-#define class_is_admin(classname) (classname == class_admin)
-#define class_is_hm(classname) (classname == class_hm)
-#define class_is_ulogin(classname) (classname == class_ulogin)
-#define class_is_ulocate(classname) (classname == class_ulocate)
-
-#define ADMIN_HELLO "HELLO" /* Opcode: hello, are you there */
-#define ADMIN_IMHERE "IHEARDYOU" /* Opcode: yes, I am here */
-#define ADMIN_SHUTDOWN "GOODBYE" /* Opcode: I am shutting down */
-#define ADMIN_BDUMP "DUMP_AVAIL" /* Opcode: I will give you a dump */
-#define ADMIN_DONE "DUMP_DONE" /* Opcode: brain dump for this server
- is complete */
-#define ADMIN_NEWCLT "NEXT_CLIENT" /* Opcode: this is a new client */
-#define ADMIN_LOST_CLT "LOST_CLIENT" /* Opcode: client not ack'ing */
-#define ADMIN_KILL_CLT "KILL_CLIENT" /* Opcode: client is dead, remove */
-#define ADMIN_STATUS "STATUS" /* Opcode: please send status */
-
-#define ADMIN_LIMBO "LIMBO" /* Class inst: please send limbo info*/
-#define ADMIN_YOU "YOUR_STATE" /* Class inst: please send your state*/
-#define ADMIN_ME "MY_STATE" /* Class inst: please send my info */
-
-#define NULLZT ((ZTriplet_t *) 0)
-#define NULLZCNT ((ZClient_t *) 0)
-#define NULLZCLT ((ZClientList_t *) 0)
-#define NULLZST ((ZSubscr_t *) 0)
-#define NULLZHLT ((ZHostList_t *) 0)
-#define NULLZNAT ((ZNotAcked_t *) 0)
-#define NULLZACLT ((ZAcl_t *) 0)
-#define NULLZPT ((ZPacket_t *) 0)
-#define NULLZSDT ((ZServerDesc_t *) 0)
-#define NULLZSPT ((ZSrvPending_t *) 0)
-
-/* me_server_idx is the index into otherservers of this server descriptor. */
-/* the 'limbo' server is always the first server */
-
-#define me_server (&otherservers[me_server_idx])
-#define limbo_server_idx() (0)
-#define limbo_server (&otherservers[limbo_server_idx()])
-
-#define msgs_queued() (ZQLength() || otherservers[me_server_idx].zs_update_queue)
-
-#define ack(a,b) clt_ack(a,b,SENT)
-#define nack(a,b) clt_ack(a,b,NOT_SENT)
-
-#define max(a,b) ((a) > (b) ? (a) : (b))
-
-#define START_CRITICAL_CODE
-#define END_CRITICAL_CODE
-
-/* the instance that matches all instances */
-#define WILDCARD_INSTANCE "*"
-
-/* SERVER_SRVTAB is defined in zephyr.h */
-#define ZEPHYR_SRVTAB SERVER_SRVTAB
-
-#ifdef KERBEROS
-#ifndef NOENCRYPTION
-/* Kerberos shouldn't stick us with array types... */
-typedef struct {
- des_key_schedule s;
-} Sched;
-#endif
-#endif
-
-/* debugging macros */
-#ifdef DEBUG
-#define zdbug(s1) if (zdebug) syslog s1;
-#else /* !DEBUG */
-#define zdbug(s1)
-#endif /* DEBUG */
-
-#endif /* !__ZSERVER_H__ */
diff --git a/server/zserver.h.old b/server/zserver.h.old
deleted file mode 100644
index 7b51ac1..0000000
--- a/server/zserver.h.old
+++ /dev/null
@@ -1,424 +0,0 @@
-#ifndef __ZSERVER_H__
-#define __ZSERVER_H__
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains declarations for use in the server.
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- * $Zephyr: /mit/zephyr/src/server/RCS/zserver.h,v 1.34 91/03/08 12:53:24 raeburn Exp $
- *
- * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#include <zephyr/zephyr.h> /* which includes <errno.h>,
- <sys/types.h>,
- <netinet/in.h>,
- <sys/time.h>,
- <stdio.h>,
- <krb.h> */
-#include <arpa/inet.h>
-#include <zephyr/acl.h>
-#include <sys/file.h>
-#include <fcntl.h>
-
-#include <zephyr/zsyslog.h>
-
-#include <strings.h>
-#include <signal.h>
-#ifdef lint
-#include <sys/uio.h> /* so it shuts up about struct iovec */
-#endif /* lint */
-#ifdef _IBMR2
-#include <sys/select.h>
-#endif
-#include "zsrv_err.h"
-
-#include "timer.h"
-#include "zsrv_conf.h" /* configuration params */
-
-#include "zstring.h"
-#include "access.h"
-#include "unix.h"
-#include "zalloc.h"
-
-/* definitions for the Zephyr server */
-
-/* structures */
-
-/*
- * ZDestination: Where is this notice going to? This includes class,
- * instance, and recipient at the moment.
- */
-
-typedef struct _ZDestination {
- unsigned long hash_value;
- ZSTRING *classname;
- ZSTRING *inst;
- ZSTRING *recip;
-} ZDestination;
-
-/* typedef struct _Notice {
- ZNotice_t *notice;
- struct _ZDestination dest;
- ZSTRING *sender;
- int msg_no;
-} Notice;
-*/
-typedef struct _ZSubscr_t {
- struct _ZSubscr_t *q_forw; /* links in client's subscr. queue */
- struct _ZSubscr_t *q_back;
- struct _ZDestination zst_dest; /* destination of messages */
-} ZSubscr_t;
-
-typedef struct _ZClient_t {
- struct sockaddr_in zct_sin; /* ipaddr/port of client */
- struct _ZSubscr_t *zct_subs; /* subscriptions */
-#ifdef KERBEROS
- C_Block zct_cblock; /* session key for this client */
-#endif /* KERBEROS */
- ZSTRING *zct_principal; /* krb principal of user */
- long last_msg; /* last message sent to this client */
- long last_check; /* actually, last time the other
- server was asked to check... */
-} ZClient_t;
-
-typedef struct _ZClientList_t {
- struct _ZClientList_t *q_forw;
- struct _ZClientList_t *q_back;
- struct _ZClient_t *zclt_client;
-} ZClientList_t;
-
-typedef struct _ZClass_t {
- struct _ZClass_t *q_forw;
- struct _ZClass_t *q_back;
- ZDestination zct_dest;
- ZAcl_t *zct_acl;
- ZClientList_t *zct_clientlist;
-} ZClass_t;
-
-typedef struct _ZHostList_t {
- struct _ZHostList_t *q_forw;
- struct _ZHostList_t *q_back;
- ZClientList_t *zh_clients;
- struct sockaddr_in zh_addr; /* IP addr/port of hostmanager */
- unsigned int zh_locked; /* 1 if this host is locked for
- a braindump */
-} ZHostList_t;
-
-typedef enum _server_state {
- SERV_UP, /* Server is up */
- SERV_TARDY, /* Server due for a hello */
- SERV_DEAD, /* Server is considered dead */
- SERV_STARTING /* Server is between dead and up */
-} server_state;
-
-typedef struct _ZNotAcked_t {
- struct _ZNotAcked_t *q_forw; /* link to next */
- struct _ZNotAcked_t *q_back; /* link to prev */
- timer na_timer; /* timer for retransmit */
- long na_abstimo; /* absolute timeout to drop after */
- short na_rexmits; /* number of retransmits */
- short na_packsz; /* size of packet */
- caddr_t na_packet; /* ptr to packet */
- ZUnique_Id_t na_uid; /* uid of packet */
- union { /* address to send to */
- struct sockaddr_in na_sin; /* client address */
- int srv_idx; /* index of server */
- } dest;
-#define na_addr dest.na_sin
-#define na_srv_idx dest.srv_idx
-} ZNotAcked_t;
-
-typedef struct _ZSrvPending_t {
- struct _ZSrvPending_t *q_forw; /* link to next */
- struct _ZSrvPending_t *q_back; /* link to prev */
- caddr_t pend_packet; /* the notice (in pkt form) */
- short pend_len; /* len of pkt */
- unsigned int pend_auth; /* whether it is authentic */
- struct sockaddr_in pend_who; /* the addr of the sender */
-} ZSrvPending_t;
-
-typedef struct _ZServerDesc_t {
- server_state zs_state; /* server's state */
- struct sockaddr_in zs_addr; /* server's address */
- long zs_timeout; /* Length of timeout in sec */
- timer zs_timer; /* timer struct for this server */
- struct _ZHostList_t *zs_hosts; /* pointer to list of info from this
- server */
- struct _ZSrvPending_t *zs_update_queue; /* queue of packets to send
- to this server when done dumping */
- short zs_numsent; /* number of hello's sent */
- unsigned int zs_dumping; /* 1 if dumping, so we should queue */
- char addr[16]; /* text version of address */
-} ZServerDesc_t;
-
-typedef enum ZSentType {
- NOT_SENT, /* message was not xmitted */
- SENT, /* message was xmitted */
- AUTH_FAILED, /* authentication failed */
- NOT_FOUND /* user not found for uloc */
-} ZSentType;
-
-/* statistics gathering */
-typedef struct _ZStatistic_t {
- int val;
- char *str;
-} ZStatistic;
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-/* Function declarations */
-
-/* found in bdump.c */
-extern void bdump_get P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
- ZServerDesc_t *server));
-extern void bdump_send P((void));
-extern void bdump_offer P((struct sockaddr_in *who));
-extern Code_t bdump_send_list_tcp P((ZNotice_Kind_t kind, int port,
- char *class_name, char *inst, char *opcode,
- char *sender, char *recip,
- char **lyst, int num));
-
-/* found in class.c */
-extern Code_t class_register P((ZClient_t *client, ZSubscr_t *subs));
-extern Code_t class_deregister P((ZClient_t *client, ZSubscr_t *subs));
-extern Code_t class_restrict P((char *z_class, ZAcl_t *acl));
-extern Code_t class_setup_restricted P((char *z_class, ZAcl_t *acl));
-extern ZClientList_t *class_lookup P((ZSubscr_t *subs));
-extern ZAcl_t *class_get_acl P((ZSTRING *z_class));
-extern void class_free P((ZClientList_t *lyst));
-extern ZSTRING *class_control, *class_admin, *class_hm;
-extern ZSTRING *class_ulogin, *class_ulocate;
-extern void set_ZDestination_hash P((ZDestination *zd));
-extern int ZDest_eq P((ZDestination *zd1, ZDestination *zd2));
-extern int order_dest_strings P((ZDestination *zd1, ZDestination *zd2));
-
-/* found in client.c */
-extern Code_t client_register P((ZNotice_t *notice, struct sockaddr_in *who,
- register ZClient_t **client,
- ZServerDesc_t *server, int wantdefaults));
-extern void client_deregister P((ZClient_t *client, ZHostList_t *host,
- int flush));
-extern void client_dump_clients P((FILE *fp, ZClientList_t *clist));
-extern ZClient_t *client_which_client P((struct sockaddr_in *who,
- ZNotice_t *notice));
-
-/* found in common.c */
-extern char *strsave P((Zconst char *str));
-extern unsigned long hash P((Zconst char *));
-
-/* found in dispatch.c */
-extern void handle_packet P((void));
-extern void clt_ack P((ZNotice_t *notice, struct sockaddr_in *who,
- ZSentType sent));
-extern void nack_release P((ZClient_t *client));
-extern void sendit P((register ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern void rexmit P((void *));
-extern void xmit P((register ZNotice_t *notice, struct sockaddr_in *dest,
- int auth, ZClient_t *client));
-extern Code_t control_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- ZServerDesc_t *server));
-extern Code_t xmit_frag P((ZNotice_t *notice, char *buf, int len,
- int waitforack));
-
-/* found in hostm.c */
-extern void hostm_flush P((ZHostList_t *host, ZServerDesc_t *server));
-extern void hostm_shutdown P((void));
-extern void hostm_losing P((ZClient_t *client, ZHostList_t *host));
-extern ZHostList_t *hostm_find_host P((struct in_addr *addr));
-extern ZServerDesc_t *hostm_find_server P((struct in_addr *addr));
-extern void hostm_transfer P((ZHostList_t *host, ZServerDesc_t *server));
-extern void hostm_deathgram P((struct sockaddr_in *sin,
- ZServerDesc_t *server));
-extern void hostm_dump_hosts P((FILE *fp));
-extern Code_t hostm_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who, ZServerDesc_t *server));
-extern void hostm_lose_ignore P((ZClient_t *client));
-extern void hostm_renumber_servers P((int *));
-
-/* found in kstuff.c */
-#ifdef KERBEROS
-extern int GetKerberosData P((int, struct in_addr, AUTH_DAT*, char*, char*));
-extern Code_t SendKerberosData P((int, KTEXT, char*, char*));
-#endif
-
-/* found in server.c */
-extern void server_timo P((void *which));
-extern void server_recover P((ZClient_t *client)),
- server_dump_servers P((FILE *fp));
-extern void server_init P((void)),
- server_shutdown P((void));
-extern void server_forward P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern void server_kill_clt P((ZClient_t *client));
-extern void server_pending_free P((register ZSrvPending_t *pending));
-extern void server_self_queue P((ZNotice_t*, int, struct sockaddr_in *)),
- server_send_queue P((ZServerDesc_t *)),
- server_reset P((void));
-extern int is_server();
-extern ZServerDesc_t *server_which_server P((struct sockaddr_in *who));
-extern ZSrvPending_t *server_dequeue P((register ZServerDesc_t *server));
-extern Code_t server_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who));
-extern Code_t server_adispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- ZServerDesc_t *server));
-
-
-/* found in subscr.c */
-extern Code_t subscr_cancel P((struct sockaddr_in *sin, ZNotice_t *notice));
-extern Code_t subscr_subscribe P((ZClient_t *who, ZNotice_t *notice)),
- subscr_send_subs P((ZClient_t *client, char *vers));;
-extern ZClientList_t *subscr_match_list P((ZNotice_t *notice));
-extern void subscr_free_list P((ZClientList_t *list)),
- subscr_cancel_client P((register ZClient_t *client)),
- subscr_sendlist P((ZNotice_t *notice, int auth, struct sockaddr_in *who));
-extern void subscr_dump_subs P((FILE *fp, ZSubscr_t *subs)),
- subscr_reset P((void));
-extern int compare_subs P((ZSubscr_t *s1, ZSubscr_t *s2, int do_wildcard));
-extern Code_t subscr_def_subs P((ZClient_t *who));
-
-/* found in uloc.c */
-extern void uloc_hflush P((struct in_addr *addr)),
- uloc_flush_client P((struct sockaddr_in *sin)),
- uloc_dump_locs P((register FILE *fp));
-extern Code_t ulogin_dispatch P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who, ZServerDesc_t *server)),
- ulocate_dispatch P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
- ZServerDesc_t *server)),
- uloc_send_locations P((ZHostList_t *host, char *vers));
-
-/* found in version.c */
-extern char *get_version P((void));
-
-#undef P
-
-
-/* global identifiers */
-
-/* found in main.c */
-extern struct sockaddr_in sock_sin; /* socket descriptors */
-extern u_short hm_port; /* port # of hostmanagers */
-extern int srv_socket; /* dgram sockets for clients
- and other servers */
-extern int bdump_socket; /* brain dump socket
- (closed most of the time) */
-
-extern fd_set interesting; /* the file descrips we are listening
- to right now */
-extern int nfildes; /* number to look at in select() */
-extern int zdebug;
-extern char myname[]; /* domain name of this host */
-extern ZNotAcked_t *nacklist; /* list of not ack'ed packets */
-extern Zconst char version[];
-extern u_long npackets; /* num of packets processed */
-extern long uptime; /* time we started */
-extern struct in_addr my_addr;
-
-/* found in bdump.c */
-extern int bdumping; /* are we dumping right now? */
-
-/* found in dispatch.c */
-extern ZStatistic i_s_ctls, i_s_logins, i_s_admins, i_s_locates;
-extern int num_rexmits;
-extern long rexmit_secs, abs_timo;
-
-/* found in server.c */
-extern ZServerDesc_t *otherservers; /* array of servers */
-extern int me_server_idx; /* me (in the array of servers) */
-extern int nservers; /* number of other servers*/
-
-/* found in subscr.c */
-extern ZSTRING *empty;
-extern ZSTRING *wildcard_instance;
-extern ZSTRING *wildcard_class;
-extern ZSubscr_t matchall_sub;
-
-extern struct in_addr my_addr; /* my inet address */
-
-#define class_is_control(classname) (classname == class_control)
-#define class_is_admin(classname) (classname == class_admin)
-#define class_is_hm(classname) (classname == class_hm)
-#define class_is_ulogin(classname) (classname == class_ulogin)
-#define class_is_ulocate(classname) (classname == class_ulocate)
-
-#define ADMIN_HELLO "HELLO" /* Opcode: hello, are you there */
-#define ADMIN_IMHERE "IHEARDYOU" /* Opcode: yes, I am here */
-#define ADMIN_SHUTDOWN "GOODBYE" /* Opcode: I am shutting down */
-#define ADMIN_BDUMP "DUMP_AVAIL" /* Opcode: I will give you a dump */
-#define ADMIN_DONE "DUMP_DONE" /* Opcode: brain dump for this server
- is complete */
-#define ADMIN_NEWCLT "NEXT_CLIENT" /* Opcode: this is a new client */
-#define ADMIN_LOST_CLT "LOST_CLIENT" /* Opcode: client not ack'ing */
-#define ADMIN_KILL_CLT "KILL_CLIENT" /* Opcode: client is dead, remove */
-#define ADMIN_STATUS "STATUS" /* Opcode: please send status */
-
-#define ADMIN_LIMBO "LIMBO" /* Class inst: please send limbo info*/
-#define ADMIN_YOU "YOUR_STATE" /* Class inst: please send your state*/
-#define ADMIN_ME "MY_STATE" /* Class inst: please send my info */
-
-#define NULLZCT ((ZClass_t *) 0)
-#define NULLZCNT ((ZClient_t *) 0)
-#define NULLZCLT ((ZClientList_t *) 0)
-#define NULLZST ((ZSubscr_t *) 0)
-#define NULLZHLT ((ZHostList_t *) 0)
-#define NULLZNAT ((ZNotAcked_t *) 0)
-#define NULLZACLT ((ZAcl_t *) 0)
-#define NULLZPT ((ZPacket_t *) 0)
-#define NULLZSDT ((ZServerDesc_t *) 0)
-#define NULLZSPT ((ZSrvPending_t *) 0)
-
-/* me_server_idx is the index into otherservers of this server descriptor. */
-/* the 'limbo' server is always the first server */
-
-#define me_server (&otherservers[me_server_idx])
-#define limbo_server_idx() (0)
-#define limbo_server (&otherservers[limbo_server_idx()])
-
-#define msgs_queued() (ZQLength() || otherservers[me_server_idx].zs_update_queue)
-
-#define ack(a,b) clt_ack(a,b,SENT)
-#define nack(a,b) clt_ack(a,b,NOT_SENT)
-
-#define max(a,b) ((a) > (b) ? (a) : (b))
-
-#define START_CRITICAL_CODE
-#define END_CRITICAL_CODE
-
-/* the magic class to match all packets */
-#define MATCHALL_CLASS "zmatch_all"
-/* the instance that matches all instances */
-#define WILDCARD_INSTANCE "*"
-
-/* SERVER_SRVTAB is defined in zephyr.h */
-#define ZEPHYR_SRVTAB SERVER_SRVTAB
-
-#ifdef KERBEROS
-#ifndef NOENCRYPTION
-/* Kerberos shouldn't stick us with array types... */
-typedef struct {
- des_key_schedule s;
-} Sched;
-#endif
-#endif
-
-/* debugging macros */
-#ifdef DEBUG
-#define zdbug(s1) if (zdebug) syslog s1;
-#else /* !DEBUG */
-#define zdbug(s1)
-#endif /* DEBUG */
-
-#endif /* !__ZSERVER_H__ */
diff --git a/server/zsrv_conf.h b/server/zsrv_conf.h
index cb81883..2440d1d 100644
--- a/server/zsrv_conf.h
+++ b/server/zsrv_conf.h
@@ -16,32 +16,22 @@
#define __ZSRV_CONF_H__
#include <zephyr/mit-copyright.h>
-/* Magic path names */
-#ifndef HESIOD
-#define SERVER_LIST_FILE "/etc/athena/zephyr/server.list"
-#endif
+/* Path names are relative to CONFDIR, except for the class registry. */
-/* ACL's for pre-registered classes */
-/* Directory containing acls and other info */
-#ifndef ZEPHYR_ACL_DIR
-#define ZEPHYR_ACL_DIR "/etc/athena/zephyr/acl/"
+#ifndef ZEPHYR_USES_HESIOD
+#define SERVER_LIST_FILE "server.list"
+#endif
+#define REALM_LIST_FILE "realm.list"
+#ifdef ZEPHYR_USES_KERBEROS
+#define ZEPHYR_SRVTAB "srvtab"
+#define ZEPHYR_TKFILE "ztkts"
#endif
-/* name of the class registry */
+#define ZEPHYR_ACL_DIR "acl/"
#define ZEPHYR_CLASS_REGISTRY "class-registry.acl"
+#define DEFAULT_SUBS_FILE "default.subscriptions"
-#ifdef KERBEROS
-/* name of file to hold the tickets for keys to exchange with other servers */
-#define ZEPHYR_TKFILE "/etc/athena/zephyr/ztkts"
-
-/* The pathname of the Kerberos srvtab file is defined in zephyr_conf.h. */
-#endif /* KERBEROS */
-
-/* default subscription file */
-#define DEFAULT_SUBS_FILE "/etc/athena/zephyr/default.subscriptions"
-
-/* client defines */
-#define REXMIT_SECS ((long) 20) /* rexmit delay on normal notices */
-#define NUM_REXMITS (9) /* number of rexmits */
+#define REXMIT_TIMES { 2, 2, 4, 4, 8, 8, 16, 32, 64, 128, 256, 512, -1 }
+#define NUM_REXMIT_TIMES 12
/* hostmanager defines */
#define LOSE_TIMO (60) /* time during which a losing host
@@ -56,4 +46,8 @@
when tardy */
#define H_NUM_STARTING 2 /* num hello's before going dead
when starting */
+
+#define SWEEP_INTERVAL 3600 /* Time between sweeps of the ticket
+ hash table */
+
#endif /* __ZSRV_CONF_H__ */
diff --git a/server/zsrv_conf.h.auth b/server/zsrv_conf.h.auth
deleted file mode 100644
index 6057130..0000000
--- a/server/zsrv_conf.h.auth
+++ /dev/null
@@ -1,63 +0,0 @@
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains site-specific definitions for use in the server.
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- * $Header$
- *
- * Copyright (c) 1988 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#ifndef __ZSRV_CONF_H__
-#define __ZSRV_CONF_H__
-#include <zephyr/mit-copyright.h>
-
-/* Magic path names */
-#ifndef HESIOD
-#define SERVER_LIST_FILE "/etc/athena/zephyr/server.list"
-#endif
-
-/* ACL's for pre-registered classes */
-/* Directory containing acls and other info */
-#ifndef ZEPHYR_ACL_DIR
-#define ZEPHYR_ACL_DIR "/etc/athena/zephyr/acl/"
-#endif
-/* name of the class registry */
-#define ZEPHYR_CLASS_REGISTRY "class-registry.acl"
-
-#ifdef KERBEROS
-/* name of file to hold the tickets for keys to exchange with other servers */
-#define ZEPHYR_TKFILE "/etc/athena/zephyr/ztkts"
-
-/* The pathname of the Kerberos srvtab file is defined in zephyr_conf.h. */
-#endif /* KERBEROS */
-
-/* default subscription file */
-#define DEFAULT_SUBS_FILE "/etc/athena/zephyr/default.subscriptions"
-
-/* client defines */
-#define REXMIT_SECS ((long) 20) /* rexmit delay on normal notices */
-#define NUM_REXMITS (9) /* number of rexmits */
-
-/* hostmanager defines */
-#define LOSE_TIMO (60) /* time during which a losing host
- must respond to a ping */
-
-/* server-server defines */
-#define TIMO_UP ((long) 60) /* timeout between up and tardy */
-#define TIMO_TARDY ((long) 120) /* timeout btw tardy hellos */
-#define TIMO_DEAD ((long)(15*60)) /* timeout between hello's for dead */
-
-#define H_NUM_TARDY 5 /* num hello's before going dead
- when tardy */
-#define H_NUM_STARTING 2 /* num hello's before going dead
- when starting */
-
-#define SWEEP_INTERVAL 3600 /* Time between sweeps of the ticket
- hash table */
-
-#endif /* __ZSRV_CONF_H__ */
diff --git a/server/zsrv_err.et b/server/zsrv_err.et
index 26bbc0d..d3b9eab 100644
--- a/server/zsrv_err.et
+++ b/server/zsrv_err.et
@@ -38,4 +38,8 @@ ec ZSRV_RCSID,
"$Id$"
ec ZSRV_BADSUBPORT,
"Illegal port specified in subscription"
+ec ZSRV_NORLM,
+ "No such realm"
+ec ZSRV_EMPTYCLASS,
+ "Class is now empty"
end
diff --git a/server/zstring.c b/server/zstring.c
index 6b5aed3..955e0b8 100644
--- a/server/zstring.c
+++ b/server/zstring.c
@@ -12,177 +12,156 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
#ifndef lint
#ifndef SABER
-static char rcsid_zstring_c[] =
- "$Id$";
+static const char rcsid_zstring_c[] =
+"$Id$";
#endif
#endif
-#include <mit-copyright.h>
+static String *zhash[STRING_HASH_TABLE_SIZE];
-#include <ctype.h>
-#if defined(__STDC__) && !defined(__HIGHC__) && !defined(SABER)
-#include <stdlib.h>
-#endif
-#include <string.h>
-
-#include <zephyr/zephyr.h>
-#include "zstring.h"
-
-static ZSTRING *zhash[ZSTRING_HASH_TABLE_SIZE];
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-extern unsigned long hash P((Zconst char *s));
-extern char *strsave P((Zconst char *s));
-#undef P
-
-ZSTRING *
-make_zstring(s, downcase)
- char *s;
- int downcase;
+String *
+make_string(s, downcase)
+ char *s;
+ int downcase;
{
- char *new_s,*p;
- ZSTRING *new_z,*hp;
- int i;
-
- if (downcase) {
- new_s = strsave(s);
- p = new_s;
- while(*p) {
- if (isascii(*p) && isupper(*p))
- *p = tolower(*p);
- p++;
+ char *new_s,*p;
+ String *new_z,*hp;
+ int i;
+
+ if (downcase) {
+ new_s = strsave(s);
+ p = new_s;
+ while(*p) {
+ if (isascii(*p) && isupper(*p))
+ *p = tolower(*p);
+ p++;
+ }
+ } else {
+ new_s = s;
}
- } else {
- new_s = s;
- }
- new_z = find_zstring(new_s,0);
- if (new_z != NULL) {
- if (downcase)
- free(new_s);
- new_z->ref_count++;
- return(new_z);
- }
-
- /* Initialize new ZSTRING */
-
- if (!downcase)
- new_s = strsave(s);
- new_z = (ZSTRING *) malloc(sizeof(ZSTRING));
- new_z->string = new_s;
- new_z->ref_count = 1;
+ new_z = find_string(new_s,0);
+ if (new_z != NULL) {
+ if (downcase)
+ free(new_s);
+ new_z->ref_count++;
+ return(new_z);
+ }
+
+ /* Initialize new String */
+
+ if (!downcase)
+ new_s = strsave(s);
+ new_z = (String *) malloc(sizeof(String));
+ new_z->string = new_s;
+ new_z->ref_count = 1;
- /* Add to beginning of hash table */
- new_z->hash_val = hash(new_s);
- i = new_z->hash_val % ZSTRING_HASH_TABLE_SIZE;
- hp = zhash[i];
- new_z->next = hp;
- if (hp != NULL)
- hp->prev = new_z;
- new_z->prev = NULL;
- zhash[i] = new_z;
-
- return(new_z);
+ /* Add to beginning of hash table */
+ new_z->hash_val = hash(new_s);
+ i = new_z->hash_val % STRING_HASH_TABLE_SIZE;
+ hp = zhash[i];
+ new_z->next = hp;
+ if (hp != NULL)
+ hp->prev = new_z;
+ new_z->prev = NULL;
+ zhash[i] = new_z;
+
+ return new_z;
}
void
-free_zstring(z)
- ZSTRING *z;
+free_string(z)
+ String *z;
{
- if (z == (ZSTRING *) NULL)
- return;
-
- z->ref_count--;
- if (z->ref_count > 0)
- return;
-
- /* delete zstring completely */
- if(z->prev == NULL)
- zhash[hash(z->string) % ZSTRING_HASH_TABLE_SIZE] = z->next;
- else
- z->prev->next = z->next;
+ if (z == (String *) NULL)
+ return;
+
+ z->ref_count--;
+ if (z->ref_count > 0)
+ return;
+
+ /* delete string completely */
+ if(z->prev == NULL)
+ zhash[hash(z->string) % STRING_HASH_TABLE_SIZE] = z->next;
+ else
+ z->prev->next = z->next;
- if (z->next != NULL)
- z->next->prev = z->prev;
+ if (z->next != NULL)
+ z->next->prev = z->prev;
- free(z->string);
- free(z);
- return;
+ free(z->string);
+ free(z);
}
-ZSTRING *
-find_zstring(s,downcase)
- char *s;
- int downcase;
+String *
+find_string(s,downcase)
+ char *s;
+ int downcase;
{
- char *new_s,*p;
- ZSTRING *z;
-
- if (downcase) {
- new_s = strsave(s);
- p = new_s;
- while (*p) {
- if (isascii(*p) && isupper(*p))
- *p = tolower(*p);
- p++;
+ char *new_s,*p;
+ String *z;
+
+ if (downcase) {
+ new_s = strsave(s);
+ p = new_s;
+ while (*p) {
+ if (isascii(*p) && isupper(*p))
+ *p = tolower(*p);
+ p++;
+ }
+ } else {
+ new_s = s;
}
- } else {
- new_s = s;
- }
- z = zhash[hash(new_s) % ZSTRING_HASH_TABLE_SIZE];
- while (z != (ZSTRING *)NULL) {
- if (strcmp(new_s,z->string) == 0)
- break;
- z = z->next;
- }
+ z = zhash[hash(new_s) % STRING_HASH_TABLE_SIZE];
+ while (z != NULL) {
+ if (strcmp(new_s, z->string) == 0)
+ break;
+ z = z->next;
+ }
- if (downcase)
- free(new_s);
+ if (downcase)
+ free(new_s);
- return(z);
+ return z;
}
int
-comp_zstring(a,b)
- ZSTRING *a, *b;
+comp_string(a,b)
+ String *a, *b;
{
- if (a->hash_val > b->hash_val)
- return(1);
- if (a->hash_val < b->hash_val)
- return(-1);
- return(strcmp(a->string,b->string));
+ if (a->hash_val > b->hash_val)
+ return 1;
+ if (a->hash_val < b->hash_val)
+ return -1;
+ return strcmp(a->string,b->string);
}
void
-print_zstring_table(f)
- FILE *f;
+print_string_table(f)
+ FILE *f;
{
- ZSTRING *p;
- int i;
-
- for(i=0;i<ZSTRING_HASH_TABLE_SIZE;i++) {
- p = zhash[i];
- while (p != (ZSTRING *) NULL) {
- fprintf(f,"[%d] %s\n",p->ref_count,p->string);
- p = p->next;
+ String *p;
+ int i;
+
+ for(i = 0; i < STRING_HASH_TABLE_SIZE; i++) {
+ p = zhash[i];
+ while (p != (String *) NULL) {
+ fprintf(f,"[%d] %s\n",p->ref_count,p->string);
+ p = p->next;
+ }
}
- }
- return;
}
-ZSTRING *
-dup_zstring(z)
- ZSTRING *z;
+String *
+dup_string(z)
+ String *z;
{
- z->ref_count++;
- return(z);
+ z->ref_count++;
+ return z;
}
+
diff --git a/server/zstring.h b/server/zstring.h
index 5d3aaa1..eb3a3da 100644
--- a/server/zstring.h
+++ b/server/zstring.h
@@ -12,33 +12,24 @@
#ifndef __zstring_h
#define __zstring_h __FILE__
-#define ZSTRING_HASH_TABLE_SIZE 1024
+#define STRING_HASH_TABLE_SIZE 1024
#include <stdio.h>
-typedef struct _zstring
+typedef struct _String
{
- char *string; /* the string itself */
- int ref_count; /* for gc */
- unsigned long hash_val; /* hash value for this string */
- struct _zstring *next; /* for linking in hash table */
- struct _zstring *prev; /* for linking in hash table */
-} ZSTRING;
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-ZSTRING *make_zstring P((char *s, int downcase));
-void free_zstring P((ZSTRING *z));
-ZSTRING *find_zstring P((char *s, int downcase));
-ZSTRING *dup_zstring P((ZSTRING *z));
-int comp_zstring P((ZSTRING *a, ZSTRING *b));
-void print_zstring_table P((FILE *f));
-
-#undef P
-
+ char *string; /* the string itself */
+ int ref_count; /* for gc */
+ unsigned long hash_val; /* hash value for this string */
+ struct _String *next, *prev; /* for linking in hash table */
+} String;
+
+String *make_string __P((char *s, int downcase));
+void free_string __P((String *z));
+String *find_string __P((char *s, int downcase));
+String *dup_string __P((String *z));
+int comp_string __P((String *a, String *b));
+void print_string_table __P((FILE *f));
#endif /* __zstring_h */
+