From: Andrew Bartlett Date: Thu, 8 Feb 2024 22:44:33 +0000 (+1300) Subject: samba-tool user getpassword: Also return the time a GMSA password is valid until X-Git-Tag: tdb-1.4.11~1666 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=2908a6d67bca58c9de6991cbe312276408a34b7a;p=thirdparty%2Fsamba.git samba-tool user getpassword: Also return the time a GMSA password is valid until Signed-off-by: Andrew Bartlett Reviewed-by: Douglas Bagnall --- diff --git a/python/samba/netcmd/user/readpasswords/common.py b/python/samba/netcmd/user/readpasswords/common.py index 27c8e6e4a2b..8af8be7341e 100644 --- a/python/samba/netcmd/user/readpasswords/common.py +++ b/python/samba/netcmd/user/readpasswords/common.py @@ -22,6 +22,7 @@ import base64 import builtins import binascii +import datetime import errno import io import os @@ -34,7 +35,8 @@ from samba.dcerpc import drsblobs, security, gmsa from samba.ndr import ndr_unpack from samba.netcmd import Command, CommandError from samba.samdb import SamDB - +from samba.nt_time import timedelta_from_nt_time_delta, nt_time_from_datetime +from samba.gkdi import MAX_CLOCK_SKEW # python[3]-gpgme is abandoned since ubuntu 1804 and debian 9 # have to use python[3]-gpg instead @@ -102,6 +104,8 @@ virtual_attributes = { "unicodePwd": { "flags": ldb.ATTR_FLAG_FORCE_BASE64_LDIF, }, + "virtualManagedPasswordQueryTime": { + }, } @@ -371,11 +375,16 @@ class GetPasswordCommand(Command): managed_password) calculated["OLDCLEARTEXT"] = \ unpacked_managed_password.passwords.previous + query_interval = unpacked_managed_password.passwords.query_interval calculated["GMSA:query_interval"] = \ - unpacked_managed_password.passwords.query_interval + query_interval + + query_time_datetime = \ + timedelta_from_nt_time_delta(query_interval) + datetime.datetime.now(tz=datetime.timezone.utc) - calculated["GMSA:unchanged_interval"] = \ - unpacked_managed_password.passwords.unchanged_interval + query_time_nttime = nt_time_from_datetime(query_time_datetime) + + calculated["GMSA:query_time"] = query_time_nttime # This password is useful for a keytab, but not for # authentication, so don't show or provide it as the new password @@ -387,9 +396,6 @@ class GetPasswordCommand(Command): calculated["Primary:CLEARTEXT"] = \ unpacked_managed_password.passwords.current - calculated["GMSA:unchanged_interval"] = \ - unpacked_managed_password.passwords.unchanged_interval - account_name = str(obj["sAMAccountName"][0]) if "userPrincipalName" in obj: account_upn = str(obj["userPrincipalName"][0]) @@ -786,6 +792,10 @@ class GetPasswordCommand(Command): v = get_wDigest(i, primary_wdigest, account_name, account_upn, domain, dns_domain) if v is None: continue + elif a == "virtualManagedPasswordQueryTime": + if "GMSA:query_time" not in calculated: + continue + v = str(calculated["GMSA:query_time"]) else: continue obj[a] = ldb.MessageElement(v, ldb.FLAG_MOD_REPLACE, vattr["raw_attr"]) diff --git a/python/samba/tests/samba_tool/user_getpassword_gmsa.py b/python/samba/tests/samba_tool/user_getpassword_gmsa.py index acd8907e992..bbb68c41b7e 100644 --- a/python/samba/tests/samba_tool/user_getpassword_gmsa.py +++ b/python/samba/tests/samba_tool/user_getpassword_gmsa.py @@ -26,6 +26,8 @@ import os sys.path.insert(0, "bin/python") os.environ["PYTHONUNBUFFERED"] = "1" +import datetime, shlex + from ldb import SCOPE_BASE from samba.credentials import MUST_USE_KERBEROS @@ -33,7 +35,8 @@ from samba.dcerpc import security, samr from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT from samba.netcmd.domain.models import User from samba.ndr import ndr_pack, ndr_unpack -from samba.tests import connect_samdb, delete_force +from samba.nt_time import nt_time_from_datetime +from samba.tests import connect_samdb, connect_samdb_env, delete_force from samba.tests import BlackboxTestCase @@ -88,7 +91,8 @@ class GMSAPasswordTest(BlackboxTestCase): cls.user = User.get(cls.samdb, username=cls.username) def getpassword(self, attrs): - cmd = f"user getpassword --attributes={attrs} {self.username}" + shattrs = shlex.quote(attrs) + cmd = f"user getpassword --attributes={shattrs} {self.username}" ldif = self.check_output(cmd).decode() res = self.samdb.parse_ldif(ldif) @@ -152,6 +156,22 @@ class GMSAPasswordTest(BlackboxTestCase): self.assertEqual(self.user.object_sid, connecting_user_sid) + def test_querytime(self): + user_msg = self.getpassword("virtualManagedPasswordQueryTime") + querytime = int(user_msg["virtualManagedPasswordQueryTime"][0]) + + # Just assert the number makes sense + self.assertGreater(querytime, nt_time_from_datetime(datetime.datetime.now(tz=datetime.timezone.utc))) + self.assertLess(querytime, nt_time_from_datetime(datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(hours = 21))) + + def test_querytime_unixtime(self): + user_msg = self.getpassword("virtualManagedPasswordQueryTime;format=UnixTime") + querytime = int(user_msg["virtualManagedPasswordQueryTime;format=UnixTime"][0]) + + # Just assert the number makes sense + self.assertGreater(querytime, datetime.datetime.now(tz=datetime.timezone.utc).timestamp()) + self.assertLess(querytime, (datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(hours = 21)).timestamp()) + @classmethod def _make_cmdline(cls, line): """Override to pass line as samba-tool subcommand instead.