4e72a0f9b35003c753ff7748ab19b776c8cf5f13
[kai/samba.git] / source / 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_USER_PRINCIPAL:
131                 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:  
132                 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: 
133                 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: 
134                         if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
135                                 printf("Unexpected success: This name lookup should fail\n");
136                                 return False;
137                         }
138                         printf ("(expected) error\n");
139                         break;
140                 default:
141                         if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
142                                 printf("Error: %d\n", r.out.ctr.ctr1->array[0].status);
143                                 return False;
144                         }
145                 }
146
147                 switch (formats[i]) {
148                 case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
149                         n_from[i] = user_principal_name;
150                         break;
151                 case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:  
152                         n_from[i] = service_principal_name;
153                         break;
154                 case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: 
155                 case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: 
156                         n_from[i] = NULL;
157                         break;
158                 default:
159                         n_from[i] = r.out.ctr.ctr1->array[0].result_name;
160                         printf("%s\n", n_from[i]);
161                 }
162         }
163
164         for (i = 0; i < ARRAY_SIZE(formats); i++) {
165                 for (j = 0; j < ARRAY_SIZE(formats); j++) {
166                         r.in.req.req1.format_offered    = formats[i];
167                         r.in.req.req1.format_desired    = formats[j];
168                         if (!n_from[i]) {
169                                 n_matrix[i][j] = NULL;
170                                 continue;
171                         }
172                         names[0].str = n_from[i];
173                         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
174                         if (!NT_STATUS_IS_OK(status)) {
175                                 const char *errstr = nt_errstr(status);
176                                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
177                                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
178                                 }
179                                 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
180                                        names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, errstr);
181                                 ret = False;
182                         } else if (!W_ERROR_IS_OK(r.out.result)) {
183                                 printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
184                                        names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, 
185                                        win_errstr(r.out.result));
186                                 ret = False;
187                         }
188                         
189                         if (!ret) {
190                                 return ret;
191                         }
192                         if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
193                                 n_matrix[i][j] = r.out.ctr.ctr1->array[0].result_name;
194                         } else {
195                                 n_matrix[i][j] = NULL;
196                         }
197                 }
198         }
199
200         for (i = 0; i < ARRAY_SIZE(formats); i++) {
201                 for (j = 0; j < ARRAY_SIZE(formats); j++) {
202                         if (n_matrix[i][j] == n_from[j]) {
203                                 
204                         /* We don't have a from name for these yet (and we can't map to them to find it out) */
205                         } else if (n_matrix[i][j] == NULL && n_from[i] == NULL) {
206                                 
207                         /* we can't map to these two */
208                         } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
209                         } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
210                         } else if (n_matrix[i][j] == NULL && n_from[j] != NULL) {
211                                 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]);
212                                 ret = False;
213                         } else if (n_matrix[i][j] != NULL && n_from[j] == NULL) {
214                                 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]);
215                                 ret = False;
216                         } else if (strcmp(n_matrix[i][j], n_from[j]) != 0) {
217                                 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]);
218                                 ret = False;
219                         }
220                 }
221         }
222         return ret;
223 }
224
225 static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
226                       struct DsPrivate *priv)
227 {
228         NTSTATUS status;
229         struct drsuapi_DsCrackNames r;
230         struct drsuapi_DsNameString names[1];
231         BOOL ret = True;
232         const char *dns_domain;
233         const char *nt4_domain;
234         const char *FQDN_1779_name;
235         const char *user_principal_name;
236         const char *service_principal_name;
237
238         ZERO_STRUCT(r);
239         r.in.bind_handle                = &priv->bind_handle;
240         r.in.level                      = 1;
241         r.in.req.req1.unknown1          = 0x000004e4;
242         r.in.req.req1.unknown2          = 0x00000407;
243         r.in.req.req1.count             = 1;
244         r.in.req.req1.names             = names;
245         r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
246
247         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
248         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
249         names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
250
251         printf("testing DsCrackNames with name '%s' desired format:%d\n",
252                         names[0].str, r.in.req.req1.format_desired);
253
254         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
255         if (!NT_STATUS_IS_OK(status)) {
256                 const char *errstr = nt_errstr(status);
257                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
258                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
259                 }
260                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
261                 ret = False;
262         } else if (!W_ERROR_IS_OK(r.out.result)) {
263                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
264                 ret = False;
265         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
266                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
267                 ret = False;
268         }
269
270         if (!ret) {
271                 return ret;
272         }
273
274         dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
275         nt4_domain = r.out.ctr.ctr1->array[0].result_name;
276
277         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
278
279         printf("testing DsCrackNames with name '%s' desired format:%d\n",
280                         names[0].str, r.in.req.req1.format_desired);
281
282         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
283         if (!NT_STATUS_IS_OK(status)) {
284                 const char *errstr = nt_errstr(status);
285                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
286                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
287                 }
288                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
289                 ret = False;
290         } else if (!W_ERROR_IS_OK(r.out.result)) {
291                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
292                 ret = False;
293         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
294                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
295                 ret = False;
296         }
297
298         if (!ret) {
299                 return ret;
300         }
301
302         priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
303         priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
304         GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
305
306
307         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
308         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
309         names[0].str = priv->domain_guid_str;
310
311         printf("testing DsCrackNames with name '%s' desired format:%d\n",
312                         names[0].str, r.in.req.req1.format_desired);
313
314         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
315         if (!NT_STATUS_IS_OK(status)) {
316                 const char *errstr = nt_errstr(status);
317                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
318                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
319                 }
320                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
321                 ret = False;
322         } else if (!W_ERROR_IS_OK(r.out.result)) {
323                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
324                 ret = False;
325         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
326                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
327                 ret = False;
328         }
329
330         if (!ret) {
331                 return ret;
332         }
333
334         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
335         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
336         names[0].str = nt4_domain;
337
338         printf("testing DsCrackNames with name '%s' desired format:%d\n",
339                         names[0].str, r.in.req.req1.format_desired);
340
341         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
342         if (!NT_STATUS_IS_OK(status)) {
343                 const char *errstr = nt_errstr(status);
344                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
345                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
346                 }
347                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
348                 ret = False;
349         } else if (!W_ERROR_IS_OK(r.out.result)) {
350                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
351                 ret = False;
352         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
353                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
354                 ret = False;
355         }
356
357         if (!ret) {
358                 return ret;
359         }
360
361         priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
362
363         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
364         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
365         names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, priv->dcinfo.netbios_name);
366
367         printf("testing DsCrackNames with name '%s' desired format:%d\n",
368                         names[0].str, r.in.req.req1.format_desired);
369
370         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
371         if (!NT_STATUS_IS_OK(status)) {
372                 const char *errstr = nt_errstr(status);
373                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
374                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
375                 }
376                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
377                 ret = False;
378         } else if (!W_ERROR_IS_OK(r.out.result)) {
379                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
380                 ret = False;
381         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
382                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
383                 ret = False;
384         }
385
386         if (!ret) {
387                 return ret;
388         }
389
390         FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
391
392         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
393         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
394         names[0].str = talloc_asprintf(mem_ctx, "%s$@%s", priv->dcinfo.netbios_name, dns_domain);
395         user_principal_name = names[0].str;
396
397         printf("testing DsCrackNames with name '%s' desired format:%d\n",
398                         names[0].str, r.in.req.req1.format_desired);
399
400         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
401         if (!NT_STATUS_IS_OK(status)) {
402                 const char *errstr = nt_errstr(status);
403                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
404                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
405                 }
406                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
407                 ret = False;
408         } else if (!W_ERROR_IS_OK(r.out.result)) {
409                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
410                 ret = False;
411         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
412                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
413                 ret = False;
414         }
415
416         if (!ret) {
417                 return ret;
418         }
419
420         if (strcmp(r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name) != 0) {
421                 printf("DsCrackNames failed - %s != %s\n", r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name);
422                 return False;
423         }
424
425         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
426         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
427         names[0].str = talloc_asprintf(mem_ctx, "HOST/%s", priv->dcinfo.netbios_name);
428         service_principal_name = names[0].str;
429
430         printf("testing DsCrackNames with name '%s' desired format:%d\n",
431                         names[0].str, r.in.req.req1.format_desired);
432
433         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
434         if (!NT_STATUS_IS_OK(status)) {
435                 const char *errstr = nt_errstr(status);
436                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
437                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
438                 }
439                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
440                 ret = False;
441         } else if (!W_ERROR_IS_OK(r.out.result)) {
442                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
443                 ret = False;
444         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
445                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
446                 ret = False;
447         }
448
449         if (!ret) {
450                 return ret;
451         }
452
453         if (strcmp(r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name) != 0) {
454                 printf("DsCrackNames failed - %s != %s\n", r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name);
455                 return False;
456         }
457
458         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
459         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
460         names[0].str = talloc_asprintf(mem_ctx, "cifs/%s.%s", priv->dcinfo.netbios_name, dns_domain);
461
462         printf("testing DsCrackNames with name '%s' desired format:%d\n",
463                         names[0].str, r.in.req.req1.format_desired);
464
465         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
466         if (!NT_STATUS_IS_OK(status)) {
467                 const char *errstr = nt_errstr(status);
468                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
469                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
470                 }
471                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
472                 ret = False;
473         } else if (!W_ERROR_IS_OK(r.out.result)) {
474                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
475                 ret = False;
476         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
477                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
478                 ret = False;
479         }
480
481         if (!ret) {
482                 return ret;
483         }
484
485         if (strcmp(r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name) != 0) {
486                 printf("DsCrackNames failed - %s != %s\n", r.out.ctr.ctr1->array[0].result_name, FQDN_1779_name);
487                 return False;
488         }
489
490         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
491         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
492         names[0].str = FQDN_1779_name;
493
494         printf("testing DsCrackNames with name '%s' desired format:%d\n",
495                         names[0].str, r.in.req.req1.format_desired);
496
497         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
498         if (!NT_STATUS_IS_OK(status)) {
499                 const char *errstr = nt_errstr(status);
500                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
501                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
502                 }
503                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
504                 ret = False;
505         } else if (!W_ERROR_IS_OK(r.out.result)) {
506                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
507                 ret = False;
508         }
509
510         if (!ret) {
511                 return ret;
512         }
513
514         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_DISPLAY;
515
516         printf("testing DsCrackNames with name '%s' desired format:%d\n",
517                         names[0].str, r.in.req.req1.format_desired);
518
519         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
520         if (!NT_STATUS_IS_OK(status)) {
521                 const char *errstr = nt_errstr(status);
522                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
523                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
524                 }
525                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
526                 ret = False;
527         } else if (!W_ERROR_IS_OK(r.out.result)) {
528                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
529                 ret = False;
530         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
531                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
532                 ret = False;
533         }
534
535         if (!ret) {
536                 return ret;
537         }
538
539         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
540
541         printf("testing DsCrackNames with name '%s' desired format:%d\n",
542                         names[0].str, r.in.req.req1.format_desired);
543
544         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
545         if (!NT_STATUS_IS_OK(status)) {
546                 const char *errstr = nt_errstr(status);
547                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
548                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
549                 }
550                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
551                 ret = False;
552         } else if (!W_ERROR_IS_OK(r.out.result)) {
553                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
554                 ret = False;
555         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
556                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
557                 ret = False;
558         }
559
560         if (!ret) {
561                 return ret;
562         }
563
564         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
565         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
566         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid);
567
568         printf("testing DsCrackNames with Site GUID '%s' desired format:%d\n",
569                         names[0].str, r.in.req.req1.format_desired);
570
571         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
572         if (!NT_STATUS_IS_OK(status)) {
573                 const char *errstr = nt_errstr(status);
574                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
575                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
576                 }
577                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
578                 ret = False;
579         } else if (!W_ERROR_IS_OK(r.out.result)) {
580                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
581                 ret = False;
582         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
583                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
584                 ret = False;
585         }
586
587         if (!ret) {
588                 return ret;
589         }
590
591         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
592         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid);
593
594         printf("testing DsCrackNames with Computer GUID '%s' desired format:%d\n",
595                         names[0].str, r.in.req.req1.format_desired);
596
597         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
598         if (!NT_STATUS_IS_OK(status)) {
599                 const char *errstr = nt_errstr(status);
600                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
601                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
602                 }
603                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
604                 ret = False;
605         } else if (!W_ERROR_IS_OK(r.out.result)) {
606                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
607                 ret = False;
608         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
609                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
610                 ret = False;
611         }
612
613         if (!ret) {
614                 return ret;
615         }
616
617         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
618         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
619         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid);
620
621         printf("testing DsCrackNames with Server GUID '%s' desired format:%d\n",
622                         names[0].str, r.in.req.req1.format_desired);
623
624         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
625         if (!NT_STATUS_IS_OK(status)) {
626                 const char *errstr = nt_errstr(status);
627                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
628                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
629                 }
630                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
631                 ret = False;
632         } else if (!W_ERROR_IS_OK(r.out.result)) {
633                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
634                 ret = False;
635         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
636                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
637                 ret = False;
638         }
639
640         if (!ret) {
641                 return ret;
642         }
643
644         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
645         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
646         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid);
647
648         printf("testing DsCrackNames with NTDS GUID '%s' desired format:%d\n",
649                         names[0].str, r.in.req.req1.format_desired);
650
651         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
652         if (!NT_STATUS_IS_OK(status)) {
653                 const char *errstr = nt_errstr(status);
654                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
655                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
656                 }
657                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
658                 ret = False;
659         } else if (!W_ERROR_IS_OK(r.out.result)) {
660                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
661                 ret = False;
662         } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
663                 printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
664                 ret = False;
665         }
666
667         if (!ret) {
668                 return ret;
669         }
670
671         /* NEGATIVE test.  This should parse, but not succeed */
672         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
673         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
674         names[0].str = GUID_string2(mem_ctx, &priv->bind_guid);
675
676         printf("testing DsCrackNames with BIND GUID '%s' desired format:%d\n",
677                         names[0].str, r.in.req.req1.format_desired);
678
679         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
680         if (!NT_STATUS_IS_OK(status)) {
681                 const char *errstr = nt_errstr(status);
682                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
683                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
684                 }
685                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
686                 ret = False;
687         } else if (!W_ERROR_IS_OK(r.out.result)) {
688                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
689                 ret = False;
690         } else if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
691                 printf("DsCrackNames succeeded on name - %d\n", r.out.ctr.ctr1->array[0].status);
692                 ret = False;
693         }
694
695         if (ret) {
696                 return test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name, user_principal_name, service_principal_name);
697         }
698
699         return ret;
700 }
701
702 static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
703                       struct DsPrivate *priv)
704 {
705         NTSTATUS status;
706         struct drsuapi_DsGetDomainControllerInfo r;
707         BOOL ret = True;
708
709         r.in.bind_handle = &priv->bind_handle;
710         r.in.level = 1;
711
712         r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
713         r.in.req.req1.level = 1;
714
715         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
716                         r.in.req.req1.level, r.in.req.req1.domain_name);
717
718         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
719         if (!NT_STATUS_IS_OK(status)) {
720                 const char *errstr = nt_errstr(status);
721                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
722                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
723                 }
724                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
725                         "    with dns domain failed - %s\n",
726                         r.in.req.req1.level, errstr);
727                 ret = False;
728         } else if (!W_ERROR_IS_OK(r.out.result)) {
729                 printf("DsGetDomainControllerInfo level %d\n"
730                         "    with dns domain failed - %s\n",
731                         r.in.req.req1.level, win_errstr(r.out.result));
732                 ret = False;
733         }
734
735         r.in.req.req1.level = 2;
736
737         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
738                         r.in.req.req1.level, r.in.req.req1.domain_name);
739
740         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
741         if (!NT_STATUS_IS_OK(status)) {
742                 const char *errstr = nt_errstr(status);
743                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
744                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
745                 }
746                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
747                         "    with dns domain failed - %s\n",
748                         r.in.req.req1.level, errstr);
749                 ret = False;
750         } else if (!W_ERROR_IS_OK(r.out.result)) {
751                 printf("DsGetDomainControllerInfo level %d\n"
752                         "    with dns domain failed - %s\n",
753                         r.in.req.req1.level, win_errstr(r.out.result));
754                 ret = False;
755         } else {
756                 if (r.out.ctr.ctr2.count > 0) {
757                         priv->dcinfo    = r.out.ctr.ctr2.array[0];
758                 }
759         }
760
761         r.in.req.req1.level = -1;
762
763         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
764                         r.in.req.req1.level, r.in.req.req1.domain_name);
765
766         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
767         if (!NT_STATUS_IS_OK(status)) {
768                 const char *errstr = nt_errstr(status);
769                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
770                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
771                 }
772                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
773                         "    with dns domain failed - %s\n",
774                         r.in.req.req1.level, errstr);
775                 ret = False;
776         } else if (!W_ERROR_IS_OK(r.out.result)) {
777                 printf("DsGetDomainControllerInfo level %d\n"
778                         "    with dns domain failed - %s\n",
779                         r.in.req.req1.level, win_errstr(r.out.result));
780                 ret = False;
781         }
782
783         r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
784         r.in.req.req1.level = 2;
785
786         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
787                         r.in.req.req1.level, r.in.req.req1.domain_name);
788
789         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
790         if (!NT_STATUS_IS_OK(status)) {
791                 const char *errstr = nt_errstr(status);
792                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
793                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
794                 }
795                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
796                         "    with netbios domain failed - %s\n",
797                         r.in.req.req1.level, errstr);
798                 ret = False;
799         } else if (!W_ERROR_IS_OK(r.out.result)) {
800                 printf("DsGetDomainControllerInfo level %d\n"
801                         "    with netbios domain failed - %s\n",
802                         r.in.req.req1.level, win_errstr(r.out.result));
803                 ret = False;
804         }
805
806         r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
807         r.in.req.req1.level = 2;
808
809         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
810                         r.in.req.req1.level, r.in.req.req1.domain_name);
811
812         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
813         if (!NT_STATUS_IS_OK(status)) {
814                 const char *errstr = nt_errstr(status);
815                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
816                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
817                 }
818                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
819                         "    with invalid domain failed - %s\n",
820                         r.in.req.req1.level, errstr);
821                 ret = False;
822         } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
823                 printf("DsGetDomainControllerInfo level %d\n"
824                         "    with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
825                         r.in.req.req1.level, win_errstr(r.out.result));
826                 ret = False;
827         }
828
829         return ret;
830 }
831
832 static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
833                         struct DsPrivate *priv)
834 {
835         NTSTATUS status;
836         struct drsuapi_DsWriteAccountSpn r;
837         struct drsuapi_DsNameString names[2];
838         BOOL ret = True;
839
840         r.in.bind_handle                = &priv->bind_handle;
841         r.in.level                      = 1;
842
843         printf("testing DsWriteAccountSpn\n");
844
845         r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
846         r.in.req.req1.unknown1  = 0;
847         r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
848         r.in.req.req1.count     = 2;
849         r.in.req.req1.spn_names = names;
850         names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
851         names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
852
853         status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
854         if (!NT_STATUS_IS_OK(status)) {
855                 const char *errstr = nt_errstr(status);
856                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
857                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
858                 }
859                 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
860                 ret = False;
861         } else if (!W_ERROR_IS_OK(r.out.result)) {
862                 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
863                 ret = False;
864         }
865
866         r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
867         r.in.req.req1.unknown1  = 0;
868
869         status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
870         if (!NT_STATUS_IS_OK(status)) {
871                 const char *errstr = nt_errstr(status);
872                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
873                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
874                 }
875                 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
876                 ret = False;
877         } else if (!W_ERROR_IS_OK(r.out.result)) {
878                 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
879                 ret = False;
880         }
881
882         return ret;
883 }
884
885 static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
886                         struct DsPrivate *priv)
887 {
888         NTSTATUS status;
889         struct drsuapi_DsReplicaGetInfo r;
890         BOOL ret = True;
891         int i;
892         struct {
893                 int32_t level;
894                 int32_t infotype;
895                 const char *obj_dn;
896         } array[] = {
897                 {       
898                         DRSUAPI_DS_REPLICA_GET_INFO,
899                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
900                         NULL
901                 },{
902                         DRSUAPI_DS_REPLICA_GET_INFO,
903                         DRSUAPI_DS_REPLICA_INFO_CURSORS,
904                         NULL
905                 },{
906                         DRSUAPI_DS_REPLICA_GET_INFO,
907                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
908                         NULL
909                 },{
910                         DRSUAPI_DS_REPLICA_GET_INFO,
911                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
912                         NULL
913                 },{
914                         DRSUAPI_DS_REPLICA_GET_INFO,
915                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
916                         NULL
917                 },{
918                         DRSUAPI_DS_REPLICA_GET_INFO,
919                         DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
920                         NULL
921                 },{
922                         DRSUAPI_DS_REPLICA_GET_INFO2,
923                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
924                         NULL
925                 },{
926                         DRSUAPI_DS_REPLICA_GET_INFO2,
927                         DRSUAPI_DS_REPLICA_INFO_CURSORS2,
928                         NULL
929                 },{
930                         DRSUAPI_DS_REPLICA_GET_INFO2,
931                         DRSUAPI_DS_REPLICA_INFO_CURSORS3,
932                         NULL
933                 },{
934                         DRSUAPI_DS_REPLICA_GET_INFO2,
935                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
936                         NULL
937                 },{
938                         DRSUAPI_DS_REPLICA_GET_INFO2,
939                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
940                         NULL
941                 },{
942                         DRSUAPI_DS_REPLICA_GET_INFO2,
943                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02,
944                         NULL
945                 },{
946                         DRSUAPI_DS_REPLICA_GET_INFO2,
947                         DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04,
948                         "__IGNORED__"
949                 },{
950                         DRSUAPI_DS_REPLICA_GET_INFO2,
951                         DRSUAPI_DS_REPLICA_INFO_CURSURS05,
952                         NULL
953                 },{
954                         DRSUAPI_DS_REPLICA_GET_INFO2,
955                         DRSUAPI_DS_REPLICA_INFO_06,
956                         NULL
957                 }
958         };
959
960         r.in.bind_handle        = &priv->bind_handle;
961
962         for (i=0; i < ARRAY_SIZE(array); i++) {
963                 const char *object_dn;
964
965                 printf("testing DsReplicaGetInfo level %d infotype %d\n",
966                         array[i].level, array[i].infotype);
967
968                 object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
969
970                 r.in.level = array[i].level;
971                 switch(r.in.level) {
972                 case DRSUAPI_DS_REPLICA_GET_INFO:
973                         r.in.req.req1.info_type = array[i].infotype;
974                         r.in.req.req1.object_dn = object_dn;
975                         ZERO_STRUCT(r.in.req.req1.guid1);
976                         break;
977                 case DRSUAPI_DS_REPLICA_GET_INFO2:
978                         r.in.req.req2.info_type = array[i].infotype;
979                         r.in.req.req2.object_dn = object_dn;
980                         ZERO_STRUCT(r.in.req.req1.guid1);
981                         r.in.req.req2.unknown1  = 0;
982                         r.in.req.req2.string1   = NULL;
983                         r.in.req.req2.string2   = NULL;
984                         r.in.req.req2.unknown2  = 0;
985                         break;
986                 }
987
988                 status = dcerpc_drsuapi_DsReplicaGetInfo(p, mem_ctx, &r);
989                 if (!NT_STATUS_IS_OK(status)) {
990                         const char *errstr = nt_errstr(status);
991                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
992                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
993                         }
994                         if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
995                                 printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
996                                 ret = False;
997                         } else {
998                                 printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
999                                         array[i].level, array[i].infotype);
1000                         }
1001                 } else if (!W_ERROR_IS_OK(r.out.result)) {
1002                         printf("DsReplicaGetInfo failed - %s\n", win_errstr(r.out.result));
1003                         ret = False;
1004                 }
1005         }
1006
1007         return ret;
1008 }
1009
1010 static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1011                         struct DsPrivate *priv)
1012 {
1013         NTSTATUS status;
1014         BOOL ret = True;
1015         int i;
1016         struct drsuapi_DsReplicaSync r;
1017         struct drsuapi_DsReplicaObjectIdentifier nc;
1018         struct GUID null_guid;
1019         struct dom_sid null_sid;
1020         struct {
1021                 int32_t level;
1022         } array[] = {
1023                 {       
1024                         1
1025                 }
1026         };
1027
1028         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1029                 printf("DsReplicaSync disabled - enable dangerous tests to use\n");
1030                 return True;
1031         }
1032
1033         ZERO_STRUCT(null_guid);
1034         ZERO_STRUCT(null_sid);
1035
1036         r.in.bind_handle        = &priv->bind_handle;
1037
1038         for (i=0; i < ARRAY_SIZE(array); i++) {
1039                 printf("testing DsReplicaSync level %d\n",
1040                         array[i].level);
1041
1042                 r.in.level = array[i].level;
1043                 switch(r.in.level) {
1044                 case 1:
1045                         nc.guid                                 = null_guid;
1046                         nc.sid                                  = null_sid;
1047                         nc.dn                                   = priv->domain_obj_dn?priv->domain_obj_dn:"";
1048
1049                         r.in.req.req1.naming_context            = &nc;
1050                         r.in.req.req1.guid1                     = priv->dcinfo.ntds_guid;
1051                         r.in.req.req1.string1                   = NULL;
1052                         r.in.req.req1.options                   = 16;
1053                         break;
1054                 }
1055
1056                 status = dcerpc_drsuapi_DsReplicaSync(p, mem_ctx, &r);
1057                 if (!NT_STATUS_IS_OK(status)) {
1058                         const char *errstr = nt_errstr(status);
1059                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1060                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1061                         }
1062                         printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr);
1063                         ret = False;
1064                 } else if (!W_ERROR_IS_OK(r.out.result)) {
1065                         printf("DsReplicaSync failed - %s\n", win_errstr(r.out.result));
1066                         ret = False;
1067                 }
1068         }
1069
1070         return ret;
1071 }
1072
1073 static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1074                         struct DsPrivate *priv)
1075 {
1076         NTSTATUS status;
1077         BOOL ret = True;
1078         int i;
1079         struct drsuapi_DsReplicaUpdateRefs r;
1080         struct drsuapi_DsReplicaObjectIdentifier nc;
1081         struct GUID null_guid;
1082         struct dom_sid null_sid;
1083         struct {
1084                 int32_t level;
1085         } array[] = {
1086                 {       
1087                         1
1088                 }
1089         };
1090
1091         ZERO_STRUCT(null_guid);
1092         ZERO_STRUCT(null_sid);
1093
1094         r.in.bind_handle        = &priv->bind_handle;
1095
1096         for (i=0; i < ARRAY_SIZE(array); i++) {
1097                 printf("testing DsReplicaUpdateRefs level %d\n",
1098                         array[i].level);
1099
1100                 r.in.level = array[i].level;
1101                 switch(r.in.level) {
1102                 case 1:
1103                         nc.guid                         = null_guid;
1104                         nc.sid                          = null_sid;
1105                         nc.dn                           = priv->domain_obj_dn?priv->domain_obj_dn:"";
1106
1107                         r.in.req.req1.naming_context    = &nc;
1108                         r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s",
1109                                                                                 priv->domain_dns_name);
1110                         r.in.req.req1.dest_dsa_guid     = null_guid;
1111                         r.in.req.req1.options           = 0;
1112                         break;
1113                 }
1114
1115                 status = dcerpc_drsuapi_DsReplicaUpdateRefs(p, mem_ctx, &r);
1116                 if (!NT_STATUS_IS_OK(status)) {
1117                         const char *errstr = nt_errstr(status);
1118                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1119                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1120                         }
1121                         printf("dcerpc_drsuapi_DsReplicaUpdateRefs failed - %s\n", errstr);
1122                         ret = False;
1123                 } else if (!W_ERROR_IS_OK(r.out.result)) {
1124                         printf("DsReplicaUpdateRefs failed - %s\n", win_errstr(r.out.result));
1125                         ret = False;
1126                 }
1127         }
1128
1129         return ret;
1130 }
1131
1132 static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1133                         struct DsPrivate *priv)
1134 {
1135         NTSTATUS status;
1136         BOOL ret = True;
1137         int i;
1138         struct drsuapi_DsGetNCChanges r;
1139         struct drsuapi_DsReplicaObjectIdentifier nc;
1140         struct GUID null_guid;
1141         struct dom_sid null_sid;
1142         struct {
1143                 int32_t level;
1144         } array[] = {
1145                 {       
1146                         5
1147                 },
1148                 {       
1149                         8
1150                 }
1151         };
1152
1153         ZERO_STRUCT(null_guid);
1154         ZERO_STRUCT(null_sid);
1155
1156         for (i=0; i < ARRAY_SIZE(array); i++) {
1157                 printf("testing DsGetNCChanges level %d\n",
1158                         array[i].level);
1159
1160                 r.in.bind_handle        = &priv->bind_handle;
1161                 r.in.level              = array[i].level;
1162
1163                 switch (r.in.level) {
1164                 case 5:
1165                         nc.guid = null_guid;
1166                         nc.sid  = null_sid;
1167                         nc.dn   = priv->domain_obj_dn?priv->domain_obj_dn:"";
1168
1169                         r.in.req.req5.destination_dsa_guid              = GUID_random();
1170                         r.in.req.req5.source_dsa_guid                   = null_guid;
1171                         r.in.req.req5.naming_context                    = &nc;
1172                         r.in.req.req5.highwatermark.tmp_highest_usn     = 0;
1173                         r.in.req.req5.highwatermark.reserved_usn        = 0;
1174                         r.in.req.req5.highwatermark.highest_usn         = 0;
1175                         r.in.req.req5.uptodateness_vector               = NULL;
1176                         r.in.req.req5.replica_flags                     = 0;
1177                         if (lp_parm_bool(-1, "drsuapi","compression", False)) {
1178                                 r.in.req.req5.replica_flags             |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
1179                         }
1180                         r.in.req.req5.unknown2                          = 0;
1181                         r.in.req.req5.unknown3                          = 0;
1182                         r.in.req.req5.unknown4                          = 0;
1183                         r.in.req.req5.h1                                = 0;
1184
1185                         break;
1186                 case 8:
1187                         nc.guid = null_guid;
1188                         nc.sid  = null_sid;
1189                         nc.dn   = priv->domain_obj_dn?priv->domain_obj_dn:"";
1190
1191                         r.in.req.req8.destination_dsa_guid              = GUID_random();
1192                         r.in.req.req8.source_dsa_guid                   = null_guid;
1193                         r.in.req.req8.naming_context                    = &nc;
1194                         r.in.req.req8.highwatermark.tmp_highest_usn     = 0;
1195                         r.in.req.req8.highwatermark.reserved_usn        = 0;
1196                         r.in.req.req8.highwatermark.highest_usn         = 0;
1197                         r.in.req.req8.uptodateness_vector               = NULL;
1198                         r.in.req.req8.replica_flags                     = 0
1199                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
1200                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
1201                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
1202                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
1203                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
1204                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES
1205                                                                         ;
1206                         r.in.req.req8.unknown2                          = 402;
1207                         r.in.req.req8.unknown3                          = 402116;
1208                         r.in.req.req8.unknown4                          = 0;
1209                         r.in.req.req8.h1                                = 0;
1210                         r.in.req.req8.unique_ptr1                       = 0;
1211                         r.in.req.req8.unique_ptr2                       = 0;
1212                         r.in.req.req8.ctr12.count                       = 0;
1213                         r.in.req.req8.ctr12.array                       = NULL;
1214
1215                         break;
1216                 }
1217
1218                 status = dcerpc_drsuapi_DsGetNCChanges(p, mem_ctx, &r);
1219                 if (!NT_STATUS_IS_OK(status)) {
1220                         const char *errstr = nt_errstr(status);
1221                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1222                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1223                         }
1224                         printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr);
1225                         ret = False;
1226                 } else if (!W_ERROR_IS_OK(r.out.result)) {
1227                         printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result));
1228                         ret = False;
1229                 }
1230         }
1231
1232         return ret;
1233 }
1234
1235 static BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1236                         struct DsPrivate *priv)
1237 {
1238         NTSTATUS status;
1239         struct drsuapi_DsUnbind r;
1240         BOOL ret = True;
1241
1242         r.in.bind_handle = &priv->bind_handle;
1243         r.out.bind_handle = &priv->bind_handle;
1244
1245         printf("testing DsUnbind\n");
1246
1247         status = dcerpc_drsuapi_DsUnbind(p, mem_ctx, &r);
1248         if (!NT_STATUS_IS_OK(status)) {
1249                 const char *errstr = nt_errstr(status);
1250                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1251                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
1252                 }
1253                 printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr);
1254                 ret = False;
1255         } else if (!W_ERROR_IS_OK(r.out.result)) {
1256                 printf("DsBind failed - %s\n", win_errstr(r.out.result));
1257                 ret = False;
1258         }
1259
1260         return ret;
1261 }
1262
1263 BOOL torture_rpc_drsuapi(void)
1264 {
1265         NTSTATUS status;
1266         struct dcerpc_pipe *p;
1267         TALLOC_CTX *mem_ctx;
1268         BOOL ret = True;
1269         struct DsPrivate priv;
1270
1271         mem_ctx = talloc_init("torture_rpc_drsuapi");
1272
1273         status = torture_rpc_connection(mem_ctx, 
1274                                         &p, 
1275                                         DCERPC_DRSUAPI_NAME,
1276                                         DCERPC_DRSUAPI_UUID,
1277                                         DCERPC_DRSUAPI_VERSION);
1278         if (!NT_STATUS_IS_OK(status)) {
1279                 talloc_free(mem_ctx);
1280                 return False;
1281         }
1282
1283         printf("Connected to DRAUAPI pipe\n");
1284
1285         ZERO_STRUCT(priv);
1286
1287         ret &= test_DsBind(p, mem_ctx, &priv);
1288
1289         ret &= test_DsGetDCInfo(p, mem_ctx, &priv);
1290
1291         ret &= test_DsCrackNames(p, mem_ctx, &priv);
1292
1293         ret &= test_DsWriteAccountSpn(p, mem_ctx, &priv);
1294
1295         ret &= test_DsReplicaGetInfo(p, mem_ctx, &priv);
1296
1297         ret &= test_DsReplicaSync(p, mem_ctx, &priv);
1298
1299         ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv);
1300
1301         ret &= test_DsGetNCChanges(p, mem_ctx, &priv);
1302
1303         ret &= test_DsUnbind(p, mem_ctx, &priv);
1304
1305         talloc_free(mem_ctx);
1306
1307         return ret;
1308 }
1309
1310 BOOL torture_rpc_drsuapi_cracknames(void)
1311 {
1312         NTSTATUS status;
1313         struct dcerpc_pipe *p;
1314         TALLOC_CTX *mem_ctx;
1315         BOOL ret = True;
1316         struct DsPrivate priv;
1317
1318         mem_ctx = talloc_init("torture_rpc_drsuapi");
1319
1320         status = torture_rpc_connection(mem_ctx, 
1321                                         &p, 
1322                                         DCERPC_DRSUAPI_NAME,
1323                                         DCERPC_DRSUAPI_UUID,
1324                                         DCERPC_DRSUAPI_VERSION);
1325         if (!NT_STATUS_IS_OK(status)) {
1326                 talloc_free(mem_ctx);
1327                 return False;
1328         }
1329
1330         printf("Connected to DRAUAPI pipe\n");
1331
1332         ZERO_STRUCT(priv);
1333
1334         ret &= test_DsBind(p, mem_ctx, &priv);
1335
1336         ret &= test_DsGetDCInfo(p, mem_ctx, &priv);
1337
1338         ret &= test_DsCrackNames(p, mem_ctx, &priv);
1339
1340         ret &= test_DsUnbind(p, mem_ctx, &priv);
1341
1342         talloc_free(mem_ctx);
1343
1344         return ret;
1345 }