tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
/*
// File     :  /std/priv.c
// Purpose  :  This is an access checking system that is inherited by
//             both generic objects and file security mechanisms.
// 92-05-31 :  Buddha wrote it
// 94-03-26 :  Pallando added delete_access()
*/


#include <uid.h>
#include <priv.h>

private mapping perms;

static nomask int check_access(mixed what);
nomask int set_access(mixed what, int new_access);
nomask int delete_access(string entry);

// debugging stuff
void debug(string str) {
#ifdef DEBUG
      write(str + "\n");
#endif
}

// start with something pretty basic.
void init_access() {
   if(!mapp(perms)) perms = ([ ]);
}

// O.K., this one returns an integer value based on the security level
// in question, as defined in priv.h.  It gets called by valid_write() and
// valid_read(), and is passed a string such as "obj/equip/sword.c".
// it will return the access for the item, or if that is unavailable, the
   // access for the node of the tree that it's on.

static nomask int check_access(string tmp) {
   int i;
   string *parts;
   
   debug("Passed to check_access: " + tmp);
   init_access();
   debug("past init_access()");
   
   // okay, first check for a direct match.  This will be a lot of 
   // cases for variables, less for files.
   
   if (perms[tmp]) return perms[tmp];
   
   // there was no match, so let's split this string up into segments.
   // If there is only one element in the resulting array, then we
   // know it's been passed already.
   
   parts = explode(tmp, "/");
   
   // question, what to do here?  For file security, it probably 
   // means they are trying to write to /, but for variables it sounds
   // like they are adding a new one.... one is harmless, the other isn't.
   // for now, I'll assume that there is another way to lock the root
   // directory... it may be necessary to add a "/" entry.
   // This is my solution, but I suspect there's a better way where
   // I won't have to do this for all objects.
   
   if (sizeof(parts) == 1) {
      debug("Only one level depth to resolve");
      if (file_name(this_object()) == "adm/newaccess")
         return MASTER_ONLY;
      else return PUBLIC;
   }
   
   // okay, let's look for the closest match we can find for this,
   // starting with things most similar and working towards root.
   
   for (i=sizeof(parts)-1;i>=0;i--) {
      tmp = implode(parts[0..i], "/");
      debug("debug: checking for an entry for " + tmp);
      if(perms[tmp]) {
         debug("Matched " + implode(parts, "/") + " with " + tmp);
         return perms[tmp];
        }
   }
   debug("No match, returning PUBLIC status.");
   return PUBLIC;
}


// This function will take either an access string or an array that
// constitutes a path through a variable tree, and set the access for
// the variable or tree segment specified.
   
nomask int set_access(string entry, int new_access) {
   string eff_user;
   int curr_access;
   
   // first, get the identity of who is trying to change the access.
   
   if (!previous_object()) eff_user = geteuid();
   else eff_user = geteuid(previous_object());
   
#ifdef DEBUG
      write(eff_user + " is trying to change access " + entry + " to " +
      new_access + " for " + file_name(this_object()) + "\n");
#endif
      
   // Only two euid can generally change the permissions on things.
   // the owner, because it makes sense, and Root, just because.
   
   if (eff_user != geteuid(this_object()) && eff_user != ROOT_UID)
      return 0;
   
   // now get it's protection level.
   // then, switch through the various types of protection.
   
   curr_access = check_access(entry);
   if(!intp(curr_access))  curr_access = 0;
   
   switch(curr_access) {
      case PUBLIC:
      case READ_ONLY:
      case OWNER_ONLY:
      perms[entry] = new_access;
      return 1;
      break;
      case LOCKED:
      case PRIVATE:
      return 0;
      break;
      case MASTER_ONLY:
      if (eff_user == ROOT_UID) {
         perms[entry] = new_access;
         return 1;
         }
      return 0;
      break;
      default: 
      // the item isn't even in priv.h - probably an error
      perms[entry] = new_access;
      return 1;
      break;
   }
}

// delete() uses delete_access(entry) rather than set_access(entry,0) because
// that is The Right Thing (tm) to do.
nomask int delete_access(string entry)
{
   string eff_user;

   eff_user = ( previous_object() ? geteuid( previous_object() ) : geteuid() );
   if( eff_user != geteuid() && eff_user != ROOT_UID ) return 0; // Fail.

   map_delete( perms, entry );
}

// Now, we do something that's purpose may look familiar to some of you 
// valid_write() and valid_read() get passed the string that represents
// what is being accessed, and is also passed the object doing the action.
// This way, we can ensure that nothing happens that shouldn't.
// the string passed will look like a file name already, i.e. it will

nomask int valid_write(string what, object act_ob) {
   string eff_user;
   int security;

   if (!what) return 0  ;   /* a hack-o by mobydick to fix a crash */
   if (!act_ob) act_ob = previous_object(); // who is this? ourself?
   if (!act_ob) act_ob = this_player();
   if (!act_ob) { 
      log_file("odd_errors", "no act_ob, /std/priv.c line 149");
      return 0;
   }
   eff_user = geteuid(act_ob);
   security = check_access(what);
   debug("check_access ok, security level " + security + " returned.");
   // Okay, let's check the access situation before going further.
   if(!intp(security))  security = 0;
   switch (security) {
      case PUBLIC :
      return 1; break;
      case READ_ONLY :
      case OWNER_ONLY :
      if (eff_user != geteuid() && eff_user != ROOT_UID)
         return 0; break;
      case MASTER_ONLY :
      case LOCKED :
      case PRIVATE :
      if (eff_user != ROOT_UID) return 0; break;
      default : debug("default case reached."); return 0; break;
   }
   // anything that makes it to this point should be ok, right?
   return 1;
}

nomask int valid_read(string what, object act_ob) { 
   string eff_user;
   int security;
   
   if (!act_ob) return 0;
   eff_user = geteuid(act_ob);
   security = check_access(what);
   debug("check_access ok, security level " + security + " returned.");
   // Okay, let's check the access situation before going further.
   if(!intp(security))  security = 0;
   switch (security) {
      case PUBLIC :
      case READ_ONLY :
      case MASTER_ONLY :
      case LOCKED :
      return 1; break;
      case OWNER_ONLY :
      case PRIVATE :
      if (eff_user != geteuid() && eff_user != ROOT_UID)
         return 0; break;
      default : debug("default case reached."); return 0; break;
   }
   // anything that makes it to this point should be ok, right?
   return 1;
}

// This function just checks with the access system and returns the
// present permissions set on an attribute.

int query_permission(string prop) { return check_access(prop); }