XRootD
Loading...
Searching...
No Matches
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"
38#include "XrdPss/XrdPssUtils.hh"
40
41/******************************************************************************/
42/* S t a t i c M e m b e r s */
43/******************************************************************************/
44
45bool XrdPssUrlInfo::MapID = false;
46
47/******************************************************************************/
48/* c o p y C G I */
49/******************************************************************************/
50
51namespace
52{
53int 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
155bool 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
202bool 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
218void 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}
char * Env(int &envlen)
Definition XrdOucEnv.hh:48
const XrdSecEntity * secEnv() const
Definition XrdOucEnv.hh:107
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)
const char * tident
Trace identifier always preset.
unsigned int ueid
Unique ID of entity instance.