diff options
author | Adrian Szyndela <adrian.s@samsung.com> | 2020-10-28 11:10:58 +0100 |
---|---|---|
committer | Adrian Szyndela <adrian.s@samsung.com> | 2020-10-30 12:47:33 +0100 |
commit | c6d04cb74ad879df4731acf9c6fc7b17d25ab865 (patch) | |
tree | cd68fc264c9809b6a30d5a05ed5d7b7c2897dd14 | |
parent | 4434b9892538978be1fb1ee81c6680b06f8d414e (diff) | |
download | libdbuspolicy-c6d04cb74ad879df4731acf9c6fc7b17d25ab865.tar.gz libdbuspolicy-c6d04cb74ad879df4731acf9c6fc7b17d25ab865.tar.bz2 libdbuspolicy-c6d04cb74ad879df4731acf9c6fc7b17d25ab865.zip |
refactoring: move generalized operations to StorageBackendSerialized
Change-Id: I9abb90ff1d81970d939ca3f80b784c9b7b60ab23
-rw-r--r-- | src/internal/storage_backend_flatbuffers.cpp | 247 | ||||
-rw-r--r-- | src/internal/storage_backend_flatbuffers.hpp | 53 | ||||
-rw-r--r-- | src/internal/storage_backend_serialized.cpp | 238 | ||||
-rw-r--r-- | src/internal/storage_backend_serialized.hpp | 53 |
4 files changed, 281 insertions, 310 deletions
diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index feba813..f2a5bec 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -13,12 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "include/fb_generated.h" -#include "serialized_convert.hpp" #include "storage_backend_flatbuffers.hpp" -#include "tslog.hpp" -#include <boost/tokenizer.hpp> -#include <string> using namespace FB; using ldp_xml_parser::MatchItemSend; @@ -32,171 +27,6 @@ const unsigned int FB_ID_SIZE = 4; } // anonymous namespace -template <typename T> -struct type_helper; - -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::makeDecisionItem(const DecisionItem *item) const { - return ldp_xml_parser::DecisionItem(makeDecision(decisionItemGetDecision(item)), - stringGetCStr(decisionItemGetPrivilege(item))); -} - -boost::string_ref StorageBackendFlatbuffers::toStringRef(const flatbuffers::String *str) const { - return boost::string_ref(stringGetCStr(str), stringGetSize(str)); -} - -template <typename T, typename I> -bool StorageBackendFlatbuffers::match(const T &match, const I *i) const { - return match.match(makeMessageType(itemSrGetMessageType(i)), - toStringRef(itemSrGetInterface(i)), - toStringRef(itemSrGetPath(i)), - toStringRef(itemSrGetMember(i)), - toStringRef(itemSrGetName(i)), - itemSrGetIsNamePrefix(i), - makeDecision(decisionItemGetDecision(itemGetDecisionItem(i)))); -} - -bool StorageBackendFlatbuffers::match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const { - return match.match(makeBusAccessType(itemAccessGetType(item)), itemAccessGetUid(item), itemAccessGetGid(item)); -} - -template <typename T, typename P = typename type_helper<T>::policy_type> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, const P *policy, ldp_serialization::ItemsType) const { - const auto *v = policyGetItems(policy); - auto rend = containerGetReverseIteratorEnd(v); - for (auto rit = containerGetReverseIterator(v); rit != rend; ++rit) { - if (match(item, *rit)) - return makeDecisionItem(itemGetDecisionItem(*rit)); - } - return ldp_xml_parser::Decision::ANY; -} - -auto StorageBackendFlatbuffers::getDecisionItemFromTree(const FB::PolicyOwnNode *node, - const tokenizer::iterator &tokens_end, - tokenizer::iterator &iterator) const { - if (iterator == tokens_end) { - if (makeDecision(decisionItemGetDecision(ownNodeGetDecisionItem(node))) != ldp_xml_parser::Decision::ANY) - return ownNodeGetDecisionItem(node); - else - return ownNodeGetPrefixDecisionItem(node); - } - - auto children = ownNodeGetChildren(node); - - if (containerEmpty(children)) - return ownNodeGetPrefixDecisionItem(node); - - auto child = containerLookupByKey(children, iterator->c_str()); - if (!child.first) - return ownNodeGetPrefixDecisionItem(node); - - ++iterator; - auto child_decision = getDecisionItemFromTree(child.second, tokens_end, iterator); - if (makeDecision(decisionItemGetDecision(child_decision)) == ldp_xml_parser::Decision::ANY) - return ownNodeGetPrefixDecisionItem(node); - - return child_decision; -} - -template <> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const ldp_xml_parser::MatchItemOwn &item, - const PolicyOwn *policy, - ldp_serialization::TreeType) const { - if (item.getName().length() == 0) - return ldp_xml_parser::Decision::DENY; - - boost::char_separator<char> separator("."); - tokenizer tokens(item.getName(), separator); - - auto iterator = tokens.begin(); - - return makeDecisionItem(getDecisionItemFromTree(policyGetTree(policy), tokens.end(), iterator)); -} - -template <typename MatchItem, typename Map> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const MatchItem &item, const Map &map, id_t id) const { - if (containerEmpty(map)) - return ldp_xml_parser::Decision::ANY; - - auto elem = containerLookupByKey(map, id); - if (!elem.first) - return ldp_xml_parser::Decision::ANY; - return getDecisionItem(item, setUserGroupGetPolicy(elem.second)); -} - -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const MatchItemSend &item, const FB::PolicySend *policy) const { - - if (!policyHasIndex(policy)) - return getDecisionItem(item, policy, ldp_serialization::ItemsType()); // make it old way for old databases - - auto index = policyGetIndex(policy); - - uint32_t currentBest = 0; - - auto updateCurrentBest = [¤tBest, &item, &policy, this](const auto &vec) { - // look from the back, the rule is the same as for the full database - // we now only check among less elements, because the database is indexed to small lists - // item_scores are in increasing order in the index, and they serve also as ids of the policy rules - for (auto item_score_it = containerGetReverseIterator(vec); - item_score_it != containerGetReverseIteratorEnd(vec); - item_score_it++) { - auto db_items = policyGetItems(policy); - auto db_item = containerLookupByIndex(db_items, *item_score_it - 1); // rules are indexed/scored from 1 - if (*item_score_it > currentBest && match(item, db_item)) { - currentBest = *item_score_it; - return; - } else if (*item_score_it <= currentBest) { - // there is no need to look further as we can't improve the score anymore - return; - } - } - }; - - auto searchAndUpdateCurrentBest = [¤tBest, &index, &updateCurrentBest, this](boost::string_ref name_ref) { - // we need to create C-string for flatbuffers lookups - // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify - // input string and keeps only the length - std::string name(name_ref.data(), name_ref.size()); - - if (containerEmpty(index)) - return; - - // check if there are any rules for the name - auto fit = containerLookupByKey(index, name.c_str()); - if (!fit.first) - return; - - // check if there's any chance to get better score - if (policyIndexGetBestScore(fit.second) <= currentBest) - return; - - // look for better score - updateCurrentBest(policyIndexGetItemRefs(fit.second)); - }; - - auto prefixIndex = policyGetPrefixIndex(policy); - - // iterate over names - for (const auto &name: item.getNames()) { - // find and check the no-prefix rules - searchAndUpdateCurrentBest(name); - - // check the prefix rules - updateCurrentBest(prefixIndex); - } - - // check no-name rules - searchAndUpdateCurrentBest(""); - - // if a matching rule was found, return the decision - if (currentBest > 0) { - auto db_item = containerLookupByIndex(policyGetItems(policy), currentBest - 1); - return makeDecisionItem(itemGetDecisionItem(db_item)); - } - - // or if no matching rule was not found, return the default decision - return ldp_xml_parser::Decision::ANY; -} - void StorageBackendFlatbuffers::release() { file = nullptr; } @@ -225,81 +55,4 @@ bool StorageBackendFlatbuffers::initFromData(const uint8_t *mem, size_t size, bo return file != nullptr; } -/*************************************************/ -#define TYPE_HELPER(T, t) \ - template <> \ - struct type_helper<ldp_xml_parser::MatchItem##T> { \ - typedef FB::T##Set policy_set_type; \ - typedef FB::Policy##T policy_type; \ - }; \ - template <> \ - auto StorageBackendFlatbuffers::getPolicySet<ldp_xml_parser::MatchItem##T>() const { \ - assert(file); \ - return fileGet##T##Set(getFile()); \ - } - -TYPE_HELPER(Own, own) -TYPE_HELPER(Send, send) -TYPE_HELPER(Receive, receive) -TYPE_HELPER(Access, access) - -template <typename T, typename P> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, P policy) const { - return getDecisionItem(item, policy, typename ldp_serialization::PolicyContentType<P>::result()); -} - -template <typename T> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const T &item) const { - return getDecisionItem(item, setGetContextMandatory(getPolicySet<T>())); -} - -template <typename T> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const T &item) const { - return getDecisionItem(item, setGetContextDefault(getPolicySet<T>())); -} - -template <typename T> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const T &item) const { - return getDecisionItem(item, setGetUser(getPolicySet<T>()), uid); -} -template <typename T> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const T &item) const { - return getDecisionItem(item, setGetGroup(getPolicySet<T>()), gid); -} - -template <typename T> -bool StorageBackendFlatbuffers::existsPolicyForGroup(gid_t gid) const { - auto map = setGetGroup(getPolicySet<T>()); - - if (containerEmpty(map)) - return false; - - return containerLookupByKey(map, gid).first; -} - -#define T_INSTANTIATION(T) \ - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const ldp_xml_parser::MatchItem##T &item) const; \ - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const ldp_xml_parser::MatchItem##T &item) const; - -T_INSTANTIATION(Own) -T_INSTANTIATION(Send) -T_INSTANTIATION(Receive) -T_INSTANTIATION(Access) - -#undef T_INSTANTIATION - -#define T_INSTANTIATION2(T) \ - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const ldp_xml_parser::MatchItem##T &item) const; \ - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const ldp_xml_parser::MatchItem##T &item) const; \ - template bool StorageBackendFlatbuffers::existsPolicyForGroup<ldp_xml_parser::MatchItem##T>(gid_t) const; - -T_INSTANTIATION2(Own) -T_INSTANTIATION2(Send) -T_INSTANTIATION2(Receive) - -#undef T_INSTANTIATION2 - -StorageBackendFlatbuffers::StorageBackendFlatbuffers() {} -StorageBackendFlatbuffers::~StorageBackendFlatbuffers() {} - } diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index cf7d4e1..d0291aa 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -18,36 +18,15 @@ #include "include/fb_generated.h" #include "policy.hpp" #include "serialization_traits.hpp" -#include <boost/tokenizer.hpp> #include <memory> namespace ldp_serialized { class StorageBackendFlatbuffers { public: - StorageBackendFlatbuffers(); - ~StorageBackendFlatbuffers(); - bool initFromData(const uint8_t *serialized_data, size_t length, bool verify); void release(); - // Supported template parameters are: - // MatchPolicyOwn, MatchPolicySend, MatchPolicyReceive - // and - only for Contexts - MatchPolicyAccess - 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; - - // This works with T set to MatchItemOwn, MatchItemSend or MatchItemReceive - // This is needed for filtering mapGroups. Check NaivePolicyChecker. - template <typename T> - bool existsPolicyForGroup(gid_t gid) const; - const FB::File *getFile() const { return file; } @@ -205,40 +184,8 @@ public: size_t stringGetSize(const flatbuffers::String *str) const { return str->size(); } - typedef boost::tokenizer<boost::char_separator<char>> tokenizer; - private: const FB::File *file{nullptr}; - - template <typename MatchItem> - auto getPolicySet() const; - - template <typename T, typename P> - ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy, ldp_serialization::ItemsType) const; - - template <typename T, typename P> - ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy, ldp_serialization::TreeType) const; - - template <typename T, typename P> - ldp_xml_parser::DecisionItem getDecisionItem(const T &item, P policy) const; - - ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const FB::PolicySend *policy) const; - - template <typename MatchItem, typename Map> - ldp_xml_parser::DecisionItem getDecisionItem(const MatchItem &item, const Map &map, id_t id) const; - - auto getDecisionItemFromTree(const FB::PolicyOwnNode *node, - const tokenizer::iterator &tokens_end, - tokenizer::iterator &iterator) const; - - template <typename T, typename I> - bool match(const T &match, const I *i) const; - - bool match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const; - - ldp_xml_parser::DecisionItem makeDecisionItem(const FB::DecisionItem *item) const; - - boost::string_ref toStringRef(const flatbuffers::String *str) const; }; } diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp index 8337ee0..ac3c5bc 100644 --- a/src/internal/storage_backend_serialized.cpp +++ b/src/internal/storage_backend_serialized.cpp @@ -21,9 +21,11 @@ * THE SOFTWARE. */ #include "print_content.hpp" +#include "serialized_convert.hpp" #include "storage_backend_serialized.hpp" #include "transaction_guard.hpp" #include "tslog.hpp" +#include <boost/tokenizer.hpp> #include <cassert> #include <fcntl.h> #include <sys/mman.h> @@ -123,3 +125,239 @@ void StorageBackendSerialized::release() { impl.release(); } + +template <> auto StorageBackendSerialized::getPolicySet<ldp_xml_parser::MatchItemOwn>() const { + return impl.fileGetOwnSet(impl.getFile()); +} + +template <> auto StorageBackendSerialized::getPolicySet<ldp_xml_parser::MatchItemSend>() const { + return impl.fileGetSendSet(impl.getFile()); +} + +template <> auto StorageBackendSerialized::getPolicySet<ldp_xml_parser::MatchItemReceive>() const { + return impl.fileGetReceiveSet(impl.getFile()); +} + +template <> auto StorageBackendSerialized::getPolicySet<ldp_xml_parser::MatchItemAccess>() const { + return impl.fileGetAccessSet(impl.getFile()); +} + +template <typename DI> +ldp_xml_parser::DecisionItem StorageBackendSerialized::makeDecisionItem(const DI &item) const { + return ldp_xml_parser::DecisionItem(makeDecision(impl.decisionItemGetDecision(item)), + impl.stringGetCStr(impl.decisionItemGetPrivilege(item))); +} + +template <typename String> +boost::string_ref StorageBackendSerialized::toStringRef(const String &str) const { + return boost::string_ref(impl.stringGetCStr(str), impl.stringGetSize(str)); +} + +template <typename T, typename I> +bool StorageBackendSerialized::match(const T &match, const I &item) const { + return match.match(makeMessageType(impl.itemSrGetMessageType(item)), + toStringRef(impl.itemSrGetInterface(item)), + toStringRef(impl.itemSrGetPath(item)), + toStringRef(impl.itemSrGetMember(item)), + toStringRef(impl.itemSrGetName(item)), + impl.itemSrGetIsNamePrefix(item), + makeDecision(impl.decisionItemGetDecision(impl.itemGetDecisionItem(item)))); +} + +template <typename I> +bool StorageBackendSerialized::match(const ldp_xml_parser::MatchItemAccess &match, const I &item) const { + return match.match(makeBusAccessType(impl.itemAccessGetType(item)), impl.itemAccessGetUid(item), impl.itemAccessGetGid(item)); +} + +template <typename T, typename P> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy, ldp_serialization::ItemsType) const { + auto v = impl.policyGetItems(policy); + auto rend = impl.containerGetReverseIteratorEnd(v); + for (auto rit = impl.containerGetReverseIterator(v); rit != rend; ++rit) { + if (match(item, *rit)) + return makeDecisionItem(impl.itemGetDecisionItem(*rit)); + } + return ldp_xml_parser::Decision::ANY; +} + +template <typename P> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const P &policy) const { + if (!impl.policyHasIndex(policy)) + return getDecisionItem(item, policy, ldp_serialization::ItemsType()); // make it old way for old databases + + auto index = impl.policyGetIndex(policy); + + uint32_t currentBest = 0; + + auto updateCurrentBest = [¤tBest, &item, &policy, this](const auto &vec) { + // look from the back, the rule is the same as for the full database + // we now only check among less elements, because the database is indexed to small lists + // item_scores are in increasing order in the index, and they serve also as ids of the policy rules + for (auto item_score_it = impl.containerGetReverseIterator(vec); + item_score_it != impl.containerGetReverseIteratorEnd(vec); + item_score_it++) { + auto db_items = impl.policyGetItems(policy); + auto db_item = impl.containerLookupByIndex(db_items, *item_score_it - 1); // rules are indexed/scored from 1 + if (*item_score_it > currentBest && match(item, db_item)) { + currentBest = *item_score_it; + return; + } else if (*item_score_it <= currentBest) { + // there is no need to look further as we can't improve the score anymore + return; + } + } + }; + + auto searchAndUpdateCurrentBest = [¤tBest, &index, &updateCurrentBest, this](boost::string_ref name_ref) { + // we need to create C-string for the lookups + // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify + // input string and keeps only the length + std::string name(name_ref.data(), name_ref.size()); + + if (impl.containerEmpty(index)) + return; + + // check if there are any rules for the name + auto fit = impl.containerLookupByKey(index, name.c_str()); + if (!fit.first) + return; + + // check if there's any chance to get better score + if (impl.policyIndexGetBestScore(fit.second) <= currentBest) + return; + + // look for better score + updateCurrentBest(impl.policyIndexGetItemRefs(fit.second)); + }; + + auto prefixIndex = impl.policyGetPrefixIndex(policy); + + // iterate over names + for (const auto &name: item.getNames()) { + // find and check the no-prefix rules + searchAndUpdateCurrentBest(name); + + // check the prefix rules + updateCurrentBest(prefixIndex); + } + + // check no-name rules + searchAndUpdateCurrentBest(""); + + // if a matching rule was found, return the decision + if (currentBest > 0) { + auto db_item = impl.containerLookupByIndex(impl.policyGetItems(policy), currentBest - 1); + return makeDecisionItem(impl.itemGetDecisionItem(db_item)); + } + + // or if no matching rule was not found, return the default decision + return ldp_xml_parser::Decision::ANY; +} + +template <typename OwnNode> +auto StorageBackendSerialized::getDecisionItemFromTree(const OwnNode &node, + const tokenizer::iterator &tokens_end, + tokenizer::iterator &iterator) const { + if (iterator == tokens_end) { + if (makeDecision(impl.decisionItemGetDecision(impl.ownNodeGetDecisionItem(node))) != ldp_xml_parser::Decision::ANY) + return impl.ownNodeGetDecisionItem(node); + else + return impl.ownNodeGetPrefixDecisionItem(node); + } + + auto children = impl.ownNodeGetChildren(node); + + if (impl.containerEmpty(children)) + return impl.ownNodeGetPrefixDecisionItem(node); + + auto child = impl.containerLookupByKey(children, iterator->c_str()); + if (!child.first) + return impl.ownNodeGetPrefixDecisionItem(node); + + ++iterator; + auto child_decision = getDecisionItemFromTree(child.second, tokens_end, iterator); + if (makeDecision(impl.decisionItemGetDecision(child_decision)) == ldp_xml_parser::Decision::ANY) + return impl.ownNodeGetPrefixDecisionItem(node); + + return child_decision; +} + +template <typename T, typename P> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy, ldp_serialization::TreeType) const { + if (item.getName().length() == 0) + return ldp_xml_parser::Decision::DENY; + + boost::char_separator<char> separator("."); + tokenizer tokens(item.getName(), separator); + + auto iterator = tokens.begin(); + + return makeDecisionItem(getDecisionItemFromTree(impl.policyGetTree(policy), tokens.end(), iterator)); +} + +template <typename T, typename P> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy) const { + return getDecisionItem(item, policy, typename ldp_serialization::PolicyContentType<P>::result()); +} + +template <typename MatchItem> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextMandatory(const MatchItem &item) const { + return getDecisionItem(item, impl.setGetContextMandatory(getPolicySet<MatchItem>())); +} + +template <typename MatchItem> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextDefault(const MatchItem &item) const { + return getDecisionItem(item, impl.setGetContextDefault(getPolicySet<MatchItem>())); +} + +template <typename MatchItem, typename Map> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const MatchItem &item, const Map &map, id_t id) const { + if (impl.containerEmpty(map)) + return ldp_xml_parser::Decision::ANY; + + auto elem = impl.containerLookupByKey(map, id); + if (!elem.first) + return ldp_xml_parser::Decision::ANY; + return getDecisionItem(item, impl.setUserGroupGetPolicy(elem.second)); +} + +template <typename MatchItem> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemUser(uid_t uid, const MatchItem &item) const { + return getDecisionItem(item, impl.setGetUser(getPolicySet<MatchItem>()), uid); +} +template <typename MatchItem> +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemGroup(gid_t gid, const MatchItem &item) const { + return getDecisionItem(item, impl.setGetGroup(getPolicySet<MatchItem>()), gid); +} + +template <typename MatchItem> +bool StorageBackendSerialized::existsPolicyForGroup(gid_t gid) const { + auto map = impl.setGetGroup(getPolicySet<MatchItem>()); + + if (impl.containerEmpty(map)) + return false; + + return impl.containerLookupByKey(map, gid).first; +} + +#define T_INSTANTIATION(T) \ + template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextMandatory(const ldp_xml_parser::MatchItem##T &item) const; \ + template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextDefault(const ldp_xml_parser::MatchItem##T &item) const; + +T_INSTANTIATION(Own) +T_INSTANTIATION(Send) +T_INSTANTIATION(Receive) +T_INSTANTIATION(Access) + +#undef T_INSTANTIATION + +#define T_INSTANTIATION2(T) \ + template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemUser(uid_t uid, const ldp_xml_parser::MatchItem##T &item) const; \ + template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemGroup(gid_t gid, const ldp_xml_parser::MatchItem##T &item) const; \ + template bool StorageBackendSerialized::existsPolicyForGroup<ldp_xml_parser::MatchItem##T>(gid_t) const; + +T_INSTANTIATION2(Own) +T_INSTANTIATION2(Send) +T_INSTANTIATION2(Receive) + +#undef T_INSTANTIATION2 diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index 1074b76..e010b72 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -23,6 +23,7 @@ #include "policy.hpp" #include "serialization_backend.hpp" +#include <boost/tokenizer.hpp> #include <sys/types.h> namespace ldp_serialized { @@ -43,23 +44,18 @@ public: // MatchItemOwn, MatchItemSend, MatchItemReceive // and - only for Contexts - MatchItemAccess template <typename MatchItem> - ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const - { return impl.getDecisionItemContextMandatory(item); } + ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const; template <typename MatchItem> - ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const - { return impl.getDecisionItemContextDefault(item); } + ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const; template <typename MatchItem> - ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const - { return impl.getDecisionItemUser(uid, item); } + ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const; template <typename MatchItem> - ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const - { return impl.getDecisionItemGroup(gid, item); } + ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const; // This works with MatchItem set to MatchItemOwn, MatchItemSend or MatchItemReceive // This is needed for filtering mapGroups. Check NaivePolicyChecker. template <typename MatchItem> - bool existsPolicyForGroup(gid_t gid) const - { return impl.existsPolicyForGroup<MatchItem>(gid); } + bool existsPolicyForGroup(gid_t gid) const; private: typedef typename ldp_serialization::SerializationBackend::Storage Backend; @@ -75,6 +71,43 @@ private: void releaseMMap(); void releaseFD(); + + template <typename MatchItem> + auto getPolicySet() const; + + template <typename T, typename P> + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy, ldp_serialization::ItemsType) const; + + template <typename T, typename P> + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy, ldp_serialization::TreeType) const; + + template <typename T, typename P> + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy) const; + + template <typename P> + ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const P &policy) const; + + template <typename MatchItem, typename Map> + ldp_xml_parser::DecisionItem getDecisionItem(const MatchItem &item, const Map &map, id_t id) const; + + typedef boost::tokenizer<boost::char_separator<char>> tokenizer; + + template <typename OwnNode> + auto getDecisionItemFromTree(const OwnNode &node, + const tokenizer::iterator &tokens, + tokenizer::iterator &iterator) const; + + template <typename T, typename I> + bool match(const T &match, const I &item) const; + + template <typename I> + bool match(const ldp_xml_parser::MatchItemAccess &match, const I &item) const; + + template <typename DI> + ldp_xml_parser::DecisionItem makeDecisionItem(const DI &item) const; + + template <typename String> + boost::string_ref toStringRef(const String &str) const; }; } |