XRootD
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"
43 #include "XrdNet/XrdNetSecurity.hh"
44 
45 #include "XrdPss/XrdPss.hh"
46 #include "XrdPss/XrdPssTrace.hh"
47 #include "XrdPss/XrdPssUrlInfo.hh"
48 #include "XrdPss/XrdPssUtils.hh"
49 
50 #include "XrdSys/XrdSysError.hh"
51 #include "XrdSys/XrdSysFD.hh"
52 #include "XrdSys/XrdSysHeaders.hh"
53 #include "XrdSys/XrdSysPlatform.hh"
54 #include "XrdSys/XrdSysPthread.hh"
55 
56 #include "XrdOuc/XrdOuca2x.hh"
57 #include "XrdOuc/XrdOucCache.hh"
58 #include "XrdOuc/XrdOucEnv.hh"
59 #include "XrdOuc/XrdOucExport.hh"
61 #include "XrdOuc/XrdOucPsx.hh"
62 #include "XrdOuc/XrdOucStream.hh"
63 #include "XrdOuc/XrdOucTList.hh"
64 #include "XrdOuc/XrdOucUtils.hh"
65 
69 
70 #include "XrdSecsss/XrdSecsssID.hh"
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 
93 const char *XrdPssSys::ConfigFN; // -> Pointer to the config file name
94 const char *XrdPssSys::myHost;
95 const char *XrdPssSys::myName;
96 
98 
100 
102  char *XrdPssSys::fileOrgn = 0;
103 const char *XrdPssSys::protName = "root:";
104 const char *XrdPssSys::hdrData = "";
105 int XrdPssSys::hdrLen = 0;
106 int XrdPssSys::Streams =512;
107 int XrdPssSys::Workers = 16;
108 int XrdPssSys::Trace = 0;
109 int XrdPssSys::dcaCTime = 0;
110 
111 bool XrdPssSys::xLfn2Pfn = false;
112 bool XrdPssSys::dcaCheck = false;
113 bool XrdPssSys::dcaWorld = false;
114 bool XrdPssSys::deferID = false;
115 bool XrdPssSys::reProxy = false;
116 
117 namespace XrdProxy
118 {
120 
122 
123 extern XrdOucSid *sidP;
124 
125 extern XrdOucEnv *envP;
126 
127 extern XrdSecsssID *idMapper; // -> Auth ID mapper
128 
129 extern int rpFD;
130 
131 extern bool idMapAll;
132 
133 extern bool outProxy; // True means outgoing proxy
134 
135 extern bool xrdProxy; // True means dest using xroot protocol
136 
137 extern XrdSysTrace SysTrace;
138 
139 static const int maxHLen = 1024;
140 }
141 
142 namespace
143 {
144 XrdOucPsx *psxConfig;
145 
146 XrdSecsssID::authType sssMap; // persona setting
147 
148 std::vector<const char *> protVec; // Additional wanted protocols
149 }
150 
151 using namespace XrdProxy;
152 
153 /******************************************************************************/
154 /* C o n f i g u r e */
155 /******************************************************************************/
156 
157 int 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");
173  myName = XrdOucUtils::InstName(1);
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 //
307  if (!XrdPosixXrootPath::AddProto(protName))
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",
339  protName, ManList->text, ManList->val,
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 
444 int 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 
496 int 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 
563 int 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 
575 do{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 
613 int 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 
662 int 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 
682 int 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 
712 int 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, '.')
853  || (!strcmp(XrdPssUtils::getDomain(mval), XrdPssUtils::getDomain(myHost))
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 
877 int XrdPssSys::xperm(XrdSysError *Eroute, XrdOucStream &Config)
878 { char *val;
879  bool pType[PolNum] = {false, false};
880  int i;
881 
882 do {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 
922 int 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 XRDOSS_HASRPXY
Definition: XrdOss.hh:542
#define XRDOSS_HASCACH
Definition: XrdOss.hh:540
#define open
Definition: XrdPosix.hh:78
#define TS_String(x, m)
Definition: XrdPssConfig.cc:80
#define TS_DBG(x, m)
Definition: XrdPssConfig.cc:87
#define TS_Xeq(x, m)
Definition: XrdPssConfig.cc:82
#define TS_PSX(x, m)
Definition: XrdPssConfig.cc:84
#define TRACEPSS_Debug
Definition: XrdPssTrace.hh:34
bool Debug
size_t strlcpy(char *dst, const char *src, size_t sz)
static bool IPV4Set()
Definition: XrdNetAddr.hh:61
static int ServPort(const char *sName, bool isUDP=false, const char **eText=0)
Definition: XrdNetUtils.cc:874
static int Export(const char *Var, const char *Val)
Definition: XrdOucEnv.cc:188
void * GetPtr(const char *varname)
Definition: XrdOucEnv.cc:281
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
static unsigned long long ParseDefs(XrdOucStream &Config, XrdSysError &Eroute, unsigned long long Flags)
Definition: XrdOucExport.cc:60
static XrdOucPList * ParsePath(XrdOucStream &Config, XrdSysError &Eroute, XrdOucPListAnchor &Export, unsigned long long Defopts)
char * Path()
Definition: XrdOucPList.hh:45
static const char * InstName(int TranOpt=0)
Definition: XrdOucUtils.cc:852
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.
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:211
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)
Definition: XrdPssUtils.cc:56
static const char * valProt(const char *pname, int &plen, int adj=0)
Definition: XrdPssUtils.cc:82
static bool Vectorize(char *str, std::vector< char * > &vec, char sep)
Definition: XrdPssUtils.cc:99
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:116
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)
Definition: XrdSysError.cc:162
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:175
XrdVersionInfo myVersion
XrdCmsConfig Config
XrdOucName2Name * theN2N
Definition: XrdPosixFile.cc:62
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