XRootD
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 
33 #include "XrdAcc/XrdAccEntity.hh"
35 #include "XrdSec/XrdSecEntity.hh"
37 #include "XrdSys/XrdSysError.hh"
38 
39 /******************************************************************************/
40 /* S t a t i c M e m b e r s */
41 /******************************************************************************/
42 
43 int XrdAccEntity::accSig = 0;
44 
45 namespace
46 {
47 XrdSysError *eDest = 0;
48 }
49 
50 /******************************************************************************/
51 /* C o n s t r u c t o r */
52 /******************************************************************************/
53 
54 XrdAccEntity::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 
163 bool 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 
204 bool 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_")
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)
Definition: XrdSecEntity.hh:71
XrdSecEntityAttr * eaAPI
non-const API to attributes
Definition: XrdSecEntity.hh:92
const char * tident
Trace identifier always preset.
Definition: XrdSecEntity.hh:81
char * grps
Entity's group name(s)
Definition: XrdSecEntity.hh:73
char * role
Entity's role(s)
Definition: XrdSecEntity.hh:72
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95