XRootD
Loading...
Searching...
No Matches
XrdOfsTPCAuth.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O f s T P C A u t h . c c */
4/* */
5/* (c) 2012 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 <cstdio>
32#include <cstdlib>
33#include <strings.h>
34
35#include "XrdOfs/XrdOfsStats.hh"
40#include "XrdSys/XrdSysError.hh"
41#include "XrdSys/XrdSysTimer.hh"
42
43/******************************************************************************/
44/* G l o b a l O b j e c t s */
45/******************************************************************************/
46
49
50namespace XrdOfsTPCParms
51{
52extern XrdOfsTPCConfig Cfg;
53}
54using namespace XrdOfsTPCParms;
55
56/******************************************************************************/
57/* S t a t i c V a r i a b l e s */
58/******************************************************************************/
59
60XrdSysMutex XrdOfsTPCAuth::authMutex;
61XrdOfsTPCAuth *XrdOfsTPCAuth::authQ = 0;
62
63/******************************************************************************/
64/* E x t e r n a l L i n k a g e s */
65/******************************************************************************/
66
67void *XrdOfsTPCAuthttl(void *pp)
68{
70 return (void *)0;
71}
72
73/******************************************************************************/
74/* A d d */
75/******************************************************************************/
76
78{
79 XrdOfsTPCAuth *aP;
80 const char *eMsg;
81 char Buff[512];
82
83// Generate the origin information
84//
85 if (!genOrg(Args.Usr, Buff, sizeof(Buff))) return Fatal(Args, Buff, EINVAL);
86 Args.Org = Buff;
87
88// Check if there is a matching authorization in the queue. If this is for a
89// pending authorization, indicated that we now have one. Otherwise, consider
90// this a potential security breach and cancel both autorizations.
91//
92 authMutex.Lock();
93 if ((aP = Find(Args)))
94 {if (aP->Info.cbP)
95 {aP->expT = expT;
96 aP->Next = authQ; authQ = aP;
97 aP->Info.Reply(SFS_OK, 0, "", &authMutex);
98 return 1;
99 } else {
100 authMutex.UnLock();
101 return Fatal(Args, "duplicate athorization", EPROTO);
102 }
103 }
104
105// Set the copy authorization information
106//
107 if ((eMsg = Info.Set(Args.Key, Buff, Args.Lfn, Args.Dst)))
108 {
109 authMutex.UnLock();
110 return Fatal(Args, eMsg, EINVAL);
111 }
112
113// Add this to queue
114//
115 Next = authQ; authQ = this; inQ = 1;
116
117// All done
118//
119 authMutex.UnLock();
120 return 1;
121}
122
123/******************************************************************************/
124/* D e l */
125/******************************************************************************/
126
128{
129 XrdOfsTPCAuth *pP;
130
131// Remove from queue if we are still in the queue
132//
133 authMutex.Lock();
134 if (inQ)
135 {if (this == authQ) authQ = Next;
136 else {pP = authQ;
137 while(pP && pP->Next != this) pP = pP->Next;
138 if (pP) pP->Next = Next;
139 }
140 inQ = 0;
141 }
142
143// Delete the element if possible
144//
145 if (Refs <= 1) delete this;
146 else Refs--;
147 authMutex.UnLock();
148}
149
150/******************************************************************************/
151/* E x p i r e d */
152/******************************************************************************/
153
154int XrdOfsTPCAuth::Expired(const char *Dst, int cnt)
155{
156 char Buff[1024];
157
158// If there is a callback, tell the client they are no longer wanted
159//
160 if (Info.cbP) Info.Reply(SFS_ERROR, EACCES, "tpc authorization expired");
161
162// Log this event
163//
164 snprintf(Buff, sizeof(Buff), "tpc grant by %s expired for", Info.Org);
165 Buff[sizeof(Buff)-1] = 0;
166 OfsEroute.Emsg("TPC", Dst, Buff, Info.Lfn);
167
168// Count stats and return
169//
171 return 0;
172}
173
174/******************************************************************************/
175/* Private: F i n d */
176/******************************************************************************/
177
178XrdOfsTPCAuth *XrdOfsTPCAuth::Find(XrdOfsTPC::Facts &Args)
179{
180 XrdOfsTPCAuth *cP, *pP = 0;
181
182// Find matching entry
183//
184 cP = authQ;
185 while(cP && !(cP->Info.Match(Args.Key, Args.Org, Args.Lfn, Args.Dst)))
186 {pP = cP; cP = cP->Next;}
187
188// Remove from queue if found
189//
190 if (cP) {if (pP) pP->Next = cP->Next;
191 else authQ = cP->Next;
192 cP->inQ = 0;
193 }
194
195// Return result
196//
197 return cP;
198}
199
200/******************************************************************************/
201/* G e t */
202/******************************************************************************/
203
205{
206 XrdSysMutexHelper authMon(&authMutex);
207 XrdOfsTPCAuth *aP;
208 const char *eMsg;
209
210// Check if there is a matching authorization in the queue. If this is for a
211// pending authorization, then consider this a potential security breach and
212// cancel both requests. Otherwise, indicate that authorization is present.
213//
214 if ((aP = Find(Args)))
215 {if (aP->Info.cbP)
216 {aP->Info.Reply(SFS_ERROR, EPROTO, "duplicate tpc auth request");
217 return Fatal(Args, "duplicate tpc auth request", EPROTO);
218 } else {
219 aP->Refs++;
220 *theTPC = aP;
221 return SFS_OK;
222 }
223 }
224
225// Add this request as a pending authorization to the queue
226//
227 if (!(aP = new XrdOfsTPCAuth(Cfg.maxTTL)))
228 return Fatal(Args, "insufficient memory", ENOMEM);
229
230// Set the copy authorization information
231//
232 if ((eMsg = aP->Info.Set(Args.Key, Args.Org, Args.Lfn, Args.Dst)))
233 {delete aP;
234 return Fatal(Args, eMsg, EINVAL);
235 }
236
237// Create a callback
238//
239 if (aP->Info.SetCB(Args.eRR)) {delete aP; return SFS_ERROR;}
240
241// Add it to the queue
242//
243 aP->Next = authQ; authQ = aP;
244
245// Return result
246//
247 *theTPC = aP;
248 aP->Refs = 0;
249 aP->Info.Engage();
250 return SFS_STARTED;
251}
252
253/******************************************************************************/
254/* R u n T T L */
255/******************************************************************************/
256
258{
259 XrdOfsTPCAuth *cP, *pP, *nP;
260 time_t eNow;
261 int eWait, eDiff, numExp;
262
263// Start the expiration thread
264//
265 if (Init)
266 {pthread_t tid;
267 int rc;
268 if ((rc = XrdSysThread::Run(&tid,XrdOfsTPCAuthttl,0,0,"TPC ttl runner")))
269 OfsEroute.Emsg("TPC", rc, "create tpc ttl runner thread");
270 return (rc ? 0 : 1);
271 }
272
273// Find all expired entries and remove them
274//
275do{authMutex.Lock();
276 cP = authQ; pP = 0;
277 eNow = time(0); eWait = Cfg.maxTTL; numExp = 0;
278 while(cP)
279 {if (eNow < cP->expT)
280 {eDiff = cP->expT - eNow;
281 if (eDiff < eWait) eWait = eDiff;
282 pP = cP; cP = cP->Next;
283 }
284 else {if (pP) pP->Next = cP->Next;
285 else authQ = cP->Next;
286 cP->Expired("localhost", 0); numExp++;
287 nP = cP->Next;
288 if (cP->Refs < 1) delete cP;
289 cP = nP;
290 }
291 }
292 authMutex.UnLock();
293
294// Add number of expirations to statistics
295//
296 if (numExp)
298 OfsStats.Data.numTPCexpr += numExp;
300 }
301
302// Wait as long as possible for a recan
303//
304 XrdSysTimer::Snooze(eWait);
305 } while(1);
306}
void * XrdOfsTPCAuthttl(void *pp)
XrdOfsStats OfsStats
Definition XrdOfs.cc:113
XrdSysError OfsEroute
XrdSysError OfsEroute(0)
XrdOfsStats OfsStats
Definition XrdOfs.cc:113
#define eMsg(x)
#define SFS_ERROR
#define SFS_STARTED
#define SFS_OK
struct XrdOfsStats::StatsData Data
void Add(int &Cntr)
XrdSysMutex sdMutex
static int Get(Facts &Args, XrdOfsTPCAuth **theTPC)
int Add(Facts &Args)
static int RunTTL(int Init)
XrdOucCallBack * cbP
const char * Set(const char *cKey, const char *cOrg, const char *xLfn, const char *xDst, const char *xCks=0)
void Reply(int rC, int eC, const char *eMsg, XrdSysMutex *mP=0)
static void Init()
Definition XrdOfsTPC.cc:414
static int Fatal(Facts &Args, const char *eMsg, int eCode, int nomsg=0)
Definition XrdOfsTPC.cc:334
XrdOfsTPCInfo Info
Definition XrdOfsTPC.hh:109
static int genOrg(const XrdSecEntity *client, char *Buff, int Blen)
Definition XrdOfsTPC.cc:359
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static void Snooze(int seconds)
XrdOfsTPCConfig Cfg
Definition XrdOfsTPC.cc:85
const XrdSecEntity * Usr
Definition XrdOfsTPC.hh:57
const char * Key
Definition XrdOfsTPC.hh:52
const char * Org
Definition XrdOfsTPC.hh:55
const char * Lfn
Definition XrdOfsTPC.hh:53
XrdOucErrInfo * eRR
Definition XrdOfsTPC.hh:58
const char * Dst
Definition XrdOfsTPC.hh:56