1 /*
2    Unix SMB/CIFS implementation.
3 
4    test security descriptor operations
5 
6    Copyright (C) Andrew Tridgell 2004
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "libcli/libcli.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "libcli/util/clilsa.h"
28 #include "libcli/security/security.h"
29 #include "torture/util.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "torture/raw/proto.h"
32 
33 #define BASEDIR "\\testsd"
34 
35 #define CHECK_STATUS(status, correct) do { \
36 	if (!NT_STATUS_EQUAL(status, correct)) { \
37 		ret = false; \
38 		torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
39 		       __location__, nt_errstr(status), nt_errstr(correct)); \
40 		goto done; \
41 	}} while (0)
42 
43 #define FAIL_UNLESS(__cond)					\
44 	do {							\
45 		if (__cond) {} else {				\
46 			ret = false; \
47 			torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n", \
48 			    __location__, #__cond); \
49 			goto done; \
50 		}						\
51 	} while(0)
52 
53 #define CHECK_SECURITY_DESCRIPTOR(_sd1, _sd2) do { \
54 	if (!security_descriptor_equal(_sd1, _sd2)) { \
55 		torture_warning(tctx, "%s: security descriptors don't match!\n", __location__); \
56 		torture_warning(tctx, "got:\n"); \
57 		NDR_PRINT_DEBUG(security_descriptor, _sd1); \
58 		torture_warning(tctx, "expected:\n"); \
59 		NDR_PRINT_DEBUG(security_descriptor, _sd2); \
60 		ret = false; \
61 	} \
62 } while (0)
63 
64 /*
65  * Helper function to verify a security descriptor, by querying
66  * and comparing against the passed in sd.
67  * Copied to smb2_util_verify_sd() for SMB2.
68  */
verify_sd(TALLOC_CTX * tctx,struct smbcli_state * cli,int fnum,struct security_descriptor * sd)69 static bool verify_sd(TALLOC_CTX *tctx, struct smbcli_state *cli,
70     int fnum, struct security_descriptor *sd)
71 {
72 	NTSTATUS status;
73 	bool ret = true;
74 	union smb_fileinfo q = {};
75 
76 	if (sd) {
77 		q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
78 		q.query_secdesc.in.file.fnum = fnum;
79 		q.query_secdesc.in.secinfo_flags =
80 		    SECINFO_OWNER |
81 		    SECINFO_GROUP |
82 		    SECINFO_DACL;
83 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
84 		CHECK_STATUS(status, NT_STATUS_OK);
85 
86 		/* More work is needed if we're going to check this bit. */
87 		sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
88 
89 		CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
90 	}
91 
92  done:
93 	return ret;
94 }
95 
96 /*
97  * Helper function to verify attributes, by querying
98  * and comparing against the passed attrib.
99  * Copied to smb2_util_verify_attrib() for SMB2.
100  */
verify_attrib(TALLOC_CTX * tctx,struct smbcli_state * cli,int fnum,uint32_t attrib)101 static bool verify_attrib(TALLOC_CTX *tctx, struct smbcli_state *cli,
102     int fnum, uint32_t attrib)
103 {
104 	NTSTATUS status;
105 	bool ret = true;
106 	union smb_fileinfo q2 = {};
107 
108 	if (attrib) {
109 		q2.standard.level = RAW_FILEINFO_STANDARD;
110 		q2.standard.in.file.fnum = fnum;
111 		status = smb_raw_fileinfo(cli->tree, tctx, &q2);
112 		CHECK_STATUS(status, NT_STATUS_OK);
113 
114 		q2.standard.out.attrib &= ~FILE_ATTRIBUTE_ARCHIVE;
115 
116 		if (q2.standard.out.attrib != attrib) {
117 			torture_warning(tctx, "%s: attributes don't match! "
118 			    "got %x, expected %x\n", __location__,
119 			    (uint32_t)q2.standard.out.attrib,
120 			    (uint32_t)attrib);
121 			ret = false;
122 		}
123 	}
124 
125  done:
126 	return ret;
127 }
128 
129 /**
130  * Test setting and removing a DACL.
131  * Test copied to torture_smb2_setinfo() for SMB2.
132  */
test_sd(struct torture_context * tctx,struct smbcli_state * cli)133 static bool test_sd(struct torture_context *tctx, struct smbcli_state *cli)
134 {
135 	NTSTATUS status;
136 	union smb_open io;
137 	const char *fname = BASEDIR "\\sd.txt";
138 	bool ret = true;
139 	int fnum = -1;
140 	union smb_fileinfo q;
141 	union smb_setfileinfo set;
142 	struct security_ace ace;
143 	struct security_descriptor *sd;
144 	struct dom_sid *test_sid;
145 
146 	if (!torture_setup_dir(cli, BASEDIR))
147 		return false;
148 
149 	torture_comment(tctx, "TESTING SETFILEINFO EA_SET\n");
150 
151 	io.generic.level = RAW_OPEN_NTCREATEX;
152 	io.ntcreatex.in.root_fid.fnum = 0;
153 	io.ntcreatex.in.flags = 0;
154 	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
155 	io.ntcreatex.in.create_options = 0;
156 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
157 	io.ntcreatex.in.share_access =
158 		NTCREATEX_SHARE_ACCESS_READ |
159 		NTCREATEX_SHARE_ACCESS_WRITE;
160 	io.ntcreatex.in.alloc_size = 0;
161 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
162 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
163 	io.ntcreatex.in.security_flags = 0;
164 	io.ntcreatex.in.fname = fname;
165 	status = smb_raw_open(cli->tree, tctx, &io);
166 	CHECK_STATUS(status, NT_STATUS_OK);
167 	fnum = io.ntcreatex.out.file.fnum;
168 
169 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
170 	q.query_secdesc.in.file.fnum = fnum;
171 	q.query_secdesc.in.secinfo_flags =
172 		SECINFO_OWNER |
173 		SECINFO_GROUP |
174 		SECINFO_DACL;
175 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
176 	CHECK_STATUS(status, NT_STATUS_OK);
177 	sd = q.query_secdesc.out.sd;
178 
179 	torture_comment(tctx, "add a new ACE to the DACL\n");
180 
181 	test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
182 
183 	ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
184 	ace.flags = 0;
185 	ace.access_mask = SEC_STD_ALL;
186 	ace.trustee = *test_sid;
187 
188 	status = security_descriptor_dacl_add(sd, &ace);
189 	CHECK_STATUS(status, NT_STATUS_OK);
190 
191 	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
192 	set.set_secdesc.in.file.fnum = fnum;
193 	set.set_secdesc.in.secinfo_flags = q.query_secdesc.in.secinfo_flags;
194 	set.set_secdesc.in.sd = sd;
195 
196 	status = smb_raw_setfileinfo(cli->tree, &set);
197 	CHECK_STATUS(status, NT_STATUS_OK);
198 	FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
199 
200 	torture_comment(tctx, "remove it again\n");
201 
202 	status = security_descriptor_dacl_del(sd, test_sid);
203 	CHECK_STATUS(status, NT_STATUS_OK);
204 
205 	status = smb_raw_setfileinfo(cli->tree, &set);
206 	CHECK_STATUS(status, NT_STATUS_OK);
207 	FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
208 
209 done:
210 	smbcli_close(cli->tree, fnum);
211 	smb_raw_exit(cli->session);
212 	smbcli_deltree(cli->tree, BASEDIR);
213 
214 	return ret;
215 }
216 
217 
218 /*
219   test using nttrans create to create a file with an initial acl set
220   Test copied to test_create_acl() for SMB2.
221 */
test_nttrans_create_ext(struct torture_context * tctx,struct smbcli_state * cli,bool test_dir)222 static bool test_nttrans_create_ext(struct torture_context *tctx,
223 				    struct smbcli_state *cli, bool test_dir)
224 {
225 	NTSTATUS status;
226 	union smb_open io;
227 	const char *fname = BASEDIR "\\acl2.txt";
228 	bool ret = true;
229 	int fnum = -1;
230 	union smb_fileinfo q = {};
231 	struct security_ace ace;
232 	struct security_descriptor *sd;
233 	struct dom_sid *test_sid;
234 	uint32_t attrib =
235 	    FILE_ATTRIBUTE_HIDDEN |
236 	    FILE_ATTRIBUTE_SYSTEM |
237 	    (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
238 	NTSTATUS (*delete_func)(struct smbcli_tree *, const char *) =
239 	    test_dir ? smbcli_rmdir : smbcli_unlink;
240 
241 	ZERO_STRUCT(ace);
242 
243 	if (!torture_setup_dir(cli, BASEDIR))
244 		return false;
245 
246 	io.generic.level = RAW_OPEN_NTTRANS_CREATE;
247 	io.ntcreatex.in.root_fid.fnum = 0;
248 	io.ntcreatex.in.flags = 0;
249 	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
250 	io.ntcreatex.in.create_options =
251 	    test_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
252 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
253 	io.ntcreatex.in.share_access =
254 		NTCREATEX_SHARE_ACCESS_READ |
255 		NTCREATEX_SHARE_ACCESS_WRITE;
256 	io.ntcreatex.in.alloc_size = 0;
257 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
258 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
259 	io.ntcreatex.in.security_flags = 0;
260 	io.ntcreatex.in.fname = fname;
261 	io.ntcreatex.in.sec_desc = NULL;
262 	io.ntcreatex.in.ea_list = NULL;
263 
264 	torture_comment(tctx, "basic create\n");
265 
266 	status = smb_raw_open(cli->tree, tctx, &io);
267 	CHECK_STATUS(status, NT_STATUS_OK);
268 	fnum = io.ntcreatex.out.file.fnum;
269 
270 	torture_comment(tctx, "querying ACL\n");
271 
272 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
273 	q.query_secdesc.in.file.fnum = fnum;
274 	q.query_secdesc.in.secinfo_flags =
275 		SECINFO_OWNER |
276 		SECINFO_GROUP |
277 		SECINFO_DACL;
278 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
279 	CHECK_STATUS(status, NT_STATUS_OK);
280 	sd = q.query_secdesc.out.sd;
281 
282 	status = smbcli_close(cli->tree, fnum);
283 	CHECK_STATUS(status, NT_STATUS_OK);
284 
285 	status = delete_func(cli->tree, fname);
286 	CHECK_STATUS(status, NT_STATUS_OK);
287 
288 	torture_comment(tctx, "adding a new ACE\n");
289 	test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
290 
291 	ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
292 	ace.flags = 0;
293 	ace.access_mask = SEC_STD_ALL;
294 	ace.trustee = *test_sid;
295 
296 	status = security_descriptor_dacl_add(sd, &ace);
297 	CHECK_STATUS(status, NT_STATUS_OK);
298 
299 	torture_comment(tctx, "creating with an initial ACL\n");
300 
301 	io.ntcreatex.in.sec_desc = sd;
302 	status = smb_raw_open(cli->tree, tctx, &io);
303 	CHECK_STATUS(status, NT_STATUS_OK);
304 	fnum = io.ntcreatex.out.file.fnum;
305 
306 	FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
307 
308 	status = smbcli_close(cli->tree, fnum);
309 	CHECK_STATUS(status, NT_STATUS_OK);
310 	status = delete_func(cli->tree, fname);
311 	CHECK_STATUS(status, NT_STATUS_OK);
312 
313 	torture_comment(tctx, "creating with attributes\n");
314 
315 	io.ntcreatex.in.sec_desc = NULL;
316 	io.ntcreatex.in.file_attr = attrib;
317 	status = smb_raw_open(cli->tree, tctx, &io);
318 	CHECK_STATUS(status, NT_STATUS_OK);
319 	fnum = io.ntcreatex.out.file.fnum;
320 
321 	FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
322 
323 	status = smbcli_close(cli->tree, fnum);
324 	CHECK_STATUS(status, NT_STATUS_OK);
325 
326 	status = delete_func(cli->tree, fname);
327 	CHECK_STATUS(status, NT_STATUS_OK);
328 
329 	torture_comment(tctx, "creating with attributes and ACL\n");
330 
331 	io.ntcreatex.in.sec_desc = sd;
332 	io.ntcreatex.in.file_attr = attrib;
333 	status = smb_raw_open(cli->tree, tctx, &io);
334 	CHECK_STATUS(status, NT_STATUS_OK);
335 	fnum = io.ntcreatex.out.file.fnum;
336 
337 	FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
338 	FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
339 
340 	status = smbcli_close(cli->tree, fnum);
341 	CHECK_STATUS(status, NT_STATUS_OK);
342 	status = delete_func(cli->tree, fname);
343 	CHECK_STATUS(status, NT_STATUS_OK);
344 
345  done:
346 	smbcli_close(cli->tree, fnum);
347 	smb_raw_exit(cli->session);
348 	smbcli_deltree(cli->tree, BASEDIR);
349 	return ret;
350 }
351 
352 /*
353   test using nttrans create to create a file and directory with an initial acl
354   and owner.
355 */
test_nttrans_create_ext_owner(struct torture_context * tctx,struct smbcli_state * cli,bool test_dir)356 static bool test_nttrans_create_ext_owner(
357 	struct torture_context *tctx,
358 	struct smbcli_state *cli, bool test_dir)
359 {
360 	NTSTATUS status;
361 	union smb_open io;
362 	const char *fname = BASEDIR "\\foo.txt";
363 	bool ret = true;
364 	int fnum = -1;
365 	struct security_ace ace;
366 	struct security_descriptor *sd;
367 	uint32_t attrib =
368 	    FILE_ATTRIBUTE_HIDDEN |
369 	    FILE_ATTRIBUTE_SYSTEM |
370 	    (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
371 	NTSTATUS (*delete_func)(struct smbcli_tree *, const char *) =
372 	    test_dir ? smbcli_rmdir : smbcli_unlink;
373 
374 	ZERO_STRUCT(ace);
375 
376 	smbcli_deltree(cli->tree, BASEDIR);
377 
378 	if (!torture_setup_dir(cli, BASEDIR))
379 		return false;
380 
381 	io.generic.level = RAW_OPEN_NTTRANS_CREATE;
382 	io.ntcreatex.in.root_fid.fnum = 0;
383 	io.ntcreatex.in.flags = 0;
384 	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
385 	io.ntcreatex.in.create_options =
386 	    test_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
387 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
388 	io.ntcreatex.in.share_access =
389 		NTCREATEX_SHARE_ACCESS_READ |
390 		NTCREATEX_SHARE_ACCESS_WRITE;
391 	io.ntcreatex.in.alloc_size = 0;
392 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
393 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
394 	io.ntcreatex.in.security_flags = 0;
395 	io.ntcreatex.in.fname = fname;
396 	io.ntcreatex.in.sec_desc = NULL;
397 	io.ntcreatex.in.ea_list = NULL;
398 
399 	torture_comment(tctx, "creating with attributes, ACL and owner\n");
400 
401 	sd = security_descriptor_dacl_create(tctx,
402 					0, SID_WORLD, SID_BUILTIN_USERS,
403 					SID_WORLD,
404 					SEC_ACE_TYPE_ACCESS_ALLOWED,
405 					SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
406 					0,
407 					NULL);
408 
409 	io.ntcreatex.in.sec_desc = sd;
410 	io.ntcreatex.in.file_attr = attrib;
411 	status = smb_raw_open(cli->tree, tctx, &io);
412 	CHECK_STATUS(status, NT_STATUS_OK);
413 	fnum = io.ntcreatex.out.file.fnum;
414 
415 	FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
416 	FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
417 
418 	status = smbcli_close(cli->tree, fnum);
419 	CHECK_STATUS(status, NT_STATUS_OK);
420 	status = delete_func(cli->tree, fname);
421 	CHECK_STATUS(status, NT_STATUS_OK);
422 
423  done:
424 	smbcli_close(cli->tree, fnum);
425 	smb_raw_exit(cli->session);
426 	smbcli_deltree(cli->tree, BASEDIR);
427 	return ret;
428 }
429 
test_nttrans_create_file(struct torture_context * tctx,struct smbcli_state * cli)430 static bool test_nttrans_create_file(struct torture_context *tctx,
431     struct smbcli_state *cli)
432 {
433 	torture_comment(tctx, "Testing nttrans create with sec_desc on files\n");
434 
435 	return test_nttrans_create_ext(tctx, cli, false);
436 }
437 
test_nttrans_create_dir(struct torture_context * tctx,struct smbcli_state * cli)438 static bool test_nttrans_create_dir(struct torture_context *tctx,
439     struct smbcli_state *cli)
440 {
441 	torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n");
442 
443 	return test_nttrans_create_ext(tctx, cli, true);
444 }
445 
test_nttrans_create_owner_file(struct torture_context * tctx,struct smbcli_state * cli)446 static bool test_nttrans_create_owner_file(struct torture_context *tctx,
447     struct smbcli_state *cli)
448 {
449 	torture_comment(tctx, "Testing nttrans create with sec_desc with owner on file\n");
450 
451 	return test_nttrans_create_ext_owner(tctx, cli, false);
452 }
453 
test_nttrans_create_owner_dir(struct torture_context * tctx,struct smbcli_state * cli)454 static bool test_nttrans_create_owner_dir(struct torture_context *tctx,
455     struct smbcli_state *cli)
456 {
457 	torture_comment(tctx, "Testing nttrans create with sec_desc with owner on directory\n");
458 
459 	return test_nttrans_create_ext_owner(tctx, cli, true);
460 }
461 
462 #define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
463 	union smb_fileinfo _q; \
464 	_q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
465 	_q.access_information.in.file.fnum = (_fnum); \
466 	status = smb_raw_fileinfo(cli->tree, tctx, &_q); \
467 	CHECK_STATUS(status, NT_STATUS_OK); \
468 	if (_q.access_information.out.access_flags != (flags)) { \
469 		ret = false; \
470 		torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
471 		       __location__, _q.access_information.out.access_flags, (flags)); \
472 		goto done; \
473 	} \
474 } while (0)
475 
476 /*
477   test using NTTRANS CREATE to create a file with a null ACL set
478   Test copied to test_create_null_dacl() for SMB2.
479 */
test_nttrans_create_null_dacl(struct torture_context * tctx,struct smbcli_state * cli)480 static bool test_nttrans_create_null_dacl(struct torture_context *tctx,
481 					  struct smbcli_state *cli)
482 {
483 	NTSTATUS status;
484 	union smb_open io;
485 	const char *fname = BASEDIR "\\nulldacl.txt";
486 	bool ret = true;
487 	int fnum = -1;
488 	union smb_fileinfo q;
489 	union smb_setfileinfo s;
490 	struct security_descriptor *sd = security_descriptor_initialise(tctx);
491 	struct security_acl dacl;
492 
493 	if (!torture_setup_dir(cli, BASEDIR))
494 		return false;
495 
496 	torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");
497 
498 	io.generic.level = RAW_OPEN_NTTRANS_CREATE;
499 	io.ntcreatex.in.root_fid.fnum = 0;
500 	io.ntcreatex.in.flags = 0;
501 	io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
502 		| SEC_STD_WRITE_OWNER;
503 	io.ntcreatex.in.create_options = 0;
504 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
505 	io.ntcreatex.in.share_access =
506 		NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
507 	io.ntcreatex.in.alloc_size = 0;
508 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
509 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
510 	io.ntcreatex.in.security_flags = 0;
511 	io.ntcreatex.in.fname = fname;
512 	io.ntcreatex.in.sec_desc = sd;
513 	io.ntcreatex.in.ea_list = NULL;
514 
515 	torture_comment(tctx, "creating a file with a empty sd\n");
516 	status = smb_raw_open(cli->tree, tctx, &io);
517 	CHECK_STATUS(status, NT_STATUS_OK);
518 	fnum = io.ntcreatex.out.file.fnum;
519 
520 	torture_comment(tctx, "get the original sd\n");
521 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
522 	q.query_secdesc.in.file.fnum = fnum;
523 	q.query_secdesc.in.secinfo_flags =
524 		SECINFO_OWNER |
525 		SECINFO_GROUP |
526 		SECINFO_DACL;
527 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
528 	CHECK_STATUS(status, NT_STATUS_OK);
529 
530 	/*
531 	 * Testing the created DACL,
532 	 * the server should add the inherited DACL
533 	 * when SEC_DESC_DACL_PRESENT isn't specified
534 	 */
535 	if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
536 		ret = false;
537 		torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
538 		goto done;
539 	}
540 	if (q.query_secdesc.out.sd->dacl == NULL) {
541 		ret = false;
542 		torture_result(tctx, TORTURE_FAIL, "no DACL has been created on the server!\n");
543 		goto done;
544 	}
545 
546 	torture_comment(tctx, "set NULL DACL\n");
547 	sd->type |= SEC_DESC_DACL_PRESENT;
548 
549 	s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
550 	s.set_secdesc.in.file.fnum = fnum;
551 	s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
552 	s.set_secdesc.in.sd = sd;
553 	status = smb_raw_setfileinfo(cli->tree, &s);
554 	CHECK_STATUS(status, NT_STATUS_OK);
555 
556 	torture_comment(tctx, "get the sd\n");
557 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
558 	q.query_secdesc.in.file.fnum = fnum;
559 	q.query_secdesc.in.secinfo_flags =
560 		SECINFO_OWNER |
561 		SECINFO_GROUP |
562 		SECINFO_DACL;
563 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
564 	CHECK_STATUS(status, NT_STATUS_OK);
565 
566 	/* Testing the modified DACL */
567 	if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
568 		ret = false;
569 		torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
570 		goto done;
571 	}
572 	if (q.query_secdesc.out.sd->dacl != NULL) {
573 		ret = false;
574 		torture_result(tctx, TORTURE_FAIL, "DACL has been created on the server!\n");
575 		goto done;
576 	}
577 
578 	torture_comment(tctx, "try open for read control\n");
579 	io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
580 	status = smb_raw_open(cli->tree, tctx, &io);
581 	CHECK_STATUS(status, NT_STATUS_OK);
582 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
583 		SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
584 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
585 
586 	torture_comment(tctx, "try open for write\n");
587 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
588 	status = smb_raw_open(cli->tree, tctx, &io);
589 	CHECK_STATUS(status, NT_STATUS_OK);
590 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
591 		SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
592 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
593 
594 	torture_comment(tctx, "try open for read\n");
595 	io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
596 	status = smb_raw_open(cli->tree, tctx, &io);
597 	CHECK_STATUS(status, NT_STATUS_OK);
598 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
599 		SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE);
600 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
601 
602 	torture_comment(tctx, "try open for generic write\n");
603 	io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
604 	status = smb_raw_open(cli->tree, tctx, &io);
605 	CHECK_STATUS(status, NT_STATUS_OK);
606 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
607 		SEC_RIGHTS_FILE_WRITE | SEC_FILE_READ_ATTRIBUTE);
608 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
609 
610 	torture_comment(tctx, "try open for generic read\n");
611 	io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
612 	status = smb_raw_open(cli->tree, tctx, &io);
613 	CHECK_STATUS(status, NT_STATUS_OK);
614 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
615 		SEC_RIGHTS_FILE_READ | SEC_FILE_READ_ATTRIBUTE);
616 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
617 
618 	torture_comment(tctx, "set DACL with 0 aces\n");
619 	ZERO_STRUCT(dacl);
620 	dacl.revision = SECURITY_ACL_REVISION_NT4;
621 	dacl.num_aces = 0;
622 	sd->dacl = &dacl;
623 
624 	s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
625 	s.set_secdesc.in.file.fnum = fnum;
626 	s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
627 	s.set_secdesc.in.sd = sd;
628 	status = smb_raw_setfileinfo(cli->tree, &s);
629 	CHECK_STATUS(status, NT_STATUS_OK);
630 
631 	torture_comment(tctx, "get the sd\n");
632 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
633 	q.query_secdesc.in.file.fnum = fnum;
634 	q.query_secdesc.in.secinfo_flags =
635 		SECINFO_OWNER |
636 		SECINFO_GROUP |
637 		SECINFO_DACL;
638 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
639 	CHECK_STATUS(status, NT_STATUS_OK);
640 
641 	/* Testing the modified DACL */
642 	if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
643 		ret = false;
644 		torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
645 		goto done;
646 	}
647 	if (q.query_secdesc.out.sd->dacl == NULL) {
648 		ret = false;
649 		torture_result(tctx, TORTURE_FAIL, "no DACL has been created on the server!\n");
650 		goto done;
651 	}
652 	if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
653 		ret = false;
654 		torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
655 		       q.query_secdesc.out.sd->dacl->num_aces);
656 		goto done;
657 	}
658 
659 	torture_comment(tctx, "try open for read control\n");
660 	io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
661 	status = smb_raw_open(cli->tree, tctx, &io);
662 	CHECK_STATUS(status, NT_STATUS_OK);
663 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
664 		SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
665 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
666 
667 	torture_comment(tctx, "try open for write => access_denied\n");
668 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
669 	status = smb_raw_open(cli->tree, tctx, &io);
670 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
671 
672 	torture_comment(tctx, "try open for read => access_denied\n");
673 	io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
674 	status = smb_raw_open(cli->tree, tctx, &io);
675 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
676 
677 	torture_comment(tctx, "try open for generic write => access_denied\n");
678 	io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
679 	status = smb_raw_open(cli->tree, tctx, &io);
680 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
681 
682 	torture_comment(tctx, "try open for generic read => access_denied\n");
683 	io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
684 	status = smb_raw_open(cli->tree, tctx, &io);
685 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
686 
687 	torture_comment(tctx, "set empty sd\n");
688 	sd->type &= ~SEC_DESC_DACL_PRESENT;
689 	sd->dacl = NULL;
690 
691 	s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
692 	s.set_secdesc.in.file.fnum = fnum;
693 	s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
694 	s.set_secdesc.in.sd = sd;
695 	status = smb_raw_setfileinfo(cli->tree, &s);
696 	CHECK_STATUS(status, NT_STATUS_OK);
697 
698 	torture_comment(tctx, "get the sd\n");
699 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
700 	q.query_secdesc.in.file.fnum = fnum;
701 	q.query_secdesc.in.secinfo_flags =
702 		SECINFO_OWNER |
703 		SECINFO_GROUP |
704 		SECINFO_DACL;
705 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
706 	CHECK_STATUS(status, NT_STATUS_OK);
707 
708 	/* Testing the modified DACL */
709 	if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
710 		ret = false;
711 		torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
712 		goto done;
713 	}
714 	if (q.query_secdesc.out.sd->dacl != NULL) {
715 		ret = false;
716 		torture_result(tctx, TORTURE_FAIL, "DACL has been created on the server!\n");
717 		goto done;
718 	}
719 done:
720 	smbcli_close(cli->tree, fnum);
721 	smb_raw_exit(cli->session);
722 	smbcli_deltree(cli->tree, BASEDIR);
723 	return ret;
724 }
725 
726 /*
727   test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
728   mapping bits
729   Test copied to smb2/acls.c for SMB2.
730 */
test_creator_sid(struct torture_context * tctx,struct smbcli_state * cli)731 static bool test_creator_sid(struct torture_context *tctx,
732 							 struct smbcli_state *cli)
733 {
734 	NTSTATUS status;
735 	union smb_open io;
736 	const char *fname = BASEDIR "\\creator.txt";
737 	bool ret = true;
738 	int fnum = -1;
739 	union smb_fileinfo q;
740 	union smb_setfileinfo set;
741 	struct security_descriptor *sd, *sd_orig, *sd2;
742 	const char *owner_sid;
743 
744 	if (!torture_setup_dir(cli, BASEDIR))
745 		return false;
746 
747 	torture_comment(tctx, "TESTING SID_CREATOR_OWNER\n");
748 
749 	io.generic.level = RAW_OPEN_NTCREATEX;
750 	io.ntcreatex.in.root_fid.fnum = 0;
751 	io.ntcreatex.in.flags = 0;
752 	io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
753 	io.ntcreatex.in.create_options = 0;
754 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
755 	io.ntcreatex.in.share_access =
756 		NTCREATEX_SHARE_ACCESS_READ |
757 		NTCREATEX_SHARE_ACCESS_WRITE;
758 	io.ntcreatex.in.alloc_size = 0;
759 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
760 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
761 	io.ntcreatex.in.security_flags = 0;
762 	io.ntcreatex.in.fname = fname;
763 	status = smb_raw_open(cli->tree, tctx, &io);
764 	CHECK_STATUS(status, NT_STATUS_OK);
765 	fnum = io.ntcreatex.out.file.fnum;
766 
767 	torture_comment(tctx, "get the original sd\n");
768 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
769 	q.query_secdesc.in.file.fnum = fnum;
770 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
771 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
772 	CHECK_STATUS(status, NT_STATUS_OK);
773 	sd_orig = q.query_secdesc.out.sd;
774 
775 	owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
776 
777 	torture_comment(tctx, "set a sec desc allowing no write by CREATOR_OWNER\n");
778 	sd = security_descriptor_dacl_create(tctx,
779 					0, NULL, NULL,
780 					SID_CREATOR_OWNER,
781 					SEC_ACE_TYPE_ACCESS_ALLOWED,
782 					SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
783 					0,
784 					NULL);
785 
786 	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
787 	set.set_secdesc.in.file.fnum = fnum;
788 	set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
789 	set.set_secdesc.in.sd = sd;
790 
791 	status = smb_raw_setfileinfo(cli->tree, &set);
792 	CHECK_STATUS(status, NT_STATUS_OK);
793 
794 	torture_comment(tctx, "try open for write\n");
795 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
796 	status = smb_raw_open(cli->tree, tctx, &io);
797 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
798 
799 	torture_comment(tctx, "try open for read\n");
800 	io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
801 	status = smb_raw_open(cli->tree, tctx, &io);
802 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
803 
804 	torture_comment(tctx, "try open for generic write\n");
805 	io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
806 	status = smb_raw_open(cli->tree, tctx, &io);
807 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
808 
809 	torture_comment(tctx, "try open for generic read\n");
810 	io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
811 	status = smb_raw_open(cli->tree, tctx, &io);
812 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
813 
814 	torture_comment(tctx, "set a sec desc allowing no write by owner\n");
815 	sd = security_descriptor_dacl_create(tctx,
816 					0, owner_sid, NULL,
817 					owner_sid,
818 					SEC_ACE_TYPE_ACCESS_ALLOWED,
819 					SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
820 					0,
821 					NULL);
822 
823 	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
824 	set.set_secdesc.in.file.fnum = fnum;
825 	set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
826 	set.set_secdesc.in.sd = sd;
827 	status = smb_raw_setfileinfo(cli->tree, &set);
828 	CHECK_STATUS(status, NT_STATUS_OK);
829 
830 	torture_comment(tctx, "check that sd has been mapped correctly\n");
831 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
832 	CHECK_STATUS(status, NT_STATUS_OK);
833 	CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
834 
835 	torture_comment(tctx, "try open for write\n");
836 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
837 	status = smb_raw_open(cli->tree, tctx, &io);
838 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
839 
840 	torture_comment(tctx, "try open for read\n");
841 	io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
842 	status = smb_raw_open(cli->tree, tctx, &io);
843 	CHECK_STATUS(status, NT_STATUS_OK);
844 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
845 			   SEC_FILE_READ_DATA|
846 			   SEC_FILE_READ_ATTRIBUTE);
847 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
848 
849 	torture_comment(tctx, "try open for generic write\n");
850 	io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
851 	status = smb_raw_open(cli->tree, tctx, &io);
852 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
853 
854 	torture_comment(tctx, "try open for generic read\n");
855 	io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
856 	status = smb_raw_open(cli->tree, tctx, &io);
857 	CHECK_STATUS(status, NT_STATUS_OK);
858 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
859 			   SEC_RIGHTS_FILE_READ);
860 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
861 
862 	torture_comment(tctx, "set a sec desc allowing generic read by owner\n");
863 	sd = security_descriptor_dacl_create(tctx,
864 					0, NULL, NULL,
865 					owner_sid,
866 					SEC_ACE_TYPE_ACCESS_ALLOWED,
867 					SEC_GENERIC_READ | SEC_STD_ALL,
868 					0,
869 					NULL);
870 
871 	set.set_secdesc.in.sd = sd;
872 	status = smb_raw_setfileinfo(cli->tree, &set);
873 	CHECK_STATUS(status, NT_STATUS_OK);
874 
875 	torture_comment(tctx, "check that generic read has been mapped correctly\n");
876 	sd2 = security_descriptor_dacl_create(tctx,
877 					 0, owner_sid, NULL,
878 					 owner_sid,
879 					 SEC_ACE_TYPE_ACCESS_ALLOWED,
880 					 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
881 					 0,
882 					 NULL);
883 
884 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
885 	CHECK_STATUS(status, NT_STATUS_OK);
886 	CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
887 
888 	torture_comment(tctx, "try open for write\n");
889 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
890 	status = smb_raw_open(cli->tree, tctx, &io);
891 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
892 
893 	torture_comment(tctx, "try open for read\n");
894 	io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
895 	status = smb_raw_open(cli->tree, tctx, &io);
896 	CHECK_STATUS(status, NT_STATUS_OK);
897 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
898 			   SEC_FILE_READ_DATA |
899 			   SEC_FILE_READ_ATTRIBUTE);
900 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
901 
902 	torture_comment(tctx, "try open for generic write\n");
903 	io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
904 	status = smb_raw_open(cli->tree, tctx, &io);
905 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
906 
907 	torture_comment(tctx, "try open for generic read\n");
908 	io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
909 	status = smb_raw_open(cli->tree, tctx, &io);
910 	CHECK_STATUS(status, NT_STATUS_OK);
911 	CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, SEC_RIGHTS_FILE_READ);
912 	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
913 
914 
915 	torture_comment(tctx, "put back original sd\n");
916 	set.set_secdesc.in.sd = sd_orig;
917 	status = smb_raw_setfileinfo(cli->tree, &set);
918 	CHECK_STATUS(status, NT_STATUS_OK);
919 
920 
921 done:
922 	smbcli_close(cli->tree, fnum);
923 	smb_raw_exit(cli->session);
924 	smbcli_deltree(cli->tree, BASEDIR);
925 	return ret;
926 }
927 
928 
929 /*
930   test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
931   SEC_FILE_xx bits
932   Test copied to smb2/acls.c for SMB2.
933 */
test_generic_bits(struct torture_context * tctx,struct smbcli_state * cli)934 static bool test_generic_bits(struct torture_context *tctx,
935 							  struct smbcli_state *cli)
936 {
937 	NTSTATUS status;
938 	union smb_open io;
939 	const char *fname = BASEDIR "\\generic.txt";
940 	bool ret = true;
941 	int fnum = -1, i;
942 	union smb_fileinfo q;
943 	union smb_setfileinfo set;
944 	struct security_descriptor *sd, *sd_orig, *sd2;
945 	const char *owner_sid;
946 	const struct {
947 		uint32_t gen_bits;
948 		uint32_t specific_bits;
949 	} file_mappings[] = {
950 		{ 0,                       0 },
951 		{ SEC_GENERIC_READ,        SEC_RIGHTS_FILE_READ },
952 		{ SEC_GENERIC_WRITE,       SEC_RIGHTS_FILE_WRITE },
953 		{ SEC_GENERIC_EXECUTE,     SEC_RIGHTS_FILE_EXECUTE },
954 		{ SEC_GENERIC_ALL,         SEC_RIGHTS_FILE_ALL },
955 		{ SEC_FILE_READ_DATA,      SEC_FILE_READ_DATA },
956 		{ SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
957 	};
958 	const struct {
959 		uint32_t gen_bits;
960 		uint32_t specific_bits;
961 	} dir_mappings[] = {
962 		{ 0,                   0 },
963 		{ SEC_GENERIC_READ,    SEC_RIGHTS_DIR_READ },
964 		{ SEC_GENERIC_WRITE,   SEC_RIGHTS_DIR_WRITE },
965 		{ SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
966 		{ SEC_GENERIC_ALL,     SEC_RIGHTS_DIR_ALL }
967 	};
968 	bool has_restore_privilege;
969 	bool has_take_ownership_privilege;
970 
971 	if (!torture_setup_dir(cli, BASEDIR))
972 		return false;
973 
974 	torture_comment(tctx, "TESTING FILE GENERIC BITS\n");
975 
976 	io.generic.level = RAW_OPEN_NTCREATEX;
977 	io.ntcreatex.in.root_fid.fnum = 0;
978 	io.ntcreatex.in.flags = 0;
979 	io.ntcreatex.in.access_mask =
980 		SEC_STD_READ_CONTROL |
981 		SEC_STD_WRITE_DAC |
982 		SEC_STD_WRITE_OWNER;
983 	io.ntcreatex.in.create_options = 0;
984 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
985 	io.ntcreatex.in.share_access =
986 		NTCREATEX_SHARE_ACCESS_READ |
987 		NTCREATEX_SHARE_ACCESS_WRITE;
988 	io.ntcreatex.in.alloc_size = 0;
989 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
990 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
991 	io.ntcreatex.in.security_flags = 0;
992 	io.ntcreatex.in.fname = fname;
993 	status = smb_raw_open(cli->tree, tctx, &io);
994 	CHECK_STATUS(status, NT_STATUS_OK);
995 	fnum = io.ntcreatex.out.file.fnum;
996 
997 	torture_comment(tctx, "get the original sd\n");
998 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
999 	q.query_secdesc.in.file.fnum = fnum;
1000 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1001 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
1002 	CHECK_STATUS(status, NT_STATUS_OK);
1003 	sd_orig = q.query_secdesc.out.sd;
1004 
1005 	owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1006 
1007 	status = torture_check_privilege(cli,
1008 					    owner_sid,
1009 					    sec_privilege_name(SEC_PRIV_RESTORE));
1010 	has_restore_privilege = NT_STATUS_IS_OK(status);
1011 	if (!NT_STATUS_IS_OK(status)) {
1012 		torture_warning(tctx, "torture_check_privilege - %s\n",
1013 		    nt_errstr(status));
1014 	}
1015 	torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1016 
1017 	status = torture_check_privilege(cli,
1018 					    owner_sid,
1019 					    sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1020 	has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1021 	if (!NT_STATUS_IS_OK(status)) {
1022 		torture_warning(tctx, "torture_check_privilege - %s\n",
1023 		    nt_errstr(status));
1024 	}
1025 	torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1026 
1027 	for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
1028 		uint32_t expected_mask =
1029 			SEC_STD_WRITE_DAC |
1030 			SEC_STD_READ_CONTROL |
1031 			SEC_FILE_READ_ATTRIBUTE |
1032 			SEC_STD_DELETE;
1033 		uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
1034 
1035 		if (has_restore_privilege) {
1036 			expected_mask_anon |= SEC_STD_DELETE;
1037 		}
1038 
1039 		torture_comment(tctx, "Testing generic bits 0x%08x\n",
1040 		       file_mappings[i].gen_bits);
1041 		sd = security_descriptor_dacl_create(tctx,
1042 						0, owner_sid, NULL,
1043 						owner_sid,
1044 						SEC_ACE_TYPE_ACCESS_ALLOWED,
1045 						file_mappings[i].gen_bits,
1046 						0,
1047 						NULL);
1048 
1049 		set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1050 		set.set_secdesc.in.file.fnum = fnum;
1051 		set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1052 		set.set_secdesc.in.sd = sd;
1053 
1054 		status = smb_raw_setfileinfo(cli->tree, &set);
1055 		CHECK_STATUS(status, NT_STATUS_OK);
1056 
1057 		sd2 = security_descriptor_dacl_create(tctx,
1058 						 0, owner_sid, NULL,
1059 						 owner_sid,
1060 						 SEC_ACE_TYPE_ACCESS_ALLOWED,
1061 						 file_mappings[i].specific_bits,
1062 						 0,
1063 						 NULL);
1064 
1065 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
1066 		CHECK_STATUS(status, NT_STATUS_OK);
1067 		CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1068 
1069 		io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1070 		status = smb_raw_open(cli->tree, tctx, &io);
1071 		CHECK_STATUS(status, NT_STATUS_OK);
1072 		CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1073 				   expected_mask | file_mappings[i].specific_bits);
1074 		smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1075 
1076 		if (!has_take_ownership_privilege) {
1077 			continue;
1078 		}
1079 
1080 		torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
1081 		       file_mappings[i].gen_bits);
1082 		sd = security_descriptor_dacl_create(tctx,
1083 						0, SID_NT_ANONYMOUS, NULL,
1084 						owner_sid,
1085 						SEC_ACE_TYPE_ACCESS_ALLOWED,
1086 						file_mappings[i].gen_bits,
1087 						0,
1088 						NULL);
1089 
1090 		set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1091 		set.set_secdesc.in.file.fnum = fnum;
1092 		set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1093 		set.set_secdesc.in.sd = sd;
1094 
1095 		status = smb_raw_setfileinfo(cli->tree, &set);
1096 		CHECK_STATUS(status, NT_STATUS_OK);
1097 
1098 		sd2 = security_descriptor_dacl_create(tctx,
1099 						 0, SID_NT_ANONYMOUS, NULL,
1100 						 owner_sid,
1101 						 SEC_ACE_TYPE_ACCESS_ALLOWED,
1102 						 file_mappings[i].specific_bits,
1103 						 0,
1104 						 NULL);
1105 
1106 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
1107 		CHECK_STATUS(status, NT_STATUS_OK);
1108 		CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1109 
1110 		io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1111 		status = smb_raw_open(cli->tree, tctx, &io);
1112 		CHECK_STATUS(status, NT_STATUS_OK);
1113 		CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1114 				   expected_mask_anon | file_mappings[i].specific_bits);
1115 		smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1116 	}
1117 
1118 	torture_comment(tctx, "put back original sd\n");
1119 	set.set_secdesc.in.sd = sd_orig;
1120 	status = smb_raw_setfileinfo(cli->tree, &set);
1121 	CHECK_STATUS(status, NT_STATUS_OK);
1122 
1123 	smbcli_close(cli->tree, fnum);
1124 	smbcli_unlink(cli->tree, fname);
1125 
1126 
1127 	torture_comment(tctx, "TESTING DIR GENERIC BITS\n");
1128 
1129 	io.generic.level = RAW_OPEN_NTCREATEX;
1130 	io.ntcreatex.in.root_fid.fnum = 0;
1131 	io.ntcreatex.in.flags = 0;
1132 	io.ntcreatex.in.access_mask =
1133 		SEC_STD_READ_CONTROL |
1134 		SEC_STD_WRITE_DAC |
1135 		SEC_STD_WRITE_OWNER;
1136 	io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1137 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1138 	io.ntcreatex.in.share_access =
1139 		NTCREATEX_SHARE_ACCESS_READ |
1140 		NTCREATEX_SHARE_ACCESS_WRITE;
1141 	io.ntcreatex.in.alloc_size = 0;
1142 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1143 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1144 	io.ntcreatex.in.security_flags = 0;
1145 	io.ntcreatex.in.fname = fname;
1146 	status = smb_raw_open(cli->tree, tctx, &io);
1147 	CHECK_STATUS(status, NT_STATUS_OK);
1148 	fnum = io.ntcreatex.out.file.fnum;
1149 
1150 	torture_comment(tctx, "get the original sd\n");
1151 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1152 	q.query_secdesc.in.file.fnum = fnum;
1153 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1154 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
1155 	CHECK_STATUS(status, NT_STATUS_OK);
1156 	sd_orig = q.query_secdesc.out.sd;
1157 
1158 	owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1159 
1160 	status = torture_check_privilege(cli,
1161 					    owner_sid,
1162 					    sec_privilege_name(SEC_PRIV_RESTORE));
1163 	has_restore_privilege = NT_STATUS_IS_OK(status);
1164 	if (!NT_STATUS_IS_OK(status)) {
1165 		torture_warning(tctx, "torture_check_privilege - %s\n",
1166 		    nt_errstr(status));
1167 	}
1168 	torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1169 
1170 	status = torture_check_privilege(cli,
1171 					    owner_sid,
1172 					    sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1173 	has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1174 	if (!NT_STATUS_IS_OK(status)) {
1175 		torture_warning(tctx, "torture_check_privilege - %s\n",
1176 		    nt_errstr(status));
1177 	}
1178 	torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1179 
1180 	for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
1181 		uint32_t expected_mask =
1182 			SEC_STD_WRITE_DAC |
1183 			SEC_STD_READ_CONTROL |
1184 			SEC_FILE_READ_ATTRIBUTE |
1185 			SEC_STD_DELETE;
1186 		uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
1187 
1188 		if (has_restore_privilege) {
1189 			expected_mask_anon |= SEC_STD_DELETE;
1190 		}
1191 
1192 		torture_comment(tctx, "Testing generic bits 0x%08x\n",
1193 		       file_mappings[i].gen_bits);
1194 		sd = security_descriptor_dacl_create(tctx,
1195 						0, owner_sid, NULL,
1196 						owner_sid,
1197 						SEC_ACE_TYPE_ACCESS_ALLOWED,
1198 						dir_mappings[i].gen_bits,
1199 						0,
1200 						NULL);
1201 
1202 		set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1203 		set.set_secdesc.in.file.fnum = fnum;
1204 		set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1205 		set.set_secdesc.in.sd = sd;
1206 
1207 		status = smb_raw_setfileinfo(cli->tree, &set);
1208 		CHECK_STATUS(status, NT_STATUS_OK);
1209 
1210 		sd2 = security_descriptor_dacl_create(tctx,
1211 						 0, owner_sid, NULL,
1212 						 owner_sid,
1213 						 SEC_ACE_TYPE_ACCESS_ALLOWED,
1214 						 dir_mappings[i].specific_bits,
1215 						 0,
1216 						 NULL);
1217 
1218 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
1219 		CHECK_STATUS(status, NT_STATUS_OK);
1220 		CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1221 
1222 		io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1223 		status = smb_raw_open(cli->tree, tctx, &io);
1224 		CHECK_STATUS(status, NT_STATUS_OK);
1225 		CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1226 				   expected_mask | dir_mappings[i].specific_bits);
1227 		smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1228 
1229 		if (!has_take_ownership_privilege) {
1230 			continue;
1231 		}
1232 
1233 		torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
1234 		       file_mappings[i].gen_bits);
1235 		sd = security_descriptor_dacl_create(tctx,
1236 						0, SID_NT_ANONYMOUS, NULL,
1237 						owner_sid,
1238 						SEC_ACE_TYPE_ACCESS_ALLOWED,
1239 						file_mappings[i].gen_bits,
1240 						0,
1241 						NULL);
1242 
1243 		set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1244 		set.set_secdesc.in.file.fnum = fnum;
1245 		set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1246 		set.set_secdesc.in.sd = sd;
1247 
1248 		status = smb_raw_setfileinfo(cli->tree, &set);
1249 		CHECK_STATUS(status, NT_STATUS_OK);
1250 
1251 		sd2 = security_descriptor_dacl_create(tctx,
1252 						 0, SID_NT_ANONYMOUS, NULL,
1253 						 owner_sid,
1254 						 SEC_ACE_TYPE_ACCESS_ALLOWED,
1255 						 file_mappings[i].specific_bits,
1256 						 0,
1257 						 NULL);
1258 
1259 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
1260 		CHECK_STATUS(status, NT_STATUS_OK);
1261 		CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1262 
1263 		io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1264 		status = smb_raw_open(cli->tree, tctx, &io);
1265 		CHECK_STATUS(status, NT_STATUS_OK);
1266 		CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1267 				   expected_mask_anon | dir_mappings[i].specific_bits);
1268 		smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1269 	}
1270 
1271 	torture_comment(tctx, "put back original sd\n");
1272 	set.set_secdesc.in.sd = sd_orig;
1273 	status = smb_raw_setfileinfo(cli->tree, &set);
1274 	CHECK_STATUS(status, NT_STATUS_OK);
1275 
1276 	smbcli_close(cli->tree, fnum);
1277 	smbcli_unlink(cli->tree, fname);
1278 
1279 done:
1280 	smbcli_close(cli->tree, fnum);
1281 	smb_raw_exit(cli->session);
1282 	smbcli_deltree(cli->tree, BASEDIR);
1283 	return ret;
1284 }
1285 
1286 
1287 /*
1288   see what access bits the owner of a file always gets
1289   Test copied to smb2/acls.c for SMB2.
1290 */
test_owner_bits(struct torture_context * tctx,struct smbcli_state * cli)1291 static bool test_owner_bits(struct torture_context *tctx,
1292 							struct smbcli_state *cli)
1293 {
1294 	NTSTATUS status;
1295 	union smb_open io;
1296 	const char *fname = BASEDIR "\\test_owner_bits.txt";
1297 	bool ret = true;
1298 	int fnum = -1, i;
1299 	union smb_fileinfo q;
1300 	union smb_setfileinfo set;
1301 	struct security_descriptor *sd, *sd_orig;
1302 	const char *owner_sid;
1303 	bool has_restore_privilege;
1304 	bool has_take_ownership_privilege;
1305 	uint32_t expected_bits;
1306 
1307 	if (!torture_setup_dir(cli, BASEDIR))
1308 		return false;
1309 
1310 	torture_comment(tctx, "TESTING FILE OWNER BITS\n");
1311 
1312 	io.generic.level = RAW_OPEN_NTCREATEX;
1313 	io.ntcreatex.in.root_fid.fnum = 0;
1314 	io.ntcreatex.in.flags = 0;
1315 	io.ntcreatex.in.access_mask =
1316 		SEC_STD_READ_CONTROL |
1317 		SEC_STD_WRITE_DAC |
1318 		SEC_STD_WRITE_OWNER;
1319 	io.ntcreatex.in.create_options = 0;
1320 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1321 	io.ntcreatex.in.share_access =
1322 		NTCREATEX_SHARE_ACCESS_READ |
1323 		NTCREATEX_SHARE_ACCESS_WRITE;
1324 	io.ntcreatex.in.alloc_size = 0;
1325 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1326 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1327 	io.ntcreatex.in.security_flags = 0;
1328 	io.ntcreatex.in.fname = fname;
1329 	status = smb_raw_open(cli->tree, tctx, &io);
1330 	CHECK_STATUS(status, NT_STATUS_OK);
1331 	fnum = io.ntcreatex.out.file.fnum;
1332 
1333 	torture_comment(tctx, "get the original sd\n");
1334 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1335 	q.query_secdesc.in.file.fnum = fnum;
1336 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1337 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
1338 	CHECK_STATUS(status, NT_STATUS_OK);
1339 	sd_orig = q.query_secdesc.out.sd;
1340 
1341 	owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1342 
1343 	status = torture_check_privilege(cli,
1344 					    owner_sid,
1345 					    sec_privilege_name(SEC_PRIV_RESTORE));
1346 	has_restore_privilege = NT_STATUS_IS_OK(status);
1347 	if (!NT_STATUS_IS_OK(status)) {
1348 		torture_warning(tctx, "torture_check_privilege - %s\n", nt_errstr(status));
1349 	}
1350 	torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1351 
1352 	status = torture_check_privilege(cli,
1353 					    owner_sid,
1354 					    sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1355 	has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1356 	if (!NT_STATUS_IS_OK(status)) {
1357 		torture_warning(tctx, "torture_check_privilege - %s\n", nt_errstr(status));
1358 	}
1359 	torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1360 
1361 	sd = security_descriptor_dacl_create(tctx,
1362 					0, NULL, NULL,
1363 					owner_sid,
1364 					SEC_ACE_TYPE_ACCESS_ALLOWED,
1365 					SEC_FILE_WRITE_DATA,
1366 					0,
1367 					NULL);
1368 
1369 	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1370 	set.set_secdesc.in.file.fnum = fnum;
1371 	set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1372 	set.set_secdesc.in.sd = sd;
1373 
1374 	status = smb_raw_setfileinfo(cli->tree, &set);
1375 	CHECK_STATUS(status, NT_STATUS_OK);
1376 
1377 	expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
1378 
1379 	for (i=0;i<16;i++) {
1380 		uint32_t bit = (1<<i);
1381 		io.ntcreatex.in.access_mask = bit;
1382 		status = smb_raw_open(cli->tree, tctx, &io);
1383 		if (expected_bits & bit) {
1384 			if (!NT_STATUS_IS_OK(status)) {
1385 				torture_warning(tctx, "failed with access mask 0x%08x of expected 0x%08x\n",
1386 				       bit, expected_bits);
1387 			}
1388 			CHECK_STATUS(status, NT_STATUS_OK);
1389 			CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, bit | SEC_FILE_READ_ATTRIBUTE);
1390 			smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1391 		} else {
1392 			if (NT_STATUS_IS_OK(status)) {
1393 				torture_warning(tctx, "open succeeded with access mask 0x%08x of "
1394 					"expected 0x%08x - should fail\n",
1395 				       bit, expected_bits);
1396 			}
1397 			CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1398 		}
1399 	}
1400 
1401 	torture_comment(tctx, "put back original sd\n");
1402 	set.set_secdesc.in.sd = sd_orig;
1403 	status = smb_raw_setfileinfo(cli->tree, &set);
1404 	CHECK_STATUS(status, NT_STATUS_OK);
1405 
1406 done:
1407 	smbcli_close(cli->tree, fnum);
1408 	smbcli_unlink(cli->tree, fname);
1409 	smb_raw_exit(cli->session);
1410 	smbcli_deltree(cli->tree, BASEDIR);
1411 	return ret;
1412 }
1413 
1414 
1415 
1416 /*
1417   test the inheritance of ACL flags onto new files and directories
1418   Test copied to smb2/acls.c for SMB2.
1419 */
test_inheritance(struct torture_context * tctx,struct smbcli_state * cli)1420 static bool test_inheritance(struct torture_context *tctx,
1421 							 struct smbcli_state *cli)
1422 {
1423 	NTSTATUS status;
1424 	union smb_open io;
1425 	const char *dname = BASEDIR "\\inheritance";
1426 	const char *fname1 = BASEDIR "\\inheritance\\testfile";
1427 	const char *fname2 = BASEDIR "\\inheritance\\testdir";
1428 	bool ret = true;
1429 	int fnum=0, fnum2, i;
1430 	union smb_fileinfo q;
1431 	union smb_setfileinfo set;
1432 	struct security_descriptor *sd, *sd2, *sd_orig=NULL, *sd_def1, *sd_def2;
1433 	const char *owner_sid, *group_sid;
1434 	const struct dom_sid *creator_owner;
1435 	const struct {
1436 		uint32_t parent_flags;
1437 		uint32_t file_flags;
1438 		uint32_t dir_flags;
1439 	} test_flags[] = {
1440 		{
1441 			0,
1442 			0,
1443 			0
1444 		},
1445 		{
1446 			SEC_ACE_FLAG_OBJECT_INHERIT,
1447 			0,
1448 			SEC_ACE_FLAG_OBJECT_INHERIT |
1449 			SEC_ACE_FLAG_INHERIT_ONLY,
1450 		},
1451 		{
1452 			SEC_ACE_FLAG_CONTAINER_INHERIT,
1453 			0,
1454 			SEC_ACE_FLAG_CONTAINER_INHERIT,
1455 		},
1456 		{
1457 			SEC_ACE_FLAG_OBJECT_INHERIT |
1458 			SEC_ACE_FLAG_CONTAINER_INHERIT,
1459 			0,
1460 			SEC_ACE_FLAG_OBJECT_INHERIT |
1461 			SEC_ACE_FLAG_CONTAINER_INHERIT,
1462 		},
1463 		{
1464 			SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1465 			0,
1466 			0,
1467 		},
1468 		{
1469 			SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1470 			SEC_ACE_FLAG_OBJECT_INHERIT,
1471 			0,
1472 			0,
1473 		},
1474 		{
1475 			SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1476 			SEC_ACE_FLAG_CONTAINER_INHERIT,
1477 			0,
1478 			0,
1479 		},
1480 		{
1481 			SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1482 			SEC_ACE_FLAG_CONTAINER_INHERIT |
1483 			SEC_ACE_FLAG_OBJECT_INHERIT,
1484 			0,
1485 			0,
1486 		},
1487 		{
1488 			SEC_ACE_FLAG_INHERIT_ONLY,
1489 			0,
1490 			0,
1491 		},
1492 		{
1493 			SEC_ACE_FLAG_INHERIT_ONLY |
1494 			SEC_ACE_FLAG_OBJECT_INHERIT,
1495 			0,
1496 			SEC_ACE_FLAG_OBJECT_INHERIT |
1497 			SEC_ACE_FLAG_INHERIT_ONLY,
1498 		},
1499 		{
1500 			SEC_ACE_FLAG_INHERIT_ONLY |
1501 			SEC_ACE_FLAG_CONTAINER_INHERIT,
1502 			0,
1503 			SEC_ACE_FLAG_CONTAINER_INHERIT,
1504 		},
1505 		{
1506 			SEC_ACE_FLAG_INHERIT_ONLY |
1507 			SEC_ACE_FLAG_CONTAINER_INHERIT |
1508 			SEC_ACE_FLAG_OBJECT_INHERIT,
1509 			0,
1510 			SEC_ACE_FLAG_CONTAINER_INHERIT |
1511 			SEC_ACE_FLAG_OBJECT_INHERIT,
1512 		},
1513 		{
1514 			SEC_ACE_FLAG_INHERIT_ONLY |
1515 			SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1516 			0,
1517 			0,
1518 		},
1519 		{
1520 			SEC_ACE_FLAG_INHERIT_ONLY |
1521 			SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1522 			SEC_ACE_FLAG_OBJECT_INHERIT,
1523 			0,
1524 			0,
1525 		},
1526 		{
1527 			SEC_ACE_FLAG_INHERIT_ONLY |
1528 			SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1529 			SEC_ACE_FLAG_CONTAINER_INHERIT,
1530 			0,
1531 			0,
1532 		},
1533 		{
1534 			SEC_ACE_FLAG_INHERIT_ONLY |
1535 			SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1536 			SEC_ACE_FLAG_CONTAINER_INHERIT |
1537 			SEC_ACE_FLAG_OBJECT_INHERIT,
1538 			0,
1539 			0,
1540 		}
1541 	};
1542 
1543 	if (!torture_setup_dir(cli, BASEDIR))
1544 		return false;
1545 
1546 	torture_comment(tctx, "TESTING ACL INHERITANCE\n");
1547 
1548 	io.generic.level = RAW_OPEN_NTCREATEX;
1549 	io.ntcreatex.in.root_fid.fnum = 0;
1550 	io.ntcreatex.in.flags = 0;
1551 	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1552 	io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1553 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1554 	io.ntcreatex.in.share_access = 0;
1555 	io.ntcreatex.in.alloc_size = 0;
1556 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1557 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1558 	io.ntcreatex.in.security_flags = 0;
1559 	io.ntcreatex.in.fname = dname;
1560 
1561 	status = smb_raw_open(cli->tree, tctx, &io);
1562 	CHECK_STATUS(status, NT_STATUS_OK);
1563 	fnum = io.ntcreatex.out.file.fnum;
1564 
1565 	torture_comment(tctx, "get the original sd\n");
1566 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1567 	q.query_secdesc.in.file.fnum = fnum;
1568 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
1569 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
1570 	CHECK_STATUS(status, NT_STATUS_OK);
1571 	sd_orig = q.query_secdesc.out.sd;
1572 
1573 	owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1574 	group_sid = dom_sid_string(tctx, sd_orig->group_sid);
1575 
1576 	torture_comment(tctx, "owner_sid is %s\n", owner_sid);
1577 	torture_comment(tctx, "group_sid is %s\n", group_sid);
1578 
1579 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1580 
1581 	if (torture_setting_bool(tctx, "samba4", false)) {
1582 		/* the default ACL in Samba4 includes the group and
1583 		   other permissions */
1584 		sd_def1 = security_descriptor_dacl_create(tctx,
1585 							 0, owner_sid, NULL,
1586 							 owner_sid,
1587 							 SEC_ACE_TYPE_ACCESS_ALLOWED,
1588 							 SEC_RIGHTS_FILE_ALL,
1589 							 0,
1590 							 group_sid,
1591 							 SEC_ACE_TYPE_ACCESS_ALLOWED,
1592 							 SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE,
1593 							 0,
1594 							 SID_WORLD,
1595 							 SEC_ACE_TYPE_ACCESS_ALLOWED,
1596 							 SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE,
1597 							 0,
1598 							 SID_NT_SYSTEM,
1599 							 SEC_ACE_TYPE_ACCESS_ALLOWED,
1600 							 SEC_RIGHTS_FILE_ALL,
1601 							 0,
1602 							 NULL);
1603 	} else {
1604 		/*
1605 		 * The Windows Default ACL for a new file, when there is no ACL to be
1606 		 * inherited: FullControl for the owner and SYSTEM.
1607 		 */
1608 		sd_def1 = security_descriptor_dacl_create(tctx,
1609 							 0, owner_sid, NULL,
1610 							 owner_sid,
1611 							 SEC_ACE_TYPE_ACCESS_ALLOWED,
1612 							 SEC_RIGHTS_FILE_ALL,
1613 							 0,
1614 							 SID_NT_SYSTEM,
1615 							 SEC_ACE_TYPE_ACCESS_ALLOWED,
1616 							 SEC_RIGHTS_FILE_ALL,
1617 							 0,
1618 							 NULL);
1619 	}
1620 
1621 	/*
1622 	 * Use this in the case the system being tested does not add an ACE for
1623 	 * the SYSTEM SID.
1624 	 */
1625 	sd_def2 = security_descriptor_dacl_create(tctx,
1626 					    0, owner_sid, NULL,
1627 					    owner_sid,
1628 					    SEC_ACE_TYPE_ACCESS_ALLOWED,
1629 					    SEC_RIGHTS_FILE_ALL,
1630 					    0,
1631 					    NULL);
1632 
1633 	creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
1634 
1635 	for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1636 		sd = security_descriptor_dacl_create(tctx,
1637 						0, NULL, NULL,
1638 						SID_CREATOR_OWNER,
1639 						SEC_ACE_TYPE_ACCESS_ALLOWED,
1640 						SEC_FILE_WRITE_DATA,
1641 						test_flags[i].parent_flags,
1642 						SID_WORLD,
1643 						SEC_ACE_TYPE_ACCESS_ALLOWED,
1644 						SEC_FILE_ALL | SEC_STD_ALL,
1645 						0,
1646 						NULL);
1647 		set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1648 		set.set_secdesc.in.file.fnum = fnum;
1649 		set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1650 		set.set_secdesc.in.sd = sd;
1651 		status = smb_raw_setfileinfo(cli->tree, &set);
1652 		CHECK_STATUS(status, NT_STATUS_OK);
1653 
1654 		io.ntcreatex.in.fname = fname1;
1655 		io.ntcreatex.in.create_options = 0;
1656 		status = smb_raw_open(cli->tree, tctx, &io);
1657 		CHECK_STATUS(status, NT_STATUS_OK);
1658 		fnum2 = io.ntcreatex.out.file.fnum;
1659 
1660 		q.query_secdesc.in.file.fnum = fnum2;
1661 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
1662 		CHECK_STATUS(status, NT_STATUS_OK);
1663 
1664 		smbcli_close(cli->tree, fnum2);
1665 		smbcli_unlink(cli->tree, fname1);
1666 
1667 		if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1668 			if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
1669 			    !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
1670 				torture_warning(tctx, "Expected default sd "
1671 				    "for i=%d:\n", i);
1672 				NDR_PRINT_DEBUG(security_descriptor, sd_def1);
1673 				torture_warning(tctx, "at %d - got:\n", i);
1674 				NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1675 			}
1676 			goto check_dir;
1677 		}
1678 
1679 		if (q.query_secdesc.out.sd->dacl == NULL ||
1680 		    q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1681 		    q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1682 		    !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1683 				   sd_orig->owner_sid)) {
1684 			ret = false;
1685 			torture_warning(tctx, "Bad sd in child file at %d\n", i);
1686 			NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1687 			goto check_dir;
1688 		}
1689 
1690 		if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
1691 		    test_flags[i].file_flags) {
1692 			torture_warning(tctx, "incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1693 			       q.query_secdesc.out.sd->dacl->aces[0].flags,
1694 			       test_flags[i].file_flags,
1695 			       test_flags[i].parent_flags,
1696 			       i);
1697 			ret = false;
1698 		}
1699 
1700 	check_dir:
1701 		io.ntcreatex.in.fname = fname2;
1702 		io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1703 		status = smb_raw_open(cli->tree, tctx, &io);
1704 		CHECK_STATUS(status, NT_STATUS_OK);
1705 		fnum2 = io.ntcreatex.out.file.fnum;
1706 
1707 		q.query_secdesc.in.file.fnum = fnum2;
1708 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
1709 		CHECK_STATUS(status, NT_STATUS_OK);
1710 
1711 		smbcli_close(cli->tree, fnum2);
1712 		smbcli_rmdir(cli->tree, fname2);
1713 
1714 		if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1715 		    (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1716 		     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1717 			if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
1718 			    !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
1719 				torture_warning(tctx, "Expected default sd for dir at %d:\n", i);
1720 				NDR_PRINT_DEBUG(security_descriptor, sd_def1);
1721 				torture_warning(tctx, "got:\n");
1722 				NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1723 			}
1724 			continue;
1725 		}
1726 
1727 		if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1728 		    (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1729 			if (q.query_secdesc.out.sd->dacl == NULL ||
1730 			    q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1731 			    q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1732 			    !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1733 					   sd_orig->owner_sid) ||
1734 			    q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1735 				torture_warning(tctx, "(CI & NP) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1736 				       test_flags[i].dir_flags,
1737 				       test_flags[i].parent_flags, i);
1738 				NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1739 				torture_comment(tctx, "FYI, here is the parent sd:\n");
1740 				NDR_PRINT_DEBUG(security_descriptor, sd);
1741 				ret = false;
1742 				continue;
1743 			}
1744 		} else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1745 			if (q.query_secdesc.out.sd->dacl == NULL ||
1746 			    q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1747 			    q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1748 			    !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1749 					   sd_orig->owner_sid) ||
1750 			    q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1751 			    !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1752 					   creator_owner) ||
1753 			    q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1754 			    q.query_secdesc.out.sd->dacl->aces[1].flags !=
1755 			    (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1756 				torture_warning(tctx, "(CI) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1757 				       test_flags[i].dir_flags,
1758 				       test_flags[i].parent_flags, i);
1759 				NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1760 				torture_comment(tctx, "FYI, here is the parent sd:\n");
1761 				NDR_PRINT_DEBUG(security_descriptor, sd);
1762 				ret = false;
1763 				continue;
1764 			}
1765 		} else {
1766 			if (q.query_secdesc.out.sd->dacl == NULL ||
1767 			    q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1768 			    q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1769 			    !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1770 					   creator_owner) ||
1771 			    q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1772 				torture_warning(tctx, "(0) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1773 				       test_flags[i].dir_flags,
1774 				       test_flags[i].parent_flags, i);
1775 				NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1776 				torture_comment(tctx, "FYI, here is the parent sd:\n");
1777 				NDR_PRINT_DEBUG(security_descriptor, sd);
1778 				ret = false;
1779 				continue;
1780 			}
1781 		}
1782 	}
1783 
1784 	torture_comment(tctx, "Testing access checks on inherited create with %s\n", fname1);
1785 	sd = security_descriptor_dacl_create(tctx,
1786 					0, NULL, NULL,
1787 					owner_sid,
1788 					SEC_ACE_TYPE_ACCESS_ALLOWED,
1789 					SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1790 					SEC_ACE_FLAG_OBJECT_INHERIT,
1791 					SID_WORLD,
1792 					SEC_ACE_TYPE_ACCESS_ALLOWED,
1793 					SEC_FILE_ALL | SEC_STD_ALL,
1794 					0,
1795 					NULL);
1796 	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1797 	set.set_secdesc.in.file.fnum = fnum;
1798 	set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1799 	set.set_secdesc.in.sd = sd;
1800 	status = smb_raw_setfileinfo(cli->tree, &set);
1801 	CHECK_STATUS(status, NT_STATUS_OK);
1802 
1803 	/* Check DACL we just set. */
1804 	torture_comment(tctx, "checking new sd\n");
1805 	q.query_secdesc.in.file.fnum = fnum;
1806 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
1807 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
1808 	CHECK_STATUS(status, NT_STATUS_OK);
1809 	CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
1810 
1811 	io.ntcreatex.in.fname = fname1;
1812 	io.ntcreatex.in.create_options = 0;
1813 	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1814 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1815 	status = smb_raw_open(cli->tree, tctx, &io);
1816 	CHECK_STATUS(status, NT_STATUS_OK);
1817 	fnum2 = io.ntcreatex.out.file.fnum;
1818 	CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1819 
1820 	q.query_secdesc.in.file.fnum = fnum2;
1821 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1822 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
1823 	CHECK_STATUS(status, NT_STATUS_OK);
1824 	smbcli_close(cli->tree, fnum2);
1825 
1826 	sd2 = security_descriptor_dacl_create(tctx,
1827 					 0, owner_sid, NULL,
1828 					 owner_sid,
1829 					 SEC_ACE_TYPE_ACCESS_ALLOWED,
1830 					 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1831 					 0,
1832 					 NULL);
1833 	CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1834 
1835 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1836 	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1837 	status = smb_raw_open(cli->tree, tctx, &io);
1838 	if (NT_STATUS_IS_OK(status)) {
1839 		torture_warning(tctx, "failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1840 		ret = false;
1841 		fnum2 = io.ntcreatex.out.file.fnum;
1842 		CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1843 		smbcli_close(cli->tree, fnum2);
1844 	} else {
1845 		if (TARGET_IS_WIN7(tctx)) {
1846 			CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1847 		} else {
1848 			CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1849 		}
1850 	}
1851 
1852 	torture_comment(tctx, "trying without execute\n");
1853 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1854 	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1855 	status = smb_raw_open(cli->tree, tctx, &io);
1856 	if (TARGET_IS_WIN7(tctx)) {
1857 		CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1858 	} else {
1859 		CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1860 	}
1861 
1862 	torture_comment(tctx, "and with full permissions again\n");
1863 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1864 	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1865 	status = smb_raw_open(cli->tree, tctx, &io);
1866 	if (TARGET_IS_WIN7(tctx)) {
1867 		CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1868 	} else {
1869 		CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1870 	}
1871 
1872 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1873 	status = smb_raw_open(cli->tree, tctx, &io);
1874 	CHECK_STATUS(status, NT_STATUS_OK);
1875 	fnum2 = io.ntcreatex.out.file.fnum;
1876 	CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1877 	smbcli_close(cli->tree, fnum2);
1878 
1879 	torture_comment(tctx, "put back original sd\n");
1880 	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1881 	set.set_secdesc.in.file.fnum = fnum;
1882 	set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1883 	set.set_secdesc.in.sd = sd_orig;
1884 	status = smb_raw_setfileinfo(cli->tree, &set);
1885 	CHECK_STATUS(status, NT_STATUS_OK);
1886 
1887 	smbcli_close(cli->tree, fnum);
1888 
1889 	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1890 	status = smb_raw_open(cli->tree, tctx, &io);
1891 	if (TARGET_IS_WIN7(tctx)) {
1892 		CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1893 	} else {
1894 		CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1895 	}
1896 
1897 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1898 	status = smb_raw_open(cli->tree, tctx, &io);
1899 	CHECK_STATUS(status, NT_STATUS_OK);
1900 	fnum2 = io.ntcreatex.out.file.fnum;
1901 	CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1902 	smbcli_close(cli->tree, fnum2);
1903 
1904 done:
1905 	if (sd_orig != NULL) {
1906 		set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1907 		set.set_secdesc.in.file.fnum = fnum;
1908 		set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1909 		set.set_secdesc.in.sd = sd_orig;
1910 		status = smb_raw_setfileinfo(cli->tree, &set);
1911 	}
1912 
1913 	smbcli_close(cli->tree, fnum);
1914 	smbcli_unlink(cli->tree, fname1);
1915 	smbcli_rmdir(cli->tree, dname);
1916 	smb_raw_exit(cli->session);
1917 	smbcli_deltree(cli->tree, BASEDIR);
1918 
1919 	if (!ret) {
1920 		torture_result(tctx,
1921 			TORTURE_FAIL, "(%s) test_inheritance\n",
1922 			__location__);
1923 	}
1924 
1925 	return ret;
1926 }
1927 
test_inheritance_flags(struct torture_context * tctx,struct smbcli_state * cli)1928 static bool test_inheritance_flags(struct torture_context *tctx,
1929     struct smbcli_state *cli)
1930 {
1931 	NTSTATUS status;
1932 	union smb_open io;
1933 	const char *dname = BASEDIR "\\inheritance";
1934 	const char *fname1 = BASEDIR "\\inheritance\\testfile";
1935 	bool ret = true;
1936 	int fnum=0, fnum2, i, j;
1937 	union smb_fileinfo q;
1938 	union smb_setfileinfo set;
1939 	struct security_descriptor *sd, *sd2, *sd_orig=NULL;
1940 	const char *owner_sid;
1941 	struct {
1942 		uint32_t parent_set_sd_type; /* 3 options */
1943 		uint32_t parent_set_ace_inherit; /* 1 option */
1944 		uint32_t parent_get_sd_type;
1945 		uint32_t parent_get_ace_inherit;
1946 		uint32_t child_get_sd_type;
1947 		uint32_t child_get_ace_inherit;
1948 	} tflags[16] = {{0}}; /* 2^4 */
1949 
1950 	for (i = 0; i < 15; i++) {
1951 		torture_comment(tctx, "i=%d:", i);
1952 
1953 		ZERO_STRUCT(tflags[i]);
1954 
1955 		if (i & 1) {
1956 			tflags[i].parent_set_sd_type |=
1957 			    SEC_DESC_DACL_AUTO_INHERITED;
1958 			torture_comment(tctx, "AUTO_INHERITED, ");
1959 		}
1960 		if (i & 2) {
1961 			tflags[i].parent_set_sd_type |=
1962 			    SEC_DESC_DACL_AUTO_INHERIT_REQ;
1963 			torture_comment(tctx, "AUTO_INHERIT_REQ, ");
1964 		}
1965 		if (i & 4) {
1966 			tflags[i].parent_set_sd_type |=
1967 			    SEC_DESC_DACL_PROTECTED;
1968 			tflags[i].parent_get_sd_type |=
1969 			    SEC_DESC_DACL_PROTECTED;
1970 			torture_comment(tctx, "PROTECTED, ");
1971 		}
1972 		if (i & 8) {
1973 			tflags[i].parent_set_ace_inherit |=
1974 			    SEC_ACE_FLAG_INHERITED_ACE;
1975 			tflags[i].parent_get_ace_inherit |=
1976 			    SEC_ACE_FLAG_INHERITED_ACE;
1977 			torture_comment(tctx, "INHERITED, ");
1978 		}
1979 
1980 		if ((tflags[i].parent_set_sd_type &
1981 		    (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) ==
1982 		    (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) {
1983 			tflags[i].parent_get_sd_type |=
1984 			    SEC_DESC_DACL_AUTO_INHERITED;
1985 			tflags[i].child_get_sd_type |=
1986 			    SEC_DESC_DACL_AUTO_INHERITED;
1987 			tflags[i].child_get_ace_inherit |=
1988 			    SEC_ACE_FLAG_INHERITED_ACE;
1989 			torture_comment(tctx, "  ... parent is AUTO INHERITED");
1990 		}
1991 
1992 		if (tflags[i].parent_set_ace_inherit &
1993 		    SEC_ACE_FLAG_INHERITED_ACE) {
1994 			tflags[i].parent_get_ace_inherit =
1995 			    SEC_ACE_FLAG_INHERITED_ACE;
1996 			torture_comment(tctx, "  ... parent ACE is INHERITED");
1997 		}
1998 
1999 		torture_comment(tctx, "\n");
2000 	}
2001 
2002 	if (!torture_setup_dir(cli, BASEDIR))
2003 		return false;
2004 
2005 	torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
2006 
2007 	ZERO_STRUCT(io);
2008 
2009 	io.generic.level = RAW_OPEN_NTCREATEX;
2010 	io.ntcreatex.in.root_fid.fnum = 0;
2011 	io.ntcreatex.in.flags = 0;
2012 	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2013 	io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2014 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
2015 	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
2016 	io.ntcreatex.in.alloc_size = 0;
2017 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2018 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2019 	io.ntcreatex.in.security_flags = 0;
2020 	io.ntcreatex.in.fname = dname;
2021 
2022 	torture_comment(tctx, "creating initial directory %s\n", dname);
2023 	status = smb_raw_open(cli->tree, tctx, &io);
2024 	CHECK_STATUS(status, NT_STATUS_OK);
2025 	fnum = io.ntcreatex.out.file.fnum;
2026 
2027 	torture_comment(tctx, "getting original sd\n");
2028 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2029 	q.query_secdesc.in.file.fnum = fnum;
2030 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2031 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
2032 	CHECK_STATUS(status, NT_STATUS_OK);
2033 	sd_orig = q.query_secdesc.out.sd;
2034 
2035 	owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
2036 	torture_comment(tctx, "owner_sid is %s\n", owner_sid);
2037 
2038 	for (i=0; i < ARRAY_SIZE(tflags); i++) {
2039 		torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
2040 
2041 		sd = security_descriptor_dacl_create(tctx,
2042 						tflags[i].parent_set_sd_type,
2043 						NULL, NULL,
2044 						owner_sid,
2045 						SEC_ACE_TYPE_ACCESS_ALLOWED,
2046 						SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
2047 						SEC_ACE_FLAG_OBJECT_INHERIT |
2048 						SEC_ACE_FLAG_CONTAINER_INHERIT |
2049 						tflags[i].parent_set_ace_inherit,
2050 						SID_WORLD,
2051 						SEC_ACE_TYPE_ACCESS_ALLOWED,
2052 						SEC_FILE_ALL | SEC_STD_ALL,
2053 						0,
2054 						NULL);
2055 		set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2056 		set.set_secdesc.in.file.fnum = fnum;
2057 		set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2058 		set.set_secdesc.in.sd = sd;
2059 		status = smb_raw_setfileinfo(cli->tree, &set);
2060 		CHECK_STATUS(status, NT_STATUS_OK);
2061 
2062 		/*
2063 		 * Check DACL we just set, except change the bits to what they
2064 		 * should be.
2065 		 */
2066 		torture_comment(tctx, "  checking new sd\n");
2067 
2068 		/* REQ bit should always be false. */
2069 		sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
2070 
2071 		if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
2072 			sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
2073 
2074 		q.query_secdesc.in.file.fnum = fnum;
2075 		q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
2076 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
2077 		CHECK_STATUS(status, NT_STATUS_OK);
2078 		CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
2079 
2080 		/* Create file. */
2081 		torture_comment(tctx, "  creating file %s\n", fname1);
2082 		io.ntcreatex.in.fname = fname1;
2083 		io.ntcreatex.in.create_options = 0;
2084 		io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2085 		io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2086 		io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2087 		status = smb_raw_open(cli->tree, tctx, &io);
2088 		CHECK_STATUS(status, NT_STATUS_OK);
2089 		fnum2 = io.ntcreatex.out.file.fnum;
2090 		CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
2091 
2092 		q.query_secdesc.in.file.fnum = fnum2;
2093 		q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2094 		status = smb_raw_fileinfo(cli->tree, tctx, &q);
2095 		CHECK_STATUS(status, NT_STATUS_OK);
2096 
2097 		torture_comment(tctx, "  checking sd on file %s\n", fname1);
2098 		sd2 = security_descriptor_dacl_create(tctx,
2099 						 tflags[i].child_get_sd_type,
2100 						 owner_sid, NULL,
2101 						 owner_sid,
2102 						 SEC_ACE_TYPE_ACCESS_ALLOWED,
2103 						 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
2104 						 tflags[i].child_get_ace_inherit,
2105 						 NULL);
2106 		CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
2107 
2108 		/*
2109 		 * Set new sd on file ... prove that the bits have nothing to
2110 		 * do with the parents bits when manually setting an ACL. The
2111 		 * _AUTO_INHERITED bit comes directly from the ACL set.
2112 		 */
2113 		for (j = 0; j < ARRAY_SIZE(tflags); j++) {
2114 			torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
2115 
2116 			/* Change sd type. */
2117 			sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
2118 			    SEC_DESC_DACL_AUTO_INHERIT_REQ |
2119 			    SEC_DESC_DACL_PROTECTED);
2120 			sd2->type |= tflags[j].parent_set_sd_type;
2121 
2122 			sd2->dacl->aces[0].flags &=
2123 			    ~SEC_ACE_FLAG_INHERITED_ACE;
2124 			sd2->dacl->aces[0].flags |=
2125 			    tflags[j].parent_set_ace_inherit;
2126 
2127 			set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2128 			set.set_secdesc.in.file.fnum = fnum2;
2129 			set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2130 			set.set_secdesc.in.sd = sd2;
2131 			status = smb_raw_setfileinfo(cli->tree, &set);
2132 			CHECK_STATUS(status, NT_STATUS_OK);
2133 
2134 			/* Check DACL we just set. */
2135 			sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
2136 			if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
2137 				sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
2138 
2139 			q.query_secdesc.in.file.fnum = fnum2;
2140 			q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2141 			status = smb_raw_fileinfo(cli->tree, tctx, &q);
2142 			CHECK_STATUS(status, NT_STATUS_OK);
2143 
2144 			CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
2145 		}
2146 
2147 		smbcli_close(cli->tree, fnum2);
2148 		smbcli_unlink(cli->tree, fname1);
2149 	}
2150 
2151 done:
2152 	smbcli_close(cli->tree, fnum);
2153 	smb_raw_exit(cli->session);
2154 	smbcli_deltree(cli->tree, BASEDIR);
2155 
2156 	if (!ret) {
2157 		torture_result(tctx,
2158 			TORTURE_FAIL, "(%s) test_inheritance_flags\n",
2159 			__location__);
2160 	}
2161 
2162 	return ret;
2163 }
2164 
2165 /*
2166   test dynamic acl inheritance
2167   Test copied to smb2/acls.c for SMB2.
2168 */
test_inheritance_dynamic(struct torture_context * tctx,struct smbcli_state * cli)2169 static bool test_inheritance_dynamic(struct torture_context *tctx,
2170 									 struct smbcli_state *cli)
2171 {
2172 	NTSTATUS status;
2173 	union smb_open io;
2174 	const char *dname = BASEDIR "\\inheritance2";
2175 	const char *fname1 = BASEDIR "\\inheritance2\\testfile";
2176 	bool ret = true;
2177 	int fnum=0, fnum2;
2178 	union smb_fileinfo q;
2179 	union smb_setfileinfo set;
2180 	struct security_descriptor *sd, *sd_orig=NULL;
2181 	const char *owner_sid;
2182 
2183 	torture_comment(tctx, "TESTING DYNAMIC ACL INHERITANCE\n");
2184 
2185 	if (!torture_setup_dir(cli, BASEDIR))
2186 		return false;
2187 
2188 	io.generic.level = RAW_OPEN_NTCREATEX;
2189 	io.ntcreatex.in.root_fid.fnum = 0;
2190 	io.ntcreatex.in.flags = 0;
2191 	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2192 	io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2193 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
2194 	io.ntcreatex.in.share_access = 0;
2195 	io.ntcreatex.in.alloc_size = 0;
2196 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2197 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2198 	io.ntcreatex.in.security_flags = 0;
2199 	io.ntcreatex.in.fname = dname;
2200 
2201 	status = smb_raw_open(cli->tree, tctx, &io);
2202 	CHECK_STATUS(status, NT_STATUS_OK);
2203 	fnum = io.ntcreatex.out.file.fnum;
2204 
2205 	torture_comment(tctx, "get the original sd\n");
2206 	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2207 	q.query_secdesc.in.file.fnum = fnum;
2208 	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2209 	status = smb_raw_fileinfo(cli->tree, tctx, &q);
2210 	CHECK_STATUS(status, NT_STATUS_OK);
2211 	sd_orig = q.query_secdesc.out.sd;
2212 
2213 	owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
2214 
2215 	torture_comment(tctx, "owner_sid is %s\n", owner_sid);
2216 
2217 	sd = security_descriptor_dacl_create(tctx,
2218 					0, NULL, NULL,
2219 					owner_sid,
2220 					SEC_ACE_TYPE_ACCESS_ALLOWED,
2221 					SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
2222 					SEC_ACE_FLAG_OBJECT_INHERIT,
2223 					NULL);
2224 	sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
2225 
2226 	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2227 	set.set_secdesc.in.file.fnum = fnum;
2228 	set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2229 	set.set_secdesc.in.sd = sd;
2230 	status = smb_raw_setfileinfo(cli->tree, &set);
2231 	CHECK_STATUS(status, NT_STATUS_OK);
2232 
2233 	torture_comment(tctx, "create a file with an inherited acl\n");
2234 	io.ntcreatex.in.fname = fname1;
2235 	io.ntcreatex.in.create_options = 0;
2236 	io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
2237 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2238 	status = smb_raw_open(cli->tree, tctx, &io);
2239 	CHECK_STATUS(status, NT_STATUS_OK);
2240 	fnum2 = io.ntcreatex.out.file.fnum;
2241 	smbcli_close(cli->tree, fnum2);
2242 
2243 	torture_comment(tctx, "try and access file with base rights - should be OK\n");
2244 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
2245 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2246 	status = smb_raw_open(cli->tree, tctx, &io);
2247 	CHECK_STATUS(status, NT_STATUS_OK);
2248 	fnum2 = io.ntcreatex.out.file.fnum;
2249 	smbcli_close(cli->tree, fnum2);
2250 
2251 	torture_comment(tctx, "try and access file with extra rights - should be denied\n");
2252 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
2253 	status = smb_raw_open(cli->tree, tctx, &io);
2254 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
2255 
2256 	torture_comment(tctx, "update parent sd\n");
2257 	sd = security_descriptor_dacl_create(tctx,
2258 					0, NULL, NULL,
2259 					owner_sid,
2260 					SEC_ACE_TYPE_ACCESS_ALLOWED,
2261 					SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
2262 					SEC_ACE_FLAG_OBJECT_INHERIT,
2263 					NULL);
2264 	sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
2265 
2266 	set.set_secdesc.in.sd = sd;
2267 	status = smb_raw_setfileinfo(cli->tree, &set);
2268 	CHECK_STATUS(status, NT_STATUS_OK);
2269 
2270 	torture_comment(tctx, "try and access file with base rights - should be OK\n");
2271 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
2272 	status = smb_raw_open(cli->tree, tctx, &io);
2273 	CHECK_STATUS(status, NT_STATUS_OK);
2274 	fnum2 = io.ntcreatex.out.file.fnum;
2275 	smbcli_close(cli->tree, fnum2);
2276 
2277 
2278 	torture_comment(tctx, "try and access now - should be OK if dynamic inheritance works\n");
2279 	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
2280 	status = smb_raw_open(cli->tree, tctx, &io);
2281 	if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2282 		torture_comment(tctx, "Server does not have dynamic inheritance\n");
2283 	}
2284 	if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
2285 		torture_comment(tctx, "Server does have dynamic inheritance\n");
2286 	}
2287 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
2288 
2289 	smbcli_unlink(cli->tree, fname1);
2290 
2291 done:
2292 	if (sd_orig != NULL) {
2293 		torture_comment(tctx, "put back original sd\n");
2294 		set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2295 		set.set_secdesc.in.file.fnum = fnum;
2296 		set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2297 		set.set_secdesc.in.sd = sd_orig;
2298 		status = smb_raw_setfileinfo(cli->tree, &set);
2299 	}
2300 	smbcli_close(cli->tree, fnum);
2301 	smbcli_rmdir(cli->tree, dname);
2302 	smb_raw_exit(cli->session);
2303 	smbcli_deltree(cli->tree, BASEDIR);
2304 
2305 	return ret;
2306 }
2307 
2308 #define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
2309 	if (!(bits & desired_64)) {\
2310 		CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
2311 		action; \
2312 	} else { \
2313 		CHECK_STATUS(status, NT_STATUS_OK); \
2314 	} \
2315 } while (0)
2316 
2317 #define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
2318 	if (NT_STATUS_IS_OK(status)) { \
2319 		if (!(granted & access)) {\
2320 			ret = false; \
2321 			torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
2322 			       __location__, nt_errstr(status), access, granted, desired); \
2323 			goto done; \
2324 		} \
2325 	} else { \
2326 		if (granted & access) {\
2327 			ret = false; \
2328 			torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
2329 			       __location__, nt_errstr(status), access, granted, desired); \
2330 			goto done; \
2331 		} \
2332 	} \
2333 	CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
2334 } while (0)
2335 
2336 #if 0
2337 
2338 /* test what access mask is needed for getting and setting security_descriptors
2339   Test copied to smb2/acls.c for SMB2. */
2340 static bool test_sd_get_set(struct torture_context *tctx,
2341 							struct smbcli_state *cli)
2342 {
2343 	NTSTATUS status;
2344 	bool ret = true;
2345 	union smb_open io;
2346 	union smb_fileinfo fi;
2347 	union smb_setfileinfo si;
2348 	struct security_descriptor *sd;
2349 	struct security_descriptor *sd_owner = NULL;
2350 	struct security_descriptor *sd_group = NULL;
2351 	struct security_descriptor *sd_dacl = NULL;
2352 	struct security_descriptor *sd_sacl = NULL;
2353 	int fnum=0;
2354 	const char *fname = BASEDIR "\\sd_get_set.txt";
2355 	uint64_t desired_64;
2356 	uint32_t desired = 0, granted;
2357 	int i = 0;
2358 #define NO_BITS_HACK (((uint64_t)1)<<32)
2359 	uint64_t open_bits =
2360 		SEC_MASK_GENERIC |
2361 		SEC_FLAG_SYSTEM_SECURITY |
2362 		SEC_FLAG_MAXIMUM_ALLOWED |
2363 		SEC_STD_ALL |
2364 		SEC_FILE_ALL |
2365 		NO_BITS_HACK;
2366 	uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2367 	uint64_t set_owner_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
2368 	uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2369 	uint64_t set_group_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
2370 	uint64_t get_dacl_bits  = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2371 	uint64_t set_dacl_bits  = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC;
2372 	uint64_t get_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
2373 	uint64_t set_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
2374 
2375 	if (!torture_setup_dir(cli, BASEDIR))
2376 		return false;
2377 
2378 	torture_comment(tctx, "TESTING ACCESS MASKS FOR SD GET/SET\n");
2379 
2380 	/* first create a file with full access for everyone */
2381 	sd = security_descriptor_dacl_create(tctx,
2382 					0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS,
2383 					SID_WORLD,
2384 					SEC_ACE_TYPE_ACCESS_ALLOWED,
2385 					SEC_GENERIC_ALL,
2386 					0,
2387 					NULL);
2388 	sd->type |= SEC_DESC_SACL_PRESENT;
2389 	sd->sacl = NULL;
2390 	io.ntcreatex.level = RAW_OPEN_NTTRANS_CREATE;
2391 	io.ntcreatex.in.root_fid.fnum = 0;
2392 	io.ntcreatex.in.flags = 0;
2393 	io.ntcreatex.in.access_mask = SEC_GENERIC_ALL;
2394 	io.ntcreatex.in.create_options = 0;
2395 	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2396 	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2397 	io.ntcreatex.in.alloc_size = 0;
2398 	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2399 	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2400 	io.ntcreatex.in.security_flags = 0;
2401 	io.ntcreatex.in.fname = fname;
2402 	io.ntcreatex.in.sec_desc = sd;
2403 	io.ntcreatex.in.ea_list = NULL;
2404 	status = smb_raw_open(cli->tree, tctx, &io);
2405 	CHECK_STATUS(status, NT_STATUS_OK);
2406 	fnum = io.ntcreatex.out.file.fnum;
2407 
2408 	status = smbcli_close(cli->tree, fnum);
2409 	CHECK_STATUS(status, NT_STATUS_OK);
2410 
2411 	/*
2412 	 * now try each access_mask bit and no bit at all in a loop
2413 	 * and see what's allowed
2414 	 * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
2415 	 */
2416 	for (i=0; i <= 32; i++) {
2417 		desired_64 = ((uint64_t)1) << i;
2418 		desired = (uint32_t)desired_64;
2419 
2420 		/* first open the file with the desired access */
2421 		io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2422 		io.ntcreatex.in.access_mask = desired;
2423 		io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2424 		status = smb_raw_open(cli->tree, tctx, &io);
2425 		CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next);
2426 		fnum = io.ntcreatex.out.file.fnum;
2427 
2428 		/* then check what access was granted */
2429 		fi.access_information.level		= RAW_FILEINFO_ACCESS_INFORMATION;
2430 		fi.access_information.in.file.fnum	= fnum;
2431 		status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2432 		CHECK_STATUS(status, NT_STATUS_OK);
2433 		granted = fi.access_information.out.access_flags;
2434 
2435 		/* test the owner */
2436 		ZERO_STRUCT(fi);
2437 		fi.query_secdesc.level			= RAW_FILEINFO_SEC_DESC;
2438 		fi.query_secdesc.in.file.fnum		= fnum;
2439 		fi.query_secdesc.in.secinfo_flags	= SECINFO_OWNER;
2440 		status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2441 		CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL);
2442 		if (fi.query_secdesc.out.sd) {
2443 			sd_owner = fi.query_secdesc.out.sd;
2444 		} else if (!sd_owner) {
2445 			sd_owner = sd;
2446 		}
2447 		si.set_secdesc.level			= RAW_SFILEINFO_SEC_DESC;
2448 		si.set_secdesc.in.file.fnum		= fnum;
2449 		si.set_secdesc.in.secinfo_flags		= SECINFO_OWNER;
2450 		si.set_secdesc.in.sd			= sd_owner;
2451 		status = smb_raw_setfileinfo(cli->tree, &si);
2452 		CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER);
2453 
2454 		/* test the group */
2455 		ZERO_STRUCT(fi);
2456 		fi.query_secdesc.level			= RAW_FILEINFO_SEC_DESC;
2457 		fi.query_secdesc.in.file.fnum		= fnum;
2458 		fi.query_secdesc.in.secinfo_flags	= SECINFO_GROUP;
2459 		status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2460 		CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL);
2461 		if (fi.query_secdesc.out.sd) {
2462 			sd_group = fi.query_secdesc.out.sd;
2463 		} else if (!sd_group) {
2464 			sd_group = sd;
2465 		}
2466 		si.set_secdesc.level			= RAW_SFILEINFO_SEC_DESC;
2467 		si.set_secdesc.in.file.fnum		= fnum;
2468 		si.set_secdesc.in.secinfo_flags		= SECINFO_GROUP;
2469 		si.set_secdesc.in.sd			= sd_group;
2470 		status = smb_raw_setfileinfo(cli->tree, &si);
2471 		CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER);
2472 
2473 		/* test the DACL */
2474 		ZERO_STRUCT(fi);
2475 		fi.query_secdesc.level			= RAW_FILEINFO_SEC_DESC;
2476 		fi.query_secdesc.in.file.fnum		= fnum;
2477 		fi.query_secdesc.in.secinfo_flags	= SECINFO_DACL;
2478 		status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2479 		CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL);
2480 		if (fi.query_secdesc.out.sd) {
2481 			sd_dacl = fi.query_secdesc.out.sd;
2482 		} else if (!sd_dacl) {
2483 			sd_dacl = sd;
2484 		}
2485 		si.set_secdesc.level			= RAW_SFILEINFO_SEC_DESC;
2486 		si.set_secdesc.in.file.fnum		= fnum;
2487 		si.set_secdesc.in.secinfo_flags		= SECINFO_DACL;
2488 		si.set_secdesc.in.sd			= sd_dacl;
2489 		status = smb_raw_setfileinfo(cli->tree, &si);
2490 		CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC);
2491 
2492 		/* test the SACL */
2493 		ZERO_STRUCT(fi);
2494 		fi.query_secdesc.level			= RAW_FILEINFO_SEC_DESC;
2495 		fi.query_secdesc.in.file.fnum		= fnum;
2496 		fi.query_secdesc.in.secinfo_flags	= SECINFO_SACL;
2497 		status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2498 		CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
2499 		if (fi.query_secdesc.out.sd) {
2500 			sd_sacl = fi.query_secdesc.out.sd;
2501 		} else if (!sd_sacl) {
2502 			sd_sacl = sd;
2503 		}
2504 		si.set_secdesc.level			= RAW_SFILEINFO_SEC_DESC;
2505 		si.set_secdesc.in.file.fnum		= fnum;
2506 		si.set_secdesc.in.secinfo_flags		= SECINFO_SACL;
2507 		si.set_secdesc.in.sd			= sd_sacl;
2508 		status = smb_raw_setfileinfo(cli->tree, &si);
2509 		CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
2510 
2511 		/* close the handle */
2512 		status = smbcli_close(cli->tree, fnum);
2513 		CHECK_STATUS(status, NT_STATUS_OK);
2514 next:
2515 		continue;
2516 	}
2517 
2518 done:
2519 	smbcli_close(cli->tree, fnum);
2520 	smbcli_unlink(cli->tree, fname);
2521 	smb_raw_exit(cli->session);
2522 	smbcli_deltree(cli->tree, BASEDIR);
2523 
2524 	return ret;
2525 }
2526 
2527 #endif
2528 
2529 /*
2530    basic testing of security descriptor calls
2531 */
torture_raw_acls(TALLOC_CTX * mem_ctx)2532 struct torture_suite *torture_raw_acls(TALLOC_CTX *mem_ctx)
2533 {
2534 	struct torture_suite *suite = torture_suite_create(mem_ctx, "acls");
2535 
2536 	torture_suite_add_1smb_test(suite, "sd", test_sd);
2537 	torture_suite_add_1smb_test(suite, "create_file", test_nttrans_create_file);
2538 	torture_suite_add_1smb_test(suite, "create_dir", test_nttrans_create_dir);
2539 	torture_suite_add_1smb_test(suite, "create_owner_file", test_nttrans_create_owner_file);
2540 	torture_suite_add_1smb_test(suite, "create_owner_dir", test_nttrans_create_owner_dir);
2541 	torture_suite_add_1smb_test(suite, "nulldacl", test_nttrans_create_null_dacl);
2542 	torture_suite_add_1smb_test(suite, "creator", test_creator_sid);
2543 	torture_suite_add_1smb_test(suite, "generic", test_generic_bits);
2544 	torture_suite_add_1smb_test(suite, "owner", test_owner_bits);
2545 	torture_suite_add_1smb_test(suite, "inheritance", test_inheritance);
2546 
2547 	torture_suite_add_1smb_test(suite, "INHERITFLAGS", test_inheritance_flags);
2548 	torture_suite_add_1smb_test(suite, "dynamic", test_inheritance_dynamic);
2549 #if 0
2550 	/* XXX This test does not work against XP or Vista. */
2551 	torture_suite_add_1smb_test(suite, "GETSET", test_sd_get_set);
2552 #endif
2553 
2554 	return suite;
2555 }
2556