ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / source4 / torture / drs / python / cracknames.py
blobf2446050d8c163f8168d3349fbbe58a5987b60e4
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
4 # Copyright (C) Catalyst .Net Ltd 2017
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 import samba.tests
21 import ldb
22 import drs_base
24 from samba.dcerpc import drsuapi
27 class DrsCracknamesTestCase(drs_base.DrsBaseTestCase):
28 def setUp(self):
29 super(DrsCracknamesTestCase, self).setUp()
30 (self.drs, self.drs_handle) = self._ds_bind(self.dnsname_dc1)
32 self.ou = "ou=Cracknames_ou,%s" % self.ldb_dc1.get_default_basedn()
33 self.username = "Cracknames_user"
34 self.user = "cn=%s,%s" % (self.username, self.ou)
36 self.ldb_dc1.add({
37 "dn": self.ou,
38 "objectclass": "organizationalUnit"})
40 self.user_record = {
41 "dn": self.user,
42 "objectclass": "user",
43 "sAMAccountName": self.username,
44 "userPrincipalName": "test@test.com",
45 "servicePrincipalName": "test/%s" % self.ldb_dc1.get_default_basedn(),
46 "displayName": "test"}
48 self.ldb_dc1.add(self.user_record)
49 self.ldb_dc1.delete(self.user_record["dn"])
50 self.ldb_dc1.add(self.user_record)
52 # The formats specified in MS-DRSR 4.1.4.13; DS_NAME_FORMAT
53 # We don't support any of the ones specified in 4.1.4.1.2.
54 self.formats = {
55 drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
56 drsuapi.DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
57 drsuapi.DRSUAPI_DS_NAME_FORMAT_DISPLAY,
58 drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID,
59 drsuapi.DRSUAPI_DS_NAME_FORMAT_CANONICAL,
60 drsuapi.DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
61 drsuapi.DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
62 drsuapi.DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
63 drsuapi.DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
64 # This format is not supported by Windows (or us)
65 # drsuapi.DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN,
68 def tearDown(self):
69 self.ldb_dc1.delete(self.user)
70 self.ldb_dc1.delete(self.ou)
71 super(DrsCracknamesTestCase, self).tearDown()
73 def test_Cracknames(self):
74 """
75 Verifies that we can cracknames any of the standard formats
76 (DS_NAME_FORMAT) to a GUID, and that we can cracknames a
77 GUID to any of the standard formats.
79 GUID was chosen just so that we don't have to do an n^2 loop.
80 """
81 (result, ctr) = self._do_cracknames(self.user,
82 drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
83 drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID)
85 self.assertEqual(ctr.count, 1)
86 self.assertEqual(ctr.array[0].status,
87 drsuapi.DRSUAPI_DS_NAME_STATUS_OK)
89 user_guid = ctr.array[0].result_name
91 for name_format in self.formats:
92 (result, ctr) = self._do_cracknames(user_guid,
93 drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID,
94 name_format)
96 self.assertEqual(ctr.count, 1)
97 self.assertEqual(ctr.array[0].status,
98 drsuapi.DRSUAPI_DS_NAME_STATUS_OK,
99 "Expected 0, got %s, desired format is %s"
100 % (ctr.array[0].status, name_format))
102 (result, ctr) = self._do_cracknames(ctr.array[0].result_name,
103 name_format,
104 drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID)
106 self.assertEqual(ctr.count, 1)
107 self.assertEqual(ctr.array[0].status,
108 drsuapi.DRSUAPI_DS_NAME_STATUS_OK,
109 "Expected 0, got %s, offered format is %s"
110 % (ctr.array[0].status, name_format))
112 def test_MultiValuedAttribute(self):
114 Verifies that, if we try and cracknames with the desired output
115 being a multi-valued attribute, it returns
116 DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE.
118 username = "Cracknames_user_MVA"
119 user = "cn=%s,%s" % (username, self.ou)
121 user_record = {
122 "dn": user,
123 "objectclass": "user",
124 "sAMAccountName": username,
125 "userPrincipalName": "test2@test.com",
126 "servicePrincipalName": ["test2/%s" % self.ldb_dc1.get_default_basedn(),
127 "test3/%s" % self.ldb_dc1.get_default_basedn()],
128 "displayName": "test2"}
130 self.ldb_dc1.add(user_record)
132 (result, ctr) = self._do_cracknames(user,
133 drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
134 drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID)
136 self.assertEqual(ctr.count, 1)
137 self.assertEqual(ctr.array[0].status,
138 drsuapi.DRSUAPI_DS_NAME_STATUS_OK)
140 user_guid = ctr.array[0].result_name
142 (result, ctr) = self._do_cracknames(user_guid,
143 drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID,
144 drsuapi.DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL)
146 self.assertEqual(ctr.count, 1)
147 self.assertEqual(ctr.array[0].status,
148 drsuapi.DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE)
150 self.ldb_dc1.delete(user)
152 def test_NoSPNAttribute(self):
154 Verifies that, if we try and cracknames with the desired output
155 being an SPN, it returns
156 DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE.
158 username = "Cracknames_no_SPN"
159 user = "cn=%s,%s" % (username, self.ou)
161 user_record = {
162 "dn": user,
163 "objectclass": "user",
164 "sAMAccountName" : username,
165 "userPrincipalName" : "test4@test.com",
166 "displayName" : "test4"}
168 self.ldb_dc1.add(user_record)
170 (result, ctr) = self._do_cracknames(user,
171 drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
172 drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID)
174 self.assertEqual(ctr.count, 1)
175 self.assertEqual(ctr.array[0].status,
176 drsuapi.DRSUAPI_DS_NAME_STATUS_OK)
178 user_guid = ctr.array[0].result_name
180 (result, ctr) = self._do_cracknames(user_guid,
181 drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID,
182 drsuapi.DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL)
184 self.assertEqual(ctr.count, 1)
185 self.assertEqual(ctr.array[0].status,
186 drsuapi.DRSUAPI_DS_NAME_STATUS_NOT_FOUND)
188 self.ldb_dc1.delete(user)
190 def _do_cracknames(self, name, format_offered, format_desired):
191 req = drsuapi.DsNameRequest1()
192 names = drsuapi.DsNameString()
193 names.str = name
195 req.codepage = 1252 # German, but it doesn't really matter here
196 req.language = 1033
197 req.format_flags = 0
198 req.format_offered = format_offered
199 req.format_desired = format_desired
200 req.count = 1
201 req.names = [names]
203 (result, ctr) = self.drs.DsCrackNames(self.drs_handle, 1, req)
204 return (result, ctr)