1 /*
2    Unix SMB/CIFS implementation.
3    test suite for winreg rpc operations
4 
5    Copyright (C) Tim Potter 2003
6    Copyright (C) Jelmer Vernooij 2004-2007
7    Copyright (C) Günther Deschner 2007,2010
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #include "includes.h"
24 #include "librpc/gen_ndr/ndr_winreg_c.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "libcli/security/security.h"
27 #include "torture/rpc/torture_rpc.h"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
30 
31 #define TEST_KEY_BASE "winreg_torture_test"
32 #define TEST_KEY1 "spottyfoot"
33 #define TEST_KEY2 "with a SD (#1)"
34 #define TEST_KEY3 "with a subkey"
35 #define TEST_KEY4 "sd_tests"
36 #define TEST_SUBKEY "subkey"
37 #define TEST_SUBKEY_SD  "subkey_sd"
38 #define TEST_SUBSUBKEY_SD "subkey_sd\\subsubkey_sd"
39 #define TEST_VALUE "torture_value_name"
40 #define TEST_KEY_VOLATILE "torture_volatile_key"
41 #define TEST_SUBKEY_VOLATILE "torture_volatile_subkey"
42 #define TEST_KEY_SYMLINK "torture_symlink_key"
43 #define TEST_KEY_SYMLINK_DEST "torture_symlink_dest"
44 
45 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
46 
init_lsa_StringLarge(struct lsa_StringLarge * name,const char * s)47 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
48 {
49 	name->string = s;
50 }
51 
init_winreg_String(struct winreg_String * name,const char * s)52 static void init_winreg_String(struct winreg_String *name, const char *s)
53 {
54 	name->name = s;
55 	if (s) {
56 		name->name_len = 2 * (strlen_m(s) + 1);
57 		name->name_size = name->name_len;
58 	} else {
59 		name->name_len = 0;
60 		name->name_size = 0;
61 	}
62 }
63 
test_GetVersion(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)64 static bool test_GetVersion(struct dcerpc_binding_handle *b,
65 			    struct torture_context *tctx,
66 			    struct policy_handle *handle)
67 {
68 	struct winreg_GetVersion r;
69 	uint32_t v;
70 
71 	torture_comment(tctx, "Testing GetVersion\n");
72 
73 	ZERO_STRUCT(r);
74 	r.in.handle = handle;
75 	r.out.version = &v;
76 
77 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
78 				   "GetVersion failed");
79 
80 	torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
81 
82 	return true;
83 }
84 
test_NotifyChangeKeyValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)85 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
86 				      struct torture_context *tctx,
87 				      struct policy_handle *handle)
88 {
89 	struct winreg_NotifyChangeKeyValue r;
90 
91 	ZERO_STRUCT(r);
92 	r.in.handle = handle;
93 	r.in.watch_subtree = true;
94 	r.in.notify_filter = 0;
95 	r.in.unknown = r.in.unknown2 = 0;
96 	init_winreg_String(&r.in.string1, NULL);
97 	init_winreg_String(&r.in.string2, NULL);
98 
99 	torture_assert_ntstatus_ok(tctx,
100 				   dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
101 				   "NotifyChangeKeyValue failed");
102 
103 	if (!W_ERROR_IS_OK(r.out.result)) {
104 		torture_comment(tctx,
105 				"NotifyChangeKeyValue failed - %s - not considering\n",
106 				win_errstr(r.out.result));
107 		return true;
108 	}
109 
110 	return true;
111 }
112 
test_CreateKey_opts(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,const char * name,const char * kclass,uint32_t options,uint32_t access_mask,struct winreg_SecBuf * secdesc,WERROR expected_result,enum winreg_CreateAction * action_taken_p,struct policy_handle * new_handle_p)113 static bool test_CreateKey_opts(struct torture_context *tctx,
114 				struct dcerpc_binding_handle *b,
115 				struct policy_handle *handle,
116 				const char *name,
117 				const char *kclass,
118 				uint32_t options,
119 				uint32_t access_mask,
120 				struct winreg_SecBuf *secdesc,
121 				WERROR expected_result,
122 				enum winreg_CreateAction *action_taken_p,
123 				struct policy_handle *new_handle_p)
124 {
125 	struct winreg_CreateKey r;
126 	struct policy_handle newhandle;
127 	enum winreg_CreateAction action_taken = 0;
128 
129 	torture_comment(tctx, "Testing CreateKey(%s)\n", name);
130 
131 	ZERO_STRUCT(r);
132 	r.in.handle = handle;
133 	init_winreg_String(&r.in.name, name);
134 	init_winreg_String(&r.in.keyclass, kclass);
135 	r.in.options = options;
136 	r.in.access_mask = access_mask;
137 	r.in.action_taken = &action_taken;
138 	r.in.secdesc = secdesc;
139 	r.out.new_handle = &newhandle;
140 	r.out.action_taken = &action_taken;
141 
142 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
143 				   "CreateKey failed");
144 
145 	torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
146 
147 	if (new_handle_p) {
148 		*new_handle_p = newhandle;
149 	}
150 	if (action_taken_p) {
151 		*action_taken_p = *r.out.action_taken;
152 	}
153 
154 	return true;
155 }
156 
test_CreateKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * name,const char * kclass)157 static bool test_CreateKey(struct dcerpc_binding_handle *b,
158 			   struct torture_context *tctx,
159 			   struct policy_handle *handle, const char *name,
160 			   const char *kclass)
161 {
162 	return test_CreateKey_opts(tctx, b, handle, name, kclass,
163 				   REG_OPTION_NON_VOLATILE,
164 				   SEC_FLAG_MAXIMUM_ALLOWED,
165 				   NULL, /* secdesc */
166 				   WERR_OK,
167 				   NULL, /* action_taken */
168 				   NULL /* new_handle */);
169 }
170 
171 /*
172   createkey testing with a SD
173 */
test_CreateKey_sd(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * name,const char * kclass,struct policy_handle * newhandle)174 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
175 			      struct torture_context *tctx,
176 			      struct policy_handle *handle, const char *name,
177 			      const char *kclass,
178 			      struct policy_handle *newhandle)
179 {
180 	struct winreg_CreateKey r;
181 	enum winreg_CreateAction action_taken = 0;
182 	struct security_descriptor *sd;
183 	DATA_BLOB sdblob;
184 	struct winreg_SecBuf secbuf;
185 
186 	sd = security_descriptor_dacl_create(tctx,
187 					0,
188 					NULL, NULL,
189 					SID_NT_AUTHENTICATED_USERS,
190 					SEC_ACE_TYPE_ACCESS_ALLOWED,
191 					SEC_GENERIC_ALL,
192 					SEC_ACE_FLAG_OBJECT_INHERIT |
193 					SEC_ACE_FLAG_CONTAINER_INHERIT,
194 					NULL);
195 
196 	torture_assert_ndr_success(tctx,
197 		ndr_push_struct_blob(&sdblob, tctx, sd,
198 				     (ndr_push_flags_fn_t)ndr_push_security_descriptor),
199 				     "Failed to push security_descriptor ?!\n");
200 
201 	secbuf.sd.data = sdblob.data;
202 	secbuf.sd.len = sdblob.length;
203 	secbuf.sd.size = sdblob.length;
204 	secbuf.length = sdblob.length-10;
205 	secbuf.inherit = 0;
206 
207 	ZERO_STRUCT(r);
208 	r.in.handle = handle;
209 	r.out.new_handle = newhandle;
210 	init_winreg_String(&r.in.name, name);
211 	init_winreg_String(&r.in.keyclass, kclass);
212 	r.in.options = 0x0;
213 	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
214 	r.in.action_taken = r.out.action_taken = &action_taken;
215 	r.in.secdesc = &secbuf;
216 
217 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
218 				   "CreateKey with sd failed");
219 
220 	torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
221 
222 	return true;
223 }
224 
_test_GetKeySecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,uint32_t * sec_info_ptr,WERROR get_werr,struct security_descriptor ** sd_out)225 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
226 				 struct torture_context *tctx,
227 				 struct policy_handle *handle,
228 				 uint32_t *sec_info_ptr,
229 				 WERROR get_werr,
230 				 struct security_descriptor **sd_out)
231 {
232 	struct winreg_GetKeySecurity r;
233 	struct security_descriptor *sd = NULL;
234 	uint32_t sec_info;
235 	DATA_BLOB sdblob;
236 	struct dcerpc_binding_handle *b = p->binding_handle;
237 
238 	if (sec_info_ptr) {
239 		sec_info = *sec_info_ptr;
240 	} else {
241 		sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
242 	}
243 
244 	ZERO_STRUCT(r);
245 
246 	r.in.handle = handle;
247 	r.in.sec_info = sec_info;
248 	r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
249 	r.in.sd->size = 0x1000;
250 
251 	torture_assert_ntstatus_ok(tctx,
252 				   dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
253 				   "GetKeySecurity failed");
254 
255 	torture_assert_werr_equal(tctx, r.out.result, get_werr,
256 				  "GetKeySecurity failed");
257 
258 	sdblob.data = r.out.sd->data;
259 	sdblob.length = r.out.sd->len;
260 
261 	sd = talloc_zero(tctx, struct security_descriptor);
262 
263 	torture_assert_ndr_success(tctx,
264 		ndr_pull_struct_blob(&sdblob, tctx, sd,
265 				     (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
266 				     "pull_security_descriptor failed");
267 
268 	if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
269 		NDR_PRINT_DEBUG(security_descriptor, sd);
270 	}
271 
272 	if (sd_out) {
273 		*sd_out = sd;
274 	} else {
275 		talloc_free(sd);
276 	}
277 
278 	return true;
279 }
280 
test_GetKeySecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,struct security_descriptor ** sd_out)281 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
282 				struct torture_context *tctx,
283 				struct policy_handle *handle,
284 				struct security_descriptor **sd_out)
285 {
286 	return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
287 }
288 
_test_SetKeySecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,uint32_t * sec_info_ptr,struct security_descriptor * sd,WERROR werr)289 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
290 				 struct torture_context *tctx,
291 				 struct policy_handle *handle,
292 				 uint32_t *sec_info_ptr,
293 				 struct security_descriptor *sd,
294 				 WERROR werr)
295 {
296 	struct winreg_SetKeySecurity r;
297 	struct KeySecurityData *sdata = NULL;
298 	DATA_BLOB sdblob;
299 	uint32_t sec_info;
300 	struct dcerpc_binding_handle *b = p->binding_handle;
301 
302 	ZERO_STRUCT(r);
303 
304 	if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
305 		NDR_PRINT_DEBUG(security_descriptor, sd);
306 	}
307 
308 	torture_assert_ndr_success(tctx,
309 		ndr_push_struct_blob(&sdblob, tctx, sd,
310 				     (ndr_push_flags_fn_t)ndr_push_security_descriptor),
311 				     "push_security_descriptor failed");
312 
313 	sdata = talloc_zero(tctx, struct KeySecurityData);
314 	sdata->data = sdblob.data;
315 	sdata->size = sdblob.length;
316 	sdata->len = sdblob.length;
317 
318 	if (sec_info_ptr) {
319 		sec_info = *sec_info_ptr;
320 	} else {
321 		sec_info = SECINFO_UNPROTECTED_SACL |
322 			   SECINFO_UNPROTECTED_DACL;
323 		if (sd->owner_sid) {
324 			sec_info |= SECINFO_OWNER;
325 		}
326 		if (sd->group_sid) {
327 			sec_info |= SECINFO_GROUP;
328 		}
329 		if (sd->sacl) {
330 			sec_info |= SECINFO_SACL;
331 		}
332 		if (sd->dacl) {
333 			sec_info |= SECINFO_DACL;
334 		}
335 	}
336 
337 	r.in.handle = handle;
338 	r.in.sec_info = sec_info;
339 	r.in.sd = sdata;
340 
341 	torture_assert_ntstatus_ok(tctx,
342 				   dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
343 				   "SetKeySecurity failed");
344 
345 	torture_assert_werr_equal(tctx, r.out.result, werr,
346 				  "SetKeySecurity failed");
347 
348 	return true;
349 }
350 
test_SetKeySecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,struct security_descriptor * sd)351 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
352 				struct torture_context *tctx,
353 				struct policy_handle *handle,
354 				struct security_descriptor *sd)
355 {
356 	return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
357 }
358 
test_CloseKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)359 static bool test_CloseKey(struct dcerpc_binding_handle *b,
360 			  struct torture_context *tctx,
361 			  struct policy_handle *handle)
362 {
363 	struct winreg_CloseKey r;
364 
365 	ZERO_STRUCT(r);
366 	r.in.handle = r.out.handle = handle;
367 
368 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
369 				   "CloseKey failed");
370 
371 	torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
372 
373 	return true;
374 }
375 
test_FlushKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)376 static bool test_FlushKey(struct dcerpc_binding_handle *b,
377 			  struct torture_context *tctx,
378 			  struct policy_handle *handle)
379 {
380 	struct winreg_FlushKey r;
381 
382 	ZERO_STRUCT(r);
383 	r.in.handle = handle;
384 
385 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
386 				   "FlushKey failed");
387 
388 	torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
389 
390 	return true;
391 }
392 
test_OpenKey_opts(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * hive_handle,const char * keyname,uint32_t options,uint32_t access_mask,struct policy_handle * key_handle,WERROR expected_result)393 static bool test_OpenKey_opts(struct torture_context *tctx,
394 			      struct dcerpc_binding_handle *b,
395 			      struct policy_handle *hive_handle,
396 			      const char *keyname,
397 			      uint32_t options,
398 			      uint32_t access_mask,
399 			      struct policy_handle *key_handle,
400 			      WERROR expected_result)
401 {
402 	struct winreg_OpenKey r;
403 
404 	ZERO_STRUCT(r);
405 	r.in.parent_handle = hive_handle;
406 	init_winreg_String(&r.in.keyname, keyname);
407 	r.in.options = options;
408 	r.in.access_mask = access_mask;
409 	r.out.handle = key_handle;
410 
411 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
412 				   "OpenKey failed");
413 
414 	torture_assert_werr_equal(tctx, r.out.result, expected_result,
415 				  "OpenKey failed");
416 
417 	return true;
418 }
419 
test_OpenKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * hive_handle,const char * keyname,struct policy_handle * key_handle)420 static bool test_OpenKey(struct dcerpc_binding_handle *b,
421 			 struct torture_context *tctx,
422 			 struct policy_handle *hive_handle,
423 			 const char *keyname, struct policy_handle *key_handle)
424 {
425 	return test_OpenKey_opts(tctx, b, hive_handle, keyname,
426 				 REG_OPTION_NON_VOLATILE,
427 				 SEC_FLAG_MAXIMUM_ALLOWED,
428 				 key_handle,
429 				 WERR_OK);
430 }
431 
test_Cleanup(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * key)432 static bool test_Cleanup(struct dcerpc_binding_handle *b,
433 			 struct torture_context *tctx,
434 			 struct policy_handle *handle, const char *key)
435 {
436 	struct winreg_DeleteKey r;
437 
438 	ZERO_STRUCT(r);
439 	r.in.handle = handle;
440 
441 	init_winreg_String(&r.in.key, key);
442 	dcerpc_winreg_DeleteKey_r(b, tctx, &r);
443 
444 	return true;
445 }
446 
_test_GetSetSecurityDescriptor(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,WERROR get_werr,WERROR set_werr)447 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
448 					   struct torture_context *tctx,
449 					   struct policy_handle *handle,
450 					   WERROR get_werr,
451 					   WERROR set_werr)
452 {
453 	struct security_descriptor *sd = NULL;
454 
455 	if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
456 		return false;
457 	}
458 
459 	if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
460 		return false;
461 	}
462 
463 	return true;
464 }
465 
test_SecurityDescriptor(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)466 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
467 				    struct torture_context *tctx,
468 				    struct policy_handle *handle,
469 				    const char *key)
470 {
471 	struct policy_handle new_handle;
472 	bool ret = true;
473 	struct dcerpc_binding_handle *b = p->binding_handle;
474 
475 	torture_comment(tctx, "SecurityDescriptor get & set\n");
476 
477 	if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
478 		return false;
479 	}
480 
481 	if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
482 					    WERR_OK, WERR_OK)) {
483 		ret = false;
484 	}
485 
486 	if (!test_CloseKey(b, tctx, &new_handle)) {
487 		return false;
488 	}
489 
490 	return ret;
491 }
492 
_test_SecurityDescriptor(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,uint32_t access_mask,const char * key,WERROR open_werr,WERROR get_werr,WERROR set_werr)493 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
494 				     struct torture_context *tctx,
495 				     struct policy_handle *handle,
496 				     uint32_t access_mask,
497 				     const char *key,
498 				     WERROR open_werr,
499 				     WERROR get_werr,
500 				     WERROR set_werr)
501 {
502 	struct policy_handle new_handle;
503 	bool ret = true;
504 	struct dcerpc_binding_handle *b = p->binding_handle;
505 
506 	torture_assert(tctx,
507 		test_OpenKey_opts(tctx, b, handle, key,
508 				  REG_OPTION_NON_VOLATILE,
509 				  access_mask,
510 				  &new_handle,
511 				  open_werr),
512 		"failed to open key");
513 
514 	if (!W_ERROR_IS_OK(open_werr)) {
515 		return true;
516 	}
517 
518 	if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
519 					    get_werr, set_werr)) {
520 		ret = false;
521 	}
522 
523 	if (!test_CloseKey(b, tctx, &new_handle)) {
524 		return false;
525 	}
526 
527 	return ret;
528 }
529 
test_dacl_trustee_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid)530 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
531 				      struct torture_context *tctx,
532 				      struct policy_handle *handle,
533 				      const struct dom_sid *sid)
534 {
535 	struct security_descriptor *sd = NULL;
536 	int i;
537 
538 	if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
539 		return false;
540 	}
541 
542 	if (!sd || !sd->dacl) {
543 		return false;
544 	}
545 
546 	for (i = 0; i < sd->dacl->num_aces; i++) {
547 		if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
548 			return true;
549 		}
550 	}
551 
552 	return false;
553 }
554 
_test_dacl_trustee_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const struct dom_sid * sid)555 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
556 				       struct torture_context *tctx,
557 				       struct policy_handle *handle,
558 				       const char *key,
559 				       const struct dom_sid *sid)
560 {
561 	struct policy_handle new_handle;
562 	bool ret = true;
563 	struct dcerpc_binding_handle *b = p->binding_handle;
564 
565 	if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
566 		return false;
567 	}
568 
569 	ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
570 
571 	test_CloseKey(b, tctx, &new_handle);
572 
573 	return ret;
574 }
575 
test_sacl_trustee_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid)576 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
577 				      struct torture_context *tctx,
578 				      struct policy_handle *handle,
579 				      const struct dom_sid *sid)
580 {
581 	struct security_descriptor *sd = NULL;
582 	int i;
583 	uint32_t sec_info = SECINFO_SACL;
584 
585 	if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
586 		return false;
587 	}
588 
589 	if (!sd || !sd->sacl) {
590 		return false;
591 	}
592 
593 	for (i = 0; i < sd->sacl->num_aces; i++) {
594 		if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
595 			return true;
596 		}
597 	}
598 
599 	return false;
600 }
601 
_test_sacl_trustee_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const struct dom_sid * sid)602 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
603 				       struct torture_context *tctx,
604 				       struct policy_handle *handle,
605 				       const char *key,
606 				       const struct dom_sid *sid)
607 {
608 	struct policy_handle new_handle;
609 	bool ret = true;
610 	struct dcerpc_binding_handle *b = p->binding_handle;
611 
612 	torture_assert(tctx,
613 		test_OpenKey_opts(tctx, b, handle, key,
614 				  REG_OPTION_NON_VOLATILE,
615 				  SEC_FLAG_SYSTEM_SECURITY,
616 				  &new_handle,
617 				  WERR_OK),
618 		"failed to open key");
619 
620 	ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
621 
622 	test_CloseKey(b, tctx, &new_handle);
623 
624 	return ret;
625 }
626 
test_owner_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid)627 static bool test_owner_present(struct dcerpc_pipe *p,
628 			       struct torture_context *tctx,
629 			       struct policy_handle *handle,
630 			       const struct dom_sid *sid)
631 {
632 	struct security_descriptor *sd = NULL;
633 	uint32_t sec_info = SECINFO_OWNER;
634 
635 	if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
636 		return false;
637 	}
638 
639 	if (!sd || !sd->owner_sid) {
640 		return false;
641 	}
642 
643 	return dom_sid_equal(sd->owner_sid, sid);
644 }
645 
_test_owner_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const struct dom_sid * sid)646 static bool _test_owner_present(struct dcerpc_pipe *p,
647 				struct torture_context *tctx,
648 				struct policy_handle *handle,
649 				const char *key,
650 				const struct dom_sid *sid)
651 {
652 	struct policy_handle new_handle;
653 	bool ret = true;
654 	struct dcerpc_binding_handle *b = p->binding_handle;
655 
656 	if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
657 		return false;
658 	}
659 
660 	ret = test_owner_present(p, tctx, &new_handle, sid);
661 
662 	test_CloseKey(b, tctx, &new_handle);
663 
664 	return ret;
665 }
666 
test_group_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid)667 static bool test_group_present(struct dcerpc_pipe *p,
668 			       struct torture_context *tctx,
669 			       struct policy_handle *handle,
670 			       const struct dom_sid *sid)
671 {
672 	struct security_descriptor *sd = NULL;
673 	uint32_t sec_info = SECINFO_GROUP;
674 
675 	if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
676 		return false;
677 	}
678 
679 	if (!sd || !sd->group_sid) {
680 		return false;
681 	}
682 
683 	return dom_sid_equal(sd->group_sid, sid);
684 }
685 
_test_group_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const struct dom_sid * sid)686 static bool _test_group_present(struct dcerpc_pipe *p,
687 				struct torture_context *tctx,
688 				struct policy_handle *handle,
689 				const char *key,
690 				const struct dom_sid *sid)
691 {
692 	struct policy_handle new_handle;
693 	bool ret = true;
694 	struct dcerpc_binding_handle *b = p->binding_handle;
695 
696 	if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
697 		return false;
698 	}
699 
700 	ret = test_group_present(p, tctx, &new_handle, sid);
701 
702 	test_CloseKey(b, tctx, &new_handle);
703 
704 	return ret;
705 }
706 
test_dacl_trustee_flags_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid,uint8_t flags)707 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
708 					    struct torture_context *tctx,
709 					    struct policy_handle *handle,
710 					    const struct dom_sid *sid,
711 					    uint8_t flags)
712 {
713 	struct security_descriptor *sd = NULL;
714 	int i;
715 
716 	if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
717 		return false;
718 	}
719 
720 	if (!sd || !sd->dacl) {
721 		return false;
722 	}
723 
724 	for (i = 0; i < sd->dacl->num_aces; i++) {
725 		if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
726 		    (sd->dacl->aces[i].flags == flags)) {
727 			return true;
728 		}
729 	}
730 
731 	return false;
732 }
733 
test_dacl_ace_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct security_ace * ace)734 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
735 				  struct torture_context *tctx,
736 				  struct policy_handle *handle,
737 				  const struct security_ace *ace)
738 {
739 	struct security_descriptor *sd = NULL;
740 	int i;
741 
742 	if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
743 		return false;
744 	}
745 
746 	if (!sd || !sd->dacl) {
747 		return false;
748 	}
749 
750 	for (i = 0; i < sd->dacl->num_aces; i++) {
751 		if (security_ace_equal(&sd->dacl->aces[i], ace)) {
752 			return true;
753 		}
754 	}
755 
756 	return false;
757 }
758 
test_RestoreSecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,struct security_descriptor * sd)759 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
760 				 struct torture_context *tctx,
761 				 struct policy_handle *handle,
762 				 const char *key,
763 				 struct security_descriptor *sd)
764 {
765 	struct policy_handle new_handle;
766 	bool ret = true;
767 	struct dcerpc_binding_handle *b = p->binding_handle;
768 
769 	if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
770 		return false;
771 	}
772 
773 	if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
774 		ret = false;
775 	}
776 
777 	if (!test_CloseKey(b, tctx, &new_handle)) {
778 		ret = false;
779 	}
780 
781 	return ret;
782 }
783 
test_BackupSecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,struct security_descriptor ** sd)784 static bool test_BackupSecurity(struct dcerpc_pipe *p,
785 				struct torture_context *tctx,
786 				struct policy_handle *handle,
787 				const char *key,
788 				struct security_descriptor **sd)
789 {
790 	struct policy_handle new_handle;
791 	bool ret = true;
792 	struct dcerpc_binding_handle *b = p->binding_handle;
793 
794 	if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
795 		return false;
796 	}
797 
798 	if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
799 		ret = false;
800 	}
801 
802 	if (!test_CloseKey(b, tctx, &new_handle)) {
803 		ret = false;
804 	}
805 
806 	return ret;
807 }
808 
test_SecurityDescriptorInheritance(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)809 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
810 					       struct torture_context *tctx,
811 					       struct policy_handle *handle,
812 					       const char *key)
813 {
814 	/* get sd
815 	   add ace SEC_ACE_FLAG_CONTAINER_INHERIT
816 	   set sd
817 	   get sd
818 	   check ace
819 	   add subkey
820 	   get sd
821 	   check ace
822 	   add subsubkey
823 	   get sd
824 	   check ace
825 	   del subsubkey
826 	   del subkey
827 	   reset sd
828 	*/
829 
830 	struct security_descriptor *sd = NULL;
831 	struct security_descriptor *sd_orig = NULL;
832 	struct security_ace *ace = NULL;
833 	struct policy_handle new_handle;
834 	bool ret = true;
835 	struct dcerpc_binding_handle *b = p->binding_handle;
836 	const char *test_subkey_sd;
837 	const char *test_subsubkey_sd;
838 
839 	torture_comment(tctx, "SecurityDescriptor inheritance\n");
840 
841 	if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
842 		return false;
843 	}
844 
845 	if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
846 		return false;
847 	}
848 
849 	sd_orig = security_descriptor_copy(tctx, sd);
850 	if (sd_orig == NULL) {
851 		return false;
852 	}
853 
854 	ace = security_ace_create(tctx,
855 				  TEST_SID,
856 				  SEC_ACE_TYPE_ACCESS_ALLOWED,
857 				  SEC_STD_REQUIRED,
858 				  SEC_ACE_FLAG_CONTAINER_INHERIT);
859 
860 	torture_assert_ntstatus_ok(tctx,
861 		security_descriptor_dacl_add(sd, ace),
862 		"failed to add ace");
863 
864 	/* FIXME: add further tests for these flags */
865 	sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
866 		    SEC_DESC_SACL_AUTO_INHERITED;
867 
868 	if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
869 		return false;
870 	}
871 
872 	torture_assert(tctx,
873 		test_dacl_ace_present(p, tctx, &new_handle, ace),
874 		"new ACE not present!");
875 
876 	if (!test_CloseKey(b, tctx, &new_handle)) {
877 		return false;
878 	}
879 
880 	test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
881 
882 	if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
883 		ret = false;
884 		goto out;
885 	}
886 
887 	if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
888 		ret = false;
889 		goto out;
890 	}
891 
892 	if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
893 		torture_comment(tctx, "inherited ACE not present!\n");
894 		ret = false;
895 		goto out;
896 	}
897 
898 	test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
899 
900 	test_CloseKey(b, tctx, &new_handle);
901 	if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
902 		ret = false;
903 		goto out;
904 	}
905 
906 	if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
907 		ret = false;
908 		goto out;
909 	}
910 
911 	if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
912 		torture_comment(tctx, "inherited ACE not present!\n");
913 		ret = false;
914 		goto out;
915 	}
916 
917  out:
918 	test_CloseKey(b, tctx, &new_handle);
919 	test_Cleanup(b, tctx, handle, test_subkey_sd);
920 	test_RestoreSecurity(p, tctx, handle, key, sd_orig);
921 
922 	return ret;
923 }
924 
test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)925 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
926 						    struct torture_context *tctx,
927 						    struct policy_handle *handle,
928 						    const char *key)
929 {
930 	/* get sd
931 	   add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
932 	   set sd
933 	   add subkey/subkey
934 	   get sd
935 	   check ace
936 	   get sd from subkey
937 	   check ace
938 	   del subkey/subkey
939 	   del subkey
940 	   reset sd
941 	*/
942 
943 	struct security_descriptor *sd = NULL;
944 	struct security_descriptor *sd_orig = NULL;
945 	struct security_ace *ace = NULL;
946 	struct policy_handle new_handle;
947 	struct dom_sid *sid = NULL;
948 	bool ret = true;
949 	uint8_t ace_flags = 0x0;
950 	struct dcerpc_binding_handle *b = p->binding_handle;
951 	const char *test_subkey_sd;
952 	const char *test_subsubkey_sd;
953 
954 	torture_comment(tctx, "SecurityDescriptor inheritance block\n");
955 
956 	if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
957 		return false;
958 	}
959 
960 	if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
961 		return false;
962 	}
963 
964 	sd_orig = security_descriptor_copy(tctx, sd);
965 	if (sd_orig == NULL) {
966 		return false;
967 	}
968 
969 	ace = security_ace_create(tctx,
970 				  TEST_SID,
971 				  SEC_ACE_TYPE_ACCESS_ALLOWED,
972 				  SEC_STD_REQUIRED,
973 				  SEC_ACE_FLAG_CONTAINER_INHERIT |
974 				  SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
975 
976 	torture_assert_ntstatus_ok(tctx,
977 		security_descriptor_dacl_add(sd, ace),
978 		"failed to add ace");
979 
980 	if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
981 		return false;
982 	}
983 
984 	torture_assert(tctx,
985 		test_dacl_ace_present(p, tctx, &new_handle, ace),
986 		"new ACE not present!");
987 
988 	if (!test_CloseKey(b, tctx, &new_handle)) {
989 		return false;
990 	}
991 
992 	test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
993 	test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
994 
995 	if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
996 		return false;
997 	}
998 
999 	if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
1000 		ret = false;
1001 		goto out;
1002 	}
1003 
1004 	if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1005 		torture_comment(tctx, "inherited ACE present but should not!\n");
1006 		ret = false;
1007 		goto out;
1008 	}
1009 
1010 	sid = dom_sid_parse_talloc(tctx, TEST_SID);
1011 	if (sid == NULL) {
1012 		return false;
1013 	}
1014 
1015 	if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1016 		torture_comment(tctx, "inherited trustee SID present but should not!\n");
1017 		ret = false;
1018 		goto out;
1019 	}
1020 
1021 	test_CloseKey(b, tctx, &new_handle);
1022 
1023 	if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
1024 		ret = false;
1025 		goto out;
1026 	}
1027 
1028 	if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1029 		torture_comment(tctx, "inherited ACE present but should not!\n");
1030 		ret = false;
1031 		goto out;
1032 	}
1033 
1034 	if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1035 		torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1036 			ace_flags);
1037 		ret = false;
1038 		goto out;
1039 	}
1040 
1041  out:
1042 	test_CloseKey(b, tctx, &new_handle);
1043 	test_Cleanup(b, tctx, handle, test_subkey_sd);
1044 	test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1045 
1046 	return ret;
1047 }
1048 
test_SecurityDescriptorsMasks(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)1049 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1050 					  struct torture_context *tctx,
1051 					  struct policy_handle *handle,
1052 					  const char *key)
1053 {
1054 	bool ret = true;
1055 	int i;
1056 
1057 	struct winreg_mask_result_table {
1058 		uint32_t access_mask;
1059 		WERROR open_werr;
1060 		WERROR get_werr;
1061 		WERROR set_werr;
1062 	} sd_mask_tests[] = {
1063 		{ 0,
1064 			WERR_ACCESS_DENIED, WERR_FILE_NOT_FOUND, WERR_FOOBAR },
1065 		{ SEC_FLAG_MAXIMUM_ALLOWED,
1066 			WERR_OK, WERR_OK, WERR_OK },
1067 		{ SEC_STD_WRITE_DAC,
1068 			WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1069 		{ SEC_FLAG_SYSTEM_SECURITY,
1070 			WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1071 	};
1072 
1073 	/* FIXME: before this test can ever run successfully we need a way to
1074 	 * correctly read a NULL security_descritpor in ndr, get the required
1075 	 * length, requery, etc.
1076 	 */
1077 
1078 	return true;
1079 
1080 	for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1081 
1082 		torture_comment(tctx,
1083 				"SecurityDescriptor get & set with access_mask: 0x%08x\n",
1084 				sd_mask_tests[i].access_mask);
1085 		torture_comment(tctx,
1086 				"expecting: open %s, get: %s, set: %s\n",
1087 				win_errstr(sd_mask_tests[i].open_werr),
1088 				win_errstr(sd_mask_tests[i].get_werr),
1089 				win_errstr(sd_mask_tests[i].set_werr));
1090 
1091 		if (_test_SecurityDescriptor(p, tctx, handle,
1092 					     sd_mask_tests[i].access_mask, key,
1093 					     sd_mask_tests[i].open_werr,
1094 					     sd_mask_tests[i].get_werr,
1095 					     sd_mask_tests[i].set_werr)) {
1096 			ret = false;
1097 		}
1098 	}
1099 
1100 	return ret;
1101 }
1102 
1103 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1104 				  struct torture_context *,
1105 				  struct policy_handle *,
1106 				  const char *,
1107 				  const struct dom_sid *);
1108 
test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const char * test,uint32_t access_mask,uint32_t sec_info,struct security_descriptor * sd,WERROR set_werr,bool expect_present,bool (* fn)(struct dcerpc_pipe *,struct torture_context *,struct policy_handle *,const char *,const struct dom_sid *),const struct dom_sid * sid)1109 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1110 					       struct torture_context *tctx,
1111 					       struct policy_handle *handle,
1112 					       const char *key,
1113 					       const char *test,
1114 					       uint32_t access_mask,
1115 					       uint32_t sec_info,
1116 					       struct security_descriptor *sd,
1117 					       WERROR set_werr,
1118 					       bool expect_present,
1119 					       bool (*fn) (struct dcerpc_pipe *,
1120 							   struct torture_context *,
1121 							   struct policy_handle *,
1122 							   const char *,
1123 							   const struct dom_sid *),
1124 					       const struct dom_sid *sid)
1125 {
1126 	struct policy_handle new_handle;
1127 	struct dcerpc_binding_handle *b = p->binding_handle;
1128 
1129 	torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1130 			"0x%08x, access_mask: 0x%08x\n",
1131 			test, sec_info, access_mask);
1132 
1133 	torture_assert(tctx,
1134 		test_OpenKey_opts(tctx, b, handle, key,
1135 				  REG_OPTION_NON_VOLATILE,
1136 				  access_mask,
1137 				  &new_handle,
1138 				  WERR_OK),
1139 		"failed to open key");
1140 
1141 	if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1142 				  sd,
1143 				  set_werr)) {
1144 		torture_warning(tctx,
1145 				"SetKeySecurity with secinfo: 0x%08x has failed\n",
1146 				sec_info);
1147 		smb_panic("");
1148 		test_CloseKey(b, tctx, &new_handle);
1149 		return false;
1150 	}
1151 
1152 	test_CloseKey(b, tctx, &new_handle);
1153 
1154 	if (W_ERROR_IS_OK(set_werr)) {
1155 		bool present;
1156 		present = fn(p, tctx, handle, key, sid);
1157 		if ((expect_present) && (!present)) {
1158 			torture_warning(tctx,
1159 					"%s sid is not present!\n",
1160 					test);
1161 			return false;
1162 		}
1163 		if ((!expect_present) && (present)) {
1164 			torture_warning(tctx,
1165 					"%s sid is present but not expected!\n",
1166 					test);
1167 			return false;
1168 		}
1169 	}
1170 
1171 	return true;
1172 }
1173 
test_SecurityDescriptorsSecInfo(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)1174 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1175 					    struct torture_context *tctx,
1176 					    struct policy_handle *handle,
1177 					    const char *key)
1178 {
1179 	struct security_descriptor *sd_orig = NULL;
1180 	struct dom_sid *sid = NULL;
1181 	bool ret = true;
1182 	int i, a;
1183 
1184 	struct security_descriptor *sd_owner =
1185 		security_descriptor_dacl_create(tctx,
1186 						0,
1187 						TEST_SID, NULL, NULL);
1188 
1189 	struct security_descriptor *sd_group =
1190 		security_descriptor_dacl_create(tctx,
1191 						0,
1192 						NULL, TEST_SID, NULL);
1193 
1194 	struct security_descriptor *sd_dacl =
1195 		security_descriptor_dacl_create(tctx,
1196 						0,
1197 						NULL, NULL,
1198 						TEST_SID,
1199 						SEC_ACE_TYPE_ACCESS_ALLOWED,
1200 						SEC_GENERIC_ALL,
1201 						0,
1202 						SID_NT_AUTHENTICATED_USERS,
1203 						SEC_ACE_TYPE_ACCESS_ALLOWED,
1204 						SEC_GENERIC_ALL,
1205 						0,
1206 						NULL);
1207 
1208 	struct security_descriptor *sd_sacl =
1209 		security_descriptor_sacl_create(tctx,
1210 						0,
1211 						NULL, NULL,
1212 						TEST_SID,
1213 						SEC_ACE_TYPE_SYSTEM_AUDIT,
1214 						SEC_GENERIC_ALL,
1215 						SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1216 						NULL);
1217 
1218 	struct winreg_secinfo_table {
1219 		struct security_descriptor *sd;
1220 		uint32_t sec_info;
1221 		WERROR set_werr;
1222 		bool sid_present;
1223 		secinfo_verify_fn fn;
1224 	};
1225 
1226 	struct winreg_secinfo_table sec_info_owner_tests[] = {
1227 		{
1228 			.sd          = sd_owner,
1229 			.sec_info    = 0,
1230 			.set_werr    = WERR_OK,
1231 			.sid_present = false,
1232 			.fn          = (secinfo_verify_fn)_test_owner_present,
1233 		},
1234 		{
1235 			.sd          = sd_owner,
1236 			.sec_info    = SECINFO_OWNER,
1237 			.set_werr    = WERR_OK,
1238 			.sid_present = true,
1239 			.fn          = (secinfo_verify_fn)_test_owner_present,
1240 		},
1241 		{
1242 			.sd          = sd_owner,
1243 			.sec_info    = SECINFO_GROUP,
1244 			.set_werr    = WERR_INVALID_PARAMETER,
1245 			.sid_present  = false,
1246 		},
1247 		{
1248 			.sd          = sd_owner,
1249 			.sec_info    = SECINFO_DACL,
1250 			.set_werr    = WERR_OK,
1251 			.sid_present = true,
1252 			.fn          = (secinfo_verify_fn)_test_owner_present,
1253 		},
1254 		{
1255 			.sd          = sd_owner,
1256 			.sec_info    = SECINFO_SACL,
1257 			.set_werr    = WERR_ACCESS_DENIED,
1258 			.sid_present  = false,
1259 		},
1260 	};
1261 
1262 	uint32_t sd_owner_good_access_masks[] = {
1263 		SEC_FLAG_MAXIMUM_ALLOWED,
1264 		/* SEC_STD_WRITE_OWNER, */
1265 	};
1266 
1267 	struct winreg_secinfo_table sec_info_group_tests[] = {
1268 		{
1269 			.sd          = sd_group,
1270 			.sec_info    = 0,
1271 			.set_werr    = WERR_OK,
1272 			.sid_present = false,
1273 			.fn          = (secinfo_verify_fn)_test_group_present,
1274 		},
1275 		{
1276 			.sd          = sd_group,
1277 			.sec_info    = SECINFO_OWNER,
1278 			.set_werr    = WERR_INVALID_PARAMETER,
1279 			.sid_present = false,
1280 		},
1281 		{
1282 			.sd          = sd_group,
1283 			.sec_info    = SECINFO_GROUP,
1284 			.set_werr    = WERR_OK,
1285 			.sid_present = true,
1286 			.fn          = (secinfo_verify_fn)_test_group_present,
1287 		},
1288 		{
1289 			.sd          = sd_group,
1290 			.sec_info    = SECINFO_DACL,
1291 			.set_werr    = WERR_OK,
1292 			.sid_present = true,
1293 			.fn          = (secinfo_verify_fn)_test_group_present,
1294 		},
1295 		{
1296 			.sd          = sd_group,
1297 			.sec_info    = SECINFO_SACL,
1298 			.set_werr    = WERR_ACCESS_DENIED,
1299 			.sid_present = false,
1300 		},
1301 	};
1302 
1303 	uint32_t sd_group_good_access_masks[] = {
1304 		SEC_FLAG_MAXIMUM_ALLOWED,
1305 	};
1306 
1307 	struct winreg_secinfo_table sec_info_dacl_tests[] = {
1308 		{
1309 			.sd          = sd_dacl,
1310 			.sec_info    = 0,
1311 			.set_werr    = WERR_OK,
1312 			.sid_present = false,
1313 			.fn          = (secinfo_verify_fn)_test_dacl_trustee_present,
1314 		},
1315 		{
1316 			.sd          = sd_dacl,
1317 			.sec_info    = SECINFO_OWNER,
1318 			.set_werr    = WERR_INVALID_PARAMETER,
1319 			.sid_present = false,
1320 		},
1321 		{
1322 			.sd          = sd_dacl,
1323 			.sec_info    = SECINFO_GROUP,
1324 			.set_werr    = WERR_INVALID_PARAMETER,
1325 			.sid_present = false,
1326 		},
1327 		{
1328 			.sd          = sd_dacl,
1329 			.sec_info    = SECINFO_DACL,
1330 			.set_werr    = WERR_OK,
1331 			.sid_present = true,
1332 			.fn          = (secinfo_verify_fn)_test_dacl_trustee_present
1333 		},
1334 		{
1335 			.sd          = sd_dacl,
1336 			.sec_info    = SECINFO_SACL,
1337 			.set_werr    = WERR_ACCESS_DENIED,
1338 			.sid_present = false,
1339 		},
1340 	};
1341 
1342 	uint32_t sd_dacl_good_access_masks[] = {
1343 		SEC_FLAG_MAXIMUM_ALLOWED,
1344 		SEC_STD_WRITE_DAC,
1345 	};
1346 
1347 	struct winreg_secinfo_table sec_info_sacl_tests[] = {
1348 		{
1349 			.sd          = sd_sacl,
1350 			.sec_info    = 0,
1351 			.set_werr    = WERR_OK,
1352 			.sid_present = false,
1353 			.fn          = (secinfo_verify_fn)_test_sacl_trustee_present,
1354 		},
1355 		{
1356 			.sd          = sd_sacl,
1357 			.sec_info    = SECINFO_OWNER,
1358 			.set_werr    = WERR_INVALID_PARAMETER,
1359 			.sid_present = false,
1360 		},
1361 		{
1362 			.sd          = sd_sacl,
1363 			.sec_info    = SECINFO_GROUP,
1364 			.set_werr    = WERR_INVALID_PARAMETER,
1365 			.sid_present = false,
1366 		},
1367 		{
1368 			.sd          = sd_sacl,
1369 			.sec_info    = SECINFO_DACL,
1370 			.set_werr    = WERR_OK,
1371 			.sid_present = false,
1372 			.fn          = (secinfo_verify_fn)_test_sacl_trustee_present,
1373 		},
1374 		{
1375 			.sd          = sd_sacl,
1376 			.sec_info    = SECINFO_SACL,
1377 			.set_werr    = WERR_OK,
1378 			.sid_present = true,
1379 			.fn          = (secinfo_verify_fn)_test_sacl_trustee_present,
1380 		},
1381 	};
1382 
1383 	uint32_t sd_sacl_good_access_masks[] = {
1384 		SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1385 		/* SEC_FLAG_SYSTEM_SECURITY, */
1386 	};
1387 
1388 	sid = dom_sid_parse_talloc(tctx, TEST_SID);
1389 	if (sid == NULL) {
1390 		return false;
1391 	}
1392 
1393 	if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1394 		return false;
1395 	}
1396 
1397 	/* OWNER */
1398 
1399 	for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1400 
1401 		for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1402 
1403 			if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1404 					key,
1405 					"OWNER",
1406 					sd_owner_good_access_masks[a],
1407 					sec_info_owner_tests[i].sec_info,
1408 					sec_info_owner_tests[i].sd,
1409 					sec_info_owner_tests[i].set_werr,
1410 					sec_info_owner_tests[i].sid_present,
1411 					sec_info_owner_tests[i].fn,
1412 					sid))
1413 			{
1414 				torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1415 				ret = false;
1416 				goto out;
1417 			}
1418 		}
1419 	}
1420 
1421 	/* GROUP */
1422 
1423 	for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1424 
1425 		for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1426 
1427 			if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1428 					key,
1429 					"GROUP",
1430 					sd_group_good_access_masks[a],
1431 					sec_info_group_tests[i].sec_info,
1432 					sec_info_group_tests[i].sd,
1433 					sec_info_group_tests[i].set_werr,
1434 					sec_info_group_tests[i].sid_present,
1435 					sec_info_group_tests[i].fn,
1436 					sid))
1437 			{
1438 				torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1439 				ret = false;
1440 				goto out;
1441 			}
1442 		}
1443 	}
1444 
1445 	/* DACL */
1446 
1447 	for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1448 
1449 		for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1450 
1451 			if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1452 					key,
1453 					"DACL",
1454 					sd_dacl_good_access_masks[a],
1455 					sec_info_dacl_tests[i].sec_info,
1456 					sec_info_dacl_tests[i].sd,
1457 					sec_info_dacl_tests[i].set_werr,
1458 					sec_info_dacl_tests[i].sid_present,
1459 					sec_info_dacl_tests[i].fn,
1460 					sid))
1461 			{
1462 				torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1463 				ret = false;
1464 				goto out;
1465 			}
1466 		}
1467 	}
1468 
1469 	/* SACL */
1470 
1471 	for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1472 
1473 		for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1474 
1475 			if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1476 					key,
1477 					"SACL",
1478 					sd_sacl_good_access_masks[a],
1479 					sec_info_sacl_tests[i].sec_info,
1480 					sec_info_sacl_tests[i].sd,
1481 					sec_info_sacl_tests[i].set_werr,
1482 					sec_info_sacl_tests[i].sid_present,
1483 					sec_info_sacl_tests[i].fn,
1484 					sid))
1485 			{
1486 				torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1487 				ret = false;
1488 				goto out;
1489 			}
1490 		}
1491 	}
1492 
1493  out:
1494 	test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1495 
1496 	return ret;
1497 }
1498 
test_SecurityDescriptors(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)1499 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1500 				     struct torture_context *tctx,
1501 				     struct policy_handle *handle,
1502 				     const char *key)
1503 {
1504 	bool ret = true;
1505 
1506 	if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1507 		torture_comment(tctx, "test_SecurityDescriptor failed\n");
1508 		ret = false;
1509 	}
1510 
1511 	if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1512 		torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1513 		ret = false;
1514 	}
1515 
1516 	if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1517 		torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1518 		ret = false;
1519 	}
1520 
1521 	if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1522 		torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1523 		ret = false;
1524 	}
1525 
1526 	if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1527 		torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1528 		ret = false;
1529 	}
1530 
1531 	return ret;
1532 }
1533 
test_DeleteKey_opts(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * key,WERROR expected_result)1534 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1535 				struct torture_context *tctx,
1536 				struct policy_handle *handle,
1537 				const char *key,
1538 				WERROR expected_result)
1539 {
1540 	struct winreg_DeleteKey r;
1541 
1542 	torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1543 
1544 	r.in.handle = handle;
1545 	init_winreg_String(&r.in.key, key);
1546 
1547 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1548 		"Delete Key failed");
1549 	torture_assert_werr_equal(tctx, r.out.result, expected_result,
1550 		"DeleteKey failed");
1551 
1552 	return true;
1553 }
1554 
test_DeleteKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * key)1555 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1556 			   struct torture_context *tctx,
1557 			   struct policy_handle *handle, const char *key)
1558 {
1559 	return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1560 }
1561 
test_QueryInfoKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,char * kclass,uint32_t * pmax_valnamelen,uint32_t * pmax_valbufsize)1562 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1563 			      struct torture_context *tctx,
1564 			      struct policy_handle *handle,
1565 			      char *kclass,
1566 			      uint32_t *pmax_valnamelen,
1567 			      uint32_t *pmax_valbufsize)
1568 {
1569 	struct winreg_QueryInfoKey r;
1570 	uint32_t num_subkeys, max_subkeylen, max_classlen,
1571 		num_values, max_valnamelen, max_valbufsize,
1572 		secdescsize;
1573 	NTTIME last_changed_time;
1574 
1575 	ZERO_STRUCT(r);
1576 	r.in.handle = handle;
1577 	r.out.num_subkeys = &num_subkeys;
1578 	r.out.max_subkeylen = &max_subkeylen;
1579 	r.out.max_classlen = &max_classlen;
1580 	r.out.num_values = &num_values;
1581 	r.out.max_valnamelen = &max_valnamelen;
1582 	r.out.max_valbufsize = &max_valbufsize;
1583 	r.out.secdescsize = &secdescsize;
1584 	r.out.last_changed_time = &last_changed_time;
1585 
1586 	r.out.classname = talloc(tctx, struct winreg_String);
1587 
1588 	r.in.classname = talloc(tctx, struct winreg_String);
1589 	init_winreg_String(r.in.classname, kclass);
1590 
1591 	torture_assert_ntstatus_ok(tctx,
1592 				   dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1593 				   "QueryInfoKey failed");
1594 
1595 	torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1596 
1597 	if (pmax_valnamelen) {
1598 		*pmax_valnamelen = max_valnamelen;
1599 	}
1600 
1601 	if (pmax_valbufsize) {
1602 		*pmax_valbufsize = max_valbufsize;
1603 	}
1604 
1605 	return true;
1606 }
1607 
test_SetValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * value_name,enum winreg_Type type,uint8_t * data,uint32_t size)1608 static bool test_SetValue(struct dcerpc_binding_handle *b,
1609 			  struct torture_context *tctx,
1610 			  struct policy_handle *handle,
1611 			  const char *value_name,
1612 			  enum winreg_Type type,
1613 			  uint8_t *data,
1614 			  uint32_t size)
1615 {
1616 	struct winreg_SetValue r;
1617 	struct winreg_String name;
1618 
1619 	torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1620 		value_name, str_regtype(type), size);
1621 
1622 	init_winreg_String(&name, value_name);
1623 
1624 	r.in.handle = handle;
1625 	r.in.name = name;
1626 	r.in.type = type;
1627 	r.in.data = data;
1628 	r.in.size = size;
1629 
1630 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1631 		"winreg_SetValue failed");
1632 	torture_assert_werr_ok(tctx, r.out.result,
1633 		"winreg_SetValue failed");
1634 
1635 	return true;
1636 }
1637 
test_DeleteValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * value_name)1638 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1639 			     struct torture_context *tctx,
1640 			     struct policy_handle *handle,
1641 			     const char *value_name)
1642 {
1643 	struct winreg_DeleteValue r;
1644 	struct winreg_String value;
1645 
1646 	torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1647 
1648 	init_winreg_String(&value, value_name);
1649 
1650 	r.in.handle = handle;
1651 	r.in.value = value;
1652 
1653 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1654 		"winreg_DeleteValue failed");
1655 	torture_assert_werr_ok(tctx, r.out.result,
1656 		"winreg_DeleteValue failed");
1657 
1658 	return true;
1659 }
1660 
1661 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1662 		     struct policy_handle *handle, int depth,
1663 		     bool test_security);
1664 
test_EnumKey(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,int depth,bool test_security)1665 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1666 			 struct policy_handle *handle, int depth,
1667 			 bool test_security)
1668 {
1669 	struct winreg_EnumKey r;
1670 	struct winreg_StringBuf kclass, name;
1671 	NTSTATUS status;
1672 	NTTIME t = 0;
1673 	struct dcerpc_binding_handle *b = p->binding_handle;
1674 
1675 	kclass.name   = "";
1676 	kclass.size   = 1024;
1677 
1678 	ZERO_STRUCT(r);
1679 	r.in.handle = handle;
1680 	r.in.enum_index = 0;
1681 	r.in.name = &name;
1682 	r.in.keyclass = &kclass;
1683 	r.out.name = &name;
1684 	r.in.last_changed_time = &t;
1685 
1686 	do {
1687 		name.name   = NULL;
1688 		name.size   = 1024;
1689 
1690 		status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1691 
1692 		if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1693 			struct policy_handle key_handle;
1694 
1695 			torture_comment(tctx, "EnumKey: %d: %s\n",
1696 					r.in.enum_index,
1697 					r.out.name->name);
1698 
1699 			if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1700 					  &key_handle)) {
1701 			} else {
1702 				test_key(p, tctx, &key_handle,
1703 					 depth + 1, test_security);
1704 			}
1705 		}
1706 
1707 		r.in.enum_index++;
1708 
1709 	} while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1710 
1711 	torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1712 
1713 	if (!W_ERROR_IS_OK(r.out.result) &&
1714 		!W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1715 		torture_fail(tctx, "EnumKey failed");
1716 	}
1717 
1718 	return true;
1719 }
1720 
test_QueryMultipleValues(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * valuename)1721 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1722 				     struct torture_context *tctx,
1723 				     struct policy_handle *handle,
1724 				     const char *valuename)
1725 {
1726 	struct winreg_QueryMultipleValues r;
1727 	uint32_t bufsize=0;
1728 
1729 	ZERO_STRUCT(r);
1730 
1731 	r.in.key_handle = handle;
1732 	r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1733 	r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1734 	r.in.values_in[0].ve_valuename->name = valuename;
1735 	/* size needs to be set manually for winreg_ValNameBuf */
1736 	r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1737 
1738 	r.in.num_values = 1;
1739 	r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1740 	*r.in.buffer_size = bufsize;
1741 	do {
1742 		*r.in.buffer_size = bufsize;
1743 		r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1744 							       *r.in.buffer_size);
1745 
1746 		torture_assert_ntstatus_ok(tctx,
1747 			dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1748 			"QueryMultipleValues failed");
1749 
1750 		talloc_free(r.in.buffer);
1751 		bufsize += 0x20;
1752 	} while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1753 
1754 	torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1755 
1756 	return true;
1757 }
1758 
test_QueryMultipleValues_full(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,uint32_t num_values,const char * const * valuenames,bool existing_value)1759 static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1760 					  struct torture_context *tctx,
1761 					  struct policy_handle *handle,
1762 					  uint32_t num_values,
1763 					  const char * const *valuenames,
1764 					  bool existing_value)
1765 {
1766 	struct winreg_QueryMultipleValues r;
1767 	uint32_t bufsize = 0;
1768 	int i;
1769 
1770 	torture_comment(tctx, "Testing QueryMultipleValues\n");
1771 
1772 	ZERO_STRUCT(r);
1773 
1774 	r.in.key_handle = handle;
1775 	r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1776 	r.in.buffer_size = r.out.buffer_size = &bufsize;
1777 
1778 	torture_assert_ntstatus_ok(tctx,
1779 		dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1780 		"QueryMultipleValues failed");
1781 	torture_assert_werr_ok(tctx, r.out.result,
1782 		"QueryMultipleValues failed");
1783 
1784 	/* this test crashes w2k8 remote registry */
1785 #if 0
1786 	r.in.num_values = num_values;
1787 	r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1788 
1789 	torture_assert_ntstatus_ok(tctx,
1790 		dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1791 		"QueryMultipleValues failed");
1792 	torture_assert_werr_ok(tctx, r.out.result,
1793 		"QueryMultipleValues failed");
1794 #endif
1795 	r.in.num_values = num_values;
1796 	r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1797 	for (i=0; i < r.in.num_values; i++) {
1798 		r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1799 		r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1800 		r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1801 	}
1802 
1803 	torture_assert_ntstatus_ok(tctx,
1804 		dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1805 		"QueryMultipleValues failed");
1806 	torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
1807 		"QueryMultipleValues failed");
1808 
1809 	if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
1810 		return true;
1811 	}
1812 
1813 	if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1814 		*r.in.buffer_size = 0xff;
1815 		r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1816 
1817 		torture_assert_ntstatus_ok(tctx,
1818 			dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1819 			"QueryMultipleValues failed");
1820 	}
1821 
1822 	torture_assert_werr_ok(tctx, r.out.result,
1823 		"QueryMultipleValues failed");
1824 
1825 	return true;
1826 }
1827 
1828 
test_QueryMultipleValues2_full(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,uint32_t num_values,const char * const * valuenames,bool existing_value)1829 static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1830 					   struct torture_context *tctx,
1831 					   struct policy_handle *handle,
1832 					   uint32_t num_values,
1833 					   const char * const *valuenames,
1834 					   bool existing_value)
1835 {
1836 	struct winreg_QueryMultipleValues2 r;
1837 	uint32_t offered = 0, needed;
1838 	int i;
1839 
1840 	torture_comment(tctx, "Testing QueryMultipleValues2\n");
1841 
1842 	ZERO_STRUCT(r);
1843 
1844 	r.in.key_handle = handle;
1845 	r.in.offered = &offered;
1846 	r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1847 	r.out.needed = &needed;
1848 
1849 	torture_assert_ntstatus_ok(tctx,
1850 		dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1851 		"QueryMultipleValues2 failed");
1852 	torture_assert_werr_ok(tctx, r.out.result,
1853 		"QueryMultipleValues2 failed");
1854 
1855 	/* this test crashes w2k8 remote registry */
1856 #if 0
1857 	r.in.num_values = num_values;
1858 	r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1859 
1860 	torture_assert_ntstatus_ok(tctx,
1861 		dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1862 		"QueryMultipleValues2 failed");
1863 	torture_assert_werr_ok(tctx, r.out.result,
1864 		"QueryMultipleValues2 failed");
1865 #endif
1866 	r.in.num_values = num_values;
1867 	r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1868 	for (i=0; i < r.in.num_values; i++) {
1869 		r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1870 		r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1871 		r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1872 	}
1873 
1874 	torture_assert_ntstatus_ok(tctx,
1875 		dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1876 		"QueryMultipleValues2 failed");
1877 	torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
1878 		"QueryMultipleValues2 failed");
1879 
1880 	if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
1881 		return true;
1882 	}
1883 
1884 	if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1885 		*r.in.offered = *r.out.needed;
1886 		r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1887 
1888 		torture_assert_ntstatus_ok(tctx,
1889 			dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1890 			"QueryMultipleValues2 failed");
1891 	}
1892 
1893 	torture_assert_werr_ok(tctx, r.out.result,
1894 		"QueryMultipleValues2 failed");
1895 
1896 	return true;
1897 }
1898 
test_QueryMultipleValues2(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * valuename)1899 static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1900 				      struct torture_context *tctx,
1901 				      struct policy_handle *handle,
1902 				      const char *valuename)
1903 {
1904 	struct winreg_QueryMultipleValues2 r;
1905 	uint32_t offered = 0, needed;
1906 
1907 	ZERO_STRUCT(r);
1908 
1909 	r.in.key_handle = handle;
1910 	r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1911 	r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1912 	r.in.values_in[0].ve_valuename->name = valuename;
1913 	/* size needs to be set manually for winreg_ValNameBuf */
1914 	r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1915 
1916 	r.in.num_values = 1;
1917 	r.in.offered = &offered;
1918 	r.out.needed = &needed;
1919 
1920 	torture_assert_ntstatus_ok(tctx,
1921 		dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1922 		"QueryMultipleValues2 failed");
1923 	if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1924 		*r.in.offered = *r.out.needed;
1925 		r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1926 
1927 		torture_assert_ntstatus_ok(tctx,
1928 			dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1929 			"QueryMultipleValues2 failed");
1930 	}
1931 
1932 	torture_assert_werr_ok(tctx, r.out.result,
1933 		"QueryMultipleValues2 failed");
1934 
1935 	return true;
1936 }
1937 
test_QueryValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * valuename)1938 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1939 			    struct torture_context *tctx,
1940 			    struct policy_handle *handle,
1941 			    const char *valuename)
1942 {
1943 	struct winreg_QueryValue r;
1944 	NTSTATUS status;
1945 	enum winreg_Type zero_type = 0;
1946 	uint32_t offered = 0xfff;
1947 	uint32_t zero = 0;
1948 
1949 	ZERO_STRUCT(r);
1950 	r.in.handle = handle;
1951 	r.in.data = NULL;
1952 	r.in.value_name = talloc_zero(tctx, struct winreg_String);
1953 	r.in.value_name->name = valuename;
1954 	r.in.type = &zero_type;
1955 	r.in.data_size = &offered;
1956 	r.in.data_length = &zero;
1957 
1958 	status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1959 	if (NT_STATUS_IS_ERR(status)) {
1960 		torture_fail(tctx, "QueryValue failed");
1961 	}
1962 
1963 	torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1964 
1965 	return true;
1966 }
1967 
test_QueryValue_full(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * valuename,bool existing_value)1968 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1969 				 struct torture_context *tctx,
1970 				 struct policy_handle *handle,
1971 				 const char *valuename,
1972 				 bool existing_value)
1973 {
1974 	struct winreg_QueryValue r;
1975 	struct winreg_String value_name;
1976 	enum winreg_Type type = REG_NONE;
1977 	uint32_t data_size = 0;
1978 	uint32_t real_data_size = 0;
1979 	uint32_t data_length = 0;
1980 	uint8_t *data = NULL;
1981 	WERROR expected_error = WERR_FILE_NOT_FOUND;
1982 	const char *errmsg_nonexisting = "expected WERR_FILE_NOT_FOUND for nonexisting value";
1983 
1984 	if (valuename == NULL) {
1985 		expected_error = WERR_INVALID_PARAMETER;
1986 		errmsg_nonexisting = "expected WERR_INVALID_PARAMETER for NULL valuename";
1987 	}
1988 
1989 	ZERO_STRUCT(r);
1990 
1991 	init_winreg_String(&value_name, NULL);
1992 
1993 	torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1994 
1995 	r.in.handle = handle;
1996 	r.in.value_name = &value_name;
1997 
1998 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1999 	torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2000 		"expected WERR_INVALID_PARAMETER for NULL winreg_String.name");
2001 
2002 	init_winreg_String(&value_name, valuename);
2003 	r.in.value_name = &value_name;
2004 
2005 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2006 		"QueryValue failed");
2007 	torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2008 		"expected WERR_INVALID_PARAMETER for missing type length and size");
2009 
2010 	r.in.type = &type;
2011 	r.out.type = &type;
2012 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2013 		"QueryValue failed");
2014 	torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2015 		"expected WERR_INVALID_PARAMETER for missing length and size");
2016 
2017 	r.in.data_length = &data_length;
2018 	r.out.data_length = &data_length;
2019 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2020 		"QueryValue failed");
2021 	torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2022 		"expected WERR_INVALID_PARAMETER for missing size");
2023 
2024 	r.in.data_size = &data_size;
2025 	r.out.data_size = &data_size;
2026 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2027 		"QueryValue failed");
2028 	if (existing_value) {
2029 		torture_assert_werr_ok(tctx, r.out.result,
2030 			"QueryValue failed");
2031 	} else {
2032 		torture_assert_werr_equal(tctx, r.out.result, expected_error,
2033 			errmsg_nonexisting);
2034 	}
2035 
2036 	real_data_size = *r.out.data_size;
2037 
2038 	data = talloc_zero_array(tctx, uint8_t, 0);
2039 	r.in.data = data;
2040 	r.out.data = data;
2041 	*r.in.data_size = 0;
2042 	*r.out.data_size = 0;
2043 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2044 		"QueryValue failed");
2045 	if (existing_value) {
2046 		torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
2047 			"expected WERR_MORE_DATA for query with too small buffer");
2048 	} else {
2049 		torture_assert_werr_equal(tctx, r.out.result, expected_error,
2050 			errmsg_nonexisting);
2051 	}
2052 
2053 	data = talloc_zero_array(tctx, uint8_t, real_data_size);
2054 	r.in.data = data;
2055 	r.out.data = data;
2056 	r.in.data_size = &real_data_size;
2057 	r.out.data_size = &real_data_size;
2058 	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2059 		"QueryValue failed");
2060 	if (existing_value) {
2061 		torture_assert_werr_ok(tctx, r.out.result,
2062 			"QueryValue failed");
2063 	} else {
2064 		torture_assert_werr_equal(tctx, r.out.result, expected_error,
2065 			errmsg_nonexisting);
2066 	}
2067 
2068 	return true;
2069 }
2070 
test_EnumValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,int max_valnamelen,int max_valbufsize)2071 static bool test_EnumValue(struct dcerpc_binding_handle *b,
2072 			   struct torture_context *tctx,
2073 			   struct policy_handle *handle, int max_valnamelen,
2074 			   int max_valbufsize)
2075 {
2076 	struct winreg_EnumValue r;
2077 	enum winreg_Type type = 0;
2078 	uint32_t size = max_valbufsize, zero = 0;
2079 	bool ret = true;
2080 	uint8_t *data = NULL;
2081 	struct winreg_ValNameBuf name;
2082 	char n = '\0';
2083 
2084 	ZERO_STRUCT(r);
2085 	r.in.handle = handle;
2086 	r.in.enum_index = 0;
2087 	r.in.name = &name;
2088 	r.out.name = &name;
2089 	r.in.type = &type;
2090 	r.in.length = &zero;
2091 	r.in.size = &size;
2092 
2093 	do {
2094 		name.name = &n;
2095 		name.size = max_valnamelen + 2;
2096 		name.length = 0;
2097 
2098 		data = NULL;
2099 		if (size) {
2100 			data = talloc_array(tctx, uint8_t, size);
2101 		}
2102 		r.in.value = data;
2103 
2104 		torture_assert_ntstatus_ok(tctx,
2105 					   dcerpc_winreg_EnumValue_r(b, tctx, &r),
2106 					   "EnumValue failed");
2107 
2108 		if (W_ERROR_IS_OK(r.out.result)) {
2109 			ret &= test_QueryValue(b, tctx, handle,
2110 					       r.out.name->name);
2111 			ret &= test_QueryMultipleValues(b, tctx, handle,
2112 							r.out.name->name);
2113 			ret &= test_QueryMultipleValues2(b, tctx, handle,
2114 							 r.out.name->name);
2115 		}
2116 
2117 		talloc_free(data);
2118 
2119 		r.in.enum_index++;
2120 	} while (W_ERROR_IS_OK(r.out.result));
2121 
2122 	torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2123 				  "EnumValue failed");
2124 
2125 	return ret;
2126 }
2127 
test_AbortSystemShutdown(struct dcerpc_binding_handle * b,struct torture_context * tctx)2128 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2129 				     struct torture_context *tctx)
2130 {
2131 	struct winreg_AbortSystemShutdown r;
2132 	uint16_t server = 0x0;
2133 
2134 	ZERO_STRUCT(r);
2135 	r.in.server = &server;
2136 
2137 	torture_assert_ntstatus_ok(tctx,
2138 				   dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2139 				   "AbortSystemShutdown failed");
2140 
2141 	torture_assert_werr_ok(tctx, r.out.result,
2142 			       "AbortSystemShutdown failed");
2143 
2144 	return true;
2145 }
2146 
test_InitiateSystemShutdown(struct torture_context * tctx,struct dcerpc_pipe * p)2147 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2148 					struct dcerpc_pipe *p)
2149 {
2150 	struct winreg_InitiateSystemShutdown r;
2151 	uint16_t hostname = 0x0;
2152 	struct dcerpc_binding_handle *b = p->binding_handle;
2153 
2154 	ZERO_STRUCT(r);
2155 	r.in.hostname = &hostname;
2156 	r.in.message = talloc(tctx, struct lsa_StringLarge);
2157 	init_lsa_StringLarge(r.in.message, "spottyfood");
2158 	r.in.force_apps = 1;
2159 	r.in.timeout = 30;
2160 	r.in.do_reboot = 1;
2161 
2162 	torture_assert_ntstatus_ok(tctx,
2163 				   dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2164 				   "InitiateSystemShutdown failed");
2165 
2166 	torture_assert_werr_ok(tctx, r.out.result,
2167 			       "InitiateSystemShutdown failed");
2168 
2169 	return test_AbortSystemShutdown(b, tctx);
2170 }
2171 
2172 
test_InitiateSystemShutdownEx(struct torture_context * tctx,struct dcerpc_pipe * p)2173 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2174 					  struct dcerpc_pipe *p)
2175 {
2176 	struct winreg_InitiateSystemShutdownEx r;
2177 	uint16_t hostname = 0x0;
2178 	struct dcerpc_binding_handle *b = p->binding_handle;
2179 
2180 	ZERO_STRUCT(r);
2181 	r.in.hostname = &hostname;
2182 	r.in.message = talloc(tctx, struct lsa_StringLarge);
2183 	init_lsa_StringLarge(r.in.message, "spottyfood");
2184 	r.in.force_apps = 1;
2185 	r.in.timeout = 30;
2186 	r.in.do_reboot = 1;
2187 	r.in.reason = 0;
2188 
2189 	torture_assert_ntstatus_ok(tctx,
2190 		dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2191 		"InitiateSystemShutdownEx failed");
2192 
2193 	torture_assert_werr_ok(tctx, r.out.result,
2194 			       "InitiateSystemShutdownEx failed");
2195 
2196 	return test_AbortSystemShutdown(b, tctx);
2197 }
2198 #define MAX_DEPTH 2		/* Only go this far down the tree */
2199 
test_key(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,int depth,bool test_security)2200 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2201 		     struct policy_handle *handle, int depth,
2202 		     bool test_security)
2203 {
2204 	struct dcerpc_binding_handle *b = p->binding_handle;
2205 	uint32_t max_valnamelen = 0;
2206 	uint32_t max_valbufsize = 0;
2207 
2208 	if (depth == MAX_DEPTH)
2209 		return true;
2210 
2211 	if (!test_QueryInfoKey(b, tctx, handle, NULL,
2212 			       &max_valnamelen, &max_valbufsize)) {
2213 	}
2214 
2215 	if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2216 	}
2217 
2218 	if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2219 	}
2220 
2221 	if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2222 	}
2223 
2224 	if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
2225 	}
2226 
2227 	if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
2228 	}
2229 
2230 	test_CloseKey(b, tctx, handle);
2231 
2232 	return true;
2233 }
2234 
test_SetValue_simple(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)2235 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2236 				 struct torture_context *tctx,
2237 				 struct policy_handle *handle)
2238 {
2239 	const char *value_name = TEST_VALUE;
2240 	uint32_t value = 0x12345678;
2241 	uint64_t value2 = 0x12345678;
2242 	const char *string = "torture";
2243 	const char *array[2];
2244 	DATA_BLOB blob;
2245 	enum winreg_Type types[] = {
2246 		REG_DWORD,
2247 		REG_DWORD_BIG_ENDIAN,
2248 		REG_QWORD,
2249 		REG_BINARY,
2250 		REG_SZ,
2251 		REG_MULTI_SZ
2252 	};
2253 	int t;
2254 
2255 	array[0] = "array0";
2256 	array[1] = NULL;
2257 
2258 	torture_comment(tctx, "Testing SetValue (standard formats)\n");
2259 
2260 	for (t=0; t < ARRAY_SIZE(types); t++) {
2261 
2262 		enum winreg_Type w_type;
2263 		uint32_t w_size, w_length;
2264 		uint8_t *w_data;
2265 
2266 		switch (types[t]) {
2267 		case REG_DWORD:
2268 		case REG_DWORD_BIG_ENDIAN:
2269 			blob = data_blob_talloc_zero(tctx, 4);
2270 			SIVAL(blob.data, 0, value);
2271 			break;
2272 		case REG_QWORD:
2273 			blob = data_blob_talloc_zero(tctx, 8);
2274 			SBVAL(blob.data, 0, value2);
2275 			break;
2276 		case REG_BINARY:
2277 			blob = data_blob_string_const("binary_blob");
2278 			break;
2279 		case REG_SZ:
2280 			torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2281 			break;
2282 		case REG_MULTI_SZ:
2283 			torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2284 			break;
2285 		default:
2286 			break;
2287 		}
2288 
2289 		torture_assert(tctx,
2290 			test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2291 			"test_SetValue failed");
2292 		torture_assert(tctx,
2293 			test_QueryValue_full(b, tctx, handle, value_name, true),
2294 			talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2295 		torture_assert(tctx,
2296 			test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2297 			"test_winreg_QueryValue failed");
2298 		torture_assert(tctx,
2299 			test_DeleteValue(b, tctx, handle, value_name),
2300 			"test_DeleteValue failed");
2301 
2302 		torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2303 		torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2304 		torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2305 		torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2306 	}
2307 
2308 	torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2309 
2310 	return true;
2311 }
2312 
test_SetValue_values(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)2313 static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2314 				 struct torture_context *tctx,
2315 				 struct policy_handle *handle)
2316 {
2317 	DATA_BLOB blob;
2318 	const char *values[] = {
2319 		"torture_value",
2320 		"torture value",
2321 		"torture,value",
2322 		"torture;value",
2323 		"torture/value",
2324 		"torture\\value",
2325 		"torture_value_name",
2326 		"torture value name",
2327 		"torture,value,name",
2328 		"torture;value;name",
2329 		"torture/value/name",
2330 		"torture\\value\\name",
2331 	};
2332 	int i;
2333 
2334 	torture_comment(tctx, "Testing SetValue (values)\n");
2335 
2336 	for (i=0; i < ARRAY_SIZE(values); i++) {
2337 
2338 		enum winreg_Type w_type;
2339 		uint32_t w_size, w_length;
2340 		uint8_t *w_data;
2341 
2342 		blob = data_blob_talloc(tctx, NULL, 32);
2343 
2344 		generate_random_buffer(blob.data, 32);
2345 
2346 		torture_assert(tctx,
2347 			test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2348 			"test_SetValue failed");
2349 		torture_assert(tctx,
2350 			test_QueryValue_full(b, tctx, handle, values[i], true),
2351 			talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2352 		torture_assert(tctx,
2353 			test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2354 			"test_winreg_QueryValue failed");
2355 		torture_assert(tctx,
2356 			test_DeleteValue(b, tctx, handle, values[i]),
2357 			"test_DeleteValue failed");
2358 
2359 		torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2360 		torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2361 		torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2362 		torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2363 	}
2364 
2365 	torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2366 
2367 	return true;
2368 }
2369 
2370 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2371 
test_SetValue_extended(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)2372 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2373 				   struct torture_context *tctx,
2374 				   struct policy_handle *handle)
2375 {
2376 	const char *value_name = TEST_VALUE;
2377 	enum winreg_Type types[] = {
2378 		REG_NONE,
2379 		REG_SZ,
2380 		REG_EXPAND_SZ,
2381 		REG_BINARY,
2382 		REG_DWORD,
2383 		REG_DWORD_BIG_ENDIAN,
2384 		REG_LINK,
2385 		REG_MULTI_SZ,
2386 		REG_RESOURCE_LIST,
2387 		REG_FULL_RESOURCE_DESCRIPTOR,
2388 		REG_RESOURCE_REQUIREMENTS_LIST,
2389 		REG_QWORD,
2390 		12,
2391 		13,
2392 		14,
2393 		55,
2394 		123456,
2395 		653210,
2396 		__LINE__
2397 	};
2398 	int t, l;
2399 
2400 	if (torture_setting_bool(tctx, "samba4", false)) {
2401 		torture_skip(tctx, "skipping extended SetValue test against Samba4");
2402 	}
2403 
2404 	torture_comment(tctx, "Testing SetValue (extended formats)\n");
2405 
2406 	for (t=0; t < ARRAY_SIZE(types); t++) {
2407 	for (l=0; l < 16; l++) {
2408 
2409 		enum winreg_Type w_type;
2410 		uint32_t w_size, w_length;
2411 		uint8_t *w_data;
2412 
2413 		uint32_t size;
2414 		uint8_t *data;
2415 
2416 		size = l;
2417 		data = talloc_array(tctx, uint8_t, size);
2418 
2419 		generate_random_buffer(data, size);
2420 
2421 		torture_assert(tctx,
2422 			test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2423 			"test_SetValue failed");
2424 
2425 		torture_assert(tctx,
2426 			test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2427 			"test_winreg_QueryValue failed");
2428 
2429 		torture_assert(tctx,
2430 			test_DeleteValue(b, tctx, handle, value_name),
2431 			"test_DeleteValue failed");
2432 
2433 		torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2434 		torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2435 		torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2436 		torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2437 	}
2438 	}
2439 
2440 	torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2441 
2442 	return true;
2443 }
2444 
test_create_keynames(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)2445 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2446 				 struct torture_context *tctx,
2447 				 struct policy_handle *handle)
2448 {
2449 	const char *keys[] = {
2450 		"torture_key",
2451 		"torture key",
2452 		"torture,key",
2453 		"torture/key",
2454 		"torture\\key",
2455 	};
2456 	int i;
2457 
2458 	for (i=0; i < ARRAY_SIZE(keys); i++) {
2459 
2460 		enum winreg_CreateAction action_taken;
2461 		struct policy_handle new_handle;
2462 		char *q, *tmp;
2463 
2464 		torture_assert(tctx,
2465 			test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2466 					    REG_OPTION_NON_VOLATILE,
2467 					    SEC_FLAG_MAXIMUM_ALLOWED,
2468 					    NULL,
2469 					    WERR_OK,
2470 					    &action_taken,
2471 					    &new_handle),
2472 			talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2473 
2474 		torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2475 
2476 		torture_assert(tctx,
2477 			test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2478 			"failed to delete key");
2479 
2480 		torture_assert(tctx,
2481 			test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_FILE_NOT_FOUND),
2482 			"failed 2nd delete key");
2483 
2484 		tmp = talloc_strdup(tctx, keys[i]);
2485 
2486 		q = strchr(tmp, '\\');
2487 		if (q != NULL) {
2488 			*q = '\0';
2489 			q++;
2490 
2491 			torture_assert(tctx,
2492 				test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2493 				"failed to delete key");
2494 
2495 			torture_assert(tctx,
2496 				test_DeleteKey_opts(b, tctx, handle, tmp, WERR_FILE_NOT_FOUND),
2497 				"failed 2nd delete key");
2498 		}
2499 	}
2500 
2501 	return true;
2502 }
2503 
2504 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2505 #define VALUE_CURRENT_VERSION "CurrentVersion"
2506 #define VALUE_SYSTEM_ROOT "SystemRoot"
2507 
2508 static const struct {
2509 	const char *values[3];
2510 	uint32_t num_values;
2511 	bool existing_value;
2512 	const char *error_message;
2513 } multiple_values_tests[] = {
2514 	{
2515 		.values = { VALUE_CURRENT_VERSION, NULL, NULL },
2516 		.num_values = 1,
2517 		.existing_value = true,
2518 		.error_message = NULL
2519 	},{
2520 		.values = { VALUE_SYSTEM_ROOT, NULL, NULL },
2521 		.num_values = 1,
2522 		.existing_value = true,
2523 		.error_message = NULL
2524 	},{
2525 		.values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT, NULL },
2526 		.num_values = 2,
2527 		.existing_value = true,
2528 		.error_message = NULL
2529 	},{
2530 		.values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT,
2531 			    VALUE_CURRENT_VERSION },
2532 		.num_values = 3,
2533 		.existing_value = true,
2534 		.error_message = NULL
2535 	},{
2536 		.values = { VALUE_CURRENT_VERSION, NULL, VALUE_SYSTEM_ROOT },
2537 		.num_values = 3,
2538 		.existing_value = false,
2539 		.error_message = NULL
2540 	},{
2541 		.values = { VALUE_CURRENT_VERSION, "", VALUE_SYSTEM_ROOT },
2542 		.num_values = 3,
2543 		.existing_value = false,
2544 		.error_message = NULL
2545 	},{
2546 		.values = { "IDoNotExist", NULL, NULL },
2547 		.num_values = 1,
2548 		.existing_value = false,
2549 		.error_message = NULL
2550 	},{
2551 		.values = { "IDoNotExist", VALUE_CURRENT_VERSION, NULL },
2552 		.num_values = 2,
2553 		.existing_value = false,
2554 		.error_message = NULL
2555 	},{
2556 		.values = { VALUE_CURRENT_VERSION, "IDoNotExist", NULL },
2557 		.num_values = 2,
2558 		.existing_value = false,
2559 		.error_message = NULL
2560 	}
2561 };
2562 
test_HKLM_wellknown(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle)2563 static bool test_HKLM_wellknown(struct torture_context *tctx,
2564 				struct dcerpc_binding_handle *b,
2565 				struct policy_handle *handle)
2566 {
2567 	struct policy_handle newhandle;
2568 	int i;
2569 
2570 	/* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2571 	if (torture_setting_bool(tctx, "samba3", false)) {
2572 		torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2573 			       KEY_CURRENT_VERSION,
2574 			       REG_OPTION_NON_VOLATILE,
2575 			       KEY_QUERY_VALUE,
2576 			       &newhandle,
2577 			       WERR_OK),
2578 			"failed to open current version key");
2579 	} else {
2580 		torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2581 			"failed to open current version key");
2582 	}
2583 
2584 	torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2585 		"failed to query current version");
2586 	torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2587 		"succeeded to query nonexistent value");
2588 	torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2589 		"succeeded to query value with NULL name");
2590 	torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2591 		"succeeded to query nonexistent default value (\"\")");
2592 
2593 	if (torture_setting_bool(tctx, "samba4", false)) {
2594 		torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2595 		goto close_key;
2596 	}
2597 
2598 	for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2599 		const char *msg;
2600 		msg = talloc_asprintf(tctx,
2601 				"failed to query %d %sexisting values\n",
2602 					multiple_values_tests[i].num_values,
2603 					multiple_values_tests[i].existing_value ? "":"non");
2604 
2605 		torture_assert(tctx,
2606 			test_QueryMultipleValues_full(b, tctx, &newhandle,
2607 						      multiple_values_tests[i].num_values,
2608 						      multiple_values_tests[i].values,
2609 						      multiple_values_tests[i].existing_value),
2610 			msg);
2611 		torture_assert(tctx,
2612 			test_QueryMultipleValues2_full(b, tctx, &newhandle,
2613 						       multiple_values_tests[i].num_values,
2614 						       multiple_values_tests[i].values,
2615 						       multiple_values_tests[i].existing_value),
2616 			msg);
2617 	}
2618 
2619  close_key:
2620 	torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2621 		"failed to close current version key");
2622 
2623 	return true;
2624 }
2625 
test_OpenHive(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,int hkey)2626 static bool test_OpenHive(struct torture_context *tctx,
2627 			  struct dcerpc_binding_handle *b,
2628 			  struct policy_handle *handle,
2629 			  int hkey)
2630 {
2631 	struct winreg_OpenHKLM r;
2632 
2633 	r.in.system_name = 0;
2634 	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2635 	r.out.handle = handle;
2636 
2637 	switch (hkey) {
2638 	case HKEY_LOCAL_MACHINE:
2639 		torture_assert_ntstatus_ok(tctx,
2640 			dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2641 			"failed to open HKLM");
2642 		torture_assert_werr_ok(tctx, r.out.result,
2643 			"failed to open HKLM");
2644 		break;
2645 	case HKEY_CURRENT_USER:
2646 		torture_assert_ntstatus_ok(tctx,
2647 			dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
2648 			"failed to open HKCU");
2649 		torture_assert_werr_ok(tctx, r.out.result,
2650 			"failed to open HKCU");
2651 		break;
2652 	case HKEY_USERS:
2653 		torture_assert_ntstatus_ok(tctx,
2654 			dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
2655 			"failed to open HKU");
2656 		torture_assert_werr_ok(tctx, r.out.result,
2657 			"failed to open HKU");
2658 		break;
2659 	case HKEY_CLASSES_ROOT:
2660 		torture_assert_ntstatus_ok(tctx,
2661 			dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
2662 			"failed to open HKCR");
2663 		torture_assert_werr_ok(tctx, r.out.result,
2664 			"failed to open HKCR");
2665 		break;
2666 	default:
2667 		torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2668 		return false;
2669 	}
2670 
2671 	return true;
2672 }
2673 
test_volatile_keys(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,int hkey)2674 static bool test_volatile_keys(struct torture_context *tctx,
2675 			       struct dcerpc_binding_handle *b,
2676 			       struct policy_handle *handle,
2677 			       int hkey)
2678 {
2679 	struct policy_handle new_handle, hive_handle;
2680 	enum winreg_CreateAction action_taken = REG_ACTION_NONE;
2681 
2682 	ZERO_STRUCT(new_handle);
2683 	ZERO_STRUCT(hive_handle);
2684 
2685 	torture_comment(tctx, "Testing VOLATILE key\n");
2686 
2687 	test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2688 
2689 	torture_assert(tctx,
2690 		test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2691 				    REG_OPTION_VOLATILE,
2692 				    SEC_FLAG_MAXIMUM_ALLOWED,
2693 				    NULL,
2694 				    WERR_OK,
2695 				    &action_taken,
2696 				    &new_handle),
2697 		"failed to create REG_OPTION_VOLATILE type key");
2698 
2699 	torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2700 
2701 	torture_assert(tctx,
2702 		test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2703 				    REG_OPTION_NON_VOLATILE,
2704 				    SEC_FLAG_MAXIMUM_ALLOWED,
2705 				    NULL,
2706 				    WERR_CHILD_MUST_BE_VOLATILE,
2707 				    NULL,
2708 				    NULL),
2709 		"failed to fail create REG_OPTION_VOLATILE type key");
2710 
2711 	torture_assert(tctx,
2712 		test_CloseKey(b, tctx, &new_handle),
2713 		"failed to close");
2714 
2715 	torture_assert(tctx,
2716 		test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2717 				  REG_OPTION_NON_VOLATILE,
2718 				  SEC_FLAG_MAXIMUM_ALLOWED,
2719 				  &new_handle,
2720 				  WERR_OK),
2721 		"failed to open volatile key");
2722 
2723 	torture_assert(tctx,
2724 		test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2725 		"failed to delete key");
2726 
2727 	torture_assert(tctx,
2728 		test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2729 				    REG_OPTION_VOLATILE,
2730 				    SEC_FLAG_MAXIMUM_ALLOWED,
2731 				    NULL,
2732 				    WERR_OK,
2733 				    &action_taken,
2734 				    &new_handle),
2735 		"failed to create REG_OPTION_VOLATILE type key");
2736 
2737 	torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2738 
2739 	torture_assert(tctx,
2740 		test_CloseKey(b, tctx, &new_handle),
2741 		"failed to close");
2742 
2743 	torture_assert(tctx,
2744 		test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2745 				  REG_OPTION_VOLATILE,
2746 				  SEC_FLAG_MAXIMUM_ALLOWED,
2747 				  &new_handle,
2748 				  WERR_OK),
2749 		"failed to open volatile key");
2750 
2751 	torture_assert(tctx,
2752 		test_CloseKey(b, tctx, &new_handle),
2753 		"failed to close");
2754 
2755 	torture_assert(tctx,
2756 		test_OpenHive(tctx, b, &hive_handle, hkey),
2757 		"failed top open hive");
2758 
2759 	torture_assert(tctx,
2760 		test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2761 				  REG_OPTION_VOLATILE,
2762 				  SEC_FLAG_MAXIMUM_ALLOWED,
2763 				  &new_handle,
2764 				  WERR_FILE_NOT_FOUND),
2765 		"failed to open volatile key");
2766 
2767 	torture_assert(tctx,
2768 		test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2769 				  REG_OPTION_NON_VOLATILE,
2770 				  SEC_FLAG_MAXIMUM_ALLOWED,
2771 				  &new_handle,
2772 				  WERR_FILE_NOT_FOUND),
2773 		"failed to open volatile key");
2774 
2775 	torture_assert(tctx,
2776 		test_CloseKey(b, tctx, &hive_handle),
2777 		"failed to close");
2778 
2779 	torture_assert(tctx,
2780 		test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2781 		"failed to delete key");
2782 
2783 
2784 	torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2785 
2786 	return true;
2787 }
2788 
kernel_mode_registry_path(struct torture_context * tctx,int hkey,const char * sid_string,const char * path)2789 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2790 					     int hkey,
2791 					     const char *sid_string,
2792 					     const char *path)
2793 {
2794 	switch (hkey) {
2795 	case HKEY_LOCAL_MACHINE:
2796 		return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2797 	case HKEY_CURRENT_USER:
2798 		return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2799 	case HKEY_USERS:
2800 		return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2801 	case HKEY_CLASSES_ROOT:
2802 		return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2803 	default:
2804 		torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2805 		return NULL;
2806 	}
2807 }
2808 
test_symlink_keys(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,const char * key,int hkey)2809 static bool test_symlink_keys(struct torture_context *tctx,
2810 			      struct dcerpc_binding_handle *b,
2811 			      struct policy_handle *handle,
2812 			      const char *key,
2813 			      int hkey)
2814 {
2815 	struct policy_handle new_handle;
2816 	enum winreg_CreateAction action_taken;
2817 	DATA_BLOB blob;
2818 	uint32_t value = 42;
2819 	const char *test_key_symlink_dest;
2820 	const char *test_key_symlink;
2821 	const char *kernel_mode_path;
2822 
2823 	/* disable until we know how to delete a symbolic link */
2824 	torture_skip(tctx, "symlink test disabled");
2825 
2826 	torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2827 
2828 	/* create destination key with testvalue */
2829 	test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2830 			key, TEST_KEY_SYMLINK);
2831 	test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2832 			key, TEST_KEY_SYMLINK_DEST);
2833 
2834 	test_DeleteKey(b, tctx, handle, test_key_symlink);
2835 
2836 	torture_assert(tctx,
2837 		test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2838 				    0,
2839 				    SEC_FLAG_MAXIMUM_ALLOWED,
2840 				    NULL,
2841 				    WERR_OK,
2842 				    &action_taken,
2843 				    &new_handle),
2844 		"failed to create symlink destination");
2845 
2846 	blob = data_blob_talloc_zero(tctx, 4);
2847 	SIVAL(blob.data, 0, value);
2848 
2849 	torture_assert(tctx,
2850 		test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2851 		"failed to create TestValue");
2852 
2853 	torture_assert(tctx,
2854 		test_CloseKey(b, tctx, &new_handle),
2855 		"failed to close");
2856 
2857 	/* create symlink */
2858 
2859 	torture_assert(tctx,
2860 		test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2861 				    REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2862 				    SEC_FLAG_MAXIMUM_ALLOWED,
2863 				    NULL,
2864 				    WERR_OK,
2865 				    &action_taken,
2866 				    &new_handle),
2867 		"failed to create REG_OPTION_CREATE_LINK type key");
2868 
2869 	torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2870 
2871 	kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2872 
2873 	torture_assert(tctx,
2874 		convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2875 				      kernel_mode_path,
2876 				      strlen(kernel_mode_path), /* not NULL terminated */
2877 				      &blob.data, &blob.length),
2878 		"failed to convert");
2879 
2880 	torture_assert(tctx,
2881 		test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2882 		"failed to create SymbolicLinkValue value");
2883 
2884 	torture_assert(tctx,
2885 		test_CloseKey(b, tctx, &new_handle),
2886 		"failed to close");
2887 
2888 	/* test follow symlink */
2889 
2890 	torture_assert(tctx,
2891 		test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2892 				  0,
2893 				  SEC_FLAG_MAXIMUM_ALLOWED,
2894 				  &new_handle,
2895 				  WERR_OK),
2896 		"failed to follow symlink key");
2897 
2898 	torture_assert(tctx,
2899 		test_QueryValue(b, tctx, &new_handle, "TestValue"),
2900 		"failed to query value");
2901 
2902 	torture_assert(tctx,
2903 		test_CloseKey(b, tctx, &new_handle),
2904 		"failed to close");
2905 
2906 	/* delete link */
2907 
2908 	torture_assert(tctx,
2909 		test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2910 				  REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2911 				  SEC_FLAG_MAXIMUM_ALLOWED,
2912 				  &new_handle,
2913 				  WERR_OK),
2914 		"failed to open symlink key");
2915 
2916 	torture_assert(tctx,
2917 		test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2918 		"failed to delete value SymbolicLinkValue");
2919 
2920 	torture_assert(tctx,
2921 		test_CloseKey(b, tctx, &new_handle),
2922 		"failed to close");
2923 
2924 	torture_assert(tctx,
2925 		test_DeleteKey(b, tctx, handle, test_key_symlink),
2926 		"failed to delete key");
2927 
2928 	/* delete destination */
2929 
2930 	torture_assert(tctx,
2931 		test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2932 		"failed to delete key");
2933 
2934 	return true;
2935 }
2936 
test_CreateKey_keytypes(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,const char * key,int hkey)2937 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2938 				    struct dcerpc_binding_handle *b,
2939 				    struct policy_handle *handle,
2940 				    const char *key,
2941 				    int hkey)
2942 {
2943 
2944 	if (torture_setting_bool(tctx, "samba3", false) ||
2945 	    torture_setting_bool(tctx, "samba4", false)) {
2946 		torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2947 	}
2948 
2949 	torture_assert(tctx,
2950 		test_volatile_keys(tctx, b, handle, hkey),
2951 		"failed to test volatile keys");
2952 
2953 	torture_assert(tctx,
2954 		test_symlink_keys(tctx, b, handle, key, hkey),
2955 		"failed to test symlink keys");
2956 
2957 	return true;
2958 }
2959 
test_key_base(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,const char * base_key,int hkey)2960 static bool test_key_base(struct torture_context *tctx,
2961 			  struct dcerpc_binding_handle *b,
2962 			  struct policy_handle *handle,
2963 			  const char *base_key,
2964 			  int hkey)
2965 {
2966 	struct policy_handle newhandle;
2967 	bool ret = true, created = false, deleted = false;
2968 	bool created3 = false;
2969 	const char *test_key1;
2970 	const char *test_key3;
2971 	const char *test_subkey;
2972 
2973 	test_Cleanup(b, tctx, handle, base_key);
2974 
2975 	if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2976 		torture_comment(tctx,
2977 				"CreateKey(%s) failed\n", base_key);
2978 	}
2979 
2980 	test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2981 
2982 	if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2983 		torture_comment(tctx,
2984 				"CreateKey failed - not considering a failure\n");
2985 	} else {
2986 		created = true;
2987 	}
2988 
2989 	if (created) {
2990 		if (!test_FlushKey(b, tctx, handle)) {
2991 			torture_comment(tctx, "FlushKey failed\n");
2992 			ret = false;
2993 		}
2994 
2995 		if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2996 			torture_fail(tctx,
2997 				     "CreateKey failed (OpenKey after Create didn't work)\n");
2998 		}
2999 
3000 		if (hkey == HKEY_CURRENT_USER) {
3001 			torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
3002 				"simple SetValue test failed");
3003 			torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
3004 				"values SetValue test failed");
3005 			torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
3006 				"extended SetValue test failed");
3007 			torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
3008 				"keyname CreateKey test failed");
3009 		} else {
3010 			torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
3011 				"keytype test failed");
3012 		}
3013 
3014 		if (!test_CloseKey(b, tctx, &newhandle)) {
3015 			torture_fail(tctx,
3016 				     "CreateKey failed (CloseKey after Open didn't work)\n");
3017 		}
3018 
3019 		if (!test_DeleteKey(b, tctx, handle, test_key1)) {
3020 			torture_comment(tctx, "DeleteKey(%s) failed\n",
3021 					      test_key1);
3022 			ret = false;
3023 		} else {
3024 			deleted = true;
3025 		}
3026 
3027 		if (!test_FlushKey(b, tctx, handle)) {
3028 			torture_comment(tctx, "FlushKey failed\n");
3029 			ret = false;
3030 		}
3031 
3032 		if (deleted) {
3033 			if (!test_OpenKey_opts(tctx, b, handle, test_key1,
3034 					       REG_OPTION_NON_VOLATILE,
3035 					       SEC_FLAG_MAXIMUM_ALLOWED,
3036 					       &newhandle,
3037 					       WERR_FILE_NOT_FOUND)) {
3038 				torture_comment(tctx,
3039 						"DeleteKey failed (OpenKey after Delete "
3040 						"did not return WERR_FILE_NOT_FOUND)\n");
3041 				ret = false;
3042 			}
3043 		}
3044 
3045 		test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
3046 
3047 		if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
3048 			created3 = true;
3049 		}
3050 
3051 		test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
3052 
3053 		if (created3) {
3054 			if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
3055 				if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
3056 					torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
3057 					ret = false;
3058 				}
3059 			}
3060 
3061 			if (!test_DeleteKey(b, tctx, handle, test_key3)) {
3062 				torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
3063 				ret = false;
3064 			}
3065 		}
3066 	}
3067 
3068 	test_Cleanup(b, tctx, handle, base_key);
3069 
3070 	return ret;
3071 }
3072 
test_key_base_sd(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * handle,const char * base_key)3073 static bool test_key_base_sd(struct torture_context *tctx,
3074 			     struct dcerpc_pipe *p,
3075 			     struct policy_handle *handle,
3076 			     const char *base_key)
3077 {
3078 	struct policy_handle newhandle;
3079 	bool ret = true, created2 = false, created4 = false;
3080 	struct dcerpc_binding_handle *b = p->binding_handle;
3081 	const char *test_key2;
3082 	const char *test_key4;
3083 
3084 	torture_skip(tctx, "security descriptor test disabled\n");
3085 
3086 	if (torture_setting_bool(tctx, "samba3", false) ||
3087 	    torture_setting_bool(tctx, "samba4", false)) {
3088 		torture_skip(tctx, "skipping security descriptor tests against Samba");
3089 	}
3090 
3091 	test_Cleanup(b, tctx, handle, base_key);
3092 
3093 	if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
3094 		torture_comment(tctx,
3095 				"CreateKey(%s) failed\n", base_key);
3096 	}
3097 
3098 	test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
3099 
3100 	if (test_CreateKey_sd(b, tctx, handle, test_key2,
3101 			      NULL, &newhandle)) {
3102 		created2 = true;
3103 	}
3104 
3105 	if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
3106 		torture_comment(tctx, "CloseKey failed\n");
3107 		ret = false;
3108 	}
3109 
3110 	test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
3111 
3112 	if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
3113 		created4 = true;
3114 	}
3115 
3116 	if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
3117 		torture_comment(tctx, "CloseKey failed\n");
3118 		ret = false;
3119 	}
3120 
3121 	if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3122 		ret = false;
3123 	}
3124 
3125 	if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3126 		torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3127 		ret = false;
3128 	}
3129 
3130 	if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3131 		torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3132 		ret = false;
3133 	}
3134 
3135 	test_Cleanup(b, tctx, handle, base_key);
3136 
3137 	return ret;
3138 }
3139 
test_Open(struct torture_context * tctx,struct dcerpc_pipe * p,void * userdata)3140 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3141 		      void *userdata)
3142 {
3143 	struct policy_handle handle;
3144 	bool ret = true;
3145 	struct winreg_OpenHKLM r;
3146 	struct dcerpc_binding_handle *b = p->binding_handle;
3147 	const char *torture_base_key;
3148 	int hkey = 0;
3149 
3150 	winreg_open_fn open_fn = (winreg_open_fn)userdata;
3151 
3152 	r.in.system_name = 0;
3153 	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3154 	r.out.handle = &handle;
3155 
3156 	torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3157 				   "open");
3158 
3159 	if (!test_GetVersion(b, tctx, &handle)) {
3160 		torture_comment(tctx, "GetVersion failed\n");
3161 		ret = false;
3162 	}
3163 
3164 	if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3165 		hkey = HKEY_LOCAL_MACHINE;
3166 		torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3167 	} else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3168 		hkey = HKEY_USERS;
3169 		torture_base_key = TEST_KEY_BASE;
3170 	} else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3171 		hkey = HKEY_CLASSES_ROOT;
3172 		torture_base_key = TEST_KEY_BASE;
3173 	} else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3174 		hkey = HKEY_CURRENT_USER;
3175 		torture_base_key = TEST_KEY_BASE;
3176 	} else {
3177 		torture_fail(tctx, "unsupported hkey");
3178 	}
3179 
3180 	if (hkey == HKEY_LOCAL_MACHINE) {
3181 		torture_assert(tctx,
3182 			test_HKLM_wellknown(tctx, b, &handle),
3183 			"failed to test HKLM wellknown keys");
3184 	}
3185 
3186 	if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3187 		torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3188 				torture_base_key);
3189 		ret = false;
3190 	}
3191 
3192 	if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3193 		torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3194 				torture_base_key);
3195 		ret = false;
3196 	}
3197 
3198 	/* The HKCR hive has a very large fanout */
3199 	if (hkey == HKEY_CLASSES_ROOT) {
3200 		if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3201 			ret = false;
3202 		}
3203 	} else if (hkey == HKEY_LOCAL_MACHINE) {
3204 		/* FIXME we are not allowed to enum values in the HKLM root */
3205 	} else {
3206 		if (!test_key(p, tctx, &handle, 0, false)) {
3207 			ret = false;
3208 		}
3209 	}
3210 
3211 	return ret;
3212 }
3213 
torture_rpc_winreg(TALLOC_CTX * mem_ctx)3214 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3215 {
3216 	struct torture_rpc_tcase *tcase;
3217 	struct torture_suite *suite = torture_suite_create(mem_ctx, "winreg");
3218 	struct torture_test *test;
3219 
3220 	tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3221 						  &ndr_table_winreg);
3222 
3223 	test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3224 					  test_InitiateSystemShutdown);
3225 	test->dangerous = true;
3226 
3227 	test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3228 					  test_InitiateSystemShutdownEx);
3229 	test->dangerous = true;
3230 
3231 	torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3232 				      test_Open,
3233 				      (void *)dcerpc_winreg_OpenHKLM_r);
3234 	torture_rpc_tcase_add_test_ex(tcase, "HKU",
3235 				      test_Open,
3236 				      (void *)dcerpc_winreg_OpenHKU_r);
3237 	torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3238 				      test_Open,
3239 				      (void *)dcerpc_winreg_OpenHKCR_r);
3240 	torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3241 				      test_Open,
3242 				      (void *)dcerpc_winreg_OpenHKCU_r);
3243 
3244 	return suite;
3245 }
3246