s3:utils: Fix 'Usage:' for 'net ads enctypes'
[samba4-gss.git] / python / samba / netcmd / user / readpasswords / getpassword.py
blob278c4b241e75ce58cf2fed85e2461f0f91c2da13
1 # user management
3 # user getpassword command
5 # Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
6 # Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 import ldb
23 import samba.getopt as options
24 from samba.netcmd import CommandError, Option
26 from .common import (
27 GetPasswordCommand,
28 gpg_decrypt,
29 decrypt_samba_gpg_help,
30 virtual_attributes_help
34 class cmd_user_getpassword(GetPasswordCommand):
35 """Get the password fields of a user/computer account.
37 This command gets the logon password for a user/computer account.
39 The username specified on the command is the sAMAccountName.
40 The username may also be specified using the --filter option.
42 The command must be run from the root user id or another authorized user id.
43 The '-H' or '--URL' option normally only supports ldapi:// or [tdb://] and
44 can be used to adjust the local path. By default, tdb:// is used.
45 if the target account is a group managed service account, then in this
46 case the -H can point to a remote AD DC LDAP server.
48 The '--attributes' parameter takes a comma separated list of attributes,
49 which will be printed or given to the script specified by '--script'. If a
50 specified attribute is not available on an object it's silently omitted.
51 All attributes defined in the schema (e.g. the unicodePwd attribute holds
52 the NTHASH) and the following virtual attributes are possible (see --help
53 for which virtual attributes are supported in your environment):
55 virtualClearTextUTF16: The raw cleartext as stored in the
56 'Primary:CLEARTEXT' (or 'Primary:SambaGPG'
57 with '--decrypt-samba-gpg') buffer inside the
58 supplementalCredentials attribute. This typically
59 contains valid UTF-16-LE, but may contain random
60 bytes, e.g. for computer and gMSA accounts.
61 When the account is a group managed service account,
62 and the user is permitted to access
63 msDS-ManagedPassword then the current and previous
64 password can be read over LDAP. Add ;previous=1
65 to read the previous password.
67 virtualClearTextUTF8: As virtualClearTextUTF16, but converted to UTF-8
68 (invalid UTF-16-LE is mapped in the same way as
69 Windows).
71 virtualSSHA: As virtualClearTextUTF8, but a salted SHA-1
72 checksum, useful for OpenLDAP's '{SSHA}' algorithm.
74 virtualCryptSHA256: As virtualClearTextUTF8, but a salted SHA256
75 checksum, useful for OpenLDAP's '{CRYPT}' algorithm,
76 with a $5$... salt, see crypt(3) on modern systems.
77 The number of rounds used to calculate the hash can
78 also be specified. By appending ";rounds=x" to the
79 attribute name i.e. virtualCryptSHA256;rounds=10000
80 will calculate a SHA256 hash with 10,000 rounds.
81 Non-numeric values for rounds are silently ignored.
82 The value is calculated as follows:
83 1) If a value exists in 'Primary:userPassword' with
84 the specified number of rounds it is returned.
85 2) If 'Primary:CLEARTEXT', or 'Primary:SambaGPG'
86 with '--decrypt-samba-gpg'. Calculate a hash with
87 the specified number of rounds.
88 3) Return the first CryptSHA256 value in
89 'Primary:userPassword'.
92 virtualCryptSHA512: As virtualClearTextUTF8, but a salted SHA512
93 checksum, useful for OpenLDAP's '{CRYPT}' algorithm,
94 with a $6$... salt, see crypt(3) on modern systems.
95 The number of rounds used to calculate the hash can
96 also be specified. By appending ";rounds=x" to the
97 attribute name i.e. virtualCryptSHA512;rounds=10000
98 will calculate a SHA512 hash with 10,000 rounds.
99 Non-numeric values for rounds are silently ignored.
100 The value is calculated as follows:
101 1) If a value exists in 'Primary:userPassword' with
102 the specified number of rounds it is returned.
103 2) If 'Primary:CLEARTEXT', or 'Primary:SambaGPG'
104 with '--decrypt-samba-gpg'. Calculate a hash with
105 the specified number of rounds.
106 3) Return the first CryptSHA512 value in
107 'Primary:userPassword'.
109 virtualWDigestNN: The individual hash values stored in
110 'Primary:WDigest' where NN is the hash number in
111 the range 01 to 29.
112 NOTE: As at 22-05-2017 the documentation:
113 3.1.1.8.11.3.1 WDIGEST_CREDENTIALS Construction
114 https://msdn.microsoft.com/en-us/library/cc245680.aspx
115 is incorrect.
117 virtualKerberosSalt: This results the salt string that is used to compute
118 Kerberos keys from a UTF-8 cleartext password.
120 virtualSambaGPG: The raw cleartext as stored in the
121 'Primary:SambaGPG' buffer inside the
122 supplementalCredentials attribute.
123 See the 'password hash gpg key ids' option in
124 smb.conf.
126 The '--decrypt-samba-gpg' option triggers decryption of the
127 Primary:SambaGPG buffer. Check with '--help' if this feature is available
128 in your environment or not (the python-gpgme package is required). Please
129 note that you might need to set the GNUPGHOME environment variable. If the
130 decryption key has a passphrase you have to make sure that the GPG_AGENT_INFO
131 environment variable has been set correctly and the passphrase is already
132 known by the gpg-agent.
134 Attributes with time values can take an additional format specifier, which
135 converts the time value into the requested format. The format can be specified
136 by adding ";format=formatSpecifier" to the requested attribute name, whereby
137 "formatSpecifier" must be a valid specifier. The syntax looks like:
139 --attributes=attributeName;format=formatSpecifier
141 The following format specifiers are available:
142 - GeneralizedTime (e.g. 20210224113259.0Z)
143 - UnixTime (e.g. 1614166392)
144 - TimeSpec (e.g. 161416639.267546892)
146 Attributes with an original NTTIME value of 0 and 9223372036854775807 are
147 treated as non-existing value.
149 Example1:
150 samba-tool user getpassword TestUser1 --attributes=pwdLastSet,virtualClearTextUTF8
152 Example2:
153 samba-tool user getpassword --filter=samaccountname=TestUser3 --attributes=msDS-KeyVersionNumber,unicodePwd,virtualClearTextUTF16
157 synopsis = "%prog (<username>|--filter <filter>) [options]"
159 takes_optiongroups = {
160 "sambaopts": options.SambaOptions,
161 "versionopts": options.VersionOptions,
162 "credopts": options.CredentialsOptions,
163 "hostopts": options.HostOptions,
166 takes_options = [
167 Option("--filter", help="LDAP Filter to get password for (must match single account)", type=str),
168 Option("--attributes", type=str,
169 help=virtual_attributes_help,
170 metavar="ATTRIBUTELIST", dest="attributes"),
171 Option("--decrypt-samba-gpg",
172 help=decrypt_samba_gpg_help,
173 action="store_true", default=False, dest="decrypt_samba_gpg"),
176 takes_args = ["username?"]
178 def run(self, username=None, H=None, filter=None,
179 attributes=None, decrypt_samba_gpg=None,
180 sambaopts=None, versionopts=None, hostopts=None,
181 credopts=None):
182 self.lp = sambaopts.get_loadparm()
184 if decrypt_samba_gpg and not gpg_decrypt:
185 raise CommandError(decrypt_samba_gpg_help)
187 if filter is None and username is None:
188 raise CommandError("Either the username or '--filter' must be specified!")
190 if filter is None:
191 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
193 if attributes is None:
194 raise CommandError("Please specify --attributes")
196 password_attrs = self.parse_attributes(attributes)
198 creds = credopts.get_credentials(self.lp)
199 samdb = self.connect_for_passwords(url=hostopts.H, require_ldapi=False, creds=creds)
201 obj = self.get_account_attributes(samdb, username,
202 basedn=None,
203 filter=filter,
204 scope=ldb.SCOPE_SUBTREE,
205 attrs=password_attrs,
206 decrypt=decrypt_samba_gpg)
208 ldif = samdb.write_ldif(obj, ldb.CHANGETYPE_NONE)
209 self.outf.write("%s" % ldif)
210 self.errf.write("Any available password returned OK\n")