src/internal/tslog.cpp \
src/internal/serializer.cpp \
src/internal/print_content.cpp \
- src/internal/storage_backend_serialized.cpp
+ src/internal/storage_backend_serialized.cpp \
+ src/internal/storage_backend_xml.cpp
src_libdbuspolicy1_la_SOURCES =\
$(COMMON_SRC) \
#include "print_content.hpp"
#include "tslog.hpp"
#include "type_list.h"
+#include "storage_backend_xml.hpp"
#include <cassert>
#include <map>
namespace ldp_xml_parser {
-/* The following two are building blocks for PolicySet class.
- * They specify if a given PolicySet class supports user and group policies.
- */
-/****************** UserAndGroupContext ************************/
-template <typename P>
-class UserAndGroupContext {
-protected:
- /** Map with policies for different users */
- std::map<uid_t, P> user;
- /** Map with policies for different groups */
- std::map<gid_t, P> group;
-
- template <typename T>
- void addItemUser(uid_t uid, T &item) { user[uid].addItem(item); }
-
- template <typename T>
- void addItemGroup(gid_t gid, T &item) { group[gid].addItem(item); }
-
- void printContent() const {
- for (const auto& i : user) {
- std::cerr << "user: " << i.first << std::endl;
- i.second.printContent();
- }
-
- for (const auto& i : group) {
- std::cerr << "group: " << i.first << std::endl;
- i.second.printContent();
- }
- }
-
- size_t getSize() const {
- size_t size = user.size() * sizeof(typename decltype(user)::value_type);
- for (const auto& i : user)
- size += i.second.getSize();
-
- size += group.size() * sizeof(typename decltype(group)::value_type);
- for (const auto& i : group)
- size += i.second.getSize();
- return size;
- }
-
-public:
- const P *getPolicyUser(uid_t uid) const {
- tslog::log("---policy_type = USER =", uid, "\n");
-
- auto it = user.find(uid);
- if (it == user.end()) {
- tslog::log_verbose("GetPolicy: Out of Range exception\n");
- return nullptr;
- }
- return &(it->second);
- }
-
- const P *getPolicyGroup(gid_t gid) const {
- tslog::log("---policy_type = GROUP = ", gid, "\n");
-
- auto it = group.find(gid);
- if (it == group.end()) {
- tslog::log_verbose("GetPolicy: Out of Range exception\n");
- return nullptr;
- }
- return &(it->second);
- }
-
- const std::map<uid_t, P> &getPoliciesUser() const { return user; }
- const std::map<uid_t, P> &getPoliciesGroup() const { return group; }
-};
-
-/****************** NoUserAndGroupContext ************************/
-class NoUserAndGroupContext {
-protected:
- template <typename T>
- void addItemUser(uid_t, T &) { assert(false); }
-
- template <typename T>
- void addItemGroup(gid_t, T &) { assert(false); }
-
- void printContent() const {}
- size_t getSize() const { return 0; }
-};
-
-template<typename P, typename UG = UserAndGroupContext<P>>
-class PolicySet : public UG {
- /** Policies for all contexts */
- P contextMandatory;
- P contextDefault;
-
- P &getPolicyContext(ContextType type) {
- if (ContextType::MANDATORY == type)
- return contextMandatory;
-
- assert(ContextType::DEFAULT == type);
- return contextDefault;
- }
-
-public:
- typedef P policy_type;
- /** Adds given item to policy
- * \param[in] policy_type Policy type
- * \param[in] policy_type_value Policy type value
- * \param[in] item Item to add
- */
- template<typename T>
- void addItem(const PolicyType policy_type,
- const PolicyTypeValue policy_type_value,
- T &item) {
- switch (policy_type) {
- case PolicyType::CONTEXT:
- getPolicyContext(policy_type_value.context).addItem(item);
- break;
- case PolicyType::USER:
- UG::addItemUser(policy_type_value.user, item);
- break;
- case PolicyType::GROUP:
- UG::addItemGroup(policy_type_value.group, item);
- break;
- case PolicyType::NONE:
- assert(false);
- break;
- }
- }
-
- const P &getRefPolicyContextMandatory() const { return contextMandatory; }
- const P &getRefPolicyContextDefault() const { return contextDefault; }
-
- const P *getPolicyContextMandatory() const {
- tslog::log("---policy_type = CONTEXT = MANDATORY\n");
- return &contextMandatory;
- }
-
- const P *getPolicyContextDefault() const {
- tslog::log("---policy_type = CONTEXT = DEFAULT\n");
- return &contextDefault;
- }
-
- void printSet() const {
- std::cerr << "context default" << std::endl;
- contextDefault.printContent();
- std::cerr << "context mandatory" << std::endl;
- contextMandatory.printContent();
-
- UG::printContent();
-
- std::cerr << "Memory consumption: " << getSetSize() << " B" << std::endl;
- }
-
- size_t getSetSize() const {
- size_t size = sizeof(*this);
-
- size += contextMandatory.getSize();
- size += contextDefault.getSize();
-
- size += UG::getSize();
- return size;
- }
-};
-
-/****************** NaivePolicyDbImpl ************************/
-class NaivePolicyDb::NaivePolicyDbImpl {
-public:
- /** Set of ownership policies */
- PolicySet<PolicyOwn> m_own_set;
- /** Set of send policies */
- PolicySet<PolicySend> m_send_set;
- /** Set of receive policies */
- PolicySet<PolicyReceive> m_receive_set;
- /** Set of bus access policies */
- PolicySet<PolicyAccess, NoUserAndGroupContext> m_access_set;
-
- template <typename T>
- struct MatchPolicy; // provide policy_type in specializations
-
- template <typename T>
- const typename MatchPolicy<T>::policy_set_type &getPolicySet() const;
- template <typename T>
- typename MatchPolicy<T>::policy_set_type &getPolicySet();
-
- template <typename T,
- typename P = typename MatchPolicy<T>::policy_type,
- typename PS = typename MatchPolicy<T>::policy_set_type,
- typename ...Args>
- DecisionItem getDecisionItem(const T &item,
- const P *(PS::*f)(Args ... args) const,
- Args ...args) const;
-};
-
-/* Tie MatchItems with proper policy sets.
- * Parameters: T - MatchItem* type
- * field - one of m_*_set fields from NaivePolicyDb
- *
- * The below DEF_GET_POLICY_SET defines specialization for MatchPolicy<T> template,
- * and a specialization of NaivePolicyDb::getPolicySet template function
- *
- * Specialization for MatchPolicy<T> provides field 'policy_type' which specifies
- * a type of policy used within 'field' parameter, and field 'policy_set_type'
- * which specifies a type of the 'field' parameter.
- * Specialization of NaivePolicyDb::getPolicySet returns the 'field'.
- *
- * For example: DEF_GET_POLICY_SET(MatchItemOwn, m_own_set) defines equivalent to
- * MatchPolicy<MatchItemOwn> {
- * typedef PolicyOwn policy_type;
- * typedef PolicySet<PolicyOwn> policy_set_type;
- * }
- * PolicySet<PolicyOwn> &getPolicySet<MatchItemOwn> const;
- *
- * Thanks to this construction we do not need to manually specify PolicyOwn in functions that
- * know MatchItemOwn - it is inferred.
- *
- */
-#define DEF_GET_POLICY_SET(T, field) \
- template <> struct NaivePolicyDb::NaivePolicyDbImpl::MatchPolicy<T> { \
- typedef decltype(field)::policy_type policy_type; \
- typedef decltype(field) policy_set_type; \
- }; \
- template <> struct NaivePolicyDb::NaivePolicyDbImpl::MatchPolicy<typename decltype(NaivePolicyDb::NaivePolicyDbImpl::field)::policy_type> { \
- typedef decltype(field) policy_set_type; \
- }; \
- template <> \
- auto NaivePolicyDb::NaivePolicyDbImpl::getPolicySet<T>() const -> decltype((field)) { \
- return field; \
- } \
- template <> \
- auto NaivePolicyDb::NaivePolicyDbImpl::getPolicySet<T>() -> decltype((field)) { \
- return field; \
- } \
- template <> \
- auto NaivePolicyDb::NaivePolicyDbImpl::getPolicySet<typename decltype(NaivePolicyDb::NaivePolicyDbImpl::field)::policy_type>() -> decltype((field)) { \
- return field; \
- }
-
-DEF_GET_POLICY_SET(MatchItemOwn, m_own_set)
-DEF_GET_POLICY_SET(MatchItemSend, m_send_set)
-DEF_GET_POLICY_SET(MatchItemReceive, m_receive_set)
-DEF_GET_POLICY_SET(MatchItemAccess, m_access_set)
-
-#undef DEF_GET_POLICY_SET
-
-template <typename T, typename P, typename PS, typename ...Args>
-DecisionItem NaivePolicyDb::NaivePolicyDbImpl::getDecisionItem(const T &item,
- const P *(PS::*f)(Args ... args) const,
- Args ...args) const
-{
- const auto &policySet = getPolicySet<T>();
- typedef typename std::remove_reference<decltype(policySet)>::type PolicySetType;
-
- auto policy = (policySet.*f)(args...);
- if (nullptr == policy)
- return Decision::ANY;
-
- tslog::log_verbose("Checking ", PolicySetType::policy_type::name, " policy for: ", item, "\n");
-
- return policy->getDecisionItem(item);
-}
-
void NaivePolicyDb::updateSupplementaryGroups(const VGid &groups, uid_t uid, gid_t gid) const {
auto &vsend = getMapGroup<MatchItemSend>(uid);
auto &vrecv = getMapGroup<MatchItemReceive>(uid);
/* insert supplementary group */
for (const auto group : groups) {
- if (pimpl->getPolicySet<MatchItemSend>().getPolicyGroup(group) != nullptr)
+ if (backend.existsPolicyForGroup<MatchItemSend>(group))
vsend.push_back(group);
- if (pimpl->getPolicySet<MatchItemReceive>().getPolicyGroup(group) != nullptr)
+ if (backend.existsPolicyForGroup<MatchItemReceive>(group))
vrecv.push_back(group);
vaccess.push_back(group); // no filtering, it will be used once
}
vown.push_back(gid);
} else {
for (const auto group : groups) {
- if (pimpl->getPolicySet<MatchItemOwn>().getPolicyGroup(group) != nullptr)
+ if (backend.existsPolicyForGroup<MatchItemOwn>(group))
vown.push_back(group);
}
}
const PolicyTypeValue policy_type_value,
T &item) {
tslog::log("Add item: ", item, ", decision: ", item.getDecision(), "\n");
- pimpl->getPolicySet<typename T::match_type>().addItem(policy_type, policy_type_value, item);
+ backend.addItem(policy_type, policy_type_value, item);
}
void NaivePolicyDb::printContent() const
{
- #define PRINT_SET(x) \
- std::cerr << std::endl << "----" #x "----" << std::endl; \
- (x).printSet();
-
- PRINT_SET(pimpl->m_own_set)
- PRINT_SET(pimpl->m_send_set)
- PRINT_SET(pimpl->m_receive_set)
- PRINT_SET(pimpl->m_access_set)
-
- #undef PRINT_SET
+ backend.printContent();
for (const auto &mapGroup : mapGroups) {
std::cerr << std::endl << "---- mapGroup ----" << std::endl;
}
}
-template <typename T>
-DecisionItem NaivePolicyDb::getDecisionItemContextMandatory(const T &item) const
-{
- return pimpl->getDecisionItem<T>(item, &NaivePolicyDbImpl::MatchPolicy<T>::policy_set_type::getPolicyContextMandatory);
-}
-
-template <typename T>
-DecisionItem NaivePolicyDb::getDecisionItemContextDefault(const T &item) const
-{
- return pimpl->getDecisionItem<T>(item, &NaivePolicyDbImpl::MatchPolicy<T>::policy_set_type::getPolicyContextDefault);
-}
-
-template <typename T>
-DecisionItem NaivePolicyDb::getDecisionItemUser(uid_t uid, const T &item) const
-{
- return pimpl->getDecisionItem<T>(item, &NaivePolicyDbImpl::MatchPolicy<T>::policy_set_type::getPolicyUser, uid);
-}
-
-template <typename T>
-DecisionItem NaivePolicyDb::getDecisionItemGroup(gid_t gid, const T &item) const
-{
- return pimpl->getDecisionItem<T>(item, &NaivePolicyDbImpl::MatchPolicy<T>::policy_set_type::getPolicyGroup, gid);
-}
-
template <>
const VGid *NaivePolicyDb::getGroups<MatchItemOwn>(uid_t uid, gid_t) const
{
}
void NaivePolicyDb::clear() {
- pimpl = std::unique_ptr<NaivePolicyDbImpl>{new NaivePolicyDbImpl};
+ backend.clear();
}
template <typename T>
const T &NaivePolicyDb::getPolicyContextMandatory() const {
- return pimpl->getPolicySet<T>().getRefPolicyContextMandatory();
+ return backend.getPolicyContextMandatory<T>();
}
template <typename T>
const T &NaivePolicyDb::getPolicyContextDefault() const {
- return pimpl->getPolicySet<T>().getRefPolicyContextDefault();
+ return backend.getPolicyContextDefault<T>();
}
template <typename T>
const std::map<uid_t, T> &NaivePolicyDb::getPoliciesUser() const {
- return pimpl->getPolicySet<T>().getPoliciesUser();
+ return backend.getPoliciesUser<T>();
}
template <typename T>
const std::map<gid_t, T> &NaivePolicyDb::getPoliciesGroup() const {
- return pimpl->getPolicySet<T>().getPoliciesGroup();
+ return backend.getPoliciesGroup<T>();
}
-NaivePolicyDb::NaivePolicyDb() : pimpl{new NaivePolicyDbImpl} {
-}
-
-NaivePolicyDb::~NaivePolicyDb() = default;
-
/* Explicit instantiation is needed for used public template methods defined in this file.
*/
#define T_INSTANTIATION(T) \
- template DecisionItem NaivePolicyDb::getDecisionItemContextMandatory<T>(const T &) const; \
- template DecisionItem NaivePolicyDb::getDecisionItemContextDefault<T>(const T &) const; \
- template const VGid *NaivePolicyDb::getGroups<T>(uid_t, gid_t) const;
-
-T_INSTANTIATION(MatchItemOwn)
-T_INSTANTIATION(MatchItemSend)
-T_INSTANTIATION(MatchItemReceive)
-T_INSTANTIATION(MatchItemAccess)
-
-#define T_INSTANTIATION2(T) \
- template DecisionItem NaivePolicyDb::getDecisionItemUser<T>(uid_t, const T &) const; \
- template DecisionItem NaivePolicyDb::getDecisionItemGroup<T>(gid_t, const T &) const;
-
-T_INSTANTIATION2(MatchItemOwn)
-T_INSTANTIATION2(MatchItemSend)
-T_INSTANTIATION2(MatchItemReceive)
+ template const VGid *NaivePolicyDb::getGroups<MatchItem##T>(uid_t, gid_t) const; \
+ template void NaivePolicyDb::addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, Item##T &item); \
+ template const Policy##T &NaivePolicyDb::getPolicyContextMandatory() const; \
+ template const Policy##T &NaivePolicyDb::getPolicyContextDefault() const;
-#define T_INSTANTIATION3(T) \
- template void NaivePolicyDb::addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, T &item);
+T_INSTANTIATION(Own)
+T_INSTANTIATION(Send)
+T_INSTANTIATION(Receive)
+T_INSTANTIATION(Access)
-T_INSTANTIATION3(ItemOwn)
-T_INSTANTIATION3(ItemSend)
-T_INSTANTIATION3(ItemReceive)
-T_INSTANTIATION3(ItemAccess)
-
-#define T_INSTANTIATION4(T) \
- template const T &NaivePolicyDb::getPolicyContextMandatory() const; \
- template const T &NaivePolicyDb::getPolicyContextDefault() const;
-
-T_INSTANTIATION4(PolicyOwn)
-T_INSTANTIATION4(PolicySend)
-T_INSTANTIATION4(PolicyReceive)
-T_INSTANTIATION4(PolicyAccess)
+#undef T_INSTANTIATION
-#define T_INSTANTIATION5(T) \
- template const std::map<uid_t, T> &NaivePolicyDb::getPoliciesGroup() const; \
- template const std::map<gid_t, T> &NaivePolicyDb::getPoliciesUser() const;
+#define T_INSTANTIATION(T) \
+ template const std::map<uid_t, Policy##T> &NaivePolicyDb::getPoliciesGroup() const; \
+ template const std::map<gid_t, Policy##T> &NaivePolicyDb::getPoliciesUser() const;
-T_INSTANTIATION5(PolicyOwn)
-T_INSTANTIATION5(PolicySend)
-T_INSTANTIATION5(PolicyReceive)
+T_INSTANTIATION(Own)
+T_INSTANTIATION(Send)
+T_INSTANTIATION(Receive)
#undef T_INSTANTIATION
-#undef T_INSTANTIATION2
-#undef T_INSTANTIATION3
-#undef T_INSTANTIATION4
-#undef T_INSTANTIATION5
} // namespace ldp_xml_parser
#ifndef _NAIVE_DB_H
#define _NAIVE_DB_H
+#include "storage_backend_xml.hpp"
#include <memory>
#include <vector>
#include <map>
/** Database class, contains policies for ownership and send/receive */
class NaivePolicyDb {
private:
- class NaivePolicyDbImpl;
-
- std::unique_ptr<NaivePolicyDbImpl> pimpl;
+ ldp_xml::StorageBackendXML backend;
mutable std::map<uid_t, VGid> mapGroups[MatchItemTypes::count];
/* A mutex for mapGroups */
void updateSupplementaryGroups(const VGid &groups, uid_t uid, gid_t gid) const;
void updateSupplementaryGroupsOwn(const VGid &groups, uid_t uid, gid_t gid) const;
- public:
-
- NaivePolicyDb();
- ~NaivePolicyDb();
+ public:
+ /***** Common interface for all backends ******/
void printContent() const;
template <typename T>
- DecisionItem getDecisionItemContextMandatory(const T &item) const;
+ DecisionItem getDecisionItemContextMandatory(const T &item) const
+ { return backend.getDecisionItemContextMandatory(item); }
+
template <typename T>
- DecisionItem getDecisionItemContextDefault(const T &item) const;
+ DecisionItem getDecisionItemContextDefault(const T &item) const
+ { return backend.getDecisionItemContextDefault(item); }
+
template <typename T>
- DecisionItem getDecisionItemUser(uid_t uid, const T &item) const;
+ DecisionItem getDecisionItemUser(uid_t uid, const T &item) const
+ { return backend.getDecisionItemUser(uid, item); }
+
template <typename T>
- DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const;
+ DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const
+ { return backend.getDecisionItemGroup(gid, item); }
+ /******* Common interface for group maps management **********/
template <typename T>
const VGid *getGroups(uid_t uid, gid_t gid) const;
void initializeGroups(uid_t uid, gid_t gid);
+ /******* Interface for read-write backends (e.g. XML-based) */
+ /* This will be probably moved from here */
+
/** Adds item to a policy
* \param[in] policy_type Policy type
* \param[in] policy_type_value Policy type value
--- /dev/null
+#include "storage_backend_xml.hpp"
+#include "policy_containers.hpp"
+
+using namespace ldp_xml_parser;
+
+namespace ldp_xml {
+
+/* The following two are building blocks for PolicySet class.
+ * They specify if a given PolicySet class supports user and group policies.
+ */
+/****************** UserAndGroupContext ************************/
+template <typename P>
+class UserAndGroupContext {
+protected:
+ /** Map with policies for different users */
+ std::map<uid_t, P> user;
+ /** Map with policies for different groups */
+ std::map<gid_t, P> group;
+
+ template <typename T>
+ void addItemUser(uid_t uid, T &item) { user[uid].addItem(item); }
+
+ template <typename T>
+ void addItemGroup(gid_t gid, T &item) { group[gid].addItem(item); }
+
+ void printContent() const {
+ for (const auto& i : user) {
+ std::cerr << "user: " << i.first << std::endl;
+ i.second.printContent();
+ }
+
+ for (const auto& i : group) {
+ std::cerr << "group: " << i.first << std::endl;
+ i.second.printContent();
+ }
+ }
+
+ size_t getSize() const {
+ size_t size = user.size() * sizeof(typename decltype(user)::value_type);
+ for (const auto& i : user)
+ size += i.second.getSize();
+
+ size += group.size() * sizeof(typename decltype(group)::value_type);
+ for (const auto& i : group)
+ size += i.second.getSize();
+ return size;
+ }
+
+public:
+ const P *getPolicyUser(uid_t uid) const {
+ tslog::log("---policy_type = USER =", uid, "\n");
+
+ auto it = user.find(uid);
+ if (it == user.end()) {
+ tslog::log_verbose("GetPolicy: Out of Range exception\n");
+ return nullptr;
+ }
+ return &(it->second);
+ }
+
+ const P *getPolicyGroup(gid_t gid) const {
+ tslog::log("---policy_type = GROUP = ", gid, "\n");
+
+ auto it = group.find(gid);
+ if (it == group.end()) {
+ tslog::log_verbose("GetPolicy: Out of Range exception\n");
+ return nullptr;
+ }
+ return &(it->second);
+ }
+
+ const std::map<uid_t, P> &getPoliciesUser() const { return user; }
+ const std::map<uid_t, P> &getPoliciesGroup() const { return group; }
+};
+
+/****************** NoUserAndGroupContext ************************/
+class NoUserAndGroupContext {
+protected:
+ template <typename T>
+ void addItemUser(uid_t, T &) { assert(false); }
+
+ template <typename T>
+ void addItemGroup(gid_t, T &) { assert(false); }
+
+ void printContent() const {}
+ size_t getSize() const { return 0; }
+};
+
+/****************** PolicySet ************************/
+template<typename P, typename UG = UserAndGroupContext<P>>
+class PolicySet : public UG {
+ /** Policies for all contexts */
+ P contextMandatory;
+ P contextDefault;
+
+ P &getPolicyContext(ContextType type) {
+ if (ContextType::MANDATORY == type)
+ return contextMandatory;
+
+ assert(ContextType::DEFAULT == type);
+ return contextDefault;
+ }
+
+public:
+ typedef P policy_type;
+ /** Adds given item to policy
+ * \param[in] policy_type Policy type
+ * \param[in] policy_type_value Policy type value
+ * \param[in] item Item to add
+ */
+ template<typename T>
+ void addItem(const PolicyType policy_type,
+ const PolicyTypeValue policy_type_value,
+ T &item) {
+ switch (policy_type) {
+ case PolicyType::CONTEXT:
+ getPolicyContext(policy_type_value.context).addItem(item);
+ break;
+ case PolicyType::USER:
+ UG::addItemUser(policy_type_value.user, item);
+ break;
+ case PolicyType::GROUP:
+ UG::addItemGroup(policy_type_value.group, item);
+ break;
+ case PolicyType::NONE:
+ assert(false);
+ break;
+ }
+ }
+
+ const P &getRefPolicyContextMandatory() const { return contextMandatory; }
+ const P &getRefPolicyContextDefault() const { return contextDefault; }
+
+ const P *getPolicyContextMandatory() const {
+ tslog::log("---policy_type = CONTEXT = MANDATORY\n");
+ return &contextMandatory;
+ }
+
+ const P *getPolicyContextDefault() const {
+ tslog::log("---policy_type = CONTEXT = DEFAULT\n");
+ return &contextDefault;
+ }
+
+ void printSet() const {
+ std::cerr << "context default" << std::endl;
+ contextDefault.printContent();
+ std::cerr << "context mandatory" << std::endl;
+ contextMandatory.printContent();
+
+ UG::printContent();
+
+ std::cerr << "Memory consumption: " << getSetSize() << " B" << std::endl;
+ }
+
+ size_t getSetSize() const {
+ size_t size = sizeof(*this);
+
+ size += contextMandatory.getSize();
+ size += contextDefault.getSize();
+
+ size += UG::getSize();
+ return size;
+ }
+};
+
+/****************** StorageBackendXML ************************/
+class StorageBackendXML::StorageBackendXMLImpl {
+public:
+ /** Set of ownership policies */
+ PolicySet<PolicyOwn> m_own_set;
+ /** Set of send policies */
+ PolicySet<PolicySend> m_send_set;
+ /** Set of receive policies */
+ PolicySet<PolicyReceive> m_receive_set;
+ /** Set of bus access policies */
+ PolicySet<PolicyAccess, NoUserAndGroupContext> m_access_set;
+
+ template <typename T>
+ struct MatchPolicy; // provide policy_type in specializations
+
+ template <typename T>
+ const typename MatchPolicy<T>::policy_set_type &getPolicySet() const;
+ template <typename T>
+ typename MatchPolicy<T>::policy_set_type &getPolicySet();
+
+ template <typename T,
+ typename P = typename MatchPolicy<T>::policy_type,
+ typename PS = typename MatchPolicy<T>::policy_set_type,
+ typename ...Args>
+ DecisionItem getDecisionItem(const T &item,
+ const P *(PS::*f)(Args ... args) const,
+ Args ...args) const;
+};
+
+/* Tie MatchItems with proper policy sets.
+ * Parameters: T - MatchItem* type
+ * field - one of m_*_set fields from StorageBackendXMLImpl
+ *
+ * The below DEF_GET_POLICY_SET defines specialization for MatchPolicy<T> template,
+ * and a specialization of StorageBackendXMLImpl::getPolicySet template function
+ *
+ * Specialization for MatchPolicy<T> provides field 'policy_type' which specifies
+ * a type of policy used within 'field' parameter, and field 'policy_set_type'
+ * which specifies a type of the 'field' parameter.
+ * Specialization of StorageBackendXMLImpl::getPolicySet returns the 'field'.
+ *
+ * For example: DEF_GET_POLICY_SET(MatchItemOwn, m_own_set) defines equivalent to
+ * MatchPolicy<MatchItemOwn> {
+ * typedef PolicyOwn policy_type;
+ * typedef PolicySet<PolicyOwn> policy_set_type;
+ * }
+ * PolicySet<PolicyOwn> &getPolicySet<MatchItemOwn> const;
+ *
+ * Thanks to this construction we do not need to manually specify PolicyOwn in functions that
+ * know MatchItemOwn - it is inferred.
+ *
+ */
+#define DEF_GET_POLICY_SET(T, field) \
+ template <> struct StorageBackendXML::StorageBackendXMLImpl::MatchPolicy<T> { \
+ typedef decltype(field)::policy_type policy_type; \
+ typedef decltype(field) policy_set_type; \
+ }; \
+ template <> struct StorageBackendXML::StorageBackendXMLImpl::MatchPolicy<typename decltype(StorageBackendXML::StorageBackendXMLImpl::field)::policy_type> { \
+ typedef decltype(field) policy_set_type; \
+ }; \
+ template <> \
+ auto StorageBackendXML::StorageBackendXMLImpl::getPolicySet<T>() const -> decltype((field)) { \
+ return field; \
+ } \
+ template <> \
+ auto StorageBackendXML::StorageBackendXMLImpl::getPolicySet<T>() -> decltype((field)) { \
+ return field; \
+ } \
+ template <> \
+ auto StorageBackendXML::StorageBackendXMLImpl::getPolicySet<typename decltype(StorageBackendXML::StorageBackendXMLImpl::field)::policy_type>() -> decltype((field)) { \
+ return field; \
+ }
+
+DEF_GET_POLICY_SET(MatchItemOwn, m_own_set)
+DEF_GET_POLICY_SET(MatchItemSend, m_send_set)
+DEF_GET_POLICY_SET(MatchItemReceive, m_receive_set)
+DEF_GET_POLICY_SET(MatchItemAccess, m_access_set)
+
+#undef DEF_GET_POLICY_SET
+
+template <typename T, typename P, typename PS, typename ...Args>
+DecisionItem StorageBackendXML::StorageBackendXMLImpl::getDecisionItem(const T &item,
+ const P *(PS::*f)(Args ... args) const,
+ Args ...args) const
+{
+ const auto &policySet = getPolicySet<T>();
+ typedef typename std::remove_reference<decltype(policySet)>::type PolicySetType;
+
+ auto policy = (policySet.*f)(args...);
+ if (nullptr == policy)
+ return Decision::ANY;
+
+ tslog::log_verbose("Checking ", PolicySetType::policy_type::name, " policy for: ", item, "\n");
+
+ return policy->getDecisionItem(item);
+}
+
+template <typename T>
+void StorageBackendXML::addItem(const ldp_xml_parser::PolicyType policy_type,
+ const ldp_xml_parser::PolicyTypeValue policy_type_value,
+ T &item) {
+ pimpl->getPolicySet<typename T::match_type>().addItem(policy_type, policy_type_value, item);
+}
+
+void StorageBackendXML::clear() {
+ pimpl.reset(new StorageBackendXMLImpl);
+}
+
+void StorageBackendXML::printContent() const {
+ #define PRINT_SET(x) \
+ std::cerr << std::endl << "----" #x "----" << std::endl; \
+ (x).printSet();
+
+ PRINT_SET(pimpl->m_own_set)
+ PRINT_SET(pimpl->m_send_set)
+ PRINT_SET(pimpl->m_receive_set)
+ PRINT_SET(pimpl->m_access_set)
+
+ #undef PRINT_SET
+}
+
+template <typename T>
+const T &StorageBackendXML::getPolicyContextMandatory() const {
+ return pimpl->getPolicySet<T>().getRefPolicyContextMandatory();
+}
+
+template <typename T>
+const T &StorageBackendXML::getPolicyContextDefault() const {
+ return pimpl->getPolicySet<T>().getRefPolicyContextDefault();
+}
+
+template <typename T>
+const std::map<uid_t, T> &StorageBackendXML::getPoliciesUser() const {
+ return pimpl->getPolicySet<T>().getPoliciesUser();
+}
+
+template <typename T>
+const std::map<gid_t, T> &StorageBackendXML::getPoliciesGroup() const {
+ return pimpl->getPolicySet<T>().getPoliciesGroup();
+}
+
+template <typename T>
+bool StorageBackendXML::existsPolicyForGroup(gid_t gid) const {
+ return pimpl->getPolicySet<T>().getPolicyGroup(gid) != nullptr;
+}
+
+template <typename T>
+ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemContextMandatory(const T &item) const {
+ return pimpl->getDecisionItem<T>(item, &StorageBackendXMLImpl::MatchPolicy<T>::policy_set_type::getPolicyContextMandatory);
+}
+
+template <typename T>
+ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemContextDefault(const T &item) const {
+ return pimpl->getDecisionItem<T>(item, &StorageBackendXMLImpl::MatchPolicy<T>::policy_set_type::getPolicyContextDefault);
+}
+
+template <typename T>
+ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemUser(uid_t uid, const T &item) const {
+ return pimpl->getDecisionItem<T>(item, &StorageBackendXMLImpl::MatchPolicy<T>::policy_set_type::getPolicyUser, uid);
+}
+
+template <typename T>
+ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemGroup(gid_t gid, const T &item) const {
+ return pimpl->getDecisionItem<T>(item, &StorageBackendXMLImpl::MatchPolicy<T>::policy_set_type::getPolicyGroup, gid);
+}
+
+StorageBackendXML::StorageBackendXML() : pimpl{new StorageBackendXMLImpl} {
+}
+
+StorageBackendXML::~StorageBackendXML() = default;
+
+/* Explicit instantiation is needed for used public template methods defined in this file.
+ */
+#define T_INSTANTIATION(T) \
+ template ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemContextMandatory(const MatchItem##T &item) const; \
+ template ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemContextDefault(const MatchItem##T &item) const; \
+ template void StorageBackendXML::addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, Item##T &item); \
+ template const Policy##T &StorageBackendXML::getPolicyContextMandatory() const; \
+ template const Policy##T &StorageBackendXML::getPolicyContextDefault() const;
+
+T_INSTANTIATION(Own)
+T_INSTANTIATION(Send)
+T_INSTANTIATION(Receive)
+T_INSTANTIATION(Access)
+
+#undef T_INSTANTIATION
+
+#define T_INSTANTIATION(T) \
+ template bool StorageBackendXML::existsPolicyForGroup<MatchItem##T>(gid_t gid) const; \
+ template ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemUser(uid_t uid, const MatchItem##T &item) const; \
+ template ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemGroup(gid_t gid, const MatchItem##T &item) const; \
+ template const std::map<gid_t, Policy##T> &StorageBackendXML::getPoliciesGroup() const; \
+ template const std::map<uid_t, Policy##T> &StorageBackendXML::getPoliciesUser() const;
+
+T_INSTANTIATION(Own)
+T_INSTANTIATION(Send)
+T_INSTANTIATION(Receive)
+
+#undef T_INSTANTIATION
+
+} // namespace ldp_xml
--- /dev/null
+#pragma once
+
+#include "policy.hpp"
+#include <sys/types.h>
+#include <map>
+#include <memory>
+
+namespace ldp_xml {
+
+class StorageBackendXML {
+ class StorageBackendXMLImpl;
+ std::unique_ptr<StorageBackendXMLImpl> pimpl;
+public:
+ StorageBackendXML();
+ ~StorageBackendXML();
+
+ // This works with T set to MatchItemOwn, MatchItemSend, MatchItemReceive or MatchItemAccess
+ template <typename T>
+ void addItem(const ldp_xml_parser::PolicyType policy_type,
+ const ldp_xml_parser::PolicyTypeValue policy_type_value,
+ T &item);
+
+ void clear();
+
+ void printContent() const;
+
+ // The getPolicy*() methods are intended for Serializers to get
+ // access to policy structures.
+ // Supported template parameters are: PolicyOwn, PolicySend, PolicyReceive
+ // and for PolicyAccess only getPolicyContext*()
+ template <typename T>
+ const T &getPolicyContextMandatory() const;
+ template <typename T>
+ const T &getPolicyContextDefault() const;
+ template <typename T>
+ const std::map<uid_t, T> &getPoliciesUser() const;
+ template <typename T>
+ const std::map<gid_t, T> &getPoliciesGroup() const;
+
+ // This works with T set to MatchItemOwn, MatchItemSend or MatchItemReceive
+ // This is needed for filtering mapGroups. Check NaivePolicyDb.
+ template <typename T>
+ bool existsPolicyForGroup(gid_t gid) const;
+
+ // These work with T set to MatchItemOwn, MatchItemSend, MatchItemReceive or MatchItemAccess
+ template <typename T>
+ ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const T &item) const;
+ template <typename T>
+ ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const T &item) const;
+ template <typename T>
+ ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const T &item) const;
+ template <typename T>
+ ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const;
+};
+
+}