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"
31 static BOOL test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
32 struct DsPrivate *priv, const char *dn,
33 const char *user_principal_name, const char *service_principal_name)
39 struct drsuapi_DsCrackNames r;
40 enum drsuapi_DsNameFormat formats[] = {
41 DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
42 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
43 DRSUAPI_DS_NAME_FORMAT_DISPLAY,
44 DRSUAPI_DS_NAME_FORMAT_GUID,
45 DRSUAPI_DS_NAME_FORMAT_CANONICAL,
46 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
47 DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
48 DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
49 DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
50 DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN
52 struct drsuapi_DsNameString names[ARRAY_SIZE(formats)];
55 const char *n_matrix[ARRAY_SIZE(formats)][ARRAY_SIZE(formats)];
56 const char *n_from[ARRAY_SIZE(formats)];
59 r.in.bind_handle = &priv->bind_handle;
61 r.in.req.req1.unknown1 = 0x000004e4;
62 r.in.req.req1.unknown2 = 0x00000407;
63 r.in.req.req1.count = 1;
64 r.in.req.req1.names = names;
65 r.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
69 for (i = 0; i < ARRAY_SIZE(formats); i++) {
70 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
71 r.in.req.req1.format_desired = formats[i];
73 printf("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
74 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
76 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
77 if (!NT_STATUS_IS_OK(status)) {
78 const char *errstr = nt_errstr(status);
79 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
80 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
82 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
84 } else if (!W_ERROR_IS_OK(r.out.result)) {
85 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
93 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
94 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) {
95 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
96 r.out.ctr.ctr1->array[0].status);
99 printf ("(expected) error\n");
101 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
102 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
103 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
104 r.out.ctr.ctr1->array[0].status);
107 printf ("(expected) error\n");
109 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
110 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
111 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR) {
112 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n",
113 r.out.ctr.ctr1->array[0].status);
116 printf ("(expected) error\n");
119 if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
120 printf("Error: %d\n", r.out.ctr.ctr1->array[0].status);
125 switch (formats[i]) {
126 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
127 n_from[i] = user_principal_name;
129 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
130 n_from[i] = service_principal_name;
132 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
133 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
137 n_from[i] = r.out.ctr.ctr1->array[0].result_name;
138 printf("%s\n", n_from[i]);
142 for (i = 0; i < ARRAY_SIZE(formats); i++) {
143 for (j = 0; j < ARRAY_SIZE(formats); j++) {
144 r.in.req.req1.format_offered = formats[i];
145 r.in.req.req1.format_desired = formats[j];
147 n_matrix[i][j] = NULL;
150 names[0].str = n_from[i];
151 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
152 if (!NT_STATUS_IS_OK(status)) {
153 const char *errstr = nt_errstr(status);
154 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
155 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
157 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
158 names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, errstr);
160 } else if (!W_ERROR_IS_OK(r.out.result)) {
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,
163 win_errstr(r.out.result));
170 if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
171 n_matrix[i][j] = r.out.ctr.ctr1->array[0].result_name;
173 n_matrix[i][j] = NULL;
178 for (i = 0; i < ARRAY_SIZE(formats); i++) {
179 for (j = 0; j < ARRAY_SIZE(formats); j++) {
180 if (n_matrix[i][j] == n_from[j]) {
182 /* We don't have a from name for these yet (and we can't map to them to find it out) */
183 } else if (n_matrix[i][j] == NULL && n_from[i] == NULL) {
185 /* we can't map to these two */
186 } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
187 } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
188 } else if (n_matrix[i][j] == NULL && n_from[j] != NULL) {
189 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]);
191 } else if (n_matrix[i][j] != NULL && n_from[j] == NULL) {
192 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]);
194 } else if (strcmp(n_matrix[i][j], n_from[j]) != 0) {
195 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]);
203 BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
204 struct DsPrivate *priv, const char *test_dc)
207 struct drsuapi_DsCrackNames r;
208 struct drsuapi_DsNameString names[1];
210 const char *dns_domain;
211 const char *nt4_domain;
212 const char *FQDN_1779_name;
213 struct ldb_dn *FQDN_1779_dn;
214 struct ldb_dn *realm_dn;
215 const char *realm_dn_str;
216 const char *realm_canonical;
217 const char *realm_canonical_ex;
218 const char *user_principal_name;
219 char *user_principal_name_short;
220 const char *service_principal_name;
221 const char *canonical_name;
222 const char *canonical_ex_name;
225 r.in.bind_handle = &priv->bind_handle;
227 r.in.req.req1.unknown1 = 0x000004e4;
228 r.in.req.req1.unknown2 = 0x00000407;
229 r.in.req.req1.count = 1;
230 r.in.req.req1.names = names;
231 r.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
233 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
234 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
235 names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
237 printf("testing DsCrackNames with name '%s' desired format:%d\n",
238 names[0].str, r.in.req.req1.format_desired);
240 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
241 if (!NT_STATUS_IS_OK(status)) {
242 const char *errstr = nt_errstr(status);
243 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
244 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
246 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
248 } else if (!W_ERROR_IS_OK(r.out.result)) {
249 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
251 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
252 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
260 dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
261 nt4_domain = r.out.ctr.ctr1->array[0].result_name;
263 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID;
265 printf("testing DsCrackNames with name '%s' desired format:%d\n",
266 names[0].str, r.in.req.req1.format_desired);
268 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
269 if (!NT_STATUS_IS_OK(status)) {
270 const char *errstr = nt_errstr(status);
271 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
272 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
274 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
276 } else if (!W_ERROR_IS_OK(r.out.result)) {
277 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
279 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
280 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
288 priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
289 priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
290 GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
292 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
294 printf("testing DsCrackNames with name '%s' desired format:%d\n",
295 names[0].str, r.in.req.req1.format_desired);
297 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
298 if (!NT_STATUS_IS_OK(status)) {
299 const char *errstr = nt_errstr(status);
300 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
301 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
303 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
305 } else if (!W_ERROR_IS_OK(r.out.result)) {
306 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
308 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
309 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
317 realm_dn_str = r.out.ctr.ctr1->array[0].result_name;
318 realm_dn = ldb_dn_explode(mem_ctx, realm_dn_str);
319 realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn);
321 if (strcmp(realm_canonical,
322 talloc_asprintf(mem_ctx, "%s/", lp_realm()))!= 0) {
323 printf("local Round trip on canonical name failed: %s != %s!\n",
325 talloc_asprintf(mem_ctx, "%s/", lp_realm()));
329 realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn);
331 if (strcmp(realm_canonical_ex,
332 talloc_asprintf(mem_ctx, "%s\n", lp_realm()))!= 0) {
333 printf("local Round trip on canonical ex name failed: %s != %s!\n",
335 talloc_asprintf(mem_ctx, "%s\n", lp_realm()));
339 r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
340 r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
341 names[0].str = nt4_domain;
343 printf("testing DsCrackNames with name '%s' desired format:%d\n",
344 names[0].str, r.in.req.req1.format_desired);
346 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
347 if (!NT_STATUS_IS_OK(status)) {
348 const char *errstr = nt_errstr(status);
349 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
350 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
352 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
354 } else if (!W_ERROR_IS_OK(r.out.result)) {
355 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
357 } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
358 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
366 priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
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 = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
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 FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
397 FQDN_1779_dn = ldb_dn_explode(mem_ctx, FQDN_1779_name);
399 canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn);
400 canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn);
402 user_principal_name = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain);
404 /* form up a user@DOMAIN */
405 user_principal_name_short = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, nt4_domain);
406 /* variable nt4_domain includs a trailing \ */
407 user_principal_name_short[strlen(user_principal_name_short) - 1] = '\0';
409 service_principal_name = talloc_asprintf(mem_ctx, "HOST/%s", test_dc);
413 enum drsuapi_DsNameFormat format_offered;
414 enum drsuapi_DsNameFormat format_desired;
417 const char *expected_str;
418 enum drsuapi_DsNameStatus status;
419 enum drsuapi_DsNameFlags flags;
422 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
423 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
424 .str = user_principal_name,
425 .expected_str = FQDN_1779_name,
426 .status = DRSUAPI_DS_NAME_STATUS_OK
429 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
430 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
431 .str = user_principal_name_short,
432 .expected_str = FQDN_1779_name,
433 .status = DRSUAPI_DS_NAME_STATUS_OK
436 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
437 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
438 .str = service_principal_name,
439 .expected_str = FQDN_1779_name,
440 .status = DRSUAPI_DS_NAME_STATUS_OK
443 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
444 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
445 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s", test_dc, dns_domain),
446 .comment = "ServicePrincipal Name",
447 .expected_str = FQDN_1779_name,
448 .status = DRSUAPI_DS_NAME_STATUS_OK
451 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
452 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
453 .str = FQDN_1779_name,
454 .expected_str = canonical_name,
455 .status = DRSUAPI_DS_NAME_STATUS_OK
458 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
459 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
460 .str = FQDN_1779_name,
461 .expected_str = canonical_ex_name,
462 .status = DRSUAPI_DS_NAME_STATUS_OK
465 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
466 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
467 .str = FQDN_1779_name,
468 .comment = "DN to cannoical syntactial only",
469 .status = DRSUAPI_DS_NAME_STATUS_OK,
470 .expected_str = canonical_name,
471 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
474 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
475 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
476 .str = FQDN_1779_name,
477 .comment = "DN to cannoical EX syntactial only",
478 .status = DRSUAPI_DS_NAME_STATUS_OK,
479 .expected_str = canonical_ex_name,
480 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
483 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
484 .format_desired = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
485 .str = FQDN_1779_name,
486 .status = DRSUAPI_DS_NAME_STATUS_OK
489 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
490 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
491 .str = FQDN_1779_name,
492 .status = DRSUAPI_DS_NAME_STATUS_OK
495 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
496 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
497 .str = priv->domain_guid_str,
498 .comment = "Domain GUID to NT4 ACCOUNT",
499 .expected_str = nt4_domain,
500 .status = DRSUAPI_DS_NAME_STATUS_OK
503 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
504 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
505 .str = priv->domain_guid_str,
506 .comment = "Domain GUID to Canonical",
507 .expected_str = talloc_asprintf(mem_ctx, "%s/", dns_domain),
508 .status = DRSUAPI_DS_NAME_STATUS_OK
511 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
512 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
513 .str = priv->domain_guid_str,
514 .comment = "Domain GUID to Canonical EX",
515 .expected_str = talloc_asprintf(mem_ctx, "%s\n", dns_domain),
516 .status = DRSUAPI_DS_NAME_STATUS_OK
519 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
520 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
521 .str = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US",
522 .comment = "display name for Microsoft Support Account",
523 .status = DRSUAPI_DS_NAME_STATUS_OK
526 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
527 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
528 .str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid),
529 .comment = "Site GUID",
530 .status = DRSUAPI_DS_NAME_STATUS_OK
533 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
534 .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
535 .comment = "Computer GUID",
536 .status = DRSUAPI_DS_NAME_STATUS_OK
539 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
540 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
541 .str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid),
542 .comment = "Server GUID",
543 .status = DRSUAPI_DS_NAME_STATUS_OK
546 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
547 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
548 .str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid),
549 .comment = "NTDS GUID",
550 .status = DRSUAPI_DS_NAME_STATUS_OK
553 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
554 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
556 .comment = "BUILTIN domain SID",
557 .status = DRSUAPI_DS_NAME_STATUS_OK
560 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
561 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
563 .comment = "DISPAY NAME search for DC short name",
564 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
567 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
568 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
569 .str = talloc_asprintf(mem_ctx, "krbtgt/%s", dns_domain),
570 .comment = "Looking for KRBTGT as a serivce principal",
571 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
574 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
575 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
576 .str = talloc_asprintf(mem_ctx, "krbtgt"),
577 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
580 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
581 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
582 .comment = "Looking for the kadmin/changepw service as a serivce principal",
583 .str = talloc_asprintf(mem_ctx, "kadmin/changepw"),
584 .status = DRSUAPI_DS_NAME_STATUS_OK,
585 .expected_str = talloc_asprintf(mem_ctx, "CN=krbtgt,CN=Users,%s", realm_dn_str)
588 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
589 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
590 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
593 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
596 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
597 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
598 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
601 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
604 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
605 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
606 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
609 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
612 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
613 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
614 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s",
615 test_dc, dns_domain),
616 .status = DRSUAPI_DS_NAME_STATUS_OK
619 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
620 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
621 .str = talloc_asprintf(mem_ctx, "cifs/%s",
623 .status = DRSUAPI_DS_NAME_STATUS_OK
626 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
627 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
629 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
632 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
633 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
635 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
638 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
639 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
640 .str = "NOT AN NT4 NAME",
641 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
644 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
645 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
646 .comment = "Unparsable DN",
648 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
651 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
652 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
653 .comment = "Unparsable user principal",
654 .str = "NOT A PRINCIPAL",
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 .comment = "Unparsable service principal",
661 .str = "NOT A SERVICE PRINCIPAL",
662 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
665 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
666 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
667 .comment = "BIND GUID (ie, not in the directory)",
668 .str = GUID_string2(mem_ctx, &priv->bind_guid),
669 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
672 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
673 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
674 .comment = "Unqualified Machine account as user principal",
675 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
676 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
679 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
680 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
681 .comment = "Machine account as service principal",
682 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
683 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
686 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
687 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
688 .comment = "Full Machine account as service principal",
689 .str = user_principal_name,
690 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
693 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
694 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
695 .comment = "Realm as an NT4 domain lookup",
696 .str = talloc_asprintf(mem_ctx, "%s\\", lp_realm()),
697 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
700 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
701 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
702 .comment = "BUITIN SID -> NT4 account",
704 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
707 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
708 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
709 .str = SID_BUILTIN_ADMINISTRATORS,
710 .status = DRSUAPI_DS_NAME_STATUS_OK
713 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
714 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
715 .str = SID_BUILTIN_ADMINISTRATORS,
716 .status = DRSUAPI_DS_NAME_STATUS_OK
719 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
720 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
722 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
727 for (i=0; i < ARRAY_SIZE(crack); i++) {
728 r.in.req.req1.format_flags = crack[i].flags;
729 r.in.req.req1.format_offered = crack[i].format_offered;
730 r.in.req.req1.format_desired = crack[i].format_desired;
731 names[0].str = crack[i].str;
733 if (crack[i].comment) {
734 printf("testing DsCrackNames '%s' with name '%s' desired format:%d\n",
735 crack[i].comment, names[0].str, r.in.req.req1.format_desired);
737 printf("testing DsCrackNames with name '%s' desired format:%d\n",
738 names[0].str, r.in.req.req1.format_desired);
740 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
741 if (!NT_STATUS_IS_OK(status)) {
742 const char *errstr = nt_errstr(status);
743 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
744 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
746 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
748 } else if (!W_ERROR_IS_OK(r.out.result)) {
749 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
751 } else if (r.out.ctr.ctr1->array[0].status != crack[i].status) {
752 printf("DsCrackNames unexpected status %d, wanted %d on name: %s\n",
753 r.out.ctr.ctr1->array[0].status,
757 } else if (crack[i].expected_str
758 && (strcmp(r.out.ctr.ctr1->array[0].result_name,
759 crack[i].expected_str) != 0)) {
760 printf("DsCrackNames failed - got %s, expected %s\n",
761 r.out.ctr.ctr1->array[0].result_name,
762 crack[i].expected_str);
768 if (!test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name,
769 user_principal_name, service_principal_name)) {
776 BOOL torture_rpc_drsuapi_cracknames(struct torture_context *torture)
779 struct dcerpc_pipe *p;
782 struct DsPrivate priv;
784 mem_ctx = talloc_init("torture_rpc_drsuapi");
786 status = torture_rpc_connection(mem_ctx,
788 &dcerpc_table_drsuapi);
789 if (!NT_STATUS_IS_OK(status)) {
790 talloc_free(mem_ctx);
794 printf("Connected to DRSUAPI pipe\n");
798 ret &= test_DsBind(p, mem_ctx, &priv);
800 ret &= test_DsCrackNames(p, mem_ctx, &priv,
801 torture_setting_string(torture, "host", NULL));
803 ret &= test_DsUnbind(p, mem_ctx, &priv);
805 talloc_free(mem_ctx);