[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Mon Jan 9 11:07:03 MST 2012


The branch, master has been updated
       via  73d96ed s4:scripting/devel: add repl_cleartext_pwd.py script
      from  88258c3 s4-kerberos: remove some unused prototypes.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 73d96ed239a1616f1074186d5ba0d02f716cae0e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 15 16:28:08 2011 +0100

    s4:scripting/devel: add repl_cleartext_pwd.py script
    
    This is useful to sync passwords from an AD domain.
    
     $
     $ source4/scripting/devel/repl_cleartext_pwd.py \
     	-Uadministrator%A1b2C3d4 \
     	172.31.9.219 DC=bla,DC=base /tmp/cookie cleartext_utf8 131085 displayName
     # starting at usn[0]
     dn: CN=Test User1,CN=Users,DC=bla,DC=base
     cleartext_utf8: A1b2C3d4
     displayName:: VABlAHMAdAAgAFUAcwBlAHIAMQA=
    
     # up to usn[16449]
     $
     $ source4/scripting/devel/repl_cleartext_pwd.py \
     	-Uadministrator%A1b2C3d4
     	172.31.9.219 DC=bla,DC=base /tmp/cookie cleartext_utf8 131085 displayName
     # starting at usn[16449]
     # up to usn[16449]
     $
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Mon Jan  9 19:06:06 CET 2012 on sn-devel-104

-----------------------------------------------------------------------

Summary of changes:
 source4/scripting/devel/repl_cleartext_pwd.py |  377 +++++++++++++++++++++++++
 1 files changed, 377 insertions(+), 0 deletions(-)
 create mode 100755 source4/scripting/devel/repl_cleartext_pwd.py


Changeset truncated at 500 lines:

diff --git a/source4/scripting/devel/repl_cleartext_pwd.py b/source4/scripting/devel/repl_cleartext_pwd.py
new file mode 100755
index 0000000..ac650d9
--- /dev/null
+++ b/source4/scripting/devel/repl_cleartext_pwd.py
@@ -0,0 +1,377 @@
+#!/usr/bin/env python
+#
+# Copyright Stefan Metzmacher 2011-2012
+#
+# 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/>.
+#
+# This is useful to sync passwords from an AD domain.
+#
+#  $
+#  $ source4/scripting/devel/repl_cleartext_pwd.py \
+#  	-Uadministrator%A1b2C3d4 \
+#  	172.31.9.219 DC=bla,DC=base /tmp/cookie cleartext_utf8 131085 displayName
+#  # starting at usn[0]
+#  dn: CN=Test User1,CN=Users,DC=bla,DC=base
+#  cleartext_utf8: A1b2C3d4
+#  displayName:: VABlAHMAdAAgAFUAcwBlAHIAMQA=
+#
+#  # up to usn[16449]
+#  $
+#  $ source4/scripting/devel/repl_cleartext_pwd.py \
+#  	-Uadministrator%A1b2C3d4
+#  	172.31.9.219 DC=bla,DC=base cookie_file cleartext_utf8 131085 displayName
+#  # starting at usn[16449]
+#  # up to usn[16449]
+#  $
+#
+
+import sys
+
+# Find right direction when running from source tree
+sys.path.insert(0, "bin/python")
+
+import samba.getopt as options
+from optparse import OptionParser
+
+from samba.dcerpc import drsuapi, drsblobs, misc
+from samba.ndr import ndr_pack, ndr_unpack, ndr_print
+
+import binascii
+import hashlib
+import Crypto.Cipher.ARC4
+import struct
+import os
+
+from ldif import LDIFWriter
+
+class globals:
+    def __init__(self):
+        self.global_objs = {}
+        self.ldif = LDIFWriter(sys.stdout)
+
+    def add_attr(self, dn, attname, vals):
+        if dn not in self.global_objs:
+           self.global_objs[dn] = {}
+        self.global_objs[dn][attname] = vals
+
+    def print_all(self):
+        for dn, obj in self.global_objs.items():
+           self.ldif.unparse(dn, obj)
+           continue
+        self.global_objs = {}
+
+########### main code ###########
+if __name__ == "__main__":
+    parser = OptionParser("repl_cleartext_pwd.py [options] server dn cookie_file cleartext_name [attid attname]")
+    sambaopts = options.SambaOptions(parser)
+    credopts = options.CredentialsOptions(parser)
+    parser.add_option_group(credopts)
+
+    (opts, args) = parser.parse_args()
+
+    if len(args) < 4 or len(args) == 5:
+        parser.error("more arguments required")
+
+    server = args[0]
+    dn = args[1]
+    cookie_file = args[2]
+    if len(cookie_file) == 0:
+        cookie_file = None
+    cleartext_name = args[3]
+    if len(args) >= 5:
+        attid = int(args[4])
+        attname = args[5]
+    else:
+        attid = -1
+        attname = None
+
+    lp = sambaopts.get_loadparm()
+    creds = credopts.get_credentials(lp)
+
+    if not creds.authentication_requested():
+        parser.error("You must supply credentials")
+
+    gls = globals()
+    try:
+       f = open(cookie_file, 'r')
+       store_blob = f.read()
+       f.close()
+
+       store_hdr = store_blob[0:28]
+       (store_version, \
+        store_dn_len, store_dn_ofs, \
+        store_hwm_len, store_hwm_ofs, \
+        store_utdv_len, store_utdv_ofs) = \
+        struct.unpack("<LLLLLLL", store_hdr)
+
+       store_dn = store_blob[store_dn_ofs:store_dn_ofs+store_dn_len]
+       store_hwm_blob = store_blob[store_hwm_ofs:store_hwm_ofs+store_hwm_len]
+       store_utdv_blob = store_blob[store_utdv_ofs:store_utdv_ofs+store_utdv_len]
+
+       store_hwm = ndr_unpack(drsuapi.DsReplicaHighWaterMark, store_hwm_blob)
+       store_utdv = ndr_unpack(drsblobs.replUpToDateVectorBlob, store_utdv_blob)
+
+       assert store_dn == dn
+       #print "%s" % ndr_print(store_hwm)
+       #print "%s" % ndr_print(store_utdv)
+    except:
+       store_dn = dn
+       store_hwm = drsuapi.DsReplicaHighWaterMark()
+       store_hwm.tmp_highest_usn  = 0
+       store_hwm.reserved_usn     = 0
+       store_hwm.highest_usn      = 0
+       store_utdv = None
+
+    binding_str = "ncacn_ip_tcp:%s[spnego,seal]" % server
+
+    drs_conn = drsuapi.drsuapi(binding_str, lp, creds)
+
+    bind_info = drsuapi.DsBindInfoCtr()
+    bind_info.length = 28
+    bind_info.info = drsuapi.DsBindInfo28()
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_BASE
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7
+    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT
+    (info, drs_handle) = drs_conn.DsBind(misc.GUID(drsuapi.DRSUAPI_DS_BIND_GUID), bind_info)
+
+    null_guid = misc.GUID()
+
+    naming_context = drsuapi.DsReplicaObjectIdentifier()
+    naming_context.dn              = dn
+    highwatermark                  = store_hwm
+    uptodateness_vector            = None
+    if store_utdv is not None:
+        uptodateness_vector = drsuapi.DsReplicaCursorCtrEx()
+        if store_utdv.version == 1:
+            uptodateness_vector.cursors = store_utdv.cursors
+        elif store_utdv.version == 2:
+            cursors = []
+            for i in range(0, store_utdv.ctr.count):
+                cursor = drsuapi.DsReplicaCursor()
+                cursor.source_dsa_invocation_id = store_utdv.ctr.cursors[i].source_dsa_invocation_id
+                cursor.highest_usn = store_utdv.ctr.cursors[i].highest_usn
+                cursors.append(cursor)
+            uptodateness_vector.cursors = cursors
+
+    req8 = drsuapi.DsGetNCChangesRequest8()
+
+    req8.destination_dsa_guid           = null_guid
+    req8.source_dsa_invocation_id       = null_guid
+    req8.naming_context                 = naming_context
+    req8.highwatermark                  = highwatermark
+    req8.uptodateness_vector            = uptodateness_vector
+    req8.replica_flags                  = (drsuapi.DRSUAPI_DRS_INIT_SYNC |
+                                           drsuapi.DRSUAPI_DRS_PER_SYNC |
+                                           drsuapi.DRSUAPI_DRS_GET_ANC |
+                                           drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
+                                           drsuapi.DRSUAPI_DRS_WRIT_REP)
+    req8.max_object_count = 402
+    req8.max_ndr_size = 402116
+    req8.extended_op = 0
+    req8.fsmo_info = 0
+    req8.partial_attribute_set = None
+    req8.partial_attribute_set_ex = None
+    req8.mapping_ctr.num_mappings = 0
+    req8.mapping_ctr.mappings = None
+
+    user_session_key = drs_conn.user_session_key
+
+    print "# starting at usn[%d]" % (highwatermark.highest_usn)
+
+    while True:
+        (level, ctr) = drs_conn.DsGetNCChanges(drs_handle, 8, req8)
+        if ctr.first_object == None and ctr.object_count != 0:
+            raise RuntimeError("DsGetNCChanges: NULL first_object with object_count=%u" % (ctr.object_count))
+
+        obj_item = ctr.first_object
+        while obj_item is not None:
+            obj = obj_item.object
+
+            if obj.identifier is None:
+                obj_item = obj_item.next_object
+                continue
+
+            #print '%s' % obj.identifier.dn
+
+            is_deleted = False
+            for i in range(0, obj.attribute_ctr.num_attributes):
+                attr = obj.attribute_ctr.attributes[i]
+                if attr.attid == drsuapi.DRSUAPI_ATTID_isDeleted:
+                    is_deleted = True
+            if is_deleted:
+                obj_item = obj_item.next_object
+                continue
+
+            spl_crypt = None
+            attvals = None
+            for i in range(0, obj.attribute_ctr.num_attributes):
+                attr = obj.attribute_ctr.attributes[i]
+                if attr.attid == attid:
+                    attvals = []
+                    for j in range(0, attr.value_ctr.num_values):
+                        assert attr.value_ctr.values[j].blob is not None
+                        attvals.append(attr.value_ctr.values[j].blob)
+                if attr.attid != drsuapi.DRSUAPI_ATTID_supplementalCredentials:
+                    continue
+                assert attr.value_ctr.num_values <= 1
+                if attr.value_ctr.num_values == 0:
+                    break
+                assert attr.value_ctr.values[0].blob is not None
+                spl_crypt = attr.value_ctr.values[0].blob
+                break
+
+            if spl_crypt is None:
+                obj_item = obj_item.next_object
+                continue
+
+            assert len(spl_crypt) >= 20
+            confounder = spl_crypt[0:16]
+            enc_buffer = spl_crypt[16:]
+
+            m5 = hashlib.md5()
+            m5.update(user_session_key)
+            m5.update(confounder)
+            enc_key = m5.digest()
+
+            rc4 = Crypto.Cipher.ARC4.new(enc_key)
+            plain_buffer = rc4.decrypt(enc_buffer)
+
+            (crc32_v) = struct.unpack("<L", plain_buffer[0:4])
+            attr_val = plain_buffer[4:]
+            crc32_c = binascii.crc32(attr_val) & 0xffffffff
+            assert int(crc32_v[0]) == int(crc32_c), "CRC32 0x%08X != 0x%08X" % (crc32_v[0], crc32_c)
+
+            spl = ndr_unpack(drsblobs.supplementalCredentialsBlob, attr_val)
+
+            #print '%s' % ndr_print(spl)
+
+            cleartext_hex = None
+
+            for i in range(0, spl.sub.num_packages):
+                pkg = spl.sub.packages[i]
+                if pkg.name != "Primary:CLEARTEXT":
+                    continue
+                cleartext_hex = pkg.data
+
+            if cleartext_hex is not None:
+                cleartext_utf16 = binascii.a2b_hex(cleartext_hex)
+                cleartext_unicode = unicode(cleartext_utf16, 'utf-16-le')
+                cleartext_utf8 = cleartext_unicode.encode('utf-8')
+
+                gls.add_attr(obj.identifier.dn, cleartext_name, [cleartext_utf8])
+
+                if attvals is not None:
+                    gls.add_attr(obj.identifier.dn, attname, attvals)
+
+            krb5_old_hex = None
+
+            for i in range(0, spl.sub.num_packages):
+                pkg = spl.sub.packages[i]
+                if pkg.name != "Primary:Kerberos":
+                    continue
+                krb5_old_hex = pkg.data
+
+            if krb5_old_hex is not None:
+                krb5_old_raw = binascii.a2b_hex(krb5_old_hex)
+                krb5_old = ndr_unpack(drsblobs.package_PrimaryKerberosBlob, krb5_old_raw, allow_remaining=True)
+
+                #print '%s' % ndr_print(krb5_old)
+
+            krb5_new_hex = None
+
+            for i in range(0, spl.sub.num_packages):
+                pkg = spl.sub.packages[i]
+                if pkg.name != "Primary:Kerberos-Newer-Keys":
+                    continue
+                krb5_new_hex = pkg.data
+
+            if krb5_new_hex is not None:
+                krb5_new_raw = binascii.a2b_hex(krb5_new_hex)
+                krb5_new = ndr_unpack(drsblobs.package_PrimaryKerberosBlob, krb5_new_raw, allow_remaining=True)
+
+                #print '%s' % ndr_print(krb5_new)
+
+            obj_item = obj_item.next_object
+
+        gls.print_all()
+
+        if ctr.more_data == 0:
+            store_hwm = ctr.new_highwatermark
+
+            store_utdv = drsblobs.replUpToDateVectorBlob()
+            store_utdv.version = ctr.uptodateness_vector.version
+            store_utdv_ctr = store_utdv.ctr
+            store_utdv_ctr.count = ctr.uptodateness_vector.count
+            store_utdv_ctr.cursors = ctr.uptodateness_vector.cursors
+            store_utdv.ctr = store_utdv_ctr
+
+            #print "%s" % ndr_print(store_hwm)
+            #print "%s" % ndr_print(store_utdv)
+
+            store_hwm_blob = ndr_pack(store_hwm)
+            store_utdv_blob = ndr_pack(store_utdv)
+
+            #
+            # uint32_t version '1'
+            # uint32_t dn_str_len
+            # uint32_t dn_str_ofs
+            # uint32_t hwm_blob_len
+            # uint32_t hwm_blob_ofs
+            # uint32_t utdv_blob_len
+            # uint32_t utdv_blob_ofs
+            store_hdr_len = 7 * 4
+            dn_ofs = store_hdr_len
+            hwm_ofs = dn_ofs + len(dn)
+            utdv_ofs = hwm_ofs + len(store_hwm_blob)
+            store_blob = struct.pack("<LLLLLLL", 1, \
+                                     len(dn), dn_ofs,
+                                     len(store_hwm_blob), hwm_ofs, \
+                                     len(store_utdv_blob), utdv_ofs) + \
+                                     dn + store_hwm_blob + store_utdv_blob
+
+            tmp_file = "%s.tmp" % cookie_file
+            f = open(tmp_file, 'wb')
+            f.write(store_blob)
+            f.close()
+            os.rename(tmp_file, cookie_file)
+
+            print "# up to usn[%d]" % (ctr.new_highwatermark.highest_usn)
+            break
+        print "# up to tmp_usn[%d]" % (ctr.new_highwatermark.highest_usn)
+        req8.highwatermark.tmp_highest_usn = ctr.new_highwatermark.tmp_highest_usn


-- 
Samba Shared Repository


More information about the samba-cvs mailing list