XRootD
Loading...
Searching...
No Matches
XrdSecsssEnt.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S e c s s s E n t . c c */
4/* */
5/* (c) 2020 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 "XrdOuc/XrdOucPup.hh"
32#include "XrdOuc/XrdOucUtils.hh"
40
41using namespace XrdSecsssMap;
42
43/******************************************************************************/
44/* L o c a l C l a s s e s */
45/******************************************************************************/
46
47namespace
48{
49class copyAttrs : public XrdSecEntityAttrCB
50{
51public:
52
53XrdSecEntityAttrCB::Action Attr(const char *key, const char *val)
54 {if (!key) return XrdSecEntityAttrCB::Stop;
55 if (calcSz)
56 {bL += strlen(key) + strlen(val) + 8;
57 } else {
59 XrdOucPup::Pack(&bP,key);
61 XrdOucPup::Pack(&bP,val);
62 }
64 }
65char *bP;
66int bL;
67bool calcSz;
68
69 copyAttrs() : bP(0), bL(0), calcSz(false) {}
70 ~copyAttrs() {}
71};
72}
73
74/******************************************************************************/
75/* S t a t i c M e m b e r s */
76/******************************************************************************/
77
78char *XrdSecsssEnt::myHostName = 0;
79int XrdSecsssEnt::myHostNLen = 0;
80
81/******************************************************************************/
82/* A d d C o n t a c t */
83/******************************************************************************/
84
85void XrdSecsssEnt::AddContact(const std::string &hostID)
86{
87// If we are tracking connections then add this one to the set. We use the
88// fact that a set can only have one instance of a member and ignores dups.
89//
90 if (conTrack) Contacts.insert(hostID);
91}
92
93/******************************************************************************/
94/* D e l e t e */
95/******************************************************************************/
96
98{
99// Invoke the cleanup call back if there is something to clean up
100//
101 if (conTrack && Contacts.size()) conTrack->Cleanup(Contacts, *eP);
102
103// Now we can delete ourselves
104//
105 delete this;
106}
107
108/******************************************************************************/
109/* R R _ D a t a */
110/******************************************************************************/
111
112int XrdSecsssEnt::RR_Data(char *&dP, const char *hostIP, int dataOpts)
113{
114 char *bP;
115 int cpyLen, totLen = XrdSecsssRR_Data_HdrLen;
116 int n = 0;
117
118// If we have not yet serialized the data, do so now.
119//
120 if (!eData && !Serialize()) return 0;
121
122// Compute the length we will need for the buffer (it must be exact)
123//
124 if (dataOpts & v2Client)
125 {cpyLen = tLen;
126 if (dataOpts & addCreds) cpyLen += credLen;
127 } else cpyLen = iLen;
128 totLen += cpyLen;
129
130// Add in the hostIP if specified and hostname if available
131//
132 n = strlen(hostIP) + 4;
133 if (hostIP) totLen += n;
134 totLen += myHostNLen;
135
136// Allocate a buffer
137//
138 if (!(dP = (char *)malloc(totLen))) return 0;
139 bP = dP + XrdSecsssRR_Data_HdrLen;
140
141// The first thing in the serialized packet is the host IP
142//
143 if (hostIP)
145 XrdOucPup::Pack(&bP, hostIP);
146 }
147
148// The next thing is to addthe hostname for backward compatibility
149//
150 if (myHostName)
151 {memcpy(bP, myHostName, myHostNLen); bP += myHostNLen;}
152
153// Copy the remaining data
154//
155 memcpy(bP, eData, cpyLen);
156
157// Return length of the whole thing
158//
159 return totLen;
160}
161
162/******************************************************************************/
163/* Private: S e r i a l i z e */
164/******************************************************************************/
165
166bool XrdSecsssEnt::Serialize()
167{
168 copyAttrs theAttr;
169 char *bP, rBuff[XrdSecsssRR_Data::MinDSz], uName[256], gName[256];
170 int n, rLen = 0;
171 bool incCreds = false;
172
173// Make sure we have an entity here
174//
175 if (!eP) return false;
176
177// Perform some initialization here
178//
179 *uName = 0;
180 *gName = 0;
181
182// Calculate the length needed for the entity (4 bytes overhead for each item)
183// These items ae always sent to all servers.
184//
185 iLen = (eP->name ? strlen(eP->name) + 4 : 0)
186 + (eP->vorg ? strlen(eP->vorg) + 4 : 0)
187 + (eP->role ? strlen(eP->role) + 4 : 0)
188 + (eP->grps ? strlen(eP->grps) + 4 : 0)
189 + (eP->caps ? strlen(eP->caps) + 4 : 0)
190 + (eP->endorsements ? strlen(eP->endorsements) + 4 : 0);
191
192// The above is always sent to V1 servers and it can't be too short
193//
196 {rLen = XrdSecsssRR_Data::MinDSz - n;
197 XrdSecsssKT::genKey(rBuff, rLen);
198 if (!rBuff[0]) rBuff[0] = 0xff;
199 iLen += rLen + 4;
200 }
201
202// Now, compute the size of all extra stuff we will be sending. Note that
203// V1 servers will ignore them but we might exceed their maximum buffer size
204// if we do, so we never send this information.
205//
206 tLen = iLen;
207 theAttr.calcSz = true;
208 eP->eaAPI->List(theAttr);
209 theAttr.calcSz = false;
210 tLen += theAttr.bL;
211
212// Add in the length authnetication protocol (original)
213//
214 tLen += strlen(eP->prot) + 4;
215
216// Add in the length of the traceID that we will send
217//
218 if (eP->tident) tLen += strlen(eP->tident) + 4;
219
220// If the underlying protocol is not sss then it may replace the username
221// and group name which determines the uid and gid. Otherwise, those are
222// extracted from the keyfile by the server. This only applies if a uid
223// or gid was enetered in the SecEntity object in the first place.
224//
225 if (*(eP->prot) && strcmp("sss", eP->prot))
226 {if (eP->uid && !XrdOucUtils::UserName( eP->uid, uName, sizeof(uName)))
227 tLen += strlen(uName) + 4;
228 else *uName = 0;
229 if (eP->gid && XrdOucUtils::GroupName(eP->gid, gName, sizeof(gName)))
230 tLen += strlen(gName) + 4;
231 else *gName = 0;
232 }
233
234// At the end we attach the credentials if they are not too large. The data
235// must be at the end because it can optionally be pruned when returned.
236//
238 {tLen += eP->credslen + 3;
239 incCreds = true;
240 }
241
242// If no identity information, return failure otherwise allocate a struct
243//
244 if (!tLen || !(eData = (char *)malloc(tLen))) return 0;
245
246// Now stick each entry into the iData field
247//
248 bP = eData;
249 if (eP->name)
251 if (eP->vorg)
253 if (eP->role)
255 if (eP->grps)
257 if (eP->caps)
259 if (eP->endorsements)
261 if (rLen)
262 {*bP++ = XrdSecsssRR_Data::theRand; XrdOucPup::Pack(&bP, rBuff, rLen);}
263 iLen = bP - eData;
264
265// Add the underlying security protocol
266//
267 if (*(eP->prot))
269
270// Add the trace ident
271//
272 if (eP->tident)
274
275// Add the user name if present
276//
277 if (*uName)
278 {*bP++ = XrdSecsssRR_Data::theUser; XrdOucPup::Pack(&bP,uName);}
279
280// Add the group name if present
281//
282 if (*gName)
283 {*bP++ = XrdSecsssRR_Data::theGrup; XrdOucPup::Pack(&bP,gName);}
284
285// Add additional attributes. The buffer is gauranteed to be big enough.
286//
287 if (theAttr.bL > 0)
288 {theAttr.bP = bP;
289 eP->eaAPI->List(theAttr);
290 bP = theAttr.bP;
291 }
292
293// Compue total length
294//
295 tLen = bP - eData;
296
297// Attach the credentials if we must
298//
299 if (incCreds)
301 credLen = XrdOucPup::Pack(&bP, eP->creds, eP->credslen) + 1;
302 } else credLen = 0;
303
304// All done
305//
306 return true;
307}
308
309/******************************************************************************/
310/* s e t H o s t N a m e */
311/******************************************************************************/
312
313void XrdSecsssEnt::setHostName(const char *hnP)
314{
315 char *bP;
316 int n = strlen(hnP);
317
318// The host name always goes into the serialized data. So, we prepack it here.
319//
320 if (n)
321 {if (myHostName) free(myHostName);
322 myHostName = bP = (char *)malloc(n+4);
324 myHostNLen = XrdOucPup::Pack(&bP, hnP) + 1;
325 }
326}
static const int XrdSecsssRR_Data_HdrLen
static int Pack(struct iovec **, const char *, unsigned short &buff)
Definition XrdOucPup.cc:52
static int UserName(uid_t uID, char *uName, int uNsz)
static int GroupName(gid_t gID, char *gName, int gNsz)
@ Stop
Stop the iteration.
@ Next
Proceed to the next key-value pair.
virtual Action Attr(const char *key, const char *val)=0
void List(XrdSecEntityAttrCB &attrCB)
char * vorg
Entity's virtual organization(s)
int credslen
Length of the 'creds' data.
XrdSecEntityAttr * eaAPI
non-const API to attributes
const char * tident
Trace identifier always preset.
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
char * caps
Entity's capabilities.
char * creds
Raw entity credentials or cert.
gid_t gid
Unix gid or 0 if none.
char * grps
Entity's group name(s)
uid_t uid
Unix uid or 0 if none.
char * name
Entity's name.
char * role
Entity's role(s)
char * endorsements
Protocol specific endorsements.
virtual void Cleanup(const std::set< std::string > &Contacts, const XrdSecEntity &Entity)=0
void Delete()
Delete this entity object.
static void setHostName(const char *hnP)
static const int v2Client
Data for a v2 client wanted.
void AddContact(const std::string &hostID)
static const int addCreds
Add v2 data plus creds.
int RR_Data(char *&dP, const char *hostIP, int dataOpts)
static void genKey(char *Buff, int blen)
XrdSecsssCon * conTrack
static const char theHost
static const int MaxCSz
static const char theUser
static const char theAKey
static const char theCaps
static const char theAuth
static const char theRole
static const char theName
static const int MinDSz
static const char theGrps
static const char theRand
static const char theEndo
static const char theAVal
static const char theVorg
static const char theGrup
static const char theTID
static const char theCred