diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/client.h ircd-hybrid-6.0/include/client.h
--- ircd-hybrid-6.0.orig/include/client.h	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/include/client.h	Mon Jun 18 22:48:35 2001
@@ -450,7 +450,7 @@
  *   -- asuffield
  */
 
-extern umode_t send_umodes;
+/*extern umode_t send_umodes;*/
 extern umode_t user_umodes;
 extern umode_t all_umodes;
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/config.h ircd-hybrid-6.0/include/config.h
--- ircd-hybrid-6.0.orig/include/config.h	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/include/config.h	Mon Jun 18 22:48:35 2001
@@ -57,8 +57,8 @@
  */
 
 #define CHALLENGERESPONSE
-#undef CHALLENGERESPONSE_FALLBACK
-#define CHALLENGERESPONSE_EXPIRY 15
+#define CHALLENGERESPONSE_FALLBACK
+#undef CHALLENGERESPONSE_EXPIRY
 
 
 
@@ -616,7 +616,7 @@
  * need not be the same for both, as long as the opposite end has the
  * right password in the opposite line.
  */
-#undef  CRYPT_LINK_PASSWORD
+#define  CRYPT_LINK_PASSWORD
 
 /* CRYPT_I_PASSWORD - use crypted I-line passwords in the ircd.conf
  * define this if you want to use crypted passwords for connecting users
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/s_serv.h ircd-hybrid-6.0/include/s_serv.h
--- ircd-hybrid-6.0.orig/include/s_serv.h	Mon Jun 18 22:54:36 2001
+++ ircd-hybrid-6.0/include/s_serv.h	Mon Jun 18 22:48:35 2001
@@ -47,6 +47,10 @@
 #define CAP_DE          0x00000020      /* Can do channel +d (regex deny) */
 #define CAP_IE          0x00000040      /* can do +I */
 #define CAP_QU          0x00000080      /* can do +q (quiet) */
+#define CAP_RW          0x00000100      /* can handle WHOIS messages from remote users. 
+					   This is used in m_whois to prevent services
+					   from being queried remotely, which it can't
+					   do anything with */
 #define CAP_OPN         0x10000000      /* Can do sethost, setident, setname,
                                            allows opers to hack modes, accepts
                                            glines without vote, has nicklen 30
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/client.c ircd-hybrid-6.0/src/client.c
--- ircd-hybrid-6.0.orig/src/client.c	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/src/client.c	Mon Jun 18 22:48:35 2001
@@ -57,7 +57,7 @@
 
 struct  bitfield_lookup_t bitfield_lookup[BITFIELD_SIZE];
 umode_t user_umodes;
-umode_t send_umodes;
+/*umode_t send_umodes;*/
 umode_t all_umodes;
 
 /* 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/ircd.c ircd-hybrid-6.0/src/ircd.c
--- ircd-hybrid-6.0.orig/src/ircd.c	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/src/ircd.c	Mon Jun 18 22:52:28 2001
@@ -532,13 +532,7 @@
     nextping = check_pings(CurrentTime);
     timeout_auth_queries(CurrentTime);
   }
-#ifdef CHALLENGERESPONSE
-#ifdef CHALLENGERESPONSE_FALLBACK
-  if (cr_challengeexpirytime && (CurrentTime >= cr_challengeexpirytime)) {
-    cr_checkfallback();
-  }
-#endif
-#endif
+
   if (dorehash && !LIFESUX)
     {
       rehash(&me, &me, 1);
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_oper.c ircd-hybrid-6.0/src/m_oper.c
--- ircd-hybrid-6.0.orig/src/m_oper.c	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/src/m_oper.c	Mon Jun 18 22:48:35 2001
@@ -227,12 +227,12 @@
       else
 	fdlist_add(sptr->fd, FDL_OPER);
 #ifdef CUSTOM_ERR
-      sendto_ops("%s (%s@%s) just activated an %c-line, hmmm.", parv[0],
+      sendto_ops_flag_butone(NULL, UMODE_SERVNOTICE, "%s (%s@%s) just activated an %c-line, hmmm.", parv[0],
 #else
-      sendto_ops("%s (%s@%s) is now operator (%c)", parv[0],
+      sendto_ops_flag_butone(NULL, UMODE_SERVNOTICE, ("%s (%s@%s) is now operator (%c)", parv[0],
 #endif /* CUSTOM_ERR */
-                 sptr->username, sptr->host,
-                 IsLocOp(sptr) ? 'o' : 'O');
+						      sptr->username, sptr->host,
+						      IsLocOp(sptr) ? 'o' : 'O');
       send_umode_out(cptr, sptr, old);
       sendto_one(sptr, form_str(RPL_YOUREOPER), me.name, parv[0]);
       {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_whois.c ircd-hybrid-6.0/src/m_whois.c
--- ircd-hybrid-6.0.orig/src/m_whois.c	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/src/m_whois.c	Mon Jun 18 22:48:35 2001
@@ -224,6 +224,17 @@
           member = (user->channel) ? 1 : 0;
 
           a2cptr = find_server(user->server);
+
+	  /* Now, a minor bypass. If the WHOIS request has no masks, then it may be forwarded
+	   * to a remote server, instead of being handled locally. This allows idle times and
+	   * oper privs to be displayed correctly.
+	   *  -- asuffield
+	   */
+	  if (!MyClient(acptr) && IsCapable(a2cptr,CAP_RW) && acptr->name)
+	    {
+	      sendto_one(a2cptr, ":%s WHOIS %s", sptr->name, acptr->name);
+	      return 0;
+	    }
           
           sendto_one(sptr, form_str(RPL_WHOISUSER), me.name,
                      parv[0], name,
@@ -300,7 +311,7 @@
 	      else
 		sendto_one(sptr, form_str(RPL_WHOISOPER_NOTGOD),
 			   me.name, parv[0], name);
-	      if (SeesOperPrivs(sptr))
+	      if (SeesOperPrivs(sptr) || acptr == sptr)
 		sendto_one(sptr, form_str(RPL_WHOISOPER_PRIVS),
 			   me.name, parv[0], name, oper_flags_as_string(acptr->allowed_umodes));
 	    }
@@ -321,7 +332,7 @@
 
           if ((acptr->user
 #ifdef SERVERHIDE
-              && IsSetOperAuspex(sptr)
+	       /*              && IsSetOperAuspex(sptr)*/
 #endif
               && MyConnect(acptr)))
             sendto_one(sptr, form_str(RPL_WHOISIDLE),
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/s_cr.c ircd-hybrid-6.0/src/s_cr.c
--- ircd-hybrid-6.0.orig/src/s_cr.c	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/src/s_cr.c	Mon Jun 18 22:53:25 2001
@@ -13,48 +13,6 @@
 #include <time.h>
 
 #ifdef CHALLENGERESPONSE
-#ifdef CHALLENGERESPONSE_FALLBACK
-extern time_t cr_challengeexpirytime;
-void cr_checkfallback() {
-  /* The cr_challengeexpirytime was reached. So, let's look through
-     or list for servers we are connecting to which we haven't got
-     a password for (aka no RESP received), and the connect happened 
-     more than CHALLENGERESPONSE_EXPIRY seconds ago. If we find one,
-     we revert to PASS. By lagging servers it'd be possible to provoke
-     a fallback to PASS, so this could be exploited.
-     - einride.
-  */  
-  time_t nextexpiry = 0;
-  struct Client * cptr;
-  struct ConfItem *c_conf, *n_conf;
-  for (cptr=GlobalClientList; cptr; cptr = cptr->next_local_client) {
-    if (Challenged(cptr) && !Responded(cptr)) {
-      if (cptr->firsttime < (CurrentTime - CHALLENGERESPONSE_EXPIRY)) {
-	/* Revert to PASS */
-	log(L_NOTICE, "CR expiry time reached for %s - fallback", cptr->name ? cptr->name : "<unknown>");
-	c_conf = find_conf_by_name(cptr->name, CONF_CONNECT_SERVER);
-	n_conf = find_conf_by_name(cptr->name, CONF_NOCONNECT_SERVER);
-	if (c_conf && n_conf) {
-	  sendto_ops("Trying PASS to authenticate with %s", cptr->name);
-	  if (!EmptyString(c_conf->passwd))
-	    sendto_one(cptr, "PASS %s :TS", c_conf->passwd);
-	  send_capabilities(cptr, (c_conf->flags & CONF_FLAGS_ZIP_LINK));
-	  sendto_one(cptr, "SERVER %s 1 :%s",
-		     my_name_for_link(me.name, n_conf), me.info);
-	} else {
-	  sendto_ops("Can't find C/N lines on CR expiry - dropping %s", cptr->name);
-	  log(L_NOTICE, "Can't find C/N lines on CR expiry - dropping %s", cptr->name);
-	  exit_client(cptr, cptr, cptr, "No C/N lines");
-	}
-      } else {
-	if (!nextexpiry || nextexpiry > (cptr->firsttime + CHALLENGERESPONSE_EXPIRY))
-	  nextexpiry = (cptr->firsttime + CHALLENGERESPONSE_EXPIRY);
-      }
-    }
-  }
-  cr_challengeexpirytime=nextexpiry;
-}
-#endif
 
 void cr_sendchallenge(struct Client * cptr, struct ConfItem * n_conf) {
   /* Create a challenge using random data and sending it as a hex value.
@@ -77,10 +35,6 @@
   strcpy(cptr->passwd, chall);
   SetChallenged(cptr);
   sendto_ops("Sent password challenge to %s", cptr->name);
-#ifdef CHALLENGERESPONSE_FALLBACK
-  if (!cr_challengeexpirytime)
-    cr_challengeexpirytime = CurrentTime + CHALLENGERESPONSE_EXPIRY;
-#endif
 }
 
 void cr_hashstring(char * src, char * trg) {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/s_serv.c ircd-hybrid-6.0/src/s_serv.c
--- ircd-hybrid-6.0.orig/src/s_serv.c	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/src/s_serv.c	Mon Jun 18 22:48:35 2001
@@ -79,6 +79,7 @@
 #ifdef QUIET_MODE
   { "QU",       CAP_QU },
 #endif
+  { "RW",       CAP_RW }, /* Remote WHOIS, because services can't do it */
   { 0,   0 }
 };
 
@@ -474,7 +475,7 @@
 
   if (IsPerson(acptr))
     {
-      send_umode(NULL, acptr, 0, send_umodes, ubuf);
+      send_umode(NULL, acptr, 0, all_umodes, ubuf);
       if (!*ubuf)
         { /* trivial optimization - Dianora */
           
@@ -562,13 +563,29 @@
     }
 
 #ifdef CHALLENGERESPONSE
-# ifndef CHALLENGERESPONSE_FALLBACK
   if (!Responded(cptr)) {
+# ifndef CHALLENGERESPONSE_FALLBACK
     sendto_realops("Access denied (plaintext password) %s", inpath);
     return exit_client(cptr, cptr, cptr, "Non CR server");
-  }
+# else
+#  ifdef CRYPT_LINK_PASSWORD
+    /* use first two chars of the password they send in as salt */
+
+    /* passwd may be NULL. Head it off at the pass... */
+    if(*cptr->passwd && *n_conf->passwd)
+      {
+	extern char * libshadow_md5_crypt(const char *pw, const char *salt);
+	encr = libshadow_md5_crypt(cptr->passwd, n_conf->passwd);
+      }
+    else
+      encr = "";
+#  else
+    encr = cptr->passwd;
+#  endif  /* CRYPT_LINK_PASSWORD */
 # endif
-  encr = cptr->passwd;
+  }
+  else
+    encr = cptr->passwd;
 #else
 # ifdef CRYPT_LINK_PASSWORD
   /* use first two chars of the password they send in as salt */
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/s_user.c ircd-hybrid-6.0/src/s_user.c
--- ircd-hybrid-6.0.orig/src/s_user.c	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/src/s_user.c	Mon Jun 18 22:48:35 2001
@@ -859,7 +859,7 @@
         }
     }
 
-  send_umode(NULL, sptr, 0, send_umodes, ubuf);
+  send_umode(NULL, sptr, 0, all_umodes, ubuf);
   if (!*ubuf)
     {
       ubuf[0] = '+';
@@ -1147,7 +1147,7 @@
                 {
                   Count.oper++;
                 }
-	      if (TestBit(send_umodes, flag))
+	      /*	      if (TestBit(send_umodes, flag))*/
 		SetBit(sptr->umodes, flag);
               m++;
             }
@@ -2134,7 +2134,8 @@
 		/* I'm going to disable this for now, we do things differently
 		 *  --asuffield
 		 */
-		break;
+		if (!IsServer(sptr))
+		  break;
 
 		if((IsServer(cptr) || ircophack) && !IsOper(acptr))
 		  {
@@ -2349,7 +2350,7 @@
   aClient *acptr;
   char buf[BUFSIZE];
 
-  send_umode(NULL, sptr, old, send_umodes, buf);
+  send_umode(NULL, sptr, old, all_umodes, buf);
 
   for(acptr = serv_cptr_list; acptr; acptr = acptr->next_server_client)
     {
@@ -2493,7 +2494,7 @@
     }
 
   /* Here we fill in send_umodes and user_umodes */
-  ClearBitfield(send_umodes);
+  /*  ClearBitfield(send_umodes);*/
   ClearBitfield(user_umodes);
   ClearBitfield(all_umodes);
   NotUmodes(all_umodes, all_umodes);
@@ -2502,14 +2503,20 @@
  * checked at the source, so don't need to be propogated
  *  -- asuffield
  */
-  SetBit(send_umodes, UMODE_INVISIBLE);
+/* I changed my mind; to have UMODE_GRANT and oper WHOIS sane, we need to
+ * propogate the lot. Ah well. Network load is minimal while number of opers
+ * isn't huge. server-server mode command should carry an unlimited number of
+ * umodes to cut down on bandwidth usage.
+ *  -- asuffield
+ */
+/*  SetBit(send_umodes, UMODE_INVISIBLE);
   SetBit(send_umodes, UMODE_OPER);
   SetBit(send_umodes, UMODE_WALLOP);
   SetBit(send_umodes, UMODE_IMMUNE);
   SetBit(send_umodes, UMODE_IDENTIFIED);
   SetBit(send_umodes, UMODE_NINVITE);
   SetBit(send_umodes, UMODE_BLOCK_NOTID);
-  SetBit(send_umodes, UMODE_NCTCP);
+  SetBit(send_umodes, UMODE_NCTCP);*/
 
 /*
  * Only opers can have modes outside USER_UMODES.  If you change this
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/send.c ircd-hybrid-6.0/src/send.c
--- ircd-hybrid-6.0.orig/src/send.c	Mon Jun 18 22:54:37 2001
+++ ircd-hybrid-6.0/src/send.c	Mon Jun 18 22:48:35 2001
@@ -1542,7 +1542,7 @@
 
   va_start(args, pattern);
 
-  for(cptr = local_cptr_list; cptr; cptr = cptr->next)
+  for(cptr = local_cptr_list; cptr; cptr = cptr->next_local_client)
     {
       if (IsPerson(cptr) && TestBit(cptr->umodes,flag))
 	{
