tslog::log_verbose("Destination too long: ", destination, "\n");
return false;
}
- return static_cast<int>(policy_checker().check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::SEND));
+ return static_cast<int>(policy_checker().check(bus_type, user, group, label, matcher));
}
int __internal_can_send_multi_dest(bool bus_type,
while (destination[i]) {
matcher.addName(destination[i++]);
}
- return static_cast<int>(policy_checker().check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::SEND));
+ return static_cast<int>(policy_checker().check(bus_type, user, group, label, matcher));
}
int __internal_can_recv(bool bus_type,
tslog::log_verbose("Sender too long: ", sender, "\n");
return false;
}
- return static_cast<int>(policy_checker().check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::RECEIVE));
+ return static_cast<int>(policy_checker().check(bus_type, user, group, label, matcher));
}
int __internal_can_recv_multi(bool bus_type,
while (sender[i]) {
matcher.addName(sender[i++]);
}
- return static_cast<int>(policy_checker().check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::RECEIVE));
+ return static_cast<int>(policy_checker().check(bus_type, user, group, label, matcher));
}
return DecisionResult::DENY;
}
+DecisionItem NaivePolicyChecker::checkItemAccess(bool bus_type, const MatchItemAccess& item)
+{
+ const NaivePolicyDb& policy_db = getPolicyDb(bus_type);
+
+ DecisionItem ret = policy_db.getDecisionItem(PolicyType::CONTEXT, ContextType::MANDATORY, item);
+ // access rules can be defined only in default/mandatory context
+ // defining them elsewhere is considered as policy syntax error by dbus-daemon
+ // thus, no checking in user or group policies
+ if (ret.getDecision() == Decision::ANY)
+ ret = policy_db.getDecisionItem(PolicyType::CONTEXT, ContextType::DEFAULT, item);
+
+ return ret;
+}
+
DecisionResult NaivePolicyChecker::check(bool bus_type,
uid_t bus_owner,
uid_t uid,
gid_t gid,
const char* const label) {
- const auto &gids = *getPolicyDb(bus_type).getGroups(uid, gid, ItemType::ACCESS);
- auto ret = checkItem<MatchItemAccess>(bus_type, uid, gid, MatchItemAccess(uid, gids), ItemType::ACCESS);
+ const auto &gids = *getPolicyDb(bus_type).getGroups<MatchItemAccess>(uid, gid);
+ auto ret = checkItemAccess(bus_type, MatchItemAccess(uid, gids));
if (ret.getDecision() == Decision::ANY) {
if (bus_owner == uid) {
ret = Decision::ALLOW;
gid_t gid,
const char* const label,
const char* const name) {
- auto ret = checkItem<MatchItemOwn>(bus_type, uid, gid, name, ItemType::OWN);
+ auto ret = checkItem(bus_type, uid, gid, MatchItemOwn(name));
return parseDecision(ret, uid, label);
}
uid_t uid,
gid_t gid,
const char* const label,
- MatchItemSend &matcher,
- ItemType type) {
- auto ret = checkItem<MatchItemSend>(bus_type, uid, gid, matcher, type);
+ MatchItemSend &matcher) {
+ auto ret = checkItem(bus_type, uid, gid, matcher);
return parseDecision(ret, uid, label);
}
uid_t uid,
gid_t gid,
const char* const label,
- MatchItemReceive &matcher,
- ItemType type) {
- auto ret = checkItem<MatchItemReceive>(bus_type, uid, gid, matcher, type);
+ MatchItemReceive &matcher) {
+ auto ret = checkItem(bus_type, uid, gid, matcher);
return parseDecision(ret, uid, label);
}
template<typename T>
-DecisionItem NaivePolicyChecker::checkItem(bool bus_type, uid_t uid, gid_t gid, const T& item, const ItemType type) {
+DecisionItem NaivePolicyChecker::checkItem(bool bus_type, uid_t uid, gid_t gid, const T& item) {
const NaivePolicyDb& policy_db = getPolicyDb(bus_type);
- DecisionItem ret = policy_db.getDecisionItem<T>(PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY), item);
+ DecisionItem ret = policy_db.getDecisionItem(PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY), item);
- // access rules can be defined only in default/mandatory context
- // defining them elsewhere is considered as policy syntax error by dbus-daemon
- if (type != ItemType::ACCESS) {
- if (ret.getDecision() == Decision::ANY)
- ret = policy_db.getDecisionItem<T>(PolicyType::USER, PolicyTypeValue(uid), item);
+ if (ret.getDecision() == Decision::ANY)
+ ret = policy_db.getDecisionItem(PolicyType::USER, PolicyTypeValue(uid), item);
+
+ if (ret.getDecision() == Decision::ANY)
+ ret = checkGroupPolicies<T>(policy_db, uid, gid, item);
- if (ret.getDecision() == Decision::ANY)
- ret = checkGroupPolicies<T>(policy_db, uid, gid, item, type);
- }
if (ret.getDecision() == Decision::ANY)
- ret = policy_db.getDecisionItem<T>(PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), item);
+ ret = policy_db.getDecisionItem(PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), item);
return ret;
}
template<typename T>
-DecisionItem NaivePolicyChecker::checkGroupPolicies(const NaivePolicyDb& policy_db, uid_t uid, gid_t gid, const T& item, const ItemType type) {
- const auto *sgroups = policy_db.getGroups(uid, gid, type);
+DecisionItem NaivePolicyChecker::checkGroupPolicies(const NaivePolicyDb& policy_db, uid_t uid, gid_t gid, const T& item) {
+ const auto *sgroups = policy_db.getGroups<T>(uid, gid);
if (sgroups == nullptr)
return Decision::ANY;
- for (auto sgid : *sgroups) {
- DecisionItem ret = policy_db.getDecisionItem<T>(PolicyType::GROUP, PolicyTypeValue(sgid), item);
+ for (const auto sgid : *sgroups) {
+ DecisionItem ret = policy_db.getDecisionItem(PolicyType::GROUP, PolicyTypeValue(sgid), item);
if (ret.getDecision() != Decision::ANY)
return ret;
uid_t uid,
const char* label) const;
- /** Checks type P policy for given item
+ /** Checks policy for a given own, send or receive item
* \param[in] bus_type Bus type (system/session)
* \param[in] uid User id
* \param[in] gid User group id
- * \param[in] label User label
* \param[in] item Item to check
- * \param[in] type Item type
* \return Returns deny=0, allow=1 or cynara error
* \ingroup Implementation
*/
DecisionItem checkItem(bool bus_type,
uid_t uid,
gid_t gid,
- const T& item,
- const ItemType type);
+ const T& item);
+
+ /** Checks policy for a given access item
+ * \param[in] bus_type Bus type (system/session)
+ * \param[in] item Item to check
+ * \return Returns deny=0, allow=1 or cynara error
+ * \ingroup Implementation
+ */
+ DecisionItem checkItemAccess(bool bus_type, const MatchItemAccess &item);
template<typename T>
DecisionItem checkGroupPolicies(const NaivePolicyDb& policy_db,
uid_t uid,
gid_t gid,
- const T& item,
- const ItemType type);
+ const T& item);
/** Provides db handle for parsing purposes
*/
* \param[in] gid User group id
* \param[in] label User label
* \param[in] matcher Structure with multiple names to check
- * \param[in] type Item type
* \return Returns deny=0, allow=1 or cynara error
* \ingroup Implementation
*/
uid_t uid,
gid_t gid,
const char* const label,
- MatchItemSend &matcher,
- ItemType type);
+ MatchItemSend &matcher);
DecisionResult check(bool bus_type,
uid_t uid,
gid_t gid,
const char* const label,
- MatchItemReceive &matcher,
- ItemType type);
+ MatchItemReceive &matcher);
};
}
* Parameters: T - MatchItem* type
* field - one of m_*_set fields from NaivePolicyDb
*
- * The below DEF_GET_POLICY_SET defines specialization for MatchPolicy<T> template.
+ * 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<PolicyOwn> const;
*
* Thanks to this construction we do not need to manually specify PolicyOwn in functions that
* know MatchItemOwn - it is inferred.
typedef decltype(field)::type policy_type; \
typedef decltype(field) policy_set_type; \
}; \
+ template <> \
+ auto NaivePolicyDb::getPolicySet<T>() const -> decltype((field)) { \
+ return field; \
+ }
DEF_GET_POLICY_SET(MatchItemOwn, m_own_set)
DEF_GET_POLICY_SET(MatchItemSend, m_send_set)
return policy->getDecisionItem(item);
}
-template DecisionItem NaivePolicyDb::getDecisionItem<MatchItemOwn>(PolicyType policy_type, PolicyTypeValue policy_type_value, const MatchItemOwn &item) const;
-template DecisionItem NaivePolicyDb::getDecisionItem<MatchItemSend>(PolicyType policy_type, PolicyTypeValue policy_type_value, const MatchItemSend &item) const;
-template DecisionItem NaivePolicyDb::getDecisionItem<MatchItemReceive>(PolicyType policy_type, PolicyTypeValue policy_type_value, const MatchItemReceive &item) const;
-template DecisionItem NaivePolicyDb::getDecisionItem<MatchItemAccess>(PolicyType policy_type, PolicyTypeValue policy_type_value, const MatchItemAccess &item) const;
template <typename P>
const P *NaivePolicyDb::getPolicy(const PolicyType policy_type,
}
}
-const NaivePolicyDb::VGid *NaivePolicyDb::getGroups(uid_t uid, gid_t gid, const ItemType type) const
+template <typename T>
+const NaivePolicyDb::VGid *NaivePolicyDb::getGroups(uid_t uid, gid_t gid) const
{
- if (type == ItemType::OWN) {
- return &m_own_set.getMapGroup(uid);
- }
- if (type == ItemType::ACCESS) {
- return &m_access_set.getMapGroup(uid);
- }
-
if (uid == getuid() && gid == getgid())
- return (type == ItemType::SEND) ? &m_send_set.getMapGroup(uid) : &m_receive_set.getMapGroup(uid);
+ return &getPolicySet<T>().getMapGroup(uid);
pthread_mutex_lock(&mutexGroup);
- auto &vgid = (type == ItemType::SEND) ? m_send_set.getMapGroup(uid) : m_receive_set.getMapGroup(uid);
+ auto &vgid = getPolicySet<T>().getMapGroup(uid);
if (vgid.empty())
updateSupplementaryGroups(get_groups(uid, gid), uid, gid);
return &vgid;
}
+namespace ldp_xml_parser {
+template <>
+const NaivePolicyDb::VGid *NaivePolicyDb::getGroups<MatchItemOwn>(uid_t uid, gid_t) const
+{
+ return &m_own_set.getMapGroup(uid);
+}
+
+template <>
+const NaivePolicyDb::VGid *NaivePolicyDb::getGroups<MatchItemAccess>(uid_t uid, gid_t) const
+{
+ return &m_access_set.getMapGroup(uid);
+}
+} // namespace ldp_xml_parser
+
void NaivePolicyDb::initializeGroups(uid_t uid, gid_t gid)
{
pthread_mutex_lock(&mutexGroup);
for (const auto& i : m_items)
std::cerr << i << std::endl;
}
+
+/* Explicit instantiation is needed for used public template methods defined in this file.
+ */
+#define T_INSTANTIATION(T) \
+ template DecisionItem NaivePolicyDb::getDecisionItem<T>(PolicyType policy_type, PolicyTypeValue policy_type_value, const T &item) const; \
+ template const NaivePolicyDb::VGid *NaivePolicyDb::getGroups<T>(uid_t, gid_t) const;
+
+T_INSTANTIATION(MatchItemOwn)
+T_INSTANTIATION(MatchItemSend)
+T_INSTANTIATION(MatchItemReceive)
+T_INSTANTIATION(MatchItemAccess)
+
+#undef T_INSTANTIATION
template <typename T>
struct MatchPolicy; // provide policy_type in specializations
+ template <typename T>
+ const typename MatchPolicy<T>::policy_set_type &getPolicySet() const;
+
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:
void printContent() const;
- const VGid *getGroups(uid_t uid, gid_t gid, const ItemType type) const;
+ template <typename T>
+ const VGid *getGroups(uid_t uid, gid_t gid) const;
void initializeGroups(uid_t uid, gid_t gid);