Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Copyright (C) Ralph Boehme 2016
5 :
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.
10 :
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.
15 :
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/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "lib/cmdline/cmdline.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"
33 :
34 : #define BASEDIR "smb2-testsd"
35 :
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)
49 :
50 : /**
51 : * SMB2 connect with explicit share
52 : **/
53 4 : static bool torture_smb2_con_share(struct torture_context *tctx,
54 : const char *share,
55 : struct smb2_tree **tree)
56 : {
57 : struct smbcli_options options;
58 : NTSTATUS status;
59 4 : const char *host = torture_setting_string(tctx, "host", NULL);
60 :
61 4 : lpcfg_smbcli_options(tctx->lp_ctx, &options);
62 :
63 4 : status = smb2_connect_ext(tctx,
64 : host,
65 : lpcfg_smb_ports(tctx->lp_ctx),
66 : share,
67 : lpcfg_resolve_context(tctx->lp_ctx),
68 : samba_cmdline_get_creds(),
69 : 0,
70 : tree,
71 : tctx->ev,
72 : &options,
73 : lpcfg_socket_options(tctx->lp_ctx),
74 : lpcfg_gensec_settings(tctx, tctx->lp_ctx)
75 : );
76 4 : if (!NT_STATUS_IS_OK(status)) {
77 0 : printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
78 : host, share, nt_errstr(status));
79 0 : return false;
80 : }
81 4 : return true;
82 : }
83 :
84 2 : static bool test_default_acl_posix(struct torture_context *tctx,
85 : struct smb2_tree *tree_unused)
86 : {
87 2 : struct smb2_tree *tree = NULL;
88 : NTSTATUS status;
89 : bool ok;
90 2 : bool ret = true;
91 2 : const char *dname = BASEDIR "\\testdir";
92 2 : const char *fname = BASEDIR "\\testdir\\testfile";
93 2 : struct smb2_handle fhandle = {{0}};
94 2 : struct smb2_handle dhandle = {{0}};
95 : union smb_fileinfo q;
96 : union smb_setfileinfo set;
97 2 : struct security_descriptor *sd = NULL;
98 2 : struct security_descriptor *exp_sd = NULL;
99 2 : char *owner_sid = NULL;
100 2 : char *group_sid = NULL;
101 :
102 2 : ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_posix", &tree);
103 2 : torture_assert_goto(tctx, ok == true, ret, done,
104 : "Unable to connect to 'acl_xattr_ign_sysacl_posix'\n");
105 :
106 2 : ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
107 2 : torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");
108 :
109 2 : ZERO_STRUCT(dhandle);
110 2 : status = torture_smb2_testdir(tree, dname, &dhandle);
111 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");
112 :
113 2 : torture_comment(tctx, "Get the original sd\n");
114 :
115 2 : ZERO_STRUCT(q);
116 2 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
117 2 : q.query_secdesc.in.file.handle = dhandle;
118 2 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
119 2 : status = smb2_getinfo_file(tree, tctx, &q);
120 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
121 :
122 2 : sd = q.query_secdesc.out.sd;
123 2 : owner_sid = dom_sid_string(tctx, sd->owner_sid);
124 2 : group_sid = dom_sid_string(tctx, sd->group_sid);
125 2 : torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);
126 :
127 2 : torture_comment(tctx, "Set ACL with no inheritable ACE\n");
128 :
129 2 : sd = security_descriptor_dacl_create(tctx,
130 : 0, NULL, NULL,
131 : owner_sid,
132 : SEC_ACE_TYPE_ACCESS_ALLOWED,
133 : SEC_RIGHTS_DIR_ALL,
134 : 0,
135 : NULL);
136 :
137 2 : ZERO_STRUCT(set);
138 2 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
139 2 : set.set_secdesc.in.file.handle = dhandle;
140 2 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
141 2 : set.set_secdesc.in.sd = sd;
142 2 : status = smb2_setinfo_file(tree, &set);
143 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");
144 :
145 2 : TALLOC_FREE(sd);
146 2 : smb2_util_close(tree, dhandle);
147 :
148 2 : torture_comment(tctx, "Create file\n");
149 :
150 2 : ZERO_STRUCT(fhandle);
151 2 : status = torture_smb2_testfile(tree, fname, &fhandle);
152 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");
153 :
154 2 : torture_comment(tctx, "Query file SD\n");
155 :
156 2 : ZERO_STRUCT(q);
157 2 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
158 2 : q.query_secdesc.in.file.handle = fhandle;
159 2 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
160 2 : status = smb2_getinfo_file(tree, tctx, &q);
161 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
162 2 : sd = q.query_secdesc.out.sd;
163 :
164 2 : smb2_util_close(tree, fhandle);
165 2 : ZERO_STRUCT(fhandle);
166 :
167 2 : torture_comment(tctx, "Checking actual file SD against expected SD\n");
168 :
169 2 : 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, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
173 : SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
174 : SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
175 : NULL);
176 :
177 2 : CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);
178 :
179 4 : done:
180 2 : if (!smb2_util_handle_empty(fhandle)) {
181 0 : smb2_util_close(tree, fhandle);
182 : }
183 2 : if (!smb2_util_handle_empty(dhandle)) {
184 2 : smb2_util_close(tree, dhandle);
185 : }
186 2 : if (tree != NULL) {
187 2 : smb2_deltree(tree, BASEDIR);
188 2 : smb2_tdis(tree);
189 : }
190 :
191 2 : return ret;
192 : }
193 :
194 2 : static bool test_default_acl_win(struct torture_context *tctx,
195 : struct smb2_tree *tree_unused)
196 : {
197 2 : struct smb2_tree *tree = NULL;
198 : NTSTATUS status;
199 : bool ok;
200 2 : bool ret = true;
201 2 : const char *dname = BASEDIR "\\testdir";
202 2 : const char *fname = BASEDIR "\\testdir\\testfile";
203 2 : struct smb2_handle fhandle = {{0}};
204 2 : struct smb2_handle dhandle = {{0}};
205 : union smb_fileinfo q;
206 : union smb_setfileinfo set;
207 2 : struct security_descriptor *sd = NULL;
208 2 : struct security_descriptor *exp_sd = NULL;
209 2 : char *owner_sid = NULL;
210 2 : char *group_sid = NULL;
211 :
212 2 : ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_windows", &tree);
213 2 : torture_assert_goto(tctx, ok == true, ret, done,
214 : "Unable to connect to 'acl_xattr_ign_sysacl_windows'\n");
215 :
216 2 : ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
217 2 : torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");
218 :
219 2 : ZERO_STRUCT(dhandle);
220 2 : status = torture_smb2_testdir(tree, dname, &dhandle);
221 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");
222 :
223 2 : torture_comment(tctx, "Get the original sd\n");
224 :
225 2 : ZERO_STRUCT(q);
226 2 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
227 2 : q.query_secdesc.in.file.handle = dhandle;
228 2 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
229 2 : status = smb2_getinfo_file(tree, tctx, &q);
230 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
231 :
232 2 : sd = q.query_secdesc.out.sd;
233 2 : owner_sid = dom_sid_string(tctx, sd->owner_sid);
234 2 : group_sid = dom_sid_string(tctx, sd->group_sid);
235 2 : torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);
236 :
237 2 : torture_comment(tctx, "Set ACL with no inheritable ACE\n");
238 :
239 2 : sd = security_descriptor_dacl_create(tctx,
240 : 0, NULL, NULL,
241 : owner_sid,
242 : SEC_ACE_TYPE_ACCESS_ALLOWED,
243 : SEC_RIGHTS_DIR_ALL,
244 : 0,
245 : NULL);
246 :
247 2 : ZERO_STRUCT(set);
248 2 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
249 2 : set.set_secdesc.in.file.handle = dhandle;
250 2 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
251 2 : set.set_secdesc.in.sd = sd;
252 2 : status = smb2_setinfo_file(tree, &set);
253 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");
254 :
255 2 : TALLOC_FREE(sd);
256 2 : smb2_util_close(tree, dhandle);
257 :
258 2 : torture_comment(tctx, "Create file\n");
259 :
260 2 : ZERO_STRUCT(fhandle);
261 2 : status = torture_smb2_testfile(tree, fname, &fhandle);
262 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");
263 :
264 2 : torture_comment(tctx, "Query file SD\n");
265 :
266 2 : ZERO_STRUCT(q);
267 2 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
268 2 : q.query_secdesc.in.file.handle = fhandle;
269 2 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
270 2 : status = smb2_getinfo_file(tree, tctx, &q);
271 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
272 2 : sd = q.query_secdesc.out.sd;
273 :
274 2 : smb2_util_close(tree, fhandle);
275 2 : ZERO_STRUCT(fhandle);
276 :
277 2 : torture_comment(tctx, "Checking actual file SD against expected SD\n");
278 :
279 2 : exp_sd = security_descriptor_dacl_create(
280 : tctx, 0, owner_sid, group_sid,
281 : owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
282 : SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
283 : NULL);
284 :
285 2 : CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);
286 :
287 4 : done:
288 2 : if (!smb2_util_handle_empty(fhandle)) {
289 0 : smb2_util_close(tree, fhandle);
290 : }
291 2 : if (!smb2_util_handle_empty(dhandle)) {
292 2 : smb2_util_close(tree, dhandle);
293 : }
294 2 : if (tree != NULL) {
295 2 : smb2_deltree(tree, BASEDIR);
296 2 : smb2_tdis(tree);
297 : }
298 :
299 2 : return ret;
300 : }
301 :
302 : /*
303 : basic testing of vfs_acl_xattr
304 : */
305 2355 : struct torture_suite *torture_acl_xattr(TALLOC_CTX *ctx)
306 : {
307 2355 : struct torture_suite *suite = torture_suite_create(ctx, "acl_xattr");
308 :
309 2355 : torture_suite_add_1smb2_test(suite, "default-acl-style-posix", test_default_acl_posix);
310 2355 : torture_suite_add_1smb2_test(suite, "default-acl-style-windows", test_default_acl_win);
311 :
312 2355 : suite->description = talloc_strdup(suite, "vfs_acl_xattr tests");
313 :
314 2355 : return suite;
315 : }
|