fbe62ae7d41375dda1c5cd8a2c86e61e991516b6
[jra/samba/.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    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26 #include "torture/torture.h"
27 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
28 #include "torture/rpc/rpc.h"
29
30 #define TEST_MACHINE_NAME "torturetest"
31
32 BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
33                  struct DsPrivate *priv)
34 {
35         NTSTATUS status;
36         struct drsuapi_DsBind r;
37         BOOL ret = True;
38
39         GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
40
41         r.in.bind_guid = &priv->bind_guid;
42         r.in.bind_info = NULL;
43         r.out.bind_handle = &priv->bind_handle;
44
45         printf("testing DsBind\n");
46
47         status = dcerpc_drsuapi_DsBind(p, mem_ctx, &r);
48         if (!NT_STATUS_IS_OK(status)) {
49                 const char *errstr = nt_errstr(status);
50                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
51                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
52                 }
53                 printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);
54                 ret = False;
55         } else if (!W_ERROR_IS_OK(r.out.result)) {
56                 printf("DsBind failed - %s\n", win_errstr(r.out.result));
57                 ret = False;
58         }
59
60         return ret;
61 }
62
63 static BOOL test_DsGetDomainControllerInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
64                       struct DsPrivate *priv)
65 {
66         NTSTATUS status;
67         struct drsuapi_DsGetDomainControllerInfo r;
68         BOOL ret = True;
69
70         if (lp_parm_bool(-1, "torture", "samba4", False)) {
71                 printf("skipping DsGetDCInfo test against Samba4\n");
72                 return True;
73         }
74
75         r.in.bind_handle = &priv->bind_handle;
76         r.in.level = 1;
77
78         r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
79         r.in.req.req1.level = 1;
80
81         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
82                         r.in.req.req1.level, r.in.req.req1.domain_name);
83
84         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
85         if (!NT_STATUS_IS_OK(status)) {
86                 const char *errstr = nt_errstr(status);
87                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
88                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
89                 }
90                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
91                         "    with dns domain failed - %s\n",
92                         r.in.req.req1.level, errstr);
93                 ret = False;
94         } else if (!W_ERROR_IS_OK(r.out.result)) {
95                 printf("DsGetDomainControllerInfo level %d\n"
96                         "    with dns domain failed - %s\n",
97                         r.in.req.req1.level, win_errstr(r.out.result));
98                 ret = False;
99         }
100
101         r.in.req.req1.level = 2;
102
103         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
104                         r.in.req.req1.level, r.in.req.req1.domain_name);
105
106         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
107         if (!NT_STATUS_IS_OK(status)) {
108                 const char *errstr = nt_errstr(status);
109                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
110                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
111                 }
112                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
113                         "    with dns domain failed - %s\n",
114                         r.in.req.req1.level, errstr);
115                 ret = False;
116         } else if (!W_ERROR_IS_OK(r.out.result)) {
117                 printf("DsGetDomainControllerInfo level %d\n"
118                         "    with dns domain failed - %s\n",
119                         r.in.req.req1.level, win_errstr(r.out.result));
120                 ret = False;
121         } else {
122                 if (r.out.ctr.ctr2.count > 0) {
123                         priv->dcinfo    = r.out.ctr.ctr2.array[0];
124                 }
125         }
126
127         r.in.req.req1.level = -1;
128
129         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
130                         r.in.req.req1.level, r.in.req.req1.domain_name);
131
132         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
133         if (!NT_STATUS_IS_OK(status)) {
134                 const char *errstr = nt_errstr(status);
135                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
136                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
137                 }
138                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
139                         "    with dns domain failed - %s\n",
140                         r.in.req.req1.level, errstr);
141                 ret = False;
142         } else if (!W_ERROR_IS_OK(r.out.result)) {
143                 printf("DsGetDomainControllerInfo level %d\n"
144                         "    with dns domain failed - %s\n",
145                         r.in.req.req1.level, win_errstr(r.out.result));
146                 ret = False;
147         }
148
149         r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
150         r.in.req.req1.level = 2;
151
152         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
153                         r.in.req.req1.level, r.in.req.req1.domain_name);
154
155         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
156         if (!NT_STATUS_IS_OK(status)) {
157                 const char *errstr = nt_errstr(status);
158                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
159                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
160                 }
161                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
162                         "    with netbios domain failed - %s\n",
163                         r.in.req.req1.level, errstr);
164                 ret = False;
165         } else if (!W_ERROR_IS_OK(r.out.result)) {
166                 printf("DsGetDomainControllerInfo level %d\n"
167                         "    with netbios domain failed - %s\n",
168                         r.in.req.req1.level, win_errstr(r.out.result));
169                 ret = False;
170         }
171
172         r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
173         r.in.req.req1.level = 2;
174
175         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
176                         r.in.req.req1.level, r.in.req.req1.domain_name);
177
178         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
179         if (!NT_STATUS_IS_OK(status)) {
180                 const char *errstr = nt_errstr(status);
181                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
182                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
183                 }
184                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
185                         "    with invalid domain failed - %s\n",
186                         r.in.req.req1.level, errstr);
187                 ret = False;
188         } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
189                 printf("DsGetDomainControllerInfo level %d\n"
190                         "    with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
191                         r.in.req.req1.level, win_errstr(r.out.result));
192                 ret = False;
193         }
194
195         return ret;
196 }
197
198 static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
199                                    struct DsPrivate *priv)
200 {
201         NTSTATUS status;
202         struct drsuapi_DsWriteAccountSpn r;
203         struct drsuapi_DsNameString names[2];
204         BOOL ret = True;
205
206         r.in.bind_handle                = &priv->bind_handle;
207         r.in.level                      = 1;
208
209         printf("testing DsWriteAccountSpn\n");
210
211         r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
212         r.in.req.req1.unknown1  = 0;
213         r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
214         r.in.req.req1.count     = 2;
215         r.in.req.req1.spn_names = names;
216         names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
217         names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
218
219         status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
220         if (!NT_STATUS_IS_OK(status)) {
221                 const char *errstr = nt_errstr(status);
222                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
223                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
224                 }
225                 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
226                 ret = False;
227         } else if (!W_ERROR_IS_OK(r.out.result)) {
228                 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
229                 ret = False;
230         }
231
232         r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
233         r.in.req.req1.unknown1  = 0;
234
235         status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
236         if (!NT_STATUS_IS_OK(status)) {
237                 const char *errstr = nt_errstr(status);
238                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
239                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
240                 }
241                 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
242                 ret = False;
243         } else if (!W_ERROR_IS_OK(r.out.result)) {
244                 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
245                 ret = False;
246         }
247
248         return ret;
249 }
250
251 static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
252                         struct DsPrivate *priv)
253 {
254         NTSTATUS status;
255         struct drsuapi_DsReplicaGetInfo r;
256         BOOL ret = True;
257         int i;
258         struct {
259                 int32_t level;
260                 int32_t infotype;
261                 const char *obj_dn;
262         } array[] = {
263                 {       
264                         DRSUAPI_DS_REPLICA_GET_INFO,
265                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
266                         NULL
267                 },{
268                         DRSUAPI_DS_REPLICA_GET_INFO,
269                         DRSUAPI_DS_REPLICA_INFO_CURSORS,
270                         NULL
271                 },{
272                         DRSUAPI_DS_REPLICA_GET_INFO,
273                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
274                         NULL
275                 },{
276                         DRSUAPI_DS_REPLICA_GET_INFO,
277                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
278                         NULL
279                 },{
280                         DRSUAPI_DS_REPLICA_GET_INFO,
281                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
282                         NULL
283                 },{
284                         DRSUAPI_DS_REPLICA_GET_INFO,
285                         DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
286                         NULL
287                 },{
288                         DRSUAPI_DS_REPLICA_GET_INFO2,
289                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
290                         NULL
291                 },{
292                         DRSUAPI_DS_REPLICA_GET_INFO2,
293                         DRSUAPI_DS_REPLICA_INFO_CURSORS2,
294                         NULL
295                 },{
296                         DRSUAPI_DS_REPLICA_GET_INFO2,
297                         DRSUAPI_DS_REPLICA_INFO_CURSORS3,
298                         NULL
299                 },{
300                         DRSUAPI_DS_REPLICA_GET_INFO2,
301                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
302                         NULL
303                 },{
304                         DRSUAPI_DS_REPLICA_GET_INFO2,
305                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
306                         NULL
307                 },{
308                         DRSUAPI_DS_REPLICA_GET_INFO2,
309                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02,
310                         NULL
311                 },{
312                         DRSUAPI_DS_REPLICA_GET_INFO2,
313                         DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04,
314                         "__IGNORED__"
315                 },{
316                         DRSUAPI_DS_REPLICA_GET_INFO2,
317                         DRSUAPI_DS_REPLICA_INFO_CURSURS05,
318                         NULL
319                 },{
320                         DRSUAPI_DS_REPLICA_GET_INFO2,
321                         DRSUAPI_DS_REPLICA_INFO_06,
322                         NULL
323                 }
324         };
325
326         if (lp_parm_bool(-1, "torture", "samba4", False)) {
327                 printf("skipping DsReplicaGetInfo test against Samba4\n");
328                 return True;
329         }
330
331         r.in.bind_handle        = &priv->bind_handle;
332
333         for (i=0; i < ARRAY_SIZE(array); i++) {
334                 const char *object_dn;
335
336                 printf("testing DsReplicaGetInfo level %d infotype %d\n",
337                         array[i].level, array[i].infotype);
338
339                 object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
340
341                 r.in.level = array[i].level;
342                 switch(r.in.level) {
343                 case DRSUAPI_DS_REPLICA_GET_INFO:
344                         r.in.req.req1.info_type = array[i].infotype;
345                         r.in.req.req1.object_dn = object_dn;
346                         ZERO_STRUCT(r.in.req.req1.guid1);
347                         break;
348                 case DRSUAPI_DS_REPLICA_GET_INFO2:
349                         r.in.req.req2.info_type = array[i].infotype;
350                         r.in.req.req2.object_dn = object_dn;
351                         ZERO_STRUCT(r.in.req.req1.guid1);
352                         r.in.req.req2.unknown1  = 0;
353                         r.in.req.req2.string1   = NULL;
354                         r.in.req.req2.string2   = NULL;
355                         r.in.req.req2.unknown2  = 0;
356                         break;
357                 }
358
359                 status = dcerpc_drsuapi_DsReplicaGetInfo(p, mem_ctx, &r);
360                 if (!NT_STATUS_IS_OK(status)) {
361                         const char *errstr = nt_errstr(status);
362                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
363                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
364                         }
365                         if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
366                                 printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
367                                 ret = False;
368                         } else {
369                                 printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
370                                         array[i].level, array[i].infotype);
371                         }
372                 } else if (!W_ERROR_IS_OK(r.out.result)) {
373                         printf("DsReplicaGetInfo failed - %s\n", win_errstr(r.out.result));
374                         ret = False;
375                 }
376         }
377
378         return ret;
379 }
380
381 static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
382                         struct DsPrivate *priv)
383 {
384         NTSTATUS status;
385         BOOL ret = True;
386         int i;
387         struct drsuapi_DsReplicaSync r;
388         struct drsuapi_DsReplicaObjectIdentifier nc;
389         struct GUID null_guid;
390         struct dom_sid null_sid;
391         struct {
392                 int32_t level;
393         } array[] = {
394                 {       
395                         1
396                 }
397         };
398
399         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
400                 printf("DsReplicaSync disabled - enable dangerous tests to use\n");
401                 return True;
402         }
403
404         if (lp_parm_bool(-1, "torture", "samba4", False)) {
405                 printf("skipping DsReplicaSync test against Samba4\n");
406                 return True;
407         }
408
409         ZERO_STRUCT(null_guid);
410         ZERO_STRUCT(null_sid);
411
412         r.in.bind_handle        = &priv->bind_handle;
413
414         for (i=0; i < ARRAY_SIZE(array); i++) {
415                 printf("testing DsReplicaSync level %d\n",
416                         array[i].level);
417
418                 r.in.level = array[i].level;
419                 switch(r.in.level) {
420                 case 1:
421                         nc.guid                                 = null_guid;
422                         nc.sid                                  = null_sid;
423                         nc.dn                                   = priv->domain_obj_dn?priv->domain_obj_dn:"";
424
425                         r.in.req.req1.naming_context            = &nc;
426                         r.in.req.req1.guid1                     = priv->dcinfo.ntds_guid;
427                         r.in.req.req1.string1                   = NULL;
428                         r.in.req.req1.options                   = 16;
429                         break;
430                 }
431
432                 status = dcerpc_drsuapi_DsReplicaSync(p, mem_ctx, &r);
433                 if (!NT_STATUS_IS_OK(status)) {
434                         const char *errstr = nt_errstr(status);
435                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
436                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
437                         }
438                         printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr);
439                         ret = False;
440                 } else if (!W_ERROR_IS_OK(r.out.result)) {
441                         printf("DsReplicaSync failed - %s\n", win_errstr(r.out.result));
442                         ret = False;
443                 }
444         }
445
446         return ret;
447 }
448
449 static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
450                         struct DsPrivate *priv)
451 {
452         NTSTATUS status;
453         BOOL ret = True;
454         int i;
455         struct drsuapi_DsReplicaUpdateRefs r;
456         struct drsuapi_DsReplicaObjectIdentifier nc;
457         struct GUID null_guid;
458         struct dom_sid null_sid;
459         struct {
460                 int32_t level;
461         } array[] = {
462                 {       
463                         1
464                 }
465         };
466
467         if (lp_parm_bool(-1, "torture", "samba4", False)) {
468                 printf("skipping DsReplicaUpdateRefs test against Samba4\n");
469                 return True;
470         }
471
472         ZERO_STRUCT(null_guid);
473         ZERO_STRUCT(null_sid);
474
475         r.in.bind_handle        = &priv->bind_handle;
476
477         for (i=0; i < ARRAY_SIZE(array); i++) {
478                 printf("testing DsReplicaUpdateRefs level %d\n",
479                         array[i].level);
480
481                 r.in.level = array[i].level;
482                 switch(r.in.level) {
483                 case 1:
484                         nc.guid                         = null_guid;
485                         nc.sid                          = null_sid;
486                         nc.dn                           = priv->domain_obj_dn?priv->domain_obj_dn:"";
487
488                         r.in.req.req1.naming_context    = &nc;
489                         r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s",
490                                                                                 priv->domain_dns_name);
491                         r.in.req.req1.dest_dsa_guid     = null_guid;
492                         r.in.req.req1.options           = 0;
493                         break;
494                 }
495
496                 status = dcerpc_drsuapi_DsReplicaUpdateRefs(p, mem_ctx, &r);
497                 if (!NT_STATUS_IS_OK(status)) {
498                         const char *errstr = nt_errstr(status);
499                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
500                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
501                         }
502                         printf("dcerpc_drsuapi_DsReplicaUpdateRefs failed - %s\n", errstr);
503                         ret = False;
504                 } else if (!W_ERROR_IS_OK(r.out.result)) {
505                         printf("DsReplicaUpdateRefs failed - %s\n", win_errstr(r.out.result));
506                         ret = False;
507                 }
508         }
509
510         return ret;
511 }
512
513 static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
514                         struct DsPrivate *priv)
515 {
516         NTSTATUS status;
517         BOOL ret = True;
518         int i;
519         struct drsuapi_DsGetNCChanges r;
520         struct drsuapi_DsReplicaObjectIdentifier nc;
521         struct GUID null_guid;
522         struct dom_sid null_sid;
523         struct {
524                 int32_t level;
525         } array[] = {
526                 {       
527                         5
528                 },
529                 {       
530                         8
531                 }
532         };
533
534         if (lp_parm_bool(-1, "torture", "samba4", False)) {
535                 printf("skipping DsGetNCChanges test against Samba4\n");
536                 return True;
537         }
538
539         ZERO_STRUCT(null_guid);
540         ZERO_STRUCT(null_sid);
541
542         for (i=0; i < ARRAY_SIZE(array); i++) {
543                 printf("testing DsGetNCChanges level %d\n",
544                         array[i].level);
545
546                 r.in.bind_handle        = &priv->bind_handle;
547                 r.in.level              = array[i].level;
548
549                 switch (r.in.level) {
550                 case 5:
551                         nc.guid = null_guid;
552                         nc.sid  = null_sid;
553                         nc.dn   = priv->domain_obj_dn?priv->domain_obj_dn:"";
554
555                         r.in.req.req5.destination_dsa_guid              = GUID_random();
556                         r.in.req.req5.source_dsa_invocation_id          = null_guid;
557                         r.in.req.req5.naming_context                    = &nc;
558                         r.in.req.req5.highwatermark.tmp_highest_usn     = 0;
559                         r.in.req.req5.highwatermark.reserved_usn        = 0;
560                         r.in.req.req5.highwatermark.highest_usn         = 0;
561                         r.in.req.req5.uptodateness_vector               = NULL;
562                         r.in.req.req5.replica_flags                     = 0;
563                         if (lp_parm_bool(-1, "drsuapi","compression", False)) {
564                                 r.in.req.req5.replica_flags             |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
565                         }
566                         r.in.req.req5.max_object_count                  = 0;
567                         r.in.req.req5.max_ndr_size                      = 0;
568                         r.in.req.req5.unknown4                          = 0;
569                         r.in.req.req5.h1                                = 0;
570
571                         break;
572                 case 8:
573                         nc.guid = null_guid;
574                         nc.sid  = null_sid;
575                         nc.dn   = priv->domain_obj_dn?priv->domain_obj_dn:"";
576
577                         r.in.req.req8.destination_dsa_guid              = GUID_random();
578                         r.in.req.req8.source_dsa_invocation_id          = null_guid;
579                         r.in.req.req8.naming_context                    = &nc;
580                         r.in.req.req8.highwatermark.tmp_highest_usn     = 0;
581                         r.in.req.req8.highwatermark.reserved_usn        = 0;
582                         r.in.req.req8.highwatermark.highest_usn         = 0;
583                         r.in.req.req8.uptodateness_vector               = NULL;
584                         r.in.req.req8.replica_flags                     = 0;
585                         if (lp_parm_bool(-1,"drsuapi","compression",False)) {
586                                 r.in.req.req8.replica_flags             |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
587                         }
588                         if (lp_parm_bool(-1,"drsuapi","neighbour_writeable",True)) {
589                                 r.in.req.req8.replica_flags             |= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE;
590                         }
591                         r.in.req.req8.replica_flags                     |= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
592                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
593                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
594                                                                         | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
595                                                                         ;
596                         r.in.req.req8.max_object_count                  = 402;
597                         r.in.req.req8.max_ndr_size                      = 402116;
598                         r.in.req.req8.unknown4                          = 0;
599                         r.in.req.req8.h1                                = 0;
600                         r.in.req.req8.unique_ptr1                       = 0;
601                         r.in.req.req8.unique_ptr2                       = 0;
602                         r.in.req.req8.ctr12.count                       = 0;
603                         r.in.req.req8.ctr12.array                       = NULL;
604
605                         break;
606                 }
607
608                 status = dcerpc_drsuapi_DsGetNCChanges(p, mem_ctx, &r);
609                 if (!NT_STATUS_IS_OK(status)) {
610                         const char *errstr = nt_errstr(status);
611                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
612                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
613                         }
614                         printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr);
615                         ret = False;
616                 } else if (!W_ERROR_IS_OK(r.out.result)) {
617                         printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result));
618                         ret = False;
619                 }
620         }
621
622         return ret;
623 }
624
625 BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
626                    struct DsPrivate *priv)
627 {
628         NTSTATUS status;
629         struct drsuapi_DsUnbind r;
630         BOOL ret = True;
631
632         r.in.bind_handle = &priv->bind_handle;
633         r.out.bind_handle = &priv->bind_handle;
634
635         printf("testing DsUnbind\n");
636
637         status = dcerpc_drsuapi_DsUnbind(p, mem_ctx, &r);
638         if (!NT_STATUS_IS_OK(status)) {
639                 const char *errstr = nt_errstr(status);
640                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
641                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
642                 }
643                 printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr);
644                 ret = False;
645         } else if (!W_ERROR_IS_OK(r.out.result)) {
646                 printf("DsBind failed - %s\n", win_errstr(r.out.result));
647                 ret = False;
648         }
649
650         return ret;
651 }
652
653 BOOL torture_rpc_drsuapi(struct torture_context *torture)
654 {
655         NTSTATUS status;
656         struct dcerpc_pipe *p;
657         TALLOC_CTX *mem_ctx;
658         BOOL ret = True;
659         struct DsPrivate priv;
660         struct cli_credentials *machine_credentials;
661
662         mem_ctx = talloc_init("torture_rpc_drsuapi");
663
664         printf("Connected to DRAUAPI pipe\n");
665
666         ZERO_STRUCT(priv);
667
668         priv.join = torture_join_domain(TEST_MACHINE_NAME, ACB_SVRTRUST, 
669                                        &machine_credentials);
670         if (!priv.join) {
671                 talloc_free(mem_ctx);
672                 printf("Failed to join as BDC\n");
673                 return False;
674         }
675
676         status = torture_rpc_connection(mem_ctx, 
677                                         &p, 
678                                         &dcerpc_table_drsuapi);
679         if (!NT_STATUS_IS_OK(status)) {
680                 torture_leave_domain(priv.join);
681                 talloc_free(mem_ctx);
682                 return False;
683         }
684
685         ret &= test_DsBind(p, mem_ctx, &priv);
686
687         ret &= test_DsGetDomainControllerInfo(p, mem_ctx, &priv);
688
689         ret &= test_DsCrackNames(p, mem_ctx, &priv);
690
691         ret &= test_DsWriteAccountSpn(p, mem_ctx, &priv);
692
693         ret &= test_DsReplicaGetInfo(p, mem_ctx, &priv);
694
695         ret &= test_DsReplicaSync(p, mem_ctx, &priv);
696
697         ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv);
698
699         ret &= test_DsGetNCChanges(p, mem_ctx, &priv);
700
701         ret &= test_DsUnbind(p, mem_ctx, &priv);
702
703         talloc_free(mem_ctx);
704
705         torture_leave_domain(priv.join);
706
707         return ret;
708 }
709
710
711 BOOL torture_rpc_drsuapi_cracknames(struct torture_context *torture)
712 {
713         NTSTATUS status;
714         struct dcerpc_pipe *p;
715         TALLOC_CTX *mem_ctx;
716         BOOL ret = True;
717         struct DsPrivate priv;
718         struct cli_credentials *machine_credentials;
719
720         mem_ctx = talloc_init("torture_rpc_drsuapi");
721
722         printf("Connected to DRAUAPI pipe\n");
723
724         ZERO_STRUCT(priv);
725
726         priv.join = torture_join_domain(TEST_MACHINE_NAME, ACB_SVRTRUST, 
727                                        &machine_credentials);
728         if (!priv.join) {
729                 talloc_free(mem_ctx);
730                 printf("Failed to join as BDC\n");
731                 return False;
732         }
733
734         status = torture_rpc_connection(mem_ctx, 
735                                         &p, 
736                                         &dcerpc_table_drsuapi);
737         if (!NT_STATUS_IS_OK(status)) {
738                 torture_leave_domain(priv.join);
739                 talloc_free(mem_ctx);
740                 return False;
741         }
742
743         ret &= test_DsBind(p, mem_ctx, &priv);
744
745         if (ret) {
746                 ret &= test_DsGetDomainControllerInfo(p, mem_ctx, &priv);
747                 
748                 ret &= test_DsCrackNames(p, mem_ctx, &priv);
749                 
750                 ret &= test_DsUnbind(p, mem_ctx, &priv);
751         }
752         talloc_free(mem_ctx);
753
754         torture_leave_domain(priv.join);
755
756         return ret;
757 }
758