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