XRootD
XrdPssUrlInfo.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d P s s U r l I n f o . c c */
4 /* */
5 /* (c) 2018 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 <iostream>
32 #include <cstring>
33 
34 #include "XrdOuc/XrdOucEnv.hh"
35 #include "XrdOuc/XrdOucSid.hh"
36 #include "XrdOuc/XrdOucTPC.hh"
37 #include "XrdPss/XrdPssUrlInfo.hh"
38 #include "XrdPss/XrdPssUtils.hh"
39 #include "XrdSec/XrdSecEntity.hh"
40 
41 /******************************************************************************/
42 /* S t a t i c M e m b e r s */
43 /******************************************************************************/
44 
45 bool XrdPssUrlInfo::MapID = false;
46 
47 /******************************************************************************/
48 /* c o p y C G I */
49 /******************************************************************************/
50 
51 namespace
52 {
53 int copyCGI(const char *cgi, char *Buff, int Blen)
54 {
55  int n;
56 
57  if (!cgi) {*Buff = 0; return 0;}
58 
59 // Skip over initial ampersands
60 //
61  while(*cgi == '&' && *cgi) cgi++;
62 
63 // Check if there is anything here
64 //
65  if (*cgi == 0) {*Buff = 0; return 0;}
66 
67 // Copy out all variables omitting the ones that cause trouble
68 //
69  char *bP = Buff;
70  const char *beg = cgi;
71  do {if (!strncmp(cgi, "xrd.", 4) || !strncmp(cgi, "xrdcl.", 6))
72  {int n = cgi - beg - 1;
73  if (n > 0)
74  {if (n >= Blen) {*bP = 0; return bP - Buff;}
75  strncpy(bP, beg, n);
76  bP += n; Blen -= n; *bP = 0;
77  }
78  if ((beg = index(cgi, '&')))
79  {cgi = beg+1;
80  if (bP == Buff) beg++;
81  }
82  } else {
83  if ((cgi = index(cgi, '&'))) cgi++;
84  }
85  } while(beg && cgi);
86 
87 // See if we have the end to copy
88 //
89  if (beg)
90  {n = strlen(beg) + 1;
91  if (n < Blen)
92  {strncpy(bP, beg, Blen);
93  bP += n;
94  }
95  }
96 
97 // Return length make sure buffer ends with a null
98 //
99  *bP = 0;
100 //std::cerr <<"PSS cgi OT: '" <<Buff <<"' " <<(bP-Buff) <<'\n' <<std::flush;
101  return bP - Buff;
102 }
103 }
104 
105 /******************************************************************************/
106 /* C o n s t r u c t o r */
107 /******************************************************************************/
108 
110  const char *xtra, bool addusrcgi, bool addident)
111  : Path(path), CgiUsr(""), CgiUsz(0), CgiSsz(0), sidP(0),
112  eIDvalid(false)
113 {
114  const char *amp1= "", *amp2 = "";
115 
116 // Preset for no id in the url
117 //
118  *theID = 0;
119  tident = 0;
120 
121 // If there is an environment point, get user's cgi and set the tident from it
122 //
123  if (envP)
124  {if (addusrcgi && !(CgiUsr = envP->Env(CgiUsz))) CgiUsr = "";
125  const XrdSecEntity *secP = envP->secEnv();
126  if (secP)
127  {entityID = secP->ueid;
128  eIDvalid = true;
129  tident = secP->tident;
130  }
131  }
132 
133 // Make sure we have a tident
134 //
135  if (!tident) tident = "unk.0:0@host";
136 
137 // Generate additional cgi information as needed
138 //
139  if (*xtra && *xtra != '&') amp2 = "&";
140  if (CgiUsz) amp1 = "&";
141 
142  if (addident)
143  {CgiSsz = snprintf(CgiSfx, sizeof(CgiSfx),
144  "%spss.tid=%s%s%s", amp1, tident, amp2, xtra);
145  } else {
146  if (*xtra) CgiSsz = snprintf(CgiSfx, sizeof(CgiSfx), "%s%s", amp1, xtra);
147  else *CgiSfx = 0;
148  }
149 }
150 
151 /******************************************************************************/
152 /* a d d C G I */
153 /******************************************************************************/
154 
155 bool XrdPssUrlInfo::addCGI(const char *prot, char *buff, int blen)
156 {
157  bool forXrd = XrdPssUtils::is4Xrootd(prot);
158 
159 // Short circuit all of this if there is no cgi
160 //
161  if (!CgiUsz && (!CgiSsz || forXrd))
162  {*buff = 0;
163  return true;
164  }
165 
166 // Make sure that we can fit whatever CGI we have into the buffer. Include the
167 // implicit question mark and ending null byte.
168 //
169  int n = CgiUsz + (forXrd ? CgiSsz : 0) + 1;
170  if (n >= blen) return false;
171  *buff++ = '?'; blen--;
172 
173 // If the protocol is headed to an xroot server then we need to remove any
174 // offending CGI elements from the user CGI. Otherwise, we can use the CGI
175 // that was specified by the client.
176 //
177  if (CgiUsz)
178  {if (forXrd) n = copyCGI(CgiUsr, buff, blen);
179  else {n = CgiUsz;
180  strcpy(buff, CgiUsr);
181  }
182  buff += n; blen -= n;
183  }
184 
185 // If this is destined to an xroot server, add any extended CGI.
186 //
187  if (forXrd && CgiSsz)
188  {if (CgiSsz >= blen) return false;
189  strcpy(buff, CgiSfx);
190  } else *buff = 0;
191 
192 // All done
193 //
194 //std::cerr <<"Final URL: '" <<prot <<"' " <<strlen(prot) <<'\n' <<std::flush;
195  return true;
196 }
197 
198 /******************************************************************************/
199 /* E x t e n d */
200 /******************************************************************************/
201 
202 bool XrdPssUrlInfo::Extend(const char *cgi, int cgiln)
203 {
204  const char *amp = (*cgi == '&' ? "" : "&");
205  int blen = sizeof(CgiSfx) - CgiSsz;
206 
207  if (blen <= cgiln) return false;
208  int n = snprintf(&CgiSfx[CgiSsz], blen, "%s%s", amp, cgi);
209  if (n >= blen) return false;
210  CgiSsz += n;
211  return true;
212 }
213 
214 /******************************************************************************/
215 /* s e t I D */
216 /******************************************************************************/
217 
218 void XrdPssUrlInfo::setID(const char *tid)
219 {
220  const char *atP, *colon;
221 
222 // If we are mapping id then use the entity's idenification
223 //
224  if (MapID && eIDvalid)
225  {const char *fmt = (entityID & 0xf0000000 ? "%x@" : "U%x@");
226  snprintf(theID, sizeof(theID), fmt, entityID); // 8+1+nul = 10 bytes
227  return;
228  }
229 
230 // Use the connection file descriptor number as the id lgnid.pid:fd@host
231 //
232  if (tid == 0) tid = tident;
233  if ((colon = index(tid, ':')) && (atP = index(colon+1, '@')))
234  {int n = atP - colon;
235  if (n <= (int)sizeof(theID))
236  {*theID = 'u';
237  strncpy(theID+1, colon+1, n); // Include '@'
238  theID[n+1] = 0;
239  } else *theID = 0;
240  } else *theID = 0;
241 }
XrdOucString Path
const XrdSecEntity * secEnv() const
Definition: XrdOucEnv.hh:107
char * Env(int &envlen)
Definition: XrdOucEnv.hh:48
XrdPssUrlInfo(XrdOucEnv *envP, const char *path, const char *xtra="", bool addusrcgi=true, bool addident=true)
bool Extend(const char *cgi, int cgiln)
void setID(const char *tid=0)
bool addCGI(const char *prot, char *buff, int blen)
static bool is4Xrootd(const char *pname)
Definition: XrdPssUtils.cc:68
const char * tident
Trace identifier always preset.
Definition: XrdSecEntity.hh:81
unsigned int ueid
Unique ID of entity instance.
Definition: XrdSecEntity.hh:79
XrdOucSid * sidP
Definition: XrdPss.cc:107
XrdOucEnv * envP
Definition: XrdPss.cc:109