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