1 # Tests for Tests for source4/dsdb/samdb/ldb_modules/password_hash.c
3 # Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Tests for source4/dsdb/samdb/ldb_modules/password_hash.c
22 These tests are designed to also run against Windows to confirm the values
23 returned from Windows.
25 To run against Windows:
26 Set the following environment variables:
27 PASSWORD=Administrator password
28 USERNAME=Administrator
29 SMB_CONF_PATH=/dev/null
31 SERVER=Windows server IP
33 /usr/bin/python source4/scripting/bin/subunitrun
34 samba.tests.password_hash_ldap.PassWordHashLDAPTests
35 -U"Administrator%adminpassword"
38 from samba
.tests
.password_hash
import (
43 from samba
.samdb
import SamDB
44 from samba
.ndr
import ndr_unpack
45 from samba
.dcerpc
import drsblobs
, drsuapi
, misc
46 from samba
import drs_utils
, net
47 from samba
.credentials
import Credentials
52 def attid_equal(a1
, a2
):
53 return (a1
& 0xffffffff) == (a2
& 0xffffffff)
56 class PassWordHashLDAPTests(PassWordHashTests
):
58 # Get the supplemental credentials for the user under test
59 def get_supplemental_creds_drs(self
):
60 binding_str
= "ncacn_ip_tcp:%s[seal]" % os
.environ
["SERVER"]
61 dn
= "cn=" + USER_NAME
+ ",cn=users," + self
.base_dn
62 drs
= drsuapi
.drsuapi(binding_str
, self
.get_loadparm(), self
.creds
)
63 (drs_handle
, supported_extensions
) = drs_utils
.drs_DsBind(drs
)
65 req8
= drsuapi
.DsGetNCChangesRequest8()
67 null_guid
= misc
.GUID()
68 req8
.destination_dsa_guid
= null_guid
69 req8
.source_dsa_invocation_id
= null_guid
70 req8
.naming_context
= drsuapi
.DsReplicaObjectIdentifier()
71 req8
.naming_context
.dn
= dn
73 req8
.highwatermark
= drsuapi
.DsReplicaHighWaterMark()
74 req8
.highwatermark
.tmp_highest_usn
= 0
75 req8
.highwatermark
.reserved_usn
= 0
76 req8
.highwatermark
.highest_usn
= 0
77 req8
.uptodateness_vector
= None
78 req8
.replica_flags
= (drsuapi
.DRSUAPI_DRS_INIT_SYNC |
79 drsuapi
.DRSUAPI_DRS_PER_SYNC |
80 drsuapi
.DRSUAPI_DRS_GET_ANC |
81 drsuapi
.DRSUAPI_DRS_NEVER_SYNCED |
82 drsuapi
.DRSUAPI_DRS_WRIT_REP
)
83 req8
.max_object_count
= 402
84 req8
.max_ndr_size
= 402116
85 req8
.extended_op
= drsuapi
.DRSUAPI_EXOP_REPL_OBJ
87 req8
.partial_attribute_set
= None
88 req8
.partial_attribute_set_ex
= None
89 req8
.mapping_ctr
.num_mappings
= 0
90 req8
.mapping_ctr
.mappings
= None
91 (level
, ctr
) = drs
.DsGetNCChanges(drs_handle
, 8, req8
)
93 obj_item
= ctr
.first_object
98 for i
in range(0, obj
.attribute_ctr
.num_attributes
):
99 attr
= obj
.attribute_ctr
.attributes
[i
]
100 if attid_equal(attr
.attid
,
101 drsuapi
.DRSUAPI_ATTID_supplementalCredentials
):
102 net_ctx
= net
.Net(self
.creds
)
103 net_ctx
.replicate_decrypt(drs
, attr
, 0)
104 sc_blob
= attr
.value_ctr
.values
[0].blob
106 sc
= ndr_unpack(drsblobs
.supplementalCredentialsBlob
, sc_blob
)
109 def test_wDigest_supplementalCredentials(self
):
110 self
.creds
= Credentials()
111 self
.creds
.set_username(os
.environ
["USERNAME"])
112 self
.creds
.set_password(os
.environ
["PASSWORD"])
113 self
.creds
.guess(self
.lp
)
114 ldb
= SamDB("ldap://" + os
.environ
["SERVER"],
115 credentials
=self
.creds
,
118 self
.add_user(ldb
=ldb
)
120 sc
= self
.get_supplemental_creds_drs()
122 (pos
, package
) = get_package(sc
, "Primary:WDigest")
123 self
.assertEqual("Primary:WDigest", package
.name
)
125 # Check that the WDigest values are correct.
127 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
128 binascii
.a2b_hex(package
.data
))
129 self
.check_wdigests(digests
)