*** request.c	Fri Aug 20 16:58:16 2004
--- request.c.sipb	Thu Sep 23 15:39:05 2004
***************
*** 342,347 ****
--- 342,349 ----
   */
  static int resolve_symlink(char *d, apr_finfo_t *lfi, int opts, apr_pool_t *p)
  {
+ #define AFS_ST_DEV 0x1234
+ 
      apr_finfo_t fi;
      int res;
      const char *savename;
***************
*** 353,395 ****
      /* Save the name from the valid bits. */
      savename = (lfi->valid & APR_FINFO_NAME) ? lfi->name : NULL;
  
!     if (opts & OPT_SYM_LINKS) {
!         if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME 
!                                                  | APR_FINFO_LINK), p)) 
!                  != APR_SUCCESS) {
              return HTTP_FORBIDDEN;
          }
  
!         /* Give back the target */
!         memcpy(lfi, &fi, sizeof(fi));
!         if (savename) {
!             lfi->name = savename;
!             lfi->valid |= APR_FINFO_NAME;
!         }
! 
!         return OK;
      }
  
!     /* OPT_SYM_OWNER only works if we can get the owner of
!      * both the file and symlink.  First fill in a missing
!      * owner of the symlink, then get the info of the target.
!      */
!     if (!(lfi->valid & APR_FINFO_OWNER)) {
!         if ((res = apr_lstat(&fi, d, lfi->valid | APR_FINFO_OWNER, p))
              != APR_SUCCESS) {
!             return HTTP_FORBIDDEN;
          }
!     }
  
!     if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME), p))
!         != APR_SUCCESS) {
          return HTTP_FORBIDDEN;
!     }
  
!     if (apr_compare_users(fi.user, lfi->user) != APR_SUCCESS) {
          return HTTP_FORBIDDEN;
      }
! 
      /* Give back the target */
      memcpy(lfi, &fi, sizeof(fi));
      if (savename) {
--- 355,406 ----
      /* Save the name from the valid bits. */
      savename = (lfi->valid & APR_FINFO_NAME) ? lfi->name : NULL;
  
!     /* first step: make sure it's not a symlink out of AFS */
!     
!     if (!(lfi->valid & APR_FINFO_DEV)) {
!         if ((res = apr_lstat(lfi, d, (lfi->valid | APR_FINFO_DEV) & ~(APR_FINFO_NAME), p))
!             != APR_SUCCESS) {
              return HTTP_FORBIDDEN;
          }
+     }
+     if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME), p))
+ 	!= APR_SUCCESS) {
+       return HTTP_FORBIDDEN;
+     }     
+     if (fi.device != AFS_ST_DEV) {
+       return HTTP_FORBIDDEN;
+     }
  
!     if (opts & OPT_SYM_LINKS) {
!       if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME 
!                                                  | APR_FINFO_LINK), p)) 
! 	  != APR_SUCCESS) {
! 	return HTTP_FORBIDDEN;
!       }
      }
  
!     if (opts & OPT_SYM_OWNER) {
!       /* OPT_SYM_OWNER only works if we can get the owner of
!        * both the file and symlink.  First fill in a missing
!        * owner of the symlink, then get the info of the target.
!        */
!       if (!(lfi->valid & APR_FINFO_OWNER)) {
!         if ((res = apr_lstat(lfi, d, lfi->valid | APR_FINFO_OWNER, p))
              != APR_SUCCESS) {
! 	  return HTTP_FORBIDDEN;
          }
!       }
  
!       if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME), p))
! 	  != APR_SUCCESS) {
          return HTTP_FORBIDDEN;
!       }
  
!       if (apr_compare_users(fi.user, lfi->user) != APR_SUCCESS) {
          return HTTP_FORBIDDEN;
+       }
      }
!     
      /* Give back the target */
      memcpy(lfi, &fi, sizeof(fi));
      if (savename) {
***************
*** 920,937 ****
               *      we know the canonical_filename matches to _this_ name, and
               * if...we have allowed symlinks
               * skip the lstat and dummy up an APR_DIR value for thisinfo.
               */
-             if (r->finfo.filetype
- #ifdef CASE_BLIND_FILESYSTEM
-                 && (filename_len <= canonical_len)
- #endif
-                 && ((opts.opts & (OPT_SYM_OWNER | OPT_SYM_LINKS)) == OPT_SYM_LINKS))
-             {
  
!                 thisinfo.filetype = APR_DIR;
!                 ++seg;
!                 continue;
!             }
  
              /* We choose apr_lstat here, rather that apr_stat, so that we
               * capture this path object rather than its target.  We will
--- 931,951 ----
               *      we know the canonical_filename matches to _this_ name, and
               * if...we have allowed symlinks
               * skip the lstat and dummy up an APR_DIR value for thisinfo.
+ 	     *
+ 	     * This doesn't work with the AFS checking, so take it out
               */
  
! /*             if (r->finfo.filetype */
! /* #ifdef CASE_BLIND_FILESYSTEM */
! /*                 && (filename_len <= canonical_len) */
! /* #endif */
! /*                 && ((opts.opts & (OPT_SYM_OWNER | OPT_SYM_LINKS)) == OPT_SYM_LINKS)) */
! /*             { */
! 
! /*                 thisinfo.filetype = APR_DIR; */
! /*                 ++seg; */
! /*                 continue; */
! /*             } */
  
              /* We choose apr_lstat here, rather that apr_stat, so that we
               * capture this path object rather than its target.  We will
