• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source4/torture/rpc/
1/*
2   Unix SMB/CIFS implementation.
3
4   DRSUapi tests
5
6   Copyright (C) Andrew Tridgell 2003
7   Copyright (C) Stefan (metze) Metzmacher 2004
8   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
9
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.
14
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.
19
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/>.
22*/
23
24#include "includes.h"
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
31struct DsCrackNamesPrivate {
32	struct DsPrivate base;
33
34	/* following names are used in Crack Names Matrix test */
35	const char *fqdn_name;
36	const char *user_principal_name;
37	const char *service_principal_name;
38};
39
40static bool test_DsCrackNamesMatrix(struct torture_context *tctx,
41				    struct DsPrivate *priv, const char *dn,
42				    const char *user_principal_name, const char *service_principal_name)
43{
44	NTSTATUS status;
45	const char *err_msg;
46	struct drsuapi_DsCrackNames r;
47	union drsuapi_DsNameRequest req;
48	int32_t level_out;
49	union drsuapi_DsNameCtr ctr;
50	struct dcerpc_pipe *p = priv->pipe;
51	TALLOC_CTX *mem_ctx = priv;
52
53	enum drsuapi_DsNameFormat formats[] = {
54		DRSUAPI_DS_NAME_FORMAT_UNKNOWN,
55		DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
56		DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
57		DRSUAPI_DS_NAME_FORMAT_DISPLAY,
58		DRSUAPI_DS_NAME_FORMAT_GUID,
59		DRSUAPI_DS_NAME_FORMAT_CANONICAL,
60		DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
61		DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
62		DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
63		DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
64		DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN
65	};
66	struct drsuapi_DsNameString names[ARRAY_SIZE(formats)];
67	int i, j;
68
69	const char *n_matrix[ARRAY_SIZE(formats)][ARRAY_SIZE(formats)];
70	const char *n_from[ARRAY_SIZE(formats)];
71
72	ZERO_STRUCT(r);
73	r.in.bind_handle		= &priv->bind_handle;
74	r.in.level			= 1;
75	r.in.req			= &req;
76	r.in.req->req1.codepage		= 1252; /* german */
77	r.in.req->req1.language		= 0x00000407; /* german */
78	r.in.req->req1.count		= 1;
79	r.in.req->req1.names		= names;
80	r.in.req->req1.format_flags	= DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
81
82	r.out.level_out			= &level_out;
83	r.out.ctr			= &ctr;
84
85	n_matrix[0][0] = dn;
86
87	for (i = 0; i < ARRAY_SIZE(formats); i++) {
88		r.in.req->req1.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
89		r.in.req->req1.format_desired	= formats[i];
90		names[0].str = dn;
91		status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
92		if (!NT_STATUS_IS_OK(status)) {
93			const char *errstr = nt_errstr(status);
94			if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
95				errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
96			}
97			err_msg = talloc_asprintf(mem_ctx,
98					"testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d failed - %s",
99					names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired, errstr);
100			torture_fail(tctx, err_msg);
101		} else if (!W_ERROR_IS_OK(r.out.result)) {
102			err_msg = talloc_asprintf(mem_ctx,
103					"testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d failed - %s",
104			       names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired, win_errstr(r.out.result));
105			torture_fail(tctx, err_msg);
106		}
107
108		switch (formats[i]) {
109		case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
110			if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) {
111				err_msg = talloc_asprintf(mem_ctx,
112						"Unexpected error (%d): This name lookup should fail",
113						r.out.ctr->ctr1->array[0].status);
114				torture_fail(tctx, err_msg);
115			}
116			torture_comment(tctx, __location__ ": (expected) error\n");
117			break;
118		case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
119			if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
120				err_msg = talloc_asprintf(mem_ctx,
121						"Unexpected error (%d): This name lookup should fail",
122						r.out.ctr->ctr1->array[0].status);
123				torture_fail(tctx, err_msg);
124			}
125			torture_comment(tctx, __location__ ": (expected) error\n");
126			break;
127		case DRSUAPI_DS_NAME_FORMAT_UNKNOWN:	/* should fail as we ask server to convert to Unknown format */
128		case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
129		case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
130			if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR) {
131				err_msg = talloc_asprintf(mem_ctx,
132						"Unexpected error (%d): This name lookup should fail",
133						r.out.ctr->ctr1->array[0].status);
134				torture_fail(tctx, err_msg);
135			}
136			torture_comment(tctx, __location__ ": (expected) error\n");
137			break;
138		default:
139			if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
140				err_msg = talloc_asprintf(mem_ctx,
141						"DsCrackNames error: %d",
142						r.out.ctr->ctr1->array[0].status);
143				torture_fail(tctx, err_msg);
144			}
145			break;
146		}
147
148		switch (formats[i]) {
149		case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
150			n_from[i] = user_principal_name;
151			break;
152		case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:
153			n_from[i] = service_principal_name;
154			break;
155		case DRSUAPI_DS_NAME_FORMAT_UNKNOWN:
156		case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY:
157		case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
158			n_from[i] = NULL;
159			break;
160		default:
161			n_from[i] = r.out.ctr->ctr1->array[0].result_name;
162			printf("%s\n", n_from[i]);
163			break;
164		}
165	}
166
167	for (i = 0; i < ARRAY_SIZE(formats); i++) {
168		for (j = 0; j < ARRAY_SIZE(formats); j++) {
169			r.in.req->req1.format_offered	= formats[i];
170			r.in.req->req1.format_desired	= formats[j];
171			if (!n_from[i]) {
172				n_matrix[i][j] = NULL;
173				continue;
174			}
175			names[0].str = n_from[i];
176			status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
177			if (!NT_STATUS_IS_OK(status)) {
178				const char *errstr = nt_errstr(status);
179				if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
180					errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
181				}
182				err_msg = talloc_asprintf(mem_ctx,
183						"testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
184						names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired, errstr);
185				torture_fail(tctx, err_msg);
186			} else if (!W_ERROR_IS_OK(r.out.result)) {
187				err_msg = talloc_asprintf(mem_ctx,
188						"testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
189						names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired,
190						win_errstr(r.out.result));
191				torture_fail(tctx, err_msg);
192			}
193
194			if (r.out.ctr->ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
195				n_matrix[i][j] = r.out.ctr->ctr1->array[0].result_name;
196			} else {
197				n_matrix[i][j] = NULL;
198			}
199		}
200	}
201
202	for (i = 0; i < ARRAY_SIZE(formats); i++) {
203		for (j = 0; j < ARRAY_SIZE(formats); j++) {
204			if (n_matrix[i][j] == n_from[j]) {
205
206			/* We don't have a from name for these yet (and we can't map to them to find it out) */
207			} else if (n_matrix[i][j] == NULL && n_from[i] == NULL) {
208
209			/* we can't map to these two */
210			} else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
211			} else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
212			} else if (n_matrix[i][j] == NULL && n_from[j] != NULL) {
213				err_msg = talloc_asprintf(mem_ctx,
214						"dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s",
215						formats[i], formats[j], n_matrix[i][j], n_from[j]);
216				torture_fail(tctx, err_msg);
217			} else if (n_matrix[i][j] != NULL && n_from[j] == NULL) {
218				err_msg = talloc_asprintf(mem_ctx,
219						"dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s",
220						formats[i], formats[j], n_matrix[i][j], n_from[j]);
221				torture_fail(tctx, err_msg);
222			} else if (strcmp(n_matrix[i][j], n_from[j]) != 0) {
223				err_msg = talloc_asprintf(mem_ctx,
224						"dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s",
225						formats[i], formats[j], n_matrix[i][j], n_from[j]);
226				torture_fail(tctx, err_msg);
227			}
228		}
229	}
230
231	return true;
232}
233
234bool test_DsCrackNames(struct torture_context *tctx,
235		       struct DsPrivate *priv)
236{
237	NTSTATUS status;
238	const char *err_msg;
239	struct drsuapi_DsCrackNames r;
240	union drsuapi_DsNameRequest req;
241	int32_t level_out;
242	union drsuapi_DsNameCtr ctr;
243	struct drsuapi_DsNameString names[1];
244	const char *dns_domain;
245	const char *nt4_domain;
246	const char *FQDN_1779_name;
247	struct ldb_context *ldb;
248	struct ldb_dn *FQDN_1779_dn;
249	struct ldb_dn *realm_dn;
250	const char *realm_dn_str;
251	const char *realm_canonical;
252	const char *realm_canonical_ex;
253	const char *user_principal_name;
254	char *user_principal_name_short;
255	const char *service_principal_name;
256	const char *canonical_name;
257	const char *canonical_ex_name;
258	const char *dom_sid;
259	const char *test_dc = torture_join_netbios_name(priv->join);
260	struct dcerpc_pipe *p = priv->pipe;
261	TALLOC_CTX *mem_ctx = priv;
262
263	ZERO_STRUCT(r);
264	r.in.bind_handle		= &priv->bind_handle;
265	r.in.level			= 1;
266	r.in.req			= &req;
267	r.in.req->req1.codepage		= 1252; /* german */
268	r.in.req->req1.language		= 0x00000407; /* german */
269	r.in.req->req1.count		= 1;
270	r.in.req->req1.names		= names;
271	r.in.req->req1.format_flags	= DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
272
273	r.in.req->req1.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
274	r.in.req->req1.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
275
276	r.out.level_out			= &level_out;
277	r.out.ctr			= &ctr;
278
279	dom_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join));
280
281	names[0].str = dom_sid;
282
283	torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
284			names[0].str, r.in.req->req1.format_desired);
285
286	status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
287	if (!NT_STATUS_IS_OK(status)) {
288		const char *errstr = nt_errstr(status);
289		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
290			errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
291		}
292		err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
293		torture_fail(tctx, err_msg);
294	} else if (!W_ERROR_IS_OK(r.out.result)) {
295		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
296		torture_fail(tctx, err_msg);
297	} else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
298		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
299					  r.out.ctr->ctr1->array[0].status);
300		torture_fail(tctx, err_msg);
301	}
302
303	dns_domain = r.out.ctr->ctr1->array[0].dns_domain_name;
304	nt4_domain = r.out.ctr->ctr1->array[0].result_name;
305
306	r.in.req->req1.format_desired	= DRSUAPI_DS_NAME_FORMAT_GUID;
307
308	torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
309			names[0].str, r.in.req->req1.format_desired);
310
311	status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
312	if (!NT_STATUS_IS_OK(status)) {
313		const char *errstr = nt_errstr(status);
314		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
315			errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
316		}
317		err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
318		torture_fail(tctx, err_msg);
319	} else if (!W_ERROR_IS_OK(r.out.result)) {
320		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
321		torture_fail(tctx, err_msg);
322	} else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
323		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
324					  r.out.ctr->ctr1->array[0].status);
325		torture_fail(tctx, err_msg);
326	}
327
328	priv->domain_dns_name = r.out.ctr->ctr1->array[0].dns_domain_name;
329	priv->domain_guid_str = r.out.ctr->ctr1->array[0].result_name;
330	GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
331
332	r.in.req->req1.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
333
334	torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
335			names[0].str, r.in.req->req1.format_desired);
336
337	status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
338	if (!NT_STATUS_IS_OK(status)) {
339		const char *errstr = nt_errstr(status);
340		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
341			errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
342		}
343		err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
344		torture_fail(tctx, err_msg);
345	} else if (!W_ERROR_IS_OK(r.out.result)) {
346		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
347		torture_fail(tctx, err_msg);
348	} else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
349		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
350					  r.out.ctr->ctr1->array[0].status);
351		torture_fail(tctx, err_msg);
352	}
353
354	ldb = ldb_init(mem_ctx, tctx->ev);
355
356	realm_dn_str = r.out.ctr->ctr1->array[0].result_name;
357	realm_dn =  ldb_dn_new(mem_ctx, ldb, realm_dn_str);
358	realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn);
359
360	if (strcmp(realm_canonical,
361		   talloc_asprintf(mem_ctx, "%s/", dns_domain))!= 0) {
362		err_msg = talloc_asprintf(mem_ctx, "local Round trip on canonical name failed: %s != %s!",
363				          realm_canonical,
364				          talloc_asprintf(mem_ctx, "%s/", dns_domain));
365		torture_fail(tctx, err_msg);
366	};
367
368	realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn);
369
370	if (strcmp(realm_canonical_ex,
371		   talloc_asprintf(mem_ctx, "%s\n", dns_domain))!= 0) {
372		err_msg = talloc_asprintf(mem_ctx, "local Round trip on canonical ex name failed: %s != %s!",
373				          realm_canonical,
374				          talloc_asprintf(mem_ctx, "%s\n", dns_domain));
375		torture_fail(tctx, err_msg);
376	};
377
378	r.in.req->req1.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
379	r.in.req->req1.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
380	names[0].str = nt4_domain;
381
382	torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
383			names[0].str, r.in.req->req1.format_desired);
384
385	status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
386	if (!NT_STATUS_IS_OK(status)) {
387		const char *errstr = nt_errstr(status);
388		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
389			errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
390		}
391		err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
392		torture_fail(tctx, err_msg);
393	} else if (!W_ERROR_IS_OK(r.out.result)) {
394		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
395		torture_fail(tctx, err_msg);
396	} else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
397		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
398					  r.out.ctr->ctr1->array[0].status);
399		torture_fail(tctx, err_msg);
400	}
401
402	priv->domain_obj_dn = r.out.ctr->ctr1->array[0].result_name;
403
404	r.in.req->req1.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
405	r.in.req->req1.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
406	names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
407
408	torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
409			names[0].str, r.in.req->req1.format_desired);
410
411	status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
412	if (!NT_STATUS_IS_OK(status)) {
413		const char *errstr = nt_errstr(status);
414		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
415			errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
416		}
417		err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
418		torture_fail(tctx, err_msg);
419	} else if (!W_ERROR_IS_OK(r.out.result)) {
420		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
421		torture_fail(tctx, err_msg);
422	} else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
423		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
424					  r.out.ctr->ctr1->array[0].status);
425		torture_fail(tctx, err_msg);
426	}
427
428	FQDN_1779_name = r.out.ctr->ctr1->array[0].result_name;
429
430	r.in.req->req1.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID;
431	r.in.req->req1.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
432	names[0].str = priv->domain_guid_str;
433
434	torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
435			names[0].str, r.in.req->req1.format_desired);
436
437	status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
438	if (!NT_STATUS_IS_OK(status)) {
439		const char *errstr = nt_errstr(status);
440		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
441			errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
442		}
443		err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
444		torture_fail(tctx, err_msg);
445	} else if (!W_ERROR_IS_OK(r.out.result)) {
446		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
447		torture_fail(tctx, err_msg);
448	} else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
449		err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
450					  r.out.ctr->ctr1->array[0].status);
451		torture_fail(tctx, err_msg);
452	}
453
454	if (strcmp(priv->domain_dns_name, r.out.ctr->ctr1->array[0].dns_domain_name) != 0) {
455		err_msg = talloc_asprintf(mem_ctx,
456				"DsCrackNames failed to return same DNS name - expected %s got %s",
457				priv->domain_dns_name, r.out.ctr->ctr1->array[0].dns_domain_name);
458		torture_fail(tctx, err_msg);
459	}
460
461	FQDN_1779_dn = ldb_dn_new(mem_ctx, ldb, FQDN_1779_name);
462
463	canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn);
464	canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn);
465
466	user_principal_name = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain);
467
468	/* form up a user@DOMAIN */
469	user_principal_name_short = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, nt4_domain);
470	/* variable nt4_domain includs a trailing \ */
471	user_principal_name_short[strlen(user_principal_name_short) - 1] = '\0';
472
473	service_principal_name = talloc_asprintf(mem_ctx, "HOST/%s", test_dc);
474	{
475
476		struct {
477			enum drsuapi_DsNameFormat format_offered;
478			enum drsuapi_DsNameFormat format_desired;
479			const char *comment;
480			const char *str;
481			const char *expected_str;
482			const char *expected_dns;
483			enum drsuapi_DsNameStatus status;
484			enum drsuapi_DsNameStatus alternate_status;
485			enum drsuapi_DsNameFlags flags;
486			bool skip;
487		} crack[] = {
488			{
489				.format_offered	= DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
490				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
491				.str = user_principal_name,
492				.expected_str = FQDN_1779_name,
493				.status = DRSUAPI_DS_NAME_STATUS_OK
494			},
495			{
496				.format_offered	= DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
497				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
498				.str = user_principal_name_short,
499				.expected_str = FQDN_1779_name,
500				.status = DRSUAPI_DS_NAME_STATUS_OK
501			},
502			{
503				.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
504				.format_desired	= DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
505				.str = FQDN_1779_name,
506				.status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
507			},
508			{
509				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
510				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
511				.str = service_principal_name,
512				.expected_str = FQDN_1779_name,
513				.status = DRSUAPI_DS_NAME_STATUS_OK
514			},
515			{
516				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
517				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
518				.str = talloc_asprintf(mem_ctx, "cifs/%s.%s", test_dc, dns_domain),
519				.comment = "ServicePrincipal Name",
520				.expected_str = FQDN_1779_name,
521				.status = DRSUAPI_DS_NAME_STATUS_OK
522			},
523			{
524				.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
525				.format_desired	= DRSUAPI_DS_NAME_FORMAT_CANONICAL,
526				.str = FQDN_1779_name,
527				.expected_str = canonical_name,
528				.status = DRSUAPI_DS_NAME_STATUS_OK
529			},
530			{
531				.format_offered	= DRSUAPI_DS_NAME_FORMAT_CANONICAL,
532				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
533				.str = canonical_name,
534				.expected_str = FQDN_1779_name,
535				.status = DRSUAPI_DS_NAME_STATUS_OK
536			},
537			{
538				.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
539				.format_desired	= DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
540				.str = FQDN_1779_name,
541				.expected_str = canonical_ex_name,
542				.status = DRSUAPI_DS_NAME_STATUS_OK
543			},
544			{
545				.format_offered	= DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
546				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
547				.str = canonical_ex_name,
548				.expected_str = FQDN_1779_name,
549				.status = DRSUAPI_DS_NAME_STATUS_OK
550			},
551			{
552				.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
553				.format_desired	= DRSUAPI_DS_NAME_FORMAT_CANONICAL,
554				.str = FQDN_1779_name,
555				.comment = "DN to cannoical syntactial only",
556				.status = DRSUAPI_DS_NAME_STATUS_OK,
557				.expected_str = canonical_name,
558				.flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
559			},
560			{
561				.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
562				.format_desired	= DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
563				.str = FQDN_1779_name,
564				.comment = "DN to cannoical EX syntactial only",
565				.status = DRSUAPI_DS_NAME_STATUS_OK,
566				.expected_str = canonical_ex_name,
567				.flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
568			},
569			{
570				.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
571				.format_desired	= DRSUAPI_DS_NAME_FORMAT_DISPLAY,
572				.str = FQDN_1779_name,
573				.status = DRSUAPI_DS_NAME_STATUS_OK
574			},
575			{
576				.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
577				.format_desired	= DRSUAPI_DS_NAME_FORMAT_GUID,
578				.str = FQDN_1779_name,
579				.status = DRSUAPI_DS_NAME_STATUS_OK
580			},
581			{
582				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
583				.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
584				.str = priv->domain_guid_str,
585				.comment = "Domain GUID to NT4 ACCOUNT",
586				.expected_str = nt4_domain,
587				.status = DRSUAPI_DS_NAME_STATUS_OK
588			},
589			{
590				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
591				.format_desired	= DRSUAPI_DS_NAME_FORMAT_CANONICAL,
592				.str = priv->domain_guid_str,
593				.comment = "Domain GUID to Canonical",
594				.expected_str = talloc_asprintf(mem_ctx, "%s/", dns_domain),
595				.status = DRSUAPI_DS_NAME_STATUS_OK
596			},
597			{
598				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
599				.format_desired	= DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
600				.str = priv->domain_guid_str,
601				.comment = "Domain GUID to Canonical EX",
602				.expected_str = talloc_asprintf(mem_ctx, "%s\n", dns_domain),
603				.status = DRSUAPI_DS_NAME_STATUS_OK
604			},
605			{
606				.format_offered	= DRSUAPI_DS_NAME_FORMAT_DISPLAY,
607				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
608				.str = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US",
609				.comment = "display name for Microsoft Support Account",
610				.status = DRSUAPI_DS_NAME_STATUS_OK,
611				.alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE,
612				.skip = torture_setting_bool(tctx, "samba4", false)
613			},
614			{
615				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
616				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
617				.str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)),
618				.comment = "Account GUID -> DN",
619				.expected_str = FQDN_1779_name,
620				.status = DRSUAPI_DS_NAME_STATUS_OK
621			},
622			{
623				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
624				.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
625				.str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)),
626				.comment = "Account GUID -> NT4 Account",
627				.expected_str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc),
628				.status = DRSUAPI_DS_NAME_STATUS_OK
629			},
630			{
631				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
632				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
633				.str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid),
634				.comment = "Site GUID",
635				.expected_str = priv->dcinfo.site_dn,
636				.status = DRSUAPI_DS_NAME_STATUS_OK
637			},
638			{
639				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
640				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
641				.str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
642				.comment = "Computer GUID",
643				.expected_str = priv->dcinfo.computer_dn,
644				.status = DRSUAPI_DS_NAME_STATUS_OK
645			},
646			{
647				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
648				.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
649				.str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
650				.comment = "Computer GUID -> NT4 Account",
651				.status = DRSUAPI_DS_NAME_STATUS_OK
652			},
653			{
654				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
655				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
656				.str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid),
657				.comment = "Server GUID",
658				.expected_str = priv->dcinfo.server_dn,
659				.status = DRSUAPI_DS_NAME_STATUS_OK
660			},
661			{
662				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
663				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
664				.str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid),
665				.comment = "NTDS GUID",
666				.expected_str = priv->dcinfo.ntds_dn,
667				.status = DRSUAPI_DS_NAME_STATUS_OK,
668				.skip = GUID_all_zero(&priv->dcinfo.ntds_guid)
669			},
670			{
671				.format_offered	= DRSUAPI_DS_NAME_FORMAT_DISPLAY,
672				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
673				.str = test_dc,
674				.comment = "DISLPAY NAME search for DC short name",
675				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
676			},
677			{
678				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
679				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
680				.str = talloc_asprintf(mem_ctx, "krbtgt/%s", dns_domain),
681				.comment = "Looking for KRBTGT as a serivce principal",
682				.status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
683				.expected_dns = dns_domain
684			},
685			{
686				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
687				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
688				.str = talloc_asprintf(mem_ctx, "bogus/%s", dns_domain),
689				.comment = "Looking for bogus serivce principal",
690				.status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
691				.expected_dns = dns_domain
692			},
693			{
694				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
695				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
696				.str = talloc_asprintf(mem_ctx, "bogus/%s.%s", test_dc, dns_domain),
697				.comment = "Looking for bogus serivce on test DC",
698				.status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
699				.expected_dns = talloc_asprintf(mem_ctx, "%s.%s", test_dc, dns_domain)
700			},
701			{
702				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
703				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
704				.str = talloc_asprintf(mem_ctx, "krbtgt"),
705				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
706			},
707			{
708				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
709				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
710				.comment = "Looking for the kadmin/changepw service as a serivce principal",
711				.str = talloc_asprintf(mem_ctx, "kadmin/changepw"),
712				.status = DRSUAPI_DS_NAME_STATUS_OK,
713				.expected_str = talloc_asprintf(mem_ctx, "CN=krbtgt,CN=Users,%s", realm_dn_str),
714				.alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
715			},
716			{
717				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
718				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
719				.str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
720						       test_dc, dns_domain,
721						       dns_domain),
722				.status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
723			},
724			{
725				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
726				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
727				.str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
728						       test_dc, dns_domain,
729						       "BOGUS"),
730				.status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
731				.expected_dns = "BOGUS"
732			},
733			{
734				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
735				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
736				.str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
737						       test_dc, "REALLY",
738						       "BOGUS"),
739				.status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
740				.expected_dns = "BOGUS"
741			},
742			{
743				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
744				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
745				.str = talloc_asprintf(mem_ctx, "cifs/%s.%s",
746						       test_dc, dns_domain),
747				.status = DRSUAPI_DS_NAME_STATUS_OK
748			},
749			{
750				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
751				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
752				.str = talloc_asprintf(mem_ctx, "cifs/%s",
753						       test_dc),
754				.status = DRSUAPI_DS_NAME_STATUS_OK
755			},
756			{
757				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
758				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
759				.str = "NOT A GUID",
760				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
761			},
762			{
763				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
764				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
765				.str = "NOT A SID",
766				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
767			},
768			{
769				.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
770				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
771				.str = "NOT AN NT4 NAME",
772				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
773			},
774			{
775				.format_offered	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
776				.format_desired	= DRSUAPI_DS_NAME_FORMAT_GUID,
777				.comment = "Unparsable DN",
778				.str = "NOT A DN",
779				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
780			},
781			{
782				.format_offered	= DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
783				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
784				.comment = "Unparsable user principal",
785				.str = "NOT A PRINCIPAL",
786				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
787			},
788			{
789				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
790				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
791				.comment = "Unparsable service principal",
792				.str = "NOT A SERVICE PRINCIPAL",
793				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
794			},
795			{
796				.format_offered	= DRSUAPI_DS_NAME_FORMAT_GUID,
797				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
798				.comment = "BIND GUID (ie, not in the directory)",
799				.str = GUID_string2(mem_ctx, &priv->bind_guid),
800				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
801			},
802			{
803				.format_offered	= DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
804				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
805				.comment = "Unqualified Machine account as user principal",
806				.str = talloc_asprintf(mem_ctx, "%s$", test_dc),
807				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
808			},
809			{
810				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
811				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
812				.comment = "Machine account as service principal",
813				.str = talloc_asprintf(mem_ctx, "%s$", test_dc),
814				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
815			},
816			{
817				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
818				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
819				.comment = "Full Machine account as service principal",
820				.str = user_principal_name,
821				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
822			},
823			{
824				.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
825				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
826				.comment = "Realm as an NT4 domain lookup",
827				.str = talloc_asprintf(mem_ctx, "%s\\", dns_domain),
828				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
829			},
830			{
831				.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
832				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
833				.comment = "BUILTIN\\ -> DN",
834				.str = "BUILTIN\\",
835				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
836			},
837			{
838				.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
839				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
840				.comment = "NT AUTHORITY\\ -> DN",
841				.str = "NT AUTHORITY\\",
842				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
843			},
844			{
845				.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
846				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
847				.comment = "NT AUTHORITY\\ANONYMOUS LOGON -> DN",
848				.str = "NT AUTHORITY\\ANONYMOUS LOGON",
849				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
850			},
851			{
852				.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
853				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
854				.comment = "NT AUTHORITY\\SYSTEM -> DN",
855				.str = "NT AUTHORITY\\SYSTEM",
856				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
857			},
858			{
859				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
860				.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
861				.comment = "BUITIN SID -> NT4 account",
862				.str = SID_BUILTIN,
863				.status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING,
864				.alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
865			},
866			{
867				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
868				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
869				.str = SID_BUILTIN,
870				.comment = "Builtin Domain SID -> DN",
871				.status = DRSUAPI_DS_NAME_STATUS_OK,
872				.expected_str = talloc_asprintf(mem_ctx, "CN=Builtin,%s", realm_dn_str),
873				.alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
874			},
875			{
876				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
877				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
878				.str = SID_BUILTIN_ADMINISTRATORS,
879				.comment = "Builtin Administrors SID -> DN",
880				.status = DRSUAPI_DS_NAME_STATUS_OK,
881				.alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
882			},
883			{
884				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
885				.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
886				.str = SID_BUILTIN_ADMINISTRATORS,
887				.comment = "Builtin Administrors SID -> NT4 Account",
888				.status = DRSUAPI_DS_NAME_STATUS_OK,
889				.alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
890			},
891			{
892				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
893				.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
894				.str = SID_NT_ANONYMOUS,
895				.comment = "NT Anonymous SID -> NT4 Account",
896				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
897			},
898			{
899				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
900				.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
901				.str = SID_NT_SYSTEM,
902				.comment = "NT SYSTEM SID -> NT4 Account",
903				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
904			},
905			{
906				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
907				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
908				.comment = "Domain SID -> DN",
909				.str = dom_sid,
910				.expected_str = realm_dn_str,
911				.status = DRSUAPI_DS_NAME_STATUS_OK
912			},
913			{
914				.format_offered	= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
915				.format_desired	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
916				.comment = "Domain SID -> NT4 account",
917				.str = dom_sid,
918				.expected_str = nt4_domain,
919				.status = DRSUAPI_DS_NAME_STATUS_OK
920			},
921			{
922				.format_offered	= DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
923				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
924				.comment = "invalid user principal name",
925				.str = "foo@bar",
926				.status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
927				.expected_dns = "bar"
928			},
929			{
930				.format_offered	= DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
931				.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
932				.comment = "invalid user principal name in valid domain",
933				.str = talloc_asprintf(mem_ctx, "invalidusername@%s", dns_domain),
934				.status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
935			}
936		};
937		int i;
938
939		for (i=0; i < ARRAY_SIZE(crack); i++) {
940			const char *comment;
941			r.in.req->req1.format_flags   = crack[i].flags;
942			r.in.req->req1.format_offered = crack[i].format_offered;
943			r.in.req->req1.format_desired = crack[i].format_desired;
944			names[0].str = crack[i].str;
945
946			if (crack[i].comment) {
947				comment = talloc_asprintf(mem_ctx, "'%s' with name '%s' desired format:%d\n",
948							  crack[i].comment, names[0].str, r.in.req->req1.format_desired);
949			} else {
950				comment = talloc_asprintf(mem_ctx, "'%s' desired format:%d\n",
951				       names[0].str, r.in.req->req1.format_desired);
952			}
953			if (crack[i].skip) {
954				torture_comment(tctx, "skipping: %s", comment);
955				continue;
956			}
957			status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
958			if (!NT_STATUS_IS_OK(status)) {
959				const char *errstr = nt_errstr(status);
960				if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
961					errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
962				}
963				err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
964				torture_fail(tctx, err_msg);
965			} else if (!W_ERROR_IS_OK(r.out.result)) {
966				err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
967				torture_fail(tctx, err_msg);
968			} else if (r.out.ctr->ctr1->array[0].status != crack[i].status) {
969				if (crack[i].alternate_status) {
970					if (r.out.ctr->ctr1->array[0].status != crack[i].alternate_status) {
971						err_msg = talloc_asprintf(mem_ctx,
972								"DsCrackNames unexpected status %d, wanted %d or %d on: %s",
973								r.out.ctr->ctr1->array[0].status,
974								crack[i].status,
975								crack[i].alternate_status,
976								comment);
977						torture_fail(tctx, err_msg);
978					}
979				} else {
980					err_msg = talloc_asprintf(mem_ctx,
981							"DsCrackNames unexpected status %d, wanted %d on: %s\n",
982							r.out.ctr->ctr1->array[0].status,
983							crack[i].status,
984							comment);
985					torture_fail(tctx, err_msg);
986				}
987			} else if (crack[i].expected_str
988				   && (strcmp(r.out.ctr->ctr1->array[0].result_name,
989					      crack[i].expected_str) != 0)) {
990				if (strcasecmp(r.out.ctr->ctr1->array[0].result_name,
991					       crack[i].expected_str) != 0) {
992					err_msg = talloc_asprintf(mem_ctx,
993							"DsCrackNames failed - got %s, expected %s on %s",
994							r.out.ctr->ctr1->array[0].result_name,
995							crack[i].expected_str, comment);
996					torture_fail(tctx, err_msg);
997				} else {
998					torture_comment(tctx,
999							"(warning) DsCrackNames returned different case - got %s, expected %s on %s\n",
1000							r.out.ctr->ctr1->array[0].result_name,
1001							crack[i].expected_str, comment);
1002				}
1003			} else if (crack[i].expected_dns
1004				   && (strcmp(r.out.ctr->ctr1->array[0].dns_domain_name,
1005					      crack[i].expected_dns) != 0)) {
1006				err_msg = talloc_asprintf(mem_ctx,
1007						"DsCrackNames failed - got DNS name %s, expected %s on %s",
1008						r.out.ctr->ctr1->array[0].result_name,
1009						crack[i].expected_str, comment);
1010				torture_fail(tctx, err_msg);
1011			}
1012		}
1013	}
1014
1015	return test_DsCrackNamesMatrix(tctx, priv, FQDN_1779_name,
1016					user_principal_name, service_principal_name);
1017}
1018
1019/**
1020 * Test case setup for CrackNames
1021 */
1022static bool torture_drsuapi_cracknames_setup(struct torture_context *tctx, void **data)
1023{
1024	struct DsCrackNamesPrivate *priv;
1025
1026	*data = priv = talloc_zero(tctx, struct DsCrackNamesPrivate);
1027
1028	return torture_drsuapi_tcase_setup_common(tctx, &priv->base);
1029}
1030
1031/**
1032 * Test case tear-down for CrackNames
1033 */
1034static bool torture_drsuapi_cracknames_teardown(struct torture_context *tctx, void *data)
1035{
1036	struct DsCrackNamesPrivate *priv = talloc_get_type(data, struct DsCrackNamesPrivate);
1037
1038	return torture_drsuapi_tcase_teardown_common(tctx, &priv->base);
1039}
1040
1041/**
1042 * CRACKNAMES test suite implementation
1043 */
1044void torture_rpc_drsuapi_cracknames_tcase(struct torture_suite *suite)
1045{
1046	typedef bool (*run_func) (struct torture_context *test, void *tcase_data);
1047
1048	struct torture_test *test;
1049	struct torture_tcase *tcase = torture_suite_add_tcase(suite, "CRACKNAMES");
1050
1051	torture_tcase_set_fixture(tcase,
1052				  torture_drsuapi_cracknames_setup,
1053				  torture_drsuapi_cracknames_teardown);
1054
1055	test = torture_tcase_add_simple_test(tcase, "CRACKNAMES-TEST", (run_func)test_DsCrackNames);
1056}
1057