|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
|
Packit Service |
384592 |
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* You may not use this file except in compliance with
|
|
Packit Service |
384592 |
* the License. You may obtain a copy of the License at
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* If any of the files related to licensing are missing or if you have any
|
|
Packit Service |
384592 |
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
|
Packit Service |
384592 |
* directly using the email address security@modsecurity.org.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include <limits.h>
|
|
Packit Service |
384592 |
#include <stdio.h>
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "http_core.h"
|
|
Packit Service |
384592 |
#include "http_request.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "modsecurity.h"
|
|
Packit Service |
384592 |
#include "apache2.h"
|
|
Packit Service |
384592 |
#include "http_main.h"
|
|
Packit Service |
384592 |
#include "http_connection.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "apr_optional.h"
|
|
Packit Service |
384592 |
#include "mod_log_config.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "msc_logging.h"
|
|
Packit Service |
384592 |
#include "msc_util.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "ap_mpm.h"
|
|
Packit Service |
384592 |
#include "scoreboard.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "apr_version.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "apr_lib.h"
|
|
Packit Service |
384592 |
#include "ap_config.h"
|
|
Packit Service |
384592 |
#include "http_config.h"
|
|
Packit Service |
384592 |
#include "apr_fnmatch.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
AP_DECLARE(int) ap_cfg_closefile(ap_configfile_t *cfp)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
#ifdef DEBUG
|
|
Packit Service |
384592 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
|
|
Packit Service |
384592 |
"Done with config file %s", cfp->name);
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
return (cfp->close == NULL) ? 0 : cfp->close(cfp->param);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
|
|
Packit Service |
384592 |
static apr_status_t cfg_close(void *param)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_file_t *cfp = (apr_file_t *) param;
|
|
Packit Service |
384592 |
return (apr_file_close(cfp));
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int cfg_getch(void *param)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
char ch;
|
|
Packit Service |
384592 |
apr_file_t *cfp = (apr_file_t *) param;
|
|
Packit Service |
384592 |
if (apr_file_getc(&ch, cfp) == APR_SUCCESS)
|
|
Packit Service |
384592 |
return ch;
|
|
Packit Service |
384592 |
return (int)EOF;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static void *cfg_getstr(void *buf, size_t bufsiz, void *param)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_file_t *cfp = (apr_file_t *) param;
|
|
Packit Service |
384592 |
apr_status_t rv;
|
|
Packit Service |
384592 |
rv = apr_file_gets(buf, bufsiz, cfp);
|
|
Packit Service |
384592 |
if (rv == APR_SUCCESS) {
|
|
Packit Service |
384592 |
return buf;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#else
|
|
Packit Service |
384592 |
/* we can't use apr_file_* directly because of linking issues on Windows */
|
|
Packit Service |
384592 |
static apr_status_t cfg_close(void *param)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
return apr_file_close(param);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static apr_status_t cfg_getch(char *ch, void *param)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
return apr_file_getc(ch, param);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static apr_status_t cfg_getstr(void *buf, apr_size_t bufsiz, void *param)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
return apr_file_gets(buf, bufsiz, param);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Read one line from open ap_configfile_t, strip LF, increase line number */
|
|
Packit Service |
384592 |
/* If custom handler does not define a getstr() function, read char by char */
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
|
|
Packit Service |
384592 |
AP_DECLARE(int) ap_cfg_getline(char *buf, size_t bufsize, ap_configfile_t *cfp)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
/* If a "get string" function is defined, use it */
|
|
Packit Service |
384592 |
if (cfp->getstr != NULL) {
|
|
Packit Service |
384592 |
char *src, *dst;
|
|
Packit Service |
384592 |
char *cp;
|
|
Packit Service |
384592 |
char *cbuf = buf;
|
|
Packit Service |
384592 |
size_t cbufsize = bufsize;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (1) {
|
|
Packit Service |
384592 |
++cfp->line_number;
|
|
Packit Service |
384592 |
if (cfp->getstr(cbuf, cbufsize, cfp->param) == NULL)
|
|
Packit Service |
384592 |
return 1;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* check for line continuation,
|
|
Packit Service |
384592 |
* i.e. match [^\\]\\[\r]\n only
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
cp = cbuf;
|
|
Packit Service |
384592 |
while (cp < cbuf+cbufsize && *cp != '\0')
|
|
Packit Service |
384592 |
cp++;
|
|
Packit Service |
384592 |
if (cp > cbuf && cp[-1] == LF) {
|
|
Packit Service |
384592 |
cp--;
|
|
Packit Service |
384592 |
if (cp > cbuf && cp[-1] == CR)
|
|
Packit Service |
384592 |
cp--;
|
|
Packit Service |
384592 |
if (cp > cbuf && cp[-1] == '\\') {
|
|
Packit Service |
384592 |
cp--;
|
|
Packit Service |
384592 |
if (!(cp > cbuf && cp[-1] == '\\')) {
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* line continuation requested -
|
|
Packit Service |
384592 |
* then remove backslash and continue
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
cbufsize -= (cp-cbuf);
|
|
Packit Service |
384592 |
cbuf = cp;
|
|
Packit Service |
384592 |
continue;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* no real continuation because escaped -
|
|
Packit Service |
384592 |
* then just remove escape character
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
for ( ; cp < cbuf+cbufsize && *cp != '\0'; cp++)
|
|
Packit Service |
384592 |
cp[0] = cp[1];
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* Leading and trailing white space is eliminated completely
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
src = buf;
|
|
Packit Service |
384592 |
while (apr_isspace(*src))
|
|
Packit Service |
384592 |
++src;
|
|
Packit Service |
384592 |
/* blast trailing whitespace */
|
|
Packit Service |
384592 |
dst = &src[strlen(src)];
|
|
Packit Service |
384592 |
while (--dst >= src && apr_isspace(*dst))
|
|
Packit Service |
384592 |
*dst = '\0';
|
|
Packit Service |
384592 |
/* Zap leading whitespace by shifting */
|
|
Packit Service |
384592 |
if (src != buf)
|
|
Packit Service |
384592 |
for (dst = buf; (*dst++ = *src++) != '\0'; )
|
|
Packit Service |
384592 |
;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#ifdef DEBUG_CFG_LINES
|
|
Packit Service |
384592 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "Read config: %s", buf);
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
return 0;
|
|
Packit Service |
384592 |
} else {
|
|
Packit Service |
384592 |
/* No "get string" function defined; read character by character */
|
|
Packit Service |
384592 |
register int c;
|
|
Packit Service |
384592 |
register size_t i = 0;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
buf[0] = '\0';
|
|
Packit Service |
384592 |
/* skip leading whitespace */
|
|
Packit Service |
384592 |
do {
|
|
Packit Service |
384592 |
c = cfp->getch(cfp->param);
|
|
Packit Service |
384592 |
} while (c == '\t' || c == ' ');
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (c == EOF)
|
|
Packit Service |
384592 |
return 1;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(bufsize < 2) {
|
|
Packit Service |
384592 |
/* too small, assume caller is crazy */
|
|
Packit Service |
384592 |
return 1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (1) {
|
|
Packit Service |
384592 |
if ((c == '\t') || (c == ' ')) {
|
|
Packit Service |
384592 |
buf[i++] = ' ';
|
|
Packit Service |
384592 |
while ((c == '\t') || (c == ' '))
|
|
Packit Service |
384592 |
c = cfp->getch(cfp->param);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (c == CR) {
|
|
Packit Service |
384592 |
/* silently ignore CR (_assume_ that a LF follows) */
|
|
Packit Service |
384592 |
c = cfp->getch(cfp->param);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (c == LF) {
|
|
Packit Service |
384592 |
/* increase line number and return on LF */
|
|
Packit Service |
384592 |
++cfp->line_number;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (c == EOF || c == 0x4 || c == LF || i >= (bufsize - 2)) {
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* check for line continuation
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
if (i > 0 && buf[i-1] == '\\') {
|
|
Packit Service |
384592 |
i--;
|
|
Packit Service |
384592 |
if (!(i > 0 && buf[i-1] == '\\')) {
|
|
Packit Service |
384592 |
/* line is continued */
|
|
Packit Service |
384592 |
c = cfp->getch(cfp->param);
|
|
Packit Service |
384592 |
continue;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
/* else nothing needs be done because
|
|
Packit Service |
384592 |
* then the backslash is escaped and
|
|
Packit Service |
384592 |
* we just strip to a single one
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
/* blast trailing whitespace */
|
|
Packit Service |
384592 |
while (i > 0 && apr_isspace(buf[i - 1]))
|
|
Packit Service |
384592 |
--i;
|
|
Packit Service |
384592 |
buf[i] = '\0';
|
|
Packit Service |
384592 |
#ifdef DEBUG_CFG_LINES
|
|
Packit Service |
384592 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
|
|
Packit Service |
384592 |
"Read config: %s", buf);
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
return 0;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
buf[i] = c;
|
|
Packit Service |
384592 |
++i;
|
|
Packit Service |
384592 |
c = cfp->getch(cfp->param);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#else
|
|
Packit Service |
384592 |
static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize,
|
|
Packit Service |
384592 |
ap_configfile_t *cfp)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_status_t rc;
|
|
Packit Service |
384592 |
/* If a "get string" function is defined, use it */
|
|
Packit Service |
384592 |
if (cfp->getstr != NULL) {
|
|
Packit Service |
384592 |
char *cp;
|
|
Packit Service |
384592 |
char *cbuf = buf;
|
|
Packit Service |
384592 |
apr_size_t cbufsize = bufsize;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (1) {
|
|
Packit Service |
384592 |
++cfp->line_number;
|
|
Packit Service |
384592 |
rc = cfp->getstr(cbuf, cbufsize, cfp->param);
|
|
Packit Service |
384592 |
if (rc == APR_EOF) {
|
|
Packit Service |
384592 |
if (cbuf != buf) {
|
|
Packit Service |
384592 |
*cbuf = '\0';
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
return APR_EOF;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (rc != APR_SUCCESS) {
|
|
Packit Service |
384592 |
return rc;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* check for line continuation,
|
|
Packit Service |
384592 |
* i.e. match [^\\]\\[\r]\n only
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
cp = cbuf;
|
|
Packit Service |
384592 |
cp += strlen(cp);
|
|
Packit Service |
384592 |
if (cp > cbuf && cp[-1] == LF) {
|
|
Packit Service |
384592 |
cp--;
|
|
Packit Service |
384592 |
if (cp > cbuf && cp[-1] == CR)
|
|
Packit Service |
384592 |
cp--;
|
|
Packit Service |
384592 |
if (cp > cbuf && cp[-1] == '\\') {
|
|
Packit Service |
384592 |
cp--;
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* line continuation requested -
|
|
Packit Service |
384592 |
* then remove backslash and continue
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
cbufsize -= (cp-cbuf);
|
|
Packit Service |
384592 |
cbuf = cp;
|
|
Packit Service |
384592 |
continue;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (cp - buf >= bufsize - 1) {
|
|
Packit Service |
384592 |
return APR_ENOSPC;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
} else {
|
|
Packit Service |
384592 |
/* No "get string" function defined; read character by character */
|
|
Packit Service |
384592 |
apr_size_t i = 0;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (bufsize < 2) {
|
|
Packit Service |
384592 |
/* too small, assume caller is crazy */
|
|
Packit Service |
384592 |
return APR_EINVAL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
buf[0] = '\0';
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (1) {
|
|
Packit Service |
384592 |
char c;
|
|
Packit Service |
384592 |
rc = cfp->getch(&c, cfp->param);
|
|
Packit Service |
384592 |
if (rc == APR_EOF) {
|
|
Packit Service |
384592 |
if (i > 0)
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
else
|
|
Packit Service |
384592 |
return APR_EOF;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (rc != APR_SUCCESS)
|
|
Packit Service |
384592 |
return rc;
|
|
Packit Service |
384592 |
if (c == LF) {
|
|
Packit Service |
384592 |
++cfp->line_number;
|
|
Packit Service |
384592 |
/* check for line continuation */
|
|
Packit Service |
384592 |
if (i > 0 && buf[i-1] == '\\') {
|
|
Packit Service |
384592 |
i--;
|
|
Packit Service |
384592 |
continue;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (i >= bufsize - 2) {
|
|
Packit Service |
384592 |
return APR_ENOSPC;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
buf[i] = c;
|
|
Packit Service |
384592 |
++i;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
buf[i] = '\0';
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
return APR_SUCCESS;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int cfg_trim_line(char *buf)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
char *start, *end;
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* Leading and trailing white space is eliminated completely
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
start = buf;
|
|
Packit Service |
384592 |
while (apr_isspace(*start))
|
|
Packit Service |
384592 |
++start;
|
|
Packit Service |
384592 |
/* blast trailing whitespace */
|
|
Packit Service |
384592 |
end = &start[strlen(start)];
|
|
Packit Service |
384592 |
while (--end >= start && apr_isspace(*end))
|
|
Packit Service |
384592 |
*end = '\0';
|
|
Packit Service |
384592 |
/* Zap leading whitespace by shifting */
|
|
Packit Service |
384592 |
if (start != buf)
|
|
Packit Service |
384592 |
memmove(buf, start, end - start + 2);
|
|
Packit Service |
384592 |
#ifdef DEBUG_CFG_LINES
|
|
Packit Service |
384592 |
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, APLOGNO(00555) "Read config: '%s'", buf);
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
return end - start + 1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, apr_size_t bufsize,
|
|
Packit Service |
384592 |
ap_configfile_t *cfp)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_status_t rc = ap_cfg_getline_core(buf, bufsize, cfp);
|
|
Packit Service |
384592 |
if (rc == APR_SUCCESS)
|
|
Packit Service |
384592 |
cfg_trim_line(buf);
|
|
Packit Service |
384592 |
return rc;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static char *substring_conf(apr_pool_t *p, const char *start, int len,
|
|
Packit Service |
384592 |
char quote)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
char *result = apr_palloc(p, len + 2);
|
|
Packit Service |
384592 |
char *resp = result;
|
|
Packit Service |
384592 |
int i;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
for (i = 0; i < len; ++i) {
|
|
Packit Service |
384592 |
if (start[i] == '\\' && (start[i + 1] == '\\'
|
|
Packit Service |
384592 |
|| (quote && start[i + 1] == quote)))
|
|
Packit Service |
384592 |
*resp++ = start[++i];
|
|
Packit Service |
384592 |
else
|
|
Packit Service |
384592 |
*resp++ = start[i];
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
*resp++ = '\0';
|
|
Packit Service |
384592 |
#if RESOLVE_ENV_PER_TOKEN
|
|
Packit Service |
384592 |
return (char *)ap_resolve_env(p,result);
|
|
Packit Service |
384592 |
#else
|
|
Packit Service |
384592 |
return result;
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
AP_DECLARE(char *) ap_getword_conf(apr_pool_t *p, const char **line)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
const char *str = *line, *strend;
|
|
Packit Service |
384592 |
char *res;
|
|
Packit Service |
384592 |
char quote;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (*str && apr_isspace(*str))
|
|
Packit Service |
384592 |
++str;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (!*str) {
|
|
Packit Service |
384592 |
*line = str;
|
|
Packit Service |
384592 |
return "";
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ((quote = *str) == '"' || quote == '\'') {
|
|
Packit Service |
384592 |
strend = str + 1;
|
|
Packit Service |
384592 |
while (*strend && *strend != quote) {
|
|
Packit Service |
384592 |
if (*strend == '\\' && strend[1] &&
|
|
Packit Service |
384592 |
(strend[1] == quote || strend[1] == '\\')) {
|
|
Packit Service |
384592 |
strend += 2;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
++strend;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
res = substring_conf(p, str + 1, strend - str - 1, quote);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*strend == quote)
|
|
Packit Service |
384592 |
++strend;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
strend = str;
|
|
Packit Service |
384592 |
while (*strend && !apr_isspace(*strend))
|
|
Packit Service |
384592 |
++strend;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
res = substring_conf(p, str, strend - str, 0);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (*strend && apr_isspace(*strend))
|
|
Packit Service |
384592 |
++strend;
|
|
Packit Service |
384592 |
*line = strend;
|
|
Packit Service |
384592 |
return res;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Open a ap_configfile_t as FILE, return open ap_configfile_t struct pointer */
|
|
Packit Service |
384592 |
AP_DECLARE(apr_status_t) ap_pcfg_openfile(ap_configfile_t **ret_cfg,
|
|
Packit Service |
384592 |
apr_pool_t *p, const char *name)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
ap_configfile_t *new_cfg;
|
|
Packit Service |
384592 |
apr_file_t *file = NULL;
|
|
Packit Service |
384592 |
apr_finfo_t finfo;
|
|
Packit Service |
384592 |
apr_status_t status;
|
|
Packit Service |
384592 |
int exist_type;
|
|
Packit Service |
384592 |
#ifdef DEBUG
|
|
Packit Service |
384592 |
char buf[120];
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (name == NULL) {
|
|
Packit Service |
384592 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
|
Packit Service |
384592 |
"Internal error: pcfg_openfile() called with NULL filename");
|
|
Packit Service |
384592 |
return APR_EBADF;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
status = apr_file_open(&file, name, APR_READ | APR_BUFFERED,
|
|
Packit Service |
384592 |
APR_OS_DEFAULT, p);
|
|
Packit Service |
384592 |
#ifdef DEBUG
|
|
Packit Service |
384592 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
|
|
Packit Service |
384592 |
"Opening config file %s (%s)",
|
|
Packit Service |
384592 |
name, (status != APR_SUCCESS) ?
|
|
Packit Service |
384592 |
apr_strerror(status, buf, sizeof(buf)) : "successful");
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
if (status != APR_SUCCESS)
|
|
Packit Service |
384592 |
return status;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
status = apr_file_info_get(&finfo, APR_FINFO_TYPE, file);
|
|
Packit Service |
384592 |
if (status != APR_SUCCESS)
|
|
Packit Service |
384592 |
return status;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
exist_type = (finfo.filetype != APR_REG);
|
|
Packit Service |
384592 |
#if defined(WIN32) || defined(OS2) || defined(NETWARE)
|
|
Packit Service |
384592 |
exist_type = (exist_type && strcasecmp(apr_filepath_name_get(name), "nul") != 0);
|
|
Packit Service |
384592 |
#else
|
|
Packit Service |
384592 |
exist_type = (exist_type && strcmp(name, "/dev/null") != 0);
|
|
Packit Service |
384592 |
#endif /* WIN32 || OS2 */
|
|
Packit Service |
384592 |
if (exist_type){ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
|
Packit Service |
384592 |
"Access to file %s denied by server: not a regular file",
|
|
Packit Service |
384592 |
name);
|
|
Packit Service |
384592 |
apr_file_close(file);
|
|
Packit Service |
384592 |
return APR_EBADF;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#ifdef WIN32
|
|
Packit Service |
384592 |
/* Some twisted character [no pun intended] at MS decided that a
|
|
Packit Service |
384592 |
* zero width joiner as the lead wide character would be ideal for
|
|
Packit Service |
384592 |
* describing Unicode text files. This was further convoluted to
|
|
Packit Service |
384592 |
* another MSism that the same character mapped into utf-8, EF BB BF
|
|
Packit Service |
384592 |
* would signify utf-8 text files.
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* Since MS configuration files are all protecting utf-8 encoded
|
|
Packit Service |
384592 |
* Unicode path, file and resource names, we already have the correct
|
|
Packit Service |
384592 |
* WinNT encoding. But at least eat the stupid three bytes up front.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
unsigned char buf[4];
|
|
Packit Service |
384592 |
apr_size_t len = 3;
|
|
Packit Service |
384592 |
status = apr_file_read(file, buf, &len;;
|
|
Packit Service |
384592 |
if ((status != APR_SUCCESS) || (len < 3)
|
|
Packit Service |
384592 |
|| memcmp(buf, "\xEF\xBB\xBF", 3) != 0) {
|
|
Packit Service |
384592 |
apr_off_t zero = 0;
|
|
Packit Service |
384592 |
apr_file_seek(file, APR_SET, &zero);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
new_cfg = apr_palloc(p, sizeof(*new_cfg));
|
|
Packit Service |
384592 |
new_cfg->param = file;
|
|
Packit Service |
384592 |
new_cfg->name = apr_pstrdup(p, name);
|
|
Packit Service |
384592 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
|
|
Packit Service |
384592 |
new_cfg->getch = (int (*)(void *)) cfg_getch;
|
|
Packit Service |
384592 |
new_cfg->getstr = (void *(*)(void *, size_t, void *)) cfg_getstr;
|
|
Packit Service |
384592 |
new_cfg->close = (int (*)(void *)) cfg_close;
|
|
Packit Service |
384592 |
#else
|
|
Packit Service |
384592 |
new_cfg->getch = cfg_getch;
|
|
Packit Service |
384592 |
new_cfg->getstr = cfg_getstr;
|
|
Packit Service |
384592 |
new_cfg->close = cfg_close;
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
new_cfg->line_number = 0;
|
|
Packit Service |
384592 |
*ret_cfg = new_cfg;
|
|
Packit Service |
384592 |
return APR_SUCCESS;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name,
|
|
Packit Service |
384592 |
const command_rec *cmds)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
while (cmds->name) {
|
|
Packit Service |
384592 |
if (!strcasecmp(name, cmds->name))
|
|
Packit Service |
384592 |
return cmds;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
++cmds;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#define AP_MAX_ARGC 64
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
|
|
Packit Service |
384592 |
void *mconfig, const char *args)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
char *w, *w2, *w3;
|
|
Packit Service |
384592 |
const char *errmsg = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if ((parms->override & cmd->req_override) == 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name, " not allowed here", NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
parms->info = cmd->cmd_data;
|
|
Packit Service |
384592 |
parms->cmd = cmd;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
switch (cmd->args_how) {
|
|
Packit Service |
384592 |
case RAW_ARGS:
|
|
Packit Service |
384592 |
#ifdef RESOLVE_ENV_PER_TOKEN
|
|
Packit Service |
384592 |
args = ap_resolve_env(parms->pool,args);
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
return cmd->AP_RAW_ARGS(parms, mconfig, args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case TAKE_ARGV:
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
char *argv[AP_MAX_ARGC];
|
|
Packit Service |
384592 |
int argc = 0;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
do {
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
if (*w == '\0' && *args == '\0') {
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
argv[argc] = w;
|
|
Packit Service |
384592 |
argc++;
|
|
Packit Service |
384592 |
} while (argc < AP_MAX_ARGC && *args != '\0');
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_TAKE_ARGV(parms, mconfig, argc, argv);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case NO_ARGS:
|
|
Packit Service |
384592 |
if (*args != 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name, " takes no arguments",
|
|
Packit Service |
384592 |
NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_NO_ARGS(parms, mconfig);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case TAKE1:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || *args != 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name, " takes one argument",
|
|
Packit Service |
384592 |
cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_TAKE1(parms, mconfig, w);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case TAKE2:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
w2 = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || *w2 == '\0' || *args != 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name, " takes two arguments",
|
|
Packit Service |
384592 |
cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_TAKE2(parms, mconfig, w, w2);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case TAKE12:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
w2 = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || *args != 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
|
|
Packit Service |
384592 |
cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_TAKE2(parms, mconfig, w, *w2 ? w2 : NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case TAKE3:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
w2 = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
w3 = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name, " takes three arguments",
|
|
Packit Service |
384592 |
cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case TAKE23:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
w2 = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || *w2 == '\0' || *args != 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name,
|
|
Packit Service |
384592 |
" takes two or three arguments",
|
|
Packit Service |
384592 |
cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case TAKE123:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
|
|
Packit Service |
384592 |
w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || *args != 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name,
|
|
Packit Service |
384592 |
" takes one, two or three arguments",
|
|
Packit Service |
384592 |
cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case TAKE13:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
|
|
Packit Service |
384592 |
w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || (w2 && *w2 && !w3) || *args != 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name,
|
|
Packit Service |
384592 |
" takes one or three arguments",
|
|
Packit Service |
384592 |
cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case ITERATE:
|
|
Packit Service |
384592 |
while (*(w = ap_getword_conf(parms->pool, &args)) != '\0') {
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
errmsg = cmd->AP_TAKE1(parms, mconfig, w);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
|
|
Packit Service |
384592 |
return errmsg;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return errmsg;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case ITERATE2:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || *args == 0)
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name,
|
|
Packit Service |
384592 |
" requires at least two arguments",
|
|
Packit Service |
384592 |
cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0') {
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
errmsg = cmd->AP_TAKE2(parms, mconfig, w, w2);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
|
|
Packit Service |
384592 |
return errmsg;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return errmsg;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case FLAG:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp(w, "off")))
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name, " must be On or Off",
|
|
Packit Service |
384592 |
NULL);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return cmd->AP_FLAG(parms, mconfig, strcasecmp(w, "off") != 0);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
default:
|
|
Packit Service |
384592 |
return apr_pstrcat(parms->pool, cmd->name,
|
|
Packit Service |
384592 |
" is improperly configured internally (server bug)",
|
|
Packit Service |
384592 |
NULL);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
|
|
Packit Service |
384592 |
static cmd_parms default_parms =
|
|
Packit Service |
384592 |
{NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 3
|
|
Packit Service |
384592 |
static cmd_parms default_parms =
|
|
Packit Service |
384592 |
{NULL, 0, 0, NULL, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
typedef struct {
|
|
Packit Service |
384592 |
const char *fname;
|
|
Packit Service |
384592 |
} fnames;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_finfo_t finfo;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS)
|
|
Packit Service |
384592 |
return 0; /* in error condition, just return no */
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return (finfo.filetype == APR_DIR);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
AP_DECLARE(char *) ap_make_full_path(apr_pool_t *a, const char *src1,
|
|
Packit Service |
384592 |
const char *src2)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_size_t len1, len2;
|
|
Packit Service |
384592 |
char *path;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
len1 = strlen(src1);
|
|
Packit Service |
384592 |
len2 = strlen(src2);
|
|
Packit Service |
384592 |
/* allocate +3 for '/' delimiter, trailing NULL and overallocate
|
|
Packit Service |
384592 |
* one extra byte to allow the caller to add a trailing '/'
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
path = (char *)apr_palloc(a, len1 + len2 + 3);
|
|
Packit Service |
384592 |
if (len1 == 0) {
|
|
Packit Service |
384592 |
*path = '/';
|
|
Packit Service |
384592 |
memcpy(path + 1, src2, len2 + 1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
char *next;
|
|
Packit Service |
384592 |
memcpy(path, src1, len1);
|
|
Packit Service |
384592 |
next = path + len1;
|
|
Packit Service |
384592 |
if (next[-1] != '/') {
|
|
Packit Service |
384592 |
*next++ = '/';
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
memcpy(next, src2, len2 + 1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
return path;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static int fname_alphasort(const void *fn1, const void *fn2)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
const fnames *f1 = fn1;
|
|
Packit Service |
384592 |
const fnames *f2 = fn2;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return strcmp(f1->fname,f2->fname);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
int fnmatch_test(const char *pattern)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
int nesting;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
nesting = 0;
|
|
Packit Service |
384592 |
while (*pattern) {
|
|
Packit Service |
384592 |
switch (*pattern) {
|
|
Packit Service |
384592 |
case '?':
|
|
Packit Service |
384592 |
case '*':
|
|
Packit Service |
384592 |
return 1;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* case '\\':
|
|
Packit Service |
384592 |
if (*++pattern == '\0') {
|
|
Packit Service |
384592 |
return 0;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
break;*/ // this breaks on Windows
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case '[': /* '[' is only a glob if it has a matching ']' */
|
|
Packit Service |
384592 |
++nesting;
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
case ']':
|
|
Packit Service |
384592 |
if (nesting) {
|
|
Packit Service |
384592 |
return 1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
++pattern; }
|
|
Packit Service |
384592 |
return 0;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
AP_DECLARE(const char *) process_resource_config(const char *fname,
|
|
Packit Service |
384592 |
apr_array_header_t *ari,
|
|
Packit Service |
384592 |
apr_pool_t *ptemp)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
*(char **)apr_array_push(ari) = (char *)fname;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static const char *process_resource_config_nofnmatch(const char *fname,
|
|
Packit Service |
384592 |
apr_array_header_t *ari,
|
|
Packit Service |
384592 |
apr_pool_t *p,
|
|
Packit Service |
384592 |
apr_pool_t *ptemp,
|
|
Packit Service |
384592 |
unsigned depth,
|
|
Packit Service |
384592 |
int optional)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
const char *error;
|
|
Packit Service |
384592 |
apr_status_t rv;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (ap_is_directory(ptemp, fname)) {
|
|
Packit Service |
384592 |
apr_dir_t *dirp;
|
|
Packit Service |
384592 |
apr_finfo_t dirent;
|
|
Packit Service |
384592 |
int current;
|
|
Packit Service |
384592 |
apr_array_header_t *candidates = NULL;
|
|
Packit Service |
384592 |
fnames *fnew;
|
|
Packit Service |
384592 |
char *path = apr_pstrdup(ptemp, fname);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (++depth > 100) {
|
|
Packit Service |
384592 |
return apr_psprintf(p, "Directory %s exceeds the maximum include "
|
|
Packit Service |
384592 |
"directory nesting level of %u. You have "
|
|
Packit Service |
384592 |
"probably a recursion somewhere.", path,
|
|
Packit Service |
384592 |
100);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* first course of business is to grok all the directory
|
|
Packit Service |
384592 |
* entries here and store 'em away. Recall we need full pathnames
|
|
Packit Service |
384592 |
* for this.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
rv = apr_dir_open(&dirp, path, ptemp);
|
|
Packit Service |
384592 |
if (rv != APR_SUCCESS) {
|
|
Packit Service |
384592 |
char errmsg[120];
|
|
Packit Service |
384592 |
return apr_psprintf(p, "Could not open config directory %s: %s",
|
|
Packit Service |
384592 |
path, apr_strerror(rv, errmsg, sizeof errmsg));
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
candidates = apr_array_make(ptemp, 1, sizeof(fnames));
|
|
Packit Service |
384592 |
while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
|
|
Packit Service |
384592 |
/* strip out '.' and '..' */
|
|
Packit Service |
384592 |
if (strcmp(dirent.name, ".")
|
|
Packit Service |
384592 |
&& strcmp(dirent.name, "..")) {
|
|
Packit Service |
384592 |
fnew = (fnames *) apr_array_push(candidates);
|
|
Packit Service |
384592 |
fnew->fname = ap_make_full_path(ptemp, path, dirent.name);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_dir_close(dirp);
|
|
Packit Service |
384592 |
if (candidates->nelts != 0) {
|
|
Packit Service |
384592 |
qsort((void *) candidates->elts, candidates->nelts,
|
|
Packit Service |
384592 |
sizeof(fnames), fname_alphasort);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* Now recurse these... we handle errors and subdirectories
|
|
Packit Service |
384592 |
* via the recursion, which is nice
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
for (current = 0; current < candidates->nelts; ++current) {
|
|
Packit Service |
384592 |
fnew = &((fnames *) candidates->elts)[current];
|
|
Packit Service |
384592 |
error = process_resource_config_nofnmatch(fnew->fname,
|
|
Packit Service |
384592 |
ari, p, ptemp,
|
|
Packit Service |
384592 |
depth, optional);
|
|
Packit Service |
384592 |
if (error) {
|
|
Packit Service |
384592 |
return error;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return process_resource_config(fname, ari, ptemp);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
static const char *process_resource_config_fnmatch(const char *path,
|
|
Packit Service |
384592 |
const char *fname,
|
|
Packit Service |
384592 |
apr_array_header_t *ari,
|
|
Packit Service |
384592 |
apr_pool_t *p,
|
|
Packit Service |
384592 |
apr_pool_t *ptemp,
|
|
Packit Service |
384592 |
unsigned depth,
|
|
Packit Service |
384592 |
int optional)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
const char *rest;
|
|
Packit Service |
384592 |
apr_status_t rv;
|
|
Packit Service |
384592 |
apr_dir_t *dirp;
|
|
Packit Service |
384592 |
apr_finfo_t dirent;
|
|
Packit Service |
384592 |
apr_array_header_t *candidates = NULL;
|
|
Packit Service |
384592 |
fnames *fnew;
|
|
Packit Service |
384592 |
int current;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* find the first part of the filename */
|
|
Packit Service |
384592 |
rest = ap_strchr_c(fname, '/');
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(rest == NULL)
|
|
Packit Service |
384592 |
rest = ap_strchr_c(fname, '\\');
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (rest) {
|
|
Packit Service |
384592 |
fname = apr_pstrndup(ptemp, fname, rest - fname);
|
|
Packit Service |
384592 |
rest++;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* optimisation - if the filename isn't a wildcard, process it directly */
|
|
Packit Service |
384592 |
if (!fnmatch_test(fname)) {
|
|
Packit Service |
384592 |
path = ap_make_full_path(ptemp, path, fname);
|
|
Packit Service |
384592 |
if (!rest) {
|
|
Packit Service |
384592 |
return process_resource_config_nofnmatch(path,
|
|
Packit Service |
384592 |
ari, p,
|
|
Packit Service |
384592 |
ptemp, 0, optional);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
return process_resource_config_fnmatch(path, rest,
|
|
Packit Service |
384592 |
ari, p,
|
|
Packit Service |
384592 |
ptemp, 0, optional);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* first course of business is to grok all the directory
|
|
Packit Service |
384592 |
* entries here and store 'em away. Recall we need full pathnames
|
|
Packit Service |
384592 |
* for this.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
rv = apr_dir_open(&dirp, path, ptemp);
|
|
Packit Service |
384592 |
if (rv != APR_SUCCESS) {
|
|
Packit Service |
384592 |
char errmsg[120];
|
|
Packit Service |
384592 |
return apr_psprintf(p, "Could not open config directory %s: %s",
|
|
Packit Service |
384592 |
path, apr_strerror(rv, errmsg, sizeof errmsg));
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
candidates = apr_array_make(ptemp, 1, sizeof(fnames));
|
|
Packit Service |
384592 |
while (apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_TYPE, dirp) == APR_SUCCESS) {
|
|
Packit Service |
384592 |
/* strip out '.' and '..' */
|
|
Packit Service |
384592 |
if (strcmp(dirent.name, ".")
|
|
Packit Service |
384592 |
&& strcmp(dirent.name, "..")
|
|
Packit Service |
384592 |
&& (apr_fnmatch(fname, dirent.name,
|
|
Packit Service |
384592 |
APR_FNM_PERIOD | APR_FNM_NOESCAPE | APR_FNM_PATHNAME) == APR_SUCCESS)) {
|
|
Packit Service |
384592 |
const char *full_path = ap_make_full_path(ptemp, path, dirent.name);
|
|
Packit Service |
384592 |
/* If matching internal to path, and we happen to match something
|
|
Packit Service |
384592 |
* other than a directory, skip it
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
if (rest && (rv == APR_SUCCESS) && (dirent.filetype != APR_DIR)) {
|
|
Packit Service |
384592 |
continue;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
fnew = (fnames *) apr_array_push(candidates);
|
|
Packit Service |
384592 |
fnew->fname = full_path;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_dir_close(dirp);
|
|
Packit Service |
384592 |
if (candidates->nelts != 0) {
|
|
Packit Service |
384592 |
const char *error;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
qsort((void *) candidates->elts, candidates->nelts,
|
|
Packit Service |
384592 |
sizeof(fnames), fname_alphasort);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* Now recurse these... we handle errors and subdirectories
|
|
Packit Service |
384592 |
* via the recursion, which is nice
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
for (current = 0; current < candidates->nelts; ++current) {
|
|
Packit Service |
384592 |
fnew = &((fnames *) candidates->elts)[current];
|
|
Packit Service |
384592 |
if (!rest) {
|
|
Packit Service |
384592 |
error = process_resource_config_nofnmatch(fnew->fname,
|
|
Packit Service |
384592 |
ari, p,
|
|
Packit Service |
384592 |
ptemp, 0, optional);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
error = process_resource_config_fnmatch(fnew->fname, rest,
|
|
Packit Service |
384592 |
ari, p,
|
|
Packit Service |
384592 |
ptemp, 0, optional);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (error) {
|
|
Packit Service |
384592 |
return error;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (!optional) {
|
|
Packit Service |
384592 |
return apr_psprintf(p, "No matches for the wildcard '%s' in '%s', failing "
|
|
Packit Service |
384592 |
"(use IncludeOptional if required)", fname, path);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
AP_DECLARE(const char *) process_fnmatch_configs(apr_array_header_t *ari,
|
|
Packit Service |
384592 |
const char *fname,
|
|
Packit Service |
384592 |
apr_pool_t *p,
|
|
Packit Service |
384592 |
apr_pool_t *ptemp,
|
|
Packit Service |
384592 |
int optional)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
if (!fnmatch_test(fname)) {
|
|
Packit Service |
384592 |
return process_resource_config(fname, ari, p);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else {
|
|
Packit Service |
384592 |
apr_status_t status;
|
|
Packit Service |
384592 |
const char *rootpath, *filepath = fname;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* locate the start of the directories proper */
|
|
Packit Service |
384592 |
status = apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME | APR_FILEPATH_NATIVE, ptemp);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* we allow APR_SUCCESS and APR_EINCOMPLETE */
|
|
Packit Service |
384592 |
if (APR_ERELATIVE == status) {
|
|
Packit Service |
384592 |
return apr_pstrcat(p, "Include must have an absolute path, ", fname, NULL);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (APR_EBADPATH == status) {
|
|
Packit Service |
384592 |
return apr_pstrcat(p, "Include has a bad path, ", fname, NULL);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* walk the filepath */
|
|
Packit Service |
384592 |
return process_resource_config_fnmatch(rootpath, filepath, ari, p, ptemp,
|
|
Packit Service |
384592 |
0, optional);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
const char *populate_include_files(apr_pool_t *p, apr_pool_t *ptemp, apr_array_header_t *ari, const char *fname, int optional)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
return process_fnmatch_configs(ari, fname, p, ptemp, optional);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
const char *process_command_config(server_rec *s,
|
|
Packit Service |
384592 |
void *mconfig,
|
|
Packit Service |
384592 |
apr_pool_t *p,
|
|
Packit Service |
384592 |
apr_pool_t *ptemp,
|
|
Packit Service |
384592 |
const char *filename)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
const char *errmsg;
|
|
Packit Service |
384592 |
char *l = apr_palloc (ptemp, MAX_STRING_LEN);
|
|
Packit Service |
384592 |
const char *args = l;
|
|
Packit Service |
384592 |
char *cmd_name, *w;
|
|
Packit Service |
384592 |
const command_rec *cmd;
|
|
Packit Service |
384592 |
apr_array_header_t *arr = apr_array_make(p, 1, sizeof(cmd_parms));
|
|
Packit Service |
384592 |
apr_array_header_t *ari = apr_array_make(p, 1, sizeof(char *));
|
|
Packit Service |
384592 |
cmd_parms *parms;
|
|
Packit Service |
384592 |
apr_status_t status;
|
|
Packit Service |
384592 |
ap_directive_t *newdir;
|
|
Packit Service |
384592 |
int optional;
|
|
Packit Service |
384592 |
char *err = NULL;
|
|
Packit Service |
384592 |
char *rootpath, *incpath;
|
|
Packit Service |
384592 |
int li;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
errmsg = populate_include_files(p, ptemp, ari, filename, 0);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(errmsg != NULL)
|
|
Packit Service |
384592 |
goto Exit;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while(ari->nelts != 0 || arr->nelts != 0)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
if(ari->nelts > 0)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
char *fn = *(char **)apr_array_pop(ari);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
parms = (cmd_parms *)apr_array_push(arr);
|
|
Packit Service |
384592 |
*parms = default_parms;
|
|
Packit Service |
384592 |
parms->pool = p;
|
|
Packit Service |
384592 |
parms->temp_pool = ptemp;
|
|
Packit Service |
384592 |
parms->server = s;
|
|
Packit Service |
384592 |
parms->override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
|
|
Packit Service |
384592 |
parms->override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
status = ap_pcfg_openfile(&parms->config_file, p, fn);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(status != APR_SUCCESS)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_array_pop(arr);
|
|
Packit Service |
384592 |
errmsg = apr_pstrcat(p, "Cannot open config file: ", fn, NULL);
|
|
Packit Service |
384592 |
goto Exit;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (arr->nelts > 1024) {
|
|
Packit Service |
384592 |
errmsg = "Exceeded the maximum include directory nesting level. You have "
|
|
Packit Service |
384592 |
"probably a recursion somewhere.";
|
|
Packit Service |
384592 |
goto Exit;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
parms = (cmd_parms *)apr_array_pop(arr);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(parms == NULL)
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
|
|
Packit Service |
384592 |
if (*l == '#' || *l == '\0')
|
|
Packit Service |
384592 |
continue;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
args = l;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
cmd_name = ap_getword_conf(p, &args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*cmd_name == '\0')
|
|
Packit Service |
384592 |
continue;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (!strcasecmp(cmd_name, "IncludeOptional"))
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
optional = 1;
|
|
Packit Service |
384592 |
goto ProcessInclude;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (!strcasecmp(cmd_name, "Include"))
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
optional = 0;
|
|
Packit Service |
384592 |
ProcessInclude:
|
|
Packit Service |
384592 |
w = ap_getword_conf(parms->pool, &args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (*w == '\0' || *args != 0)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
ap_cfg_closefile(parms->config_file);
|
|
Packit Service |
384592 |
errmsg = apr_pstrcat(parms->pool, "Include takes one argument", NULL);
|
|
Packit Service |
384592 |
goto Exit;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
incpath = w;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* locate the start of the directories proper */
|
|
Packit Service |
384592 |
status = apr_filepath_root(&rootpath, &incpath, APR_FILEPATH_TRUENAME | APR_FILEPATH_NATIVE, ptemp);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* we allow APR_SUCCESS and APR_EINCOMPLETE */
|
|
Packit Service |
384592 |
if (APR_ERELATIVE == status) {
|
|
Packit Service |
384592 |
rootpath = apr_pstrdup(ptemp, parms->config_file->name);
|
|
Packit Service |
384592 |
li = strlen(rootpath) - 1;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
while(li >= 0 && rootpath[li] != '/' && rootpath[li] != '\\')
|
|
Packit Service |
384592 |
rootpath[li--] = 0;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
w = apr_pstrcat(p, rootpath, w, NULL);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else if (APR_EBADPATH == status) {
|
|
Packit Service |
384592 |
ap_cfg_closefile(parms->config_file);
|
|
Packit Service |
384592 |
errmsg = apr_pstrcat(p, "Include file has a bad path, ", w, NULL);
|
|
Packit Service |
384592 |
goto Exit;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
errmsg = populate_include_files(p, ptemp, ari, w, optional);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
*(cmd_parms *)apr_array_push(arr) = *parms;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(errmsg != NULL)
|
|
Packit Service |
384592 |
goto Exit;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
// we don't want to close the current file yet
|
|
Packit Service |
384592 |
//
|
|
Packit Service |
384592 |
parms = NULL;
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
cmd = ap_find_command(cmd_name, security2_module.cmds);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(cmd == NULL)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
// unknown command, should error
|
|
Packit Service |
384592 |
//
|
|
Packit Service |
384592 |
ap_cfg_closefile(parms->config_file);
|
|
Packit Service |
384592 |
errmsg = apr_pstrcat(p, "Unknown command in config: ", cmd_name, NULL);
|
|
Packit Service |
384592 |
goto Exit;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
newdir = apr_pcalloc(p, sizeof(ap_directive_t));
|
|
Packit Service |
384592 |
newdir->filename = parms->config_file->name;
|
|
Packit Service |
384592 |
newdir->line_num = parms->config_file->line_number;
|
|
Packit Service |
384592 |
newdir->directive = cmd_name;
|
|
Packit Service |
384592 |
newdir->args = apr_pstrdup(p, args);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
parms->directive = newdir;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#ifdef WIN32
|
|
Packit Service |
384592 |
// some config commands fail in APR when there are file
|
|
Packit Service |
384592 |
// permission issues or other OS-specific problems
|
|
Packit Service |
384592 |
//
|
|
Packit Service |
384592 |
__try
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
errmsg = invoke_cmd(cmd, parms, mconfig, args);
|
|
Packit Service |
384592 |
#ifdef WIN32
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
errmsg = "Command failed to execute (check file/folder permissions, syntax, etc.).";
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(errmsg != NULL)
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(parms != NULL)
|
|
Packit Service |
384592 |
ap_cfg_closefile(parms->config_file);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(errmsg != NULL)
|
|
Packit Service |
384592 |
break;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (errmsg) {
|
|
Packit Service |
384592 |
err = (char *)apr_palloc(p, 1024);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if(parms != NULL)
|
|
Packit Service |
384592 |
apr_snprintf(err, 1024, "Syntax error in config file %s, line %d: %s", parms->config_file->name,
|
|
Packit Service |
384592 |
parms->config_file->line_number, errmsg);
|
|
Packit Service |
384592 |
else
|
|
Packit Service |
384592 |
apr_snprintf(err, 1024, "Syntax error in config file: %s", errmsg);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
errmsg = err;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
Exit:
|
|
Packit Service |
384592 |
while((parms = (cmd_parms *)apr_array_pop(arr)) != NULL)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
ap_cfg_closefile(parms->config_file);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return errmsg;
|
|
Packit Service |
384592 |
}
|