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
= {{0}};
95 struct smb2_handle dhandle
= {{0}};
97 union smb_setfileinfo set
;
98 struct security_descriptor
*sd
= NULL
;
99 struct security_descriptor
*exp_sd
= NULL
;
100 char *owner_sid
= NULL
;
101 char *group_sid
= NULL
;
103 ok
= torture_smb2_con_share(tctx
, "acl_xattr_ign_sysacl_posix", &tree
);
104 torture_assert_goto(tctx
, ok
== true, ret
, done
,
105 "Unable to connect to 'acl_xattr_ign_sysacl_posix'\n");
107 ok
= smb2_util_setup_dir(tctx
, tree
, BASEDIR
);
108 torture_assert_goto(tctx
, ok
== true, ret
, done
, "Unable to setup testdir\n");
110 ZERO_STRUCT(dhandle
);
111 status
= torture_smb2_testdir(tree
, dname
, &dhandle
);
112 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "torture_smb2_testdir\n");
114 torture_comment(tctx
, "Get the original sd\n");
117 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
118 q
.query_secdesc
.in
.file
.handle
= dhandle
;
119 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
| SECINFO_GROUP
;
120 status
= smb2_getinfo_file(tree
, tctx
, &q
);
121 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_getinfo_file\n");
123 sd
= q
.query_secdesc
.out
.sd
;
124 owner_sid
= dom_sid_string(tctx
, sd
->owner_sid
);
125 group_sid
= dom_sid_string(tctx
, sd
->group_sid
);
126 torture_comment(tctx
, "owner [%s] group [%s]\n", owner_sid
, group_sid
);
128 torture_comment(tctx
, "Set ACL with no inheritable ACE\n");
130 sd
= security_descriptor_dacl_create(tctx
,
133 SEC_ACE_TYPE_ACCESS_ALLOWED
,
139 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
140 set
.set_secdesc
.in
.file
.handle
= dhandle
;
141 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
142 set
.set_secdesc
.in
.sd
= sd
;
143 status
= smb2_setinfo_file(tree
, &set
);
144 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_setinfo_file\n");
147 smb2_util_close(tree
, dhandle
);
149 torture_comment(tctx
, "Create file\n");
151 ZERO_STRUCT(fhandle
);
152 status
= torture_smb2_testfile(tree
, fname
, &fhandle
);
153 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_create_complex_file\n");
155 torture_comment(tctx
, "Query file SD\n");
158 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
159 q
.query_secdesc
.in
.file
.handle
= fhandle
;
160 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
| SECINFO_GROUP
;
161 status
= smb2_getinfo_file(tree
, tctx
, &q
);
162 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_getinfo_file\n");
163 sd
= q
.query_secdesc
.out
.sd
;
165 smb2_util_close(tree
, fhandle
);
166 ZERO_STRUCT(fhandle
);
168 torture_comment(tctx
, "Checking actual file SD against expected SD\n");
170 exp_sd
= security_descriptor_dacl_create(
171 tctx
, 0, owner_sid
, group_sid
,
172 owner_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, SEC_RIGHTS_FILE_ALL
, 0,
173 group_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, FILE_GENERIC_READ
|FILE_GENERIC_WRITE
|FILE_GENERIC_EXECUTE
, 0,
174 SID_WORLD
, SEC_ACE_TYPE_ACCESS_ALLOWED
, FILE_GENERIC_READ
|FILE_GENERIC_WRITE
|FILE_GENERIC_EXECUTE
, 0,
175 SID_NT_SYSTEM
, SEC_ACE_TYPE_ACCESS_ALLOWED
, SEC_RIGHTS_FILE_ALL
, 0,
178 CHECK_SECURITY_DESCRIPTOR(sd
, exp_sd
);
181 if (!smb2_util_handle_empty(fhandle
)) {
182 smb2_util_close(tree
, fhandle
);
184 if (!smb2_util_handle_empty(dhandle
)) {
185 smb2_util_close(tree
, dhandle
);
188 smb2_deltree(tree
, BASEDIR
);
195 static bool test_default_acl_win(struct torture_context
*tctx
,
196 struct smb2_tree
*tree_unused
)
198 struct smb2_tree
*tree
= NULL
;
202 const char *dname
= BASEDIR
"\\testdir";
203 const char *fname
= BASEDIR
"\\testdir\\testfile";
204 struct smb2_handle fhandle
= {{0}};
205 struct smb2_handle dhandle
= {{0}};
206 union smb_fileinfo q
;
207 union smb_setfileinfo set
;
208 struct security_descriptor
*sd
= NULL
;
209 struct security_descriptor
*exp_sd
= NULL
;
210 char *owner_sid
= NULL
;
211 char *group_sid
= NULL
;
213 ok
= torture_smb2_con_share(tctx
, "acl_xattr_ign_sysacl_windows", &tree
);
214 torture_assert_goto(tctx
, ok
== true, ret
, done
,
215 "Unable to connect to 'acl_xattr_ign_sysacl_windows'\n");
217 ok
= smb2_util_setup_dir(tctx
, tree
, BASEDIR
);
218 torture_assert_goto(tctx
, ok
== true, ret
, done
, "Unable to setup testdir\n");
220 ZERO_STRUCT(dhandle
);
221 status
= torture_smb2_testdir(tree
, dname
, &dhandle
);
222 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "torture_smb2_testdir\n");
224 torture_comment(tctx
, "Get the original sd\n");
227 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
228 q
.query_secdesc
.in
.file
.handle
= dhandle
;
229 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
| SECINFO_GROUP
;
230 status
= smb2_getinfo_file(tree
, tctx
, &q
);
231 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_getinfo_file\n");
233 sd
= q
.query_secdesc
.out
.sd
;
234 owner_sid
= dom_sid_string(tctx
, sd
->owner_sid
);
235 group_sid
= dom_sid_string(tctx
, sd
->group_sid
);
236 torture_comment(tctx
, "owner [%s] group [%s]\n", owner_sid
, group_sid
);
238 torture_comment(tctx
, "Set ACL with no inheritable ACE\n");
240 sd
= security_descriptor_dacl_create(tctx
,
243 SEC_ACE_TYPE_ACCESS_ALLOWED
,
249 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
250 set
.set_secdesc
.in
.file
.handle
= dhandle
;
251 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
252 set
.set_secdesc
.in
.sd
= sd
;
253 status
= smb2_setinfo_file(tree
, &set
);
254 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_setinfo_file\n");
257 smb2_util_close(tree
, dhandle
);
259 torture_comment(tctx
, "Create file\n");
261 ZERO_STRUCT(fhandle
);
262 status
= torture_smb2_testfile(tree
, fname
, &fhandle
);
263 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_create_complex_file\n");
265 torture_comment(tctx
, "Query file SD\n");
268 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
269 q
.query_secdesc
.in
.file
.handle
= fhandle
;
270 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
| SECINFO_GROUP
;
271 status
= smb2_getinfo_file(tree
, tctx
, &q
);
272 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_getinfo_file\n");
273 sd
= q
.query_secdesc
.out
.sd
;
275 smb2_util_close(tree
, fhandle
);
276 ZERO_STRUCT(fhandle
);
278 torture_comment(tctx
, "Checking actual file SD against expected SD\n");
280 exp_sd
= security_descriptor_dacl_create(
281 tctx
, 0, owner_sid
, group_sid
,
282 owner_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, SEC_RIGHTS_FILE_ALL
, 0,
283 SID_NT_SYSTEM
, SEC_ACE_TYPE_ACCESS_ALLOWED
, SEC_RIGHTS_FILE_ALL
, 0,
286 CHECK_SECURITY_DESCRIPTOR(sd
, exp_sd
);
289 if (!smb2_util_handle_empty(fhandle
)) {
290 smb2_util_close(tree
, fhandle
);
292 if (!smb2_util_handle_empty(dhandle
)) {
293 smb2_util_close(tree
, dhandle
);
296 smb2_deltree(tree
, BASEDIR
);
304 basic testing of vfs_acl_xattr
306 struct torture_suite
*torture_acl_xattr(void)
308 struct torture_suite
*suite
= torture_suite_create(talloc_autofree_context(), "acl_xattr");
310 torture_suite_add_1smb2_test(suite
, "default-acl-style-posix", test_default_acl_posix
);
311 torture_suite_add_1smb2_test(suite
, "default-acl-style-windows", test_default_acl_win
);
313 suite
->description
= talloc_strdup(suite
, "vfs_acl_xattr tests");