From de373db52b40256b2cb27d457e37da05b5e18b87 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Wed, 20 Sep 2017 00:27:39 +0900 Subject: [PATCH] policy checking scheme: support supplementary group Change-Id: I163bc517d0fdcdbbc8b971ccdf927aa5df47af4a Signed-off-by: sanghyeok.oh --- src/internal/naive_policy_checker.cpp | 25 +++++++++--- src/internal/naive_policy_db.cpp | 77 ++++++++++++++++++++++++++++++++++- src/internal/naive_policy_db.hpp | 8 ++++ 3 files changed, 103 insertions(+), 7 deletions(-) mode change 100644 => 100755 src/internal/naive_policy_checker.cpp mode change 100644 => 100755 src/internal/naive_policy_db.hpp diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp old mode 100644 new mode 100755 index f684ac6..e743147 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -164,8 +164,16 @@ DecisionResult NaivePolicyChecker::checkItemOwn(bool bus_type, uid_t uid, gid_t ret = checkPolicyOwn(*curr_policy, item, privilege); } if (ret == Decision::ANY) { - if (policy_db.getPolicy(PolicyType::GROUP, PolicyTypeValue(gid), curr_policy)) - ret = checkPolicyOwn(*curr_policy, item, privilege); + auto sgroups = policy_db.getGroups(uid, gid); + if (sgroups != nullptr) { + for (auto sgid : *sgroups) { + if (policy_db.getPolicy(PolicyType::GROUP, PolicyTypeValue(sgid), curr_policy)) { + ret = checkPolicyOwn(*curr_policy, item, privilege); + if (ret != Decision::ANY) + break; + } + } + } } if (ret == Decision::ANY) { if (policy_db.getPolicy(PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), curr_policy)) @@ -178,7 +186,6 @@ DecisionResult NaivePolicyChecker::checkItemOwn(bool bus_type, uid_t uid, gid_t } } - DecisionResult NaivePolicyChecker::checkItemSR(bool bus_type, uid_t uid, gid_t gid, const char* label, const MatchItemSR& item, const ItemType type) { NaivePolicyDb& policy_db = getPolicyDb(bus_type); Decision ret = Decision::ANY; @@ -193,8 +200,16 @@ DecisionResult NaivePolicyChecker::checkItemSR(bool bus_type, uid_t uid, gid_t g ret = checkPolicySR(*curr_policy, item, privilege); } if (ret == Decision::ANY) { - if (policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(gid), curr_policy)) - ret = checkPolicySR(*curr_policy, item, privilege); + auto sgroups = policy_db.getGroups(uid, gid, type); + if (sgroups != nullptr) { + for (auto sgid : *sgroups) { + if (policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(sgid), curr_policy)) { + ret = checkPolicySR(*curr_policy, item, privilege); + if (ret != Decision::ANY) + break; + } + } + } } if (ret == Decision::ANY) { if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), curr_policy)) diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index b01f8da..4c88baf 100755 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -1,6 +1,9 @@ #include "naive_policy_db.hpp" #include "cynara.hpp" #include "tslog.hpp" +#include +#include +#include /** * \file @@ -67,8 +70,6 @@ void NaivePolicyDb::addItem(const PolicyType policy_type, addItem(m_own_set, policy_type, policy_type_value, item); } - - bool NaivePolicyDb::getPolicy(const PolicyType policy_type, const PolicyTypeValue policy_type_value, const NaivePolicyDb::PolicyOwn*& policy) const { @@ -294,3 +295,75 @@ void NaivePolicyDb::addItem(NaivePolicyDb::PolicyTypeSetOwn& set, break; } } + +void NaivePolicyDb::updateSupplementaryGroups(uid_t uid, gid_t gid) +{ + auto vsend = &mapSendGroup[uid]; + auto vrecv = &mapRecvGroup[uid]; + auto vown = &mapOwnGroup[uid]; + int ngroups = 100; + gid_t groups[100]; + + struct passwd *user_pw; + user_pw = getpwuid(uid); + if (!user_pw) { + if (tslog::enabled()) + std::cout << "getpwuid failed" << " uid:" << uid << " gid:" << gid << "\n"; + + (*vsend).push_back(gid); + (*vrecv).push_back(gid); + (*vown).push_back(gid); + + return ; + } + + if (getgrouplist(user_pw->pw_name, gid, groups, &ngroups) == -1) { + if (tslog::enabled()) + std::cout << "getgrouplist failed" << " uid:" << uid << " gid:" << gid << "\n"; + + (*vsend).push_back(gid); + (*vrecv).push_back(gid); + (*vown).push_back(gid); + + return ; + } + + /* insert supplementary group */ + for (int i = 0; i < ngroups; i++) { + if (m_send_set.group.find(groups[i]) != m_send_set.group.end()) + (*vsend).push_back(groups[i]); + if (m_receive_set.group.find(groups[i]) != m_receive_set.group.end()) + (*vrecv).push_back(groups[i]); + if (m_own_set.group.find(groups[i]) != m_own_set.group.end()) + (*vown).push_back(groups[i]); + } + + if ((*vsend).size() == 0 ) + (*vsend).push_back(-1); + if ((*vrecv).size() == 0 ) + (*vrecv).push_back(-1); + if ((*vown).size() == 0 ) + (*vown).push_back(-1); +} + +std::vector * NaivePolicyDb::getGroups(uid_t uid, gid_t gid) +{ + if (mapOwnGroup[uid].size() == 0) + updateSupplementaryGroups(uid, gid); + if (mapOwnGroup[uid][0] == (gid_t)-1) + return nullptr; + + return &mapOwnGroup[uid]; +} + +std::vector * NaivePolicyDb::getGroups(uid_t uid, gid_t gid, ItemType type) +{ + auto vgid = (type == ItemType::SEND) ? &mapSendGroup[uid] : &mapRecvGroup[uid]; + + if ((*vgid).size() == 0) + updateSupplementaryGroups(uid, gid); + if ((*vgid)[0] == (gid_t)-1) + return nullptr; + + return vgid; +} diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp old mode 100644 new mode 100755 index d4bf231..dc3ed61 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -30,6 +30,14 @@ namespace ldp_xml_parser { /** Database class, contains policies for ownership and send/receive */ class NaivePolicyDb { + private: + std::map> mapOwnGroup; + std::map> mapSendGroup; + std::map> mapRecvGroup; + void updateSupplementaryGroups(uid_t uid, gid_t gid); + public: + std::vector * getGroups(uid_t uid, gid_t gid); + std::vector *getGroups(uid_t uid, gid_t gid, const ItemType type); public: /** Class containing policy with send/receive rules */ class PolicySR { -- 2.7.4