httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "William A. Rowe, Jr." <wr...@rowe-clan.net>
Subject Revised: [patch 1.3.13] Win32/NW Filesystem '/' override patch
Date Thu, 14 Sep 2000 21:57:53 GMT
Slight revision... some optimized and clarified behavior.

> From: William A. Rowe, Jr. [mailto:wrowe@rowe-clan.net]
> Sent: Thursday, September 14, 2000 4:30 PM
> 
> This patch:
> 
>   1. incorporates Tim Costello's fix from PR3412 to process the root
>      <Directory /> block of any request in Win32/Netware.
> 
>   2. fixes Win32 behavior to accept <Directory //>, 
> <Directory //server>
>      and so on, without actually tripping file system checks 
> (that would
>      be deadly.)
> 
>   3. proposes a similar fix for Netware to process <Directory 
> server/>,
>      <Directory server/vol:>, although I have no idea if it will work
>      at this moment.
> 
> Please review (carefully) and comment


Index: main/http_request.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_request.c,v
retrieving revision 1.154
diff -u -r1.154 http_request.c
--- main/http_request.c	2000/08/04 18:59:04	1.154
+++ main/http_request.c	2000/09/14 21:54:34
@@ -325,8 +325,11 @@
     char *test_filename;
     char *test_dirname;
     int res;
-    unsigned i, num_dirs, iStart;
+    unsigned i, num_dirs;
     int j, test_filename_len;
+#if defined(WIN32) || defined(NETWARE)
+    unsigned iStart;
+#endif
 
     /*
      * Are we dealing with a file? If not, we can (hopefuly) safely assume we
@@ -433,18 +436,49 @@
      */
     test_dirname = ap_palloc(r->pool, test_filename_len + 2);
 
-    iStart = 1;
-#ifdef WIN32
-    /* If the name is a UNC name, then do not walk through the
-     * machine and share name (e.g. \\machine\share\)
+#if defined(WIN32)
+    /* Should match <Directory> sections starting from '/', not 'e:/' 
+     * (for example).  WIN32/NETWARE do not have a single root directory,
+     * they have one for each filesystem.  Traditionally, Apache has treated 
+     * <Directory /> permissions as the base for the whole server, and this 
+     * tradition should probably be preserved. 
+     *
+     * NOTE: MUST SYNC WITH ap_make_dirstr_prefix() CHANGE IN src/main/util.c
+     *
+     * Also, If the name is a UNC name, then do not perform any true file test
+     * against the machine name (start at //machine/share/)
+     * This is optimized to use the normal walk (skips the redundant '/' root)
+     */
+    if (test_filename[0] == '/') {
+        if (test_filename[1] == '/')
+            iStart = 4;
+        else
+            iStart = 1;
+        i = 1;
+    }
+    else {
+        iStart = 1;
+        i = 0;
+    }
+#elif defined(NETWARE)
+    /* If the name is a fully qualified volume name, then do not perform any
+     * true file test on the machine name (start at machine/share:/)
+     * XXX: The implementation eludes me at this moment... 
+     *      Does this make sense?  Please test!
      */
-    if (num_dirs > 3 && test_filename[0] == '/' && test_filename[1] ==
'/')
-        iStart = 4;
+    if (strchr(test_filename, '/') < strchr(test_filename, ':'))
+        iStart = 3;
+    else
+        iStart = 1;
+    i = 0;
+#else
+    /* Normal file systems are rooted at '/' */
+    i = 1;
 #endif
 
     /* j keeps track of which section we're on, see core_reorder_directories */
     j = 0;
-    for (i = iStart; i <= num_dirs; ++i) {
+    for (; i <= num_dirs; ++i) {
         int overrides_here;
         core_dir_config *core_dir = (core_dir_config *)
             ap_get_module_config(per_dir_defaults, &core_module);
@@ -460,6 +494,10 @@
          * permissions appropriate to the *parent* directory...
          */
 
+#if defined(WIN32) || defined(NETWARE)
+        /* Test only legal names against the real filesystem */
+        if (i >= iStart)
+#endif
         if ((res = check_symlinks(test_dirname, core_dir->opts))) {
             ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                         "Symbolic link not allowed: %s", test_dirname);
@@ -483,7 +521,15 @@
 
             if (entry_core->r
 		|| !ap_os_is_path_absolute(entry_dir)
+#if defined(WIN32) || defined(NETWARE)
+    /* To account for the top-level "/" directory when i == 0 
+     * XXX: I think the net test is wrong... may fail ap_os_is_path_absolute
+     */
+                || (entry_core->d_components > 1
+                    && entry_core->d_components > i))
+#else
                 || entry_core->d_components > i)
+#endif /* def WIN32 || NETWARE */                  
                 break;
 
             this_conf = NULL;
@@ -502,11 +548,24 @@
                 core_dir = (core_dir_config *)
                            ap_get_module_config(per_dir_defaults, &core_module);
             }
+#if defined(WIN32) || defined(NETWARE)
+            /* So that other top-level directory sections (e.g. "e:/") aren't
+             * skipped when i == 0
+             * XXX: HUH?  I don't get you here, Tim... That's a level 1 section.
+             *      Did you mean fast-forward to the next?
+             */
+            else if (!i)
+                break;
+#endif /* def WIN32 || NETWARE */
         }
         overrides_here = core_dir->override;
 
         /* If .htaccess files are enabled, check for one. */
 
+#if defined(WIN32) || defined(NETWARE)
+        /* Test only legal names against the real filesystem */
+        if (i >= iStart)
+#endif
         if (overrides_here) {
             void *htaccess_conf = NULL;
 
Index: main/util.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/util.c,v
retrieving revision 1.186
diff -u -r1.186 util.c
--- main/util.c	2000/07/30 01:24:03	1.186
+++ main/util.c	2000/09/14 21:54:34
@@ -536,9 +536,20 @@
  *    /a/b, 2  ==> /a/
  *    /a/b, 3  ==> /a/b/
  *    /a/b, 4  ==> /a/b/
+ *
+ * *** MODIFIED FOR WIN32, so that if n == 0, "/" is returned in d
+ * *** with n == 1 and s == "e:/test.html", "e:/" is returned in d
+ * *** See also directory_walk in src/main/http_request.c
  */
 API_EXPORT(char *) ap_make_dirstr_prefix(char *d, const char *s, int n)
 {
+#if defined(WIN32) || defined(NETWARE)
+    if (!n) {
+        *d = '/';
+        *++d = 0;
+        return (d);
+    }
+#endif /* def WIN32 || NETWARE */
     for (;;) {
 	*d = *s;
 	if (*d == '\0') {


Mime
View raw message