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 [patch 1.3.13] Win32/NW Filesystem '/' override patch
Date Thu, 14 Sep 2000 21:30:12 GMT
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

Bill


 
Index: main/http_request.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_request.c,v
retrieving revision 1.154
diff -u -u -5 -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:23:25
@@ -422,31 +422,50 @@
         --num_dirs;
 
     if (S_ISDIR(r->finfo.st_mode))
         ++num_dirs;
 
+#if defined(WIN32)
+    /* If the name is a UNC name, then do not walk through the
+     * machine and share name (start at //machine/share/)
+     */
+    if ((i == 1) && (test_filename[0] == '/') && (test_filename[1] == '/'))
+        iStart = 4;
+#elif defined(NETWARE)
+    /* If the name is a volume name, then do not walk through the
+     * machine and share name (start at machine/share:/)
+     * XXX: The implementation eludes me at this moment... 
+     *      Does this make sense?  Please test!
+
+    if (strchr(test_filename, '/') < strchr(test_filename, ':'))
+        iStart = 3;
+     */
+#endif
+
     /*
      * We will use test_dirname as scratch space while we build directory
      * names during the walk.  Profiling shows directory_walk to be a busy
      * function so we try to avoid allocating lots of extra memory here.
      * We need 2 extra bytes, one for trailing \0 and one because
      * make_dirstr_prefix will add potentially one extra /.
      */
     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 (num_dirs > 3 && test_filename[0] == '/' && test_filename[1] ==
'/')
-        iStart = 4;
-#endif
-
     /* j keeps track of which section we're on, see core_reorder_directories */
     j = 0;
-    for (i = iStart; i <= num_dirs; ++i) {
+#if defined(WIN32) || defined(NETWARE)
+    /* 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
+     */
+    for (i = 0; i <= num_dirs; ++i) {
+#else
+    for (i = 1; i <= num_dirs; ++i) {
+#endif
         int overrides_here;
         core_dir_config *core_dir = (core_dir_config *)
             ap_get_module_config(per_dir_defaults, &core_module);
 
         /*
@@ -458,10 +477,14 @@
         /*
          * Do symlink checks first, because they are done with the
          * 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);
             return res;
         }
@@ -481,11 +504,17 @@
                          ap_get_module_config(entry_config, &core_module);
             entry_dir = entry_core->d;
 
             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 */
+                || (entry_core->d_components > 1
+                && entry_core->d_components > i))
+#else
                 || entry_core->d_components > i)
+#endif /* def WIN32 || NETWARE*/                  
                 break;
 
             this_conf = NULL;
             if (entry_core->d_is_fnmatch) {
                 if (!ap_fnmatch(entry_dir, test_dirname, FNM_PATHNAME)) {
@@ -500,15 +529,28 @@
                                                          per_dir_defaults,
                                                          this_conf);
                 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 */
         }
         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;
 
             res = ap_parse_htaccess(&htaccess_conf, r, overrides_here,
                                  ap_pstrdup(r->pool, test_dirname),
Index: main/util.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/util.c,v
retrieving revision 1.186
diff -u -u -5 -r1.186 util.c
--- main/util.c	2000/07/30 01:24:03	1.186
+++ main/util.c	2000/09/14 21:23:26
@@ -534,13 +534,24 @@
  * examples:
  *    /a/b, 1  ==> /
  *    /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') {
 	    *d = '/';
 	    break;

     

Mime
View raw message