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 2 : static bool test_default_acl_posix(struct torture_context *tctx,
51 : struct smb2_tree *tree_unused)
52 : {
53 2 : struct smb2_tree *tree = NULL;
54 0 : NTSTATUS status;
55 0 : bool ok;
56 2 : bool ret = true;
57 2 : const char *dname = BASEDIR "\\testdir";
58 2 : const char *fname = BASEDIR "\\testdir\\testfile";
59 2 : struct smb2_handle fhandle = {{0}};
60 2 : struct smb2_handle dhandle = {{0}};
61 0 : union smb_fileinfo q;
62 0 : union smb_setfileinfo set;
63 2 : struct security_descriptor *sd = NULL;
64 2 : struct security_descriptor *exp_sd = NULL;
65 2 : char *owner_sid = NULL;
66 2 : char *group_sid = NULL;
67 :
68 2 : ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_posix", &tree);
69 2 : torture_assert_goto(tctx, ok == true, ret, done,
70 : "Unable to connect to 'acl_xattr_ign_sysacl_posix'\n");
71 :
72 2 : ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
73 2 : torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");
74 :
75 2 : ZERO_STRUCT(dhandle);
76 2 : status = torture_smb2_testdir(tree, dname, &dhandle);
77 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");
78 :
79 2 : torture_comment(tctx, "Get the original sd\n");
80 :
81 2 : ZERO_STRUCT(q);
82 2 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
83 2 : q.query_secdesc.in.file.handle = dhandle;
84 2 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
85 2 : status = smb2_getinfo_file(tree, tctx, &q);
86 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
87 :
88 2 : sd = q.query_secdesc.out.sd;
89 2 : owner_sid = dom_sid_string(tctx, sd->owner_sid);
90 2 : group_sid = dom_sid_string(tctx, sd->group_sid);
91 2 : torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);
92 :
93 2 : torture_comment(tctx, "Set ACL with no inheritable ACE\n");
94 :
95 2 : sd = security_descriptor_dacl_create(tctx,
96 : 0, NULL, NULL,
97 : owner_sid,
98 : SEC_ACE_TYPE_ACCESS_ALLOWED,
99 : SEC_RIGHTS_DIR_ALL,
100 : 0,
101 : NULL);
102 :
103 2 : ZERO_STRUCT(set);
104 2 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
105 2 : set.set_secdesc.in.file.handle = dhandle;
106 2 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
107 2 : set.set_secdesc.in.sd = sd;
108 2 : status = smb2_setinfo_file(tree, &set);
109 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");
110 :
111 2 : TALLOC_FREE(sd);
112 2 : smb2_util_close(tree, dhandle);
113 :
114 2 : torture_comment(tctx, "Create file\n");
115 :
116 2 : ZERO_STRUCT(fhandle);
117 2 : status = torture_smb2_testfile(tree, fname, &fhandle);
118 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");
119 :
120 2 : torture_comment(tctx, "Query file SD\n");
121 :
122 2 : ZERO_STRUCT(q);
123 2 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
124 2 : q.query_secdesc.in.file.handle = fhandle;
125 2 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
126 2 : status = smb2_getinfo_file(tree, tctx, &q);
127 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
128 2 : sd = q.query_secdesc.out.sd;
129 :
130 2 : smb2_util_close(tree, fhandle);
131 2 : ZERO_STRUCT(fhandle);
132 :
133 2 : torture_comment(tctx, "Checking actual file SD against expected SD\n");
134 :
135 2 : exp_sd = security_descriptor_dacl_create(
136 : tctx, 0, owner_sid, group_sid,
137 : owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
138 : group_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
139 : SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
140 : SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
141 : NULL);
142 :
143 2 : CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);
144 :
145 2 : done:
146 2 : if (!smb2_util_handle_empty(fhandle)) {
147 0 : smb2_util_close(tree, fhandle);
148 : }
149 2 : if (!smb2_util_handle_empty(dhandle)) {
150 2 : smb2_util_close(tree, dhandle);
151 : }
152 2 : if (tree != NULL) {
153 2 : smb2_deltree(tree, BASEDIR);
154 2 : smb2_tdis(tree);
155 : }
156 :
157 2 : return ret;
158 : }
159 :
160 2 : static bool test_default_acl_win(struct torture_context *tctx,
161 : struct smb2_tree *tree_unused)
162 : {
163 2 : struct smb2_tree *tree = NULL;
164 0 : NTSTATUS status;
165 0 : bool ok;
166 2 : bool ret = true;
167 2 : const char *dname = BASEDIR "\\testdir";
168 2 : const char *fname = BASEDIR "\\testdir\\testfile";
169 2 : struct smb2_handle fhandle = {{0}};
170 2 : struct smb2_handle dhandle = {{0}};
171 0 : union smb_fileinfo q;
172 0 : union smb_setfileinfo set;
173 2 : struct security_descriptor *sd = NULL;
174 2 : struct security_descriptor *exp_sd = NULL;
175 2 : char *owner_sid = NULL;
176 2 : char *group_sid = NULL;
177 :
178 2 : ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_windows", &tree);
179 2 : torture_assert_goto(tctx, ok == true, ret, done,
180 : "Unable to connect to 'acl_xattr_ign_sysacl_windows'\n");
181 :
182 2 : ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
183 2 : torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");
184 :
185 2 : ZERO_STRUCT(dhandle);
186 2 : status = torture_smb2_testdir(tree, dname, &dhandle);
187 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");
188 :
189 2 : torture_comment(tctx, "Get the original sd\n");
190 :
191 2 : ZERO_STRUCT(q);
192 2 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
193 2 : q.query_secdesc.in.file.handle = dhandle;
194 2 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
195 2 : status = smb2_getinfo_file(tree, tctx, &q);
196 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
197 :
198 2 : sd = q.query_secdesc.out.sd;
199 2 : owner_sid = dom_sid_string(tctx, sd->owner_sid);
200 2 : group_sid = dom_sid_string(tctx, sd->group_sid);
201 2 : torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);
202 :
203 2 : torture_comment(tctx, "Set ACL with no inheritable ACE\n");
204 :
205 2 : sd = security_descriptor_dacl_create(tctx,
206 : 0, NULL, NULL,
207 : owner_sid,
208 : SEC_ACE_TYPE_ACCESS_ALLOWED,
209 : SEC_RIGHTS_DIR_ALL,
210 : 0,
211 : NULL);
212 :
213 2 : ZERO_STRUCT(set);
214 2 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
215 2 : set.set_secdesc.in.file.handle = dhandle;
216 2 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
217 2 : set.set_secdesc.in.sd = sd;
218 2 : status = smb2_setinfo_file(tree, &set);
219 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");
220 :
221 2 : TALLOC_FREE(sd);
222 2 : smb2_util_close(tree, dhandle);
223 :
224 2 : torture_comment(tctx, "Create file\n");
225 :
226 2 : ZERO_STRUCT(fhandle);
227 2 : status = torture_smb2_testfile(tree, fname, &fhandle);
228 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");
229 :
230 2 : torture_comment(tctx, "Query file SD\n");
231 :
232 2 : ZERO_STRUCT(q);
233 2 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
234 2 : q.query_secdesc.in.file.handle = fhandle;
235 2 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
236 2 : status = smb2_getinfo_file(tree, tctx, &q);
237 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
238 2 : sd = q.query_secdesc.out.sd;
239 :
240 2 : smb2_util_close(tree, fhandle);
241 2 : ZERO_STRUCT(fhandle);
242 :
243 2 : torture_comment(tctx, "Checking actual file SD against expected SD\n");
244 :
245 2 : exp_sd = security_descriptor_dacl_create(
246 : tctx, 0, owner_sid, group_sid,
247 : owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
248 : SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
249 : NULL);
250 :
251 2 : CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);
252 :
253 2 : done:
254 2 : if (!smb2_util_handle_empty(fhandle)) {
255 0 : smb2_util_close(tree, fhandle);
256 : }
257 2 : if (!smb2_util_handle_empty(dhandle)) {
258 2 : smb2_util_close(tree, dhandle);
259 : }
260 2 : if (tree != NULL) {
261 2 : smb2_deltree(tree, BASEDIR);
262 2 : smb2_tdis(tree);
263 : }
264 :
265 2 : return ret;
266 : }
267 :
268 : /*
269 : basic testing of vfs_acl_xattr
270 : */
271 2354 : struct torture_suite *torture_acl_xattr(TALLOC_CTX *ctx)
272 : {
273 2354 : struct torture_suite *suite = torture_suite_create(ctx, "acl_xattr");
274 :
275 2354 : torture_suite_add_1smb2_test(suite, "default-acl-style-posix", test_default_acl_posix);
276 2354 : torture_suite_add_1smb2_test(suite, "default-acl-style-windows", test_default_acl_win);
277 :
278 2354 : suite->description = talloc_strdup(suite, "vfs_acl_xattr tests");
279 :
280 2354 : return suite;
281 : }
|