XRootD
Loading...
Searching...
No Matches
XrdPssConfig.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d P s s C o n f i g . c c */
4/* */
5/* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#include <unistd.h>
32#include <cctype>
33#include <cstdio>
34#include <cstring>
35#include <strings.h>
36#include <sys/param.h>
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <fcntl.h>
40
41#include "XrdNet/XrdNetAddr.hh"
42#include "XrdNet/XrdNetUtils.hh"
44
45#include "XrdPss/XrdPss.hh"
46#include "XrdPss/XrdPssTrace.hh"
48#include "XrdPss/XrdPssUtils.hh"
49
50#include "XrdSys/XrdSysError.hh"
51#include "XrdSys/XrdSysFD.hh"
55
56#include "XrdOuc/XrdOuca2x.hh"
57#include "XrdOuc/XrdOucCache.hh"
58#include "XrdOuc/XrdOucEnv.hh"
61#include "XrdOuc/XrdOucPsx.hh"
63#include "XrdOuc/XrdOucTList.hh"
64#include "XrdOuc/XrdOucUtils.hh"
65
69
71
73
74/******************************************************************************/
75/* d e f i n e s */
76/******************************************************************************/
77
78#define Duplicate(x,y) if (y) free(y); y = strdup(x)
79
80#define TS_String(x,m) if (!strcmp(x,var)) {Duplicate(val,m); return 0;}
81
82#define TS_Xeq(x,m) if (!strcmp(x,var)) return m(&eDest, Config);
83
84#define TS_PSX(x,m) if (!strcmp(x,var)) \
85 return (psxConfig->m(&eDest, Config) ? 0 : 1);
86
87#define TS_DBG(x,m) if (!strcmp(x,var)) {SysTrace.What |= m; return 0;}
88
89/******************************************************************************/
90/* G l o b a l s */
91/******************************************************************************/
92
93const char *XrdPssSys::ConfigFN; // -> Pointer to the config file name
94const char *XrdPssSys::myHost;
95const char *XrdPssSys::myName;
96
98
100
102 char *XrdPssSys::fileOrgn = 0;
103const char *XrdPssSys::protName = "root:";
104const char *XrdPssSys::hdrData = "";
105int XrdPssSys::hdrLen = 0;
106int XrdPssSys::Streams =512;
107int XrdPssSys::Workers = 16;
108int XrdPssSys::Trace = 0;
109int XrdPssSys::dcaCTime = 0;
110
111bool XrdPssSys::xLfn2Pfn = false;
112bool XrdPssSys::dcaCheck = false;
113bool XrdPssSys::dcaWorld = false;
114bool XrdPssSys::deferID = false;
115bool XrdPssSys::reProxy = false;
116
117namespace XrdProxy
118{
120
122
123extern XrdOucSid *sidP;
124
125extern XrdOucEnv *envP;
126
127extern XrdSecsssID *idMapper; // -> Auth ID mapper
128
129extern int rpFD;
130
131extern bool idMapAll;
132
133extern bool outProxy; // True means outgoing proxy
134
135extern bool xrdProxy; // True means dest using xroot protocol
136
137extern XrdSysTrace SysTrace;
138
139static const int maxHLen = 1024;
140}
141
142namespace
143{
144XrdOucPsx *psxConfig;
145
146XrdSecsssID::authType sssMap; // persona setting
147
148std::vector<const char *> protVec; // Additional wanted protocols
149}
150
151using namespace XrdProxy;
152
153/******************************************************************************/
154/* C o n f i g u r e */
155/******************************************************************************/
156
157int XrdPssSys::Configure(const char *cfn, XrdOucEnv *envP)
158{
159/*
160 Function: Establish configuration at start up time.
161
162 Input: None.
163
164 Output: 0 upon success or !0 otherwise.
165*/
166 char theRdr[maxHLen];
167 void* voidPtr;
168 int NoGo = 0;
169
170// Get environmental values
171//
172 myHost = getenv("XRDHOST");
174 ConfigFN = cfn;
175
176// Thell xrootd to disable POSC mode as this is meaningless here
177//
178 XrdOucEnv::Export("XRDXROOTD_NOPOSC", "1");
179
180// Create a configurator. It will be deleted when we are done.
181//
182 psxConfig = new XrdOucPsx(myVersion, cfn, eDest.logger(), envP);
183
184// Set debug level if so wanted
185//
186 if (getenv("XRDDEBUG"))
187 {psxConfig->traceLvl = 4;
189 }
190
191// Set the defaault number of worker threads for the client
192//
193 XrdPosixConfig::SetEnv("WorkerThreads", 64);
194
195// Set client IP mode based on what the server is set to
196//
197 if (XrdNetAddr::IPV4Set()) psxConfig->useV4 = true;
198
199// Set default number of event loops
200//
201 XrdPosixConfig::SetEnv("ParallelEvtLoop", 10);
202
203// Turn off the fork handler as we always exec after forking.
204//
205 XrdPosixConfig::SetEnv("RunForkHandler", 0);
206
207// Process the configuration file
208//
209 if ((NoGo = ConfigProc(cfn))) return NoGo;
210
211// Make sure we have some kind of origin
212//
213 if (!ManList && !outProxy && !fileOrgn)
214 {eDest.Emsg("Config", "Origin for proxy service not specified.");
215 return 1;
216 }
217
218// Re-export pfc.gStream* internal envar. Normally, this is used inconjunction
219// with a cache but that isn't necessarily true in the future.
220//
221 if ((voidPtr = envP->GetPtr("pfc.gStream*")))
222 XrdPosixConfig::SetEnv("pfc.gStream*", voidPtr);
223
224// Check if we should configure authentication security mapping
225//
226 if (sssMap && !ConfigMapID()) return 1;
227
228// Handle the local root here
229//
230 if (LocalRoot) psxConfig->SetRoot(LocalRoot);
231
232// Pre-screen any n2n library parameters
233//
234 if (outProxy && psxConfig->xLfn2Pfn)
235 {const char *txt;
236 if (!(psxConfig->xNameLib)) txt = "localroot directive";
237 else if (psxConfig->xPfn2Lfn) txt = "namelib -lfn2pfn option";
238 else txt = "namelib directive";
239 eDest.Say("Config warning: ignoring ",txt,"; this is forwarding proxy!");
240 psxConfig->xLfn2Pfn = false;
241 }
242
243// If we have a cache, indicate so in the feature set
244//
245 if(psxConfig->hasCache()) myFeatures |= XRDOSS_HASCACH;
246
247// If we need to reproxy, then open the directory where the reproxy information
248// will ne placed. The path is in the Env.
249//
250 if (reProxy)
251 {char *rPath;
252 if (!envP || !(rPath = envP->Get("tpc.rpdir")))
253 {eDest.Say("Config warning: ignoring 'pss.reproxy'; TPC is not enabled!");
254 reProxy = false;
255 myFeatures &= ~XRDOSS_HASRPXY;
256 } else {
257 rpFD = XrdSysFD_Open(rPath, O_DIRECTORY);
258 if (rpFD < 0)
259 {eDest.Emsg("Config", "to open reproxy directory", rPath);
260 return 1;
261 }
262 }
263 }
264
265// Finalize the configuration
266//
267 if (!(psxConfig->ConfigSetup(eDest))) return 1;
268
269// Complete initialization (we would set the env pointer here)
270//
271 if (!XrdPosixConfig::SetConfig(*psxConfig)) return 1;
272
273// Save the N2N library pointer if we will be using it
274//
275 if (psxConfig->xLfn2Pfn) xLfn2Pfn = (theN2N = psxConfig->theN2N) != 0;
276
277// If we have a cache then save it and check if we need to tell
278// xrootd we allow a redirect on a read (this is complicated).
279// ??? Why are we doing this
280// if (psxConfig->theCache2 && dcaCTime)
281// {char buff[32];
282// sprintf(buff, "%d", dcaCTime);
283// XrdOucEnv::Export("XRDXROOTD_CACHERDRDR", buff);
284// }
285
286// All done with the configurator
287//
288 delete psxConfig;
289
290// Allocate an Xroot proxy object (only one needed here). Tell it to not
291// shadow open files with real file descriptors (we will be honest).
292//
293 Xroot = new XrdPosixXrootd(-32768, 16384);
294
295// Allocate an streaim ID object if need be
296//
297 if (Streams) sidP = new XrdOucSid((Streams > 8192 ? 8192 : Streams));
298
299// Tell any security manager we are a proxy as this will force it to use our
300// credentials. We don't support credential forwarding, yet. If we did we would
301// also set XrdSecPROXYCREDS to accomplish that feat.
302//
303 XrdOucEnv::Export("XrdSecPROXY", "1");
304
305// Add the origin protocl to the recognized list of protocol names
306//
308 {eDest.Emsg("Config", "Unable to add origin protocol to protocol list.");
309 return 1;
310 }
311
312// Add any other protocols to the recognized list of protocol names
313//
314 if (protVec.size())
315 {for (int i = 0; i < (int)protVec.size(); i++)
316 {if (!XrdPosixXrootPath::AddProto(protVec[i]))
317 {eDest.Emsg("Config", "Unable to add", protVec[i],
318 "protocol to protocol list.");
319 return 1;
320 }
321 }
322 protVec.clear();
323 }
324
325// Construct the redirector name:port (we might not have one) export it
326//
327 const char *outeq = (outProxy ? "= " : "");
328 if (ManList) sprintf(theRdr, "%s%s:%d", outeq, ManList->text, ManList->val);
329 else if (fileOrgn) sprintf(theRdr, "%s%s", outeq, fileOrgn);
330 else strcpy(theRdr, outeq);
331 XrdOucEnv::Export("XRDXROOTD_PROXY", theRdr);
332 XrdOucEnv::Export("XRDXROOTD_ORIGIN", theRdr); // Backward compatibility
333 if (HostArena) XrdOucEnv::Export("XRDXROOTD_PROXYARENA", HostArena);
334
335// Construct the contact URL header
336//
337 if (ManList) //<prot><id>@<host>:<port>/<path>
338 {hdrLen = sprintf(theRdr, "%s%%s%s:%d/%s%%s",
340 (HostArena ? HostArena : ""));
341 hdrData = strdup(theRdr);
342 } else {
343 if (fileOrgn)
344//?? {if (!(myFeatures & XRDOSS_HASCACH))
345// {eDest.Emsg("Config", "File origins only supported for caching proxies.");
346// return 1;
347// }
348 {hdrLen = sprintf(theRdr, "%s%s%%s", protName, fileOrgn);
349 hdrData = strdup(theRdr);
350 }
351 }
352
353// Export the URL
354//
355 if (hdrData && *hdrData)
356 {snprintf(theRdr, sizeof(theRdr), hdrData, "", "");
357 XrdOucEnv::Export("XRDXROOTD_PROXYURL", theRdr);
358 }
359
360// Check if we have any r/w exports as this will determine whether or not we
361// need to initialize any r/w cache. Currently, we don't support this so we
362// have no particular initialization to do.
363//
364// XrdOucPList *fP = XPList.First();
365// while(fP && !(fP->Flag() & XRDEXP_NOTRW)) fP = fP->Next();
366// if (!fP) . . .
367
368// All done
369//
370 return 0;
371}
372
373/******************************************************************************/
374/* P r i v a t e F u n c t i o n s */
375/******************************************************************************/
376/******************************************************************************/
377/* C o n f i g M a p I D */
378/******************************************************************************/
379
381{
382 XrdSecsssCon *conTracker;
383 bool isOK, Debug = (SysTrace.What & TRACEPSS_Debug) != 0;
384
385// If this is a generic static ID mapping, we are done
386//
387 if (sssMap == XrdSecsssID::idStatic) return true;
388
389// For optimzation we also note if we have a cache in he way of the map
390//
391 deferID = psxConfig->hasCache();
392
393// Now that we did the cache thing, currently we don't support client personas
394// with a cache because aren't able to tell which client will be used.
395//
396 if (deferID)
397 {eDest.Emsg("Config", "Client personas are not supported for "
398 "caching proxy servers.");
399 return false;
400 }
401
402// If this server is only a forwarding proxy server, we can't support client
403// personas either because we don't control the URL. However, if we have an
404// origin then simply warn that the client persona applies to the origin.
405//
406 if (outProxy)
407 {if (!ManList)
408 {eDest.Emsg("Config", "Client personas are not supported for "
409 "strictly forwarding proxy servers.");
410 return false;
411 }
412 eDest.Say("Config warning: client personas only apply to "
413 "the origin server!");
414 }
415
416// We need to get a connection tracker object from the posix interface.
417// However, we only need it if we are actually mapping id's.
418//
419 if (sssMap == XrdSecsssID::idStaticM) conTracker = 0;
420 else conTracker = XrdPosixConfig::conTracker(Debug);
421
422// Get an mapper object
423//
424 idMapper = new XrdSecsssID(sssMap, 0, conTracker, &isOK);
425 if (!isOK)
426 {eDest.Emsg("Config", "Unable to render persona; persona mapper failed!");
427 return false;
428 }
429
430// If ths is a server persona then we don't need the mapper; abandon it.
431//
432 if (sssMap == XrdSecsssID::idStaticM) idMapper = 0;
433 else XrdPssUrlInfo::setMapID(true);
434
435// We are all done
436//
437 return true;
438}
439
440/******************************************************************************/
441/* C o n f i g P r o c */
442/******************************************************************************/
443
444int XrdPssSys::ConfigProc(const char *Cfn)
445{
446 char *var;
447 int cfgFD, retc, NoGo = 0;
448 XrdOucEnv myEnv;
449 XrdOucStream Config(&eDest, getenv("XRDINSTANCE"), &myEnv, "=====> ");
450
451// Make sure we have a config file
452//
453 if (!Cfn || !*Cfn)
454 {eDest.Emsg("Config", "pss configuration file not specified.");
455 return 1;
456 }
457
458// Try to open the configuration file.
459//
460 if ( (cfgFD = open(Cfn, O_RDONLY, 0)) < 0)
461 {eDest.Emsg("Config", errno, "open config file", Cfn);
462 return 1;
463 }
464 Config.Attach(cfgFD);
465 static const char *cvec[] = { "*** pss (oss) plugin config:", 0 };
466 Config.Capture(cvec);
467
468// Now start reading records until eof.
469//
470 while((var = Config.GetMyFirstWord()))
471 {if (!strncmp(var, "pss.", 4)
472 || !strcmp(var, "oss.defaults")
473 || !strcmp(var, "all.export"))
474 if (ConfigXeq(var+4, Config)) {Config.Echo(); NoGo = 1;}
475 }
476
477// Now check if any errors occurred during file i/o
478//
479 if ((retc = Config.LastError()))
480 NoGo = eDest.Emsg("Config", retc, "read config file", Cfn);
481 Config.Close();
482
483// Set the defaults for the export list
484//
485 XPList.Set(DirFlags);
486
487// Return final return code
488//
489 return NoGo;
490}
491
492/******************************************************************************/
493/* C o n f i g X e q */
494/******************************************************************************/
495
496int XrdPssSys::ConfigXeq(char *var, XrdOucStream &Config)
497{
498 char myVar[80], *val;
499
500 // Process items. for either a local or a remote configuration
501 //
502 TS_PSX("namelib", ParseNLib);
503 TS_PSX("memcache", ParseCache); // Backward compatibility
504 TS_PSX("cache", ParseCache);
505 TS_PSX("cachelib", ParseCLib);
506 TS_PSX("ccmlib", ParseMLib);
507 TS_PSX("ciosync", ParseCio);
508 TS_Xeq("config", xconf);
509 TS_Xeq("dca", xdca);
510 TS_Xeq("defaults", xdef);
511 TS_DBG("debug", TRACEPSS_Debug);
512 TS_Xeq("export", xexp);
513 TS_PSX("inetmode", ParseINet);
514 TS_Xeq("origin", xorig);
515 TS_Xeq("permit", xperm);
516 TS_Xeq("persona", xpers);
517 TS_PSX("setopt", ParseSet);
518 TS_PSX("trace", ParseTrace);
519
520 if (!strcmp("reproxy", var))
521 {myFeatures |= XRDOSS_HASRPXY;
522 reProxy = true;
523 Config.GetWord(); // Force echo
524 return 0;
525 }
526
527 // Copy the variable name as this may change because it points to an
528 // internal buffer in Config. The vagaries of effeciency. Then get value.
529 //
530 strlcpy(myVar, var, sizeof(myVar)); var = myVar;
531 if (!(val = Config.GetWord()))
532 {eDest.Emsg("Config", "no value for directive", var);
533 return 1;
534 }
535
536 // Match directives that take a single argument
537 //
538 TS_String("hostarena", HostArena);
539 TS_String("localroot", LocalRoot);
540
541 // No match found, complain.
542 //
543 eDest.Say("Config warning: ignoring unknown directive '",var,"'.");
544 Config.Echo();
545 return 0;
546}
547
548/******************************************************************************/
549/* x c o n f */
550/******************************************************************************/
551
552/* Function: xconf
553
554 Purpose: To parse the directive: config <keyword> <value>
555
556 <keyword> is one of the following:
557 streams number of i/o streams
558 workers number of queue workers
559
560 Output: 0 upon success or 1 upon failure.
561*/
562
563int XrdPssSys::xconf(XrdSysError *Eroute, XrdOucStream &Config)
564{
565 char *val, *kvp;
566 int kval;
567 struct Xtab {const char *Key; int *Val;} Xopts[] =
568 {{"streams", &Streams},
569 {"workers", &Workers}};
570 int i, numopts = sizeof(Xopts)/sizeof(struct Xtab);
571
572 if (!(val = Config.GetWord()))
573 {Eroute->Emsg("Config", "options argument not specified."); return 1;}
574
575do{for (i = 0; i < numopts; i++) if (!strcmp(Xopts[i].Key, val)) break;
576
577 if (i >= numopts)
578 Eroute->Say("Config warning: ignoring unknown config option '",val,"'.");
579 else {if (!(val = Config.GetWord()))
580 {Eroute->Emsg("Config","config",Xopts[i].Key,"value not specified.");
581 return 1;
582 }
583
584 kval = strtol(val, &kvp, 10);
585 if (*kvp || !kval)
586 {Eroute->Emsg("Config", Xopts[i].Key,
587 "config value is invalid -", val);
588 return 1;
589 }
590 *(Xopts[i].Val) = kval;
591 }
592 val = Config.GetWord();
593 } while(val && *val);
594
595 return 0;
596}
597
598/******************************************************************************/
599/* x d c a */
600/******************************************************************************/
601
602/* Function: xdca
603
604 Purpose: To parse the directive: dca [group|world] [recheck {<tm> | off}]
605
606 <tm> recheck for applicability every <tm> interval
607 world When specified, files are made world deadable.
608 Otherwise, they are only made group readable.
609
610 Output: 0 upon success or 1 upon failure.
611*/
612
613int XrdPssSys::xdca(XrdSysError *errp, XrdOucStream &Config)
614{
615 static const int maxsz = 0x7fffffff;
616 char *val;
617
618// Preset the defaults
619//
620 dcaCheck = true;
621 dcaCTime = 0;
622 dcaWorld = false;
623
624// If no options then we are done
625//
626 while((val = Config.GetWord()))
627 { if (!strcmp(val, "world")) dcaWorld = true;
628 else if (!strcmp(val, "group")) dcaWorld = false;
629 else if (!strcmp(val, "recheck"))
630 {if (!strcmp(val, "off")) dcaCTime = 0;
631 else {if (!(val = Config.GetWord()))
632 {errp->Emsg("Config",
633 "dca recheck value not specified");
634 return 1;
635 }
636 if (XrdOuca2x::a2tm(*errp,"dca recheck",val,
637 &dcaCTime,10,maxsz)) return 1;
638 }
639 }
640 else {errp->Emsg("Config","invalid dca option -", val); return 1;}
641 }
642
643// All done
644//
645 return 0;
646}
647
648/******************************************************************************/
649/* x d e f */
650/******************************************************************************/
651
652/* Function: xdef
653
654 Purpose: Parse: defaults <default options>
655
656 Notes: See the oss configuration manual for the meaning of each option.
657 The actual implementation is defined in XrdOucExport.
658
659 Output: 0 upon success or !0 upon failure.
660*/
661
662int XrdPssSys::xdef(XrdSysError *Eroute, XrdOucStream &Config)
663{
664 DirFlags = XrdOucExport::ParseDefs(Config, *Eroute, DirFlags);
665 return 0;
666}
667
668/******************************************************************************/
669/* x e x p */
670/******************************************************************************/
671
672/* Function: xrcp
673
674 Purpose: To parse the directive: {export | path} <path> [<options>]
675
676 <path> the full path that resides in a remote system.
677 <options> a blank separated list of options (see XrdOucExport)
678
679 Output: 0 upon success or !0 upon failure.
680*/
681
682int XrdPssSys::xexp(XrdSysError *Eroute, XrdOucStream &Config)
683{
684 XrdOucPList *pP;
685
686// Parse the arguments
687//
688 if (!(pP = XrdOucExport::ParsePath(Config, *Eroute, XPList, DirFlags)))
689 return 1;
690
691// Check if we are allowing object id's
692//
693 if (*(pP->Path()) == '*') XrdPosixConfig::setOids(true);
694 return 0;
695}
696
697/******************************************************************************/
698/* x o r i g */
699/******************************************************************************/
700
701/* Function: xorig
702
703 Purpose: Parse: origin {=[<prot>,<prot>,...] [<dest>] | <dest>}
704
705 where: <dest> <host>[+][:<port>|<port>] or a URL of the form
706 <prot>://<dest>[:<port>] where <prot> is one
707 http, https, root, xroot
708
709 Output: 0 upon success or !0 upon failure.
710*/
711
712int XrdPssSys::xorig(XrdSysError *errp, XrdOucStream &Config)
713{
714 XrdOucTList *tp = 0;
715 char *val, *colon, *slash, *mval = 0;
716 int i, port = 0;
717 bool isURL;
718
719// We are looking for regular managers. These are our points of contact
720//
721 if (!(val = Config.GetWord()))
722 {errp->Emsg("Config","origin host name not specified"); return 1;}
723
724// Check for outgoing proxy
725//
726 if (*val == '=')
727 {outProxy = true;
728 if (*(val+1))
729 {std::vector<char *> pVec;
730 char *pData = strdup(val+1);
731 const char *pName;
732 protVec.clear();
733 if (!XrdPssUtils::Vectorize(pData, pVec, ','))
734 {errp->Emsg("Config", "Malformed forwarding specification");
735 free(pData);
736 return 1;
737 }
738 protVec.reserve(pVec.size());
739 for (int i = 0; i < (int)pVec.size(); i++)
740 {int n = strlen(pVec[i]);
741 if (!(pName = XrdPssUtils::valProt(pVec[i], n, 3)))
742 {errp->Emsg("Config","Unsupported forwarding protocol -",pVec[i]);
743 free(pData);
744 return 1;
745 }
746 protVec.push_back(pName);
747 }
748 free(pData);
749 }
750 if (!(val = Config.GetWord())) return 0;
751 }
752 else outProxy = false;
753
754// We must always cleanup the file origin if it exists
755//
756 if (fileOrgn) {free(fileOrgn); fileOrgn = 0;}
757
758// Check if dest is some local filesystem
759//
760 if (*val == '/')
761 {char *vP = val +strlen(val) - 1;
762 while(*vP == '/'&& vP != val) {*vP-- = 0;}
763 if (ManList) {delete ManList; ManList = 0;}
764 protName = "file://";
765 fileOrgn = strdup(val);
766 return 0;
767 }
768
769
770// Check if the <dest> is a url, if so, the protocol, must be supported
771//
772 if ((colon = index(val, ':')) && *(colon+1) == '/' && *(colon+2) == '/')
773 {int pnlen;
774 protName = XrdPssUtils::valProt(val, pnlen);
775 if (!protName)
776 {errp->Emsg("Config", "Unsupported origin protocol -", val);
777 return 1;
778 }
779 if (*val == 'x') protName++;
780 xrdProxy = (*val == 'r');
781 val += pnlen;
782 if ((slash = index(val, '/')))
783 {if (*(slash+1))
784 {errp->Emsg("Config","badly formed origin URL"); return 1;}
785 *slash = 0;
786 }
787 mval = strdup(val);
788 isURL = true;
789 } else {
790 protName = "root://";
791 mval = strdup(val);
792 isURL = false;
793 xrdProxy = true;
794 }
795
796// Check if there is a port number. This could be as ':port' or ' port'.
797//
798 if (!(val = index(mval,':')) && !isURL) val = Config.GetWord();
799 else if (val) {*val = '\0'; val++;}
800
801// At this point, make sure we actually have a host name
802//
803 if (!(*mval))
804 {errp->Emsg("Config","origin host name not specified"); return 1;}
805
806// Validate the port number
807//
808 if (val)
809 {if (isdigit(*val))
810 {if (XrdOuca2x::a2i(*errp,"origin port",val,&port,1,65535))
811 port = 0;
812 }
813 else if (!(port = XrdNetUtils::ServPort(val)))
814 {errp->Emsg("Config", "unable to find tcp service", val);
815 port = 0;
816 }
817 } else {
818 if (protName) {
819 // use default port for protocol
820 port = *protName == 'h' ? (strncmp(protName, "https", 5) == 0 ? 443 : 80) : 1094;
821 } else {
822 // assume protocol is root(s)://
823 port = 1094;
824 }
825 errp->Say("Config warning: origin port not specified, using port ",
826 std::to_string(port).c_str(), " as default for ", protName);
827 }
828
829// If port is invalid or missing, fail this
830//
831 if (!port) {free(mval); return 1;}
832
833// For proxies we need not expand 'host+' spec but need to supress the plus
834//
835 if ((i = strlen(mval)) > 1 && mval[i-1] == '+') mval[i-1] = 0;
836
837// We used to support multiple destinations in the URL but the new client
838// does not support this. So, we only provide a single destination here. The
839// original code is left commented out just in case we actually revert to this.
840//
841// tp = ManList;
842// while(tp && (strcmp(tp->text, mval) || tp->val != port)) tp = tp->next;
843// if (tp) errp->Emsg("Config","Duplicate origin",mval);
844// else ManList = new XrdOucTList(mval, port, ManList);
845
846 if (ManList) delete ManList;
847 ManList = new XrdOucTList(mval, port);
848
849// We now set the default dirlist flag based on whether the origin is in or out
850// of domain. Composite listings are normally disabled for out of domain nodes.
851//
852 if (!index(mval, '.')
854 && !strcmp(protName, "http://") && !strcmp(protName, "https://")))
855 XrdPosixConfig::SetEnv("DirlistDflt", 1);
856
857// All done
858//
859 free(mval);
860 return tp != 0;
861}
862
863/******************************************************************************/
864/* x p e r m */
865/******************************************************************************/
866
867/* Function: xperm
868
869 Purpose: To parse the directive: permit [/] [*] <name>
870
871 netgroup name the host must be a member of. For DNS names,
872 A single asterisk may be specified anywhere in the name.
873
874 Output: 0 upon success or !0 upon failure.
875*/
876
877int XrdPssSys::xperm(XrdSysError *Eroute, XrdOucStream &Config)
878{ char *val;
879 bool pType[PolNum] = {false, false};
880 int i;
881
882do {if (!(val = Config.GetWord()))
883 {Eroute->Emsg("Config", "permit target not specified"); return 1;}
884 if (!strcmp(val, "/")) pType[PolPath] = true;
885 else if (!strcmp(val, "*")) pType[PolObj ] = true;
886 else break;
887 } while(1);
888
889 if (!pType[PolPath] && !pType[PolObj])
890 pType[PolPath] = pType[PolObj] = true;
891
892 for (i = 0; i < PolNum; i++)
893 {if (pType[i])
894 {if (!Police[i]){Police[i] = new XrdNetSecurity();}
895 Police[i]->AddHost(val);
896 }
897 }
898
899 return 0;
900}
901
902/******************************************************************************/
903/* x p e r s */
904/******************************************************************************/
905
906/* Function: xpers
907
908 Purpose: To parse the directive: persona {client | server} [options]
909
910 options: [[non]strict] [[no]verify]
911
912 client proxy client's identity via sss authentication
913 server use server's identity at end point
914 strict all requests must use the client persona
915 nonstrict certain requests can use a server persona
916 noverify do not verify endpoint
917 verify verify endpoint
918
919 Output: 0 upon success or !0 upon failure.
920*/
921
922int XrdPssSys::xpers(XrdSysError *Eroute, XrdOucStream &Config)
923{ char *val;
924 bool isClient = false, strict = false;
925 int doVer = -1;
926
927// Make sure a parameter was specified
928//
929 if (!(val = Config.GetWord()))
930 {Eroute->Emsg("Config", "persona not specified"); return 1;}
931
932// Check for persona
933//
934 if (!strcmp(val, "client")) isClient = true;
935 else if (!strcmp(val, "server")) isClient = false;
936 else {Eroute->Emsg("Config", "Invalid persona - ", val); return 1;}
937
938// Process the subsequent options
939//
940 while ((val = Config.GetWord()))
941 { if (!strcmp(val, "strict" )) strict = true;
942 else if (!strcmp(val, "nonstrict" )) strict = false;
943 else if (!strcmp(val, "verify" )) doVer = 1;
944 else if (!strcmp(val, "noverify" )) doVer = 0;
945 else {Eroute->Emsg("Config", "Invalid persona option - ", val);
946 return 1;
947 }
948 }
949
950// Resolve options vs persona
951//
952 if (isClient)
953 {idMapAll = (strict ? true : false);
954 if (doVer < 0) doVer = 1;
955 }
956
957// Now record the information for future processin
958//
959 if (isClient) sssMap = (doVer ? XrdSecsssID::idMappedM
961 else sssMap = (doVer ? XrdSecsssID::idStaticM
963
964// All done
965//
966 return 0;
967}
#define TS_String(x, m)
#define TS_Xeq(x, m)
Definition XrdConfig.cc:160
XrdSysError eDest(0, "HttpMon")
#define XRDOSS_HASRPXY
Definition XrdOss.hh:542
#define XRDOSS_HASCACH
Definition XrdOss.hh:540
XrdPosixXrootd Xroot
Definition XrdPosix.cc:53
#define open
Definition XrdPosix.hh:78
#define TS_DBG(x, m)
#define TS_PSX(x, m)
#define TRACEPSS_Debug
bool Debug
size_t strlcpy(char *dst, const char *src, size_t sz)
static bool IPV4Set()
Definition XrdNetAddr.hh:61
void AddHost(char *hname)
static int ServPort(const char *sName, bool isUDP=false, const char **eText=0)
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
static int Export(const char *Var, const char *Val)
Definition XrdOucEnv.cc:170
void * GetPtr(const char *varname)
Definition XrdOucEnv.cc:263
static unsigned long long ParseDefs(XrdOucStream &Config, XrdSysError &Eroute, unsigned long long Flags)
static XrdOucPList * ParsePath(XrdOucStream &Config, XrdSysError &Eroute, XrdOucPListAnchor &Export, unsigned long long Defopts)
char * Path()
void Set(int aval)
XrdOucPsx(XrdVersionInfo *vInfo, const char *cfn, XrdSysLogger *lp=0, XrdOucEnv *vp=0)
Definition XrdOucPsx.hh:102
XrdOucSid(int numSid=256, bool mtproof=true, XrdOucSid *glblSid=0)
Definition XrdOucSid.cc:37
XrdOucTList(const char *tval, long long *dv, XrdOucTList *np=0)
static const char * InstName(int TranOpt=0)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition XrdOuca2x.cc:45
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition XrdOuca2x.cc:288
static void SetEnv(const char *kword, int kval)
static void setOids(bool isok)
static XrdSecsssCon * conTracker(bool debug=false)
static bool SetConfig(XrdOucPsx &parms)
static bool AddProto(const char *proto)
POSIX interface to XRootD with some extensions, as noted.
XrdPosixXrootd(int maxfd=255, int maxdir=0, int maxthr=0)
static const int PolNum
Definition XrdPss.hh:195
static int dcaCTime
Definition XrdPss.hh:220
static int Streams
Definition XrdPss.hh:217
static bool deferID
Definition XrdPss.hh:225
static const char * ConfigFN
Definition XrdPss.hh:205
static int hdrLen
Definition XrdPss.hh:216
static const char * hdrData
Definition XrdPss.hh:215
static XrdOucTList * ManList
Definition XrdPss.hh:212
static char * fileOrgn
Definition XrdPss.hh:213
static bool dcaCheck
Definition XrdPss.hh:223
static bool reProxy
Definition XrdPss.hh:226
static int Workers
Definition XrdPss.hh:218
static XrdNetSecurity * Police[PolNum]
Definition XrdPss.hh:99
static const char * myName
Definition XrdPss.hh:207
static int Trace
Definition XrdPss.hh:219
bool ConfigMapID()
static XrdOucPListAnchor XPList
Definition XrdPss.hh:209
static const char * myHost
Definition XrdPss.hh:206
static bool xLfn2Pfn
Definition XrdPss.hh:222
static bool dcaWorld
Definition XrdPss.hh:224
static const char * protName
Definition XrdPss.hh:214
static void setMapID(bool onoff)
static const char * getDomain(const char *hName)
static const char * valProt(const char *pname, int &plen, int adj=0)
static bool Vectorize(char *str, std::vector< char * > &vec, char sep)
XrdSecsssID(authType aType=idStatic, const XrdSecEntity *Ident=0, XrdSecsssCon *Tracker=0, bool *isOK=0)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
XrdSysLogger * logger(XrdSysLogger *lp=0)
XrdCmsConfig Config
XrdSecsssID * idMapper
Definition XrdPss.cc:114
XrdSysTrace SysTrace("Pss", 0)
Definition XrdPssCks.cc:55
bool xrdProxy
Definition XrdPss.cc:128
XrdOucSid * sidP
Definition XrdPss.cc:108
XrdSysError eDest(0, "pss_")
static const int maxHLen
bool outProxy
Definition XrdPss.cc:126
bool idMapAll
Definition XrdPss.cc:124
int rpFD
Definition XrdPss.cc:122
static XrdPosixXrootd * Xroot
XrdOucEnv * envP
Definition XrdPss.cc:110