42#include <sys/isa_defs.h>
45#include "XrdVersion.hh"
131 const char *,
const char *,
137 const char *configFn,
158char *FSLib[2] = {0,0};
159std::vector<std::string> FSLPath;
160std::vector<std::string> RDLPath;
161std::vector<std::string> RDLParm;
168static const int asDebug = 0x01;
169static const int asNoCache = 0x02;
189 const char *configFn,
190 const char *theParms);
194 char *adminp, *rdf, *bP, *tmp, buff[1024];
225 for (i = 1; i < pi->
argc; i++) xexpdo(pi->
argv[i]);
245 rdf = (parms && *parms ? parms : pi->
ConfigFN);
246 if (rdf && Config(rdf))
return 0;
258 else if (bad)
return 0;
263 {
eDest.Say(
"Config exporting ",
XPList.Path(n)); n += 2;}
268 if (!(xp =
XPList.Next()) && !n)
269 {
XPList.Insert(
"/tmp"); n = 8;
270 eDest.Say(
"Config warning: only '/tmp' will be exported.");
272 while(xp) {
eDest.Say(
"Config exporting ", xp->
Path(i));
273 n += i+2; xp = xp->
Next();
279 bP = tmp = (
char *)malloc(n);
281 {strcpy(bP,
XPList.Path(i)); bP += i, *bP++ =
' ';}
283 while(xp) {strcpy(bP, xp->
Path(i)); bP += i; *bP++ =
' '; xp = xp->
Next();}
289 if (!ConfigSecurity(xrootdEnv, pi->
ConfigFN))
return 0;
308 if (theMon) xrootdEnv.
PutPtr(
"XrdMonRoll*", theMon);
314 if (!ConfigMon(pi, xrootdEnv))
return 0;
318 if (!ConfigFS(xrootdEnv, pi->
ConfigFN))
return 0;
333 {
TRACE(
DEBUG,
"Loading dig filesystem builtin");
335 if (!
digFS)
eDest.Emsg(
"Config",
"Unable to load digFS; "
336 "remote debugging disabled!");
350 eDest.Emsg(
"Config", tP->
text,
"checksum is not natively supported.");
355 if (csNum) csList +=
',';
372 if (!RDLPath.empty())
373 {
for (
int i = 0; i < (int)RDLPath.size(); i++)
374 {
const char* parm = (RDLParm[i].length() ? RDLParm[i].c_str() : 0);
375 if (!ConfigRedirPI(RDLPath[i].c_str(),xrootdEnv,pi->
ConfigFN,parm))
387 if (!(asyncFlags & asDebug) &&
as_aioOK)
391 if (!
as_aioOK)
eDest.Say(
"Config asynchronous I/O has been disabled!");
407 eDest.Say(
"Config sendfile has been disabled by ", why);
420 ProtStack.Set(n, 60*60);
430 sprintf(buff,
"%%s://%s:%d/&L=%%d&U=%%s", pi->
myName, pi->
Port);
437 if ((rdf = getenv(
"XRDREDIRECT"))
438 && (!strcmp(rdf,
"R") || !strcmp(rdf,
"M")))
451 eDest.Say(
"Config warning: 'redirect client' ignored; "
452 "not a redirector nor a proxy server");
459 char buff[2048], puff[1024];
463 else sprintf(puff,
"%%%s:%d",
Route[k].Host[1],
Route[k].
Port[1]);
464 sprintf(buff,
" to %s:%d%s",
Route[k].Host[0],
Route[k].
Port[0],puff);
465 eDest.Say(
"Config redirect static ", xp->
Path(), buff);
472 const char *cgi1, *cgi2;
473 char buff[2048], puff[1024], xCgi[RD_Num] = {0};
474 if (
isRedir) {cgi1 =
"+"; cgi2 = getenv(
"XRDCMSCLUSTERID");}
475 else {cgi1 =
""; cgi2 = pi->
myName;}
476 myCNlen = snprintf(buff,
sizeof(buff),
"%s%s", cgi1, cgi2);
481 else sprintf(puff,
"%%%s:%d",
Route[k].Host[1],
Route[k].
Port[1]);
482 sprintf(buff,
" to %s:%d%s",
Route[k].Host[0],
Route[k].
Port[0],puff);
483 eDest.Say(
"Config redirect enoent ", xp->
Path(), buff);
484 if (!xCgi[k] && cgi2)
485 {
bool isdup =
Route[k].Host[0] ==
Route[k].Host[1]
487 for (i = 0; i < 2; i++)
488 {n = snprintf(buff,
sizeof(buff),
"%s?tried=%s%s",
489 Route[k].Host[i], cgi1, cgi2);
490 free(
Route[k].Host[i]);
Route[k].Host[i] = strdup(buff);
491 Route[k].RDSz[i] = n;
492 if (isdup) {
Route[k].Host[1] =
Route[k].Host[0];
493 Route[k].RDSz[1] = n;
break;
538 {
const char *penv = getenv(
"XRDXROOTD_PROXY");
539 if (!penv || *penv !=
'=')
541 eDest.Say(
"Config warning: 'fsoverload bypass' ignored; "
542 "not a forwarding proxy.");
568#define TS_Xeq(x,m) (!strcmp(x,var)) GoNo = m(Config)
569#define TS_Zeq(x,m) (!strcmp(x,var)) GoNo = m(&eDest, Config)
571int XrdXrootdProtocol::Config(
const char *ConfigFN)
576 int cfgFD, GoNo, NoGo = 0, ismine;
580 if ((cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
581 return eDest.Emsg(
"Config", errno,
"open config file", ConfigFN);
582 Config.Attach(cfgFD);
586 static const char *cvec[] = {
"*** xroot protocol config:", 0 };
587 Config.Capture(cvec);
591 while((var = Config.GetMyFirstWord()))
592 {
if ((ismine = !strncmp(
"xrootd.", var, 7)) && var[7]) var += 7;
593 else if ((ismine = !strcmp(
"all.export", var))) var += 4;
594 else if ((ismine = !strcmp(
"all.seclib", var))) var += 4;
597 {
if TS_Xeq(
"async", xasync);
598 else if TS_Xeq(
"bindif", xbif);
599 else if TS_Xeq(
"chksum", xcksum);
600 else if TS_Xeq(
"diglib", xdig);
601 else if TS_Xeq(
"export", xexp);
602 else if TS_Xeq(
"fslib", xfsl);
603 else if TS_Xeq(
"fsoverload", xfso);
604 else if TS_Xeq(
"gpflib", xgpf);
605 else if TS_Xeq(
"log", xlog);
606 else if TS_Xeq(
"mongstream", xmongs);
607 else if TS_Xeq(
"monitor", xmon);
609 else if TS_Xeq(
"prep", xprep);
610 else if TS_Xeq(
"redirect", xred);
611 else if TS_Xeq(
"redirlib", xrdl);
612 else if TS_Xeq(
"seclib", xsecl);
613 else if TS_Xeq(
"tls", xtls);
614 else if TS_Xeq(
"tlsreuse", xtlsr);
615 else if TS_Xeq(
"trace", xtrace);
616 else if TS_Xeq(
"limit", xlimit);
617 else {
if (!strcmp(var,
"pidpath"))
618 {
eDest.Say(
"Config warning: 'xrootd.pidpath' no longer "
619 "supported; use 'all.pidpath'.");
621 eDest.Say(
"Config warning: ignoring unknown "
622 "directive '", var,
"'.");
627 if (GoNo) {Config.Echo(); NoGo = 1;}
637 {
eDest.Say(
"Config failure: unable to setup TLS for protocol!");
640 static const char *sessID =
"xroots";
657int XrdXrootdProtocol::CheckTLS(
const char *tlsProt)
677 {
eDest.Say(
"Config Authentication protocol(s)", tlsProt,
678 " require TLS; login now requires TLS.");
686 {
eDest.Say(
"Config failure: unable to honor TLS requirement; "
687 "TLS not configured!");
700bool XrdXrootdProtocol::ConfigFS(
XrdOucEnv &xEnv,
const char *cfn)
709 XrdOucString csList(1024);
712 if (csList.length()) csList +=
' ';
713 csList.append(tP->
text);
716 if (csList.length()) xEnv.
Put(
"csList", csList.c_str());
722 {
TRACE(
DEBUG,
"Loading base filesystem library " <<FSLib[0]);
733 {
eDest.Emsg(
"Config",
"Unable to load base file system using", fsLoc);
736 if (FSLib[0])
osFS->EnvInfo(&xEnv);
740 if (FSLib[1] && !ConfigFS(FSLib[1], xEnv, cfn))
return false;
744 if ((n = FSLPath.size()))
745 for (
int i = 0; i < n; i++)
746 {
if (!ConfigFS(FSLPath[i].c_str(), xEnv, cfn))
return false;}
759bool XrdXrootdProtocol::ConfigFS(
const char *path,
XrdOucEnv &xEnv,
765 TRACE(
DEBUG,
"Loading wrapper filesystem library " <<path);
768 {
eDest.Emsg(
"Config",
"Unable to load file system wrapper from", path);
771 osFS->EnvInfo(&xEnv);
779bool XrdXrootdProtocol::ConfigRedirPI(
const char *path,
XrdOucEnv &xEnv,
780 const char *cfn,
const char *parms)
785 TRACE(
DEBUG,
"Loading redirect plugin library " <<path);
794int XrdXrootdProtocol::ConfigSecurity(
XrdOucEnv &xEnv,
const char *cfn)
823 {
eDest.Say(
"Config warning: 'xrootd.seclib' not specified;"
824 " strong authentication disabled!");
825 xEnv.
PutPtr(
"XrdSecGetProtocol*", (
void *)0);
826 xEnv.
PutPtr(
"XrdSecProtector*" , (
void *)0);
832 TRACE(
DEBUG,
"Loading security library " <<SecLib);
837 (strcmp(SecLib,
"default") ? SecLib : 0),
839 {
eDest.Emsg(
"Config",
"Unable to load security system.");
845 xEnv.
PutPtr(
"XrdSecGetProtocol*", (
void *)secGetProt);
846 xEnv.
PutPtr(
"XrdSecProtector*" , (
void *)
DHS);
850 const char *tlsProt =
CIA->protTLS();
851 if (tlsProt)
return CheckTLS(tlsProt);
897 int V_force=-1, V_syncw = -1, V_off = -1, V_mstall = -1, V_nosf = -1;
898 int V_limit=-1, V_msegs=-1, V_mtot=-1, V_minsz=-1, V_segsz=-1;
899 int V_minsf=-1, V_debug=-1, V_noca=-1, V_tmo=-1;
901 struct asyncopts {
const char *opname;
int minv;
int *oploc;
902 const char *opmsg;} asopts[] =
904 {
"Debug", -1, &V_debug,
""},
905 {
"force", -1, &V_force,
""},
906 {
"off", -1, &V_off,
""},
907 {
"nocache", -1, &V_noca,
""},
908 {
"nosf", -1, &V_nosf,
""},
909 {
"syncw", -1, &V_syncw,
""},
910 {
"limit", 0, &V_limit,
"async limit"},
911 {
"segsize", 4096, &V_segsz,
"async segsize"},
912 {
"timeout", 0, &V_tmo,
"async timeout"},
913 {
"maxsegs", 0, &V_msegs,
"async maxsegs"},
914 {
"maxstalls", 0, &V_mstall,
"async maxstalls"},
915 {
"maxtot", 0, &V_mtot,
"async maxtot"},
916 {
"minsfsz", 1, &V_minsf,
"async minsfsz"},
917 {
"minsize", 4096, &V_minsz,
"async minsize"}};
918 int numopts =
sizeof(asopts)/
sizeof(
struct asyncopts);
920 if (!(val = Config.GetWord()))
921 {
eDest.Emsg(
"Config",
"async option not specified");
return 1;}
924 {
for (i = 0; i < numopts; i++)
925 if (!strcmp(val, asopts[i].opname))
926 {
if (asopts[i].minv >= 0 && !(val = Config.GetWord()))
927 {
eDest.Emsg(
"Config",
"async",(
char *)asopts[i].opname,
928 "value not specified");
931 if (asopts[i].minv > 0)
933 (
long long)asopts[i].minv))
return 1;
934 else *asopts[i].oploc = (int)llp;
935 else if (asopts[i].minv == 0)
938 else *asopts[i].oploc = ppp;
939 else *asopts[i].oploc = 1;
943 eDest.Emsg(
"Config",
"Warning, invalid async option", val);
944 val = Config.GetWord();
949 if (V_limit > 0 && V_mtot > 0 && V_limit > V_mtot)
950 {
eDest.Emsg(
"Config",
"async limit may not be greater than maxtot");
957 {i =
BPool->Recalc(V_segsz);
958 if (!i) {
eDest.Emsg(
"Config",
"async segsize is too large");
return 1;}
961 sprintf(buff,
"%d readjusted to %d", V_segsz, i);
962 eDest.Emsg(
"Config",
"async segsize", buff);
971 if (V_tmo < 1) i = 1;
972 else if (V_tmo > 360) i = 360;
975 sprintf(buff,
"%d readjusted to %d", V_tmo, i);
976 eDest.Emsg(
"Config",
"async timeout", buff);
990 if (V_debug > 0) asyncFlags |= asDebug;
994 if (V_noca > 0) asyncFlags |= asNoCache;
995 if (V_nosf > 0)
as_nosf =
true;
1024 XrdOucString bSpec[2];
1025 char *bHost[2], *val, buff[512];
1026 int bPort[2], thePort;
1031 {
if (bifResp[1] != bifResp[0]) free(bifResp[1]);
1041 while((val = Config.GetWord()) && *val)
1042 {
if (!xred_php(val, bHost, bPort,
"bindif",
true))
return 1;
1043 for (
int i = 0; i < 2 && bHost[i] != 0; i++)
1045 snprintf(buff,
sizeof(buff),
"%s%s:%d",
1046 (bSpec[i].length() ?
"," :
""), bHost[i], thePort);
1053 for (
int i = 0; i < 2 && bSpec[i].
length(); i++)
1054 {
int n = brSize + bSpec[i].
length() + 1;
1057 memset(bifRec, 0, n);
1060 strcpy(((
char *)bifRec)+brSize, bSpec[i].c_str());
1067 if (bifResp[0] && bifResp[1] == 0)
1098 static XrdOucProg *theProg = 0;
1099 int (*Proc)(XrdOucStream *,
char **, int) = 0;
1100 XrdOucTList *tP, *algFirst = 0, *algLast = 0;
1101 char *palg, prog[2048];
1102 int jmax = 4, anum[2] = {0,0};
1107 while ((palg = Config.GetWord()) && *palg !=
'/')
1108 {
if (!strcmp(palg,
"chkcgi")) {
JobCKCGI = 1;
continue;}
1109 if (strcmp(palg,
"max"))
1111 XrdOucTList *xalg =
new XrdOucTList(palg, anum); anum[0]++;
1112 if (algLast) algLast->next = xalg;
1113 else algFirst = xalg;
1117 if (!(palg = Config.GetWord()))
1118 {
eDest.Emsg(
"Config",
"chksum max not specified");
return 1;}
1125 {
eDest.Emsg(
"Config",
"chksum algorithm not specified");
return 1;}
1138 {
int n = strlen(palg);
1139 if (n+2 >= (
int)
sizeof(prog))
1140 {
eDest.Emsg(
"Config",
"cksum program too long");
return 1;}
1141 strcpy(prog, palg); palg = prog+n; *palg++ =
' '; n =
sizeof(prog)-n-1;
1142 if (!Config.GetRest(palg, n))
1143 {
eDest.Emsg(
"Config",
"cksum parameters too long");
return 1;}
1150 else {
JobLCL = 1; Proc = &CheckSum; strcpy(prog,
"chksum");}
1154 if (!theProg) theProg =
new XrdOucProg(0);
1155 if (theProg->
Setup(prog, &
eDest, Proc))
return 1;
1157 if (jmax)
JobCKS =
new XrdXrootdJob(
Sched, theProg,
"chksum", jmax);
1178 char parms[4096], *val;
1182 if (!(val = Config.GetWord()))
1183 {
eDest.Emsg(
"Config",
"diglib not specified");
return 1;}
1187 if (strcmp(val,
"*"))
1188 {
eDest.Emsg(
"Config",
"builtin diglib not specified");
return 1;}
1192 if (!Config.GetRest(parms,
sizeof(parms)))
1193 {
eDest.Emsg(
"Config",
"diglib parameters too long");
return 1;}
1194 if (digParm) free(digParm);
1195 digParm = strdup(parms);
1217 char *val, pbuff[1024];
1222 val = Config.GetWord();
1223 if (!val || !val[0])
1224 {
eDest.Emsg(
"Config",
"export path not specified");
return 1;}
1225 strlcpy(pbuff, val,
sizeof(pbuff));
1229 while((val = Config.GetWord()))
1231 else if (!strcmp(
"lock", val)) popt &= ~XROOTDXP_NOLK;
1233 else {Config.RetToken();
break;}
1238 return xexpdo(pbuff, popt);
1243int XrdXrootdProtocol::xexpdo(
char *path,
int popt)
1253 {
if (*(path+1) ==
'?') popt &= ~XROOTDXP_NOCGI;
1254 else {
eDest.Emsg(
"Config",
"invalid export path -",path);
return 1;}
1262 if (rpCheck(path, &opaque))
1263 {
eDest.Emsg(
"Config",
"non-absolute export path -", path);
return 1;}
1267 if (!(xopt = Squash(path)) || xopt != (popt|
XROOTDXP_OK))
1268 XPList.Insert(path, popt);
1300 if (!(val = Config.GetWord()))
1301 {
eDest.Emsg(
"Config",
"fslib not specified");
return 1;}
1305 if (!strcmp(
"++", val))
1306 {
if (!(val = Config.GetWord()))
1307 {
eDest.Emsg(
"Config",
"fslib wrapper not specified");
return 1;}
1308 if (strcmp(
"throttle", val)) FSLPath.push_back((std::string)val);
1309 else FSLPath.push_back(
"libXrdThrottle.so");
1315 if (FSLib[0]) {free(FSLib[0]); FSLib[0] = 0;}
1316 if (FSLib[1]) {free(FSLib[1]); FSLib[1] = 0;}
1320 if (!strcmp(
"throttle", val))
1321 {FSLib[1] = strdup(
"libXrdThrottle.so");
1322 if (!(val = Config.GetWord()))
1323 {
eDest.Emsg(
"Config",
"fslib throttle target library not specified");
1326 return xfsL(Config, val, 0);
1331 if (xfsL(Config, val, 1))
return 1;
1332 if (!FSLib[1])
return 0;
1336 if (!(val = Config.GetWord()))
1337 {FSLib[0] = FSLib[1]; FSLib[1] = 0;
1343 return xfsL(Config, val, 0);
1348int XrdXrootdProtocol::xfsL(
XrdOucStream &Config,
char *val,
int lix)
1354 if (!strcmp(val,
"-2"))
1355 {
if (!(val = Config.GetWord()))
1356 {
eDest.Emsg(
"Config",
"fslib not specified");
return 1;}
1362 if (!strcmp(
"default", val))
return 0;
1367 if (!(Slash = rindex(val,
'/'))) Slash = val;
1369 if (!strcmp(Slash,
"libXrdOfs.so"))
1370 eDest.Say(
"Config warning: 'fslib libXrdOfs.so' is actually built-in.");
1371 else FSLib[lix] = strdup(val);
1395 static const int rHLen = 264;
1396 char rHost[2][rHLen], *hP[2] = {0,0}, *val;
1397 int rPort[2], bypass = -1, stall = -1;
1401 while((val = Config.GetWord()) && *val)
1402 {
if (!strcmp(val,
"bypass")) bypass = 1;
1403 else if (!strcmp(val,
"nobypass")) bypass = 0;
1404 else if (!strcmp(val,
"redirect"))
1405 {val = Config.GetWord();
1406 if (!xred_php(val, hP, rPort,
"redirect"))
return 1;
1407 for (
int i = 0; i < 2; i++)
1408 {
if (!hP[i]) rHost[i][0] = 0;
1409 else {
strlcpy(rHost[i], hP[i], rHLen);
1414 else if (!strcmp(val,
"stall"))
1415 {
if (!(val = Config.GetWord()) || !(*val))
1416 {
eDest.Emsg(
"Config",
"stall value not specified");
1422 else {
eDest.Emsg(
"config",
"invalid fsoverload option",val);
return 1;}
1427 if (bypass >= 0)
OD_Bypass = (bypass ? true :
false);
1430 {
if (
Route[RD_ovld].Host[0]) free(
Route[RD_ovld].Host[0]);
1431 if (
Route[RD_ovld].Host[1]) free(
Route[RD_ovld].Host[1]);
1432 Route[RD_ovld].Host[0] = strdup(hP[0]);
1433 Route[RD_ovld].Port[0] = rPort[0];
1434 Route[RD_ovld].RDSz[0] = strlen(hP[0]);
1436 {
Route[RD_ovld].Host[1] = strdup(hP[1]);
1437 Route[RD_ovld].Port[1] = rPort[1];
1438 Route[RD_ovld].RDSz[1] = strlen(hP[1]);
1440 Route[RD_ovld].Host[1] =
Route[RD_ovld].Host[0];
1441 Route[RD_ovld].Port[1] =
Route[RD_ovld].Port[0];
1442 Route[RD_ovld].RDSz[1] =
Route[RD_ovld].RDSz[0];
1466 char parms[4096], *val;
1470 if (gpfLib) {free(gpfLib); gpfLib = 0;}
1471 if (gpfParm) {free(gpfParm); gpfParm = 0;}
1475 if (!(val = Config.GetWord()))
1476 {
eDest.Emsg(
"Config",
"gpflib not specified");
return 1;}
1480 if (strcmp(val,
"default")) gpfLib = strdup(val);
1484 if (!Config.GetRest(parms,
sizeof(parms)))
1485 {
eDest.Emsg(
"Config",
"gpflib parameters too long");
return 1;}
1486 gpfParm = strdup(parms);
1509 static struct logopts {
const char *opname;
int opval;} lgopts[] =
1515 int i, neg, lgval = -1, numopts =
sizeof(lgopts)/
sizeof(
struct logopts);
1517 if (!(val = Config.GetWord()))
1518 {
eDest.Emsg(
"config",
"log option not specified");
return 1;}
1520 {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
1521 for (i = 0; i < numopts; i++)
1522 {
if (!strcmp(val, lgopts[i].opname))
1523 {
if (neg) lgval &= ~lgopts[i].opval;
1524 else lgval |= lgopts[i].opval;
1528 if (i >= numopts)
eDest.Emsg(
"config",
"invalid log option",val);
1529 val = Config.GetWord();
1531 eDest.setMsgMask(lgval);
1550{
int rc, keep = 0, scrub=0;
1551 char *ldir=0,*val,buff[1024];
1553 if (!(val = Config.GetWord()))
1554 {
eDest.Emsg(
"Config",
"prep options not specified");
return 1;}
1556 do {
if (!strcmp(
"keep", val))
1557 {
if (!(val = Config.GetWord()))
1558 {
eDest.Emsg(
"Config",
"prep keep value not specified");
1563 else if (!strcmp(
"scrub", val))
1564 {
if (!(val = Config.GetWord()))
1565 {
eDest.Emsg(
"Config",
"prep scrub value not specified");
1570 else if (!strcmp(
"logdir", val))
1571 {
if (!(ldir = Config.GetWord()))
1572 {
eDest.Emsg(
"Config",
"prep logdir value not specified");
1576 else eDest.Emsg(
"Config",
"Warning, invalid prep option", val);
1577 }
while((val = Config.GetWord()));
1586 {
eDest.Emsg(
"Config", rc,
"process logdir", ldir);
1616 if (!(val = Config.GetWord()))
1617 {
eDest.Emsg(
"Config",
"redirlib path not specified");
return 1;}
1621 if (!strcmp(
"++", val))
1622 {
if (!(val = Config.GetWord()))
1623 {
eDest.Emsg(
"Config",
"redrilib wrapper not specified");
return 1;}
1624 if (RDLPath.empty())
1625 {
eDest.Emsg(
"Config",
"base redrilib not specified");
return 1;}
1626 if (*val ==
'+' && !(val = xrdlopt(Config, val)))
return 1;
1627 RDLPath.push_back((std::string)val);
1628 if (!Config.GetRest(pbuff,
sizeof(pbuff)))
1629 {
eDest.Emsg(
"Config",
"redirlib parameters too long");
return 1;}
1630 RDLParm.push_back((std::string)pbuff);
1632 }
else if (*val ==
'+' && !(val = xrdlopt(Config, val)))
return 1;
1636 if (RDLPath.empty()) RDLPath.push_back((std::string)val);
1637 else RDLPath[0] = val;
1641 if (!Config.GetRest(pbuff,
sizeof(pbuff)))
1642 {
eDest.Emsg(
"Config",
"redirlib parameters too long");
return 1;}
1643 if (RDLParm.empty()) RDLParm.push_back((std::string)pbuff);
1644 else RDLParm[0] = pbuff;
1655char* XrdXrootdProtocol::xrdlopt(
XrdOucStream &Config,
char* val)
1661do{
if (!strcmp(val,
"+iphold"))
1662 {
if (!(val = Config.GetWord()))
1663 {
eDest.Emsg(
"Config",
"+iphold value not specified");
return 0;}
1667 }
while((val = Config.GetWord()) && *val ==
'+');
1703 static struct rediropts {
const char *opname; RD_func opval;} rdopts[] =
1705 {
"chmod", RD_chmod},
1706 {
"chksum", RD_chksum},
1707 {
"dirlist", RD_dirlist},
1708 {
"locate", RD_locate},
1709 {
"mkdir", RD_mkdir},
1711 {
"openw", RD_openw},
1712 {
"prepare", RD_prepare},
1713 {
"prepstage",RD_prepstg},
1715 {
"rmdir", RD_rmdir},
1719 static const int rHLen = 264;
1720 char rHost[2][rHLen], *hP[2], *val;
1721 int i, k, neg, numopts =
sizeof(rdopts)/
sizeof(
struct rediropts);
1722 int rPort[2], isQ = 0;
1726 val = Config.GetWord();
1727 if (!xred_php(val, hP, rPort,
"redirect"))
return 1;
1731 for (i = 0; i < 2; i++)
1732 {
if (!hP[i]) rHost[i][0] = 0;
1733 else {
strlcpy(rHost[i], hP[i], rHLen);
1740 if (!(val = Config.GetWord()))
1741 {
eDest.Emsg(
"config",
"redirect option not specified");
return 1;}
1745 if (!strcmp(
"client", val))
return xred_clnt(Config, hP, rPort);
1747 if (*val ==
'/' || (isQ = ((*val ==
'?') || !strcmp(val,
"enoent"))))
1750 if (!(val = Config.GetWord()))
1751 {
eDest.Emsg(
"Config",
"redirect path not specified.");
1755 {
eDest.Emsg(
"Config",
"non-absolute redirect path -", val);
1759 for (k =
static_cast<int>(RD_open1); k < RD_Num; k++)
1760 if (xred_xok(k, hP, rPort))
break;
1762 {
eDest.Emsg(
"Config",
"too many different path redirects");
return 1;}
1763 xred_set(RD_func(k), hP, rPort);
1764 do {
if (isQ)
RQList.Insert(val, k, 0);
1765 else RPList.Insert(val, k, 0);
1766 if ((val = Config.GetWord()) && *val !=
'/')
1767 {
eDest.Emsg(
"Config",
"non-absolute redirect path -", val);
1775 {
if (!strcmp(val,
"all"))
1776 {
for (i = 0; i < numopts; i++)
1777 xred_set(rdopts[i].opval, hP, rPort);
1779 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
1780 for (i = 0; i < numopts; i++)
1781 {
if (!strcmp(val, rdopts[i].opname))
1782 {
if (neg) xred_set(rdopts[i].opval, 0, 0);
1783 else xred_set(rdopts[i].opval, hP, rPort);
1788 eDest.Emsg(
"config",
"invalid redirect option", val);
1790 val = Config.GetWord();
1797int XrdXrootdProtocol::xred_clnt(
XrdOucStream &Config,
char *hP[2],
int rPort[2])
1799 static const int maxDom =
sizeof(
RouteClient.Domain)/
sizeof(
char*);
1808 for (
int i = 0; i < maxDom; i++)
RouteClient.Domain[i] = 0;
1816 if (!(val = Config.GetWord()))
1817 {
eDest.Emsg(
"Config",
"redirect client argument not specified.");
1822 {
if (!strcmp(
"private", val))
RouteClient.pvtIP =
true;
1823 else if (!strcmp(
"local", val))
RouteClient.lclDom =
true;
1824 else if (*val ==
'.')
1826 {
eDest.Emsg(
"Config",
1827 "Too many redirect client domains specified.");
1832 else {
eDest.Emsg(
"Config",
"Invalid redirect client domain -", val);
1835 val = Config.GetWord();
1840 xred_set(RD_client, hP, rPort);
1846bool XrdXrootdProtocol::xred_php(
char *val,
char *hP[2],
int rPort[2],
1847 const char *what,
bool optport)
1849 XrdNetAddr testAddr;
1854 if (!val || !(*val))
1855 {
eDest.Emsg(
"config", what,
"argument not specified");
return false;}
1860 if (!(pp = index(val,
'%'))) hP[1] = 0;
1861 else {hP[1] = pp+1; *pp = 0;}
1865 if (!(*val) || (hP[1] && !*hP[1]))
1866 {
eDest.Emsg(
"Config",
"malformed", what,
"host specification");
1872 for (
int i = 0; i < 2; i++)
1873 {
if (!(val = hP[i]))
break;
1874 if (!val || !val[0] || val[0] ==
':')
1875 {
eDest.Emsg(
"Config", what,
"host not specified");
return false;}
1876 if ((pp = rindex(val,
':')))
1881 if (optport) rPort[i] = 0;
1882 else {
eDest.Emsg(
"Config", what,
"port not specified");
1886 const char *eText = testAddr.
Set(val, 0);
1889 eDest.Say(
"Config warning: ", eText,
" as ", val);
1890 else {
eDest.Say(
"Config failure: ", what,
" target ", val,
1891 " is invalid; ", eText);
1902void XrdXrootdProtocol::xred_set(RD_func func,
char *rHost[2],
int rPort[2])
1907 if (
Route[func].Host[0]) free(
Route[func].Host[0]);
1908 if (
Route[func].Host[0] !=
Route[func].Host[1]) free(
Route[func].Host[1]);
1911 {
Route[func].Host[0] = strdup(rHost[0]);
1912 Route[func].Port[0] = rPort[0];
1914 Route[func].Host[0] =
Route[func].Host[1] = 0;
1915 Route[func].Port[0] =
Route[func].Port[1] = 0;
1923 Route[func].Host[1] = strdup(rHost[1]);
1924 Route[func].Port[1] = rPort[1];
1928bool XrdXrootdProtocol::xred_xok(
int func,
char *rHost[2],
int rPort[2])
1930 if (!
Route[func].Host[0])
return true;
1932 if (strcmp(
Route[func].Host[0], rHost[0])
1933 ||
Route[func].
Port[0] != rPort[0])
return false;
1935 if (!rHost[1])
return Route[func].Host[0] ==
Route[func].Host[1];
1937 if (strcmp(
Route[func].Host[1], rHost[1])
1938 ||
Route[func].
Port[1] != rPort[1])
return false;
1963 val = Config.GetWord();
1964 if (!val || !val[0])
1965 {
eDest.Emsg(
"Config",
"seclib argument not specified");
return 1;}
1969 if (SecLib) free(SecLib);
1970 SecLib = strdup(val);
2004 static struct enforceopts {
const char *opname;
int opval;
int enval;}
2015 int i, numopts =
sizeof(enfopts)/
sizeof(
struct enforceopts);
2016 bool neg, forall =
true;
2018 if (!(val = Config.GetWord()))
2019 {
eDest.Emsg(
"config",
"tls parameter not specified");
return 1;}
2021 if (!strcmp(
"capable", val))
2023 if (!(val = Config.GetWord()))
2024 {
eDest.Emsg(
"config",
"tls requirement not specified");
return 1;}
2028 {
if (!strcmp(val,
"off") || !strcmp(val,
"none"))
2033 if ((neg = (val[0] ==
'-' && val[1]))) val++;
2034 for (i = 0; i < numopts; i++)
2035 {
if (!strcmp(val, enfopts[i].opname))
2036 {
if (neg)
myRole &= ~enfopts[i].opval;
2037 else myRole |= enfopts[i].opval;
2038 if (neg)
tlsCap &= ~enfopts[i].enval;
2039 else tlsCap |= enfopts[i].enval;
2041 {
if (neg)
tlsNot &= ~enfopts[i].enval;
2042 else tlsNot |= enfopts[i].enval;
2048 {
eDest.Emsg(
"config",
"Invalid tls requirement -", val);
2052 val = Config.GetWord();
2066 return (CheckTLS(0) ? 0 : 1);
2092 val = Config.GetWord();
2093 if (!val || !val[0])
2094 {
eDest.Emsg(
"Config",
"tlsreuse argument not specified");
return 1;}
2098 if (!strcmp(val,
"off"))
2105 if (!strcmp(val,
"on"))
2106 {
if (!
tlsCtx) {
eDest.Emsg(
"Config warning:",
"Ignoring "
2107 "'tlsreuse on'; TLS not configured!");
2111 if (!(val = Config.GetWord()))
return 0;
2112 if (!strcmp(val,
"flush" ))
2113 {
if (!(val = Config.GetWord()))
2114 {
eDest.Emsg(
"Config",
"tlsreuse flush value not specified");
2118 if (num < 60) num = 60;
2127 eDest.Emsg(
"config",
"Invalid tlsreuse option -", val);
2148 static struct traceopts {
const char *opname;
int opval;} tropts[] =
2165 int i, neg, trval = 0, numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
2167 if (!(val = Config.GetWord()))
2168 {
eDest.Emsg(
"config",
"trace option not specified");
return 1;}
2170 {
if (!strcmp(val,
"off")) trval = 0;
2171 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
2172 for (i = 0; i < numopts; i++)
2173 {
if (!strcmp(val, tropts[i].opname))
2174 {
if (neg) trval &= ~tropts[i].opval;
2175 else trval |= tropts[i].opval;
2180 eDest.Emsg(
"config",
"invalid trace option", val);
2182 val = Config.GetWord();
2211 while ( (word = Config.GetWord()) ) {
2212 if (!strcmp(word,
"prepare")) {
2213 if (!(word = Config.GetWord()))
2215 eDest.Emsg(
"Config",
"'limit prepare' value not specified");
2219 }
else if (!strcmp(word,
"noerror")) {
static XrdSysLogger Logger
static XrdSysError eDest(0,"crypto_")
XrdSfsFileSystem * XrdDigGetFS(XrdSfsFileSystem *native_fs, XrdSysLogger *lp, const char *cFN, const char *parms)
XrdSfsFileSystem * XrdSfsGetDefaultFileSystem(XrdSfsFileSystem *native_fs, XrdSysLogger *lp, const char *configfn, XrdOucEnv *EnvInfo)
XrdSecProtocol *(* XrdSecGetProt_t)(const char *hostname, XrdNetAddrInfo &endPoint, XrdSecParameters §oken, XrdOucErrInfo *einfo)
Typedef to simplify the encoding of methods returning XrdSecProtocol.
XrdSecService * XrdSecLoadSecService(XrdSysError *eDest, const char *cfn, const char *seclib, XrdSecGetProt_t *getP, XrdSecProtector **proP)
XrdSysTrace XrdXrootdTrace
const char * XrdXrootdInstance
XrdXrootdPrepare * XrdXrootdPrepQ
XrdSfsFileSystem * XrdXrootdloadFileSystem(XrdSysError *, XrdSfsFileSystem *, const char *, const char *, XrdOucEnv *)
XrdSfsFileSystem * XrdSfsGetDefaultFileSystem(XrdSfsFileSystem *nativeFS, XrdSysLogger *Logger, const char *configFn, XrdOucEnv *EnvInfo)
XrdXrootdRedirPI * XrdXrootdloadRedirLib(XrdSysError *, XrdXrootdRedirPI *, const char *, const char *, const char *, XrdOucEnv *)
XrdOucString * XrdXrootdCF
static bool isHostName(const char *name)
const char * Set(const char *hSpec, int pNum=PortInSpec)
void Display(const char *pfx="=====> ")
static int Parse(XrdSysError *eLog, XrdOucStream &Config)
static XrdNetPMark * Config(XrdSysError *eLog, XrdScheduler *sched, XrdSysTrace *trc, bool &fatal)
static XrdNetSocket * Create(XrdSysError *Say, const char *path, const char *fn, mode_t mode, int isudp=0)
long GetInt(const char *varname)
char * Get(const char *varname)
static int Export(const char *Var, const char *Val)
void * GetPtr(const char *varname)
void PutPtr(const char *varname, void *value)
void Put(const char *varname, const char *value)
int Setup(const char *prog, XrdSysError *errP=0, int(*Proc)(XrdOucStream *, char **, int)=0)
const char * c_str() const
static const mode_t pathMode
static char * genPath(const char *path, const char *inst, const char *psfx=0)
static int GidName(gid_t gID, char *gName, int gNsz, time_t keepT=0)
static int UidName(uid_t uID, char *uName, int uNsz, time_t keepT=0)
static int makePath(char *path, mode_t mode, bool reset=false)
static void toLower(char *str)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
static int a2p(XrdSysError &, const char *ptype, const char *val, bool anyOK=true)
XrdSysLogger * logger(XrdSysLogger *lp=0)
XrdTlsContext * Clone(bool full=true, bool startCRLRefresh=false)
int SessionCache(int opts=scNone, const char *id=0, int idlen=0)
static const int scNone
Do not change any option settings.
static const int scOff
Turn off cache.
static const int scSrvr
Turn on cache server mode (default).
static int Init(XrdSysError *erp, XrdNetSocket *asock)
static void addJob(const char *jname, XrdXrootdJob *jp)
static void setVals(XrdSysError *erp, XrdXrootdStats *SIp, XrdScheduler *schp, int port)
static void Init(XrdXrootdFileLock *lp, XrdSysError *erP, bool sfok)
static int setParms(int stime, int skeep)
static XrdXrootdStats * SI
static const char * myInst
static XrdSfsFileSystem * digFS
static XrdNetPMark * PMark
static short as_okstutter
static XrdXrootdXPath RPList
static XrdNetSocket * AdminSock
static const char Req_TLSGPFile
static const char Req_TLSSess
static XrdXrootdJob * JobCKS
static XrdSysError & eDest
static XrdXrootdRedirPI * RedirPI
static const char * myCName
static const char Req_TLSData
static XrdXrootdFileLock * Locker
static const char Req_TLSTPC
static XrdTlsContext * tlsCtx
static XrdXrootdXPath XPList
static XrdScheduler * Sched
static struct XrdXrootdProtocol::RC_Table RouteClient
static const char * myUName
static const char Req_TLSLogin
static int Configure(char *parms, XrdProtocol_Config *pi)
static XrdOucTList * JobCKTLST
static XrdXrootdXPath RQList
static struct XrdXrootdProtocol::RD_Table Route[RD_Num]
static XrdSecProtector * DHS
static XrdBuffManager * BPool
static XrdSecService * CIA
static const char * myGName
static uint64_t fsFeatures
static XrdOucReqID * PrepID
static XrdSfsFileSystem * osFS
static void Init(XrdXrootdRedirPI *pi, XrdSysError *eDest, int ipHold)
static void Init(XrdScheduler *schedP, int qMax, int qTTL)
Perform one-time initialization.
struct ServerResponseBifs_Protocol bifReqs
static const int maxRvecsz
static const uint64_t hasPGRW
Feature: pgRead and pgWrite.
static const uint64_t hasPRP2
Feature: Prepare Handler Version 2 (different calling conventions).
static const uint64_t hasGPFA
Feature: gpFile anonymous.
static const uint64_t hasCACH
Feature: Implements a data cache.
static const uint64_t hasNOSF
Feature: Supports no sendfile.
static const uint64_t hasPOSC
Feature: Persist On Successful Close.
static const uint64_t hasGPF
Feature: gpFile.
static const uint64_t hasNAIO
Feature: Supports no async I/O.
static const uint64_t hasPRXY
Feature: Proxy Server.