Allow sensor value override in mfg mode only
Issue: User is able to override sensor value even though system is not
in manufacturing mode
Fix: Code changes are done to patch sensor values when system is only
in manufacturing Mode.
Tested:
1. Redfish validator - passed for this new change
Case 1:
1. Enable manufacturing mode by pressing power button while bmc booting
2. Patch sensor values from Redfish.
Redfish URI:
PATCH https://<BMC-IP>/redfish/v1/Chassis/WC_Baseboard/Thermal
Body:
{
"Temperatures": [
{
"MemberId": "SSB_Temp",
"ReadingCelsius":112
}
]
}
Response:
{
"@odata.id": "/redfish/v1/Chassis/WC_Baseboard/Thermal",
"@odata.type": "#Thermal.v1_4_0.Thermal",
"Fans": [],
"Id": "Thermal",
"Name": "Thermal",
"Temperatures": []
}
3. Sensor value Overridden successfully
Case 2: Varified for ValidationUnsecure mode.
Case 3: Tested without SpecialMode mode
1. Stop the specialmodemgr.service service
2. Patch sensor values from Redfish.
3. Sensor value Overridden successfully
Case 4:
1. Disable manufacturing mode
Command: ipmitool raw 0x30 0xB4 3 0
Response: //Success
2. Patch sensor values from Redfish.
Redfish URI:
PATCH https://<BMC-IP>/redfish/v1/Chassis/WC_Baseboard/Thermal
Body:
{
"Temperatures": [
{
"MemberId": "SSB_Temp",
"ReadingCelsius":112
}
]
}
3. Returning proper error.
Response :
{
"error": {
"@Message.ExtendedInfo": [
{
"@odata.type": "/redfish/v1/$metadata#Message.v1_0_0.Message",
"Message": "The action Overriding of Sensor Value for
non manufacturing mode is not supported by the resource.",
"MessageArgs": [
"Overriding of Sensor Value for non manufacturing mode"
],
"MessageId": "Base.1.4.0.ActionNotSupported",
"Resolution": "The action supplied cannot be resubmitted to
the implementation. Perhaps the action was invalid, the
wrong resource was the target or the implementation
documentation may be of assistance.",
"Severity": "Critical"
}
],
"code": "Base.1.4.0.ActionNotSupported",
"message": "The action Overriding of Sensor Value for
non manufacturing mode is not supported by the resource."
}
}
Signed-off-by: jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
Change-Id: I34cd53fba939fb367310c531a050792ef749dd70
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index adcdc25..6c1f830 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -2598,15 +2598,15 @@
* @param res response object
* @param allCollections Collections extract from sensors' request patch info
* @param typeList TypeList of sensors for the resource queried
- * @param chassisSubNode Chassis Node for which the query has to happen
+ * @param chassisSubNode Chassis Node for which the query has to happen
*/
-void setSensorOverride(
+void setSensorsOverride(
std::shared_ptr<SensorsAsyncResp> sensorAsyncResp,
std::unordered_map<std::string, std::vector<nlohmann::json>>&
allCollections,
const std::string& chassisName, const std::vector<const char*> typeList)
{
- BMCWEB_LOG_INFO << "setSensorOverride for subNode"
+ BMCWEB_LOG_INFO << "setSensorsOverride for subNode"
<< sensorAsyncResp->chassisSubNode << "\n";
const char* propertyValueName;
@@ -2726,6 +2726,138 @@
getChassis(sensorAsyncResp, std::move(getChassisSensorListCb));
}
+bool isOverridingAllowed(const std::string& manufacturingModeStatus)
+{
+ if (manufacturingModeStatus ==
+ "xyz.openbmc_project.Control.Security.SpecialMode.Modes.Manufacturing")
+ {
+ return true;
+ }
+
+#ifdef BMCWEB_ENABLE_VALIDATION_UNSECURE_FEATURE
+ if (manufacturingModeStatus == "xyz.openbmc_project.Control.Security."
+ "SpecialMode.Modes.ValidationUnsecure")
+ {
+ return true;
+ }
+
+#endif
+
+ return false;
+}
+
+/**
+ * @brief Entry point for Checking the manufacturing mode before doing sensor
+ * override values of given sensor
+ *
+ * @param res response object
+ * @param allCollections Collections extract from sensors' request patch info
+ * @param typeList TypeList of sensors for the resource queried
+ * @param chassisSubNode Chassis Node for which the query has to happen
+ */
+void checkAndDoSensorsOverride(
+ std::shared_ptr<SensorsAsyncResp> sensorAsyncResp,
+ std::unordered_map<std::string, std::vector<nlohmann::json>>& allCollect,
+ const std::string& chassisName, const std::vector<const char*> typeList)
+{
+ BMCWEB_LOG_INFO << "checkAndDoSensorsOverride for subnode"
+ << sensorAsyncResp->chassisSubNode << "\n";
+
+ const std::array<std::string, 1> interfaces = {
+ "xyz.openbmc_project.Security.SpecialMode"};
+
+ crow::connections::systemBus->async_method_call(
+ [sensorAsyncResp, allCollect, chassisName,
+ typeList](const boost::system::error_code ec,
+ const GetSubTreeType& resp) mutable {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG
+ << "Error in querying GetSubTree with Object Mapper. "
+ << ec;
+ messages::internalError(sensorAsyncResp->res);
+ return;
+ }
+ if (!resp.size())
+ {
+ // Special mode manager doesn't exist, proceed with sensor
+ // override
+ setSensorsOverride(sensorAsyncResp, allCollect, chassisName,
+ typeList);
+ return;
+ }
+
+ if (resp.size() != 1)
+ {
+ BMCWEB_LOG_DEBUG << "Queried object count mismatch. ";
+ messages::internalError(sensorAsyncResp->res);
+ return;
+ }
+ const std::string& path = resp[0].first;
+ const std::string& serviceName = resp[0].second.begin()->first;
+
+ if (path.empty() || serviceName.empty())
+ {
+ BMCWEB_LOG_DEBUG
+ << "Path or service name is returned as empty. ";
+ messages::internalError(sensorAsyncResp->res);
+ return;
+ }
+
+ // Sensor override is allowed only in manufacturing mode or
+ // validation unsecure mode .
+ crow::connections::systemBus->async_method_call(
+ [sensorAsyncResp, allCollect, chassisName, typeList,
+ path](const boost::system::error_code ec,
+ std::variant<std::string>& getManufactMode) mutable {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG
+ << "Error in querying Special mode property " << ec;
+ messages::internalError(sensorAsyncResp->res);
+ return;
+ }
+
+ const std::string* manufacturingModeStatus =
+ std::get_if<std::string>(&getManufactMode);
+
+ if (nullptr == manufacturingModeStatus)
+ {
+ BMCWEB_LOG_DEBUG << "Sensor override mode is not "
+ "Enabled. Returning ... ";
+ messages::internalError(sensorAsyncResp->res);
+ return;
+ }
+
+ if (isOverridingAllowed(*manufacturingModeStatus))
+ {
+ BMCWEB_LOG_INFO << "Manufacturing mode is Enabled. "
+ "Proceeding further... ";
+ setSensorsOverride(sensorAsyncResp, allCollect,
+ chassisName, typeList);
+ }
+ else
+ {
+ BMCWEB_LOG_WARNING
+ << "Manufacturing mode is not Enabled...can't "
+ "Override the sensor value. ";
+
+ messages::actionNotSupported(
+ sensorAsyncResp->res,
+ "Overriding of Sensor Value for non "
+ "manufacturing mode");
+ return;
+ }
+ },
+ serviceName, path, "org.freedesktop.DBus.Properties", "Get",
+ "xyz.openbmc_project.Security.SpecialMode", "SpecialMode");
+ },
+
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", 5, interfaces);
+}
+
class SensorCollection : public Node
{
public: