--- /dev/null
+# user management
+#
+# user get-kerberos-ticket command - obtain a TGT for a database user
+#
+# Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
+# Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
+# Copyright Andrew Bartlett 2023 <abartlet@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]
+ creds.set_utf16_password(utf16_pw)
+ except KeyError:
+ pass
+
+ if utf16_pw is None:
+ try:
+ nt_pass = samr.Password()
+ nt_pass.hash = list(obj["unicodePwd"][0])
+ creds.set_nt_hash(nt_pass)
+ except KeyError:
+ pass
+
+ if nt_pass is None and utf16_pw is None:
+ if samdb.url.startswith("ldap://") or samdb.url.startswith("ldaps://"):
+ raise CommandError("No password was available for this user. "
+ "Only Group Managed Service accounts allow access to passwords over LDAP, "
+ "you may need to access the sam.ldb directly on the Samba AD DC and export the file.")
+ else:
+ raise CommandError("No password was available for this user")
+ creds.guess(lp_ctx)
+ creds.get_named_ccache(lp_ctx, output_krb5_ccache)