r10953: Add a new function to form a canonicalName out of a DN to ldb_dn.c
[mat/samba.git] / source4 / torture / rpc / drsuapi_cracknames.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    DRSUapi tests
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Stefan (metze) Metzmacher 2004
8    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26 #include "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_canonical;
215         const char *realm_canonical_ex;
216         const char *user_principal_name;
217         const char *service_principal_name;
218         const char *canonical_name;
219         const char *canonical_ex_name;
220
221         ZERO_STRUCT(r);
222         r.in.bind_handle                = &priv->bind_handle;
223         r.in.level                      = 1;
224         r.in.req.req1.unknown1          = 0x000004e4;
225         r.in.req.req1.unknown2          = 0x00000407;
226         r.in.req.req1.count             = 1;
227         r.in.req.req1.names             = names;
228         r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
229
230         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
231         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
232         names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
233
234         printf("testing DsCrackNames with name '%s' desired format:%d\n",
235                         names[0].str, r.in.req.req1.format_desired);
236
237         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
238         if (!NT_STATUS_IS_OK(status)) {
239                 const char *errstr = nt_errstr(status);
240                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
241                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
242                 }
243                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
244                 ret = False;
245         } else if (!W_ERROR_IS_OK(r.out.result)) {
246                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
247                 ret = False;
248         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
249                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
250                 ret = False;
251         }
252
253         if (!ret) {
254                 return ret;
255         }
256
257         dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
258         nt4_domain = r.out.ctr.ctr1->array[0].result_name;
259
260         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
261
262         printf("testing DsCrackNames with name '%s' desired format:%d\n",
263                         names[0].str, r.in.req.req1.format_desired);
264
265         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
266         if (!NT_STATUS_IS_OK(status)) {
267                 const char *errstr = nt_errstr(status);
268                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
269                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
270                 }
271                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
272                 ret = False;
273         } else if (!W_ERROR_IS_OK(r.out.result)) {
274                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
275                 ret = False;
276         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
277                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
278                 ret = False;
279         }
280
281         if (!ret) {
282                 return ret;
283         }
284
285         priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
286         priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
287         GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
288
289         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
290
291         printf("testing DsCrackNames with name '%s' desired format:%d\n",
292                         names[0].str, r.in.req.req1.format_desired);
293
294         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
295         if (!NT_STATUS_IS_OK(status)) {
296                 const char *errstr = nt_errstr(status);
297                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
298                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
299                 }
300                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
301                 ret = False;
302         } else if (!W_ERROR_IS_OK(r.out.result)) {
303                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
304                 ret = False;
305         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
306                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
307                 ret = False;
308         }
309
310         if (!ret) {
311                 return ret;
312         }
313         
314         realm_dn =  ldb_dn_explode(mem_ctx, r.out.ctr.ctr1->array[0].result_name);
315         realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn);
316
317         if (strcmp(realm_canonical, 
318                    talloc_asprintf(mem_ctx, "%s/", lp_realm()))!= 0) {
319                 printf("local Round trip on canonical name failed: %s != %s!\n",
320                        realm_canonical, 
321                        talloc_asprintf(mem_ctx, "%s/", lp_realm()));
322                     return False;
323         };
324
325         realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn);
326
327         if (strcmp(realm_canonical_ex, 
328                    talloc_asprintf(mem_ctx, "%s\n", lp_realm()))!= 0) {
329                 printf("local Round trip on canonical ex name failed: %s != %s!\n",
330                        realm_canonical, 
331                        talloc_asprintf(mem_ctx, "%s\n", lp_realm()));
332                     return False;
333         };
334
335         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
336         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
337         names[0].str = nt4_domain;
338
339         printf("testing DsCrackNames with name '%s' desired format:%d\n",
340                         names[0].str, r.in.req.req1.format_desired);
341
342         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
343         if (!NT_STATUS_IS_OK(status)) {
344                 const char *errstr = nt_errstr(status);
345                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
346                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
347                 }
348                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
349                 ret = False;
350         } else if (!W_ERROR_IS_OK(r.out.result)) {
351                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
352                 ret = False;
353         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
354                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
355                 ret = False;
356         }
357
358         if (!ret) {
359                 return ret;
360         }
361
362         priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
363
364         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
365         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
366         names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
367
368         printf("testing DsCrackNames with name '%s' desired format:%d\n",
369                         names[0].str, r.in.req.req1.format_desired);
370
371         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
372         if (!NT_STATUS_IS_OK(status)) {
373                 const char *errstr = nt_errstr(status);
374                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
375                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
376                 }
377                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
378                 ret = False;
379         } else if (!W_ERROR_IS_OK(r.out.result)) {
380                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
381                 ret = False;
382         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
383                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
384                 ret = False;
385         }
386
387         if (!ret) {
388                 return ret;
389         }
390
391         FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
392
393         FQDN_1779_dn = ldb_dn_explode(mem_ctx, FQDN_1779_name);
394
395         canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn);
396         canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn);
397
398         user_principal_name = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain);
399         service_principal_name = talloc_asprintf(mem_ctx, "HOST/%s", test_dc);
400         {
401                 
402                 struct {
403                         enum drsuapi_DsNameFormat format_offered;
404                         enum drsuapi_DsNameFormat format_desired;
405                         const char *comment;
406                         const char *str;
407                         const char *expected_str;
408                         enum drsuapi_DsNameStatus status;
409                         enum drsuapi_DsNameFlags flags;
410                 } crack[] = {
411                         {
412                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
413                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
414                                 .str = user_principal_name,
415                                 .expected_str = FQDN_1779_name,
416                                 .status = DRSUAPI_DS_NAME_STATUS_OK
417                         },
418                         {
419                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
420                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
421                                 .str = service_principal_name,
422                                 .expected_str = FQDN_1779_name,
423                                 .status = DRSUAPI_DS_NAME_STATUS_OK
424                         },
425                         {
426                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
427                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
428                                 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s", test_dc, dns_domain),
429                                 .comment = "ServicePrincipal Name",
430                                 .expected_str = FQDN_1779_name,
431                                 .status = DRSUAPI_DS_NAME_STATUS_OK
432                         },
433                         {
434                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
435                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
436                                 .str = FQDN_1779_name,
437                                 .expected_str = canonical_name,
438                                 .status = DRSUAPI_DS_NAME_STATUS_OK
439                         },
440                         {
441                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
442                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
443                                 .str = FQDN_1779_name,
444                                 .expected_str = canonical_ex_name,
445                                 .status = DRSUAPI_DS_NAME_STATUS_OK
446                         },
447                         {
448                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
449                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
450                                 .str = FQDN_1779_name,
451                                 .comment = "DN to cannoical syntactial only",
452                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
453                                 .expected_str = canonical_name,
454                                 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
455                         },
456                         {
457                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
458                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
459                                 .str = FQDN_1779_name,
460                                 .comment = "DN to cannoical EX syntactial only",
461                                 .status = DRSUAPI_DS_NAME_STATUS_OK,
462                                 .expected_str = canonical_ex_name,
463                                 .flags = DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY
464                         },
465                         {
466                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
467                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
468                                 .str = FQDN_1779_name,
469                                 .status = DRSUAPI_DS_NAME_STATUS_OK
470                         },
471                         {
472                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
473                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
474                                 .str = FQDN_1779_name,
475                                 .status = DRSUAPI_DS_NAME_STATUS_OK
476                         },
477                         {
478                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
479                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
480                                 .str = priv->domain_guid_str,
481                                 .comment = "Domain GUID to NT4 ACCOUNT",
482                                 .expected_str = nt4_domain,
483                                 .status = DRSUAPI_DS_NAME_STATUS_OK
484                         },
485                         {
486                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
487                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
488                                 .str = priv->domain_guid_str,
489                                 .comment = "Domain GUID to Canonical",
490                                 .expected_str = talloc_asprintf(mem_ctx, "%s/", dns_domain),
491                                 .status = DRSUAPI_DS_NAME_STATUS_OK
492                         },
493                         {
494                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
495                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
496                                 .str = priv->domain_guid_str,
497                                 .comment = "Domain GUID to Canonical EX",
498                                 .expected_str = talloc_asprintf(mem_ctx, "%s\n", dns_domain),
499                                 .status = DRSUAPI_DS_NAME_STATUS_OK
500                         },
501                         {
502                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
503                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
504                                 .str = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US",
505                                 .comment = "display name for Microsoft Support Account",
506                                 .status = DRSUAPI_DS_NAME_STATUS_OK
507                         },
508                         {               
509                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
510                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
511                                 .str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid),
512                                 .comment = "Site GUID",
513                                 .status = DRSUAPI_DS_NAME_STATUS_OK
514                         },
515                         {
516                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
517                                 .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
518                                 .comment = "Computer GUID",
519                                 .status = DRSUAPI_DS_NAME_STATUS_OK
520                         },
521                         {
522                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
523                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
524                                 .str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid),
525                                 .comment = "Server GUID",
526                                 .status = DRSUAPI_DS_NAME_STATUS_OK
527                         },
528                         {
529                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
530                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
531                                 .str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid),
532                                 .comment = "NTDS GUID",
533                                 .status = DRSUAPI_DS_NAME_STATUS_OK
534                         },
535                         {
536                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
537                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
538                                 .str = SID_BUILTIN,
539                                 .comment = "BUILTIN domain SID",
540                                 .status = DRSUAPI_DS_NAME_STATUS_OK
541                         },
542                         {
543                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
544                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
545                                 .str = test_dc,
546                                 .comment = "DISPAY NAME search for DC short name",
547                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
548                         },
549                         {
550                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
551                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
552                                 .str = talloc_asprintf(mem_ctx, "krbtgt/%s", dns_domain),
553                                 .comment = "Looking for KRBTGT as a serivce principal",
554                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
555                         },
556                         { 
557                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
558                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
559                                 .str = talloc_asprintf(mem_ctx, "krbtgt"),
560                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
561                         },
562                         {
563                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
564                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
565                                 .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s", 
566                                                        test_dc, dns_domain,
567                                                        dns_domain),
568                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
569                         },
570                         {
571                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
572                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
573                                 .str = "NOT A GUID",
574                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
575                         },
576                         {
577                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
578                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
579                                 .str = "NOT A SID",
580                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
581                         },
582                         {
583                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
584                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
585                                 .str = "NOT AN NT4 NAME",
586                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
587                         },
588                         {
589                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
590                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_GUID,
591                                 .comment = "Unparsable DN",
592                                 .str = "NOT A DN",
593                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
594                         },
595                         {
596                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
597                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
598                                 .comment = "Unparsable user principal",
599                                 .str = "NOT A PRINCIPAL",
600                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
601                         },
602                         {
603                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
604                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
605                                 .comment = "Unparsable service principal",
606                                 .str = "NOT A SERVICE PRINCIPAL",
607                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
608                         },
609                         {
610                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
611                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
612                                 .comment = "BIND GUID (ie, not in the directory)",
613                                 .str = GUID_string2(mem_ctx, &priv->bind_guid),
614                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
615                         },
616                         {
617                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
618                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
619                                 .comment = "Unqualified Machine account as user principal",
620                                 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
621                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
622                         },
623                         {
624                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
625                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
626                                 .comment = "Machine account as service principal",
627                                 .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
628                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
629                         },
630                         {
631                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
632                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
633                                 .comment = "Realm as an NT4 domain lookup",
634                                 .str = talloc_asprintf(mem_ctx, "%s\\", lp_realm()),
635                                 .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
636                         }, 
637                         {
638                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
639                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
640                                 .comment = "BUITIN SID -> NT4 account",
641                                 .str = SID_BUILTIN,
642                                 .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
643                         }, 
644                         {
645                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
646                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
647                                 .str = SID_BUILTIN_ADMINISTRATORS,
648                                 .status = DRSUAPI_DS_NAME_STATUS_OK
649                         },
650                         {
651                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
652                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
653                                 .str = SID_BUILTIN_ADMINISTRATORS,
654                                 .status = DRSUAPI_DS_NAME_STATUS_OK
655                         },
656                         {
657                                 .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
658                                 .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
659                                 .str = "foo@bar",
660                                 .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
661                         },
662                 };
663                 int i;
664                 
665                 for (i=0; i < ARRAY_SIZE(crack); i++) {
666                         r.in.req.req1.format_flags   = crack[i].flags;
667                         r.in.req.req1.format_offered = crack[i].format_offered; 
668                         r.in.req.req1.format_desired = crack[i].format_desired;
669                         names[0].str = crack[i].str;
670                         
671                         if (crack[i].comment) {
672                                 printf("testing DsCrackNames '%s' with name '%s' desired format:%d\n",
673                                        crack[i].comment, names[0].str, r.in.req.req1.format_desired);
674                         } else {
675                                 printf("testing DsCrackNames with name '%s' desired format:%d\n",
676                                        names[0].str, r.in.req.req1.format_desired);
677                         }
678                         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
679                         if (!NT_STATUS_IS_OK(status)) {
680                                 const char *errstr = nt_errstr(status);
681                                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
682                                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
683                                 }
684                                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
685                                 ret = False;
686                         } else if (!W_ERROR_IS_OK(r.out.result)) {
687                                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
688                                 ret = False;
689                         } else if (r.out.ctr.ctr1->array[0].status != crack[i].status) {
690                                 printf("DsCrackNames unexpected status %d, wanted %d on name: %s\n", 
691                                        r.out.ctr.ctr1->array[0].status,
692                                        crack[i].status,
693                                        crack[i].str);
694                                 ret = False;
695                         } else if (crack[i].expected_str
696                                    && (strcmp(r.out.ctr.ctr1->array[0].result_name, 
697                                               crack[i].expected_str) != 0)) {
698                                 printf("DsCrackNames failed - got %s, expected %s\n", 
699                                        r.out.ctr.ctr1->array[0].result_name, 
700                                        crack[i].expected_str);
701                                 ret = False;
702                         }
703                 }
704         }
705
706         if (!test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name, 
707                                      user_principal_name, service_principal_name)) {
708                 ret = False;
709         }
710
711         return ret;
712 }
713
714 BOOL torture_rpc_drsuapi_cracknames(void)
715 {
716         NTSTATUS status;
717         struct dcerpc_pipe *p;
718         TALLOC_CTX *mem_ctx;
719         BOOL ret = True;
720         struct DsPrivate priv;
721
722         mem_ctx = talloc_init("torture_rpc_drsuapi");
723
724         status = torture_rpc_connection(mem_ctx, 
725                                         &p, 
726                                         DCERPC_DRSUAPI_NAME,
727                                         DCERPC_DRSUAPI_UUID,
728                                         DCERPC_DRSUAPI_VERSION);
729         if (!NT_STATUS_IS_OK(status)) {
730                 talloc_free(mem_ctx);
731                 return False;
732         }
733
734         printf("Connected to DRAUAPI pipe\n");
735
736         ZERO_STRUCT(priv);
737
738         ret &= test_DsBind(p, mem_ctx, &priv);
739
740         ret &= test_DsCrackNames(p, mem_ctx, &priv, lp_parm_string(-1, "torture", "host"));
741
742         ret &= test_DsUnbind(p, mem_ctx, &priv);
743
744         talloc_free(mem_ctx);
745
746         return ret;
747 }