]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blobdiff - zephyr/server/subscr.c
r4262@bucket (orig r252): kcr | 2008-01-20 22:11:00 -0500
[1ts-debian.git] / zephyr / server / subscr.c
index a8ccdd1b0e8371f03da25c63fe4e1a72027b4e01..70aa1a8b54835eab8d81975b5ed4da3ddafe5437 100644 (file)
@@ -3,8 +3,8 @@
  *
  *     Created by:     John T. Kohl
  *
- *     $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/subscr.c,v $
- *     $Author: zacheiss $
+ *     $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/subscr.c,v $
+ *     $Author$
  *
  *     Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
  *     For copying and distribution information, see the file
@@ -16,7 +16,7 @@
 
 #ifndef lint
 #ifndef SABER
-static const char rcsid_subscr_c[] = "$Id: subscr.c,v 1.59 2001/07/03 03:28:31 zacheiss Exp $";
+static const char rcsid_subscr_c[] = "$Id$";
 #endif
 #endif
 
@@ -70,21 +70,35 @@ Sched       serv_ksched;
 
 /* for compatibility when sending subscription information to old clients */
 
-extern char *re_comp(), *re_conv();
-static Code_t add_subscriptions __P((Client *who, Destlist *subs_queue,
-                                  ZNotice_t *notice, Server *server));
-static Destlist *extract_subscriptions __P((ZNotice_t *notice));
-static void free_subscriptions __P((Destlist *subs));
-static void free_subscription __P((Destlist *sub));
-static char **subscr_marshal_subs __P((Destlist *subs, 
-                                      int *found));
-static Destlist *subscr_copy_def_subs __P((char *person));
-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((Client *who, Destlist *subs, 
-                                    Realm *realm));
-static int cl_match  __P((Destlist*, Client *));
+#ifdef OLD_COMPAT
+#define        OLD_ZEPHYR_VERSION      "ZEPH0.0"
+#define        OLD_CLIENT_INCOMPSUBS   "INCOMP"
+static void old_compat_subscr_sendlist(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(ZNotice_t *notice, int auth,
+                                          struct sockaddr_in *who); 
+extern int new_compat_count_subscr;    /* counter of old use */
+#endif /* NEW_COMPAT */
+
+static Code_t add_subscriptions(Client *who, Destlist *subs_queue,
+                               ZNotice_t *notice, Server *server);
+static Destlist *extract_subscriptions(ZNotice_t *notice);
+static void free_subscriptions(Destlist *subs);
+static void free_subscription(Destlist *sub);
+static char **subscr_marshal_subs(ZNotice_t *notice, int auth,
+                                 struct sockaddr_in *who,
+                                 int *found);
+static Destlist *subscr_copy_def_subs(char *person);
+static Code_t subscr_realm_sendit(Client *who, Destlist *subs,
+                                 ZNotice_t *notice, ZRealm *realm);
+static void subscr_unsub_realms(Destlist *newsubs);
+static void subscr_unsub_sendit(Client *who, Destlist *subs, 
+                               ZRealm *realm);
+static int cl_match (Destlist*, Client *);
 
 static int defaults_read = 0;          /* set to 1 if the default subs
                                           are in memory */
@@ -103,10 +117,9 @@ String *empty;
  */
 
 Code_t
-subscr_subscribe(who, notice, server)
-    Client *who;
-    ZNotice_t *notice;
-    Server *server;
+subscr_subscribe(Client *who,
+                ZNotice_t *notice,
+                Server *server)
 {
     Destlist *subs;
 
@@ -115,17 +128,16 @@ subscr_subscribe(who, notice, server)
 }
 
 static Code_t
-add_subscriptions(who, subs, notice, server)
-    Client *who;
-    Destlist *subs;
-    ZNotice_t *notice;
-    Server *server;
+add_subscriptions(Client *who,
+                 Destlist *subs,
+                 ZNotice_t *notice,
+                 Server *server)
 {
     Destlist *next;
     Code_t retval;
     Acl *acl;
     String *sender;
-    Realm *realm = NULL;
+    ZRealm *realm = NULL;
 
     if (!subs)
        return ZERR_NONE;       /* no subscr -> no error */
@@ -142,7 +154,7 @@ add_subscriptions(who, subs, notice, server)
        /* check the recipient for a realm which isn't ours */
        realm = NULL;
        if (subs->dest.recip->string[0] == '@' &&
-           strcmp((subs->dest.recip->string + 1), my_galaxy) != 0)
+           strcmp((subs->dest.recip->string + 1), ZGetRealm()) != 0)
            realm = realm_get_realm_by_name(subs->dest.recip->string + 1);
        if (!bdumping) {
            if (subs->dest.recip != empty && subs->dest.recip != sender
@@ -172,18 +184,14 @@ add_subscriptions(who, subs, notice, server)
            }
        }
        if (realm && !bdumping) {
-           if (server && server == me_server) {
                retval = subscr_realm_sendit(who, subs, notice, realm);
                if (retval != ZERR_NONE) {
-                   free_subscriptions(subs);
-                   free_string(sender);
-                   return(retval);
-               } else {
-                   /* free this one, will get from ADD */
                    free_subscription(subs);
-               }
+                   continue; /* the for loop */
            } else {
                    /* Indicates we leaked traffic back to our realm */
+                   free_subscription(subs); /* free this one, wil get from
+                                               ADD */
            }
        } else {
          retval = triplet_register(who, &subs->dest, NULL);
@@ -211,8 +219,7 @@ add_subscriptions(who, subs, notice, server)
  */
 
 Code_t
-subscr_def_subs(who)
-    Client *who;
+subscr_def_subs(Client *who)
 {
     Destlist *subs;
 
@@ -221,7 +228,7 @@ subscr_def_subs(who)
 }
 
 void
-subscr_reset()
+subscr_reset(void)
 {
 #if 0
     zdbug((LOG_DEBUG, "subscr_reset()"));
@@ -232,8 +239,7 @@ subscr_reset()
 }
 
 static Destlist *
-subscr_copy_def_subs(person)
-    char *person;
+subscr_copy_def_subs(char *person)
 {
     int retval, fd;
     struct stat statbuf;
@@ -314,11 +320,10 @@ subscr_copy_def_subs(person)
  */
 
 Code_t
-subscr_cancel(sin, notice)
-    struct sockaddr_in *sin;
-    ZNotice_t *notice;
+subscr_cancel(struct sockaddr_in *sin,
+             ZNotice_t *notice)
 {
-    Realm *realm;
+    ZRealm *realm;
     Client *who;
     Destlist *cancel_subs, *subs, *cancel_next, *client_subs, *client_next;
     Code_t retval;
@@ -378,10 +383,9 @@ subscr_cancel(sin, notice)
 }
 
 Code_t
-subscr_realm_cancel(sin, notice, realm)
-    struct sockaddr_in *sin;
-    ZNotice_t *notice;
-    Realm *realm;
+subscr_realm_cancel(struct sockaddr_in *sin,
+                   ZNotice_t *notice,
+                   ZRealm *realm)
 {
     Client *who;
     Destlist *cancel_subs, *subs, *client_subs, *next, *next2;
@@ -432,12 +436,11 @@ subscr_realm_cancel(sin, notice, realm)
  */
 
 void
-subscr_cancel_client(client)
-    Client *client;
+subscr_cancel_client(Client *client)
 {
     Destlist *subs, *next;
     Code_t retval;
-    Realm *realm;
+    ZRealm *realm;
 
 #if 0
     zdbug((LOG_DEBUG,"subscr_cancel_client %s",
@@ -470,20 +473,32 @@ subscr_cancel_client(client)
  */
 
 void
-subscr_sendlist(notice, auth, who)
-    ZNotice_t *notice;
-    int auth;
-    struct sockaddr_in *who;
+subscr_sendlist(ZNotice_t *notice,
+               int auth,
+               struct sockaddr_in *who)
 {
-    unsigned short temp;
-    int defsubs = 0;
-    Destlist *subs = NULL;
-    Client *client;
-    char **answer = NULL;
+    char **answer;
     int found;
     struct sockaddr_in send_to_who;
     Code_t retval;
 
+#ifdef OLD_COMPAT
+    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) == 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 */
 
@@ -491,13 +506,54 @@ subscr_sendlist(notice, auth, who)
     if (retval != ZERR_NONE) {
        syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
               error_message(retval));
+       if (answer)
+           free(answer);
        return;
     }
 
-    if (strcmp(notice->z_opcode, CLIENT_GIMMESUBS) == 0) {
-       if (!auth)
-           goto got_answer;
+    /* XXX for now, don't do authentication */
+    auth = 0;
 
+    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, "subscr_sendlist xmit: %s", error_message(retval));
+    if (answer)
+       free(answer);
+}
+
+static char **
+subscr_marshal_subs(ZNotice_t *notice,
+                   int auth,
+                   struct sockaddr_in *who,
+                   int *found)
+{
+    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"));
+#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) == 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
@@ -507,25 +563,11 @@ subscr_sendlist(notice, auth, who)
        if (retval != ZERR_NONE) {
            syslog(LOG_WARNING, "subscr_marshal read port num: %s",
                   error_message(retval));
-           goto got_answer;
+           return(NULL);
        }
 
        client = client_find(&who->sin_addr, htons(temp));
 
-       if (!client)
-           goto got_answer;
-
-       /* check authenticity here.  The user must be authentic to get
-          a list of subscriptions. */
-
-       if (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->principal->string,
-                   inet_ntoa(who->sin_addr), ntohs(who->sin_port)));
-           goto got_answer;
-       }
-
        if (client)
            subs = client->subs;
     } else if (strcmp(notice->z_opcode, CLIENT_GIMMEDEFS) == 0) {
@@ -540,74 +582,237 @@ subscr_sendlist(notice, auth, who)
     } else {
        syslog(LOG_ERR, "subscr_marshal bogus opcode %s",
               notice->z_opcode);
-       goto got_answer;
+       return(NULL);
     }
 
-    answer = subscr_marshal_subs(subs, &found);
+    if (subs) {
 
- got_answer:
-    notice->z_kind = ACKED;
+       /* 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->principal->string,
+                       inet_ntoa(who->sin_addr), ntohs(who->sin_port)));
+               return 0;
+           }
+       }
 
-    /* use xmit_frag() to send each piece of the notice */
+       for (sub = subs; sub; sub = sub->next)
+           (*found)++;
 
-    retval = ZSrvSendRawList(notice, answer, found * NUM_FIELDS, xmit_frag);
-    if (retval != ZERR_NONE)
-       syslog(LOG_WARNING, "subscr_sendlist xmit: %s", error_message(retval));
+       /* 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(subs);
-    if (answer)
-       free(answer);
+    return answer;
 }
 
-static char **
-subscr_marshal_subs(subs, found)
-    Destlist *subs;
-    int *found;
+#ifdef NEW_COMPAT
+static void
+new_old_compat_subscr_sendlist(notice, auth, who)
+    ZNotice_t *notice;
+    int auth;
+    struct sockaddr_in *who;
 {
-    char **answer = NULL;
     Code_t retval;
-    Destlist *sub;
+    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);
+
+    /* 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, "subscr_marshal"));
+    zdbug((LOG_DEBUG,"Found %d subscriptions for %d packets", found, count));
 #endif
-    *found = 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"));
+#endif
+    if (answer)
+       free(answer);
+}
+#endif /* NEW_COMPAT */
 
-    /* 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. */
+#ifdef OLD_COMPAT
+static void
+old_compat_subscr_sendlist(notice, auth, who)
+    ZNotice_t *notice;
+    int auth;
+    struct sockaddr_in *who;
+{
+    Client *client = client_find(&who->sin_addr, notice->z_port);
+    Destlist *subs;
+    Code_t retval;
+    ZNotice_t reply;
+    ZPacket_t reppacket;
+    int packlen, i, found = 0;
+    char **answer = NULL;
 
-    /* Make our own copy so we can send directly back to the client */
-    /* RSF 11/07/87 */
+    old_compat_count_subscr++;
 
-    if (!subs)
-       return(NULL);
+    syslog(LOG_INFO, "old old subscr, %s", inet_ntoa(who->sin_addr));
+    if (client && client->subs) {
 
-    for (sub = subs; sub; sub = sub->next)
-       (*found)++;
+       /* 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 */
 
-    /* found is now the number of subscriptions */
+       if (!auth) {
+           clt_ack(notice, who, AUTH_FAILED);
+           return;
+       }
 
-    /* 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++;
+       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++;
+           }
        }
     }
 
-    return answer;
+    /* 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)
+           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 */
 
 /*
  * Send the client's subscriptions to another server
@@ -618,15 +823,19 @@ subscr_marshal_subs(subs, found)
 
 /*ARGSUSED*/
 Code_t
-subscr_send_subs(client)
-    Client *client;
+subscr_send_subs(Client *client)
 {
     int i = 0;
     Destlist *subs;
+#ifdef HAVE_KRB5
+    char buf[512];
+    char *bufp;
+#else
 #ifdef HAVE_KRB4
     char buf[512];
     C_Block cblock;
 #endif /* HAVE_KRB4 */
+#endif
     char buf2[512];
     char *list[7 * NUM_FIELDS];
     int num = 0;
@@ -639,14 +848,45 @@ subscr_send_subs(client)
 
     list[num++] = buf2;
 
+#ifdef HAVE_KRB5
+#ifdef HAVE_KRB4 /* XXX make this optional for server transition time */
+    if (Z_enctype(client->session_keyblock) == ENCTYPE_DES_CBC_CRC) {
+       bufp = malloc(Z_keylen(client->session_keyblock));
+       if (bufp == NULL) {
+           syslog(LOG_WARNING, "subscr_send_subs: cannot allocate memory for DES keyblock: %m");
+           return errno;
+       }
+       des_ecb_encrypt(Z_keydata(client->session_keyblock), bufp, serv_ksched.s, DES_ENCRYPT);
+       retval = ZMakeAscii(buf, sizeof(buf), bufp, Z_keylen(client->session_keyblock));
+    } else {
+#endif
+       bufp = malloc(Z_keylen(client->session_keyblock) + 8); /* + enctype
+                                                               + length */
+       if (bufp == NULL) {
+           syslog(LOG_WARNING, "subscr_send_subs: cannot allocate memory for keyblock: %m");
+           return errno;
+       }
+       *(krb5_enctype *)&bufp[0] = htonl(Z_enctype(client->session_keyblock));
+       *(u_int32_t *)&bufp[4] = htonl(Z_keylen(client->session_keyblock));
+       memcpy(&bufp[8], Z_keydata(client->session_keyblock), Z_keylen(client->session_keyblock));
+
+       retval = ZMakeZcode(buf, sizeof(buf), bufp, Z_keylen(client->session_keyblock) + 8);
+#ifdef HAVE_KRB4
+    }
+#endif /* HAVE_KRB4 */
+#else /* HAVE_KRB5 */
 #ifdef HAVE_KRB4
 #ifdef NOENCRYPTION
     memcpy(cblock, client->session_key, sizeof(C_Block));
-#else
+#else /* NOENCRYPTION */
     des_ecb_encrypt(client->session_key, cblock, serv_ksched.s, DES_ENCRYPT);
-#endif
+#endif /* NOENCRYPTION */
 
     retval = ZMakeAscii(buf, sizeof(buf), cblock, sizeof(C_Block));
+#endif /* HAVE_KRB4 */
+#endif /* HAVE_KRB5 */    
+
+#if defined(HAVE_KRB4) || defined(HAVE_KRB5)
     if (retval != ZERR_NONE) {
 #if 0
        zdbug((LOG_DEBUG,"zmakeascii failed: %s", error_message(retval)));
@@ -657,7 +897,7 @@ subscr_send_subs(client)
        zdbug((LOG_DEBUG, "cblock %s", buf));
 #endif
     }          
-#endif /* HAVE_KRB4 */
+#endif /* HAVE_KRB4 || HAVE_KRB5*/
     retval = bdump_send_list_tcp(SERVACK, &client->addr, ZEPHYR_ADMIN_CLASS,
                                 num > 1 ? "CBLOCK" : "", ADMIN_NEWCLT,
                                 client->principal->string, "", list, num);
@@ -721,8 +961,7 @@ free_subscription(Destlist *sub)
 }
 
 static void
-free_subscriptions(subs)
-    Destlist *subs;
+free_subscriptions(Destlist *subs)
 {
     Destlist *next;
 
@@ -745,8 +984,7 @@ free_subscriptions(subs)
  */
 
 static Destlist *
-extract_subscriptions(notice)
-    ZNotice_t *notice;
+extract_subscriptions(ZNotice_t *notice)
 {
     Destlist *subs = NULL, *sub;
     char *recip, *class_name, *classinst;
@@ -778,7 +1016,7 @@ extract_subscriptions(notice)
        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, my_galaxy))
+       if (recip[0] == '@' && !strcmp(recip + 1, ZGetRealm()))
            sub->dest.recip = make_string("", 0);
        else
            sub->dest.recip = make_string(recip, 0);
@@ -794,9 +1032,8 @@ extract_subscriptions(notice)
  */
 
 void
-subscr_dump_subs(fp, subs)
-    FILE *fp;
-    Destlist *subs;
+subscr_dump_subs(FILE *fp,
+                Destlist *subs)
 {
     char *p;
 
@@ -824,11 +1061,10 @@ subscr_dump_subs(fp, subs)
 /* 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;
+subscr_realm_sendit(Client *who,
+                   Destlist *subs,
+                   ZNotice_t *notice,
+                   ZRealm *realm)
 {
   ZNotice_t snotice;
   char *pack;
@@ -911,10 +1147,9 @@ subscr_realm_sendit(who, subs, notice, realm)
 
 /* Called from subscr_realm and subscr_foreign_user */
 static Code_t
-subscr_add_raw(client, realm, newsubs)
-    Client *client;
-    Realm *realm;
-    Destlist *newsubs;
+subscr_add_raw(Client *client,
+              ZRealm *realm,
+              Destlist *newsubs)
 {
   Destlist *subs, *subs2, *subs3, **head;
   Code_t retval;
@@ -943,7 +1178,7 @@ subscr_add_raw(client, realm, newsubs)
        }
     } else {
       if (!realm) {
-       Realm *remrealm = 
+       ZRealm *remrealm = 
          realm_get_realm_by_name(subs->dest.recip->string + 1);
        if (remrealm) {
          Destlist *sub = (Destlist *) malloc(sizeof(Destlist));
@@ -970,9 +1205,8 @@ subscr_add_raw(client, realm, newsubs)
 
 /* Called from bdump_recv_loop to decapsulate realm subs */
 Code_t
-subscr_realm(realm, notice)
-    Realm *realm;
-    ZNotice_t *notice;
+subscr_realm(ZRealm *realm,
+            ZNotice_t *notice)
 {
         Destlist  *newsubs;
 
@@ -988,10 +1222,9 @@ subscr_realm(realm, notice)
 
 /* Like realm_sendit, this only takes one item from subs */
 static void
-subscr_unsub_sendit(who, subs, realm)
-    Client *who;
-    Destlist *subs;
-    Realm *realm;
+subscr_unsub_sendit(Client *who,
+                   Destlist *subs,
+                   ZRealm *realm)
 {
   ZNotice_t unotice;
   Code_t retval;
@@ -1024,7 +1257,6 @@ subscr_unsub_sendit(who, subs, realm)
   list[1] = subs->dest.inst->string;
   list[2] = "";
 
-  (void) memset((char *)&unotice, 0, sizeof(unotice));
   unotice.z_class = ZEPHYR_CTL_CLASS;
   unotice.z_class_inst = ZEPHYR_CTL_REALM;
   unotice.z_opcode = REALM_UNSUBSCRIBE;
@@ -1056,8 +1288,7 @@ subscr_unsub_sendit(who, subs, realm)
 
 /* Called from bump_send_loop by way of realm_send_realms */
 Code_t
-subscr_send_realm_subs(realm)
-    Realm *realm;
+subscr_send_realm_subs(ZRealm *realm)
 {
   int i = 0;
   Destlist *subs, *next;
@@ -1123,8 +1354,7 @@ subscr_send_realm_subs(realm)
 }
 
 Code_t
-subscr_realm_subs(realm)
-    Realm *realm;
+subscr_realm_subs(ZRealm *realm)
 {
   int i = 0;
   Destlist *subs, *next;
@@ -1168,7 +1398,6 @@ subscr_realm_subs(realm)
     text[4] = subs->dest.recip->string;
 
     /* format snotice */
-    (void) memset((char *)&snotice, 0, sizeof(snotice));
     snotice.z_class_inst = ZEPHYR_CTL_REALM;
     snotice.z_opcode = REALM_REQ_SUBSCRIBE;
     snotice.z_port = 0;
@@ -1210,14 +1439,13 @@ subscr_realm_subs(realm)
 
 /* Called from subscr_foreign_user for REALM_REQ_SUBSCRIBE */
 static Code_t
-subscr_check_foreign_subs(notice, who, server, realm, newsubs)
-    ZNotice_t *notice;
-    struct sockaddr_in *who;
-    Server *server;
-    Realm *realm;
-    Destlist *newsubs;
+subscr_check_foreign_subs(ZNotice_t *notice,
+                         struct sockaddr_in *who,
+                         Server *server,
+                         ZRealm *realm,
+                         Destlist *newsubs)
 {
-    Destlist *subs, *subs2;
+    Destlist *subs, *subs2, *next;
     Acl *acl;
     char **text;
     int found = 0;
@@ -1226,7 +1454,6 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs)
     int packlen;
     Code_t retval;
     String *sender;
-    Realm *rlm;
 
     for (subs = newsubs; subs; subs = subs->next)
        found++;
@@ -1253,18 +1480,19 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs)
     I_ADVANCE(3);
 
     found = 0;
-
-    rlm = realm_which_realm(who); 
-
-    for (subs = newsubs; subs; subs = subs->next) {
+    for (subs = newsubs; subs; subs = next) {
+       ZRealm *rlm;
+       next=subs->next;
        if (subs->dest.recip->string[0] != '\0') {
-           syslog(LOG_WARNING, "subscr bad recip %s by %s (%s)", 
-                   subs->dest.recip->string, 
-                   sender->string, rlm->name); 
-           continue;
+         rlm = realm_which_realm(who);
+         syslog(LOG_WARNING, "subscr bad recip %s by %s (%s)",
+                subs->dest.recip->string,
+                sender->string, rlm->name);
+         continue;
        }
        acl = class_get_acl(subs->dest.classname);
        if (acl) {
+           rlm = realm_which_realm(who); 
            if (rlm && server == me_server) { 
                if (!realm_sender_in_realm(rlm->name, sender->string)) { 
                    syslog(LOG_WARNING, "subscr auth not verifiable %s (%s) class %s",
@@ -1345,11 +1573,10 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs)
 }
 
 /* Called from realm_control_dispatch for REALM_REQ/ADD_SUBSCRIBE */
-Code_t subscr_foreign_user(notice, who, server, realm)
-    ZNotice_t *notice;
-    struct sockaddr_in *who;
-    Server *server;
-    Realm *realm;
+Code_t subscr_foreign_user(ZNotice_t *notice,
+                          struct sockaddr_in *who,
+                          Server *server,
+                          ZRealm *realm)
 {
   Destlist *newsubs, *temp;
   Acl *acl;
@@ -1423,7 +1650,7 @@ Code_t subscr_foreign_user(notice, who, server, realm)
         temp->dest.recip = make_string(rlm_recipient, 0);
     }
     
-    status = subscr_add_raw(client, (Realm *)0, newsubs);
+    status = subscr_add_raw(client, (ZRealm *)0, newsubs);
   } else if (!strcmp(snotice.z_opcode, REALM_REQ_SUBSCRIBE)) {
     zdbug((LOG_DEBUG, "subscr_foreign_user REQ %s/%s", tp0, tp1));
     status = subscr_check_foreign_subs(notice, who, server, realm, newsubs);