Apache has several bugs in mod_rewrite and mod_vhost_alias that could
cause arbirtary files on the server to be exposed under certain configurations.
if you are using theses modules.


Apply by doing:
	cd /usr/src
	patch -p0 < 031_httpd_patch
	cd usr.sbin/httpd
	make -f Makefile.bsd-wrapper obj
	make -f Makefile.bsd-wrapper depend
	make -f Makefile.bsd-wrapper 
	make -f Makefile.bsd-wrapper install

Index: usr.sbin/httpd/src/modules/standard/mod_rewrite.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/modules/standard/mod_rewrite.c,v
retrieving revision 1.5
diff -u -r1.5 mod_rewrite.c
--- usr.sbin/httpd/src/modules/standard/mod_rewrite.c	2000/01/25 18:30:02	1.5
+++ usr.sbin/httpd/src/modules/standard/mod_rewrite.c	2000/10/18 20:27:27
@@ -1130,20 +1130,7 @@
                        r->filename);
             return OK;
         }
-        else if (  (strlen(r->filename) > 7 &&
-                    strncasecmp(r->filename, "http://",   7) == 0)
-                || (strlen(r->filename) > 8 &&
-                    strncasecmp(r->filename, "https://",  8) == 0)
-                || (strlen(r->filename) > 9 &&
-                    strncasecmp(r->filename, "gopher://", 9) == 0)
-                || (strlen(r->filename) > 6 &&
-                    strncasecmp(r->filename, "ftp://",    6) == 0)
-                || (strlen(r->filename) > 5 &&
-                    strncasecmp(r->filename, "ldap:",     5) == 0)
-                || (strlen(r->filename) > 5 &&
-                    strncasecmp(r->filename, "news:",     5) == 0)
-                || (strlen(r->filename) > 7 &&
-                    strncasecmp(r->filename, "mailto:",   7) == 0)) {
+        else if (is_absolute_uri(r->filename)) {
             /* it was finally rewritten to a remote URL */
 
             /* skip 'scheme:' */
@@ -1394,20 +1381,7 @@
                        "%s [OK]", dconf->directory, r->filename);
             return OK;
         }
-        else if (  (strlen(r->filename) > 7 &&
-                    strncasecmp(r->filename, "http://",   7) == 0)
-                || (strlen(r->filename) > 8 &&
-                    strncasecmp(r->filename, "https://",  8) == 0)
-                || (strlen(r->filename) > 9 &&
-                    strncasecmp(r->filename, "gopher://", 9) == 0)
-                || (strlen(r->filename) > 6 &&
-                    strncasecmp(r->filename, "ftp://",    6) == 0)
-                || (strlen(r->filename) > 5 &&
-                    strncasecmp(r->filename, "ldap:",     5) == 0)
-                || (strlen(r->filename) > 5 &&
-                    strncasecmp(r->filename, "news:",     5) == 0)
-                || (strlen(r->filename) > 7 &&
-                    strncasecmp(r->filename, "mailto:",   7) == 0)) {
+        else if (is_absolute_uri(r->filename)) {
             /* it was finally rewritten to a remote URL */
 
             /* because we are in a per-dir context
@@ -1745,7 +1719,6 @@
     char *output;
     const char *vary;
     char newuri[MAX_STRING_LEN];
-    char env[MAX_STRING_LEN];
     regex_t *regexp;
     regmatch_t regmatch[MAX_NMATCH];
     backrefinfo *briRR = NULL;
@@ -1913,20 +1886,7 @@
      *  (`RewriteRule <pat> - [E=...]')
      */
     if (strcmp(output, "-") == 0) {
-        for (i = 0; p->env[i] != NULL; i++) {
-            /*  1. take the string  */
-            ap_cpystrn(env, p->env[i], sizeof(env));
-            /*  2. expand $N (i.e. backrefs to RewriteRule pattern)  */
-            expand_backref_inbuffer(r->pool, env, sizeof(env), briRR, '$');
-            /*  3. expand %N (i.e. backrefs to latest RewriteCond pattern)  */
-            expand_backref_inbuffer(r->pool, env, sizeof(env), briRC, '%');
-            /*  4. expand %{...} (i.e. variables) */
-            expand_variables_inbuffer(r, env, sizeof(env));
-            /*  5. expand ${...} (RewriteMap lookups)  */
-            expand_map_lookups(r, env, sizeof(env));
-            /*  and add the variable to Apache's structures  */
-            add_env_variable(r, env);
-        }
+	do_expand_env(r, p->env, briRR, briRC);
         if (p->forced_mimetype != NULL) {
             if (perdir == NULL) {
                 /* In the per-server context we can force the MIME-type
@@ -1961,17 +1921,7 @@
      *  that there is something to replace, so we create the
      *  substitution URL string in `newuri'.
      */
-    /*  1. take the output string  */
-    ap_cpystrn(newuri, output, sizeof(newuri));
-    /*  2. expand $N (i.e. backrefs to RewriteRule pattern)  */
-    expand_backref_inbuffer(r->pool, newuri, sizeof(newuri), briRR, '$');
-    /*  3. expand %N (i.e. backrefs to latest RewriteCond pattern)  */
-    expand_backref_inbuffer(r->pool, newuri, sizeof(newuri), briRC, '%');
-    /*  4. expand %{...} (i.e. variables) */
-    expand_variables_inbuffer(r, newuri, sizeof(newuri));
-    /*  5. expand ${...} (RewriteMap lookups)  */
-    expand_map_lookups(r, newuri, sizeof(newuri));
-    /*  and log the result... */
+    do_expand(r, output, newuri, sizeof(newuri), briRR, briRC);
     if (perdir == NULL) {
         rewritelog(r, 2, "rewrite %s -> %s", uri, newuri);
     }
@@ -1983,20 +1933,7 @@
      *  Additionally do expansion for the environment variable
      *  strings (`RewriteRule .. .. [E=<string>]').
      */
-    for (i = 0; p->env[i] != NULL; i++) {
-        /*  1. take the string  */
-        ap_cpystrn(env, p->env[i], sizeof(env));
-        /*  2. expand $N (i.e. backrefs to RewriteRule pattern)  */
-        expand_backref_inbuffer(r->pool, env, sizeof(env), briRR, '$');
-        /*  3. expand %N (i.e. backrefs to latest RewriteCond pattern)  */
-        expand_backref_inbuffer(r->pool, env, sizeof(env), briRC, '%');
-        /*  4. expand %{...} (i.e. variables) */
-        expand_variables_inbuffer(r, env, sizeof(env));
-        /*  5. expand ${...} (RewriteMap lookups)  */
-        expand_map_lookups(r, env, sizeof(env));
-        /*  and add the variable to Apache's structures  */
-        add_env_variable(r, env);
-    }
+    do_expand_env(r, p->env, briRR, briRC);
 
     /*
      *  Now replace API's knowledge of the current URI:
@@ -2012,16 +1949,8 @@
      *   location, i.e. if it's not starting with either a slash
      *   or a fully qualified URL scheme.
      */
-    i = strlen(r->filename);
-    if (   prefixstrip
-        && !(   r->filename[0] == '/'
-             || (   (i > 7 && strncasecmp(r->filename, "http://",   7) == 0)
-                 || (i > 8 && strncasecmp(r->filename, "https://",  8) == 0)
-                 || (i > 9 && strncasecmp(r->filename, "gopher://", 9) == 0)
-                 || (i > 6 && strncasecmp(r->filename, "ftp://",    6) == 0)
-                 || (i > 5 && strncasecmp(r->filename, "ldap:",     5) == 0)
-                 || (i > 5 && strncasecmp(r->filename, "news:",     5) == 0)
-                 || (i > 7 && strncasecmp(r->filename, "mailto:",   7) == 0)))) {
+    if (prefixstrip && r->filename[0] != '/'
+	&& !is_absolute_uri(r->filename)) {
         rewritelog(r, 3, "[per-dir %s] add per-dir prefix: %s -> %s%s",
                    perdir, r->filename, perdir, r->filename);
         r->filename = ap_pstrcat(r->pool, perdir, r->filename, NULL);
@@ -2085,14 +2014,7 @@
      *  redirection (`RewriteRule .. <scheme>://...') then
      *  directly force an external HTTP redirect.
      */
-    i = strlen(r->filename);
-    if (   (i > 7 && strncasecmp(r->filename, "http://",   7) == 0)
-        || (i > 8 && strncasecmp(r->filename, "https://",  8) == 0)
-        || (i > 9 && strncasecmp(r->filename, "gopher://", 9) == 0)
-        || (i > 6 && strncasecmp(r->filename, "ftp://",    6) == 0)
-        || (i > 5 && strncasecmp(r->filename, "ldap:",     5) == 0)
-        || (i > 5 && strncasecmp(r->filename, "news:",     5) == 0)
-        || (i > 7 && strncasecmp(r->filename, "mailto:",   7) == 0) ) {
+    if (is_absolute_uri(r->filename)) {
         if (perdir == NULL) {
             rewritelog(r, 2,
                        "implicitly forcing redirect (rc=%d) with %s",
@@ -2163,16 +2085,7 @@
      *   Construct the string we match against
      */
 
-    /*  1. take the string  */
-    ap_cpystrn(input, p->input, sizeof(input));
-    /*  2. expand $N (i.e. backrefs to RewriteRule pattern)  */
-    expand_backref_inbuffer(r->pool, input, sizeof(input), briRR, '$');
-    /*  3. expand %N (i.e. backrefs to latest RewriteCond pattern)  */
-    expand_backref_inbuffer(r->pool, input, sizeof(input), briRC, '%');
-    /*  4. expand %{...} (i.e. variables) */
-    expand_variables_inbuffer(r, input, sizeof(input));
-    /*  5. expand ${...} (RewriteMap lookups)  */
-    expand_map_lookups(r, input, sizeof(input));
+    do_expand(r, p->input, input, sizeof(input), briRR, briRC);
 
     /*
      *   Apply the patterns
@@ -2194,7 +2107,7 @@
         }
     }
     else if (strcmp(p->pattern, "-l") == 0) {
-#if !defined(OS2) && !defined(WIN32)
+#if !defined(OS2) && !defined(WIN32)  && !defined(NETWARE)
         if (lstat(input, &sb) == 0) {
             if (S_ISLNK(sb.st_mode)) {
                 rc = 1;
@@ -2211,12 +2124,7 @@
     }
     else if (strcmp(p->pattern, "-U") == 0) {
         /* avoid infinite subrequest recursion */
-        if (strlen(input) > 0               /* nonempty path, and            */
-            && (   r->main == NULL          /* - either not in a subrequest  */
-                || (   r->main->uri != NULL /* - or in a subrequest...       */
-                    && r->uri != NULL       /*   ...and URIs aren't NULL...  */
-                                            /*   ...and sub/main URIs differ */
-                    && strcmp(r->main->uri, r->uri) != 0) ) ) {
+        if (strlen(input) > 0 && subreq_ok(r)) {
 
             /* run a URI-based subrequest */
             rsub = ap_sub_req_lookup_uri(input, r);
@@ -2235,12 +2143,7 @@
     }
     else if (strcmp(p->pattern, "-F") == 0) {
         /* avoid infinite subrequest recursion */
-        if (strlen(input) > 0               /* nonempty path, and            */
-            && (   r->main == NULL          /* - either not in a subrequest  */
-                || (   r->main->uri != NULL /* - or in a subrequest...       */
-                    && r->uri != NULL       /*   ...and URIs aren't NULL...  */
-                                            /*   ...and sub/main URIs differ */
-                    && strcmp(r->main->uri, r->uri) != 0) ) ) {
+        if (strlen(input) > 0 && subreq_ok(r)) {
 
             /* process a file-based subrequest:
              * this differs from -U in that no path translation is done.
@@ -2314,8 +2217,161 @@
 ** +-------------------------------------------------------+
 */
 
+
 /*
 **
+**  perform all the expansions on the input string
+**  leaving the result in the supplied buffer
+**
+*/
+
+static void do_expand(request_rec *r, char *input, char *buffer, int nbuf,
+		       backrefinfo *briRR, backrefinfo *briRC)
+{
+    char *inp, *outp;
+    size_t span, space;
+
+    /*
+     * for security reasons this expansion must be perfomed in a
+     * single pass, otherwise an attacker can arrange for the result
+     * of an earlier expansion to include expansion specifiers that
+     * are interpreted by a later expansion, producing results that
+     * were not intended by the administrator.
+     */
+
+    inp = input;
+    outp = buffer;
+    space = nbuf - 1; /* room for '\0' */
+
+    for (;;) {
+	span = strcspn(inp, "$%");
+	if (span > space) {
+	    span = space;
+	}
+	memcpy(outp, inp, span);
+	inp += span;
+	outp += span;
+	space -= span;
+	if (space == 0 || *inp == '\0') {
+	    break;
+	}
+	/* now we have a '$' or a '%' */
+	if (inp[1] == '{') {
+	    char *endp;
+	    endp = find_closing_bracket(inp+2, '{', '}');
+	    if (endp == NULL) {
+		goto skip;
+	    }
+	    *endp = '\0';
+	    if (inp[0] == '$') {
+		/* ${...} map lookup expansion */
+		/*
+		 * To make rewrite maps useful the lookup key and
+		 * default values must be expanded, so we make
+		 * recursive calls to do the work. For security
+		 * reasons we must never expand a string that includes
+		 * verbatim data from the network. The recursion here
+		 * isn't a problem because the result of expansion is
+		 * only passed to lookup_map() so it cannot be
+		 * re-expanded, only re-looked-up. Another way of
+		 * looking at it is that the recursion is entirely
+		 * driven by the syntax of the nested curly brackets.
+		 */
+		char *key, *dflt, *result;
+		char xkey[MAX_STRING_LEN];
+		char xdflt[MAX_STRING_LEN];
+		char *empty = "";
+		key = strchr(inp, ':');
+		if (key == NULL) {
+		    goto skip;
+		}
+		*key++ = '\0';
+		dflt = strchr(key, '|');
+		if (dflt == NULL) {
+		    dflt = empty;
+		}
+		else {
+		    *dflt++ = '\0';
+		}
+		do_expand(r, key,  xkey,  sizeof(xkey),  briRR, briRC);
+		do_expand(r, dflt, xdflt, sizeof(xdflt), briRR, briRC);
+		result = lookup_map(r, inp+2, xkey);
+		if (result == NULL) {
+		    result = xdflt;
+		}
+		span = ap_cpystrn(outp, result, space) - outp;
+		key[-1] = ':';
+		if (dflt != empty) {
+		    dflt[-1] = '|';
+		}
+	    }
+	    else if (inp[0] == '%') {
+		/* %{...} variable lookup expansion */
+		span = ap_cpystrn(outp, lookup_variable(r, inp+2), space) - outp;
+	    }
+	    else {
+		span = 0;
+	    }
+	    *endp = '}';
+	    inp = endp+1;
+	    outp += span;
+	    space -= span;
+	    continue;
+	}
+	else if (ap_isdigit(inp[1])) {
+	    int n = inp[1] - '0';
+	    backrefinfo *bri = NULL;
+	    if (inp[0] == '$') {
+		/* $N RewriteRule regexp backref expansion */
+		bri = briRR;
+	    }
+	    else if (inp[0] == '%') {
+		/* %N RewriteCond regexp backref expansion */
+		bri = briRC;
+	    }
+	    /* see ap_pregsub() in src/main/util.c */
+            if (bri && n <= bri->nsub &&
+		bri->regmatch[n].rm_eo > bri->regmatch[n].rm_so) {
+		span = bri->regmatch[n].rm_eo - bri->regmatch[n].rm_so;
+		if (span > space) {
+		    span = space;
+		}
+		memcpy(outp, bri->source + bri->regmatch[n].rm_so, span);
+		outp += span;
+		space -= span;
+	    }
+	    inp += 2;
+	    continue;
+	}
+    skip:
+	*outp++ = *inp++;
+	space--;
+    }
+    *outp++ = '\0';
+}
+
+
+/*
+**
+**  perform all the expansions on the environment variables
+**
+*/
+
+static void do_expand_env(request_rec *r, char *env[],
+			  backrefinfo *briRR, backrefinfo *briRC)
+{
+    int i;
+    char buf[MAX_STRING_LEN];
+
+    for (i = 0; env[i] != NULL; i++) {
+	do_expand(r, env[i], buf, sizeof(buf), briRR, briRC);
+	add_env_variable(r, buf);
+    }
+}
+
+
+/*
+**
 **  split out a QUERY_STRING part from
 **  the current URI string
 **
@@ -2442,20 +2498,12 @@
 
 static void fully_qualify_uri(request_rec *r)
 {
-    int i;
     char buf[32];
     const char *thisserver;
     char *thisport;
     int port;
 
-    i = strlen(r->filename);
-    if (!(   (i > 7 && strncasecmp(r->filename, "http://",   7) == 0)
-          || (i > 8 && strncasecmp(r->filename, "https://",  8) == 0)
-          || (i > 9 && strncasecmp(r->filename, "gopher://", 9) == 0)
-          || (i > 6 && strncasecmp(r->filename, "ftp://",    6) == 0)
-          || (i > 5 && strncasecmp(r->filename, "ldap:",     5) == 0)
-          || (i > 5 && strncasecmp(r->filename, "news:",     5) == 0)
-          || (i > 7 && strncasecmp(r->filename, "mailto:",   7) == 0))) {
+    if (!is_absolute_uri(r->filename)) {
 
         thisserver = ap_get_server_name(r);
         port = ap_get_server_port(r);
@@ -2484,45 +2532,24 @@
 
 /*
 **
-**  Expand the %0-%9 or $0-$9 regex backreferences
+**  return non-zero if the URI is absolute (includes a scheme etc.)
 **
 */
 
-static void expand_backref_inbuffer(pool *p, char *buf, int nbuf,
-                                    backrefinfo *bri, char c)
+static int is_absolute_uri(char *uri)
 {
-    register int i;
-
-    /* protect existing $N and & backrefs and replace <c>N with $N backrefs */
-    for (i = 0; buf[i] != '\0' && i < nbuf; i++) {
-        if (buf[i] == '\\' && (buf[i+1] != '\0' && i < (nbuf-1))) {
-            i++; /* protect next */
-        }
-        else if (buf[i] == '&') {
-            buf[i] = '\001';
-        }
-        else if (c != '$' && buf[i] == '$' && (buf[i+1] >= '0' && buf[i+1] <= '9')) {
-            buf[i] = '\002';
-            i++; /* speedup */
-        }
-        else if (buf[i] == c && (buf[i+1] >= '0' && buf[i+1] <= '9')) {
-            buf[i] = '$';
-            i++; /* speedup */
-        }
+    int i = strlen(uri);
+    if (   (i > 7 && strncasecmp(uri, "http://",   7) == 0)
+        || (i > 8 && strncasecmp(uri, "https://",  8) == 0)
+        || (i > 9 && strncasecmp(uri, "gopher://", 9) == 0)
+        || (i > 6 && strncasecmp(uri, "ftp://",    6) == 0)
+        || (i > 5 && strncasecmp(uri, "ldap:",     5) == 0)
+        || (i > 5 && strncasecmp(uri, "news:",     5) == 0)
+        || (i > 7 && strncasecmp(uri, "mailto:",   7) == 0) ) {
+	return 1;
     }
-
-    /* now apply the standard regex substitution function */
-    ap_cpystrn(buf, ap_pregsub(p, buf, bri->source,
-                               bri->nsub+1, bri->regmatch), nbuf);
-
-    /* restore the original $N and & backrefs */
-    for (i = 0; buf[i] != '\0' && i < nbuf; i++) {
-        if (buf[i] == '\001') {
-            buf[i] = '&';
-        }
-        else if (buf[i] == '\002') {
-            buf[i] = '$';
-        }
+    else {
+	return 0;
     }
 }
 
@@ -2571,121 +2598,8 @@
 }
 #endif
 
-/*
-**
-**  mapfile expansion support
-**  i.e. expansion of MAP lookup directives
-**  ${<mapname>:<key>} in RewriteRule rhs
-**
-*/
 
-#define limit_length(n) (n > LONG_STRING_LEN-1 ? LONG_STRING_LEN-1 : n)
 
-static void expand_map_lookups(request_rec *r, char *uri, int uri_len)
-{
-    char newuri[MAX_STRING_LEN];
-    char *cpI;
-    char *cpIE;
-    char *cpO;
-    char *cpT;
-    char *cpT2;
-    char mapname[LONG_STRING_LEN];
-    char mapkey[LONG_STRING_LEN];
-    char defaultvalue[LONG_STRING_LEN];
-    int n;
-
-    cpI = uri;
-    cpIE = cpI+strlen(cpI);
-    cpO = newuri;
-    while (cpI < cpIE) {
-        if (cpI+6 < cpIE && strncmp(cpI, "${", 2) == 0) {
-            /* missing delimiter -> take it as plain text */
-            if (   strchr(cpI+2, ':') == NULL
-                || strchr(cpI+2, '}') == NULL) {
-                memcpy(cpO, cpI, 2);
-                cpO += 2;
-                cpI += 2;
-                continue;
-            }
-            cpI += 2;
-
-            cpT = strchr(cpI, ':');
-            n = cpT-cpI;
-            memcpy(mapname, cpI, limit_length(n));
-            mapname[limit_length(n)] = '\0';
-            cpI += n+1;
-
-            cpT2 = strchr(cpI, '|');
-            cpT = strchr(cpI, '}');
-            if (cpT2 != NULL && cpT2 < cpT) {
-                n = cpT2-cpI;
-                memcpy(mapkey, cpI, limit_length(n));
-                mapkey[limit_length(n)] = '\0';
-                cpI += n+1;
-
-                n = cpT-cpI;
-                memcpy(defaultvalue, cpI, limit_length(n));
-                defaultvalue[limit_length(n)] = '\0';
-                cpI += n+1;
-            }
-            else {
-                n = cpT-cpI;
-                memcpy(mapkey, cpI, limit_length(n));
-                mapkey[limit_length(n)] = '\0';
-                cpI += n+1;
-
-                defaultvalue[0] = '\0';
-            }
-
-            cpT = lookup_map(r, mapname, mapkey);
-            if (cpT != NULL) {
-                n = strlen(cpT);
-                if (cpO + n >= newuri + sizeof(newuri)) {
-                    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
-                                 r, "insufficient space in "
-                                 "expand_map_lookups, aborting");
-                    return;
-                }
-                memcpy(cpO, cpT, n);
-                cpO += n;
-            }
-            else {
-                n = strlen(defaultvalue);
-                if (cpO + n >= newuri + sizeof(newuri)) {
-                    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 
-                                 r, "insufficient space in "
-                                 "expand_map_lookups, aborting");
-                    return;
-                }
-                memcpy(cpO, defaultvalue, n);
-                cpO += n;
-            }
-        }
-        else {
-            cpT = strstr(cpI, "${");
-            if (cpT == NULL)
-                cpT = cpI+strlen(cpI);
-            n = cpT-cpI;
-            if (cpO + n >= newuri + sizeof(newuri)) {
-                ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 
-                             r, "insufficient space in "
-                             "expand_map_lookups, aborting");
-                return;
-            }
-            memcpy(cpO, cpI, n);
-            cpO += n;
-            cpI += n;
-        }
-    }
-    *cpO = '\0';
-    ap_cpystrn(uri, newuri, uri_len);
-    return;
-}
-
-#undef limit_length
-
-
-
 /*
 ** +-------------------------------------------------------+
 ** |                                                       |
@@ -3109,7 +3023,9 @@
     char *fname;
     piped_log *pl;
     int    rewritelog_flags = ( O_WRONLY|O_APPEND|O_CREAT );
-#ifdef WIN32
+#if defined(NETWARE)
+    mode_t rewritelog_mode  = ( S_IREAD|S_IWRITE );
+#elif defined(WIN32)
     mode_t rewritelog_mode  = ( _S_IREAD|_S_IWRITE );
 #else
     mode_t rewritelog_mode  = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
@@ -3267,7 +3183,9 @@
 ** +-------------------------------------------------------+
 */
 
-#ifdef WIN32
+#if defined(NETWARE)
+#define REWRITELOCK_MODE ( S_IREAD|S_IWRITE )
+#elif defined(WIN32)
 #define REWRITELOCK_MODE ( _S_IREAD|_S_IWRITE )
 #else
 #define REWRITELOCK_MODE ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH )
@@ -3275,10 +3193,6 @@
 
 static void rewritelock_create(server_rec *s, pool *p)
 {
-    rewrite_server_conf *conf;
-
-    conf = ap_get_module_config(s->module_config, &rewrite_module);
-
     /* only operate if a lockfile is used */
     if (lockname == NULL || *(lockname) == '\0') {
         return;
@@ -3307,10 +3221,6 @@
 
 static void rewritelock_open(server_rec *s, pool *p)
 {
-    rewrite_server_conf *conf;
-
-    conf = ap_get_module_config(s->module_config, &rewrite_module);
-
     /* only operate if a lockfile is used */
     if (lockname == NULL || *(lockname) == '\0') {
         return;
@@ -3483,53 +3393,6 @@
 */
 
 
-static void expand_variables_inbuffer(request_rec *r, char *buf, int buf_len)
-{
-    char *newbuf;
-    newbuf = expand_variables(r, buf);
-    if (strcmp(newbuf, buf) != 0) {
-        ap_cpystrn(buf, newbuf, buf_len);
-    }
-    return;
-}
-
-static char *expand_variables(request_rec *r, char *str)
-{
-    char output[MAX_STRING_LEN];
-    char input[MAX_STRING_LEN];
-    char *cp;
-    char *cp2;
-    char *cp3;
-    int expanded;
-    char *outp;
-    char *endp;
-
-    ap_cpystrn(input, str, sizeof(input));
-    output[0] = '\0';
-    outp = output;
-    endp = output + sizeof(output);
-    expanded = 0;
-    for (cp = input; cp < input+MAX_STRING_LEN; ) {
-        if ((cp2 = strstr(cp, "%{")) != NULL) {
-            if ((cp3 = strstr(cp2, "}")) != NULL) {
-                *cp2 = '\0';
-                outp = ap_cpystrn(outp, cp, endp - outp);
-
-                cp2 += 2;
-                *cp3 = '\0';
-                outp = ap_cpystrn(outp, lookup_variable(r, cp2), endp - outp);
-
-                cp = cp3+1;
-                expanded = 1;
-                continue;
-            }
-        }
-        outp = ap_cpystrn(outp, cp, endp - outp);
-        break;
-    }
-    return expanded ? ap_pstrdup(r->pool, output) : str;
-}
-
 static char *lookup_variable(request_rec *r, char *var)
 {
     const char *result;
@@ -3869,11 +3732,11 @@
     char *p;
 
     n = 0;
-    for (p=key; *p != '\0'; ++p) {
-        n = n * 53711 + 134561 + (unsigned)(*p & 0xff);
+    for (p = key; *p != '\0'; p++) {
+        n = ((n << 5) + n) ^ (unsigned long)(*p++);
     }
 
-    return n % CACHE_TLB_ROWS;
+    return (int)(n % CACHE_TLB_ROWS);
 }
 
 static cacheentry *cache_tlb_lookup(cachetlbentry *tlb, cacheentry *elt,
@@ -4156,6 +4019,23 @@
 }
 
 
+/*
+**
+**  check that a subrequest won't cause infinite recursion
+**
+*/
+
+static int subreq_ok(request_rec *r)
+{
+    /*
+     * either not in a subrequest, or in a subrequest
+     * and URIs aren't NULL and sub/main URIs differ
+     */
+    return (r->main == NULL ||
+	    (r->main->uri != NULL && r->uri != NULL &&
+	     strcmp(r->main->uri, r->uri) != 0));
+}
+
 
 /*
 **
@@ -4291,12 +4171,27 @@
     }
     return 0;
 }
+
+/*
+**
+**  Find end of bracketed expression
+**  s points after the opening bracket
+**
+*/
 
-#ifdef NETWARE
-int main(int argc, char *argv[]) 
+static char *find_closing_bracket(char *s, int left, int right)
 {
-    ExitThread(TSR_THREAD, 0);
+    int depth;
+
+    for (depth = 1; *s; ++s) {
+	if (*s == right && --depth == 0) {
+	    return s;
+	}
+	else if (*s == left) {
+	    ++depth;
+	}
+    }
+    return NULL;
 }
-#endif
 
 /*EOF*/
Index: usr.sbin/httpd/src/modules/standard/mod_rewrite.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/modules/standard/mod_rewrite.h,v
retrieving revision 1.4
diff -u -r1.4 mod_rewrite.h
--- usr.sbin/httpd/src/modules/standard/mod_rewrite.h	2000/01/25 18:30:03	1.4
+++ usr.sbin/httpd/src/modules/standard/mod_rewrite.h	2000/10/18 20:27:27
@@ -168,7 +168,7 @@
 #include <fcntl.h>
 #endif
 #endif
-#ifdef AIX
+#if defined(AIX) || defined(AIXIA64)
 #undef USE_FLOCK
 #define USE_FCNTL 1
 #include <fcntl.h>
@@ -420,14 +420,17 @@
                               char *perdir, backrefinfo *briRR,
                               backrefinfo *briRC);
 
+static void do_expand(request_rec *r, char *input, char *buffer, int nbuf,
+		       backrefinfo *briRR, backrefinfo *briRC);
+static void do_expand_env(request_rec *r, char *env[],
+			  backrefinfo *briRR, backrefinfo *briRC);
+
     /* URI transformation function */
 static void  splitout_queryargs(request_rec *r, int qsappend);
 static void  fully_qualify_uri(request_rec *r);
 static void  reduce_uri(request_rec *r);
-static void  expand_backref_inbuffer(pool *p, char *buf, int nbuf,
-                                     backrefinfo *bri, char c);
+static int   is_absolute_uri(char *uri);
 static char *expand_tildepaths(request_rec *r, char *uri);
-static void  expand_map_lookups(request_rec *r, char *uri, int uri_len);
 
     /* rewrite map support functions */
 static char *lookup_map(request_rec *r, char *name, char *key);
@@ -466,8 +469,6 @@
 static int   rewritemap_program_child(void *cmd, child_info *pinfo);
 
     /* env variable support */
-static void  expand_variables_inbuffer(request_rec *r, char *buf, int buf_len);
-static char *expand_variables(request_rec *r, char *str);
 static char *lookup_variable(request_rec *r, char *var);
 static char *lookup_header(request_rec *r, const char *name);
 
@@ -486,6 +487,7 @@
 static int    parseargline(char *str, char **a1, char **a2, char **a3);
 static int    prefix_stat(const char *path, struct stat *sb);
 static void   add_env_variable(request_rec *r, char *s);
+static int    subreq_ok(request_rec *r);
 
     /* File locking */
 static void fd_lock(request_rec *r, int fd);
@@ -493,6 +495,9 @@
 
     /* Lexicographic Comparison */
 static int compare_lexicography(char *cpNum1, char *cpNum2);
+
+    /* Find end of bracketed expression */
+static char *find_closing_bracket(char *s, int left, int right);
 
 #endif /* _MOD_REWRITE_H */
 
Index: usr.sbin/httpd/src/modules/standard/mod_vhost_alias.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/modules/standard/mod_vhost_alias.c,v
retrieving revision 1.1
diff -u -r1.1 mod_vhost_alias.c
--- usr.sbin/httpd/src/modules/standard/mod_vhost_alias.c	1999/09/29 06:29:57	1.1
+++ usr.sbin/httpd/src/modules/standard/mod_vhost_alias.c	2000/10/18 20:27:27
@@ -412,25 +412,23 @@
     mva_sconf_t *conf;
     const char *name, *map, *uri;
     mva_mode_e mode;
-    int cgi;
+    const char *cgi;
   
     conf = (mva_sconf_t *) ap_get_module_config(r->server->module_config,
 					      &vhost_alias_module);
-    if (!strncmp(r->uri, "/cgi-bin/", 9)) {
+    cgi = strstr(r->uri, "cgi-bin/");
+    if (cgi && cgi - r->uri != strspn(r->uri, "/")) {
+        cgi = NULL;
+    }
+    if (cgi) {
 	mode = conf->cgi_root_mode;
 	map = conf->cgi_root;
-	uri = r->uri + 8;
-	/*
-	 * can't force cgi immediately because we might not handle this
-	 * call if the mode is wrong
-	 */
-	cgi = 1;
+	uri = cgi + strlen("cgi-bin");
     }
     else if (r->uri[0] == '/') {
 	mode = conf->doc_root_mode;
 	map = conf->doc_root;
 	uri = r->uri;
-	cgi = 0;
     }
     else {
 	return DECLINED;
