Roxen.git / server / modules / filesystems / filesystem.pike

version» Context lines:

Roxen.git/server/modules/filesystems/filesystem.pike:1:   // This is a roxen module. (c) Informationsv√§varna AB 1996.      // This is a virtual "file-system".   // It will be located somewhere in the name-space of the server.   // Also inherited by some of the other filesystems.    - string cvs_version= "$Id: filesystem.pike,v 1.17 1997/06/11 23:20:17 grubba Exp $"; + string cvs_version= "$Id: filesystem.pike,v 1.18 1997/07/06 18:29:11 grubba Exp $";      #include <module.h>   #include <roxen.h>   #include <stat.h>      #if DEBUG_LEVEL > 20   # ifndef FILESYSTEM_DEBUG   # define FILESYSTEM_DEBUG   # endif   #endif
Roxen.git/server/modules/filesystems/filesystem.pike:85:       defvar("stat_cache", 1, "Cache the results of stat(2)",    TYPE_FLAG,    "This can speed up the retrieval of files up to 60/70% if you"    " use NFS, but it does use some memory.");       defvar("access_as_user", 0, "Access file as the logged in user",    TYPE_FLAG,    "EXPERIMENTAL. Access file as the logged in user.<br>\n"    "This is useful for eg named-ftp."); +  +  defvar("no_symlinks", 0, "Forbid access to symlinks", TYPE_FLAG, +  "EXPERIMENTAL.\n" +  "Forbid access to paths containing symbolic links.<br>\n" +  "NOTE: This can cause *alot* of lstat system-calls to be performed " +  "and can make the server much slower.");   }         mixed *register_module()   {    return ({    MODULE_LOCATION,    "Filesystem",    ("This is a virtual filesystem, use it to make files available to "+    "the users of your WWW-server. If you want to serve any 'normal' "
Roxen.git/server/modules/filesystems/filesystem.pike:218:    {    id->misc->stat = fs;    cache_set("stat_cache",(X),fs);    return fs[ST_SIZE];    }    return -1;   }      #define FILE_SIZE(X) (stat_cache?_file_size((X),id):Stdio.file_size(X))    + int contains_symlinks(string root, string path) + { +  array arr = path/"/"; +  +  foreach(arr - ({ "" }), path) { +  root += "/" + path; +  if (arr = file_stat(root, 1)) { +  if (arr[1] == -3) { +  return(1); +  } +  } else { +  return(0); +  } +  } +  return(0); + } +    mixed find_file( string f, object id )   {    object o;    int size;    string tmp; -  +  string oldf = f;   #ifdef FILESYSTEM_DEBUG    perror("FILESYSTEM: Request for "+f+"\n");   #endif    size = FILE_SIZE( f = path + f );       switch(id->method)    {    case "GET":    case "HEAD":    case "POST":
Roxen.git/server/modules/filesystems/filesystem.pike:269:    if (((int)id->misc->uid) && ((int)id->misc->gid) &&    (QUERY(access_as_user))) {    privs=((program)"privs")("Getting file", (int)id->misc->uid,    (int)id->misc->gid );    }       o = open( f, "r" );       privs = 0;    -  if(!o) +  if(!o || (QUERY(no_symlinks) && (contains_symlinks(path, oldf))))    {    errors++;    report_error("Open of " + f + " failed. Permission denied.\n");    return http_low_answer(403, "<h2>File exists, but access forbidden "    "by user</h2>");    }       id->realfile = f;    accesses++;   #ifdef COMPAT
Roxen.git/server/modules/filesystems/filesystem.pike:306:    "<h1>Permission to 'PUT' files denied</h1>");    puts++;       object privs;       if (((int)id->misc->uid) && ((int)id->misc->gid)) {    privs=((program)"privs")("Saving file", (int)id->misc->uid,    (int)id->misc->gid );    }    +  if (QUERY(no_symlinks) && (contains_symlinks(path, oldf))) { +  errors++; +  report_error("Creation of " + f + " failed. Permission denied.\n"); +  return http_low_answer(403, "<h2>Permission denied.</h2>"); +  } +     rm( f );    mkdirhier( f );    object to = open(f, "wc");       privs = 0;       if(!to)    {    id->misc->error_code = 403;    return 0;
Roxen.git/server/modules/filesystems/filesystem.pike:344:       case "DELETE":    if(!QUERY(delete) || size==-1)    {    id->misc->error_code = 405;    return 0;    }    if(QUERY(check_auth) && (!id->auth || !id->auth[0]))    return http_low_answer(403, "<h1>Permission to DELETE file denied</h1>");    +  if (QUERY(no_symlinks) && (contains_symlinks(path, oldf))) { +  errors++; +  report_error("Deletion of " + f + " failed. Permission denied.\n"); +  return http_low_answer(403, "<h2>Permission denied.</h2>"); +  } +     report_notice("DELETING the file "+f+"\n");    accesses++;       if (((int)id->misc->uid) && ((int)id->misc->gid)) {    privs=((program)"privs")("Deleting file", id->misc->uid, id->misc->gid );    }       if(!rm(f))    {    id->misc->error_code = 405;