diff options
Diffstat (limited to 'python/samba/netcmd/user/readpasswords/getpassword.py')
-rw-r--r-- | python/samba/netcmd/user/readpasswords/getpassword.py | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/python/samba/netcmd/user/readpasswords/getpassword.py b/python/samba/netcmd/user/readpasswords/getpassword.py new file mode 100644 index 0000000..f962412 --- /dev/null +++ b/python/samba/netcmd/user/readpasswords/getpassword.py @@ -0,0 +1,210 @@ +# user management +# +# user getpassword command +# +# Copyright Jelmer Vernooij 2010 <jelmer@samba.org> +# Copyright Theresa Halloran 2011 <theresahalloran@gmail.com> +# +# 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 .common import ( + GetPasswordCommand, + gpg_decrypt, + decrypt_samba_gpg_help, + virtual_attributes_help +) + + +class cmd_user_getpassword(GetPasswordCommand): + """Get the password fields of a user/computer account. + +This command gets the logon 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 normally only supports ldapi:// or [tdb://] and +can be used to adjust the local path. By default, tdb:// is used. +if the target account is a group managed service account, then in this +case the -H can point to a remote AD DC LDAP server. + +The '--attributes' parameter takes a comma separated list of attributes, +which will be printed or given to the script specified by '--script'. If a +specified attribute is not available on an object it's silently omitted. +All attributes defined in the schema (e.g. the unicodePwd attribute holds +the NTHASH) and the following virtual attributes are possible (see --help +for which virtual attributes are supported in your environment): + + virtualClearTextUTF16: The raw cleartext as stored in the + 'Primary:CLEARTEXT' (or 'Primary:SambaGPG' + with '--decrypt-samba-gpg') buffer inside the + supplementalCredentials attribute. This typically + contains valid UTF-16-LE, but may contain random + bytes, e.g. for computer and gMSA accounts. + When the account is a group managed service account, + and the user is permitted to access + msDS-ManagedPassword then the current and previous + password can be read over LDAP. Add ;previous=1 + to read the previous password. + + virtualClearTextUTF8: As virtualClearTextUTF16, but converted to UTF-8 + (invalid UTF-16-LE is mapped in the same way as + Windows). + + virtualSSHA: As virtualClearTextUTF8, but a salted SHA-1 + checksum, useful for OpenLDAP's '{SSHA}' algorithm. + + virtualCryptSHA256: As virtualClearTextUTF8, but a salted SHA256 + checksum, useful for OpenLDAP's '{CRYPT}' algorithm, + with a $5$... salt, see crypt(3) on modern systems. + The number of rounds used to calculate the hash can + also be specified. By appending ";rounds=x" to the + attribute name i.e. virtualCryptSHA256;rounds=10000 + will calculate a SHA256 hash with 10,000 rounds. + Non-numeric values for rounds are silently ignored. + The value is calculated as follows: + 1) If a value exists in 'Primary:userPassword' with + the specified number of rounds it is returned. + 2) If 'Primary:CLEARTEXT', or 'Primary:SambaGPG' + with '--decrypt-samba-gpg'. Calculate a hash with + the specified number of rounds. + 3) Return the first CryptSHA256 value in + 'Primary:userPassword'. + + + virtualCryptSHA512: As virtualClearTextUTF8, but a salted SHA512 + checksum, useful for OpenLDAP's '{CRYPT}' algorithm, + with a $6$... salt, see crypt(3) on modern systems. + The number of rounds used to calculate the hash can + also be specified. By appending ";rounds=x" to the + attribute name i.e. virtualCryptSHA512;rounds=10000 + will calculate a SHA512 hash with 10,000 rounds. + Non-numeric values for rounds are silently ignored. + The value is calculated as follows: + 1) If a value exists in 'Primary:userPassword' with + the specified number of rounds it is returned. + 2) If 'Primary:CLEARTEXT', or 'Primary:SambaGPG' + with '--decrypt-samba-gpg'. Calculate a hash with + the specified number of rounds. + 3) Return the first CryptSHA512 value in + 'Primary:userPassword'. + + virtualWDigestNN: The individual hash values stored in + 'Primary:WDigest' where NN is the hash number in + the range 01 to 29. + NOTE: As at 22-05-2017 the documentation: + 3.1.1.8.11.3.1 WDIGEST_CREDENTIALS Construction + https://msdn.microsoft.com/en-us/library/cc245680.aspx + is incorrect. + + virtualKerberosSalt: This results the salt string that is used to compute + Kerberos keys from a UTF-8 cleartext password. + + virtualSambaGPG: The raw cleartext as stored in the + 'Primary:SambaGPG' buffer inside the + supplementalCredentials attribute. + See the 'password hash gpg key ids' option in + smb.conf. + +The '--decrypt-samba-gpg' option triggers decryption of the +Primary:SambaGPG buffer. 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. + +Attributes with time values can take an additional format specifier, which +converts the time value into the requested format. The format can be specified +by adding ";format=formatSpecifier" to the requested attribute name, whereby +"formatSpecifier" must be a valid specifier. The syntax looks like: + + --attributes=attributeName;format=formatSpecifier + +The following format specifiers are available: + - GeneralizedTime (e.g. 20210224113259.0Z) + - UnixTime (e.g. 1614166392) + - TimeSpec (e.g. 161416639.267546892) + +Attributes with an original NTTIME value of 0 and 9223372036854775807 are +treated as non-existing value. + +Example1: +samba-tool user getpassword TestUser1 --attributes=pwdLastSet,virtualClearTextUTF8 + +Example2: +samba-tool user getpassword --filter=samaccountname=TestUser3 --attributes=msDS-KeyVersionNumber,unicodePwd,virtualClearTextUTF16 + +""" + + 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 password for (must match single account)", type=str), + Option("--attributes", type=str, + help=virtual_attributes_help, + metavar="ATTRIBUTELIST", dest="attributes"), + 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): + 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)) + + if attributes is None: + raise CommandError("Please specify --attributes") + + password_attrs = self.parse_attributes(attributes) + + 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) + + ldif = samdb.write_ldif(obj, ldb.CHANGETYPE_NONE) + self.outf.write("%s" % ldif) + self.errf.write("Got password OK\n") |