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