s4-torture: add test for clusapi_CreateGroupResourceEnum
[sfrench/samba-autobuild/.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         if (!W_ERROR_IS_OK(r.out.result) &&
950             !W_ERROR_EQUAL(r.out.result, WERR_IO_PENDING)) {
951                 torture_result(tctx, TORTURE_FAIL,
952                                "OnlineResource failed with %s",
953                                 win_errstr(r.out.result));
954                 return false;
955         }
956
957         return true;
958 }
959
960 static bool test_OnlineResource(struct torture_context *tctx,
961                                 void *data)
962 {
963         struct torture_clusapi_context *t =
964                 talloc_get_type_abort(data, struct torture_clusapi_context);
965         struct policy_handle hResource;
966         bool ret = true;
967
968         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
969                 return false;
970         }
971
972         ret = test_OnlineResource_int(tctx, t->p, &hResource);
973
974         test_CloseResource_int(tctx, t->p, &hResource);
975
976         return ret;
977 }
978
979 bool test_OfflineResource_int(struct torture_context *tctx,
980                               struct dcerpc_pipe *p,
981                               struct policy_handle *hResource)
982 {
983         struct dcerpc_binding_handle *b = p->binding_handle;
984         struct clusapi_OfflineResource r;
985         WERROR rpc_status;
986
987         r.in.hResource = *hResource;
988         r.out.rpc_status = &rpc_status;
989
990         torture_assert_ntstatus_ok(tctx,
991                 dcerpc_clusapi_OfflineResource_r(b, tctx, &r),
992                 "OfflineResource failed");
993         if (!W_ERROR_IS_OK(r.out.result) &&
994             !W_ERROR_EQUAL(r.out.result, WERR_IO_PENDING)) {
995                 torture_result(tctx, TORTURE_FAIL,
996                                "OfflineResource failed with %s",
997                                win_errstr(r.out.result));
998                 return false;
999         }
1000
1001         return true;
1002 }
1003
1004 static bool test_OfflineResource(struct torture_context *tctx,
1005                                  void *data)
1006 {
1007         struct torture_clusapi_context *t =
1008                 talloc_get_type_abort(data, struct torture_clusapi_context);
1009         struct policy_handle hResource;
1010         bool ret = true;
1011
1012         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1013                 return false;
1014         }
1015
1016         ret = test_OfflineResource_int(tctx, t->p, &hResource);
1017
1018         test_CloseResource_int(tctx, t->p, &hResource);
1019
1020         return ret;
1021 }
1022
1023 static bool test_CreateResEnum_int(struct torture_context *tctx,
1024                                    struct dcerpc_pipe *p,
1025                                    struct policy_handle *hResource)
1026 {
1027         struct dcerpc_binding_handle *b = p->binding_handle;
1028         struct clusapi_CreateResEnum r;
1029         uint32_t dwType = CLUSTER_ENUM_RESOURCE;
1030         struct ENUM_LIST *ReturnEnum;
1031         WERROR rpc_status;
1032
1033         r.in.hResource = *hResource;
1034         r.in.dwType = dwType;
1035         r.out.ReturnEnum = &ReturnEnum;
1036         r.out.rpc_status = &rpc_status;
1037
1038         torture_assert_ntstatus_ok(tctx,
1039                 dcerpc_clusapi_CreateResEnum_r(b, tctx, &r),
1040                 "CreateResEnum failed");
1041         torture_assert_werr_ok(tctx,
1042                 r.out.result,
1043                 "CreateResEnum failed");
1044
1045         return true;
1046 }
1047
1048 static bool test_CreateResEnum(struct torture_context *tctx,
1049                                void *data)
1050 {
1051         struct torture_clusapi_context *t =
1052                 talloc_get_type_abort(data, struct torture_clusapi_context);
1053         struct policy_handle hResource;
1054         bool ret = true;
1055
1056         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1057                 return false;
1058         }
1059
1060         ret = test_CreateResEnum_int(tctx, t->p, &hResource);
1061
1062         test_CloseResource_int(tctx, t->p, &hResource);
1063
1064         return ret;
1065 }
1066
1067 static bool test_GetResourceDependencyExpression_int(struct torture_context *tctx,
1068                                                      struct dcerpc_pipe *p,
1069                                                      struct policy_handle *hResource)
1070 {
1071         struct dcerpc_binding_handle *b = p->binding_handle;
1072         struct clusapi_GetResourceDependencyExpression r;
1073         const char *lpszDependencyExpression;
1074         WERROR rpc_status;
1075
1076         r.in.hResource = *hResource;
1077         r.out.lpszDependencyExpression = &lpszDependencyExpression;
1078         r.out.rpc_status = &rpc_status;
1079
1080         torture_assert_ntstatus_ok(tctx,
1081                 dcerpc_clusapi_GetResourceDependencyExpression_r(b, tctx, &r),
1082                 "GetResourceDependencyExpression failed");
1083         torture_assert_werr_ok(tctx,
1084                 r.out.result,
1085                 "GetResourceDependencyExpression failed");
1086
1087         return true;
1088 }
1089
1090 static bool test_GetResourceDependencyExpression(struct torture_context *tctx,
1091                                                  void *data)
1092 {
1093         struct torture_clusapi_context *t =
1094                 talloc_get_type_abort(data, struct torture_clusapi_context);
1095         struct policy_handle hResource;
1096         bool ret = true;
1097
1098         if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1099                 return false;
1100         }
1101
1102         ret = test_GetResourceDependencyExpression_int(tctx, t->p, &hResource);
1103
1104         test_CloseResource_int(tctx, t->p, &hResource);
1105
1106         return ret;
1107 }
1108
1109 static bool test_GetResourceNetworkName_int(struct torture_context *tctx,
1110                                             struct dcerpc_pipe *p,
1111                                             struct policy_handle *hResource)
1112 {
1113         struct dcerpc_binding_handle *b = p->binding_handle;
1114         struct clusapi_GetResourceNetworkName r;
1115         const char *lpszName;
1116         WERROR rpc_status;
1117
1118         r.in.hResource = *hResource;
1119         r.out.lpszName = &lpszName;
1120         r.out.rpc_status = &rpc_status;
1121
1122         torture_assert_ntstatus_ok(tctx,
1123                 dcerpc_clusapi_GetResourceNetworkName_r(b, tctx, &r),
1124                 "GetResourceNetworkName failed");
1125         torture_assert_werr_ok(tctx,
1126                 r.out.result,
1127                 "GetResourceNetworkName failed");
1128
1129         return true;
1130 }
1131
1132 static bool test_GetResourceNetworkName(struct torture_context *tctx,
1133                                         void *data)
1134 {
1135         struct torture_clusapi_context *t =
1136                 talloc_get_type_abort(data, struct torture_clusapi_context);
1137         struct policy_handle hResource;
1138         bool ret = true;
1139
1140         if (!test_OpenResource_int(tctx, t->p, "Network Name", &hResource)) {
1141                 return false;
1142         }
1143
1144         ret = test_GetResourceNetworkName_int(tctx, t->p, &hResource);
1145
1146         test_CloseResource_int(tctx, t->p, &hResource);
1147
1148         return ret;
1149 }
1150
1151 static bool test_ResourceTypeControl_int(struct torture_context *tctx,
1152                                          struct dcerpc_pipe *p,
1153                                          struct policy_handle *Cluster,
1154                                          const char *resource_type,
1155                                          enum clusapi_ClusterControlCode dwControlCode)
1156 {
1157         struct dcerpc_binding_handle *b = p->binding_handle;
1158         struct clusapi_ResourceTypeControl r;
1159         uint32_t lpBytesReturned;
1160         uint32_t lpcbRequired;
1161         WERROR rpc_status;
1162
1163         r.in.hCluster = *Cluster;
1164         r.in.lpszResourceTypeName = resource_type;
1165         r.in.dwControlCode = 0;
1166         r.in.lpInBuffer = NULL;
1167         r.in.nInBufferSize = 0;
1168         r.in.nOutBufferSize = 0;
1169         r.out.lpOutBuffer = NULL;
1170         r.out.lpBytesReturned = &lpBytesReturned;
1171         r.out.lpcbRequired = &lpcbRequired;
1172         r.out.rpc_status = &rpc_status;
1173
1174         torture_assert_ntstatus_ok(tctx,
1175                 dcerpc_clusapi_ResourceTypeControl_r(b, tctx, &r),
1176                 "ResourceTypeControl failed");
1177
1178         if (strequal(r.in.lpszResourceTypeName, "MSMQ") ||
1179             strequal(r.in.lpszResourceTypeName, "MSMQTriggers")) {
1180                 torture_assert_werr_equal(tctx,
1181                         r.out.result,
1182                         WERR_CLUSTER_RESTYPE_NOT_SUPPORTED,
1183                         "ResourceTypeControl failed");
1184                 return true;
1185         }
1186
1187         torture_assert_werr_equal(tctx,
1188                 r.out.result,
1189                 WERR_INVALID_FUNCTION,
1190                 "ResourceTypeControl failed");
1191
1192         r.in.dwControlCode = dwControlCode;
1193
1194         torture_assert_ntstatus_ok(tctx,
1195                 dcerpc_clusapi_ResourceTypeControl_r(b, tctx, &r),
1196                 "ResourceTypeControl failed");
1197
1198         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1199                 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
1200                 r.in.nOutBufferSize = *r.out.lpcbRequired;
1201                 torture_assert_ntstatus_ok(tctx,
1202                         dcerpc_clusapi_ResourceTypeControl_r(b, tctx, &r),
1203                         "ResourceTypeControl failed");
1204         }
1205         torture_assert_werr_ok(tctx,
1206                 r.out.result,
1207                 "ResourceTypeControl failed");
1208
1209         /* now try what happens when we query with a buffer large enough to hold
1210          * the entire packet */
1211
1212         r.in.nOutBufferSize = 0x400;
1213         r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
1214
1215         torture_assert_ntstatus_ok(tctx,
1216                 dcerpc_clusapi_ResourceTypeControl_r(b, tctx, &r),
1217                 "ResourceTypeControl failed");
1218         torture_assert_werr_ok(tctx,
1219                 r.out.result,
1220                 "ResourceTypeControl failed");
1221         torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
1222                 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
1223
1224         return true;
1225 }
1226
1227 static bool test_ResourceTypeControl(struct torture_context *tctx,
1228                                      struct dcerpc_pipe *p,
1229                                      const char *resourcetype_name)
1230 {
1231         struct policy_handle Cluster;
1232         bool ret;
1233         uint32_t control_codes[] = {
1234                 CLUSCTL_RESOURCE_TYPE_GET_CLASS_INFO,
1235                 CLUSCTL_RESOURCE_TYPE_GET_CHARACTERISTICS,
1236                 CLUSCTL_RESOURCE_TYPE_GET_COMMON_PROPERTIES,
1237                 CLUSCTL_RESOURCE_TYPE_GET_RO_COMMON_PROPERTIES,
1238                 CLUSCTL_RESOURCE_TYPE_GET_PRIVATE_PROPERTIES
1239         };
1240         int i;
1241
1242         if (!test_OpenCluster_int(tctx, p, &Cluster)) {
1243                 return false;
1244         }
1245
1246         for (i=0; i < ARRAY_SIZE(control_codes); i++) {
1247                 ret = test_ResourceTypeControl_int(tctx, p, &Cluster,
1248                                                    resourcetype_name,
1249                                                    control_codes[i]);
1250                 if (!ret) {
1251                         goto done;
1252                 }
1253         }
1254
1255  done:
1256         test_CloseCluster_int(tctx, p, &Cluster);
1257
1258         return ret;
1259 }
1260
1261
1262
1263 static bool test_one_resourcetype(struct torture_context *tctx,
1264                                   struct dcerpc_pipe *p,
1265                                   const char *resourcetype_name)
1266 {
1267         torture_assert(tctx,
1268                 test_ResourceTypeControl(tctx, p, resourcetype_name),
1269                 "failed to query ResourceTypeControl");
1270
1271         return true;
1272 }
1273
1274 static bool test_one_resource(struct torture_context *tctx,
1275                               struct dcerpc_pipe *p,
1276                               const char *resource_name)
1277 {
1278         struct policy_handle hResource;
1279
1280         torture_assert(tctx,
1281                 test_OpenResource_int(tctx, p, resource_name, &hResource),
1282                 "failed to open resource");
1283         test_CloseResource_int(tctx, p, &hResource);
1284
1285         torture_assert(tctx,
1286                 test_OpenResourceEx_int(tctx, p, resource_name, &hResource),
1287                 "failed to openex resource");
1288
1289         torture_assert(tctx,
1290                 test_GetResourceType_int(tctx, p, &hResource),
1291                 "failed to query resource type");
1292         torture_assert(tctx,
1293                 test_GetResourceId_int(tctx, p, &hResource),
1294                 "failed to query resource id");
1295         torture_assert(tctx,
1296                 test_GetResourceState_int(tctx, p, &hResource),
1297                 "failed to query resource state");
1298         torture_assert(tctx,
1299                 test_CreateResEnum_int(tctx, p, &hResource),
1300                 "failed to query resource enum");
1301         torture_assert(tctx,
1302                 test_GetResourceDependencyExpression_int(tctx, p, &hResource),
1303                 "failed to query resource dependency expression");
1304         torture_assert(tctx,
1305                 test_GetResourceNetworkName_int(tctx, p, &hResource),
1306                 "failed to query resource network name");
1307
1308         test_CloseResource_int(tctx, p, &hResource);
1309
1310         return true;
1311 }
1312
1313 static bool test_all_resources(struct torture_context *tctx,
1314                                void *data)
1315 {
1316         struct torture_clusapi_context *t =
1317                 talloc_get_type_abort(data, struct torture_clusapi_context);
1318         struct dcerpc_binding_handle *b = t->p->binding_handle;
1319         struct clusapi_CreateEnum r;
1320         uint32_t dwType = CLUSTER_ENUM_RESOURCE;
1321         struct ENUM_LIST *ReturnEnum;
1322         WERROR rpc_status;
1323         int i;
1324
1325         r.in.dwType = dwType;
1326         r.out.ReturnEnum = &ReturnEnum;
1327         r.out.rpc_status = &rpc_status;
1328
1329         torture_assert_ntstatus_ok(tctx,
1330                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1331                 "CreateEnum failed");
1332         torture_assert_werr_ok(tctx,
1333                 r.out.result,
1334                 "CreateEnum failed");
1335
1336         for (i=0; i < ReturnEnum->EntryCount; i++) {
1337
1338                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1339
1340                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_RESOURCE, "type mismatch");
1341
1342                 torture_assert(tctx,
1343                         test_one_resource(tctx, t->p, e.Name),
1344                         "failed to test one resource");
1345         }
1346
1347         return true;
1348 }
1349
1350 static bool test_all_resourcetypes(struct torture_context *tctx,
1351                                    void *data)
1352 {
1353         struct torture_clusapi_context *t =
1354                 talloc_get_type_abort(data, struct torture_clusapi_context);
1355         struct dcerpc_binding_handle *b = t->p->binding_handle;
1356         struct clusapi_CreateEnum r;
1357         uint32_t dwType = CLUSTER_ENUM_RESTYPE;
1358         struct ENUM_LIST *ReturnEnum;
1359         WERROR rpc_status;
1360         int i;
1361
1362         r.in.dwType = dwType;
1363         r.out.ReturnEnum = &ReturnEnum;
1364         r.out.rpc_status = &rpc_status;
1365
1366         torture_assert_ntstatus_ok(tctx,
1367                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1368                 "CreateEnum failed");
1369         torture_assert_werr_ok(tctx,
1370                 r.out.result,
1371                 "CreateEnum failed");
1372
1373         for (i=0; i < ReturnEnum->EntryCount; i++) {
1374
1375                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1376
1377                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_RESTYPE, "type mismatch");
1378
1379                 torture_assert(tctx,
1380                         test_one_resourcetype(tctx, t->p, e.Name),
1381                         "failed to test one resourcetype");
1382         }
1383
1384         return true;
1385 }
1386
1387
1388 static bool test_OpenNode_int(struct torture_context *tctx,
1389                               struct dcerpc_pipe *p,
1390                               const char *lpszNodeName,
1391                               struct policy_handle *hNode)
1392 {
1393         struct dcerpc_binding_handle *b = p->binding_handle;
1394         struct clusapi_OpenNode r;
1395         WERROR Status;
1396         WERROR rpc_status;
1397
1398         r.in.lpszNodeName = lpszNodeName;
1399         r.out.rpc_status = &rpc_status;
1400         r.out.Status = &Status;
1401         r.out.hNode= hNode;
1402
1403         torture_assert_ntstatus_ok(tctx,
1404                 dcerpc_clusapi_OpenNode_r(b, tctx, &r),
1405                 "OpenNode failed");
1406         torture_assert_werr_ok(tctx,
1407                 *r.out.Status,
1408                 "OpenNode failed");
1409
1410         return true;
1411 }
1412
1413 static bool test_OpenNodeEx_int(struct torture_context *tctx,
1414                                 struct dcerpc_pipe *p,
1415                                 const char *lpszNodeName,
1416                                 struct policy_handle *hNode)
1417 {
1418         struct dcerpc_binding_handle *b = p->binding_handle;
1419         struct clusapi_OpenNodeEx r;
1420         uint32_t lpdwGrantedAccess;
1421         WERROR Status;
1422         WERROR rpc_status;
1423
1424         r.in.lpszNodeName = lpszNodeName;
1425         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
1426         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
1427         r.out.rpc_status = &rpc_status;
1428         r.out.Status = &Status;
1429         r.out.hNode= hNode;
1430
1431         torture_assert_ntstatus_ok(tctx,
1432                 dcerpc_clusapi_OpenNodeEx_r(b, tctx, &r),
1433                 "OpenNodeEx failed");
1434         torture_assert_werr_ok(tctx,
1435                 *r.out.Status,
1436                 "OpenNodeEx failed");
1437
1438         return true;
1439 }
1440
1441
1442 static bool test_CloseNode_int(struct torture_context *tctx,
1443                                struct dcerpc_pipe *p,
1444                                struct policy_handle *Node)
1445 {
1446         struct dcerpc_binding_handle *b = p->binding_handle;
1447         struct clusapi_CloseNode r;
1448
1449         r.in.Node = Node;
1450         r.out.Node = Node;
1451
1452         torture_assert_ntstatus_ok(tctx,
1453                 dcerpc_clusapi_CloseNode_r(b, tctx, &r),
1454                 "CloseNode failed");
1455         torture_assert_werr_ok(tctx,
1456                 r.out.result,
1457                 "CloseNode failed");
1458         torture_assert(tctx,
1459                 ndr_policy_handle_empty(Node),
1460                 "policy_handle non empty after CloseNode");
1461
1462         return true;
1463 }
1464
1465 static bool test_OpenNode(struct torture_context *tctx,
1466                           void *data)
1467 {
1468         struct torture_clusapi_context *t =
1469                 talloc_get_type_abort(data, struct torture_clusapi_context);
1470         struct policy_handle hNode;
1471
1472         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1473                 return false;
1474         }
1475
1476         test_CloseNode_int(tctx, t->p, &hNode);
1477
1478         return true;
1479 }
1480
1481 static bool test_OpenNodeEx(struct torture_context *tctx,
1482                             void *data)
1483 {
1484         struct torture_clusapi_context *t =
1485                 talloc_get_type_abort(data, struct torture_clusapi_context);
1486         struct policy_handle hNode;
1487
1488         if (!test_OpenNodeEx_int(tctx, t->p, t->NodeName, &hNode)) {
1489                 return false;
1490         }
1491
1492         test_CloseNode_int(tctx, t->p, &hNode);
1493
1494         return true;
1495 }
1496
1497 static bool test_CloseNode(struct torture_context *tctx,
1498                            void *data)
1499 {
1500         struct torture_clusapi_context *t =
1501                 talloc_get_type_abort(data, struct torture_clusapi_context);
1502         struct policy_handle hNode;
1503
1504         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1505                 return false;
1506         }
1507
1508         return test_CloseNode_int(tctx, t->p, &hNode);
1509 }
1510
1511 static bool test_GetNodeState_int(struct torture_context *tctx,
1512                                   struct dcerpc_pipe *p,
1513                                   struct policy_handle *hNode)
1514 {
1515         struct dcerpc_binding_handle *b = p->binding_handle;
1516         struct clusapi_GetNodeState r;
1517         enum clusapi_ClusterNodeState State;
1518         WERROR rpc_status;
1519
1520         r.in.hNode = *hNode;
1521         r.out.State = &State;
1522         r.out.rpc_status = &rpc_status;
1523
1524         torture_assert_ntstatus_ok(tctx,
1525                 dcerpc_clusapi_GetNodeState_r(b, tctx, &r),
1526                 "GetNodeState failed");
1527         torture_assert_werr_ok(tctx,
1528                 r.out.result,
1529                 "GetNodeState failed");
1530
1531         return true;
1532 }
1533
1534 static bool test_GetNodeState(struct torture_context *tctx,
1535                               void *data)
1536 {
1537         struct torture_clusapi_context *t =
1538                 talloc_get_type_abort(data, struct torture_clusapi_context);
1539         struct policy_handle hNode;
1540         bool ret = true;
1541
1542         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1543                 return false;
1544         }
1545
1546         ret = test_GetNodeState_int(tctx, t->p, &hNode);
1547
1548         test_CloseNode_int(tctx, t->p, &hNode);
1549
1550         return ret;
1551 }
1552
1553 static bool test_GetNodeId_int(struct torture_context *tctx,
1554                                struct dcerpc_pipe *p,
1555                                struct policy_handle *hNode)
1556 {
1557         struct dcerpc_binding_handle *b = p->binding_handle;
1558         struct clusapi_GetNodeId r;
1559         const char *pGuid;
1560         WERROR rpc_status;
1561
1562         r.in.hNode = *hNode;
1563         r.out.pGuid = &pGuid;
1564         r.out.rpc_status = &rpc_status;
1565
1566         torture_assert_ntstatus_ok(tctx,
1567                 dcerpc_clusapi_GetNodeId_r(b, tctx, &r),
1568                 "GetNodeId failed");
1569         torture_assert_werr_ok(tctx,
1570                 r.out.result,
1571                 "GetNodeId failed");
1572
1573         return true;
1574 }
1575
1576 static bool test_GetNodeId(struct torture_context *tctx,
1577                            void *data)
1578 {
1579         struct torture_clusapi_context *t =
1580                 talloc_get_type_abort(data, struct torture_clusapi_context);
1581         struct policy_handle hNode;
1582         bool ret = true;
1583
1584         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1585                 return false;
1586         }
1587
1588         ret = test_GetNodeId_int(tctx, t->p, &hNode);
1589
1590         test_CloseNode_int(tctx, t->p, &hNode);
1591
1592         return ret;
1593 }
1594
1595 static bool test_NodeControl_int(struct torture_context *tctx,
1596                                  struct dcerpc_pipe *p,
1597                                  struct policy_handle *hNode,
1598                                  enum clusapi_NodeControlCode dwControlCode)
1599 {
1600         struct dcerpc_binding_handle *b = p->binding_handle;
1601         struct clusapi_NodeControl r;
1602         uint32_t lpBytesReturned;
1603         uint32_t lpcbRequired;
1604         WERROR rpc_status;
1605
1606         r.in.hNode = *hNode;
1607         r.in.dwControlCode = 0;
1608         r.in.lpInBuffer = NULL;
1609         r.in.nInBufferSize = 0;
1610         r.in.nOutBufferSize = 0;
1611         r.out.lpOutBuffer = NULL;
1612         r.out.lpBytesReturned = &lpBytesReturned;
1613         r.out.lpcbRequired = &lpcbRequired;
1614         r.out.rpc_status = &rpc_status;
1615
1616         torture_assert_ntstatus_ok(tctx,
1617                 dcerpc_clusapi_NodeControl_r(b, tctx, &r),
1618                 "NodeControl failed");
1619         torture_assert_werr_equal(tctx,
1620                 r.out.result,
1621                 WERR_INVALID_FUNCTION,
1622                 "NodeControl failed");
1623
1624         r.in.dwControlCode = dwControlCode;
1625
1626         torture_assert_ntstatus_ok(tctx,
1627                 dcerpc_clusapi_NodeControl_r(b, tctx, &r),
1628                 "NodeControl failed");
1629
1630         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1631                 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
1632                 r.in.nOutBufferSize = *r.out.lpcbRequired;
1633                 torture_assert_ntstatus_ok(tctx,
1634                         dcerpc_clusapi_NodeControl_r(b, tctx, &r),
1635                         "NodeControl failed");
1636         }
1637         torture_assert_werr_ok(tctx,
1638                 r.out.result,
1639                 "NodeControl failed");
1640
1641         /* now try what happens when we query with a buffer large enough to hold
1642          * the entire packet */
1643
1644         r.in.nOutBufferSize = 0x400;
1645         r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
1646
1647         torture_assert_ntstatus_ok(tctx,
1648                 dcerpc_clusapi_NodeControl_r(b, tctx, &r),
1649                 "NodeControl failed");
1650         torture_assert_werr_ok(tctx,
1651                 r.out.result,
1652                 "NodeControl failed");
1653         torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
1654                 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
1655
1656         if (dwControlCode == CLUSCTL_NODE_GET_ID) {
1657                 const char *str;
1658                 DATA_BLOB blob = data_blob_const(r.out.lpOutBuffer, *r.out.lpBytesReturned);
1659
1660                 torture_assert(tctx, *r.out.lpBytesReturned < 4, "unexpected size");
1661                 torture_assert(tctx, *r.out.lpBytesReturned % 2, "must be a multiple of 2");
1662
1663                 torture_assert(tctx,
1664                         pull_reg_sz(tctx, &blob, &str),
1665                         "failed to pull unicode string");
1666
1667                 torture_comment(tctx, "got this node id: '%s'", str);
1668         }
1669
1670         return true;
1671 }
1672
1673 static bool test_NodeControl(struct torture_context *tctx,
1674                              void *data)
1675 {
1676         struct torture_clusapi_context *t =
1677                 talloc_get_type_abort(data, struct torture_clusapi_context);
1678         struct policy_handle hNode;
1679         bool ret = true;
1680
1681         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1682                 return false;
1683         }
1684
1685         ret = test_NodeControl_int(tctx, t->p, &hNode, CLUSCTL_NODE_GET_RO_COMMON_PROPERTIES);
1686         if (!ret) {
1687                 return false;
1688         }
1689
1690         ret = test_NodeControl_int(tctx, t->p, &hNode, CLUSCTL_NODE_GET_ID);
1691         if (!ret) {
1692                 return false;
1693         }
1694
1695         test_CloseNode_int(tctx, t->p, &hNode);
1696
1697         return ret;
1698 }
1699
1700 static bool test_PauseNode_int(struct torture_context *tctx,
1701                                struct dcerpc_pipe *p,
1702                                struct policy_handle *hNode)
1703 {
1704         struct dcerpc_binding_handle *b = p->binding_handle;
1705         struct clusapi_PauseNode r;
1706         WERROR rpc_status;
1707
1708         r.in.hNode = *hNode;
1709         r.out.rpc_status = &rpc_status;
1710
1711         torture_assert_ntstatus_ok(tctx,
1712                 dcerpc_clusapi_PauseNode_r(b, tctx, &r),
1713                 "PauseNode failed");
1714         torture_assert_werr_ok(tctx,
1715                 r.out.result,
1716                 "PauseNode failed");
1717
1718         return true;
1719 }
1720
1721 static bool test_PauseNode(struct torture_context *tctx,
1722                            void *data)
1723 {
1724         struct torture_clusapi_context *t =
1725                 talloc_get_type_abort(data, struct torture_clusapi_context);
1726         struct policy_handle hNode;
1727         bool ret = true;
1728
1729         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1730                 return false;
1731         }
1732
1733         ret = test_PauseNode_int(tctx, t->p, &hNode);
1734
1735         test_CloseNode_int(tctx, t->p, &hNode);
1736
1737         return ret;
1738 }
1739
1740 static bool test_ResumeNode_int(struct torture_context *tctx,
1741                                 struct dcerpc_pipe *p,
1742                                 struct policy_handle *hNode)
1743 {
1744         struct dcerpc_binding_handle *b = p->binding_handle;
1745         struct clusapi_ResumeNode r;
1746         WERROR rpc_status;
1747
1748         r.in.hNode = *hNode;
1749         r.out.rpc_status = &rpc_status;
1750
1751         torture_assert_ntstatus_ok(tctx,
1752                 dcerpc_clusapi_ResumeNode_r(b, tctx, &r),
1753                 "ResumeNode failed");
1754         torture_assert_werr_equal(tctx,
1755                 r.out.result,
1756                 WERR_CLUSTER_NODE_NOT_PAUSED,
1757                 "ResumeNode gave unexpected result");
1758
1759         return true;
1760 }
1761
1762 static bool test_ResumeNode(struct torture_context *tctx,
1763                             void *data)
1764 {
1765         struct torture_clusapi_context *t =
1766                 talloc_get_type_abort(data, struct torture_clusapi_context);
1767         struct policy_handle hNode;
1768         bool ret = true;
1769
1770         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1771                 return false;
1772         }
1773
1774         ret = test_ResumeNode_int(tctx, t->p, &hNode);
1775
1776         test_CloseNode_int(tctx, t->p, &hNode);
1777
1778         return ret;
1779 }
1780
1781 static bool test_EvictNode_int(struct torture_context *tctx,
1782                                struct dcerpc_pipe *p,
1783                                struct policy_handle *hNode)
1784 {
1785         struct dcerpc_binding_handle *b = p->binding_handle;
1786         struct clusapi_EvictNode r;
1787         WERROR rpc_status;
1788
1789         r.in.hNode = *hNode;
1790         r.out.rpc_status = &rpc_status;
1791
1792         torture_assert_ntstatus_ok(tctx,
1793                 dcerpc_clusapi_EvictNode_r(b, tctx, &r),
1794                 "EvictNode failed");
1795         torture_assert_werr_ok(tctx,
1796                 r.out.result,
1797                 "EvictNode failed");
1798
1799         return true;
1800 }
1801
1802 static bool test_EvictNode(struct torture_context *tctx,
1803                            void *data)
1804 {
1805         struct torture_clusapi_context *t =
1806                 talloc_get_type_abort(data, struct torture_clusapi_context);
1807         struct policy_handle hNode;
1808         bool ret = true;
1809
1810         if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1811                 return false;
1812         }
1813
1814         ret = test_EvictNode_int(tctx, t->p, &hNode);
1815
1816         test_CloseNode_int(tctx, t->p, &hNode);
1817
1818         return ret;
1819 }
1820
1821 static bool test_one_node(struct torture_context *tctx,
1822                           struct dcerpc_pipe *p,
1823                           const char *node_name)
1824 {
1825         struct policy_handle hNode;
1826
1827         torture_assert(tctx,
1828                 test_OpenNode_int(tctx, p, node_name, &hNode),
1829                 "failed to open node");
1830         test_CloseNode_int(tctx, p, &hNode);
1831
1832         torture_assert(tctx,
1833                 test_OpenNodeEx_int(tctx, p, node_name, &hNode),
1834                 "failed to openex node");
1835
1836         torture_assert(tctx,
1837                 test_GetNodeId_int(tctx, p, &hNode),
1838                 "failed to query node id");
1839         torture_assert(tctx,
1840                 test_GetNodeState_int(tctx, p, &hNode),
1841                 "failed to query node id");
1842
1843         test_CloseNode_int(tctx, p, &hNode);
1844
1845         return true;
1846 }
1847
1848 static bool test_all_nodes(struct torture_context *tctx,
1849                            void *data)
1850 {
1851         struct torture_clusapi_context *t =
1852                 talloc_get_type_abort(data, struct torture_clusapi_context);
1853         struct dcerpc_binding_handle *b = t->p->binding_handle;
1854         struct clusapi_CreateEnum r;
1855         uint32_t dwType = CLUSTER_ENUM_NODE;
1856         struct ENUM_LIST *ReturnEnum;
1857         WERROR rpc_status;
1858         int i;
1859
1860         r.in.dwType = dwType;
1861         r.out.ReturnEnum = &ReturnEnum;
1862         r.out.rpc_status = &rpc_status;
1863
1864         torture_assert_ntstatus_ok(tctx,
1865                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1866                 "CreateEnum failed");
1867         torture_assert_werr_ok(tctx,
1868                 r.out.result,
1869                 "CreateEnum failed");
1870
1871         for (i=0; i < ReturnEnum->EntryCount; i++) {
1872
1873                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1874
1875                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NODE, "type mismatch");
1876
1877                 torture_assert(tctx,
1878                         test_one_node(tctx, t->p, e.Name),
1879                         "failed to test one node");
1880         }
1881
1882         return true;
1883 }
1884
1885 static bool test_OpenGroup_int(struct torture_context *tctx,
1886                                struct dcerpc_pipe *p,
1887                                const char *lpszGroupName,
1888                                struct policy_handle *hGroup)
1889 {
1890         struct dcerpc_binding_handle *b = p->binding_handle;
1891         struct clusapi_OpenGroup r;
1892         WERROR Status;
1893         WERROR rpc_status;
1894
1895         r.in.lpszGroupName = lpszGroupName;
1896         r.out.rpc_status = &rpc_status;
1897         r.out.Status = &Status;
1898         r.out.hGroup= hGroup;
1899
1900         torture_assert_ntstatus_ok(tctx,
1901                 dcerpc_clusapi_OpenGroup_r(b, tctx, &r),
1902                 "OpenGroup failed");
1903         torture_assert_werr_ok(tctx,
1904                 *r.out.Status,
1905                 "OpenGroup failed");
1906
1907         return true;
1908 }
1909
1910 static bool test_OpenGroupEx_int(struct torture_context *tctx,
1911                                  struct dcerpc_pipe *p,
1912                                  const char *lpszGroupName,
1913                                  struct policy_handle *hGroup)
1914 {
1915         struct dcerpc_binding_handle *b = p->binding_handle;
1916         struct clusapi_OpenGroupEx r;
1917         uint32_t lpdwGrantedAccess;
1918         WERROR Status;
1919         WERROR rpc_status;
1920
1921         r.in.lpszGroupName = lpszGroupName;
1922         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
1923         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
1924         r.out.rpc_status = &rpc_status;
1925         r.out.Status = &Status;
1926         r.out.hGroup= hGroup;
1927
1928         torture_assert_ntstatus_ok(tctx,
1929                 dcerpc_clusapi_OpenGroupEx_r(b, tctx, &r),
1930                 "OpenGroupEx failed");
1931         torture_assert_werr_ok(tctx,
1932                 *r.out.Status,
1933                 "OpenGroupEx failed");
1934
1935         return true;
1936 }
1937
1938 static bool test_CloseGroup_int(struct torture_context *tctx,
1939                                 struct dcerpc_pipe *p,
1940                                 struct policy_handle *Group)
1941 {
1942         struct dcerpc_binding_handle *b = p->binding_handle;
1943         struct clusapi_CloseGroup r;
1944
1945         r.in.Group = Group;
1946         r.out.Group = Group;
1947
1948         torture_assert_ntstatus_ok(tctx,
1949                 dcerpc_clusapi_CloseGroup_r(b, tctx, &r),
1950                 "CloseGroup failed");
1951         torture_assert_werr_ok(tctx,
1952                 r.out.result,
1953                 "CloseGroup failed");
1954         torture_assert(tctx,
1955                 ndr_policy_handle_empty(Group),
1956                 "policy_handle non empty after CloseGroup");
1957
1958         return true;
1959 }
1960
1961 static bool test_OpenGroup(struct torture_context *tctx,
1962                            void *data)
1963 {
1964         struct torture_clusapi_context *t =
1965                 talloc_get_type_abort(data, struct torture_clusapi_context);
1966         struct policy_handle hGroup;
1967
1968         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
1969                 return false;
1970         }
1971
1972         test_CloseGroup_int(tctx, t->p, &hGroup);
1973
1974         return true;
1975 }
1976
1977 static bool test_OpenGroupEx(struct torture_context *tctx,
1978                              void *data)
1979 {
1980         struct torture_clusapi_context *t =
1981                 talloc_get_type_abort(data, struct torture_clusapi_context);
1982         struct policy_handle hGroup;
1983
1984         if (!test_OpenGroupEx_int(tctx, t->p, "Cluster Group", &hGroup)) {
1985                 return false;
1986         }
1987
1988         test_CloseGroup_int(tctx, t->p, &hGroup);
1989
1990         return true;
1991 }
1992
1993 static bool test_CloseGroup(struct torture_context *tctx,
1994                             void *data)
1995 {
1996         struct torture_clusapi_context *t =
1997                 talloc_get_type_abort(data, struct torture_clusapi_context);
1998         struct policy_handle hGroup;
1999
2000         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2001                 return false;
2002         }
2003
2004         return test_CloseGroup_int(tctx, t->p, &hGroup);
2005 }
2006
2007 static bool test_GetGroupState_int(struct torture_context *tctx,
2008                                    struct dcerpc_pipe *p,
2009                                    struct policy_handle *hGroup)
2010 {
2011         struct dcerpc_binding_handle *b = p->binding_handle;
2012         struct clusapi_GetGroupState r;
2013         enum clusapi_ClusterGroupState State;
2014         const char *NodeName;
2015         WERROR rpc_status;
2016
2017         r.in.hGroup = *hGroup;
2018         r.out.State = &State;
2019         r.out.NodeName = &NodeName;
2020         r.out.rpc_status = &rpc_status;
2021
2022         torture_assert_ntstatus_ok(tctx,
2023                 dcerpc_clusapi_GetGroupState_r(b, tctx, &r),
2024                 "GetGroupState failed");
2025         torture_assert_werr_ok(tctx,
2026                 r.out.result,
2027                 "GetGroupState failed");
2028
2029         return true;
2030 }
2031
2032 static bool test_GetGroupState(struct torture_context *tctx,
2033                                void *data)
2034 {
2035         struct torture_clusapi_context *t =
2036                 talloc_get_type_abort(data, struct torture_clusapi_context);
2037         struct policy_handle hGroup;
2038         bool ret = true;
2039
2040         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2041                 return false;
2042         }
2043
2044         ret = test_GetGroupState_int(tctx, t->p, &hGroup);
2045
2046         test_CloseGroup_int(tctx, t->p, &hGroup);
2047
2048         return ret;
2049 }
2050
2051 static bool test_GetGroupId_int(struct torture_context *tctx,
2052                                 struct dcerpc_pipe *p,
2053                                 struct policy_handle *hGroup)
2054 {
2055         struct dcerpc_binding_handle *b = p->binding_handle;
2056         struct clusapi_GetGroupId r;
2057         const char *pGuid;
2058         WERROR rpc_status;
2059
2060         r.in.hGroup = *hGroup;
2061         r.out.pGuid = &pGuid;
2062         r.out.rpc_status = &rpc_status;
2063
2064         torture_assert_ntstatus_ok(tctx,
2065                 dcerpc_clusapi_GetGroupId_r(b, tctx, &r),
2066                 "GetGroupId failed");
2067         torture_assert_werr_ok(tctx,
2068                 r.out.result,
2069                 "GetGroupId failed");
2070
2071         return true;
2072 }
2073
2074 static bool test_GetGroupId(struct torture_context *tctx,
2075                             void *data)
2076 {
2077         struct torture_clusapi_context *t =
2078                 talloc_get_type_abort(data, struct torture_clusapi_context);
2079         struct policy_handle hGroup;
2080         bool ret = true;
2081
2082         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2083                 return false;
2084         }
2085
2086         ret = test_GetGroupId_int(tctx, t->p, &hGroup);
2087
2088         test_CloseGroup_int(tctx, t->p, &hGroup);
2089
2090         return ret;
2091 }
2092
2093 static bool test_GroupControl_int(struct torture_context *tctx,
2094                                   struct dcerpc_pipe *p,
2095                                   struct policy_handle *hGroup,
2096                                   enum clusapi_GroupControlCode dwControlCode)
2097 {
2098         struct dcerpc_binding_handle *b = p->binding_handle;
2099         struct clusapi_GroupControl r;
2100         uint32_t lpBytesReturned;
2101         uint32_t lpcbRequired;
2102         WERROR rpc_status;
2103
2104         r.in.hGroup = *hGroup;
2105         r.in.dwControlCode = 0;
2106         r.in.lpInBuffer = NULL;
2107         r.in.nInBufferSize = 0;
2108         r.in.nOutBufferSize = 0;
2109         r.out.lpOutBuffer = NULL;
2110         r.out.lpBytesReturned = &lpBytesReturned;
2111         r.out.lpcbRequired = &lpcbRequired;
2112         r.out.rpc_status = &rpc_status;
2113
2114         torture_assert_ntstatus_ok(tctx,
2115                 dcerpc_clusapi_GroupControl_r(b, tctx, &r),
2116                 "GroupControl failed");
2117         torture_assert_werr_equal(tctx,
2118                 r.out.result,
2119                 WERR_INVALID_FUNCTION,
2120                 "GroupControl failed");
2121
2122         r.in.dwControlCode = dwControlCode;
2123
2124         torture_assert_ntstatus_ok(tctx,
2125                 dcerpc_clusapi_GroupControl_r(b, tctx, &r),
2126                 "GroupControl failed");
2127
2128         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
2129                 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
2130                 r.in.nOutBufferSize = *r.out.lpcbRequired;
2131                 torture_assert_ntstatus_ok(tctx,
2132                         dcerpc_clusapi_GroupControl_r(b, tctx, &r),
2133                         "GroupControl failed");
2134         }
2135         torture_assert_werr_ok(tctx,
2136                 r.out.result,
2137                 "GroupControl failed");
2138
2139         /* now try what happens when we query with a buffer large enough to hold
2140          * the entire packet */
2141
2142         r.in.nOutBufferSize = 0x400;
2143         r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
2144
2145         torture_assert_ntstatus_ok(tctx,
2146                 dcerpc_clusapi_GroupControl_r(b, tctx, &r),
2147                 "GroupControl failed");
2148         torture_assert_werr_ok(tctx,
2149                 r.out.result,
2150                 "GroupControl failed");
2151         torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
2152                 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
2153
2154         return true;
2155 }
2156
2157 static bool test_CreateGroupResourceEnum_int(struct torture_context *tctx,
2158                                              struct dcerpc_pipe *p,
2159                                              struct policy_handle *hGroup)
2160 {
2161         struct dcerpc_binding_handle *b = p->binding_handle;
2162         struct clusapi_CreateGroupResourceEnum r;
2163         uint32_t dwType[] = {
2164                 CLUSTER_GROUP_ENUM_CONTAINS,
2165                 CLUSTER_GROUP_ENUM_NODES
2166         };
2167         uint32_t dwType_invalid[] = {
2168                 0x00000040,
2169                 0x00000080,
2170                 0x00000100 /* and many more ... */
2171         };
2172         struct ENUM_LIST *ReturnEnum;
2173         WERROR rpc_status;
2174         int i;
2175
2176         r.in.hGroup = *hGroup;
2177
2178         for (i=0; i < ARRAY_SIZE(dwType); i++) {
2179
2180                 r.in.hGroup = *hGroup;
2181                 r.in.dwType = dwType[i];
2182                 r.out.ReturnEnum = &ReturnEnum;
2183                 r.out.rpc_status = &rpc_status;
2184
2185                 torture_assert_ntstatus_ok(tctx,
2186                         dcerpc_clusapi_CreateGroupResourceEnum_r(b, tctx, &r),
2187                         "CreateGroupResourceEnum failed");
2188                 torture_assert_werr_ok(tctx,
2189                         r.out.result,
2190                         "CreateGroupResourceEnum failed");
2191         }
2192
2193         for (i=0; i < ARRAY_SIZE(dwType_invalid); i++) {
2194
2195                 r.in.dwType = dwType_invalid[i];
2196                 r.out.ReturnEnum = &ReturnEnum;
2197                 r.out.rpc_status = &rpc_status;
2198
2199                 torture_assert_ntstatus_ok(tctx,
2200                         dcerpc_clusapi_CreateGroupResourceEnum_r(b, tctx, &r),
2201                         "CreateGroupResourceEnum failed");
2202                 torture_assert_werr_ok(tctx,
2203                         r.out.result,
2204                         "CreateGroupResourceEnum failed");
2205         }
2206
2207         return true;
2208 }
2209
2210
2211 static bool test_GroupControl(struct torture_context *tctx,
2212                               void *data)
2213 {
2214         struct torture_clusapi_context *t =
2215                 talloc_get_type_abort(data, struct torture_clusapi_context);
2216         struct policy_handle hGroup;
2217         bool ret = true;
2218
2219         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2220                 return false;
2221         }
2222
2223         ret = test_GroupControl_int(tctx, t->p, &hGroup, CLUSCTL_GROUP_GET_CHARACTERISTICS);
2224         if (!ret) {
2225                 return false;
2226         }
2227
2228         ret = test_GroupControl_int(tctx, t->p, &hGroup, CLUSCTL_GROUP_GET_RO_COMMON_PROPERTIES);
2229         if (!ret) {
2230                 return false;
2231         }
2232
2233         test_CloseGroup_int(tctx, t->p, &hGroup);
2234
2235         return ret;
2236 }
2237
2238 static bool test_OnlineGroup_int(struct torture_context *tctx,
2239                                  struct dcerpc_pipe *p,
2240                                  struct policy_handle *hGroup)
2241 {
2242         struct dcerpc_binding_handle *b = p->binding_handle;
2243         struct clusapi_OnlineGroup r;
2244         WERROR rpc_status;
2245
2246         r.in.hGroup = *hGroup;
2247         r.out.rpc_status = &rpc_status;
2248
2249         torture_assert_ntstatus_ok(tctx,
2250                 dcerpc_clusapi_OnlineGroup_r(b, tctx, &r),
2251                 "OnlineGroup failed");
2252         torture_assert_werr_ok(tctx,
2253                 r.out.result,
2254                 "OnlineGroup failed");
2255
2256         return true;
2257 }
2258
2259 static bool test_OnlineGroup(struct torture_context *tctx,
2260                              void *data)
2261 {
2262         struct torture_clusapi_context *t =
2263                 talloc_get_type_abort(data, struct torture_clusapi_context);
2264         struct policy_handle hGroup;
2265         bool ret = true;
2266
2267         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2268                 return false;
2269         }
2270
2271         ret = test_OnlineGroup_int(tctx, t->p, &hGroup);
2272
2273         test_CloseGroup_int(tctx, t->p, &hGroup);
2274
2275         return ret;
2276 }
2277
2278 static bool test_OfflineGroup_int(struct torture_context *tctx,
2279                                   struct dcerpc_pipe *p,
2280                                   struct policy_handle *hGroup)
2281 {
2282         struct dcerpc_binding_handle *b = p->binding_handle;
2283         struct clusapi_OfflineGroup r;
2284         WERROR rpc_status;
2285
2286         r.in.hGroup = *hGroup;
2287         r.out.rpc_status = &rpc_status;
2288
2289         torture_assert_ntstatus_ok(tctx,
2290                 dcerpc_clusapi_OfflineGroup_r(b, tctx, &r),
2291                 "OfflineGroup failed");
2292         torture_assert_werr_ok(tctx,
2293                 r.out.result,
2294                 "OfflineGroup failed");
2295
2296         return true;
2297 }
2298
2299 static bool test_OfflineGroup(struct torture_context *tctx,
2300                               void *data)
2301 {
2302         struct torture_clusapi_context *t =
2303                 talloc_get_type_abort(data, struct torture_clusapi_context);
2304         struct policy_handle hGroup;
2305         bool ret = true;
2306
2307         if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2308                 return false;
2309         }
2310
2311         ret = test_OfflineGroup_int(tctx, t->p, &hGroup);
2312
2313         test_CloseGroup_int(tctx, t->p, &hGroup);
2314
2315         return ret;
2316 }
2317
2318 static bool test_one_group(struct torture_context *tctx,
2319                            struct dcerpc_pipe *p,
2320                            const char *node_name)
2321 {
2322         struct policy_handle hGroup;
2323
2324         torture_assert(tctx,
2325                 test_OpenGroup_int(tctx, p, node_name, &hGroup),
2326                 "failed to open group");
2327         test_CloseGroup_int(tctx, p, &hGroup);
2328
2329         torture_assert(tctx,
2330                 test_OpenGroupEx_int(tctx, p, node_name, &hGroup),
2331                 "failed to openex group");
2332
2333         torture_assert(tctx,
2334                 test_GetGroupId_int(tctx, p, &hGroup),
2335                 "failed to query group id");
2336         torture_assert(tctx,
2337                 test_GetGroupState_int(tctx, p, &hGroup),
2338                 "failed to query group id");
2339
2340         torture_assert(tctx,
2341                 test_CreateGroupResourceEnum_int(tctx, p, &hGroup),
2342                 "failed to query resource enum");
2343
2344         test_CloseGroup_int(tctx, p, &hGroup);
2345
2346         return true;
2347 }
2348
2349 static bool test_all_groups(struct torture_context *tctx,
2350                             void *data)
2351 {
2352         struct torture_clusapi_context *t =
2353                 talloc_get_type_abort(data, struct torture_clusapi_context);
2354         struct dcerpc_binding_handle *b = t->p->binding_handle;
2355         struct clusapi_CreateEnum r;
2356         uint32_t dwType = CLUSTER_ENUM_GROUP;
2357         struct ENUM_LIST *ReturnEnum;
2358         WERROR rpc_status;
2359         int i;
2360
2361         r.in.dwType = dwType;
2362         r.out.ReturnEnum = &ReturnEnum;
2363         r.out.rpc_status = &rpc_status;
2364
2365         torture_assert_ntstatus_ok(tctx,
2366                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
2367                 "CreateEnum failed");
2368         torture_assert_werr_ok(tctx,
2369                 r.out.result,
2370                 "CreateEnum failed");
2371
2372         for (i=0; i < ReturnEnum->EntryCount; i++) {
2373
2374                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
2375
2376                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_GROUP, "type mismatch");
2377
2378                 torture_assert(tctx,
2379                         test_one_group(tctx, t->p, e.Name),
2380                         "failed to test one group");
2381         }
2382
2383         return true;
2384 }
2385
2386 static bool test_BackupClusterDatabase(struct torture_context *tctx,
2387                                        void *data)
2388 {
2389         struct torture_clusapi_context *t =
2390                 talloc_get_type_abort(data, struct torture_clusapi_context);
2391         struct dcerpc_binding_handle *b = t->p->binding_handle;
2392         struct clusapi_BackupClusterDatabase r;
2393         WERROR rpc_status;
2394
2395         r.in.lpszPathName = "c:\\cluster_backup";
2396         r.out.rpc_status = &rpc_status;
2397
2398         torture_assert_ntstatus_ok(tctx,
2399                 dcerpc_clusapi_BackupClusterDatabase_r(b, tctx, &r),
2400                 "BackupClusterDatabase failed");
2401         torture_assert_werr_equal(tctx,
2402                 r.out.result,
2403                 WERR_CALL_NOT_IMPLEMENTED,
2404                 "BackupClusterDatabase failed");
2405
2406         return true;
2407 }
2408
2409 static bool test_SetServiceAccountPassword(struct torture_context *tctx,
2410                                            void *data)
2411 {
2412         struct torture_clusapi_context *t =
2413                 talloc_get_type_abort(data, struct torture_clusapi_context);
2414         struct dcerpc_binding_handle *b = t->p->binding_handle;
2415         struct clusapi_SetServiceAccountPassword r;
2416         uint32_t SizeReturned;
2417         uint32_t ExpectedBufferSize;
2418
2419         r.in.lpszNewPassword = "P@ssw0rd!";
2420         r.in.dwFlags = IDL_CLUSTER_SET_PASSWORD_IGNORE_DOWN_NODES;
2421         r.in.ReturnStatusBufferSize = 1024;
2422         r.out.ReturnStatusBufferPtr = NULL;
2423         r.out.SizeReturned = &SizeReturned;
2424         r.out.ExpectedBufferSize = &ExpectedBufferSize;
2425
2426         torture_assert_ntstatus_ok(tctx,
2427                 dcerpc_clusapi_SetServiceAccountPassword_r(b, tctx, &r),
2428                 "SetServiceAccountPassword failed");
2429         torture_assert_werr_equal(tctx,
2430                 r.out.result,
2431                 WERR_CALL_NOT_IMPLEMENTED,
2432                 "SetServiceAccountPassword failed");
2433
2434         return true;
2435 }
2436
2437 static bool test_ClusterControl_int(struct torture_context *tctx,
2438                                     struct dcerpc_pipe *p,
2439                                     struct policy_handle *Cluster,
2440                                     enum clusapi_ClusterControlCode dwControlCode)
2441 {
2442         struct dcerpc_binding_handle *b = p->binding_handle;
2443         struct clusapi_ClusterControl r;
2444         uint32_t lpBytesReturned;
2445         uint32_t lpcbRequired;
2446         WERROR rpc_status;
2447
2448         r.in.hCluster = *Cluster;
2449         r.in.dwControlCode = 0;
2450         r.in.lpInBuffer = NULL;
2451         r.in.nInBufferSize = 0;
2452         r.in.nOutBufferSize = 0;
2453         r.out.lpOutBuffer = NULL;
2454         r.out.lpBytesReturned = &lpBytesReturned;
2455         r.out.lpcbRequired = &lpcbRequired;
2456         r.out.rpc_status = &rpc_status;
2457
2458         torture_assert_ntstatus_ok(tctx,
2459                 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2460                 "ClusterControl failed");
2461         torture_assert_werr_equal(tctx,
2462                 r.out.result,
2463                 WERR_INVALID_FUNCTION,
2464                 "ClusterControl failed");
2465
2466         r.in.dwControlCode = dwControlCode;
2467
2468         torture_assert_ntstatus_ok(tctx,
2469                 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2470                 "ClusterControl failed");
2471
2472         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
2473                 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
2474                 r.in.nOutBufferSize = *r.out.lpcbRequired;
2475                 torture_assert_ntstatus_ok(tctx,
2476                         dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2477                         "ClusterControl failed");
2478         }
2479         torture_assert_werr_ok(tctx,
2480                 r.out.result,
2481                 "ClusterControl failed");
2482
2483         /* now try what happens when we query with a buffer large enough to hold
2484          * the entire packet */
2485
2486         r.in.nOutBufferSize = 0xffff;
2487         r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
2488
2489         torture_assert_ntstatus_ok(tctx,
2490                 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2491                 "ClusterControl failed");
2492         torture_assert_werr_ok(tctx,
2493                 r.out.result,
2494                 "ClusterControl failed");
2495         torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
2496                 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
2497
2498         return true;
2499 }
2500
2501 static bool test_ClusterControl(struct torture_context *tctx,
2502                                 void *data)
2503 {
2504         struct torture_clusapi_context *t =
2505                 talloc_get_type_abort(data, struct torture_clusapi_context);
2506         struct policy_handle Cluster;
2507         bool ret;
2508         uint32_t control_codes[] = {
2509                 CLUSCTL_CLUSTER_GET_COMMON_PROPERTIES,
2510                 CLUSCTL_CLUSTER_GET_RO_COMMON_PROPERTIES,
2511                 CLUSCTL_CLUSTER_GET_FQDN,
2512                 CLUSCTL_CLUSTER_GET_PRIVATE_PROPERTIES
2513         };
2514         int i;
2515
2516         if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
2517                 return false;
2518         }
2519
2520         for (i=0; i < ARRAY_SIZE(control_codes); i++) {
2521                 ret = test_ClusterControl_int(tctx, t->p, &Cluster,
2522                                               control_codes[i]);
2523                 if (!ret) {
2524                         goto done;
2525                 }
2526         }
2527
2528  done:
2529         test_CloseCluster_int(tctx, t->p, &Cluster);
2530
2531         return ret;
2532 }
2533
2534 static bool test_OpenNetwork_int(struct torture_context *tctx,
2535                                  struct dcerpc_pipe *p,
2536                                  const char *lpszNetworkName,
2537                                  struct policy_handle *hNetwork)
2538 {
2539         struct dcerpc_binding_handle *b = p->binding_handle;
2540         struct clusapi_OpenNetwork r;
2541         WERROR Status;
2542         WERROR rpc_status;
2543
2544         r.in.lpszNetworkName = lpszNetworkName;
2545         r.out.rpc_status = &rpc_status;
2546         r.out.Status = &Status;
2547         r.out.hNetwork = hNetwork ;
2548
2549         torture_assert_ntstatus_ok(tctx,
2550                 dcerpc_clusapi_OpenNetwork_r(b, tctx, &r),
2551                 "OpenNetwork failed");
2552         torture_assert_werr_ok(tctx,
2553                 *r.out.Status,
2554                 "OpenNetwork failed");
2555
2556         return true;
2557 }
2558
2559 static bool test_OpenNetworkEx_int(struct torture_context *tctx,
2560                                    struct dcerpc_pipe *p,
2561                                    const char *lpszNetworkName,
2562                                    struct policy_handle *hNetwork)
2563 {
2564         struct dcerpc_binding_handle *b = p->binding_handle;
2565         struct clusapi_OpenNetworkEx r;
2566         uint32_t lpdwGrantedAccess;
2567         WERROR Status;
2568         WERROR rpc_status;
2569
2570         r.in.lpszNetworkName = lpszNetworkName;
2571         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
2572         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
2573         r.out.rpc_status = &rpc_status;
2574         r.out.Status = &Status;
2575         r.out.hNetwork = hNetwork ;
2576
2577         torture_assert_ntstatus_ok(tctx,
2578                 dcerpc_clusapi_OpenNetworkEx_r(b, tctx, &r),
2579                 "OpenNetworkEx failed");
2580         torture_assert_werr_ok(tctx,
2581                 *r.out.Status,
2582                 "OpenNetworkEx failed");
2583
2584         return true;
2585 }
2586
2587 static bool test_CloseNetwork_int(struct torture_context *tctx,
2588                                   struct dcerpc_pipe *p,
2589                                   struct policy_handle *Network)
2590 {
2591         struct dcerpc_binding_handle *b = p->binding_handle;
2592         struct clusapi_CloseNetwork r;
2593
2594         r.in.Network = Network;
2595         r.out.Network = Network;
2596
2597         torture_assert_ntstatus_ok(tctx,
2598                 dcerpc_clusapi_CloseNetwork_r(b, tctx, &r),
2599                 "CloseNetwork failed");
2600         torture_assert_werr_ok(tctx,
2601                 r.out.result,
2602                 "CloseNetwork failed");
2603         torture_assert(tctx,
2604                 ndr_policy_handle_empty(Network),
2605                 "policy_handle non empty after CloseNetwork");
2606
2607         return true;
2608 }
2609
2610 static bool test_OpenNetwork(struct torture_context *tctx,
2611                              void *data)
2612 {
2613         struct torture_clusapi_context *t =
2614                 talloc_get_type_abort(data, struct torture_clusapi_context);
2615         struct policy_handle hNetwork;
2616
2617         if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2618                 return false;
2619         }
2620
2621         test_CloseNetwork_int(tctx, t->p, &hNetwork);
2622
2623         return true;
2624 }
2625
2626 static bool test_OpenNetworkEx(struct torture_context *tctx,
2627                                void *data)
2628 {
2629         struct torture_clusapi_context *t =
2630                 talloc_get_type_abort(data, struct torture_clusapi_context);
2631         struct policy_handle hNetwork;
2632
2633         if (!test_OpenNetworkEx_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2634                 return false;
2635         }
2636
2637         test_CloseNetwork_int(tctx, t->p, &hNetwork);
2638
2639         return true;
2640 }
2641
2642 static bool test_CloseNetwork(struct torture_context *tctx,
2643                               void *data)
2644 {
2645         struct torture_clusapi_context *t =
2646                 talloc_get_type_abort(data, struct torture_clusapi_context);
2647         struct policy_handle hNetwork;
2648
2649         if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2650                 return false;
2651         }
2652
2653         return test_CloseNetwork_int(tctx, t->p, &hNetwork);
2654 }
2655
2656 static bool test_GetNetworkState_int(struct torture_context *tctx,
2657                                      struct dcerpc_pipe *p,
2658                                      struct policy_handle *hNetwork)
2659 {
2660         struct dcerpc_binding_handle *b = p->binding_handle;
2661         struct clusapi_GetNetworkState r;
2662         enum clusapi_ClusterNetworkState State;
2663         WERROR rpc_status;
2664
2665         r.in.hNetwork = *hNetwork;
2666         r.out.State = &State;
2667         r.out.rpc_status = &rpc_status;
2668
2669         torture_assert_ntstatus_ok(tctx,
2670                 dcerpc_clusapi_GetNetworkState_r(b, tctx, &r),
2671                 "GetNetworkState failed");
2672         torture_assert_werr_ok(tctx,
2673                 r.out.result,
2674                 "GetNetworkState failed");
2675
2676         return true;
2677 }
2678
2679 static bool test_GetNetworkState(struct torture_context *tctx,
2680                                  void *data)
2681 {
2682         struct torture_clusapi_context *t =
2683                 talloc_get_type_abort(data, struct torture_clusapi_context);
2684         struct policy_handle hNetwork;
2685         bool ret = true;
2686
2687         if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2688                 return false;
2689         }
2690
2691         ret = test_GetNetworkState_int(tctx, t->p, &hNetwork);
2692
2693         test_CloseNetwork_int(tctx, t->p, &hNetwork);
2694
2695         return ret;
2696 }
2697
2698 static bool test_GetNetworkId_int(struct torture_context *tctx,
2699                                   struct dcerpc_pipe *p,
2700                                   struct policy_handle *hNetwork)
2701 {
2702         struct dcerpc_binding_handle *b = p->binding_handle;
2703         struct clusapi_GetNetworkId r;
2704         const char *pGuid;
2705         WERROR rpc_status;
2706
2707         r.in.hNetwork = *hNetwork;
2708         r.out.pGuid = &pGuid;
2709         r.out.rpc_status = &rpc_status;
2710
2711         torture_assert_ntstatus_ok(tctx,
2712                 dcerpc_clusapi_GetNetworkId_r(b, tctx, &r),
2713                 "GetNetworkId failed");
2714         torture_assert_werr_ok(tctx,
2715                 r.out.result,
2716                 "GetNetworkId failed");
2717
2718         return true;
2719 }
2720
2721 static bool test_GetNetworkId(struct torture_context *tctx,
2722                               void *data)
2723 {
2724         struct torture_clusapi_context *t =
2725                 talloc_get_type_abort(data, struct torture_clusapi_context);
2726         struct policy_handle hNetwork;
2727         bool ret = true;
2728
2729         if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2730                 return false;
2731         }
2732
2733         ret = test_GetNetworkId_int(tctx, t->p, &hNetwork);
2734
2735         test_CloseNetwork_int(tctx, t->p, &hNetwork);
2736
2737         return ret;
2738 }
2739
2740 static bool test_one_network(struct torture_context *tctx,
2741                              struct dcerpc_pipe *p,
2742                              const char *network_name)
2743 {
2744         struct policy_handle hNetwork;
2745
2746         torture_assert(tctx,
2747                 test_OpenNetwork_int(tctx, p, network_name, &hNetwork),
2748                 "failed to open network");
2749         test_CloseNetwork_int(tctx, p, &hNetwork);
2750
2751         torture_assert(tctx,
2752                 test_OpenNetworkEx_int(tctx, p, network_name, &hNetwork),
2753                 "failed to openex network");
2754
2755         torture_assert(tctx,
2756                 test_GetNetworkId_int(tctx, p, &hNetwork),
2757                 "failed to query network id");
2758         torture_assert(tctx,
2759                 test_GetNetworkState_int(tctx, p, &hNetwork),
2760                 "failed to query network id");
2761
2762         test_CloseNetwork_int(tctx, p, &hNetwork);
2763
2764         return true;
2765 }
2766
2767 static bool test_all_networks(struct torture_context *tctx,
2768                               void *data)
2769 {
2770         struct torture_clusapi_context *t =
2771                 talloc_get_type_abort(data, struct torture_clusapi_context);
2772         struct dcerpc_binding_handle *b = t->p->binding_handle;
2773         struct clusapi_CreateEnum r;
2774         uint32_t dwType = CLUSTER_ENUM_NETWORK;
2775         struct ENUM_LIST *ReturnEnum;
2776         WERROR rpc_status;
2777         int i;
2778
2779         r.in.dwType = dwType;
2780         r.out.ReturnEnum = &ReturnEnum;
2781         r.out.rpc_status = &rpc_status;
2782
2783         torture_assert_ntstatus_ok(tctx,
2784                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
2785                 "CreateEnum failed");
2786         torture_assert_werr_ok(tctx,
2787                 r.out.result,
2788                 "CreateEnum failed");
2789
2790         for (i=0; i < ReturnEnum->EntryCount; i++) {
2791
2792                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
2793
2794                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NETWORK, "type mismatch");
2795
2796                 torture_assert(tctx,
2797                         test_one_network(tctx, t->p, e.Name),
2798                         "failed to test one network");
2799         }
2800
2801         return true;
2802 }
2803
2804 static bool test_OpenNetInterface_int(struct torture_context *tctx,
2805                                       struct dcerpc_pipe *p,
2806                                       const char *lpszNetInterfaceName,
2807                                       struct policy_handle *hNetInterface)
2808 {
2809         struct dcerpc_binding_handle *b = p->binding_handle;
2810         struct clusapi_OpenNetInterface r;
2811         WERROR Status;
2812         WERROR rpc_status;
2813
2814         r.in.lpszNetInterfaceName = lpszNetInterfaceName;
2815         r.out.rpc_status = &rpc_status;
2816         r.out.Status = &Status;
2817         r.out.hNetInterface = hNetInterface;
2818
2819         torture_assert_ntstatus_ok(tctx,
2820                 dcerpc_clusapi_OpenNetInterface_r(b, tctx, &r),
2821                 "OpenNetInterface failed");
2822         torture_assert_werr_ok(tctx,
2823                 *r.out.Status,
2824                 "OpenNetInterface failed");
2825
2826         return true;
2827 }
2828
2829 static bool test_OpenNetInterfaceEx_int(struct torture_context *tctx,
2830                                         struct dcerpc_pipe *p,
2831                                         const char *lpszNetInterfaceName,
2832                                         struct policy_handle *hNetInterface)
2833 {
2834         struct dcerpc_binding_handle *b = p->binding_handle;
2835         struct clusapi_OpenNetInterfaceEx r;
2836         uint32_t lpdwGrantedAccess;
2837         WERROR Status;
2838         WERROR rpc_status;
2839
2840         r.in.lpszNetInterfaceName = lpszNetInterfaceName;
2841         r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
2842         r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
2843         r.out.rpc_status = &rpc_status;
2844         r.out.Status = &Status;
2845         r.out.hNetInterface = hNetInterface;
2846
2847         torture_assert_ntstatus_ok(tctx,
2848                 dcerpc_clusapi_OpenNetInterfaceEx_r(b, tctx, &r),
2849                 "OpenNetInterfaceEx failed");
2850         torture_assert_werr_ok(tctx,
2851                 *r.out.Status,
2852                 "OpenNetInterfaceEx failed");
2853
2854         return true;
2855 }
2856
2857 static bool test_CloseNetInterface_int(struct torture_context *tctx,
2858                                        struct dcerpc_pipe *p,
2859                                        struct policy_handle *NetInterface)
2860 {
2861         struct dcerpc_binding_handle *b = p->binding_handle;
2862         struct clusapi_CloseNetInterface r;
2863
2864         r.in.NetInterface = NetInterface;
2865         r.out.NetInterface = NetInterface;
2866
2867         torture_assert_ntstatus_ok(tctx,
2868                 dcerpc_clusapi_CloseNetInterface_r(b, tctx, &r),
2869                 "CloseNetInterface failed");
2870         torture_assert_werr_ok(tctx,
2871                 r.out.result,
2872                 "CloseNetInterface failed");
2873         torture_assert(tctx,
2874                 ndr_policy_handle_empty(NetInterface),
2875                 "policy_handle non empty after CloseNetInterface");
2876
2877         return true;
2878 }
2879
2880 static bool test_OpenNetInterface(struct torture_context *tctx,
2881                                   void *data)
2882 {
2883         struct torture_clusapi_context *t =
2884                 talloc_get_type_abort(data, struct torture_clusapi_context);
2885         struct policy_handle hNetInterface;
2886
2887         if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2888                 return false;
2889         }
2890
2891         test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2892
2893         return true;
2894 }
2895
2896 static bool test_OpenNetInterfaceEx(struct torture_context *tctx,
2897                                     void *data)
2898 {
2899         struct torture_clusapi_context *t =
2900                 talloc_get_type_abort(data, struct torture_clusapi_context);
2901         struct policy_handle hNetInterface;
2902
2903         if (!test_OpenNetInterfaceEx_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2904                 return false;
2905         }
2906
2907         test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2908
2909         return true;
2910 }
2911
2912 static bool test_CloseNetInterface(struct torture_context *tctx,
2913                                    void *data)
2914 {
2915         struct torture_clusapi_context *t =
2916                 talloc_get_type_abort(data, struct torture_clusapi_context);
2917         struct policy_handle hNetInterface;
2918
2919         if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2920                 return false;
2921         }
2922
2923         return test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2924 }
2925
2926 static bool test_GetNetInterfaceState_int(struct torture_context *tctx,
2927                                           struct dcerpc_pipe *p,
2928                                           struct policy_handle *hNetInterface)
2929 {
2930         struct dcerpc_binding_handle *b = p->binding_handle;
2931         struct clusapi_GetNetInterfaceState r;
2932         enum clusapi_ClusterNetInterfaceState State;
2933         WERROR rpc_status;
2934
2935         r.in.hNetInterface = *hNetInterface;
2936         r.out.State = &State;
2937         r.out.rpc_status = &rpc_status;
2938
2939         torture_assert_ntstatus_ok(tctx,
2940                 dcerpc_clusapi_GetNetInterfaceState_r(b, tctx, &r),
2941                 "GetNetInterfaceState failed");
2942         torture_assert_werr_ok(tctx,
2943                 r.out.result,
2944                 "GetNetInterfaceState failed");
2945
2946         return true;
2947 }
2948
2949 static bool test_GetNetInterfaceState(struct torture_context *tctx,
2950                                       void *data)
2951 {
2952         struct torture_clusapi_context *t =
2953                 talloc_get_type_abort(data, struct torture_clusapi_context);
2954         struct policy_handle hNetInterface;
2955         bool ret = true;
2956
2957         if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
2958                 return false;
2959         }
2960
2961         ret = test_GetNetInterfaceState_int(tctx, t->p, &hNetInterface);
2962
2963         test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
2964
2965         return ret;
2966 }
2967
2968 static bool test_GetNetInterfaceId_int(struct torture_context *tctx,
2969                                        struct dcerpc_pipe *p,
2970                                        struct policy_handle *hNetInterface)
2971 {
2972         struct dcerpc_binding_handle *b = p->binding_handle;
2973         struct clusapi_GetNetInterfaceId r;
2974         const char *pGuid;
2975         WERROR rpc_status;
2976
2977         r.in.hNetInterface = *hNetInterface;
2978         r.out.pGuid = &pGuid;
2979         r.out.rpc_status = &rpc_status;
2980
2981         torture_assert_ntstatus_ok(tctx,
2982                 dcerpc_clusapi_GetNetInterfaceId_r(b, tctx, &r),
2983                 "GetNetInterfaceId failed");
2984         torture_assert_werr_ok(tctx,
2985                 r.out.result,
2986                 "GetNetInterfaceId failed");
2987
2988         return true;
2989 }
2990
2991 static bool test_GetNetInterfaceId(struct torture_context *tctx,
2992                                    void *data)
2993 {
2994         struct torture_clusapi_context *t =
2995                 talloc_get_type_abort(data, struct torture_clusapi_context);
2996         struct policy_handle hNetInterface;
2997         bool ret = true;
2998
2999         if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
3000                 return false;
3001         }
3002
3003         ret = test_GetNetInterfaceId_int(tctx, t->p, &hNetInterface);
3004
3005         test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
3006
3007         return ret;
3008 }
3009
3010 static bool test_one_netinterface(struct torture_context *tctx,
3011                                   struct dcerpc_pipe *p,
3012                                   const char *netinterface_name)
3013 {
3014         struct policy_handle hNetInterface;
3015
3016         torture_assert(tctx,
3017                 test_OpenNetInterface_int(tctx, p, netinterface_name, &hNetInterface),
3018                 "failed to open netinterface");
3019         test_CloseNetInterface_int(tctx, p, &hNetInterface);
3020
3021         torture_assert(tctx,
3022                 test_OpenNetInterfaceEx_int(tctx, p, netinterface_name, &hNetInterface),
3023                 "failed to openex netinterface");
3024
3025         torture_assert(tctx,
3026                 test_GetNetInterfaceId_int(tctx, p, &hNetInterface),
3027                 "failed to query netinterface id");
3028         torture_assert(tctx,
3029                 test_GetNetInterfaceState_int(tctx, p, &hNetInterface),
3030                 "failed to query netinterface id");
3031
3032         test_CloseNetInterface_int(tctx, p, &hNetInterface);
3033
3034         return true;
3035 }
3036
3037 static bool test_all_netinterfaces(struct torture_context *tctx,
3038                                    void *data)
3039 {
3040         struct torture_clusapi_context *t =
3041                 talloc_get_type_abort(data, struct torture_clusapi_context);
3042         struct dcerpc_binding_handle *b = t->p->binding_handle;
3043         struct clusapi_CreateEnum r;
3044         uint32_t dwType = CLUSTER_ENUM_NETINTERFACE;
3045         struct ENUM_LIST *ReturnEnum;
3046         WERROR rpc_status;
3047         int i;
3048
3049         r.in.dwType = dwType;
3050         r.out.ReturnEnum = &ReturnEnum;
3051         r.out.rpc_status = &rpc_status;
3052
3053         torture_assert_ntstatus_ok(tctx,
3054                 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
3055                 "CreateEnum failed");
3056         torture_assert_werr_ok(tctx,
3057                 r.out.result,
3058                 "CreateEnum failed");
3059
3060         for (i=0; i < ReturnEnum->EntryCount; i++) {
3061
3062                 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
3063
3064                 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NETINTERFACE, "type mismatch");
3065
3066                 torture_assert(tctx,
3067                         test_one_netinterface(tctx, t->p, e.Name),
3068                         "failed to test one netinterface");
3069         }
3070
3071         return true;
3072 }
3073
3074 static bool test_CloseKey_int(struct torture_context *tctx,
3075                               struct dcerpc_pipe *p,
3076                               struct policy_handle *pKey)
3077 {
3078         struct dcerpc_binding_handle *b = p->binding_handle;
3079         struct clusapi_CloseKey r;
3080
3081         r.in.pKey = pKey;
3082         r.out.pKey = pKey;
3083
3084         torture_assert_ntstatus_ok(tctx,
3085                 dcerpc_clusapi_CloseKey_r(b, tctx, &r),
3086                 "CloseKey failed");
3087         torture_assert_werr_ok(tctx,
3088                 r.out.result,
3089                 "CloseKey failed");
3090         torture_assert(tctx,
3091                 ndr_policy_handle_empty(pKey),
3092                 "policy_handle non empty after CloseKey");
3093
3094         return true;
3095 }
3096
3097 static bool test_GetRootKey_int(struct torture_context *tctx,
3098                                 struct dcerpc_pipe *p,
3099                                 struct policy_handle *phKey)
3100 {
3101         struct dcerpc_binding_handle *b = p->binding_handle;
3102         struct clusapi_GetRootKey r;
3103         WERROR Status;
3104         WERROR rpc_status;
3105
3106         r.in.samDesired = SEC_FLAG_MAXIMUM_ALLOWED;
3107         r.out.Status = &Status;
3108         r.out.rpc_status = &rpc_status;
3109         r.out.phKey = phKey;
3110
3111         torture_assert_ntstatus_ok(tctx,
3112                 dcerpc_clusapi_GetRootKey_r(b, tctx, &r),
3113                 "GetRootKey failed");
3114         torture_assert_werr_ok(tctx,
3115                 *r.out.Status,
3116                 "GetRootKey failed");
3117
3118         return true;
3119 }
3120
3121 static bool test_EnumKey_int(struct torture_context *tctx,
3122                              struct dcerpc_pipe *p,
3123                              struct policy_handle *hKey)
3124 {
3125         struct dcerpc_binding_handle *b = p->binding_handle;
3126         struct clusapi_EnumKey r;
3127         const char *KeyName;
3128         NTTIME lpftLastWriteTime;
3129         WERROR rpc_status;
3130
3131         r.in.hKey = *hKey;
3132         r.in.dwIndex = 0;
3133         r.out.KeyName = &KeyName;
3134         r.out.lpftLastWriteTime = &lpftLastWriteTime;
3135         r.out.rpc_status = &rpc_status;
3136
3137         torture_assert_ntstatus_ok(tctx,
3138                 dcerpc_clusapi_EnumKey_r(b, tctx, &r),
3139                 "EnumKey failed");
3140         torture_assert_werr_ok(tctx,
3141                 r.out.result,
3142                 "EnumKey failed");
3143
3144         return true;
3145 }
3146
3147 static bool test_OpenKey_int(struct torture_context *tctx,
3148                              struct dcerpc_pipe *p,
3149                              struct policy_handle *hKey,
3150                              const char *lpSubKey,
3151                              struct policy_handle *phKey)
3152 {
3153         struct dcerpc_binding_handle *b = p->binding_handle;
3154         struct clusapi_OpenKey r;
3155         WERROR Status;
3156         WERROR rpc_status;
3157
3158         r.in.hKey = *hKey;
3159         r.in.lpSubKey = lpSubKey;
3160         r.in.samDesired = SEC_FLAG_MAXIMUM_ALLOWED;
3161         r.out.Status = &Status;
3162         r.out.rpc_status = &rpc_status;
3163         r.out.phKey = phKey;
3164
3165         torture_assert_ntstatus_ok(tctx,
3166                 dcerpc_clusapi_OpenKey_r(b, tctx, &r),
3167                 "OpenKey failed");
3168         torture_assert_werr_ok(tctx,
3169                 *r.out.Status,
3170                 "OpenKey failed");
3171
3172         return true;
3173 }
3174
3175 static bool test_EnumValue_int(struct torture_context *tctx,
3176                                struct dcerpc_pipe *p,
3177                                struct policy_handle *hKey)
3178 {
3179         struct dcerpc_binding_handle *b = p->binding_handle;
3180         struct clusapi_EnumValue r;
3181         const char *lpValueName;
3182         uint32_t lpType;
3183         uint32_t TotalSize;
3184         WERROR rpc_status;
3185         int i = 0;
3186
3187         do {
3188                 uint32_t lpcbData = 1024;
3189
3190                 r.in.hKey = *hKey;
3191                 r.in.dwIndex = i++;
3192                 r.in.lpcbData = &lpcbData;
3193                 r.out.lpValueName = &lpValueName;
3194                 r.out.lpType = &lpType;
3195                 r.out.lpData = talloc_array(tctx, uint8_t, lpcbData);
3196                 r.out.TotalSize = &TotalSize;
3197                 r.out.rpc_status = &rpc_status;
3198                 r.out.lpcbData = &lpcbData;
3199
3200                 torture_assert_ntstatus_ok(tctx,
3201                         dcerpc_clusapi_EnumValue_r(b, tctx, &r),
3202                         "EnumValue failed");
3203
3204         } while (W_ERROR_IS_OK(r.out.result));
3205
3206         torture_assert_werr_equal(tctx,
3207                 r.out.result,
3208                 WERR_NO_MORE_ITEMS,
3209                 "EnumValue failed");
3210
3211         return true;
3212 }
3213
3214 static bool test_QueryInfoKey_int(struct torture_context *tctx,
3215                                   struct dcerpc_pipe *p,
3216                                   struct policy_handle *hKey)
3217 {
3218         struct dcerpc_binding_handle *b = p->binding_handle;
3219         struct clusapi_QueryInfoKey r;
3220         uint32_t lpcSubKeys;
3221         uint32_t lpcbMaxSubKeyLen;
3222         uint32_t lpcValues;
3223         uint32_t lpcbMaxValueNameLen;
3224         uint32_t lpcbMaxValueLen;
3225         uint32_t lpcbSecurityDescriptor;
3226         NTTIME lpftLastWriteTime;
3227         WERROR rpc_status;
3228
3229         r.in.hKey = *hKey;
3230         r.out.lpcSubKeys = &lpcSubKeys;
3231         r.out.lpcbMaxSubKeyLen = &lpcbMaxSubKeyLen;
3232         r.out.lpcValues = &lpcValues;
3233         r.out.lpcbMaxValueNameLen = &lpcbMaxValueNameLen;
3234         r.out.lpcbMaxValueLen = &lpcbMaxValueLen;
3235         r.out.lpcbSecurityDescriptor = &lpcbSecurityDescriptor;
3236         r.out.lpftLastWriteTime = &lpftLastWriteTime;
3237         r.out.rpc_status = &rpc_status;
3238
3239         torture_assert_ntstatus_ok(tctx,
3240                 dcerpc_clusapi_QueryInfoKey_r(b, tctx, &r),
3241                 "QueryInfoKey failed");
3242         torture_assert_werr_ok(tctx,
3243                 r.out.result,
3244                 "QueryInfoKey failed");
3245
3246         return true;
3247 }
3248
3249 static bool test_GetKeySecurity_int(struct torture_context *tctx,
3250                                     struct dcerpc_pipe *p,
3251                                     struct policy_handle *hKey)
3252 {
3253         struct dcerpc_binding_handle *b = p->binding_handle;
3254         struct clusapi_GetKeySecurity r;
3255         uint32_t SecurityInformation = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
3256         struct RPC_SECURITY_DESCRIPTOR pRpcSecurityDescriptor;
3257         WERROR rpc_status;
3258
3259         ZERO_STRUCT(pRpcSecurityDescriptor);
3260
3261         r.in.hKey = *hKey;
3262         r.in.SecurityInformation = SecurityInformation;
3263         r.in.pRpcSecurityDescriptor = &pRpcSecurityDescriptor;
3264         r.out.rpc_status = &rpc_status;
3265         r.out.pRpcSecurityDescriptor = &pRpcSecurityDescriptor;
3266
3267         torture_assert_ntstatus_ok(tctx,
3268                 dcerpc_clusapi_GetKeySecurity_r(b, tctx, &r),
3269                 "GetKeySecurity failed");
3270
3271         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
3272                 pRpcSecurityDescriptor.lpSecurityDescriptor = talloc_array(tctx,
3273                 uint8_t, pRpcSecurityDescriptor.cbInSecurityDescriptor);
3274
3275                 torture_assert_ntstatus_ok(tctx,
3276                         dcerpc_clusapi_GetKeySecurity_r(b, tctx, &r),
3277                         "GetKeySecurity failed");
3278         }
3279
3280         torture_assert_werr_ok(tctx,
3281                 r.out.result,
3282                 "GetKeySecurity failed");
3283
3284         return true;
3285 }
3286
3287 static bool test_GetRootKey(struct torture_context *tctx,
3288                             void *data)
3289 {
3290         struct torture_clusapi_context *t =
3291                 talloc_get_type_abort(data, struct torture_clusapi_context);
3292         struct policy_handle hKey;
3293
3294         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3295                 return false;
3296         }
3297
3298         test_CloseKey_int(tctx, t->p, &hKey);
3299
3300         return true;
3301 }
3302
3303 static bool test_CloseKey(struct torture_context *tctx,
3304                           void *data)
3305 {
3306         struct torture_clusapi_context *t =
3307                 talloc_get_type_abort(data, struct torture_clusapi_context);
3308         struct policy_handle hKey;
3309
3310         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3311                 return false;
3312         }
3313
3314         return test_CloseKey_int(tctx, t->p, &hKey);
3315 }
3316
3317 static bool test_EnumKey(struct torture_context *tctx,
3318                          void *data)
3319 {
3320         struct torture_clusapi_context *t =
3321                 talloc_get_type_abort(data, struct torture_clusapi_context);
3322         struct policy_handle hKey;
3323         bool ret = true;
3324
3325         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3326                 return false;
3327         }
3328
3329         ret = test_EnumKey_int(tctx, t->p, &hKey);
3330
3331         test_CloseKey_int(tctx, t->p, &hKey);
3332
3333         return ret;
3334 }
3335
3336 static bool test_QueryValue_int(struct torture_context *tctx,
3337                                 struct dcerpc_pipe *p,
3338                                 struct policy_handle *hKey,
3339                                 const char *ValueName)
3340 {
3341         struct dcerpc_binding_handle *b = p->binding_handle;
3342         struct clusapi_QueryValue r;
3343         uint32_t lpValueType;
3344         uint32_t lpcbRequired;
3345         WERROR rpc_status;
3346
3347         r.in.hKey = *hKey;
3348         r.in.lpValueName = ValueName;
3349         r.in.cbData = 0;
3350         r.out.lpValueType = &lpValueType;
3351         r.out.lpData = NULL;
3352         r.out.lpcbRequired = &lpcbRequired;
3353         r.out.rpc_status = &rpc_status;
3354
3355         torture_assert_ntstatus_ok(tctx,
3356                 dcerpc_clusapi_QueryValue_r(b, tctx, &r),
3357                 "QueryValue failed");
3358
3359         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
3360
3361                 r.in.cbData = lpcbRequired;
3362                 r.out.lpData = talloc_zero_array(tctx, uint8_t, r.in.cbData);
3363
3364                 torture_assert_ntstatus_ok(tctx,
3365                         dcerpc_clusapi_QueryValue_r(b, tctx, &r),
3366                         "QueryValue failed");
3367         }
3368
3369         torture_assert_werr_ok(tctx,
3370                 r.out.result,
3371                 "QueryValue failed");
3372
3373         if (lpValueType == REG_SZ) {
3374                 const char *s;
3375                 DATA_BLOB blob = data_blob_const(r.out.lpData, lpcbRequired);
3376                 pull_reg_sz(tctx, &blob, &s);
3377                 torture_comment(tctx, "got: %s\n", s);
3378         }
3379
3380         return true;
3381 }
3382
3383 static bool test_QueryValue(struct torture_context *tctx,
3384                             void *data)
3385 {
3386         struct torture_clusapi_context *t =
3387                 talloc_get_type_abort(data, struct torture_clusapi_context);
3388         struct policy_handle hKey;
3389         bool ret = true;
3390
3391         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3392                 return false;
3393         }
3394
3395         ret = test_QueryValue_int(tctx, t->p, &hKey, "ClusterInstanceID");
3396
3397         test_CloseKey_int(tctx, t->p, &hKey);
3398
3399         return ret;
3400 }
3401
3402
3403 static bool test_one_key(struct torture_context *tctx,
3404                          struct dcerpc_pipe *p,
3405                          struct policy_handle *hKey,
3406                          const char *KeyName)
3407 {
3408         struct policy_handle phKey;
3409
3410         torture_assert(tctx,
3411                 test_OpenKey_int(tctx, p, hKey, KeyName, &phKey),
3412                 "failed to open key");
3413
3414         torture_assert(tctx,
3415                 test_QueryInfoKey_int(tctx, p, &phKey),
3416                 "failed to enum values");
3417         torture_assert(tctx,
3418                 test_GetKeySecurity_int(tctx, p, &phKey),
3419                 "failed to get key security");
3420
3421         torture_assert(tctx,
3422                 test_EnumValue_int(tctx, p, &phKey),
3423                 "failed to enum values");
3424
3425         torture_assert(tctx,
3426                 test_CloseKey_int(tctx, p, &phKey),
3427                 "failed to close key");
3428
3429         return true;
3430 }
3431
3432 static bool test_all_keys(struct torture_context *tctx,
3433                           void *data)
3434 {
3435         struct torture_clusapi_context *t =
3436                 talloc_get_type_abort(data, struct torture_clusapi_context);
3437         struct dcerpc_binding_handle *b = t->p->binding_handle;
3438         struct policy_handle hKey;
3439         struct clusapi_EnumKey r;
3440         const char *KeyName;
3441         NTTIME lpftLastWriteTime;
3442         WERROR rpc_status;
3443         int i = 0;
3444
3445         if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3446                 return false;
3447         }
3448
3449         do {
3450                 r.in.hKey = hKey;
3451                 r.in.dwIndex = i++;
3452                 r.out.KeyName = &KeyName;
3453                 r.out.lpftLastWriteTime = &lpftLastWriteTime;
3454                 r.out.rpc_status = &rpc_status;
3455
3456                 torture_assert_ntstatus_ok(tctx,
3457                         dcerpc_clusapi_EnumKey_r(b, tctx, &r),
3458                         "EnumKey failed");
3459
3460                 if (W_ERROR_IS_OK(r.out.result)) {
3461                         torture_assert(tctx,
3462                                 test_one_key(tctx, t->p, &hKey, KeyName),
3463                                 "failed to test one key");
3464                 }
3465
3466         } while (W_ERROR_IS_OK(r.out.result));
3467
3468         torture_assert_werr_equal(tctx,
3469                 r.out.result,
3470                 WERR_NO_MORE_ITEMS,
3471                 "EnumKey failed");
3472
3473         test_CloseKey_int(tctx, t->p, &hKey);
3474
3475         return true;
3476 }
3477
3478 static bool torture_rpc_clusapi_setup_common(struct torture_context *tctx,
3479                                              struct torture_clusapi_context *t)
3480 {
3481         struct dcerpc_binding_handle *b;
3482
3483         torture_assert_ntstatus_ok(tctx,
3484                 torture_rpc_connection(tctx, &t->p, &ndr_table_clusapi),
3485                 "Error connecting to server");
3486
3487         {
3488                 struct clusapi_GetClusterName r;
3489
3490                 b = t->p->binding_handle;
3491
3492                 r.out.ClusterName = &t->ClusterName;
3493                 r.out.NodeName = &t->NodeName;
3494
3495                 torture_assert_ntstatus_ok(tctx,
3496                         dcerpc_clusapi_GetClusterName_r(b, tctx, &r),
3497                         "GetClusterName failed");
3498                 torture_assert_werr_ok(tctx,
3499                         r.out.result,
3500                         "GetClusterName failed");
3501         }
3502
3503         return true;
3504 }
3505
3506 static bool torture_rpc_clusapi_setup(struct torture_context *tctx,
3507                                       void **data)
3508 {
3509         struct torture_clusapi_context *t;
3510
3511         *data = t = talloc_zero(tctx, struct torture_clusapi_context);
3512
3513         return torture_rpc_clusapi_setup_common(tctx, t);
3514 }
3515
3516 static bool torture_rpc_clusapi_teardown(struct torture_context *tctx,
3517                                          void *data)
3518 {
3519         talloc_free(data);
3520
3521         return true;
3522 }
3523
3524 void torture_tcase_cluster(struct torture_tcase *tcase)
3525 {
3526         torture_tcase_add_simple_test(tcase, "OpenCluster",
3527                                       test_OpenCluster);
3528         torture_tcase_add_simple_test(tcase, "OpenClusterEx",
3529                                       test_OpenClusterEx);
3530         torture_tcase_add_simple_test(tcase, "CloseCluster",
3531                                       test_CloseCluster);
3532         torture_tcase_add_simple_test(tcase, "SetClusterName",
3533                                       test_SetClusterName);
3534         torture_tcase_add_simple_test(tcase, "GetClusterName",
3535                                       test_GetClusterName);
3536         torture_tcase_add_simple_test(tcase, "GetClusterVersion",
3537                                       test_GetClusterVersion);
3538         torture_tcase_add_simple_test(tcase, "CreateEnum",
3539                                       test_CreateEnum);
3540         torture_tcase_add_simple_test(tcase, "CreateEnumEx",
3541                                       test_CreateEnumEx);
3542         torture_tcase_add_simple_test(tcase, "GetClusterVersion2",
3543                                       test_GetClusterVersion2);
3544         torture_tcase_add_simple_test(tcase, "BackupClusterDatabase",
3545                                       test_BackupClusterDatabase);
3546         torture_tcase_add_simple_test(tcase, "SetServiceAccountPassword",
3547                                       test_SetServiceAccountPassword);
3548         torture_tcase_add_simple_test(tcase, "ClusterControl",
3549                                       test_ClusterControl);
3550
3551 }
3552
3553 void torture_tcase_resource(struct torture_tcase *tcase)
3554 {
3555         struct torture_test *test;
3556
3557         torture_tcase_add_simple_test(tcase, "GetQuorumResource",
3558                                       test_GetQuorumResource);
3559         torture_tcase_add_simple_test(tcase, "SetQuorumResource",
3560                                       test_SetQuorumResource);
3561         torture_tcase_add_simple_test(tcase, "OpenResource",
3562                                       test_OpenResource);
3563         torture_tcase_add_simple_test(tcase, "OpenResourceEx",
3564                                       test_OpenResourceEx);
3565         torture_tcase_add_simple_test(tcase, "CloseResource",
3566                                       test_CloseResource);
3567         torture_tcase_add_simple_test(tcase, "CreateResource",
3568                                       test_CreateResource);
3569         torture_tcase_add_simple_test(tcase, "DeleteResource",
3570                                       test_DeleteResource);
3571         torture_tcase_add_simple_test(tcase, "SetResourceName",
3572                                       test_SetResourceName);
3573         torture_tcase_add_simple_test(tcase, "GetResourceState",
3574                                       test_GetResourceState);
3575         torture_tcase_add_simple_test(tcase, "GetResourceId",
3576                                       test_GetResourceId);
3577         torture_tcase_add_simple_test(tcase, "GetResourceType",
3578                                       test_GetResourceType);
3579         torture_tcase_add_simple_test(tcase, "CreateResEnum",
3580                                       test_CreateResEnum);
3581         test = torture_tcase_add_simple_test(tcase, "FailResource",
3582                                       test_FailResource);
3583         test->dangerous = true;
3584         torture_tcase_add_simple_test(tcase, "OnlineResource",
3585                                       test_OnlineResource);
3586         test = torture_tcase_add_simple_test(tcase, "OfflineResource",
3587                                       test_OfflineResource);
3588         test->dangerous = true;
3589         torture_tcase_add_simple_test(tcase, "GetResourceDependencyExpression",
3590                                       test_GetResourceDependencyExpression);
3591         torture_tcase_add_simple_test(tcase, "GetResourceNetworkName",
3592                                       test_GetResourceNetworkName);
3593         torture_tcase_add_simple_test(tcase, "all_resources",
3594                                       test_all_resources);
3595 }
3596
3597 void torture_tcase_resourcetype(struct torture_tcase *tcase)
3598 {
3599         torture_tcase_add_simple_test(tcase, "all_resourcetypes",
3600                                       test_all_resourcetypes);
3601 }
3602
3603 void torture_tcase_node(struct torture_tcase *tcase)
3604 {
3605         struct torture_test *test;
3606
3607         torture_tcase_add_simple_test(tcase, "OpenNode",
3608                                       test_OpenNode);
3609         torture_tcase_add_simple_test(tcase, "OpenNodeEx",
3610                                       test_OpenNodeEx);
3611         torture_tcase_add_simple_test(tcase, "CloseNode",
3612                                       test_CloseNode);
3613         torture_tcase_add_simple_test(tcase, "GetNodeState",
3614                                       test_GetNodeState);
3615         torture_tcase_add_simple_test(tcase, "GetNodeId",
3616                                       test_GetNodeId);
3617         torture_tcase_add_simple_test(tcase, "NodeControl",
3618                                       test_NodeControl);
3619         test = torture_tcase_add_simple_test(tcase, "PauseNode",
3620                                              test_PauseNode);
3621         test->dangerous = true;
3622         torture_tcase_add_simple_test(tcase, "ResumeNode",
3623                                       test_ResumeNode);
3624         test = torture_tcase_add_simple_test(tcase, "EvictNode",
3625                                              test_EvictNode);
3626         test->dangerous = true;
3627         torture_tcase_add_simple_test(tcase, "all_nodes",
3628                                       test_all_nodes);
3629 }
3630
3631 void torture_tcase_group(struct torture_tcase *tcase)
3632 {
3633         struct torture_test *test;
3634
3635         torture_tcase_add_simple_test(tcase, "OpenGroup",
3636                                       test_OpenGroup);
3637         torture_tcase_add_simple_test(tcase, "OpenGroupEx",
3638                                       test_OpenGroupEx);
3639         torture_tcase_add_simple_test(tcase, "CloseGroup",
3640                                       test_CloseGroup);
3641         torture_tcase_add_simple_test(tcase, "GetGroupState",
3642                                       test_GetGroupState);
3643         torture_tcase_add_simple_test(tcase, "GetGroupId",
3644                                       test_GetGroupId);
3645         torture_tcase_add_simple_test(tcase, "GroupControl",
3646                                       test_GroupControl);
3647         torture_tcase_add_simple_test(tcase, "OnlineGroup",
3648                                       test_OnlineGroup);
3649         test = torture_tcase_add_simple_test(tcase, "OfflineGroup",
3650                                       test_OfflineGroup);
3651         test->dangerous = true;
3652         torture_tcase_add_simple_test(tcase, "all_groups",
3653                                       test_all_groups);
3654 }
3655
3656 void torture_tcase_network(struct torture_tcase *tcase)
3657 {
3658         torture_tcase_add_simple_test(tcase, "OpenNetwork",
3659                                       test_OpenNetwork);
3660         torture_tcase_add_simple_test(tcase, "OpenNetworkEx",
3661                                       test_OpenNetworkEx);
3662         torture_tcase_add_simple_test(tcase, "CloseNetwork",
3663                                       test_CloseNetwork);
3664         torture_tcase_add_simple_test(tcase, "GetNetworkState",
3665                                       test_GetNetworkState);
3666         torture_tcase_add_simple_test(tcase, "GetNetworkId",
3667                                       test_GetNetworkId);
3668         torture_tcase_add_simple_test(tcase, "all_networks",
3669                                       test_all_networks);
3670 }
3671
3672 void torture_tcase_netinterface(struct torture_tcase *tcase)
3673 {
3674         torture_tcase_add_simple_test(tcase, "OpenNetInterface",
3675                                       test_OpenNetInterface);
3676         torture_tcase_add_simple_test(tcase, "OpenNetInterfaceEx",
3677                                       test_OpenNetInterfaceEx);
3678         torture_tcase_add_simple_test(tcase, "CloseNetInterface",
3679                                       test_CloseNetInterface);
3680         torture_tcase_add_simple_test(tcase, "GetNetInterfaceState",
3681                                       test_GetNetInterfaceState);
3682         torture_tcase_add_simple_test(tcase, "GetNetInterfaceId",
3683                                       test_GetNetInterfaceId);
3684         torture_tcase_add_simple_test(tcase, "all_netinterfaces",
3685                                       test_all_netinterfaces);
3686 }
3687
3688 void torture_tcase_registry(struct torture_tcase *tcase)
3689 {
3690         torture_tcase_add_simple_test(tcase, "GetRootKey",
3691                                       test_GetRootKey);
3692         torture_tcase_add_simple_test(tcase, "CloseKey",
3693                                       test_CloseKey);
3694         torture_tcase_add_simple_test(tcase, "EnumKey",
3695                                       test_EnumKey);
3696         torture_tcase_add_simple_test(tcase, "QueryValue",
3697                                       test_QueryValue);
3698         torture_tcase_add_simple_test(tcase, "all_keys",
3699                                       test_all_keys);
3700 }
3701
3702 struct torture_suite *torture_rpc_clusapi(TALLOC_CTX *mem_ctx)
3703 {
3704         struct torture_tcase *tcase;
3705         struct torture_suite *suite = torture_suite_create(mem_ctx, "clusapi");
3706
3707         tcase = torture_suite_add_tcase(suite, "cluster");
3708
3709         torture_tcase_set_fixture(tcase,
3710                                   torture_rpc_clusapi_setup,
3711                                   torture_rpc_clusapi_teardown);
3712
3713         torture_tcase_cluster(tcase);
3714
3715         tcase = torture_suite_add_tcase(suite, "resource");
3716
3717         torture_tcase_set_fixture(tcase,
3718                                   torture_rpc_clusapi_setup,
3719                                   torture_rpc_clusapi_teardown);
3720
3721         torture_tcase_resource(tcase);
3722
3723         tcase = torture_suite_add_tcase(suite, "resourcetype");
3724
3725         torture_tcase_set_fixture(tcase,
3726                                   torture_rpc_clusapi_setup,
3727                                   torture_rpc_clusapi_teardown);
3728
3729         torture_tcase_resourcetype(tcase);
3730
3731
3732         tcase = torture_suite_add_tcase(suite, "node");
3733
3734         torture_tcase_set_fixture(tcase,
3735                                   torture_rpc_clusapi_setup,
3736                                   torture_rpc_clusapi_teardown);
3737
3738         torture_tcase_node(tcase);
3739
3740         tcase = torture_suite_add_tcase(suite, "group");
3741
3742         torture_tcase_set_fixture(tcase,
3743                                   torture_rpc_clusapi_setup,
3744                                   torture_rpc_clusapi_teardown);
3745
3746         torture_tcase_group(tcase);
3747
3748         tcase = torture_suite_add_tcase(suite, "network");
3749
3750         torture_tcase_set_fixture(tcase,
3751                                   torture_rpc_clusapi_setup,
3752                                   torture_rpc_clusapi_teardown);
3753
3754         torture_tcase_network(tcase);
3755
3756         tcase = torture_suite_add_tcase(suite, "netinterface");
3757
3758         torture_tcase_set_fixture(tcase,
3759                                   torture_rpc_clusapi_setup,
3760                                   torture_rpc_clusapi_teardown);
3761
3762         torture_tcase_netinterface(tcase);
3763
3764         tcase = torture_suite_add_tcase(suite, "registry");
3765
3766         torture_tcase_set_fixture(tcase,
3767                                   torture_rpc_clusapi_setup,
3768                                   torture_rpc_clusapi_teardown);
3769
3770         torture_tcase_registry(tcase);
3771
3772         return suite;
3773 }