Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

AccessControlClient.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 //
00020 // AccessControlClient.C
00021 //
00022 // AccessControl implementation required on the client side
00023 //
00024 
00025 #include "AccessControl.H"
00026 #include <pwd.h>
00027 
00028 using std::cerr;
00029 using std::endl;
00030 
00031 const char* AccessControl::realm = 0;  // [Repository]realm
00032 unsigned int AccessControl::realmlen = 0;
00033 AccessControl::IdentityRep::Flavor AccessControl::defaultFlavor
00034   = AccessControl::IdentityRep::unspecified;
00035 bool AccessControl::restrictDelete;
00036 uid_t AccessControl::vforeignUser;
00037 gid_t AccessControl::vforeignGroup;
00038 const char* AccessControl::vadminUser;
00039 const char* AccessControl::vadminGroup;
00040 const char* AccessControl::rootUser;
00041 const char* AccessControl::runtoolUser;
00042 const char* AccessControl::vwizardUser;
00043 AccessControl::Identity AccessControl::self_ = 0;
00044 
00045 static bool clientDone, commonDone;
00046 
00047 static void ensure_realm(Text &val /*IN/OUT*/, const Text &default_realm)
00048 {
00049   if(val.FindChar('@') == -1)
00050     {
00051       // Add the local realm
00052       val += "@";
00053       val += default_realm;
00054     }
00055 }
00056 
00057 extern "C"
00058 {
00059   void AccessControl_commonInit_inner() throw()
00060   {
00061     try
00062       {
00063         // ------------------------------------------------------------
00064         // Client initialization
00065         // ------------------------------------------------------------
00066         Text t, flavor_var = "[UserInterface]default_flavor";
00067 
00068         // If realm is unitialized, initialize it.
00069         if(AccessControl::realm == 0)
00070           {
00071             // Use [UserInterface]realm if set, otherwise use [Repository]realm
00072             if(!VestaConfig::get("UserInterface", "realm", t))
00073               {
00074                 t = VestaConfig::get_Text("Repository", "realm");
00075               }
00076             AccessControl::realm = strdup(t.cchars());
00077             AccessControl::realmlen = strlen(AccessControl::realm);
00078           }
00079 
00080         // If defaultFlavor is unitialized, initialize it.
00081         if(AccessControl::defaultFlavor == AccessControl::IdentityRep::unspecified)
00082           {
00083             // Use [UserInterface]default_flavor if set, otherwise use
00084             // [Repository]default_flavor
00085             if(!VestaConfig::get("UserInterface", "default_flavor", t))
00086               {
00087                 t = VestaConfig::get_Text("Repository", "default_flavor");
00088                 flavor_var = "[Repository]default_flavor";
00089               }
00090             if (strcasecmp(t.cchars(), "unix") == 0) {
00091               AccessControl::defaultFlavor = AccessControl::IdentityRep::unix_flavor;
00092             } else if (strcasecmp(t.cchars(), "global") == 0) {
00093               AccessControl::defaultFlavor = AccessControl::IdentityRep::global;
00094             } else if (strcasecmp(t.cchars(), "gssapi") == 0) {
00095               AccessControl::defaultFlavor = AccessControl::IdentityRep::gssapi;
00096             } else {
00097               throw(VestaConfig::failure("bad value for "+flavor_var));
00098             }
00099           }
00100 
00101         // ------------------------------------------------------------
00102         // Common initialization
00103         // ------------------------------------------------------------
00104         Text rrealm;
00105 
00106         // We need to get [Repository]realm here.  AccessControl::realm
00107         // could be set to [UserInterface]realm, which could be different
00108         // from [Repository]realm.  However, when defaulting the realm for
00109         // the special users/groups, we need to use [Repository]realm, so we
00110         // ignore AccessControl::realm here.
00111         rrealm = VestaConfig::get_Text("Repository", "realm");
00112 
00113         t = VestaConfig::get_Text("Repository", "root_user");
00114         ensure_realm(t, rrealm);
00115         AccessControl::rootUser = strdup(t.cchars());
00116 
00117         t = VestaConfig::get_Text("Repository", "vadmin_user");
00118         ensure_realm(t, rrealm);
00119         AccessControl::vadminUser = strdup(t.cchars());
00120 
00121         t = VestaConfig::get_Text("Repository", "vadmin_group");
00122         ensure_realm(t, rrealm);
00123         // Make sure vadminGroup starts with '^' (the group specifier
00124         // character)
00125         if(t[0] != '^')
00126           {
00127             t = "^" + t;
00128           }
00129         AccessControl::vadminGroup = strdup(t.cchars());
00130 
00131         t = VestaConfig::get_Text("Repository", "runtool_user");
00132         ensure_realm(t, rrealm);
00133         AccessControl::runtoolUser = strdup(t.cchars());
00134 
00135         try {
00136           t = VestaConfig::get_Text("Repository", "vwizard_user");
00137           ensure_realm(t, rrealm);
00138           AccessControl::vwizardUser = strdup(t.cchars());
00139         } catch (VestaConfig::failure) {
00140           AccessControl::vwizardUser = "";
00141         }
00142 
00143         AccessControl::vforeignUser =
00144           VestaConfig::get_int("Repository", "vforeign_uid");
00145 
00146         AccessControl::vforeignGroup =
00147           VestaConfig::get_int("Repository", "vforeign_gid");
00148 
00149         AccessControl::restrictDelete =
00150           (bool) VestaConfig::get_int("Repository", "restrict_delete");
00151 
00153       }
00154     catch(const VestaConfig::failure &f)
00155       {
00156         cerr << "Configuration error in AccessControl::commonInit:" << endl
00157              << f.msg << endl;
00158         // Fatal error
00159         abort();
00160       }
00161     /* catch(gssapi::failure) ? */
00162   }
00163 }
00164 
00165 void
00166 AccessControl::commonInit() throw ()
00167 {
00168   static pthread_once_t common_once = PTHREAD_ONCE_INIT;
00169   pthread_once(&common_once, AccessControl_commonInit_inner);
00170 }
00171 
00172 extern "C"
00173 {
00174   void AccessControl_selfInit_inner() throw()
00175   {
00176     switch (AccessControl::defaultFlavor) {
00177     case AccessControl::IdentityRep::global:
00178       AccessControl::self_ = NEW(AccessControl::GlobalIdentityRep);
00179       break;
00180 #if 0
00181     case AccessControl::IdentityRep::gssapi:
00182       AccessControl::self_ = NEW(AccessControl::GssapiIdentityRep);
00183       break;
00184 #endif
00185     case AccessControl::IdentityRep::unix_flavor:
00186       AccessControl::self_ = NEW(AccessControl::UnixIdentityRep);
00187       break;
00188     default:
00189       assert("unsupported flavor" && false);
00190       break;
00191     }
00192   }
00193 }
00194 
00195 void
00196 AccessControl::selfInit() throw ()
00197 {
00198   // commonInit sets AccessControl::defaultFlavor, which is needed
00199   // first.
00200   commonInit();
00201 
00202   static pthread_once_t self_once = PTHREAD_ONCE_INIT;
00203   pthread_once(&self_once, AccessControl_selfInit_inner);
00204 }
00205 
00206 static void free_CharsSeq(CharsSeq *s)
00207 {
00208   while(s->size() > 0)
00209     {
00210       const char *val = s->remhi();
00211       assert(val != NULL);
00212       delete [] val;
00213    }
00214   delete s;
00215 }
00216 
00217 AccessControl::IdentityRep::~IdentityRep()
00218 {
00219   if(this->users_cache)
00220     {
00221       free_CharsSeq(this->users_cache);
00222       this->users_cache = 0;
00223     }
00224   if(this->groups_cache)
00225     {
00226       free_CharsSeq(this->groups_cache);
00227       this->groups_cache = 0;
00228     }
00229 }
00230 
00231 const char*
00232 AccessControl::IdentityRep::user(int n) throw ()
00233 {
00234   if(this->users_cache == 0) this->fill_caches();
00235   assert(this->users_cache != 0);
00236 
00237   if(n < this->users_cache->size())
00238     return this->users_cache->get(n);
00239   return NULL;
00240 }
00241 
00242 const char*
00243 AccessControl::IdentityRep::group(int n) throw ()
00244 {
00245   if(this->groups_cache == 0) this->fill_caches();
00246   assert(this->groups_cache != 0);
00247 
00248   if(n < this->groups_cache->size())
00249     return this->groups_cache->get(n);
00250   return NULL;
00251 }
00252 
00253 AccessControl::GlobalIdentityRep::GlobalIdentityRep
00254   (const char* u, const sockaddr_in* o) throw ()
00255 {
00256   commonInit();
00257   flavor = global;
00258   if(o) {
00259     origin = *o;
00260   } 
00261   else {
00262     memset(&origin,0,sizeof(origin));
00263   }
00264   readOnly = false;
00265   if(u) {
00266     user_ = u;
00267   } 
00268   else {
00269     uid_t uid = geteuid();
00270     char *buf = 0;
00271     OS::Passwd passwd;
00272     if(OS::getPwUid(uid, passwd)) {
00273       buf = NEW_PTRFREE_ARRAY(char, (passwd.name.Length() + 1 +
00274                                      AccessControl::realmlen + 1));
00275       sprintf(buf, "%s@%s", passwd.name.cchars(), AccessControl::realm);
00276     } 
00277     else {
00278       buf = NEW_PTRFREE_ARRAY(char, 22 + AccessControl::realmlen);
00279       sprintf(buf, "%u@%s", uid, AccessControl::realm);
00280     }
00281     user_ = buf;
00282   }
00283 }
00284 
00285 bool AccessControl::GlobalIdentityRep::operator==
00286 (const AccessControl::IdentityRep &other)
00287   const throw()
00288 {
00289   // If the other is the same flavor...
00290   if(other.flavor == global)
00291     {
00292       // Cast it to the right pointer type.
00293       AccessControl::GlobalIdentityRep *global_other =
00294         (AccessControl::GlobalIdentityRep *) (&other);
00295 
00296       // It's equivalent if the global username is the same.
00297       return (strcmp(global_other->user_, this->user_) == 0);
00298     }
00299 
00300   // If the other isn't of the same flavor, it's not equal.
00301   return false;
00302 }
00303 
00304 void AccessControl::GlobalIdentityRep::send(SRPC *srpc)
00305   const throw(SRPC::failure)
00306 {
00307   srpc->send_int((int) this->flavor);
00308   srpc->send_chars(this->user_);
00309 }
00310 
00311 AccessControl::GlobalIdentityRep::~GlobalIdentityRep()
00312 {
00313   if(this->user_) delete [] this->user_;
00314 }
00315 
00316 #if 0
00317 // !!Unfinished
00318 AccessControl::GssapiIdentityRep::GssapiIdentityRep(!!)
00319   throw (AccessControl::GssapiIdentityRep::failure)
00320 {
00321   commonInit();
00322   !!
00323 }
00324 #endif
00325 
00326 AccessControl::UnixIdentityRep::UnixIdentityRep
00327 (authunix_parms* aup, const sockaddr_in* o, bool own_aup) throw ()
00328   : free_aup_(own_aup)
00329 {
00330   commonInit();
00331   flavor = unix_flavor;
00332   if (o) {
00333     origin = *o;
00334   } else {
00335     memset(&origin,0,sizeof(origin));
00336   }
00337   readOnly = false;
00338   if (aup) {
00339     aup_ = aup;
00340   } else {
00341     aup_ = NEW(authunix_parms);
00342     aup_->aup_machname = NEW_PTRFREE_ARRAY(char, MAX_MACHINE_NAME+1);
00343 #if defined(__linux__) || defined(__sun__)
00344     aup_->aup_gids = NEW_PTRFREE_ARRAY(gid_t, NGRPS);
00345 #else
00346     aup_->aup_gids = NEW_PTRFREE_ARRAY(int, NGRPS);
00347 #endif    
00348     aup_->aup_time = time(NULL);
00349     gethostname(aup_->aup_machname, MAX_MACHINE_NAME+1);
00350     aup_->aup_uid = geteuid();
00351     aup_->aup_gid = getegid();
00352     aup_->aup_len = getgroups(NGRPS, (gid_t*) aup_->aup_gids);
00353   }
00354 }
00355 
00356 bool AccessControl::UnixIdentityRep::operator==
00357 (const AccessControl::IdentityRep &other)
00358   const throw()
00359 {
00360   // If the other is the same flavor...
00361   if(other.flavor == unix_flavor)
00362     {
00363       // Cast it to the right pointer type.
00364       AccessControl::UnixIdentityRep *unix_other =
00365         (AccessControl::UnixIdentityRep *) (&other);
00366 
00367       // It's equivalent if the user ID is the same
00368       return (unix_other->aup_->aup_uid == this->aup_->aup_uid);
00369     }
00370 
00371   // If the other isn't of the same flavor, it's not equal.
00372   return false;
00373 }
00374 
00375 void AccessControl::UnixIdentityRep::send(SRPC *srpc)
00376   const throw(SRPC::failure)
00377 {
00378   srpc->send_int((int) this->flavor);
00379   authunix_parms* aup = this->aup_;
00380   srpc->send_int((int) aup->aup_time);
00381   srpc->send_chars(aup->aup_machname);
00382   srpc->send_int(aup->aup_uid);
00383   srpc->send_int(aup->aup_gid);
00384   srpc->send_seq_start((int)aup->aup_len);
00385   unsigned int i;
00386   for (i=0; i<aup->aup_len; i++) {
00387     srpc->send_int(aup->aup_gids[i]);
00388   }
00389   srpc->send_seq_end();
00390 }
00391 
00392 AccessControl::UnixIdentityRep::~UnixIdentityRep()
00393 {
00394   if(this->free_aup_ && this->aup_)
00395     {
00396       if(this->aup_->aup_machname) delete [] this->aup_->aup_machname;
00397       if(this->aup_->aup_gids) delete [] this->aup_->aup_gids;
00398       delete this->aup_;
00399     }
00400 }
00401 
00402 AccessControl::Identity
00403 AccessControl::self() throw (/*GssapiIdentityRep::failure*/)
00404 {
00405   selfInit();
00406   return self_;
00407 }

Generated on Mon May 8 00:48:43 2006 for Vesta by  doxygen 1.4.2