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/>.
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", \
51 * SMB2 connect with explicit share
53 static bool torture_smb2_con_share(struct torture_context
*tctx
,
55 struct smb2_tree
**tree
)
57 struct smbcli_options options
;
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
,
66 lpcfg_smb_ports(tctx
->lp_ctx
),
68 lpcfg_resolve_context(tctx
->lp_ctx
),
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
));
85 static bool test_default_acl_posix(struct torture_context
*tctx
,
86 struct smb2_tree
*tree_unused
)
88 struct smb2_tree
*tree
= NULL
;
92 const char *dname
= BASEDIR
"\\testdir";
93 const char *fname
= BASEDIR
"\\testdir\\testfile";
94 struct smb2_handle fhandle
, dhandle
;
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");
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
,
132 SEC_ACE_TYPE_ACCESS_ALLOWED
,
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");
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");
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,
177 CHECK_SECURITY_DESCRIPTOR(sd
, exp_sd
);
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
);
187 smb2_deltree(tree
, BASEDIR
);
194 static bool test_default_acl_win(struct torture_context
*tctx
,
195 struct smb2_tree
*tree_unused
)
197 struct smb2_tree
*tree
= NULL
;
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");
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
,
241 SEC_ACE_TYPE_ACCESS_ALLOWED
,
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");
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");
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,
284 CHECK_SECURITY_DESCRIPTOR(sd
, exp_sd
);
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
);
294 smb2_deltree(tree
, BASEDIR
);
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");