diff --git a/src/XrdOfs/XrdOfsTPC.cc b/src/XrdOfs/XrdOfsTPC.cc index d9cc892af05..4aea576dcfc 100644 --- a/src/XrdOfs/XrdOfsTPC.cc +++ b/src/XrdOfs/XrdOfsTPC.cc @@ -582,6 +582,7 @@ int XrdOfsTPC::Validate(XrdOfsTPC **theTPC, XrdOfsTPC::Facts &Args) const char *tpcLfn = Args.Env->Get(XrdOucTPC::tpcLfn); const char *tpcSrc = Args.Env->Get(XrdOucTPC::tpcSrc); const char *tpcCks = Args.Env->Get(XrdOucTPC::tpcCks); + const char *tpcSgi = Args.Env->Get(XrdOucTPC::tpcSgi); const char *tpcStr = Args.Env->Get(XrdOucTPC::tpcStr); const char *tpcSpr = Args.Env->Get(XrdOucTPC::tpcSpr); const char *tpcTpr = Args.Env->Get(XrdOucTPC::tpcTpr); @@ -635,20 +636,39 @@ int XrdOfsTPC::Validate(XrdOfsTPC **theTPC, XrdOfsTPC::Facts &Args) // Generate the origin id // - if (!genOrg(Args.Usr, Buff, sizeof(Buff))) return Death(Args, Buff, EINVAL); + if (!enVar && !genOrg(Args.Usr, Buff, sizeof(Buff))) + return Death(Args, Buff, EINVAL); // Construct the source url (it may be very big) // n = snprintf(myURL, myURLen, "xroot://%s/%s?", tpcSrc, tpcLfn); - if (n >= int(sizeof(myURL))) return Death(Args, "url too long", EINVAL); + char *cgiP = myURL+n; + int cgiL = myURLen-n; + if (cgiL < 3) return Death(Args, "url too long", EINVAL); // Set lfn location in the URL but only if we need to do a rename // if (doRN) {lfnLoc[1] = strlen(tpcLfn); lfnLoc[0] = n - lfnLoc[1];} else lfnLoc[1] = lfnLoc[0] = 0; - theCGI = XrdOucTPC::cgiD2Src(Args.Key, Buff, myURL+n, myURLen-n); - if (*theCGI == '!') return Death(Args, theCGI+1, EINVAL); +// Copy user specified CGI into the source URL (omit tpc tokens) +// + if (tpcSgi) + {if ((int)strlen(tpcSgi) >= cgiL) + return Death(Args, "url too long", EINVAL); + n = XrdOucTPC::copyCGI(tpcSgi, cgiP, cgiL); + cgiP += n; + cgiL -= n; + } + +// Insert tpc toksns unless this is a delegated tpc which needs no tokens +// + if (!enVar) + {if (cgiL < 3) return Death(Args, "url too long", EINVAL); + *cgiP++ = '&'; cgiL--; *cgiP = 0; + theCGI = XrdOucTPC::cgiD2Src(Args.Key, Buff, cgiP, cgiL); + if (*theCGI == '!') return Death(Args, theCGI+1, EINVAL); + } // Create a pseudo tpc object that will contain the information we need to // actually peform this copy. diff --git a/src/XrdOfs/XrdOfsTPCProg.cc b/src/XrdOfs/XrdOfsTPCProg.cc index 8b158a35fd8..7d600ba3d25 100644 --- a/src/XrdOfs/XrdOfsTPCProg.cc +++ b/src/XrdOfs/XrdOfsTPCProg.cc @@ -305,13 +305,9 @@ int XrdOfsTPCProg::Xeq() eVec[i++] = sprBuff; } -// Determine if credentials are being passed, If so, we don't need any cgi but -// we must set an envar to point to the file holding the credentials. +// Determine if credentials are being passed, If so, pass where it is. // - if (cFile.Path) - {eVec[i++] = cFile.pEnv; - if (Quest) *Quest = 0; - } + if (cFile.Path) eVec[i++] = cFile.pEnv; eVec[i] = 0; // Start the job. diff --git a/src/XrdOuc/XrdOucTPC.cc b/src/XrdOuc/XrdOucTPC.cc index b462921f6ce..4a8041b2ea5 100644 --- a/src/XrdOuc/XrdOucTPC.cc +++ b/src/XrdOuc/XrdOucTPC.cc @@ -28,6 +28,7 @@ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ +//#include #include #include #include @@ -46,6 +47,7 @@ const char *XrdOucTPC::tpcKey = "tpc.key"; const char *XrdOucTPC::tpcLfn = "tpc.lfn"; const char *XrdOucTPC::tpcOrg = "tpc.org"; const char *XrdOucTPC::tpcPsh = "tpc.psh"; +const char *XrdOucTPC::tpcSgi = "tpc.scgi"; const char *XrdOucTPC::tpcSrc = "tpc.src"; const char *XrdOucTPC::tpcSpr = "tpc.spr"; const char *XrdOucTPC::tpcStr = "tpc.str"; @@ -215,3 +217,50 @@ bool XrdOucTPC::cgiHost(tpcInfo &Info, const char *hSpec) if ((hName = hAddr.Name())) Info.hName = strdup(hName); return hName != 0; } + +/******************************************************************************/ +/* c o p y C G I */ +/******************************************************************************/ + +int XrdOucTPC::copyCGI(const char *cgi, char *Buff, int Blen) +{ + const char *bgi; + char *bP = Buff; + int xlen; + bool eqs; + +// Skip over initial ampersands +// + while(*cgi == '&' && *cgi) cgi++; + +// Check if there is anything here +// + if (!cgi || *cgi == 0) {*Buff = 0; return 0;} + Blen--; + +// Copy all keys except system oriented ones. +// +//std::cerr <<"TPC cgi IN: " < Blen) xlen = Blen; + strncpy(bP, bgi, xlen); + bP += xlen; + Blen -= xlen; + } + while(*cgi && *cgi == '\t') cgi++; + } while(*cgi && Blen > 2); + +// Compute length and return +// + *bP = 0; +// std::cerr <<"TPC cgi OT: " <