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