XRootD
Loading...
Searching...
No Matches
XrdAccEntity.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d A c c E n t i t y . c c */
4/* */
5/* (c) 2019 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* Produced by Andrew Hanushevsky for Stanford University under contract */
7/* DE-AC02-76-SFO0515 with the Department of Energy */
8/* */
9/* This file is part of the XRootD software suite. */
10/* */
11/* XRootD is free software: you can redistribute it and/or modify it under */
12/* the terms of the GNU Lesser General Public License as published by the */
13/* Free Software Foundation, either version 3 of the License, or (at your */
14/* option) any later version. */
15/* */
16/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19/* License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24/* */
25/* The copyright holder's institutional names and contributor's names may not */
26/* be used to endorse or promote products derived from this software without */
27/* specific prior written permission of the institution or contributor. */
28/******************************************************************************/
29
30#include <cstdio>
31#include <cstring>
32
37#include "XrdSys/XrdSysError.hh"
38
39/******************************************************************************/
40/* S t a t i c M e m b e r s */
41/******************************************************************************/
42
43int XrdAccEntity::accSig = 0;
44
45namespace
46{
48}
49
50/******************************************************************************/
51/* C o n s t r u c t o r */
52/******************************************************************************/
53
54XrdAccEntity::XrdAccEntity(const XrdSecEntity *secP, bool &aOK)
55 : XrdSecAttr(&accSig)
56{
57 EntityAttr attrInfo;
58 int have, want = 0;
59
60// Assume all is going to be well and set our unique id.
61//
62 aOK = true;
63
64// Copy out the various attributes we want to tokenize
65//
66 if (secP->vorg) {vorgInfo = strdup(secP->vorg); want++;}
67 else vorgInfo = 0;
68 if (secP->role) {roleInfo = strdup(secP->role); want++;}
69 else roleInfo = 0;
70 if (secP->grps) {grpsInfo = strdup(secP->grps); want++;}
71 else grpsInfo = 0;
72
73// If there are no attributes, then we are done.
74//
75 if (!want) return;
76
77// If there is zero or one vorg and role then we can accept a short form
78// attribute entry. This provides not only backward compatabilty but also
79// takes care of the common case.
80//
81 if (OneOrZero(vorgInfo, attrInfo.vorg) && OneOrZero(roleInfo, attrInfo.role))
82 {if (grpsInfo)
83 {XrdOucTokenizer grpsLine(grpsInfo);
84 grpsLine.GetLine();
85 while((attrInfo.grup = grpsLine.GetToken()))
86 attrVec.push_back(attrInfo);
87 }
88 if (attrVec.size() == 0) attrVec.push_back(attrInfo);
89 return;
90 }
91
92// Tokenize each of the lists
93//
94 XrdOucTokenizer vorgLine(vorgInfo);
95 if (vorgInfo) vorgLine.GetLine();
96 attrInfo.vorg = 0;
97
98 XrdOucTokenizer roleLine(roleInfo);
99 if (roleInfo) roleLine.GetLine();
100 attrInfo.role = 0;
101
102 XrdOucTokenizer grpsLine(grpsInfo);
103 if (grpsInfo) grpsLine.GetLine();
104 attrInfo.grup = 0;
105
106 while(true)
107 {have = 0;
108 if (vorgInfo && setAttr(vorgLine, attrInfo.vorg)) have++;
109 if (roleInfo && setAttr(roleLine, attrInfo.role)) have++;
110 if (grpsInfo && setAttr(grpsLine, attrInfo.grup)) have++;
111 if (want != have) break;
112 attrVec.push_back(attrInfo);
113 }
114
115// Check if pairing was violated and indicate if so.
116//
117 if (have) aOK = false;
118}
119
120/******************************************************************************/
121/* G e t E n t i t y */
122/******************************************************************************/
123
125{
126 XrdAccEntity *aeP;
127 XrdSecAttr *seP;
128 bool aOK;
129
130// If we already compiled the identity informaion, reuse it.
131//
132 if ((seP = secP->eaAPI->Get(&accSig)))
133 {isNew = false;
134 return static_cast<XrdAccEntity *>(seP);
135 }
136
137// At this point we muxt create a new entity for authorization purposes and
138// return it if all went well. We do not attach it to its SecEntity object as
139// this will be done by the AccEntityInit object upon deletion to avoid
140// race conditions and memory leaks. This allows for parallel processing.
141//
142 isNew = true;
143 aeP = new XrdAccEntity(secP, aOK);
144 if (aOK) return aeP;
145
146// Produce message indicating why we failed (there is only one possible reason)
147//
148 if (eDest)
149 {char eBuff[128];
150 snprintf(eBuff, sizeof(eBuff), "missing attrs in col %d for",
151 static_cast<int>(aeP->attrVec.size()));
152 eDest->Emsg("Entity", "Unable to validate entity;", eBuff,
153 (secP->tident ? secP->tident : "???"));
154 }
155 delete aeP;
156 return 0;
157}
158
159/******************************************************************************/
160/* Private: O n e O r Z e r o */
161/******************************************************************************/
162
163bool XrdAccEntity::OneOrZero(char *src, const char *&dest)
164{
165
166// If there is no source, then we are done
167//
168 if (!src)
169 {dest = 0;
170 return true;
171 }
172
173// Check if source has only one item;
174//
175 while(*src == ' ') src++;
176 char *sP = src;
177 while(*src && *src != ' ') src++;
178 char *eP = src;
179 while(*src == ' ') src++;
180 if (*src) return false;
181 if (*sP) {dest = sP; *eP = 0;}
182 else dest = 0;
183 return true;
184}
185
186/******************************************************************************/
187/* P u t E n t i t y */
188/******************************************************************************/
189
191{
192
193// Add this object to the indicated SecEntity object. There may be one there
194// already if some other thread beat us to the punch (unlike). If there is
195// we simply delete ourselves to avoid a memory leak.
196//
197 if (!secP->eaAPI->Add(*this)) delete this;
198}
199
200/******************************************************************************/
201/* Private: s e t A t t r */
202/******************************************************************************/
203
204bool XrdAccEntity::setAttr(XrdOucTokenizer &tkl, const char *&dest)
205{
206 const char *attr = tkl.GetToken();
207 if (!attr || !dest || strcmp(dest, attr)) dest = attr;
208 return attr != 0;
209}
210
211/******************************************************************************/
212/* s e t E r r o r */
213/******************************************************************************/
214
static XrdSysError eDest(0,"crypto_")
if(ec< 0) ec
static void setError(XrdSysError *errP)
void PutEntity(const XrdSecEntity *secP)
static XrdAccEntity * GetEntity(const XrdSecEntity *secP, bool &isNew)
char * GetToken(char **rest=0, int lowcase=0)
bool Add(XrdSecAttr &attr)
XrdSecAttr * Get(const void *sigkey)
char * vorg
Entity's virtual organization(s)
XrdSecEntityAttr * eaAPI
non-const API to attributes
const char * tident
Trace identifier always preset.
char * grps
Entity's group name(s)
char * role
Entity's role(s)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)