summaryrefslogtreecommitdiff
path: root/source3/torture
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2019-05-30 10:38:41 +0200
committerJeremy Allison <jra@samba.org>2019-06-20 17:18:17 +0000
commit7dec53ed0c1c58b4ab7b7483b2da3e4cd58750fa (patch)
tree4f9a07d57746992688c363e0f1c577293e793b6f /source3/torture
parentff992d1c6c3c6327893f0505a5d03087777087ee (diff)
downloadsamba-7dec53ed0c1c58b4ab7b7483b2da3e4cd58750fa.tar.gz
torture3: Add a test to block a locking&read
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>
Diffstat (limited to 'source3/torture')
-rw-r--r--source3/torture/torture.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 45ef5c60f7b..fee101791d4 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -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)
@@ -12047,6 +12214,10 @@ static struct {
.fn = run_locktest9,
},
{
+ .name = "LOCK10",
+ .fn = run_locktest10,
+ },
+ {
.name = "UNLINK",
.fn = run_unlinktest,
},