00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "XrdProofdPlatform.h"
00025
00026 #include "XrdProofdManager.h"
00027
00028 #ifdef OLDXRDOUC
00029 # include "XrdOuc/XrdOucPlugin.hh"
00030 # include "XrdOuc/XrdOucTimer.hh"
00031 #else
00032 # include "XrdSys/XrdSysPlugin.hh"
00033 # include "XrdSys/XrdSysTimer.hh"
00034 #endif
00035 #include "XrdNet/XrdNetDNS.hh"
00036 #include "XrdOuc/XrdOucEnv.hh"
00037 #include "XrdOuc/XrdOucStream.hh"
00038 #include "XrdSys/XrdSysPriv.hh"
00039
00040 #include "XrdProofdAdmin.h"
00041 #include "XrdProofdClient.h"
00042 #include "XrdProofdClientMgr.h"
00043 #include "XrdProofdConfig.h"
00044 #include "XrdProofdNetMgr.h"
00045 #include "XrdProofdPriorityMgr.h"
00046 #include "XrdProofdProofServMgr.h"
00047 #include "XrdProofdProtocol.h"
00048 #include "XrdProofGroup.h"
00049 #include "XrdProofSched.h"
00050 #include "XrdProofdProofServ.h"
00051 #include "XrdProofWorker.h"
00052 #include "XrdROOT.h"
00053
00054
00055 #include "XrdProofdTrace.h"
00056
00057
00058
00059
00060
00061
00062
00063
00064 void *XrdProofdManagerCron(void *p)
00065 {
00066
00067 XPDLOC(PMGR, "ManagerCron")
00068
00069 XrdProofdManager *mgr = (XrdProofdManager *)p;
00070 if (!(mgr)) {
00071 TRACE(REQ, "undefined manager: cannot start");
00072 return (void *)0;
00073 }
00074
00075 TRACE(REQ, "started with frequency " << mgr->CronFrequency() << " sec");
00076
00077
00078 int now = time(0);
00079 int mid = XrdSysTimer::Midnight(now);
00080 while (mid < now) {
00081 mid += 86400;
00082 }
00083 TRACE(REQ, "midnight in " << (mid - now) << " secs");
00084
00085 while (1) {
00086
00087 TRACE(REQ, "running periodical checks");
00088
00089 mgr->CheckLogFileOwnership();
00090
00091 int tw = mgr->CronFrequency();
00092 now = time(0);
00093 if ((mid - now) <= tw) {
00094 tw = mid - now + 2;
00095 mid += 86400;
00096 }
00097
00098
00099
00100 if (mgr->SessionMgr()) mgr->SessionMgr()->Config(1);
00101 if (mgr->GroupsMgr()) mgr->GroupsMgr()->Config(mgr->GroupsMgr()->GetCfgFile());
00102
00103 XrdSysTimer::Wait(tw * 1000);
00104 }
00105
00106
00107 return (void *)0;
00108 }
00109
00110
00111 XrdProofdManager::XrdProofdManager(XrdProtocol_Config *pi, XrdSysError *edest)
00112 : XrdProofdConfig(pi->ConfigFN, edest)
00113 {
00114
00115
00116 fSrvType = kXPD_AnyServer;
00117 fEffectiveUser = "";
00118 fHost = "";
00119 fPort = XPD_DEF_PORT;
00120 fImage = "";
00121 fSockPathDir = "";
00122 fTMPdir = "/tmp";
00123 fWorkDir = "";
00124 fSuperMst = 0;
00125 fNamespace = "/proofpool";
00126 fMastersAllowed.clear();
00127 fOperationMode = kXPD_OpModeOpen;
00128 fMultiUser = 0;
00129 fChangeOwn = 0;
00130 fCronFrequency = 30;
00131
00132
00133 fDataDir = "";
00134 fDataDirOpts = "gW";
00135
00136
00137
00138 fAdminPath = pi->AdmPath;
00139 fAdminPath += "/.xproofd.";
00140
00141
00142 fSched = pi->Sched;
00143 fAdmin = 0;
00144 fClientMgr = 0;
00145 fGroupsMgr = 0;
00146 fNetMgr = 0;
00147 fPriorityMgr = 0;
00148 fProofSched = 0;
00149 fSessionMgr = 0;
00150
00151
00152 RegisterDirectives();
00153
00154
00155 fAdmin = new XrdProofdAdmin(this, pi, edest);
00156
00157
00158 fClientMgr = new XrdProofdClientMgr(this, pi, edest);
00159
00160
00161 fNetMgr = new XrdProofdNetMgr(this, pi, edest);
00162
00163
00164 fPriorityMgr = new XrdProofdPriorityMgr(this, pi, edest);
00165
00166
00167 fROOTMgr = new XrdROOTMgr(this, pi, edest);
00168
00169
00170 fSessionMgr = new XrdProofdProofServMgr(this, pi, edest);
00171 }
00172
00173
00174 XrdProofdManager::~XrdProofdManager()
00175 {
00176
00177
00178
00179 SafeDelete(fAdmin);
00180 SafeDelete(fClientMgr);
00181 SafeDelete(fNetMgr);
00182 SafeDelete(fPriorityMgr);
00183 SafeDelete(fProofSched);
00184 SafeDelete(fROOTMgr);
00185 SafeDelete(fSessionMgr);
00186 }
00187
00188
00189 void XrdProofdManager::CheckLogFileOwnership()
00190 {
00191
00192 XPDLOC(ALL, "Manager::CheckLogFileOwnership")
00193
00194
00195 if (getuid()) return;
00196
00197 struct stat st;
00198 if (fstat(STDERR_FILENO, &st) != 0) {
00199 if (errno != ENOENT) {
00200 TRACE(XERR, "could not stat log file; errno: " << errno);
00201 return;
00202 }
00203 }
00204
00205 TRACE(HDBG, "uid: " << st.st_uid << ", gid: " << st.st_gid);
00206
00207
00208 struct passwd *epwd = getpwuid(XrdProofdProtocol::EUidAtStartup());
00209 if (!epwd) {
00210 TRACE(XERR, "could not get effective user identity; errno: " << errno);
00211 return;
00212 }
00213
00214
00215 if (st.st_uid != epwd->pw_uid || st.st_gid != epwd->pw_gid) {
00216 if (fchown(STDERR_FILENO, epwd->pw_uid, epwd->pw_gid) != 0) {
00217 TRACE(XERR, "could not set stderr ownership; errno: " << errno);
00218 return;
00219 }
00220 }
00221 }
00222
00223
00224 bool XrdProofdManager::CheckMaster(const char *m)
00225 {
00226
00227 bool rc = 1;
00228
00229 if (fMastersAllowed.size() > 0) {
00230 rc = 0;
00231 XrdOucString wm(m);
00232 std::list<XrdOucString *>::iterator i;
00233 for (i = fMastersAllowed.begin(); i != fMastersAllowed.end(); ++i) {
00234 if (wm.matches((*i)->c_str())) {
00235 rc = 1;
00236 break;
00237 }
00238 }
00239 }
00240
00241
00242 return rc;
00243 }
00244
00245
00246 int XrdProofdManager::CheckUser(const char *usr,
00247 XrdProofUI &ui, XrdOucString &e, bool &su)
00248 {
00249
00250
00251
00252 su = 0;
00253
00254 if (!usr || strlen(usr) <= 0) {
00255 e = "CheckUser: 'usr' string is undefined ";
00256 return -1;
00257 }
00258
00259
00260 if (strlen(usr) == 4 && !strcmp(usr, "root")) {
00261 e = "CheckUser: 'root' logins not accepted ";
00262 return -1;
00263 }
00264
00265 XrdSysMutexHelper mtxh(&fMutex);
00266
00267
00268
00269
00270 if (fChangeOwn) {
00271 if (XrdProofdAux::GetUserInfo(usr, ui) != 0) {
00272 e = "CheckUser: unknown ClientID: ";
00273 e += usr;
00274 return -1;
00275 }
00276 } else {
00277 if (XrdProofdAux::GetUserInfo(geteuid(), ui) != 0) {
00278 e = "CheckUser: problems getting user info for id: ";
00279 e += (int)geteuid();
00280 return -1;
00281 }
00282 }
00283
00284
00285 if (fSuperUsers.length() > 0) {
00286 XrdOucString tkn;
00287 int from = 0;
00288 while ((from = fSuperUsers.tokenize(tkn, from, ',')) != -1) {
00289 if (tkn == usr) {
00290 su = 1;
00291 break;
00292 }
00293 }
00294 }
00295
00296
00297
00298
00299 if (fOperationMode == kXPD_OpModeControlled) {
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 bool grpok = 1;
00315
00316 if (fAllowedGroups.Num() > 0) {
00317
00318 grpok = 0;
00319
00320 XrdProofGI gi;
00321 if (XrdProofdAux::GetGroupInfo(ui.fGid, gi) == 0) {
00322 int *st = fAllowedGroups.Find(gi.fGroup.c_str());
00323 if (st) {
00324 grpok = 1;
00325 } else {
00326 e = "CheckUser: group '";
00327 e += gi.fGroup;
00328 e += "' is not allowed to connect";
00329 }
00330 }
00331 }
00332
00333 bool usrok = grpok;
00334 if (fAllowedUsers.Num() > 0) {
00335
00336 int *st = fAllowedUsers.Find(usr);
00337 if (st) {
00338 if ((*st == 1)) {
00339 usrok = 1;
00340 } else {
00341 e = "CheckUser: user '";
00342 e += usr;
00343 e += "' is not allowed to connect";
00344 usrok = 0;
00345 }
00346 }
00347 }
00348
00349 if (!usrok && su) {
00350 usrok = 1;
00351 e = "";
00352 }
00353
00354 if (!usrok) return -1;
00355 }
00356
00357
00358 return 0;
00359 }
00360
00361
00362 XrdProofSched *XrdProofdManager::LoadScheduler()
00363 {
00364
00365 XPDLOC(ALL, "Manager::LoadScheduler")
00366
00367 XrdProofSched *sched = 0;
00368 XrdOucString name, lib, m;
00369
00370 const char *cfn = CfgFile();
00371
00372
00373 if (cfn && strlen(cfn) > 0) {
00374 XrdOucEnv myEnv;
00375 XrdOucStream cfg(fEDest, getenv("XRDINSTANCE"), &myEnv);
00376
00377 int cfgFD;
00378 if ((cfgFD = open(cfn, O_RDONLY, 0)) >= 0) {
00379 cfg.Attach(cfgFD);
00380
00381 char *val = 0, *var = 0;
00382 while ((var = cfg.GetMyFirstWord())) {
00383 if (!(strcmp("xpd.sched", var))) {
00384
00385 val = cfg.GetWord();
00386 if (val && val[0]) {
00387 name = val;
00388
00389 val = cfg.GetWord();
00390 if (val && val[0])
00391 lib = val;
00392
00393 break;
00394 }
00395 }
00396 }
00397 } else {
00398 XPDFORM(m, "failure opening config file; errno: %d", errno);
00399 TRACE(XERR, m);
00400 }
00401 }
00402
00403
00404 if (name == "default" || !(name.length() > 0 && lib.length() > 0)) {
00405 if ((name.length() <= 0 && lib.length() > 0) ||
00406 (name.length() > 0 && lib.length() <= 0)) {
00407 XPDFORM(m, "missing or incomplete info (name: %s, lib: %s)", name.c_str(), lib.c_str());
00408 TRACE(DBG, m);
00409 }
00410 TRACE(DBG, "instantiating default scheduler");
00411 sched = new XrdProofSched("default", this, fGroupsMgr, cfn, fEDest);
00412 } else {
00413
00414 if (lib.beginswith("~") || lib.beginswith("$"))
00415 XrdProofdAux::Expand(lib);
00416 XrdSysPlugin *h = new XrdSysPlugin(fEDest, lib.c_str());
00417 if (!h)
00418 return (XrdProofSched *)0;
00419
00420 XrdProofSchedLoader_t ep = (XrdProofSchedLoader_t) h->getPlugin("XrdgetProofSched", 1);
00421 if (!ep) {
00422 delete h;
00423 return (XrdProofSched *)0;
00424 }
00425
00426 if (!(sched = (*ep)(cfn, this, fGroupsMgr, cfn, fEDest))) {
00427 TRACE(XERR, "unable to create scheduler object from " << lib);
00428 return (XrdProofSched *)0;
00429 }
00430 }
00431
00432 if (!(sched->IsValid())) {
00433 TRACE(XERR, " unable to instantiate the " << sched->Name() << " scheduler using " << cfn);
00434 delete sched;
00435 return (XrdProofSched *)0;
00436 }
00437
00438 TRACE(ALL, "scheduler loaded: type: " << sched->Name());
00439
00440
00441 return sched;
00442 }
00443
00444
00445 int XrdProofdManager::GetWorkers(XrdOucString &lw, XrdProofdProofServ *xps,
00446 const char *query)
00447 {
00448
00449 XPDLOC(ALL, "Manager::GetWorkers")
00450
00451 int rc = 0;
00452 TRACE(REQ, "enter");
00453
00454
00455 if (!fProofSched) {
00456 TRACE(XERR, "scheduler undefined");
00457 return -1;
00458 }
00459
00460
00461 std::list<XrdProofWorker *> wrks;
00462 if ((rc = fProofSched->GetWorkers(xps, &wrks, query)) < 0) {
00463 TRACE(XERR, "error getting list of workers from the scheduler");
00464 return -1;
00465 }
00466
00467 if (rc == 0) {
00468
00469 TRACE(DBG, "list size: " << wrks.size());
00470
00471
00472 XrdOucString ord;
00473 int ii = -1;
00474 std::list<XrdProofWorker *>::iterator iw;
00475 for (iw = wrks.begin(); iw != wrks.end() ; iw++) {
00476 XrdProofWorker *w = *iw;
00477
00478 if (ii == -1)
00479 ord = "master";
00480 else
00481 XPDFORM(ord, "%d", ii);
00482 ii++;
00483 xps->AddWorker(ord.c_str(), w);
00484
00485 w->AddProofServ(xps);
00486 }
00487 }
00488
00489 int proto = (xps->ROOT()) ? xps->ROOT()->SrvProtVers() : -1;
00490 if (rc != 2 || (proto < 21 && rc == 0)) {
00491
00492 xps->ExportWorkers(lw);
00493 TRACE(DBG, "from ExportWorkers: " << lw);
00494 } else if (proto >= 21) {
00495
00496 lw = XPD_GW_QueryEnqueued;
00497 }
00498
00499 if (TRACING(REQ)) fNetMgr->Dump();
00500
00501 return rc;
00502 }
00503
00504
00505 static int FillKeyValues(const char *k, int *d, void *s)
00506 {
00507
00508
00509 XrdOucString *ls = (XrdOucString *)s;
00510
00511 if (ls) {
00512 if (*d == 1) {
00513
00514 if (ls->length() > 0) *ls += ",";
00515
00516 if (k) *ls += k;
00517 }
00518 } else {
00519
00520 return 1;
00521 }
00522
00523
00524 return 0;
00525 }
00526
00527
00528 int XrdProofdManager::Config(bool rcf)
00529 {
00530
00531
00532 XPDLOC(ALL, "Manager::Config")
00533
00534 XrdSysMutexHelper mtxh(fMutex);
00535
00536
00537 if (XrdProofdConfig::Config(rcf) != 0) {
00538 XPDERR("problems parsing file ");
00539 return -1;
00540 }
00541
00542 XrdOucString msg;
00543 msg = (rcf) ? "re-configuring" : "configuring";
00544 TRACE(ALL, msg);
00545
00546
00547 fChangeOwn = (fMultiUser && getuid()) ? 0 : 1;
00548
00549
00550 XPDFORM(msg, "listening on port %d", fPort);
00551 TRACE(ALL, msg);
00552
00553 XrdProofUI ui;
00554 uid_t effuid = geteuid();
00555 if (!rcf) {
00556
00557 if (XrdProofdAux::GetUserInfo(effuid, ui) == 0) {
00558 fEffectiveUser = ui.fUser;
00559 } else {
00560 XPDFORM(msg, "could not resolve effective uid %d (errno: %d)", effuid, errno);
00561 XPDERR(msg);
00562 return -1;
00563 }
00564
00565
00566 char *host = XrdNetDNS::getHostName();
00567 fHost = host ? host : "";
00568 SafeFree(host);
00569
00570
00571 TRACE(ALL, "using temp dir: " << fTMPdir);
00572
00573
00574 const char *roles[] = { "any", "worker", "submaster", "master" };
00575 TRACE(ALL, "role set to: " << roles[fSrvType+1]);
00576
00577
00578 fAdminPath += fPort;
00579 if (XrdProofdAux::AssertDir(fAdminPath.c_str(), ui, fChangeOwn) != 0) {
00580 XPDERR("unable to assert the admin path: " << fAdminPath);
00581 return -1;
00582 }
00583 TRACE(ALL, "admin path set to: " << fAdminPath);
00584
00585
00586 if (fSockPathDir.length() <= 0) {
00587
00588 XPDFORM(fSockPathDir, "%s/socks", fAdminPath.c_str());
00589 }
00590 if (XrdProofdAux::AssertDir(fSockPathDir.c_str(), ui, fChangeOwn) != 0) {
00591 XPDERR("unable to assert the admin path: " << fSockPathDir);
00592 return -1;
00593 }
00594 TRACE(ALL, "unix sockets under: " << fSockPathDir);
00595
00596
00597 XrdOucString pidfile(fAdminPath);
00598 pidfile += "/xrootd.pid";
00599 FILE *fpid = fopen(pidfile.c_str(), "w");
00600 if (!fpid) {
00601 XPDFORM(msg, "unable to open pid file: %s; errno: %d", pidfile.c_str(), errno);
00602 XPDERR(msg);
00603 return -1;
00604 }
00605 fprintf(fpid, "%d", getpid());
00606 fclose(fpid);
00607 } else {
00608 if (XrdProofdAux::GetUserInfo(effuid, ui) == 0) {
00609 XPDFORM(msg, "could not resolve effective uid %d (errno: %d)", effuid, errno);
00610 XPDERR(msg);
00611 }
00612 }
00613
00614
00615 if (fWorkDir.length() > 0) {
00616
00617 if (XrdProofdAux::AssertDir(fWorkDir.c_str(), ui, fChangeOwn) != 0) {
00618 XPDERR("unable to assert working dir: " << fWorkDir);
00619 return -1;
00620 }
00621 TRACE(ALL, "working directories under: " << fWorkDir);
00622
00623 XrdProofdSandbox::SetWorkdir(fWorkDir.c_str());
00624 }
00625
00626
00627 if (fDataDir.length() > 0) {
00628
00629 if (XrdProofdAux::AssertDir(fDataDir.c_str(), ui, fChangeOwn) != 0) {
00630 XPDERR("unable to assert data dir: " << fDataDir);
00631 return -1;
00632 }
00633
00634 XrdSysPrivGuard pGuard((uid_t)ui.fUid, (gid_t)ui.fGid);
00635 if (XpdBadPGuard(pGuard, ui.fUid)) {
00636 TRACE(XERR, "could not get privileges to set/change ownership of " << fDataDir);
00637 return -1;
00638 }
00639 if (chmod(fDataDir.c_str(), 0777) != 0) {
00640 XPDERR("problems setting permissions 0777 data dir: " << fDataDir);
00641 return -1;
00642 }
00643 TRACE(ALL, "data directories under: " << fDataDir);
00644 }
00645
00646
00647 if (fSrvType == kXPD_Worker) {
00648 if (fMastersAllowed.size() > 0) {
00649 std::list<XrdOucString *>::iterator i;
00650 for (i = fMastersAllowed.begin(); i != fMastersAllowed.end(); ++i)
00651 TRACE(ALL, "masters allowed to connect: " << (*i)->c_str());
00652 } else {
00653 TRACE(ALL, "masters allowed to connect: any");
00654 }
00655 }
00656
00657
00658 if (fPoolURL.length() <= 0) {
00659
00660 fPoolURL = "root://";
00661 fPoolURL += fHost;
00662 }
00663 TRACE(ALL, "PROOF pool: " << fPoolURL);
00664 TRACE(ALL, "PROOF pool namespace: " << fNamespace);
00665
00666
00667 if (fSrvType != kXPD_Worker) {
00668
00669
00670 if (!(fProofSched = LoadScheduler())) {
00671 XPDERR("scheduler initialization failed");
00672 return 0;
00673 }
00674 const char *st[] = { "disabled", "enabled" };
00675 TRACE(ALL, "user config files are " << st[fNetMgr->WorkerUsrCfg()]);
00676 }
00677
00678
00679 if (fSrvType != kXPD_Worker && fDataSetSrcs.size() > 0) {
00680
00681 std::list<XrdProofdDSInfo *>::iterator ii = fDataSetSrcs.begin();
00682 bool goodsrc = 0;
00683 for (ii = fDataSetSrcs.begin(); ii != fDataSetSrcs.end();) {
00684 if (!(goodsrc = ValidateLocalDataSetSrc((*ii)->fUrl, (*ii)->fLocal))) {
00685 XPDERR("source " << (*ii)->fUrl << " could not be validated");
00686 ii = fDataSetSrcs.erase(ii);
00687 } else {
00688
00689 ii++;
00690 }
00691 }
00692 if (fDataSetSrcs.size() > 0) {
00693 TRACE(ALL, fDataSetSrcs.size() << " dataset sources defined");
00694 for (ii = fDataSetSrcs.begin(); ii != fDataSetSrcs.end(); ii++) {
00695 TRACE(ALL, " url:" << (*ii)->fUrl << ", local:" << (*ii)->fLocal << ", rw:" << (*ii)->fRW);
00696 }
00697 } else {
00698 TRACE(ALL, "no dataset sources defined");
00699 }
00700 } else {
00701 TRACE(ALL, "no dataset sources defined");
00702 }
00703
00704
00705 XrdProofUI sui;
00706 if (XrdProofdAux::GetUserInfo(XrdProofdProtocol::EUidAtStartup(), sui) == 0) {
00707 if (fSuperUsers.find(sui.fUser.c_str()) == STR_NPOS) {
00708 if (fSuperUsers.length() > 0) fSuperUsers += ",";
00709 fSuperUsers += sui.fUser;
00710 }
00711 } else {
00712 XPDFORM(msg, "could not resolve effective uid %d (errno: %d)",
00713 XrdProofdProtocol::EUidAtStartup(), errno);
00714 XPDERR(msg);
00715 }
00716 XPDFORM(msg, "list of superusers: %s", fSuperUsers.c_str());
00717 TRACE(ALL, msg);
00718
00719
00720 if (fOperationMode == kXPD_OpModeControlled) {
00721
00722 int from = 0;
00723 XrdOucString usr;
00724 while ((from = fSuperUsers.tokenize(usr, from, ',')) != STR_NPOS) {
00725 fAllowedUsers.Add(usr.c_str(), new int(1));
00726 }
00727
00728 XrdOucString uls;
00729 fAllowedUsers.Apply(FillKeyValues, (void *)&uls);
00730 if (uls.length()) {
00731 XPDFORM(msg, "running in controlled access mode: users allowed: %s", uls.c_str());
00732 TRACE(ALL, msg);
00733 }
00734
00735 XrdOucString gls;
00736 fAllowedGroups.Apply(FillKeyValues, (void *)&gls);
00737 if (gls.length()) {
00738 XPDFORM(msg, "running in controlled access mode: UNIX groups allowed: %s", gls.c_str());
00739 TRACE(ALL, msg);
00740 }
00741 }
00742
00743
00744 if (getenv(XPD_LIBPATH)) {
00745
00746 XrdOucString paths = getenv(XPD_LIBPATH);
00747 XrdOucString ldir;
00748 int from = 0;
00749 while ((from = paths.tokenize(ldir, from, ':')) != STR_NPOS) {
00750 bool isROOT = 0;
00751 if (ldir.length() > 0) {
00752
00753 DIR *dir = opendir(ldir.c_str());
00754 if (dir) {
00755
00756 struct dirent *ent = 0;
00757 while ((ent = (struct dirent *)readdir(dir))) {
00758 if (!strncmp(ent->d_name, "libCore", 7)) {
00759 isROOT = 1;
00760 break;
00761 }
00762 }
00763
00764 closedir(dir);
00765 }
00766 if (!isROOT) {
00767 if (fBareLibPath.length() > 0)
00768 fBareLibPath += ":";
00769 fBareLibPath += ldir;
00770 }
00771 }
00772 }
00773 TRACE(ALL, "bare lib path for proofserv: " << fBareLibPath);
00774 }
00775
00776
00777 if (!fGroupsMgr)
00778
00779 fGroupsMgr = new XrdProofGroupMgr;
00780
00781 if (fGroupsMgr)
00782 fGroupsMgr->Print(0);
00783
00784
00785 if (fAdmin && fAdmin->Config(rcf) != 0) {
00786 XPDERR("problems configuring the admin handler");
00787 return -1;
00788 }
00789
00790
00791 if (fNetMgr && fNetMgr->Config(rcf) != 0) {
00792 XPDERR("problems configuring the network manager");
00793 return -1;
00794 }
00795
00796
00797 if (fPriorityMgr && fPriorityMgr->Config(rcf) != 0) {
00798 XPDERR("problems configuring the priority manager");
00799 return -1;
00800 }
00801
00802
00803 if (fROOTMgr) {
00804 fROOTMgr->SetLogDir(fAdminPath.c_str());
00805 if (fROOTMgr && fROOTMgr->Config(rcf) != 0) {
00806 XPDERR("problems configuring the ROOT versions manager");
00807 return -1;
00808 }
00809 }
00810
00811
00812 if (fClientMgr && fClientMgr->Config(rcf) != 0) {
00813 XPDERR("problems configuring the client manager");
00814 return -1;
00815 }
00816
00817
00818 if (fSessionMgr && fSessionMgr->Config(rcf) != 0) {
00819 XPDERR("problems configuring the session manager");
00820 return -1;
00821 }
00822
00823
00824 if (fProofSched && fProofSched->Config(rcf) != 0) {
00825 XPDERR("problems configuring the scheduler");
00826 return -1;
00827 }
00828
00829 if (!rcf) {
00830
00831 pthread_t tid;
00832 if (XrdSysThread::Run(&tid, XrdProofdManagerCron,
00833 (void *)this, 0, "ProofdManager cron thread") != 0) {
00834 XPDERR("could not start cron thread");
00835 return 0;
00836 }
00837 TRACE(ALL, "manager cron thread started");
00838 }
00839
00840
00841 return 0;
00842 }
00843
00844
00845 bool XrdProofdManager::ValidateLocalDataSetSrc(XrdOucString &url, bool &local)
00846 {
00847
00848
00849
00850 XPDLOC(ALL, "Manager::ValidateLocalDataSetSrc")
00851
00852 TRACE(ALL, "validating '" << url << "' ...");
00853 local = 0;
00854 bool goodsrc = 1;
00855 if (url.length() > 0) {
00856
00857 if (url.beginswith("file:")) url.replace("file:", "");
00858 if (url.beginswith("/")) {
00859 local = 1;
00860 goodsrc = 0;
00861
00862 XrdProofUI ui;
00863 XrdProofdAux::GetUserInfo(XrdProofdProtocol::EUidAtStartup(), ui);
00864 if (XrdProofdAux::AssertDir(url.c_str(), ui, ChangeOwn()) == 0) {
00865 goodsrc = 1;
00866 if (XrdProofdAux::ChangeMod(url.c_str(), 0777) != 0) {
00867 TRACE(XERR, "Problems setting permissions 0777 on path '" << url << "'");
00868 }
00869 } else {
00870 TRACE(XERR, "Cannot assert path '" << url << "' - ignoring");
00871 }
00872 if (goodsrc) {
00873
00874 XrdOucString fnpath(url.c_str());
00875 fnpath += "/dataset.list";
00876 if (access(fnpath.c_str(), F_OK) != 0) {
00877 FILE *flst = fopen(fnpath.c_str(), "w");
00878 if (!flst) {
00879 TRACE(XERR, "Cannot open file '" << fnpath << "' for the dataset list; errno: " << errno);
00880 goodsrc = 0;
00881 } else {
00882 if (fclose(flst) != 0)
00883 TRACE(XERR, "Problems closing file '" << fnpath << "'; errno: " << errno);
00884 if (XrdProofdAux::ChangeOwn(fnpath.c_str(), ui) != 0) {
00885 TRACE(XERR, "Problems asserting ownership of " << fnpath);
00886 }
00887 }
00888 }
00889
00890 if (goodsrc && XrdProofdAux::ChangeMod(fnpath.c_str(), 0666) != 0) {
00891 TRACE(XERR, "Problems setting permissions to 0666 on file '" << fnpath << "'; errno: " << errno);
00892 goodsrc = 0;
00893 }
00894
00895 if (goodsrc) {
00896 fnpath.replace("/dataset.list", "/lock.location");
00897 if (access(fnpath.c_str(), F_OK) != 0) {
00898 FILE *flck = fopen(fnpath.c_str(), "w");
00899 if (!flck) {
00900 TRACE(XERR, "Cannot open file '" << fnpath << "' with the lock file path; errno: " << errno);
00901 } else {
00902
00903 XrdOucString fnlock(url);
00904 fnlock.replace("/", "%");
00905 fnlock.replace(":", "%");
00906 fnlock.insert("/tmp/", 0);
00907 fprintf(flck, "%s\n", fnlock.c_str());
00908 if (fclose(flck) != 0)
00909 TRACE(XERR, "Problems closing file '" << fnpath << "'; errno: " << errno);
00910 if (XrdProofdAux::ChangeOwn(fnpath.c_str(), ui) != 0) {
00911 TRACE(XERR, "Problems asserting ownership of " << fnpath);
00912 }
00913 }
00914 }
00915 }
00916
00917 if (goodsrc && XrdProofdAux::ChangeMod(fnpath.c_str(), 0644) != 0) {
00918 TRACE(XERR, "Problems setting permissions to 0644 on file '" << fnpath << "'; errno: " << errno);
00919 }
00920 }
00921 }
00922 }
00923
00924 return goodsrc;
00925 }
00926
00927
00928 void XrdProofdManager::RegisterDirectives()
00929 {
00930
00931
00932
00933 Register("trace", new XrdProofdDirective("trace", this, &DoDirectiveClass));
00934 Register("groupfile", new XrdProofdDirective("groupfile", this, &DoDirectiveClass));
00935 Register("multiuser", new XrdProofdDirective("multiuser", this, &DoDirectiveClass));
00936 Register("maxoldlogs", new XrdProofdDirective("maxoldlogs", this, &DoDirectiveClass));
00937 Register("allow", new XrdProofdDirective("allow", this, &DoDirectiveClass));
00938 Register("allowedgroups", new XrdProofdDirective("allowedgroups", this, &DoDirectiveClass));
00939 Register("allowedusers", new XrdProofdDirective("allowedusers", this, &DoDirectiveClass));
00940 Register("role", new XrdProofdDirective("role", this, &DoDirectiveClass));
00941 Register("cron", new XrdProofdDirective("cron", this, &DoDirectiveClass));
00942 Register("port", new XrdProofdDirective("port", this, &DoDirectiveClass));
00943 Register("datadir", new XrdProofdDirective("datadir", this, &DoDirectiveClass));
00944 Register("datasetsrc", new XrdProofdDirective("datasetsrc", this, &DoDirectiveClass));
00945 Register("xrd.protocol", new XrdProofdDirective("xrd.protocol", this, &DoDirectiveClass));
00946
00947 Register("tmp", new XrdProofdDirective("tmp", (void *)&fTMPdir, &DoDirectiveString));
00948 Register("poolurl", new XrdProofdDirective("poolurl", (void *)&fPoolURL, &DoDirectiveString));
00949 Register("namespace", new XrdProofdDirective("namespace", (void *)&fNamespace, &DoDirectiveString));
00950 Register("superusers", new XrdProofdDirective("superusers", (void *)&fSuperUsers, &DoDirectiveString));
00951 Register("image", new XrdProofdDirective("image", (void *)&fImage, &DoDirectiveString));
00952 Register("workdir", new XrdProofdDirective("workdir", (void *)&fWorkDir, &DoDirectiveString));
00953 Register("sockpathdir", new XrdProofdDirective("sockpathdir", (void *)&fSockPathDir, &DoDirectiveString));
00954 }
00955
00956
00957 int XrdProofdManager::ResolveKeywords(XrdOucString &s, XrdProofdClient *pcl)
00958 {
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 XPDLOC(ALL, "Manager::ResolveKeywords")
00969
00970 int nk = 0;
00971
00972 TRACE(HDBG, "enter: " << s << " - WorkDir(): " << WorkDir());
00973
00974
00975 if (s.replace("<workdir>", WorkDir()))
00976 nk++;
00977
00978 TRACE(HDBG, "after <workdir>: " << s);
00979
00980
00981 if (s.replace("<host>", Host()))
00982 nk++;
00983
00984 TRACE(HDBG, "after <host>: " << s);
00985
00986
00987 if (pcl)
00988 if (s.replace("<user>", pcl->User()))
00989 nk++;
00990
00991
00992 if (pcl)
00993 if (s.replace("<group>", pcl->Group()))
00994 nk++;
00995
00996
00997 if (pcl)
00998 if (s.replace("<homedir>", pcl->UI().fHomeDir.c_str()))
00999 nk++;
01000
01001
01002 if (pcl && (s.find("<uid>") != STR_NPOS)) {
01003 XrdOucString suid;
01004 suid += pcl->UI().fUid;
01005 if (s.replace("<uid>", suid.c_str()))
01006 nk++;
01007 }
01008
01009
01010 if (pcl && (s.find("<gid>") != STR_NPOS)) {
01011 XrdOucString sgid;
01012 sgid += pcl->UI().fGid;
01013 if (s.replace("<gid>", sgid.c_str()))
01014 nk++;
01015 }
01016
01017 TRACE(HDBG, "exit: " << s);
01018
01019
01020 return nk;
01021 }
01022
01023
01024
01025
01026
01027 int XrdProofdManager::DoDirective(XrdProofdDirective *d,
01028 char *val, XrdOucStream *cfg, bool rcf)
01029 {
01030
01031 XPDLOC(ALL, "Manager::DoDirective")
01032
01033 if (!d)
01034
01035 return -1;
01036
01037 if (d->fName == "trace") {
01038 return DoDirectiveTrace(val, cfg, rcf);
01039 } else if (d->fName == "groupfile") {
01040 return DoDirectiveGroupfile(val, cfg, rcf);
01041 } else if (d->fName == "maxoldlogs") {
01042 return DoDirectiveMaxOldLogs(val, cfg, rcf);
01043 } else if (d->fName == "allow") {
01044 return DoDirectiveAllow(val, cfg, rcf);
01045 } else if (d->fName == "allowedgroups") {
01046 return DoDirectiveAllowedGroups(val, cfg, rcf);
01047 } else if (d->fName == "allowedusers") {
01048 return DoDirectiveAllowedUsers(val, cfg, rcf);
01049 } else if (d->fName == "role") {
01050 return DoDirectiveRole(val, cfg, rcf);
01051 } else if (d->fName == "multiuser") {
01052 return DoDirectiveMultiUser(val, cfg, rcf);
01053 } else if (d->fName == "port") {
01054 return DoDirectivePort(val, cfg, rcf);
01055 } else if (d->fName == "datadir") {
01056 return DoDirectiveDataDir(val, cfg, rcf);
01057 } else if (d->fName == "datasetsrc") {
01058 return DoDirectiveDataSetSrc(val, cfg, rcf);
01059 } else if (d->fName == "xrd.protocol") {
01060 return DoDirectivePort(val, cfg, rcf);
01061 }
01062 TRACE(XERR, "unknown directive: " << d->fName);
01063 return -1;
01064 }
01065
01066
01067 int XrdProofdManager::DoDirectiveTrace(char *val, XrdOucStream *cfg, bool)
01068 {
01069
01070 XPDLOC(ALL, "Manager::DoDirectiveTrace")
01071
01072 if (!val || !cfg)
01073
01074 return -1;
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 while (val && val[0]) {
01108 bool on = 1;
01109 if (val[0] == '-') {
01110 on = 0;
01111 val++;
01112 }
01113 if (!strcmp(val, "err")) {
01114 TRACESET(XERR, on);
01115 } else if (!strcmp(val, "req")) {
01116 TRACESET(REQ, on);
01117 } else if (!strcmp(val, "dbg")) {
01118 TRACESET(DBG, on);
01119 TRACESET(LOGIN, on);
01120 TRACESET(FORK, on);
01121 TRACESET(MEM, on);
01122 } else if (!strcmp(val, "login")) {
01123 TRACESET(LOGIN, on);
01124 } else if (!strcmp(val, "fork")) {
01125 TRACESET(FORK, on);
01126 } else if (!strcmp(val, "mem")) {
01127 TRACESET(MEM, on);
01128 } else if (!strcmp(val, "hdbg")) {
01129 TRACESET(HDBG, on);
01130 TRACESET(DBG, on);
01131 TRACESET(LOGIN, on);
01132 TRACESET(FORK, on);
01133 TRACESET(MEM, on);
01134 } else if (!strcmp(val, "rsp")) {
01135 TRACESET(RSP, on);
01136 } else if (!strcmp(val, "aux")) {
01137 TRACESET(AUX, on);
01138 } else if (!strcmp(val, "cmgr")) {
01139 TRACESET(CMGR, on);
01140 } else if (!strcmp(val, "smgr")) {
01141 TRACESET(SMGR, on);
01142 } else if (!strcmp(val, "nmgr")) {
01143 TRACESET(NMGR, on);
01144 } else if (!strcmp(val, "pmgr")) {
01145 TRACESET(PMGR, on);
01146 } else if (!strcmp(val, "gmgr")) {
01147 TRACESET(GMGR, on);
01148 } else if (!strcmp(val, "sched")) {
01149 TRACESET(SCHED, on);
01150 } else if (!strcmp(val, "all") || !strcmp(val, "dump")) {
01151
01152 TRACE(ALL, "Setting trace: " << on);
01153 XrdProofdTrace->What = (on) ? TRACE_ALL : 0;
01154 }
01155
01156
01157 val = cfg->GetWord();
01158 }
01159
01160 return 0;
01161 }
01162
01163
01164 int XrdProofdManager::DoDirectiveGroupfile(char *val, XrdOucStream *cfg, bool rcf)
01165 {
01166
01167 XPDLOC(ALL, "Manager::DoDirectiveGroupfile")
01168
01169 if (!val)
01170
01171 return -1;
01172
01173
01174 if (Host() && cfg)
01175 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01176 return 0;
01177
01178
01179 if (rcf) {
01180 SafeDelete(fGroupsMgr);
01181 } else if (fGroupsMgr) {
01182 TRACE(XERR, "groups manager already initialized: ignoring ");
01183 return -1;
01184 }
01185 fGroupsMgr = new XrdProofGroupMgr;
01186 fGroupsMgr->Config(val);
01187 return 0;
01188 }
01189
01190
01191 int XrdProofdManager::DoDirectiveMaxOldLogs(char *val, XrdOucStream *cfg, bool)
01192 {
01193
01194
01195 if (!val)
01196
01197 return -1;
01198
01199
01200 if (Host() && cfg)
01201 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01202 return 0;
01203
01204
01205 int maxoldlogs = strtol(val, 0, 10);
01206 XrdProofdSandbox::SetMaxOldSessions(maxoldlogs);
01207 return 0;
01208 }
01209
01210
01211 int XrdProofdManager::DoDirectiveAllow(char *val, XrdOucStream *cfg, bool)
01212 {
01213
01214
01215 if (!val)
01216
01217 return -1;
01218
01219
01220 if (Host() && cfg)
01221 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01222 return 0;
01223
01224
01225 fMastersAllowed.push_back(new XrdOucString(val));
01226 return 0;
01227 }
01228
01229
01230 int XrdProofdManager::DoDirectiveAllowedGroups(char *val, XrdOucStream *cfg, bool)
01231 {
01232
01233 XPDLOC(ALL, "Manager::DoDirectiveAllowedGroups")
01234
01235 if (!val)
01236
01237 return -1;
01238
01239
01240 if (Host() && cfg)
01241 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01242 return 0;
01243
01244
01245 fOperationMode = kXPD_OpModeControlled;
01246
01247
01248 XrdOucString s = val;
01249 int from = 0;
01250 XrdOucString grp;
01251 XrdProofGI gi;
01252 while ((from = s.tokenize(grp, from, ',')) != STR_NPOS) {
01253 int st = 1;
01254 if (grp.beginswith('-')) {
01255 st = 0;
01256 grp.erasefromstart(1);
01257 }
01258 int rc = 0;
01259 if ((rc = XrdProofdAux::GetGroupInfo(grp.c_str(), gi)) == 0) {
01260
01261 fAllowedGroups.Add(grp.c_str(), new int(st));
01262 } else {
01263 TRACE(XERR, "problems getting info for group: '" << grp << "' - errno: " << -rc);
01264 }
01265 }
01266
01267
01268 return 0;
01269 }
01270
01271
01272 int XrdProofdManager::DoDirectiveAllowedUsers(char *val, XrdOucStream *cfg, bool)
01273 {
01274
01275 XPDLOC(ALL, "Manager::DoDirectiveAllowedUsers")
01276
01277 if (!val)
01278
01279 return -1;
01280
01281
01282 if (Host() && cfg)
01283 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01284 return 0;
01285
01286
01287 fOperationMode = kXPD_OpModeControlled;
01288
01289
01290 XrdOucString s = val;
01291 int from = 0;
01292 XrdOucString usr;
01293 XrdProofUI ui;
01294 while ((from = s.tokenize(usr, from, ',')) != STR_NPOS) {
01295 int st = 1;
01296 if (usr.beginswith('-')) {
01297 st = 0;
01298 usr.erasefromstart(1);
01299 }
01300 int rc = 0;
01301 if ((rc = XrdProofdAux::GetUserInfo(usr.c_str(), ui)) == 0) {
01302
01303 fAllowedUsers.Add(usr.c_str(), new int(st));
01304 } else {
01305 TRACE(XERR, "problems getting info for user: '" << usr << "' - errno: " << -rc);
01306 }
01307 }
01308
01309
01310 return 0;
01311 }
01312
01313
01314 int XrdProofdManager::DoDirectiveRole(char *val, XrdOucStream *cfg, bool)
01315 {
01316
01317 #if defined(BUILD_BONJOUR)
01318 XPDLOC(ALL, "Manager::DoDirectiveRole")
01319 #endif
01320
01321 if (!val)
01322
01323 return -1;
01324
01325
01326 if (Host() && cfg)
01327 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01328 return 0;
01329
01330
01331 XrdOucString tval(val);
01332 if (tval == "supermaster") {
01333 fSrvType = kXPD_TopMaster;
01334 fSuperMst = 1;
01335 } else if (tval == "master") {
01336 fSrvType = kXPD_TopMaster;
01337 } else if (tval == "submaster") {
01338 fSrvType = kXPD_Master;
01339 } else if (tval == "worker") {
01340 fSrvType = kXPD_Worker;
01341 } else if (tval == "any") {
01342 fSrvType = kXPD_AnyServer;
01343 }
01344
01345 #if defined(BUILD_BONJOUR)
01346
01347 if (!XrdProofdNetMgr::CheckBonjourRoleCoherence(SrvType(), fNetMgr->GetBonjourRequestedServiceType())) {
01348 TRACE(XERR, "Warning: xpd.role directive and xpd.bonjour service selection are not compatible");
01349 }
01350 #endif
01351
01352 return 0;
01353 }
01354
01355
01356 int XrdProofdManager::DoDirectivePort(char *val, XrdOucStream *, bool)
01357 {
01358
01359
01360 if (!val)
01361
01362 return -1;
01363
01364 XrdOucString port(val);
01365 if (port.beginswith("xproofd:")) {
01366 port.replace("xproofd:", "");
01367 }
01368 if (port.length() > 0 && port.isdigit()) {
01369 fPort = strtol(port.c_str(), 0, 10);
01370 }
01371 fPort = (fPort < 0) ? XPD_DEF_PORT : fPort;
01372
01373 return 0;
01374 }
01375
01376
01377 int XrdProofdManager::DoDirectiveMultiUser(char *val, XrdOucStream *cfg, bool)
01378 {
01379
01380
01381 if (!val)
01382
01383 return -1;
01384
01385
01386 if (Host() && cfg)
01387 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01388 return 0;
01389
01390
01391 int mu = strtol(val, 0, 10);
01392 fMultiUser = (mu == 1) ? 1 : fMultiUser;
01393 return 0;
01394 }
01395
01396
01397 int XrdProofdManager::DoDirectiveDataSetSrc(char *val, XrdOucStream *cfg, bool)
01398 {
01399
01400
01401 if (!val)
01402
01403 return -1;
01404
01405
01406 XrdOucString type(val), url, opts;
01407 bool rw = 0, local = 0, goodsrc = 1;
01408 char *nxt = 0;
01409 while ((nxt = cfg->GetWord())) {
01410 if (!strcmp(nxt, "rw=1") || !strcmp(nxt, "rw:1")) {
01411 rw = 1;
01412 } else if (!strncmp(nxt, "url:", 4)) {
01413 url = nxt + 4;
01414 } else if (!strncmp(nxt, "opt:", 4)) {
01415 opts = nxt + 4;
01416 }
01417 }
01418
01419
01420 if (goodsrc) {
01421
01422 std::list<XrdProofdDSInfo *>::iterator ii = fDataSetSrcs.begin();
01423 bool haslocal = 0;
01424 for (ii = fDataSetSrcs.begin(); ii != fDataSetSrcs.end(); ii++) {
01425 if ((*ii)->fLocal) {
01426 haslocal = 1;
01427 break;
01428 }
01429 }
01430
01431 if (opts.length() <= 0) {
01432 opts = rw ? "Ar:Av:" : "-Ar:-Av:";
01433 }
01434 if (haslocal || !local) {
01435 fDataSetSrcs.push_back(new XrdProofdDSInfo(type.c_str(), url.c_str(), local, rw, opts.c_str()));
01436 } else {
01437 fDataSetSrcs.push_front(new XrdProofdDSInfo(type.c_str(), url.c_str(), local, rw, opts.c_str()));
01438 }
01439 }
01440 return 0;
01441 }
01442
01443
01444 int XrdProofdManager::DoDirectiveDataDir(char *val, XrdOucStream *cfg, bool)
01445 {
01446
01447
01448 if (!val)
01449
01450 return -1;
01451
01452
01453 fDataDir = val;
01454 XrdOucString opts;
01455 char *nxt = 0;
01456 while ((nxt = cfg->GetWord()) && (opts.length() == 0)) {
01457 opts = nxt;
01458 }
01459 if (opts.length() > 0) fDataDirOpts = opts;
01460
01461
01462 return 0;
01463 }
01464
01465
01466 int XrdProofdManager::Process(XrdProofdProtocol *p)
01467 {
01468
01469 XPDLOC(ALL, "Manager::Process")
01470
01471 int rc = 0;
01472 XPD_SETRESP(p, "Process");
01473
01474 TRACEP(p, REQ, "req id: " << p->Request()->header.requestid << " (" <<
01475 XrdProofdAux::ProofRequestTypes(p->Request()->header.requestid) << ")");
01476
01477
01478 if (!p->Status() || !(p->Status() & XPD_LOGGEDIN)) {
01479 switch (p->Request()->header.requestid) {
01480 case kXP_auth:
01481 return fClientMgr->Auth(p);
01482 case kXP_login:
01483 return fClientMgr->Login(p);
01484 default:
01485 TRACEP(p, XERR, "invalid request: " << p->Request()->header.requestid);
01486 response->Send(kXR_InvalidRequest, "Invalid request; user not logged in");
01487 return p->Link()->setEtext("protocol sequence error 1");
01488 }
01489 }
01490
01491
01492 XrdOucString emsg;
01493 switch (p->Request()->header.requestid) {
01494 case kXP_admin: {
01495 int type = ntohl(p->Request()->proof.int1);
01496 return fAdmin->Process(p, type);
01497 }
01498 case kXP_readbuf:
01499 return fNetMgr->ReadBuffer(p);
01500 case kXP_create:
01501 case kXP_destroy:
01502 case kXP_attach:
01503 case kXP_detach:
01504 return fSessionMgr->Process(p);
01505 default:
01506 emsg += "Invalid request: ";
01507 emsg += p->Request()->header.requestid;
01508 break;
01509 }
01510
01511
01512 response->Send(kXR_InvalidRequest, emsg.c_str());
01513
01514
01515 return 0;
01516 }