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