summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac10
-rw-r--r--phosphor-ldap-mapper/Makefile.am6
-rw-r--r--phosphor-ldap-mapper/ldap_mapper_entry.cpp17
-rw-r--r--phosphor-ldap-mapper/ldap_mapper_entry.hpp9
-rw-r--r--phosphor-ldap-mapper/ldap_mapper_mgr.cpp37
-rw-r--r--phosphor-ldap-mapper/ldap_mapper_mgr.hpp5
-rw-r--r--phosphor-ldap-mapper/ldap_mapper_serialize.cpp95
-rw-r--r--phosphor-ldap-mapper/ldap_mapper_serialize.hpp33
-rw-r--r--phosphor-ldap-mapper/main.cpp6
9 files changed, 214 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index fa32305..c190307 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,6 +24,16 @@ AC_ARG_VAR(LDAP_MAPPER_MANAGER_BUSNAME, [The Dbus busname LDAP privilege mapper
AS_IF([test "x$LDAP_MAPPER_MANAGER_BUSNAME" == "x"], [LDAP_MAPPER_MANAGER_BUSNAME="xyz.openbmc_project.LDAP.PrivilegeMapper"])
AC_DEFINE_UNQUOTED([LDAP_MAPPER_MANAGER_BUSNAME], ["$LDAP_MAPPER_MANAGER_BUSNAME"], [The Dbus busname LDAP privilege mapper application])
+AC_ARG_VAR(LDAP_MAPPER_PERSIST_PATH, [Path of directory containing LDAP groups privilege mapping])
+AS_IF([test "x$LDAP_MAPPER_PERSIST_PATH" == "x"], \
+ [LDAP_MAPPER_PERSIST_PATH="/var/lib/phosphor-ldap-mapper/groups"])
+AC_DEFINE_UNQUOTED([LDAP_MAPPER_PERSIST_PATH], ["$LDAP_MAPPER_PERSIST_PATH"], \
+ [Path of directory containing LDAP groups privilege mapping])
+
+AC_ARG_VAR(CLASS_VERSION, [Class version to register with Cereal])
+AS_IF([test "x$CLASS_VERSION" == "x"], [CLASS_VERSION=1])
+AC_DEFINE_UNQUOTED([CLASS_VERSION], [$CLASS_VERSION], [Class version to register with Cereal])
+
# Default crypt algorithm to choose if one not found in shadow file
# Per crypt(3), 1 is for MD5
AC_ARG_VAR(DEFAULT_CRYPT_ALGO, [The default crypt algorithm if one not found in shadow])
diff --git a/phosphor-ldap-mapper/Makefile.am b/phosphor-ldap-mapper/Makefile.am
index 4aeca7b..c2896ba 100644
--- a/phosphor-ldap-mapper/Makefile.am
+++ b/phosphor-ldap-mapper/Makefile.am
@@ -1,12 +1,14 @@
sbin_PROGRAMS = phosphor-ldap-mapper
noinst_HEADERS = ldap_mapper_mgr.hpp \
- ldap_mapper_entry.hpp
+ ldap_mapper_entry.hpp \
+ ldap_mapper_serialize.hpp
phosphor_ldap_mapper_SOURCES = \
main.cpp \
ldap_mapper_mgr.cpp \
- ldap_mapper_entry.cpp
+ ldap_mapper_entry.cpp \
+ ldap_mapper_serialize.cpp
phosphor_ldap_mapper_LDFLAGS = $(SDBUSPLUS_LIBS) \
$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
diff --git a/phosphor-ldap-mapper/ldap_mapper_entry.cpp b/phosphor-ldap-mapper/ldap_mapper_entry.cpp
index 64d3578..95f381d 100644
--- a/phosphor-ldap-mapper/ldap_mapper_entry.cpp
+++ b/phosphor-ldap-mapper/ldap_mapper_entry.cpp
@@ -7,6 +7,7 @@
#include "config.h"
#include "ldap_mapper_entry.hpp"
#include "ldap_mapper_mgr.hpp"
+#include "ldap_mapper_serialize.hpp"
namespace phosphor
{
@@ -31,6 +32,14 @@ LDAPMapperEntry::LDAPMapperEntry(sdbusplus::bus::bus &bus, const char *path,
Ifaces::emit_object_added();
}
+LDAPMapperEntry::LDAPMapperEntry(sdbusplus::bus::bus &bus, const char *path,
+ LDAPMapperMgr &parent) :
+ Ifaces(bus, path, true),
+ id(std::stol(std::experimental::filesystem::path(path).filename())),
+ manager(parent)
+{
+}
+
void LDAPMapperEntry::delete_(void)
{
manager.deletePrivilegeMapper(id);
@@ -44,7 +53,9 @@ std::string LDAPMapperEntry::groupName(std::string value)
}
manager.checkPrivilegeMapper(value);
- return Ifaces::groupName(value);
+ auto val = Ifaces::groupName(value);
+ serialize(*this, id);
+ return val;
}
std::string LDAPMapperEntry::privilege(std::string value)
@@ -55,7 +66,9 @@ std::string LDAPMapperEntry::privilege(std::string value)
}
manager.checkPrivilegeLevel(value);
- return Ifaces::privilege(value);
+ auto val = Ifaces::privilege(value);
+ serialize(*this, id);
+ return val;
}
} // namespace user
diff --git a/phosphor-ldap-mapper/ldap_mapper_entry.hpp b/phosphor-ldap-mapper/ldap_mapper_entry.hpp
index 689639d..ea8a0bc 100644
--- a/phosphor-ldap-mapper/ldap_mapper_entry.hpp
+++ b/phosphor-ldap-mapper/ldap_mapper_entry.hpp
@@ -46,6 +46,15 @@ class LDAPMapperEntry : public Ifaces
const std::string &groupName, const std::string &privilege,
LDAPMapperMgr &parent);
+ /** @brief Constructs LDAP privilege mapper entry object
+ *
+ * @param[in] bus - sdbusplus handler
+ * @param[in] path - D-Bus path
+ * @param[in] parent - LDAP privilege mapper manager
+ */
+ LDAPMapperEntry(sdbusplus::bus::bus &bus, const char *path,
+ LDAPMapperMgr &parent);
+
/** @brief Delete privilege mapper entry object
*
* This method deletes the privilege mapper entry.
diff --git a/phosphor-ldap-mapper/ldap_mapper_mgr.cpp b/phosphor-ldap-mapper/ldap_mapper_mgr.cpp
index 9fe40ad..a321331 100644
--- a/phosphor-ldap-mapper/ldap_mapper_mgr.cpp
+++ b/phosphor-ldap-mapper/ldap_mapper_mgr.cpp
@@ -5,6 +5,7 @@
#include <phosphor-logging/elog-errors.hpp>
#include "config.h"
#include "ldap_mapper_mgr.hpp"
+#include "ldap_mapper_serialize.hpp"
namespace phosphor
{
@@ -38,6 +39,8 @@ ObjectPath LDAPMapperMgr::create(std::string groupName, std::string privilege)
auto entry = std::make_unique<phosphor::user::LDAPMapperEntry>(
bus, mapperObject.c_str(), groupName, privilege, *this);
+ serialize(*entry, entryId);
+
PrivilegeMapperList.emplace(entryId, std::move(entry));
return mapperObject;
@@ -45,6 +48,11 @@ ObjectPath LDAPMapperMgr::create(std::string groupName, std::string privilege)
void LDAPMapperMgr::deletePrivilegeMapper(Id id)
{
+ // Delete the persistent representation of the privilege mapper.
+ fs::path mapperPath(LDAP_MAPPER_PERSIST_PATH);
+ mapperPath /= std::to_string(id);
+ fs::remove(mapperPath);
+
PrivilegeMapperList.erase(id);
}
@@ -84,5 +92,34 @@ void LDAPMapperMgr::checkPrivilegeLevel(const std::string &privilege)
}
}
+void LDAPMapperMgr::restore()
+{
+ namespace fs = std::experimental::filesystem;
+
+ fs::path dir(LDAP_MAPPER_PERSIST_PATH);
+ if (!fs::exists(dir) || fs::is_empty(dir))
+ {
+ return;
+ }
+
+ for (auto &file : fs::directory_iterator(dir))
+ {
+ std::string id = file.path().filename().c_str();
+ size_t idNum = std::stol(id);
+ auto entryPath = std::string(mapperMgrRoot) + '/' + id;
+ auto entry = std::make_unique<phosphor::user::LDAPMapperEntry>(
+ bus, entryPath.c_str(), *this);
+ if (deserialize(file.path(), *entry))
+ {
+ entry->Ifaces::emit_object_added();
+ PrivilegeMapperList.emplace(idNum, std::move(entry));
+ if (idNum > entryId)
+ {
+ entryId = idNum;
+ }
+ }
+ }
+}
+
} // namespace user
} // namespace phosphor
diff --git a/phosphor-ldap-mapper/ldap_mapper_mgr.hpp b/phosphor-ldap-mapper/ldap_mapper_mgr.hpp
index 450626d..b2617ca 100644
--- a/phosphor-ldap-mapper/ldap_mapper_mgr.hpp
+++ b/phosphor-ldap-mapper/ldap_mapper_mgr.hpp
@@ -80,6 +80,11 @@ class LDAPMapperMgr : public MapperMgrIface
*/
void checkPrivilegeLevel(const std::string &privilege);
+ /** @brief Construct LDAP mapper entry D-Bus objects from their persisted
+ * representations.
+ */
+ void restore();
+
private:
/** @brief sdbusplus handler */
sdbusplus::bus::bus &bus;
diff --git a/phosphor-ldap-mapper/ldap_mapper_serialize.cpp b/phosphor-ldap-mapper/ldap_mapper_serialize.cpp
new file mode 100644
index 0000000..534e0a1
--- /dev/null
+++ b/phosphor-ldap-mapper/ldap_mapper_serialize.cpp
@@ -0,0 +1,95 @@
+#include <cereal/archives/binary.hpp>
+#include <cereal/types/string.hpp>
+#include <fstream>
+#include <phosphor-logging/log.hpp>
+#include "config.h"
+#include "ldap_mapper_serialize.hpp"
+
+// Register class version
+// From cereal documentation;
+// "This macro should be placed at global scope"
+CEREAL_CLASS_VERSION(phosphor::user::LDAPMapperEntry, CLASS_VERSION);
+
+namespace phosphor
+{
+namespace user
+{
+
+using namespace phosphor::logging;
+
+/** @brief Function required by Cereal to perform serialization.
+ *
+ * @tparam Archive - Cereal archive type (binary in this case).
+ * @param[in] archive - reference to cereal archive.
+ * @param[in] entry- const reference to LDAP mapper entry
+ * @param[in] version - Class version that enables handling a serialized data
+ * across code levels
+ */
+template <class Archive>
+void save(Archive& archive, const LDAPMapperEntry& entry,
+ const std::uint32_t version)
+{
+ archive(entry.groupName(), entry.privilege());
+}
+
+/** @brief Function required by Cereal to perform deserialization.
+ *
+ * @tparam Archive - Cereal archive type (binary in our case).
+ * @param[in] archive - reference to cereal archive.
+ * @param[out] entry - LDAP mapper entry to be read
+ * @param[in] version - Class version that enables handling a serialized data
+ * across code levels
+ */
+template <class Archive>
+void load(Archive& archive, LDAPMapperEntry& entry, const std::uint32_t version)
+{
+ std::string groupName{};
+ std::string privilege{};
+
+ archive(groupName, privilege);
+
+ entry.sdbusplus::xyz::openbmc_project::User::server::PrivilegeMapperEntry::
+ groupName(groupName, true);
+ entry.sdbusplus::xyz::openbmc_project::User::server::PrivilegeMapperEntry::
+ privilege(privilege, true);
+}
+
+fs::path serialize(const LDAPMapperEntry& entry, Id id)
+{
+ fs::path dir(LDAP_MAPPER_PERSIST_PATH);
+ auto path = dir / std::to_string(id);
+ std::ofstream os(path.c_str(), std::ios::binary);
+ cereal::BinaryOutputArchive oarchive(os);
+ oarchive(entry);
+ return path;
+}
+
+bool deserialize(const fs::path& path, LDAPMapperEntry& entry)
+{
+ try
+ {
+ if (fs::exists(path))
+ {
+ std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
+ cereal::BinaryInputArchive iarchive(is);
+ iarchive(entry);
+ return true;
+ }
+ return false;
+ }
+ catch (cereal::Exception& e)
+ {
+ log<level::ERR>(e.what());
+ fs::remove(path);
+ return false;
+ }
+ catch (const std::length_error& e)
+ {
+ log<level::ERR>(e.what());
+ fs::remove(path);
+ return false;
+ }
+}
+
+} // namespace user
+} // namespace phosphor
diff --git a/phosphor-ldap-mapper/ldap_mapper_serialize.hpp b/phosphor-ldap-mapper/ldap_mapper_serialize.hpp
new file mode 100644
index 0000000..f48f73c
--- /dev/null
+++ b/phosphor-ldap-mapper/ldap_mapper_serialize.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <experimental/filesystem>
+#include "ldap_mapper_entry.hpp"
+
+namespace phosphor
+{
+namespace user
+{
+
+namespace fs = std::experimental::filesystem;
+
+/** @brief Serialize and persist LDAP privilege mapper D-Bus object
+ *
+ * @param[in] entry - LDAP privilege mapper entry
+ * @param[in] id - filename of the persisted LDAP mapper entry
+ *
+ * @return fs::path - pathname of persisted error file
+ */
+fs::path serialize(const LDAPMapperEntry& entry, Id id);
+
+/** @brief Deserialize a persisted LDAP privilege mapper into a D-Bus object
+ *
+ * @param[in] path - pathname of persisted file
+ * @param[in/out] entry - reference to LDAP privilege mapper entry object
+ * which is the target of deserialization.
+ *
+ * @return bool - true if the deserialization was successful, false otherwise.
+ */
+bool deserialize(const fs::path& path, LDAPMapperEntry& entry);
+
+} // namespace user
+} // namespace phosphor
diff --git a/phosphor-ldap-mapper/main.cpp b/phosphor-ldap-mapper/main.cpp
index b4a0650..15c9802 100644
--- a/phosphor-ldap-mapper/main.cpp
+++ b/phosphor-ldap-mapper/main.cpp
@@ -11,6 +11,12 @@ int main(int argc, char** argv)
phosphor::user::LDAPMapperMgr mapperMgr(bus, phosphor::user::mapperMgrRoot);
+ // Create a directory to persist errors.
+ std::experimental::filesystem::create_directories(LDAP_MAPPER_PERSIST_PATH);
+
+ // Restore the serialized LDAP group privilege mapping.
+ mapperMgr.restore();
+
// Claim the bus name for the application
bus.request_name(LDAP_MAPPER_MANAGER_BUSNAME);
OpenPOWER on IntegriCloud