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