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