From a78bad158bca59dadb93c9c52d6daefa1c52b9cf Mon Sep 17 00:00:00 2001 From: Richard Marian Thomaiyar Date: Mon, 24 Feb 2020 13:37:12 +0530 Subject: [PATCH] Use groupmems instead of getgrnam_r due to overlay With JFFS2 overlay, getgrnam_r during initial time returns the old group details as per the lower dir, instead of the overlay one but at the same time groupmems where returning proper values, which reads the file everytime. Hence replacing getgrnam_r with groupmems Tested: 1. Verified that when added multiple user and then doing BMC reset using ipmitool raw 6 2 doesn't reproduce the issue of user with only ssh group. (on 38 version source + this fix) 2. Updated using redfish to version 39 + this fix, and made sure issue doesn't happen. Note: For testing purpose added debug statements to dump ouput of both getgrnam_r & groupmems and able to see proper list only in groupmems when the issue is reproduced Signed-off-by: Richard Marian Thomaiyar Signed-off-by: jayaprakash Mutyala --- user_service.cpp | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/user_service.cpp b/user_service.cpp index c3c45bd..0a6b171 100644 --- a/user_service.cpp +++ b/user_service.cpp @@ -143,28 +143,26 @@ class ShadowService : public phosphor::user::UserServiceInterface getUsersInGroup(const std::string &groupName) const override { std::vector usersInGroup; - // Should be more than enough to get the pwd structure. - std::array buffer{}; - struct group grp; - struct group *grpPtr = &grp; - struct group *resultPtr; - - int status = getgrnam_r(groupName.c_str(), grpPtr, buffer.data(), - buffer.max_size(), &resultPtr); - - if (!status && (grpPtr == resultPtr)) + std::vector output; + try { - for (; *(grp.gr_mem) != NULL; ++(grp.gr_mem)) - { - usersInGroup.emplace_back(*(grp.gr_mem)); - } + output = phosphor::user::executeCmd("/usr/sbin/groupmems", "-l", + "-g", groupName.c_str()); } - else + catch (const phosphor::user::InternalFailure &e) { phosphor::logging::log( "Group not found", phosphor::logging::entry("GROUP=%s", groupName.c_str())); // Don't throw error, just return empty usersInGroup - fallback + return usersInGroup; + } + if (!output.empty()) + { + boost::algorithm::trim_right(output[0]); + boost::algorithm::split(usersInGroup, output[0], + boost::algorithm::is_any_of("\t "), + boost::token_compress_on); } return usersInGroup; } -- 2.7.4