API support to update password for special user

Provide API support to update password for special user.
This API will be used by OEM Command to update the special
user password - linux uid 0 (root user).
More details can be referred from
https://github.com/openbmc/docs/blob/master/user_management.md#deployment---out-of-factory

Tested:
1. Verified the API with OEM command implementation, and able to
configure the password for user exists in the system /etc/passwd.
2. Verified the negative case for failure

Change-Id: I3c2a7007587e52c7e713f0cd976f249dd84a5f75
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
diff --git a/user_channel/user_layer.cpp b/user_channel/user_layer.cpp
index b241564..adfc656 100644
--- a/user_channel/user_layer.cpp
+++ b/user_channel/user_layer.cpp
@@ -88,6 +88,12 @@
     return getUserAccessObject().setUserPassword(userId, userPassword);
 }
 
+ipmi_ret_t ipmiSetSpecialUserPassword(const std::string& userName,
+                                      const std::string& userPassword)
+{
+    return getUserAccessObject().setSpecialUserPassword(userName, userPassword);
+}
+
 ipmi_ret_t ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
                                 uint8_t& fixedUsers)
 {
diff --git a/user_channel/user_layer.hpp b/user_channel/user_layer.hpp
index 5f3567a..57f5317 100644
--- a/user_channel/user_layer.hpp
+++ b/user_channel/user_layer.hpp
@@ -138,6 +138,16 @@
 ipmi_ret_t ipmiUserSetUserPassword(const uint8_t userId,
                                    const char* userPassword);
 
+/** @brief set special user password (non-ipmi accounts)
+ *
+ *  @param[in] userName - user name
+ *  @param[in] userPassword - New Password
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiSetSpecialUserPassword(const std::string& userName,
+                                      const std::string& userPassword);
+
 /** @brief get user name
  *
  *  @param[in] userId - user id
diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp
index 6f4a79f..5ca2884 100644
--- a/user_channel/user_mgmt.cpp
+++ b/user_channel/user_mgmt.cpp
@@ -715,6 +715,17 @@
     return true;
 }
 
+ipmi_ret_t UserAccess::setSpecialUserPassword(const std::string& userName,
+                                              const std::string& userPassword)
+{
+    if (!pamUpdatePasswd(userName.c_str(), userPassword.c_str()))
+    {
+        log<level::DEBUG>("Failed to update password");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    return IPMI_CC_OK;
+}
+
 ipmi_ret_t UserAccess::setUserPassword(const uint8_t userId,
                                        const char* userPassword)
 {
diff --git a/user_channel/user_mgmt.hpp b/user_channel/user_mgmt.hpp
index 9ea9f6b..857be99 100644
--- a/user_channel/user_mgmt.hpp
+++ b/user_channel/user_mgmt.hpp
@@ -217,6 +217,16 @@
      */
     ipmi_ret_t setUserPassword(const uint8_t userId, const char* userPassword);
 
+    /** @brief to set special user password
+     *
+     *  @param[in] userName - user name
+     *  @param[in] userPassword  - new password of the user
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t setSpecialUserPassword(const std::string& userName,
+                                      const std::string& userPassword);
+
     /** @brief to set user privilege and access details
      *
      *  @param[in] userId - user id