akosut 96/07/25 12:32:33
Modified: src alloc.c alloc.h buff.c conf.h http_bprintf.c
http_core.c http_core.h http_request.c
Log:
Add <Files> directive, and allow <Directory> and <Location> (and <Files>)
to use regex. Also fix <Location> "bug" and add regcomp() function.
Reviewed by: Randy Terbush, Brian Behlendorf
Revision Changes Path
1.8 +21 -0 apache/src/alloc.c
Index: alloc.c
===================================================================
RCS file: /export/home/cvs/apache/src/alloc.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C3 -r1.7 -r1.8
*** alloc.c 1996/07/21 14:49:01 1.7
--- alloc.c 1996/07/25 19:32:25 1.8
***************
*** 803,808 ****
--- 803,829 ----
return res;
}
+ /*
+ * Here's a pool-based interface to POSIX regex's regcomp().
+ * Note that we return regex_t instead of being passed one.
+ * The reason is that if you use an already-used regex_t structure,
+ * the memory that you've already allocated gets forgotten, and
+ * regfree() doesn't clear it. So we don't allow it.
+ */
+
+ static void regex_cleanup (void *preg) { regfree ((regex_t *)preg); }
+
+ regex_t *pregcomp(pool *p, const char *pattern, int cflags) {
+ regex_t *preg = palloc(p, sizeof(regex_t));
+
+ if (regcomp(preg, pattern, cflags))
+ return NULL;
+
+ register_cleanup (p, (void *)preg, regex_cleanup, regex_cleanup);
+
+ return preg;
+ }
+
/*****************************************************************
*
* More grotty system stuff... subprocesses. Frump. These don't use
1.7 +2 -0 apache/src/alloc.h
Index: alloc.h
===================================================================
RCS file: /export/home/cvs/apache/src/alloc.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -C3 -r1.6 -r1.7
*** alloc.h 1996/07/21 14:49:01 1.6
--- alloc.h 1996/07/25 19:32:26 1.7
***************
*** 207,212 ****
--- 207,214 ----
void note_cleanups_for_fd (pool *, int);
void kill_cleanups_for_fd (pool *p, int fd);
+ regex_t *pregcomp(pool *p, const char *pattern, int cflags);
+
/* routines to note closes... file descriptors are constrained enough
* on some systems that we want to support this.
*/
1.4 +1 -0 apache/src/buff.c
Index: buff.c
===================================================================
RCS file: /export/home/cvs/apache/src/buff.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C3 -r1.3 -r1.4
*** buff.c 1996/05/08 15:28:19 1.3
--- buff.c 1996/07/25 19:32:26 1.4
***************
*** 56,61 ****
--- 56,62 ----
#include <string.h>
#include <unistd.h>
+ #include "conf.h"
#include "alloc.h"
#include "buff.h"
1.24 +1 -0 apache/src/conf.h
Index: conf.h
===================================================================
RCS file: /export/home/cvs/apache/src/conf.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -C3 -r1.23 -r1.24
*** conf.h 1996/07/18 18:44:44 1.23
--- conf.h 1996/07/25 19:32:27 1.24
***************
*** 388,393 ****
--- 388,394 ----
#ifndef QNX
#include <memory.h>
#endif
+ #include "regex/regex.h"
#ifdef HAVE_RESOURCE
#include <sys/resource.h>
1.5 +1 -7 apache/src/http_bprintf.c
Index: http_bprintf.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_bprintf.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C3 -r1.4 -r1.5
*** http_bprintf.c 1996/07/16 19:57:25 1.4
--- http_bprintf.c 1996/07/25 19:32:27 1.5
***************
*** 13,27 ****
* 18 May 1996 Initial revision [Ben Laurie]
*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #ifndef QNX
- #include <memory.h>
- #endif
#include <assert.h>
#include <math.h>
#include "alloc.h"
#include "buff.h"
--- 13,21 ----
* 18 May 1996 Initial revision [Ben Laurie]
*/
#include <assert.h>
#include <math.h>
+ #include "conf.h"
#include "alloc.h"
#include "buff.h"
1.19 +78 -2 apache/src/http_core.c
Index: http_core.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -C3 -r1.18 -r1.19
*** http_core.c 1996/06/12 18:14:31 1.18
--- http_core.c 1996/07/25 19:32:28 1.19
***************
*** 93,98 ****
--- 93,101 ----
conf->hostname_lookups = 2;/* binary, but will use 2 as an "unset = on"
*/
conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate
default */
+
+ conf->sec = make_array (a, 2, sizeof(void *));
+
return (void *)conf;
}
***************
*** 107,112 ****
--- 110,116 ----
memcpy ((char *)conf, (const char *)base, sizeof(core_dir_config));
conf->d = new->d;
+ conf->r = new->r;
if (new->opts != OPT_UNSET) conf->opts = new->opts;
if (new->override != OR_UNSET) conf->override = new->override;
***************
*** 124,129 ****
--- 128,135 ----
if ((new->do_rfc1413 & 2) == 0) conf->do_rfc1413 = new->do_rfc1413;
if ((new->content_md5 & 2) == 0) conf->content_md5 = new->content_md5;
+ conf->sec = append_arrays (a, base->sec, new->sec);
+
return (void*)conf;
}
***************
*** 179,184 ****
--- 185,197 ----
*new_space = url_config;
}
+ void add_file_conf (core_dir_config *conf, void *url_config)
+ {
+ void **new_space = (void **) push_array (conf->sec);
+
+ *new_space = url_config;
+ }
+
/*****************************************************************
*
* There are some elements of the core config structures in which
***************
*** 518,536 ****
char *errmsg, *endp = strrchr (arg, '>');
int old_overrides = cmd->override;
char *old_path = cmd->path;
void *new_dir_conf = create_per_dir_config (cmd->pool);
if (endp) *endp = '\0';
if (cmd->path) return "<Directory> sections don't nest";
if (cmd->limited != -1) return "Can't have <Directory> within <Limit>";
!
cmd->path = getword_conf (cmd->pool, &arg);
cmd->override = OR_ALL|ACCESS_CONF;
errmsg = srm_command_loop (cmd, new_dir_conf);
add_per_dir_conf (cmd->server, new_dir_conf);
!
cmd->path = old_path;
cmd->override = old_overrides;
--- 531,559 ----
char *errmsg, *endp = strrchr (arg, '>');
int old_overrides = cmd->override;
char *old_path = cmd->path;
+ core_dir_config *conf;
void *new_dir_conf = create_per_dir_config (cmd->pool);
+ regex_t *r = NULL;
if (endp) *endp = '\0';
if (cmd->path) return "<Directory> sections don't nest";
if (cmd->limited != -1) return "Can't have <Directory> within <Limit>";
!
cmd->path = getword_conf (cmd->pool, &arg);
cmd->override = OR_ALL|ACCESS_CONF;
+ if (!strcmp(cmd->path, "~")) {
+ cmd->path = getword_conf (cmd->pool, &arg);
+ r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
+ }
+
errmsg = srm_command_loop (cmd, new_dir_conf);
add_per_dir_conf (cmd->server, new_dir_conf);
!
! conf = (core_dir_config *)get_module_config(new_dir_conf, &core_module);
! conf->r = r;
!
cmd->path = old_path;
cmd->override = old_overrides;
***************
*** 550,555 ****
--- 573,579 ----
int old_overrides = cmd->override;
char *old_path = cmd->path;
core_dir_config *conf;
+ regex_t *r = NULL;
void *new_url_conf = create_per_dir_config (cmd->pool);
***************
*** 561,571 ****
--- 585,601 ----
cmd->path = getword_conf (cmd->pool, &arg);
cmd->override = OR_ALL|ACCESS_CONF;
+ if (!strcmp(cmd->path, "~")) {
+ cmd->path = getword_conf (cmd->pool, &arg);
+ r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
+ }
+
errmsg = srm_command_loop (cmd, new_url_conf);
if (errmsg != end_url_magic) return errmsg;
conf = (core_dir_config *)get_module_config(new_url_conf, &core_module);
conf->d = pstrdup(cmd->pool, cmd->path); /* No mangling, please
*/
+ conf->r = r;
add_per_url_conf (cmd->server, new_url_conf);
***************
*** 575,580 ****
--- 605,654 ----
return NULL;
}
+ static char *end_file_magic = "</Files> outside of any <Files> section";
+
+ char *end_filesection (cmd_parms *cmd, void *dummy) {
+ return end_file_magic;
+ }
+
+ char *filesection (cmd_parms *cmd, core_dir_config *c, char *arg)
+ {
+ char *errmsg, *endp = strrchr (arg, '>');
+ char *old_path = cmd->path;
+ core_dir_config *conf;
+ regex_t *r = NULL;
+
+ void *new_file_conf = create_per_dir_config (cmd->pool);
+
+ if (endp) *endp = '\0';
+
+ if (cmd->limited != -1) return "Can't have <Files> within <Limit>";
+
+ cmd->path = getword_conf (cmd->pool, &arg);
+
+ if (!strcmp(cmd->path, "~")) {
+ cmd->path = getword_conf (cmd->pool, &arg);
+ if (old_path && cmd->path[0] != '/' && cmd->path[0] != '^')
+ cmd->path = pstrcat(cmd->pool, "^", old_path, cmd->path, NULL);
+ r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
+ }
+ else if (old_path && cmd->path[0] != '/')
+ cmd->path = pstrcat(cmd->pool, old_path, cmd->path, NULL);
+
+ errmsg = srm_command_loop (cmd, new_file_conf);
+ if (errmsg != end_file_magic) return errmsg;
+
+ conf = (core_dir_config *)get_module_config(new_file_conf,
&core_module);
+ conf->d = pstrdup(cmd->pool, cmd->path);
+ conf->r = r;
+
+ add_file_conf (c, new_file_conf);
+
+ cmd->path = old_path;
+
+ return NULL;
+ }
+
/* httpd.conf commands... beginning with the <VirtualHost> business */
char *end_virthost_magic = "</Virtualhost> out of place";
***************
*** 779,784 ****
--- 853,860 ----
{ "</Directory>", end_dirsection, NULL, ACCESS_CONF, NO_ARGS, NULL },
{ "<Location", urlsection, NULL, RSRC_CONF, RAW_ARGS, NULL },
{ "</Location>", end_urlsection, NULL, ACCESS_CONF, NO_ARGS, NULL },
+ { "<Files", filesection, NULL, OR_ALL, RAW_ARGS, NULL },
+ { "</Files>", end_filesection, NULL, OR_ALL, NO_ARGS, NULL },
{ "<Limit", limit, NULL, OR_ALL, RAW_ARGS, NULL },
{ "</Limit>", endlimit, NULL, OR_ALL, RAW_ARGS, NULL },
{ "AuthType", set_string_slot, (void*)XtOffsetOf(core_dir_config,
auth_type),
1.7 +5 -1 apache/src/http_core.h
Index: http_core.h
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -C3 -r1.6 -r1.7
*** http_core.h 1996/04/06 23:38:25 1.6
--- http_core.h 1996/07/25 19:32:28 1.7
***************
*** 152,157 ****
--- 152,161 ----
int hostname_lookups;
int do_rfc1413; /* See if client is advertising a username? */
+ /* Access control */
+ array_header *sec;
+ regex_t *r;
+
} core_dir_config;
/* Per-server core configuration */
***************
*** 165,171 ****
char *document_root;
/* Access control */
!
char *access_name;
array_header *sec;
array_header *sec_url;
--- 169,175 ----
char *document_root;
/* Access control */
!
char *access_name;
array_header *sec;
array_header *sec_url;
1.12 +97 -10 apache/src/http_request.c
Index: http_request.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_request.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C3 -r1.11 -r1.12
*** http_request.c 1996/07/01 18:10:29 1.11
--- http_request.c 1996/07/25 19:32:29 1.12
***************
*** 242,248 ****
entry_dir = entry_core->d;
this_conf = NULL;
! if (is_matchexp(entry_dir)) {
if (!strcmp_match(test_filename, entry_dir))
this_conf = entry_config;
}
--- 242,252 ----
entry_dir = entry_core->d;
this_conf = NULL;
! if (entry_core->r) {
! if (!regexec(entry_core->r, test_filename, 0, NULL, 0))
! this_conf = entry_config;
! }
! else if (is_matchexp(entry_dir)) {
if (!strcmp_match(test_filename, entry_dir))
this_conf = entry_config;
}
***************
*** 301,311 ****
(core_dir_config *)get_module_config(entry_config, &core_module);
entry_dir = entry_core->d;
! if (is_matchexp(entry_dir) && !strcmp_match(this_dir, entry_dir)) {
! /* Don't try this wildcard again --- if it ends in '*'
! * it'll match again, and subdirectories won't be able to
! * override it...
! */
sec[j] = NULL;
this_conf = entry_config;
}
--- 305,323 ----
(core_dir_config *)get_module_config(entry_config, &core_module);
entry_dir = entry_core->d;
! if (entry_core->r) {
! if (!regexec(entry_core->r, this_dir, 0, NULL,
! (j == num_sec) ? 0 : REG_NOTEOL)) {
! /* Don't try this wildcard again --- if it ends in '*'
! * it'll match again, and subdirectories won't be able to
! * override it...
! */
! sec[j] = NULL;
! this_conf = entry_config;
! }
! }
! else if (is_matchexp(entry_dir) &&
! !strcmp_match(this_dir, entry_dir)) {
sec[j] = NULL;
this_conf = entry_config;
}
***************
*** 359,365 ****
void *per_dir_defaults = r->per_dir_config;
core_dir_config **url = (core_dir_config **)url_array->elts;
! int num_url = url_array->nelts;
char *test_location = pstrdup (r->pool, r->uri);
/* Go through the location entries, and check for matches. */
--- 371,377 ----
void *per_dir_defaults = r->per_dir_config;
core_dir_config **url = (core_dir_config **)url_array->elts;
! int len, num_url = url_array->nelts;
char *test_location = pstrdup (r->pool, r->uri);
/* Go through the location entries, and check for matches. */
***************
*** 383,394 ****
get_module_config(entry_config, &core_module);
entry_url = entry_core->d;
this_conf = NULL;
! if (is_matchexp(entry_url)) {
if (!strcmp_match(test_location, entry_url))
this_conf = entry_config;
}
! else if (!strncmp (test_location, entry_url, strlen(entry_url)))
this_conf = entry_config;
if (this_conf)
--- 395,474 ----
get_module_config(entry_config, &core_module);
entry_url = entry_core->d;
+ len = strlen(entry_url);
+
this_conf = NULL;
!
! if (entry_core->r) {
! if (!regexec(entry_core->r, test_location, 0, NULL, 0))
! this_conf = entry_config;
! }
! else if (is_matchexp(entry_url)) {
if (!strcmp_match(test_location, entry_url))
this_conf = entry_config;
}
! else if (!strncmp (test_location, entry_url, len) &&
! (entry_url[len - 1] == '/' ||
! test_location[len] == '/' || test_location[len] == '\0'))
! this_conf = entry_config;
!
! if (this_conf)
! per_dir_defaults = merge_per_dir_configs (r->pool,
! per_dir_defaults, this_conf);
! }
!
! r->per_dir_config = per_dir_defaults;
! }
!
! return OK;
! }
!
! int file_walk (request_rec *r)
! {
! core_dir_config *conf = get_module_config(r->per_dir_config,
&core_module);
! array_header *file_array = copy_array (r->pool, conf->sec);
! void *per_dir_defaults = r->per_dir_config;
!
! core_dir_config **file = (core_dir_config **)file_array->elts;
! int len, num_files = file_array->nelts;
! char *test_file = pstrdup (r->pool, r->filename);
!
! /* Go through the file entries, and check for matches. */
!
! if (num_files) {
! void *this_conf, *entry_config;
! core_dir_config *entry_core;
! char *entry_file;
! int j;
!
! /*
! * we apply the directive sections in some order; should really try them
! * with the most general first.
! */
! for (j = 0; j < num_files; ++j) {
!
! entry_config = file[j];
! if (!entry_config) continue;
!
! entry_core =(core_dir_config *)
! get_module_config(entry_config, &core_module);
! entry_file = entry_core->d;
!
! len = strlen(entry_file);
!
! this_conf = NULL;
!
! if (entry_core->r) {
! if (!regexec(entry_core->r, test_file, 0, NULL, 0))
! this_conf = entry_config;
! }
! else if (is_matchexp(entry_file)) {
! if (!strcmp_match(test_file, entry_file))
! this_conf = entry_config;
! }
! else if (!strncmp (test_file, entry_file, len) &&
! (entry_file[len - 1] == '/' ||
! test_file[len] == '/' || test_file[len] == '\0'))
this_conf = entry_config;
if (this_conf)
***************
*** 513,518 ****
--- 593,599 ----
*/
if ((res = directory_walk (rnew))
+ || (res = file_walk (rnew))
|| (!some_auth_required (rnew) ? 0 :
((res = check_user_id (rnew)) || (res = check_auth (rnew))))
|| (res = check_access (rnew))
***************
*** 555,560 ****
--- 636,642 ----
make_full_path (rnew->pool, fdir, new_file));
if ((res = directory_walk (rnew))
+ || (res = file_walk (rnew))
|| (res = check_access (rnew))
|| (!some_auth_required (rnew) ? 0 :
((res = check_user_id (rnew)) && (res = check_auth (rnew))))
***************
*** 732,742 ****
die (access_status, r);
return;
}
!
if ((access_status = location_walk (r))) {
die (access_status, r);
return;
}
if ((access_status = check_access (r)) != 0) {
decl_die (access_status, "check access", r);
--- 814,829 ----
die (access_status, r);
return;
}
!
if ((access_status = location_walk (r))) {
die (access_status, r);
return;
}
+
+ if ((access_status = file_walk (r))) {
+ die (access_status, r);
+ return;
+ }
if ((access_status = check_access (r)) != 0) {
decl_die (access_status, "check access", r);