]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
samba-tool user getpassword: Also return the time a GMSA password is valid until
authorAndrew Bartlett <abartlet@samba.org>
Thu, 8 Feb 2024 22:44:33 +0000 (11:44 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 29 Feb 2024 01:31:31 +0000 (01:31 +0000)
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
python/samba/netcmd/user/readpasswords/common.py
python/samba/tests/samba_tool/user_getpassword_gmsa.py

index 27c8e6e4a2be6f2b151f34602d392d3975b06a15..8af8be7341e5ab0e2ed681a689da78543d10ec51 100644 (file)
@@ -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"])
index acd8907e9928f7af2845cc0efc11bf0e418315e2..bbb68c41b7e6c9bd280bf183ce72c5be1708eb53 100644 (file)
@@ -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.