--- src/include/radiusd.h.orig	2007-02-09 19:27:57.000000000 +0900
+++ src/include/radiusd.h	2007-06-29 14:36:06.465092000 +0900
@@ -35,6 +35,10 @@
 #include <arpa/inet.h>
 #endif
 
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
 #include "missing.h"
 
 #define NO_SUCH_CHILD_PID (child_pid_t) (0)
@@ -139,6 +143,10 @@
 	int			acct_active;
 	time_t			acct_wakeup;
 	int			ldflag;
+#ifdef HAVE_REGEX_H
+	regex_t			*regex;
+#endif
+
 	struct _realm		*next;
 } REALM;
 
@@ -327,6 +335,7 @@
 void		clients_free(RADCLIENT *cl);
 
 /* files.c */
+int		realm_find_cmp(const REALM *rlm, const char *realm);
 REALM		*realm_find(const char *, int);
 REALM		*realm_findbyaddr(uint32_t ipno, int port);
 void		realm_free(REALM *cl);
--- src/main/files.c.orig	2007-04-08 07:20:30.000000000 +0900
+++ src/main/files.c	2007-06-29 14:36:06.465646000 +0900
@@ -33,6 +33,10 @@
 #	include <netinet/in.h>
 #endif
 
+#ifdef HAVE_REGEX_H
+#	include <regex.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 #include <netdb.h>
@@ -314,6 +318,12 @@
 
 	while(cl) {
 		next = cl->next;
+#ifdef HAVE_REGEX_H
+		if (cl->regex != NULL) {
+			regfree(cl->regex);
+			free(cl->regex);
+		}
+#endif
 		free(cl);
 		cl = next;
 	}
@@ -439,6 +449,14 @@
 		c->active = TRUE;
 		c->acct_active = TRUE;
 
+		/*
+		 * Regular expressions for realms are not supported 
+		 * with the old-style realm file
+		 */
+#ifdef HAVE_REGEX_H
+		c->regex = NULL;
+#endif
+
 		while (getword(&p, opts, sizeof(opts))) {
 			if (strcmp(opts, "nostrip") == 0)
 				c->striprealm = FALSE;
@@ -508,6 +526,21 @@
 }
 
 /*
+ *      Compare a realm name with entry
+ *      If enabled also compare with regex
+ */
+int realm_find_cmp(const REALM *rlm, const char *realm) {
+#ifdef HAVE_REGEX_H
+       	if ((rlm->regex != NULL) &&
+       	       	(regexec(rlm->regex, realm, 0, NULL, 0) == 0)) {
+       	       	return 0;
+       	}
+#endif /* HAVE_REGEX_H */
+
+        return(strcasecmp(rlm->realm, realm));
+}
+
+/*
  *	Find a realm in the REALM list.
  */
 REALM *realm_find(const char *realm, int accounting)
@@ -552,7 +585,7 @@
 			 *	dead.
 			 */
 			if ((!mainconfig.proxy_fallback) &&
-			    (strcasecmp(cl->realm, realm) == 0)) {
+			    (realm_find_cmp(cl, realm) == 0)) {
 				dead_match = 1;
 			}
 			continue;
@@ -566,7 +599,7 @@
 		 *	scatter techniques, as that's more properly
 		 *	the responsibility of the proxying code.
 		 */
-		if (strcasecmp(cl->realm, realm) == 0) {
+		if (realm_find_cmp(cl, realm) == 0) {
 			return cl;
 		}
 
@@ -589,7 +622,7 @@
 		if (mainconfig.wake_all_if_all_dead) {
 			REALM *rcl = NULL;
 			for (cl = mainconfig.realms; cl; cl = cl->next) {
-				if(strcasecmp(cl->realm,realm) == 0) {
+				if(realm_find_cmp(cl,realm) == 0) {
 					if (!accounting && !cl->active) {
 						cl->active = TRUE;
 						rcl = cl;
--- src/main/mainconfig.c.orig	2007-04-08 07:06:08.000000000 +0900
+++ src/main/mainconfig.c	2007-06-29 14:36:06.466402000 +0900
@@ -35,6 +35,10 @@
 #include <arpa/inet.h>
 #endif
 
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
 #include "radiusd.h"
 #include "rad_assert.h"
 #include "conffile.h"
@@ -500,6 +504,30 @@
 
 		c->striprealm = 1;
 
+#ifdef HAVE_REGEX_H
+		/*
+		 *	If the realm has a regex configured, try to
+		 *	precompile it and store it in the realm struct.
+		 */
+		char *regex = cf_section_value_find(cs, "regex");
+		if (regex != NULL && strcmp(c->realm, "NULL") && strcmp(c->realm, "DEFAULT")) {
+			DEBUG2("read_config_files:  found a regular expression for realm %s, trying to compile it",
+			       c->realm);
+			c->regex = rad_malloc(sizeof(regex_t));
+
+			int res = regcomp(c->regex, regex, REG_NOSUB|REG_ICASE);
+			if (res != 0) {
+				char msg[128];
+
+				regerror(res, c->regex, msg, sizeof(msg));
+				radlog(L_ERR, "%s[%d]: Found illegal regular expression %s, disabling regex support for realm %s.",
+				       filename, cf_section_lineno(cs), msg, c->realm);
+
+				return -1;
+			}
+		}
+#endif
+
 		if ((cf_section_value_find(cs, "nostrip")) != NULL)
 			c->striprealm = 0;
 		if ((cf_section_value_find(cs, "noacct")) != NULL)
--- src/main/proxy.c.orig	2005-12-08 22:24:32.000000000 +0900
+++ src/main/proxy.c	2007-06-29 14:36:06.466808000 +0900
@@ -158,7 +158,7 @@
 		/*
 		 *	The realm name doesn't match, skip it.
 		 */
-		if (strcasecmp(cl->realm, realm_name) != 0) {
+		if (realm_find_cmp(cl, realm_name) != 0) {
 			continue;
 		}
 
--- raddb/proxy.conf.orig	2006-01-11 22:09:02.000000000 +0900
+++ raddb/proxy.conf	2007-06-29 14:36:06.464636000 +0900
@@ -158,6 +158,33 @@
 #	nostrip
 #}
 
+#  A realm containing a regular expression, matching anything like
+#  "user@company2.com" as well as "user@host.company2.com". All 
+#  requests with the matching realms will be sent to radius.company2.com.
+#
+#  Please note that the regular expressions must be POSIX compatible
+#  and will be matched case insensitive.
+#  Additionally, the regex should be the same on all servers of
+#  a fail-over and round-robin realm.
+#
+#  If there are more than one realms matching the regex, the first
+#  matching entry in this file (proxy.conf) will be used.
+#
+#  Attention!
+#  Be careful not to make any loop among radius servers. The server
+#  radius.company2.com must catch all the non-existing realms such
+#  as @[no_domain].company2.com so that the requests won't propagate
+#  further or backward.
+#
+#realm company2.com {
+#	regex		= "^.*company2\.com$"
+#	type		= radius
+#	authhost	= radius.company2.com
+#	accthost	= radius.company2.com
+#	secret		= TheirKey
+#	nostrip
+#}
+
 #
 #  1st node serv.com...set up for round-robin.
 #
