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