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 - [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=]'). */ - 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 .. ://...') 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 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 -** ${:} 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 #endif #endif -#ifdef AIX +#if defined(AIX) || defined(AIXIA64) #undef USE_FLOCK #define USE_FCNTL 1 #include @@ -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;