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

version» Context lines:

Roxen.git/server/modules/filesystems/userfs.pike:17:   #endif      #include <module.h>      //<locale-token project="mod_userfs">_</locale-token>   #define _(X,Y) _DEF_LOCALE("mod_userfs",X,Y)   // end of the locale related stuff      inherit "filesystem" : filesystem;    - constant cvs_version="$Id: userfs.pike,v 1.73 2011/01/26 10:00:22 wellhard Exp $"; + constant cvs_version="$Id$";   constant module_type = MODULE_LOCATION;   LocaleString module_name = _(1,"File systems: User file system");   LocaleString module_doc =   _(2,"A file system that gives access to files in the users' home\n"   "directories. The users and home directories are found through the\n"   "current authentication module. The files from the home directories are\n"   "mounted either in the virtual file system of the site or as sites of\n"   "their own. So on one server the user Anne's files might be mounted on\n"   "<tt>http://domain.com/home/anne/</tt> while another server might give\n"   "Anne a web site of her own at <tt>http://anne.domain.com/</tt>.\n");   constant module_unique = 0;    -  + // NB: MySQL 4.1 and later prefix hashes from their internal + // password hashing function with a single "*". cf [bug 7834].   #define BAD_PASSWORD(us) (query("only_password") && \ -  ((us[1] == "") || (us[1][0] == '*'))) +  ((us[1] == "") || \ +  ((us[1][0] == '*') && (us[1][-1] == '*'))))      int uid_was_zero()   {    return !(getuid() == 0); // Somewhat misnamed function.. :-)   }      int hide_searchpath()   {    return query("homedir");   }
Roxen.git/server/modules/filesystems/userfs.pike:70:    TYPE_FLAG|VAR_INITIAL,    _(5,"Mount only home directories for users with valid passwords."));       defvar("user_listing", 0, _(6,"Enable userlisting"), TYPE_FLAG|VAR_INITIAL,    _(7,"If set a listing of all users will be shown when you access the "    "mount point."));       defvar("banish_list", ({ "root", "daemon", "bin", "sys", "admin",    "lp", "smtp", "uucp", "nuucp", "listen",    "nobody", "noaccess", "ftp", "news", -  "postmaster" }), _(8,"Banish list"), +  "postmaster", ".htaccess", "401.inc", "404.inc", +  "favicon.ico" }), _(8,"Banish list"),    TYPE_STRING_LIST,    _(9,"This is a list of users who's home directories will not be "    "mounted."));       defvar("own", 0, _(10,"Only owned files"), TYPE_FLAG,    _(11,"If set, only files actually owned by the user will be sent "    "from her home directory. This prohibits users from making "    "confidental files available by symlinking to them. On the other "    "hand it also makes it harder for user to cooperate on projects."));   
Roxen.git/server/modules/filesystems/userfs.pike:130:   multiset banish_reported = (<>);      void start()   {    filesystem::start();    // We fix all file names to be absolute before passing them to    // filesystem.pike    path="";    normalized_path="";    banish_list = mkmultiset(query("banish_list")); +  USERFS_WERR(sprintf("start: banish_list: %O\n", banish_list));    dude_ok = ([]);    // This is needed to override the inherited filesystem module start().   }    -  + protected int on_banish_list (string u) + { +  if (banish_list[u]) { +  if(!banish_reported[u]) +  { +  banish_reported[u] = 1; +  USERFS_WERR(sprintf("User %s banished...\n", u)); +  } +  return 1; +  } +  return 0; + } +    protected array(string) find_user(string f, RequestID id)   {    string of = f;    string u;       if(query("virtual_hosting")) {    NOCACHE();    if(id->misc->host) {    string host = (id->misc->host / ":")[0];    if(search(host, ".") != -1) {
Roxen.git/server/modules/filesystems/userfs.pike:174:    case 3:    break;    }    }       USERFS_WERR(sprintf("find_user(%O) => u:%O, f:%O", of, u, f));       return ({ u, f });   }    - int|mapping|Stdio.File find_file(string f, RequestID id) + protected string low_real_path(string f, RequestID id)   { -  string u, of = f; +  string norm_f;    -  USERFS_WERR(sprintf("find_file(%O)", f)); +  [string u, string rel_f] = find_user(f, id);    -  [u, f] = find_user(f, id); +  if(!u || on_banish_list(u)) { +  return 0; +  }    -  if(!u) -  return -1; +  string dir; +  if (!(dir = dude_ok[u])) { +  array(string) us = id->conf->userinfo( u, id );    -  array(string) us; -  array(int) stat; -  -  -  // FIXME: Use the find_user API instead. -  if(!dude_ok[ u ] || f == "") -  { -  us = id->conf->userinfo( u, id ); -  +     USERFS_WERR(sprintf("checking out %O: %O", u, us));       if(!us || BAD_PASSWORD(us) || banish_list[u])    { // No user, or access denied.    USERFS_WERR(sprintf("Bad password: %O? Banished? %O",    (us?BAD_PASSWORD(us):1),    banish_list[u])); -  if(!banish_reported[u]) -  { -  banish_reported[u] = 1; -  USERFS_WERR(sprintf("User %s banished (%O)...\n", u, us)); -  } +     return 0;    } -  if((f == "") && (strlen(of) && of[-1] != '/')) +  if(query("homedir"))    { -  redirects++; -  return Roxen.http_redirect(id->not_query+"/",id); +  if(us[5][-1] != '/') +  dir = us[ 5 ] + "/" + encode_path(query("pdir")); +  else +  dir = us[ 5 ] + encode_path(query("pdir")); +  } else +  dir = encode_path(query("searchpath") + u + "/"); +  dude_ok[u] = dir;    }    -  string dir; +  // For the benefit of the PHP4 module. Will set the DOCUMENT_ROOT +  // environment variable to this instead of the path to /. +  id->misc->user_document_root = dir; +  norm_f = dir + encode_path(rel_f);    -  if(query("homedir")) -  dir = us[ 5 ] + "/" + query("pdir") + "/"; -  else -  dir = query("searchpath") + "/" + u + "/"; +  return norm_f; + }    -  dir = replace(dir, "//", "/"); -  -  // If public dir does not exist, or is not a directory -  stat = filesystem::stat_file(dir, id); -  if(!stat || stat[1] != -2) + int|mapping|Stdio.File find_file(string f, RequestID id)   { -  USERFS_WERR(sprintf("Directory %O not found! (stat: %O)", dir, stat)); -  return 0; // File not found. +  string u; +  +  USERFS_WERR(sprintf("find_file(%O)", f)); +  +  [u, string rel_f] = find_user(f, id); +  +  if(!u) +  return -1; +  +  string norm_f = real_path(f, id); +  +  if (!norm_f) { +  return 0;    } -  dude_ok[u] = dir; // Always '/' terminated. -  } -  // For the benefit of the PHP4 module. Will set the DOCUMENT_ROOT -  // environment variable to this instead of the path to /. -  id->misc->user_document_root = dude_ok[u]; +     -  f = dude_ok[u] + f; +  array(string) us; +  Stdio.Stat stat;    -  if(query("own")) +  if(query("own") || query("useuserid"))    { -  if(!us) -  { +     us = id->conf->userinfo( u, id );    if(!us)    {    USERFS_WERR(sprintf("No userinfo for %O!", u));    return 0;    } -  } +     -  stat = filesystem::stat_file(f, id); +  stat = file_stat(norm_f);    -  if(!stat || (stat[5] != (int)(us[2]))) -  { -  USERFS_WERR(sprintf("File not owned by user %O.", u)); +  if (!stat) { +  USERFS_WERR("File not found.");    return 0;    } -  +  if (stat[5] == (int)us[2]) { +  if(query("useuserid")) +  id->misc->is_user = norm_f; +  } else if (query("own")) { +  USERFS_WERR("File not owned by user."); +  return 0;    } -  +  }    -  if(query("useuserid")) -  id->misc->is_user = f; -  +     USERFS_WERR(sprintf("Forwarding request to inherited filesystem."));    return filesystem::find_file( f, id );   }      string real_file(string f, RequestID id)   { -  string u; -  +     USERFS_WERR(sprintf("real_file(%O, X)", f));    -  array a = find_user(f, id); -  -  if (!a) { -  return 0; +  return ::real_file(f, id);   }    -  u = a[0]; -  f = a[1]; -  -  if(u) -  { -  array(int) fs; -  if(query("homedir")) -  { -  array(string) us; -  us = id->conf->userinfo( u, id ); -  if((!us) || BAD_PASSWORD(us) || banish_list[u]) -  return 0; -  if(us[5][-1] != '/') -  f = us[ 5 ] + "/" + query("pdir") + f; -  else -  f = us[ 5 ] + query("pdir") + f; -  } else -  f = query("searchpath") + u + "/" + f; -  -  // Use the inherited stat_file -  fs = filesystem::stat_file( f,id ); -  -  // werror(sprintf("%O: %O\n", f, fs)); -  // FIXME: Should probably have a look at this code. -  if (fs && ((fs[1] >= 0) || (fs[1] == -2))) -  return f; -  } -  return 0; - } -  +    mapping|array find_dir(string f, RequestID id)   {    USERFS_WERR(sprintf("find_dir(%O, X)", f));    -  array a = find_user(f, id); -  -  if (!a[0]) { +  if (f == "" || f == "/") {    if (query("user_listing")) {    array l;    l = id->conf->userlist(id);       if(l) return(l - query("banish_list"));    }    return 0;    }    -  string u = a[0]; -  f = a[1]; -  -  if(u) -  { -  if(query("homedir")) -  { -  array(string) us; -  us = id->conf->userinfo( u, id ); -  if((!us) || BAD_PASSWORD(us)) -  return 0; -  // FIXME: Use the banish multiset. -  if(search(query("banish_list"), u) != -1) return 0; -  if(us[5][-1] != '/') -  f = us[ 5 ] + "/" + query("pdir") + f; -  else -  f = us[ 5 ] + query("pdir") + f; +  return filesystem::find_dir(f, id);   } -  else -  f = query("searchpath") + u + "/" + f; -  array dir = filesystem::find_dir(f, id); -  return dir; -  } -  array(string) users = id->conf->userlist(id); -  return users && (users - query("banish_list")); - } +     - array(int) stat_file(string f, RequestID id) + Stdio.Stat stat_file(string f, RequestID id)   {    USERFS_WERR(sprintf("stat_file(%O)", f));    -  array a = find_user(f, id); +  string norm_f = real_path(f, id);    -  if (!a) { -  return ({ 0, -2, 0, 0, 0, 0, 0, 0, 0, 0 }); -  } -  -  string u = a[0]; -  f = a[1]; -  -  if(u) -  { -  array us, st; -  us = id->conf->userinfo( u, id ); -  if(query("homedir")) -  { -  if((!us) || BAD_PASSWORD(us)) +  if (!norm_f) { +  if ((f - "/") == "") return Stdio.Stat(({ 0, -2, 0, 0, 0, 0, 0 }));    return 0; -  // FIXME: Use the banish multiset. -  if(search(query("banish_list"), u) != -1) return 0; -  if(us[5] == "") { -  // No home directory. -  return 0; +     } -  if(us[5][-1] != '/') -  f = us[ 5 ] + "/" + query("pdir") + f; -  else -  f = us[ 5 ] + query("pdir") + f; -  } else -  f = query("searchpath") + u + "/" + f; -  st = filesystem::stat_file( f,id ); +  +  Stdio.Stat st = file_stat(norm_f);    if(!st) return 0; -  if(query("own") && (!us || ((int)us[2] != st[-2]))) return 0; +  if(query("own")) { +  [string u, string rel_f] = find_user(f, id); +  if (!u) return 0; +  array(string) us = id->conf->userinfo(u, id); +  if (!us || ((int)us[2] != st[-2])) return 0; +  }    return st;   } -  return 0; - } +          string query_name()   {    return "UserFS "+query("mountpoint")+" from "+    (query("homedir")?"~*/"+query("pdir"):query("searchpath"));   }      string status()   {