2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Stefan (metze) Metzmacher 2004
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "torture/torture.h"
27 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
28 #include "torture/rpc/rpc.h"
29 #include "ldb/include/ldb.h"
30 #include "libcli/security/security.h"
32 static BOOL test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
33 struct DsPrivate *priv, const char *dn,
34 const char *user_principal_name, const char *service_principal_name)
40 struct drsuapi_DsCrackNames r;
41 enum drsuapi_DsNameFormat formats[] = {
42 DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
43 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
44 DRSUAPI_DS_NAME_FORMAT_DISPLAY,
45 DRSUAPI_DS_NAME_FORMAT_GUID,
46 DRSUAPI_DS_NAME_FORMAT_CANONICAL,
47 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
48 DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
49 DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
50 DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
51 DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN
53 struct drsuapi_DsNameString names[ARRAY_SIZE(formats)];
56 const char *n_matrix[ARRAY_SIZE(formats)][ARRAY_SIZE(formats)];
57 const char *n_from[ARRAY_SIZE(formats)];
60 r.in.bind_handle = &priv->bind_handle;
62 r.in.req.req1.codepage = 1252; /* german */
63 r.in.req.req1.language = 0x00000407; /* german */
64 r.in.req.req1.count = 1;
65 r.in.req.req1.names = names;
66 r.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
70 for (i = 0; i < ARRAY_SIZE(formats); i++) {
71 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
72 r.in.req.req1.format_desired = formats[i];
74 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
75 if (!NT_STATUS_IS_OK(status)) {
76 const char *errstr = nt_errstr(status);
77 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
78 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
80 printf("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
81 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
83 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
85 } else if (!W_ERROR_IS_OK(r.out.result)) {
86 printf("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
87 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
89 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
97 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
98 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) {
99 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
100 r.out.ctr.ctr1->array[0].status);
103 printf ("(expected) error\n");
105 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
106 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
107 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
108 r.out.ctr.ctr1->array[0].status);
111 printf ("(expected) error\n");
113 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
114 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
115 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR) {
116 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
117 r.out.ctr.ctr1->array[0].status);
120 printf ("(expected) error\n");
123 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
124 printf("Error: %d\n", r.out.ctr.ctr1->array[0].status);
129 switch (formats[i]) {
130 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
131 n_from[i] = user_principal_name;
133 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
134 n_from[i] = service_principal_name;
136 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
137 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
141 n_from[i] = r.out.ctr.ctr1->array[0].result_name;
142 printf("%s\n", n_from[i]);
146 for (i = 0; i < ARRAY_SIZE(formats); i++) {
147 for (j = 0; j < ARRAY_SIZE(formats); j++) {
148 r.in.req.req1.format_offered = formats[i];
149 r.in.req.req1.format_desired = formats[j];
151 n_matrix[i][j] = NULL;
154 names[0].str = n_from[i];
155 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
156 if (!NT_STATUS_IS_OK(status)) {
157 const char *errstr = nt_errstr(status);
158 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
159 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
161 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
162 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, errstr);
164 } else if (!W_ERROR_IS_OK(r.out.result)) {
165 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
166 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired,
167 win_errstr(r.out.result));
174 if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
175 n_matrix[i][j] = r.out.ctr.ctr1->array[0].result_name;
177 n_matrix[i][j] = NULL;
182 for (i = 0; i < ARRAY_SIZE(formats); i++) {
183 for (j = 0; j < ARRAY_SIZE(formats); j++) {
184 if (n_matrix[i][j] == n_from[j]) {
186 /* We don't have a from name for these yet (and we can't map to them to find it out) */
187 } else if (n_matrix[i][j] == NULL && n_from[i] == NULL) {
189 /* we can't map to these two */
190 } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
191 } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
192 } else if (n_matrix[i][j] == NULL && n_from[j] != NULL) {
193 printf("dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s\n", formats[i], formats[j], n_matrix[i][j], n_from[j]);
195 } else if (n_matrix[i][j] != NULL && n_from[j] == NULL) {
196 printf("dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s\n", formats[i], formats[j], n_matrix[i][j], n_from[j]);
198 } else if (strcmp(n_matrix[i][j], n_from[j]) != 0) {
199 printf("dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s\n", formats[i], formats[j], n_matrix[i][j], n_from[j]);
207 BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
208 struct DsPrivate *priv)
211 struct drsuapi_DsCrackNames r;
212 struct drsuapi_DsNameString names[1];
214 const char *dns_domain;
215 const char *nt4_domain;
216 const char *FQDN_1779_name;
217 struct ldb_context *ldb;
218 struct ldb_dn *FQDN_1779_dn;
219 struct ldb_dn *realm_dn;
220 const char *realm_dn_str;
221 const char *realm_canonical;
222 const char *realm_canonical_ex;
223 const char *user_principal_name;
224 char *user_principal_name_short;
225 const char *service_principal_name;
226 const char *canonical_name;
227 const char *canonical_ex_name;
229 const char *test_dc = torture_join_netbios_name(priv->join);
232 r.in.bind_handle = &priv->bind_handle;
234 r.in.req.req1.codepage = 1252; /* german */
235 r.in.req.req1.language = 0x00000407; /* german */
236 r.in.req.req1.count = 1;
237 r.in.req.req1.names = names;
238 r.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
240 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
241 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
243 dom_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join));
245 names[0].str = dom_sid;
247 printf("testing DsCrackNames with name '%s' desired format:%d\n",
248 names[0].str, r.in.req.req1.format_desired);
250 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
251 if (!NT_STATUS_IS_OK(status)) {
252 const char *errstr = nt_errstr(status);
253 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
254 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
256 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
258 } else if (!W_ERROR_IS_OK(r.out.result)) {
259 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
261 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
262 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
270 dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
271 nt4_domain = r.out.ctr.ctr1->array[0].result_name;
273 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID;
275 printf("testing DsCrackNames with name '%s' desired format:%d\n",
276 names[0].str, r.in.req.req1.format_desired);
278 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
279 if (!NT_STATUS_IS_OK(status)) {
280 const char *errstr = nt_errstr(status);
281 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
282 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
284 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
286 } else if (!W_ERROR_IS_OK(r.out.result)) {
287 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
289 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
290 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
298 priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
299 priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
300 GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
302 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
304 printf("testing DsCrackNames with name '%s' desired format:%d\n",
305 names[0].str, r.in.req.req1.format_desired);
307 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
308 if (!NT_STATUS_IS_OK(status)) {
309 const char *errstr = nt_errstr(status);
310 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
311 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
313 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
315 } else if (!W_ERROR_IS_OK(r.out.result)) {
316 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
318 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
319 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
327 ldb = ldb_init(mem_ctx);
329 realm_dn_str = r.out.ctr.ctr1->array[0].result_name;
330 realm_dn = ldb_dn_new(mem_ctx, ldb, realm_dn_str);
331 realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn);
333 if (strcmp(realm_canonical,
334 talloc_asprintf(mem_ctx, "%s/", dns_domain))!= 0) {
335 printf("local Round trip on canonical name failed: %s != %s!\n",
337 talloc_asprintf(mem_ctx, "%s/", dns_domain));
341 realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn);
343 if (strcmp(realm_canonical_ex,
344 talloc_asprintf(mem_ctx, "%s\n", dns_domain))!= 0) {
345 printf("local Round trip on canonical ex name failed: %s != %s!\n",
347 talloc_asprintf(mem_ctx, "%s\n", dns_domain));
351 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
352 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
353 names[0].str = nt4_domain;
355 printf("testing DsCrackNames with name '%s' desired format:%d\n",
356 names[0].str, r.in.req.req1.format_desired);
358 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
359 if (!NT_STATUS_IS_OK(status)) {
360 const char *errstr = nt_errstr(status);
361 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
362 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
364 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
366 } else if (!W_ERROR_IS_OK(r.out.result)) {
367 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
369 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
370 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
378 priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
380 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
381 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
382 names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
384 printf("testing DsCrackNames with name '%s' desired format:%d\n",
385 names[0].str, r.in.req.req1.format_desired);
387 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
388 if (!NT_STATUS_IS_OK(status)) {
389 const char *errstr = nt_errstr(status);
390 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
391 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
393 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
395 } else if (!W_ERROR_IS_OK(r.out.result)) {
396 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
398 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
399 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
407 FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
409 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
410 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
411 names[0].str = priv->domain_guid_str;
413 printf("testing DsCrackNames with name '%s' desired format:%d\n",
414 names[0].str, r.in.req.req1.format_desired);
416 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
417 if (!NT_STATUS_IS_OK(status)) {
418 const char *errstr = nt_errstr(status);
419 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
420 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
422 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
424 } else if (!W_ERROR_IS_OK(r.out.result)) {
425 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
427 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
428 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
436 if (strcmp(priv->domain_dns_name, r.out.ctr.ctr1->array[0].dns_domain_name) != 0) {
437 printf("DsCrackNames failed to return same DNS name - expected %s got %s\n", priv->domain_dns_name, r.out.ctr.ctr1->array[0].dns_domain_name);
441 FQDN_1779_dn = ldb_dn_new(mem_ctx, ldb, FQDN_1779_name);
443 canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn);
444 canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn);
446 user_principal_name = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain);
448 /* form up a user@DOMAIN */
449 user_principal_name_short = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, nt4_domain);
450 /* variable nt4_domain includs a trailing \ */
451 user_principal_name_short[strlen(user_principal_name_short) - 1] = '\0';
453 service_principal_name = talloc_asprintf(mem_ctx, "HOST/%s", test_dc);
457 enum drsuapi_DsNameFormat format_offered;
458 enum drsuapi_DsNameFormat format_desired;
461 const char *expected_str;
462 const char *expected_dns;
463 enum drsuapi_DsNameStatus status;
464 enum drsuapi_DsNameStatus alternate_status;
465 enum drsuapi_DsNameFlags flags;
469 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
470 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
471 .str = user_principal_name,
472 .expected_str = FQDN_1779_name,
473 .status = DRSUAPI_DS_NAME_STATUS_OK
476 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
477 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
478 .str = user_principal_name_short,
479 .expected_str = FQDN_1779_name,
480 .status = DRSUAPI_DS_NAME_STATUS_OK
483 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
484 .format_desired = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
485 .str = FQDN_1779_name,
486 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
489 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
490 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
491 .str = service_principal_name,
492 .expected_str = FQDN_1779_name,
493 .status = DRSUAPI_DS_NAME_STATUS_OK
496 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
497 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
498 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s", test_dc, dns_domain),
499 .comment = "ServicePrincipal Name",
500 .expected_str = FQDN_1779_name,
501 .status = DRSUAPI_DS_NAME_STATUS_OK
504 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
505 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
506 .str = FQDN_1779_name,
507 .expected_str = canonical_name,
508 .status = DRSUAPI_DS_NAME_STATUS_OK
511 .format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
512 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
513 .str = canonical_name,
514 .expected_str = FQDN_1779_name,
515 .status = DRSUAPI_DS_NAME_STATUS_OK
518 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
519 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
520 .str = FQDN_1779_name,
521 .expected_str = canonical_ex_name,
522 .status = DRSUAPI_DS_NAME_STATUS_OK
525 .format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
526 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
527 .str = canonical_ex_name,
528 .expected_str = FQDN_1779_name,
529 .status = DRSUAPI_DS_NAME_STATUS_OK
532 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
533 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
534 .str = FQDN_1779_name,
535 .comment = "DN to cannoical syntactial only",
536 .status = DRSUAPI_DS_NAME_STATUS_OK,
537 .expected_str = canonical_name,
538 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
541 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
542 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
543 .str = FQDN_1779_name,
544 .comment = "DN to cannoical EX syntactial only",
545 .status = DRSUAPI_DS_NAME_STATUS_OK,
546 .expected_str = canonical_ex_name,
547 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
550 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
551 .format_desired = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
552 .str = FQDN_1779_name,
553 .status = DRSUAPI_DS_NAME_STATUS_OK
556 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
557 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
558 .str = FQDN_1779_name,
559 .status = DRSUAPI_DS_NAME_STATUS_OK
562 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
563 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
564 .str = priv->domain_guid_str,
565 .comment = "Domain GUID to NT4 ACCOUNT",
566 .expected_str = nt4_domain,
567 .status = DRSUAPI_DS_NAME_STATUS_OK
570 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
571 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
572 .str = priv->domain_guid_str,
573 .comment = "Domain GUID to Canonical",
574 .expected_str = talloc_asprintf(mem_ctx, "%s/", dns_domain),
575 .status = DRSUAPI_DS_NAME_STATUS_OK
578 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
579 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
580 .str = priv->domain_guid_str,
581 .comment = "Domain GUID to Canonical EX",
582 .expected_str = talloc_asprintf(mem_ctx, "%s\n", dns_domain),
583 .status = DRSUAPI_DS_NAME_STATUS_OK
586 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
587 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
588 .str = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US",
589 .comment = "display name for Microsoft Support Account",
590 .status = DRSUAPI_DS_NAME_STATUS_OK,
591 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE,
592 .skip = lp_parm_bool(-1, "torture", "samba4", False)
595 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
596 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
597 .str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)),
598 .comment = "Account GUID -> DN",
599 .expected_str = FQDN_1779_name,
600 .status = DRSUAPI_DS_NAME_STATUS_OK
603 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
604 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
605 .str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)),
606 .comment = "Account GUID -> NT4 Account",
607 .expected_str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc),
608 .status = DRSUAPI_DS_NAME_STATUS_OK
611 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
612 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
613 .str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid),
614 .comment = "Site GUID",
615 .expected_str = priv->dcinfo.site_dn,
616 .status = DRSUAPI_DS_NAME_STATUS_OK
619 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
620 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
621 .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
622 .comment = "Computer GUID",
623 .expected_str = priv->dcinfo.computer_dn,
624 .status = DRSUAPI_DS_NAME_STATUS_OK
627 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
628 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
629 .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
630 .comment = "Computer GUID -> NT4 Account",
631 .status = DRSUAPI_DS_NAME_STATUS_OK
634 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
635 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
636 .str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid),
637 .comment = "Server GUID",
638 .expected_str = priv->dcinfo.server_dn,
639 .status = DRSUAPI_DS_NAME_STATUS_OK
642 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
643 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
644 .str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid),
645 .comment = "NTDS GUID",
646 .expected_str = priv->dcinfo.ntds_dn,
647 .status = DRSUAPI_DS_NAME_STATUS_OK,
648 .skip = GUID_all_zero(&priv->dcinfo.ntds_guid)
651 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
652 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
654 .comment = "DISLPAY NAME search for DC short name",
655 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
658 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
659 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
660 .str = talloc_asprintf(mem_ctx, "krbtgt/%s", dns_domain),
661 .comment = "Looking for KRBTGT as a serivce principal",
662 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
663 .expected_dns = dns_domain
666 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
667 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
668 .str = talloc_asprintf(mem_ctx, "bogus/%s", dns_domain),
669 .comment = "Looking for bogus serivce principal",
670 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
671 .expected_dns = dns_domain
674 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
675 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
676 .str = talloc_asprintf(mem_ctx, "bogus/%s.%s", test_dc, dns_domain),
677 .comment = "Looking for bogus serivce on test DC",
678 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
679 .expected_dns = talloc_asprintf(mem_ctx, "%s.%s", test_dc, dns_domain)
682 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
683 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
684 .str = talloc_asprintf(mem_ctx, "krbtgt"),
685 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
688 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
689 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
690 .comment = "Looking for the kadmin/changepw service as a serivce principal",
691 .str = talloc_asprintf(mem_ctx, "kadmin/changepw"),
692 .status = DRSUAPI_DS_NAME_STATUS_OK,
693 .expected_str = talloc_asprintf(mem_ctx, "CN=krbtgt,CN=Users,%s", realm_dn_str),
694 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
697 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
698 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
699 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
702 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
705 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
706 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
707 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
710 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
711 .expected_dns = "BOGUS"
714 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
715 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
716 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
719 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
720 .expected_dns = "BOGUS"
723 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
724 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
725 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s",
726 test_dc, dns_domain),
727 .status = DRSUAPI_DS_NAME_STATUS_OK
730 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
731 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
732 .str = talloc_asprintf(mem_ctx, "cifs/%s",
734 .status = DRSUAPI_DS_NAME_STATUS_OK
737 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
738 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
740 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
743 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
744 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
746 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
749 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
750 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
751 .str = "NOT AN NT4 NAME",
752 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
755 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
756 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
757 .comment = "Unparsable DN",
759 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
762 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
763 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
764 .comment = "Unparsable user principal",
765 .str = "NOT A PRINCIPAL",
766 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
769 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
770 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
771 .comment = "Unparsable service principal",
772 .str = "NOT A SERVICE PRINCIPAL",
773 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
776 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
777 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
778 .comment = "BIND GUID (ie, not in the directory)",
779 .str = GUID_string2(mem_ctx, &priv->bind_guid),
780 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
783 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
784 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
785 .comment = "Unqualified Machine account as user principal",
786 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
787 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
790 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
791 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
792 .comment = "Machine account as service principal",
793 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
794 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
797 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
798 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
799 .comment = "Full Machine account as service principal",
800 .str = user_principal_name,
801 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
804 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
805 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
806 .comment = "Realm as an NT4 domain lookup",
807 .str = talloc_asprintf(mem_ctx, "%s\\", dns_domain),
808 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
811 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
812 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
813 .comment = "BUILTIN\\ -> DN",
815 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
818 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
819 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
820 .comment = "BUITIN SID -> NT4 account",
822 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING,
823 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
826 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
827 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
829 .comment = "Builtin Domain SID -> DN",
830 .status = DRSUAPI_DS_NAME_STATUS_OK,
831 .expected_str = talloc_asprintf(mem_ctx, "CN=Builtin,%s", realm_dn_str),
832 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
835 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
836 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
837 .str = SID_BUILTIN_ADMINISTRATORS,
838 .comment = "Builtin Administrors SID -> DN",
839 .status = DRSUAPI_DS_NAME_STATUS_OK,
840 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
843 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
844 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
845 .str = SID_BUILTIN_ADMINISTRATORS,
846 .comment = "Builtin Administrors SID -> NT4 Account",
847 .status = DRSUAPI_DS_NAME_STATUS_OK,
848 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
851 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
852 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
853 .comment = "Domain SID -> DN",
855 .expected_str = realm_dn_str,
856 .status = DRSUAPI_DS_NAME_STATUS_OK
859 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
860 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
861 .comment = "Domain SID -> NT4 account",
863 .expected_str = nt4_domain,
864 .status = DRSUAPI_DS_NAME_STATUS_OK
867 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
868 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
869 .comment = "invalid user principal name",
871 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
872 .expected_dns = "bar"
875 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
876 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
877 .comment = "invalid user principal name in valid domain",
878 .str = talloc_asprintf(mem_ctx, "invalidusername@%s", dns_domain),
879 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
884 for (i=0; i < ARRAY_SIZE(crack); i++) {
886 r.in.req.req1.format_flags = crack[i].flags;
887 r.in.req.req1.format_offered = crack[i].format_offered;
888 r.in.req.req1.format_desired = crack[i].format_desired;
889 names[0].str = crack[i].str;
891 if (crack[i].comment) {
892 comment = talloc_asprintf(mem_ctx, "'%s' with name '%s' desired format:%d\n",
893 crack[i].comment, names[0].str, r.in.req.req1.format_desired);
895 comment = talloc_asprintf(mem_ctx, "'%s' desired format:%d\n",
896 names[0].str, r.in.req.req1.format_desired);
899 printf("skipping: %s", comment);
902 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
903 if (!NT_STATUS_IS_OK(status)) {
904 const char *errstr = nt_errstr(status);
905 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
906 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
908 printf("dcerpc_drsuapi_DsCrackNames failed on %s - %s\n", comment, errstr);
910 } else if (!W_ERROR_IS_OK(r.out.result)) {
911 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
913 } else if (r.out.ctr.ctr1->array[0].status != crack[i].status) {
914 if (crack[i].alternate_status) {
915 if (r.out.ctr.ctr1->array[0].status != crack[i].alternate_status) {
916 printf("DsCrackNames unexpected status %d, wanted %d or %d on: %s\n",
917 r.out.ctr.ctr1->array[0].status,
919 crack[i].alternate_status,
924 printf("DsCrackNames unexpected status %d, wanted %d on: %s\n",
925 r.out.ctr.ctr1->array[0].status,
930 } else if (crack[i].expected_str
931 && (strcmp(r.out.ctr.ctr1->array[0].result_name,
932 crack[i].expected_str) != 0)) {
933 if (strcasecmp(r.out.ctr.ctr1->array[0].result_name,
934 crack[i].expected_str) != 0) {
935 printf("DsCrackNames failed - got %s, expected %s on %s\n",
936 r.out.ctr.ctr1->array[0].result_name,
937 crack[i].expected_str, comment);
940 printf("(warning) DsCrackNames returned different case - got %s, expected %s on %s\n",
941 r.out.ctr.ctr1->array[0].result_name,
942 crack[i].expected_str, comment);
944 } else if (crack[i].expected_dns
945 && (strcmp(r.out.ctr.ctr1->array[0].dns_domain_name,
946 crack[i].expected_dns) != 0)) {
947 printf("DsCrackNames failed - got DNS name %s, expected %s on %s\n",
948 r.out.ctr.ctr1->array[0].result_name,
949 crack[i].expected_str, comment);
955 if (!test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name,
956 user_principal_name, service_principal_name)) {