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