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