XrdProofdManager.cxx

Go to the documentation of this file.
00001 // @(#)root/proofd:$Id: XrdProofdManager.cxx 36944 2010-11-25 14:57:48Z ganis $
00002 // Author: G. Ganis June 2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // XrdProofdManager                                                     //
00015 //                                                                      //
00016 // Author: G. Ganis, CERN, 2007                                         //
00017 //                                                                      //
00018 // Class mapping manager functionality.                                 //
00019 // On masters it keeps info about the available worker nodes and allows //
00020 // communication with them.                                             //
00021 // On workers it handles the communication with the master.             //
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 // Tracing utilities
00055 #include "XrdProofdTrace.h"
00056 
00057 //--------------------------------------------------------------------------
00058 //
00059 // XrdProofdManagerCron
00060 //
00061 // Function run in separate thread doing regular checks
00062 //
00063 //--------------------------------------------------------------------------
00064 void *XrdProofdManagerCron(void *p)
00065 {
00066    // This is an endless loop to periodically check the system
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    // Get Midnight time
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       // Do something here
00087       TRACE(REQ, "running periodical checks");
00088       // Check the log file ownership
00089       mgr->CheckLogFileOwnership();
00090       // Wait a while
00091       int tw = mgr->CronFrequency();
00092       now = time(0);
00093       if ((mid - now) <= tw) {
00094          tw = mid - now + 2; // Always run a check just after midnight
00095          mid += 86400;
00096       }
00097       
00098       // Check if reconfiguration of some services is required (triggered by a change
00099       // of the configuration file)
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    // Should never come here
00107    return (void *)0;
00108 }
00109 
00110 //__________________________________________________________________________
00111 XrdProofdManager::XrdProofdManager(XrdProtocol_Config *pi, XrdSysError *edest)
00112                  : XrdProofdConfig(pi->ConfigFN, edest)
00113 {
00114    // Constructor
00115 
00116    fSrvType = kXPD_AnyServer;
00117    fEffectiveUser = "";
00118    fHost = "";
00119    fPort = XPD_DEF_PORT;
00120    fImage = "";        // image name for these servers
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    // Data dir
00133    fDataDir = "";        // Default <workdir>/<user>/data
00134    fDataDirOpts = "gW";  // Default: user and group can write in it; create directories
00135                          //          only for workers (or any type)
00136 
00137    // Proof admin path
00138    fAdminPath = pi->AdmPath;
00139    fAdminPath += "/.xproofd.";
00140 
00141    // Services
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    // Configuration directives
00152    RegisterDirectives();
00153 
00154    // Admin request handler
00155    fAdmin = new XrdProofdAdmin(this, pi, edest);
00156 
00157    // Client manager
00158    fClientMgr = new XrdProofdClientMgr(this, pi, edest);
00159 
00160    // Network manager
00161    fNetMgr = new XrdProofdNetMgr(this, pi, edest);
00162 
00163    // Priority manager
00164    fPriorityMgr = new XrdProofdPriorityMgr(this, pi, edest);
00165 
00166    // ROOT versions manager
00167    fROOTMgr = new XrdROOTMgr(this, pi, edest);
00168 
00169    // Session manager
00170    fSessionMgr = new XrdProofdProofServMgr(this, pi, edest);
00171 }
00172 
00173 //__________________________________________________________________________
00174 XrdProofdManager::~XrdProofdManager()
00175 {
00176    // Destructor
00177 
00178    // Destroy the configuration handler
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    // Make sure that the log file belongs to the original effective user
00192    XPDLOC(ALL, "Manager::CheckLogFileOwnership")
00193 
00194    // Nothing to do if not priviledged
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    // Get original effective user identity
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    // Set ownership of the log file to the effective user
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    // Check if master 'm' is allowed to connect to this host
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    // We are done
00242    return rc;
00243 }
00244 
00245 //_____________________________________________________________________________
00246 int XrdProofdManager::CheckUser(const char *usr,
00247                                 XrdProofUI &ui, XrdOucString &e, bool &su)
00248 {
00249    // Check if the user is allowed to use the system
00250    // Return 0 if OK, -1 if not.
00251 
00252    su = 0;
00253    // User must be defined
00254    if (!usr || strlen(usr) <= 0) {
00255       e = "CheckUser: 'usr' string is undefined ";
00256       return -1;
00257    }
00258 
00259    // No 'root' logins
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    // Here we check if the user is known locally.
00268    // If not, we fail for now.
00269    // In the future we may try to get a temporary account
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    // Check if super user
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    // If we are in controlled mode we have to check if the user (and possibly
00297    // its group) are in the authorized lists; otherwise we fail.
00298    // Privileged users are always allowed to connect.
00299    if (fOperationMode == kXPD_OpModeControlled) {
00300 
00301       // Policy: check first the general switch for groups; a user of a specific group can be
00302       // rejected by prefixing a '-'.
00303       // If a user is explicitely allowed we give the green light even if her/its group is
00304       // disallowed. If fAllowedUsers is empty, we just apply the group rules.
00305       //
00306       // Example:
00307       //
00308       // xpd.allowedgroups z2
00309       // xpd.allowedusers -jgrosseo,ganis
00310       //
00311       // accepts connections from all group 'z2' except user 'jgrosseo' and from user 'ganis'
00312       // even if not belonging to group 'z2'.
00313 
00314       bool grpok = 1;
00315       // Check unix group
00316       if (fAllowedGroups.Num() > 0) {
00317          // Reset the flag
00318          grpok = 0;
00319          // Get full group info
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       // Check username
00333       bool usrok = grpok;
00334       if (fAllowedUsers.Num() > 0) {
00335          // Look into the hash
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       // Super users are always allowed
00349       if (!usrok && su) {
00350          usrok = 1;
00351          e = "";
00352       }
00353       // Return now if disallowed
00354       if (!usrok) return -1;
00355    }
00356 
00357    // OK
00358    return 0;
00359 }
00360 
00361 //_____________________________________________________________________________
00362 XrdProofSched *XrdProofdManager::LoadScheduler()
00363 {
00364    // Load PROOF scheduler
00365    XPDLOC(ALL, "Manager::LoadScheduler")
00366 
00367    XrdProofSched *sched = 0;
00368    XrdOucString name, lib, m;
00369 
00370    const char *cfn = CfgFile();
00371 
00372    // Locate first the relevant directives in the config file
00373    if (cfn && strlen(cfn) > 0) {
00374       XrdOucEnv myEnv;
00375       XrdOucStream cfg(fEDest, getenv("XRDINSTANCE"), &myEnv);
00376       // Open and attach the config file
00377       int cfgFD;
00378       if ((cfgFD = open(cfn, O_RDONLY, 0)) >= 0) {
00379          cfg.Attach(cfgFD);
00380          // Process items
00381          char *val = 0, *var = 0;
00382          while ((var = cfg.GetMyFirstWord())) {
00383             if (!(strcmp("xpd.sched", var))) {
00384                // Get the name
00385                val = cfg.GetWord();
00386                if (val && val[0]) {
00387                   name = val;
00388                   // Get the lib
00389                   val = cfg.GetWord();
00390                   if (val && val[0])
00391                      lib = val;
00392                   // We are done
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    // If undefined or default init a default instance
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       // Load the required plugin
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       // Get the scheduler object creator
00420       XrdProofSchedLoader_t ep = (XrdProofSchedLoader_t) h->getPlugin("XrdgetProofSched", 1);
00421       if (!ep) {
00422          delete h;
00423          return (XrdProofSched *)0;
00424       }
00425       // Get the scheduler object
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    // Check result
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    // Notify
00438    TRACE(ALL, "scheduler loaded: type: " << sched->Name());
00439 
00440    // All done
00441    return sched;
00442 }
00443 
00444 //__________________________________________________________________________
00445 int XrdProofdManager::GetWorkers(XrdOucString &lw, XrdProofdProofServ *xps,
00446                                  const char *query)
00447 {
00448    // Get a list of workers from the available resource broker
00449    XPDLOC(ALL, "Manager::GetWorkers")
00450 
00451    int rc = 0;
00452    TRACE(REQ, "enter");
00453 
00454    // We need the scheduler at this point
00455    if (!fProofSched) {
00456       TRACE(XERR, "scheduler undefined");
00457       return -1;
00458    }
00459 
00460    // Query the scheduler for the list of workers
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    // If we got a new list we save it into the session object
00467    if (rc == 0) {
00468 
00469       TRACE(DBG, "list size: " << wrks.size());
00470 
00471       // The full list
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          // Count (fActive is increased inside here)
00478          if (ii == -1)
00479             ord = "master";
00480          else
00481             XPDFORM(ord, "%d", ii);
00482          ii++;
00483          xps->AddWorker(ord.c_str(), w);
00484          // Add proofserv and increase the counter
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       // Get the list in exported format
00492       xps->ExportWorkers(lw);
00493       TRACE(DBG, "from ExportWorkers: " << lw);
00494    } else if (proto >= 21) {
00495       // Signal enqueing
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    // Add the key value in the string passed via the void argument
00508 
00509    XrdOucString *ls = (XrdOucString *)s;
00510 
00511    if (ls) {
00512       if (*d == 1) {
00513          // If not empty add a separation ','
00514          if (ls->length() > 0) *ls += ",";
00515          // Add the key
00516          if (k) *ls += k;
00517       }
00518    } else {
00519       // Not enough info: stop
00520       return 1;
00521    }
00522 
00523    // Check next
00524    return 0;
00525 }
00526 
00527 //______________________________________________________________________________
00528 int XrdProofdManager::Config(bool rcf)
00529 {
00530    // Run configuration and parse the entered config directives.
00531    // Return 0 on success, -1 on error
00532    XPDLOC(ALL, "Manager::Config")
00533 
00534    XrdSysMutexHelper mtxh(fMutex);
00535 
00536    // Run first the configurator
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    // Change/DonotChange ownership when logging clients
00547    fChangeOwn = (fMultiUser && getuid()) ? 0 : 1;
00548 
00549    // Notify port
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       // Save Effective user
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       // Local FQDN
00566       char *host = XrdNetDNS::getHostName();
00567       fHost = host ? host : "";
00568       SafeFree(host);
00569 
00570       // Notify temporary directory
00571       TRACE(ALL, "using temp dir: " << fTMPdir);
00572 
00573       // Notify role
00574       const char *roles[] = { "any", "worker", "submaster", "master" };
00575       TRACE(ALL, "role set to: " << roles[fSrvType+1]);
00576 
00577       // Admin path
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       // Path for Unix sockets
00586       if (fSockPathDir.length() <= 0) {
00587          // Use default under the admin path
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       // Create / Update the process ID file under the admin path
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    // Work directory, if specified
00615    if (fWorkDir.length() > 0) {
00616       // Make sure it exists
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       // Communicate it to the sandbox service
00623       XrdProofdSandbox::SetWorkdir(fWorkDir.c_str());
00624    }
00625 
00626    // Data directory, if specified
00627    if (fDataDir.length() > 0) {
00628       // Make sure it exists
00629       if (XrdProofdAux::AssertDir(fDataDir.c_str(), ui, fChangeOwn) != 0) {
00630          XPDERR("unable to assert data dir: " << fDataDir);
00631          return -1;
00632       }
00633       // Get the right privileges now
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    // Notify allow rules
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    // Pool and namespace
00658    if (fPoolURL.length() <= 0) {
00659       // Default pool entry point is this host
00660       fPoolURL = "root://";
00661       fPoolURL += fHost;
00662    }
00663    TRACE(ALL, "PROOF pool: " << fPoolURL);
00664    TRACE(ALL, "PROOF pool namespace: " << fNamespace);
00665 
00666    // Initialize resource broker (if not worker)
00667    if (fSrvType != kXPD_Worker) {
00668 
00669       // Scheduler instance
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    // Validate dataset sources (if not worker)
00679    if (fSrvType != kXPD_Worker && fDataSetSrcs.size() > 0) {
00680       // If first local, add it in front
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             // Check next
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    // Superusers: add the effective user at startup
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    // Notify controlled mode, if such
00720    if (fOperationMode == kXPD_OpModeControlled) {
00721       // Add superusers to the hash list of allowed users
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       // Extract now the list of allowed users
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       // Extract now the list of allowed groups
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    // Bare lib path
00744    if (getenv(XPD_LIBPATH)) {
00745       // Try to remove existing ROOT dirs in the path
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             // Check this dir
00753             DIR *dir = opendir(ldir.c_str());
00754             if (dir) {
00755                // Scan the directory
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                // Close the directory
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    // Groups
00777    if (!fGroupsMgr)
00778       // Create default group, if none explicitely requested
00779       fGroupsMgr = new XrdProofGroupMgr;
00780 
00781    if (fGroupsMgr)
00782       fGroupsMgr->Print(0);
00783 
00784    // Config the admin handler
00785    if (fAdmin && fAdmin->Config(rcf) != 0) {
00786       XPDERR("problems configuring the admin handler");
00787       return -1;
00788    }
00789 
00790    // Config the network manager
00791    if (fNetMgr && fNetMgr->Config(rcf) != 0) {
00792       XPDERR("problems configuring the network manager");
00793       return -1;
00794    }
00795 
00796    // Config the priority manager
00797    if (fPriorityMgr && fPriorityMgr->Config(rcf) != 0) {
00798       XPDERR("problems configuring the priority manager");
00799       return -1;
00800    }
00801 
00802    // Config the ROOT versions manager
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    // Config the client manager
00812    if (fClientMgr && fClientMgr->Config(rcf) != 0) {
00813       XPDERR("problems configuring the client manager");
00814       return -1;
00815    }
00816 
00817    // Config the session manager
00818    if (fSessionMgr && fSessionMgr->Config(rcf) != 0) {
00819       XPDERR("problems configuring the session manager");
00820       return -1;
00821    }
00822 
00823    // Config the scheduler
00824    if (fProofSched && fProofSched->Config(rcf) != 0) {
00825       XPDERR("problems configuring the scheduler");
00826       return -1;
00827    }
00828 
00829    if (!rcf) {
00830       // Start cron thread
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    // Done
00841    return 0;
00842 }
00843 
00844 //______________________________________________________________________________
00845 bool XrdProofdManager::ValidateLocalDataSetSrc(XrdOucString &url, bool &local)
00846 {
00847    // Validate local dataset src at URL (check the URL and make the relevant
00848    // directories).
00849    // Return 1 if OK, 0 if any problem arises
00850    XPDLOC(ALL, "Manager::ValidateLocalDataSetSrc")
00851 
00852    TRACE(ALL, "validating '" << url << "' ...");
00853    local = 0;
00854    bool goodsrc = 1;
00855    if (url.length() > 0) {
00856       // Check if local source
00857       if (url.beginswith("file:")) url.replace("file:", "");
00858       if (url.beginswith("/")) {
00859          local = 1;
00860          goodsrc = 0;
00861          // Make sure the directory exists and has mode 0755
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             // Assert the file with dataset summaries
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             // Make sure that everybody can modify the file for updates
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             // Assert the file with lock file path
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                      // Write the default lock file path
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             // Make sure that everybody can modify the file for updates
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    // Done
00924    return goodsrc;
00925 }
00926 
00927 //______________________________________________________________________________
00928 void XrdProofdManager::RegisterDirectives()
00929 {
00930    // Register directives for configuration
00931 
00932    // Register special config directives
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    // Register config directives for strings
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    // Resolve special keywords in 's' for client 'pcl'. Recognized keywords
00960    //     <workdir>          root for working dirs
00961    //     <host>             local host name
00962    //     <homedir>          user home dir
00963    //     <user>             user name
00964    //     <group>            user group
00965    //     <uid>              user ID
00966    //     <gid>              user group ID
00967    // Return the number of keywords resolved.
00968    XPDLOC(ALL, "Manager::ResolveKeywords")
00969 
00970    int nk = 0;
00971 
00972    TRACE(HDBG, "enter: " << s << " - WorkDir(): " << WorkDir());
00973 
00974    // Parse <workdir>
00975    if (s.replace("<workdir>", WorkDir()))
00976       nk++;
00977 
00978    TRACE(HDBG, "after <workdir>: " << s);
00979 
00980    // Parse <host>
00981    if (s.replace("<host>", Host()))
00982       nk++;
00983 
00984    TRACE(HDBG, "after <host>: " << s);
00985 
00986    // Parse <user>
00987    if (pcl)
00988       if (s.replace("<user>", pcl->User()))
00989          nk++;
00990 
00991    // Parse <group>
00992    if (pcl)
00993       if (s.replace("<group>", pcl->Group()))
00994          nk++;
00995 
00996    // Parse <homedir>
00997    if (pcl)
00998       if (s.replace("<homedir>", pcl->UI().fHomeDir.c_str()))
00999          nk++;
01000 
01001    // Parse <uid>
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    // Parse <gid>
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    // We are done
01020    return nk;
01021 }
01022 
01023 //
01024 // Special directive processors
01025 
01026 //______________________________________________________________________________
01027 int XrdProofdManager::DoDirective(XrdProofdDirective *d,
01028                                   char *val, XrdOucStream *cfg, bool rcf)
01029 {
01030    // Update the priorities of the active sessions.
01031    XPDLOC(ALL, "Manager::DoDirective")
01032 
01033    if (!d)
01034       // undefined inputs
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    // Scan the config file for tracing settings
01070    XPDLOC(ALL, "Manager::DoDirectiveTrace")
01071 
01072    if (!val || !cfg)
01073       // undefined inputs
01074       return -1;
01075 
01076    // Specifies tracing options. This works by levels and domains.
01077    //
01078    // Valid keyword levels are:
01079    //   err            trace errors                        [on]
01080    //   req            trace protocol requests             [on]*
01081    //   dbg            trace details about actions         [off]
01082    //   hdbg           trace more details about actions    [off]
01083    // Special forms of 'dbg' (always on if 'dbg' is required) are:
01084    //   login          trace details about login requests  [on]*
01085    //   fork           trace proofserv forks               [on]*
01086    //   mem            trace mem buffer manager            [off]
01087    //
01088    // Valid keyword domains are:
01089    //   rsp            server replies                      [off]
01090    //   aux            aux functions                       [on]
01091    //   cmgr           client manager                      [on]
01092    //   smgr           session manager                     [on]
01093    //   nmgr           network manager                     [on]
01094    //   pmgr           priority manager                    [on]
01095    //   gmgr           group manager                       [on]
01096    //   sched          details about scheduling            [on]
01097    //
01098    // Global switches:
01099    //   all or dump    full tracing of everything
01100    //
01101    // Defaults are shown in brackets; '*' shows the default when the '-d'
01102    // option is passed on the command line. Each option may be
01103    // optionally prefixed by a minus sign to turn off the setting.
01104    // Order matters: 'all' in last position enables everything; in first
01105    // position is corrected by subsequent settings
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          // Everything
01152          TRACE(ALL, "Setting trace: " << on);
01153          XrdProofdTrace->What = (on) ? TRACE_ALL : 0;
01154       }
01155 
01156       // Next
01157       val = cfg->GetWord();
01158    }
01159 
01160    return 0;
01161 }
01162 
01163 //______________________________________________________________________________
01164 int XrdProofdManager::DoDirectiveGroupfile(char *val, XrdOucStream *cfg, bool rcf)
01165 {
01166    // Process 'groupfile' directive
01167    XPDLOC(ALL, "Manager::DoDirectiveGroupfile")
01168 
01169    if (!val)
01170       // undefined inputs
01171       return -1;
01172 
01173    // Check deprecated 'if' directive
01174    if (Host() && cfg)
01175       if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01176          return 0;
01177 
01178    // Defines file with the group info
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    // Process 'maxoldlogs' directive
01194 
01195    if (!val)
01196       // undefined inputs
01197       return -1;
01198 
01199    // Check deprecated 'if' directive
01200    if (Host() && cfg)
01201       if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01202          return 0;
01203 
01204    // Max number of sessions per user
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    // Process 'allow' directive
01214 
01215    if (!val)
01216       // undefined inputs
01217       return -1;
01218 
01219    // Check deprecated 'if' directive
01220    if (Host() && cfg)
01221       if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01222          return 0;
01223 
01224    // Masters allowed to connect
01225    fMastersAllowed.push_back(new XrdOucString(val));
01226    return 0;
01227 }
01228 
01229 //______________________________________________________________________________
01230 int XrdProofdManager::DoDirectiveAllowedGroups(char *val, XrdOucStream *cfg, bool)
01231 {
01232    // Process 'allowedgroups' directive
01233    XPDLOC(ALL, "Manager::DoDirectiveAllowedGroups")
01234 
01235    if (!val)
01236       // undefined inputs
01237       return -1;
01238 
01239    // Check deprecated 'if' directive
01240    if (Host() && cfg)
01241       if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01242          return 0;
01243 
01244    // We are in controlled mode
01245    fOperationMode = kXPD_OpModeControlled;
01246 
01247    // Input list (comma separated) of UNIX groups allowed to connect
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          // Group name is known to the system: add it to the list
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    // Done
01268    return 0;
01269 }
01270 
01271 //______________________________________________________________________________
01272 int XrdProofdManager::DoDirectiveAllowedUsers(char *val, XrdOucStream *cfg, bool)
01273 {
01274    // Process 'allowedusers' directive
01275    XPDLOC(ALL, "Manager::DoDirectiveAllowedUsers")
01276 
01277    if (!val)
01278       // undefined inputs
01279       return -1;
01280 
01281    // Check deprecated 'if' directive
01282    if (Host() && cfg)
01283       if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01284          return 0;
01285 
01286    // We are in controlled mode
01287    fOperationMode = kXPD_OpModeControlled;
01288 
01289    // Input list (comma separated) of users allowed to connect
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          // Username is known to the system: add it to the list
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    // Done
01310    return 0;
01311 }
01312 
01313 //______________________________________________________________________________
01314 int XrdProofdManager::DoDirectiveRole(char *val, XrdOucStream *cfg, bool)
01315 {
01316    // Process 'role' directive
01317 #if defined(BUILD_BONJOUR)
01318    XPDLOC(ALL, "Manager::DoDirectiveRole")
01319 #endif
01320 
01321    if (!val)
01322       // undefined inputs
01323       return -1;
01324 
01325    // Check deprecated 'if' directive
01326    if (Host() && cfg)
01327       if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01328          return 0;
01329 
01330    // Role this server
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    // Check the compatibility of the roles and give a warning to the user.
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    // Process 'xrd.protocol' directive to find the port
01359 
01360    if (!val)
01361       // undefined inputs
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    // Process 'multiuser' directive
01380 
01381    if (!val)
01382       // undefined inputs
01383       return -1;
01384 
01385    // Check deprecated 'if' directive
01386    if (Host() && cfg)
01387       if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
01388          return 0;
01389 
01390    // Multi-user option
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    // Process 'datasetsrc' directive
01400 
01401    if (!val)
01402       // undefined inputs
01403       return -1;
01404 
01405    // URL for this source
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    // Add to the list
01420    if (goodsrc) {
01421       // If first local, add it in front
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       // Default options
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    // Process 'datadir' directive
01447 
01448    if (!val)
01449       // undefined inputs
01450       return -1;
01451 
01452    // Data directory and write permissions
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    // Done
01462    return 0;
01463 }
01464 
01465 //______________________________________________________________________________
01466 int XrdProofdManager::Process(XrdProofdProtocol *p)
01467 {
01468    // Process manager request
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    // If the user is not yet logged in, restrict what the user can do
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    // Once logged-in, the user can request the real actions
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    // Notify invalid request
01512    response->Send(kXR_InvalidRequest, emsg.c_str());
01513 
01514    // Done
01515    return 0;
01516 }

Generated on Tue Jul 5 14:51:51 2011 for ROOT_528-00b_version by  doxygen 1.5.1