summaryrefslogtreecommitdiffstats
path: root/server/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/core.c')
-rw-r--r--server/core.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/server/core.c b/server/core.c
index d4d868d7d8..3585382460 100644
--- a/server/core.c
+++ b/server/core.c
@@ -4678,6 +4678,25 @@ static const char *set_merge_trailers(cmd_parms *cmd, void *dummy, int arg)
return NULL;
}
+#ifdef WIN32
+static const char *set_unc_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
+{
+ core_server_config *sconf = ap_get_core_module_config(cmd->server->module_config);
+ int i;
+ const char *err;
+
+ if ((err = ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST)) != NULL)
+ return err;
+
+ sconf->unc_list = apr_array_make(cmd->pool, argc, sizeof(char *));
+
+ for (i = 0; i < argc; i++) {
+ *(char **)apr_array_push(sconf->unc_list) = apr_pstrdup(cmd->pool, argv[i]);
+ }
+
+ return NULL;
+}
+#endif
/* Note --- ErrorDocument will now work from .htaccess files.
* The AllowOverride of Fileinfo allows webmasters to turn it off
*/
@@ -4781,6 +4800,10 @@ AP_INIT_TAKE1("FlushMaxThreshold", set_flush_max_threshold, NULL, RSRC_CONF,
AP_INIT_TAKE1("FlushMaxPipelined", set_flush_max_pipelined, NULL, RSRC_CONF,
"Maximum number of pipelined responses (pending) above which they are "
"flushed to the network"),
+#ifdef WIN32
+AP_INIT_TAKE_ARGV("UNCList", set_unc_list, NULL, RSRC_CONF,
+ "Controls what UNC hosts may be looked up"),
+#endif
/* Old server config file commands */
@@ -6001,6 +6024,84 @@ AP_CORE_DECLARE(apr_status_t) ap_get_pollfd_from_conn(conn_rec *c,
return ap_run_get_pollfd_from_conn(c, pfd, ptimeout);
}
+#ifdef WIN32
+static apr_status_t check_unc(const char *path, apr_pool_t *p)
+{
+ int i;
+ char *s, *teststring;
+ apr_status_t rv = APR_EACCES;
+ core_server_config *sconf = NULL;
+
+ if (!ap_server_conf) {
+ return APR_SUCCESS; /* this early, if we have a UNC, it's specified by an admin */
+ }
+
+ if (!path || (path != ap_strstr_c(path, "\\\\") &&
+ path != ap_strstr_c(path, "//"))) {
+ return APR_SUCCESS; /* not a UNC */
+ }
+
+ sconf = ap_get_core_module_config(ap_server_conf->module_config);
+ s = teststring = apr_pstrdup(p, path);
+ *s++ = '/';
+ *s++ = '/';
+
+ ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
+ "ap_filepath_merge: check converted path %s allowed %d",
+ teststring,
+ sconf->unc_list ? sconf->unc_list->nelts : 0);
+
+ for (i = 0; sconf->unc_list && i < sconf->unc_list->nelts; i++) {
+ char *configured_unc = ((char **)sconf->unc_list->elts)[i];
+ apr_uri_t uri;
+ if (APR_SUCCESS == apr_uri_parse(p, teststring, &uri) &&
+ (uri.hostinfo == NULL ||
+ !ap_cstr_casecmp(uri.hostinfo, configured_unc))) {
+ rv = APR_SUCCESS;
+ ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
+ "ap_filepath_merge: match %s %s",
+ uri.hostinfo, configured_unc);
+ break;
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
+ "ap_filepath_merge: no match %s %s", uri.hostinfo,
+ configured_unc);
+ }
+ }
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(10504)
+ "ap_filepath_merge: UNC path %s not allowed by UNCList", teststring);
+ }
+
+ return rv;
+}
+#endif
+
+AP_DECLARE(apr_status_t) ap_filepath_merge(char **newpath,
+ const char *rootpath,
+ const char *addpath,
+ apr_int32_t flags,
+ apr_pool_t *p)
+{
+#ifdef WIN32
+ apr_status_t rv;
+
+ if (APR_SUCCESS != (rv = check_unc(rootpath, p))) {
+ return rv;
+ }
+ if (APR_SUCCESS != (rv = check_unc(addpath, p))) {
+ return rv;
+ }
+#undef apr_filepath_merge
+#endif
+ return apr_filepath_merge(newpath, rootpath, addpath, flags, p);
+#ifdef WIN32
+#define apr_filepath_merge ap_filepath_merge
+#endif
+}
+
+
static void register_hooks(apr_pool_t *p)
{
errorlog_hash = apr_hash_make(p);