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