WvStreams
unipermgen.cc
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 2002 Net Integration Technologies, Inc.
00004  * 
00005  * UniPermGen is a UniConfGen for holding Unix-style permissions.  See
00006  * unipermgen.h.
00007  */
00008 #include "unipermgen.h"
00009 #include "unidefgen.h"
00010 #include "wvmoniker.h"
00011 #include "wvstringlist.h"
00012 #include "wvtclstring.h"
00013 #include "wvstream.h"
00014 #include "wvlinkerhack.h"
00015 
00016 WV_LINK(UniPermGen);
00017 
00018 
00019 
00020 UniPermGen::UniPermGen(IUniConfGen *_gen)
00021     : UniFilterGen(_gen)
00022 {
00023 }
00024 
00025 
00026 UniPermGen::UniPermGen(WvStringParm moniker)
00027     : UniFilterGen(NULL)
00028 {
00029     IUniConfGen *gen = wvcreate<IUniConfGen>(moniker);
00030     assert(gen && "Moniker doesn't get us a generator!");
00031     setinner(gen);
00032 }
00033 
00034 
00035 void UniPermGen::setowner(const UniConfKey &path, WvStringParm owner)
00036 {
00037     inner()->set(WvString("%s/owner", path), owner);
00038 }
00039 
00040 
00041 WvString UniPermGen::getowner(const UniConfKey &path)
00042 {
00043     WvString owner = inner()->get(WvString("%s/owner", path));
00044 
00045     if (!owner && !path.isempty())
00046         owner = getowner(path.removelast());
00047     return owner;
00048 }
00049 
00050 
00051 void UniPermGen::setgroup(const UniConfKey &path, WvStringParm group)
00052 {
00053     inner()->set(WvString("%s/group", path), group);
00054 }
00055 
00056 
00057 WvString UniPermGen::getgroup(const UniConfKey &path)
00058 {
00059     WvString group = inner()->get(WvString("%s/group", path));
00060     if (!group && !path.isempty())
00061         group = getgroup(path.removelast());
00062     return group;
00063 }
00064 
00065 
00066 void UniPermGen::setperm(const UniConfKey &path, Level level,
00067                          Type type, bool val)
00068 {
00069     inner()->set(WvString("%s/%s-%s", path, level2str(level),
00070                           type2str(type)), val);
00071 }
00072 
00073 
00074 bool UniPermGen::getperm(const UniConfKey &path, const Credentials &cred,
00075                          Type type)
00076 {
00077     WvString owner = getowner(path);
00078     WvString group = getgroup(path);
00079 
00080     Level level;
00081     if (!!owner && cred.user == owner) level = USER;
00082     else if (!!group && cred.groups[group]) level = GROUP;
00083     else level = WORLD;
00084 
00085     bool perm = getoneperm(path, level, type);
00086 //     wverr->print("getperm(%s/%s, %s/%s, %s,%s-%s) = %s\n",
00087 //                  cred.user, cred.groups.count(), owner, group,
00088 //                       path, level2str(level), type2str(type), perm);
00089     return perm;
00090 }
00091 
00092 
00096 bool UniPermGen::getoneperm(const UniConfKey &path, Level level, Type type)
00097 {
00098     int val = str2int(inner()->get(WvString("%s/%s-%s", path, level2str(level),
00099                                             type2str(type))), -1);
00100     if (val == -1)
00101     {
00102         if (path.isempty())
00103         {
00104             // nothing found: use default
00105             switch (type)
00106             {
00107                 case READ: return false;
00108                 case WRITE: return false;
00109                 case EXEC: return false; 
00110             }
00111         }
00112         else
00113             return getoneperm(path.removelast(), level, type);
00114     }
00115     return val;
00116 }
00117 
00118 
00119 void UniPermGen::chmod(const UniConfKey &path,
00120                        unsigned int user, unsigned int group,
00121                        unsigned int world)
00122 {
00123     static const int r = 4;
00124     static const int w = 2;
00125     static const int x = 1;
00126 
00127     setperm(path, USER, READ, (user & r));
00128     setperm(path, USER, WRITE, (user & w));
00129     setperm(path, USER, EXEC, (user & x));
00130 
00131     setperm(path, GROUP, READ, (group & r));
00132     setperm(path, GROUP, WRITE, (group & w));
00133     setperm(path, GROUP, EXEC, (group & x));
00134 
00135     setperm(path, WORLD, READ, (world & r));
00136     setperm(path, WORLD, WRITE, (world & w));
00137     setperm(path, WORLD, EXEC, (world & x));
00138 }
00139 
00140 
00141 void UniPermGen::chmod(const UniConfKey &path, unsigned int mode)
00142 {
00143     unsigned int user =  (mode & 0700) >> 6;
00144     unsigned int group = (mode & 0070) >> 3;
00145     unsigned int world = (mode & 0007);
00146     
00147     chmod(path, user, group, world);
00148 }
00149 
00150 
00151 WvString UniPermGen::level2str(Level level)
00152 {
00153     switch (level)
00154     {
00155     case USER: return "user";
00156     case GROUP: return "group";
00157     case WORLD: return "world";
00158     }
00159     assert(false && "Something in the Level enum wasn't covered");
00160     return WvString::null;
00161 }
00162 
00163 
00164 WvString UniPermGen::type2str(Type type)
00165 {
00166     switch (type)
00167     {
00168     case READ: return "read";
00169     case WRITE: return "write";
00170     case EXEC: return "exec";
00171     }
00172     assert(false && "Something in the Type enum wasn't covered");
00173     return WvString::null;
00174 }