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))
}
}
-
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;
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))
#include "naive_policy_db.hpp"
#include "cynara.hpp"
#include "tslog.hpp"
+#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
/**
* \file
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 {
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<gid_t> * 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<gid_t> * 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;
+}
{
/** Database class, contains policies for ownership and send/receive */
class NaivePolicyDb {
+ private:
+ std::map<gid_t, std::vector<gid_t>> mapOwnGroup;
+ std::map<gid_t, std::vector<gid_t>> mapSendGroup;
+ std::map<gid_t, std::vector<gid_t>> mapRecvGroup;
+ void updateSupplementaryGroups(uid_t uid, gid_t gid);
+ public:
+ std::vector<gid_t> * getGroups(uid_t uid, gid_t gid);
+ std::vector<gid_t> *getGroups(uid_t uid, gid_t gid, const ItemType type);
public:
/** Class containing policy with send/receive rules */
class PolicySR {