From 536ea32ddc61bc3f5ad34eada5788797e1771832 Mon Sep 17 00:00:00 2001 From: Tom Joseph Date: Fri, 14 Sep 2018 10:02:20 +0530 Subject: ldap: Add application to configure privilege for LDAP groups The application implements the xyz.openbmc_project.User.PrivilegeMapper D-Bus interface to configure privilege levels for LDAP groups. The Create method is used to create privilege mapping for the LDAP group. D-Bus object is created for each LDAP group and implements the D-Bus interface xyz.openbmc_project.User.PrivilegeMapperEntry. : Change-Id: I20935229a8a79ce1e52a857672a6a0085cb5ace4 Signed-off-by: Tom Joseph --- phosphor-ldap-mapper/Makefile.am | 19 ++++++ phosphor-ldap-mapper/ldap_mapper_entry.cpp | 62 +++++++++++++++++ phosphor-ldap-mapper/ldap_mapper_entry.hpp | 83 +++++++++++++++++++++++ phosphor-ldap-mapper/ldap_mapper_mgr.cpp | 88 ++++++++++++++++++++++++ phosphor-ldap-mapper/ldap_mapper_mgr.hpp | 103 +++++++++++++++++++++++++++++ phosphor-ldap-mapper/main.cpp | 25 +++++++ 6 files changed, 380 insertions(+) create mode 100644 phosphor-ldap-mapper/Makefile.am create mode 100644 phosphor-ldap-mapper/ldap_mapper_entry.cpp create mode 100644 phosphor-ldap-mapper/ldap_mapper_entry.hpp create mode 100644 phosphor-ldap-mapper/ldap_mapper_mgr.cpp create mode 100644 phosphor-ldap-mapper/ldap_mapper_mgr.hpp create mode 100644 phosphor-ldap-mapper/main.cpp (limited to 'phosphor-ldap-mapper') diff --git a/phosphor-ldap-mapper/Makefile.am b/phosphor-ldap-mapper/Makefile.am new file mode 100644 index 0000000..4aeca7b --- /dev/null +++ b/phosphor-ldap-mapper/Makefile.am @@ -0,0 +1,19 @@ +sbin_PROGRAMS = phosphor-ldap-mapper + +noinst_HEADERS = ldap_mapper_mgr.hpp \ + ldap_mapper_entry.hpp + +phosphor_ldap_mapper_SOURCES = \ + main.cpp \ + ldap_mapper_mgr.cpp \ + ldap_mapper_entry.cpp + +phosphor_ldap_mapper_LDFLAGS = $(SDBUSPLUS_LIBS) \ + $(PHOSPHOR_DBUS_INTERFACES_LIBS) \ + $(PHOSPHOR_LOGGING_LIBS) \ + -lstdc++fs + +phosphor_ldap_mapper_CXXFLAGS = $(SYSTEMD_CFLAGS) \ + $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \ + $(PHOSPHOR_LOGGING_CFLAGS) \ + -flto diff --git a/phosphor-ldap-mapper/ldap_mapper_entry.cpp b/phosphor-ldap-mapper/ldap_mapper_entry.cpp new file mode 100644 index 0000000..64d3578 --- /dev/null +++ b/phosphor-ldap-mapper/ldap_mapper_entry.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "ldap_mapper_entry.hpp" +#include "ldap_mapper_mgr.hpp" + +namespace phosphor +{ +namespace user +{ + +using namespace phosphor::logging; +using InvalidArgument = + sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument; +using Argument = xyz::openbmc_project::Common::InvalidArgument; + +LDAPMapperEntry::LDAPMapperEntry(sdbusplus::bus::bus &bus, const char *path, + const std::string &groupName, + const std::string &privilege, + LDAPMapperMgr &parent) : + Ifaces(bus, path, true), + id(std::stol(std::experimental::filesystem::path(path).filename())), + manager(parent) +{ + Ifaces::privilege(privilege, true); + Ifaces::groupName(groupName, true); + Ifaces::emit_object_added(); +} + +void LDAPMapperEntry::delete_(void) +{ + manager.deletePrivilegeMapper(id); +} + +std::string LDAPMapperEntry::groupName(std::string value) +{ + if (value == Ifaces::groupName()) + { + return value; + } + + manager.checkPrivilegeMapper(value); + return Ifaces::groupName(value); +} + +std::string LDAPMapperEntry::privilege(std::string value) +{ + if (value == Ifaces::privilege()) + { + return value; + } + + manager.checkPrivilegeLevel(value); + return Ifaces::privilege(value); +} + +} // namespace user +} // namespace phosphor diff --git a/phosphor-ldap-mapper/ldap_mapper_entry.hpp b/phosphor-ldap-mapper/ldap_mapper_entry.hpp new file mode 100644 index 0000000..689639d --- /dev/null +++ b/phosphor-ldap-mapper/ldap_mapper_entry.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include +#include + +namespace phosphor +{ +namespace user +{ + +namespace Base = sdbusplus::xyz::openbmc_project; +using Entry = + sdbusplus::xyz::openbmc_project::User::server::PrivilegeMapperEntry; +using Delete = sdbusplus::xyz::openbmc_project::Object::server::Delete; +using Ifaces = sdbusplus::server::object::object; + +// Forward declaration for LDAPMapperMgr +class LDAPMapperMgr; + +using Id = size_t; + +/** @class LDAPMapperEntry + * + * @brief This D-Bus object represents the privilege level for the LDAP group. + */ +class LDAPMapperEntry : public Ifaces +{ + public: + LDAPMapperEntry() = delete; + ~LDAPMapperEntry() = default; + LDAPMapperEntry(const LDAPMapperEntry &) = delete; + LDAPMapperEntry &operator=(const LDAPMapperEntry &) = delete; + LDAPMapperEntry(LDAPMapperEntry &&) = default; + LDAPMapperEntry &operator=(LDAPMapperEntry &&) = default; + + /** @brief Constructs LDAP privilege mapper entry object. + * + * @param[in] bus - sdbusplus handler + * @param[in] path - D-Bus path + * @param[in] privilege - the privilege for the group + * @param[in] parent - LDAP privilege mapper manager + */ + LDAPMapperEntry(sdbusplus::bus::bus &bus, const char *path, + const std::string &groupName, const std::string &privilege, + LDAPMapperMgr &parent); + + /** @brief Delete privilege mapper entry object + * + * This method deletes the privilege mapper entry. + */ + void delete_(void) override; + + /** @brief Update the group name of the mapper object + * + * @param[in] value - group name + * + * @return On success the updated group name + */ + std::string groupName(std::string value) override; + + /** @brief Update privilege associated with LDAP group + * + * @param[in] value - privilege level + * + * @return On success the updated privilege level + */ + std::string privilege(std::string value) override; + + using sdbusplus::xyz::openbmc_project::User::server::PrivilegeMapperEntry:: + privilege; + + using sdbusplus::xyz::openbmc_project::User::server::PrivilegeMapperEntry:: + groupName; + + private: + Id id; + LDAPMapperMgr &manager; +}; + +} // namespace user +} // namespace phosphor diff --git a/phosphor-ldap-mapper/ldap_mapper_mgr.cpp b/phosphor-ldap-mapper/ldap_mapper_mgr.cpp new file mode 100644 index 0000000..9fe40ad --- /dev/null +++ b/phosphor-ldap-mapper/ldap_mapper_mgr.cpp @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include "config.h" +#include "ldap_mapper_mgr.hpp" + +namespace phosphor +{ +namespace user +{ + +using namespace phosphor::logging; +using InvalidArgument = + sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument; +using Argument = xyz::openbmc_project::Common::InvalidArgument; +using PrivilegeMappingExists = sdbusplus::xyz::openbmc_project::User::Common:: + Error::PrivilegeMappingExists; + +LDAPMapperMgr::LDAPMapperMgr(sdbusplus::bus::bus &bus, const char *path) : + MapperMgrIface(bus, path), bus(bus), path(path) +{ +} + +ObjectPath LDAPMapperMgr::create(std::string groupName, std::string privilege) +{ + checkPrivilegeMapper(groupName); + checkPrivilegeLevel(privilege); + + entryId++; + + // Object path for the LDAP group privilege mapper entry + auto mapperObject = + std::string(mapperMgrRoot) + "/" + std::to_string(entryId); + + // Create mapping for LDAP privilege mapper entry + auto entry = std::make_unique( + bus, mapperObject.c_str(), groupName, privilege, *this); + + PrivilegeMapperList.emplace(entryId, std::move(entry)); + + return mapperObject; +} + +void LDAPMapperMgr::deletePrivilegeMapper(Id id) +{ + PrivilegeMapperList.erase(id); +} + +void LDAPMapperMgr::checkPrivilegeMapper(const std::string &groupName) +{ + if (groupName.empty()) + { + log("Group name is empty"); + elog(Argument::ARGUMENT_NAME("Group name"), + Argument::ARGUMENT_VALUE("Null")); + } + + for (const auto &val : PrivilegeMapperList) + { + if (val.second.get()->groupName() == groupName) + { + log("Group name already exists"); + elog(); + } + } +} + +void LDAPMapperMgr::checkPrivilegeLevel(const std::string &privilege) +{ + if (privilege.empty()) + { + log("Privilege level is empty"); + elog(Argument::ARGUMENT_NAME("Privilege level"), + Argument::ARGUMENT_VALUE("Null")); + } + + if (std::find(privMgr.begin(), privMgr.end(), privilege) == privMgr.end()) + { + log("Invalid privilege"); + elog(Argument::ARGUMENT_NAME("Privilege level"), + Argument::ARGUMENT_VALUE(privilege.c_str())); + } +} + +} // namespace user +} // namespace phosphor diff --git a/phosphor-ldap-mapper/ldap_mapper_mgr.hpp b/phosphor-ldap-mapper/ldap_mapper_mgr.hpp new file mode 100644 index 0000000..450626d --- /dev/null +++ b/phosphor-ldap-mapper/ldap_mapper_mgr.hpp @@ -0,0 +1,103 @@ +#pragma once + +#include +#include +#include "ldap_mapper_entry.hpp" +#include +#include +#include + +namespace phosphor +{ + +namespace user +{ + +using MapperMgrIface = + sdbusplus::xyz::openbmc_project::User::server::PrivilegeMapper; +using ObjectPath = sdbusplus::message::object_path; + +// D-Bus root for LDAP privilege mapper +constexpr auto mapperMgrRoot = "/xyz/openbmc_project/user/ldap"; + +/** @class LDAPMapperMgr + * + * @brief Responsible for managing LDAP groups to privilege mapping. + */ +class LDAPMapperMgr : public MapperMgrIface +{ + public: + LDAPMapperMgr() = delete; + ~LDAPMapperMgr() = default; + LDAPMapperMgr(const LDAPMapperMgr &) = delete; + LDAPMapperMgr &operator=(const LDAPMapperMgr &) = delete; + LDAPMapperMgr(LDAPMapperMgr &&) = delete; + LDAPMapperMgr &operator=(LDAPMapperMgr &&) = delete; + + /** @brief Constructs LDAPMapperMgr object. + * + * @param[in] bus - sdbusplus handler + * @param[in] path - D-Bus path + */ + LDAPMapperMgr(sdbusplus::bus::bus &bus, const char *path); + + /** @brief Creates a mapping for the group to the privilege + * + * @param[in] groupName - Group Name to which the privilege needs to be + * assigned. + * @param[in] privilege - The privilege role associated with the group. + * + * @return On success return the D-Bus object path of the created privilege + * mapper entry. + */ + ObjectPath create(std::string groupName, std::string privilege) override; + + /** @brief Delete privilege mapping for LDAP group + * + * This method deletes the privilege mapping + * + * @param[in] groupName - name of the LDAP group for which privilege + * mapping is to be deleted. + */ + void deletePrivilegeMapper(Id id); + + /** @brief Check if LDAP group privilege mapping requested is valid + * + * Check if the privilege mapping already exists for the LDAP group name + * and group name is empty. + * + * @param[in] groupName - LDAP group name + * + * @return throw exception if the conditions are not met. + */ + void checkPrivilegeMapper(const std::string &groupName); + + /** @brief Check if the privilege level is a valid one + * + * @param[in] privilege - Privilege level + * + * @return throw exception if the conditions are not met. + */ + void checkPrivilegeLevel(const std::string &privilege); + + private: + /** @brief sdbusplus handler */ + sdbusplus::bus::bus &bus; + + /** @brief object path for the manager object*/ + const std::string path; + + /** @brief available privileges container */ + std::set privMgr = {"priv-admin", "priv-operator", "priv-user", + "priv-callback"}; + + /** @brief Id of the last privilege mapper entry */ + Id entryId = 0; + + /** @brief container to hold privilege mapper objects */ + std::map> + PrivilegeMapperList; +}; + +} // namespace user +} // namespace phosphor diff --git a/phosphor-ldap-mapper/main.cpp b/phosphor-ldap-mapper/main.cpp new file mode 100644 index 0000000..b4a0650 --- /dev/null +++ b/phosphor-ldap-mapper/main.cpp @@ -0,0 +1,25 @@ +#include +#include +#include "config.h" +#include "ldap_mapper_mgr.hpp" + +int main(int argc, char** argv) +{ + auto bus = sdbusplus::bus::new_default(); + sdbusplus::server::manager::manager objManager( + bus, phosphor::user::mapperMgrRoot); + + phosphor::user::LDAPMapperMgr mapperMgr(bus, phosphor::user::mapperMgrRoot); + + // Claim the bus name for the application + bus.request_name(LDAP_MAPPER_MANAGER_BUSNAME); + + // Wait for client request + while (true) + { + // Process D-Bus calls + bus.process_discard(); + bus.wait(); + } + return 0; +} -- cgit v1.2.1