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