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