lastPasswordChange: Rework to always give all entries

When listing users, the shadow file would get parsed for each user. Now,
the functions returns all entries instead.

Change-Id: Ib1ab12d8c30381ce5bf3f0afe3e577ed63e334b2
diff --git a/src/system/Authentication.cpp b/src/system/Authentication.cpp
index 8c6aa48..b264a27 100644
--- a/src/system/Authentication.cpp
+++ b/src/system/Authentication.cpp
@@ -96,7 +96,7 @@
     throw std::runtime_error("User " + username + " doesn't exist");
 }
 
-std::optional<std::string> Authentication::lastPasswordChange(const std::string& username)
+std::map<std::string, std::optional<std::string>> Authentication::lastPasswordChanges()
 {
     auto shadowFile = impl::file_open(m_etc_shadow.c_str(), "r");
     spwd entryBuf;
@@ -104,6 +104,7 @@
     auto buffer = std::make_unique<char[]>(bufLen);
     spwd* entry;
 
+    std::map<std::string, std::optional<std::string>> res;
     while (true) {
         auto ret = fgetspent_r(shadowFile.get(), &entryBuf, buffer.get(), bufLen, &entry);
         if (ret == ERANGE) {
@@ -122,16 +123,12 @@
 
         assert(entry);
 
-        if (username != entry->sp_namp) {
-            continue;
-        }
-
         using namespace std::chrono_literals;
         using TimeType = std::chrono::time_point<std::chrono::system_clock>;
-        return velia::utils::yangTimeFormat(TimeType(24h * entry->sp_lstchg));
+        res.emplace(entry->sp_namp, velia::utils::yangTimeFormat(TimeType(24h * entry->sp_lstchg)));
     }
 
-    return std::nullopt;
+    return res;
 }
 
 std::string Authentication::authorizedKeysPath(const std::string& username)
@@ -168,6 +165,7 @@
     auto buffer = std::make_unique<char[]>(bufLen);
     passwd* entry;
 
+    auto pwChanges = lastPasswordChanges();
     while (true) {
         auto ret = fgetpwent_r(passwdFile.get(), &entryBuf, buffer.get(), bufLen, &entry);
         if (ret == ERANGE) {
@@ -188,7 +186,9 @@
         User user;
         user.name = entry->pw_name;
         user.authorizedKeys = listKeys(user.name);
-        user.lastPasswordChange = lastPasswordChange(user.name);
+        if (auto it = pwChanges.find(user.name); it != pwChanges.end()) {
+            user.lastPasswordChange = it->second;
+        }
         res.emplace_back(user);
     }
 
diff --git a/src/system/Authentication.h b/src/system/Authentication.h
index 37362bb..1a83ef7 100644
--- a/src/system/Authentication.h
+++ b/src/system/Authentication.h
@@ -39,7 +39,7 @@
     void addKey(const std::string& username, const std::string& key);
     void removeKey(const std::string& username, const int index);
     std::string homeDirectory(const std::string& username);
-    std::optional<std::string> lastPasswordChange(const std::string& username);
+    std::map<std::string, std::optional<std::string>> lastPasswordChanges();
 
 
     velia::Log m_log;