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