r25026: Move param/param.h out of includes.h
[kamenim/samba.git] / source4 / torture / rpc / drsuapi_cracknames.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    DRSUapi tests
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Stefan (metze) Metzmacher 2004
8    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "torture/torture.h"
26 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
27 #include "torture/rpc/rpc.h"
28 #include "ldb/include/ldb.h"
29 #include "libcli/security/security.h"
30
31 static bool test_DsCrackNamesMatrix(struct dcerpc_pipe *p, struct torture_context *tctx,
32                                     struct DsPrivate *priv, const char *dn,
33                                     const char *user_principal_name, const char *service_principal_name)
34 {
35         
36
37         NTSTATUS status;
38         struct drsuapi_DsCrackNames r;
39         enum drsuapi_DsNameFormat formats[] = {
40                 DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
41                 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
42                 DRSUAPI_DS_NAME_FORMAT_DISPLAY,
43                 DRSUAPI_DS_NAME_FORMAT_GUID,
44                 DRSUAPI_DS_NAME_FORMAT_CANONICAL,
45                 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
46                 DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
47                 DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
48                 DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
49                 DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN
50         };
51         struct drsuapi_DsNameString names[ARRAY_SIZE(formats)];
52         int i, j;
53
54         const char *n_matrix[ARRAY_SIZE(formats)][ARRAY_SIZE(formats)];
55         const char *n_from[ARRAY_SIZE(formats)];
56
57         ZERO_STRUCT(r);
58         r.in.bind_handle                = &priv->bind_handle;
59         r.in.level                      = 1;
60         r.in.req.req1.codepage          = 1252; /* german */
61         r.in.req.req1.language          = 0x00000407; /* german */
62         r.in.req.req1.count             = 1;
63         r.in.req.req1.names             = names;
64         r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
65
66         n_matrix[0][0] = dn;
67
68         for (i = 0; i < ARRAY_SIZE(formats); i++) {
69                 r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
70                 r.in.req.req1.format_desired    = formats[i];
71                 names[0].str = dn;
72                 status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
73
74                 torture_comment(tctx, "testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
75                                names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
76                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_drsuapi_DsCrackNames failed");
77                 torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
78                         
79                 switch (formats[i]) {
80                 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:  
81                         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE,
82                                 "Unexpected error: This name lookup should fail");
83                         torture_comment(tctx, "(expected) error\n");
84                         break;
85                 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
86                         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_NO_MAPPING,
87                                 "Unexpected error: This name lookup should fail");
88                         torture_comment(tctx, "(expected) error\n");
89                         break;
90                 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: 
91                 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: 
92                         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status,
93                                                  DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR,
94                                                  "Unexpected error: This name lookup should fail");
95                         torture_comment(tctx, "(expected) error\n");
96                         break;
97                 default:
98                         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_OK,
99                                                  "Error");
100                 }
101
102                 switch (formats[i]) {
103                 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
104                         n_from[i] = user_principal_name;
105                         break;
106                 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:  
107                         n_from[i] = service_principal_name;
108                         break;
109                 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: 
110                 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: 
111                         n_from[i] = NULL;
112                         break;
113                 default:
114                         n_from[i] = r.out.ctr.ctr1->array[0].result_name;
115                         torture_comment(tctx, "%s\n", n_from[i]);
116                 }
117         }
118
119         for (i = 0; i < ARRAY_SIZE(formats); i++) {
120                 for (j = 0; j < ARRAY_SIZE(formats); j++) {
121                         r.in.req.req1.format_offered    = formats[i];
122                         r.in.req.req1.format_desired    = formats[j];
123                         if (!n_from[i]) {
124                                 n_matrix[i][j] = NULL;
125                                 continue;
126                         }
127                         names[0].str = n_from[i];
128                         status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
129                         torture_comment(tctx, "testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d",
130                                        names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
131                         torture_assert_ntstatus_ok(tctx, status, "DsCrackNames failed");
132                         torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
133
134                         if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
135                                 n_matrix[i][j] = r.out.ctr.ctr1->array[0].result_name;
136                         } else {
137                                 n_matrix[i][j] = NULL;
138                         }
139                 }
140         }
141
142         for (i = 0; i < ARRAY_SIZE(formats); i++) {
143                 for (j = 0; j < ARRAY_SIZE(formats); j++) {
144                         if (n_matrix[i][j] == n_from[j]) {
145                                 
146                         /* We don't have a from name for these yet (and we can't map to them to find it out) */
147                         } else if (n_matrix[i][j] == NULL && n_from[i] == NULL) {
148                                 
149                         /* we can't map to these two */
150                         } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
151                         } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
152                         } else {
153                                 torture_assert_str_equal(tctx, n_matrix[i][j], n_from[j], 
154                                                          "dcerpc_drsuapi_DsCrackNames mismatch");
155                         }
156                 }
157         }
158         return true;
159 }
160
161 bool test_DsCrackNames(struct torture_context *tctx, 
162                        struct dcerpc_pipe *p, 
163                        struct DsPrivate *priv)
164 {
165         NTSTATUS status;
166         struct drsuapi_DsCrackNames r;
167         struct drsuapi_DsNameString names[1];
168         const char *dns_domain;
169         const char *nt4_domain;
170         const char *FQDN_1779_name;
171         struct ldb_context *ldb;
172         struct ldb_dn *FQDN_1779_dn;
173         struct ldb_dn *realm_dn;
174         const char *realm_dn_str;
175         const char *realm_canonical;
176         const char *realm_canonical_ex;
177         const char *user_principal_name;
178         char *user_principal_name_short;
179         const char *service_principal_name;
180         const char *canonical_name;
181         const char *canonical_ex_name;
182         const char *dom_sid;
183         const char *test_dc = torture_join_netbios_name(priv->join);
184
185         ZERO_STRUCT(r);
186         r.in.bind_handle                = &priv->bind_handle;
187         r.in.level                      = 1;
188         r.in.req.req1.codepage          = 1252; /* german */
189         r.in.req.req1.language          = 0x00000407; /* german */
190         r.in.req.req1.count             = 1;
191         r.in.req.req1.names             = names;
192         r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
193
194         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
195         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
196
197         dom_sid = dom_sid_string(tctx, torture_join_sid(priv->join));
198         
199         names[0].str = dom_sid;
200
201         printf("testing DsCrackNames with name '%s' desired format:%d\n",
202                         names[0].str, r.in.req.req1.format_desired);
203
204         status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
205         torture_assert_ntstatus_ok(tctx, status, "DsCrackNames");
206         torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
207         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_OK, 
208                 "DsCrackNames failed on name");
209
210         dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
211         nt4_domain = r.out.ctr.ctr1->array[0].result_name;
212
213         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
214
215         printf("testing DsCrackNames with name '%s' desired format:%d\n",
216                         names[0].str, r.in.req.req1.format_desired);
217
218         status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
219         torture_assert_ntstatus_ok(tctx, status, "dcerpc_drsuapi_DsCrackNames failed");
220         torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
221         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_OK,
222                 "DsCrackNames failed on name");
223
224         priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
225         priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
226         GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
227
228         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
229
230         torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
231                         names[0].str, r.in.req.req1.format_desired);
232
233         status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
234         torture_assert_ntstatus_ok(tctx, status, "dcerpc_drsuapi_DsCrackNames failed");
235         torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
236         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_OK, 
237                 "DsCrackNames failed on name");
238
239         ldb = ldb_init(tctx);
240         
241         realm_dn_str = r.out.ctr.ctr1->array[0].result_name;
242         realm_dn =  ldb_dn_new(tctx, ldb, realm_dn_str);
243         realm_canonical = ldb_dn_canonical_string(tctx, realm_dn);
244
245         torture_assert_str_equal(tctx, realm_canonical, 
246                    talloc_asprintf(tctx, "%s/", dns_domain), "local Round trip on canonical name failed");
247
248         realm_canonical_ex = ldb_dn_canonical_ex_string(tctx, realm_dn);
249
250         torture_assert_str_equal(tctx, realm_canonical_ex, talloc_asprintf(tctx, "%s\n", dns_domain), 
251                 "local Round trip on canonical ex name failed");
252
253         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
254         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
255         names[0].str = nt4_domain;
256
257         torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
258                         names[0].str, r.in.req.req1.format_desired);
259
260         status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
261         torture_assert_ntstatus_ok(tctx, status, "dcerpc_drsuapi_DsCrackNames failed");
262         torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
263         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_OK,
264                 "DsCrackNames failed on name");
265
266         priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
267
268         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
269         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
270         names[0].str = talloc_asprintf(tctx, "%s%s$", nt4_domain, test_dc);
271
272         torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
273                names[0].str, r.in.req.req1.format_desired);
274
275         status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
276         torture_assert_ntstatus_ok(tctx, status, "dcerpc_drsuapi_DsCrackNames failed");
277         torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
278         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_OK,
279                 "DsCrackNames failed on name");
280
281         FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
282
283         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
284         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
285         names[0].str = priv->domain_guid_str;
286
287         torture_comment(tctx, "testing DsCrackNames with name '%s' desired format:%d\n",
288                names[0].str, r.in.req.req1.format_desired);
289
290         status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
291         torture_assert_ntstatus_ok(tctx, status, "dcerpc_drsuapi_DsCrackNames failed");
292         torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
293         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status, DRSUAPI_DS_NAME_STATUS_OK,
294                 "DsCrackNames failed on name");
295
296         torture_assert_str_equal(tctx, priv->domain_dns_name, r.out.ctr.ctr1->array[0].dns_domain_name, 
297                 "DsCrackNames failed to return same DNS name");
298
299         FQDN_1779_dn = ldb_dn_new(tctx, ldb, FQDN_1779_name);
300
301         canonical_name = ldb_dn_canonical_string(tctx, FQDN_1779_dn);
302         canonical_ex_name = ldb_dn_canonical_ex_string(tctx, FQDN_1779_dn);
303
304         user_principal_name = talloc_asprintf(tctx, "%s$@%s", test_dc, dns_domain);
305
306         /* form up a user@DOMAIN */
307         user_principal_name_short = talloc_asprintf(tctx, "%s$@%s", test_dc, nt4_domain);
308         /* variable nt4_domain includs a trailing \ */
309         user_principal_name_short[strlen(user_principal_name_short) - 1] = '\0';
310         
311         service_principal_name = talloc_asprintf(tctx, "HOST/%s", test_dc);
312         {
313                 
314                 struct {
315                         enum drsuapi_DsNameFormat format_offered;
316                         enum drsuapi_DsNameFormat format_desired;
317                         const char *comment;
318                         const char *str;
319                         const char *expected_str;
320                         const char *expected_dns;
321                         enum drsuapi_DsNameStatus status;
322                         enum drsuapi_DsNameStatus alternate_status;
323                         enum drsuapi_DsNameFlags flags;
324                         bool skip;
325                 } crack[] = {
326                         {
327                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
328                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
329                                 .str = user_principal_name,
330                                 .expected_str = FQDN_1779_name,
331                                 .status = DRSUAPI_DS_NAME_STATUS_OK
332                         },
333                         {
334                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
335                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
336                                 .str = user_principal_name_short,
337                                 .expected_str = FQDN_1779_name,
338                                 .status = DRSUAPI_DS_NAME_STATUS_OK
339                         },
340                         {
341                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
342                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
343                                 .str = FQDN_1779_name,
344                                 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
345                         },
346                         {
347                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
348                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
349                                 .str = service_principal_name,
350                                 .expected_str = FQDN_1779_name,
351                                 .status = DRSUAPI_DS_NAME_STATUS_OK
352                         },
353                         {
354                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
355                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
356                                 .str = talloc_asprintf(tctx, "cifs/%s.%s", test_dc, dns_domain),
357                                 .comment = "ServicePrincipal Name",
358                                 .expected_str = FQDN_1779_name,
359                                 .status = DRSUAPI_DS_NAME_STATUS_OK
360                         },
361                         {
362                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
363                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
364                                 .str = FQDN_1779_name,
365                                 .expected_str = canonical_name,
366                                 .status = DRSUAPI_DS_NAME_STATUS_OK
367                         },
368                         {
369                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL, 
370                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
371                                 .str = canonical_name,
372                                 .expected_str = FQDN_1779_name,
373                                 .status = DRSUAPI_DS_NAME_STATUS_OK
374                         },
375                         {
376                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
377                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
378                                 .str = FQDN_1779_name,
379                                 .expected_str = canonical_ex_name,
380                                 .status = DRSUAPI_DS_NAME_STATUS_OK
381                         },
382                         {
383                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX, 
384                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
385                                 .str = canonical_ex_name,
386                                 .expected_str = FQDN_1779_name,
387                                 .status = DRSUAPI_DS_NAME_STATUS_OK
388                         },
389                         {
390                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
391                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
392                                 .str = FQDN_1779_name,
393                                 .comment = "DN to cannoical syntactial only",
394                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
395                                 .expected_str = canonical_name,
396                                 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
397                         },
398                         {
399                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
400                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
401                                 .str = FQDN_1779_name,
402                                 .comment = "DN to cannoical EX syntactial only",
403                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
404                                 .expected_str = canonical_ex_name,
405                                 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
406                         },
407                         {
408                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
409                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
410                                 .str = FQDN_1779_name,
411                                 .status = DRSUAPI_DS_NAME_STATUS_OK
412                         },
413                         {
414                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
415                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
416                                 .str = FQDN_1779_name,
417                                 .status = DRSUAPI_DS_NAME_STATUS_OK
418                         },
419                         {
420                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
421                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
422                                 .str = priv->domain_guid_str,
423                                 .comment = "Domain GUID to NT4 ACCOUNT",
424                                 .expected_str = nt4_domain,
425                                 .status = DRSUAPI_DS_NAME_STATUS_OK
426                         },
427                         {
428                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
429                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
430                                 .str = priv->domain_guid_str,
431                                 .comment = "Domain GUID to Canonical",
432                                 .expected_str = talloc_asprintf(tctx, "%s/", dns_domain),
433                                 .status = DRSUAPI_DS_NAME_STATUS_OK
434                         },
435                         {
436                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
437                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
438                                 .str = priv->domain_guid_str,
439                                 .comment = "Domain GUID to Canonical EX",
440                                 .expected_str = talloc_asprintf(tctx, "%s\n", dns_domain),
441                                 .status = DRSUAPI_DS_NAME_STATUS_OK
442                         },
443                         {
444                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
445                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
446                                 .str = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US",
447                                 .comment = "display name for Microsoft Support Account",
448                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
449                                 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE,
450                                 .skip = torture_setting_bool(tctx, "samba4", False)
451                         },
452                         {
453                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
454                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
455                                 .str = GUID_string2(tctx, torture_join_user_guid(priv->join)),
456                                 .comment = "Account GUID -> DN",
457                                 .expected_str = FQDN_1779_name,
458                                 .status = DRSUAPI_DS_NAME_STATUS_OK
459                         },
460                         {
461                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
462                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
463                                 .str = GUID_string2(tctx, torture_join_user_guid(priv->join)),
464                                 .comment = "Account GUID -> NT4 Account",
465                                 .expected_str = talloc_asprintf(tctx, "%s%s$", nt4_domain, test_dc),
466                                 .status = DRSUAPI_DS_NAME_STATUS_OK
467                         },
468                         {               
469                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
470                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
471                                 .str = GUID_string2(tctx, &priv->dcinfo.site_guid),
472                                 .comment = "Site GUID",
473                                 .expected_str = priv->dcinfo.site_dn,
474                                 .status = DRSUAPI_DS_NAME_STATUS_OK
475                         },
476                         {
477                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
478                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
479                                 .str = GUID_string2(tctx, &priv->dcinfo.computer_guid),
480                                 .comment = "Computer GUID",
481                                 .expected_str = priv->dcinfo.computer_dn,
482                                 .status = DRSUAPI_DS_NAME_STATUS_OK
483                         },
484                         {
485                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
486                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
487                                 .str = GUID_string2(tctx, &priv->dcinfo.computer_guid),
488                                 .comment = "Computer GUID -> NT4 Account",
489                                 .status = DRSUAPI_DS_NAME_STATUS_OK
490                         },
491                         {
492                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
493                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
494                                 .str = GUID_string2(tctx, &priv->dcinfo.server_guid),
495                                 .comment = "Server GUID",
496                                 .expected_str = priv->dcinfo.server_dn,
497                                 .status = DRSUAPI_DS_NAME_STATUS_OK
498                         },
499                         {
500                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
501                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
502                                 .str = GUID_string2(tctx, &priv->dcinfo.ntds_guid),
503                                 .comment = "NTDS GUID",
504                                 .expected_str = priv->dcinfo.ntds_dn,
505                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
506                                 .skip = GUID_all_zero(&priv->dcinfo.ntds_guid)
507                         },
508                         {
509                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
510                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
511                                 .str = test_dc,
512                                 .comment = "DISLPAY NAME search for DC short name",
513                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
514                         },
515                         {
516                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
517                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
518                                 .str = talloc_asprintf(tctx, "krbtgt/%s", dns_domain),
519                                 .comment = "Looking for KRBTGT as a serivce principal",
520                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
521                                 .expected_dns = dns_domain
522                         },
523                         {
524                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
525                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
526                                 .str = talloc_asprintf(tctx, "bogus/%s", dns_domain),
527                                 .comment = "Looking for bogus serivce principal",
528                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
529                                 .expected_dns = dns_domain
530                         },
531                         {
532                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
533                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
534                                 .str = talloc_asprintf(tctx, "bogus/%s.%s", test_dc, dns_domain),
535                                 .comment = "Looking for bogus serivce on test DC",
536                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
537                                 .expected_dns = talloc_asprintf(tctx, "%s.%s", test_dc, dns_domain)
538                         },
539                         { 
540                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
541                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
542                                 .str = talloc_asprintf(tctx, "krbtgt"),
543                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
544                         },
545                         { 
546                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
547                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
548                                 .comment = "Looking for the kadmin/changepw service as a serivce principal",
549                                 .str = talloc_asprintf(tctx, "kadmin/changepw"),
550                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
551                                 .expected_str = talloc_asprintf(tctx, "CN=krbtgt,CN=Users,%s", realm_dn_str),
552                                 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
553                         },
554                         {
555                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
556                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
557                                 .str = talloc_asprintf(tctx, "cifs/%s.%s@%s", 
558                                                        test_dc, dns_domain,
559                                                        dns_domain),
560                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
561                         },
562                         {
563                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
564                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
565                                 .str = talloc_asprintf(tctx, "cifs/%s.%s@%s", 
566                                                        test_dc, dns_domain,
567                                                        "BOGUS"),
568                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
569                                 .expected_dns = "BOGUS"
570                         },
571                         {
572                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
573                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
574                                 .str = talloc_asprintf(tctx, "cifs/%s.%s@%s", 
575                                                        test_dc, "REALLY",
576                                                        "BOGUS"),
577                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
578                                 .expected_dns = "BOGUS"
579                         },
580                         {
581                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
582                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
583                                 .str = talloc_asprintf(tctx, "cifs/%s.%s", 
584                                                        test_dc, dns_domain),
585                                 .status = DRSUAPI_DS_NAME_STATUS_OK
586                         },
587                         {
588                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
589                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
590                                 .str = talloc_asprintf(tctx, "cifs/%s", 
591                                                        test_dc),
592                                 .status = DRSUAPI_DS_NAME_STATUS_OK
593                         },
594                         {
595                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
596                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
597                                 .str = "NOT A GUID",
598                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
599                         },
600                         {
601                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
602                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
603                                 .str = "NOT A SID",
604                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
605                         },
606                         {
607                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
608                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
609                                 .str = "NOT AN NT4 NAME",
610                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
611                         },
612                         {
613                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
614                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
615                                 .comment = "Unparsable DN",
616                                 .str = "NOT A DN",
617                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
618                         },
619                         {
620                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
621                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
622                                 .comment = "Unparsable user principal",
623                                 .str = "NOT A PRINCIPAL",
624                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
625                         },
626                         {
627                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
628                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
629                                 .comment = "Unparsable service principal",
630                                 .str = "NOT A SERVICE PRINCIPAL",
631                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
632                         },
633                         {
634                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
635                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
636                                 .comment = "BIND GUID (ie, not in the directory)",
637                                 .str = GUID_string2(tctx, &priv->bind_guid),
638                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
639                         },
640                         {
641                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
642                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
643                                 .comment = "Unqualified Machine account as user principal",
644                                 .str = talloc_asprintf(tctx, "%s$", test_dc),
645                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
646                         },
647                         {
648                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
649                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
650                                 .comment = "Machine account as service principal",
651                                 .str = talloc_asprintf(tctx, "%s$", test_dc),
652                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
653                         },
654                         {
655                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
656                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
657                                 .comment = "Full Machine account as service principal",
658                                 .str = user_principal_name,
659                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
660                         },
661                         {
662                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
663                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
664                                 .comment = "Realm as an NT4 domain lookup",
665                                 .str = talloc_asprintf(tctx, "%s\\", dns_domain),
666                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
667                         }, 
668                         {
669                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
670                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
671                                 .comment = "BUILTIN\\ -> DN",
672                                 .str = "BUILTIN\\",
673                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
674                         }, 
675                         {
676                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
677                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
678                                 .comment = "BUITIN SID -> NT4 account",
679                                 .str = SID_BUILTIN,
680                                 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING,
681                                 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
682                         }, 
683                         {
684                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
685                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
686                                 .str = SID_BUILTIN,
687                                 .comment = "Builtin Domain SID -> DN",
688                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
689                                 .expected_str = talloc_asprintf(tctx, "CN=Builtin,%s", realm_dn_str),
690                                 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
691                         },
692                         {
693                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
694                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
695                                 .str = SID_BUILTIN_ADMINISTRATORS,
696                                 .comment = "Builtin Administrors SID -> DN",
697                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
698                                 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
699                         },
700                         {
701                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
702                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
703                                 .str = SID_BUILTIN_ADMINISTRATORS,
704                                 .comment = "Builtin Administrors SID -> NT4 Account",
705                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
706                                 .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
707                         },
708                         {
709                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
710                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
711                                 .comment = "Domain SID -> DN",
712                                 .str = dom_sid,
713                                 .expected_str = realm_dn_str,
714                                 .status = DRSUAPI_DS_NAME_STATUS_OK
715                         },
716                         {
717                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
718                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
719                                 .comment = "Domain SID -> NT4 account",
720                                 .str = dom_sid,
721                                 .expected_str = nt4_domain,
722                                 .status = DRSUAPI_DS_NAME_STATUS_OK
723                         },
724                         {
725                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
726                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
727                                 .comment = "invalid user principal name",
728                                 .str = "foo@bar",
729                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
730                                 .expected_dns = "bar"
731                         },
732                         {
733                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
734                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
735                                 .comment = "invalid user principal name in valid domain",
736                                 .str = talloc_asprintf(tctx, "invalidusername@%s", dns_domain),
737                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
738                         }
739                 };
740                 int i;
741                 
742                 for (i=0; i < ARRAY_SIZE(crack); i++) {
743                         const char *comment;
744                         r.in.req.req1.format_flags   = crack[i].flags;
745                         r.in.req.req1.format_offered = crack[i].format_offered; 
746                         r.in.req.req1.format_desired = crack[i].format_desired;
747                         names[0].str = crack[i].str;
748                         
749                         if (crack[i].comment) {
750                                 comment = talloc_asprintf(tctx, "'%s' with name '%s' desired format:%d\n",
751                                                           crack[i].comment, names[0].str, r.in.req.req1.format_desired);
752                         } else {
753                                 comment = talloc_asprintf(tctx, "'%s' desired format:%d\n",
754                                        names[0].str, r.in.req.req1.format_desired);
755                         }
756                         torture_comment(tctx, "Running DsCrackNames on %s", comment);
757                         if (crack[i].skip) {
758                                 printf("skipping: %s", comment);
759                                 continue;
760                         }
761                         status = dcerpc_drsuapi_DsCrackNames(p, tctx, &r);
762                         torture_assert_ntstatus_ok(tctx, status, "dcerpc_drsuapi_DsCrackNames failed");
763                         torture_assert_werr_ok(tctx, r.out.result, "DsCrackNames failed");
764                         if (r.out.ctr.ctr1->array[0].status != crack[i].status) {
765                                 if (crack[i].alternate_status) {
766                                         torture_assert_int_equal(tctx, r.out.ctr.ctr1->array[0].status,
767                                                                  crack[i].alternate_status, 
768                                                                  "DsCrackNames unexpected status");
769                                 } else {
770                                         torture_fail(tctx, "DsCrackNames unexpected status");
771                                 }
772                         } else if (crack[i].expected_str
773                                    && (strcmp(r.out.ctr.ctr1->array[0].result_name, 
774                                               crack[i].expected_str) != 0)) {
775                                 if (strcasecmp(r.out.ctr.ctr1->array[0].result_name, 
776                                                crack[i].expected_str) != 0) {
777                                         torture_comment(tctx, "DsCrackNames failed - got %s, expected %s on %s\n", 
778                                                r.out.ctr.ctr1->array[0].result_name, 
779                                                crack[i].expected_str, comment);
780                                         return False;
781                                 } else {
782                                         torture_comment(tctx, 
783                                                 "(warning) DsCrackNames returned different case - got %s, expected %s on %s\n", 
784                                                r.out.ctr.ctr1->array[0].result_name, 
785                                                crack[i].expected_str, comment);
786                                 }
787                         } else if (crack[i].expected_dns)
788                                 torture_assert_str_equal(tctx, r.out.ctr.ctr1->array[0].dns_domain_name, 
789                                               crack[i].expected_dns, "DsCrackNames failed");
790                 }
791         }
792
793         if (!test_DsCrackNamesMatrix(p, tctx, priv, FQDN_1779_name, 
794                                      user_principal_name, service_principal_name)) {
795                 return false;
796         }
797
798         return true;
799 }