#!/usr/bin/env python
import binascii
import quopri
import sys
import textwrap

from samba.credentials import Credentials
from samba.auth import system_session
from samba.dcerpc import drsblobs
from samba.ndr import ndr_unpack
from samba.samdb import SamDB

descr = """This program will produce a list of plaintext passwords for each \
user in the samdb. The plaintext passwords are only available if the \
UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED flag is set in the userAccountControl \
field for the user and the DOMAIN_PASSWORD_STORE_CLEARTEXT flag is set in \
the pwdProperties for the domain."""

if len(sys.argv) != 2:
    sys.stderr.write("usage: %s path_to_samba_private_directory\n" % sys.argv[0])
    sys.stderr.write("%s\n" % textwrap.fill(descr))
    sys.exit(2)

creds = Credentials()
samdb = SamDB(url=(sys.argv[1] + "/sam.ldb.d/DC=FPC,DC=LOCAL.ldb"), session_info=system_session(), credentials=creds.guess())
res = samdb.search(expression="(objectClass=user)", attrs=["supplementalCredentials", "sAMAccountName"])

def esc(s):
    return quopri.encodestring(s, quotetabs=True)

def print_entry(dn, user, pwd):
    print '%s\t%s\t%s' % tuple([esc(p) for p in [dn, user, pwd]])

for r in res:
     if not "supplementalCredentials" in r:
         sys.stderr.write("%s: no supplementalCredentials\n" % str(r["dn"]))
         continue
     scb = ndr_unpack(drsblobs.supplementalCredentialsBlob, str(r["supplementalCredentials"]))
     for p in scb.sub.packages:
         if p.name == "Primary:CLEARTEXT":
             print_entry(str(r["dn"]), str(r["sAMAccountName"]), binascii.unhexlify(p.data).decode("utf16"))

