Enable local users in the authentication reset cmd
Along with resetting the password and disabling LDAP,
local users should also be enabled again so one can
ssh into the system with a local user account again.
This is accomplished by setting the UserEnabled property
on every user object.
Tested: Saw users were enabled when running
ipmitool raw 0x3a 0x11 from the host.
Change-Id: I5a313cf82e2596cb797b8b9431631a3fe4ffca8d
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 7f3648f..3d369a0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,6 +3,7 @@
liboemhandler_la_SOURCES = oemhandler.cpp \
host-interface.cpp \
+ local_users.cpp \
org/open_power/OCC/Metrics/error.cpp
BUILT_SOURCES = org/open_power/OCC/Metrics/error.hpp \
diff --git a/configure.ac b/configure.ac
index a3c158a..dcf3b5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -69,6 +69,15 @@
[CONTROL_HOST_OBJ_MGR="/org/open_power/control"])
AC_DEFINE_UNQUOTED([CONTROL_HOST_OBJ_MGR], ["$CONTROL_HOST_OBJ_MGR"], [The Control Host D-Bus Object Manager])
+AC_DEFINE(MAPPER_BUS_NAME, "xyz.openbmc_project.ObjectMapper",
+ [The object mapper bus name])
+
+AC_DEFINE(MAPPER_OBJ, "/xyz/openbmc_project/object_mapper",
+ [The object mapper object path])
+
+AC_DEFINE(MAPPER_IFACE, "xyz.openbmc_project.ObjectMapper",
+ [The object mapper interface])
+
# Create configured output.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/local_users.cpp b/local_users.cpp
new file mode 100644
index 0000000..aa6519c
--- /dev/null
+++ b/local_users.cpp
@@ -0,0 +1,111 @@
+#include "config.h"
+#include "local_users.hpp"
+#include <host-ipmid/ipmid-host-cmd.hpp>
+#include <phosphor-logging/log.hpp>
+
+namespace local
+{
+namespace users
+{
+
+using namespace phosphor::logging;
+
+constexpr auto userIface = "xyz.openbmc_project.User.Attributes";
+constexpr auto propIface = "org.freedesktop.DBus.Properties";
+
+using DbusObjectPath = std::string;
+using DbusService = std::string;
+using DbusInterface = std::string;
+using ObjectTree = std::map<DbusObjectPath,
+ std::map<DbusService, std::vector<DbusInterface>>>;
+
+/**
+ * @brief Gets a list of all local users in the form of GetSubTree
+ * results.
+ *
+ * @param[out] users - Filled in with the results of a
+ * GetSubTree call that returns all users.
+ */
+void getUsers(ObjectTree& users)
+{
+ auto& bus = ipmid_get_sdbus_plus_handler();
+
+ try
+ {
+ auto method = bus->new_method_call(MAPPER_BUS_NAME,
+ MAPPER_OBJ,
+ MAPPER_IFACE,
+ "GetSubTree");
+ method.append("/xyz/openbmc_project/user/", 0,
+ std::vector<std::string>{userIface});
+
+ auto reply = bus->call(method);
+ if (reply.is_method_error())
+ {
+ throw std::runtime_error("Method error on GetSubTree call");
+ }
+
+ reply.read(users);
+ }
+ catch (sdbusplus::exception::SdBusError& e)
+ {
+ throw std::runtime_error(e.what());
+ }
+}
+
+/**
+ * @brief Enables the user passed in
+ *
+ * @param[in] path - The user object path
+ * @param[in] service - The service hosting the user
+ */
+void enableUser(const std::string& path, const std::string& service)
+{
+ auto& bus = ipmid_get_sdbus_plus_handler();
+
+ try
+ {
+ auto method = bus->new_method_call(service.c_str(),
+ path.c_str(),
+ propIface,
+ "Set");
+ sdbusplus::message::variant<bool> enabled{true};
+ method.append(userIface, "UserEnabled", enabled);
+
+ auto reply = bus->call(method);
+ if (reply.is_method_error())
+ {
+ throw std::runtime_error("Method error on property set call");
+ }
+ }
+ catch (sdbusplus::exception::SdBusError& e)
+ {
+ throw std::runtime_error(e.what());
+ }
+}
+
+ipmi_ret_t enableUsers()
+{
+ ObjectTree users;
+
+ try
+ {
+ getUsers(users);
+
+ for (const auto& user : users)
+ {
+ enableUser(user.first, user.second.begin()->first);
+ }
+ }
+ catch (std::runtime_error& e)
+ {
+ log<level::ERR>("Failed enabling local users",
+ entry("ERROR=%s", e.what()));
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ return IPMI_CC_OK;
+}
+
+}
+}
diff --git a/local_users.hpp b/local_users.hpp
new file mode 100644
index 0000000..e447a25
--- /dev/null
+++ b/local_users.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <host-ipmid/ipmid-api.h>
+
+namespace local
+{
+namespace users
+{
+
+/**
+ * @brief Enable all local BMC users
+ *
+ * Sets the UserEnabled property on all
+ * /xyz/openbmc_project/user/<user> objects.
+ *
+ * @return ipmi_ret_t - IPMI CC
+ */
+ipmi_ret_t enableUsers();
+
+}
+}
diff --git a/oemhandler.cpp b/oemhandler.cpp
index 3f443f2..99081d7 100644
--- a/oemhandler.cpp
+++ b/oemhandler.cpp
@@ -1,6 +1,7 @@
#include "oemhandler.hpp"
#include "config.h"
#include "elog-errors.hpp"
+#include "local_users.hpp"
#include <host-ipmid/ipmid-api.h>
#include <host-ipmid/ipmid-host-cmd.hpp>
#include <fstream>
@@ -211,7 +212,11 @@
ipmi_data_len_t data_len,
ipmi_context_t context)
{
- return IPMI_CC_OK;
+ ipmi_ret_t rc;
+
+ rc = local::users::enableUsers();
+
+ return rc;
}
namespace {