1ba96570456c059740c8e5d3605f1c2c7269cd95
[obnox/samba/samba-obnox.git] / source4 / torture / rpc / clusapi.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for clusapi rpc operations
4
5    Copyright (C) Günther Deschner 2015
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "librpc/gen_ndr/ndr_clusapi_c.h"
23 #include "torture/rpc/torture_rpc.h"
24 #include "param/param.h"
25 #include "libcli/registry/util_reg.h"
26
27 struct torture_clusapi_context {
28         struct dcerpc_pipe *p;
29         const char *NodeName;
30         const char *ClusterName;
31 };
32
33 static bool test_OpenCluster_int(struct torture_context *tctx,
34                                  struct dcerpc_pipe *p,
35                                  struct policy_handle *Cluster)
36 {
37         struct dcerpc_binding_handle *b = p->binding_handle;
38         struct clusapi_OpenCluster r;
39         WERROR Status;
40
41         r.out.Status = &Status;
42         r.out.Cluster = Cluster;
43
44         torture_assert_ntstatus_ok(tctx,
45                 dcerpc_clusapi_OpenCluster_r(b, tctx, &r),
46                 "OpenCluster failed");
47         torture_assert_werr_ok(tctx,
48                 *r.out.Status,
49                 "OpenCluster failed");
50
51         return true;
52 }
53
54 static bool test_OpenClusterEx_int(struct torture_context *tctx,
55                                    struct dcerpc_pipe *p,
56                                    struct policy_handle *Cluster)
57 {
58         struct dcerpc_binding_handle *b = p->binding_handle;
59         struct clusapi_OpenClusterEx r;
60         uint32_t lpdwGrantedAccess;
61         WERROR Status;
62
63         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
64         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
65         r.out.Status = &Status;
66         r.out.hCluster = Cluster;
67
68         torture_assert_ntstatus_ok(tctx,
69                 dcerpc_clusapi_OpenClusterEx_r(b, tctx, &r),
70                 "OpenClusterEx failed");
71         torture_assert_werr_ok(tctx,
72                 *r.out.Status,
73                 "OpenClusterEx failed");
74
75         return true;
76 }
77
78 static bool test_CloseCluster_int(struct torture_context *tctx,
79                                   struct dcerpc_pipe *p,
80                                   struct policy_handle *Cluster)
81 {
82         struct dcerpc_binding_handle *b = p->binding_handle;
83         struct clusapi_CloseCluster r;
84
85         r.in.Cluster = Cluster;
86         r.out.Cluster = Cluster;
87
88         torture_assert_ntstatus_ok(tctx,
89                 dcerpc_clusapi_CloseCluster_r(b, tctx, &r),
90                 "CloseCluster failed");
91         torture_assert_werr_ok(tctx,
92                 r.out.result,
93                 "CloseCluster failed");
94
95         torture_assert(tctx,
96                 ndr_policy_handle_empty(Cluster),
97                 "policy_handle non empty after CloseCluster");
98
99         return true;
100 }
101
102 static bool test_OpenCluster(struct torture_context *tctx,
103                              void *data)
104 {
105         struct torture_clusapi_context *t =
106                 talloc_get_type_abort(data, struct torture_clusapi_context);
107         struct policy_handle Cluster;
108
109         if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
110                 return false;
111         }
112
113         test_CloseCluster_int(tctx, t->p, &Cluster);
114
115         return true;
116 }
117
118 static bool test_OpenClusterEx(struct torture_context *tctx,
119                                void *data)
120 {
121         struct torture_clusapi_context *t =
122                 talloc_get_type_abort(data, struct torture_clusapi_context);
123         struct policy_handle Cluster;
124
125         if (!test_OpenClusterEx_int(tctx, t->p, &Cluster)) {
126                 return false;
127         }
128
129         test_CloseCluster_int(tctx, t->p, &Cluster);
130
131         return true;
132 }
133
134 static bool test_CloseCluster(struct torture_context *tctx,
135                               void *data)
136 {
137         struct torture_clusapi_context *t =
138                 talloc_get_type_abort(data, struct torture_clusapi_context);
139         struct policy_handle Cluster;
140
141         if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
142                 return false;
143         }
144
145         return test_CloseCluster_int(tctx, t->p, &Cluster);
146 }
147
148 static bool test_GetClusterName_int(struct torture_context *tctx,
149                                     struct dcerpc_pipe *p,
150                                     const char **ClusterName)
151 {
152         struct dcerpc_binding_handle *b = p->binding_handle;
153         struct clusapi_GetClusterName r;
154         const char *NodeName;
155
156         r.out.ClusterName = ClusterName;
157         r.out.NodeName = &NodeName;
158
159         torture_assert_ntstatus_ok(tctx,
160                 dcerpc_clusapi_GetClusterName_r(b, tctx, &r),
161                 "GetClusterName failed");
162         torture_assert_werr_ok(tctx,
163                 r.out.result,
164                 "GetClusterName failed");
165
166         return true;
167 }
168
169 static bool test_SetClusterName(struct torture_context *tctx,
170                                 void *data)
171 {
172         struct torture_clusapi_context *t =
173                 talloc_get_type_abort(data, struct torture_clusapi_context);
174         struct dcerpc_binding_handle *b = t->p->binding_handle;
175         struct clusapi_SetClusterName r;
176         const char *NewClusterName;
177         WERROR rpc_status;
178
179         torture_assert(tctx,
180                 test_GetClusterName_int(tctx, t->p, &NewClusterName),
181                 "failed to query old ClusterName");
182
183         r.in.NewClusterName = NewClusterName;
184         r.out.rpc_status = &rpc_status;
185
186         torture_assert_ntstatus_ok(tctx,
187                 dcerpc_clusapi_SetClusterName_r(b, tctx, &r),
188                 "SetClusterName failed");
189         torture_assert_werr_equal(tctx,
190                 r.out.result,
191                 WERR_RESOURCE_PROPERTIES_STORED,
192                 "SetClusterName failed");
193
194         return true;
195 }
196
197 static bool test_GetClusterName(struct torture_context *tctx,
198                                 void *data)
199 {
200         struct torture_clusapi_context *t =
201                 talloc_get_type_abort(data, struct torture_clusapi_context);
202         const char *ClusterName;
203
204         return test_GetClusterName_int(tctx, t->p, &ClusterName);
205 }
206
207 static bool test_GetClusterVersion(struct torture_context *tctx,
208                                    void *data)
209 {
210         struct torture_clusapi_context *t =
211                 talloc_get_type_abort(data, struct torture_clusapi_context);
212         struct dcerpc_binding_handle *b = t->p->binding_handle;
213         struct clusapi_GetClusterVersion r;
214         uint16_t lpwMajorVersion;
215         uint16_t lpwMinorVersion;
216         uint16_t lpwBuildNumber;
217         const char *lpszVendorId;
218         const char *lpszCSDVersion;
219
220         r.out.lpwMajorVersion = &lpwMajorVersion;
221         r.out.lpwMinorVersion = &lpwMinorVersion;
222         r.out.lpwBuildNumber = &lpwBuildNumber;
223         r.out.lpszVendorId = &lpszVendorId;
224         r.out.lpszCSDVersion = &lpszCSDVersion;
225
226         torture_assert_ntstatus_ok(tctx,
227                 dcerpc_clusapi_GetClusterVersion_r(b, tctx, &r),
228                 "GetClusterVersion failed");
229         torture_assert_werr_equal(tctx,
230                 r.out.result,
231                 WERR_CALL_NOT_IMPLEMENTED,
232                 "GetClusterVersion failed");
233
234         return true;
235 }
236
237 static bool test_GetClusterVersion2(struct torture_context *tctx,
238                                     void *data)
239 {
240         struct torture_clusapi_context *t =
241                 talloc_get_type_abort(data, struct torture_clusapi_context);
242         struct dcerpc_binding_handle *b = t->p->binding_handle;
243         struct clusapi_GetClusterVersion2 r;
244         uint16_t lpwMajorVersion;
245         uint16_t lpwMinorVersion;
246         uint16_t lpwBuildNumber;
247         const char *lpszVendorId;
248         const char *lpszCSDVersion;
249         struct CLUSTER_OPERATIONAL_VERSION_INFO *ppClusterOpVerInfo;
250         WERROR rpc_status;
251
252         r.out.lpwMajorVersion = &lpwMajorVersion;
253         r.out.lpwMinorVersion = &lpwMinorVersion;
254         r.out.lpwBuildNumber = &lpwBuildNumber;
255         r.out.lpszVendorId = &lpszVendorId;
256         r.out.lpszCSDVersion = &lpszCSDVersion;
257         r.out.ppClusterOpVerInfo = &ppClusterOpVerInfo;
258         r.out.rpc_status = &rpc_status;
259
260         torture_assert_ntstatus_ok(tctx,
261                 dcerpc_clusapi_GetClusterVersion2_r(b, tctx, &r),
262                 "GetClusterVersion2 failed");
263         torture_assert_werr_ok(tctx,
264                 r.out.result,
265                 "GetClusterVersion2 failed");
266
267         return true;
268 }
269
270 static bool test_CreateEnum(struct torture_context *tctx,
271                             void *data)
272 {
273         struct torture_clusapi_context *t =
274                 talloc_get_type_abort(data, struct torture_clusapi_context);
275         struct dcerpc_binding_handle *b = t->p->binding_handle;
276         struct clusapi_CreateEnum r;
277         uint32_t dwType[] = {
278                 CLUSTER_ENUM_NODE,
279                 CLUSTER_ENUM_RESTYPE,
280                 CLUSTER_ENUM_RESOURCE,
281                 CLUSTER_ENUM_GROUP,
282                 CLUSTER_ENUM_NETWORK,
283                 CLUSTER_ENUM_NETINTERFACE,
284                 CLUSTER_ENUM_INTERNAL_NETWORK,
285                 CLUSTER_ENUM_SHARED_VOLUME_RESOURCE
286         };
287         uint32_t dwType_invalid[] = {
288                 0x00000040,
289                 0x00000080,
290                 0x00000100 /* and many more ... */
291         };
292         struct ENUM_LIST *ReturnEnum;
293         WERROR rpc_status;
294         int i;
295
296         for (i=0; i < ARRAY_SIZE(dwType); i++) {
297
298                 r.in.dwType = dwType[i];
299                 r.out.ReturnEnum = &ReturnEnum;
300                 r.out.rpc_status = &rpc_status;
301
302                 torture_assert_ntstatus_ok(tctx,
303                         dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
304                         "CreateEnum failed");
305                 torture_assert_werr_ok(tctx,
306                         r.out.result,
307                         "CreateEnum failed");
308         }
309
310         for (i=0; i < ARRAY_SIZE(dwType_invalid); i++) {
311
312                 r.in.dwType = dwType_invalid[i];
313                 r.out.ReturnEnum = &ReturnEnum;
314                 r.out.rpc_status = &rpc_status;
315
316                 torture_assert_ntstatus_ok(tctx,
317                         dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
318                         "CreateEnum failed");
319                 torture_assert_werr_equal(tctx,
320                         r.out.result,
321                         WERR_INVALID_PARAMETER,
322                         "CreateEnum failed");
323         }
324
325         return true;
326 }
327
328 static bool test_CreateEnumEx_int(struct torture_context *tctx,
329                                   struct dcerpc_pipe *p,
330                                   struct policy_handle *Cluster)
331 {
332         struct dcerpc_binding_handle *b = p->binding_handle;
333         struct clusapi_CreateEnumEx r;
334         uint32_t dwType[] = {
335                 CLUSTER_ENUM_NODE,
336                 CLUSTER_ENUM_RESTYPE,
337                 CLUSTER_ENUM_RESOURCE,
338                 CLUSTER_ENUM_GROUP,
339                 CLUSTER_ENUM_NETWORK,
340                 CLUSTER_ENUM_NETINTERFACE,
341                 CLUSTER_ENUM_INTERNAL_NETWORK,
342                 CLUSTER_ENUM_SHARED_VOLUME_RESOURCE
343         };
344         uint32_t dwType_invalid[] = {
345                 0x00000040,
346                 0x00000080,
347                 0x00000100 /* and many more ... */
348         };
349         struct ENUM_LIST *ReturnIdEnum;
350         struct ENUM_LIST *ReturnNameEnum;
351         WERROR rpc_status;
352         int i;
353
354         for (i=0; i < ARRAY_SIZE(dwType); i++) {
355
356                 r.in.hCluster = *Cluster;
357                 r.in.dwType = dwType[i];
358                 r.in.dwOptions = 0;
359                 r.out.ReturnIdEnum = &ReturnIdEnum;
360                 r.out.ReturnNameEnum = &ReturnNameEnum;
361                 r.out.rpc_status = &rpc_status;
362
363                 torture_assert_ntstatus_ok(tctx,
364                         dcerpc_clusapi_CreateEnumEx_r(b, tctx, &r),
365                         "CreateEnumEx failed");
366                 torture_assert_werr_ok(tctx,
367                         r.out.result,
368                         "CreateEnumEx failed");
369         }
370
371         for (i=0; i < ARRAY_SIZE(dwType_invalid); i++) {
372
373                 r.in.hCluster = *Cluster;
374                 r.in.dwType = dwType_invalid[i];
375                 r.in.dwOptions = 0;
376                 r.out.ReturnIdEnum = &ReturnIdEnum;
377                 r.out.ReturnNameEnum = &ReturnNameEnum;
378                 r.out.rpc_status = &rpc_status;
379
380                 torture_assert_ntstatus_ok(tctx,
381                         dcerpc_clusapi_CreateEnumEx_r(b, tctx, &r),
382                         "CreateEnumEx failed");
383                 torture_assert_werr_equal(tctx,
384                         r.out.result,
385                         WERR_INVALID_PARAMETER,
386                         "CreateEnumEx failed");
387         }
388
389         return true;
390 }
391
392 static bool test_CreateEnumEx(struct torture_context *tctx,
393                               void *data)
394 {
395         struct torture_clusapi_context *t =
396                 talloc_get_type_abort(data, struct torture_clusapi_context);
397         struct policy_handle Cluster;
398         bool ret;
399
400         if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
401                 return false;
402         }
403
404         ret = test_CreateEnumEx_int(tctx, t->p, &Cluster);
405
406         test_CloseCluster_int(tctx, t->p, &Cluster);
407
408         return ret;
409 }
410
411
412 static bool test_GetQuorumResource(struct torture_context *tctx,
413                                    void *data)
414 {
415         struct torture_clusapi_context *t =
416                 talloc_get_type_abort(data, struct torture_clusapi_context);
417         struct dcerpc_binding_handle *b = t->p->binding_handle;
418         struct clusapi_GetQuorumResource r;
419         const char *lpszResourceName;
420         const char *lpszDeviceName;
421         uint32_t pdwMaxQuorumLogSize;
422         WERROR rpc_status;
423
424         r.out.lpszResourceName = &lpszResourceName;
425         r.out.lpszDeviceName = &lpszDeviceName;
426         r.out.pdwMaxQuorumLogSize = &pdwMaxQuorumLogSize;
427         r.out.rpc_status = &rpc_status;
428
429         torture_assert_ntstatus_ok(tctx,
430                 dcerpc_clusapi_GetQuorumResource_r(b, tctx, &r),
431                 "GetQuorumResource failed");
432         torture_assert_werr_ok(tctx,
433                 r.out.result,
434                 "GetQuorumResource failed");
435
436         return true;
437 }
438
439 static bool test_SetQuorumResource(struct torture_context *tctx,
440                                    void *data)
441 {
442         struct torture_clusapi_context *t =
443                 talloc_get_type_abort(data, struct torture_clusapi_context);
444         struct dcerpc_binding_handle *b = t->p->binding_handle;
445         struct clusapi_SetQuorumResource r;
446         const char *lpszDeviceName = "";
447         uint32_t dwMaxQuorumLogSize = 0;
448         WERROR rpc_status;
449         struct policy_handle hResource;
450
451         /* we need to figure out how this call works and what we provide as
452            devicename and resource handle - gd
453          */
454
455         torture_skip(tctx, "skipping SetQuorumResource test");
456
457         ZERO_STRUCT(hResource);
458
459         r.in.hResource = hResource;
460         r.in.lpszDeviceName = lpszDeviceName;
461         r.in.dwMaxQuorumLogSize = dwMaxQuorumLogSize;
462         r.out.rpc_status = &rpc_status;
463
464         torture_assert_ntstatus_ok(tctx,
465                 dcerpc_clusapi_SetQuorumResource_r(b, tctx, &r),
466                 "SetQuorumResource failed");
467         torture_assert_werr_ok(tctx,
468                 r.out.result,
469                 "SetQuorumResource failed");
470
471         return true;
472 }
473
474 static bool test_OpenResource_int_exp(struct torture_context *tctx,
475                                       struct dcerpc_pipe *p,
476                                       const char *lpszResourceName,
477                                       struct policy_handle *hResource,
478                                       WERROR expected_Status,
479                                       WERROR expected_rpc_status)
480 {
481         struct dcerpc_binding_handle *b = p->binding_handle;
482         struct clusapi_OpenResource r;
483         WERROR Status;
484         WERROR rpc_status;
485
486         r.in.lpszResourceName = lpszResourceName;
487         r.out.rpc_status = &rpc_status;
488         r.out.Status = &Status;
489         r.out.hResource = hResource;
490
491         torture_assert_ntstatus_ok(tctx,
492                 dcerpc_clusapi_OpenResource_r(b, tctx, &r),
493                 "OpenResource failed");
494         torture_assert_werr_equal(tctx,
495                 *r.out.Status, expected_Status,
496                 "OpenResource failed");
497         torture_assert_werr_equal(tctx,
498                 *r.out.rpc_status, expected_rpc_status,
499                 "OpenResource failed");
500
501         return true;
502 }
503
504 bool test_OpenResource_int(struct torture_context *tctx,
505                            struct dcerpc_pipe *p,
506                            const char *lpszResourceName,
507                            struct policy_handle *hResource)
508 {
509         return test_OpenResource_int_exp(tctx, p,
510                                          lpszResourceName,
511                                          hResource,
512                                          WERR_OK, WERR_OK);
513 }
514
515 static bool test_OpenResourceEx_int(struct torture_context *tctx,
516                                     struct dcerpc_pipe *p,
517                                     const char *lpszResourceName,
518                                     struct policy_handle *hResource)
519 {
520         struct dcerpc_binding_handle *b = p->binding_handle;
521         struct clusapi_OpenResourceEx r;
522         uint32_t lpdwGrantedAccess;
523         WERROR Status;
524         WERROR rpc_status;
525
526         r.in.lpszResourceName = lpszResourceName;
527         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
528         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
529         r.out.rpc_status = &rpc_status;
530         r.out.Status = &Status;
531         r.out.hResource = hResource;
532
533         torture_assert_ntstatus_ok(tctx,
534                 dcerpc_clusapi_OpenResourceEx_r(b, tctx, &r),
535                 "OpenResourceEx failed");
536         torture_assert_werr_ok(tctx,
537                 *r.out.Status,
538                 "OpenResourceEx failed");
539
540         return true;
541 }
542
543 bool test_CloseResource_int(struct torture_context *tctx,
544                             struct dcerpc_pipe *p,
545                             struct policy_handle *hResource)
546 {
547         struct dcerpc_binding_handle *b = p->binding_handle;
548         struct clusapi_CloseResource r;
549
550         r.in.Resource = hResource;
551         r.out.Resource = hResource;
552
553         torture_assert_ntstatus_ok(tctx,
554                 dcerpc_clusapi_CloseResource_r(b, tctx, &r),
555                 "CloseResource failed");
556         torture_assert_werr_ok(tctx,
557                 r.out.result,
558                 "CloseResource failed");
559         torture_assert(tctx,
560                 ndr_policy_handle_empty(hResource),
561                 "policy_handle non empty after CloseResource");
562
563         return true;
564 }
565
566 static bool test_OpenResource(struct torture_context *tctx,
567                               void *data)
568 {
569         struct torture_clusapi_context *t =
570                 talloc_get_type_abort(data, struct torture_clusapi_context);
571         struct policy_handle hResource;
572
573         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
574                 return false;
575         }
576
577         test_CloseResource_int(tctx, t->p, &hResource);
578
579         if (!test_OpenResource_int_exp(tctx, t->p, "", &hResource, WERR_RESOURCE_NOT_FOUND, WERR_OK)) {
580                 return false;
581         }
582
583         torture_assert(tctx,
584                 ndr_policy_handle_empty(&hResource),
585                 "expected empty policy handle");
586
587         if (!test_OpenResource_int_exp(tctx, t->p, "jfUF38fjSNcfn", &hResource, WERR_RESOURCE_NOT_FOUND, WERR_OK)) {
588                 return false;
589         }
590
591         torture_assert(tctx,
592                 ndr_policy_handle_empty(&hResource),
593                 "expected empty policy handle");
594
595         return true;
596 }
597
598 static bool test_OpenResourceEx(struct torture_context *tctx,
599                                 void *data)
600 {
601         struct torture_clusapi_context *t =
602                 talloc_get_type_abort(data, struct torture_clusapi_context);
603         struct policy_handle hResource;
604
605         if (!test_OpenResourceEx_int(tctx, t->p, "Cluster Name", &hResource)) {
606                 return false;
607         }
608
609         test_CloseResource_int(tctx, t->p, &hResource);
610
611         return true;
612 }
613
614
615 static bool test_CloseResource(struct torture_context *tctx,
616                                void *data)
617 {
618         struct torture_clusapi_context *t =
619                 talloc_get_type_abort(data, struct torture_clusapi_context);
620         struct policy_handle hResource;
621
622         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
623                 return false;
624         }
625
626         return test_CloseResource_int(tctx, t->p, &hResource);
627 }
628
629 static bool test_OpenGroup_int(struct torture_context *tctx,
630                                struct dcerpc_pipe *p,
631                                const char *lpszGroupName,
632                                struct policy_handle *hGroup);
633 static bool test_CloseGroup_int(struct torture_context *tctx,
634                                 struct dcerpc_pipe *p,
635                                 struct policy_handle *Group);
636
637 static bool test_CreateResource_int(struct torture_context *tctx,
638                                     struct dcerpc_pipe *p,
639                                     struct policy_handle *hResource)
640 {
641         struct dcerpc_binding_handle *b = p->binding_handle;
642         struct clusapi_CreateResource r;
643         const char *lpszResourceName = "wurst";
644         const char *lpszResourceType = "Generic Service";
645         WERROR Status;
646         WERROR rpc_status;
647         struct policy_handle hGroup;
648
649         torture_assert(tctx,
650                 test_OpenGroup_int(tctx, p, "Cluster Group", &hGroup),
651                 "failed to open group");
652
653         r.in.hGroup = hGroup;
654         r.in.lpszResourceName = lpszResourceName;
655         r.in.lpszResourceType = lpszResourceType;
656         r.in.dwFlags = CLUSTER_RESOURCE_DEFAULT_MONITOR;
657         r.out.rpc_status = &rpc_status;
658         r.out.Status = &Status;
659         r.out.hResource = hResource;
660
661         torture_assert_ntstatus_ok(tctx,
662                 dcerpc_clusapi_CreateResource_r(b, tctx, &r),
663                 "CreateResource failed");
664         torture_assert_werr_ok(tctx,
665                 *r.out.Status,
666                 "CreateResource failed");
667
668         test_CloseGroup_int(tctx, p, &hGroup);
669
670         return true;
671 }
672
673 static bool test_DeleteResource_int(struct torture_context *tctx,
674                                     struct dcerpc_pipe *p,
675                                     struct policy_handle *hResource)
676 {
677         struct dcerpc_binding_handle *b = p->binding_handle;
678         struct clusapi_DeleteResource r;
679         WERROR rpc_status;
680
681         r.in.hResource = *hResource;
682         r.out.rpc_status = &rpc_status;
683
684         torture_assert_ntstatus_ok(tctx,
685                 dcerpc_clusapi_DeleteResource_r(b, tctx, &r),
686                 "DeleteResource failed");
687         torture_assert_werr_ok(tctx,
688                 r.out.result,
689                 "DeleteResource failed");
690
691         return true;
692 }
693
694 static bool test_CreateResource(struct torture_context *tctx,
695                                 void *data)
696 {
697         struct torture_clusapi_context *t =
698                 talloc_get_type_abort(data, struct torture_clusapi_context);
699         struct policy_handle hResource;
700
701         if (!test_CreateResource_int(tctx, t->p, &hResource)) {
702                 return false;
703         }
704
705         test_DeleteResource_int(tctx, t->p, &hResource);
706
707         return true;
708 }
709
710 static bool test_DeleteResource(struct torture_context *tctx,
711                                 void *data)
712 {
713         struct torture_clusapi_context *t =
714                 talloc_get_type_abort(data, struct torture_clusapi_context);
715         struct policy_handle hResource;
716
717         if (!test_CreateResource_int(tctx, t->p, &hResource)) {
718                 return false;
719         }
720
721         return test_DeleteResource_int(tctx, t->p, &hResource);
722 }
723
724 static bool test_SetResourceName_int(struct torture_context *tctx,
725                                      struct dcerpc_pipe *p,
726                                      struct policy_handle *hResource)
727 {
728         struct dcerpc_binding_handle *b = p->binding_handle;
729         struct clusapi_SetResourceName r;
730         WERROR rpc_status;
731
732         r.in.hResource = *hResource;
733         r.in.lpszResourceName = "wurst";
734         r.out.rpc_status = &rpc_status;
735
736         torture_assert_ntstatus_ok(tctx,
737                 dcerpc_clusapi_SetResourceName_r(b, tctx, &r),
738                 "SetResourceName failed");
739         torture_assert_werr_ok(tctx,
740                 r.out.result,
741                 "SetResourceName failed");
742
743         return true;
744 }
745
746 static bool test_SetResourceName(struct torture_context *tctx,
747                                  void *data)
748 {
749         struct torture_clusapi_context *t =
750                 talloc_get_type_abort(data, struct torture_clusapi_context);
751         struct policy_handle hResource;
752         bool ret = true;
753
754         if (!test_CreateResource_int(tctx, t->p, &hResource)) {
755                 return false;
756         }
757
758         ret = test_SetResourceName_int(tctx, t->p, &hResource);
759
760         test_DeleteResource_int(tctx, t->p, &hResource);
761
762         return ret;
763 }
764
765 static bool test_GetResourceState_int(struct torture_context *tctx,
766                                       struct dcerpc_pipe *p,
767                                       struct policy_handle *hResource)
768 {
769         struct dcerpc_binding_handle *b = p->binding_handle;
770         struct clusapi_GetResourceState r;
771         enum clusapi_ClusterResourceState State;
772         const char *NodeName;
773         const char *GroupName;
774         WERROR rpc_status;
775
776         r.in.hResource = *hResource;
777         r.out.State = &State;
778         r.out.NodeName = &NodeName;
779         r.out.GroupName = &GroupName;
780         r.out.rpc_status = &rpc_status;
781
782         torture_assert_ntstatus_ok(tctx,
783                 dcerpc_clusapi_GetResourceState_r(b, tctx, &r),
784                 "GetResourceState failed");
785         torture_assert_werr_ok(tctx,
786                 r.out.result,
787                 "GetResourceState failed");
788
789         return true;
790 }
791
792 static bool test_GetResourceState(struct torture_context *tctx,
793                                   void *data)
794 {
795         struct torture_clusapi_context *t =
796                 talloc_get_type_abort(data, struct torture_clusapi_context);
797         struct policy_handle hResource;
798         bool ret = true;
799
800         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
801                 return false;
802         }
803
804         ret = test_GetResourceState_int(tctx, t->p, &hResource);
805
806         test_CloseResource_int(tctx, t->p, &hResource);
807
808         return ret;
809 }
810
811 static bool test_GetResourceId_int(struct torture_context *tctx,
812                                    struct dcerpc_pipe *p,
813                                    struct policy_handle *hResource)
814 {
815         struct dcerpc_binding_handle *b = p->binding_handle;
816         struct clusapi_GetResourceId r;
817         const char *pGuid;
818         WERROR rpc_status;
819
820         r.in.hResource = *hResource;
821         r.out.pGuid = &pGuid;
822         r.out.rpc_status = &rpc_status;
823
824         torture_assert_ntstatus_ok(tctx,
825                 dcerpc_clusapi_GetResourceId_r(b, tctx, &r),
826                 "GetResourceId failed");
827         torture_assert_werr_ok(tctx,
828                 r.out.result,
829                 "GetResourceId failed");
830
831         return true;
832 }
833
834 static bool test_GetResourceId(struct torture_context *tctx,
835                                void *data)
836 {
837         struct torture_clusapi_context *t =
838                 talloc_get_type_abort(data, struct torture_clusapi_context);
839         struct policy_handle hResource;
840         bool ret = true;
841
842         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
843                 return false;
844         }
845
846         ret = test_GetResourceId_int(tctx, t->p, &hResource);
847
848         test_CloseResource_int(tctx, t->p, &hResource);
849
850         return ret;
851 }
852
853 static bool test_GetResourceType_int(struct torture_context *tctx,
854                                      struct dcerpc_pipe *p,
855                                      struct policy_handle *hResource)
856 {
857         struct dcerpc_binding_handle *b = p->binding_handle;
858         struct clusapi_GetResourceType r;
859         const char *lpszResourceType;
860         WERROR rpc_status;
861
862         r.in.hResource = *hResource;
863         r.out.lpszResourceType = &lpszResourceType;
864         r.out.rpc_status = &rpc_status;
865
866         torture_assert_ntstatus_ok(tctx,
867                 dcerpc_clusapi_GetResourceType_r(b, tctx, &r),
868                 "GetResourceType failed");
869         torture_assert_werr_ok(tctx,
870                 r.out.result,
871                 "GetResourceType failed");
872
873         return true;
874 }
875
876 static bool test_GetResourceType(struct torture_context *tctx,
877                                  void *data)
878 {
879         struct torture_clusapi_context *t =
880                 talloc_get_type_abort(data, struct torture_clusapi_context);
881         struct policy_handle hResource;
882         bool ret = true;
883
884         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
885                 return false;
886         }
887
888         ret = test_GetResourceType_int(tctx, t->p, &hResource);
889
890         test_CloseResource_int(tctx, t->p, &hResource);
891
892         return ret;
893 }
894
895 static bool test_FailResource_int(struct torture_context *tctx,
896                                   struct dcerpc_pipe *p,
897                                   struct policy_handle *hResource)
898 {
899         struct dcerpc_binding_handle *b = p->binding_handle;
900         struct clusapi_FailResource r;
901         WERROR rpc_status;
902
903         r.in.hResource = *hResource;
904         r.out.rpc_status = &rpc_status;
905
906         torture_assert_ntstatus_ok(tctx,
907                 dcerpc_clusapi_FailResource_r(b, tctx, &r),
908                 "FailResource failed");
909         torture_assert_werr_ok(tctx,
910                 r.out.result,
911                 "FailResource failed");
912
913         return true;
914 }
915
916 static bool test_FailResource(struct torture_context *tctx,
917                               void *data)
918 {
919         struct torture_clusapi_context *t =
920                 talloc_get_type_abort(data, struct torture_clusapi_context);
921         struct policy_handle hResource;
922         bool ret = true;
923
924         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
925                 return false;
926         }
927
928         ret = test_FailResource_int(tctx, t->p, &hResource);
929
930         test_CloseResource_int(tctx, t->p, &hResource);
931
932         return ret;
933 }
934
935 bool test_OnlineResource_int(struct torture_context *tctx,
936                              struct dcerpc_pipe *p,
937                              struct policy_handle *hResource)
938 {
939         struct dcerpc_binding_handle *b = p->binding_handle;
940         struct clusapi_OnlineResource r;
941         WERROR rpc_status;
942
943         r.in.hResource = *hResource;
944         r.out.rpc_status = &rpc_status;
945
946         torture_assert_ntstatus_ok(tctx,
947                 dcerpc_clusapi_OnlineResource_r(b, tctx, &r),
948                 "OnlineResource failed");
949         torture_assert_werr_ok(tctx,
950                 r.out.result,
951                 "OnlineResource failed");
952
953         return true;
954 }
955
956 static bool test_OnlineResource(struct torture_context *tctx,
957                                 void *data)
958 {
959         struct torture_clusapi_context *t =
960                 talloc_get_type_abort(data, struct torture_clusapi_context);
961         struct policy_handle hResource;
962         bool ret = true;
963
964         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
965                 return false;
966         }
967
968         ret = test_OnlineResource_int(tctx, t->p, &hResource);
969
970         test_CloseResource_int(tctx, t->p, &hResource);
971
972         return ret;
973 }
974
975 bool test_OfflineResource_int(struct torture_context *tctx,
976                               struct dcerpc_pipe *p,
977                               struct policy_handle *hResource)
978 {
979         struct dcerpc_binding_handle *b = p->binding_handle;
980         struct clusapi_OfflineResource r;
981         WERROR rpc_status;
982
983         r.in.hResource = *hResource;
984         r.out.rpc_status = &rpc_status;
985
986         torture_assert_ntstatus_ok(tctx,
987                 dcerpc_clusapi_OfflineResource_r(b, tctx, &r),
988                 "OfflineResource failed");
989         torture_assert_werr_ok(tctx,
990                 r.out.result,
991                 "OfflineResource failed");
992
993         return true;
994 }
995
996 static bool test_OfflineResource(struct torture_context *tctx,
997                                  void *data)
998 {
999         struct torture_clusapi_context *t =
1000                 talloc_get_type_abort(data, struct torture_clusapi_context);
1001         struct policy_handle hResource;
1002         bool ret = true;
1003
1004         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1005                 return false;
1006         }
1007
1008         ret = test_OfflineResource_int(tctx, t->p, &hResource);
1009
1010         test_CloseResource_int(tctx, t->p, &hResource);
1011
1012         return ret;
1013 }
1014
1015 static bool test_CreateResEnum_int(struct torture_context *tctx,
1016                                    struct dcerpc_pipe *p,
1017                                    struct policy_handle *hResource)
1018 {
1019         struct dcerpc_binding_handle *b = p->binding_handle;
1020         struct clusapi_CreateResEnum r;
1021         uint32_t dwType = CLUSTER_ENUM_RESOURCE;
1022         struct ENUM_LIST *ReturnEnum;
1023         WERROR rpc_status;
1024
1025         r.in.hResource = *hResource;
1026         r.in.dwType = dwType;
1027         r.out.ReturnEnum = &ReturnEnum;
1028         r.out.rpc_status = &rpc_status;
1029
1030         torture_assert_ntstatus_ok(tctx,
1031                 dcerpc_clusapi_CreateResEnum_r(b, tctx, &r),
1032                 "CreateResEnum failed");
1033         torture_assert_werr_ok(tctx,
1034                 r.out.result,
1035                 "CreateResEnum failed");
1036
1037         return true;
1038 }
1039
1040 static bool test_CreateResEnum(struct torture_context *tctx,
1041                                void *data)
1042 {
1043         struct torture_clusapi_context *t =
1044                 talloc_get_type_abort(data, struct torture_clusapi_context);
1045         struct policy_handle hResource;
1046         bool ret = true;
1047
1048         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1049                 return false;
1050         }
1051
1052         ret = test_CreateResEnum_int(tctx, t->p, &hResource);
1053
1054         test_CloseResource_int(tctx, t->p, &hResource);
1055
1056         return ret;
1057 }
1058
1059 static bool test_GetResourceDependencyExpression_int(struct torture_context *tctx,
1060                                                      struct dcerpc_pipe *p,
1061                                                      struct policy_handle *hResource)
1062 {
1063         struct dcerpc_binding_handle *b = p->binding_handle;
1064         struct clusapi_GetResourceDependencyExpression r;
1065         const char *lpszDependencyExpression;
1066         WERROR rpc_status;
1067
1068         r.in.hResource = *hResource;
1069         r.out.lpszDependencyExpression = &lpszDependencyExpression;
1070         r.out.rpc_status = &rpc_status;
1071
1072         torture_assert_ntstatus_ok(tctx,
1073                 dcerpc_clusapi_GetResourceDependencyExpression_r(b, tctx, &r),
1074                 "GetResourceDependencyExpression failed");
1075         torture_assert_werr_ok(tctx,
1076                 r.out.result,
1077                 "GetResourceDependencyExpression failed");
1078
1079         return true;
1080 }
1081
1082 static bool test_GetResourceDependencyExpression(struct torture_context *tctx,
1083                                                  void *data)
1084 {
1085         struct torture_clusapi_context *t =
1086                 talloc_get_type_abort(data, struct torture_clusapi_context);
1087         struct policy_handle hResource;
1088         bool ret = true;
1089
1090         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1091                 return false;
1092         }
1093
1094         ret = test_GetResourceDependencyExpression_int(tctx, t->p, &hResource);
1095
1096         test_CloseResource_int(tctx, t->p, &hResource);
1097
1098         return ret;
1099 }
1100
1101 static bool test_GetResourceNetworkName_int(struct torture_context *tctx,
1102                                             struct dcerpc_pipe *p,
1103                                             struct policy_handle *hResource)
1104 {
1105         struct dcerpc_binding_handle *b = p->binding_handle;
1106         struct clusapi_GetResourceNetworkName r;
1107         const char *lpszName;
1108         WERROR rpc_status;
1109
1110         r.in.hResource = *hResource;
1111         r.out.lpszName = &lpszName;
1112         r.out.rpc_status = &rpc_status;
1113
1114         torture_assert_ntstatus_ok(tctx,
1115                 dcerpc_clusapi_GetResourceNetworkName_r(b, tctx, &r),
1116                 "GetResourceNetworkName failed");
1117         torture_assert_werr_ok(tctx,
1118                 r.out.result,
1119                 "GetResourceNetworkName failed");
1120
1121         return true;
1122 }
1123
1124 static bool test_GetResourceNetworkName(struct torture_context *tctx,
1125                                         void *data)
1126 {
1127         struct torture_clusapi_context *t =
1128                 talloc_get_type_abort(data, struct torture_clusapi_context);
1129         struct policy_handle hResource;
1130         bool ret = true;
1131
1132         if (!test_OpenResource_int(tctx, t->p, "Network Name", &hResource)) {
1133                 return false;
1134         }
1135
1136         ret = test_GetResourceNetworkName_int(tctx, t->p, &hResource);
1137
1138         test_CloseResource_int(tctx, t->p, &hResource);
1139
1140         return ret;
1141 }
1142
1143 static bool test_one_resource(struct torture_context *tctx,
1144                               struct dcerpc_pipe *p,
1145                               const char *resource_name)
1146 {
1147         struct policy_handle hResource;
1148
1149         torture_assert(tctx,
1150                 test_OpenResource_int(tctx, p, resource_name, &hResource),
1151                 "failed to open resource");
1152         test_CloseResource_int(tctx, p, &hResource);
1153
1154         torture_assert(tctx,
1155                 test_OpenResourceEx_int(tctx, p, resource_name, &hResource),
1156                 "failed to openex resource");
1157
1158         torture_assert(tctx,
1159                 test_GetResourceType_int(tctx, p, &hResource),
1160                 "failed to query resource type");
1161         torture_assert(tctx,
1162                 test_GetResourceId_int(tctx, p, &hResource),
1163                 "failed to query resource id");
1164         torture_assert(tctx,
1165                 test_GetResourceState_int(tctx, p, &hResource),
1166                 "failed to query resource state");
1167         torture_assert(tctx,
1168                 test_CreateResEnum_int(tctx, p, &hResource),
1169                 "failed to query resource enum");
1170         torture_assert(tctx,
1171                 test_GetResourceDependencyExpression_int(tctx, p, &hResource),
1172                 "failed to query resource dependency expression");
1173         torture_assert(tctx,
1174                 test_GetResourceNetworkName_int(tctx, p, &hResource),
1175                 "failed to query resource network name");
1176
1177         test_CloseResource_int(tctx, p, &hResource);
1178
1179         return true;
1180 }
1181
1182 static bool test_all_resources(struct torture_context *tctx,
1183                                void *data)
1184 {
1185         struct torture_clusapi_context *t =
1186                 talloc_get_type_abort(data, struct torture_clusapi_context);
1187         struct dcerpc_binding_handle *b = t->p->binding_handle;
1188         struct clusapi_CreateEnum r;
1189         uint32_t dwType = CLUSTER_ENUM_RESOURCE;
1190         struct ENUM_LIST *ReturnEnum;
1191         WERROR rpc_status;
1192         int i;
1193
1194         r.in.dwType = dwType;
1195         r.out.ReturnEnum = &ReturnEnum;
1196         r.out.rpc_status = &rpc_status;
1197
1198         torture_assert_ntstatus_ok(tctx,
1199                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1200                 "CreateEnum failed");
1201         torture_assert_werr_ok(tctx,
1202                 r.out.result,
1203                 "CreateEnum failed");
1204
1205         for (i=0; i < ReturnEnum->EntryCount; i++) {
1206
1207                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1208
1209                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_RESOURCE, "type mismatch");
1210
1211                 torture_assert(tctx,
1212                         test_one_resource(tctx, t->p, e.Name),
1213                         "failed to test one resource");
1214         }
1215
1216         return true;
1217 }
1218
1219 static bool test_OpenNode_int(struct torture_context *tctx,
1220                               struct dcerpc_pipe *p,
1221                               const char *lpszNodeName,
1222                               struct policy_handle *hNode)
1223 {
1224         struct dcerpc_binding_handle *b = p->binding_handle;
1225         struct clusapi_OpenNode r;
1226         WERROR Status;
1227         WERROR rpc_status;
1228
1229         r.in.lpszNodeName = lpszNodeName;
1230         r.out.rpc_status = &rpc_status;
1231         r.out.Status = &Status;
1232         r.out.hNode= hNode;
1233
1234         torture_assert_ntstatus_ok(tctx,
1235                 dcerpc_clusapi_OpenNode_r(b, tctx, &r),
1236                 "OpenNode failed");
1237         torture_assert_werr_ok(tctx,
1238                 *r.out.Status,
1239                 "OpenNode failed");
1240
1241         return true;
1242 }
1243
1244 static bool test_OpenNodeEx_int(struct torture_context *tctx,
1245                                 struct dcerpc_pipe *p,
1246                                 const char *lpszNodeName,
1247                                 struct policy_handle *hNode)
1248 {
1249         struct dcerpc_binding_handle *b = p->binding_handle;
1250         struct clusapi_OpenNodeEx r;
1251         uint32_t lpdwGrantedAccess;
1252         WERROR Status;
1253         WERROR rpc_status;
1254
1255         r.in.lpszNodeName = lpszNodeName;
1256         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
1257         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
1258         r.out.rpc_status = &rpc_status;
1259         r.out.Status = &Status;
1260         r.out.hNode= hNode;
1261
1262         torture_assert_ntstatus_ok(tctx,
1263                 dcerpc_clusapi_OpenNodeEx_r(b, tctx, &r),
1264                 "OpenNodeEx failed");
1265         torture_assert_werr_ok(tctx,
1266                 *r.out.Status,
1267                 "OpenNodeEx failed");
1268
1269         return true;
1270 }
1271
1272
1273 static bool test_CloseNode_int(struct torture_context *tctx,
1274                                struct dcerpc_pipe *p,
1275                                struct policy_handle *Node)
1276 {
1277         struct dcerpc_binding_handle *b = p->binding_handle;
1278         struct clusapi_CloseNode r;
1279
1280         r.in.Node = Node;
1281         r.out.Node = Node;
1282
1283         torture_assert_ntstatus_ok(tctx,
1284                 dcerpc_clusapi_CloseNode_r(b, tctx, &r),
1285                 "CloseNode failed");
1286         torture_assert_werr_ok(tctx,
1287                 r.out.result,
1288                 "CloseNode failed");
1289         torture_assert(tctx,
1290                 ndr_policy_handle_empty(Node),
1291                 "policy_handle non empty after CloseNode");
1292
1293         return true;
1294 }
1295
1296 static bool test_OpenNode(struct torture_context *tctx,
1297                           void *data)
1298 {
1299         struct torture_clusapi_context *t =
1300                 talloc_get_type_abort(data, struct torture_clusapi_context);
1301         struct policy_handle hNode;
1302
1303         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1304                 return false;
1305         }
1306
1307         test_CloseNode_int(tctx, t->p, &hNode);
1308
1309         return true;
1310 }
1311
1312 static bool test_OpenNodeEx(struct torture_context *tctx,
1313                             void *data)
1314 {
1315         struct torture_clusapi_context *t =
1316                 talloc_get_type_abort(data, struct torture_clusapi_context);
1317         struct policy_handle hNode;
1318
1319         if (!test_OpenNodeEx_int(tctx, t->p, t->NodeName, &hNode)) {
1320                 return false;
1321         }
1322
1323         test_CloseNode_int(tctx, t->p, &hNode);
1324
1325         return true;
1326 }
1327
1328 static bool test_CloseNode(struct torture_context *tctx,
1329                            void *data)
1330 {
1331         struct torture_clusapi_context *t =
1332                 talloc_get_type_abort(data, struct torture_clusapi_context);
1333         struct policy_handle hNode;
1334
1335         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1336                 return false;
1337         }
1338
1339         return test_CloseNode_int(tctx, t->p, &hNode);
1340 }
1341
1342 static bool test_GetNodeState_int(struct torture_context *tctx,
1343                                   struct dcerpc_pipe *p,
1344                                   struct policy_handle *hNode)
1345 {
1346         struct dcerpc_binding_handle *b = p->binding_handle;
1347         struct clusapi_GetNodeState r;
1348         enum clusapi_ClusterNodeState State;
1349         WERROR rpc_status;
1350
1351         r.in.hNode = *hNode;
1352         r.out.State = &State;
1353         r.out.rpc_status = &rpc_status;
1354
1355         torture_assert_ntstatus_ok(tctx,
1356                 dcerpc_clusapi_GetNodeState_r(b, tctx, &r),
1357                 "GetNodeState failed");
1358         torture_assert_werr_ok(tctx,
1359                 r.out.result,
1360                 "GetNodeState failed");
1361
1362         return true;
1363 }
1364
1365 static bool test_GetNodeState(struct torture_context *tctx,
1366                               void *data)
1367 {
1368         struct torture_clusapi_context *t =
1369                 talloc_get_type_abort(data, struct torture_clusapi_context);
1370         struct policy_handle hNode;
1371         bool ret = true;
1372
1373         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1374                 return false;
1375         }
1376
1377         ret = test_GetNodeState_int(tctx, t->p, &hNode);
1378
1379         test_CloseNode_int(tctx, t->p, &hNode);
1380
1381         return ret;
1382 }
1383
1384 static bool test_GetNodeId_int(struct torture_context *tctx,
1385                                struct dcerpc_pipe *p,
1386                                struct policy_handle *hNode)
1387 {
1388         struct dcerpc_binding_handle *b = p->binding_handle;
1389         struct clusapi_GetNodeId r;
1390         const char *pGuid;
1391         WERROR rpc_status;
1392
1393         r.in.hNode = *hNode;
1394         r.out.pGuid = &pGuid;
1395         r.out.rpc_status = &rpc_status;
1396
1397         torture_assert_ntstatus_ok(tctx,
1398                 dcerpc_clusapi_GetNodeId_r(b, tctx, &r),
1399                 "GetNodeId failed");
1400         torture_assert_werr_ok(tctx,
1401                 r.out.result,
1402                 "GetNodeId failed");
1403
1404         return true;
1405 }
1406
1407 static bool test_GetNodeId(struct torture_context *tctx,
1408                            void *data)
1409 {
1410         struct torture_clusapi_context *t =
1411                 talloc_get_type_abort(data, struct torture_clusapi_context);
1412         struct policy_handle hNode;
1413         bool ret = true;
1414
1415         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1416                 return false;
1417         }
1418
1419         ret = test_GetNodeId_int(tctx, t->p, &hNode);
1420
1421         test_CloseNode_int(tctx, t->p, &hNode);
1422
1423         return ret;
1424 }
1425
1426 static bool test_PauseNode_int(struct torture_context *tctx,
1427                                struct dcerpc_pipe *p,
1428                                struct policy_handle *hNode)
1429 {
1430         struct dcerpc_binding_handle *b = p->binding_handle;
1431         struct clusapi_PauseNode r;
1432         WERROR rpc_status;
1433
1434         r.in.hNode = *hNode;
1435         r.out.rpc_status = &rpc_status;
1436
1437         torture_assert_ntstatus_ok(tctx,
1438                 dcerpc_clusapi_PauseNode_r(b, tctx, &r),
1439                 "PauseNode failed");
1440         torture_assert_werr_ok(tctx,
1441                 r.out.result,
1442                 "PauseNode failed");
1443
1444         return true;
1445 }
1446
1447 static bool test_PauseNode(struct torture_context *tctx,
1448                            void *data)
1449 {
1450         struct torture_clusapi_context *t =
1451                 talloc_get_type_abort(data, struct torture_clusapi_context);
1452         struct policy_handle hNode;
1453         bool ret = true;
1454
1455         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1456                 return false;
1457         }
1458
1459         ret = test_PauseNode_int(tctx, t->p, &hNode);
1460
1461         test_CloseNode_int(tctx, t->p, &hNode);
1462
1463         return ret;
1464 }
1465
1466 static bool test_ResumeNode_int(struct torture_context *tctx,
1467                                 struct dcerpc_pipe *p,
1468                                 struct policy_handle *hNode)
1469 {
1470         struct dcerpc_binding_handle *b = p->binding_handle;
1471         struct clusapi_ResumeNode r;
1472         WERROR rpc_status;
1473
1474         r.in.hNode = *hNode;
1475         r.out.rpc_status = &rpc_status;
1476
1477         torture_assert_ntstatus_ok(tctx,
1478                 dcerpc_clusapi_ResumeNode_r(b, tctx, &r),
1479                 "ResumeNode failed");
1480         torture_assert_werr_equal(tctx,
1481                 r.out.result,
1482                 WERR_CLUSTER_NODE_NOT_PAUSED,
1483                 "ResumeNode gave unexpected result");
1484
1485         return true;
1486 }
1487
1488 static bool test_ResumeNode(struct torture_context *tctx,
1489                             void *data)
1490 {
1491         struct torture_clusapi_context *t =
1492                 talloc_get_type_abort(data, struct torture_clusapi_context);
1493         struct policy_handle hNode;
1494         bool ret = true;
1495
1496         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1497                 return false;
1498         }
1499
1500         ret = test_ResumeNode_int(tctx, t->p, &hNode);
1501
1502         test_CloseNode_int(tctx, t->p, &hNode);
1503
1504         return ret;
1505 }
1506
1507 static bool test_EvictNode_int(struct torture_context *tctx,
1508                                struct dcerpc_pipe *p,
1509                                struct policy_handle *hNode)
1510 {
1511         struct dcerpc_binding_handle *b = p->binding_handle;
1512         struct clusapi_EvictNode r;
1513         WERROR rpc_status;
1514
1515         r.in.hNode = *hNode;
1516         r.out.rpc_status = &rpc_status;
1517
1518         torture_assert_ntstatus_ok(tctx,
1519                 dcerpc_clusapi_EvictNode_r(b, tctx, &r),
1520                 "EvictNode failed");
1521         torture_assert_werr_ok(tctx,
1522                 r.out.result,
1523                 "EvictNode failed");
1524
1525         return true;
1526 }
1527
1528 static bool test_EvictNode(struct torture_context *tctx,
1529                            void *data)
1530 {
1531         struct torture_clusapi_context *t =
1532                 talloc_get_type_abort(data, struct torture_clusapi_context);
1533         struct policy_handle hNode;
1534         bool ret = true;
1535
1536         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1537                 return false;
1538         }
1539
1540         ret = test_EvictNode_int(tctx, t->p, &hNode);
1541
1542         test_CloseNode_int(tctx, t->p, &hNode);
1543
1544         return ret;
1545 }
1546
1547 static bool test_one_node(struct torture_context *tctx,
1548                           struct dcerpc_pipe *p,
1549                           const char *node_name)
1550 {
1551         struct policy_handle hNode;
1552
1553         torture_assert(tctx,
1554                 test_OpenNode_int(tctx, p, node_name, &hNode),
1555                 "failed to open node");
1556         test_CloseNode_int(tctx, p, &hNode);
1557
1558         torture_assert(tctx,
1559                 test_OpenNodeEx_int(tctx, p, node_name, &hNode),
1560                 "failed to openex node");
1561
1562         torture_assert(tctx,
1563                 test_GetNodeId_int(tctx, p, &hNode),
1564                 "failed to query node id");
1565         torture_assert(tctx,
1566                 test_GetNodeState_int(tctx, p, &hNode),
1567                 "failed to query node id");
1568
1569         test_CloseNode_int(tctx, p, &hNode);
1570
1571         return true;
1572 }
1573
1574 static bool test_all_nodes(struct torture_context *tctx,
1575                            void *data)
1576 {
1577         struct torture_clusapi_context *t =
1578                 talloc_get_type_abort(data, struct torture_clusapi_context);
1579         struct dcerpc_binding_handle *b = t->p->binding_handle;
1580         struct clusapi_CreateEnum r;
1581         uint32_t dwType = CLUSTER_ENUM_NODE;
1582         struct ENUM_LIST *ReturnEnum;
1583         WERROR rpc_status;
1584         int i;
1585
1586         r.in.dwType = dwType;
1587         r.out.ReturnEnum = &ReturnEnum;
1588         r.out.rpc_status = &rpc_status;
1589
1590         torture_assert_ntstatus_ok(tctx,
1591                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1592                 "CreateEnum failed");
1593         torture_assert_werr_ok(tctx,
1594                 r.out.result,
1595                 "CreateEnum failed");
1596
1597         for (i=0; i < ReturnEnum->EntryCount; i++) {
1598
1599                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1600
1601                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NODE, "type mismatch");
1602
1603                 torture_assert(tctx,
1604                         test_one_node(tctx, t->p, e.Name),
1605                         "failed to test one node");
1606         }
1607
1608         return true;
1609 }
1610
1611 static bool test_OpenGroup_int(struct torture_context *tctx,
1612                                struct dcerpc_pipe *p,
1613                                const char *lpszGroupName,
1614                                struct policy_handle *hGroup)
1615 {
1616         struct dcerpc_binding_handle *b = p->binding_handle;
1617         struct clusapi_OpenGroup r;
1618         WERROR Status;
1619         WERROR rpc_status;
1620
1621         r.in.lpszGroupName = lpszGroupName;
1622         r.out.rpc_status = &rpc_status;
1623         r.out.Status = &Status;
1624         r.out.hGroup= hGroup;
1625
1626         torture_assert_ntstatus_ok(tctx,
1627                 dcerpc_clusapi_OpenGroup_r(b, tctx, &r),
1628                 "OpenGroup failed");
1629         torture_assert_werr_ok(tctx,
1630                 *r.out.Status,
1631                 "OpenGroup failed");
1632
1633         return true;
1634 }
1635
1636 static bool test_OpenGroupEx_int(struct torture_context *tctx,
1637                                  struct dcerpc_pipe *p,
1638                                  const char *lpszGroupName,
1639                                  struct policy_handle *hGroup)
1640 {
1641         struct dcerpc_binding_handle *b = p->binding_handle;
1642         struct clusapi_OpenGroupEx r;
1643         uint32_t lpdwGrantedAccess;
1644         WERROR Status;
1645         WERROR rpc_status;
1646
1647         r.in.lpszGroupName = lpszGroupName;
1648         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
1649         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
1650         r.out.rpc_status = &rpc_status;
1651         r.out.Status = &Status;
1652         r.out.hGroup= hGroup;
1653
1654         torture_assert_ntstatus_ok(tctx,
1655                 dcerpc_clusapi_OpenGroupEx_r(b, tctx, &r),
1656                 "OpenGroupEx failed");
1657         torture_assert_werr_ok(tctx,
1658                 *r.out.Status,
1659                 "OpenGroupEx failed");
1660
1661         return true;
1662 }
1663
1664 static bool test_CloseGroup_int(struct torture_context *tctx,
1665                                 struct dcerpc_pipe *p,
1666                                 struct policy_handle *Group)
1667 {
1668         struct dcerpc_binding_handle *b = p->binding_handle;
1669         struct clusapi_CloseGroup r;
1670
1671         r.in.Group = Group;
1672         r.out.Group = Group;
1673
1674         torture_assert_ntstatus_ok(tctx,
1675                 dcerpc_clusapi_CloseGroup_r(b, tctx, &r),
1676                 "CloseGroup failed");
1677         torture_assert_werr_ok(tctx,
1678                 r.out.result,
1679                 "CloseGroup failed");
1680         torture_assert(tctx,
1681                 ndr_policy_handle_empty(Group),
1682                 "policy_handle non empty after CloseGroup");
1683
1684         return true;
1685 }
1686
1687 static bool test_OpenGroup(struct torture_context *tctx,
1688                            void *data)
1689 {
1690         struct torture_clusapi_context *t =
1691                 talloc_get_type_abort(data, struct torture_clusapi_context);
1692         struct policy_handle hGroup;
1693
1694         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
1695                 return false;
1696         }
1697
1698         test_CloseGroup_int(tctx, t->p, &hGroup);
1699
1700         return true;
1701 }
1702
1703 static bool test_OpenGroupEx(struct torture_context *tctx,
1704                              void *data)
1705 {
1706         struct torture_clusapi_context *t =
1707                 talloc_get_type_abort(data, struct torture_clusapi_context);
1708         struct policy_handle hGroup;
1709
1710         if (!test_OpenGroupEx_int(tctx, t->p, "Cluster Group", &hGroup)) {
1711                 return false;
1712         }
1713
1714         test_CloseGroup_int(tctx, t->p, &hGroup);
1715
1716         return true;
1717 }
1718
1719 static bool test_CloseGroup(struct torture_context *tctx,
1720                             void *data)
1721 {
1722         struct torture_clusapi_context *t =
1723                 talloc_get_type_abort(data, struct torture_clusapi_context);
1724         struct policy_handle hGroup;
1725
1726         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
1727                 return false;
1728         }
1729
1730         return test_CloseGroup_int(tctx, t->p, &hGroup);
1731 }
1732
1733 static bool test_GetGroupState_int(struct torture_context *tctx,
1734                                    struct dcerpc_pipe *p,
1735                                    struct policy_handle *hGroup)
1736 {
1737         struct dcerpc_binding_handle *b = p->binding_handle;
1738         struct clusapi_GetGroupState r;
1739         enum clusapi_ClusterGroupState State;
1740         const char *NodeName;
1741         WERROR rpc_status;
1742
1743         r.in.hGroup = *hGroup;
1744         r.out.State = &State;
1745         r.out.NodeName = &NodeName;
1746         r.out.rpc_status = &rpc_status;
1747
1748         torture_assert_ntstatus_ok(tctx,
1749                 dcerpc_clusapi_GetGroupState_r(b, tctx, &r),
1750                 "GetGroupState failed");
1751         torture_assert_werr_ok(tctx,
1752                 r.out.result,
1753                 "GetGroupState failed");
1754
1755         return true;
1756 }
1757
1758 static bool test_GetGroupState(struct torture_context *tctx,
1759                                void *data)
1760 {
1761         struct torture_clusapi_context *t =
1762                 talloc_get_type_abort(data, struct torture_clusapi_context);
1763         struct policy_handle hGroup;
1764         bool ret = true;
1765
1766         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
1767                 return false;
1768         }
1769
1770         ret = test_GetGroupState_int(tctx, t->p, &hGroup);
1771
1772         test_CloseGroup_int(tctx, t->p, &hGroup);
1773
1774         return ret;
1775 }
1776
1777 static bool test_GetGroupId_int(struct torture_context *tctx,
1778                                 struct dcerpc_pipe *p,
1779                                 struct policy_handle *hGroup)
1780 {
1781         struct dcerpc_binding_handle *b = p->binding_handle;
1782         struct clusapi_GetGroupId r;
1783         const char *pGuid;
1784         WERROR rpc_status;
1785
1786         r.in.hGroup = *hGroup;
1787         r.out.pGuid = &pGuid;
1788         r.out.rpc_status = &rpc_status;
1789
1790         torture_assert_ntstatus_ok(tctx,
1791                 dcerpc_clusapi_GetGroupId_r(b, tctx, &r),
1792                 "GetGroupId failed");
1793         torture_assert_werr_ok(tctx,
1794                 r.out.result,
1795                 "GetGroupId failed");
1796
1797         return true;
1798 }
1799
1800 static bool test_GetGroupId(struct torture_context *tctx,
1801                             void *data)
1802 {
1803         struct torture_clusapi_context *t =
1804                 talloc_get_type_abort(data, struct torture_clusapi_context);
1805         struct policy_handle hGroup;
1806         bool ret = true;
1807
1808         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
1809                 return false;
1810         }
1811
1812         ret = test_GetGroupId_int(tctx, t->p, &hGroup);
1813
1814         test_CloseGroup_int(tctx, t->p, &hGroup);
1815
1816         return ret;
1817 }
1818
1819 static bool test_OnlineGroup_int(struct torture_context *tctx,
1820                                  struct dcerpc_pipe *p,
1821                                  struct policy_handle *hGroup)
1822 {
1823         struct dcerpc_binding_handle *b = p->binding_handle;
1824         struct clusapi_OnlineGroup r;
1825         WERROR rpc_status;
1826
1827         r.in.hGroup = *hGroup;
1828         r.out.rpc_status = &rpc_status;
1829
1830         torture_assert_ntstatus_ok(tctx,
1831                 dcerpc_clusapi_OnlineGroup_r(b, tctx, &r),
1832                 "OnlineGroup failed");
1833         torture_assert_werr_ok(tctx,
1834                 r.out.result,
1835                 "OnlineGroup failed");
1836
1837         return true;
1838 }
1839
1840 static bool test_OnlineGroup(struct torture_context *tctx,
1841                              void *data)
1842 {
1843         struct torture_clusapi_context *t =
1844                 talloc_get_type_abort(data, struct torture_clusapi_context);
1845         struct policy_handle hGroup;
1846         bool ret = true;
1847
1848         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
1849                 return false;
1850         }
1851
1852         ret = test_OnlineGroup_int(tctx, t->p, &hGroup);
1853
1854         test_CloseGroup_int(tctx, t->p, &hGroup);
1855
1856         return ret;
1857 }
1858
1859 static bool test_OfflineGroup_int(struct torture_context *tctx,
1860                                   struct dcerpc_pipe *p,
1861                                   struct policy_handle *hGroup)
1862 {
1863         struct dcerpc_binding_handle *b = p->binding_handle;
1864         struct clusapi_OfflineGroup r;
1865         WERROR rpc_status;
1866
1867         r.in.hGroup = *hGroup;
1868         r.out.rpc_status = &rpc_status;
1869
1870         torture_assert_ntstatus_ok(tctx,
1871                 dcerpc_clusapi_OfflineGroup_r(b, tctx, &r),
1872                 "OfflineGroup failed");
1873         torture_assert_werr_ok(tctx,
1874                 r.out.result,
1875                 "OfflineGroup failed");
1876
1877         return true;
1878 }
1879
1880 static bool test_OfflineGroup(struct torture_context *tctx,
1881                               void *data)
1882 {
1883         struct torture_clusapi_context *t =
1884                 talloc_get_type_abort(data, struct torture_clusapi_context);
1885         struct policy_handle hGroup;
1886         bool ret = true;
1887
1888         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
1889                 return false;
1890         }
1891
1892         ret = test_OfflineGroup_int(tctx, t->p, &hGroup);
1893
1894         test_CloseGroup_int(tctx, t->p, &hGroup);
1895
1896         return ret;
1897 }
1898
1899 static bool test_one_group(struct torture_context *tctx,
1900                            struct dcerpc_pipe *p,
1901                            const char *node_name)
1902 {
1903         struct policy_handle hGroup;
1904
1905         torture_assert(tctx,
1906                 test_OpenGroup_int(tctx, p, node_name, &hGroup),
1907                 "failed to open group");
1908         test_CloseGroup_int(tctx, p, &hGroup);
1909
1910         torture_assert(tctx,
1911                 test_OpenGroupEx_int(tctx, p, node_name, &hGroup),
1912                 "failed to openex group");
1913
1914         torture_assert(tctx,
1915                 test_GetGroupId_int(tctx, p, &hGroup),
1916                 "failed to query group id");
1917         torture_assert(tctx,
1918                 test_GetGroupState_int(tctx, p, &hGroup),
1919                 "failed to query group id");
1920
1921         test_CloseGroup_int(tctx, p, &hGroup);
1922
1923         return true;
1924 }
1925
1926 static bool test_all_groups(struct torture_context *tctx,
1927                             void *data)
1928 {
1929         struct torture_clusapi_context *t =
1930                 talloc_get_type_abort(data, struct torture_clusapi_context);
1931         struct dcerpc_binding_handle *b = t->p->binding_handle;
1932         struct clusapi_CreateEnum r;
1933         uint32_t dwType = CLUSTER_ENUM_GROUP;
1934         struct ENUM_LIST *ReturnEnum;
1935         WERROR rpc_status;
1936         int i;
1937
1938         r.in.dwType = dwType;
1939         r.out.ReturnEnum = &ReturnEnum;
1940         r.out.rpc_status = &rpc_status;
1941
1942         torture_assert_ntstatus_ok(tctx,
1943                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1944                 "CreateEnum failed");
1945         torture_assert_werr_ok(tctx,
1946                 r.out.result,
1947                 "CreateEnum failed");
1948
1949         for (i=0; i < ReturnEnum->EntryCount; i++) {
1950
1951                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1952
1953                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_GROUP, "type mismatch");
1954
1955                 torture_assert(tctx,
1956                         test_one_group(tctx, t->p, e.Name),
1957                         "failed to test one group");
1958         }
1959
1960         return true;
1961 }
1962
1963 static bool test_BackupClusterDatabase(struct torture_context *tctx,
1964                                        void *data)
1965 {
1966         struct torture_clusapi_context *t =
1967                 talloc_get_type_abort(data, struct torture_clusapi_context);
1968         struct dcerpc_binding_handle *b = t->p->binding_handle;
1969         struct clusapi_BackupClusterDatabase r;
1970         WERROR rpc_status;
1971
1972         r.in.lpszPathName = "c:\\cluster_backup";
1973         r.out.rpc_status = &rpc_status;
1974
1975         torture_assert_ntstatus_ok(tctx,
1976                 dcerpc_clusapi_BackupClusterDatabase_r(b, tctx, &r),
1977                 "BackupClusterDatabase failed");
1978         torture_assert_werr_equal(tctx,
1979                 r.out.result,
1980                 WERR_CALL_NOT_IMPLEMENTED,
1981                 "BackupClusterDatabase failed");
1982
1983         return true;
1984 }
1985
1986 static bool test_SetServiceAccountPassword(struct torture_context *tctx,
1987                                            void *data)
1988 {
1989         struct torture_clusapi_context *t =
1990                 talloc_get_type_abort(data, struct torture_clusapi_context);
1991         struct dcerpc_binding_handle *b = t->p->binding_handle;
1992         struct clusapi_SetServiceAccountPassword r;
1993         uint32_t SizeReturned;
1994         uint32_t ExpectedBufferSize;
1995
1996         r.in.lpszNewPassword = "P@ssw0rd!";
1997         r.in.dwFlags = IDL_CLUSTER_SET_PASSWORD_IGNORE_DOWN_NODES;
1998         r.in.ReturnStatusBufferSize = 1024;
1999         r.out.ReturnStatusBufferPtr = NULL;
2000         r.out.SizeReturned = &SizeReturned;
2001         r.out.ExpectedBufferSize = &ExpectedBufferSize;
2002
2003         torture_assert_ntstatus_ok(tctx,
2004                 dcerpc_clusapi_SetServiceAccountPassword_r(b, tctx, &r),
2005                 "SetServiceAccountPassword failed");
2006         torture_assert_werr_equal(tctx,
2007                 r.out.result,
2008                 WERR_CALL_NOT_IMPLEMENTED,
2009                 "SetServiceAccountPassword failed");
2010
2011         return true;
2012 }
2013
2014 static bool test_ClusterControl_int(struct torture_context *tctx,
2015                                     struct dcerpc_pipe *p,
2016                                     struct policy_handle *Cluster)
2017 {
2018         struct dcerpc_binding_handle *b = p->binding_handle;
2019         struct clusapi_ClusterControl r;
2020         uint32_t lpBytesReturned;
2021         uint32_t lpcbRequired;
2022         WERROR rpc_status;
2023
2024         r.in.hCluster = *Cluster;
2025         r.in.dwControlCode = 0;
2026         r.in.lpInBuffer = NULL;
2027         r.in.nInBufferSize = 0;
2028         r.in.nOutBufferSize = 0;
2029         r.out.lpOutBuffer = NULL;
2030         r.out.lpBytesReturned = &lpBytesReturned;
2031         r.out.lpcbRequired = &lpcbRequired;
2032         r.out.rpc_status = &rpc_status;
2033
2034         torture_assert_ntstatus_ok(tctx,
2035                 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2036                 "ClusterControl failed");
2037         torture_assert_werr_equal(tctx,
2038                 r.out.result,
2039                 WERR_INVALID_FUNCTION,
2040                 "ClusterControl failed");
2041
2042         r.in.dwControlCode = CLUSCTL_CLUSTER_GET_RO_COMMON_PROPERTIES;
2043
2044         torture_assert_ntstatus_ok(tctx,
2045                 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2046                 "ClusterControl failed");
2047
2048         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
2049                 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
2050                 r.in.nOutBufferSize = *r.out.lpcbRequired;
2051                 torture_assert_ntstatus_ok(tctx,
2052                         dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2053                         "ClusterControl failed");
2054         }
2055         torture_assert_werr_ok(tctx,
2056                 r.out.result,
2057                 "ClusterControl failed");
2058
2059         /* now try what happens when we query with a buffer large enough to hold
2060          * the entire packet */
2061
2062         r.in.nOutBufferSize = 0x400;
2063         r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
2064
2065         torture_assert_ntstatus_ok(tctx,
2066                 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2067                 "ClusterControl failed");
2068         torture_assert_werr_ok(tctx,
2069                 r.out.result,
2070                 "ClusterControl failed");
2071         torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
2072                 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
2073
2074         return true;
2075 }
2076
2077 static bool test_ClusterControl(struct torture_context *tctx,
2078                                 void *data)
2079 {
2080         struct torture_clusapi_context *t =
2081                 talloc_get_type_abort(data, struct torture_clusapi_context);
2082         struct policy_handle Cluster;
2083         bool ret;
2084
2085         if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
2086                 return false;
2087         }
2088
2089         ret = test_ClusterControl_int(tctx, t->p, &Cluster);
2090
2091         test_CloseCluster_int(tctx, t->p, &Cluster);
2092
2093         return ret;
2094 }
2095
2096 static bool test_OpenNetwork_int(struct torture_context *tctx,
2097                                  struct dcerpc_pipe *p,
2098                                  const char *lpszNetworkName,
2099                                  struct policy_handle *hNetwork)
2100 {
2101         struct dcerpc_binding_handle *b = p->binding_handle;
2102         struct clusapi_OpenNetwork r;
2103         WERROR Status;
2104         WERROR rpc_status;
2105
2106         r.in.lpszNetworkName = lpszNetworkName;
2107         r.out.rpc_status = &rpc_status;
2108         r.out.Status = &Status;
2109         r.out.hNetwork = hNetwork ;
2110
2111         torture_assert_ntstatus_ok(tctx,
2112                 dcerpc_clusapi_OpenNetwork_r(b, tctx, &r),
2113                 "OpenNetwork failed");
2114         torture_assert_werr_ok(tctx,
2115                 *r.out.Status,
2116                 "OpenNetwork failed");
2117
2118         return true;
2119 }
2120
2121 static bool test_OpenNetworkEx_int(struct torture_context *tctx,
2122                                    struct dcerpc_pipe *p,
2123                                    const char *lpszNetworkName,
2124                                    struct policy_handle *hNetwork)
2125 {
2126         struct dcerpc_binding_handle *b = p->binding_handle;
2127         struct clusapi_OpenNetworkEx r;
2128         uint32_t lpdwGrantedAccess;
2129         WERROR Status;
2130         WERROR rpc_status;
2131
2132         r.in.lpszNetworkName = lpszNetworkName;
2133         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
2134         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
2135         r.out.rpc_status = &rpc_status;
2136         r.out.Status = &Status;
2137         r.out.hNetwork = hNetwork ;
2138
2139         torture_assert_ntstatus_ok(tctx,
2140                 dcerpc_clusapi_OpenNetworkEx_r(b, tctx, &r),
2141                 "OpenNetworkEx failed");
2142         torture_assert_werr_ok(tctx,
2143                 *r.out.Status,
2144                 "OpenNetworkEx failed");
2145
2146         return true;
2147 }
2148
2149 static bool test_CloseNetwork_int(struct torture_context *tctx,
2150                                   struct dcerpc_pipe *p,
2151                                   struct policy_handle *Network)
2152 {
2153         struct dcerpc_binding_handle *b = p->binding_handle;
2154         struct clusapi_CloseNetwork r;
2155
2156         r.in.Network = Network;
2157         r.out.Network = Network;
2158
2159         torture_assert_ntstatus_ok(tctx,
2160                 dcerpc_clusapi_CloseNetwork_r(b, tctx, &r),
2161                 "CloseNetwork failed");
2162         torture_assert_werr_ok(tctx,
2163                 r.out.result,
2164                 "CloseNetwork failed");
2165         torture_assert(tctx,
2166                 ndr_policy_handle_empty(Network),
2167                 "policy_handle non empty after CloseNetwork");
2168
2169         return true;
2170 }
2171
2172 static bool test_OpenNetwork(struct torture_context *tctx,
2173                              void *data)
2174 {
2175         struct torture_clusapi_context *t =
2176                 talloc_get_type_abort(data, struct torture_clusapi_context);
2177         struct policy_handle hNetwork;
2178
2179         if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2180                 return false;
2181         }
2182
2183         test_CloseNetwork_int(tctx, t->p, &hNetwork);
2184
2185         return true;
2186 }
2187
2188 static bool test_OpenNetworkEx(struct torture_context *tctx,
2189                                void *data)
2190 {
2191         struct torture_clusapi_context *t =
2192                 talloc_get_type_abort(data, struct torture_clusapi_context);
2193         struct policy_handle hNetwork;
2194
2195         if (!test_OpenNetworkEx_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2196                 return false;
2197         }
2198
2199         test_CloseNetwork_int(tctx, t->p, &hNetwork);
2200
2201         return true;
2202 }
2203
2204 static bool test_CloseNetwork(struct torture_context *tctx,
2205                               void *data)
2206 {
2207         struct torture_clusapi_context *t =
2208                 talloc_get_type_abort(data, struct torture_clusapi_context);
2209         struct policy_handle hNetwork;
2210
2211         if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2212                 return false;
2213         }
2214
2215         return test_CloseNetwork_int(tctx, t->p, &hNetwork);
2216 }
2217
2218 static bool test_GetNetworkState_int(struct torture_context *tctx,
2219                                      struct dcerpc_pipe *p,
2220                                      struct policy_handle *hNetwork)
2221 {
2222         struct dcerpc_binding_handle *b = p->binding_handle;
2223         struct clusapi_GetNetworkState r;
2224         enum clusapi_ClusterNetworkState State;
2225         WERROR rpc_status;
2226
2227         r.in.hNetwork = *hNetwork;
2228         r.out.State = &State;
2229         r.out.rpc_status = &rpc_status;
2230
2231         torture_assert_ntstatus_ok(tctx,
2232                 dcerpc_clusapi_GetNetworkState_r(b, tctx, &r),
2233                 "GetNetworkState failed");
2234         torture_assert_werr_ok(tctx,
2235                 r.out.result,
2236                 "GetNetworkState failed");
2237
2238         return true;
2239 }
2240
2241 static bool test_GetNetworkState(struct torture_context *tctx,
2242                                  void *data)
2243 {
2244         struct torture_clusapi_context *t =
2245                 talloc_get_type_abort(data, struct torture_clusapi_context);
2246         struct policy_handle hNetwork;
2247         bool ret = true;
2248
2249         if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2250                 return false;
2251         }
2252
2253         ret = test_GetNetworkState_int(tctx, t->p, &hNetwork);
2254
2255         test_CloseNetwork_int(tctx, t->p, &hNetwork);
2256
2257         return ret;
2258 }
2259
2260 static bool test_GetNetworkId_int(struct torture_context *tctx,
2261                                   struct dcerpc_pipe *p,
2262                                   struct policy_handle *hNetwork)
2263 {
2264         struct dcerpc_binding_handle *b = p->binding_handle;
2265         struct clusapi_GetNetworkId r;
2266         const char *pGuid;
2267         WERROR rpc_status;
2268
2269         r.in.hNetwork = *hNetwork;
2270         r.out.pGuid = &pGuid;
2271         r.out.rpc_status = &rpc_status;
2272
2273         torture_assert_ntstatus_ok(tctx,
2274                 dcerpc_clusapi_GetNetworkId_r(b, tctx, &r),
2275                 "GetNetworkId failed");
2276         torture_assert_werr_ok(tctx,
2277                 r.out.result,
2278                 "GetNetworkId failed");
2279
2280         return true;
2281 }
2282
2283 static bool test_GetNetworkId(struct torture_context *tctx,
2284                               void *data)
2285 {
2286         struct torture_clusapi_context *t =
2287                 talloc_get_type_abort(data, struct torture_clusapi_context);
2288         struct policy_handle hNetwork;
2289         bool ret = true;
2290
2291         if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2292                 return false;
2293         }
2294
2295         ret = test_GetNetworkId_int(tctx, t->p, &hNetwork);
2296
2297         test_CloseNetwork_int(tctx, t->p, &hNetwork);
2298
2299         return ret;
2300 }
2301
2302 static bool test_one_network(struct torture_context *tctx,
2303                              struct dcerpc_pipe *p,
2304                              const char *network_name)
2305 {
2306         struct policy_handle hNetwork;
2307
2308         torture_assert(tctx,
2309                 test_OpenNetwork_int(tctx, p, network_name, &hNetwork),
2310                 "failed to open network");
2311         test_CloseNetwork_int(tctx, p, &hNetwork);
2312
2313         torture_assert(tctx,
2314                 test_OpenNetworkEx_int(tctx, p, network_name, &hNetwork),
2315                 "failed to openex network");
2316
2317         torture_assert(tctx,
2318                 test_GetNetworkId_int(tctx, p, &hNetwork),
2319                 "failed to query network id");
2320         torture_assert(tctx,
2321                 test_GetNetworkState_int(tctx, p, &hNetwork),
2322                 "failed to query network id");
2323
2324         test_CloseNetwork_int(tctx, p, &hNetwork);
2325
2326         return true;
2327 }
2328
2329 static bool test_all_networks(struct torture_context *tctx,
2330                               void *data)
2331 {
2332         struct torture_clusapi_context *t =
2333                 talloc_get_type_abort(data, struct torture_clusapi_context);
2334         struct dcerpc_binding_handle *b = t->p->binding_handle;
2335         struct clusapi_CreateEnum r;
2336         uint32_t dwType = CLUSTER_ENUM_NETWORK;
2337         struct ENUM_LIST *ReturnEnum;
2338         WERROR rpc_status;
2339         int i;
2340
2341         r.in.dwType = dwType;
2342         r.out.ReturnEnum = &ReturnEnum;
2343         r.out.rpc_status = &rpc_status;
2344
2345         torture_assert_ntstatus_ok(tctx,
2346                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
2347                 "CreateEnum failed");
2348         torture_assert_werr_ok(tctx,
2349                 r.out.result,
2350                 "CreateEnum failed");
2351
2352         for (i=0; i < ReturnEnum->EntryCount; i++) {
2353
2354                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
2355
2356                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NETWORK, "type mismatch");
2357
2358                 torture_assert(tctx,
2359                         test_one_network(tctx, t->p, e.Name),
2360                         "failed to test one network");
2361         }
2362
2363         return true;
2364 }
2365
2366 static bool test_OpenNetInterface_int(struct torture_context *tctx,
2367                                       struct dcerpc_pipe *p,
2368                                       const char *lpszNetInterfaceName,
2369                                       struct policy_handle *hNetInterface)
2370 {
2371         struct dcerpc_binding_handle *b = p->binding_handle;
2372         struct clusapi_OpenNetInterface r;
2373         WERROR Status;
2374         WERROR rpc_status;
2375
2376         r.in.lpszNetInterfaceName = lpszNetInterfaceName;
2377         r.out.rpc_status = &rpc_status;
2378         r.out.Status = &Status;
2379         r.out.hNetInterface = hNetInterface;
2380
2381         torture_assert_ntstatus_ok(tctx,
2382                 dcerpc_clusapi_OpenNetInterface_r(b, tctx, &r),
2383                 "OpenNetInterface failed");
2384         torture_assert_werr_ok(tctx,
2385                 *r.out.Status,
2386                 "OpenNetInterface failed");
2387
2388         return true;
2389 }
2390
2391 static bool test_OpenNetInterfaceEx_int(struct torture_context *tctx,
2392                                         struct dcerpc_pipe *p,
2393                                         const char *lpszNetInterfaceName,
2394                                         struct policy_handle *hNetInterface)
2395 {
2396         struct dcerpc_binding_handle *b = p->binding_handle;
2397         struct clusapi_OpenNetInterfaceEx r;
2398         uint32_t lpdwGrantedAccess;
2399         WERROR Status;
2400         WERROR rpc_status;
2401
2402         r.in.lpszNetInterfaceName = lpszNetInterfaceName;
2403         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
2404         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
2405         r.out.rpc_status = &rpc_status;
2406         r.out.Status = &Status;
2407         r.out.hNetInterface = hNetInterface;
2408
2409         torture_assert_ntstatus_ok(tctx,
2410                 dcerpc_clusapi_OpenNetInterfaceEx_r(b, tctx, &r),
2411                 "OpenNetInterfaceEx failed");
2412         torture_assert_werr_ok(tctx,
2413                 *r.out.Status,
2414                 "OpenNetInterfaceEx failed");
2415
2416         return true;
2417 }
2418
2419 static bool test_CloseNetInterface_int(struct torture_context *tctx,
2420                                        struct dcerpc_pipe *p,
2421                                        struct policy_handle *NetInterface)
2422 {
2423         struct dcerpc_binding_handle *b = p->binding_handle;
2424         struct clusapi_CloseNetInterface r;
2425
2426         r.in.NetInterface = NetInterface;
2427         r.out.NetInterface = NetInterface;
2428
2429         torture_assert_ntstatus_ok(tctx,
2430                 dcerpc_clusapi_CloseNetInterface_r(b, tctx, &r),
2431                 "CloseNetInterface failed");
2432         torture_assert_werr_ok(tctx,
2433                 r.out.result,
2434                 "CloseNetInterface failed");
2435         torture_assert(tctx,
2436                 ndr_policy_handle_empty(NetInterface),
2437                 "policy_handle non empty after CloseNetInterface");
2438
2439         return true;
2440 }
2441
2442 static bool test_OpenNetInterface(struct torture_context *tctx,
2443                                   void *data)
2444 {
2445         struct torture_clusapi_context *t =
2446                 talloc_get_type_abort(data, struct torture_clusapi_context);
2447         struct policy_handle hNetInterface;
2448
2449         if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2450                 return false;
2451         }
2452
2453         test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2454
2455         return true;
2456 }
2457
2458 static bool test_OpenNetInterfaceEx(struct torture_context *tctx,
2459                                     void *data)
2460 {
2461         struct torture_clusapi_context *t =
2462                 talloc_get_type_abort(data, struct torture_clusapi_context);
2463         struct policy_handle hNetInterface;
2464
2465         if (!test_OpenNetInterfaceEx_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2466                 return false;
2467         }
2468
2469         test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2470
2471         return true;
2472 }
2473
2474 static bool test_CloseNetInterface(struct torture_context *tctx,
2475                                    void *data)
2476 {
2477         struct torture_clusapi_context *t =
2478                 talloc_get_type_abort(data, struct torture_clusapi_context);
2479         struct policy_handle hNetInterface;
2480
2481         if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2482                 return false;
2483         }
2484
2485         return test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2486 }
2487
2488 static bool test_GetNetInterfaceState_int(struct torture_context *tctx,
2489                                           struct dcerpc_pipe *p,
2490                                           struct policy_handle *hNetInterface)
2491 {
2492         struct dcerpc_binding_handle *b = p->binding_handle;
2493         struct clusapi_GetNetInterfaceState r;
2494         enum clusapi_ClusterNetInterfaceState State;
2495         WERROR rpc_status;
2496
2497         r.in.hNetInterface = *hNetInterface;
2498         r.out.State = &State;
2499         r.out.rpc_status = &rpc_status;
2500
2501         torture_assert_ntstatus_ok(tctx,
2502                 dcerpc_clusapi_GetNetInterfaceState_r(b, tctx, &r),
2503                 "GetNetInterfaceState failed");
2504         torture_assert_werr_ok(tctx,
2505                 r.out.result,
2506                 "GetNetInterfaceState failed");
2507
2508         return true;
2509 }
2510
2511 static bool test_GetNetInterfaceState(struct torture_context *tctx,
2512                                       void *data)
2513 {
2514         struct torture_clusapi_context *t =
2515                 talloc_get_type_abort(data, struct torture_clusapi_context);
2516         struct policy_handle hNetInterface;
2517         bool ret = true;
2518
2519         if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2520                 return false;
2521         }
2522
2523         ret = test_GetNetInterfaceState_int(tctx, t->p, &hNetInterface);
2524
2525         test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2526
2527         return ret;
2528 }
2529
2530 static bool test_GetNetInterfaceId_int(struct torture_context *tctx,
2531                                        struct dcerpc_pipe *p,
2532                                        struct policy_handle *hNetInterface)
2533 {
2534         struct dcerpc_binding_handle *b = p->binding_handle;
2535         struct clusapi_GetNetInterfaceId r;
2536         const char *pGuid;
2537         WERROR rpc_status;
2538
2539         r.in.hNetInterface = *hNetInterface;
2540         r.out.pGuid = &pGuid;
2541         r.out.rpc_status = &rpc_status;
2542
2543         torture_assert_ntstatus_ok(tctx,
2544                 dcerpc_clusapi_GetNetInterfaceId_r(b, tctx, &r),
2545                 "GetNetInterfaceId failed");
2546         torture_assert_werr_ok(tctx,
2547                 r.out.result,
2548                 "GetNetInterfaceId failed");
2549
2550         return true;
2551 }
2552
2553 static bool test_GetNetInterfaceId(struct torture_context *tctx,
2554                                    void *data)
2555 {
2556         struct torture_clusapi_context *t =
2557                 talloc_get_type_abort(data, struct torture_clusapi_context);
2558         struct policy_handle hNetInterface;
2559         bool ret = true;
2560
2561         if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2562                 return false;
2563         }
2564
2565         ret = test_GetNetInterfaceId_int(tctx, t->p, &hNetInterface);
2566
2567         test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2568
2569         return ret;
2570 }
2571
2572 static bool test_one_netinterface(struct torture_context *tctx,
2573                                   struct dcerpc_pipe *p,
2574                                   const char *netinterface_name)
2575 {
2576         struct policy_handle hNetInterface;
2577
2578         torture_assert(tctx,
2579                 test_OpenNetInterface_int(tctx, p, netinterface_name, &hNetInterface),
2580                 "failed to open netinterface");
2581         test_CloseNetInterface_int(tctx, p, &hNetInterface);
2582
2583         torture_assert(tctx,
2584                 test_OpenNetInterfaceEx_int(tctx, p, netinterface_name, &hNetInterface),
2585                 "failed to openex netinterface");
2586
2587         torture_assert(tctx,
2588                 test_GetNetInterfaceId_int(tctx, p, &hNetInterface),
2589                 "failed to query netinterface id");
2590         torture_assert(tctx,
2591                 test_GetNetInterfaceState_int(tctx, p, &hNetInterface),
2592                 "failed to query netinterface id");
2593
2594         test_CloseNetInterface_int(tctx, p, &hNetInterface);
2595
2596         return true;
2597 }
2598
2599 static bool test_all_netinterfaces(struct torture_context *tctx,
2600                                    void *data)
2601 {
2602         struct torture_clusapi_context *t =
2603                 talloc_get_type_abort(data, struct torture_clusapi_context);
2604         struct dcerpc_binding_handle *b = t->p->binding_handle;
2605         struct clusapi_CreateEnum r;
2606         uint32_t dwType = CLUSTER_ENUM_NETINTERFACE;
2607         struct ENUM_LIST *ReturnEnum;
2608         WERROR rpc_status;
2609         int i;
2610
2611         r.in.dwType = dwType;
2612         r.out.ReturnEnum = &ReturnEnum;
2613         r.out.rpc_status = &rpc_status;
2614
2615         torture_assert_ntstatus_ok(tctx,
2616                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
2617                 "CreateEnum failed");
2618         torture_assert_werr_ok(tctx,
2619                 r.out.result,
2620                 "CreateEnum failed");
2621
2622         for (i=0; i < ReturnEnum->EntryCount; i++) {
2623
2624                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
2625
2626                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NETINTERFACE, "type mismatch");
2627
2628                 torture_assert(tctx,
2629                         test_one_netinterface(tctx, t->p, e.Name),
2630                         "failed to test one netinterface");
2631         }
2632
2633         return true;
2634 }
2635
2636 static bool test_CloseKey_int(struct torture_context *tctx,
2637                               struct dcerpc_pipe *p,
2638                               struct policy_handle *pKey)
2639 {
2640         struct dcerpc_binding_handle *b = p->binding_handle;
2641         struct clusapi_CloseKey r;
2642
2643         r.in.pKey = pKey;
2644         r.out.pKey = pKey;
2645
2646         torture_assert_ntstatus_ok(tctx,
2647                 dcerpc_clusapi_CloseKey_r(b, tctx, &r),
2648                 "CloseKey failed");
2649         torture_assert_werr_ok(tctx,
2650                 r.out.result,
2651                 "CloseKey failed");
2652         torture_assert(tctx,
2653                 ndr_policy_handle_empty(pKey),
2654                 "policy_handle non empty after CloseKey");
2655
2656         return true;
2657 }
2658
2659 static bool test_GetRootKey_int(struct torture_context *tctx,
2660                                 struct dcerpc_pipe *p,
2661                                 struct policy_handle *phKey)
2662 {
2663         struct dcerpc_binding_handle *b = p->binding_handle;
2664         struct clusapi_GetRootKey r;
2665         WERROR Status;
2666         WERROR rpc_status;
2667
2668         r.in.samDesired = SEC_FLAG_MAXIMUM_ALLOWED;
2669         r.out.Status = &Status;
2670         r.out.rpc_status = &rpc_status;
2671         r.out.phKey = phKey;
2672
2673         torture_assert_ntstatus_ok(tctx,
2674                 dcerpc_clusapi_GetRootKey_r(b, tctx, &r),
2675                 "GetRootKey failed");
2676         torture_assert_werr_ok(tctx,
2677                 *r.out.Status,
2678                 "GetRootKey failed");
2679
2680         return true;
2681 }
2682
2683 static bool test_EnumKey_int(struct torture_context *tctx,
2684                              struct dcerpc_pipe *p,
2685                              struct policy_handle *hKey)
2686 {
2687         struct dcerpc_binding_handle *b = p->binding_handle;
2688         struct clusapi_EnumKey r;
2689         const char *KeyName;
2690         NTTIME lpftLastWriteTime;
2691         WERROR rpc_status;
2692
2693         r.in.hKey = *hKey;
2694         r.in.dwIndex = 0;
2695         r.out.KeyName = &KeyName;
2696         r.out.lpftLastWriteTime = &lpftLastWriteTime;
2697         r.out.rpc_status = &rpc_status;
2698
2699         torture_assert_ntstatus_ok(tctx,
2700                 dcerpc_clusapi_EnumKey_r(b, tctx, &r),
2701                 "EnumKey failed");
2702         torture_assert_werr_ok(tctx,
2703                 r.out.result,
2704                 "EnumKey failed");
2705
2706         return true;
2707 }
2708
2709 static bool test_OpenKey_int(struct torture_context *tctx,
2710                              struct dcerpc_pipe *p,
2711                              struct policy_handle *hKey,
2712                              const char *lpSubKey,
2713                              struct policy_handle *phKey)
2714 {
2715         struct dcerpc_binding_handle *b = p->binding_handle;
2716         struct clusapi_OpenKey r;
2717         WERROR Status;
2718         WERROR rpc_status;
2719
2720         r.in.hKey = *hKey;
2721         r.in.lpSubKey = lpSubKey;
2722         r.in.samDesired = SEC_FLAG_MAXIMUM_ALLOWED;
2723         r.out.Status = &Status;
2724         r.out.rpc_status = &rpc_status;
2725         r.out.phKey = phKey;
2726
2727         torture_assert_ntstatus_ok(tctx,
2728                 dcerpc_clusapi_OpenKey_r(b, tctx, &r),
2729                 "OpenKey failed");
2730         torture_assert_werr_ok(tctx,
2731                 *r.out.Status,
2732                 "OpenKey failed");
2733
2734         return true;
2735 }
2736
2737 static bool test_EnumValue_int(struct torture_context *tctx,
2738                                struct dcerpc_pipe *p,
2739                                struct policy_handle *hKey)
2740 {
2741         struct dcerpc_binding_handle *b = p->binding_handle;
2742         struct clusapi_EnumValue r;
2743         const char *lpValueName;
2744         uint32_t lpType;
2745         uint32_t TotalSize;
2746         WERROR rpc_status;
2747         int i = 0;
2748
2749         do {
2750                 uint32_t lpcbData = 1024;
2751
2752                 r.in.hKey = *hKey;
2753                 r.in.dwIndex = i++;
2754                 r.in.lpcbData = &lpcbData;
2755                 r.out.lpValueName = &lpValueName;
2756                 r.out.lpType = &lpType;
2757                 r.out.lpData = talloc_array(tctx, uint8_t, lpcbData);
2758                 r.out.TotalSize = &TotalSize;
2759                 r.out.rpc_status = &rpc_status;
2760                 r.out.lpcbData = &lpcbData;
2761
2762                 torture_assert_ntstatus_ok(tctx,
2763                         dcerpc_clusapi_EnumValue_r(b, tctx, &r),
2764                         "EnumValue failed");
2765
2766         } while (W_ERROR_IS_OK(r.out.result));
2767
2768         torture_assert_werr_equal(tctx,
2769                 r.out.result,
2770                 WERR_NO_MORE_ITEMS,
2771                 "EnumValue failed");
2772
2773         return true;
2774 }
2775
2776 static bool test_QueryInfoKey_int(struct torture_context *tctx,
2777                                   struct dcerpc_pipe *p,
2778                                   struct policy_handle *hKey)
2779 {
2780         struct dcerpc_binding_handle *b = p->binding_handle;
2781         struct clusapi_QueryInfoKey r;
2782         uint32_t lpcSubKeys;
2783         uint32_t lpcbMaxSubKeyLen;
2784         uint32_t lpcValues;
2785         uint32_t lpcbMaxValueNameLen;
2786         uint32_t lpcbMaxValueLen;
2787         uint32_t lpcbSecurityDescriptor;
2788         NTTIME lpftLastWriteTime;
2789         WERROR rpc_status;
2790
2791         r.in.hKey = *hKey;
2792         r.out.lpcSubKeys = &lpcSubKeys;
2793         r.out.lpcbMaxSubKeyLen = &lpcbMaxSubKeyLen;
2794         r.out.lpcValues = &lpcValues;
2795         r.out.lpcbMaxValueNameLen = &lpcbMaxValueNameLen;
2796         r.out.lpcbMaxValueLen = &lpcbMaxValueLen;
2797         r.out.lpcbSecurityDescriptor = &lpcbSecurityDescriptor;
2798         r.out.lpftLastWriteTime = &lpftLastWriteTime;
2799         r.out.rpc_status = &rpc_status;
2800
2801         torture_assert_ntstatus_ok(tctx,
2802                 dcerpc_clusapi_QueryInfoKey_r(b, tctx, &r),
2803                 "QueryInfoKey failed");
2804         torture_assert_werr_ok(tctx,
2805                 r.out.result,
2806                 "QueryInfoKey failed");
2807
2808         return true;
2809 }
2810
2811 static bool test_GetKeySecurity_int(struct torture_context *tctx,
2812                                     struct dcerpc_pipe *p,
2813                                     struct policy_handle *hKey)
2814 {
2815         struct dcerpc_binding_handle *b = p->binding_handle;
2816         struct clusapi_GetKeySecurity r;
2817         uint32_t SecurityInformation = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
2818         struct RPC_SECURITY_DESCRIPTOR pRpcSecurityDescriptor;
2819         WERROR rpc_status;
2820
2821         ZERO_STRUCT(pRpcSecurityDescriptor);
2822
2823         r.in.hKey = *hKey;
2824         r.in.SecurityInformation = SecurityInformation;
2825         r.in.pRpcSecurityDescriptor = &pRpcSecurityDescriptor;
2826         r.out.rpc_status = &rpc_status;
2827         r.out.pRpcSecurityDescriptor = &pRpcSecurityDescriptor;
2828
2829         torture_assert_ntstatus_ok(tctx,
2830                 dcerpc_clusapi_GetKeySecurity_r(b, tctx, &r),
2831                 "GetKeySecurity failed");
2832
2833         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2834                 pRpcSecurityDescriptor.lpSecurityDescriptor = talloc_array(tctx,
2835                 uint8_t, pRpcSecurityDescriptor.cbInSecurityDescriptor);
2836
2837                 torture_assert_ntstatus_ok(tctx,
2838                         dcerpc_clusapi_GetKeySecurity_r(b, tctx, &r),
2839                         "GetKeySecurity failed");
2840         }
2841
2842         torture_assert_werr_ok(tctx,
2843                 r.out.result,
2844                 "GetKeySecurity failed");
2845
2846         return true;
2847 }
2848
2849 static bool test_GetRootKey(struct torture_context *tctx,
2850                             void *data)
2851 {
2852         struct torture_clusapi_context *t =
2853                 talloc_get_type_abort(data, struct torture_clusapi_context);
2854         struct policy_handle hKey;
2855
2856         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
2857                 return false;
2858         }
2859
2860         test_CloseKey_int(tctx, t->p, &hKey);
2861
2862         return true;
2863 }
2864
2865 static bool test_CloseKey(struct torture_context *tctx,
2866                           void *data)
2867 {
2868         struct torture_clusapi_context *t =
2869                 talloc_get_type_abort(data, struct torture_clusapi_context);
2870         struct policy_handle hKey;
2871
2872         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
2873                 return false;
2874         }
2875
2876         return test_CloseKey_int(tctx, t->p, &hKey);
2877 }
2878
2879 static bool test_EnumKey(struct torture_context *tctx,
2880                          void *data)
2881 {
2882         struct torture_clusapi_context *t =
2883                 talloc_get_type_abort(data, struct torture_clusapi_context);
2884         struct policy_handle hKey;
2885         bool ret = true;
2886
2887         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
2888                 return false;
2889         }
2890
2891         ret = test_EnumKey_int(tctx, t->p, &hKey);
2892
2893         test_CloseKey_int(tctx, t->p, &hKey);
2894
2895         return ret;
2896 }
2897
2898 static bool test_QueryValue_int(struct torture_context *tctx,
2899                                 struct dcerpc_pipe *p,
2900                                 struct policy_handle *hKey,
2901                                 const char *ValueName)
2902 {
2903         struct dcerpc_binding_handle *b = p->binding_handle;
2904         struct clusapi_QueryValue r;
2905         uint32_t lpValueType;
2906         uint32_t lpcbRequired;
2907         WERROR rpc_status;
2908
2909         r.in.hKey = *hKey;
2910         r.in.lpValueName = ValueName;
2911         r.in.cbData = 0;
2912         r.out.lpValueType = &lpValueType;
2913         r.out.lpData = NULL;
2914         r.out.lpcbRequired = &lpcbRequired;
2915         r.out.rpc_status = &rpc_status;
2916
2917         torture_assert_ntstatus_ok(tctx,
2918                 dcerpc_clusapi_QueryValue_r(b, tctx, &r),
2919                 "QueryValue failed");
2920
2921         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
2922
2923                 r.in.cbData = lpcbRequired;
2924                 r.out.lpData = talloc_zero_array(tctx, uint8_t, r.in.cbData);
2925
2926                 torture_assert_ntstatus_ok(tctx,
2927                         dcerpc_clusapi_QueryValue_r(b, tctx, &r),
2928                         "QueryValue failed");
2929         }
2930
2931         torture_assert_werr_ok(tctx,
2932                 r.out.result,
2933                 "QueryValue failed");
2934
2935         if (lpValueType == REG_SZ) {
2936                 const char *s;
2937                 DATA_BLOB blob = data_blob_const(r.out.lpData, lpcbRequired);
2938                 pull_reg_sz(tctx, &blob, &s);
2939                 torture_comment(tctx, "got: %s\n", s);
2940         }
2941
2942         return true;
2943 }
2944
2945 static bool test_QueryValue(struct torture_context *tctx,
2946                             void *data)
2947 {
2948         struct torture_clusapi_context *t =
2949                 talloc_get_type_abort(data, struct torture_clusapi_context);
2950         struct policy_handle hKey;
2951         bool ret = true;
2952
2953         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
2954                 return false;
2955         }
2956
2957         ret = test_QueryValue_int(tctx, t->p, &hKey, "ClusterInstanceID");
2958
2959         test_CloseKey_int(tctx, t->p, &hKey);
2960
2961         return ret;
2962 }
2963
2964
2965 static bool test_one_key(struct torture_context *tctx,
2966                          struct dcerpc_pipe *p,
2967                          struct policy_handle *hKey,
2968                          const char *KeyName)
2969 {
2970         struct policy_handle phKey;
2971
2972         torture_assert(tctx,
2973                 test_OpenKey_int(tctx, p, hKey, KeyName, &phKey),
2974                 "failed to open key");
2975
2976         torture_assert(tctx,
2977                 test_QueryInfoKey_int(tctx, p, &phKey),
2978                 "failed to enum values");
2979         torture_assert(tctx,
2980                 test_GetKeySecurity_int(tctx, p, &phKey),
2981                 "failed to get key security");
2982
2983         torture_assert(tctx,
2984                 test_EnumValue_int(tctx, p, &phKey),
2985                 "failed to enum values");
2986
2987         torture_assert(tctx,
2988                 test_CloseKey_int(tctx, p, &phKey),
2989                 "failed to close key");
2990
2991         return true;
2992 }
2993
2994 static bool test_all_keys(struct torture_context *tctx,
2995                           void *data)
2996 {
2997         struct torture_clusapi_context *t =
2998                 talloc_get_type_abort(data, struct torture_clusapi_context);
2999         struct dcerpc_binding_handle *b = t->p->binding_handle;
3000         struct policy_handle hKey;
3001         struct clusapi_EnumKey r;
3002         const char *KeyName;
3003         NTTIME lpftLastWriteTime;
3004         WERROR rpc_status;
3005         int i = 0;
3006
3007         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3008                 return false;
3009         }
3010
3011         do {
3012                 r.in.hKey = hKey;
3013                 r.in.dwIndex = i++;
3014                 r.out.KeyName = &KeyName;
3015                 r.out.lpftLastWriteTime = &lpftLastWriteTime;
3016                 r.out.rpc_status = &rpc_status;
3017
3018                 torture_assert_ntstatus_ok(tctx,
3019                         dcerpc_clusapi_EnumKey_r(b, tctx, &r),
3020                         "EnumKey failed");
3021
3022                 if (W_ERROR_IS_OK(r.out.result)) {
3023                         torture_assert(tctx,
3024                                 test_one_key(tctx, t->p, &hKey, KeyName),
3025                                 "failed to test one key");
3026                 }
3027
3028         } while (W_ERROR_IS_OK(r.out.result));
3029
3030         torture_assert_werr_equal(tctx,
3031                 r.out.result,
3032                 WERR_NO_MORE_ITEMS,
3033                 "EnumKey failed");
3034
3035         test_CloseKey_int(tctx, t->p, &hKey);
3036
3037         return true;
3038 }
3039
3040 static bool torture_rpc_clusapi_setup_common(struct torture_context *tctx,
3041                                              struct torture_clusapi_context *t)
3042 {
3043         struct dcerpc_binding_handle *b;
3044
3045         torture_assert_ntstatus_ok(tctx,
3046                 torture_rpc_connection(tctx, &t->p, &ndr_table_clusapi),
3047                 "Error connecting to server");
3048
3049         {
3050                 struct clusapi_GetClusterName r;
3051
3052                 b = t->p->binding_handle;
3053
3054                 r.out.ClusterName = &t->ClusterName;
3055                 r.out.NodeName = &t->NodeName;
3056
3057                 torture_assert_ntstatus_ok(tctx,
3058                         dcerpc_clusapi_GetClusterName_r(b, tctx, &r),
3059                         "GetClusterName failed");
3060                 torture_assert_werr_ok(tctx,
3061                         r.out.result,
3062                         "GetClusterName failed");
3063         }
3064
3065         return true;
3066 }
3067
3068 static bool torture_rpc_clusapi_setup(struct torture_context *tctx,
3069                                       void **data)
3070 {
3071         struct torture_clusapi_context *t;
3072
3073         *data = t = talloc_zero(tctx, struct torture_clusapi_context);
3074
3075         return torture_rpc_clusapi_setup_common(tctx, t);
3076 }
3077
3078 static bool torture_rpc_clusapi_teardown(struct torture_context *tctx,
3079                                          void *data)
3080 {
3081         talloc_free(data);
3082
3083         return true;
3084 }
3085
3086 void torture_tcase_cluster(struct torture_tcase *tcase)
3087 {
3088         torture_tcase_add_simple_test(tcase, "OpenCluster",
3089                                       test_OpenCluster);
3090         torture_tcase_add_simple_test(tcase, "OpenClusterEx",
3091                                       test_OpenClusterEx);
3092         torture_tcase_add_simple_test(tcase, "CloseCluster",
3093                                       test_CloseCluster);
3094         torture_tcase_add_simple_test(tcase, "SetClusterName",
3095                                       test_SetClusterName);
3096         torture_tcase_add_simple_test(tcase, "GetClusterName",
3097                                       test_GetClusterName);
3098         torture_tcase_add_simple_test(tcase, "GetClusterVersion",
3099                                       test_GetClusterVersion);
3100         torture_tcase_add_simple_test(tcase, "CreateEnum",
3101                                       test_CreateEnum);
3102         torture_tcase_add_simple_test(tcase, "CreateEnumEx",
3103                                       test_CreateEnumEx);
3104         torture_tcase_add_simple_test(tcase, "GetClusterVersion2",
3105                                       test_GetClusterVersion2);
3106         torture_tcase_add_simple_test(tcase, "BackupClusterDatabase",
3107                                       test_BackupClusterDatabase);
3108         torture_tcase_add_simple_test(tcase, "SetServiceAccountPassword",
3109                                       test_SetServiceAccountPassword);
3110         torture_tcase_add_simple_test(tcase, "ClusterControl",
3111                                       test_ClusterControl);
3112
3113 }
3114
3115 void torture_tcase_resource(struct torture_tcase *tcase)
3116 {
3117         struct torture_test *test;
3118
3119         torture_tcase_add_simple_test(tcase, "GetQuorumResource",
3120                                       test_GetQuorumResource);
3121         torture_tcase_add_simple_test(tcase, "SetQuorumResource",
3122                                       test_SetQuorumResource);
3123         torture_tcase_add_simple_test(tcase, "OpenResource",
3124                                       test_OpenResource);
3125         torture_tcase_add_simple_test(tcase, "OpenResourceEx",
3126                                       test_OpenResourceEx);
3127         torture_tcase_add_simple_test(tcase, "CloseResource",
3128                                       test_CloseResource);
3129         torture_tcase_add_simple_test(tcase, "CreateResource",
3130                                       test_CreateResource);
3131         torture_tcase_add_simple_test(tcase, "DeleteResource",
3132                                       test_DeleteResource);
3133         torture_tcase_add_simple_test(tcase, "SetResourceName",
3134                                       test_SetResourceName);
3135         torture_tcase_add_simple_test(tcase, "GetResourceState",
3136                                       test_GetResourceState);
3137         torture_tcase_add_simple_test(tcase, "GetResourceId",
3138                                       test_GetResourceId);
3139         torture_tcase_add_simple_test(tcase, "GetResourceType",
3140                                       test_GetResourceType);
3141         torture_tcase_add_simple_test(tcase, "CreateResEnum",
3142                                       test_CreateResEnum);
3143         test = torture_tcase_add_simple_test(tcase, "FailResource",
3144                                       test_FailResource);
3145         test->dangerous = true;
3146         torture_tcase_add_simple_test(tcase, "OnlineResource",
3147                                       test_OnlineResource);
3148         test = torture_tcase_add_simple_test(tcase, "OfflineResource",
3149                                       test_OfflineResource);
3150         test->dangerous = true;
3151         torture_tcase_add_simple_test(tcase, "GetResourceDependencyExpression",
3152                                       test_GetResourceDependencyExpression);
3153         torture_tcase_add_simple_test(tcase, "GetResourceNetworkName",
3154                                       test_GetResourceNetworkName);
3155         torture_tcase_add_simple_test(tcase, "all_resources",
3156                                       test_all_resources);
3157 }
3158
3159 void torture_tcase_node(struct torture_tcase *tcase)
3160 {
3161         struct torture_test *test;
3162
3163         torture_tcase_add_simple_test(tcase, "OpenNode",
3164                                       test_OpenNode);
3165         torture_tcase_add_simple_test(tcase, "OpenNodeEx",
3166                                       test_OpenNodeEx);
3167         torture_tcase_add_simple_test(tcase, "CloseNode",
3168                                       test_CloseNode);
3169         torture_tcase_add_simple_test(tcase, "GetNodeState",
3170                                       test_GetNodeState);
3171         torture_tcase_add_simple_test(tcase, "GetNodeId",
3172                                       test_GetNodeId);
3173         test = torture_tcase_add_simple_test(tcase, "PauseNode",
3174                                              test_PauseNode);
3175         test->dangerous = true;
3176         torture_tcase_add_simple_test(tcase, "ResumeNode",
3177                                       test_ResumeNode);
3178         test = torture_tcase_add_simple_test(tcase, "EvictNode",
3179                                              test_EvictNode);
3180         test->dangerous = true;
3181         torture_tcase_add_simple_test(tcase, "all_nodes",
3182                                       test_all_nodes);
3183 }
3184
3185 void torture_tcase_group(struct torture_tcase *tcase)
3186 {
3187         struct torture_test *test;
3188
3189         torture_tcase_add_simple_test(tcase, "OpenGroup",
3190                                       test_OpenGroup);
3191         torture_tcase_add_simple_test(tcase, "OpenGroupEx",
3192                                       test_OpenGroupEx);
3193         torture_tcase_add_simple_test(tcase, "CloseGroup",
3194                                       test_CloseGroup);
3195         torture_tcase_add_simple_test(tcase, "GetGroupState",
3196                                       test_GetGroupState);
3197         torture_tcase_add_simple_test(tcase, "GetGroupId",
3198                                       test_GetGroupId);
3199         torture_tcase_add_simple_test(tcase, "OnlineGroup",
3200                                       test_OnlineGroup);
3201         test = torture_tcase_add_simple_test(tcase, "OfflineGroup",
3202                                       test_OfflineGroup);
3203         test->dangerous = true;
3204         torture_tcase_add_simple_test(tcase, "all_groups",
3205                                       test_all_groups);
3206 }
3207
3208 void torture_tcase_network(struct torture_tcase *tcase)
3209 {
3210         torture_tcase_add_simple_test(tcase, "OpenNetwork",
3211                                       test_OpenNetwork);
3212         torture_tcase_add_simple_test(tcase, "OpenNetworkEx",
3213                                       test_OpenNetworkEx);
3214         torture_tcase_add_simple_test(tcase, "CloseNetwork",
3215                                       test_CloseNetwork);
3216         torture_tcase_add_simple_test(tcase, "GetNetworkState",
3217                                       test_GetNetworkState);
3218         torture_tcase_add_simple_test(tcase, "GetNetworkId",
3219                                       test_GetNetworkId);
3220         torture_tcase_add_simple_test(tcase, "all_networks",
3221                                       test_all_networks);
3222 }
3223
3224 void torture_tcase_netinterface(struct torture_tcase *tcase)
3225 {
3226         torture_tcase_add_simple_test(tcase, "OpenNetInterface",
3227                                       test_OpenNetInterface);
3228         torture_tcase_add_simple_test(tcase, "OpenNetInterfaceEx",
3229                                       test_OpenNetInterfaceEx);
3230         torture_tcase_add_simple_test(tcase, "CloseNetInterface",
3231                                       test_CloseNetInterface);
3232         torture_tcase_add_simple_test(tcase, "GetNetInterfaceState",
3233                                       test_GetNetInterfaceState);
3234         torture_tcase_add_simple_test(tcase, "GetNetInterfaceId",
3235                                       test_GetNetInterfaceId);
3236         torture_tcase_add_simple_test(tcase, "all_netinterfaces",
3237                                       test_all_netinterfaces);
3238 }
3239
3240 void torture_tcase_registry(struct torture_tcase *tcase)
3241 {
3242         torture_tcase_add_simple_test(tcase, "GetRootKey",
3243                                       test_GetRootKey);
3244         torture_tcase_add_simple_test(tcase, "CloseKey",
3245                                       test_CloseKey);
3246         torture_tcase_add_simple_test(tcase, "EnumKey",
3247                                       test_EnumKey);
3248         torture_tcase_add_simple_test(tcase, "QueryValue",
3249                                       test_QueryValue);
3250         torture_tcase_add_simple_test(tcase, "all_keys",
3251                                       test_all_keys);
3252 }
3253
3254 struct torture_suite *torture_rpc_clusapi(TALLOC_CTX *mem_ctx)
3255 {
3256         struct torture_tcase *tcase;
3257         struct torture_suite *suite = torture_suite_create(mem_ctx, "clusapi");
3258
3259         tcase = torture_suite_add_tcase(suite, "cluster");
3260
3261         torture_tcase_set_fixture(tcase,
3262                                   torture_rpc_clusapi_setup,
3263                                   torture_rpc_clusapi_teardown);
3264
3265         torture_tcase_cluster(tcase);
3266
3267         tcase = torture_suite_add_tcase(suite, "resource");
3268
3269         torture_tcase_set_fixture(tcase,
3270                                   torture_rpc_clusapi_setup,
3271                                   torture_rpc_clusapi_teardown);
3272
3273         torture_tcase_resource(tcase);
3274
3275         tcase = torture_suite_add_tcase(suite, "node");
3276
3277         torture_tcase_set_fixture(tcase,
3278                                   torture_rpc_clusapi_setup,
3279                                   torture_rpc_clusapi_teardown);
3280
3281         torture_tcase_node(tcase);
3282
3283         tcase = torture_suite_add_tcase(suite, "group");
3284
3285         torture_tcase_set_fixture(tcase,
3286                                   torture_rpc_clusapi_setup,
3287                                   torture_rpc_clusapi_teardown);
3288
3289         torture_tcase_group(tcase);
3290
3291         tcase = torture_suite_add_tcase(suite, "network");
3292
3293         torture_tcase_set_fixture(tcase,
3294                                   torture_rpc_clusapi_setup,
3295                                   torture_rpc_clusapi_teardown);
3296
3297         torture_tcase_network(tcase);
3298
3299         tcase = torture_suite_add_tcase(suite, "netinterface");
3300
3301         torture_tcase_set_fixture(tcase,
3302                                   torture_rpc_clusapi_setup,
3303                                   torture_rpc_clusapi_teardown);
3304
3305         torture_tcase_netinterface(tcase);
3306
3307         tcase = torture_suite_add_tcase(suite, "registry");
3308
3309         torture_tcase_set_fixture(tcase,
3310                                   torture_rpc_clusapi_setup,
3311                                   torture_rpc_clusapi_teardown);
3312
3313         torture_tcase_registry(tcase);
3314
3315         return suite;
3316 }