Index: include/s_newconf.h
===================================================================
--- include/s_newconf.h	(revision 20598)
+++ include/s_newconf.h	(working copy)
@@ -94,6 +94,7 @@
 #define SHARED_TRESV	0x0800
 #define SHARED_PRESV	0x0100
 #define SHARED_UNRESV	0x0200
+#define SHARED_REHASH	0x0400
 
 #define SHARED_ALL	(SHARED_TKLINE | SHARED_PKLINE | SHARED_UNKLINE |\
 			SHARED_PXLINE | SHARED_TXLINE | SHARED_UNXLINE |\
Index: src/newconf.c
===================================================================
--- src/newconf.c	(revision 20598)
+++ src/newconf.c	(working copy)
@@ -385,6 +385,7 @@
 	{ "tresv",	SHARED_TRESV	},
 	{ "unresv",	SHARED_UNRESV	},
 	{ "locops",	SHARED_LOCOPS	},
+	{ "rehash",	SHARED_REHASH	},
 	{ "all",	SHARED_ALL	},
 	{ "none",	0		},
 	{NULL, 0}
Index: help/opers/rehash
===================================================================
--- help/opers/rehash	(revision 20598)
+++ help/opers/rehash	(working copy)
@@ -4,12 +4,23 @@
 ircd.conf file.
 
 [option] can be one of the following:
+  BANS     - Re-reads kline.conf, dline.conf, resv.conf and xline.conf
   DNS      - Re-read the /etc/resolv.conf file
+  GLINES   - Clears G Lines
   MOTD     - Re-reads MOTD file
   OMOTD    - Re-reads Oper MOTD file
-  CHANNELS - Forces a channel cleanup
+  PGLINES  - Clears pending G Lines
+  REJECTCACHE - Clears the reject cache
   TDLINES  - Clears temporary D Lines
   TKLINES  - Clears temporary K Lines
-  PGLINES  - Clears pending G Lines
+  TRESVS   - Clears temporary nick and channel resvs
+  TXLINES  - Clears temporary X Lines
 
 - Requires Oper Priv: H
+
+REHASH [option] irc.server
+
+Rehashes [option], or the config file if none given, on irc.server if
+irc.server accepts remote rehashes.
+
+- Requires Oper Priv: HB
Index: doc/example.conf
===================================================================
--- doc/example.conf	(revision 20598)
+++ doc/example.conf	(working copy)
@@ -473,6 +473,7 @@
 	 *    unresv  - allow removing xlines
 	 *    all     - allow oper/server to do all of above.
 	 *    locops  - allow locops - only used for servers who cluster
+	 *    rehash  - allow rehashing
 	 *    none    - disallow everything
 	 */
 
Index: doc/example.efnet.conf
===================================================================
--- doc/example.efnet.conf	(revision 20598)
+++ doc/example.efnet.conf	(working copy)
@@ -480,6 +480,7 @@
 	 *    unresv  - allow removing xlines
 	 *    locops  - allow locops - only used for servers who cluster
 	 *    all     - allow oper/server to do all of above.
+	 *    rehash  - allow rehashing
 	 *    none    - disallow everything
 	 */
 
Index: modules/m_rehash.c
===================================================================
--- modules/m_rehash.c	(revision 20598)
+++ modules/m_rehash.c	(working copy)
@@ -31,6 +31,7 @@
 #include "irc_string.h"
 #include "ircd.h"
 #include "s_gline.h"
+#include "s_serv.h"
 #include "numeric.h"
 #include "res.h"
 #include "s_conf.h"
@@ -46,10 +47,11 @@
 #include "cache.h"
 
 static int mo_rehash(struct Client *, struct Client *, int, const char **);
+static int me_rehash(struct Client *, struct Client *, int, const char **);
 
 struct Message rehash_msgtab = {
 	"REHASH", 0, 0, 0, MFLG_SLOW,
-	{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_rehash, 0}}
+	{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_rehash, 0}, {mo_rehash, 0}}
 };
 
 mapi_clist_av1 rehash_clist[] = { &rehash_msgtab, NULL };
@@ -280,36 +282,25 @@
 };
 /* *INDENT-ON* */
 
-/*
- * mo_rehash - REHASH message handler
- *
- */
-static int
-mo_rehash(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+static void
+do_rehash(struct Client *source_p, const char *type)
 {
-	if(!IsOperRehash(source_p))
+	if (type != NULL)
 	{
-		sendto_one(source_p, form_str(ERR_NOPRIVS),
-			   me.name, source_p->name, "rehash");
-		return 0;
-	}
-
-	if(parc > 1)
-	{
 		int x;
 		char cmdbuf[100];
 
 		for (x = 0; rehash_commands[x].cmd != NULL && rehash_commands[x].handler != NULL;
 		     x++)
 		{
-			if(irccmp(parv[1], rehash_commands[x].cmd) == 0)
+			if(irccmp(type, rehash_commands[x].cmd) == 0)
 			{
 				sendto_one(source_p, form_str(RPL_REHASHING), me.name,
 					   source_p->name, rehash_commands[x].cmd);
 				rehash_commands[x].handler(source_p);
-				ilog(L_MAIN, "REHASH %s From %s[%s]", parv[1],
+				ilog(L_MAIN, "REHASH %s From %s[%s]", type,
 				     get_oper_name(source_p), source_p->sockhost);
-				return 0;
+				return;
 			}
 		}
 
@@ -333,8 +324,69 @@
 		ilog(L_MAIN, "REHASH From %s[%s]", get_oper_name(source_p),
 		     source_p->sockhost);
 		rehash(0);
+	}
+}
+
+/*
+ * mo_rehash - REHASH message handler
+ *
+ * parv[1] = rehash type or destination
+ * parv[2] = destination
+ */
+static int
+mo_rehash(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+	const char *type = NULL, *target_server = NULL;
+
+	if(!IsOperRehash(source_p))
+	{
+		sendto_one(source_p, form_str(ERR_NOPRIVS),
+			   me.name, source_p->name, "rehash");
 		return 0;
 	}
 
+	if (parc > 2)
+		type = parv[1], target_server = parv[2];
+	else if (parc > 1 && (strchr(parv[1], '.') || strchr(parv[1], '?') || strchr(parv[1], '*')))
+		type = NULL, target_server = parv[1];
+	else if (parc > 1)
+		type = parv[1], target_server = NULL;
+	else
+		type = NULL, target_server = NULL;
+
+	if (target_server != NULL)
+	{
+		if(!IsOperRemoteBan(source_p))
+		{
+			sendto_one(source_p, form_str(ERR_NOPRIVS),
+				me.name, source_p->name, "remoteban");
+			return 0;
+		}
+		sendto_match_servs(source_p, target_server,
+				CAP_ENCAP, NOCAPS,
+				"ENCAP %s REHASH %s",
+				target_server, type != NULL ? type : "");
+		if (match(target_server, me.name) == 0)
+			return 0;
+	}
+
+	do_rehash(source_p, type);
+
 	return 0;
 }
+
+static int
+me_rehash(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+
+	if (!IsPerson(source_p))
+		return 0;
+
+	if (!find_shared_conf(source_p->username, source_p->host,
+				source_p->user->server, SHARED_REHASH))
+		return 0;
+
+	do_rehash(source_p, parc > 1 ? parv[1] : NULL);
+
+	return 0;
+}
