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