Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
XrdProofdManager.cxx
Go to the documentation of this file.
1// @(#)root/proofd:$Id$
2// Author: G. Ganis June 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//////////////////////////////////////////////////////////////////////////
13// //
14// XrdProofdManager //
15// //
16// Author: G. Ganis, CERN, 2007 //
17// //
18// Class mapping manager functionality. //
19// On masters it keeps info about the available worker nodes and allows //
20// communication with them. //
21// On workers it handles the communication with the master. //
22// //
23//////////////////////////////////////////////////////////////////////////
24#include "XrdProofdPlatform.h"
25
26#include "XrdProofdManager.h"
27
28#include "XrdVersion.hh"
29#include "Xrd/XrdProtocol.hh"
30#include "XrdOuc/XrdOucEnv.hh"
31#include "XrdOuc/XrdOucStream.hh"
32#include "XrdSys/XrdSysPriv.hh"
33
34#include "XpdSysPlugin.h"
35#include "XpdSysTimer.h"
36#include "XpdSysDNS.h"
37
38#include "XrdProofdAdmin.h"
39#include "XrdProofdClient.h"
40#include "XrdProofdClientMgr.h"
41#include "XrdProofdConfig.h"
42#include "XrdProofdNetMgr.h"
45#include "XrdProofdProtocol.h"
46#include "XrdProofGroup.h"
47#include "XrdProofSched.h"
48#include "XrdProofdProofServ.h"
49#include "XrdProofWorker.h"
50#include "XrdROOT.h"
51#include "rpdconn.h"
52
53// Tracing utilities
54#include "XrdProofdTrace.h"
55
56#include <grp.h>
57#include <unistd.h>
58
59// Auxilliary sructure used internally to extract list of allowed/denied user names
60// when running in access control mode
61typedef struct {
62 XrdOucString allowed;
63 XrdOucString denied;
65
66// Protocol loader; arguments: const char *pname, char *parms, XrdProtocol_Config *pi
67typedef XrdProtocol *(*XrdProtocolLoader_t)(const char *, char *, XrdProtocol_Config *);
68
69#ifdef __sun
70/*-
71 * Copyright (c) 1991, 1993
72 * The Regents of the University of California. All rights reserved.
73 *
74 * Redistribution and use in source and binary forms, with or without
75 * modification, are permitted provided that the following conditions
76 * are met:
77 * 1. Redistributions of source code must retain the above copyright
78 * notice, this list of conditions and the following disclaimer.
79 * 2. Redistributions in binary form must reproduce the above copyright
80 * notice, this list of conditions and the following disclaimer in the
81 * documentation and/or other materials provided with the distribution.
82 * 3. All advertising materials mentioning features or use of this software
83 * must display the following acknowledgement:
84 * This product includes software developed by the University of
85 * California, Berkeley and its contributors.
86 * 4. Neither the name of the University nor the names of its contributors
87 * may be used to endorse or promote products derived from this software
88 * without specific prior written permission.
89 *
90 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
91 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
92 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
93 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
94 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
95 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
96 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
97 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
98 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
99 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
100 * SUCH DAMAGE.
101 */
102
103#if 0
104#if defined(LIBC_SCCS) && !defined(lint)
105static char sccsid[] = "@(#)getgrouplist.c 8.2 (Berkeley) 12/8/94";
106#endif /* LIBC_SCCS and not lint */
107#include <sys/cdefs.h>
108__FBSDID("$FreeBSD: src/lib/libc/gen/getgrouplist.c,v 1.14 2005/05/03 16:20:03 delphij Exp $");
109#endif
110
111/*
112 * get credential
113 */
114#include <sys/types.h>
115
116#include <string.h>
117
118int
119getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt)
120{
121 const struct group *grp;
122 int i, maxgroups, ngroups, ret;
123
124 ret = 0;
125 ngroups = 0;
126 maxgroups = *grpcnt;
127 /*
128 * When installing primary group, duplicate it;
129 * the first element of groups is the effective gid
130 * and will be overwritten when a setgid file is executed.
131 */
132 groups ? groups[ngroups++] = agroup : ngroups++;
133 if (maxgroups > 1)
134 groups ? groups[ngroups++] = agroup : ngroups++;
135 /*
136 * Scan the group file to find additional groups.
137 */
138 setgrent();
139 while ((grp = getgrent()) != NULL) {
140 if (groups) {
141 for (i = 0; i < ngroups; i++) {
142 if (grp->gr_gid == groups[i])
143 goto skip;
144 }
145 }
146 for (i = 0; grp->gr_mem[i]; i++) {
147 if (!strcmp(grp->gr_mem[i], uname)) {
148 if (ngroups >= maxgroups) {
149 ret = -1;
150 break;
151 }
152 groups ? groups[ngroups++] = grp->gr_gid : ngroups++;
153 break;
154 }
155 }
156skip:
157 ;
158 }
159 endgrent();
160 *grpcnt = ngroups;
161 return (ret);
162}
163#endif
164
165//--------------------------------------------------------------------------
166//
167// XrdProofdManagerCron
168//
169// Function run in separate thread doing regular checks
170//
171////////////////////////////////////////////////////////////////////////////////
172/// This is an endless loop to periodically check the system
173
175{
176 XPDLOC(PMGR, "ManagerCron")
177
179 if (!(mgr)) {
180 TRACE(REQ, "undefined manager: cannot start");
181 return (void *)0;
182 }
183
184 TRACE(REQ, "started with frequency " << mgr->CronFrequency() << " sec");
185
186 // Get Midnight time
187 int now = time(0);
188 int mid = XrdSysTimer::Midnight(now);
189 while (mid < now) {
190 mid += 86400;
191 }
192 TRACE(REQ, "midnight in " << (mid - now) << " secs");
193
194 while (1) {
195 // Do something here
196 TRACE(REQ, "running periodical checks");
197 // Check the log file ownership
199 // Wait a while
200 int tw = mgr->CronFrequency();
201 now = time(0);
202 if ((mid - now) <= tw) {
203 tw = mid - now + 2; // Always run a check just after midnight
204 mid += 86400;
205 }
206
207 // Check if reconfiguration of some services is required (triggered by a change
208 // of the configuration file)
209 if (mgr->SessionMgr()) mgr->SessionMgr()->Config(1);
210 if (mgr->GroupsMgr()) mgr->GroupsMgr()->Config(mgr->GroupsMgr()->GetCfgFile());
211
212 XrdSysTimer::Wait(tw * 1000);
213 }
214
215 // Should never come here
216 return (void *)0;
217}
218
219////////////////////////////////////////////////////////////////////////////////
220/// Constructor
221
222XrdProofdManager::XrdProofdManager(char *parms, XrdProtocol_Config *pi, XrdSysError *edest)
223 : XrdProofdConfig(pi->ConfigFN, edest)
224{
225
226 fParms = parms; // only used for construction: not to be trusted later on
227 fPi = pi; // only used for construction: not to be trusted later on
228
230 fEffectiveUser = "";
231 fHost = "";
233 fImage = ""; // image name for these servers
234 fSockPathDir = "";
235 fStageReqRepo = "";
236 fTMPdir = "/tmp";
237 fWorkDir = "";
238 fMUWorkDir = "";
239 fSuperMst = 0;
240 fRemotePLite = 0;
241 fNamespace = "/proofpool";
242 fMastersAllowed.clear();
244 fMultiUser = 0;
245 fChangeOwn = 0;
246 fCronFrequency = 30;
247
248 // Data dir
249 fDataDir = ""; // Default <workdir>/<user>/data
250 fDataDirOpts = ""; // Default: no action
251 fDataDirUrlOpts = ""; // Default: none
252
253 // Tools to enable xrootd file serving
254 fXrootdLibPath = "<>";
255 fXrootdPlugin = 0;
256
257 // Proof admin path
258 fAdminPath = pi->AdmPath;
259 fAdminPath += "/.xproofd.";
260
261 // Lib paths for proofserv
262 fBareLibPath = "";
264 fLibPathsToRemove.Purge();
265
266 // Services
267 fSched = pi->Sched;
268 fAdmin = 0;
269 fClientMgr = 0;
270 fGroupsMgr = 0;
271 fNetMgr = 0;
272 fPriorityMgr = 0;
273 fProofSched = 0;
274 fSessionMgr = 0;
275
276 // Configuration directives
278
279 // Admin request handler
280 fAdmin = new XrdProofdAdmin(this, pi, edest);
281
282 // Client manager
283 fClientMgr = new XrdProofdClientMgr(this, pi, edest);
284
285 // Network manager
286 fNetMgr = new XrdProofdNetMgr(this, pi, edest);
287
288 // Priority manager
289 fPriorityMgr = new XrdProofdPriorityMgr(this, pi, edest);
290
291 // ROOT versions manager
292 fROOTMgr = new XrdROOTMgr(this, pi, edest);
293
294 // Session manager
295 fSessionMgr = new XrdProofdProofServMgr(this, pi, edest);
296}
297
298////////////////////////////////////////////////////////////////////////////////
299/// Destructor
300
302{
303 // Destroy the configuration handler
312}
313
314////////////////////////////////////////////////////////////////////////////////
315/// Load the Xrootd protocol, if required
316
317XrdProtocol *XrdProofdManager::LoadXrootd(char *parms, XrdProtocol_Config *pi, XrdSysError *edest)
318{
319 XPDLOC(ALL, "Manager::LoadXrootd")
320
321 XrdProtocol *xrp = 0;
322
323 // Create the plug-in instance
324 fXrootdPlugin = new XrdSysPlugin((edest ? edest : (XrdSysError *)0), fXrootdLibPath.c_str());
325 if (!fXrootdPlugin) {
326 TRACE(XERR, "could not create plugin instance for "<<fXrootdLibPath.c_str());
327 return xrp;
328 }
329
330 // Get the function
331 XrdProtocolLoader_t ep = (XrdProtocolLoader_t) fXrootdPlugin->getPlugin("XrdgetProtocol");
332 if (!ep) {
333 TRACE(XERR, "could not find 'XrdgetProtocol()' in "<<fXrootdLibPath.c_str());
334 return xrp;
335 }
336
337 // Get the server object
338 if (!(xrp = (*ep)("xrootd", parms, pi))) {
339 TRACE(XERR, "Unable to create xrootd protocol service object via " << fXrootdLibPath.c_str());
341 } else {
342 // Notify
343 TRACE(ALL, "xrootd protocol service created");
344 }
345
346 return xrp;
347}
348
349////////////////////////////////////////////////////////////////////////////////
350/// Make sure that the log file belongs to the original effective user
351
353{
354 XPDLOC(ALL, "Manager::CheckLogFileOwnership")
355
356 // Nothing to do if not priviledged
357 if (getuid()) return;
358
359 struct stat st;
360 if (fstat(STDERR_FILENO, &st) != 0) {
361 if (errno != ENOENT) {
362 TRACE(XERR, "could not stat log file; errno: " << errno);
363 return;
364 }
365 }
366
367 TRACE(HDBG, "uid: " << st.st_uid << ", gid: " << st.st_gid);
368
369 // Get original effective user identity
370 struct passwd *epwd = getpwuid(XrdProofdProtocol::EUidAtStartup());
371 if (!epwd) {
372 TRACE(XERR, "could not get effective user identity; errno: " << errno);
373 return;
374 }
375
376 // Set ownership of the log file to the effective user
377 if (st.st_uid != epwd->pw_uid || st.st_gid != epwd->pw_gid) {
378 if (fchown(STDERR_FILENO, epwd->pw_uid, epwd->pw_gid) != 0) {
379 TRACE(XERR, "could not set stderr ownership; errno: " << errno);
380 return;
381 }
382 }
383}
384
385////////////////////////////////////////////////////////////////////////////////
386/// Check if master 'm' is allowed to connect to this host
387
389{
390 bool rc = 1;
391
392 if (fMastersAllowed.size() > 0) {
393 rc = 0;
394 XrdOucString wm(m);
395 std::list<XrdOucString *>::iterator i;
396 for (i = fMastersAllowed.begin(); i != fMastersAllowed.end(); ++i) {
397 if (wm.matches((*i)->c_str())) {
398 rc = 1;
399 break;
400 }
401 }
402 }
403
404 // We are done
405 return rc;
406}
407
408////////////////////////////////////////////////////////////////////////////////
409/// Check if the user is allowed to use the system
410/// Return 0 if OK, -1 if not.
411
412int XrdProofdManager::CheckUser(const char *usr, const char *grp,
413 XrdProofUI &ui, XrdOucString &e, bool &su)
414{
415 su = 0;
416 // User must be defined
417 if (!usr || strlen(usr) <= 0) {
418 e = "CheckUser: 'usr' string is undefined ";
419 return -1;
420 }
421
422 // No 'root' logins
423 if (strlen(usr) == 4 && !strcmp(usr, "root")) {
424 e = "CheckUser: 'root' logins not accepted ";
425 return -1;
426 }
427
428 // Group must be defined
429 if (!grp || strlen(grp) <= 0) {
430 e = "CheckUser: 'grp' string is undefined ";
431 return -1;
432 }
433
434 XrdSysMutexHelper mtxh(&fMutex);
435
436 // Here we check if the user is known locally.
437 // If not, we fail for now.
438 // In the future we may try to get a temporary account
439 if (fChangeOwn) {
440 if (XrdProofdAux::GetUserInfo(usr, ui) != 0) {
441 e = "CheckUser: unknown ClientID: ";
442 e += usr;
443 return -1;
444 }
445 } else {
446 // We assign the ui of the effective user
447 if (XrdProofdAux::GetUserInfo(geteuid(), ui) != 0) {
448 e = "CheckUser: problems getting user info for id: ";
449 e += (int)geteuid();
450 return -1;
451 }
452 }
453
454 // Check if super user
455 if (fSuperUsers.length() > 0) {
456 XrdOucString tkn;
457 int from = 0;
458 while ((from = fSuperUsers.tokenize(tkn, from, ',')) != -1) {
459 if (tkn == usr) {
460 su = 1;
461 break;
462 }
463 }
464 }
465
466 // If we are in controlled mode we have to check if the user (and possibly
467 // its group) are in the authorized lists; otherwise we fail.
468 // Privileged users are always allowed to connect.
470
471 // Policy: check first the general directive for groups; a user of a specific group
472 // (both UNIX or PROOF groups) can be rejected by prefixing a '-'.
473 // The group check fails if active (the allowedgroups directive has entries) and at
474 // least of the two groups (UNIX or PROOF) are explicitly denied.
475 // The result of the group check is superseeded by any explicit speicification in the
476 // allowedusers, either positive or negative.
477 // UNIX group includes secondary groups; this allows to enable/disable only members of a
478 // specific subgroup
479 //
480 // Examples:
481 // Consider user 'katy' with UNIX group 'alfa' and PROOF group 'student',
482 // users 'jack' and 'john' with UNIX group 'alfa' and PROOF group 'postdoc'.
483 //
484 // 1. xpd.allowedgroups alfa
485 // Users 'katy', 'jack' and 'john' are allowed because part of UNIX group 'alfa' (no 'allowedusers' directive)
486 // 2. xpd.allowedgroups student
487 // User 'katy' is allowed because part of PROOF group 'student';
488 // users 'jack' and 'john' are denied because not part of PROOF group 'student' (no 'allowedusers' directive)
489 // 3. xpd.allowedgroups alfa,-student
490 // User 'katy' is denied because part of PROOF group 'student' which is explicitly denied;
491 // users 'jack' and 'john' are allowed becasue part of UNIX group 'alfa' (no 'allowedusers' directive)
492 // 4. xpd.allowedgroups alfa,-student
493 // xpd.allowedusers katy,-jack
494 // User 'katy' is allowed because explicitly allowed by the 'allowedusers' directive;
495 // user 'jack' is denied because explicitly denied by the 'allowedusers' directive;
496 // user 'john' is allowed because part of 'alfa' and not explicitly denied by the 'allowedusers' directive
497 // (the allowedgroups directive is in this case ignored for users 'katy' and 'jack').
498
499 bool grpok = 1;
500 // Check unix groups (secondaries included)
501 if (fAllowedGroups.Num() > 0) {
502 // Reset the flag
503 grpok = 0;
504 int ugrpok = 0, pgrpok = 0;
505 // Check UNIX groups info
506 int ngrps = 10, neg, ig = 0;
507#if defined(__APPLE__)
508 int grps[10];
509#else
510 gid_t grps[10];
511#endif
512 XrdOucString g;
513 if ((neg = getgrouplist(usr, ui.fGid, grps, &ngrps)) < 0) neg = 10;
514 if (neg > 0) {
515 for (ig = 0; ig < neg; ig++) {
516 g.form("%d", (int) grps[ig]);
517 int *st = fAllowedGroups.Find(g.c_str());
518 if (st) {
519 if (*st == 1) {
520 ugrpok = 1;
521 } else {
522 e = "Controlled access (UNIX group): user '";
523 e += usr;
524 e = "', UNIX group '";
525 e += g;
526 e += "' denied to connect";
527 ugrpok = -1;
528 break;
529 }
530 }
531 }
532 }
533 // Check PROOF group info
534 int *st = fAllowedGroups.Find(grp);
535 if (st) {
536 if (*st == 1) {
537 pgrpok = 1;
538 } else {
539 if (e.length() <= 0)
540 e = "Controlled access";
541 e += " (PROOF group): user '";
542 e += usr;
543 e += "', PROOF group '";
544 e += grp;
545 e += "' denied to connect";
546 pgrpok = -1;
547 }
548 }
549 // At least one must be explicitly allowed with the other not explicitly denied
550 grpok = ((ugrpok == 1 && pgrpok >= 0) || (ugrpok >= 0 && pgrpok == 1)) ? 1 : 0;
551 }
552 // Check username
553 int usrok = 0;
554 if (fAllowedUsers.Num() > 0) {
555 // If we do not have a group specification we need to explicitly allow the user
556 if (fAllowedGroups.Num() <= 0) usrok = -1;
557 // Look into the hash
558 int *st = fAllowedUsers.Find(usr);
559 if (st) {
560 if (*st == 1) {
561 usrok = 1;
562 } else {
563 e = "Controlled access: user '";
564 e += usr;
565 e += "', PROOF group '";
566 e += grp;
567 e += "' not allowed to connect";
568 usrok = -1;
569 }
570 }
571 }
572 // Super users are always allowed
573 if (su) {
574 usrok = 1;
575 e = "";
576 }
577 // We fail if either the user is explicitly denied or it is not explicitly allowed
578 // and the group is denied
579 if (usrok == -1 || (!grpok && usrok != 1)) return -1;
580 }
581
582 // OK
583 return 0;
584}
585
586////////////////////////////////////////////////////////////////////////////////
587/// Load PROOF scheduler
588
590{
591 XPDLOC(ALL, "Manager::LoadScheduler")
592
593 XrdProofSched *sched = 0;
594 XrdOucString name, lib, m;
595
596 const char *cfn = CfgFile();
597
598 // Locate first the relevant directives in the config file
599 if (cfn && strlen(cfn) > 0) {
600 XrdOucEnv myEnv;
601 XrdOucStream cfg(fEDest, getenv("XRDINSTANCE"), &myEnv);
602 // Open and attach the config file
603 int cfgFD;
604 if ((cfgFD = open(cfn, O_RDONLY, 0)) >= 0) {
605 cfg.Attach(cfgFD);
606 // Process items
607 char *val = 0, *var = 0;
608 while ((var = cfg.GetMyFirstWord())) {
609 if (!(strcmp("xpd.sched", var))) {
610 // Get the name
611 val = cfg.GetWord();
612 if (val && val[0]) {
613 name = val;
614 // Get the lib
615 val = cfg.GetWord();
616 if (val && val[0])
617 lib = val;
618 // We are done
619 break;
620 }
621 }
622 }
623 close(cfgFD);
624 } else {
625 XPDFORM(m, "failure opening config file; errno: %d", errno);
626 TRACE(XERR, m);
627 }
628 }
629
630 // If undefined or default init a default instance
631 if (name == "default" || !(name.length() > 0 && lib.length() > 0)) {
632 if ((name.length() <= 0 && lib.length() > 0) ||
633 (name.length() > 0 && lib.length() <= 0)) {
634 XPDFORM(m, "missing or incomplete info (name: %s, lib: %s)", name.c_str(), lib.c_str());
635 TRACE(DBG, m);
636 }
637 TRACE(DBG, "instantiating default scheduler");
638 sched = new XrdProofSched("default", this, fGroupsMgr, cfn, fEDest);
639 } else {
640 // Load the required plugin
641 if (lib.beginswith("~") || lib.beginswith("$"))
643 XrdSysPlugin *h = new XrdSysPlugin(fEDest, lib.c_str());
644 if (!h)
645 return (XrdProofSched *)0;
646 // Get the scheduler object creator
647 XrdProofSchedLoader_t ep = (XrdProofSchedLoader_t) h->getPlugin("XrdgetProofSched", 1);
648 if (!ep) {
649 delete h;
650 return (XrdProofSched *)0;
651 }
652 // Get the scheduler object
653 if (!(sched = (*ep)(cfn, this, fGroupsMgr, cfn, fEDest))) {
654 TRACE(XERR, "unable to create scheduler object from " << lib);
655 delete h;
656 return (XrdProofSched *)0;
657 }
658 delete h;
659 }
660 // Check result
661 if (!(sched->IsValid())) {
662 TRACE(XERR, " unable to instantiate the " << sched->Name() << " scheduler using " << (cfn ? cfn : "<nul>"));
663 delete sched;
664 return (XrdProofSched *)0;
665 }
666 // Notify
667 TRACE(ALL, "scheduler loaded: type: " << sched->Name());
668
669 // All done
670 return sched;
671}
672
673////////////////////////////////////////////////////////////////////////////////
674/// Get a list of workers from the available resource broker
675
677 const char *query)
678{
679 XPDLOC(ALL, "Manager::GetWorkers")
680
681 int rc = 0;
682 TRACE(REQ, "enter");
683
684 // We need the scheduler at this point
685 if (!fProofSched) {
686 TRACE(XERR, "scheduler undefined");
687 return -1;
688 }
689
690 // Query the scheduler for the list of workers
691 std::list<XrdProofWorker *> wrks, uwrks;
692 if ((rc = fProofSched->GetWorkers(xps, &wrks, query)) < 0) {
693 TRACE(XERR, "error getting list of workers from the scheduler");
694 return -1;
695 }
696 std::list<XrdProofWorker *>::iterator iw, iaw;
697 // If we got a new list we save it into the session object
698 if (rc == 0) {
699
700 TRACE(DBG, "list size: " << wrks.size());
701
702 XrdOucString ord;
703 int ii = -1;
704 // If in remote PLite mode, we need to isolate the number of workers
705 // per unique node
706 if (fRemotePLite) {
707 for (iw = wrks.begin(); iw != wrks.end() ; ++iw) {
708 XrdProofWorker *w = *iw;
709 // Do we have it already in the unique list?
710 bool isnew = 1;
711 for (iaw = uwrks.begin(); iaw != uwrks.end() ; ++iaw) {
712 XrdProofWorker *uw = *iaw;
713 if (w->fHost == uw->fHost && w->fPort == uw->fPort) {
714 uw->fNwrks += 1;
715 isnew = 0;
716 break;
717 }
718 }
719 if (isnew) {
720 // Count (fActive is increased inside here)
721 if (ii == -1) {
722 ord = "master";
723 } else {
724 XPDFORM(ord, "%d", ii);
725 }
726 ii++;
727 XrdProofWorker *uw = new XrdProofWorker(*w);
728 uw->fType = 'S';
729 uw->fOrd = ord;
730 uwrks.push_back(uw);
731 // Setup connection with the proofserv using the original
732 xps->AddWorker(ord.c_str(), w);
733 w->AddProofServ(xps);
734 }
735 }
736 for (iw = uwrks.begin(); iw != uwrks.end() ; ++iw) {
737 XrdProofWorker *w = *iw;
738 // Master at the beginning
739 if (w->fType == 'M') {
740 if (lw.length() > 0) lw.insert('&',0);
741 lw.insert(w->Export(), 0);
742 } else {
743 // Add separator if not the first
744 if (lw.length() > 0) lw += '&';
745 // Add export version of the info
746 lw += w->Export(0);
747 }
748 }
749
750 } else {
751
752 // The full list
753 for (iw = wrks.begin(); iw != wrks.end() ; ++iw) {
754 XrdProofWorker *w = *iw;
755 // Count (fActive is increased inside here)
756 if (ii == -1)
757 ord = "master";
758 else
759 XPDFORM(ord, "%d", ii);
760 ii++;
761 xps->AddWorker(ord.c_str(), w);
762 // Add proofserv and increase the counter
763 w->AddProofServ(xps);
764 }
765 }
766 }
767
768 int proto = (xps->ROOT()) ? xps->ROOT()->SrvProtVers() : -1;
769 if (rc != 2 || (proto < 21 && rc == 0)) {
770 // Get the list in exported format
771 if (lw.length() <= 0) xps->ExportWorkers(lw);
772 TRACE(DBG, "from ExportWorkers: " << lw);
773 } else if (proto >= 21) {
774 // Signal enqueing
776 }
777
778 if (TRACING(REQ)) fNetMgr->Dump();
779
780 // Clear the temp list
781 if (!uwrks.empty()) {
782 iw = uwrks.begin();
783 while (iw != uwrks.end()) {
784 XrdProofWorker *w = *iw;
785 iw = uwrks.erase(iw);
786 delete w;
787 }
788 }
789
790 return rc;
791}
792
793////////////////////////////////////////////////////////////////////////////////
794/// Add the key value in the string passed via the void argument
795
796static int FillKeyValues(const char *k, int *d, void *s)
797{
799
800 if (ls) {
801 XrdOucString &ss = (*d == 1) ? ls->allowed : ls->denied;
802 // Add the key
803 if (k) {
804 XrdOucString sk;
805 sk += k;
806 if (!sk.isdigit()) {
807 // If not empty add a separation ','
808 if (ss.length() > 0) ss += ",";
809 ss += sk;
810 }
811 }
812 } else {
813 // Not enough info: stop
814 return 1;
815 }
816
817 // Check next
818 return 0;
819}
820
821////////////////////////////////////////////////////////////////////////////////
822/// Add the key value in the string passed via the void argument
823
824static int RemoveInvalidUsers(const char *k, int *, void *s)
825{
826 XrdOucString *ls = (XrdOucString *)s;
827
828 XrdProofUI ui;
829 if (XrdProofdAux::GetUserInfo(k, ui) != 0) {
830 // Username is unknown to the system: remove it to the list
831 if (ls) {
832 // If not empty add a separation ','
833 if (ls->length() > 0) *ls += ",";
834 // Add the key
835 if (k) *ls += k;
836 }
837 // Negative return removes from the table
838 return -1;
839 }
840
841 // Check next
842 return 0;
843}
844
845////////////////////////////////////////////////////////////////////////////////
846/// Run configuration and parse the entered config directives.
847/// Return 0 on success, -1 on error
848
850{
851 XPDLOC(ALL, "Manager::Config")
852
853 XrdSysMutexHelper mtxh(fMutex);
854
855 // Run first the configurator
856 if (XrdProofdConfig::Config(rcf) != 0) {
857 XPDERR("problems parsing file ");
858 return -1;
859 }
860
861 XrdOucString msg;
862 msg = (rcf) ? "re-configuring" : "configuring";
863 TRACE(ALL, msg);
864
865 // Change/DonotChange ownership when logging clients
866 fChangeOwn = (fMultiUser && getuid()) ? 0 : 1;
867
868 // Notify port
869 XPDFORM(msg, "listening on port %d", fPort);
870 TRACE(ALL, msg);
871
872 XrdProofUI ui;
873 uid_t effuid = XrdProofdProtocol::EUidAtStartup();
874 if (!rcf) {
875 // Save Effective user
876 if (XrdProofdAux::GetUserInfo(effuid, ui) == 0) {
878 } else {
879 XPDFORM(msg, "could not resolve effective uid %d (errno: %d)", effuid, errno);
880 XPDERR(msg);
881 return -1;
882 }
883
884 // Local FQDN
885 char *host = XrdSysDNS::getHostName();
886 fHost = host ? host : "";
887 SafeFree(host);
888
889 // Notify temporary directory
890 TRACE(ALL, "using temp dir: " << fTMPdir);
891
892 // Notify role
893 const char *roles[] = { "any", "worker", "submaster", "master" };
894 TRACE(ALL, "role set to: " << roles[fSrvType+1]);
895
896 // Admin path
897 fAdminPath += fPort;
898 if (XrdProofdAux::AssertDir(fAdminPath.c_str(), ui, fChangeOwn) != 0) {
899 XPDERR("unable to assert the admin path: " << fAdminPath);
900 return -1;
901 }
902 TRACE(ALL, "admin path set to: " << fAdminPath);
903
904 // Path for Unix sockets
905 if (fSockPathDir.length() <= 0) {
906 // Use default under the admin path
907 XPDFORM(fSockPathDir, "%s/socks", fAdminPath.c_str());
908 }
909 if (XrdProofdAux::AssertDir(fSockPathDir.c_str(), ui, fChangeOwn) != 0) {
910 XPDERR("unable to assert the admin path: " << fSockPathDir);
911 return -1;
912 }
913 if (XrdProofdAux::ChangeMod(fSockPathDir.c_str(), 0777) != 0) {
914 XPDERR("unable to set mode 0777 on: " << fSockPathDir);
915 return -1;
916 }
917 TRACE(ALL, "unix sockets under: " << fSockPathDir);
918
919 // Create / Update the process ID file under the admin path
920 XrdOucString pidfile(fAdminPath);
921 pidfile += "/xrootd.pid";
922 FILE *fpid = fopen(pidfile.c_str(), "w");
923 if (!fpid) {
924 XPDFORM(msg, "unable to open pid file: %s; errno: %d", pidfile.c_str(), errno);
925 XPDERR(msg);
926 return -1;
927 }
928 fprintf(fpid, "%d", getpid());
929 fclose(fpid);
930 } else {
931 if (XrdProofdAux::GetUserInfo(effuid, ui) == 0) {
932 XPDFORM(msg, "could not resolve effective uid %d (errno: %d)", effuid, errno);
933 XPDERR(msg);
934 }
935 }
936
937 // Work directory, if specified
938 XrdOucString wdir;
939 if (fWorkDir.length() > 0) {
940 // Make sure it exists
941 if (XrdProofdAux::AssertDir(fWorkDir.c_str(), ui, fChangeOwn) != 0) {
942 XPDERR("unable to assert working dir: " << fWorkDir);
943 return -1;
944 }
945 if (fMUWorkDir.length() > 0) {
946 fMUWorkDir.replace("<workdir>", fWorkDir);
947 int iph = fMUWorkDir.find("<");
948 if (iph != STR_NPOS) {
949 wdir.assign(fMUWorkDir, 0, iph - 2);
950 if (XrdProofdAux::AssertDir(wdir.c_str(), ui, fChangeOwn) != 0) {
951 XPDERR("unable to assert working dir: " << wdir);
952 return -1;
953 }
954 wdir = "";
955 }
956 }
957 }
958 wdir = (fMultiUser && fMUWorkDir.length() > 0) ? fMUWorkDir : fWorkDir;
959 if (wdir.length() > 0) {
960 TRACE(ALL, "working directories under: " << wdir);
961 // Communicate it to the sandbox service
962 XrdProofdSandbox::SetWorkdir(wdir.c_str());
963 }
964
965 // Data directory, if specified
966 if (fDataDir.length() > 0) {
967 if (fDataDir.endswith('/')) fDataDir.erasefromend(1);
968 if (fDataDirOpts.length() > 0) {
969 // Make sure it exists
970 if (XrdProofdAux::AssertDir(fDataDir.c_str(), ui, fChangeOwn) != 0) {
971 XPDERR("unable to assert data dir: " << fDataDir << " (opts: "<<fDataDirOpts<<")");
972 return -1;
973 }
974 // Get the right privileges now
975 XrdSysPrivGuard pGuard((uid_t)ui.fUid, (gid_t)ui.fGid);
976 if (XpdBadPGuard(pGuard, ui.fUid)) {
977 TRACE(XERR, "could not get privileges to set/change ownership of " << fDataDir);
978 return -1;
979 }
980 if (chmod(fDataDir.c_str(), 0777) != 0) {
981 XPDERR("problems setting permissions 0777 data dir: " << fDataDir);
982 return -1;
983 }
984 }
985 TRACE(ALL, "data directories under: " << fDataDir);
986 }
987
988 // Notify allow rules
989 if (fSrvType == kXPD_Worker) {
990 if (fMastersAllowed.size() > 0) {
991 std::list<XrdOucString *>::iterator i;
992 for (i = fMastersAllowed.begin(); i != fMastersAllowed.end(); ++i)
993 TRACE(ALL, "masters allowed to connect: " << (*i)->c_str());
994 } else {
995 TRACE(ALL, "masters allowed to connect: any");
996 }
997 }
998
999 // Pool and namespace
1000 if (fPoolURL.length() <= 0) {
1001 // Default pool entry point is this host
1002 fPoolURL = "root://";
1003 fPoolURL += fHost;
1004 }
1005 TRACE(ALL, "PROOF pool: " << fPoolURL);
1006 TRACE(ALL, "PROOF pool namespace: " << fNamespace);
1007
1008 // Initialize resource broker (if not worker)
1009 if (fSrvType != kXPD_Worker) {
1010
1011 // Scheduler instance
1012 if (!(fProofSched = LoadScheduler())) {
1013 XPDERR("scheduler initialization failed");
1014 return 0;
1015 }
1016 const char *st[] = { "disabled", "enabled" };
1017 TRACE(ALL, "user config files are " << st[fNetMgr->WorkerUsrCfg()]);
1018 }
1019
1020 // If using the PLite optimization notify it
1021 if (fRemotePLite)
1022 TRACE(ALL, "multi-process on nodes handled with proof-lite");
1023
1024 // Validate dataset sources (if not worker)
1025 fDataSetExp = "";
1026 if (fSrvType != kXPD_Worker && fDataSetSrcs.size() > 0) {
1027 // If first local, add it in front
1028 std::list<XrdProofdDSInfo *>::iterator ii = fDataSetSrcs.begin();
1029 bool goodsrc = 0;
1030 for (ii = fDataSetSrcs.begin(); ii != fDataSetSrcs.end();) {
1031 TRACE(ALL, ">> Defined dataset: " << (*ii)->ToString());
1032 if ((*ii)->fType == "file") {
1033 if (!(goodsrc = ValidateLocalDataSetSrc((*ii)->fUrl, (*ii)->fLocal))) {
1034 XPDERR("source " << (*ii)->fUrl << " could not be validated");
1035 ii = fDataSetSrcs.erase(ii);
1036 } else {
1037 // Check next
1038 ++ii;
1039 }
1040 } else {
1041 // Validate only "file" datasets
1042 TRACE(ALL, "Skipping validation (no \"file\" type dataset source)");
1043 ++ii;
1044 }
1045 }
1046 if (fDataSetSrcs.size() > 0) {
1047 TRACE(ALL, fDataSetSrcs.size() << " dataset sources defined");
1048 for (ii = fDataSetSrcs.begin(); ii != fDataSetSrcs.end(); ++ii) {
1049 TRACE(ALL, ">> Valid dataset: " << (*ii)->ToString());
1050 if ((*ii)->fLocal && (*ii)->fRW) {
1051 if (fDataSetExp.length() > 0) fDataSetExp += ",";
1052 fDataSetExp += ((*ii)->fUrl).c_str();
1053 }
1054 }
1055 } else {
1056 TRACE(ALL, "no dataset sources defined");
1057 }
1058 } else {
1059 TRACE(ALL, "no dataset sources defined");
1060 }
1061
1062 // Superusers: add the effective user at startup
1063 XrdProofUI sui;
1065 if (fSuperUsers.find(sui.fUser.c_str()) == STR_NPOS) {
1066 if (fSuperUsers.length() > 0) fSuperUsers += ",";
1067 fSuperUsers += sui.fUser;
1068 }
1069 } else {
1070 XPDFORM(msg, "could not resolve effective uid %d (errno: %d)",
1072 XPDERR(msg);
1073 }
1074 XPDFORM(msg, "list of superusers: %s", fSuperUsers.c_str());
1075 TRACE(ALL, msg);
1076
1077 // Notify controlled mode, if such
1079 // Add superusers to the hash list of allowed users
1080 int from = 0;
1081 XrdOucString usr;
1082 while ((from = fSuperUsers.tokenize(usr, from, ',')) != STR_NPOS) {
1083 fAllowedUsers.Add(usr.c_str(), new int(1));
1084 }
1085 // If not in multiuser mode make sure that the users in the allowed list
1086 // are known to the system
1087 if (!fMultiUser) {
1088 XrdOucString ius;
1089 fAllowedUsers.Apply(RemoveInvalidUsers, (void *)&ius);
1090 if (ius.length()) {
1091 XPDFORM(msg, "running in controlled access mode: users removed because"
1092 " unknown to the system: %s", ius.c_str());
1093 TRACE(ALL, msg);
1094 }
1095 }
1096 // Extract now the list of allowed users
1097 xpd_acm_lists_t uls;
1098 fAllowedUsers.Apply(FillKeyValues, (void *)&uls);
1099 if (uls.allowed.length()) {
1100 XPDFORM(msg, "running in controlled access mode: users allowed: %s", uls.allowed.c_str());
1101 TRACE(ALL, msg);
1102 }
1103 if (uls.denied.length()) {
1104 XPDFORM(msg, "running in controlled access mode: users denied: %s", uls.denied.c_str());
1105 TRACE(ALL, msg);
1106 }
1107 // Extract now the list of allowed groups
1108 xpd_acm_lists_t gls;
1109 fAllowedGroups.Apply(FillKeyValues, (void *)&gls);
1110 if (gls.allowed.length()) {
1111 XPDFORM(msg, "running in controlled access mode: UNIX groups allowed: %s", gls.allowed.c_str());
1112 TRACE(ALL, msg);
1113 }
1114 if (gls.denied.length()) {
1115 XPDFORM(msg, "running in controlled access mode: UNIX groups denied: %s", gls.denied.c_str());
1116 TRACE(ALL, msg);
1117 }
1118 }
1119
1120 // Bare lib path
1121 if (getenv(XPD_LIBPATH)) {
1122 XrdOucString ctrim;
1123 if (fRemoveROOTLibPaths || fLibPathsToRemove.Num() > 0) {
1124 // Try to remove existing ROOT dirs in the path
1125 XrdOucString paths = getenv(XPD_LIBPATH);
1126 XrdOucString ldir;
1127 int from = 0;
1128 while ((from = paths.tokenize(ldir, from, ':')) != STR_NPOS) {
1129 bool remove = 0;
1130 if (ldir.length() > 0) {
1131 if (fLibPathsToRemove.Num() > 0 && fLibPathsToRemove.Find(ldir.c_str())) {
1132 remove = 1;
1133 } else if (fRemoveROOTLibPaths) {
1134 // Check this dir
1135 DIR *dir = opendir(ldir.c_str());
1136 if (dir) {
1137 // Scan the directory
1138 struct dirent *ent = 0;
1139 while ((ent = (struct dirent *)readdir(dir))) {
1140 if (!strncmp(ent->d_name, "libCore", 7)) {
1141 remove = 1;
1142 break;
1143 }
1144 }
1145 // Close the directory
1146 closedir(dir);
1147 }
1148 }
1149 }
1150 if (!remove) {
1151 if (fBareLibPath.length() > 0)
1152 fBareLibPath += ":";
1153 fBareLibPath += ldir;
1154 }
1155 }
1156 ctrim = " (lib paths filter applied)";
1157 } else {
1158 // Full path
1159 ctrim = " (full ";
1160 ctrim += XPD_LIBPATH;
1161 ctrim += ")";
1162 fBareLibPath = getenv(XPD_LIBPATH);
1163 }
1164 TRACE(ALL, "bare lib path for proofserv" << ctrim <<": " << fBareLibPath);
1165 }
1166
1167 // Groups
1168 if (!fGroupsMgr)
1169 // Create default group, if none explicitly requested
1171
1172 if (fGroupsMgr)
1173 fGroupsMgr->Print(0);
1174
1175 // Config the admin handler
1176 if (fAdmin && fAdmin->Config(rcf) != 0) {
1177 XPDERR("problems configuring the admin handler");
1178 return -1;
1179 }
1180
1181 // Config the network manager
1182 if (fNetMgr && fNetMgr->Config(rcf) != 0) {
1183 XPDERR("problems configuring the network manager");
1184 return -1;
1185 }
1186
1187 // Config the priority manager
1188 if (fPriorityMgr && fPriorityMgr->Config(rcf) != 0) {
1189 XPDERR("problems configuring the priority manager");
1190 return -1;
1191 }
1192
1193 // Config the ROOT versions manager
1194 if (fROOTMgr) {
1195 fROOTMgr->SetLogDir(fAdminPath.c_str());
1196 if (fROOTMgr && fROOTMgr->Config(rcf) != 0) {
1197 XPDERR("problems configuring the ROOT versions manager");
1198 return -1;
1199 }
1200 }
1201
1202 // Config the client manager
1203 if (fClientMgr && fClientMgr->Config(rcf) != 0) {
1204 XPDERR("problems configuring the client manager");
1205 return -1;
1206 }
1207
1208 // Config the session manager
1209 if (fSessionMgr && fSessionMgr->Config(rcf) != 0) {
1210 XPDERR("problems configuring the session manager");
1211 return -1;
1212 }
1213
1214 // Config the scheduler
1215 if (fProofSched && fProofSched->Config(rcf) != 0) {
1216 XPDERR("problems configuring the scheduler");
1217 return -1;
1218 }
1219
1220 // Xrootd protocol service
1221 if (!(fXrootd = LoadXrootd(fParms, fPi, fEDest))) {
1222 TRACE(ALL, "file serving (protocol: 'root://') not available");
1223 }
1224
1225 if (!rcf) {
1226 // Start cron thread
1227 pthread_t tid;
1228 if (XrdSysThread::Run(&tid, XrdProofdManagerCron,
1229 (void *)this, 0, "ProofdManager cron thread") != 0) {
1230 XPDERR("could not start cron thread");
1231 return 0;
1232 }
1233 TRACE(ALL, "manager cron thread started");
1234 }
1235
1236 // Done
1237 return 0;
1238}
1239
1240////////////////////////////////////////////////////////////////////////////////
1241/// Validate local dataset src at URL (check the URL and make the relevant
1242/// directories).
1243/// Return 1 if OK, 0 if any problem arises
1244
1245bool XrdProofdManager::ValidateLocalDataSetSrc(XrdOucString &url, bool &local)
1246{
1247 XPDLOC(ALL, "Manager::ValidateLocalDataSetSrc")
1248
1249 TRACE(ALL, "validating '" << url << "' ...");
1250 local = 0;
1251 bool goodsrc = 1;
1252 if (url.length() > 0) {
1253 // Check if local source
1254 if (url.beginswith("file:")) url.replace("file:", "");
1255 if (url.beginswith("/")) {
1256 local = 1;
1257 goodsrc = 0;
1258 // Make sure the directory exists and has mode 0755
1259 XrdProofUI ui;
1261 if (XrdProofdAux::AssertDir(url.c_str(), ui, ChangeOwn()) == 0) {
1262 goodsrc = 1;
1263 if (XrdProofdAux::ChangeMod(url.c_str(), 0777) != 0) {
1264 TRACE(XERR, "Problems setting permissions 0777 on path '" << url << "'");
1265 }
1266 } else {
1267 TRACE(XERR, "Cannot assert path '" << url << "' - ignoring");
1268 }
1269 if (goodsrc) {
1270 // Assert the file with dataset summaries
1271 XrdOucString fnpath(url.c_str());
1272 fnpath += "/dataset.list";
1273 if (access(fnpath.c_str(), F_OK) != 0) {
1274 FILE *flst = fopen(fnpath.c_str(), "w");
1275 if (!flst) {
1276 TRACE(XERR, "Cannot open file '" << fnpath << "' for the dataset list; errno: " << errno);
1277 goodsrc = 0;
1278 } else {
1279 if (fclose(flst) != 0)
1280 TRACE(XERR, "Problems closing file '" << fnpath << "'; errno: " << errno);
1281 if (XrdProofdAux::ChangeOwn(fnpath.c_str(), ui) != 0) {
1282 TRACE(XERR, "Problems asserting ownership of " << fnpath);
1283 }
1284 }
1285 }
1286 // Make sure that everybody can modify the file for updates
1287 if (goodsrc && XrdProofdAux::ChangeMod(fnpath.c_str(), 0666) != 0) {
1288 TRACE(XERR, "Problems setting permissions to 0666 on file '" << fnpath << "'; errno: " << errno);
1289 goodsrc = 0;
1290 }
1291 // Assert the file with lock file path
1292 if (goodsrc) {
1293 fnpath.replace("/dataset.list", "/lock.location");
1294 FILE *flck = fopen(fnpath.c_str(), "a");
1295 if (!flck) {
1296 TRACE(XERR, "Cannot open file '" << fnpath << "' with the lock file path; errno: " << errno);
1297 } else {
1298 errno = 0;
1299 off_t ofs = lseek(fileno(flck), 0, SEEK_CUR);
1300 if (ofs == 0) {
1301 // New file: write the default lock file path
1302 XrdOucString fnlock(url);
1303 fnlock.replace("/", "%");
1304 fnlock.replace(":", "%");
1305 fnlock.insert("/tmp/", 0);
1306 fprintf(flck, "%s\n", fnlock.c_str());
1307 if (fclose(flck) != 0)
1308 TRACE(XERR, "Problems closing file '" << fnpath << "'; errno: " << errno);
1309 flck = 0;
1310 if (XrdProofdAux::ChangeOwn(fnpath.c_str(), ui) != 0) {
1311 TRACE(XERR, "Problems asserting ownership of " << fnpath);
1312 }
1313 } else if (ofs == (off_t)(-1)) {
1314 TRACE(XERR, "Problems getting current position on file '" << fnpath << "'; errno: " << errno);
1315 }
1316 if (flck && fclose(flck) != 0)
1317 TRACE(XERR, "Problems closing file '" << fnpath << "'; errno: " << errno);
1318 }
1319 }
1320 // Make sure that everybody can modify the file for updates
1321 if (goodsrc && XrdProofdAux::ChangeMod(fnpath.c_str(), 0644) != 0) {
1322 TRACE(XERR, "Problems setting permissions to 0644 on file '" << fnpath << "'; errno: " << errno);
1323 }
1324 }
1325 }
1326 }
1327 else {
1328 TRACE(ALL, "New dataset with no URL!");
1329 }
1330 // Done
1331 return goodsrc;
1332}
1333
1334////////////////////////////////////////////////////////////////////////////////
1335/// Register directives for configuration
1336
1338{
1339 // Register special config directives
1340 Register("trace", new XrdProofdDirective("trace", this, &DoDirectiveClass));
1341 Register("groupfile", new XrdProofdDirective("groupfile", this, &DoDirectiveClass));
1342 Register("multiuser", new XrdProofdDirective("multiuser", this, &DoDirectiveClass));
1343 Register("maxoldlogs", new XrdProofdDirective("maxoldlogs", this, &DoDirectiveClass));
1344 Register("allow", new XrdProofdDirective("allow", this, &DoDirectiveClass));
1345 Register("allowedgroups", new XrdProofdDirective("allowedgroups", this, &DoDirectiveClass));
1346 Register("allowedusers", new XrdProofdDirective("allowedusers", this, &DoDirectiveClass));
1347 Register("role", new XrdProofdDirective("role", this, &DoDirectiveClass));
1348 Register("cron", new XrdProofdDirective("cron", this, &DoDirectiveClass));
1349 Register("port", new XrdProofdDirective("port", this, &DoDirectiveClass));
1350 Register("datadir", new XrdProofdDirective("datadir", this, &DoDirectiveClass));
1351 Register("datasetsrc", new XrdProofdDirective("datasetsrc", this, &DoDirectiveClass));
1352 Register("xrd.protocol", new XrdProofdDirective("xrd.protocol", this, &DoDirectiveClass));
1353 Register("filterlibpaths", new XrdProofdDirective("filterlibpaths", this, &DoDirectiveClass));
1354 Register("xrootd", new XrdProofdDirective("xrootd", this, &DoDirectiveClass));
1355 // Register config directives for strings
1356 Register("tmp", new XrdProofdDirective("tmp", (void *)&fTMPdir, &DoDirectiveString));
1357 Register("poolurl", new XrdProofdDirective("poolurl", (void *)&fPoolURL, &DoDirectiveString));
1358 Register("namespace", new XrdProofdDirective("namespace", (void *)&fNamespace, &DoDirectiveString));
1359 Register("superusers", new XrdProofdDirective("superusers", (void *)&fSuperUsers, &DoDirectiveString));
1360 Register("image", new XrdProofdDirective("image", (void *)&fImage, &DoDirectiveString));
1361 Register("workdir", new XrdProofdDirective("workdir", (void *)&fWorkDir, &DoDirectiveString));
1362 Register("sockpathdir", new XrdProofdDirective("sockpathdir", (void *)&fSockPathDir, &DoDirectiveString));
1363 Register("remoteplite", new XrdProofdDirective("remoteplite", (void *)&fRemotePLite, &DoDirectiveInt));
1364 Register("stagereqrepo", new XrdProofdDirective("stagereqrepo", (void *)&fStageReqRepo, &DoDirectiveString));
1365}
1366
1367////////////////////////////////////////////////////////////////////////////////
1368/// Resolve special keywords in 's' for client 'pcl'. Recognized keywords
1369/// <workdir> root for working dirs
1370/// <host> local host name
1371/// <port> daemon port
1372/// <homedir> user home dir
1373/// <user> user name
1374/// <group> user group
1375/// <uid> user ID
1376/// <gid> user group ID
1377/// <effuser> effective user name (for multiuser or user mapping modes)
1378/// Return the number of keywords resolved.
1379
1381{
1382 XPDLOC(ALL, "Manager::ResolveKeywords")
1383
1384 int nk = 0;
1385
1386 TRACE(HDBG, "enter: " << s << " - WorkDir(): " << WorkDir());
1387
1388 // Parse <workdir>
1389 if (s.replace("<workdir>", WorkDir()))
1390 nk++;
1391
1392 TRACE(HDBG, "after <workdir>: " << s);
1393
1394 // Parse <host>
1395 if (s.replace("<host>", Host()))
1396 nk++;
1397
1398 TRACE(HDBG, "after <host>: " << s);
1399
1400 // Parse <port>
1401 if (s.find("<port>") != STR_NPOS) {
1402 XrdOucString sport;
1403 sport += Port();
1404 if (s.replace("<port>", sport.c_str()))
1405 nk++;
1406 }
1407
1408 // Parse <effuser> of the process
1409 if (s.find("<effuser>") != STR_NPOS) {
1410 XrdProofUI eui;
1411 if (XrdProofdAux::GetUserInfo(geteuid(), eui) == 0) {
1412 if (s.replace("<effuser>", eui.fUser.c_str()))
1413 nk++;
1414 }
1415 }
1416
1417 // Parse <user>
1418 if (pcl)
1419 if (s.replace("<user>", pcl->User()))
1420 nk++;
1421
1422 // Parse <group>
1423 if (pcl)
1424 if (s.replace("<group>", pcl->Group()))
1425 nk++;
1426
1427 // Parse <homedir>
1428 if (pcl)
1429 if (s.replace("<homedir>", pcl->UI().fHomeDir.c_str()))
1430 nk++;
1431
1432 // Parse <uid>
1433 if (pcl && (s.find("<uid>") != STR_NPOS)) {
1434 XrdOucString suid;
1435 suid += pcl->UI().fUid;
1436 if (s.replace("<uid>", suid.c_str()))
1437 nk++;
1438 }
1439
1440 // Parse <gid>
1441 if (pcl && (s.find("<gid>") != STR_NPOS)) {
1442 XrdOucString sgid;
1443 sgid += pcl->UI().fGid;
1444 if (s.replace("<gid>", sgid.c_str()))
1445 nk++;
1446 }
1447
1448 TRACE(HDBG, "exit: " << s);
1449
1450 // We are done
1451 return nk;
1452}
1453
1454//
1455// Special directive processors
1456
1457////////////////////////////////////////////////////////////////////////////////
1458/// Update the priorities of the active sessions.
1459
1461 char *val, XrdOucStream *cfg, bool rcf)
1462{
1463 XPDLOC(ALL, "Manager::DoDirective")
1464
1465 if (!d)
1466 // undefined inputs
1467 return -1;
1468
1469 if (d->fName == "trace") {
1470 return DoDirectiveTrace(val, cfg, rcf);
1471 } else if (d->fName == "groupfile") {
1472 return DoDirectiveGroupfile(val, cfg, rcf);
1473 } else if (d->fName == "maxoldlogs") {
1474 return DoDirectiveMaxOldLogs(val, cfg, rcf);
1475 } else if (d->fName == "allow") {
1476 return DoDirectiveAllow(val, cfg, rcf);
1477 } else if (d->fName == "allowedgroups") {
1478 return DoDirectiveAllowedGroups(val, cfg, rcf);
1479 } else if (d->fName == "allowedusers") {
1480 return DoDirectiveAllowedUsers(val, cfg, rcf);
1481 } else if (d->fName == "role") {
1482 return DoDirectiveRole(val, cfg, rcf);
1483 } else if (d->fName == "multiuser") {
1484 return DoDirectiveMultiUser(val, cfg, rcf);
1485 } else if (d->fName == "port") {
1486 return DoDirectivePort(val, cfg, rcf);
1487 } else if (d->fName == "datadir") {
1488 return DoDirectiveDataDir(val, cfg, rcf);
1489 } else if (d->fName == "datasetsrc") {
1490 return DoDirectiveDataSetSrc(val, cfg, rcf);
1491 } else if (d->fName == "rootd") {
1492 return DoDirectiveRootd(val, cfg, rcf);
1493 } else if (d->fName == "rootdallow") {
1494 return DoDirectiveRootdAllow(val, cfg, rcf);
1495 } else if (d->fName == "xrd.protocol") {
1496 return DoDirectivePort(val, cfg, rcf);
1497 } else if (d->fName == "filterlibpaths") {
1498 return DoDirectiveFilterLibPaths(val, cfg, rcf);
1499 } else if (d->fName == "xrootd") {
1500 return DoDirectiveXrootd(val, cfg, rcf);
1501 }
1502 TRACE(XERR, "unknown directive: " << d->fName);
1503 return -1;
1504}
1505
1506////////////////////////////////////////////////////////////////////////////////
1507/// Scan the config file for tracing settings
1508
1509int XrdProofdManager::DoDirectiveTrace(char *val, XrdOucStream *cfg, bool)
1510{
1511 XPDLOC(ALL, "Manager::DoDirectiveTrace")
1512
1513 if (!val || !cfg)
1514 // undefined inputs
1515 return -1;
1516
1517 // Specifies tracing options. This works by levels and domains.
1518 //
1519 // Valid keyword levels are:
1520 // err trace errors [on]
1521 // req trace protocol requests [on]*
1522 // dbg trace details about actions [off]
1523 // hdbg trace more details about actions [off]
1524 // Special forms of 'dbg' (always on if 'dbg' is required) are:
1525 // login trace details about login requests [on]*
1526 // fork trace proofserv forks [on]*
1527 // mem trace mem buffer manager [off]
1528 //
1529 // Valid keyword domains are:
1530 // rsp server replies [off]
1531 // aux aux functions [on]
1532 // cmgr client manager [on]
1533 // smgr session manager [on]
1534 // nmgr network manager [on]
1535 // pmgr priority manager [on]
1536 // gmgr group manager [on]
1537 // sched details about scheduling [on]
1538 //
1539 // Global switches:
1540 // all or dump full tracing of everything
1541 //
1542 // Defaults are shown in brackets; '*' shows the default when the '-d'
1543 // option is passed on the command line. Each option may be
1544 // optionally prefixed by a minus sign to turn off the setting.
1545 // Order matters: 'all' in last position enables everything; in first
1546 // position is corrected by subsequent settings
1547 //
1548 while (val && val[0]) {
1549 bool on = 1;
1550 if (val[0] == '-') {
1551 on = 0;
1552 val++;
1553 }
1554 if (!strcmp(val, "err")) {
1555 TRACESET(XERR, on);
1556 } else if (!strcmp(val, "req")) {
1557 TRACESET(REQ, on);
1558 } else if (!strcmp(val, "dbg")) {
1559 TRACESET(DBG, on);
1560 TRACESET(LOGIN, on);
1561 TRACESET(FORK, on);
1562 TRACESET(MEM, on);
1563 } else if (!strcmp(val, "login")) {
1564 TRACESET(LOGIN, on);
1565 } else if (!strcmp(val, "fork")) {
1566 TRACESET(FORK, on);
1567 } else if (!strcmp(val, "mem")) {
1568 TRACESET(MEM, on);
1569 } else if (!strcmp(val, "hdbg")) {
1570 TRACESET(HDBG, on);
1571 TRACESET(DBG, on);
1572 TRACESET(LOGIN, on);
1573 TRACESET(FORK, on);
1574 TRACESET(MEM, on);
1575 } else if (!strcmp(val, "rsp")) {
1576 TRACESET(RSP, on);
1577 } else if (!strcmp(val, "aux")) {
1578 TRACESET(AUX, on);
1579 } else if (!strcmp(val, "cmgr")) {
1580 TRACESET(CMGR, on);
1581 } else if (!strcmp(val, "smgr")) {
1582 TRACESET(SMGR, on);
1583 } else if (!strcmp(val, "nmgr")) {
1584 TRACESET(NMGR, on);
1585 } else if (!strcmp(val, "pmgr")) {
1586 TRACESET(PMGR, on);
1587 } else if (!strcmp(val, "gmgr")) {
1588 TRACESET(GMGR, on);
1589 } else if (!strcmp(val, "sched")) {
1590 TRACESET(SCHED, on);
1591 } else if (!strcmp(val, "all") || !strcmp(val, "dump")) {
1592 // Everything
1593 TRACE(ALL, "Setting trace: " << on);
1594 XrdProofdTrace->What = (on) ? TRACE_ALL : 0;
1595 }
1596
1597 // Next
1598 val = cfg->GetWord();
1599 }
1600
1601 return 0;
1602}
1603
1604////////////////////////////////////////////////////////////////////////////////
1605/// Process 'groupfile' directive
1606
1607int XrdProofdManager::DoDirectiveGroupfile(char *val, XrdOucStream *cfg, bool rcf)
1608{
1609 XPDLOC(ALL, "Manager::DoDirectiveGroupfile")
1610
1611 if (!val)
1612 // undefined inputs
1613 return -1;
1614
1615 // Check deprecated 'if' directive
1616 if (Host() && cfg)
1617 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
1618 return 0;
1619
1620 // Defines file with the group info
1621 if (rcf) {
1623 } else if (fGroupsMgr) {
1624 TRACE(XERR, "groups manager already initialized: ignoring ");
1625 return -1;
1626 }
1628 fGroupsMgr->Config(val);
1629 return 0;
1630}
1631
1632////////////////////////////////////////////////////////////////////////////////
1633/// Process 'maxoldlogs' directive
1634
1635int XrdProofdManager::DoDirectiveMaxOldLogs(char *val, XrdOucStream *cfg, bool)
1636{
1637 if (!val)
1638 // undefined inputs
1639 return -1;
1640
1641 // Check deprecated 'if' directive
1642 if (Host() && cfg)
1643 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
1644 return 0;
1645
1646 // Max number of sessions per user
1647 int maxoldlogs = strtol(val, 0, 10);
1649 return 0;
1650}
1651
1652////////////////////////////////////////////////////////////////////////////////
1653/// Process 'allow' directive
1654
1655int XrdProofdManager::DoDirectiveAllow(char *val, XrdOucStream *cfg, bool)
1656{
1657 if (!val)
1658 // undefined inputs
1659 return -1;
1660
1661 // Check deprecated 'if' directive
1662 if (Host() && cfg)
1663 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
1664 return 0;
1665
1666 // Masters allowed to connect
1667 fMastersAllowed.push_back(new XrdOucString(val));
1668 return 0;
1669}
1670
1671////////////////////////////////////////////////////////////////////////////////
1672/// Process 'allowedgroups' directive
1673
1674int XrdProofdManager::DoDirectiveAllowedGroups(char *val, XrdOucStream *cfg, bool)
1675{
1676 if (!val)
1677 // undefined inputs
1678 return -1;
1679
1680 // Check deprecated 'if' directive
1681 if (Host() && cfg)
1682 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
1683 return 0;
1684
1685 // We are in controlled mode
1687
1688 // Input list (comma separated) of UNIX groups allowed to connect
1689 XrdOucString s = val;
1690 int from = 0;
1691 XrdOucString grp, gid;
1692 XrdProofGI gi;
1693 while ((from = s.tokenize(grp, from, ',')) != STR_NPOS) {
1694 int st = 1;
1695 if (grp.beginswith('-')) {
1696 st = 0;
1697 grp.erasefromstart(1);
1698 }
1699 // Unix or Proof group ?
1700 if (XrdProofdAux::GetGroupInfo(grp.c_str(), gi) == 0) {
1701 // Unix: add name and id
1702 gid.form("%d", (int) gi.fGid);
1703 fAllowedGroups.Add(gid.c_str(), new int(st));
1704 }
1705 // Add it to the list
1706 fAllowedGroups.Add(grp.c_str(), new int(st));
1707 }
1708
1709 // Done
1710 return 0;
1711}
1712
1713////////////////////////////////////////////////////////////////////////////////
1714/// Process 'allowedusers' directive
1715
1716int XrdProofdManager::DoDirectiveAllowedUsers(char *val, XrdOucStream *cfg, bool)
1717{
1718 if (!val)
1719 // undefined inputs
1720 return -1;
1721
1722 // Check deprecated 'if' directive
1723 if (Host() && cfg)
1724 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
1725 return 0;
1726
1727 // We are in controlled mode
1729
1730 // Input list (comma separated) of users allowed to connect
1731 XrdOucString s = val;
1732 int from = 0;
1733 XrdOucString usr;
1734 XrdProofUI ui;
1735 while ((from = s.tokenize(usr, from, ',')) != STR_NPOS) {
1736 int st = 1;
1737 if (usr.beginswith('-')) {
1738 st = 0;
1739 usr.erasefromstart(1);
1740 }
1741 // Add to the list; we will check later on the existence of the
1742 // user in the password file, depending on the 'multiuser' settings
1743 fAllowedUsers.Add(usr.c_str(), new int(st));
1744 }
1745
1746 // Done
1747 return 0;
1748}
1749
1750////////////////////////////////////////////////////////////////////////////////
1751/// Process 'role' directive
1752
1753int XrdProofdManager::DoDirectiveRole(char *val, XrdOucStream *cfg, bool)
1754{
1755 if (!val)
1756 // undefined inputs
1757 return -1;
1758
1759 // Check deprecated 'if' directive
1760 if (Host() && cfg)
1761 if (XrdProofdAux::CheckIf(cfg, Host()) == 0)
1762 return 0;
1763
1764 // Role this server
1765 XrdOucString tval(val);
1766 if (tval == "supermaster") {
1768 fSuperMst = 1;
1769 } else if (tval == "master") {
1771 } else if (tval == "submaster") {
1773 } else if (tval == "worker") {
1775 } else if (tval == "any") {
1777 }
1778
1779 return 0;
1780}
1781
1782////////////////////////////////////////////////////////////////////////////////
1783/// Process 'xrd.protocol' directive to find the port
1784
1785int XrdProofdManager::DoDirectivePort(char *val, XrdOucStream *, bool)
1786{
1787 if (!val)
1788 // undefined inputs
1789 return -1;
1790
1791 XrdOucString port(val);
1792 if (port.beginswith("xproofd:")) {
1793 port.replace("xproofd:", "");
1794 }
1795 if (port.length() > 0 && port.isdigit()) {
1796 fPort = strtol(port.c_str(), 0, 10);
1797 }
1798 fPort = (fPort < 0) ? XPD_DEF_PORT : fPort;
1799
1800 return 0;
1801}
1802
1803////////////////////////////////////////////////////////////////////////////////
1804/// Process 'multiuser' directive
1805
1806int XrdProofdManager::DoDirectiveMultiUser(char *val, XrdOucStream *cfg, bool)
1807{
1808 XPDLOC(ALL, "Manager::DoDirectiveMultiUser")
1809
1810 if (!val)
1811 // undefined inputs
1812 return -1;
1813
1814 // Multi-user option
1815 int mu = strtol(val, 0, 10);
1816 fMultiUser = (mu == 1) ? 1 : fMultiUser;
1817
1818 // Check if we need to change the working dir template
1819 val = cfg->GetWord();
1820 if (val) fMUWorkDir = val;
1821
1822 TRACE(DBG, "fMultiUser: "<< fMultiUser << " work dir template: " << fMUWorkDir);
1823
1824 return 0;
1825}
1826
1827////////////////////////////////////////////////////////////////////////////////
1828/// Process 'datasetsrc' directive
1829
1830int XrdProofdManager::DoDirectiveDataSetSrc(char *val, XrdOucStream *cfg, bool)
1831{
1832 if (!val)
1833 // undefined inputs
1834 return -1;
1835
1836 // URL for this source
1837 XrdOucString type(val), url, opts, obscure;
1838 bool rw = 0, local = 0, goodsrc = 1;
1839 char *nxt = 0;
1840 while ((nxt = cfg->GetWord())) {
1841 if (!strcmp(nxt, "rw=1") || !strcmp(nxt, "rw:1")) {
1842 rw = 1;
1843 } else if (!strncmp(nxt, "url:", 4)) {
1844 url = nxt + 4;
1845 XrdClientUrlInfo u(url);
1846 if (u.Proto == "" && u.HostWPort == "") local = 1;
1847 } else if (!strncmp(nxt, "opt:", 4)) {
1848 opts = nxt + 4;
1849 } else {
1850 obscure += nxt;
1851 obscure += " ";
1852 }
1853 }
1854
1855 // Add to the list
1856 if (goodsrc) {
1857 // If first local, add it in front
1858 std::list<XrdProofdDSInfo *>::iterator ii = fDataSetSrcs.begin();
1859 bool haslocal = 0;
1860 for (ii = fDataSetSrcs.begin(); ii != fDataSetSrcs.end(); ++ii) {
1861 if ((*ii)->fLocal) {
1862 haslocal = 1;
1863 break;
1864 }
1865 }
1866 // Default options
1867 if (opts.length() <= 0) {
1868 opts = rw ? "Ar:Av:" : "-Ar:-Av:";
1869 }
1870 XrdProofdDSInfo *dsi = new XrdProofdDSInfo(type.c_str(), url.c_str(),
1871 local, rw, opts.c_str(), obscure.c_str());
1872 if (haslocal || !local) {
1873 fDataSetSrcs.push_back(dsi);
1874 } else {
1875 fDataSetSrcs.push_front(dsi);
1876 }
1877 }
1878 return 0;
1879}
1880
1881////////////////////////////////////////////////////////////////////////////////
1882/// Process 'datadir' directive
1883
1884int XrdProofdManager::DoDirectiveDataDir(char *val, XrdOucStream *cfg, bool)
1885{
1886 if (!val)
1887 // undefined inputs
1888 return -1;
1889
1890 // Data directory and write permissions
1891 fDataDir = val;
1892 fDataDirOpts = "";
1893 fDataDirUrlOpts = "";
1894 XrdOucString opts;
1895 char *nxt = 0;
1896 while ((nxt = cfg->GetWord()) && (opts.length() == 0)) {
1897 opts = nxt;
1898 }
1899 if (opts.length() > 0) fDataDirOpts = opts;
1900 // Check if URL type options have been spcified in the main url
1901 int iq = STR_NPOS;
1902 if ((iq = fDataDir.rfind('?')) != STR_NPOS) {
1903 fDataDirUrlOpts.assign(fDataDir, iq + 1);
1904 fDataDir.erase(iq);
1905 }
1906
1907 // Done
1908 return 0;
1909}
1910
1911////////////////////////////////////////////////////////////////////////////////
1912/// Process 'xrootd' directive
1913/// xpd.xrootd [path/]libXrdXrootd.so
1914
1915int XrdProofdManager::DoDirectiveXrootd(char *val, XrdOucStream *, bool)
1916{
1917 XPDLOC(ALL, "Manager::DoDirectiveXrootd")
1918
1919 if (!val)
1920 // undefined inputs
1921 return -1;
1922 TRACE(ALL, "val: "<< val);
1923 // Check version (v3 does not have the plugin, loading v4 may lead to problems)
1924 if (XrdMajorVNUM(XrdVNUMBER) < 4) {
1925 TRACE(ALL, "WARNING: built against an XRootD version without libXrdXrootd.so :");
1926 TRACE(ALL, "WARNING: loading external " << val << " may lead to incompatibilities");
1927 }
1928
1929 fXrootdLibPath = val;
1930
1931 // Done
1932 return 0;
1933}
1934
1935////////////////////////////////////////////////////////////////////////////////
1936/// Process 'rootd' directive
1937/// xpd.rootd deny|allow [rootsys:<tag>] [path:abs-path/] [mode:ro|rw]
1938/// [auth:none|full] [other_rootd_args]
1939
1940int XrdProofdManager::DoDirectiveRootd(char *, XrdOucStream *, bool)
1941{
1942 XPDLOC(ALL, "Manager::DoDirectiveRootd")
1943
1944 TRACE(ALL, "unsupported!!! ");
1945
1946 // Done
1947 return 0;
1948}
1949
1950////////////////////////////////////////////////////////////////////////////////
1951/// Process 'rootdallow' directive
1952/// xpd.rootdallow host1,host2 host3
1953/// Host names may contain the wild card '*'
1954
1955int XrdProofdManager::DoDirectiveRootdAllow(char *, XrdOucStream *, bool)
1956{
1957 XPDLOC(ALL, "Manager::DoDirectiveRootdAllow")
1958
1959 TRACE(ALL, "unsupported!!! ");
1960
1961 // Done
1962 return 0;
1963}
1964
1965////////////////////////////////////////////////////////////////////////////////
1966/// Process 'filterlibpaths' directive
1967/// xpd.filterlibpaths 1|0 [path1,path2 path3 path4 ...]
1968
1969int XrdProofdManager::DoDirectiveFilterLibPaths(char *val, XrdOucStream *cfg, bool)
1970{
1971 XPDLOC(ALL, "Manager::DoDirectiveRemoveLibPaths")
1972
1973 if (!val)
1974 // undefined inputs
1975 return -1;
1976
1977 // Rebuild arguments list
1978 fLibPathsToRemove.Purge();
1979
1980 TRACE(ALL, "val: "<< val);
1981
1982 // Whether to remove ROOT lib paths before adding the effective one
1983 fRemoveROOTLibPaths = (!strcmp(val, "1") || !strcmp(val, "yes")) ? 1 : 0;
1985 TRACE(ALL, "Filtering out ROOT lib paths from "<<XPD_LIBPATH);
1986
1987 // Parse the rest, if any
1988 char *nxt = 0;
1989 while ((nxt = cfg->GetWord())) {
1990 XrdOucString pps(nxt), p;
1991 int from = 0;
1992 while ((from = pps.tokenize(p, from, ',')) != -1) {
1993 if (p.length() > 0) {
1994 fLibPathsToRemove.Add(p.c_str(), 0, 0, Hash_data_is_key);
1995 TRACE(ALL, "Filtering out from "<<XPD_LIBPATH<<" lib path '"<<p<<"'");
1996 }
1997 }
1998 }
1999
2000 // Done
2001 return 0;
2002}
2003
2004////////////////////////////////////////////////////////////////////////////////
2005/// Process manager request
2006
2008{
2009 XPDLOC(ALL, "Manager::Process")
2010
2011 int rc = 0;
2012 XPD_SETRESP(p, "Process");
2013
2014 TRACEP(p, REQ, "req id: " << p->Request()->header.requestid << " (" <<
2015 XrdProofdAux::ProofRequestTypes(p->Request()->header.requestid) << ")");
2016
2017 // If the user is not yet logged in, restrict what the user can do
2018 if (!p->Status() || !(p->Status() & XPD_LOGGEDIN)) {
2019 switch (p->Request()->header.requestid) {
2020 case kXP_auth:
2021 return fClientMgr->Auth(p);
2022 case kXP_login:
2023 return fClientMgr->Login(p);
2024 default:
2025 TRACEP(p, XERR, "invalid request: " << p->Request()->header.requestid);
2026 response->Send(kXR_InvalidRequest, "Invalid request; user not logged in");
2027 return p->Link()->setEtext("protocol sequence error 1");
2028 }
2029 }
2030
2031 // Once logged-in, the user can request the real actions
2032 XrdOucString emsg;
2033 switch (p->Request()->header.requestid) {
2034 case kXP_admin: {
2035 int type = ntohl(p->Request()->proof.int1);
2036 return fAdmin->Process(p, type);
2037 }
2038 case kXP_readbuf:
2039 return fNetMgr->ReadBuffer(p);
2040 case kXP_create:
2041 case kXP_destroy:
2042 case kXP_attach:
2043 case kXP_detach:
2044 return fSessionMgr->Process(p);
2045 default:
2046 emsg += "Invalid request: ";
2047 emsg += p->Request()->header.requestid;
2048 break;
2049 }
2050
2051 // Notify invalid request
2052 response->Send(kXR_InvalidRequest, emsg.c_str());
2053
2054 // Done
2055 return 0;
2056}
#define SafeDelete(p)
Definition RConfig.hxx:537
#define d(i)
Definition RSha256.hxx:102
#define g(i)
Definition RSha256.hxx:105
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
#define TRACE(Flag, Args)
Definition TGHtml.h:121
char name[80]
Definition TGX11.cxx:110
int type
Definition TGX11.cxx:121
int * iq
@ kXP_create
@ kXP_destroy
@ kXP_detach
@ kXP_attach
@ kXP_readbuf
@ kXP_auth
@ kXP_login
@ kXP_admin
#define kXPD_Master
#define kXPD_OpModeOpen
#define kXPD_TopMaster
#define XPD_DEF_PORT
#define kXPD_AnyServer
#define kXPD_OpModeControlled
#define kXPD_Worker
const char *const XPD_GW_QueryEnqueued
XrdProofSched *(* XrdProofSchedLoader_t)(const char *, XrdProofdManager *, XrdProofGroupMgr *, const char *, XrdSysError *)
int DoDirectiveString(XrdProofdDirective *, char *val, XrdOucStream *cfg, bool rcf)
Process directive for a string.
#define XPDFORM
#define SafeFree(x)
int DoDirectiveClass(XrdProofdDirective *, char *val, XrdOucStream *cfg, bool rcf)
Generic class directive processor.
int DoDirectiveInt(XrdProofdDirective *, char *val, XrdOucStream *cfg, bool rcf)
Process directive for an integer.
#define XpdBadPGuard(g, u)
#define XPD_LOGGEDIN
static int RemoveInvalidUsers(const char *k, int *, void *s)
Add the key value in the string passed via the void argument.
void * XrdProofdManagerCron(void *p)
This is an endless loop to periodically check the system.
static int FillKeyValues(const char *k, int *d, void *s)
Add the key value in the string passed via the void argument.
XrdProtocol *(* XrdProtocolLoader_t)(const char *, char *, XrdProtocol_Config *)
#define XPD_LIBPATH
#define XPD_SETRESP(p, x)
#define XPDLOC(d, x)
#define TRACEP(p, act, x)
#define TRACESET(act, on)
R__EXTERN XrdOucTrace * XrdProofdTrace
#define TRACE_ALL
#define TRACING(x)
#define XPDERR(x)
const char * proto
Definition civetweb.c:16613
XrdOucString HostWPort
void Print(const char *grp)
Return a string describing the group.
int Config(const char *fn)
(Re-)configure the group info using the file 'fn'.
const char * GetCfgFile() const
virtual int GetWorkers(XrdProofdProofServ *xps, std::list< XrdProofWorker * > *, const char *)
Get a list of workers that can be used by session 'xps'.
virtual int Config(bool rcf=0)
Configure this instance using the content of file 'cfn'.
const char * Name() const
virtual bool IsValid()
XrdOucString fUser
XrdOucString fHomeDir
XrdOucString fOrd
XrdOucString fHost
void AddProofServ(XrdProofdProofServ *xps)
const char * Export(const char *ord=0)
Export current content in a form understood by parsing algorithms inside the PROOF session,...
int Config(bool rcf=0)
Run configuration and parse the entered config directives.
int Process(XrdProofdProtocol *p, int type)
Process admin request.
static int ChangeOwn(const char *path, XrdProofUI ui)
Change the ownership of 'path' to the entity described by 'ui'.
static int GetUserInfo(const char *usr, XrdProofUI &ui)
Get information about user 'usr' in a thread safe way.
static int AssertDir(const char *path, XrdProofUI ui, bool changeown)
Make sure that 'path' exists and is owned by the entity described by 'ui'.
static const char * ProofRequestTypes(int type)
Translates the proof request type in a human readable string.
static int GetGroupInfo(const char *grp, XrdProofGI &gi)
Get information about group with 'gid' in a thread safe way.
static int ChangeMod(const char *path, unsigned int mode)
Change the permission mode of 'path' to 'mode'.
static int CheckIf(XrdOucStream *s, const char *h)
Check existence and match condition of an 'if' directive If none (valid) is found,...
static char * Expand(char *p)
Expand path 'p' relative to: $HOME if begins with ~/ <user>'s $HOME if begins with ~<user>/ $PWD if d...
int Auth(XrdProofdProtocol *xp)
Analyse client authentication info.
int Config(bool rcf=0)
Run configuration and parse the entered config directives.
int Login(XrdProofdProtocol *xp)
Process a login request.
XrdProofUI UI() const
const char * Group() const
const char * User() const
virtual int Config(bool rcf=0)
void Register(const char *dname, XrdProofdDirective *d)
XrdSysError * fEDest
const char * CfgFile() const
int DoDirectiveRootd(char *, XrdOucStream *, bool)
Process 'rootd' directive xpd.rootd deny|allow [rootsys:<tag>] [path:abs-path/] [mode:ro|rw] [auth:no...
int GetWorkers(XrdOucString &workers, XrdProofdProofServ *, const char *)
Get a list of workers from the available resource broker.
XrdProofdAdmin * fAdmin
bool ChangeOwn() const
XrdProofdPriorityMgr * fPriorityMgr
int DoDirectiveRole(char *, XrdOucStream *, bool)
Process 'role' directive.
XrdProtocol_Config * fPi
XrdOucString fWorkDir
int DoDirectiveDataSetSrc(char *, XrdOucStream *, bool)
Process 'datasetsrc' directive.
XrdProofdProofServMgr * fSessionMgr
XrdOucString fStageReqRepo
int DoDirective(XrdProofdDirective *d, char *val, XrdOucStream *cfg, bool rcf)
Update the priorities of the active sessions.
XrdOucString fSockPathDir
int Process(XrdProofdProtocol *p)
Process manager request.
XrdProofSched * LoadScheduler()
Load PROOF scheduler.
virtual ~XrdProofdManager()
Destructor.
XrdOucString fDataDir
XrdProofGroupMgr * GroupsMgr() const
XrdOucString fDataDirUrlOpts
int DoDirectiveMaxOldLogs(char *, XrdOucStream *, bool)
Process 'maxoldlogs' directive.
int DoDirectiveAllowedGroups(char *, XrdOucStream *, bool)
Process 'allowedgroups' directive.
XrdROOTMgr * fROOTMgr
int DoDirectiveMultiUser(char *, XrdOucStream *, bool)
Process 'multiuser' directive.
XrdOucString fAdminPath
XrdProofGroupMgr * fGroupsMgr
XrdOucString fEffectiveUser
const char * Host() const
int DoDirectiveFilterLibPaths(char *, XrdOucStream *, bool)
Process 'filterlibpaths' directive xpd.filterlibpaths 1|0 [path1,path2 path3 path4 ....
int DoDirectivePort(char *, XrdOucStream *, bool)
Process 'xrd.protocol' directive to find the port.
XrdSysRecMutex fMutex
XrdOucHash< int > fAllowedGroups
XrdOucString fPoolURL
XrdProtocol * fXrootd
XrdProofdNetMgr * fNetMgr
int DoDirectiveDataDir(char *, XrdOucStream *, bool)
Process 'datadir' directive.
void CheckLogFileOwnership()
Make sure that the log file belongs to the original effective user.
XrdSysPlugin * fXrootdPlugin
int DoDirectiveRootdAllow(char *, XrdOucStream *, bool)
Process 'rootdallow' directive xpd.rootdallow host1,host2 host3 Host names may contain the wild card ...
XrdOucHash< int > fAllowedUsers
bool CheckMaster(const char *m)
Check if master 'm' is allowed to connect to this host.
void RegisterDirectives()
Register directives for configuration.
XrdOucHash< XrdOucString > fLibPathsToRemove
XrdProtocol * LoadXrootd(char *parms, XrdProtocol_Config *pi, XrdSysError *edest)
Load the Xrootd protocol, if required.
XrdProofdManager(char *parms, XrdProtocol_Config *pi, XrdSysError *edest)
Constructor.
XrdOucString fBareLibPath
XrdOucString fDataSetExp
int DoDirectiveGroupfile(char *, XrdOucStream *, bool)
Process 'groupfile' directive.
int DoDirectiveTrace(char *, XrdOucStream *, bool)
Scan the config file for tracing settings.
XrdOucString fNamespace
XrdScheduler * fSched
std::list< XrdProofdDSInfo * > fDataSetSrcs
int DoDirectiveAllowedUsers(char *, XrdOucStream *, bool)
Process 'allowedusers' directive.
std::list< XrdOucString * > fMastersAllowed
const char * WorkDir() const
int CheckUser(const char *usr, const char *grp, XrdProofUI &ui, XrdOucString &e, bool &su)
Check if the user is allowed to use the system Return 0 if OK, -1 if not.
XrdOucString fDataDirOpts
XrdProofdProofServMgr * SessionMgr() const
bool ValidateLocalDataSetSrc(XrdOucString &url, bool &local)
Validate local dataset src at URL (check the URL and make the relevant directories).
int Config(bool rcf=0)
Run configuration and parse the entered config directives.
XrdProofSched * fProofSched
XrdOucString fXrootdLibPath
int DoDirectiveXrootd(char *, XrdOucStream *, bool)
Process 'xrootd' directive xpd.xrootd [path/]libXrdXrootd.so.
XrdOucString fSuperUsers
XrdProofdClientMgr * fClientMgr
XrdOucString fMUWorkDir
int DoDirectiveAllow(char *, XrdOucStream *, bool)
Process 'allow' directive.
int ResolveKeywords(XrdOucString &s, XrdProofdClient *pcl)
Resolve special keywords in 's' for client 'pcl'.
bool WorkerUsrCfg() const
void Dump()
Dump status.
int Config(bool rcf=0)
Run configuration and parse the entered config directives.
int ReadBuffer(XrdProofdProtocol *p)
Process a readbuf request.
int Config(bool rcf=0)
Run configuration and parse the entered config directives.
int Process(XrdProofdProtocol *p)
Process manager request.
int Config(bool rcf=0)
Run configuration and parse the entered config directives.
void AddWorker(const char *o, XrdProofWorker *w)
Add a worker assigned to this session with label 'o'.
XrdROOT * ROOT() const
void ExportWorkers(XrdOucString &wrks)
Export the assigned workers in the format understood by proofserv.
XrdLink * Link() const
static int EUidAtStartup()
XPClientRequest * Request() const
static void SetWorkdir(const char *wdir)
static void SetMaxOldSessions(int mxses)
int Config(bool rcf=0)
Run configuration and parse the entered config directives.
Definition XrdROOT.cxx:356
void SetLogDir(const char *d)
Set the log dir.
Definition XrdROOT.cxx:334
kXR_int16 SrvProtVers() const
Definition XrdROOT.h:82
char ** gr_mem
int gr_gid
int pw_gid
int pw_uid
auto * m
Definition textangle.C:8
struct ClientRequestHdr header
struct XPClientProofRequest proof