"UnixGroup",
"IdEntry",
"PasswdEntry",
+ "ShadowEntry",
"GroupEntry",
"InitgroupsEntry",
"LinuxToolsUtils",
return cls.FromDict(result[0])
+class ShadowEntry(object):
+ """
+ Result of ``getent shadow``
+ """
+
+ def __init__(
+ self,
+ name: str,
+ password: str,
+ last_changed: int,
+ min_days: int,
+ max_days: int,
+ warn_days: int,
+ inactivity_days: int,
+ expiration_date: int,
+ ) -> None:
+ self.name: str | None = name
+ """
+ User name.
+ """
+
+ self.password: str | None = password
+ """
+ User password.
+ """
+
+ self.last_changed: int = last_changed
+ """
+ Last password change.
+ """
+
+ self.min_days: int = min_days
+ """
+ Minimum number of days before a password change is allowed.
+ """
+
+ self.max_days: int = max_days
+ """
+ Maximum number of days a password is valid.
+ """
+
+ self.warn_days: int = warn_days
+ """
+ Number of days to warn the user before the password expires.
+ """
+
+ self.inactivity_days: int | None = inactivity_days
+ """
+ Number of days after a password expires before the account is disabled.
+ """
+
+ self.expiration_date: int | None = expiration_date
+ """
+ The account expiration date, expressed as the number of days since 1970-01-01 00:00:00 UTC.
+ """
+
+ def __str__(self) -> str:
+ return (
+ f"({self.name}:{self.password}:{self.last_changed}:"
+ f"{self.min_days}:{self.max_days}:{self.warn_days}:"
+ f"{self.inactivity_days}:{self.expiration_date}:)"
+ )
+
+ def __repr__(self) -> str:
+ return str(self)
+
+ @classmethod
+ def FromDict(cls, d: dict[str, Any]) -> ShadowEntry:
+ return cls(
+ name=d.get("username", None),
+ password=d.get("password", None),
+ last_changed=d.get("last_changed", None),
+ min_days=d.get("minimum", None),
+ max_days=d.get("maximum", None),
+ warn_days=d.get("warn", None),
+ inactivity_days=d.get("inactive", None),
+ expiration_date=d.get("expire", None),
+ )
+
+ @classmethod
+ def FromOutput(cls, stdout: str) -> ShadowEntry:
+ result = jc.parse("shadow", stdout)
+
+ if not isinstance(result, list):
+ raise TypeError(f"Unexpected type: {type(result)}, expecting list")
+
+ if len(result) != 1:
+ raise ValueError("More then one entry was returned")
+
+ return cls.FromDict(result[0])
+
+
class GroupEntry(object):
"""
Result of ``getent group``
"""
return self.__exec(PasswdEntry, "passwd", name, service)
+ def shadow(self, name: str | int, *, service: str | None = None) -> ShadowEntry | None:
+ """
+ Call ``getent shadow $name``
+
+ :param name: User name or id.
+ :type name: str | int
+ :param service: Service used, defaults to None
+ :type service: str | None
+ :return: shadow data, None if not found
+ :rtype: ShadowEntry | None
+ """
+ return self.__exec(ShadowEntry, "shadow", name, service)
+
def group(self, name: str | int, *, service: str | None = None) -> GroupEntry | None:
"""
Call ``getent group $name``