Fix an issue where users can sometimes get spurious 403s on persistent connections (the description in the comments explains the logic). This would particularly hit people with reverse proxies, since these have a higher tendency of accessing things from different vhosts in the same connection. Index: httpd-2.2.17/server/config.c =================================================================== --- httpd-2.2.17.orig/server/config.c +++ httpd-2.2.17/server/config.c @@ -1840,6 +1840,34 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(a else { if (!APR_STATUS_IS_ENOENT(status) && !APR_STATUS_IS_ENOTDIR(status)) { +#ifdef ITK_MPM + /* + * If we are in a persistent connection, we might end up in a state + * where we can no longer read .htaccess files because we have already + * setuid(). This can either be because the previous request was for + * another vhost (basically the same problem as when setuid() fails in + * itk.c), or it can be because a .htaccess file is readable only by + * root. + * + * In any case, we don't want to give out a 403, since the request has + * a very real chance of succeeding on a fresh connection (where + * presumably uid=0). Thus, we give up serving the request on this + * TCP connection, and do a hard close of the socket. As long as we're + * in a persistent connection (and there _should_ not be a way this + * would happen on the first request in a connection, save for subrequests, + * which we special-case), this is allowed, as it is what happens on + * a timeout. The browser will simply open a new connection and try + * again (there's of course a performance hit, though, both due to + * the new connection setup and the fork() of a new server child). + */ + if (r->main == NULL && getuid() != 0) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, status, r, + "Couldn't read %s, closing connection.", + filename); + ap_lingering_close(r->connection); + exit(0); + } +#endif ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, "%s pcfg_openfile: unable to check htaccess file, " "ensure it is readable",