r9941: Update the CrackNames test, and provide a much improved server-side
[ira/wip.git] / source4 / torture / rpc / drsuapi.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    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "librpc/gen_ndr/ndr_drsuapi.h"
26
27 struct DsPrivate {
28         struct policy_handle bind_handle;
29         struct GUID bind_guid;
30         const char *domain_obj_dn;
31         const char *domain_guid_str;
32         const char *domain_dns_name;
33         struct GUID domain_guid;
34         struct drsuapi_DsGetDCInfo2 dcinfo;
35 };
36
37 static BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
38                       struct DsPrivate *priv)
39 {
40         NTSTATUS status;
41         struct drsuapi_DsBind r;
42         BOOL ret = True;
43
44         GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
45
46         r.in.bind_guid = &priv->bind_guid;
47         r.in.bind_info = NULL;
48         r.out.bind_handle = &priv->bind_handle;
49
50         printf("testing DsBind\n");
51
52         status = dcerpc_drsuapi_DsBind(p, mem_ctx, &r);
53         if (!NT_STATUS_IS_OK(status)) {
54                 const char *errstr = nt_errstr(status);
55                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
56                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
57                 }
58                 printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);
59                 ret = False;
60         } else if (!W_ERROR_IS_OK(r.out.result)) {
61                 printf("DsBind failed - %s\n", win_errstr(r.out.result));
62                 ret = False;
63         }
64
65         return ret;
66 }
67
68 static BOOL test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
69                                     struct DsPrivate *priv, const char *dn,
70                                     const char *user_principal_name, const char *service_principal_name)
71 {
72         
73
74         NTSTATUS status;
75         BOOL ret = True;
76         struct drsuapi_DsCrackNames r;
77         struct drsuapi_DsNameString names[1];
78         enum drsuapi_DsNameFormat formats[] = {
79                 DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
80                 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
81                 DRSUAPI_DS_NAME_FORMAT_DISPLAY,
82                 DRSUAPI_DS_NAME_FORMAT_GUID,
83                 DRSUAPI_DS_NAME_FORMAT_CANONICAL,
84                 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
85                 DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
86                 DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
87                 DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
88                 DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN
89         };
90         int i, j;
91
92         const char *n_matrix[ARRAY_SIZE(formats)][ARRAY_SIZE(formats)];
93         const char *n_from[ARRAY_SIZE(formats)];
94
95         ZERO_STRUCT(r);
96         r.in.bind_handle                = &priv->bind_handle;
97         r.in.level                      = 1;
98         r.in.req.req1.unknown1          = 0x000004e4;
99         r.in.req.req1.unknown2          = 0x00000407;
100         r.in.req.req1.count             = 1;
101         r.in.req.req1.names             = names;
102         r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
103
104         n_matrix[0][0] = dn;
105
106         for (i = 0; i < ARRAY_SIZE(formats); i++) {
107                 r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
108                 r.in.req.req1.format_desired    = formats[i];
109                 names[0].str = dn;
110                 printf("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
111                        names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
112                 
113                 status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
114                 if (!NT_STATUS_IS_OK(status)) {
115                         const char *errstr = nt_errstr(status);
116                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
117                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
118                         }
119                         printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
120                         ret = False;
121                 } else if (!W_ERROR_IS_OK(r.out.result)) {
122                         printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
123                         ret = False;
124                 }
125                         
126                 if (!ret) {
127                         return ret;
128                 }
129                 switch (formats[i]) {
130                 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:  
131                         if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) {
132                                 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n", 
133                                        r.out.ctr.ctr1->array[0].status);
134                                 return False;
135                         }
136                         printf ("(expected) error\n");
137                         break;
138                 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
139                         if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
140                                 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n", 
141                                        r.out.ctr.ctr1->array[0].status);
142                                 return False;
143                         }
144                         printf ("(expected) error\n");
145                         break;
146                 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: 
147                 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: 
148                         if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR) {
149                                 printf(__location__ ": Unexpected error (%d): This name lookup should fail\n", 
150                                        r.out.ctr.ctr1->array[0].status);
151                                 return False;
152                         }
153                         printf ("(expected) error\n");
154                         break;
155                 default:
156                         if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
157                                 printf("Error: %d\n", r.out.ctr.ctr1->array[0].status);
158                                 return False;
159                         }
160                 }
161
162                 switch (formats[i]) {
163                 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
164                         n_from[i] = user_principal_name;
165                         break;
166                 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:  
167                         n_from[i] = service_principal_name;
168                         break;
169                 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: 
170                 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: 
171                         n_from[i] = NULL;
172                         break;
173                 default:
174                         n_from[i] = r.out.ctr.ctr1->array[0].result_name;
175                         printf("%s\n", n_from[i]);
176                 }
177         }
178
179         for (i = 0; i < ARRAY_SIZE(formats); i++) {
180                 for (j = 0; j < ARRAY_SIZE(formats); j++) {
181                         r.in.req.req1.format_offered    = formats[i];
182                         r.in.req.req1.format_desired    = formats[j];
183                         if (!n_from[i]) {
184                                 n_matrix[i][j] = NULL;
185                                 continue;
186                         }
187                         names[0].str = n_from[i];
188                         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
189                         if (!NT_STATUS_IS_OK(status)) {
190                                 const char *errstr = nt_errstr(status);
191                                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
192                                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
193                                 }
194                                 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
195                                        names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, errstr);
196                                 ret = False;
197                         } else if (!W_ERROR_IS_OK(r.out.result)) {
198                                 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
199                                        names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, 
200                                        win_errstr(r.out.result));
201                                 ret = False;
202                         }
203                         
204                         if (!ret) {
205                                 return ret;
206                         }
207                         if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
208                                 n_matrix[i][j] = r.out.ctr.ctr1->array[0].result_name;
209                         } else {
210                                 n_matrix[i][j] = NULL;
211                         }
212                 }
213         }
214
215         for (i = 0; i < ARRAY_SIZE(formats); i++) {
216                 for (j = 0; j < ARRAY_SIZE(formats); j++) {
217                         if (n_matrix[i][j] == n_from[j]) {
218                                 
219                         /* We don't have a from name for these yet (and we can't map to them to find it out) */
220                         } else if (n_matrix[i][j] == NULL && n_from[i] == NULL) {
221                                 
222                         /* we can't map to these two */
223                         } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
224                         } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
225                         } else if (n_matrix[i][j] == NULL && n_from[j] != NULL) {
226                                 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]);
227                                 ret = False;
228                         } else if (n_matrix[i][j] != NULL && n_from[j] == NULL) {
229                                 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]);
230                                 ret = False;
231                         } else if (strcmp(n_matrix[i][j], n_from[j]) != 0) {
232                                 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]);
233                                 ret = False;
234                         }
235                 }
236         }
237         return ret;
238 }
239
240 static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
241                               struct DsPrivate *priv, const char *test_dc)
242 {
243         NTSTATUS status;
244         struct drsuapi_DsCrackNames r;
245         struct drsuapi_DsNameString names[1];
246         BOOL ret = True;
247         const char *dns_domain;
248         const char *nt4_domain;
249         const char *FQDN_1779_name;
250         const char *user_principal_name;
251         const char *service_principal_name;
252
253         ZERO_STRUCT(r);
254         r.in.bind_handle                = &priv->bind_handle;
255         r.in.level                      = 1;
256         r.in.req.req1.unknown1          = 0x000004e4;
257         r.in.req.req1.unknown2          = 0x00000407;
258         r.in.req.req1.count             = 1;
259         r.in.req.req1.names             = names;
260         r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
261
262         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
263         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
264         names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
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         dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
290         nt4_domain = r.out.ctr.ctr1->array[0].result_name;
291
292         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
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         priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
318         priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
319         GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
320
321
322         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
323         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
324         names[0].str = priv->domain_guid_str;
325
326         printf("testing DsCrackNames with GUID '%s' desired format:%d\n",
327                         names[0].str, r.in.req.req1.format_desired);
328
329         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
330         if (!NT_STATUS_IS_OK(status)) {
331                 const char *errstr = nt_errstr(status);
332                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
333                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
334                 }
335                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
336                 ret = False;
337         } else if (!W_ERROR_IS_OK(r.out.result)) {
338                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
339                 ret = False;
340         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
341                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
342                 ret = False;
343         }
344
345         if (!ret) {
346                 return ret;
347         }
348
349         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
350         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
351         names[0].str = nt4_domain;
352
353         printf("testing DsCrackNames with name '%s' desired format:%d\n",
354                         names[0].str, r.in.req.req1.format_desired);
355
356         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
357         if (!NT_STATUS_IS_OK(status)) {
358                 const char *errstr = nt_errstr(status);
359                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
360                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
361                 }
362                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
363                 ret = False;
364         } else if (!W_ERROR_IS_OK(r.out.result)) {
365                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
366                 ret = False;
367         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
368                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
369                 ret = False;
370         }
371
372         if (!ret) {
373                 return ret;
374         }
375
376         priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
377
378         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
379         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
380         names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
381
382         printf("testing DsCrackNames with name '%s' desired format:%d\n",
383                         names[0].str, r.in.req.req1.format_desired);
384
385         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
386         if (!NT_STATUS_IS_OK(status)) {
387                 const char *errstr = nt_errstr(status);
388                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
389                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
390                 }
391                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
392                 ret = False;
393         } else if (!W_ERROR_IS_OK(r.out.result)) {
394                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
395                 ret = False;
396         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
397                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
398                 ret = False;
399         }
400
401         if (!ret) {
402                 return ret;
403         }
404
405         FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
406
407         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
408         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
409         names[0].str = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain);
410         user_principal_name = names[0].str;
411
412         printf("testing DsCrackNames with name '%s' desired format:%d\n",
413                         names[0].str, r.in.req.req1.format_desired);
414
415         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
416         if (!NT_STATUS_IS_OK(status)) {
417                 const char *errstr = nt_errstr(status);
418                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
419                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
420                 }
421                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
422                 ret = False;
423         } else if (!W_ERROR_IS_OK(r.out.result)) {
424                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
425                 ret = False;
426         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
427                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
428                 ret = False;
429         }
430
431         if (!ret) {
432                 return ret;
433         }
434
435         if (strcmp(r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name) != 0) {
436                 printf("DsCrackNames failed - %s != %s\n", r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name);
437                 return False;
438         }
439
440         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
441         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
442         names[0].str = talloc_asprintf(mem_ctx, "HOST/%s", test_dc);
443         service_principal_name = names[0].str;
444
445         printf("testing DsCrackNames with name '%s' desired format:%d\n",
446                         names[0].str, r.in.req.req1.format_desired);
447
448         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
449         if (!NT_STATUS_IS_OK(status)) {
450                 const char *errstr = nt_errstr(status);
451                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
452                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
453                 }
454                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
455                 ret = False;
456         } else if (!W_ERROR_IS_OK(r.out.result)) {
457                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
458                 ret = False;
459         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
460                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
461                 ret = False;
462         }
463
464         if (!ret) {
465                 return ret;
466         }
467
468         if (strcmp(r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name) != 0) {
469                 printf("DsCrackNames failed - %s != %s\n", r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name);
470                 return False;
471         }
472
473         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
474         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
475         names[0].str = talloc_asprintf(mem_ctx, "cifs/%s.%s", test_dc, dns_domain);
476
477         printf("testing DsCrackNames with name '%s' desired format:%d\n",
478                         names[0].str, r.in.req.req1.format_desired);
479
480         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
481         if (!NT_STATUS_IS_OK(status)) {
482                 const char *errstr = nt_errstr(status);
483                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
484                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
485                 }
486                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
487                 ret = False;
488         } else if (!W_ERROR_IS_OK(r.out.result)) {
489                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
490                 ret = False;
491         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
492                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
493                 ret = False;
494         }
495
496         if (!ret) {
497                 return ret;
498         }
499
500         if (strcmp(r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name) != 0) {
501                 printf("DsCrackNames failed - %s != %s\n", r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name);
502                 return False;
503         }
504
505         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
506         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
507         names[0].str = FQDN_1779_name;
508
509         printf("testing DsCrackNames with name '%s' desired format:%d\n",
510                         names[0].str, r.in.req.req1.format_desired);
511
512         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
513         if (!NT_STATUS_IS_OK(status)) {
514                 const char *errstr = nt_errstr(status);
515                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
516                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
517                 }
518                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
519                 ret = False;
520         } else if (!W_ERROR_IS_OK(r.out.result)) {
521                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
522                 ret = False;
523         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
524                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
525                 ret = False;
526         }
527
528         if (!ret) {
529                 return ret;
530         }
531
532         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_DISPLAY;
533
534         printf("testing DsCrackNames with name '%s' desired format:%d\n",
535                         names[0].str, r.in.req.req1.format_desired);
536
537         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
538         if (!NT_STATUS_IS_OK(status)) {
539                 const char *errstr = nt_errstr(status);
540                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
541                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
542                 }
543                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
544                 ret = False;
545         } else if (!W_ERROR_IS_OK(r.out.result)) {
546                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
547                 ret = False;
548         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
549                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
550                 ret = False;
551         }
552
553         if (!ret) {
554                 return ret;
555         }
556
557         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
558
559         printf("testing DsCrackNames with name '%s' desired format:%d\n",
560                         names[0].str, r.in.req.req1.format_desired);
561
562         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
563         if (!NT_STATUS_IS_OK(status)) {
564                 const char *errstr = nt_errstr(status);
565                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
566                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
567                 }
568                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
569                 ret = False;
570         } else if (!W_ERROR_IS_OK(r.out.result)) {
571                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
572                 ret = False;
573         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
574                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
575                 ret = False;
576         }
577
578         if (!ret) {
579                 return ret;
580         }
581
582         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
583         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
584         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid);
585
586         printf("testing DsCrackNames with Site GUID '%s' desired format:%d\n",
587                         names[0].str, r.in.req.req1.format_desired);
588
589         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
590         if (!NT_STATUS_IS_OK(status)) {
591                 const char *errstr = nt_errstr(status);
592                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
593                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
594                 }
595                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
596                 ret = False;
597         } else if (!W_ERROR_IS_OK(r.out.result)) {
598                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
599                 ret = False;
600         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
601                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
602                 ret = False;
603         }
604
605         if (!ret) {
606                 return ret;
607         }
608
609         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
610         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid);
611
612         printf("testing DsCrackNames with Computer GUID '%s' desired format:%d\n",
613                         names[0].str, r.in.req.req1.format_desired);
614
615         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
616         if (!NT_STATUS_IS_OK(status)) {
617                 const char *errstr = nt_errstr(status);
618                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
619                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
620                 }
621                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
622                 ret = False;
623         } else if (!W_ERROR_IS_OK(r.out.result)) {
624                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
625                 ret = False;
626         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
627                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
628                 ret = False;
629         }
630
631         if (!ret) {
632                 return ret;
633         }
634
635         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
636         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
637         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid);
638
639         printf("testing DsCrackNames with Server GUID '%s' desired format:%d\n",
640                         names[0].str, r.in.req.req1.format_desired);
641
642         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
643         if (!NT_STATUS_IS_OK(status)) {
644                 const char *errstr = nt_errstr(status);
645                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
646                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
647                 }
648                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
649                 ret = False;
650         } else if (!W_ERROR_IS_OK(r.out.result)) {
651                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
652                 ret = False;
653         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
654                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
655                 ret = False;
656         }
657
658         if (!ret) {
659                 return ret;
660         }
661
662         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
663         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
664         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid);
665
666         printf("testing DsCrackNames with NTDS GUID '%s' desired format:%d\n",
667                         names[0].str, r.in.req.req1.format_desired);
668
669         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
670         if (!NT_STATUS_IS_OK(status)) {
671                 const char *errstr = nt_errstr(status);
672                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
673                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
674                 }
675                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
676                 ret = False;
677         } else if (!W_ERROR_IS_OK(r.out.result)) {
678                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
679                 ret = False;
680         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
681                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
682                 ret = False;
683         }
684
685         if (!ret) {
686                 return ret;
687         }
688
689         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
690         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
691         names[0].str = SID_BUILTIN;
692
693         printf("testing DsCrackNames with SID '%s' desired format:%d\n",
694                         names[0].str, r.in.req.req1.format_desired);
695
696         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
697         if (!NT_STATUS_IS_OK(status)) {
698                 const char *errstr = nt_errstr(status);
699                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
700                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
701                 }
702                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
703                 ret = False;
704         } else if (!W_ERROR_IS_OK(r.out.result)) {
705                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
706                 ret = False;
707         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
708                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
709                 ret = False;
710         }
711
712         if (!ret) {
713                 return ret;
714         }
715
716
717         /* NEGATIVE tests.  This should parse, but not succeed */
718         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
719         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
720         names[0].str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s", 
721                                        test_dc, dns_domain,
722                                        dns_domain);
723
724         printf("testing DsCrackNames with Service Principal '%s' desired format:%d\n",
725                         names[0].str, r.in.req.req1.format_desired);
726
727         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
728         if (!NT_STATUS_IS_OK(status)) {
729                 const char *errstr = nt_errstr(status);
730                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
731                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
732                 }
733                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
734                 ret = False;
735         } else if (!W_ERROR_IS_OK(r.out.result)) {
736                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
737                 ret = False;
738         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY) {
739                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
740                 ret = False;
741         }
742
743         if (!ret) {
744                 return ret;
745         }
746
747         /* NEGATIVE tests.  This should parse, but not succeed */
748         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
749         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
750         names[0].str = "NOT A GUID";
751
752         printf("testing DsCrackNames with GUID '%s' desired format:%d\n",
753                         names[0].str, r.in.req.req1.format_desired);
754
755         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
756         if (!NT_STATUS_IS_OK(status)) {
757                 const char *errstr = nt_errstr(status);
758                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
759                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
760                 }
761                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
762                 ret = False;
763         } else if (!W_ERROR_IS_OK(r.out.result)) {
764                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
765                 ret = False;
766         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
767                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
768                 ret = False;
769         }
770
771         if (!ret) {
772                 return ret;
773         }
774
775         /* NEGATIVE tests.  This should parse, but not succeed */
776         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
777         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
778         names[0].str = "NOT A SID";
779
780         printf("testing DsCrackNames with SID '%s' desired format:%d\n",
781                         names[0].str, r.in.req.req1.format_desired);
782
783         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
784         if (!NT_STATUS_IS_OK(status)) {
785                 const char *errstr = nt_errstr(status);
786                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
787                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
788                 }
789                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
790                 ret = False;
791         } else if (!W_ERROR_IS_OK(r.out.result)) {
792                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
793                 ret = False;
794         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
795                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
796                 ret = False;
797         }
798
799         if (!ret) {
800                 return ret;
801         }
802
803         /* NEGATIVE tests.  This should parse, but not succeed */
804         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
805         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
806         names[0].str = "NOT AN NT4 NAME";
807
808         printf("testing DsCrackNames with NT4 Name '%s' desired format:%d\n",
809                         names[0].str, r.in.req.req1.format_desired);
810
811         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
812         if (!NT_STATUS_IS_OK(status)) {
813                 const char *errstr = nt_errstr(status);
814                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
815                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
816                 }
817                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
818                 ret = False;
819         } else if (!W_ERROR_IS_OK(r.out.result)) {
820                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
821                 ret = False;
822         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
823                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
824                 ret = False;
825         }
826
827         if (!ret) {
828                 return ret;
829         }
830
831         /* NEGATIVE tests.  This should parse, but not succeed */
832         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
833         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
834         names[0].str = "NOT A DN";
835
836         printf("testing DsCrackNames with DN '%s' desired format:%d\n",
837                         names[0].str, r.in.req.req1.format_desired);
838
839         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
840         if (!NT_STATUS_IS_OK(status)) {
841                 const char *errstr = nt_errstr(status);
842                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
843                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
844                 }
845                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
846                 ret = False;
847         } else if (!W_ERROR_IS_OK(r.out.result)) {
848                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
849                 ret = False;
850         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
851                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
852                 ret = False;
853         }
854
855         if (!ret) {
856                 return ret;
857         }
858
859         /* NEGATIVE tests.  This should parse, but not succeed */
860         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
861         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
862         names[0].str = "NOT A PRINCIPAL";
863
864         printf("testing DsCrackNames with user principal '%s' desired format:%d\n",
865                         names[0].str, r.in.req.req1.format_desired);
866
867         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
868         if (!NT_STATUS_IS_OK(status)) {
869                 const char *errstr = nt_errstr(status);
870                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
871                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
872                 }
873                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
874                 ret = False;
875         } else if (!W_ERROR_IS_OK(r.out.result)) {
876                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
877                 ret = False;
878         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
879                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
880                 ret = False;
881         }
882
883         if (!ret) {
884                 return ret;
885         }
886
887         /* NEGATIVE tests.  This should parse, but not succeed */
888         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
889         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
890         names[0].str = "NOT A SERVICE PRINCIPAL";
891
892         printf("testing DsCrackNames with service principal '%s' desired format:%d\n",
893                         names[0].str, r.in.req.req1.format_desired);
894
895         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
896         if (!NT_STATUS_IS_OK(status)) {
897                 const char *errstr = nt_errstr(status);
898                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
899                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
900                 }
901                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
902                 ret = False;
903         } else if (!W_ERROR_IS_OK(r.out.result)) {
904                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
905                 ret = False;
906         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
907                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
908                 ret = False;
909         }
910
911         if (!ret) {
912                 return ret;
913         }
914
915         /* NEGATIVE tests.  This should parse, but not succeed */
916         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
917         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
918         names[0].str = GUID_string2(mem_ctx, &priv->bind_guid);
919
920         printf("testing DsCrackNames with BIND GUID '%s' desired format:%d\n",
921                         names[0].str, r.in.req.req1.format_desired);
922
923         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
924         if (!NT_STATUS_IS_OK(status)) {
925                 const char *errstr = nt_errstr(status);
926                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
927                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
928                 }
929                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
930                 ret = False;
931         } else if (!W_ERROR_IS_OK(r.out.result)) {
932                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
933                 ret = False;
934         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
935                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
936                 ret = False;
937         }
938
939         /* NEGATIVE tests.  This should parse, but not succeed */
940         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
941         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
942         names[0].str = talloc_asprintf(mem_ctx, "%s$", test_dc);
943
944         printf("testing DsCrackNames with user principal name '%s' desired format:%d\n",
945                         names[0].str, r.in.req.req1.format_desired);
946
947         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
948         if (!NT_STATUS_IS_OK(status)) {
949                 const char *errstr = nt_errstr(status);
950                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
951                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
952                 }
953                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
954                 ret = False;
955         } else if (!W_ERROR_IS_OK(r.out.result)) {
956                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
957                 ret = False;
958         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
959                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
960                 ret = False;
961         }
962
963         /* NEGATIVE tests.  This should parse, but not succeed */
964         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
965         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
966         names[0].str = talloc_asprintf(mem_ctx, "%s$", test_dc);
967
968         printf("testing DsCrackNames with service principal name '%s' desired format:%d\n",
969                         names[0].str, r.in.req.req1.format_desired);
970
971         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
972         if (!NT_STATUS_IS_OK(status)) {
973                 const char *errstr = nt_errstr(status);
974                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
975                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
976                 }
977                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
978                 ret = False;
979         } else if (!W_ERROR_IS_OK(r.out.result)) {
980                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
981                 ret = False;
982         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
983                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
984                 ret = False;
985         }
986
987
988         if (!ret) {
989                 return ret;
990         }
991
992         /* NEGATIVE tests.  This should parse, but not succeed */
993         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
994         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
995         names[0].str = talloc_asprintf(mem_ctx, "%s\\", lp_realm());
996
997         printf("testing DsCrackNames with name '%s' desired format:%d\n",
998                         names[0].str, r.in.req.req1.format_desired);
999
1000         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
1001         if (!NT_STATUS_IS_OK(status)) {
1002                 const char *errstr = nt_errstr(status);
1003                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1004                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1005                 }
1006                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
1007                 ret = False;
1008         } else if (!W_ERROR_IS_OK(r.out.result)) {
1009                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
1010                 ret = False;
1011         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
1012                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
1013                 ret = False;
1014         }
1015
1016         if (!ret) {
1017                 return ret;
1018         }
1019
1020         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
1021         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
1022         names[0].str = SID_BUILTIN;
1023
1024         printf("testing DsCrackNames with SID '%s' desired format:%d\n",
1025                         names[0].str, r.in.req.req1.format_desired);
1026
1027         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
1028         if (!NT_STATUS_IS_OK(status)) {
1029                 const char *errstr = nt_errstr(status);
1030                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1031                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1032                 }
1033                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
1034                 ret = False;
1035         } else if (!W_ERROR_IS_OK(r.out.result)) {
1036                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
1037                 ret = False;
1038         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
1039                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
1040                 ret = False;
1041         }
1042
1043         if (!ret) {
1044                 return ret;
1045         }
1046
1047
1048         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
1049         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
1050         names[0].str = SID_BUILTIN_ADMINISTRATORS;
1051
1052         printf("testing DsCrackNames with SID '%s' desired format:%d\n",
1053                         names[0].str, r.in.req.req1.format_desired);
1054
1055         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
1056         if (!NT_STATUS_IS_OK(status)) {
1057                 const char *errstr = nt_errstr(status);
1058                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1059                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1060                 }
1061                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
1062                 ret = False;
1063         } else if (!W_ERROR_IS_OK(r.out.result)) {
1064                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
1065                 ret = False;
1066         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
1067                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
1068                 ret = False;
1069         }
1070
1071         if (!ret) {
1072                 return ret;
1073         }
1074
1075
1076         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
1077         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
1078         names[0].str = SID_BUILTIN_ADMINISTRATORS;
1079
1080         printf("testing DsCrackNames with SID '%s' desired format:%d\n",
1081                         names[0].str, r.in.req.req1.format_desired);
1082
1083         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
1084         if (!NT_STATUS_IS_OK(status)) {
1085                 const char *errstr = nt_errstr(status);
1086                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1087                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1088                 }
1089                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
1090                 ret = False;
1091         } else if (!W_ERROR_IS_OK(r.out.result)) {
1092                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
1093                 ret = False;
1094         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
1095                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
1096                 ret = False;
1097         }
1098
1099         if (!ret) {
1100                 return ret;
1101         }
1102
1103
1104         /* NEGATIVE tests.  This should parse, but not succeed */
1105         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
1106         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
1107         names[0].str = "foo@bar";
1108
1109         printf("testing DsCrackNames with user principal name '%s' desired format:%d\n",
1110                         names[0].str, r.in.req.req1.format_desired);
1111
1112         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
1113         if (!NT_STATUS_IS_OK(status)) {
1114                 const char *errstr = nt_errstr(status);
1115                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1116                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1117                 }
1118                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
1119                 ret = False;
1120         } else if (!W_ERROR_IS_OK(r.out.result)) {
1121                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
1122                 ret = False;
1123         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY) {
1124                 printf("DsCrackNames incorrect error on name - %d\n", r.out.ctr.ctr1->array[0].status);
1125                 ret = False;
1126         }
1127
1128         if (ret) {
1129                 return test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name, user_principal_name, service_principal_name);
1130         }
1131
1132         return ret;
1133 }
1134
1135 static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1136                       struct DsPrivate *priv)
1137 {
1138         NTSTATUS status;
1139         struct drsuapi_DsGetDomainControllerInfo r;
1140         BOOL ret = True;
1141
1142         r.in.bind_handle = &priv->bind_handle;
1143         r.in.level = 1;
1144
1145         r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
1146         r.in.req.req1.level = 1;
1147
1148         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
1149                         r.in.req.req1.level, r.in.req.req1.domain_name);
1150
1151         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
1152         if (!NT_STATUS_IS_OK(status)) {
1153                 const char *errstr = nt_errstr(status);
1154                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1155                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1156                 }
1157                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
1158                         "    with dns domain failed - %s\n",
1159                         r.in.req.req1.level, errstr);
1160                 ret = False;
1161         } else if (!W_ERROR_IS_OK(r.out.result)) {
1162                 printf("DsGetDomainControllerInfo level %d\n"
1163                         "    with dns domain failed - %s\n",
1164                         r.in.req.req1.level, win_errstr(r.out.result));
1165                 ret = False;
1166         }
1167
1168         r.in.req.req1.level = 2;
1169
1170         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
1171                         r.in.req.req1.level, r.in.req.req1.domain_name);
1172
1173         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
1174         if (!NT_STATUS_IS_OK(status)) {
1175                 const char *errstr = nt_errstr(status);
1176                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1177                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1178                 }
1179                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
1180                         "    with dns domain failed - %s\n",
1181                         r.in.req.req1.level, errstr);
1182                 ret = False;
1183         } else if (!W_ERROR_IS_OK(r.out.result)) {
1184                 printf("DsGetDomainControllerInfo level %d\n"
1185                         "    with dns domain failed - %s\n",
1186                         r.in.req.req1.level, win_errstr(r.out.result));
1187                 ret = False;
1188         } else {
1189                 if (r.out.ctr.ctr2.count > 0) {
1190                         priv->dcinfo    = r.out.ctr.ctr2.array[0];
1191                 }
1192         }
1193
1194         r.in.req.req1.level = -1;
1195
1196         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
1197                         r.in.req.req1.level, r.in.req.req1.domain_name);
1198
1199         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
1200         if (!NT_STATUS_IS_OK(status)) {
1201                 const char *errstr = nt_errstr(status);
1202                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1203                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1204                 }
1205                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
1206                         "    with dns domain failed - %s\n",
1207                         r.in.req.req1.level, errstr);
1208                 ret = False;
1209         } else if (!W_ERROR_IS_OK(r.out.result)) {
1210                 printf("DsGetDomainControllerInfo level %d\n"
1211                         "    with dns domain failed - %s\n",
1212                         r.in.req.req1.level, win_errstr(r.out.result));
1213                 ret = False;
1214         }
1215
1216         r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
1217         r.in.req.req1.level = 2;
1218
1219         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
1220                         r.in.req.req1.level, r.in.req.req1.domain_name);
1221
1222         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
1223         if (!NT_STATUS_IS_OK(status)) {
1224                 const char *errstr = nt_errstr(status);
1225                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1226                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1227                 }
1228                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
1229                         "    with netbios domain failed - %s\n",
1230                         r.in.req.req1.level, errstr);
1231                 ret = False;
1232         } else if (!W_ERROR_IS_OK(r.out.result)) {
1233                 printf("DsGetDomainControllerInfo level %d\n"
1234                         "    with netbios domain failed - %s\n",
1235                         r.in.req.req1.level, win_errstr(r.out.result));
1236                 ret = False;
1237         }
1238
1239         r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
1240         r.in.req.req1.level = 2;
1241
1242         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
1243                         r.in.req.req1.level, r.in.req.req1.domain_name);
1244
1245         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
1246         if (!NT_STATUS_IS_OK(status)) {
1247                 const char *errstr = nt_errstr(status);
1248                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1249                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1250                 }
1251                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
1252                         "    with invalid domain failed - %s\n",
1253                         r.in.req.req1.level, errstr);
1254                 ret = False;
1255         } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
1256                 printf("DsGetDomainControllerInfo level %d\n"
1257                         "    with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
1258                         r.in.req.req1.level, win_errstr(r.out.result));
1259                 ret = False;
1260         }
1261
1262         return ret;
1263 }
1264
1265 static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1266                         struct DsPrivate *priv)
1267 {
1268         NTSTATUS status;
1269         struct drsuapi_DsWriteAccountSpn r;
1270         struct drsuapi_DsNameString names[2];
1271         BOOL ret = True;
1272
1273         r.in.bind_handle                = &priv->bind_handle;
1274         r.in.level                      = 1;
1275
1276         printf("testing DsWriteAccountSpn\n");
1277
1278         r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
1279         r.in.req.req1.unknown1  = 0;
1280         r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
1281         r.in.req.req1.count     = 2;
1282         r.in.req.req1.spn_names = names;
1283         names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
1284         names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
1285
1286         status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
1287         if (!NT_STATUS_IS_OK(status)) {
1288                 const char *errstr = nt_errstr(status);
1289                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1290                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1291                 }
1292                 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
1293                 ret = False;
1294         } else if (!W_ERROR_IS_OK(r.out.result)) {
1295                 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
1296                 ret = False;
1297         }
1298
1299         r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
1300         r.in.req.req1.unknown1  = 0;
1301
1302         status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
1303         if (!NT_STATUS_IS_OK(status)) {
1304                 const char *errstr = nt_errstr(status);
1305                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1306                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1307                 }
1308                 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
1309                 ret = False;
1310         } else if (!W_ERROR_IS_OK(r.out.result)) {
1311                 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
1312                 ret = False;
1313         }
1314
1315         return ret;
1316 }
1317
1318 static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1319                         struct DsPrivate *priv)
1320 {
1321         NTSTATUS status;
1322         struct drsuapi_DsReplicaGetInfo r;
1323         BOOL ret = True;
1324         int i;
1325         struct {
1326                 int32_t level;
1327                 int32_t infotype;
1328                 const char *obj_dn;
1329         } array[] = {
1330                 {       
1331                         DRSUAPI_DS_REPLICA_GET_INFO,
1332                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
1333                         NULL
1334                 },{
1335                         DRSUAPI_DS_REPLICA_GET_INFO,
1336                         DRSUAPI_DS_REPLICA_INFO_CURSORS,
1337                         NULL
1338                 },{
1339                         DRSUAPI_DS_REPLICA_GET_INFO,
1340                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
1341                         NULL
1342                 },{
1343                         DRSUAPI_DS_REPLICA_GET_INFO,
1344                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
1345                         NULL
1346                 },{
1347                         DRSUAPI_DS_REPLICA_GET_INFO,
1348                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
1349                         NULL
1350                 },{
1351                         DRSUAPI_DS_REPLICA_GET_INFO,
1352                         DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
1353                         NULL
1354                 },{
1355                         DRSUAPI_DS_REPLICA_GET_INFO2,
1356                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
1357                         NULL
1358                 },{
1359                         DRSUAPI_DS_REPLICA_GET_INFO2,
1360                         DRSUAPI_DS_REPLICA_INFO_CURSORS2,
1361                         NULL
1362                 },{
1363                         DRSUAPI_DS_REPLICA_GET_INFO2,
1364                         DRSUAPI_DS_REPLICA_INFO_CURSORS3,
1365                         NULL
1366                 },{
1367                         DRSUAPI_DS_REPLICA_GET_INFO2,
1368                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
1369                         NULL
1370                 },{
1371                         DRSUAPI_DS_REPLICA_GET_INFO2,
1372                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
1373                         NULL
1374                 },{
1375                         DRSUAPI_DS_REPLICA_GET_INFO2,
1376                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02,
1377                         NULL
1378                 },{
1379                         DRSUAPI_DS_REPLICA_GET_INFO2,
1380                         DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04,
1381                         "__IGNORED__"
1382                 },{
1383                         DRSUAPI_DS_REPLICA_GET_INFO2,
1384                         DRSUAPI_DS_REPLICA_INFO_CURSURS05,
1385                         NULL
1386                 },{
1387                         DRSUAPI_DS_REPLICA_GET_INFO2,
1388                         DRSUAPI_DS_REPLICA_INFO_06,
1389                         NULL
1390                 }
1391         };
1392
1393         r.in.bind_handle        = &priv->bind_handle;
1394
1395         for (i=0; i < ARRAY_SIZE(array); i++) {
1396                 const char *object_dn;
1397
1398                 printf("testing DsReplicaGetInfo level %d infotype %d\n",
1399                         array[i].level, array[i].infotype);
1400
1401                 object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
1402
1403                 r.in.level = array[i].level;
1404                 switch(r.in.level) {
1405                 case DRSUAPI_DS_REPLICA_GET_INFO:
1406                         r.in.req.req1.info_type = array[i].infotype;
1407                         r.in.req.req1.object_dn = object_dn;
1408                         ZERO_STRUCT(r.in.req.req1.guid1);
1409                         break;
1410                 case DRSUAPI_DS_REPLICA_GET_INFO2:
1411                         r.in.req.req2.info_type = array[i].infotype;
1412                         r.in.req.req2.object_dn = object_dn;
1413                         ZERO_STRUCT(r.in.req.req1.guid1);
1414                         r.in.req.req2.unknown1  = 0;
1415                         r.in.req.req2.string1   = NULL;
1416                         r.in.req.req2.string2   = NULL;
1417                         r.in.req.req2.unknown2  = 0;
1418                         break;
1419                 }
1420
1421                 status = dcerpc_drsuapi_DsReplicaGetInfo(p, mem_ctx, &r);
1422                 if (!NT_STATUS_IS_OK(status)) {
1423                         const char *errstr = nt_errstr(status);
1424                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1425                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1426                         }
1427                         if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
1428                                 printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
1429                                 ret = False;
1430                         } else {
1431                                 printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
1432                                         array[i].level, array[i].infotype);
1433                         }
1434                 } else if (!W_ERROR_IS_OK(r.out.result)) {
1435                         printf("DsReplicaGetInfo failed - %s\n", win_errstr(r.out.result));
1436                         ret = False;
1437                 }
1438         }
1439
1440         return ret;
1441 }
1442
1443 static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1444                         struct DsPrivate *priv)
1445 {
1446         NTSTATUS status;
1447         BOOL ret = True;
1448         int i;
1449         struct drsuapi_DsReplicaSync r;
1450         struct drsuapi_DsReplicaObjectIdentifier nc;
1451         struct GUID null_guid;
1452         struct dom_sid null_sid;
1453         struct {
1454                 int32_t level;
1455         } array[] = {
1456                 {       
1457                         1
1458                 }
1459         };
1460
1461         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1462                 printf("DsReplicaSync disabled - enable dangerous tests to use\n");
1463                 return True;
1464         }
1465
1466         ZERO_STRUCT(null_guid);
1467         ZERO_STRUCT(null_sid);
1468
1469         r.in.bind_handle        = &priv->bind_handle;
1470
1471         for (i=0; i < ARRAY_SIZE(array); i++) {
1472                 printf("testing DsReplicaSync level %d\n",
1473                         array[i].level);
1474
1475                 r.in.level = array[i].level;
1476                 switch(r.in.level) {
1477                 case 1:
1478                         nc.guid                                 = null_guid;
1479                         nc.sid                                  = null_sid;
1480                         nc.dn                                   = priv->domain_obj_dn?priv->domain_obj_dn:"";
1481
1482                         r.in.req.req1.naming_context            = &nc;
1483                         r.in.req.req1.guid1                     = priv->dcinfo.ntds_guid;
1484                         r.in.req.req1.string1                   = NULL;
1485                         r.in.req.req1.options                   = 16;
1486                         break;
1487                 }
1488
1489                 status = dcerpc_drsuapi_DsReplicaSync(p, mem_ctx, &r);
1490                 if (!NT_STATUS_IS_OK(status)) {
1491                         const char *errstr = nt_errstr(status);
1492                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1493                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1494                         }
1495                         printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr);
1496                         ret = False;
1497                 } else if (!W_ERROR_IS_OK(r.out.result)) {
1498                         printf("DsReplicaSync failed - %s\n", win_errstr(r.out.result));
1499                         ret = False;
1500                 }
1501         }
1502
1503         return ret;
1504 }
1505
1506 static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1507                         struct DsPrivate *priv)
1508 {
1509         NTSTATUS status;
1510         BOOL ret = True;
1511         int i;
1512         struct drsuapi_DsReplicaUpdateRefs r;
1513         struct drsuapi_DsReplicaObjectIdentifier nc;
1514         struct GUID null_guid;
1515         struct dom_sid null_sid;
1516         struct {
1517                 int32_t level;
1518         } array[] = {
1519                 {       
1520                         1
1521                 }
1522         };
1523
1524         ZERO_STRUCT(null_guid);
1525         ZERO_STRUCT(null_sid);
1526
1527         r.in.bind_handle        = &priv->bind_handle;
1528
1529         for (i=0; i < ARRAY_SIZE(array); i++) {
1530                 printf("testing DsReplicaUpdateRefs level %d\n",
1531                         array[i].level);
1532
1533                 r.in.level = array[i].level;
1534                 switch(r.in.level) {
1535                 case 1:
1536                         nc.guid                         = null_guid;
1537                         nc.sid                          = null_sid;
1538                         nc.dn                           = priv->domain_obj_dn?priv->domain_obj_dn:"";
1539
1540                         r.in.req.req1.naming_context    = &nc;
1541                         r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s",
1542                                                                                 priv->domain_dns_name);
1543                         r.in.req.req1.dest_dsa_guid     = null_guid;
1544                         r.in.req.req1.options           = 0;
1545                         break;
1546                 }
1547
1548                 status = dcerpc_drsuapi_DsReplicaUpdateRefs(p, mem_ctx, &r);
1549                 if (!NT_STATUS_IS_OK(status)) {
1550                         const char *errstr = nt_errstr(status);
1551                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1552                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1553                         }
1554                         printf("dcerpc_drsuapi_DsReplicaUpdateRefs failed - %s\n", errstr);
1555                         ret = False;
1556                 } else if (!W_ERROR_IS_OK(r.out.result)) {
1557                         printf("DsReplicaUpdateRefs failed - %s\n", win_errstr(r.out.result));
1558                         ret = False;
1559                 }
1560         }
1561
1562         return ret;
1563 }
1564
1565 static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1566                         struct DsPrivate *priv)
1567 {
1568         NTSTATUS status;
1569         BOOL ret = True;
1570         int i;
1571         struct drsuapi_DsGetNCChanges r;
1572         struct drsuapi_DsReplicaObjectIdentifier nc;
1573         struct GUID null_guid;
1574         struct dom_sid null_sid;
1575         struct {
1576                 int32_t level;
1577         } array[] = {
1578                 {       
1579                         5
1580                 },
1581                 {       
1582                         8
1583                 }
1584         };
1585
1586         ZERO_STRUCT(null_guid);
1587         ZERO_STRUCT(null_sid);
1588
1589         for (i=0; i < ARRAY_SIZE(array); i++) {
1590                 printf("testing DsGetNCChanges level %d\n",
1591                         array[i].level);
1592
1593                 r.in.bind_handle        = &priv->bind_handle;
1594                 r.in.level              = array[i].level;
1595
1596                 switch (r.in.level) {
1597                 case 5:
1598                         nc.guid = null_guid;
1599                         nc.sid  = null_sid;
1600                         nc.dn   = priv->domain_obj_dn?priv->domain_obj_dn:"";
1601
1602                         r.in.req.req5.destination_dsa_guid              = GUID_random();
1603                         r.in.req.req5.source_dsa_guid                   = null_guid;
1604                         r.in.req.req5.naming_context                    = &nc;
1605                         r.in.req.req5.highwatermark.tmp_highest_usn     = 0;
1606                         r.in.req.req5.highwatermark.reserved_usn        = 0;
1607                         r.in.req.req5.highwatermark.highest_usn         = 0;
1608                         r.in.req.req5.uptodateness_vector               = NULL;
1609                         r.in.req.req5.replica_flags                     = 0;
1610                         if (lp_parm_bool(-1, "drsuapi","compression", False)) {
1611                                 r.in.req.req5.replica_flags             |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
1612                         }
1613                         r.in.req.req5.unknown2                          = 0;
1614                         r.in.req.req5.unknown3                          = 0;
1615                         r.in.req.req5.unknown4                          = 0;
1616                         r.in.req.req5.h1                                = 0;
1617
1618                         break;
1619                 case 8:
1620                         nc.guid = null_guid;
1621                         nc.sid  = null_sid;
1622                         nc.dn   = priv->domain_obj_dn?priv->domain_obj_dn:"";
1623
1624                         r.in.req.req8.destination_dsa_guid              = GUID_random();
1625                         r.in.req.req8.source_dsa_guid                   = null_guid;
1626                         r.in.req.req8.naming_context                    = &nc;
1627                         r.in.req.req8.highwatermark.tmp_highest_usn     = 0;
1628                         r.in.req.req8.highwatermark.reserved_usn        = 0;
1629                         r.in.req.req8.highwatermark.highest_usn         = 0;
1630                         r.in.req.req8.uptodateness_vector               = NULL;
1631                         r.in.req.req8.replica_flags                     = 0
1632                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
1633                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
1634                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
1635                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
1636                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
1637                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES
1638                                                                         ;
1639                         r.in.req.req8.unknown2                          = 402;
1640                         r.in.req.req8.unknown3                          = 402116;
1641                         r.in.req.req8.unknown4                          = 0;
1642                         r.in.req.req8.h1                                = 0;
1643                         r.in.req.req8.unique_ptr1                       = 0;
1644                         r.in.req.req8.unique_ptr2                       = 0;
1645                         r.in.req.req8.ctr12.count                       = 0;
1646                         r.in.req.req8.ctr12.array                       = NULL;
1647
1648                         break;
1649                 }
1650
1651                 status = dcerpc_drsuapi_DsGetNCChanges(p, mem_ctx, &r);
1652                 if (!NT_STATUS_IS_OK(status)) {
1653                         const char *errstr = nt_errstr(status);
1654                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1655                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1656                         }
1657                         printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr);
1658                         ret = False;
1659                 } else if (!W_ERROR_IS_OK(r.out.result)) {
1660                         printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result));
1661                         ret = False;
1662                 }
1663         }
1664
1665         return ret;
1666 }
1667
1668 static BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1669                         struct DsPrivate *priv)
1670 {
1671         NTSTATUS status;
1672         struct drsuapi_DsUnbind r;
1673         BOOL ret = True;
1674
1675         r.in.bind_handle = &priv->bind_handle;
1676         r.out.bind_handle = &priv->bind_handle;
1677
1678         printf("testing DsUnbind\n");
1679
1680         status = dcerpc_drsuapi_DsUnbind(p, mem_ctx, &r);
1681         if (!NT_STATUS_IS_OK(status)) {
1682                 const char *errstr = nt_errstr(status);
1683                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1684                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1685                 }
1686                 printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr);
1687                 ret = False;
1688         } else if (!W_ERROR_IS_OK(r.out.result)) {
1689                 printf("DsBind failed - %s\n", win_errstr(r.out.result));
1690                 ret = False;
1691         }
1692
1693         return ret;
1694 }
1695
1696 BOOL torture_rpc_drsuapi(void)
1697 {
1698         NTSTATUS status;
1699         struct dcerpc_pipe *p;
1700         TALLOC_CTX *mem_ctx;
1701         BOOL ret = True;
1702         struct DsPrivate priv;
1703
1704         mem_ctx = talloc_init("torture_rpc_drsuapi");
1705
1706         status = torture_rpc_connection(mem_ctx, 
1707                                         &p, 
1708                                         DCERPC_DRSUAPI_NAME,
1709                                         DCERPC_DRSUAPI_UUID,
1710                                         DCERPC_DRSUAPI_VERSION);
1711         if (!NT_STATUS_IS_OK(status)) {
1712                 talloc_free(mem_ctx);
1713                 return False;
1714         }
1715
1716         printf("Connected to DRAUAPI pipe\n");
1717
1718         ZERO_STRUCT(priv);
1719
1720         ret &= test_DsBind(p, mem_ctx, &priv);
1721
1722         ret &= test_DsGetDCInfo(p, mem_ctx, &priv);
1723
1724         ret &= test_DsCrackNames(p, mem_ctx, &priv, priv.dcinfo.netbios_name);
1725
1726         ret &= test_DsWriteAccountSpn(p, mem_ctx, &priv);
1727
1728         ret &= test_DsReplicaGetInfo(p, mem_ctx, &priv);
1729
1730         ret &= test_DsReplicaSync(p, mem_ctx, &priv);
1731
1732         ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv);
1733
1734         ret &= test_DsGetNCChanges(p, mem_ctx, &priv);
1735
1736         ret &= test_DsUnbind(p, mem_ctx, &priv);
1737
1738         talloc_free(mem_ctx);
1739
1740         return ret;
1741 }
1742
1743 BOOL torture_rpc_drsuapi_cracknames(void)
1744 {
1745         NTSTATUS status;
1746         struct dcerpc_pipe *p;
1747         TALLOC_CTX *mem_ctx;
1748         BOOL ret = True;
1749         struct DsPrivate priv;
1750
1751         mem_ctx = talloc_init("torture_rpc_drsuapi");
1752
1753         status = torture_rpc_connection(mem_ctx, 
1754                                         &p, 
1755                                         DCERPC_DRSUAPI_NAME,
1756                                         DCERPC_DRSUAPI_UUID,
1757                                         DCERPC_DRSUAPI_VERSION);
1758         if (!NT_STATUS_IS_OK(status)) {
1759                 talloc_free(mem_ctx);
1760                 return False;
1761         }
1762
1763         printf("Connected to DRAUAPI pipe\n");
1764
1765         ZERO_STRUCT(priv);
1766
1767         ret &= test_DsBind(p, mem_ctx, &priv);
1768
1769         ret &= test_DsCrackNames(p, mem_ctx, &priv, lp_parm_string(-1, "torture", "host"));
1770
1771         ret &= test_DsUnbind(p, mem_ctx, &priv);
1772
1773         talloc_free(mem_ctx);
1774
1775         return ret;
1776 }