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.unknown1 = 0x000004e4;
63 r.in.req.req1.unknown2 = 0x00000407;
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 printf("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
75 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
77 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
78 if (!NT_STATUS_IS_OK(status)) {
79 const char *errstr = nt_errstr(status);
80 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
81 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
83 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
85 } else if (!W_ERROR_IS_OK(r.out.result)) {
86 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
94 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
95 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) {
96 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
97 r.out.ctr.ctr1->array[0].status);
100 printf ("(expected) error\n");
102 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
103 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
104 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
105 r.out.ctr.ctr1->array[0].status);
108 printf ("(expected) error\n");
110 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
111 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
112 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR) {
113 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
114 r.out.ctr.ctr1->array[0].status);
117 printf ("(expected) error\n");
120 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
121 printf("Error: %d\n", r.out.ctr.ctr1->array[0].status);
126 switch (formats[i]) {
127 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
128 n_from[i] = user_principal_name;
130 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
131 n_from[i] = service_principal_name;
133 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
134 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
138 n_from[i] = r.out.ctr.ctr1->array[0].result_name;
139 printf("%s\n", n_from[i]);
143 for (i = 0; i < ARRAY_SIZE(formats); i++) {
144 for (j = 0; j < ARRAY_SIZE(formats); j++) {
145 r.in.req.req1.format_offered = formats[i];
146 r.in.req.req1.format_desired = formats[j];
148 n_matrix[i][j] = NULL;
151 names[0].str = n_from[i];
152 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
153 if (!NT_STATUS_IS_OK(status)) {
154 const char *errstr = nt_errstr(status);
155 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
156 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
158 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
159 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, errstr);
161 } else if (!W_ERROR_IS_OK(r.out.result)) {
162 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
163 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired,
164 win_errstr(r.out.result));
171 if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
172 n_matrix[i][j] = r.out.ctr.ctr1->array[0].result_name;
174 n_matrix[i][j] = NULL;
179 for (i = 0; i < ARRAY_SIZE(formats); i++) {
180 for (j = 0; j < ARRAY_SIZE(formats); j++) {
181 if (n_matrix[i][j] == n_from[j]) {
183 /* We don't have a from name for these yet (and we can't map to them to find it out) */
184 } else if (n_matrix[i][j] == NULL && n_from[i] == NULL) {
186 /* we can't map to these two */
187 } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
188 } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
189 } else if (n_matrix[i][j] == NULL && n_from[j] != NULL) {
190 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]);
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 (strcmp(n_matrix[i][j], n_from[j]) != 0) {
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]);
204 BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
205 struct DsPrivate *priv, const char *test_dc)
208 struct drsuapi_DsCrackNames r;
209 struct drsuapi_DsNameString names[1];
211 const char *dns_domain;
212 const char *nt4_domain;
213 const char *FQDN_1779_name;
214 struct ldb_dn *FQDN_1779_dn;
215 struct ldb_dn *realm_dn;
216 const char *realm_dn_str;
217 const char *realm_canonical;
218 const char *realm_canonical_ex;
219 const char *user_principal_name;
220 char *user_principal_name_short;
221 const char *service_principal_name;
222 const char *canonical_name;
223 const char *canonical_ex_name;
227 r.in.bind_handle = &priv->bind_handle;
229 r.in.req.req1.unknown1 = 0x000004e4;
230 r.in.req.req1.unknown2 = 0x00000407;
231 r.in.req.req1.count = 1;
232 r.in.req.req1.names = names;
233 r.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
235 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
236 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
238 dc_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join));
240 names[0].str = dc_sid;
242 printf("testing DsCrackNames with name '%s' desired format:%d\n",
243 names[0].str, r.in.req.req1.format_desired);
245 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
246 if (!NT_STATUS_IS_OK(status)) {
247 const char *errstr = nt_errstr(status);
248 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
249 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
251 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
253 } else if (!W_ERROR_IS_OK(r.out.result)) {
254 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
256 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
257 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
265 dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
266 nt4_domain = r.out.ctr.ctr1->array[0].result_name;
268 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID;
270 printf("testing DsCrackNames with name '%s' desired format:%d\n",
271 names[0].str, r.in.req.req1.format_desired);
273 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
274 if (!NT_STATUS_IS_OK(status)) {
275 const char *errstr = nt_errstr(status);
276 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
277 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
279 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
281 } else if (!W_ERROR_IS_OK(r.out.result)) {
282 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
284 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
285 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
293 priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
294 priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
295 GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
297 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
299 printf("testing DsCrackNames with name '%s' desired format:%d\n",
300 names[0].str, r.in.req.req1.format_desired);
302 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
303 if (!NT_STATUS_IS_OK(status)) {
304 const char *errstr = nt_errstr(status);
305 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
306 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
308 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
310 } else if (!W_ERROR_IS_OK(r.out.result)) {
311 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
313 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
314 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
322 realm_dn_str = r.out.ctr.ctr1->array[0].result_name;
323 realm_dn = ldb_dn_explode(mem_ctx, realm_dn_str);
324 realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn);
326 if (strcmp(realm_canonical,
327 talloc_asprintf(mem_ctx, "%s/", dns_domain))!= 0) {
328 printf("local Round trip on canonical name failed: %s != %s!\n",
330 talloc_asprintf(mem_ctx, "%s/", dns_domain));
334 realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn);
336 if (strcmp(realm_canonical_ex,
337 talloc_asprintf(mem_ctx, "%s\n", dns_domain))!= 0) {
338 printf("local Round trip on canonical ex name failed: %s != %s!\n",
340 talloc_asprintf(mem_ctx, "%s\n", dns_domain));
344 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
345 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
346 names[0].str = nt4_domain;
348 printf("testing DsCrackNames with name '%s' desired format:%d\n",
349 names[0].str, r.in.req.req1.format_desired);
351 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
352 if (!NT_STATUS_IS_OK(status)) {
353 const char *errstr = nt_errstr(status);
354 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
355 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
357 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
359 } else if (!W_ERROR_IS_OK(r.out.result)) {
360 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
362 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
363 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
371 priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
373 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
374 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
375 names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
377 printf("testing DsCrackNames with name '%s' desired format:%d\n",
378 names[0].str, r.in.req.req1.format_desired);
380 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
381 if (!NT_STATUS_IS_OK(status)) {
382 const char *errstr = nt_errstr(status);
383 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
384 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
386 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
388 } else if (!W_ERROR_IS_OK(r.out.result)) {
389 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
391 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
392 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
400 FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
402 FQDN_1779_dn = ldb_dn_explode(mem_ctx, FQDN_1779_name);
404 canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn);
405 canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn);
407 user_principal_name = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain);
409 /* form up a user@DOMAIN */
410 user_principal_name_short = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, nt4_domain);
411 /* variable nt4_domain includs a trailing \ */
412 user_principal_name_short[strlen(user_principal_name_short) - 1] = '\0';
414 service_principal_name = talloc_asprintf(mem_ctx, "HOST/%s", test_dc);
418 enum drsuapi_DsNameFormat format_offered;
419 enum drsuapi_DsNameFormat format_desired;
422 const char *expected_str;
423 enum drsuapi_DsNameStatus status;
424 enum drsuapi_DsNameFlags flags;
427 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
428 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
429 .str = user_principal_name,
430 .expected_str = FQDN_1779_name,
431 .status = DRSUAPI_DS_NAME_STATUS_OK
434 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
435 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
436 .str = user_principal_name_short,
437 .expected_str = FQDN_1779_name,
438 .status = DRSUAPI_DS_NAME_STATUS_OK
441 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
442 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
443 .str = service_principal_name,
444 .expected_str = FQDN_1779_name,
445 .status = DRSUAPI_DS_NAME_STATUS_OK
448 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
449 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
450 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s", test_dc, dns_domain),
451 .comment = "ServicePrincipal Name",
452 .expected_str = FQDN_1779_name,
453 .status = DRSUAPI_DS_NAME_STATUS_OK
456 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
457 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
458 .str = FQDN_1779_name,
459 .expected_str = canonical_name,
460 .status = DRSUAPI_DS_NAME_STATUS_OK
463 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
464 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
465 .str = FQDN_1779_name,
466 .expected_str = canonical_ex_name,
467 .status = DRSUAPI_DS_NAME_STATUS_OK
470 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
471 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
472 .str = FQDN_1779_name,
473 .comment = "DN to cannoical syntactial only",
474 .status = DRSUAPI_DS_NAME_STATUS_OK,
475 .expected_str = canonical_name,
476 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
479 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
480 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
481 .str = FQDN_1779_name,
482 .comment = "DN to cannoical EX syntactial only",
483 .status = DRSUAPI_DS_NAME_STATUS_OK,
484 .expected_str = canonical_ex_name,
485 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
488 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
489 .format_desired = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
490 .str = FQDN_1779_name,
491 .status = DRSUAPI_DS_NAME_STATUS_OK
494 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
495 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
496 .str = FQDN_1779_name,
497 .status = DRSUAPI_DS_NAME_STATUS_OK
500 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
501 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
502 .str = priv->domain_guid_str,
503 .comment = "Domain GUID to NT4 ACCOUNT",
504 .expected_str = nt4_domain,
505 .status = DRSUAPI_DS_NAME_STATUS_OK
508 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
509 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
510 .str = priv->domain_guid_str,
511 .comment = "Domain GUID to Canonical",
512 .expected_str = talloc_asprintf(mem_ctx, "%s/", dns_domain),
513 .status = DRSUAPI_DS_NAME_STATUS_OK
516 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
517 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
518 .str = priv->domain_guid_str,
519 .comment = "Domain GUID to Canonical EX",
520 .expected_str = talloc_asprintf(mem_ctx, "%s\n", dns_domain),
521 .status = DRSUAPI_DS_NAME_STATUS_OK
524 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
525 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
526 .str = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US",
527 .comment = "display name for Microsoft Support Account",
528 .status = DRSUAPI_DS_NAME_STATUS_OK
531 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
532 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
533 .str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid),
534 .comment = "Site GUID",
535 .status = DRSUAPI_DS_NAME_STATUS_OK
538 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
539 .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
540 .comment = "Computer GUID",
541 .status = DRSUAPI_DS_NAME_STATUS_OK
544 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
545 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
546 .str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid),
547 .comment = "Server GUID",
548 .status = DRSUAPI_DS_NAME_STATUS_OK
551 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
552 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
553 .str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid),
554 .comment = "NTDS GUID",
555 .status = DRSUAPI_DS_NAME_STATUS_OK
558 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
559 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
561 .comment = "BUILTIN domain SID",
562 .status = DRSUAPI_DS_NAME_STATUS_OK
565 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
566 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
568 .comment = "DISLPAY NAME search for DC short name",
569 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
572 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
573 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
574 .str = talloc_asprintf(mem_ctx, "krbtgt/%s", dns_domain),
575 .comment = "Looking for KRBTGT as a serivce principal",
576 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
579 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
580 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
581 .str = talloc_asprintf(mem_ctx, "krbtgt"),
582 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
585 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
586 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
587 .comment = "Looking for the kadmin/changepw service as a serivce principal",
588 .str = talloc_asprintf(mem_ctx, "kadmin/changepw"),
589 .status = DRSUAPI_DS_NAME_STATUS_OK,
590 .expected_str = talloc_asprintf(mem_ctx, "CN=krbtgt,CN=Users,%s", realm_dn_str)
593 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
594 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
595 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
598 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
601 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
602 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
603 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
606 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
609 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
610 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
611 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
614 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
617 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
618 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
619 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s",
620 test_dc, dns_domain),
621 .status = DRSUAPI_DS_NAME_STATUS_OK
624 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
625 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
626 .str = talloc_asprintf(mem_ctx, "cifs/%s",
628 .status = DRSUAPI_DS_NAME_STATUS_OK
631 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
632 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
634 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
637 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
638 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
640 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
643 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
644 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
645 .str = "NOT AN NT4 NAME",
646 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
649 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
650 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
651 .comment = "Unparsable DN",
653 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
656 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
657 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
658 .comment = "Unparsable user principal",
659 .str = "NOT A PRINCIPAL",
660 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
663 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
664 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
665 .comment = "Unparsable service principal",
666 .str = "NOT A SERVICE PRINCIPAL",
667 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
670 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
671 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
672 .comment = "BIND GUID (ie, not in the directory)",
673 .str = GUID_string2(mem_ctx, &priv->bind_guid),
674 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
677 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
678 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
679 .comment = "Unqualified Machine account as user principal",
680 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
681 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
684 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
685 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
686 .comment = "Machine account as service principal",
687 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
688 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
691 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
692 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
693 .comment = "Full Machine account as service principal",
694 .str = user_principal_name,
695 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
698 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
699 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
700 .comment = "Realm as an NT4 domain lookup",
701 .str = talloc_asprintf(mem_ctx, "%s\\", dns_domain),
702 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
705 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
706 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
707 .comment = "BUITIN SID -> NT4 account",
709 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
712 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
713 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
714 .str = SID_BUILTIN_ADMINISTRATORS,
715 .status = DRSUAPI_DS_NAME_STATUS_OK
718 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
719 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
720 .str = SID_BUILTIN_ADMINISTRATORS,
721 .status = DRSUAPI_DS_NAME_STATUS_OK
724 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
725 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
726 .comment = "DC SID -> DN",
728 .expected_str = FQDN_1779_name,
729 .status = DRSUAPI_DS_NAME_STATUS_OK
732 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
733 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
734 .comment = "DC SID -> NT4 account",
736 .status = DRSUAPI_DS_NAME_STATUS_OK
739 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
740 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
742 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
747 for (i=0; i < ARRAY_SIZE(crack); i++) {
748 r.in.req.req1.format_flags = crack[i].flags;
749 r.in.req.req1.format_offered = crack[i].format_offered;
750 r.in.req.req1.format_desired = crack[i].format_desired;
751 names[0].str = crack[i].str;
753 if (crack[i].comment) {
754 printf("testing DsCrackNames '%s' with name '%s' desired format:%d\n",
755 crack[i].comment, names[0].str, r.in.req.req1.format_desired);
757 printf("testing DsCrackNames with name '%s' desired format:%d\n",
758 names[0].str, r.in.req.req1.format_desired);
760 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
761 if (!NT_STATUS_IS_OK(status)) {
762 const char *errstr = nt_errstr(status);
763 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
764 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
766 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
768 } else if (!W_ERROR_IS_OK(r.out.result)) {
769 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
771 } else if (r.out.ctr.ctr1->array[0].status != crack[i].status) {
772 printf("DsCrackNames unexpected status %d, wanted %d on name: %s\n",
773 r.out.ctr.ctr1->array[0].status,
777 } else if (crack[i].expected_str
778 && (strcmp(r.out.ctr.ctr1->array[0].result_name,
779 crack[i].expected_str) != 0)) {
780 printf("DsCrackNames failed - got %s, expected %s\n",
781 r.out.ctr.ctr1->array[0].result_name,
782 crack[i].expected_str);
788 if (!test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name,
789 user_principal_name, service_principal_name)) {
796 BOOL torture_rpc_drsuapi_cracknames(struct torture_context *torture)
799 struct dcerpc_pipe *p;
802 struct DsPrivate priv;
804 mem_ctx = talloc_init("torture_rpc_drsuapi");
806 status = torture_rpc_connection(mem_ctx,
808 &dcerpc_table_drsuapi);
809 if (!NT_STATUS_IS_OK(status)) {
810 talloc_free(mem_ctx);
814 printf("Connected to DRSUAPI pipe\n");
818 ret &= test_DsBind(p, mem_ctx, &priv);
820 ret &= test_DsCrackNames(p, mem_ctx, &priv,
821 torture_setting_string(torture, "host", NULL));
823 ret &= test_DsUnbind(p, mem_ctx, &priv);
825 talloc_free(mem_ctx);