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