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 uint16_t lpwMajorVersion;
32 uint16_t lpwMinorVersion;
33 uint16_t lpwBuildNumber;
34 };
35
test_OpenCluster_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Cluster)36 static bool test_OpenCluster_int(struct torture_context *tctx,
37 struct dcerpc_pipe *p,
38 struct policy_handle *Cluster)
39 {
40 struct dcerpc_binding_handle *b = p->binding_handle;
41 struct clusapi_OpenCluster r;
42 WERROR Status;
43
44 r.out.Status = &Status;
45 r.out.Cluster = Cluster;
46
47 torture_assert_ntstatus_ok(tctx,
48 dcerpc_clusapi_OpenCluster_r(b, tctx, &r),
49 "OpenCluster failed");
50 torture_assert_werr_ok(tctx,
51 *r.out.Status,
52 "OpenCluster failed");
53
54 return true;
55 }
56
test_OpenClusterEx_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Cluster)57 static bool test_OpenClusterEx_int(struct torture_context *tctx,
58 struct dcerpc_pipe *p,
59 struct policy_handle *Cluster)
60 {
61 struct dcerpc_binding_handle *b = p->binding_handle;
62 struct clusapi_OpenClusterEx r;
63 uint32_t lpdwGrantedAccess;
64 WERROR Status;
65
66 r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
67 r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
68 r.out.Status = &Status;
69 r.out.hCluster = Cluster;
70
71 torture_assert_ntstatus_ok(tctx,
72 dcerpc_clusapi_OpenClusterEx_r(b, tctx, &r),
73 "OpenClusterEx failed");
74 torture_assert_werr_ok(tctx,
75 *r.out.Status,
76 "OpenClusterEx failed");
77
78 return true;
79 }
80
test_CloseCluster_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Cluster)81 static bool test_CloseCluster_int(struct torture_context *tctx,
82 struct dcerpc_pipe *p,
83 struct policy_handle *Cluster)
84 {
85 struct dcerpc_binding_handle *b = p->binding_handle;
86 struct clusapi_CloseCluster r;
87
88 r.in.Cluster = Cluster;
89 r.out.Cluster = Cluster;
90
91 torture_assert_ntstatus_ok(tctx,
92 dcerpc_clusapi_CloseCluster_r(b, tctx, &r),
93 "CloseCluster failed");
94 torture_assert_werr_ok(tctx,
95 r.out.result,
96 "CloseCluster failed");
97
98 torture_assert(tctx,
99 ndr_policy_handle_empty(Cluster),
100 "policy_handle non empty after CloseCluster");
101
102 return true;
103 }
104
test_OpenCluster(struct torture_context * tctx,void * data)105 static bool test_OpenCluster(struct torture_context *tctx,
106 void *data)
107 {
108 struct torture_clusapi_context *t =
109 talloc_get_type_abort(data, struct torture_clusapi_context);
110 struct policy_handle Cluster;
111
112 if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
113 return false;
114 }
115
116 test_CloseCluster_int(tctx, t->p, &Cluster);
117
118 return true;
119 }
120
test_OpenClusterEx(struct torture_context * tctx,void * data)121 static bool test_OpenClusterEx(struct torture_context *tctx,
122 void *data)
123 {
124 struct torture_clusapi_context *t =
125 talloc_get_type_abort(data, struct torture_clusapi_context);
126 struct policy_handle Cluster;
127
128 if (!test_OpenClusterEx_int(tctx, t->p, &Cluster)) {
129 return false;
130 }
131
132 test_CloseCluster_int(tctx, t->p, &Cluster);
133
134 return true;
135 }
136
test_CloseCluster(struct torture_context * tctx,void * data)137 static bool test_CloseCluster(struct torture_context *tctx,
138 void *data)
139 {
140 struct torture_clusapi_context *t =
141 talloc_get_type_abort(data, struct torture_clusapi_context);
142 struct policy_handle Cluster;
143
144 if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
145 return false;
146 }
147
148 return test_CloseCluster_int(tctx, t->p, &Cluster);
149 }
150
test_GetClusterName_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char ** ClusterName)151 static bool test_GetClusterName_int(struct torture_context *tctx,
152 struct dcerpc_pipe *p,
153 const char **ClusterName)
154 {
155 struct dcerpc_binding_handle *b = p->binding_handle;
156 struct clusapi_GetClusterName r;
157 const char *NodeName;
158
159 r.out.ClusterName = ClusterName;
160 r.out.NodeName = &NodeName;
161
162 torture_assert_ntstatus_ok(tctx,
163 dcerpc_clusapi_GetClusterName_r(b, tctx, &r),
164 "GetClusterName failed");
165 torture_assert_werr_ok(tctx,
166 r.out.result,
167 "GetClusterName failed");
168
169 return true;
170 }
171
test_SetClusterName(struct torture_context * tctx,void * data)172 static bool test_SetClusterName(struct torture_context *tctx,
173 void *data)
174 {
175 struct torture_clusapi_context *t =
176 talloc_get_type_abort(data, struct torture_clusapi_context);
177 struct dcerpc_binding_handle *b = t->p->binding_handle;
178 struct clusapi_SetClusterName r;
179 const char *NewClusterName;
180 WERROR rpc_status;
181
182 torture_assert(tctx,
183 test_GetClusterName_int(tctx, t->p, &NewClusterName),
184 "failed to query old ClusterName");
185
186 r.in.NewClusterName = NewClusterName;
187 r.out.rpc_status = &rpc_status;
188
189 torture_assert_ntstatus_ok(tctx,
190 dcerpc_clusapi_SetClusterName_r(b, tctx, &r),
191 "SetClusterName failed");
192 torture_assert_werr_equal(tctx,
193 r.out.result,
194 WERR_RESOURCE_PROPERTIES_STORED,
195 "SetClusterName failed");
196
197 return true;
198 }
199
test_GetClusterName(struct torture_context * tctx,void * data)200 static bool test_GetClusterName(struct torture_context *tctx,
201 void *data)
202 {
203 struct torture_clusapi_context *t =
204 talloc_get_type_abort(data, struct torture_clusapi_context);
205 const char *ClusterName;
206
207 return test_GetClusterName_int(tctx, t->p, &ClusterName);
208 }
209
test_GetClusterVersion(struct torture_context * tctx,void * data)210 static bool test_GetClusterVersion(struct torture_context *tctx,
211 void *data)
212 {
213 struct torture_clusapi_context *t =
214 talloc_get_type_abort(data, struct torture_clusapi_context);
215 struct dcerpc_binding_handle *b = t->p->binding_handle;
216 struct clusapi_GetClusterVersion r;
217 uint16_t lpwMajorVersion;
218 uint16_t lpwMinorVersion;
219 uint16_t lpwBuildNumber;
220 const char *lpszVendorId;
221 const char *lpszCSDVersion;
222
223 r.out.lpwMajorVersion = &lpwMajorVersion;
224 r.out.lpwMinorVersion = &lpwMinorVersion;
225 r.out.lpwBuildNumber = &lpwBuildNumber;
226 r.out.lpszVendorId = &lpszVendorId;
227 r.out.lpszCSDVersion = &lpszCSDVersion;
228
229 torture_assert_ntstatus_ok(tctx,
230 dcerpc_clusapi_GetClusterVersion_r(b, tctx, &r),
231 "GetClusterVersion failed");
232 torture_assert_werr_equal(tctx,
233 r.out.result,
234 WERR_CALL_NOT_IMPLEMENTED,
235 "GetClusterVersion failed");
236
237 return true;
238 }
239
test_GetClusterVersion2(struct torture_context * tctx,void * data)240 static bool test_GetClusterVersion2(struct torture_context *tctx,
241 void *data)
242 {
243 struct torture_clusapi_context *t =
244 talloc_get_type_abort(data, struct torture_clusapi_context);
245 struct dcerpc_binding_handle *b = t->p->binding_handle;
246 struct clusapi_GetClusterVersion2 r;
247 uint16_t lpwMajorVersion;
248 uint16_t lpwMinorVersion;
249 uint16_t lpwBuildNumber;
250 const char *lpszVendorId;
251 const char *lpszCSDVersion;
252 struct CLUSTER_OPERATIONAL_VERSION_INFO *ppClusterOpVerInfo;
253 WERROR rpc_status;
254
255 r.out.lpwMajorVersion = &lpwMajorVersion;
256 r.out.lpwMinorVersion = &lpwMinorVersion;
257 r.out.lpwBuildNumber = &lpwBuildNumber;
258 r.out.lpszVendorId = &lpszVendorId;
259 r.out.lpszCSDVersion = &lpszCSDVersion;
260 r.out.ppClusterOpVerInfo = &ppClusterOpVerInfo;
261 r.out.rpc_status = &rpc_status;
262
263 torture_assert_ntstatus_ok(tctx,
264 dcerpc_clusapi_GetClusterVersion2_r(b, tctx, &r),
265 "GetClusterVersion2 failed");
266 torture_assert_werr_ok(tctx,
267 r.out.result,
268 "GetClusterVersion2 failed");
269
270 return true;
271 }
272
test_CreateEnum(struct torture_context * tctx,void * data)273 static bool test_CreateEnum(struct torture_context *tctx,
274 void *data)
275 {
276 struct torture_clusapi_context *t =
277 talloc_get_type_abort(data, struct torture_clusapi_context);
278 struct dcerpc_binding_handle *b = t->p->binding_handle;
279 struct clusapi_CreateEnum r;
280 uint32_t dwType[] = {
281 CLUSTER_ENUM_NODE,
282 CLUSTER_ENUM_RESTYPE,
283 CLUSTER_ENUM_RESOURCE,
284 CLUSTER_ENUM_GROUP,
285 CLUSTER_ENUM_NETWORK,
286 CLUSTER_ENUM_NETINTERFACE,
287 CLUSTER_ENUM_INTERNAL_NETWORK,
288 CLUSTER_ENUM_SHARED_VOLUME_RESOURCE
289 };
290 uint32_t dwType_invalid[] = {
291 0x00000040,
292 0x00000080,
293 0x00000100 /* and many more ... */
294 };
295 struct ENUM_LIST *ReturnEnum;
296 WERROR rpc_status;
297 int i;
298
299 for (i=0; i < ARRAY_SIZE(dwType); i++) {
300
301 r.in.dwType = dwType[i];
302 r.out.ReturnEnum = &ReturnEnum;
303 r.out.rpc_status = &rpc_status;
304
305 torture_assert_ntstatus_ok(tctx,
306 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
307 "CreateEnum failed");
308 torture_assert_werr_ok(tctx,
309 r.out.result,
310 "CreateEnum failed");
311 }
312
313 for (i=0; i < ARRAY_SIZE(dwType_invalid); i++) {
314
315 r.in.dwType = dwType_invalid[i];
316 r.out.ReturnEnum = &ReturnEnum;
317 r.out.rpc_status = &rpc_status;
318
319 torture_assert_ntstatus_ok(tctx,
320 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
321 "CreateEnum failed");
322 torture_assert_werr_equal(tctx,
323 r.out.result,
324 WERR_INVALID_PARAMETER,
325 "CreateEnum failed");
326 }
327
328 return true;
329 }
330
test_CreateEnumEx_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Cluster)331 static bool test_CreateEnumEx_int(struct torture_context *tctx,
332 struct dcerpc_pipe *p,
333 struct policy_handle *Cluster)
334 {
335 struct dcerpc_binding_handle *b = p->binding_handle;
336 struct clusapi_CreateEnumEx r;
337 uint32_t dwType[] = {
338 CLUSTER_ENUM_NODE,
339 CLUSTER_ENUM_RESTYPE,
340 CLUSTER_ENUM_RESOURCE,
341 CLUSTER_ENUM_GROUP,
342 CLUSTER_ENUM_NETWORK,
343 CLUSTER_ENUM_NETINTERFACE,
344 CLUSTER_ENUM_INTERNAL_NETWORK,
345 CLUSTER_ENUM_SHARED_VOLUME_RESOURCE
346 };
347 uint32_t dwType_invalid[] = {
348 0x00000040,
349 0x00000080,
350 0x00000100 /* and many more ... */
351 };
352 struct ENUM_LIST *ReturnIdEnum;
353 struct ENUM_LIST *ReturnNameEnum;
354 WERROR rpc_status;
355 int i;
356
357 for (i=0; i < ARRAY_SIZE(dwType); i++) {
358
359 r.in.hCluster = *Cluster;
360 r.in.dwType = dwType[i];
361 r.in.dwOptions = 0;
362 r.out.ReturnIdEnum = &ReturnIdEnum;
363 r.out.ReturnNameEnum = &ReturnNameEnum;
364 r.out.rpc_status = &rpc_status;
365
366 torture_assert_ntstatus_ok(tctx,
367 dcerpc_clusapi_CreateEnumEx_r(b, tctx, &r),
368 "CreateEnumEx failed");
369 torture_assert_werr_ok(tctx,
370 r.out.result,
371 "CreateEnumEx failed");
372 }
373
374 for (i=0; i < ARRAY_SIZE(dwType_invalid); i++) {
375
376 r.in.hCluster = *Cluster;
377 r.in.dwType = dwType_invalid[i];
378 r.in.dwOptions = 0;
379 r.out.ReturnIdEnum = &ReturnIdEnum;
380 r.out.ReturnNameEnum = &ReturnNameEnum;
381 r.out.rpc_status = &rpc_status;
382
383 torture_assert_ntstatus_ok(tctx,
384 dcerpc_clusapi_CreateEnumEx_r(b, tctx, &r),
385 "CreateEnumEx failed");
386 torture_assert_werr_equal(tctx,
387 r.out.result,
388 WERR_INVALID_PARAMETER,
389 "CreateEnumEx failed");
390 }
391
392 return true;
393 }
394
test_CreateEnumEx(struct torture_context * tctx,void * data)395 static bool test_CreateEnumEx(struct torture_context *tctx,
396 void *data)
397 {
398 struct torture_clusapi_context *t =
399 talloc_get_type_abort(data, struct torture_clusapi_context);
400 struct policy_handle Cluster;
401 bool ret;
402
403 if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
404 return false;
405 }
406
407 ret = test_CreateEnumEx_int(tctx, t->p, &Cluster);
408
409 test_CloseCluster_int(tctx, t->p, &Cluster);
410
411 return ret;
412 }
413
414
test_GetQuorumResource(struct torture_context * tctx,void * data)415 static bool test_GetQuorumResource(struct torture_context *tctx,
416 void *data)
417 {
418 struct torture_clusapi_context *t =
419 talloc_get_type_abort(data, struct torture_clusapi_context);
420 struct dcerpc_binding_handle *b = t->p->binding_handle;
421 struct clusapi_GetQuorumResource r;
422 const char *lpszResourceName;
423 const char *lpszDeviceName;
424 uint32_t pdwMaxQuorumLogSize;
425 WERROR rpc_status;
426
427 r.out.lpszResourceName = &lpszResourceName;
428 r.out.lpszDeviceName = &lpszDeviceName;
429 r.out.pdwMaxQuorumLogSize = &pdwMaxQuorumLogSize;
430 r.out.rpc_status = &rpc_status;
431
432 torture_assert_ntstatus_ok(tctx,
433 dcerpc_clusapi_GetQuorumResource_r(b, tctx, &r),
434 "GetQuorumResource failed");
435 torture_assert_werr_ok(tctx,
436 r.out.result,
437 "GetQuorumResource failed");
438
439 return true;
440 }
441
test_SetQuorumResource(struct torture_context * tctx,void * data)442 static bool test_SetQuorumResource(struct torture_context *tctx,
443 void *data)
444 {
445 struct torture_clusapi_context *t =
446 talloc_get_type_abort(data, struct torture_clusapi_context);
447 struct dcerpc_binding_handle *b = t->p->binding_handle;
448 struct clusapi_SetQuorumResource r;
449 const char *lpszDeviceName = "";
450 uint32_t dwMaxQuorumLogSize = 0;
451 WERROR rpc_status;
452 struct policy_handle hResource;
453
454 /* we need to figure out how this call works and what we provide as
455 devicename and resource handle - gd
456 */
457
458 torture_skip(tctx, "skipping SetQuorumResource test");
459
460 ZERO_STRUCT(hResource);
461
462 r.in.hResource = hResource;
463 r.in.lpszDeviceName = lpszDeviceName;
464 r.in.dwMaxQuorumLogSize = dwMaxQuorumLogSize;
465 r.out.rpc_status = &rpc_status;
466
467 torture_assert_ntstatus_ok(tctx,
468 dcerpc_clusapi_SetQuorumResource_r(b, tctx, &r),
469 "SetQuorumResource failed");
470 torture_assert_werr_ok(tctx,
471 r.out.result,
472 "SetQuorumResource failed");
473
474 return true;
475 }
476
test_OpenResource_int_exp(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszResourceName,struct policy_handle * hResource,WERROR expected_Status,WERROR expected_rpc_status)477 static bool test_OpenResource_int_exp(struct torture_context *tctx,
478 struct dcerpc_pipe *p,
479 const char *lpszResourceName,
480 struct policy_handle *hResource,
481 WERROR expected_Status,
482 WERROR expected_rpc_status)
483 {
484 struct dcerpc_binding_handle *b = p->binding_handle;
485 struct clusapi_OpenResource r;
486 WERROR Status;
487 WERROR rpc_status;
488
489 r.in.lpszResourceName = lpszResourceName;
490 r.out.rpc_status = &rpc_status;
491 r.out.Status = &Status;
492 r.out.hResource = hResource;
493
494 torture_assert_ntstatus_ok(tctx,
495 dcerpc_clusapi_OpenResource_r(b, tctx, &r),
496 "OpenResource failed");
497 torture_assert_werr_equal(tctx,
498 *r.out.Status, expected_Status,
499 "OpenResource failed");
500 torture_assert_werr_equal(tctx,
501 *r.out.rpc_status, expected_rpc_status,
502 "OpenResource failed");
503
504 return true;
505 }
506
test_OpenResource_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszResourceName,struct policy_handle * hResource)507 bool test_OpenResource_int(struct torture_context *tctx,
508 struct dcerpc_pipe *p,
509 const char *lpszResourceName,
510 struct policy_handle *hResource)
511 {
512 return test_OpenResource_int_exp(tctx, p,
513 lpszResourceName,
514 hResource,
515 WERR_OK, WERR_OK);
516 }
517
test_OpenResourceEx_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszResourceName,struct policy_handle * hResource)518 static bool test_OpenResourceEx_int(struct torture_context *tctx,
519 struct dcerpc_pipe *p,
520 const char *lpszResourceName,
521 struct policy_handle *hResource)
522 {
523 struct dcerpc_binding_handle *b = p->binding_handle;
524 struct clusapi_OpenResourceEx r;
525 uint32_t lpdwGrantedAccess;
526 WERROR Status;
527 WERROR rpc_status;
528
529 r.in.lpszResourceName = lpszResourceName;
530 r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
531 r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
532 r.out.rpc_status = &rpc_status;
533 r.out.Status = &Status;
534 r.out.hResource = hResource;
535
536 torture_assert_ntstatus_ok(tctx,
537 dcerpc_clusapi_OpenResourceEx_r(b, tctx, &r),
538 "OpenResourceEx failed");
539 torture_assert_werr_ok(tctx,
540 *r.out.Status,
541 "OpenResourceEx failed");
542
543 return true;
544 }
545
test_CloseResource_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)546 bool test_CloseResource_int(struct torture_context *tctx,
547 struct dcerpc_pipe *p,
548 struct policy_handle *hResource)
549 {
550 struct dcerpc_binding_handle *b = p->binding_handle;
551 struct clusapi_CloseResource r;
552
553 r.in.Resource = hResource;
554 r.out.Resource = hResource;
555
556 torture_assert_ntstatus_ok(tctx,
557 dcerpc_clusapi_CloseResource_r(b, tctx, &r),
558 "CloseResource failed");
559 torture_assert_werr_ok(tctx,
560 r.out.result,
561 "CloseResource failed");
562 torture_assert(tctx,
563 ndr_policy_handle_empty(hResource),
564 "policy_handle non empty after CloseResource");
565
566 return true;
567 }
568
test_OpenResource(struct torture_context * tctx,void * data)569 static bool test_OpenResource(struct torture_context *tctx,
570 void *data)
571 {
572 struct torture_clusapi_context *t =
573 talloc_get_type_abort(data, struct torture_clusapi_context);
574 struct policy_handle hResource;
575
576 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
577 return false;
578 }
579
580 test_CloseResource_int(tctx, t->p, &hResource);
581
582 if (!test_OpenResource_int_exp(tctx, t->p, "", &hResource, WERR_RESOURCE_NOT_FOUND, WERR_OK)) {
583 return false;
584 }
585
586 torture_assert(tctx,
587 ndr_policy_handle_empty(&hResource),
588 "expected empty policy handle");
589
590 if (!test_OpenResource_int_exp(tctx, t->p, "jfUF38fjSNcfn", &hResource, WERR_RESOURCE_NOT_FOUND, WERR_OK)) {
591 return false;
592 }
593
594 torture_assert(tctx,
595 ndr_policy_handle_empty(&hResource),
596 "expected empty policy handle");
597
598 return true;
599 }
600
test_OpenResourceEx(struct torture_context * tctx,void * data)601 static bool test_OpenResourceEx(struct torture_context *tctx,
602 void *data)
603 {
604 struct torture_clusapi_context *t =
605 talloc_get_type_abort(data, struct torture_clusapi_context);
606 struct policy_handle hResource;
607
608 if (!test_OpenResourceEx_int(tctx, t->p, "Cluster Name", &hResource)) {
609 return false;
610 }
611
612 test_CloseResource_int(tctx, t->p, &hResource);
613
614 return true;
615 }
616
617
test_CloseResource(struct torture_context * tctx,void * data)618 static bool test_CloseResource(struct torture_context *tctx,
619 void *data)
620 {
621 struct torture_clusapi_context *t =
622 talloc_get_type_abort(data, struct torture_clusapi_context);
623 struct policy_handle hResource;
624
625 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
626 return false;
627 }
628
629 return test_CloseResource_int(tctx, t->p, &hResource);
630 }
631
632 static bool test_OpenGroup_int(struct torture_context *tctx,
633 struct dcerpc_pipe *p,
634 const char *lpszGroupName,
635 struct policy_handle *hGroup);
636 static bool test_CloseGroup_int(struct torture_context *tctx,
637 struct dcerpc_pipe *p,
638 struct policy_handle *Group);
639
test_CreateResource_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)640 static bool test_CreateResource_int(struct torture_context *tctx,
641 struct dcerpc_pipe *p,
642 struct policy_handle *hResource)
643 {
644 struct dcerpc_binding_handle *b = p->binding_handle;
645 struct clusapi_CreateResource r;
646 const char *lpszResourceName = "wurst";
647 const char *lpszResourceType = "Generic Service";
648 WERROR Status;
649 WERROR rpc_status;
650 struct policy_handle hGroup;
651
652 torture_assert(tctx,
653 test_OpenGroup_int(tctx, p, "Cluster Group", &hGroup),
654 "failed to open group");
655
656 r.in.hGroup = hGroup;
657 r.in.lpszResourceName = lpszResourceName;
658 r.in.lpszResourceType = lpszResourceType;
659 r.in.dwFlags = CLUSTER_RESOURCE_DEFAULT_MONITOR;
660 r.out.rpc_status = &rpc_status;
661 r.out.Status = &Status;
662 r.out.hResource = hResource;
663
664 torture_assert_ntstatus_ok(tctx,
665 dcerpc_clusapi_CreateResource_r(b, tctx, &r),
666 "CreateResource failed");
667 torture_assert_werr_ok(tctx,
668 *r.out.Status,
669 "CreateResource failed");
670
671 test_CloseGroup_int(tctx, p, &hGroup);
672
673 return true;
674 }
675
test_DeleteResource_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)676 static bool test_DeleteResource_int(struct torture_context *tctx,
677 struct dcerpc_pipe *p,
678 struct policy_handle *hResource)
679 {
680 struct dcerpc_binding_handle *b = p->binding_handle;
681 struct clusapi_DeleteResource r;
682 WERROR rpc_status;
683
684 r.in.hResource = *hResource;
685 r.out.rpc_status = &rpc_status;
686
687 torture_assert_ntstatus_ok(tctx,
688 dcerpc_clusapi_DeleteResource_r(b, tctx, &r),
689 "DeleteResource failed");
690 torture_assert_werr_ok(tctx,
691 r.out.result,
692 "DeleteResource failed");
693
694 return true;
695 }
696
test_CreateResource(struct torture_context * tctx,void * data)697 static bool test_CreateResource(struct torture_context *tctx,
698 void *data)
699 {
700 struct torture_clusapi_context *t =
701 talloc_get_type_abort(data, struct torture_clusapi_context);
702 struct policy_handle hResource;
703
704 if (!test_CreateResource_int(tctx, t->p, &hResource)) {
705 return false;
706 }
707
708 test_DeleteResource_int(tctx, t->p, &hResource);
709
710 return true;
711 }
712
test_DeleteResource(struct torture_context * tctx,void * data)713 static bool test_DeleteResource(struct torture_context *tctx,
714 void *data)
715 {
716 struct torture_clusapi_context *t =
717 talloc_get_type_abort(data, struct torture_clusapi_context);
718 struct policy_handle hResource;
719
720 if (!test_CreateResource_int(tctx, t->p, &hResource)) {
721 return false;
722 }
723
724 return test_DeleteResource_int(tctx, t->p, &hResource);
725 }
726
test_SetResourceName_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)727 static bool test_SetResourceName_int(struct torture_context *tctx,
728 struct dcerpc_pipe *p,
729 struct policy_handle *hResource)
730 {
731 struct dcerpc_binding_handle *b = p->binding_handle;
732 struct clusapi_SetResourceName r;
733 WERROR rpc_status;
734
735 r.in.hResource = *hResource;
736 r.in.lpszResourceName = "wurst";
737 r.out.rpc_status = &rpc_status;
738
739 torture_assert_ntstatus_ok(tctx,
740 dcerpc_clusapi_SetResourceName_r(b, tctx, &r),
741 "SetResourceName failed");
742 torture_assert_werr_ok(tctx,
743 r.out.result,
744 "SetResourceName failed");
745
746 return true;
747 }
748
test_SetResourceName(struct torture_context * tctx,void * data)749 static bool test_SetResourceName(struct torture_context *tctx,
750 void *data)
751 {
752 struct torture_clusapi_context *t =
753 talloc_get_type_abort(data, struct torture_clusapi_context);
754 struct policy_handle hResource;
755 bool ret = true;
756
757 if (!test_CreateResource_int(tctx, t->p, &hResource)) {
758 return false;
759 }
760
761 ret = test_SetResourceName_int(tctx, t->p, &hResource);
762
763 test_DeleteResource_int(tctx, t->p, &hResource);
764
765 return ret;
766 }
767
test_GetResourceState_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)768 static bool test_GetResourceState_int(struct torture_context *tctx,
769 struct dcerpc_pipe *p,
770 struct policy_handle *hResource)
771 {
772 struct dcerpc_binding_handle *b = p->binding_handle;
773 struct clusapi_GetResourceState r;
774 enum clusapi_ClusterResourceState State;
775 const char *NodeName;
776 const char *GroupName;
777 WERROR rpc_status;
778
779 r.in.hResource = *hResource;
780 r.out.State = &State;
781 r.out.NodeName = &NodeName;
782 r.out.GroupName = &GroupName;
783 r.out.rpc_status = &rpc_status;
784
785 torture_assert_ntstatus_ok(tctx,
786 dcerpc_clusapi_GetResourceState_r(b, tctx, &r),
787 "GetResourceState failed");
788 torture_assert_werr_ok(tctx,
789 r.out.result,
790 "GetResourceState failed");
791
792 return true;
793 }
794
test_GetResourceState(struct torture_context * tctx,void * data)795 static bool test_GetResourceState(struct torture_context *tctx,
796 void *data)
797 {
798 struct torture_clusapi_context *t =
799 talloc_get_type_abort(data, struct torture_clusapi_context);
800 struct policy_handle hResource;
801 bool ret = true;
802
803 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
804 return false;
805 }
806
807 ret = test_GetResourceState_int(tctx, t->p, &hResource);
808
809 test_CloseResource_int(tctx, t->p, &hResource);
810
811 return ret;
812 }
813
test_GetResourceId_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)814 static bool test_GetResourceId_int(struct torture_context *tctx,
815 struct dcerpc_pipe *p,
816 struct policy_handle *hResource)
817 {
818 struct dcerpc_binding_handle *b = p->binding_handle;
819 struct clusapi_GetResourceId r;
820 const char *pGuid;
821 WERROR rpc_status;
822
823 r.in.hResource = *hResource;
824 r.out.pGuid = &pGuid;
825 r.out.rpc_status = &rpc_status;
826
827 torture_assert_ntstatus_ok(tctx,
828 dcerpc_clusapi_GetResourceId_r(b, tctx, &r),
829 "GetResourceId failed");
830 torture_assert_werr_ok(tctx,
831 r.out.result,
832 "GetResourceId failed");
833
834 return true;
835 }
836
test_GetResourceId(struct torture_context * tctx,void * data)837 static bool test_GetResourceId(struct torture_context *tctx,
838 void *data)
839 {
840 struct torture_clusapi_context *t =
841 talloc_get_type_abort(data, struct torture_clusapi_context);
842 struct policy_handle hResource;
843 bool ret = true;
844
845 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
846 return false;
847 }
848
849 ret = test_GetResourceId_int(tctx, t->p, &hResource);
850
851 test_CloseResource_int(tctx, t->p, &hResource);
852
853 return ret;
854 }
855
test_GetResourceType_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)856 static bool test_GetResourceType_int(struct torture_context *tctx,
857 struct dcerpc_pipe *p,
858 struct policy_handle *hResource)
859 {
860 struct dcerpc_binding_handle *b = p->binding_handle;
861 struct clusapi_GetResourceType r;
862 const char *lpszResourceType;
863 WERROR rpc_status;
864
865 r.in.hResource = *hResource;
866 r.out.lpszResourceType = &lpszResourceType;
867 r.out.rpc_status = &rpc_status;
868
869 torture_assert_ntstatus_ok(tctx,
870 dcerpc_clusapi_GetResourceType_r(b, tctx, &r),
871 "GetResourceType failed");
872 torture_assert_werr_ok(tctx,
873 r.out.result,
874 "GetResourceType failed");
875
876 return true;
877 }
878
test_GetResourceType(struct torture_context * tctx,void * data)879 static bool test_GetResourceType(struct torture_context *tctx,
880 void *data)
881 {
882 struct torture_clusapi_context *t =
883 talloc_get_type_abort(data, struct torture_clusapi_context);
884 struct policy_handle hResource;
885 bool ret = true;
886
887 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
888 return false;
889 }
890
891 ret = test_GetResourceType_int(tctx, t->p, &hResource);
892
893 test_CloseResource_int(tctx, t->p, &hResource);
894
895 return ret;
896 }
897
test_FailResource_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)898 static bool test_FailResource_int(struct torture_context *tctx,
899 struct dcerpc_pipe *p,
900 struct policy_handle *hResource)
901 {
902 struct dcerpc_binding_handle *b = p->binding_handle;
903 struct clusapi_FailResource r;
904 WERROR rpc_status;
905
906 r.in.hResource = *hResource;
907 r.out.rpc_status = &rpc_status;
908
909 torture_assert_ntstatus_ok(tctx,
910 dcerpc_clusapi_FailResource_r(b, tctx, &r),
911 "FailResource failed");
912 torture_assert_werr_ok(tctx,
913 r.out.result,
914 "FailResource failed");
915
916 return true;
917 }
918
test_FailResource(struct torture_context * tctx,void * data)919 static bool test_FailResource(struct torture_context *tctx,
920 void *data)
921 {
922 struct torture_clusapi_context *t =
923 talloc_get_type_abort(data, struct torture_clusapi_context);
924 struct policy_handle hResource;
925 bool ret = true;
926
927 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
928 return false;
929 }
930
931 ret = test_FailResource_int(tctx, t->p, &hResource);
932
933 test_CloseResource_int(tctx, t->p, &hResource);
934
935 return ret;
936 }
937
test_OnlineResource_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)938 bool test_OnlineResource_int(struct torture_context *tctx,
939 struct dcerpc_pipe *p,
940 struct policy_handle *hResource)
941 {
942 struct dcerpc_binding_handle *b = p->binding_handle;
943 struct clusapi_OnlineResource r;
944 WERROR rpc_status;
945
946 r.in.hResource = *hResource;
947 r.out.rpc_status = &rpc_status;
948
949 torture_assert_ntstatus_ok(tctx,
950 dcerpc_clusapi_OnlineResource_r(b, tctx, &r),
951 "OnlineResource failed");
952 if (!W_ERROR_IS_OK(r.out.result) &&
953 !W_ERROR_EQUAL(r.out.result, WERR_IO_PENDING)) {
954 torture_result(tctx, TORTURE_FAIL,
955 "OnlineResource failed with %s",
956 win_errstr(r.out.result));
957 return false;
958 }
959
960 return true;
961 }
962
test_OnlineResource(struct torture_context * tctx,void * data)963 static bool test_OnlineResource(struct torture_context *tctx,
964 void *data)
965 {
966 struct torture_clusapi_context *t =
967 talloc_get_type_abort(data, struct torture_clusapi_context);
968 struct policy_handle hResource;
969 bool ret = true;
970
971 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
972 return false;
973 }
974
975 ret = test_OnlineResource_int(tctx, t->p, &hResource);
976
977 test_CloseResource_int(tctx, t->p, &hResource);
978
979 return ret;
980 }
981
test_OfflineResource_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)982 bool test_OfflineResource_int(struct torture_context *tctx,
983 struct dcerpc_pipe *p,
984 struct policy_handle *hResource)
985 {
986 struct dcerpc_binding_handle *b = p->binding_handle;
987 struct clusapi_OfflineResource r;
988 WERROR rpc_status;
989
990 r.in.hResource = *hResource;
991 r.out.rpc_status = &rpc_status;
992
993 torture_assert_ntstatus_ok(tctx,
994 dcerpc_clusapi_OfflineResource_r(b, tctx, &r),
995 "OfflineResource failed");
996 if (!W_ERROR_IS_OK(r.out.result) &&
997 !W_ERROR_EQUAL(r.out.result, WERR_IO_PENDING)) {
998 torture_result(tctx, TORTURE_FAIL,
999 "OfflineResource failed with %s",
1000 win_errstr(r.out.result));
1001 return false;
1002 }
1003
1004 return true;
1005 }
1006
test_OfflineResource(struct torture_context * tctx,void * data)1007 static bool test_OfflineResource(struct torture_context *tctx,
1008 void *data)
1009 {
1010 struct torture_clusapi_context *t =
1011 talloc_get_type_abort(data, struct torture_clusapi_context);
1012 struct policy_handle hResource;
1013 bool ret = true;
1014
1015 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1016 return false;
1017 }
1018
1019 ret = test_OfflineResource_int(tctx, t->p, &hResource);
1020
1021 test_CloseResource_int(tctx, t->p, &hResource);
1022
1023 return ret;
1024 }
1025
test_CreateResEnum_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)1026 static bool test_CreateResEnum_int(struct torture_context *tctx,
1027 struct dcerpc_pipe *p,
1028 struct policy_handle *hResource)
1029 {
1030 struct dcerpc_binding_handle *b = p->binding_handle;
1031 struct clusapi_CreateResEnum r;
1032 uint32_t dwType = CLUSTER_ENUM_RESOURCE;
1033 struct ENUM_LIST *ReturnEnum;
1034 WERROR rpc_status;
1035
1036 r.in.hResource = *hResource;
1037 r.in.dwType = dwType;
1038 r.out.ReturnEnum = &ReturnEnum;
1039 r.out.rpc_status = &rpc_status;
1040
1041 torture_assert_ntstatus_ok(tctx,
1042 dcerpc_clusapi_CreateResEnum_r(b, tctx, &r),
1043 "CreateResEnum failed");
1044 torture_assert_werr_ok(tctx,
1045 r.out.result,
1046 "CreateResEnum failed");
1047
1048 return true;
1049 }
1050
test_CreateResEnum(struct torture_context * tctx,void * data)1051 static bool test_CreateResEnum(struct torture_context *tctx,
1052 void *data)
1053 {
1054 struct torture_clusapi_context *t =
1055 talloc_get_type_abort(data, struct torture_clusapi_context);
1056 struct policy_handle hResource;
1057 bool ret = true;
1058
1059 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1060 return false;
1061 }
1062
1063 ret = test_CreateResEnum_int(tctx, t->p, &hResource);
1064
1065 test_CloseResource_int(tctx, t->p, &hResource);
1066
1067 return ret;
1068 }
1069
test_GetResourceDependencyExpression_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)1070 static bool test_GetResourceDependencyExpression_int(struct torture_context *tctx,
1071 struct dcerpc_pipe *p,
1072 struct policy_handle *hResource)
1073 {
1074 struct dcerpc_binding_handle *b = p->binding_handle;
1075 struct clusapi_GetResourceDependencyExpression r;
1076 const char *lpszDependencyExpression;
1077 WERROR rpc_status;
1078
1079 r.in.hResource = *hResource;
1080 r.out.lpszDependencyExpression = &lpszDependencyExpression;
1081 r.out.rpc_status = &rpc_status;
1082
1083 torture_assert_ntstatus_ok(tctx,
1084 dcerpc_clusapi_GetResourceDependencyExpression_r(b, tctx, &r),
1085 "GetResourceDependencyExpression failed");
1086 torture_assert_werr_ok(tctx,
1087 r.out.result,
1088 "GetResourceDependencyExpression failed");
1089
1090 return true;
1091 }
1092
test_GetResourceDependencyExpression(struct torture_context * tctx,void * data)1093 static bool test_GetResourceDependencyExpression(struct torture_context *tctx,
1094 void *data)
1095 {
1096 struct torture_clusapi_context *t =
1097 talloc_get_type_abort(data, struct torture_clusapi_context);
1098 struct policy_handle hResource;
1099 bool ret = true;
1100
1101 if (!test_OpenResource_int(tctx, t->p, "Cluster Name", &hResource)) {
1102 return false;
1103 }
1104
1105 ret = test_GetResourceDependencyExpression_int(tctx, t->p, &hResource);
1106
1107 test_CloseResource_int(tctx, t->p, &hResource);
1108
1109 return ret;
1110 }
1111
test_GetResourceNetworkName_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hResource)1112 static bool test_GetResourceNetworkName_int(struct torture_context *tctx,
1113 struct dcerpc_pipe *p,
1114 struct policy_handle *hResource)
1115 {
1116 struct dcerpc_binding_handle *b = p->binding_handle;
1117 struct clusapi_GetResourceNetworkName r;
1118 const char *lpszName;
1119 WERROR rpc_status;
1120
1121 r.in.hResource = *hResource;
1122 r.out.lpszName = &lpszName;
1123 r.out.rpc_status = &rpc_status;
1124
1125 torture_assert_ntstatus_ok(tctx,
1126 dcerpc_clusapi_GetResourceNetworkName_r(b, tctx, &r),
1127 "GetResourceNetworkName failed");
1128 torture_assert_werr_ok(tctx,
1129 r.out.result,
1130 "GetResourceNetworkName failed");
1131
1132 return true;
1133 }
1134
test_GetResourceNetworkName(struct torture_context * tctx,void * data)1135 static bool test_GetResourceNetworkName(struct torture_context *tctx,
1136 void *data)
1137 {
1138 struct torture_clusapi_context *t =
1139 talloc_get_type_abort(data, struct torture_clusapi_context);
1140 struct policy_handle hResource;
1141 bool ret = true;
1142
1143 if (!test_OpenResource_int(tctx, t->p, "Network Name", &hResource)) {
1144 return false;
1145 }
1146
1147 ret = test_GetResourceNetworkName_int(tctx, t->p, &hResource);
1148
1149 test_CloseResource_int(tctx, t->p, &hResource);
1150
1151 return ret;
1152 }
1153
test_ResourceTypeControl_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Cluster,const char * resource_type,enum clusapi_ResourceTypeControlCode dwControlCode)1154 static bool test_ResourceTypeControl_int(struct torture_context *tctx,
1155 struct dcerpc_pipe *p,
1156 struct policy_handle *Cluster,
1157 const char *resource_type,
1158 enum clusapi_ResourceTypeControlCode dwControlCode)
1159 {
1160 struct dcerpc_binding_handle *b = p->binding_handle;
1161 struct clusapi_ResourceTypeControl r;
1162 uint32_t lpBytesReturned;
1163 uint32_t lpcbRequired;
1164 WERROR rpc_status;
1165
1166 r.in.hCluster = *Cluster;
1167 r.in.lpszResourceTypeName = resource_type;
1168 r.in.dwControlCode = 0;
1169 r.in.lpInBuffer = NULL;
1170 r.in.nInBufferSize = 0;
1171 r.in.nOutBufferSize = 0;
1172 r.out.lpOutBuffer = NULL;
1173 r.out.lpBytesReturned = &lpBytesReturned;
1174 r.out.lpcbRequired = &lpcbRequired;
1175 r.out.rpc_status = &rpc_status;
1176
1177 torture_assert_ntstatus_ok(tctx,
1178 dcerpc_clusapi_ResourceTypeControl_r(b, tctx, &r),
1179 "ResourceTypeControl failed");
1180
1181 if (strequal(r.in.lpszResourceTypeName, "MSMQ") ||
1182 strequal(r.in.lpszResourceTypeName, "MSMQTriggers")) {
1183 torture_assert_werr_equal(tctx,
1184 r.out.result,
1185 WERR_CLUSTER_RESTYPE_NOT_SUPPORTED,
1186 "ResourceTypeControl failed");
1187 return true;
1188 }
1189
1190 torture_assert_werr_equal(tctx,
1191 r.out.result,
1192 WERR_INVALID_FUNCTION,
1193 "ResourceTypeControl failed");
1194
1195 r.in.dwControlCode = dwControlCode;
1196
1197 torture_assert_ntstatus_ok(tctx,
1198 dcerpc_clusapi_ResourceTypeControl_r(b, tctx, &r),
1199 "ResourceTypeControl failed");
1200
1201 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1202 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
1203 r.in.nOutBufferSize = *r.out.lpcbRequired;
1204 torture_assert_ntstatus_ok(tctx,
1205 dcerpc_clusapi_ResourceTypeControl_r(b, tctx, &r),
1206 "ResourceTypeControl failed");
1207 }
1208 torture_assert_werr_ok(tctx,
1209 r.out.result,
1210 "ResourceTypeControl failed");
1211
1212 /* now try what happens when we query with a buffer large enough to hold
1213 * the entire packet */
1214
1215 r.in.nOutBufferSize = 0x4000;
1216 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
1217
1218 torture_assert_ntstatus_ok(tctx,
1219 dcerpc_clusapi_ResourceTypeControl_r(b, tctx, &r),
1220 "ResourceTypeControl failed");
1221 torture_assert_werr_ok(tctx,
1222 r.out.result,
1223 "ResourceTypeControl failed");
1224 torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
1225 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
1226
1227 return true;
1228 }
1229
test_ResourceTypeControl(struct torture_context * tctx,struct dcerpc_pipe * p,const char * resourcetype_name)1230 static bool test_ResourceTypeControl(struct torture_context *tctx,
1231 struct dcerpc_pipe *p,
1232 const char *resourcetype_name)
1233 {
1234 struct policy_handle Cluster;
1235 bool ret;
1236 uint32_t control_codes[] = {
1237 CLUSCTL_RESOURCE_TYPE_GET_CLASS_INFO,
1238 CLUSCTL_RESOURCE_TYPE_GET_CHARACTERISTICS,
1239 CLUSCTL_RESOURCE_TYPE_GET_COMMON_PROPERTIES,
1240 CLUSCTL_RESOURCE_TYPE_GET_RO_COMMON_PROPERTIES,
1241 CLUSCTL_RESOURCE_TYPE_GET_PRIVATE_PROPERTIES
1242 };
1243 int i;
1244
1245 if (!test_OpenCluster_int(tctx, p, &Cluster)) {
1246 return false;
1247 }
1248
1249 for (i=0; i < ARRAY_SIZE(control_codes); i++) {
1250 ret = test_ResourceTypeControl_int(tctx, p, &Cluster,
1251 resourcetype_name,
1252 control_codes[i]);
1253 if (!ret) {
1254 goto done;
1255 }
1256 }
1257
1258 done:
1259 test_CloseCluster_int(tctx, p, &Cluster);
1260
1261 return ret;
1262 }
1263
1264
1265
test_one_resourcetype(struct torture_context * tctx,struct dcerpc_pipe * p,const char * resourcetype_name)1266 static bool test_one_resourcetype(struct torture_context *tctx,
1267 struct dcerpc_pipe *p,
1268 const char *resourcetype_name)
1269 {
1270 torture_assert(tctx,
1271 test_ResourceTypeControl(tctx, p, resourcetype_name),
1272 "failed to query ResourceTypeControl");
1273
1274 return true;
1275 }
1276
test_one_resource(struct torture_context * tctx,struct dcerpc_pipe * p,const char * resource_name)1277 static bool test_one_resource(struct torture_context *tctx,
1278 struct dcerpc_pipe *p,
1279 const char *resource_name)
1280 {
1281 struct policy_handle hResource;
1282
1283 torture_assert(tctx,
1284 test_OpenResource_int(tctx, p, resource_name, &hResource),
1285 "failed to open resource");
1286 test_CloseResource_int(tctx, p, &hResource);
1287
1288 torture_assert(tctx,
1289 test_OpenResourceEx_int(tctx, p, resource_name, &hResource),
1290 "failed to openex resource");
1291
1292 torture_assert(tctx,
1293 test_GetResourceType_int(tctx, p, &hResource),
1294 "failed to query resource type");
1295 torture_assert(tctx,
1296 test_GetResourceId_int(tctx, p, &hResource),
1297 "failed to query resource id");
1298 torture_assert(tctx,
1299 test_GetResourceState_int(tctx, p, &hResource),
1300 "failed to query resource state");
1301 torture_assert(tctx,
1302 test_CreateResEnum_int(tctx, p, &hResource),
1303 "failed to query resource enum");
1304 torture_assert(tctx,
1305 test_GetResourceDependencyExpression_int(tctx, p, &hResource),
1306 "failed to query resource dependency expression");
1307 torture_assert(tctx,
1308 test_GetResourceNetworkName_int(tctx, p, &hResource),
1309 "failed to query resource network name");
1310
1311 test_CloseResource_int(tctx, p, &hResource);
1312
1313 return true;
1314 }
1315
test_all_resources(struct torture_context * tctx,void * data)1316 static bool test_all_resources(struct torture_context *tctx,
1317 void *data)
1318 {
1319 struct torture_clusapi_context *t =
1320 talloc_get_type_abort(data, struct torture_clusapi_context);
1321 struct dcerpc_binding_handle *b = t->p->binding_handle;
1322 struct clusapi_CreateEnum r;
1323 uint32_t dwType = CLUSTER_ENUM_RESOURCE;
1324 struct ENUM_LIST *ReturnEnum;
1325 WERROR rpc_status;
1326 int i;
1327
1328 r.in.dwType = dwType;
1329 r.out.ReturnEnum = &ReturnEnum;
1330 r.out.rpc_status = &rpc_status;
1331
1332 torture_assert_ntstatus_ok(tctx,
1333 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1334 "CreateEnum failed");
1335 torture_assert_werr_ok(tctx,
1336 r.out.result,
1337 "CreateEnum failed");
1338
1339 for (i=0; i < ReturnEnum->EntryCount; i++) {
1340
1341 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1342
1343 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_RESOURCE, "type mismatch");
1344
1345 torture_assert(tctx,
1346 test_one_resource(tctx, t->p, e.Name),
1347 "failed to test one resource");
1348 }
1349
1350 return true;
1351 }
1352
test_all_resourcetypes(struct torture_context * tctx,void * data)1353 static bool test_all_resourcetypes(struct torture_context *tctx,
1354 void *data)
1355 {
1356 struct torture_clusapi_context *t =
1357 talloc_get_type_abort(data, struct torture_clusapi_context);
1358 struct dcerpc_binding_handle *b = t->p->binding_handle;
1359 struct clusapi_CreateEnum r;
1360 uint32_t dwType = CLUSTER_ENUM_RESTYPE;
1361 struct ENUM_LIST *ReturnEnum;
1362 WERROR rpc_status;
1363 int i;
1364
1365 r.in.dwType = dwType;
1366 r.out.ReturnEnum = &ReturnEnum;
1367 r.out.rpc_status = &rpc_status;
1368
1369 torture_assert_ntstatus_ok(tctx,
1370 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1371 "CreateEnum failed");
1372 torture_assert_werr_ok(tctx,
1373 r.out.result,
1374 "CreateEnum failed");
1375
1376 for (i=0; i < ReturnEnum->EntryCount; i++) {
1377
1378 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1379
1380 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_RESTYPE, "type mismatch");
1381
1382 torture_assert(tctx,
1383 test_one_resourcetype(tctx, t->p, e.Name),
1384 "failed to test one resourcetype");
1385 }
1386
1387 return true;
1388 }
1389
1390
test_OpenNode_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszNodeName,struct policy_handle * hNode)1391 static bool test_OpenNode_int(struct torture_context *tctx,
1392 struct dcerpc_pipe *p,
1393 const char *lpszNodeName,
1394 struct policy_handle *hNode)
1395 {
1396 struct dcerpc_binding_handle *b = p->binding_handle;
1397 struct clusapi_OpenNode r;
1398 WERROR Status;
1399 WERROR rpc_status;
1400
1401 r.in.lpszNodeName = lpszNodeName;
1402 r.out.rpc_status = &rpc_status;
1403 r.out.Status = &Status;
1404 r.out.hNode= hNode;
1405
1406 torture_assert_ntstatus_ok(tctx,
1407 dcerpc_clusapi_OpenNode_r(b, tctx, &r),
1408 "OpenNode failed");
1409 torture_assert_werr_ok(tctx,
1410 *r.out.Status,
1411 "OpenNode failed");
1412
1413 return true;
1414 }
1415
test_OpenNodeEx_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszNodeName,struct policy_handle * hNode)1416 static bool test_OpenNodeEx_int(struct torture_context *tctx,
1417 struct dcerpc_pipe *p,
1418 const char *lpszNodeName,
1419 struct policy_handle *hNode)
1420 {
1421 struct dcerpc_binding_handle *b = p->binding_handle;
1422 struct clusapi_OpenNodeEx r;
1423 uint32_t lpdwGrantedAccess;
1424 WERROR Status;
1425 WERROR rpc_status;
1426
1427 r.in.lpszNodeName = lpszNodeName;
1428 r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
1429 r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
1430 r.out.rpc_status = &rpc_status;
1431 r.out.Status = &Status;
1432 r.out.hNode= hNode;
1433
1434 torture_assert_ntstatus_ok(tctx,
1435 dcerpc_clusapi_OpenNodeEx_r(b, tctx, &r),
1436 "OpenNodeEx failed");
1437 torture_assert_werr_ok(tctx,
1438 *r.out.Status,
1439 "OpenNodeEx failed");
1440
1441 return true;
1442 }
1443
1444
test_CloseNode_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Node)1445 static bool test_CloseNode_int(struct torture_context *tctx,
1446 struct dcerpc_pipe *p,
1447 struct policy_handle *Node)
1448 {
1449 struct dcerpc_binding_handle *b = p->binding_handle;
1450 struct clusapi_CloseNode r;
1451
1452 r.in.Node = Node;
1453 r.out.Node = Node;
1454
1455 torture_assert_ntstatus_ok(tctx,
1456 dcerpc_clusapi_CloseNode_r(b, tctx, &r),
1457 "CloseNode failed");
1458 torture_assert_werr_ok(tctx,
1459 r.out.result,
1460 "CloseNode failed");
1461 torture_assert(tctx,
1462 ndr_policy_handle_empty(Node),
1463 "policy_handle non empty after CloseNode");
1464
1465 return true;
1466 }
1467
test_OpenNode(struct torture_context * tctx,void * data)1468 static bool test_OpenNode(struct torture_context *tctx,
1469 void *data)
1470 {
1471 struct torture_clusapi_context *t =
1472 talloc_get_type_abort(data, struct torture_clusapi_context);
1473 struct policy_handle hNode;
1474
1475 if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1476 return false;
1477 }
1478
1479 test_CloseNode_int(tctx, t->p, &hNode);
1480
1481 return true;
1482 }
1483
test_OpenNodeEx(struct torture_context * tctx,void * data)1484 static bool test_OpenNodeEx(struct torture_context *tctx,
1485 void *data)
1486 {
1487 struct torture_clusapi_context *t =
1488 talloc_get_type_abort(data, struct torture_clusapi_context);
1489 struct policy_handle hNode;
1490
1491 if (!test_OpenNodeEx_int(tctx, t->p, t->NodeName, &hNode)) {
1492 return false;
1493 }
1494
1495 test_CloseNode_int(tctx, t->p, &hNode);
1496
1497 return true;
1498 }
1499
test_CloseNode(struct torture_context * tctx,void * data)1500 static bool test_CloseNode(struct torture_context *tctx,
1501 void *data)
1502 {
1503 struct torture_clusapi_context *t =
1504 talloc_get_type_abort(data, struct torture_clusapi_context);
1505 struct policy_handle hNode;
1506
1507 if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1508 return false;
1509 }
1510
1511 return test_CloseNode_int(tctx, t->p, &hNode);
1512 }
1513
test_GetNodeState_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNode)1514 static bool test_GetNodeState_int(struct torture_context *tctx,
1515 struct dcerpc_pipe *p,
1516 struct policy_handle *hNode)
1517 {
1518 struct dcerpc_binding_handle *b = p->binding_handle;
1519 struct clusapi_GetNodeState r;
1520 enum clusapi_ClusterNodeState State;
1521 WERROR rpc_status;
1522
1523 r.in.hNode = *hNode;
1524 r.out.State = &State;
1525 r.out.rpc_status = &rpc_status;
1526
1527 torture_assert_ntstatus_ok(tctx,
1528 dcerpc_clusapi_GetNodeState_r(b, tctx, &r),
1529 "GetNodeState failed");
1530 torture_assert_werr_ok(tctx,
1531 r.out.result,
1532 "GetNodeState failed");
1533
1534 return true;
1535 }
1536
test_GetNodeState(struct torture_context * tctx,void * data)1537 static bool test_GetNodeState(struct torture_context *tctx,
1538 void *data)
1539 {
1540 struct torture_clusapi_context *t =
1541 talloc_get_type_abort(data, struct torture_clusapi_context);
1542 struct policy_handle hNode;
1543 bool ret = true;
1544
1545 if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1546 return false;
1547 }
1548
1549 ret = test_GetNodeState_int(tctx, t->p, &hNode);
1550
1551 test_CloseNode_int(tctx, t->p, &hNode);
1552
1553 return ret;
1554 }
1555
test_GetNodeId_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNode)1556 static bool test_GetNodeId_int(struct torture_context *tctx,
1557 struct dcerpc_pipe *p,
1558 struct policy_handle *hNode)
1559 {
1560 struct dcerpc_binding_handle *b = p->binding_handle;
1561 struct clusapi_GetNodeId r;
1562 const char *pGuid;
1563 WERROR rpc_status;
1564
1565 r.in.hNode = *hNode;
1566 r.out.pGuid = &pGuid;
1567 r.out.rpc_status = &rpc_status;
1568
1569 torture_assert_ntstatus_ok(tctx,
1570 dcerpc_clusapi_GetNodeId_r(b, tctx, &r),
1571 "GetNodeId failed");
1572 torture_assert_werr_ok(tctx,
1573 r.out.result,
1574 "GetNodeId failed");
1575
1576 return true;
1577 }
1578
test_GetNodeId(struct torture_context * tctx,void * data)1579 static bool test_GetNodeId(struct torture_context *tctx,
1580 void *data)
1581 {
1582 struct torture_clusapi_context *t =
1583 talloc_get_type_abort(data, struct torture_clusapi_context);
1584 struct policy_handle hNode;
1585 bool ret = true;
1586
1587 if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1588 return false;
1589 }
1590
1591 ret = test_GetNodeId_int(tctx, t->p, &hNode);
1592
1593 test_CloseNode_int(tctx, t->p, &hNode);
1594
1595 return ret;
1596 }
1597
test_NodeControl_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNode,enum clusapi_NodeControlCode dwControlCode)1598 static bool test_NodeControl_int(struct torture_context *tctx,
1599 struct dcerpc_pipe *p,
1600 struct policy_handle *hNode,
1601 enum clusapi_NodeControlCode dwControlCode)
1602 {
1603 struct dcerpc_binding_handle *b = p->binding_handle;
1604 struct clusapi_NodeControl r;
1605 uint32_t lpBytesReturned;
1606 uint32_t lpcbRequired;
1607 WERROR rpc_status;
1608
1609 r.in.hNode = *hNode;
1610 r.in.dwControlCode = 0;
1611 r.in.lpInBuffer = NULL;
1612 r.in.nInBufferSize = 0;
1613 r.in.nOutBufferSize = 0;
1614 r.out.lpOutBuffer = NULL;
1615 r.out.lpBytesReturned = &lpBytesReturned;
1616 r.out.lpcbRequired = &lpcbRequired;
1617 r.out.rpc_status = &rpc_status;
1618
1619 torture_assert_ntstatus_ok(tctx,
1620 dcerpc_clusapi_NodeControl_r(b, tctx, &r),
1621 "NodeControl failed");
1622 torture_assert_werr_equal(tctx,
1623 r.out.result,
1624 WERR_INVALID_FUNCTION,
1625 "NodeControl failed");
1626
1627 r.in.dwControlCode = dwControlCode;
1628
1629 torture_assert_ntstatus_ok(tctx,
1630 dcerpc_clusapi_NodeControl_r(b, tctx, &r),
1631 "NodeControl failed");
1632
1633 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1634 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
1635 r.in.nOutBufferSize = *r.out.lpcbRequired;
1636 torture_assert_ntstatus_ok(tctx,
1637 dcerpc_clusapi_NodeControl_r(b, tctx, &r),
1638 "NodeControl failed");
1639 }
1640 torture_assert_werr_ok(tctx,
1641 r.out.result,
1642 "NodeControl failed");
1643
1644 /* now try what happens when we query with a buffer large enough to hold
1645 * the entire packet */
1646
1647 r.in.nOutBufferSize = 0x4000;
1648 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
1649
1650 torture_assert_ntstatus_ok(tctx,
1651 dcerpc_clusapi_NodeControl_r(b, tctx, &r),
1652 "NodeControl failed");
1653 torture_assert_werr_ok(tctx,
1654 r.out.result,
1655 "NodeControl failed");
1656 torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
1657 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
1658
1659 if (dwControlCode == CLUSCTL_NODE_GET_ID) {
1660 const char *str;
1661 DATA_BLOB blob = data_blob_const(r.out.lpOutBuffer, *r.out.lpBytesReturned);
1662
1663 torture_assert(tctx, *r.out.lpBytesReturned >= 4, "must be at least 4 bytes long");
1664 torture_assert(tctx, (*r.out.lpBytesReturned % 2) == 0, "must be a multiple of 2");
1665
1666 torture_assert(tctx,
1667 pull_reg_sz(tctx, &blob, &str),
1668 "failed to pull unicode string");
1669
1670 torture_comment(tctx, "got this node id: '%s'", str);
1671 }
1672
1673 return true;
1674 }
1675
test_NodeControl(struct torture_context * tctx,void * data)1676 static bool test_NodeControl(struct torture_context *tctx,
1677 void *data)
1678 {
1679 struct torture_clusapi_context *t =
1680 talloc_get_type_abort(data, struct torture_clusapi_context);
1681 struct policy_handle hNode;
1682 bool ret = true;
1683
1684 if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1685 return false;
1686 }
1687
1688 ret = test_NodeControl_int(tctx, t->p, &hNode, CLUSCTL_NODE_GET_RO_COMMON_PROPERTIES);
1689 if (!ret) {
1690 return false;
1691 }
1692
1693 ret = test_NodeControl_int(tctx, t->p, &hNode, CLUSCTL_NODE_GET_ID);
1694 if (!ret) {
1695 return false;
1696 }
1697
1698 test_CloseNode_int(tctx, t->p, &hNode);
1699
1700 return ret;
1701 }
1702
test_PauseNode_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNode)1703 static bool test_PauseNode_int(struct torture_context *tctx,
1704 struct dcerpc_pipe *p,
1705 struct policy_handle *hNode)
1706 {
1707 struct dcerpc_binding_handle *b = p->binding_handle;
1708 struct clusapi_PauseNode r;
1709 WERROR rpc_status;
1710
1711 r.in.hNode = *hNode;
1712 r.out.rpc_status = &rpc_status;
1713
1714 torture_assert_ntstatus_ok(tctx,
1715 dcerpc_clusapi_PauseNode_r(b, tctx, &r),
1716 "PauseNode failed");
1717 torture_assert_werr_ok(tctx,
1718 r.out.result,
1719 "PauseNode failed");
1720
1721 return true;
1722 }
1723
test_PauseNode(struct torture_context * tctx,void * data)1724 static bool test_PauseNode(struct torture_context *tctx,
1725 void *data)
1726 {
1727 struct torture_clusapi_context *t =
1728 talloc_get_type_abort(data, struct torture_clusapi_context);
1729 struct policy_handle hNode;
1730 bool ret = true;
1731
1732 if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1733 return false;
1734 }
1735
1736 ret = test_PauseNode_int(tctx, t->p, &hNode);
1737
1738 test_CloseNode_int(tctx, t->p, &hNode);
1739
1740 return ret;
1741 }
1742
test_ResumeNode_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNode)1743 static bool test_ResumeNode_int(struct torture_context *tctx,
1744 struct dcerpc_pipe *p,
1745 struct policy_handle *hNode)
1746 {
1747 struct dcerpc_binding_handle *b = p->binding_handle;
1748 struct clusapi_ResumeNode r;
1749 WERROR rpc_status;
1750
1751 r.in.hNode = *hNode;
1752 r.out.rpc_status = &rpc_status;
1753
1754 torture_assert_ntstatus_ok(tctx,
1755 dcerpc_clusapi_ResumeNode_r(b, tctx, &r),
1756 "ResumeNode failed");
1757 torture_assert_werr_equal(tctx,
1758 r.out.result,
1759 WERR_CLUSTER_NODE_NOT_PAUSED,
1760 "ResumeNode gave unexpected result");
1761
1762 return true;
1763 }
1764
test_ResumeNode(struct torture_context * tctx,void * data)1765 static bool test_ResumeNode(struct torture_context *tctx,
1766 void *data)
1767 {
1768 struct torture_clusapi_context *t =
1769 talloc_get_type_abort(data, struct torture_clusapi_context);
1770 struct policy_handle hNode;
1771 bool ret = true;
1772
1773 if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1774 return false;
1775 }
1776
1777 ret = test_ResumeNode_int(tctx, t->p, &hNode);
1778
1779 test_CloseNode_int(tctx, t->p, &hNode);
1780
1781 return ret;
1782 }
1783
test_EvictNode_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNode)1784 static bool test_EvictNode_int(struct torture_context *tctx,
1785 struct dcerpc_pipe *p,
1786 struct policy_handle *hNode)
1787 {
1788 struct dcerpc_binding_handle *b = p->binding_handle;
1789 struct clusapi_EvictNode r;
1790 WERROR rpc_status;
1791
1792 r.in.hNode = *hNode;
1793 r.out.rpc_status = &rpc_status;
1794
1795 torture_assert_ntstatus_ok(tctx,
1796 dcerpc_clusapi_EvictNode_r(b, tctx, &r),
1797 "EvictNode failed");
1798 torture_assert_werr_ok(tctx,
1799 r.out.result,
1800 "EvictNode failed");
1801
1802 return true;
1803 }
1804
test_EvictNode(struct torture_context * tctx,void * data)1805 static bool test_EvictNode(struct torture_context *tctx,
1806 void *data)
1807 {
1808 struct torture_clusapi_context *t =
1809 talloc_get_type_abort(data, struct torture_clusapi_context);
1810 struct policy_handle hNode;
1811 bool ret = true;
1812
1813 if (!test_OpenNode_int(tctx, t->p, t->NodeName, &hNode)) {
1814 return false;
1815 }
1816
1817 ret = test_EvictNode_int(tctx, t->p, &hNode);
1818
1819 test_CloseNode_int(tctx, t->p, &hNode);
1820
1821 return ret;
1822 }
1823
test_one_node(struct torture_context * tctx,struct dcerpc_pipe * p,const char * node_name)1824 static bool test_one_node(struct torture_context *tctx,
1825 struct dcerpc_pipe *p,
1826 const char *node_name)
1827 {
1828 struct policy_handle hNode;
1829
1830 torture_assert(tctx,
1831 test_OpenNode_int(tctx, p, node_name, &hNode),
1832 "failed to open node");
1833 test_CloseNode_int(tctx, p, &hNode);
1834
1835 torture_assert(tctx,
1836 test_OpenNodeEx_int(tctx, p, node_name, &hNode),
1837 "failed to openex node");
1838
1839 torture_assert(tctx,
1840 test_GetNodeId_int(tctx, p, &hNode),
1841 "failed to query node id");
1842 torture_assert(tctx,
1843 test_GetNodeState_int(tctx, p, &hNode),
1844 "failed to query node id");
1845
1846 test_CloseNode_int(tctx, p, &hNode);
1847
1848 return true;
1849 }
1850
test_all_nodes(struct torture_context * tctx,void * data)1851 static bool test_all_nodes(struct torture_context *tctx,
1852 void *data)
1853 {
1854 struct torture_clusapi_context *t =
1855 talloc_get_type_abort(data, struct torture_clusapi_context);
1856 struct dcerpc_binding_handle *b = t->p->binding_handle;
1857 struct clusapi_CreateEnum r;
1858 uint32_t dwType = CLUSTER_ENUM_NODE;
1859 struct ENUM_LIST *ReturnEnum;
1860 WERROR rpc_status;
1861 int i;
1862
1863 r.in.dwType = dwType;
1864 r.out.ReturnEnum = &ReturnEnum;
1865 r.out.rpc_status = &rpc_status;
1866
1867 torture_assert_ntstatus_ok(tctx,
1868 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
1869 "CreateEnum failed");
1870 torture_assert_werr_ok(tctx,
1871 r.out.result,
1872 "CreateEnum failed");
1873
1874 for (i=0; i < ReturnEnum->EntryCount; i++) {
1875
1876 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
1877
1878 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NODE, "type mismatch");
1879
1880 torture_assert(tctx,
1881 test_one_node(tctx, t->p, e.Name),
1882 "failed to test one node");
1883 }
1884
1885 return true;
1886 }
1887
test_OpenGroup_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszGroupName,struct policy_handle * hGroup)1888 static bool test_OpenGroup_int(struct torture_context *tctx,
1889 struct dcerpc_pipe *p,
1890 const char *lpszGroupName,
1891 struct policy_handle *hGroup)
1892 {
1893 struct dcerpc_binding_handle *b = p->binding_handle;
1894 struct clusapi_OpenGroup r;
1895 WERROR Status;
1896 WERROR rpc_status;
1897
1898 r.in.lpszGroupName = lpszGroupName;
1899 r.out.rpc_status = &rpc_status;
1900 r.out.Status = &Status;
1901 r.out.hGroup= hGroup;
1902
1903 torture_assert_ntstatus_ok(tctx,
1904 dcerpc_clusapi_OpenGroup_r(b, tctx, &r),
1905 "OpenGroup failed");
1906 torture_assert_werr_ok(tctx,
1907 *r.out.Status,
1908 "OpenGroup failed");
1909
1910 return true;
1911 }
1912
test_OpenGroupEx_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszGroupName,struct policy_handle * hGroup)1913 static bool test_OpenGroupEx_int(struct torture_context *tctx,
1914 struct dcerpc_pipe *p,
1915 const char *lpszGroupName,
1916 struct policy_handle *hGroup)
1917 {
1918 struct dcerpc_binding_handle *b = p->binding_handle;
1919 struct clusapi_OpenGroupEx r;
1920 uint32_t lpdwGrantedAccess;
1921 WERROR Status;
1922 WERROR rpc_status;
1923
1924 r.in.lpszGroupName = lpszGroupName;
1925 r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
1926 r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
1927 r.out.rpc_status = &rpc_status;
1928 r.out.Status = &Status;
1929 r.out.hGroup= hGroup;
1930
1931 torture_assert_ntstatus_ok(tctx,
1932 dcerpc_clusapi_OpenGroupEx_r(b, tctx, &r),
1933 "OpenGroupEx failed");
1934 torture_assert_werr_ok(tctx,
1935 *r.out.Status,
1936 "OpenGroupEx failed");
1937
1938 return true;
1939 }
1940
test_CloseGroup_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Group)1941 static bool test_CloseGroup_int(struct torture_context *tctx,
1942 struct dcerpc_pipe *p,
1943 struct policy_handle *Group)
1944 {
1945 struct dcerpc_binding_handle *b = p->binding_handle;
1946 struct clusapi_CloseGroup r;
1947
1948 r.in.Group = Group;
1949 r.out.Group = Group;
1950
1951 torture_assert_ntstatus_ok(tctx,
1952 dcerpc_clusapi_CloseGroup_r(b, tctx, &r),
1953 "CloseGroup failed");
1954 torture_assert_werr_ok(tctx,
1955 r.out.result,
1956 "CloseGroup failed");
1957 torture_assert(tctx,
1958 ndr_policy_handle_empty(Group),
1959 "policy_handle non empty after CloseGroup");
1960
1961 return true;
1962 }
1963
test_OpenGroup(struct torture_context * tctx,void * data)1964 static bool test_OpenGroup(struct torture_context *tctx,
1965 void *data)
1966 {
1967 struct torture_clusapi_context *t =
1968 talloc_get_type_abort(data, struct torture_clusapi_context);
1969 struct policy_handle hGroup;
1970
1971 if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
1972 return false;
1973 }
1974
1975 test_CloseGroup_int(tctx, t->p, &hGroup);
1976
1977 return true;
1978 }
1979
test_OpenGroupEx(struct torture_context * tctx,void * data)1980 static bool test_OpenGroupEx(struct torture_context *tctx,
1981 void *data)
1982 {
1983 struct torture_clusapi_context *t =
1984 talloc_get_type_abort(data, struct torture_clusapi_context);
1985 struct policy_handle hGroup;
1986
1987 if (!test_OpenGroupEx_int(tctx, t->p, "Cluster Group", &hGroup)) {
1988 return false;
1989 }
1990
1991 test_CloseGroup_int(tctx, t->p, &hGroup);
1992
1993 return true;
1994 }
1995
test_CloseGroup(struct torture_context * tctx,void * data)1996 static bool test_CloseGroup(struct torture_context *tctx,
1997 void *data)
1998 {
1999 struct torture_clusapi_context *t =
2000 talloc_get_type_abort(data, struct torture_clusapi_context);
2001 struct policy_handle hGroup;
2002
2003 if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2004 return false;
2005 }
2006
2007 return test_CloseGroup_int(tctx, t->p, &hGroup);
2008 }
2009
test_GetGroupState_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hGroup)2010 static bool test_GetGroupState_int(struct torture_context *tctx,
2011 struct dcerpc_pipe *p,
2012 struct policy_handle *hGroup)
2013 {
2014 struct dcerpc_binding_handle *b = p->binding_handle;
2015 struct clusapi_GetGroupState r;
2016 enum clusapi_ClusterGroupState State;
2017 const char *NodeName;
2018 WERROR rpc_status;
2019
2020 r.in.hGroup = *hGroup;
2021 r.out.State = &State;
2022 r.out.NodeName = &NodeName;
2023 r.out.rpc_status = &rpc_status;
2024
2025 torture_assert_ntstatus_ok(tctx,
2026 dcerpc_clusapi_GetGroupState_r(b, tctx, &r),
2027 "GetGroupState failed");
2028 torture_assert_werr_ok(tctx,
2029 r.out.result,
2030 "GetGroupState failed");
2031
2032 return true;
2033 }
2034
test_GetGroupState(struct torture_context * tctx,void * data)2035 static bool test_GetGroupState(struct torture_context *tctx,
2036 void *data)
2037 {
2038 struct torture_clusapi_context *t =
2039 talloc_get_type_abort(data, struct torture_clusapi_context);
2040 struct policy_handle hGroup;
2041 bool ret = true;
2042
2043 if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2044 return false;
2045 }
2046
2047 ret = test_GetGroupState_int(tctx, t->p, &hGroup);
2048
2049 test_CloseGroup_int(tctx, t->p, &hGroup);
2050
2051 return ret;
2052 }
2053
test_GetGroupId_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hGroup)2054 static bool test_GetGroupId_int(struct torture_context *tctx,
2055 struct dcerpc_pipe *p,
2056 struct policy_handle *hGroup)
2057 {
2058 struct dcerpc_binding_handle *b = p->binding_handle;
2059 struct clusapi_GetGroupId r;
2060 const char *pGuid;
2061 WERROR rpc_status;
2062
2063 r.in.hGroup = *hGroup;
2064 r.out.pGuid = &pGuid;
2065 r.out.rpc_status = &rpc_status;
2066
2067 torture_assert_ntstatus_ok(tctx,
2068 dcerpc_clusapi_GetGroupId_r(b, tctx, &r),
2069 "GetGroupId failed");
2070 torture_assert_werr_ok(tctx,
2071 r.out.result,
2072 "GetGroupId failed");
2073
2074 return true;
2075 }
2076
test_GetGroupId(struct torture_context * tctx,void * data)2077 static bool test_GetGroupId(struct torture_context *tctx,
2078 void *data)
2079 {
2080 struct torture_clusapi_context *t =
2081 talloc_get_type_abort(data, struct torture_clusapi_context);
2082 struct policy_handle hGroup;
2083 bool ret = true;
2084
2085 if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2086 return false;
2087 }
2088
2089 ret = test_GetGroupId_int(tctx, t->p, &hGroup);
2090
2091 test_CloseGroup_int(tctx, t->p, &hGroup);
2092
2093 return ret;
2094 }
2095
test_GroupControl_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hGroup,enum clusapi_GroupControlCode dwControlCode)2096 static bool test_GroupControl_int(struct torture_context *tctx,
2097 struct dcerpc_pipe *p,
2098 struct policy_handle *hGroup,
2099 enum clusapi_GroupControlCode dwControlCode)
2100 {
2101 struct dcerpc_binding_handle *b = p->binding_handle;
2102 struct clusapi_GroupControl r;
2103 uint32_t lpBytesReturned;
2104 uint32_t lpcbRequired;
2105 WERROR rpc_status;
2106
2107 r.in.hGroup = *hGroup;
2108 r.in.dwControlCode = 0;
2109 r.in.lpInBuffer = NULL;
2110 r.in.nInBufferSize = 0;
2111 r.in.nOutBufferSize = 0;
2112 r.out.lpOutBuffer = NULL;
2113 r.out.lpBytesReturned = &lpBytesReturned;
2114 r.out.lpcbRequired = &lpcbRequired;
2115 r.out.rpc_status = &rpc_status;
2116
2117 torture_assert_ntstatus_ok(tctx,
2118 dcerpc_clusapi_GroupControl_r(b, tctx, &r),
2119 "GroupControl failed");
2120 torture_assert_werr_equal(tctx,
2121 r.out.result,
2122 WERR_INVALID_FUNCTION,
2123 "GroupControl failed");
2124
2125 r.in.dwControlCode = dwControlCode;
2126
2127 torture_assert_ntstatus_ok(tctx,
2128 dcerpc_clusapi_GroupControl_r(b, tctx, &r),
2129 "GroupControl failed");
2130
2131 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
2132 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
2133 r.in.nOutBufferSize = *r.out.lpcbRequired;
2134 torture_assert_ntstatus_ok(tctx,
2135 dcerpc_clusapi_GroupControl_r(b, tctx, &r),
2136 "GroupControl failed");
2137 }
2138 torture_assert_werr_ok(tctx,
2139 r.out.result,
2140 "GroupControl failed");
2141
2142 /* now try what happens when we query with a buffer large enough to hold
2143 * the entire packet */
2144
2145 r.in.nOutBufferSize = 0x400;
2146 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
2147
2148 torture_assert_ntstatus_ok(tctx,
2149 dcerpc_clusapi_GroupControl_r(b, tctx, &r),
2150 "GroupControl failed");
2151 torture_assert_werr_ok(tctx,
2152 r.out.result,
2153 "GroupControl failed");
2154 torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
2155 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
2156
2157 return true;
2158 }
2159
test_CreateGroupResourceEnum_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hGroup)2160 static bool test_CreateGroupResourceEnum_int(struct torture_context *tctx,
2161 struct dcerpc_pipe *p,
2162 struct policy_handle *hGroup)
2163 {
2164 struct dcerpc_binding_handle *b = p->binding_handle;
2165 struct clusapi_CreateGroupResourceEnum r;
2166 uint32_t dwType[] = {
2167 CLUSTER_GROUP_ENUM_CONTAINS,
2168 CLUSTER_GROUP_ENUM_NODES
2169 };
2170 uint32_t dwType_invalid[] = {
2171 0x00000040,
2172 0x00000080,
2173 0x00000100 /* and many more ... */
2174 };
2175 struct ENUM_LIST *ReturnEnum;
2176 WERROR rpc_status;
2177 int i;
2178
2179 r.in.hGroup = *hGroup;
2180
2181 for (i=0; i < ARRAY_SIZE(dwType); i++) {
2182
2183 r.in.hGroup = *hGroup;
2184 r.in.dwType = dwType[i];
2185 r.out.ReturnEnum = &ReturnEnum;
2186 r.out.rpc_status = &rpc_status;
2187
2188 torture_assert_ntstatus_ok(tctx,
2189 dcerpc_clusapi_CreateGroupResourceEnum_r(b, tctx, &r),
2190 "CreateGroupResourceEnum failed");
2191 torture_assert_werr_ok(tctx,
2192 r.out.result,
2193 "CreateGroupResourceEnum failed");
2194 }
2195
2196 for (i=0; i < ARRAY_SIZE(dwType_invalid); i++) {
2197
2198 r.in.dwType = dwType_invalid[i];
2199 r.out.ReturnEnum = &ReturnEnum;
2200 r.out.rpc_status = &rpc_status;
2201
2202 torture_assert_ntstatus_ok(tctx,
2203 dcerpc_clusapi_CreateGroupResourceEnum_r(b, tctx, &r),
2204 "CreateGroupResourceEnum failed");
2205 torture_assert_werr_ok(tctx,
2206 r.out.result,
2207 "CreateGroupResourceEnum failed");
2208 }
2209
2210 return true;
2211 }
2212
2213
test_GroupControl(struct torture_context * tctx,void * data)2214 static bool test_GroupControl(struct torture_context *tctx,
2215 void *data)
2216 {
2217 struct torture_clusapi_context *t =
2218 talloc_get_type_abort(data, struct torture_clusapi_context);
2219 struct policy_handle hGroup;
2220 bool ret = true;
2221
2222 if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2223 return false;
2224 }
2225
2226 ret = test_GroupControl_int(tctx, t->p, &hGroup, CLUSCTL_GROUP_GET_CHARACTERISTICS);
2227 if (!ret) {
2228 return false;
2229 }
2230
2231 ret = test_GroupControl_int(tctx, t->p, &hGroup, CLUSCTL_GROUP_GET_RO_COMMON_PROPERTIES);
2232 if (!ret) {
2233 return false;
2234 }
2235
2236 ret = test_GroupControl_int(tctx, t->p, &hGroup, CLUSCTL_GROUP_GET_FLAGS);
2237 if (!ret) {
2238 return false;
2239 }
2240
2241 test_CloseGroup_int(tctx, t->p, &hGroup);
2242
2243 return ret;
2244 }
2245
test_OnlineGroup_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hGroup)2246 static bool test_OnlineGroup_int(struct torture_context *tctx,
2247 struct dcerpc_pipe *p,
2248 struct policy_handle *hGroup)
2249 {
2250 struct dcerpc_binding_handle *b = p->binding_handle;
2251 struct clusapi_OnlineGroup r;
2252 WERROR rpc_status;
2253
2254 r.in.hGroup = *hGroup;
2255 r.out.rpc_status = &rpc_status;
2256
2257 torture_assert_ntstatus_ok(tctx,
2258 dcerpc_clusapi_OnlineGroup_r(b, tctx, &r),
2259 "OnlineGroup failed");
2260 torture_assert_werr_ok(tctx,
2261 r.out.result,
2262 "OnlineGroup failed");
2263
2264 return true;
2265 }
2266
test_OnlineGroup(struct torture_context * tctx,void * data)2267 static bool test_OnlineGroup(struct torture_context *tctx,
2268 void *data)
2269 {
2270 struct torture_clusapi_context *t =
2271 talloc_get_type_abort(data, struct torture_clusapi_context);
2272 struct policy_handle hGroup;
2273 bool ret = true;
2274
2275 if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2276 return false;
2277 }
2278
2279 ret = test_OnlineGroup_int(tctx, t->p, &hGroup);
2280
2281 test_CloseGroup_int(tctx, t->p, &hGroup);
2282
2283 return ret;
2284 }
2285
test_OfflineGroup_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hGroup)2286 static bool test_OfflineGroup_int(struct torture_context *tctx,
2287 struct dcerpc_pipe *p,
2288 struct policy_handle *hGroup)
2289 {
2290 struct dcerpc_binding_handle *b = p->binding_handle;
2291 struct clusapi_OfflineGroup r;
2292 WERROR rpc_status;
2293
2294 r.in.hGroup = *hGroup;
2295 r.out.rpc_status = &rpc_status;
2296
2297 torture_assert_ntstatus_ok(tctx,
2298 dcerpc_clusapi_OfflineGroup_r(b, tctx, &r),
2299 "OfflineGroup failed");
2300 torture_assert_werr_ok(tctx,
2301 r.out.result,
2302 "OfflineGroup failed");
2303
2304 return true;
2305 }
2306
test_OfflineGroup(struct torture_context * tctx,void * data)2307 static bool test_OfflineGroup(struct torture_context *tctx,
2308 void *data)
2309 {
2310 struct torture_clusapi_context *t =
2311 talloc_get_type_abort(data, struct torture_clusapi_context);
2312 struct policy_handle hGroup;
2313 bool ret = true;
2314
2315 if (!test_OpenGroup_int(tctx, t->p, "Cluster Group", &hGroup)) {
2316 return false;
2317 }
2318
2319 ret = test_OfflineGroup_int(tctx, t->p, &hGroup);
2320
2321 test_CloseGroup_int(tctx, t->p, &hGroup);
2322
2323 return ret;
2324 }
2325
test_one_group(struct torture_context * tctx,struct dcerpc_pipe * p,const char * group_name)2326 static bool test_one_group(struct torture_context *tctx,
2327 struct dcerpc_pipe *p,
2328 const char *group_name)
2329 {
2330 struct policy_handle hGroup;
2331
2332 torture_assert(tctx,
2333 test_OpenGroup_int(tctx, p, group_name, &hGroup),
2334 "failed to open group");
2335 test_CloseGroup_int(tctx, p, &hGroup);
2336
2337 torture_assert(tctx,
2338 test_OpenGroupEx_int(tctx, p, group_name, &hGroup),
2339 "failed to openex group");
2340
2341 torture_assert(tctx,
2342 test_GetGroupId_int(tctx, p, &hGroup),
2343 "failed to query group id");
2344 torture_assert(tctx,
2345 test_GetGroupState_int(tctx, p, &hGroup),
2346 "failed to query group id");
2347
2348 torture_assert(tctx,
2349 test_GroupControl_int(tctx, p, &hGroup, CLUSCTL_GROUP_GET_FLAGS),
2350 "failed to query group control");
2351
2352 torture_assert(tctx,
2353 test_CreateGroupResourceEnum_int(tctx, p, &hGroup),
2354 "failed to query resource enum");
2355
2356 test_CloseGroup_int(tctx, p, &hGroup);
2357
2358 return true;
2359 }
2360
test_all_groups(struct torture_context * tctx,void * data)2361 static bool test_all_groups(struct torture_context *tctx,
2362 void *data)
2363 {
2364 struct torture_clusapi_context *t =
2365 talloc_get_type_abort(data, struct torture_clusapi_context);
2366 struct dcerpc_binding_handle *b = t->p->binding_handle;
2367 struct clusapi_CreateEnum r;
2368 uint32_t dwType = CLUSTER_ENUM_GROUP;
2369 struct ENUM_LIST *ReturnEnum;
2370 WERROR rpc_status;
2371 int i;
2372
2373 r.in.dwType = dwType;
2374 r.out.ReturnEnum = &ReturnEnum;
2375 r.out.rpc_status = &rpc_status;
2376
2377 torture_assert_ntstatus_ok(tctx,
2378 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
2379 "CreateEnum failed");
2380 torture_assert_werr_ok(tctx,
2381 r.out.result,
2382 "CreateEnum failed");
2383
2384 for (i=0; i < ReturnEnum->EntryCount; i++) {
2385
2386 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
2387
2388 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_GROUP, "type mismatch");
2389
2390 torture_assert(tctx,
2391 test_one_group(tctx, t->p, e.Name),
2392 "failed to test one group");
2393 }
2394
2395 return true;
2396 }
2397
test_BackupClusterDatabase(struct torture_context * tctx,void * data)2398 static bool test_BackupClusterDatabase(struct torture_context *tctx,
2399 void *data)
2400 {
2401 struct torture_clusapi_context *t =
2402 talloc_get_type_abort(data, struct torture_clusapi_context);
2403 struct dcerpc_binding_handle *b = t->p->binding_handle;
2404 struct clusapi_BackupClusterDatabase r;
2405 WERROR rpc_status;
2406
2407 r.in.lpszPathName = "c:\\cluster_backup";
2408 r.out.rpc_status = &rpc_status;
2409
2410 torture_assert_ntstatus_ok(tctx,
2411 dcerpc_clusapi_BackupClusterDatabase_r(b, tctx, &r),
2412 "BackupClusterDatabase failed");
2413 torture_assert_werr_equal(tctx,
2414 r.out.result,
2415 WERR_CALL_NOT_IMPLEMENTED,
2416 "BackupClusterDatabase failed");
2417
2418 return true;
2419 }
2420
test_SetServiceAccountPassword(struct torture_context * tctx,void * data)2421 static bool test_SetServiceAccountPassword(struct torture_context *tctx,
2422 void *data)
2423 {
2424 struct torture_clusapi_context *t =
2425 talloc_get_type_abort(data, struct torture_clusapi_context);
2426 struct dcerpc_binding_handle *b = t->p->binding_handle;
2427 struct clusapi_SetServiceAccountPassword r;
2428 uint32_t SizeReturned;
2429 uint32_t ExpectedBufferSize;
2430
2431 r.in.lpszNewPassword = "P@ssw0rd!";
2432 r.in.dwFlags = IDL_CLUSTER_SET_PASSWORD_IGNORE_DOWN_NODES;
2433 r.in.ReturnStatusBufferSize = 1024;
2434 r.out.ReturnStatusBufferPtr = NULL;
2435 r.out.SizeReturned = &SizeReturned;
2436 r.out.ExpectedBufferSize = &ExpectedBufferSize;
2437
2438 torture_assert_ntstatus_ok(tctx,
2439 dcerpc_clusapi_SetServiceAccountPassword_r(b, tctx, &r),
2440 "SetServiceAccountPassword failed");
2441 torture_assert_werr_equal(tctx,
2442 r.out.result,
2443 WERR_CALL_NOT_IMPLEMENTED,
2444 "SetServiceAccountPassword failed");
2445
2446 return true;
2447 }
2448
test_ClusterControl_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Cluster,enum clusapi_ClusterControlCode dwControlCode)2449 static bool test_ClusterControl_int(struct torture_context *tctx,
2450 struct dcerpc_pipe *p,
2451 struct policy_handle *Cluster,
2452 enum clusapi_ClusterControlCode dwControlCode)
2453 {
2454 struct dcerpc_binding_handle *b = p->binding_handle;
2455 struct clusapi_ClusterControl r;
2456 uint32_t lpBytesReturned;
2457 uint32_t lpcbRequired;
2458 WERROR rpc_status;
2459
2460 r.in.hCluster = *Cluster;
2461 r.in.dwControlCode = 0;
2462 r.in.lpInBuffer = NULL;
2463 r.in.nInBufferSize = 0;
2464 r.in.nOutBufferSize = 0;
2465 r.out.lpOutBuffer = NULL;
2466 r.out.lpBytesReturned = &lpBytesReturned;
2467 r.out.lpcbRequired = &lpcbRequired;
2468 r.out.rpc_status = &rpc_status;
2469
2470 torture_assert_ntstatus_ok(tctx,
2471 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2472 "ClusterControl failed");
2473 torture_assert_werr_equal(tctx,
2474 r.out.result,
2475 WERR_INVALID_FUNCTION,
2476 "ClusterControl failed");
2477
2478 r.in.dwControlCode = dwControlCode;
2479
2480 torture_assert_ntstatus_ok(tctx,
2481 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2482 "ClusterControl failed");
2483
2484 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
2485 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, *r.out.lpcbRequired);
2486 r.in.nOutBufferSize = *r.out.lpcbRequired;
2487 torture_assert_ntstatus_ok(tctx,
2488 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2489 "ClusterControl failed");
2490 }
2491 torture_assert_werr_ok(tctx,
2492 r.out.result,
2493 "ClusterControl failed");
2494
2495 /* now try what happens when we query with a buffer large enough to hold
2496 * the entire packet */
2497
2498 r.in.nOutBufferSize = 0xffff;
2499 r.out.lpOutBuffer = talloc_zero_array(tctx, uint8_t, r.in.nOutBufferSize);
2500
2501 torture_assert_ntstatus_ok(tctx,
2502 dcerpc_clusapi_ClusterControl_r(b, tctx, &r),
2503 "ClusterControl failed");
2504 torture_assert_werr_ok(tctx,
2505 r.out.result,
2506 "ClusterControl failed");
2507 torture_assert(tctx, *r.out.lpBytesReturned < r.in.nOutBufferSize,
2508 "lpBytesReturned expected to be smaller than input size nOutBufferSize");
2509
2510 return true;
2511 }
2512
test_ClusterControl(struct torture_context * tctx,void * data)2513 static bool test_ClusterControl(struct torture_context *tctx,
2514 void *data)
2515 {
2516 struct torture_clusapi_context *t =
2517 talloc_get_type_abort(data, struct torture_clusapi_context);
2518 struct policy_handle Cluster;
2519 bool ret;
2520 uint32_t control_codes[] = {
2521 CLUSCTL_CLUSTER_GET_COMMON_PROPERTIES,
2522 CLUSCTL_CLUSTER_GET_RO_COMMON_PROPERTIES,
2523 CLUSCTL_CLUSTER_GET_FQDN,
2524 CLUSCTL_CLUSTER_GET_PRIVATE_PROPERTIES,
2525 CLUSCTL_CLUSTER_CHECK_VOTER_DOWN
2526 };
2527 int i;
2528
2529 if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
2530 return false;
2531 }
2532
2533 for (i=0; i < ARRAY_SIZE(control_codes); i++) {
2534 ret = test_ClusterControl_int(tctx, t->p, &Cluster,
2535 control_codes[i]);
2536 if (!ret) {
2537 goto done;
2538 }
2539 }
2540
2541 done:
2542 test_CloseCluster_int(tctx, t->p, &Cluster);
2543
2544 return ret;
2545 }
2546
test_CreateResTypeEnum(struct torture_context * tctx,void * data)2547 static bool test_CreateResTypeEnum(struct torture_context *tctx,
2548 void *data)
2549 {
2550 struct torture_clusapi_context *t =
2551 talloc_get_type_abort(data, struct torture_clusapi_context);
2552 struct dcerpc_binding_handle *b = t->p->binding_handle;
2553 struct clusapi_CreateResTypeEnum r;
2554 uint32_t dwType[] = {
2555 CLUSTER_RESOURCE_TYPE_ENUM_NODES,
2556 CLUSTER_RESOURCE_TYPE_ENUM_RESOURCES
2557 };
2558 uint32_t dwType_invalid[] = {
2559 0x00000040,
2560 0x00000080,
2561 0x00000100 /* and many more ... */
2562 };
2563 const char *valid_names[] = {
2564 "Physical Disk",
2565 "Storage Pool"
2566 };
2567 const char *invalid_names[] = {
2568 "INVALID_TYPE_XXXX"
2569 };
2570 struct ENUM_LIST *ReturnEnum;
2571 WERROR rpc_status;
2572 int i, s;
2573
2574 for (s = 0; s < ARRAY_SIZE(valid_names); s++) {
2575
2576 r.in.lpszTypeName = valid_names[s];
2577
2578 for (i=0; i < ARRAY_SIZE(dwType); i++) {
2579
2580 r.in.dwType = dwType[i];
2581 r.out.ReturnEnum = &ReturnEnum;
2582 r.out.rpc_status = &rpc_status;
2583
2584 torture_assert_ntstatus_ok(tctx,
2585 dcerpc_clusapi_CreateResTypeEnum_r(b, tctx, &r),
2586 "CreateResTypeEnum failed");
2587 torture_assert_werr_ok(tctx,
2588 r.out.result,
2589 "CreateResTypeEnum failed");
2590 }
2591
2592 for (i=0; i < ARRAY_SIZE(dwType_invalid); i++) {
2593
2594 r.in.dwType = dwType_invalid[i];
2595 r.out.ReturnEnum = &ReturnEnum;
2596 r.out.rpc_status = &rpc_status;
2597
2598 torture_assert_ntstatus_ok(tctx,
2599 dcerpc_clusapi_CreateResTypeEnum_r(b, tctx, &r),
2600 "CreateResTypeEnum failed");
2601 torture_assert_werr_ok(tctx,
2602 r.out.result,
2603 "CreateResTypeEnum failed");
2604 }
2605 }
2606
2607 for (s = 0; s < ARRAY_SIZE(invalid_names); s++) {
2608
2609 r.in.lpszTypeName = invalid_names[s];
2610
2611 for (i=0; i < ARRAY_SIZE(dwType); i++) {
2612
2613 r.in.dwType = dwType[i];
2614 r.out.ReturnEnum = &ReturnEnum;
2615 r.out.rpc_status = &rpc_status;
2616
2617 torture_assert_ntstatus_ok(tctx,
2618 dcerpc_clusapi_CreateResTypeEnum_r(b, tctx, &r),
2619 "CreateResTypeEnum failed");
2620 torture_assert_werr_equal(tctx,
2621 r.out.result,
2622 WERR_CLUSTER_RESOURCE_TYPE_NOT_FOUND,
2623 "CreateResTypeEnum failed");
2624 }
2625
2626 for (i=0; i < ARRAY_SIZE(dwType_invalid); i++) {
2627
2628 r.in.dwType = dwType_invalid[i];
2629 r.out.ReturnEnum = &ReturnEnum;
2630 r.out.rpc_status = &rpc_status;
2631
2632 torture_assert_ntstatus_ok(tctx,
2633 dcerpc_clusapi_CreateResTypeEnum_r(b, tctx, &r),
2634 "CreateResTypeEnum failed");
2635 torture_assert_werr_equal(tctx,
2636 r.out.result,
2637 WERR_CLUSTER_RESOURCE_TYPE_NOT_FOUND,
2638 "CreateResTypeEnum failed");
2639 }
2640 }
2641
2642
2643 return true;
2644 }
2645
test_CreateGroupEnum_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Cluster,const char ** multi_sz,const char ** multi_sz_ro)2646 static bool test_CreateGroupEnum_int(struct torture_context *tctx,
2647 struct dcerpc_pipe *p,
2648 struct policy_handle *Cluster,
2649 const char **multi_sz,
2650 const char **multi_sz_ro)
2651 {
2652 struct dcerpc_binding_handle *b = p->binding_handle;
2653 struct clusapi_CreateGroupEnum r;
2654 struct GROUP_ENUM_LIST *pResultList;
2655 WERROR rpc_status;
2656 DATA_BLOB blob = data_blob_null;
2657 DATA_BLOB blob_ro = data_blob_null;
2658
2659 r.in.hCluster = *Cluster;
2660 r.in.pProperties = blob.data;
2661 r.in.cbProperties = blob.length;
2662 r.in.pRoProperties = blob_ro.data;
2663 r.in.cbRoProperties = blob_ro.length;
2664 r.out.ppResultList = &pResultList;
2665 r.out.rpc_status = &rpc_status;
2666
2667 torture_assert_ntstatus_ok(tctx,
2668 dcerpc_clusapi_CreateGroupEnum_r(b, tctx, &r),
2669 "CreateGroupEnum failed");
2670 torture_assert_werr_ok(tctx,
2671 r.out.result,
2672 "CreateGroupEnum failed");
2673
2674 if (!push_reg_multi_sz(tctx, &blob, multi_sz)) {
2675 return false;
2676 }
2677
2678 if (!push_reg_multi_sz(tctx, &blob_ro, multi_sz_ro)) {
2679 return false;
2680 }
2681
2682 r.in.pProperties = blob.data;
2683 r.in.cbProperties = blob.length;
2684
2685 r.in.pRoProperties = blob_ro.data;
2686 r.in.cbRoProperties = blob_ro.length;
2687
2688 torture_assert_ntstatus_ok(tctx,
2689 dcerpc_clusapi_CreateGroupEnum_r(b, tctx, &r),
2690 "CreateGroupEnum failed");
2691 torture_assert_werr_ok(tctx,
2692 r.out.result,
2693 "CreateGroupEnum failed");
2694
2695 #if 0
2696 {
2697 int i;
2698 enum ndr_err_code ndr_err;
2699
2700 for (i=0; i < pResultList->EntryCount; i++) {
2701 struct clusapi_PROPERTY_LIST list;
2702 torture_comment(tctx, "entry #%d\n", i);
2703
2704 blob = data_blob_const(pResultList->Entry[i].Properties,
2705 pResultList->Entry[i].cbProperties);
2706
2707 ndr_err = ndr_pull_struct_blob(&blob, tctx, &list,
2708 (ndr_pull_flags_fn_t)ndr_pull_clusapi_PROPERTY_LIST);
2709 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2710 NDR_PRINT_DEBUG(clusapi_PROPERTY_LIST, &list);
2711 }
2712
2713 blob_ro = data_blob_const(pResultList->Entry[i].RoProperties,
2714 pResultList->Entry[i].cbRoProperties);
2715
2716 ndr_err = ndr_pull_struct_blob(&blob_ro, tctx, &list,
2717 (ndr_pull_flags_fn_t)ndr_pull_clusapi_PROPERTY_LIST);
2718 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2719 NDR_PRINT_DEBUG(clusapi_PROPERTY_LIST, &list);
2720 }
2721 }
2722 }
2723 #endif
2724
2725 return true;
2726 }
2727
test_CreateGroupEnum(struct torture_context * tctx,void * data)2728 static bool test_CreateGroupEnum(struct torture_context *tctx,
2729 void *data)
2730 {
2731 struct torture_clusapi_context *t =
2732 talloc_get_type_abort(data, struct torture_clusapi_context);
2733 struct policy_handle Cluster;
2734 bool ret;
2735 const char *multi_sz[] = {
2736 "Priority", NULL,
2737 };
2738 const char *multi_sz_ro[] = {
2739 "GroupType", NULL,
2740 };
2741
2742 if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
2743 return false;
2744 }
2745
2746 ret = test_CreateGroupEnum_int(tctx, t->p, &Cluster,
2747 multi_sz, multi_sz_ro);
2748 if (!ret) {
2749 goto done;
2750 }
2751
2752 done:
2753 test_CloseCluster_int(tctx, t->p, &Cluster);
2754
2755 return ret;
2756 }
2757
test_OpenNetwork_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszNetworkName,struct policy_handle * hNetwork)2758 static bool test_OpenNetwork_int(struct torture_context *tctx,
2759 struct dcerpc_pipe *p,
2760 const char *lpszNetworkName,
2761 struct policy_handle *hNetwork)
2762 {
2763 struct dcerpc_binding_handle *b = p->binding_handle;
2764 struct clusapi_OpenNetwork r;
2765 WERROR Status;
2766 WERROR rpc_status;
2767
2768 r.in.lpszNetworkName = lpszNetworkName;
2769 r.out.rpc_status = &rpc_status;
2770 r.out.Status = &Status;
2771 r.out.hNetwork = hNetwork ;
2772
2773 torture_assert_ntstatus_ok(tctx,
2774 dcerpc_clusapi_OpenNetwork_r(b, tctx, &r),
2775 "OpenNetwork failed");
2776 torture_assert_werr_ok(tctx,
2777 *r.out.Status,
2778 "OpenNetwork failed");
2779
2780 return true;
2781 }
2782
test_OpenNetworkEx_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszNetworkName,struct policy_handle * hNetwork)2783 static bool test_OpenNetworkEx_int(struct torture_context *tctx,
2784 struct dcerpc_pipe *p,
2785 const char *lpszNetworkName,
2786 struct policy_handle *hNetwork)
2787 {
2788 struct dcerpc_binding_handle *b = p->binding_handle;
2789 struct clusapi_OpenNetworkEx r;
2790 uint32_t lpdwGrantedAccess;
2791 WERROR Status;
2792 WERROR rpc_status;
2793
2794 r.in.lpszNetworkName = lpszNetworkName;
2795 r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
2796 r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
2797 r.out.rpc_status = &rpc_status;
2798 r.out.Status = &Status;
2799 r.out.hNetwork = hNetwork ;
2800
2801 torture_assert_ntstatus_ok(tctx,
2802 dcerpc_clusapi_OpenNetworkEx_r(b, tctx, &r),
2803 "OpenNetworkEx failed");
2804 torture_assert_werr_ok(tctx,
2805 *r.out.Status,
2806 "OpenNetworkEx failed");
2807
2808 return true;
2809 }
2810
test_CloseNetwork_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * Network)2811 static bool test_CloseNetwork_int(struct torture_context *tctx,
2812 struct dcerpc_pipe *p,
2813 struct policy_handle *Network)
2814 {
2815 struct dcerpc_binding_handle *b = p->binding_handle;
2816 struct clusapi_CloseNetwork r;
2817
2818 r.in.Network = Network;
2819 r.out.Network = Network;
2820
2821 torture_assert_ntstatus_ok(tctx,
2822 dcerpc_clusapi_CloseNetwork_r(b, tctx, &r),
2823 "CloseNetwork failed");
2824 torture_assert_werr_ok(tctx,
2825 r.out.result,
2826 "CloseNetwork failed");
2827 torture_assert(tctx,
2828 ndr_policy_handle_empty(Network),
2829 "policy_handle non empty after CloseNetwork");
2830
2831 return true;
2832 }
2833
test_OpenNetwork(struct torture_context * tctx,void * data)2834 static bool test_OpenNetwork(struct torture_context *tctx,
2835 void *data)
2836 {
2837 struct torture_clusapi_context *t =
2838 talloc_get_type_abort(data, struct torture_clusapi_context);
2839 struct policy_handle hNetwork;
2840
2841 if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2842 return false;
2843 }
2844
2845 test_CloseNetwork_int(tctx, t->p, &hNetwork);
2846
2847 return true;
2848 }
2849
test_OpenNetworkEx(struct torture_context * tctx,void * data)2850 static bool test_OpenNetworkEx(struct torture_context *tctx,
2851 void *data)
2852 {
2853 struct torture_clusapi_context *t =
2854 talloc_get_type_abort(data, struct torture_clusapi_context);
2855 struct policy_handle hNetwork;
2856
2857 if (!test_OpenNetworkEx_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2858 return false;
2859 }
2860
2861 test_CloseNetwork_int(tctx, t->p, &hNetwork);
2862
2863 return true;
2864 }
2865
test_CloseNetwork(struct torture_context * tctx,void * data)2866 static bool test_CloseNetwork(struct torture_context *tctx,
2867 void *data)
2868 {
2869 struct torture_clusapi_context *t =
2870 talloc_get_type_abort(data, struct torture_clusapi_context);
2871 struct policy_handle hNetwork;
2872
2873 if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2874 return false;
2875 }
2876
2877 return test_CloseNetwork_int(tctx, t->p, &hNetwork);
2878 }
2879
test_GetNetworkState_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNetwork)2880 static bool test_GetNetworkState_int(struct torture_context *tctx,
2881 struct dcerpc_pipe *p,
2882 struct policy_handle *hNetwork)
2883 {
2884 struct dcerpc_binding_handle *b = p->binding_handle;
2885 struct clusapi_GetNetworkState r;
2886 enum clusapi_ClusterNetworkState State;
2887 WERROR rpc_status;
2888
2889 r.in.hNetwork = *hNetwork;
2890 r.out.State = &State;
2891 r.out.rpc_status = &rpc_status;
2892
2893 torture_assert_ntstatus_ok(tctx,
2894 dcerpc_clusapi_GetNetworkState_r(b, tctx, &r),
2895 "GetNetworkState failed");
2896 torture_assert_werr_ok(tctx,
2897 r.out.result,
2898 "GetNetworkState failed");
2899
2900 return true;
2901 }
2902
test_GetNetworkState(struct torture_context * tctx,void * data)2903 static bool test_GetNetworkState(struct torture_context *tctx,
2904 void *data)
2905 {
2906 struct torture_clusapi_context *t =
2907 talloc_get_type_abort(data, struct torture_clusapi_context);
2908 struct policy_handle hNetwork;
2909 bool ret = true;
2910
2911 if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2912 return false;
2913 }
2914
2915 ret = test_GetNetworkState_int(tctx, t->p, &hNetwork);
2916
2917 test_CloseNetwork_int(tctx, t->p, &hNetwork);
2918
2919 return ret;
2920 }
2921
test_GetNetworkId_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNetwork)2922 static bool test_GetNetworkId_int(struct torture_context *tctx,
2923 struct dcerpc_pipe *p,
2924 struct policy_handle *hNetwork)
2925 {
2926 struct dcerpc_binding_handle *b = p->binding_handle;
2927 struct clusapi_GetNetworkId r;
2928 const char *pGuid;
2929 WERROR rpc_status;
2930
2931 r.in.hNetwork = *hNetwork;
2932 r.out.pGuid = &pGuid;
2933 r.out.rpc_status = &rpc_status;
2934
2935 torture_assert_ntstatus_ok(tctx,
2936 dcerpc_clusapi_GetNetworkId_r(b, tctx, &r),
2937 "GetNetworkId failed");
2938 torture_assert_werr_ok(tctx,
2939 r.out.result,
2940 "GetNetworkId failed");
2941
2942 return true;
2943 }
2944
test_GetNetworkId(struct torture_context * tctx,void * data)2945 static bool test_GetNetworkId(struct torture_context *tctx,
2946 void *data)
2947 {
2948 struct torture_clusapi_context *t =
2949 talloc_get_type_abort(data, struct torture_clusapi_context);
2950 struct policy_handle hNetwork;
2951 bool ret = true;
2952
2953 if (!test_OpenNetwork_int(tctx, t->p, "Cluster Network 1", &hNetwork)) {
2954 return false;
2955 }
2956
2957 ret = test_GetNetworkId_int(tctx, t->p, &hNetwork);
2958
2959 test_CloseNetwork_int(tctx, t->p, &hNetwork);
2960
2961 return ret;
2962 }
2963
test_one_network(struct torture_context * tctx,struct dcerpc_pipe * p,const char * network_name)2964 static bool test_one_network(struct torture_context *tctx,
2965 struct dcerpc_pipe *p,
2966 const char *network_name)
2967 {
2968 struct policy_handle hNetwork;
2969
2970 torture_assert(tctx,
2971 test_OpenNetwork_int(tctx, p, network_name, &hNetwork),
2972 "failed to open network");
2973 test_CloseNetwork_int(tctx, p, &hNetwork);
2974
2975 torture_assert(tctx,
2976 test_OpenNetworkEx_int(tctx, p, network_name, &hNetwork),
2977 "failed to openex network");
2978
2979 torture_assert(tctx,
2980 test_GetNetworkId_int(tctx, p, &hNetwork),
2981 "failed to query network id");
2982 torture_assert(tctx,
2983 test_GetNetworkState_int(tctx, p, &hNetwork),
2984 "failed to query network id");
2985
2986 test_CloseNetwork_int(tctx, p, &hNetwork);
2987
2988 return true;
2989 }
2990
test_all_networks(struct torture_context * tctx,void * data)2991 static bool test_all_networks(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 dcerpc_binding_handle *b = t->p->binding_handle;
2997 struct clusapi_CreateEnum r;
2998 uint32_t dwType = CLUSTER_ENUM_NETWORK;
2999 struct ENUM_LIST *ReturnEnum;
3000 WERROR rpc_status;
3001 int i;
3002
3003 r.in.dwType = dwType;
3004 r.out.ReturnEnum = &ReturnEnum;
3005 r.out.rpc_status = &rpc_status;
3006
3007 torture_assert_ntstatus_ok(tctx,
3008 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
3009 "CreateEnum failed");
3010 torture_assert_werr_ok(tctx,
3011 r.out.result,
3012 "CreateEnum failed");
3013
3014 for (i=0; i < ReturnEnum->EntryCount; i++) {
3015
3016 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
3017
3018 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NETWORK, "type mismatch");
3019
3020 torture_assert(tctx,
3021 test_one_network(tctx, t->p, e.Name),
3022 "failed to test one network");
3023 }
3024
3025 return true;
3026 }
3027
test_OpenNetInterface_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszNetInterfaceName,struct policy_handle * hNetInterface)3028 static bool test_OpenNetInterface_int(struct torture_context *tctx,
3029 struct dcerpc_pipe *p,
3030 const char *lpszNetInterfaceName,
3031 struct policy_handle *hNetInterface)
3032 {
3033 struct dcerpc_binding_handle *b = p->binding_handle;
3034 struct clusapi_OpenNetInterface r;
3035 WERROR Status;
3036 WERROR rpc_status;
3037
3038 r.in.lpszNetInterfaceName = lpszNetInterfaceName;
3039 r.out.rpc_status = &rpc_status;
3040 r.out.Status = &Status;
3041 r.out.hNetInterface = hNetInterface;
3042
3043 torture_assert_ntstatus_ok(tctx,
3044 dcerpc_clusapi_OpenNetInterface_r(b, tctx, &r),
3045 "OpenNetInterface failed");
3046 torture_assert_werr_ok(tctx,
3047 *r.out.Status,
3048 "OpenNetInterface failed");
3049
3050 return true;
3051 }
3052
test_OpenNetInterfaceEx_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszNetInterfaceName,struct policy_handle * hNetInterface)3053 static bool test_OpenNetInterfaceEx_int(struct torture_context *tctx,
3054 struct dcerpc_pipe *p,
3055 const char *lpszNetInterfaceName,
3056 struct policy_handle *hNetInterface)
3057 {
3058 struct dcerpc_binding_handle *b = p->binding_handle;
3059 struct clusapi_OpenNetInterfaceEx r;
3060 uint32_t lpdwGrantedAccess;
3061 WERROR Status;
3062 WERROR rpc_status;
3063
3064 r.in.lpszNetInterfaceName = lpszNetInterfaceName;
3065 r.in.dwDesiredAccess = SEC_FLAG_MAXIMUM_ALLOWED;
3066 r.out.lpdwGrantedAccess = &lpdwGrantedAccess;
3067 r.out.rpc_status = &rpc_status;
3068 r.out.Status = &Status;
3069 r.out.hNetInterface = hNetInterface;
3070
3071 torture_assert_ntstatus_ok(tctx,
3072 dcerpc_clusapi_OpenNetInterfaceEx_r(b, tctx, &r),
3073 "OpenNetInterfaceEx failed");
3074 torture_assert_werr_ok(tctx,
3075 *r.out.Status,
3076 "OpenNetInterfaceEx failed");
3077
3078 return true;
3079 }
3080
test_CloseNetInterface_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * NetInterface)3081 static bool test_CloseNetInterface_int(struct torture_context *tctx,
3082 struct dcerpc_pipe *p,
3083 struct policy_handle *NetInterface)
3084 {
3085 struct dcerpc_binding_handle *b = p->binding_handle;
3086 struct clusapi_CloseNetInterface r;
3087
3088 r.in.NetInterface = NetInterface;
3089 r.out.NetInterface = NetInterface;
3090
3091 torture_assert_ntstatus_ok(tctx,
3092 dcerpc_clusapi_CloseNetInterface_r(b, tctx, &r),
3093 "CloseNetInterface failed");
3094 torture_assert_werr_ok(tctx,
3095 r.out.result,
3096 "CloseNetInterface failed");
3097 torture_assert(tctx,
3098 ndr_policy_handle_empty(NetInterface),
3099 "policy_handle non empty after CloseNetInterface");
3100
3101 return true;
3102 }
3103
test_OpenNetInterface(struct torture_context * tctx,void * data)3104 static bool test_OpenNetInterface(struct torture_context *tctx,
3105 void *data)
3106 {
3107 struct torture_clusapi_context *t =
3108 talloc_get_type_abort(data, struct torture_clusapi_context);
3109 struct policy_handle hNetInterface;
3110
3111 if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
3112 return false;
3113 }
3114
3115 test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
3116
3117 return true;
3118 }
3119
test_OpenNetInterfaceEx(struct torture_context * tctx,void * data)3120 static bool test_OpenNetInterfaceEx(struct torture_context *tctx,
3121 void *data)
3122 {
3123 struct torture_clusapi_context *t =
3124 talloc_get_type_abort(data, struct torture_clusapi_context);
3125 struct policy_handle hNetInterface;
3126
3127 if (!test_OpenNetInterfaceEx_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
3128 return false;
3129 }
3130
3131 test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
3132
3133 return true;
3134 }
3135
test_CloseNetInterface(struct torture_context * tctx,void * data)3136 static bool test_CloseNetInterface(struct torture_context *tctx,
3137 void *data)
3138 {
3139 struct torture_clusapi_context *t =
3140 talloc_get_type_abort(data, struct torture_clusapi_context);
3141 struct policy_handle hNetInterface;
3142
3143 if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
3144 return false;
3145 }
3146
3147 return test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
3148 }
3149
test_GetNetInterfaceState_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNetInterface)3150 static bool test_GetNetInterfaceState_int(struct torture_context *tctx,
3151 struct dcerpc_pipe *p,
3152 struct policy_handle *hNetInterface)
3153 {
3154 struct dcerpc_binding_handle *b = p->binding_handle;
3155 struct clusapi_GetNetInterfaceState r;
3156 enum clusapi_ClusterNetInterfaceState State;
3157 WERROR rpc_status;
3158
3159 r.in.hNetInterface = *hNetInterface;
3160 r.out.State = &State;
3161 r.out.rpc_status = &rpc_status;
3162
3163 torture_assert_ntstatus_ok(tctx,
3164 dcerpc_clusapi_GetNetInterfaceState_r(b, tctx, &r),
3165 "GetNetInterfaceState failed");
3166 torture_assert_werr_ok(tctx,
3167 r.out.result,
3168 "GetNetInterfaceState failed");
3169
3170 return true;
3171 }
3172
test_GetNetInterfaceState(struct torture_context * tctx,void * data)3173 static bool test_GetNetInterfaceState(struct torture_context *tctx,
3174 void *data)
3175 {
3176 struct torture_clusapi_context *t =
3177 talloc_get_type_abort(data, struct torture_clusapi_context);
3178 struct policy_handle hNetInterface;
3179 bool ret = true;
3180
3181 if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
3182 return false;
3183 }
3184
3185 ret = test_GetNetInterfaceState_int(tctx, t->p, &hNetInterface);
3186
3187 test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
3188
3189 return ret;
3190 }
3191
test_GetNetInterfaceId_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hNetInterface)3192 static bool test_GetNetInterfaceId_int(struct torture_context *tctx,
3193 struct dcerpc_pipe *p,
3194 struct policy_handle *hNetInterface)
3195 {
3196 struct dcerpc_binding_handle *b = p->binding_handle;
3197 struct clusapi_GetNetInterfaceId r;
3198 const char *pGuid;
3199 WERROR rpc_status;
3200
3201 r.in.hNetInterface = *hNetInterface;
3202 r.out.pGuid = &pGuid;
3203 r.out.rpc_status = &rpc_status;
3204
3205 torture_assert_ntstatus_ok(tctx,
3206 dcerpc_clusapi_GetNetInterfaceId_r(b, tctx, &r),
3207 "GetNetInterfaceId failed");
3208 torture_assert_werr_ok(tctx,
3209 r.out.result,
3210 "GetNetInterfaceId failed");
3211
3212 return true;
3213 }
3214
test_GetNetInterfaceId(struct torture_context * tctx,void * data)3215 static bool test_GetNetInterfaceId(struct torture_context *tctx,
3216 void *data)
3217 {
3218 struct torture_clusapi_context *t =
3219 talloc_get_type_abort(data, struct torture_clusapi_context);
3220 struct policy_handle hNetInterface;
3221 bool ret = true;
3222
3223 if (!test_OpenNetInterface_int(tctx, t->p, "node1 - Ethernet", &hNetInterface)) {
3224 return false;
3225 }
3226
3227 ret = test_GetNetInterfaceId_int(tctx, t->p, &hNetInterface);
3228
3229 test_CloseNetInterface_int(tctx, t->p, &hNetInterface);
3230
3231 return ret;
3232 }
3233
test_one_netinterface(struct torture_context * tctx,struct dcerpc_pipe * p,const char * netinterface_name)3234 static bool test_one_netinterface(struct torture_context *tctx,
3235 struct dcerpc_pipe *p,
3236 const char *netinterface_name)
3237 {
3238 struct policy_handle hNetInterface;
3239
3240 torture_assert(tctx,
3241 test_OpenNetInterface_int(tctx, p, netinterface_name, &hNetInterface),
3242 "failed to open netinterface");
3243 test_CloseNetInterface_int(tctx, p, &hNetInterface);
3244
3245 torture_assert(tctx,
3246 test_OpenNetInterfaceEx_int(tctx, p, netinterface_name, &hNetInterface),
3247 "failed to openex netinterface");
3248
3249 torture_assert(tctx,
3250 test_GetNetInterfaceId_int(tctx, p, &hNetInterface),
3251 "failed to query netinterface id");
3252 torture_assert(tctx,
3253 test_GetNetInterfaceState_int(tctx, p, &hNetInterface),
3254 "failed to query netinterface id");
3255
3256 test_CloseNetInterface_int(tctx, p, &hNetInterface);
3257
3258 return true;
3259 }
3260
test_all_netinterfaces(struct torture_context * tctx,void * data)3261 static bool test_all_netinterfaces(struct torture_context *tctx,
3262 void *data)
3263 {
3264 struct torture_clusapi_context *t =
3265 talloc_get_type_abort(data, struct torture_clusapi_context);
3266 struct dcerpc_binding_handle *b = t->p->binding_handle;
3267 struct clusapi_CreateEnum r;
3268 uint32_t dwType = CLUSTER_ENUM_NETINTERFACE;
3269 struct ENUM_LIST *ReturnEnum;
3270 WERROR rpc_status;
3271 int i;
3272
3273 r.in.dwType = dwType;
3274 r.out.ReturnEnum = &ReturnEnum;
3275 r.out.rpc_status = &rpc_status;
3276
3277 torture_assert_ntstatus_ok(tctx,
3278 dcerpc_clusapi_CreateEnum_r(b, tctx, &r),
3279 "CreateEnum failed");
3280 torture_assert_werr_ok(tctx,
3281 r.out.result,
3282 "CreateEnum failed");
3283
3284 for (i=0; i < ReturnEnum->EntryCount; i++) {
3285
3286 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
3287
3288 torture_assert_int_equal(tctx, e.Type, CLUSTER_ENUM_NETINTERFACE, "type mismatch");
3289
3290 torture_assert(tctx,
3291 test_one_netinterface(tctx, t->p, e.Name),
3292 "failed to test one netinterface");
3293 }
3294
3295 return true;
3296 }
3297
test_CloseKey_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * pKey)3298 static bool test_CloseKey_int(struct torture_context *tctx,
3299 struct dcerpc_pipe *p,
3300 struct policy_handle *pKey)
3301 {
3302 struct dcerpc_binding_handle *b = p->binding_handle;
3303 struct clusapi_CloseKey r;
3304
3305 r.in.pKey = pKey;
3306 r.out.pKey = pKey;
3307
3308 torture_assert_ntstatus_ok(tctx,
3309 dcerpc_clusapi_CloseKey_r(b, tctx, &r),
3310 "CloseKey failed");
3311 torture_assert_werr_ok(tctx,
3312 r.out.result,
3313 "CloseKey failed");
3314 torture_assert(tctx,
3315 ndr_policy_handle_empty(pKey),
3316 "policy_handle non empty after CloseKey");
3317
3318 return true;
3319 }
3320
test_GetRootKey_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * phKey)3321 static bool test_GetRootKey_int(struct torture_context *tctx,
3322 struct dcerpc_pipe *p,
3323 struct policy_handle *phKey)
3324 {
3325 struct dcerpc_binding_handle *b = p->binding_handle;
3326 struct clusapi_GetRootKey r;
3327 WERROR Status;
3328 WERROR rpc_status;
3329
3330 r.in.samDesired = SEC_FLAG_MAXIMUM_ALLOWED;
3331 r.out.Status = &Status;
3332 r.out.rpc_status = &rpc_status;
3333 r.out.phKey = phKey;
3334
3335 torture_assert_ntstatus_ok(tctx,
3336 dcerpc_clusapi_GetRootKey_r(b, tctx, &r),
3337 "GetRootKey failed");
3338 torture_assert_werr_ok(tctx,
3339 *r.out.Status,
3340 "GetRootKey failed");
3341
3342 return true;
3343 }
3344
test_EnumKey_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hKey)3345 static bool test_EnumKey_int(struct torture_context *tctx,
3346 struct dcerpc_pipe *p,
3347 struct policy_handle *hKey)
3348 {
3349 struct dcerpc_binding_handle *b = p->binding_handle;
3350 struct clusapi_EnumKey r;
3351 const char *KeyName;
3352 NTTIME lpftLastWriteTime;
3353 WERROR rpc_status;
3354
3355 r.in.hKey = *hKey;
3356 r.in.dwIndex = 0;
3357 r.out.KeyName = &KeyName;
3358 r.out.lpftLastWriteTime = &lpftLastWriteTime;
3359 r.out.rpc_status = &rpc_status;
3360
3361 torture_assert_ntstatus_ok(tctx,
3362 dcerpc_clusapi_EnumKey_r(b, tctx, &r),
3363 "EnumKey failed");
3364 torture_assert_werr_ok(tctx,
3365 r.out.result,
3366 "EnumKey failed");
3367
3368 return true;
3369 }
3370
test_OpenKey_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hKey,const char * lpSubKey,struct policy_handle * phKey)3371 static bool test_OpenKey_int(struct torture_context *tctx,
3372 struct dcerpc_pipe *p,
3373 struct policy_handle *hKey,
3374 const char *lpSubKey,
3375 struct policy_handle *phKey)
3376 {
3377 struct dcerpc_binding_handle *b = p->binding_handle;
3378 struct clusapi_OpenKey r;
3379 WERROR Status;
3380 WERROR rpc_status;
3381
3382 r.in.hKey = *hKey;
3383 r.in.lpSubKey = lpSubKey;
3384 r.in.samDesired = SEC_FLAG_MAXIMUM_ALLOWED;
3385 r.out.Status = &Status;
3386 r.out.rpc_status = &rpc_status;
3387 r.out.phKey = phKey;
3388
3389 torture_assert_ntstatus_ok(tctx,
3390 dcerpc_clusapi_OpenKey_r(b, tctx, &r),
3391 "OpenKey failed");
3392 torture_assert_werr_ok(tctx,
3393 *r.out.Status,
3394 "OpenKey failed");
3395
3396 return true;
3397 }
3398
test_EnumValue_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hKey)3399 static bool test_EnumValue_int(struct torture_context *tctx,
3400 struct dcerpc_pipe *p,
3401 struct policy_handle *hKey)
3402 {
3403 struct dcerpc_binding_handle *b = p->binding_handle;
3404 struct clusapi_EnumValue r;
3405 const char *lpValueName;
3406 uint32_t lpType;
3407 uint32_t TotalSize;
3408 WERROR rpc_status;
3409 int i = 0;
3410
3411 do {
3412 uint32_t lpcbData = 2048;
3413
3414 r.in.hKey = *hKey;
3415 r.in.dwIndex = i++;
3416 r.in.lpcbData = &lpcbData;
3417 r.out.lpValueName = &lpValueName;
3418 r.out.lpType = &lpType;
3419 r.out.lpData = talloc_array(tctx, uint8_t, lpcbData);
3420 r.out.TotalSize = &TotalSize;
3421 r.out.rpc_status = &rpc_status;
3422 r.out.lpcbData = &lpcbData;
3423
3424 torture_assert_ntstatus_ok(tctx,
3425 dcerpc_clusapi_EnumValue_r(b, tctx, &r),
3426 "EnumValue failed");
3427
3428 } while (W_ERROR_IS_OK(r.out.result));
3429
3430 torture_assert_werr_equal(tctx,
3431 r.out.result,
3432 WERR_NO_MORE_ITEMS,
3433 "EnumValue failed");
3434
3435 return true;
3436 }
3437
test_QueryInfoKey_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hKey)3438 static bool test_QueryInfoKey_int(struct torture_context *tctx,
3439 struct dcerpc_pipe *p,
3440 struct policy_handle *hKey)
3441 {
3442 struct dcerpc_binding_handle *b = p->binding_handle;
3443 struct clusapi_QueryInfoKey r;
3444 uint32_t lpcSubKeys;
3445 uint32_t lpcbMaxSubKeyLen;
3446 uint32_t lpcValues;
3447 uint32_t lpcbMaxValueNameLen;
3448 uint32_t lpcbMaxValueLen;
3449 uint32_t lpcbSecurityDescriptor;
3450 NTTIME lpftLastWriteTime;
3451 WERROR rpc_status;
3452
3453 r.in.hKey = *hKey;
3454 r.out.lpcSubKeys = &lpcSubKeys;
3455 r.out.lpcbMaxSubKeyLen = &lpcbMaxSubKeyLen;
3456 r.out.lpcValues = &lpcValues;
3457 r.out.lpcbMaxValueNameLen = &lpcbMaxValueNameLen;
3458 r.out.lpcbMaxValueLen = &lpcbMaxValueLen;
3459 r.out.lpcbSecurityDescriptor = &lpcbSecurityDescriptor;
3460 r.out.lpftLastWriteTime = &lpftLastWriteTime;
3461 r.out.rpc_status = &rpc_status;
3462
3463 torture_assert_ntstatus_ok(tctx,
3464 dcerpc_clusapi_QueryInfoKey_r(b, tctx, &r),
3465 "QueryInfoKey failed");
3466 torture_assert_werr_ok(tctx,
3467 r.out.result,
3468 "QueryInfoKey failed");
3469
3470 return true;
3471 }
3472
test_GetKeySecurity_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hKey)3473 static bool test_GetKeySecurity_int(struct torture_context *tctx,
3474 struct dcerpc_pipe *p,
3475 struct policy_handle *hKey)
3476 {
3477 struct dcerpc_binding_handle *b = p->binding_handle;
3478 struct clusapi_GetKeySecurity r;
3479 uint32_t SecurityInformation = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
3480 struct RPC_SECURITY_DESCRIPTOR pRpcSecurityDescriptor;
3481 WERROR rpc_status;
3482
3483 ZERO_STRUCT(pRpcSecurityDescriptor);
3484
3485 r.in.hKey = *hKey;
3486 r.in.SecurityInformation = SecurityInformation;
3487 r.in.pRpcSecurityDescriptor = &pRpcSecurityDescriptor;
3488 r.out.rpc_status = &rpc_status;
3489 r.out.pRpcSecurityDescriptor = &pRpcSecurityDescriptor;
3490
3491 torture_assert_ntstatus_ok(tctx,
3492 dcerpc_clusapi_GetKeySecurity_r(b, tctx, &r),
3493 "GetKeySecurity failed");
3494
3495 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
3496 pRpcSecurityDescriptor.lpSecurityDescriptor = talloc_array(tctx,
3497 uint8_t, pRpcSecurityDescriptor.cbInSecurityDescriptor);
3498
3499 torture_assert_ntstatus_ok(tctx,
3500 dcerpc_clusapi_GetKeySecurity_r(b, tctx, &r),
3501 "GetKeySecurity failed");
3502 }
3503
3504 torture_assert_werr_ok(tctx,
3505 r.out.result,
3506 "GetKeySecurity failed");
3507
3508 return true;
3509 }
3510
test_GetRootKey(struct torture_context * tctx,void * data)3511 static bool test_GetRootKey(struct torture_context *tctx,
3512 void *data)
3513 {
3514 struct torture_clusapi_context *t =
3515 talloc_get_type_abort(data, struct torture_clusapi_context);
3516 struct policy_handle hKey;
3517
3518 if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3519 return false;
3520 }
3521
3522 test_CloseKey_int(tctx, t->p, &hKey);
3523
3524 return true;
3525 }
3526
test_CloseKey(struct torture_context * tctx,void * data)3527 static bool test_CloseKey(struct torture_context *tctx,
3528 void *data)
3529 {
3530 struct torture_clusapi_context *t =
3531 talloc_get_type_abort(data, struct torture_clusapi_context);
3532 struct policy_handle hKey;
3533
3534 if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3535 return false;
3536 }
3537
3538 return test_CloseKey_int(tctx, t->p, &hKey);
3539 }
3540
test_EnumKey(struct torture_context * tctx,void * data)3541 static bool test_EnumKey(struct torture_context *tctx,
3542 void *data)
3543 {
3544 struct torture_clusapi_context *t =
3545 talloc_get_type_abort(data, struct torture_clusapi_context);
3546 struct policy_handle hKey;
3547 bool ret = true;
3548
3549 if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3550 return false;
3551 }
3552
3553 ret = test_EnumKey_int(tctx, t->p, &hKey);
3554
3555 test_CloseKey_int(tctx, t->p, &hKey);
3556
3557 return ret;
3558 }
3559
test_QueryValue_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hKey,const char * ValueName)3560 static bool test_QueryValue_int(struct torture_context *tctx,
3561 struct dcerpc_pipe *p,
3562 struct policy_handle *hKey,
3563 const char *ValueName)
3564 {
3565 struct dcerpc_binding_handle *b = p->binding_handle;
3566 struct clusapi_QueryValue r;
3567 uint32_t lpValueType;
3568 uint32_t lpcbRequired;
3569 WERROR rpc_status;
3570
3571 r.in.hKey = *hKey;
3572 r.in.lpValueName = ValueName;
3573 r.in.cbData = 0;
3574 r.out.lpValueType = &lpValueType;
3575 r.out.lpData = NULL;
3576 r.out.lpcbRequired = &lpcbRequired;
3577 r.out.rpc_status = &rpc_status;
3578
3579 torture_assert_ntstatus_ok(tctx,
3580 dcerpc_clusapi_QueryValue_r(b, tctx, &r),
3581 "QueryValue failed");
3582
3583 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
3584
3585 r.in.cbData = lpcbRequired;
3586 r.out.lpData = talloc_zero_array(tctx, uint8_t, r.in.cbData);
3587
3588 torture_assert_ntstatus_ok(tctx,
3589 dcerpc_clusapi_QueryValue_r(b, tctx, &r),
3590 "QueryValue failed");
3591 }
3592
3593 torture_assert_werr_ok(tctx,
3594 r.out.result,
3595 "QueryValue failed");
3596
3597 if (lpValueType == REG_SZ) {
3598 const char *s;
3599 DATA_BLOB blob = data_blob_const(r.out.lpData, lpcbRequired);
3600 pull_reg_sz(tctx, &blob, &s);
3601 torture_comment(tctx, "got: %s\n", s);
3602 }
3603
3604 return true;
3605 }
3606
test_QueryValue(struct torture_context * tctx,void * data)3607 static bool test_QueryValue(struct torture_context *tctx,
3608 void *data)
3609 {
3610 struct torture_clusapi_context *t =
3611 talloc_get_type_abort(data, struct torture_clusapi_context);
3612 struct policy_handle hKey;
3613 bool ret = true;
3614
3615 if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3616 return false;
3617 }
3618
3619 ret = test_QueryValue_int(tctx, t->p, &hKey, "ClusterInstanceID");
3620
3621 test_CloseKey_int(tctx, t->p, &hKey);
3622
3623 return ret;
3624 }
3625
3626
test_one_key(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * hKey,const char * KeyName)3627 static bool test_one_key(struct torture_context *tctx,
3628 struct dcerpc_pipe *p,
3629 struct policy_handle *hKey,
3630 const char *KeyName)
3631 {
3632 struct policy_handle phKey;
3633
3634 torture_assert(tctx,
3635 test_OpenKey_int(tctx, p, hKey, KeyName, &phKey),
3636 "failed to open key");
3637
3638 torture_assert(tctx,
3639 test_QueryInfoKey_int(tctx, p, &phKey),
3640 "failed to enum values");
3641 torture_assert(tctx,
3642 test_GetKeySecurity_int(tctx, p, &phKey),
3643 "failed to get key security");
3644
3645 torture_assert(tctx,
3646 test_EnumValue_int(tctx, p, &phKey),
3647 "failed to enum values");
3648
3649 torture_assert(tctx,
3650 test_CloseKey_int(tctx, p, &phKey),
3651 "failed to close key");
3652
3653 return true;
3654 }
3655
test_all_keys(struct torture_context * tctx,void * data)3656 static bool test_all_keys(struct torture_context *tctx,
3657 void *data)
3658 {
3659 struct torture_clusapi_context *t =
3660 talloc_get_type_abort(data, struct torture_clusapi_context);
3661 struct dcerpc_binding_handle *b = t->p->binding_handle;
3662 struct policy_handle hKey;
3663 struct clusapi_EnumKey r;
3664 const char *KeyName;
3665 NTTIME lpftLastWriteTime;
3666 WERROR rpc_status;
3667 int i = 0;
3668
3669 if (!test_GetRootKey_int(tctx, t->p, &hKey)) {
3670 return false;
3671 }
3672
3673 do {
3674 r.in.hKey = hKey;
3675 r.in.dwIndex = i++;
3676 r.out.KeyName = &KeyName;
3677 r.out.lpftLastWriteTime = &lpftLastWriteTime;
3678 r.out.rpc_status = &rpc_status;
3679
3680 torture_assert_ntstatus_ok(tctx,
3681 dcerpc_clusapi_EnumKey_r(b, tctx, &r),
3682 "EnumKey failed");
3683
3684 if (W_ERROR_IS_OK(r.out.result)) {
3685 torture_assert(tctx,
3686 test_one_key(tctx, t->p, &hKey, KeyName),
3687 "failed to test one key");
3688 }
3689
3690 } while (W_ERROR_IS_OK(r.out.result));
3691
3692 torture_assert_werr_equal(tctx,
3693 r.out.result,
3694 WERR_NO_MORE_ITEMS,
3695 "EnumKey failed");
3696
3697 test_CloseKey_int(tctx, t->p, &hKey);
3698
3699 return true;
3700 }
3701
test_OpenGroupSet_int(struct torture_context * tctx,struct dcerpc_pipe * p,const char * lpszGroupSetName,struct policy_handle * hGroupSet)3702 static bool test_OpenGroupSet_int(struct torture_context *tctx,
3703 struct dcerpc_pipe *p,
3704 const char *lpszGroupSetName,
3705 struct policy_handle *hGroupSet)
3706 {
3707 struct dcerpc_binding_handle *b = p->binding_handle;
3708 struct clusapi_OpenGroupSet r;
3709 WERROR Status;
3710 WERROR rpc_status;
3711
3712 r.in.lpszGroupSetName = lpszGroupSetName;
3713 r.out.rpc_status = &rpc_status;
3714 r.out.Status = &Status;
3715 r.out.hGroupSet = hGroupSet;
3716
3717 torture_assert_ntstatus_ok(tctx,
3718 dcerpc_clusapi_OpenGroupSet_r(b, tctx, &r),
3719 "OpenGroupSet failed");
3720 torture_assert_werr_ok(tctx,
3721 *r.out.Status,
3722 "OpenGroupSet failed");
3723
3724 return true;
3725 }
3726
test_CloseGroupSet_int(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * GroupSet)3727 static bool test_CloseGroupSet_int(struct torture_context *tctx,
3728 struct dcerpc_pipe *p,
3729 struct policy_handle *GroupSet)
3730 {
3731 struct dcerpc_binding_handle *b = p->binding_handle;
3732 struct clusapi_CloseGroupSet r;
3733
3734 r.in.GroupSet = GroupSet;
3735 r.out.GroupSet = GroupSet;
3736
3737 torture_assert_ntstatus_ok(tctx,
3738 dcerpc_clusapi_CloseGroupSet_r(b, tctx, &r),
3739 "CloseGroupSet failed");
3740 torture_assert_werr_ok(tctx,
3741 r.out.result,
3742 "CloseGroupSet failed");
3743 torture_assert(tctx,
3744 ndr_policy_handle_empty(GroupSet),
3745 "policy_handle non empty after CloseGroupSet");
3746
3747 return true;
3748 }
3749
test_OpenGroupSet(struct torture_context * tctx,void * data)3750 static bool test_OpenGroupSet(struct torture_context *tctx,
3751 void *data)
3752 {
3753 struct torture_clusapi_context *t =
3754 talloc_get_type_abort(data, struct torture_clusapi_context);
3755 struct policy_handle hGroupSet;
3756
3757 if (t->lpwMajorVersion < 0x000a) {
3758 torture_skip(tctx, "GroupSet fn not available on old clusters");
3759 return true;
3760 }
3761
3762 if (!test_OpenGroupSet_int(tctx, t->p, "Cluster Group", &hGroupSet)) {
3763 return false;
3764 }
3765
3766 test_CloseGroupSet_int(tctx, t->p, &hGroupSet);
3767
3768 return true;
3769 }
3770
test_CloseGroupSet(struct torture_context * tctx,void * data)3771 static bool test_CloseGroupSet(struct torture_context *tctx,
3772 void *data)
3773 {
3774 struct torture_clusapi_context *t =
3775 talloc_get_type_abort(data, struct torture_clusapi_context);
3776 struct policy_handle hGroupSet;
3777
3778 if (t->lpwMajorVersion < 0x000a) {
3779 torture_skip(tctx, "GroupSet fn not available on old clusters");
3780 return true;
3781 }
3782
3783 if (!test_OpenGroupSet_int(tctx, t->p, "Cluster Group", &hGroupSet)) {
3784 return false;
3785 }
3786
3787 return test_CloseGroupSet_int(tctx, t->p, &hGroupSet);
3788 }
3789
test_one_groupset(struct torture_context * tctx,struct dcerpc_pipe * p,const char * groupset_name)3790 static bool test_one_groupset(struct torture_context *tctx,
3791 struct dcerpc_pipe *p,
3792 const char *groupset_name)
3793 {
3794 struct policy_handle hGroupSet;
3795
3796 torture_assert(tctx,
3797 test_OpenGroupSet_int(tctx, p, groupset_name, &hGroupSet),
3798 "failed to open groupset");
3799
3800 test_CloseGroupSet_int(tctx, p, &hGroupSet);
3801
3802 return true;
3803 }
3804
test_all_groupsets(struct torture_context * tctx,void * data)3805 static bool test_all_groupsets(struct torture_context *tctx,
3806 void *data)
3807 {
3808 struct torture_clusapi_context *t =
3809 talloc_get_type_abort(data, struct torture_clusapi_context);
3810 struct dcerpc_binding_handle *b = t->p->binding_handle;
3811 struct clusapi_CreateGroupSetEnum r;
3812 struct ENUM_LIST *ReturnEnum;
3813 struct policy_handle Cluster;
3814 WERROR rpc_status;
3815 int i;
3816
3817 if (!test_OpenCluster_int(tctx, t->p, &Cluster)) {
3818 return false;
3819 }
3820
3821 r.in.hCluster = Cluster;
3822 r.out.ReturnEnum = &ReturnEnum;
3823 r.out.rpc_status = &rpc_status;
3824
3825 torture_assert_ntstatus_ok(tctx,
3826 dcerpc_clusapi_CreateGroupSetEnum_r(b, tctx, &r),
3827 "CreateGroupSetEnum failed");
3828 torture_assert_werr_ok(tctx,
3829 r.out.result,
3830 "CreateGroupSetEnum failed");
3831
3832 test_CloseCluster_int(tctx, t->p, &Cluster);
3833
3834 for (i=0; i < ReturnEnum->EntryCount; i++) {
3835
3836 struct ENUM_ENTRY e = ReturnEnum->Entry[i];
3837
3838 torture_assert(tctx,
3839 test_one_groupset(tctx, t->p, e.Name),
3840 "failed to test one groupset");
3841 }
3842
3843 return true;
3844 }
3845
torture_rpc_clusapi_setup_common(struct torture_context * tctx,struct torture_clusapi_context * t)3846 static bool torture_rpc_clusapi_setup_common(struct torture_context *tctx,
3847 struct torture_clusapi_context *t)
3848 {
3849 struct dcerpc_binding_handle *b;
3850
3851 torture_assert_ntstatus_ok(tctx,
3852 torture_rpc_connection(tctx, &t->p, &ndr_table_clusapi),
3853 "Error connecting to server");
3854
3855 b = t->p->binding_handle;
3856
3857 {
3858 struct clusapi_GetClusterName r;
3859
3860 r.out.ClusterName = &t->ClusterName;
3861 r.out.NodeName = &t->NodeName;
3862
3863 torture_assert_ntstatus_ok(tctx,
3864 dcerpc_clusapi_GetClusterName_r(b, tctx, &r),
3865 "GetClusterName failed");
3866 torture_assert_werr_ok(tctx,
3867 r.out.result,
3868 "GetClusterName failed");
3869 }
3870 {
3871 struct clusapi_GetClusterVersion2 r;
3872 const char *lpszVendorId;
3873 const char *lpszCSDVersion;
3874 struct CLUSTER_OPERATIONAL_VERSION_INFO *ppClusterOpVerInfo;
3875 WERROR rpc_status;
3876
3877 r.out.lpwMajorVersion = &t->lpwMajorVersion;
3878 r.out.lpwMinorVersion = &t->lpwMinorVersion;
3879 r.out.lpwBuildNumber = &t->lpwBuildNumber;
3880 r.out.lpszVendorId = &lpszVendorId;
3881 r.out.lpszCSDVersion = &lpszCSDVersion;
3882 r.out.ppClusterOpVerInfo = &ppClusterOpVerInfo;
3883 r.out.rpc_status = &rpc_status;
3884
3885 torture_assert_ntstatus_ok(tctx,
3886 dcerpc_clusapi_GetClusterVersion2_r(b, tctx, &r),
3887 "GetClusterVersion2 failed");
3888 torture_assert_werr_ok(tctx,
3889 r.out.result,
3890 "GetClusterVersion2 failed");
3891 }
3892
3893 return true;
3894 }
3895
torture_rpc_clusapi_setup(struct torture_context * tctx,void ** data)3896 static bool torture_rpc_clusapi_setup(struct torture_context *tctx,
3897 void **data)
3898 {
3899 struct torture_clusapi_context *t;
3900
3901 *data = t = talloc_zero(tctx, struct torture_clusapi_context);
3902
3903 return torture_rpc_clusapi_setup_common(tctx, t);
3904 }
3905
torture_rpc_clusapi_teardown(struct torture_context * tctx,void * data)3906 static bool torture_rpc_clusapi_teardown(struct torture_context *tctx,
3907 void *data)
3908 {
3909 talloc_free(data);
3910
3911 return true;
3912 }
3913
torture_tcase_cluster(struct torture_tcase * tcase)3914 void torture_tcase_cluster(struct torture_tcase *tcase)
3915 {
3916 torture_tcase_add_simple_test(tcase, "OpenCluster",
3917 test_OpenCluster);
3918 torture_tcase_add_simple_test(tcase, "OpenClusterEx",
3919 test_OpenClusterEx);
3920 torture_tcase_add_simple_test(tcase, "CloseCluster",
3921 test_CloseCluster);
3922 torture_tcase_add_simple_test(tcase, "SetClusterName",
3923 test_SetClusterName);
3924 torture_tcase_add_simple_test(tcase, "GetClusterName",
3925 test_GetClusterName);
3926 torture_tcase_add_simple_test(tcase, "GetClusterVersion",
3927 test_GetClusterVersion);
3928 torture_tcase_add_simple_test(tcase, "CreateEnum",
3929 test_CreateEnum);
3930 torture_tcase_add_simple_test(tcase, "CreateEnumEx",
3931 test_CreateEnumEx);
3932 torture_tcase_add_simple_test(tcase, "GetClusterVersion2",
3933 test_GetClusterVersion2);
3934 torture_tcase_add_simple_test(tcase, "BackupClusterDatabase",
3935 test_BackupClusterDatabase);
3936 torture_tcase_add_simple_test(tcase, "SetServiceAccountPassword",
3937 test_SetServiceAccountPassword);
3938 torture_tcase_add_simple_test(tcase, "ClusterControl",
3939 test_ClusterControl);
3940 torture_tcase_add_simple_test(tcase, "CreateResTypeEnum",
3941 test_CreateResTypeEnum);
3942 torture_tcase_add_simple_test(tcase, "CreateGroupEnum",
3943 test_CreateGroupEnum);
3944
3945 }
3946
torture_tcase_resource(struct torture_tcase * tcase)3947 void torture_tcase_resource(struct torture_tcase *tcase)
3948 {
3949 struct torture_test *test;
3950
3951 torture_tcase_add_simple_test(tcase, "GetQuorumResource",
3952 test_GetQuorumResource);
3953 torture_tcase_add_simple_test(tcase, "SetQuorumResource",
3954 test_SetQuorumResource);
3955 torture_tcase_add_simple_test(tcase, "OpenResource",
3956 test_OpenResource);
3957 torture_tcase_add_simple_test(tcase, "OpenResourceEx",
3958 test_OpenResourceEx);
3959 torture_tcase_add_simple_test(tcase, "CloseResource",
3960 test_CloseResource);
3961 torture_tcase_add_simple_test(tcase, "CreateResource",
3962 test_CreateResource);
3963 torture_tcase_add_simple_test(tcase, "DeleteResource",
3964 test_DeleteResource);
3965 torture_tcase_add_simple_test(tcase, "SetResourceName",
3966 test_SetResourceName);
3967 torture_tcase_add_simple_test(tcase, "GetResourceState",
3968 test_GetResourceState);
3969 torture_tcase_add_simple_test(tcase, "GetResourceId",
3970 test_GetResourceId);
3971 torture_tcase_add_simple_test(tcase, "GetResourceType",
3972 test_GetResourceType);
3973 torture_tcase_add_simple_test(tcase, "CreateResEnum",
3974 test_CreateResEnum);
3975 test = torture_tcase_add_simple_test(tcase, "FailResource",
3976 test_FailResource);
3977 test->dangerous = true;
3978 torture_tcase_add_simple_test(tcase, "OnlineResource",
3979 test_OnlineResource);
3980 test = torture_tcase_add_simple_test(tcase, "OfflineResource",
3981 test_OfflineResource);
3982 test->dangerous = true;
3983 torture_tcase_add_simple_test(tcase, "GetResourceDependencyExpression",
3984 test_GetResourceDependencyExpression);
3985 torture_tcase_add_simple_test(tcase, "GetResourceNetworkName",
3986 test_GetResourceNetworkName);
3987 torture_tcase_add_simple_test(tcase, "all_resources",
3988 test_all_resources);
3989 }
3990
torture_tcase_resourcetype(struct torture_tcase * tcase)3991 void torture_tcase_resourcetype(struct torture_tcase *tcase)
3992 {
3993 torture_tcase_add_simple_test(tcase, "all_resourcetypes",
3994 test_all_resourcetypes);
3995 }
3996
torture_tcase_node(struct torture_tcase * tcase)3997 void torture_tcase_node(struct torture_tcase *tcase)
3998 {
3999 struct torture_test *test;
4000
4001 torture_tcase_add_simple_test(tcase, "OpenNode",
4002 test_OpenNode);
4003 torture_tcase_add_simple_test(tcase, "OpenNodeEx",
4004 test_OpenNodeEx);
4005 torture_tcase_add_simple_test(tcase, "CloseNode",
4006 test_CloseNode);
4007 torture_tcase_add_simple_test(tcase, "GetNodeState",
4008 test_GetNodeState);
4009 torture_tcase_add_simple_test(tcase, "GetNodeId",
4010 test_GetNodeId);
4011 torture_tcase_add_simple_test(tcase, "NodeControl",
4012 test_NodeControl);
4013 test = torture_tcase_add_simple_test(tcase, "PauseNode",
4014 test_PauseNode);
4015 test->dangerous = true;
4016 torture_tcase_add_simple_test(tcase, "ResumeNode",
4017 test_ResumeNode);
4018 test = torture_tcase_add_simple_test(tcase, "EvictNode",
4019 test_EvictNode);
4020 test->dangerous = true;
4021 torture_tcase_add_simple_test(tcase, "all_nodes",
4022 test_all_nodes);
4023 }
4024
torture_tcase_group(struct torture_tcase * tcase)4025 void torture_tcase_group(struct torture_tcase *tcase)
4026 {
4027 struct torture_test *test;
4028
4029 torture_tcase_add_simple_test(tcase, "OpenGroup",
4030 test_OpenGroup);
4031 torture_tcase_add_simple_test(tcase, "OpenGroupEx",
4032 test_OpenGroupEx);
4033 torture_tcase_add_simple_test(tcase, "CloseGroup",
4034 test_CloseGroup);
4035 torture_tcase_add_simple_test(tcase, "GetGroupState",
4036 test_GetGroupState);
4037 torture_tcase_add_simple_test(tcase, "GetGroupId",
4038 test_GetGroupId);
4039 torture_tcase_add_simple_test(tcase, "GroupControl",
4040 test_GroupControl);
4041 torture_tcase_add_simple_test(tcase, "OnlineGroup",
4042 test_OnlineGroup);
4043 test = torture_tcase_add_simple_test(tcase, "OfflineGroup",
4044 test_OfflineGroup);
4045 test->dangerous = true;
4046 torture_tcase_add_simple_test(tcase, "all_groups",
4047 test_all_groups);
4048 }
4049
torture_tcase_network(struct torture_tcase * tcase)4050 void torture_tcase_network(struct torture_tcase *tcase)
4051 {
4052 torture_tcase_add_simple_test(tcase, "OpenNetwork",
4053 test_OpenNetwork);
4054 torture_tcase_add_simple_test(tcase, "OpenNetworkEx",
4055 test_OpenNetworkEx);
4056 torture_tcase_add_simple_test(tcase, "CloseNetwork",
4057 test_CloseNetwork);
4058 torture_tcase_add_simple_test(tcase, "GetNetworkState",
4059 test_GetNetworkState);
4060 torture_tcase_add_simple_test(tcase, "GetNetworkId",
4061 test_GetNetworkId);
4062 torture_tcase_add_simple_test(tcase, "all_networks",
4063 test_all_networks);
4064 }
4065
torture_tcase_netinterface(struct torture_tcase * tcase)4066 void torture_tcase_netinterface(struct torture_tcase *tcase)
4067 {
4068 torture_tcase_add_simple_test(tcase, "OpenNetInterface",
4069 test_OpenNetInterface);
4070 torture_tcase_add_simple_test(tcase, "OpenNetInterfaceEx",
4071 test_OpenNetInterfaceEx);
4072 torture_tcase_add_simple_test(tcase, "CloseNetInterface",
4073 test_CloseNetInterface);
4074 torture_tcase_add_simple_test(tcase, "GetNetInterfaceState",
4075 test_GetNetInterfaceState);
4076 torture_tcase_add_simple_test(tcase, "GetNetInterfaceId",
4077 test_GetNetInterfaceId);
4078 torture_tcase_add_simple_test(tcase, "all_netinterfaces",
4079 test_all_netinterfaces);
4080 }
4081
torture_tcase_registry(struct torture_tcase * tcase)4082 void torture_tcase_registry(struct torture_tcase *tcase)
4083 {
4084 torture_tcase_add_simple_test(tcase, "GetRootKey",
4085 test_GetRootKey);
4086 torture_tcase_add_simple_test(tcase, "CloseKey",
4087 test_CloseKey);
4088 torture_tcase_add_simple_test(tcase, "EnumKey",
4089 test_EnumKey);
4090 torture_tcase_add_simple_test(tcase, "QueryValue",
4091 test_QueryValue);
4092 torture_tcase_add_simple_test(tcase, "all_keys",
4093 test_all_keys);
4094 }
4095
torture_tcase_groupset(struct torture_tcase * tcase)4096 void torture_tcase_groupset(struct torture_tcase *tcase)
4097 {
4098 torture_tcase_add_simple_test(tcase, "OpenGroupSet",
4099 test_OpenGroupSet);
4100 torture_tcase_add_simple_test(tcase, "CloseGroupSet",
4101 test_CloseGroupSet);
4102 torture_tcase_add_simple_test(tcase, "all_groupsets",
4103 test_all_groupsets);
4104 }
4105
torture_rpc_clusapi(TALLOC_CTX * mem_ctx)4106 struct torture_suite *torture_rpc_clusapi(TALLOC_CTX *mem_ctx)
4107 {
4108 struct torture_tcase *tcase;
4109 struct torture_suite *suite = torture_suite_create(mem_ctx, "clusapi");
4110
4111 tcase = torture_suite_add_tcase(suite, "cluster");
4112
4113 torture_tcase_set_fixture(tcase,
4114 torture_rpc_clusapi_setup,
4115 torture_rpc_clusapi_teardown);
4116
4117 torture_tcase_cluster(tcase);
4118
4119 tcase = torture_suite_add_tcase(suite, "resource");
4120
4121 torture_tcase_set_fixture(tcase,
4122 torture_rpc_clusapi_setup,
4123 torture_rpc_clusapi_teardown);
4124
4125 torture_tcase_resource(tcase);
4126
4127 tcase = torture_suite_add_tcase(suite, "resourcetype");
4128
4129 torture_tcase_set_fixture(tcase,
4130 torture_rpc_clusapi_setup,
4131 torture_rpc_clusapi_teardown);
4132
4133 torture_tcase_resourcetype(tcase);
4134
4135
4136 tcase = torture_suite_add_tcase(suite, "node");
4137
4138 torture_tcase_set_fixture(tcase,
4139 torture_rpc_clusapi_setup,
4140 torture_rpc_clusapi_teardown);
4141
4142 torture_tcase_node(tcase);
4143
4144 tcase = torture_suite_add_tcase(suite, "group");
4145
4146 torture_tcase_set_fixture(tcase,
4147 torture_rpc_clusapi_setup,
4148 torture_rpc_clusapi_teardown);
4149
4150 torture_tcase_group(tcase);
4151
4152 tcase = torture_suite_add_tcase(suite, "network");
4153
4154 torture_tcase_set_fixture(tcase,
4155 torture_rpc_clusapi_setup,
4156 torture_rpc_clusapi_teardown);
4157
4158 torture_tcase_network(tcase);
4159
4160 tcase = torture_suite_add_tcase(suite, "netinterface");
4161
4162 torture_tcase_set_fixture(tcase,
4163 torture_rpc_clusapi_setup,
4164 torture_rpc_clusapi_teardown);
4165
4166 torture_tcase_netinterface(tcase);
4167
4168 tcase = torture_suite_add_tcase(suite, "registry");
4169
4170 torture_tcase_set_fixture(tcase,
4171 torture_rpc_clusapi_setup,
4172 torture_rpc_clusapi_teardown);
4173
4174 torture_tcase_registry(tcase);
4175
4176 tcase = torture_suite_add_tcase(suite, "groupset");
4177
4178 torture_tcase_set_fixture(tcase,
4179 torture_rpc_clusapi_setup,
4180 torture_rpc_clusapi_teardown);
4181
4182 torture_tcase_groupset(tcase);
4183
4184 return suite;
4185 }
4186