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 3 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, see <http://www.gnu.org/licenses/>.
25 #include "torture/torture.h"
26 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
27 #include "torture/rpc/rpc.h"
28 #include "ldb/include/ldb.h"
29 #include "libcli/security/security.h"
30 #include "param/param.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 union drsuapi_DsNameRequest req;
43 union drsuapi_DsNameCtr ctr;
45 enum drsuapi_DsNameFormat formats[] = {
46 DRSUAPI_DS_NAME_FORMAT_UNKNOWN,
47 DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
48 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
49 DRSUAPI_DS_NAME_FORMAT_DISPLAY,
50 DRSUAPI_DS_NAME_FORMAT_GUID,
51 DRSUAPI_DS_NAME_FORMAT_CANONICAL,
52 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
53 DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
54 DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
55 DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
56 DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN
58 struct drsuapi_DsNameString names[ARRAY_SIZE(formats)];
61 const char *n_matrix[ARRAY_SIZE(formats)][ARRAY_SIZE(formats)];
62 const char *n_from[ARRAY_SIZE(formats)];
65 r.in.bind_handle = &priv->bind_handle;
68 r.in.req->req1.codepage = 1252; /* german */
69 r.in.req->req1.language = 0x00000407; /* german */
70 r.in.req->req1.count = 1;
71 r.in.req->req1.names = names;
72 r.in.req->req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
74 r.out.level_out = &level_out;
79 for (i = 0; i < ARRAY_SIZE(formats); i++) {
80 r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
81 r.in.req->req1.format_desired = formats[i];
83 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
84 if (!NT_STATUS_IS_OK(status)) {
85 const char *errstr = nt_errstr(status);
86 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
87 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
89 printf("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
90 names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired);
92 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
94 } else if (!W_ERROR_IS_OK(r.out.result)) {
95 printf("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
96 names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired);
98 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
105 switch (formats[i]) {
106 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
107 if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) {
108 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
109 r.out.ctr->ctr1->array[0].status);
112 printf ("(expected) error\n");
114 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
115 if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
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");
122 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
123 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
124 if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR) {
125 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
126 r.out.ctr->ctr1->array[0].status);
129 printf ("(expected) error\n");
132 if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
133 printf("Error: %d\n", r.out.ctr->ctr1->array[0].status);
138 switch (formats[i]) {
139 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
140 n_from[i] = user_principal_name;
142 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
143 n_from[i] = service_principal_name;
145 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
146 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
150 n_from[i] = r.out.ctr->ctr1->array[0].result_name;
151 printf("%s\n", n_from[i]);
155 for (i = 0; i < ARRAY_SIZE(formats); i++) {
156 for (j = 0; j < ARRAY_SIZE(formats); j++) {
157 r.in.req->req1.format_offered = formats[i];
158 r.in.req->req1.format_desired = formats[j];
160 n_matrix[i][j] = NULL;
163 names[0].str = n_from[i];
164 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
165 if (!NT_STATUS_IS_OK(status)) {
166 const char *errstr = nt_errstr(status);
167 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
168 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
170 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
171 names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired, errstr);
173 } else if (!W_ERROR_IS_OK(r.out.result)) {
174 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
175 names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired,
176 win_errstr(r.out.result));
183 if (r.out.ctr->ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
184 n_matrix[i][j] = r.out.ctr->ctr1->array[0].result_name;
186 n_matrix[i][j] = NULL;
191 for (i = 0; i < ARRAY_SIZE(formats); i++) {
192 for (j = 0; j < ARRAY_SIZE(formats); j++) {
193 if (n_matrix[i][j] == n_from[j]) {
195 /* We don't have a from name for these yet (and we can't map to them to find it out) */
196 } else if (n_matrix[i][j] == NULL && n_from[i] == NULL) {
198 /* we can't map to these two */
199 } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
200 } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
201 } else if (n_matrix[i][j] == NULL && n_from[j] != NULL) {
202 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]);
204 } else if (n_matrix[i][j] != NULL && n_from[j] == NULL) {
205 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 } else if (strcmp(n_matrix[i][j], n_from[j]) != 0) {
208 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]);
216 bool test_DsCrackNames(struct torture_context *tctx,
217 struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
218 struct DsPrivate *priv)
221 struct drsuapi_DsCrackNames r;
222 union drsuapi_DsNameRequest req;
224 union drsuapi_DsNameCtr ctr;
225 struct drsuapi_DsNameString names[1];
227 const char *dns_domain;
228 const char *nt4_domain;
229 const char *FQDN_1779_name;
230 struct ldb_context *ldb;
231 struct ldb_dn *FQDN_1779_dn;
232 struct ldb_dn *realm_dn;
233 const char *realm_dn_str;
234 const char *realm_canonical;
235 const char *realm_canonical_ex;
236 const char *user_principal_name;
237 char *user_principal_name_short;
238 const char *service_principal_name;
239 const char *canonical_name;
240 const char *canonical_ex_name;
242 const char *test_dc = torture_join_netbios_name(priv->join);
245 r.in.bind_handle = &priv->bind_handle;
248 r.in.req->req1.codepage = 1252; /* german */
249 r.in.req->req1.language = 0x00000407; /* german */
250 r.in.req->req1.count = 1;
251 r.in.req->req1.names = names;
252 r.in.req->req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
254 r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
255 r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
257 r.out.level_out = &level_out;
260 dom_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join));
262 names[0].str = dom_sid;
264 printf("testing DsCrackNames with name '%s' desired format:%d\n",
265 names[0].str, r.in.req->req1.format_desired);
267 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
268 if (!NT_STATUS_IS_OK(status)) {
269 const char *errstr = nt_errstr(status);
270 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
271 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
273 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
275 } else if (!W_ERROR_IS_OK(r.out.result)) {
276 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
278 } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
279 printf("DsCrackNames failed on name - %d\n", r.out.ctr->ctr1->array[0].status);
287 dns_domain = r.out.ctr->ctr1->array[0].dns_domain_name;
288 nt4_domain = r.out.ctr->ctr1->array[0].result_name;
290 r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID;
292 printf("testing DsCrackNames with name '%s' desired format:%d\n",
293 names[0].str, r.in.req->req1.format_desired);
295 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
296 if (!NT_STATUS_IS_OK(status)) {
297 const char *errstr = nt_errstr(status);
298 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
299 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
301 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
303 } else if (!W_ERROR_IS_OK(r.out.result)) {
304 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
306 } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
307 printf("DsCrackNames failed on name - %d\n", r.out.ctr->ctr1->array[0].status);
315 priv->domain_dns_name = r.out.ctr->ctr1->array[0].dns_domain_name;
316 priv->domain_guid_str = r.out.ctr->ctr1->array[0].result_name;
317 GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
319 r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
321 printf("testing DsCrackNames with name '%s' desired format:%d\n",
322 names[0].str, r.in.req->req1.format_desired);
324 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
325 if (!NT_STATUS_IS_OK(status)) {
326 const char *errstr = nt_errstr(status);
327 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
328 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
330 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
332 } else if (!W_ERROR_IS_OK(r.out.result)) {
333 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
335 } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
336 printf("DsCrackNames failed on name - %d\n", r.out.ctr->ctr1->array[0].status);
344 ldb = ldb_init(mem_ctx, tctx->ev);
346 realm_dn_str = r.out.ctr->ctr1->array[0].result_name;
347 realm_dn = ldb_dn_new(mem_ctx, ldb, realm_dn_str);
348 realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn);
350 if (strcmp(realm_canonical,
351 talloc_asprintf(mem_ctx, "%s/", dns_domain))!= 0) {
352 printf("local Round trip on canonical name failed: %s != %s!\n",
354 talloc_asprintf(mem_ctx, "%s/", dns_domain));
358 realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn);
360 if (strcmp(realm_canonical_ex,
361 talloc_asprintf(mem_ctx, "%s\n", dns_domain))!= 0) {
362 printf("local Round trip on canonical ex name failed: %s != %s!\n",
364 talloc_asprintf(mem_ctx, "%s\n", dns_domain));
368 r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
369 r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
370 names[0].str = nt4_domain;
372 printf("testing DsCrackNames with name '%s' desired format:%d\n",
373 names[0].str, r.in.req->req1.format_desired);
375 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
376 if (!NT_STATUS_IS_OK(status)) {
377 const char *errstr = nt_errstr(status);
378 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
379 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
381 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
383 } else if (!W_ERROR_IS_OK(r.out.result)) {
384 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
386 } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
387 printf("DsCrackNames failed on name - %d\n", r.out.ctr->ctr1->array[0].status);
395 priv->domain_obj_dn = r.out.ctr->ctr1->array[0].result_name;
397 r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
398 r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
399 names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
401 printf("testing DsCrackNames with name '%s' desired format:%d\n",
402 names[0].str, r.in.req->req1.format_desired);
404 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
405 if (!NT_STATUS_IS_OK(status)) {
406 const char *errstr = nt_errstr(status);
407 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
408 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
410 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
412 } else if (!W_ERROR_IS_OK(r.out.result)) {
413 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
415 } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
416 printf("DsCrackNames failed on name - %d\n", r.out.ctr->ctr1->array[0].status);
424 FQDN_1779_name = r.out.ctr->ctr1->array[0].result_name;
426 r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
427 r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
428 names[0].str = priv->domain_guid_str;
430 printf("testing DsCrackNames with name '%s' desired format:%d\n",
431 names[0].str, r.in.req->req1.format_desired);
433 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
434 if (!NT_STATUS_IS_OK(status)) {
435 const char *errstr = nt_errstr(status);
436 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
437 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
439 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
441 } else if (!W_ERROR_IS_OK(r.out.result)) {
442 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
444 } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
445 printf("DsCrackNames failed on name - %d\n", r.out.ctr->ctr1->array[0].status);
453 if (strcmp(priv->domain_dns_name, r.out.ctr->ctr1->array[0].dns_domain_name) != 0) {
454 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);
458 FQDN_1779_dn = ldb_dn_new(mem_ctx, ldb, FQDN_1779_name);
460 canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn);
461 canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn);
463 user_principal_name = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain);
465 /* form up a user@DOMAIN */
466 user_principal_name_short = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, nt4_domain);
467 /* variable nt4_domain includs a trailing \ */
468 user_principal_name_short[strlen(user_principal_name_short) - 1] = '\0';
470 service_principal_name = talloc_asprintf(mem_ctx, "HOST/%s", test_dc);
474 enum drsuapi_DsNameFormat format_offered;
475 enum drsuapi_DsNameFormat format_desired;
478 const char *expected_str;
479 const char *expected_dns;
480 enum drsuapi_DsNameStatus status;
481 enum drsuapi_DsNameStatus alternate_status;
482 enum drsuapi_DsNameFlags flags;
486 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
487 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
488 .str = user_principal_name,
489 .expected_str = FQDN_1779_name,
490 .status = DRSUAPI_DS_NAME_STATUS_OK
493 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
494 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
495 .str = user_principal_name_short,
496 .expected_str = FQDN_1779_name,
497 .status = DRSUAPI_DS_NAME_STATUS_OK
500 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
501 .format_desired = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
502 .str = FQDN_1779_name,
503 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
506 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
507 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
508 .str = service_principal_name,
509 .expected_str = FQDN_1779_name,
510 .status = DRSUAPI_DS_NAME_STATUS_OK
513 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
514 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
515 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s", test_dc, dns_domain),
516 .comment = "ServicePrincipal Name",
517 .expected_str = FQDN_1779_name,
518 .status = DRSUAPI_DS_NAME_STATUS_OK
521 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
522 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
523 .str = FQDN_1779_name,
524 .expected_str = canonical_name,
525 .status = DRSUAPI_DS_NAME_STATUS_OK
528 .format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
529 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
530 .str = canonical_name,
531 .expected_str = FQDN_1779_name,
532 .status = DRSUAPI_DS_NAME_STATUS_OK
535 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
536 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
537 .str = FQDN_1779_name,
538 .expected_str = canonical_ex_name,
539 .status = DRSUAPI_DS_NAME_STATUS_OK
542 .format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
543 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
544 .str = canonical_ex_name,
545 .expected_str = FQDN_1779_name,
546 .status = DRSUAPI_DS_NAME_STATUS_OK
549 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
550 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
551 .str = FQDN_1779_name,
552 .comment = "DN to cannoical syntactial only",
553 .status = DRSUAPI_DS_NAME_STATUS_OK,
554 .expected_str = canonical_name,
555 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
558 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
559 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
560 .str = FQDN_1779_name,
561 .comment = "DN to cannoical EX syntactial only",
562 .status = DRSUAPI_DS_NAME_STATUS_OK,
563 .expected_str = canonical_ex_name,
564 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
567 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
568 .format_desired = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
569 .str = FQDN_1779_name,
570 .status = DRSUAPI_DS_NAME_STATUS_OK
573 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
574 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
575 .str = FQDN_1779_name,
576 .status = DRSUAPI_DS_NAME_STATUS_OK
579 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
580 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
581 .str = priv->domain_guid_str,
582 .comment = "Domain GUID to NT4 ACCOUNT",
583 .expected_str = nt4_domain,
584 .status = DRSUAPI_DS_NAME_STATUS_OK
587 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
588 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
589 .str = priv->domain_guid_str,
590 .comment = "Domain GUID to Canonical",
591 .expected_str = talloc_asprintf(mem_ctx, "%s/", dns_domain),
592 .status = DRSUAPI_DS_NAME_STATUS_OK
595 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
596 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
597 .str = priv->domain_guid_str,
598 .comment = "Domain GUID to Canonical EX",
599 .expected_str = talloc_asprintf(mem_ctx, "%s\n", dns_domain),
600 .status = DRSUAPI_DS_NAME_STATUS_OK
603 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
604 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
605 .str = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US",
606 .comment = "display name for Microsoft Support Account",
607 .status = DRSUAPI_DS_NAME_STATUS_OK,
608 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE,
609 .skip = torture_setting_bool(tctx, "samba4", false)
612 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
613 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
614 .str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)),
615 .comment = "Account GUID -> DN",
616 .expected_str = FQDN_1779_name,
617 .status = DRSUAPI_DS_NAME_STATUS_OK
620 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
621 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
622 .str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)),
623 .comment = "Account GUID -> NT4 Account",
624 .expected_str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc),
625 .status = DRSUAPI_DS_NAME_STATUS_OK
628 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
629 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
630 .str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid),
631 .comment = "Site GUID",
632 .expected_str = priv->dcinfo.site_dn,
633 .status = DRSUAPI_DS_NAME_STATUS_OK
636 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
637 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
638 .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
639 .comment = "Computer GUID",
640 .expected_str = priv->dcinfo.computer_dn,
641 .status = DRSUAPI_DS_NAME_STATUS_OK
644 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
645 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
646 .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
647 .comment = "Computer GUID -> NT4 Account",
648 .status = DRSUAPI_DS_NAME_STATUS_OK
651 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
652 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
653 .str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid),
654 .comment = "Server GUID",
655 .expected_str = priv->dcinfo.server_dn,
656 .status = DRSUAPI_DS_NAME_STATUS_OK
659 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
660 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
661 .str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid),
662 .comment = "NTDS GUID",
663 .expected_str = priv->dcinfo.ntds_dn,
664 .status = DRSUAPI_DS_NAME_STATUS_OK,
665 .skip = GUID_all_zero(&priv->dcinfo.ntds_guid)
668 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
669 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
671 .comment = "DISLPAY NAME search for DC short name",
672 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
675 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
676 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
677 .str = talloc_asprintf(mem_ctx, "krbtgt/%s", dns_domain),
678 .comment = "Looking for KRBTGT as a serivce principal",
679 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
680 .expected_dns = dns_domain
683 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
684 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
685 .str = talloc_asprintf(mem_ctx, "bogus/%s", dns_domain),
686 .comment = "Looking for bogus serivce principal",
687 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
688 .expected_dns = dns_domain
691 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
692 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
693 .str = talloc_asprintf(mem_ctx, "bogus/%s.%s", test_dc, dns_domain),
694 .comment = "Looking for bogus serivce on test DC",
695 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
696 .expected_dns = talloc_asprintf(mem_ctx, "%s.%s", test_dc, dns_domain)
699 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
700 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
701 .str = talloc_asprintf(mem_ctx, "krbtgt"),
702 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
705 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
706 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
707 .comment = "Looking for the kadmin/changepw service as a serivce principal",
708 .str = talloc_asprintf(mem_ctx, "kadmin/changepw"),
709 .status = DRSUAPI_DS_NAME_STATUS_OK,
710 .expected_str = talloc_asprintf(mem_ctx, "CN=krbtgt,CN=Users,%s", realm_dn_str),
711 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
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
722 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
723 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
724 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
727 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
728 .expected_dns = "BOGUS"
731 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
732 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
733 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
736 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
737 .expected_dns = "BOGUS"
740 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
741 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
742 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s",
743 test_dc, dns_domain),
744 .status = DRSUAPI_DS_NAME_STATUS_OK
747 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
748 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
749 .str = talloc_asprintf(mem_ctx, "cifs/%s",
751 .status = DRSUAPI_DS_NAME_STATUS_OK
754 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
755 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
757 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
760 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
761 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
763 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
766 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
767 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
768 .str = "NOT AN NT4 NAME",
769 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
772 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
773 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
774 .comment = "Unparsable DN",
776 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
779 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
780 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
781 .comment = "Unparsable user principal",
782 .str = "NOT A PRINCIPAL",
783 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
786 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
787 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
788 .comment = "Unparsable service principal",
789 .str = "NOT A SERVICE PRINCIPAL",
790 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
793 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
794 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
795 .comment = "BIND GUID (ie, not in the directory)",
796 .str = GUID_string2(mem_ctx, &priv->bind_guid),
797 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
800 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
801 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
802 .comment = "Unqualified Machine account as user principal",
803 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
804 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
807 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
808 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
809 .comment = "Machine account as service principal",
810 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
811 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
814 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
815 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
816 .comment = "Full Machine account as service principal",
817 .str = user_principal_name,
818 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
821 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
822 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
823 .comment = "Realm as an NT4 domain lookup",
824 .str = talloc_asprintf(mem_ctx, "%s\\", dns_domain),
825 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
828 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
829 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
830 .comment = "BUILTIN\\ -> DN",
832 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
835 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
836 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
837 .comment = "NT AUTHORITY\\ -> DN",
838 .str = "NT AUTHORITY\\",
839 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
842 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
843 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
844 .comment = "NT AUTHORITY\\ANONYMOUS LOGON -> DN",
845 .str = "NT AUTHORITY\\ANONYMOUS LOGON",
846 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
849 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
850 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
851 .comment = "NT AUTHORITY\\SYSTEM -> DN",
852 .str = "NT AUTHORITY\\SYSTEM",
853 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
856 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
857 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
858 .comment = "BUITIN SID -> NT4 account",
860 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING,
861 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
864 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
865 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
867 .comment = "Builtin Domain SID -> DN",
868 .status = DRSUAPI_DS_NAME_STATUS_OK,
869 .expected_str = talloc_asprintf(mem_ctx, "CN=Builtin,%s", realm_dn_str),
870 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
873 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
874 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
875 .str = SID_BUILTIN_ADMINISTRATORS,
876 .comment = "Builtin Administrors SID -> DN",
877 .status = DRSUAPI_DS_NAME_STATUS_OK,
878 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
881 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
882 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
883 .str = SID_BUILTIN_ADMINISTRATORS,
884 .comment = "Builtin Administrors SID -> NT4 Account",
885 .status = DRSUAPI_DS_NAME_STATUS_OK,
886 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
889 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
890 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
891 .str = SID_NT_ANONYMOUS,
892 .comment = "NT Anonymous SID -> NT4 Account",
893 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
896 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
897 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
898 .str = SID_NT_SYSTEM,
899 .comment = "NT SYSTEM SID -> NT4 Account",
900 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
903 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
904 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
905 .comment = "Domain SID -> DN",
907 .expected_str = realm_dn_str,
908 .status = DRSUAPI_DS_NAME_STATUS_OK
911 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
912 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
913 .comment = "Domain SID -> NT4 account",
915 .expected_str = nt4_domain,
916 .status = DRSUAPI_DS_NAME_STATUS_OK
919 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
920 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
921 .comment = "invalid user principal name",
923 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
924 .expected_dns = "bar"
927 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
928 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
929 .comment = "invalid user principal name in valid domain",
930 .str = talloc_asprintf(mem_ctx, "invalidusername@%s", dns_domain),
931 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
936 for (i=0; i < ARRAY_SIZE(crack); i++) {
938 r.in.req->req1.format_flags = crack[i].flags;
939 r.in.req->req1.format_offered = crack[i].format_offered;
940 r.in.req->req1.format_desired = crack[i].format_desired;
941 names[0].str = crack[i].str;
943 if (crack[i].comment) {
944 comment = talloc_asprintf(mem_ctx, "'%s' with name '%s' desired format:%d\n",
945 crack[i].comment, names[0].str, r.in.req->req1.format_desired);
947 comment = talloc_asprintf(mem_ctx, "'%s' desired format:%d\n",
948 names[0].str, r.in.req->req1.format_desired);
951 printf("skipping: %s", comment);
954 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
955 if (!NT_STATUS_IS_OK(status)) {
956 const char *errstr = nt_errstr(status);
957 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
958 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
960 printf("dcerpc_drsuapi_DsCrackNames failed on %s - %s\n", comment, errstr);
962 } else if (!W_ERROR_IS_OK(r.out.result)) {
963 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
965 } else if (r.out.ctr->ctr1->array[0].status != crack[i].status) {
966 if (crack[i].alternate_status) {
967 if (r.out.ctr->ctr1->array[0].status != crack[i].alternate_status) {
968 printf("DsCrackNames unexpected status %d, wanted %d or %d on: %s\n",
969 r.out.ctr->ctr1->array[0].status,
971 crack[i].alternate_status,
976 printf("DsCrackNames unexpected status %d, wanted %d on: %s\n",
977 r.out.ctr->ctr1->array[0].status,
982 } else if (crack[i].expected_str
983 && (strcmp(r.out.ctr->ctr1->array[0].result_name,
984 crack[i].expected_str) != 0)) {
985 if (strcasecmp(r.out.ctr->ctr1->array[0].result_name,
986 crack[i].expected_str) != 0) {
987 printf("DsCrackNames failed - got %s, expected %s on %s\n",
988 r.out.ctr->ctr1->array[0].result_name,
989 crack[i].expected_str, comment);
992 printf("(warning) DsCrackNames returned different case - got %s, expected %s on %s\n",
993 r.out.ctr->ctr1->array[0].result_name,
994 crack[i].expected_str, comment);
996 } else if (crack[i].expected_dns
997 && (strcmp(r.out.ctr->ctr1->array[0].dns_domain_name,
998 crack[i].expected_dns) != 0)) {
999 printf("DsCrackNames failed - got DNS name %s, expected %s on %s\n",
1000 r.out.ctr->ctr1->array[0].result_name,
1001 crack[i].expected_str, comment);
1007 if (!test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name,
1008 user_principal_name, service_principal_name)) {