2 Unix SMB/CIFS implementation.
4 test suite for SMB2 resilient opens
6 Copyright (C) Stefan Metzmacher 2008
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include "torture/torture.h"
26 #include "torture/smb2/proto.h"
28 #define CHECK_VAL(v, correct) do { \
29 if ((v) != (correct)) { \
30 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
31 __location__, #v, (int)v, (int)correct); \
35 #define CHECK_STATUS(status, correct) do { \
36 if (!NT_STATUS_EQUAL(status, correct)) { \
37 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
38 nt_errstr(status), nt_errstr(correct)); \
43 #define CHECK_CREATED(__io, __created, __attribute) \
45 CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \
46 CHECK_VAL((__io)->out.alloc_size, 0); \
47 CHECK_VAL((__io)->out.size, 0); \
48 CHECK_VAL((__io)->out.file_attr, (__attribute)); \
49 CHECK_VAL((__io)->out.reserved2, 0); \
53 static inline uint32_t map_lease(const char *ls)
58 for (i = 0; i < strlen(ls); i++) {
61 val |= SMB2_LEASE_READ;
64 val |= SMB2_LEASE_HANDLE;
67 val |= SMB2_LEASE_WRITE;
75 static inline uint32_t map_sharemode(const char *sharemode)
77 uint32_t val = NTCREATEX_SHARE_ACCESS_NONE; /* 0 */
80 for (i = 0; i < strlen(sharemode); i++) {
81 switch(sharemode[i]) {
83 val |= NTCREATEX_SHARE_ACCESS_READ;
86 val |= NTCREATEX_SHARE_ACCESS_WRITE;
89 val |= NTCREATEX_SHARE_ACCESS_DELETE;
98 * basic durable_open test.
99 * durable state should only be granted when requested
100 * along with a batch oplock or a handle lease.
102 * This test tests durable open with all possible oplock types.
105 bool test_resilient_open_open1(struct torture_context *tctx,
106 struct smb2_tree *tree)
108 TALLOC_CTX *mem_ctx = talloc_new(tctx);
109 struct smb2_create cr;
110 struct smb2_ioctl io;
115 struct smb2_handle _h;
116 struct smb2_handle *h = NULL;
117 uint8_t resiliency[8];
118 struct smb2_lease ls;
120 /* Choose a random name in case the state is left a little funky. */
121 snprintf(fname, 256, "resilient_open_open1_%s.dat",
122 generate_random_str(tctx, 8));
124 smb2_util_unlink(tree, fname);
127 memset(&ls.lease_key, 0xef, sizeof(ls.lease_key));
128 ls.lease_state = SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE;
131 cr.in.security_flags = 0x00;
132 cr.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
133 cr.in.create_flags = 0x00000000;
134 cr.in.reserved = 0x00000000;
135 cr.in.desired_access = SEC_RIGHTS_FILE_ALL;
136 cr.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
137 cr.in.create_disposition = NTCREATEX_DISP_CREATE;
138 cr.in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
139 NTCREATEX_OPTIONS_ASYNC_ALERT |
140 NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
142 NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
143 cr.in.durable_open = false;
145 cr.in.share_access = map_sharemode("RWD");
146 cr.in.oplock_level = SMB2_OPLOCK_LEVEL_LEASE;
147 cr.in.lease_request = &ls;
149 status = smb2_create(tree, mem_ctx, &cr);
150 CHECK_STATUS(status, NT_STATUS_OK);
151 _h = cr.out.file.handle;
153 CHECK_CREATED(&cr, CREATED, FILE_ATTRIBUTE_ARCHIVE);
154 CHECK_VAL(cr.out.durable_open, false);
155 CHECK_VAL(cr.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
157 SIVAL(resiliency, 0, 60*1000);
158 SIVAL(resiliency, 4, 0);
161 io.level = RAW_IOCTL_SMB2;
162 io.in.file.handle = *h;
163 io.in.function = FSCTL_LMR_REQ_RESILIENCY;
164 io.in.max_response_size = 0;
165 io.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
166 io.in.in = data_blob_const(resiliency, ARRAY_SIZE(resiliency));
167 io.in.out = data_blob_const(resiliency, ARRAY_SIZE(resiliency));
169 status = smb2_ioctl(tree, mem_ctx, &io);
170 CHECK_STATUS(status, NT_STATUS_OK);
174 smb2_util_close(tree, *h);
176 talloc_free(mem_ctx);
181 struct torture_suite *torture_smb2_resilient_open_init(void)
183 struct torture_suite *suite =
184 torture_suite_create(talloc_autofree_context(), "resilient-open");
186 torture_suite_add_1smb2_test(suite, "open1", test_resilient_open_open1);
188 suite->description = talloc_strdup(suite, "SMB2-RESILIENT-OPEN tests");