s4/torture: tests for vfs_acl_xattr default ACL styles
[Samba.git] / source4 / torture / vfs / acl_xattr.c
blob7fd10d0dcd177567bc18b6803505a60661a7efdb
1 /*
2 Unix SMB/CIFS implementation.
4 Copyright (C) Ralph Boehme 2016
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "lib/cmdline/popt_common.h"
22 #include "libcli/smb2/smb2.h"
23 #include "libcli/smb2/smb2_calls.h"
24 #include "libcli/smb/smbXcli_base.h"
25 #include "torture/torture.h"
26 #include "torture/vfs/proto.h"
27 #include "libcli/resolve/resolve.h"
28 #include "torture/util.h"
29 #include "torture/smb2/proto.h"
30 #include "libcli/security/security.h"
31 #include "librpc/gen_ndr/ndr_security.h"
32 #include "lib/param/param.h"
34 #define BASEDIR "smb2-testsd"
36 #define CHECK_SECURITY_DESCRIPTOR(_sd1, _sd2) do { \
37 if (!security_descriptor_equal(_sd1, _sd2)) { \
38 torture_warning(tctx, "security descriptors don't match!\n"); \
39 torture_warning(tctx, "got:\n"); \
40 NDR_PRINT_DEBUG(security_descriptor, _sd1); \
41 torture_warning(tctx, "expected:\n"); \
42 NDR_PRINT_DEBUG(security_descriptor, _sd2); \
43 torture_result(tctx, TORTURE_FAIL, \
44 "%s: security descriptors don't match!\n", \
45 __location__); \
46 ret = false; \
47 } \
48 } while (0)
50 /**
51 * SMB2 connect with explicit share
52 **/
53 static bool torture_smb2_con_share(struct torture_context *tctx,
54 const char *share,
55 struct smb2_tree **tree)
57 struct smbcli_options options;
58 NTSTATUS status;
59 const char *host = torture_setting_string(tctx, "host", NULL);
60 struct cli_credentials *credentials = cmdline_credentials;
62 lpcfg_smbcli_options(tctx->lp_ctx, &options);
64 status = smb2_connect_ext(tctx,
65 host,
66 lpcfg_smb_ports(tctx->lp_ctx),
67 share,
68 lpcfg_resolve_context(tctx->lp_ctx),
69 credentials,
71 tree,
72 tctx->ev,
73 &options,
74 lpcfg_socket_options(tctx->lp_ctx),
75 lpcfg_gensec_settings(tctx, tctx->lp_ctx)
77 if (!NT_STATUS_IS_OK(status)) {
78 printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
79 host, share, nt_errstr(status));
80 return false;
82 return true;
85 static bool test_default_acl_posix(struct torture_context *tctx,
86 struct smb2_tree *tree_unused)
88 struct smb2_tree *tree = NULL;
89 NTSTATUS status;
90 bool ok;
91 bool ret = true;
92 const char *dname = BASEDIR "\\testdir";
93 const char *fname = BASEDIR "\\testdir\\testfile";
94 struct smb2_handle fhandle, dhandle;
95 union smb_fileinfo q;
96 union smb_setfileinfo set;
97 struct security_descriptor *sd = NULL;
98 struct security_descriptor *exp_sd = NULL;
99 char *owner_sid = NULL;
100 char *group_sid = NULL;
102 ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_posix", &tree);
103 torture_assert_goto(tctx, ok == true, ret, done,
104 "Unable to connect to 'acl_xattr_ign_sysacl_posix'\n");
106 ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
107 torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");
109 ZERO_STRUCT(dhandle);
110 status = torture_smb2_testdir(tree, dname, &dhandle);
111 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");
113 torture_comment(tctx, "Get the original sd\n");
115 ZERO_STRUCT(q);
116 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
117 q.query_secdesc.in.file.handle = dhandle;
118 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
119 status = smb2_getinfo_file(tree, tctx, &q);
120 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
122 sd = q.query_secdesc.out.sd;
123 owner_sid = dom_sid_string(tctx, sd->owner_sid);
124 group_sid = dom_sid_string(tctx, sd->group_sid);
125 torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);
127 torture_comment(tctx, "Set ACL with no inheritable ACE\n");
129 sd = security_descriptor_dacl_create(tctx,
130 0, NULL, NULL,
131 owner_sid,
132 SEC_ACE_TYPE_ACCESS_ALLOWED,
133 SEC_RIGHTS_DIR_ALL,
135 NULL);
137 ZERO_STRUCT(set);
138 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
139 set.set_secdesc.in.file.handle = dhandle;
140 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
141 set.set_secdesc.in.sd = sd;
142 status = smb2_setinfo_file(tree, &set);
143 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");
145 TALLOC_FREE(sd);
146 smb2_util_close(tree, dhandle);
148 torture_comment(tctx, "Create file\n");
150 ZERO_STRUCT(fhandle);
151 status = torture_smb2_testfile(tree, fname, &fhandle);
152 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");
154 torture_comment(tctx, "Query file SD\n");
156 ZERO_STRUCT(q);
157 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
158 q.query_secdesc.in.file.handle = fhandle;
159 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
160 status = smb2_getinfo_file(tree, tctx, &q);
161 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
162 sd = q.query_secdesc.out.sd;
164 smb2_util_close(tree, fhandle);
165 ZERO_STRUCT(fhandle);
167 torture_comment(tctx, "Checking actual file SD against expected SD\n");
169 exp_sd = security_descriptor_dacl_create(
170 tctx, 0, owner_sid, group_sid,
171 owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
172 group_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE, 0,
173 SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE, 0,
174 SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
175 NULL);
177 CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);
179 done:
180 if (!smb2_util_handle_empty(fhandle)) {
181 smb2_util_close(tree, fhandle);
183 if (!smb2_util_handle_empty(dhandle)) {
184 smb2_util_close(tree, dhandle);
186 if (tree != NULL) {
187 smb2_deltree(tree, BASEDIR);
188 smb2_tdis(tree);
191 return ret;
194 static bool test_default_acl_win(struct torture_context *tctx,
195 struct smb2_tree *tree_unused)
197 struct smb2_tree *tree = NULL;
198 NTSTATUS status;
199 bool ok;
200 bool ret = true;
201 const char *dname = BASEDIR "\\testdir";
202 const char *fname = BASEDIR "\\testdir\\testfile";
203 struct smb2_handle fhandle, dhandle;
204 union smb_fileinfo q;
205 union smb_setfileinfo set;
206 struct security_descriptor *sd = NULL;
207 struct security_descriptor *exp_sd = NULL;
208 char *owner_sid = NULL;
209 char *group_sid = NULL;
211 ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_windows", &tree);
212 torture_assert_goto(tctx, ok == true, ret, done,
213 "Unable to connect to 'acl_xattr_ign_sysacl_windows'\n");
215 ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
216 torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");
218 ZERO_STRUCT(dhandle);
219 status = torture_smb2_testdir(tree, dname, &dhandle);
220 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");
222 torture_comment(tctx, "Get the original sd\n");
224 ZERO_STRUCT(q);
225 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
226 q.query_secdesc.in.file.handle = dhandle;
227 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
228 status = smb2_getinfo_file(tree, tctx, &q);
229 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
231 sd = q.query_secdesc.out.sd;
232 owner_sid = dom_sid_string(tctx, sd->owner_sid);
233 group_sid = dom_sid_string(tctx, sd->group_sid);
234 torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);
236 torture_comment(tctx, "Set ACL with no inheritable ACE\n");
238 sd = security_descriptor_dacl_create(tctx,
239 0, NULL, NULL,
240 owner_sid,
241 SEC_ACE_TYPE_ACCESS_ALLOWED,
242 SEC_RIGHTS_DIR_ALL,
244 NULL);
246 ZERO_STRUCT(set);
247 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
248 set.set_secdesc.in.file.handle = dhandle;
249 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
250 set.set_secdesc.in.sd = sd;
251 status = smb2_setinfo_file(tree, &set);
252 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");
254 TALLOC_FREE(sd);
255 smb2_util_close(tree, dhandle);
257 torture_comment(tctx, "Create file\n");
259 ZERO_STRUCT(fhandle);
260 status = torture_smb2_testfile(tree, fname, &fhandle);
261 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");
263 torture_comment(tctx, "Query file SD\n");
265 ZERO_STRUCT(q);
266 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
267 q.query_secdesc.in.file.handle = fhandle;
268 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
269 status = smb2_getinfo_file(tree, tctx, &q);
270 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
271 sd = q.query_secdesc.out.sd;
273 smb2_util_close(tree, fhandle);
274 ZERO_STRUCT(fhandle);
276 torture_comment(tctx, "Checking actual file SD against expected SD\n");
278 exp_sd = security_descriptor_dacl_create(
279 tctx, 0, owner_sid, group_sid,
280 owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
281 SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
282 NULL);
284 CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);
286 done:
287 if (!smb2_util_handle_empty(fhandle)) {
288 smb2_util_close(tree, fhandle);
290 if (!smb2_util_handle_empty(dhandle)) {
291 smb2_util_close(tree, dhandle);
293 if (tree != NULL) {
294 smb2_deltree(tree, BASEDIR);
295 smb2_tdis(tree);
298 return ret;
302 basic testing of vfs_acl_xattr
304 struct torture_suite *torture_acl_xattr(void)
306 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "acl_xattr");
308 torture_suite_add_1smb2_test(suite, "default-acl-style-posix", test_default_acl_posix);
309 torture_suite_add_1smb2_test(suite, "default-acl-style-windows", test_default_acl_win);
311 suite->description = talloc_strdup(suite, "vfs_acl_xattr tests");
313 return suite;