00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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;
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 , const Text &default_realm)
00048 {
00049 if(val.FindChar('@') == -1)
00050 {
00051
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
00065
00066 Text t, flavor_var = "[UserInterface]default_flavor";
00067
00068
00069 if(AccessControl::realm == 0)
00070 {
00071
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
00081 if(AccessControl::defaultFlavor == AccessControl::IdentityRep::unspecified)
00082 {
00083
00084
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
00103
00104 Text rrealm;
00105
00106
00107
00108
00109
00110
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
00124
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
00159 abort();
00160 }
00161
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
00199
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
00290 if(other.flavor == global)
00291 {
00292
00293 AccessControl::GlobalIdentityRep *global_other =
00294 (AccessControl::GlobalIdentityRep *) (&other);
00295
00296
00297 return (strcmp(global_other->user_, this->user_) == 0);
00298 }
00299
00300
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
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
00361 if(other.flavor == unix_flavor)
00362 {
00363
00364 AccessControl::UnixIdentityRep *unix_other =
00365 (AccessControl::UnixIdentityRep *) (&other);
00366
00367
00368 return (unix_other->aup_->aup_uid == this->aup_->aup_uid);
00369 }
00370
00371
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 ()
00404 {
00405 selfInit();
00406 return self_;
00407 }