user_mgr: Fix user enabled state check

Detect user enabled state by checking user account expiration date
against current date.
Until this change user enabled state was detecting by checking user
account expiration date against 0 value. This check is incorrect
because it is false positive in case when account expiration date is in
the future but such user is reported as disabled.

Steps to reproduce the issue:
1. create some user on the system
2. set account expiration date for this user to happen in the future via
   'chage' or 'usermod' utilities (I set account expiration date to
   01-01-2100
3. check ```UserEnabled``` attribute for this user on D-Bus[1], it is
   false, though user is actually enabled
4. check ```Enabled``` attribute for this user in response to REST API
   request getting this user information [2], it is false

Tested:
1. create user1 on the system, set its account expiration date to the
   past (I set it to 01-01-2000), verify that user ```UserEnabled```
   attribute is false on D-Bus and ```Enabled``` is false in REST API
   response
2. create user2 in the system, set its account expiration date to the
   future (I set it to 01-01-2100), verify that user ```UserEnabled```
   attribute is true on D-Bus and ```Enabled``` is true in REST API
   response
3. create user3 in the system, verify that it is enabled

[1] ```
   busctl get-property xyz.openbmc_project.User.Manager \
   /xyz/openbmc_project/user/user1 xyz.openbmc_project.User.Attributes \
   UserEnabled
   ```
[2] ```
   curl -k -X GET https://<bmc>/redfish/v1/AccountService/Accounts/user1
   ```

Change-Id: Ie3dc735bc106bcd747f64cbaf94eace12e09847f
Signed-off-by: Ivan Moiseev <moiseev.ivan4w@yandex.com>
diff --git a/user_mgr.cpp b/user_mgr.cpp
index b8b3afd..f4e745f 100644
--- a/user_mgr.cpp
+++ b/user_mgr.cpp
@@ -144,6 +144,25 @@
     }
 }
 
+long currentDate()
+{
+    const auto date = std::chrono::duration_cast<std::chrono::days>(
+                          std::chrono::system_clock::now().time_since_epoch())
+                          .count();
+
+    if (date > std::numeric_limits<long>::max())
+    {
+        return std::numeric_limits<long>::max();
+    }
+
+    if (date < std::numeric_limits<long>::min())
+    {
+        return std::numeric_limits<long>::min();
+    }
+
+    return date;
+}
+
 } // namespace
 
 std::string getCSVFromVector(std::span<const std::string> vec)
@@ -998,11 +1017,20 @@
                             buffer.max_size(), &resultPtr);
     if (!status && (&spwd == resultPtr))
     {
-        if (resultPtr->sp_expire >= 0)
+        // according to chage/usermod code -1 means that account does not expire
+        // https://github.com/shadow-maint/shadow/blob/7a796897e52293efe9e210ab8da32b7aefe65591/src/chage.c
+        if (resultPtr->sp_expire < 0)
         {
-            return false; // user locked out
+            return true;
         }
-        return true;
+
+        // check account expiration date against current date
+        if (resultPtr->sp_expire > currentDate())
+        {
+            return true;
+        }
+
+        return false;
     }
     return false; // assume user is disabled for any error.
 }