]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
torture3: Add a test to block a locking&read
authorVolker Lendecke <vl@samba.org>
Thu, 30 May 2019 08:38:41 +0000 (10:38 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 20 Jun 2019 17:18:17 +0000 (17:18 +0000)
Right now we fail this with smbd, we return LOCK_NOT_GRANTED instead
of FILE_LOCK_CONFLICT. This will change with later commits.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
selftest/knownfail
source3/selftest/tests.py
source3/torture/torture.c

index 2c31bf916190c7cc420c9ce145bffb4bcedbe3f5..81fe4e6df8e67636b5e1a4060337567bb9b531b8 100644 (file)
@@ -12,6 +12,8 @@
 ^samba3.smb2.session enc.reconnect # expected to give CONNECTION_DISCONNECTED, we need to fix the test
 ^samba3.raw.session enc # expected to give ACCESS_DENIED as SMB1 encryption isn't used
 ^samba3.smbtorture_s3.crypt_server # expected to give ACCESS_DENIED as SMB1 encryption isn't used
+^samba3.smbtorture_s3.*.LOCK10.*\(fileserver\)
+^samba3.smbtorture_s3.*.LOCK10.*\(nt4_dc\)
 ^samba3.nbt.dgram.*netlogon2\(nt4_dc\)
 ^samba3.*rap.sam.*.useradd # Not provided by Samba 3
 ^samba3.*rap.sam.*.userdelete # Not provided by Samba 3
index 512a0b2c42150a86c2586409c25fc56361b5ece2..9bc5bdd0e5f73e23d397baf7fb79954000e17091 100755 (executable)
@@ -79,6 +79,7 @@ plantestsuite("samba3.local_s3", "nt4_dc:local", [os.path.join(samba3srcdir, "sc
 plantestsuite("samba3.blackbox.registry.upgrade", "nt4_dc:local", [os.path.join(samba3srcdir, "script/tests/test_registry_upgrade.sh"), net, dbwrap_tool])
 
 tests = ["FDPASS", "LOCK1", "LOCK2", "LOCK3", "LOCK4", "LOCK5", "LOCK6", "LOCK7", "LOCK9",
+         "LOCK10",
          "UNLINK", "BROWSE", "ATTR", "TRANS2", "TORTURE",
          "OPLOCK1", "OPLOCK2", "OPLOCK4", "STREAMERROR",
          "DIR", "DIR1", "DIR-CREATETIME", "TCON", "TCONDEV", "RW1", "RW2", "RW3", "LARGE_READX", "RW-SIGNING",
index 45ef5c60f7bc15b9f3e5f608a34f6a9dab009cef..fee101791d42c4acee8e3443669d1c8212ef164f 100644 (file)
@@ -2727,6 +2727,173 @@ fail_nofd:
        return correct;
 }
 
+struct locktest10_state {
+       bool ok;
+       bool done;
+};
+
+static void locktest10_lockingx_done(struct tevent_req *subreq);
+static void locktest10_read_andx_done(struct tevent_req *subreq);
+
+static bool run_locktest10(int dummy)
+{
+       struct tevent_context *ev = NULL;
+       struct cli_state *cli1 = NULL;
+       struct cli_state *cli2 = NULL;
+       struct smb1_lock_element lck = { 0 };
+       struct tevent_req *reqs[2] = { NULL };
+       struct tevent_req *smbreqs[2] = { NULL };
+       const char fname[] = "\\lockt10.lck";
+       uint16_t fnum1, fnum2;
+       bool ret = false;
+       bool ok;
+       uint8_t data = 1;
+       struct locktest10_state state = { .ok = true };
+       NTSTATUS status;
+
+       printf("starting locktest10\n");
+
+       ev = samba_tevent_context_init(NULL);
+       if (ev == NULL) {
+               d_fprintf(stderr, "samba_tevent_context_init failed\n");
+               goto done;
+       }
+
+       ok = torture_open_connection(&cli1, 0);
+       if (!ok) {
+               goto done;
+       }
+       smbXcli_conn_set_sockopt(cli1->conn, sockops);
+
+       ok = torture_open_connection(&cli2, 1);
+       if (!ok) {
+               goto done;
+       }
+       smbXcli_conn_set_sockopt(cli2->conn, sockops);
+
+       status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr,
+                         "cli_openx failed: %s\n",
+                         nt_errstr(status));
+               goto done;
+       }
+
+       status = cli_writeall(cli1, fnum1, 0, &data, 0, sizeof(data), NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr,
+                         "cli_writeall failed: %s\n",
+                         nt_errstr(status));
+               goto done;
+       }
+
+       status = cli_openx(cli2, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr,
+                         "cli_openx failed: %s\n",
+                         nt_errstr(status));
+               goto done;
+       }
+
+       status = cli_locktype(
+               cli2, fnum2, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr,
+                         "cli_locktype failed: %s\n",
+                         nt_errstr(status));
+               goto done;
+       }
+
+       lck = (struct smb1_lock_element) {
+               .pid = cli_getpid(cli1), .offset = 0, .length = 1,
+       };
+
+       reqs[0] = cli_lockingx_create(
+               ev,                             /* mem_ctx */
+               ev,                             /* tevent_context */
+               cli1,                           /* cli */
+               fnum1,                          /* fnum */
+               LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
+               0,                              /* newoplocklevel */
+               1,                              /* timeout */
+               0,                              /* num_unlocks */
+               NULL,                           /* unlocks */
+               1,                              /* num_locks */
+               &lck,                           /* locks */
+               &smbreqs[0]);                   /* psmbreq */
+       if (reqs[0] == NULL) {
+               d_fprintf(stderr, "cli_lockingx_create failed\n");
+               goto done;
+       }
+       tevent_req_set_callback(reqs[0], locktest10_lockingx_done, &state);
+
+       reqs[1] = cli_read_andx_create(
+               ev,             /* mem_ctx */
+               ev,             /* ev */
+               cli1,           /* cli */
+               fnum1,          /* fnum */
+               0,              /* offset */
+               1,              /* size */
+               &smbreqs[1]);   /* psmbreq */
+       if (reqs[1] == NULL) {
+               d_fprintf(stderr, "cli_read_andx_create failed\n");
+               goto done;
+       }
+       tevent_req_set_callback(reqs[1], locktest10_read_andx_done, &state);
+
+       status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr,
+                         "smb1cli_req_chain_submit failed: %s\n",
+                         nt_errstr(status));
+               goto done;
+       }
+
+       while (!state.done) {
+               tevent_loop_once(ev);
+       }
+
+       torture_close_connection(cli1);
+
+       if (state.ok) {
+               ret = true;
+       }
+done:
+       return ret;
+}
+
+static void locktest10_lockingx_done(struct tevent_req *subreq)
+{
+       struct locktest10_state *state = tevent_req_callback_data_void(subreq);
+       NTSTATUS status;
+
+       status = cli_lockingx_recv(subreq);
+       TALLOC_FREE(subreq);
+
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
+               d_printf("cli_lockingx returned %s\n", nt_errstr(status));
+               state->ok = false;
+       }
+}
+
+static void locktest10_read_andx_done(struct tevent_req *subreq)
+{
+       struct locktest10_state *state = tevent_req_callback_data_void(subreq);
+       ssize_t received = -1;
+       uint8_t *rcvbuf = NULL;
+       NTSTATUS status;
+
+       status = cli_read_andx_recv(subreq, &received, &rcvbuf);
+
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_ABORTED)) {
+               d_printf("cli_read_andx returned %s\n", nt_errstr(status));
+               state->ok = false;
+       }
+
+       state->done = true;
+       TALLOC_FREE(subreq);
+}
+
 /*
 test whether fnums and tids open on one VC are available on another (a major
 security hole)
@@ -12046,6 +12213,10 @@ static struct {
                .name = "LOCK9",
                .fn   =  run_locktest9,
        },
+       {
+               .name = "LOCK10",
+               .fn   =  run_locktest10,
+       },
        {
                .name = "UNLINK",
                .fn   = run_unlinktest,