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
);
61 lpcfg_smbcli_options(tctx
->lp_ctx
, &options
);
63 status
= smb2_connect_ext(tctx
,
65 lpcfg_smb_ports(tctx
->lp_ctx
),
67 lpcfg_resolve_context(tctx
->lp_ctx
),
68 popt_get_cmdline_credentials(),
73 lpcfg_socket_options(tctx
->lp_ctx
),
74 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
)
76 if (!NT_STATUS_IS_OK(status
)) {
77 printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
78 host
, share
, nt_errstr(status
));
84 static bool test_default_acl_posix(struct torture_context
*tctx
,
85 struct smb2_tree
*tree_unused
)
87 struct smb2_tree
*tree
= NULL
;
91 const char *dname
= BASEDIR
"\\testdir";
92 const char *fname
= BASEDIR
"\\testdir\\testfile";
93 struct smb2_handle fhandle
= {{0}};
94 struct smb2_handle dhandle
= {{0}};
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
, 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,
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
= {{0}};
204 struct smb2_handle dhandle
= {{0}};
205 union smb_fileinfo q
;
206 union smb_setfileinfo set
;
207 struct security_descriptor
*sd
= NULL
;
208 struct security_descriptor
*exp_sd
= NULL
;
209 char *owner_sid
= NULL
;
210 char *group_sid
= NULL
;
212 ok
= torture_smb2_con_share(tctx
, "acl_xattr_ign_sysacl_windows", &tree
);
213 torture_assert_goto(tctx
, ok
== true, ret
, done
,
214 "Unable to connect to 'acl_xattr_ign_sysacl_windows'\n");
216 ok
= smb2_util_setup_dir(tctx
, tree
, BASEDIR
);
217 torture_assert_goto(tctx
, ok
== true, ret
, done
, "Unable to setup testdir\n");
219 ZERO_STRUCT(dhandle
);
220 status
= torture_smb2_testdir(tree
, dname
, &dhandle
);
221 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "torture_smb2_testdir\n");
223 torture_comment(tctx
, "Get the original sd\n");
226 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
227 q
.query_secdesc
.in
.file
.handle
= dhandle
;
228 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
| SECINFO_GROUP
;
229 status
= smb2_getinfo_file(tree
, tctx
, &q
);
230 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_getinfo_file\n");
232 sd
= q
.query_secdesc
.out
.sd
;
233 owner_sid
= dom_sid_string(tctx
, sd
->owner_sid
);
234 group_sid
= dom_sid_string(tctx
, sd
->group_sid
);
235 torture_comment(tctx
, "owner [%s] group [%s]\n", owner_sid
, group_sid
);
237 torture_comment(tctx
, "Set ACL with no inheritable ACE\n");
239 sd
= security_descriptor_dacl_create(tctx
,
242 SEC_ACE_TYPE_ACCESS_ALLOWED
,
248 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
249 set
.set_secdesc
.in
.file
.handle
= dhandle
;
250 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
251 set
.set_secdesc
.in
.sd
= sd
;
252 status
= smb2_setinfo_file(tree
, &set
);
253 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_setinfo_file\n");
256 smb2_util_close(tree
, dhandle
);
258 torture_comment(tctx
, "Create file\n");
260 ZERO_STRUCT(fhandle
);
261 status
= torture_smb2_testfile(tree
, fname
, &fhandle
);
262 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_create_complex_file\n");
264 torture_comment(tctx
, "Query file SD\n");
267 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
268 q
.query_secdesc
.in
.file
.handle
= fhandle
;
269 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
| SECINFO_GROUP
;
270 status
= smb2_getinfo_file(tree
, tctx
, &q
);
271 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
, "smb2_getinfo_file\n");
272 sd
= q
.query_secdesc
.out
.sd
;
274 smb2_util_close(tree
, fhandle
);
275 ZERO_STRUCT(fhandle
);
277 torture_comment(tctx
, "Checking actual file SD against expected SD\n");
279 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,
285 CHECK_SECURITY_DESCRIPTOR(sd
, exp_sd
);
288 if (!smb2_util_handle_empty(fhandle
)) {
289 smb2_util_close(tree
, fhandle
);
291 if (!smb2_util_handle_empty(dhandle
)) {
292 smb2_util_close(tree
, dhandle
);
295 smb2_deltree(tree
, BASEDIR
);
303 basic testing of vfs_acl_xattr
305 struct torture_suite
*torture_acl_xattr(TALLOC_CTX
*ctx
)
307 struct torture_suite
*suite
= torture_suite_create(ctx
, "acl_xattr");
309 torture_suite_add_1smb2_test(suite
, "default-acl-style-posix", test_default_acl_posix
);
310 torture_suite_add_1smb2_test(suite
, "default-acl-style-windows", test_default_acl_win
);
312 suite
->description
= talloc_strdup(suite
, "vfs_acl_xattr tests");