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);
  
  
  

Reply via email to