/*
- * Copyright 2001-2009 Internet2
+ * Copyright 2001-2010 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/ReloadableXMLFile.h>
+#include <xmltooling/util/Threads.h>
#include <xmltooling/util/XMLHelper.h>
#include <xercesc/util/XMLUniDefs.hpp>
#endif
// Each Policy has a functor for determining applicability and a map of
- // attribute IDs to Accept/Deny functor pairs (which can include NULLs).
+ // attribute IDs to Accept/Deny functor pairs (which can include nullptrs).
struct SHIBSP_DLLLOCAL Policy
{
- Policy() : m_applies(NULL) {}
+ Policy() : m_applies(nullptr) {}
const MatchFunctor* m_applies;
typedef multimap< string,pair<const MatchFunctor*,const MatchFunctor*> > rules_t;
rules_t m_rules;
class SHIBSP_DLLLOCAL XMLFilter : public AttributeFilter, public ReloadableXMLFile
{
public:
- XMLFilter(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeFilter")), m_impl(NULL) {
- load();
+ XMLFilter(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeFilter")), m_impl(nullptr) {
+ background_load();
}
~XMLFilter() {
+ shutdown();
delete m_impl;
}
}
protected:
- pair<bool,DOMElement*> load();
+ pair<bool,DOMElement*> background_load();
private:
XMLFilterImpl* m_impl;
static const XMLCh _ref[] = UNICODE_LITERAL_3(r,e,f);
};
-XMLFilterImpl::XMLFilterImpl(const DOMElement* e, Category& log) : m_log(log), m_document(NULL)
+XMLFilterImpl::XMLFilterImpl(const DOMElement* e, Category& log) : m_log(log), m_document(nullptr)
{
#ifdef _DEBUG
xmltooling::NDC ndc("XMLFilterImpl");
}
else if (XMLHelper::isNodeNamed(child, SHIB2ATTRIBUTEFILTER_NS, AttributeFilterPolicy)) {
e = XMLHelper::getFirstChildElement(child);
- MatchFunctor* func = NULL;
+ MatchFunctor* func = nullptr;
if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, PolicyRequirementRule)) {
func = buildFunctor(e, reqFunctors, "PolicyRequirementRule", false);
}
else if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, PolicyRequirementRuleReference)) {
- auto_ptr_char ref(e->getAttributeNS(NULL, _ref));
- if (ref.get() && *ref.get()) {
- multimap<string,MatchFunctor*>::const_iterator prr = m_policyReqRules.find(ref.get());
- func = (prr!=m_policyReqRules.end()) ? prr->second : NULL;
+ string ref(XMLHelper::getAttrString(e, nullptr, _ref));
+ if (!ref.empty()) {
+ multimap<string,MatchFunctor*>::const_iterator prr = m_policyReqRules.find(ref);
+ func = (prr!=m_policyReqRules.end()) ? prr->second : nullptr;
}
}
if (func) {
m_policies.back().m_rules.insert(Policy::rules_t::value_type(rule.first, rule.second));
}
else if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, AttributeRuleReference)) {
- auto_ptr_char ref(e->getAttributeNS(NULL, _ref));
- if (ref.get() && *ref.get()) {
- map< string,pair< string,pair< const MatchFunctor*,const MatchFunctor*> > >::const_iterator ar = m_attrRules.find(ref.get());
+ string ref(XMLHelper::getAttrString(e, nullptr, _ref));
+ if (!ref.empty()) {
+ map< string,pair< string,pair< const MatchFunctor*,const MatchFunctor*> > >::const_iterator ar = m_attrRules.find(ref);
if (ar != m_attrRules.end())
m_policies.back().m_rules.insert(Policy::rules_t::value_type(ar->second.first, ar->second.second));
else
- m_log.warn("skipping invalid AttributeRuleReference (%s)", ref.get());
+ m_log.warn("skipping invalid AttributeRuleReference (%s)", ref.c_str());
}
}
e = XMLHelper::getNextSiblingElement(e);
const DOMElement* e, const FilterPolicyContext& functorMap, const char* logname, bool standalone
)
{
- auto_ptr_char temp(e->getAttributeNS(NULL,_id));
- const char* id = (temp.get() && *temp.get()) ? temp.get() : "";
+ string id(XMLHelper::getAttrString(e, nullptr, _id));
- if (standalone && !*id) {
+ if (standalone && id.empty()) {
m_log.warn("skipping stand-alone %s with no id", logname);
- return NULL;
+ return nullptr;
}
- else if (*id && functorMap.getMatchFunctors().count(id)) {
+ else if (!id.empty() && functorMap.getMatchFunctors().count(id)) {
if (standalone) {
- m_log.warn("skipping duplicate stand-alone %s with id (%s)", logname, id);
- return NULL;
+ m_log.warn("skipping duplicate stand-alone %s with id (%s)", logname, id.c_str());
+ return nullptr;
}
else
- id = "";
+ id.clear();
}
auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
else
m_log.error("%s with no xsi:type", logname);
- return NULL;
+ return nullptr;
}
pair< string,pair<const MatchFunctor*,const MatchFunctor*> > XMLFilterImpl::buildAttributeRule(
const DOMElement* e, const FilterPolicyContext& permMap, const FilterPolicyContext& denyMap, bool standalone
)
{
- auto_ptr_char temp(e->getAttributeNS(NULL,_id));
- const char* id = (temp.get() && *temp.get()) ? temp.get() : "";
+ string id(XMLHelper::getAttrString(e, nullptr, _id));
- if (standalone && !*id) {
+ if (standalone && id.empty()) {
m_log.warn("skipping stand-alone AttributeRule with no id");
- return make_pair(string(),pair<const MatchFunctor*,const MatchFunctor*>(NULL,NULL));
+ return make_pair(string(),pair<const MatchFunctor*,const MatchFunctor*>(nullptr,nullptr));
}
- else if (*id && m_attrRules.count(id)) {
+ else if (!id.empty() && m_attrRules.count(id)) {
if (standalone) {
- m_log.warn("skipping duplicate stand-alone AttributeRule with id (%s)", id);
- return make_pair(string(),pair<const MatchFunctor*,const MatchFunctor*>(NULL,NULL));
+ m_log.warn("skipping duplicate stand-alone AttributeRule with id (%s)", id.c_str());
+ return make_pair(string(),pair<const MatchFunctor*,const MatchFunctor*>(nullptr,nullptr));
}
else
- id = "";
+ id.clear();
}
- auto_ptr_char attrID(e->getAttributeNS(NULL,attributeID));
- if (!attrID.get() || !*attrID.get())
+ string attrID(XMLHelper::getAttrString(e, nullptr, attributeID));
+ if (attrID.empty())
m_log.warn("skipping AttributeRule with no attributeID");
- MatchFunctor* perm=NULL;
- MatchFunctor* deny=NULL;
+ MatchFunctor* perm=nullptr;
+ MatchFunctor* deny=nullptr;
e = XMLHelper::getFirstChildElement(e);
if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, PermitValueRule)) {
e = XMLHelper::getNextSiblingElement(e);
}
else if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, PermitValueRuleReference)) {
- auto_ptr_char ref(e->getAttributeNS(NULL, _ref));
- if (ref.get() && *ref.get()) {
- multimap<string,MatchFunctor*>::const_iterator pvr = m_permitValRules.find(ref.get());
- perm = (pvr!=m_permitValRules.end()) ? pvr->second : NULL;
+ string ref(XMLHelper::getAttrString(e, nullptr, _ref));
+ if (!ref.empty()) {
+ multimap<string,MatchFunctor*>::const_iterator pvr = m_permitValRules.find(ref);
+ perm = (pvr!=m_permitValRules.end()) ? pvr->second : nullptr;
}
e = XMLHelper::getNextSiblingElement(e);
}
deny = buildFunctor(e, denyMap, "DenyValueRule", false);
}
else if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, DenyValueRuleReference)) {
- auto_ptr_char ref(e->getAttributeNS(NULL, _ref));
- if (ref.get() && *ref.get()) {
- multimap<string,MatchFunctor*>::const_iterator pvr = m_denyValRules.find(ref.get());
- deny = (pvr!=m_denyValRules.end()) ? pvr->second : NULL;
+ string ref(XMLHelper::getAttrString(e, nullptr, _ref));
+ if (!ref.empty()) {
+ multimap<string,MatchFunctor*>::const_iterator pvr = m_denyValRules.find(ref);
+ deny = (pvr!=m_denyValRules.end()) ? pvr->second : nullptr;
}
}
if (perm || deny) {
- if (*id) {
- m_attrRules[id] = pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID.get(), pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
+ if (!id.empty()) {
+ m_attrRules[id] =
+ pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID, pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
return m_attrRules[id];
}
else {
- return pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID.get(), pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
+ return pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID, pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
}
}
- m_log.warn("skipping AttributeRule (%s), permit and denial rule(s) invalid or missing", id);
- return pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(string(),pair<const MatchFunctor*,const MatchFunctor*>(NULL,NULL));
+ if (!id.empty())
+ m_log.warn("skipping AttributeRule (%s), permit and denial rule(s) invalid or missing", id.c_str());
+ else
+ m_log.warn("skipping AttributeRule, permit and denial rule(s) invalid or missing");
+ return pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(string(),pair<const MatchFunctor*,const MatchFunctor*>(nullptr,nullptr));
}
void XMLFilterImpl::filterAttributes(const FilteringContext& context, vector<Attribute*>& attributes) const
// If no rules apply, remove the attribute entirely.
if (rulesToRun.empty()) {
m_log.warn(
- "no rule found, removing attribute (%s) from (%s)",
+ "no rule found, will remove attribute (%s) from (%s)",
attr->getId(), issuer.get() ? issuer.get() : "unknown source"
);
deletedAttributes[a] = true;
Attribute* attr = attributes[a];
if (deletedAttributes[a]) {
+ m_log.warn(
+ "removing filtered attribute (%s) from (%s)",
+ attr->getId(), issuer.get() ? issuer.get() : "unknown source"
+ );
delete attr;
deletedAttributes.erase(deletedAttributes.begin() + a);
attributes.erase(attributes.begin() + a);
attr->getId(), issuer.get() ? issuer.get() : "unknown source"
);
delete attr;
+ deletedAttributes.erase(deletedAttributes.begin() + a);
attributes.erase(attributes.begin() + a);
continue;
}
}
}
-pair<bool,DOMElement*> XMLFilter::load()
+pair<bool,DOMElement*> XMLFilter::background_load()
{
// Load from source using base class.
pair<bool,DOMElement*> raw = ReloadableXMLFile::load();
// If we own it, wrap it.
- XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL);
+ XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr);
XMLFilterImpl* impl = new XMLFilterImpl(raw.second, m_log);
// If we held the document, transfer it to the impl. If we didn't, it's a no-op.
impl->setDocument(docjanitor.release());
+ // Perform the swap inside a lock.
+ if (m_lock)
+ m_lock->wrlock();
+ SharedLock locker(m_lock, false);
delete m_impl;
m_impl = impl;
- return make_pair(false,(DOMElement*)NULL);
+ return make_pair(false,(DOMElement*)nullptr);
}