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