return ret;
}
+static const char* OPLOCK_LEVEL[] = {"", "s", "x", "b", NULL};
+static const char* LEASE_TYPE[] = {"", "R", "RW", "RH", "RWH", NULL};
+static const char* SHARE_MODE[] = {"", "R", "W", "D", "RD", "RW", "WD", "RWD", NULL};
+
+struct open_oplock_result {
+ const char *level;
+ bool durable;
+ bool persistent;
+};
+
+static struct open_oplock_result
+open_oplock_result(struct smbXcli_tcon *tcon, const char *level,
+ 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 batch = (level[0] == 'b');
+
+ struct open_oplock_result ret = {
+ .level = (share_is_sofs && batch) ? "s" : level,
+ .durable = (share_is_ca && persistent) || (!share_is_sofs && batch),
+ .persistent = persistent && share_is_ca,
+ };
+
+ (void)share_mode;
+ return ret;
+}
+
+static bool test_open_oplock(struct torture_context *tctx,
+ struct smb2_tree *tree,
+ const char *fname,
+ const char *level,
+ 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_oplock_result exp = open_oplock_result(tree->smbXcli, level, share_mode, persistent);
+
+ torture_result(tctx, TORTURE_OK,
+ "durable_v2_open_oplock: level: \"%3s\" shm: \"%3s\" %s",
+ level, share_mode, persistent ? "persistent" : "");
+
+
+ smb2_util_unlink(tree, fname);
+
+ smb2_oplock_create_share(&io, fname,
+ smb2_util_share_access(share_mode),
+ smb2_util_oplock_level(level));
+ 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_util_oplock_level(exp.level));
+
+ if (!ret) {
+ torture_result(tctx, TORTURE_FAIL, "durable_v2_open_oplock failed, "
+ "expected durable: %d persistent: %d level \"%s\"",
+ exp.durable, exp.persistent, exp.level);
+ }
+done:
+ if (h != NULL) {
+ smb2_util_close(tree, *h);
+ }
+ smb2_util_unlink(tree, fname);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+static bool test_open_oplock_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 **level;
+ for (level=&OPLOCK_LEVEL[0]; *level; level++) {
+ const char **shm;
+ for (shm=&SHARE_MODE[0]; *shm; shm++) {
+ ret &= test_open_oplock(tctx, tree, fname,
+ *level, *shm, persistent);
+ }
+ }
+ }
+ if (!ret) {
+ torture_result(tctx, TORTURE_FAIL, "durable_v2_open_oplock_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_2smb2_test(suite, "app-instance", test_durable_v2_open_app_instance);
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);
suite->description = talloc_strdup(suite, "SMB2-DURABLE-V2-OPEN tests");