From d1e54019d9e9acad733d95f24e0b67dbff947e36 Mon Sep 17 00:00:00 2001 From: Andrew Hanushevsky Date: Tue, 10 Sep 2019 23:40:32 -0700 Subject: [PATCH] [Sec] Add method to iterate over attribute key-value pairs. [Sec] Further encapsulate he SecEntity implementation. --- src/XrdSec/XrdSecEntity.cc | 123 +++++++++++++++++++------------------ src/XrdSec/XrdSecEntity.hh | 64 ++++++++++++++++--- 2 files changed, 118 insertions(+), 69 deletions(-) diff --git a/src/XrdSec/XrdSecEntity.cc b/src/XrdSec/XrdSecEntity.cc index 0bffe6bde27..1a64ac375be 100644 --- a/src/XrdSec/XrdSecEntity.cc +++ b/src/XrdSec/XrdSecEntity.cc @@ -33,29 +33,24 @@ #include "XrdSec/XrdSecAttr.hh" #include "XrdSec/XrdSecEntity.hh" +#include "XrdSys/XrdSysPthread.hh" /******************************************************************************/ /* L o c a l C l a s s e s */ /******************************************************************************/ -class XrdSecEntityAttrs +class XrdSecEntityXtra { public: +XrdSysMutex xMutex; + std::vector attrVec; std::map attrMap; - XrdSecEntityAttrs() {} - ~XrdSecEntityAttrs() {} -}; - -class XrdSecEntityXtend -{ -public: - - XrdSecEntityXtend() {} - ~XrdSecEntityXtend() {} + XrdSecEntityXtra() {} + ~XrdSecEntityXtra() {} }; /******************************************************************************/ @@ -64,20 +59,17 @@ class XrdSecEntityXtend bool XrdSecEntity::Add(XrdSecAttr &attr) { - XrdSysMutexHelper mHelp(eMutex); + XrdSysMutexHelper mHelp(entXtra->xMutex); + std::vector::iterator it; // Check if this attribute already exists // - if (!entAttrs) entAttrs = new XrdSecEntityAttrs; - else {std::vector::iterator it; - for (it = entAttrs->attrVec.begin(); - it != entAttrs->attrVec.end(); it++) - {if ((*it)->Signature == attr.Signature) return false;} - } + for (it = entXtra->attrVec.begin(); it != entXtra->attrVec.end(); it++) + if ((*it)->Signature == attr.Signature) return false; // Add the attribute object to our list of objects // - entAttrs->attrVec.push_back(&attr); + entXtra->attrVec.push_back(&attr); return true; } @@ -86,23 +78,22 @@ bool XrdSecEntity::Add(XrdSecAttr &attr) bool XrdSecEntity::Add(const std::string &key, const std::string &val, bool replace) { - XrdSysMutexHelper mHelp(eMutex); + XrdSysMutexHelper mHelp(entXtra->xMutex); std::map::iterator it; bool found = false; // Check if this attribute already exists // - if (!entAttrs) entAttrs = new XrdSecEntityAttrs; - else {it = entAttrs->attrMap.find(key); - if (it != entAttrs->attrMap.end()) - {if (!replace) return false; - found = true; - } } + it = entXtra->attrMap.find(key); + if (it != entXtra->attrMap.end()) + {if (!replace) return false; + found = true; + } // Add or replace the value // if (found) it->second = val; - else entAttrs->attrMap.insert(std::make_pair(key, val)); + else entXtra->attrMap.insert(std::make_pair(key, val)); return true; } @@ -112,16 +103,13 @@ bool XrdSecEntity::Add(const std::string &key, XrdSecAttr *XrdSecEntity::Get(const void *sigkey) { - XrdSysMutexHelper mHelp(eMutex); + XrdSysMutexHelper mHelp(entXtra->xMutex); + std::vector::iterator it; // Return pointer to the attribute if it exists // - if (entAttrs) - {std::vector::iterator it; - for (it = entAttrs->attrVec.begin(); - it != entAttrs->attrVec.end(); it++) - {if ((*it)->Signature == sigkey) return *it;} - } + for (it = entXtra->attrVec.begin(); it != entXtra->attrVec.end(); it++) + if ((*it)->Signature == sigkey) return *it; // Attribute not found // @@ -132,17 +120,15 @@ XrdSecAttr *XrdSecEntity::Get(const void *sigkey) bool XrdSecEntity::Get(const std::string &key, std::string &val) { - XrdSysMutexHelper mHelp(eMutex); + XrdSysMutexHelper mHelp(entXtra->xMutex); + std::map::iterator it; // Return pointer to the attribute if it exists // - if (entAttrs) - {std::map::iterator it; - it = entAttrs->attrMap.find(key); - if (it != entAttrs->attrMap.end()) - {val = it->second; - return true; - } + it = entXtra->attrMap.find(key); + if (it != entXtra->attrMap.end()) + {val = it->second; + return true; } // The key does not exists @@ -150,6 +136,32 @@ bool XrdSecEntity::Get(const std::string &key, std::string &val) return false; } +/******************************************************************************/ +/* L i s t */ +/******************************************************************************/ + +void XrdSecEntity::List(XrdSecEntityAttrCB &attrCB) +{ + XrdSysMutexHelper mHelp(entXtra->xMutex); + std::map::iterator itM; + std::vector attrDel; + std::vector::iterator itV; + XrdSecEntityAttrCB::Action rc; + + for (itM = entXtra->attrMap.begin(); + itM != entXtra->attrMap.end(); itM++) + {rc = attrCB.Attr(itM->first.c_str(), itM->second.c_str()); + if (rc == XrdSecEntityAttrCB::Stop) break; + else if (rc == XrdSecEntityAttrCB::Delete) + attrDel.push_back(itM->first.c_str()); + } + + if (rc != XrdSecEntityAttrCB::Stop) attrCB.Attr(0, 0); + + for (itV = attrDel.begin(); itV != attrDel.end(); itV++) + entXtra->attrMap.erase(std::string(*itV)); +} + /******************************************************************************/ /* R e s e t */ /******************************************************************************/ @@ -178,42 +190,33 @@ void XrdSecEntity::Reset(bool isnew, const char *spV, const char *dpV) gid = 0; memset(future, 0, sizeof(future)); - if (isnew) - {entAttrs = 0; - entXtend = 0; - } else { - if (entAttrs) ResetAttrs(); - entXtend = 0; // No extension for now. - } + if (isnew) entXtra = new XrdSecEntityXtra; + else ResetXtra(); } /******************************************************************************/ -/* R e s e t A t t r s */ +/* R e s e t X t r a */ /******************************************************************************/ -void XrdSecEntity::ResetAttrs(bool dodel) +void XrdSecEntity::ResetXtra(bool dodel) { - XrdSysMutexHelper mHelp(eMutex); - -// If we have no attributes we are done -// - if (!entAttrs) return; + XrdSysMutexHelper mHelp(entXtra->xMutex); // Cleanup the key-value map // - entAttrs->attrMap.clear(); + entXtra->attrMap.clear(); // Run through attribute objects, deleting each one // std::vector::iterator it; - for (it = entAttrs->attrVec.begin(); it != entAttrs->attrVec.end(); it++) + for (it = entXtra->attrVec.begin(); it != entXtra->attrVec.end(); it++) {(*it)->Delete();} // Now clear the whole vector // - entAttrs->attrVec.clear(); + entXtra->attrVec.clear(); // Delete the extension if so wanted // - if (dodel) {delete entAttrs; entAttrs = 0;} + if (dodel) {delete entXtra; entXtra = 0;} } diff --git a/src/XrdSec/XrdSecEntity.hh b/src/XrdSec/XrdSecEntity.hh index 20885f7c1aa..87b4ec54597 100644 --- a/src/XrdSec/XrdSecEntity.hh +++ b/src/XrdSec/XrdSecEntity.hh @@ -44,14 +44,12 @@ #include -#include "XrdSys/XrdSysPthread.hh" - #define XrdSecPROTOIDSIZE 8 class XrdNetAddrInfo; class XrdSecAttr; -class XrdSecEntityAttrs; -class XrdSecEntityXtend; +class XrdSecEntityAttrCB; +class XrdSecEntityXtra; /******************************************************************************/ /* X r d S e c E n t i t y */ @@ -136,6 +134,14 @@ XrdSecAttr *Get(const void *sigkey); bool Get(const std::string &key, std::string &val); +//------------------------------------------------------------------------------ +//! List key-value pairs via iterative callback on passed ovject. +//! +//! @param attrCB - Reference to the callback object to receive list entries. +//------------------------------------------------------------------------------ + + void List(XrdSecEntityAttrCB &attrCB); + //------------------------------------------------------------------------------ //! Reset object to it's pristine self. //! @@ -152,7 +158,7 @@ XrdSecAttr *Get(const void *sigkey); //! @param doDel - When true, the attribute extension is deleted as well. //------------------------------------------------------------------------------ - void ResetAttrs(bool doDel=false); + void ResetXtra(bool doDel=false); //------------------------------------------------------------------------------ //! Constructor. @@ -164,14 +170,54 @@ XrdSecAttr *Get(const void *sigkey); XrdSecEntity(const char *spName=0, const char *dpName=0) {Reset(true, dpName, spName);} - ~XrdSecEntity() {ResetAttrs(true);} + ~XrdSecEntity() {ResetXtra(true);} private: -XrdSysMutex eMutex; -XrdSecEntityAttrs *entAttrs; -XrdSecEntityXtend *entXtend; +XrdSecEntityXtra *entXtra; }; #define XrdSecClientName XrdSecEntity #define XrdSecServerName XrdSecEntity + + +/******************************************************************************/ +/* X r d S e c E n t i t y A t t r C B */ +/******************************************************************************/ + +// The XrdSecEntityAttrCB class defines the callback object passed to the +// XrdSecEntity::List() method to iteratively obtain the key-value attribute +// pairs associated with the entity. The XrdSecEntityAttrCB::Attr() method is +// called for each key-value pair. The end of the list is indicated by calling +// Attr() with nil key-value pointers. The Attr() method should not call +// the XrdSecEntity::Add() or XrdSecEntity::Get() methods; otherwise, a +// deadlock will occur. +// +class XrdSecEntityAttrCB +{ +public: + +//------------------------------------------------------------------------------ +//! Acceppt a key-value attribute pair from the XrdSecEntity::List() method. +//! +//! @param key - The key, if nil this is the end of the list. +//! @param val - The associated value, if nil this is the end of the list. +//! +//! @return One of the Action enum values. The return value is ignored when +//! the end of the list indicator is returned. +//------------------------------------------------------------------------------ + +enum Action {Delete = -1, //!< Delete the key-value + Stop = 0, //!< Stop the iteration + Next = 1 //!< Proceed to the next key-value pair + }; + +virtual Action Attr(const char *key, const char *val) = 0; + +//------------------------------------------------------------------------------ +//! Constructor and Destructor. +//------------------------------------------------------------------------------ + + XrdSecEntityAttrCB() {} +virtual ~XrdSecEntityAttrCB() {} +}; #endif