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