torture: add smbtorture testcase "related7" for failure in compound related chain
authorAnubhav Rakshit <anubhav.rakshit@gmail.com>
Wed, 15 Jul 2020 04:44:52 +0000 (10:14 +0530)
committerJeremy Allison <jra@samba.org>
Thu, 8 Apr 2021 16:13:34 +0000 (16:13 +0000)
We want to verify what Windows does when the first request of the
chain has failed and an async request is part of the chain. We see
Windows fails the async request with the same error. Also the async
request is immediately failed.

Signed-off-by: Anubhav Rakshit <anubhav.rakshit@gmail.com>
Reviewed-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
selftest/knownfail.d/samba3.smb2.compound
source4/torture/smb2/compound.c

index 2286f6a682bb81d405daced2b5a4a8baa5ac03fe..f2905ec0025a2d696dadb23f48d7a375b98ecc11 100644 (file)
@@ -1,2 +1,4 @@
 ^samba3.smb2.compound.related4
 ^samba3.smb2.compound aio.related4
+^samba3.smb2.compound.related7
+^samba3.smb2.compound aio.related7
index bf85fed78b996fbab09f6bbab917df569425dbbd..13172306c8b8b2f70678901b070c5f602a0a9097 100644 (file)
@@ -730,6 +730,127 @@ static bool test_compound_related6(struct torture_context *tctx,
        return ret;
 }
 
+static bool test_compound_related7(struct torture_context *tctx,
+                       struct smb2_tree *tree)
+{
+       const char *fname = "compound_related4.dat";
+       struct security_descriptor *sd = NULL;
+       struct smb2_handle hd;
+       struct smb2_create cr;
+       union smb_setfileinfo set;
+       struct smb2_notify nt;
+       struct smb2_close cl;
+       NTSTATUS status;
+       struct smb2_request *req[4];
+       bool ret = true;
+
+       smb2_util_unlink(tree, fname);
+
+       ZERO_STRUCT(cr);
+       cr.level = RAW_OPEN_SMB2;
+       cr.in.create_flags = 0;
+       cr.in.desired_access = SEC_STD_READ_CONTROL |
+                               SEC_STD_WRITE_DAC |
+                               SEC_STD_WRITE_OWNER;
+       cr.in.create_options = 0;
+       cr.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       cr.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
+                               NTCREATEX_SHARE_ACCESS_READ |
+                               NTCREATEX_SHARE_ACCESS_WRITE;
+       cr.in.alloc_size = 0;
+       cr.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+       cr.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
+       cr.in.security_flags = 0;
+       cr.in.fname = fname;
+
+       status = smb2_create(tree, tctx, &cr);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_create failed\n");
+
+       hd = cr.out.file.handle;
+       torture_comment(tctx, "set a sec desc allowing no write by CREATOR_OWNER\n");
+       sd = security_descriptor_dacl_create(tctx,
+                       0, NULL, NULL,
+                       SID_CREATOR_OWNER,
+                       SEC_ACE_TYPE_ACCESS_ALLOWED,
+                       SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
+                       0,
+                       NULL);
+       torture_assert_not_null_goto(tctx, sd, ret, done,
+                                    "security_descriptor_dacl_create failed\n");
+
+       set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
+       set.set_secdesc.in.file.handle = hd;
+       set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
+       set.set_secdesc.in.sd = sd;
+
+       status = smb2_setinfo_file(tree, &set);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_setinfo_file failed\n");
+
+       torture_comment(tctx, "try open for write\n");
+       cr.in.desired_access = SEC_FILE_WRITE_DATA;
+       smb2_transport_compound_start(tree->session->transport, 4);
+
+       req[0] = smb2_create_send(tree, &cr);
+       torture_assert_not_null_goto(tctx, req[0], ret, done,
+                                    "smb2_create_send failed\n");
+
+       hd.data[0] = UINT64_MAX;
+       hd.data[1] = UINT64_MAX;
+
+       smb2_transport_compound_set_related(tree->session->transport, true);
+
+       ZERO_STRUCT(nt);
+       nt.in.recursive          = true;
+       nt.in.buffer_size        = 0x1000;
+       nt.in.file.handle        = hd;
+       nt.in.completion_filter  = FILE_NOTIFY_CHANGE_NAME;
+       nt.in.unknown            = 0x00000000;
+
+       req[1] = smb2_notify_send(tree, &nt);
+       torture_assert_not_null_goto(tctx, req[1], ret, done,
+                                    "smb2_notify_send failed\n");
+
+       ZERO_STRUCT(cl);
+       cl.in.file.handle = hd;
+
+       req[2] = smb2_close_send(tree, &cl);
+       torture_assert_not_null_goto(tctx, req[2], ret, done,
+                                    "smb2_close_send failed\n");
+
+       set.set_secdesc.in.file.handle = hd;
+
+       req[3] = smb2_setinfo_file_send(tree, &set);
+       torture_assert_not_null_goto(tctx, req[3], ret, done,
+                                    "smb2_setinfo_file_send failed\n");
+
+       status = smb2_create_recv(req[0], tree, &cr);
+       torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ACCESS_DENIED,
+                                          ret, done,
+                                          "smb2_create_recv failed\n");
+
+       status = smb2_notify_recv(req[1], tree, &nt);
+       torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ACCESS_DENIED,
+                                          ret, done,
+                                          "smb2_notify_recv failed\n");
+
+       status = smb2_close_recv(req[2], &cl);
+       torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ACCESS_DENIED,
+                                          ret, done,
+                                          "smb2_close_recv failed\n");
+
+       status = smb2_setinfo_recv(req[3]);
+       torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ACCESS_DENIED,
+                                          ret, done,
+                                          "smb2_setinfo_recv failed\n");
+
+done:
+       smb2_util_unlink(tree, fname);
+       smb2_tdis(tree);
+       smb2_logoff(tree->session);
+       return ret;
+}
 static bool test_compound_padding(struct torture_context *tctx,
                                  struct smb2_tree *tree)
 {
@@ -1731,6 +1852,8 @@ struct torture_suite *torture_smb2_compound_init(TALLOC_CTX *ctx)
                                     test_compound_related5);
        torture_suite_add_1smb2_test(suite, "related6",
                                     test_compound_related6);
+       torture_suite_add_1smb2_test(suite, "related7",
+                                    test_compound_related7);
        torture_suite_add_1smb2_test(suite, "unrelated1", test_compound_unrelated1);
        torture_suite_add_1smb2_test(suite, "invalid1", test_compound_invalid1);
        torture_suite_add_1smb2_test(suite, "invalid2", test_compound_invalid2);