const char **level;
for (level=&OPLOCK_LEVEL[0]; *level; level++) {
const char **shm;
- for (shm=&SHARE_MODE[0]; *shm; shm++) {
+ for (shm=&SHARE_MODE[7]; *shm; shm++) {
ret &= test_open_oplock(tctx, tree, fname,
*level, *shm, persistent);
}
}
+
+struct open_lease_result {
+ const char *type;
+ bool durable;
+ bool persistent;
+};
+
+static struct open_lease_result
+open_lease_result(struct smbXcli_tcon *tcon, const char *type,
+ const char *share_mode, bool persistent)
+{
+ const uint32_t share_capabilities = smb2cli_tcon_capabilities(tcon);
+ const bool share_is_ca = share_capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
+ const bool share_is_sofs = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
+ const bool read = strchr(type, 'R');
+ const bool handle = strchr(type, 'H');
+
+ struct open_lease_result ret = {
+ .type = (share_is_sofs && read) ? "R" : type,
+ .durable = (share_is_ca && persistent) || (!share_is_sofs && handle),
+ .persistent = persistent && share_is_ca,
+ };
+
+ (void)share_mode;
+ return ret;
+}
+
+static bool test_open_lease(struct torture_context *tctx,
+ struct smb2_tree *tree,
+ const char *fname,
+ const char *type,
+ const char *share_mode,
+ bool persistent)
+{
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_handle _h;
+ struct smb2_handle *h = NULL;
+ bool ret = true;
+ struct smb2_create io;
+ struct open_lease_result exp = open_lease_result(tree->smbXcli, type, share_mode, persistent);
+
+ struct smb2_lease ls;
+ uint64_t lease = random();
+
+ torture_result(tctx, TORTURE_OK,
+ "durable_v2_open_lease: type: \"%3s\" shm: \"%3s\" %s",
+ type, share_mode, persistent ? "persistent" : "");
+
+
+ smb2_util_unlink(tree, fname);
+
+ smb2_lease_create_share(&io, &ls, false /* dir */, fname,
+ smb2_util_share_access(share_mode),
+ lease,
+ smb2_util_lease_state(type));
+
+ io.in.durable_open = false;
+ io.in.durable_open_v2 = true;
+ io.in.persistent_open = persistent;
+ io.in.create_guid = GUID_random();
+
+ status = smb2_create(tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ _h = io.out.file.handle;
+ h = &_h;
+
+ CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_VAL(io.out.durable_open, false);
+ CHECK_VAL(io.out.durable_open_v2, exp.durable);
+ CHECK_VAL(io.out.persistent_open, exp.persistent);
+ CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
+ CHECK_VAL(io.out.lease_response.lease_key.data[0], lease);
+ CHECK_VAL(io.out.lease_response.lease_key.data[1], ~lease);
+ CHECK_VAL(io.out.lease_response.lease_state,
+ smb2_util_lease_state(exp.type));
+
+ if (!ret) {
+ torture_result(tctx, TORTURE_FAIL, "durable_v2_open_oplock failed, "
+ "expected durable: %d persistent: %d type \"%s\"",
+ exp.durable, exp.persistent, exp.type);
+ }
+done:
+ if (h != NULL) {
+ smb2_util_close(tree, *h);
+ }
+ smb2_util_unlink(tree, fname);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+static bool test_open_lease_all(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ bool ret = true;
+ uint32_t share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
+ uint32_t server_capabilities = smb2cli_conn_server_capabilities(tree->session->transport->conn);
+ TALLOC_CTX *frame = talloc_stackframe();
+ const char *fname = talloc_asprintf(frame, "open_oplock_all_%s.dat", generate_random_str(frame, 8));
+ int persistent;
+
+ torture_comment(tctx, "server capabilities: 0x%08x\n", server_capabilities);
+ torture_comment(tctx, "share capabilities: 0x%08x\n", share_capabilities);
+
+ for (persistent=0; persistent <2; persistent++) {
+ const char **type;
+ for (type=&LEASE_TYPE[0]; *type; type++) {
+ const char **shm;
+ for (shm=&SHARE_MODE[7]; *shm; shm++) {
+ ret &= test_open_lease(tctx, tree, fname,
+ *type, *shm, persistent);
+ }
+ }
+ }
+ if (!ret) {
+ torture_result(tctx, TORTURE_FAIL, "durable_v2_open_lease_all failed\n");
+ }
+ talloc_free(frame);
+ return ret;
+
+}
+
+
+
struct torture_suite *torture_smb2_durable_v2_open_init(void)
{
struct torture_suite *suite =
torture_suite_add_1smb2_test(suite, "persistent-open-oplock", test_persistent_open_oplock);
torture_suite_add_1smb2_test(suite, "persistent-open-lease", test_persistent_open_lease);
torture_suite_add_1smb2_test(suite, "open-oplock-all", test_open_oplock_all);
+ torture_suite_add_1smb2_test(suite, "open-lease-all", test_open_lease_all);
suite->description = talloc_strdup(suite, "SMB2-DURABLE-V2-OPEN tests");