summaryrefslogtreecommitdiffstats
path: root/python/samba/netcmd/user/readpasswords/get_kerberos_ticket.py
blob: 3a8296b187af1708b3ef685a5caf1af692bed042 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# 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)