XRootD
XrdAccAccess Class Reference

#include <XrdAccAccess.hh>

+ Inheritance diagram for XrdAccAccess:
+ Collaboration diagram for XrdAccAccess:

Public Member Functions

 XrdAccAccess (XrdSysError *erp)
 
 ~XrdAccAccess ()
 
XrdAccPrivs Access (const XrdSecEntity *Entity, const char *path, const Access_Operation oper, XrdOucEnv *Env=0)
 
int Audit (const int accok, const XrdSecEntity *Entity, const char *path, const Access_Operation oper, XrdOucEnv *Env=0)
 
void SwapTabs (struct XrdAccAccess_Tables &newtab)
 
int Test (const XrdAccPrivs priv, const Access_Operation oper)
 
- Public Member Functions inherited from XrdAccAuthorize
 XrdAccAuthorize ()
 Constructor. More...
 
virtual ~XrdAccAuthorize ()
 Destructor. More...
 
virtual XrdAccPrivs Access (const XrdSecEntity *Entity, const char *path, const Access_Operation oper, std::string &eInfo, XrdOucEnv *Env=0)
 

Static Public Member Functions

static const char * Resolve (const XrdSecEntity *Entity)
 

Friends

class XrdAccConfig
 

Detailed Description

Definition at line 127 of file XrdAccAccess.hh.

Constructor & Destructor Documentation

◆ XrdAccAccess()

XrdAccAccess::XrdAccAccess ( XrdSysError erp)

Definition at line 94 of file XrdAccAccess.cc.

95 {
96 // Get the audit option that we should use
97 //
98  Auditor = XrdAccAuditObject(erp);
99 }
XrdAccAudit * XrdAccAuditObject(XrdSysError *erp)
Definition: XrdAccAudit.cc:92

References XrdAccAuditObject().

+ Here is the call graph for this function:

◆ ~XrdAccAccess()

XrdAccAccess::~XrdAccAccess ( )
inline

Definition at line 156 of file XrdAccAccess.hh.

156 {} // The access object is never deleted

Member Function Documentation

◆ Access()

XrdAccPrivs XrdAccAccess::Access ( const XrdSecEntity Entity,
const char *  path,
const Access_Operation  oper,
XrdOucEnv Env = 0 
)
virtual

Check whether or not the client is permitted specified access to a path.

Parameters
Entity-> Authentication information
path-> The logical path which is the target of oper
oper-> The operation being attempted (see the enum above). If the oper is AOP_Any, then the actual privileges are returned and the caller may make subsequent tests using Test().
Env-> Environmental information at the time of the operation as supplied by the path CGI string. This is optional and the pointer may be zero.
Returns
Permit: a non-zero value (access is permitted) Deny: zero (access is denied)

Implements XrdAccAuthorize.

Definition at line 105 of file XrdAccAccess.cc.

109 {
110  XrdAccGroupList *glp;
111  XrdAccPrivCaps caps;
112  XrdAccCapability *cp;
113  XrdAccEntity *aeP;
114  XrdAccEntityInfo eInfo;
115  int plen = strlen(path);
116  long phash = XrdOucHashVal2(path, plen);
117  bool isuser;
118 
119 // Obtain an authorization entity (it will be released upon return).
120 //
121  XrdAccEntityInit accEntity(Entity, aeP);
122  if (!aeP) return Access2(caps, Entity, path, oper);
123 
124 // Setup the id (we don't need a lock for that)
125 //
126  std::string username;
127  auto got_token = Entity->eaAPI->Get("request.name", username);
128  if (got_token && !username.empty())
129  {eInfo.name = username.c_str();
130  isuser = true;
131  }
132  else if (Entity->name)
133  {eInfo.name = Entity->name;
134  isuser = (*eInfo.name != 0);
135  } else {
136  eInfo.name = "*";
137  isuser = false;
138  }
139 
140 // Get a shared context for these potentially long running routines
141 //
142  Access_Context.Lock(xs_Shared);
143 
144 // Setup the host entry in the eInfo structure (it may need to be resolved)
145 //
146  eInfo.host = (hostRefX ? Resolve(Entity) : "?");
147 
148 // Run through the exclusive list first as only one rule will apply
149 //
150  if (Atab.SXList)
151  {XrdAccAccess_ID *xlP = Atab.SXList;
152  do {int aSeq = 0;
153  while(aeP->Next(aSeq, eInfo))
154  {if (xlP->Applies(eInfo))
155  {xlP->caps->Privs(caps, path, plen, phash);
156  Access_Context.UnLock(xs_Shared);
157  return Access2(caps, Entity, path, oper);
158  }
159  }
160  xlP = xlP->next;
161  } while(xlP);
162  }
163 
164 // Check if we really need to resolve the host name
165 //
166 //??? if (Atab.D_List || Atab.H_Hash || Atab.N_Hash) host = Resolve(Entity);
167  if (!hostRefX && hostRefY) eInfo.host = Resolve(Entity);
168 
169 // Establish default privileges
170 //
171  if (Atab.Z_List) Atab.Z_List->Privs(caps, path, plen, phash);
172 
173 // Next add in the host domain privileges
174 //
175  if (Atab.D_List && (cp = Atab.D_List->Find(eInfo.host)))
176  cp->Privs(caps, path, plen, phash);
177 
178 // Next add in the host-specific privileges
179 //
180  if (Atab.H_Hash && (cp = Atab.H_Hash->Find(eInfo.host)))
181  cp->Privs(caps, path, plen, phash);
182 
183 // Now add in the netgroup privileges
184 //
185  if (Atab.N_Hash && *eInfo.host != '?' &&
186  (glp = XrdAccConfiguration.GroupMaster.NetGroups(eInfo.name,eInfo.host)))
187  {char *gname;
188  while((gname = (char *)glp->Next()))
189  if ((cp = Atab.N_Hash->Find((const char *)gname)))
190  cp->Privs(caps, path, plen, phash);
191  delete glp;
192  }
193 
194 // Check for user fungible privileges
195 //
196  if (isuser && Atab.X_List)
197  Atab.X_List->Privs(caps, path, plen, phash, eInfo.name);
198 
199 // Add in specific user privileges
200 //
201  if (isuser && Atab.U_Hash && (cp = Atab.U_Hash->Find(eInfo.name)))
202  cp->Privs(caps, path, plen, phash);
203 
204 // The following privileges are based on multiple attributes. Orgs and roles
205 // may be repeated but groups generally will not be.
206 //
207  const char *vorgPrev = 0, *rolePrev = 0;
208  int aSeq = 0;
209 
210  while(aeP->Next(aSeq, eInfo))
211  {
212  // Add in the group privileges.
213  //
214  if (Atab.G_Hash && eInfo.grup && (cp = Atab.G_Hash->Find(eInfo.grup)))
215  cp->Privs(caps, path, plen, phash);
216 
217  // Add in the org-specific privileges
218  //
219  if (Atab.O_Hash && eInfo.vorg && eInfo.vorg != vorgPrev)
220  {vorgPrev = eInfo.vorg;
221  if ((cp = Atab.O_Hash->Find(eInfo.vorg)))
222  cp->Privs(caps, path, plen, phash);
223  }
224 
225  // Add in the role-specific privileges
226  //
227  if (Atab.R_Hash && eInfo.role && eInfo.role != rolePrev)
228  {rolePrev = eInfo.role;
229  if ((cp = Atab.R_Hash->Find(eInfo.role)))
230  cp->Privs(caps, path, plen, phash);
231  }
232 
233  // Finally run through the inclusive list and apply all relevant rules
234  //
235  XrdAccAccess_ID *ylP = Atab.SYList;
236  while (ylP)
237  {if (ylP->Applies(eInfo))
238  ylP->caps->Privs(caps, path, plen, phash);
239  ylP = ylP->next;
240  }
241  }
242 
243 // We are now done with looking at changeable data
244 //
245  Access_Context.UnLock(xs_Shared);
246 
247 // Return the privileges as needed
248 //
249  return Access2(caps, Entity, path, oper);
250 }
unsigned long XrdOucHashVal2(const char *KeyVal, int KeyLen)
XrdAccConfig XrdAccConfiguration
Definition: XrdAccConfig.cc:61
@ xs_Shared
Definition: XrdSysXSLock.hh:38
static const char * Resolve(const XrdSecEntity *Entity)
XrdAccCapability * Find(const char *name)
int Privs(XrdAccPrivCaps &pathpriv, const char *pathname, const int pathlen, const unsigned long pathhash, const char *pathsub=0)
XrdAccGroups GroupMaster
Definition: XrdAccConfig.hh:79
bool Next(int &seq, XrdAccEntityInfo &info)
Definition: XrdAccEntity.hh:71
const char * Next()
Definition: XrdAccGroups.hh:49
XrdAccGroupList * NetGroups(const char *user, const char *host)
T * Find(const char *KeyVal, time_t *KeyTime=0)
Definition: XrdOucHash.icc:160
XrdSecAttr * Get(const void *sigkey)
XrdSecEntityAttr * eaAPI
non-const API to attributes
Definition: XrdSecEntity.hh:92
char * name
Entity's name.
Definition: XrdSecEntity.hh:69
void Lock(const XrdSysXS_Type usage)
Definition: XrdSysXSLock.cc:55
void UnLock(const XrdSysXS_Type usage=xs_None)
Definition: XrdSysXSLock.cc:95
bool Applies(const XrdAccEntityInfo &Entity)
XrdAccCapability * caps
Definition: XrdAccAccess.hh:54
XrdAccAccess_ID * next
Definition: XrdAccAccess.hh:55
XrdOucHash< XrdAccCapability > * U_Hash
Definition: XrdAccAccess.hh:93
XrdOucHash< XrdAccCapability > * G_Hash
Definition: XrdAccAccess.hh:86
XrdOucHash< XrdAccCapability > * N_Hash
Definition: XrdAccAccess.hh:88
XrdAccCapability * X_List
Definition: XrdAccAccess.hh:96
XrdAccAccess_ID * SXList
Definition: XrdAccAccess.hh:98
XrdAccCapability * Z_List
Definition: XrdAccAccess.hh:97
XrdOucHash< XrdAccCapability > * O_Hash
Definition: XrdAccAccess.hh:89
XrdAccCapName * D_List
Definition: XrdAccAccess.hh:94
XrdOucHash< XrdAccCapability > * H_Hash
Definition: XrdAccAccess.hh:87
XrdOucHash< XrdAccCapability > * R_Hash
Definition: XrdAccAccess.hh:90
XrdAccAccess_ID * SYList
Definition: XrdAccAccess.hh:99
const char * vorg
Definition: XrdAccEntity.hh:44
const char * role
Definition: XrdAccEntity.hh:45
const char * name
Definition: XrdAccEntity.hh:42
const char * host
Definition: XrdAccEntity.hh:43
const char * grup
Definition: XrdAccEntity.hh:46

References XrdAccAccess_ID::Applies(), XrdAccAccess_ID::caps, XrdAccAccess_Tables::D_List, XrdSecEntity::eaAPI, XrdOucHash< T >::Find(), XrdAccCapName::Find(), XrdAccAccess_Tables::G_Hash, XrdSecEntityAttr::Get(), XrdAccConfig::GroupMaster, XrdAccEntityInfo::grup, XrdAccAccess_Tables::H_Hash, XrdAccEntityInfo::host, XrdSysXSLock::Lock(), XrdAccAccess_Tables::N_Hash, XrdAccEntityInfo::name, XrdSecEntity::name, XrdAccGroups::NetGroups(), XrdAccAccess_ID::next, XrdAccGroupList::Next(), XrdAccEntity::Next(), XrdAccAccess_Tables::O_Hash, XrdAccCapability::Privs(), XrdAccAccess_Tables::R_Hash, Resolve(), XrdAccEntityInfo::role, XrdAccAccess_Tables::SXList, XrdAccAccess_Tables::SYList, XrdAccAccess_Tables::U_Hash, XrdSysXSLock::UnLock(), XrdAccEntityInfo::vorg, XrdAccAccess_Tables::X_List, XrdAccConfiguration, XrdOucHashVal2(), xs_Shared, and XrdAccAccess_Tables::Z_List.

+ Here is the call graph for this function:

◆ Audit()

int XrdAccAccess::Audit ( const int  accok,
const XrdSecEntity Entity,
const char *  path,
const Access_Operation  oper,
XrdOucEnv Env = 0 
)
virtual

Route an audit message to the appropriate audit exit routine. See XrdAccAudit.h for more information on how the default implementation works. Currently, this method is not called by the ofs but should be used by the implementation to record denials or grants, as warranted.

Parameters
accok-> True is access was grated; false otherwise.
Entity-> Authentication information
path-> The logical path which is the target of oper
oper-> The operation being attempted (see above)
Env-> Environmental information at the time of the operation as supplied by the path CGI string. This is optional and the pointer may be zero.
Returns
Success: !0 information recorded. Failure: 0 information could not be recorded.

Implements XrdAccAuthorize.

Definition at line 284 of file XrdAccAccess.cc.

289 {
290 // Warning! This table must be in 1-to-1 correspondence with Access_Operation
291 //
292  static const char *Opername[] = {"any", // 0
293  "chmod", // 1
294  "chown", // 2
295  "create", // 3
296  "delete", // 4
297  "insert", // 5
298  "lock", // 6
299  "mkdir", // 7
300  "read", // 8
301  "readdir", // 9
302  "rename", // 10
303  "stat", // 11
304  "update", // 12
305  "excl_create", // 13
306  "excl_insert", // 14
307  "stage", // 15
308  "poll" // 16
309  };
310  const char *opname = (oper > AOP_LastOp ? "???" : Opername[oper]);
311  std::string username;
312  const char *id = "*";
313  auto got_token = Entity->eaAPI->Get("request.name", username);
314  if (got_token && !username.empty()) {
315  id = username.c_str();
316  } else if (Entity->name) id = Entity->name;
317  const char *host = (Entity->host ? (const char *)Entity->host : "?");
318  char atype[XrdSecPROTOIDSIZE+1];
319 
320 // Get the protocol type in a printable format
321 //
322  strncpy(atype, Entity->prot, XrdSecPROTOIDSIZE);
323  atype[XrdSecPROTOIDSIZE] = '\0';
324 
325 // Route the message appropriately
326 //
327  if (accok) Auditor->Grant(opname, Entity->tident, atype, id, host, path);
328  else Auditor->Deny( opname, Entity->tident, atype, id, host, path);
329 
330 // All done, finally
331 //
332  return accok;
333 }
@ AOP_LastOp
#define XrdSecPROTOIDSIZE
Definition: XrdSecEntity.hh:47
virtual void Deny(const char *opname, const char *tident, const char *atype, const char *id, const char *host, const char *path)
Definition: XrdAccAudit.cc:54
virtual void Grant(const char *opname, const char *tident, const char *atype, const char *id, const char *host, const char *path)
Definition: XrdAccAudit.cc:73
const char * tident
Trace identifier always preset.
Definition: XrdSecEntity.hh:81
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
Definition: XrdSecEntity.hh:67
char * host
Entity's host name dnr dependent.
Definition: XrdSecEntity.hh:70

References AOP_LastOp, XrdAccAudit::Deny(), XrdSecEntity::eaAPI, XrdSecEntityAttr::Get(), XrdAccAudit::Grant(), XrdSecEntity::host, XrdSecEntity::name, XrdSecEntity::prot, XrdSecEntity::tident, and XrdSecPROTOIDSIZE.

+ Here is the call graph for this function:

◆ Resolve()

const char * XrdAccAccess::Resolve ( const XrdSecEntity Entity)
static

Definition at line 339 of file XrdAccAccess.cc.

340 {
341 // Make a quick test for IPv6 (as that's the future) and a minimal one for ipV4
342 // to see if we have to do a DNS lookup.
343 //
344  if (Entity->host == 0 || *(Entity->host) == '[' || isdigit(*(Entity->host)))
345  return Entity->addrInfo->Name("?");
346  return Entity->host;
347 }
const char * Name(const char *eName=0, const char **eText=0)
XrdNetAddrInfo * addrInfo
Entity's connection details.
Definition: XrdSecEntity.hh:80

References XrdSecEntity::addrInfo, XrdSecEntity::host, and XrdNetAddrInfo::Name().

Referenced by Access().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SwapTabs()

void XrdAccAccess::SwapTabs ( struct XrdAccAccess_Tables newtab)

Definition at line 356 of file XrdAccAccess.cc.

357 {
358  struct XrdAccAccess_Tables oldtab;
359  bool hRefX = false, hRefY = false;
360 
361 // Determine if we need to resolve the host name early
362 //
363  XrdAccAccess_ID *xlP = newtab.SXList;
364  while(xlP)
365  {if (xlP->host) {hRefX = true; break;}
366  xlP = xlP->next;
367  }
368 
369 // Determine if we need to resolve the hostname at all.
370 //
371  if (!hRefX)
372  {if (newtab.D_List || newtab.H_Hash || newtab.N_Hash) hRefY = true;
373  else {XrdAccAccess_ID *ylP = newtab.SYList;
374  while (ylP)
375  {if (ylP->host) {hRefY = true; break;}
376  ylP = ylP->next;
377  }
378  }
379  }
380 
381 // Get an exclusive context to change the table pointers
382 //
383  Access_Context.Lock(xs_Exclusive);
384 
385 // Save the old pointer while replacing it with the new pointer
386 //
401  hostRefX = hRefX;
402  hostRefY = hRefY;
403 
404 // When we set new access tables, we should purge the group cache
405 //
407 
408 // We can now let loose new table searchers
409 //
410  Access_Context.UnLock(xs_Exclusive);
411 }
#define XrdAccSWAP(x)
@ xs_Exclusive
Definition: XrdSysXSLock.hh:38
void PurgeCache()
XrdAccCapName * E_List
Definition: XrdAccAccess.hh:95
XrdOucHash< XrdAccCapability > * T_Hash
Definition: XrdAccAccess.hh:92
XrdOucHash< XrdAccAccess_ID > * S_Hash
Definition: XrdAccAccess.hh:91

References XrdAccAccess_Tables::D_List, XrdAccAccess_Tables::E_List, XrdAccAccess_Tables::G_Hash, XrdAccConfig::GroupMaster, XrdAccAccess_Tables::H_Hash, XrdAccAccess_ID::host, XrdSysXSLock::Lock(), XrdAccAccess_Tables::N_Hash, XrdAccAccess_ID::next, XrdAccAccess_Tables::O_Hash, XrdAccGroups::PurgeCache(), XrdAccAccess_Tables::R_Hash, XrdAccAccess_Tables::S_Hash, XrdAccAccess_Tables::SXList, XrdAccAccess_Tables::SYList, XrdAccAccess_Tables::T_Hash, XrdAccAccess_Tables::U_Hash, XrdSysXSLock::UnLock(), XrdAccAccess_Tables::X_List, XrdAccConfiguration, XrdAccSWAP, xs_Exclusive, and XrdAccAccess_Tables::Z_List.

Referenced by XrdAccConfig::ConfigDB().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Test()

int XrdAccAccess::Test ( const XrdAccPrivs  priv,
const Access_Operation  oper 
)
virtual

Check whether the specified operation is permitted.

Parameters
priv-> the privileges as returned by Access().
oper-> The operation being attempted (see above)
Returns
Permit: a non-zero value (access is permitted) Deny: zero (access is denied)

Implements XrdAccAuthorize.

Definition at line 417 of file XrdAccAccess.cc.

418 {
419 
420 // Warning! This table must be in 1-to-1 correspondence with Access_Operation
421 //
422  static XrdAccPrivs need[] = {XrdAccPriv_None, // 0
423  XrdAccPriv_Chmod, // 1
424  XrdAccPriv_Chown, // 2
425  XrdAccPriv_Create, // 3
426  XrdAccPriv_Delete, // 4
427  XrdAccPriv_Insert, // 5
428  XrdAccPriv_Lock, // 6
429  XrdAccPriv_Mkdir, // 7
430  XrdAccPriv_Read, // 8
431  XrdAccPriv_Readdir, // 9
432  XrdAccPriv_Rename, // 10
433  XrdAccPriv_Lookup, // 11
434  XrdAccPriv_Update, // 12
435  (XrdAccPrivs)0xffff, // 13
436  (XrdAccPrivs)0xffff // 14
437  };
438  // Note AOP_Excl* does not have a corresponding XrdAccPrivs; this is on
439  // purpose as the Excl* privilege is not modelled within the AuditDB framework.
440  if (oper < 0 || oper > AOP_LastOp) return 0;
441  return (int)(need[oper] & priv) == need[oper];
442 }
XrdAccPrivs
Definition: XrdAccPrivs.hh:39
@ XrdAccPriv_Mkdir
Definition: XrdAccPrivs.hh:46
@ XrdAccPriv_Chown
Definition: XrdAccPrivs.hh:41
@ XrdAccPriv_Insert
Definition: XrdAccPrivs.hh:44
@ XrdAccPriv_Lookup
Definition: XrdAccPrivs.hh:47
@ XrdAccPriv_Rename
Definition: XrdAccPrivs.hh:48
@ XrdAccPriv_Update
Definition: XrdAccPrivs.hh:52
@ XrdAccPriv_Read
Definition: XrdAccPrivs.hh:49
@ XrdAccPriv_Lock
Definition: XrdAccPrivs.hh:45
@ XrdAccPriv_None
Definition: XrdAccPrivs.hh:55
@ XrdAccPriv_Delete
Definition: XrdAccPrivs.hh:43
@ XrdAccPriv_Create
Definition: XrdAccPrivs.hh:42
@ XrdAccPriv_Readdir
Definition: XrdAccPrivs.hh:50
@ XrdAccPriv_Chmod
Definition: XrdAccPrivs.hh:40

References AOP_LastOp, XrdAccPriv_Chmod, XrdAccPriv_Chown, XrdAccPriv_Create, XrdAccPriv_Delete, XrdAccPriv_Insert, XrdAccPriv_Lock, XrdAccPriv_Lookup, XrdAccPriv_Mkdir, XrdAccPriv_None, XrdAccPriv_Read, XrdAccPriv_Readdir, XrdAccPriv_Rename, and XrdAccPriv_Update.

Friends And Related Function Documentation

◆ XrdAccConfig

friend class XrdAccConfig
friend

Definition at line 131 of file XrdAccAccess.hh.


The documentation for this class was generated from the following files: