[SCM] Samba Shared Repository - branch master updated
Douglas Bagnall
dbagnall at samba.org
Thu Dec 21 03:05:02 UTC 2023
The branch, master has been updated
via 31637d40371 WHATSNEW: Add entry for "samba-tool user get-kerberos-ticket"
via 7c9fa2804b8 selftest: Add tests for "samba-tool user get-kerberos-ticket"
via d8b3b1fed9a python/netcmd: Improve documentation for "samba-tool user getpassword"
via 8eadc19f35e python/netcmd: Add "samba-tool user get-kerberos-ticket" to get a ticket for a gMSA
via a39e19dfa75 WHATSNEW: Add entry for "samba-tool user getpassword" changes
via 128710c2f3c python: tests: blackbox test for GMSA
via 339e7ae186d samba-tool: document that -H can be used with gMSA accounts
via 72f0c99a7aa samba-tool: fix some grammar in getpassword docstrings
via 113d2aab30f samba-tool: Make samba-tool user getpassword support a ';previous=1' option
via 2c54a754842 samba-tool user getpassword: Prepare to support a ;previous=1 option, change behaviour for ;rounds=
via 175a13ca134 selftest: Modify expected output of 'samba-tool user getpassword' to be more consistant
via 562bde91b44 selftest: fix failing user setpassword test
via 8b67a86584d samba-tool: Add support for getting the generated unicodePwd for a gMSA account
via 9557140f196 netcmd: user: samba-tool support to allow non-windows use of GMSA accounts (show password)
via 23326105cd6 samba-tool user getpassword: Use UTF16_MUNGED charcnv to map "UTF16" to UTF8
via f89a2065a68 samba-tool: Prepare to allow samba-tool user getpasswords to operate against a remote server
via c5a2d57e5fa netcmd: models: add object sid field to User model
via bf37d538e63 netcmd: getpassword: print OK message on stderr
via 587642a63ad selftest: Avoid assertTrue() and assertFalse() where a better test exists
via ba29bb54cad selftest: require named parameters for callers of connect_samdb() and connect_samdb_ex()
via 5e823724389 selftest: add get_env_credentials()
via 18fd2e4ff35 selftest: make get_loadparm a classmethod
via 9f8786f0edc selftest: make _get_attribute use parse_ldif
via a30657d42f4 selftest: make _get_attribute a method on base class
via 6ed2b445f55 selftest: pep8: fix incorrect number of blank lines
via 2f5b06253bb selftest: remove unused imports from virtualCryptSHA tests
via b236856a3e3 selftest: function _get_attribute() was in two places
from 8cfc6ea9232 Revert "rpc_server:srvsvc - retrieve share ACL via root context"
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 31637d403719613a536028ef35ef8504288b8946
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 18 17:24:26 2023 +1300
WHATSNEW: Add entry for "samba-tool user get-kerberos-ticket"
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Autobuild-User(master): Douglas Bagnall <dbagnall at samba.org>
Autobuild-Date(master): Thu Dec 21 03:04:12 UTC 2023 on atb-devel-224
commit 7c9fa2804b8e0ef3cef0365da58a8bae4f170840
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Dec 15 17:10:42 2023 +1300
selftest: Add tests for "samba-tool user get-kerberos-ticket"
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit d8b3b1fed9a30edd16d04b2094ceaf8e3571a7de
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Dec 14 14:50:05 2023 +1300
python/netcmd: Improve documentation for "samba-tool user getpassword"
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 8eadc19f35ee90ca318c43a90fef7fcdbec263bd
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Dec 14 14:43:44 2023 +1300
python/netcmd: Add "samba-tool user get-kerberos-ticket" to get a ticket for a gMSA
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit a39e19dfa759c62cd59545da8ead13d2ae49e6e0
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 18 17:14:27 2023 +1300
WHATSNEW: Add entry for "samba-tool user getpassword" changes
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 128710c2f3c1ee3dd73eba8d755ea7caeb9f3196
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Thu Dec 7 15:53:01 2023 +1300
python: tests: blackbox test for GMSA
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 339e7ae186d5fe3569652f173988858b7e9651e4
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Fri Dec 15 15:12:42 2023 +1300
samba-tool: document that -H can be used with gMSA accounts
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 72f0c99a7aa4f44cbb1b96be73e14d1f506fff7b
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Fri Dec 15 15:10:39 2023 +1300
samba-tool: fix some grammar in getpassword docstrings
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 113d2aab30fc84e5434d5475982ae579d8433b70
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 11 20:56:16 2023 +1300
samba-tool: Make samba-tool user getpassword support a ';previous=1' option
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 2c54a754842e0deb6e6a4944fde6dec37d7742a2
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 11 20:55:10 2023 +1300
samba-tool user getpassword: Prepare to support a ;previous=1 option, change behaviour for ;rounds=
This will return the previous password, but the pattern is to include
the option in the returned attribute name, so we need to use
vatter["raw_attr"], not 'a'.
This changes the behaviour for the ;rounds= option used when we hold
the plaintext password (possibly under GPG encryption).
This is now consistant with other parameters in the LDAP attribute,
and is now included in the returned attribute name.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 175a13ca134a2c990ae20df83f80ed4194055c96
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 11 21:40:44 2023 +1300
selftest: Modify expected output of 'samba-tool user getpassword' to be more consistant
This is consistant with ;format= support for time attributes and
other users of this parameter style elsewhere in LDAP.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 562bde91b44620a475923b90d76eb2eaf5109141
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Fri Dec 15 12:36:14 2023 +1300
selftest: fix failing user setpassword test
A side effect of being able to generate at read time unicodePwd for a gMSA is that we can also generate the unicodePwd from a virtualSambaGPG password.
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 8b67a86584d20b59a1e2af7c37f342870a505192
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 11 20:49:44 2023 +1300
samba-tool: Add support for getting the generated unicodePwd for a gMSA account
This pre-hashed value may be more practical to use than the random "UTF-16"
password. In particular it is easy to compare with the DB values.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 9557140f1969650192569da2168677195de01933
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Fri Dec 1 16:14:16 2023 +1300
netcmd: user: samba-tool support to allow non-windows use of GMSA accounts (show password)
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 23326105cd612d8c1fea1a4d7f1f3c5117d5a674
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Dec 12 16:38:13 2023 +1300
samba-tool user getpassword: Use UTF16_MUNGED charcnv to map "UTF16" to UTF8
This copes with random invalid UTF-16 as seen with gMSA accounts.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit f89a2065a686a20532813e8b2e80987da61333e1
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 11 16:54:57 2023 +1300
samba-tool: Prepare to allow samba-tool user getpasswords to operate against a remote server
While passwords are not normally available for read, Group Managed Service Account
passwords are, as this is how they are distributed.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit c5a2d57e5fa8d42e3a1028a4274163b56a16f079
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Thu Dec 7 15:29:27 2023 +1300
netcmd: models: add object sid field to User model
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit bf37d538e63791d740a9a0bc50557915e7401c0e
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Thu Dec 7 15:28:04 2023 +1300
netcmd: getpassword: print OK message on stderr
This makes it easier to machine parse the output in tests
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 587642a63ad3d35718e0d789a8227bcac4debe36
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 11 17:41:21 2023 +1300
selftest: Avoid assertTrue() and assertFalse() where a better test exists
This allows the unittest framework to show the strings that the value was
not found in.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit ba29bb54cada2e0d01a8b6f7a7587696d44fa1f9
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Wed Dec 13 14:03:14 2023 +1300
selftest: require named parameters for callers of connect_samdb() and connect_samdb_ex()
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 5e823724389984379ae1f624cf1051a77179ef28
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Wed Dec 13 14:00:45 2023 +1300
selftest: add get_env_credentials()
This is like get_credentials but works for tests that are based
on environment variable for usernames and passwords.
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 18fd2e4ff35e4ec3491a1836c1896c1417126b08
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Wed Dec 13 14:00:00 2023 +1300
selftest: make get_loadparm a classmethod
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 9f8786f0edc3427361a6777a7f1868a66ed4cc83
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Thu Dec 14 12:57:09 2023 +1300
selftest: make _get_attribute use parse_ldif
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit a30657d42f4368027fe699e817228d35391244b5
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Wed Dec 13 16:50:18 2023 +1300
selftest: make _get_attribute a method on base class
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 6ed2b445f5508fce69fe9080ff21cf1a71595f08
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Wed Dec 13 16:41:11 2023 +1300
selftest: pep8: fix incorrect number of blank lines
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 2f5b06253bb01e56518d1f7fdfb8a7b542f19609
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Wed Dec 13 16:40:17 2023 +1300
selftest: remove unused imports from virtualCryptSHA tests
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit b236856a3e38a390ffd980fb9bd507801df826c1
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Wed Dec 13 16:39:06 2023 +1300
selftest: function _get_attribute() was in two places
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
-----------------------------------------------------------------------
Summary of changes:
WHATSNEW.txt | 42 +++++
docs-xml/manpages/samba-tool.8.xml | 5 +
python/samba/netcmd/domain/models/user.py | 3 +-
python/samba/netcmd/user/__init__.py | 7 +-
python/samba/netcmd/user/readpasswords/__init__.py | 1 +
python/samba/netcmd/user/readpasswords/common.py | 118 +++++++++----
.../user/readpasswords/get_kerberos_ticket.py | 146 +++++++++++++++
.../samba/netcmd/user/readpasswords/getpassword.py | 38 ++--
.../netcmd/user/readpasswords/syncpasswords.py | 6 +-
python/samba/netcmd/user/setexpiry.py | 2 +-
python/samba/tests/__init__.py | 31 +++-
python/samba/tests/samba_tool/user.py | 9 +-
.../tests/samba_tool/user_get_kerberos_ticket.py | 195 +++++++++++++++++++++
.../tests/samba_tool/user_getpassword_gmsa.py | 171 ++++++++++++++++++
.../samba/tests/samba_tool/user_virtualCryptSHA.py | 100 +++++------
.../tests/samba_tool/user_virtualCryptSHA_base.py | 30 +---
.../tests/samba_tool/user_virtualCryptSHA_gpg.py | 105 +++++------
.../user_virtualCryptSHA_userPassword.py | 59 ++++---
python/samba/tests/samba_tool/user_wdigest.py | 5 +-
.../samba-tool-user-get-kerberos-ticket | 5 +
selftest/knownfail.d/user_getpassword_gmsa | 1 +
source4/selftest/tests.py | 5 +
22 files changed, 847 insertions(+), 237 deletions(-)
create mode 100644 python/samba/netcmd/user/readpasswords/get_kerberos_ticket.py
create mode 100644 python/samba/tests/samba_tool/user_get_kerberos_ticket.py
create mode 100644 python/samba/tests/samba_tool/user_getpassword_gmsa.py
create mode 100644 selftest/knownfail.d/samba-tool-user-get-kerberos-ticket
create mode 100644 selftest/knownfail.d/user_getpassword_gmsa
Changeset truncated at 500 lines:
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 12dff08271c..aba6726840c 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -38,6 +38,48 @@ source tree. While there will be some differences - due to features
chosen by packagers - comparing these lists with the build dependencies
in a package may locate other dependencies we no longer require.
+samba-tool user getpassword / syncpasswords ;rounds= change
+-----------------------------------------------------------
+
+The password access tool "samba-tool user getpassword" and the
+password sync tool "samba-tool user syncpasswords" allow attributes to
+be chosen for output, and accept parameters like
+pwdLastSet;format=GeneralizedTime
+
+These attributes then appear, in the same format, as the attributes in
+the LDIF output. This was not the case for the ;rounds= parameter of
+virtualCryptSHA256 and virtualCryptSHA512, for example as
+--attributes="virtualCryptSHA256;rounds=50000"
+
+This release makes the behaviour consistent between these two
+features. Installations using GPG-encrypted passwords (or plaintext
+storage) and the rounds= option, will find the output has changed
+
+from:
+virtualCryptSHA256: {CRYPT}$5$rounds=2561$hXem.M9onhM9Vuix$dFdSBwF
+
+to:
+virtualCryptSHA256;rounds=2561: {CRYPT}$5$rounds=2561$hXem.M9onhM9Vuix$dFdSBwF
+
+Group Managed service account client-side features
+--------------------------------------------------
+
+samba-tool has been extended to provide client-side support for Group
+Managed Service accounts. These accounts have passwords that change
+automatically, giving the advantages of service isolation without risk
+of poor, unchanging passwords.
+
+Where possible, Samba's existing samba-tool password handling
+commands, which in the past have only operated against the local
+sam.ldb have been extended to permit operation against a remote server
+with authenticated access to "-H ldap://$DCNAME"
+
+Supported operations include:
+ - reading the current and previous gMSA password via
+ "samba-tool user getpassword"
+ - writing a Kerberos Ticket Granting Ticket (TGT) to a local
+ credentials cache with a new command
+ "samba-tool user get-kerberos-ticket"
REMOVED FEATURES
================
diff --git a/docs-xml/manpages/samba-tool.8.xml b/docs-xml/manpages/samba-tool.8.xml
index 6b3a73020e3..3471b0e1991 100644
--- a/docs-xml/manpages/samba-tool.8.xml
+++ b/docs-xml/manpages/samba-tool.8.xml
@@ -2743,6 +2743,11 @@
<para>Gets the password of a user account.</para>
</refsect3>
+<refsect3>
+ <title>user get-kerberos-ticket <replaceable>username</replaceable> [options]</title>
+ <para>Gets a Kerberos Ticket Granting Ticket as the account.</para>
+</refsect3>
+
<refsect3>
<title>user syncpasswords <replaceable>--cache-ldb-initialize</replaceable> [options]</title>
<para>Syncs the passwords of all user accounts, using an optional script.</para>
diff --git a/python/samba/netcmd/domain/models/user.py b/python/samba/netcmd/domain/models/user.py
index 79e30453532..7b0785a0fb3 100644
--- a/python/samba/netcmd/domain/models/user.py
+++ b/python/samba/netcmd/domain/models/user.py
@@ -24,7 +24,7 @@ from ldb import Dn
from samba.dsdb import DS_GUID_USERS_CONTAINER
-from .fields import DnField, StringField
+from .fields import DnField, SIDField, StringField
from .model import Model
@@ -32,6 +32,7 @@ class User(Model):
username = StringField("sAMAccountName")
assigned_policy = DnField("msDS-AssignedAuthNPolicy")
assigned_silo = DnField("msDS-AssignedAuthNPolicySilo")
+ object_sid = SIDField("objectSid")
def __str__(self):
"""Return username rather than cn for User model."""
diff --git a/python/samba/netcmd/user/__init__.py b/python/samba/netcmd/user/__init__.py
index 6175e651ed9..fab657c2278 100644
--- a/python/samba/netcmd/user/__init__.py
+++ b/python/samba/netcmd/user/__init__.py
@@ -30,8 +30,10 @@ from .getgroups import cmd_user_getgroups
from .list import cmd_user_list
from .move import cmd_user_move
from .password import cmd_user_password
-from .readpasswords import (cmd_user_getpassword, cmd_user_show,
- cmd_user_syncpasswords)
+from .readpasswords import (cmd_user_getpassword,
+ cmd_user_show,
+ cmd_user_syncpasswords,
+ cmd_user_get_kerberos_ticket)
from .rename import cmd_user_rename
from .sensitive import cmd_user_sensitive
from .setexpiry import cmd_user_setexpiry
@@ -57,6 +59,7 @@ class cmd_user(SuperCommand):
subcommands["setprimarygroup"] = cmd_user_setprimarygroup()
subcommands["setpassword"] = cmd_user_setpassword()
subcommands["getpassword"] = cmd_user_getpassword()
+ subcommands["get-kerberos-ticket"] = cmd_user_get_kerberos_ticket()
subcommands["syncpasswords"] = cmd_user_syncpasswords()
subcommands["edit"] = cmd_user_edit()
subcommands["show"] = cmd_user_show()
diff --git a/python/samba/netcmd/user/readpasswords/__init__.py b/python/samba/netcmd/user/readpasswords/__init__.py
index 8ca999b0215..75ba31365b7 100644
--- a/python/samba/netcmd/user/readpasswords/__init__.py
+++ b/python/samba/netcmd/user/readpasswords/__init__.py
@@ -22,3 +22,4 @@
from .getpassword import cmd_user_getpassword
from .show import cmd_user_show
from .syncpasswords import cmd_user_syncpasswords
+from .get_kerberos_ticket import cmd_user_get_kerberos_ticket
diff --git a/python/samba/netcmd/user/readpasswords/common.py b/python/samba/netcmd/user/readpasswords/common.py
index 02f7d36f5fc..6d44881823d 100644
--- a/python/samba/netcmd/user/readpasswords/common.py
+++ b/python/samba/netcmd/user/readpasswords/common.py
@@ -30,7 +30,7 @@ import ldb
from samba import credentials, nttime2float
from samba.auth import system_session
from samba.common import get_bytes, get_string
-from samba.dcerpc import drsblobs, security
+from samba.dcerpc import drsblobs, security, gmsa
from samba.ndr import ndr_unpack
from samba.netcmd import Command, CommandError
from samba.samdb import SamDB
@@ -99,6 +99,9 @@ virtual_attributes = {
"virtualSambaGPG": {
"flags": ldb.ATTR_FLAG_FORCE_BASE64_LDIF,
},
+ "unicodePwd": {
+ "flags": ldb.ATTR_FLAG_FORCE_BASE64_LDIF,
+ },
}
@@ -188,23 +191,23 @@ class GetPasswordCommand(Command):
flags = ldb.ATTR_FLAG_HIDDEN | virtual_attributes[a].get("flags", 0)
samdb.schema_attribute_add(a, flags, ldb.SYNTAX_OCTET_STRING)
- def connect_system_samdb(self, url, allow_local=False, verbose=False):
+ def connect_for_passwords(self, url,
+ creds=None,
+ require_ldapi=True,
+ verbose=False):
# using anonymous here, results in no authentication
# which means we can get system privileges via
# the privileged ldapi socket
- creds = credentials.Credentials()
- creds.set_anonymous()
+ anon_creds = credentials.Credentials()
+ anon_creds.set_anonymous()
- if url is None and allow_local:
+ if url is None and not require_ldapi:
pass
elif url.lower().startswith("ldapi://"):
+ creds = anon_creds
pass
- elif url.lower().startswith("ldap://"):
- raise CommandError("--url ldap:// is not supported for this command")
- elif url.lower().startswith("ldaps://"):
- raise CommandError("--url ldaps:// is not supported for this command")
- elif not allow_local:
+ elif require_ldapi:
raise CommandError("--url requires an ldapi:// url for this command")
if verbose:
@@ -213,19 +216,20 @@ class GetPasswordCommand(Command):
samdb = SamDB(url=url, session_info=system_session(),
credentials=creds, lp=self.lp)
- try:
- #
- # Make sure we're connected as SYSTEM
- #
- res = samdb.search(base='', scope=ldb.SCOPE_BASE, attrs=["tokenGroups"])
- assert len(res) == 1
- sids = res[0].get("tokenGroups")
- assert len(sids) == 1
- sid = ndr_unpack(security.dom_sid, sids[0])
- assert str(sid) == security.SID_NT_SYSTEM
- except Exception as msg:
- raise CommandError("You need to specify an URL that gives privileges as SID_NT_SYSTEM(%s)" %
- (security.SID_NT_SYSTEM))
+ if require_ldapi or url is None:
+ try:
+ #
+ # Make sure we're connected as SYSTEM
+ #
+ res = samdb.search(base='', scope=ldb.SCOPE_BASE, attrs=["tokenGroups"])
+ assert len(res) == 1
+ sids = res[0].get("tokenGroups")
+ assert len(sids) == 1
+ sid = ndr_unpack(security.dom_sid, sids[0])
+ assert str(sid) == security.SID_NT_SYSTEM
+ except Exception as msg:
+ raise CommandError("You need to specify an URL that gives privileges as SID_NT_SYSTEM(%s)" %
+ (security.SID_NT_SYSTEM))
self.inject_virtual_attributes(samdb)
@@ -322,6 +326,7 @@ class GetPasswordCommand(Command):
required_attrs = [
"supplementalCredentials",
"unicodePwd",
+ "msDS-ManagedPassword",
]
for required_attr in required_attrs:
a = parse_raw_attr(required_attr, is_hidden=True)
@@ -349,6 +354,8 @@ class GetPasswordCommand(Command):
raise CommandError("Failed to get password for user '%s': %s" % (username or filter, msg))
obj = res[0]
+ calculated = {}
+
sc = None
unicodePwd = None
if "supplementalCredentials" in obj:
@@ -356,6 +363,17 @@ class GetPasswordCommand(Command):
sc = ndr_unpack(drsblobs.supplementalCredentialsBlob, sc_blob)
if "unicodePwd" in obj:
unicodePwd = obj["unicodePwd"][0]
+ if "msDS-ManagedPassword" in obj:
+ # unpack a GMSA managed password as if we could read the
+ # hidden password attributes.
+ managed_password = obj["msDS-ManagedPassword"][0]
+ unpacked_managed_password = ndr_unpack(gmsa.MANAGEDPASSWORD_BLOB,
+ managed_password)
+ calculated["Primary:CLEARTEXT"] = \
+ unpacked_managed_password.passwords.current
+ calculated["OLDCLEARTEXT"] = \
+ unpacked_managed_password.passwords.previous
+
account_name = str(obj["sAMAccountName"][0])
if "userPrincipalName" in obj:
account_upn = str(obj["userPrincipalName"][0])
@@ -363,8 +381,6 @@ class GetPasswordCommand(Command):
realm = samdb.domain_dns_name()
account_upn = "%s@%s" % (account_name, realm.lower())
- calculated = {}
-
def get_package(name, min_idx=0):
if name in calculated:
return calculated[name]
@@ -383,6 +399,17 @@ class GetPasswordCommand(Command):
return binascii.a2b_hex(p.data)
return None
+ def get_cleartext(attr_opts):
+ param = get_option(attr_opts, "previous")
+ if param:
+ if param != "1":
+ raise CommandError(
+ f"Invalid attribute parameter ;previous={param}, "
+ "only supported value is previous=1")
+ return calculated.get("OLDCLEARTEXT")
+ else:
+ return get_package("Primary:CLEARTEXT")
+
def get_kerberos_ctr():
primary_krb5 = get_package("Primary:Kerberos-Newer-Keys")
if primary_krb5 is None:
@@ -453,14 +480,14 @@ class GetPasswordCommand(Command):
username or account_name, e))
def get_utf8(a, b, username):
- try:
- u = str(get_bytes(b), 'utf-16-le')
- except UnicodeDecodeError as e:
- self.outf.write("WARNING: '%s': CLEARTEXT is invalid UTF-16-LE unable to generate %s\n" % (
- username, a))
- return None
- u8 = u.encode('utf-8')
- return u8
+ creds_for_charcnv = credentials.Credentials()
+ creds_for_charcnv.set_anonymous()
+ creds_for_charcnv.set_utf16_password(get_bytes(b))
+
+ # This can't fail due to character conversion issues as it
+ # includes a built-in fallback (UTF16_MUNGED) matching
+ # exactly what we need.
+ return creds_for_charcnv.get_password().encode()
# Extract the WDigest hash for the value specified by i.
# Builds an htdigest compatible value
@@ -582,7 +609,7 @@ class GetPasswordCommand(Command):
if sv is None:
# No exact match on algorithm and number of rounds
# try and calculate one from the Primary:CLEARTEXT
- b = get_package("Primary:CLEARTEXT")
+ b = get_cleartext(attr_opts)
if b is not None:
u8 = get_utf8(a, b, username or account_name)
if u8 is not None:
@@ -650,6 +677,14 @@ class GetPasswordCommand(Command):
except ValueError:
return 0
+ def get_unicode_pwd_hash(pwd):
+ # We can't read unicodePwd directly, but we can regenerate
+ # it from msDS-ManagedPassword
+ tmp = credentials.Credentials()
+ tmp.set_anonymous()
+ tmp.set_utf16_password(pwd)
+ return tmp.get_nt_hash()
+
# We use sort here in order to have a predictable processing order
for a in sorted(virtual_attributes.keys()):
vattr = None
@@ -665,7 +700,7 @@ class GetPasswordCommand(Command):
attr_opts = vattr["opts"]
if a == "virtualClearTextUTF8":
- b = get_package("Primary:CLEARTEXT")
+ b = get_cleartext(attr_opts)
if b is None:
continue
u8 = get_utf8(a, b, username or account_name)
@@ -673,11 +708,11 @@ class GetPasswordCommand(Command):
continue
v = u8
elif a == "virtualClearTextUTF16":
- v = get_package("Primary:CLEARTEXT")
+ v = get_cleartext(attr_opts)
if v is None:
continue
elif a == "virtualSSHA":
- b = get_package("Primary:CLEARTEXT")
+ b = get_cleartext(attr_opts)
if b is None:
continue
u8 = get_utf8(a, b, username or account_name)
@@ -714,6 +749,13 @@ class GetPasswordCommand(Command):
v = kerberos_salt
if v is None:
continue
+ elif a == "unicodePwd" and unicodePwd is None:
+ if "Primary:CLEARTEXT" in calculated and not get_option(attr_opts, "previous"):
+ v = get_unicode_pwd_hash(calculated["Primary:CLEARTEXT"])
+ elif "OLDCLEARTEXT" in calculated and get_option(attr_opts, "previous"):
+ v = get_unicode_pwd_hash(calculated["OLDCLEARTEXT"])
+ else:
+ continue
elif a.startswith("virtualWDigest"):
primary_wdigest = get_package("Primary:WDigest")
if primary_wdigest is None:
@@ -730,7 +772,7 @@ class GetPasswordCommand(Command):
continue
else:
continue
- obj[a] = ldb.MessageElement(v, ldb.FLAG_MOD_REPLACE, a)
+ obj[a] = ldb.MessageElement(v, ldb.FLAG_MOD_REPLACE, vattr["raw_attr"])
def get_src_attrname(srcattrg):
srcattrl = srcattrg.lower()
diff --git a/python/samba/netcmd/user/readpasswords/get_kerberos_ticket.py b/python/samba/netcmd/user/readpasswords/get_kerberos_ticket.py
new file mode 100644
index 00000000000..3a8296b187a
--- /dev/null
+++ b/python/samba/netcmd/user/readpasswords/get_kerberos_ticket.py
@@ -0,0 +1,146 @@
+# user management
+#
+# user get-kerberos-ticket command - obtain a TGT for a database user
+#
+# Copyright Jelmer Vernooij 2010 <jelmer at samba.org>
+# Copyright Theresa Halloran 2011 <theresahalloran at gmail.com>
+# Copyright Andrew Bartlett 2023 <abartlet at samba.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import ldb
+import samba.getopt as options
+from samba.netcmd import CommandError, Option
+from samba.credentials import Credentials
+from .common import (
+ GetPasswordCommand,
+ gpg_decrypt,
+ decrypt_samba_gpg_help,
+)
+from samba.dcerpc import samr
+
+class cmd_user_get_kerberos_ticket(GetPasswordCommand):
+ """Get a Kerberos Ticket Granting Ticket as a user
+
+This command gets a Kerberos TGT using the password for a user/computer account.
+
+The username specified on the command is the sAMAccountName.
+The username may also be specified using the --filter option.
+
+The command must be run from the root user id or another authorized
+user id. The '-H' or '--URL' option supports ldap:// for remote Group
+Managed Service accounts, and ldapi:// or tdb:// can be used to
+adjust the local path. tdb:// is used by default for a bare path.
+
+The --output-krb5-ccache option should point to a location for the
+credentials cache. The default is a FILE: type cache if no prefix is
+specified.
+
+The '--decrypt-samba-gpg' option triggers decryption of the
+Primary:SambaGPG buffer to get the password.
+
+Check with '--help' if this feature is available
+in your environment or not (the python-gpgme package is required). Please
+note that you might need to set the GNUPGHOME environment variable. If the
+decryption key has a passphrase you have to make sure that the GPG_AGENT_INFO
+environment variable has been set correctly and the passphrase is already
+known by the gpg-agent.
+
+Example1:
+samba-tool user get-kerberos-ticket TestUser1 --output-krb5-ccache=/srv/service/krb5_ccache
+
+Example2:
+samba-tool user get-kerberos-ticket --filter='(samAccountName=TestUser3)' --output-krb5-ccache=FILE:/srv/service/krb5_ccache
+
+ """
+ synopsis = "%prog (<username>|--filter <filter>) [options]"
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "versionopts": options.VersionOptions,
+ "credopts": options.CredentialsOptions,
+ "hostopts": options.HostOptions,
+ }
+
+ takes_options = [
+ Option("--filter", help="LDAP Filter to get Kerberos ticket for (must match single account)", type=str),
+ Option("--output-krb5-ccache", type=str,
+ help="Location of Kerberos credentials cache to write ticket into",
+ metavar="CCACHE", dest="output_krb5_ccache"),
+ Option("--decrypt-samba-gpg",
+ help=decrypt_samba_gpg_help,
+ action="store_true", default=False, dest="decrypt_samba_gpg"),
+ ]
+
+ takes_args = ["username?"]
+
+ def run(self, username=None, H=None, filter=None,
+ attributes=None, decrypt_samba_gpg=None,
+ sambaopts=None, versionopts=None, hostopts=None,
+ credopts=None, output_krb5_ccache=None):
+ self.lp = sambaopts.get_loadparm()
+
+ if decrypt_samba_gpg and not gpg_decrypt:
+ raise CommandError(decrypt_samba_gpg_help)
+
+ if filter is None and username is None:
+ raise CommandError("Either the username or '--filter' must be specified!")
+
+ if filter is None:
+ filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
+
+ password_attrs = ["virtualClearTextUTF16", "samAccountName", "unicodePwd"]
+
+ creds = credopts.get_credentials(self.lp)
+ samdb = self.connect_for_passwords(url=hostopts.H, require_ldapi=False, creds=creds)
+
+ obj = self.get_account_attributes(samdb, username,
+ basedn=None,
+ filter=filter,
+ scope=ldb.SCOPE_SUBTREE,
+ attrs=password_attrs,
+ decrypt=decrypt_samba_gpg)
+
+ lp_ctx = sambaopts.get_loadparm()
+
+ creds = Credentials()
+ creds.set_username(str(obj["samAccountName"][0]))
+ creds.set_realm(samdb.domain_dns_name())
+
+ utf16_pw = None
+ nt_pass = None
+ try:
+ utf16_pw = obj["virtualClearTextUTF16"][0]
--
Samba Shared Repository
More information about the samba-cvs
mailing list