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