struct smbd_smb2_send_queue *prev, *next;
DATA_BLOB *sendfile_header;
- void (*sendfile_fn)(void *sendfile_private);
- void *sendfile_private;
struct iovec *vector;
int count;
uint32_t in_remaining_bytes;
struct tevent_req *subreq;
- status = NT_STATUS_OK;//smbd_smb2_request_verify_sizes(req, 0x31);
+ status = smbd_smb2_request_verify_sizes(req, 0x31);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
- status = NT_STATUS_OK;//smbd_smb2_request_verify_creditcharge(req, in_length);
+ status = smbd_smb2_request_verify_creditcharge(req, in_length);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
if (subreq == NULL) {
return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
}
- //tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
+ tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
- smbd_smb2_request_read_done(req);
- return NT_STATUS_OK;
return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_read_done(struct tevent_req *subreq)
{
- struct smbd_smb2_request *req = subreq;//tevent_req_callback_data(subreq,
- //struct smbd_smb2_request);
- subreq = NULL;
+ struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
+ struct smbd_smb2_request);
DATA_BLOB outbody;
DATA_BLOB outdyn;
uint8_t out_data_offset;
uint8_t _out_hdr_buf[NBT_HDR_SIZE + SMB2_HDR_BODY + 0x10];
DATA_BLOB out_data;
uint32_t out_remaining;
- NTSTATUS status;
};
-static struct smbd_smb2_read_state _state;
-
static int smb2_smb2_read_state_deny_destructor(struct smbd_smb2_read_state *state)
{
return -1;
return 0;
}
-static void smb2_sendfile_fn(struct smbd_smb2_read_state *state)
-{
- smb2_sendfile_send_data(state);
- ZERO_STRUCTP(state);
-}
-
static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
struct smbd_smb2_read_state *state)
{
NTSTATUS smb2_read_complete(struct tevent_req *req, ssize_t nread, int err)
{
- struct smbd_smb2_read_state *state = &_state;//tevent_req_data(req,
- //struct smbd_smb2_read_state);
+ struct smbd_smb2_read_state *state = tevent_req_data(req,
+ struct smbd_smb2_read_state);
files_struct *fsp = state->fsp;
if (nread < 0) {
static bool smbd_smb2_read_cancel(struct tevent_req *req)
{
- struct smbd_smb2_read_state *state = &_state;
- //tevent_req_data(req,
- //struct smbd_smb2_read_state);
+ struct smbd_smb2_read_state *state =
+ tevent_req_data(req,
+ struct smbd_smb2_read_state);
return cancel_smb2_aio(state->smbreq);
}
uint32_t in_remaining)
{
NTSTATUS status;
- //struct tevent_req *req = NULL;
+ struct tevent_req *req = NULL;
struct smbd_smb2_read_state *state = NULL;
struct smb_request *smbreq = NULL;
connection_struct *conn = smb2req->tcon->compat;
struct lock_struct lock;
int saved_errno;
- //req = tevent_req_create(mem_ctx, &state,
- // struct smbd_smb2_read_state);
- //if (req == NULL) {
- // return NULL;
- //}
- state = &_state;
- ZERO_STRUCTP(state);
+ req = tevent_req_create(mem_ctx, &state,
+ struct smbd_smb2_read_state);
+ if (req == NULL) {
+ return NULL;
+ }
state->smb2req = smb2req;
state->in_length = in_length;
state->in_offset = in_offset;
fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));
smbreq = smbd_smb2_fake_smb_request(smb2req);
- //if (tevent_req_nomem(smbreq, req)) {
- // return tevent_req_post(req, ev);
- //}
+ if (tevent_req_nomem(smbreq, req)) {
+ return tevent_req_post(req, ev);
+ }
state->smbreq = smbreq;
- //if (fsp->is_directory) {
- // tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
- // return tevent_req_post(req, ev);
- //}
+ if (fsp->is_directory) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
+ return tevent_req_post(req, ev);
+ }
state->fsp = fsp;
- //if (IS_IPC(smbreq->conn)) {
- // struct tevent_req *subreq = NULL;
-
- // state->out_data = data_blob_talloc(state, NULL, in_length);
- // if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
- // return tevent_req_post(req, ev);
- // }
-
- // if (!fsp_is_np(fsp)) {
- // tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
- // return tevent_req_post(req, ev);
- // }
-
- // subreq = np_read_send(state, ev,
- // fsp->fake_file_handle,
- // state->out_data.data,
- // state->out_data.length);
- // if (tevent_req_nomem(subreq, req)) {
- // return tevent_req_post(req, ev);
- // }
- // tevent_req_set_callback(subreq,
- // smbd_smb2_read_pipe_done,
- // req);
- // return req;
- //}
-
- //if (!CHECK_READ(fsp, smbreq)) {
- // tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
- // return tevent_req_post(req, ev);
- //}
+ if (IS_IPC(smbreq->conn)) {
+ struct tevent_req *subreq = NULL;
+
+ state->out_data = data_blob_talloc(state, NULL, in_length);
+ if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ if (!fsp_is_np(fsp)) {
+ tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = np_read_send(state, ev,
+ fsp->fake_file_handle,
+ state->out_data.data,
+ state->out_data.length);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq,
+ smbd_smb2_read_pipe_done,
+ req);
+ return req;
+ }
+
+ if (!CHECK_READ(fsp, smbreq)) {
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return tevent_req_post(req, ev);
+ }
status = schedule_smb2_aio_read(fsp->conn,
smbreq,
* Doing an async read, allow this
* request to be canceled
*/
- //tevent_req_set_cancel_fn(req, smbd_smb2_read_cancel);
- state->status = status;
- return state;
- //return req;
+ tevent_req_set_cancel_fn(req, smbd_smb2_read_cancel);
+ return req;
}
if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
- state->status = status;
- return state;
- // /* Real error in setting up aio. Fail. */
- // tevent_req_nterror(req, status);
- // return tevent_req_post(req, ev);
+ /* Real error in setting up aio. Fail. */
+ tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
+ return tevent_req_post(req, ev);
}
/* Fallback to synchronous. */
&lock);
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
- // tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
- // return tevent_req_post(req, ev);
+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+ return tevent_req_post(req, ev);
}
/* Try sendfile in preference. */
status = schedule_smb2_sendfile_read(smb2req, state);
if (NT_STATUS_IS_OK(status)) {
- //tevent_req_done(req);
- return state;//req;//tevent_req_post(req, ev);
+ tevent_req_done(req);
+ return req;//tevent_req_post(req, ev);
} else {
if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
- state->status = status;
- return state;
-// tevent_req_nterror(req, status);
-// return tevent_req_post(req, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
}
/* Ok, read into memory. Allocate the out buffer. */
state->out_data = data_blob_talloc(state, NULL, in_length);
-// if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
-// SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
-// return tevent_req_post(req, ev);
-// }
+ if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+ return tevent_req_post(req, ev);
+ }
nread = read_file(fsp,
(char *)state->out_data.data,
(unsigned long long)in_length,
(long long)nread));
- status = smb2_read_complete(NULL, nread, saved_errno);
-// if (!NT_STATUS_IS_OK(status)) {
-// tevent_req_nterror(req, status);
-// } else {
-// /* Success. */
-// tevent_req_done(req);
-// }
- state->status = status;
- return state;
- return state;//req;//tevent_req_post(req, ev);
+ status = smb2_read_complete(req, nread, saved_errno);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ } else {
+ /* Success. */
+ tevent_req_done(req);
+ }
+ return req;//tevent_req_post(req, ev);
}
static void smbd_smb2_read_pipe_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
- struct smbd_smb2_read_state *state = &_state;//tevent_req_data(req,
- //struct smbd_smb2_read_state);
+ struct smbd_smb2_read_state *state = tevent_req_data(req,
+ struct smbd_smb2_read_state);
NTSTATUS status;
ssize_t nread = -1;
bool is_data_outstanding;
uint32_t *out_remaining)
{
NTSTATUS status;
- struct smbd_smb2_read_state *state = &_state;//tevent_req_data(req,
- //struct smbd_smb2_read_state);
+ struct smbd_smb2_read_state *state = tevent_req_data(req,
+ struct smbd_smb2_read_state);
- if (!NT_STATUS_IS_OK(state->status)) {
- status = state->status;
- ZERO_STRUCTP(state);
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
return status;
}
- //if (tevent_req_is_nterror(req, &status)) {
- // tevent_req_received(req);
- // return status;
- //}
*out_data = state->out_data;
talloc_steal(mem_ctx, out_data->data);
*out_remaining = state->out_remaining;
if (state->out_headers.length > 0) {
- //talloc_steal(mem_ctx, state);
- //talloc_set_destructor(state, smb2_smb2_read_state_deny_destructor);
- //tevent_req_received(req);
+ talloc_steal(mem_ctx, state);
+ talloc_set_destructor(state, smb2_smb2_read_state_deny_destructor);
+ tevent_req_received(req);
state->smb2req->queue_entry.sendfile_header = &state->out_headers;
- state->smb2req->queue_entry.sendfile_private = state;
- state->smb2req->queue_entry.sendfile_fn = smb2_sendfile_fn;
- //talloc_set_destructor(state, smb2_sendfile_send_data);
+ talloc_set_destructor(state, smb2_sendfile_send_data);
} else {
- //tevent_req_received(req);
+ tevent_req_received(req);
}
return NT_STATUS_OK;
void *private_data);
static NTSTATUS smbd_smb2_io_handler(struct smbd_server_connection *sconn,
uint16_t fde_flags);
-static NTSTATUS smbd_smb2_flush_send_queue(struct smbd_server_connection *sconn);
static const struct smbd_smb2_dispatch_table {
uint16_t opcode;
return true;
}
-static inline NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
+static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
{
int count;
int idx;
count = req->in.vector_count;
-// if (unlikely(count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ)) {
-// /* It's not a SMB2 request */
-// return NT_STATUS_INVALID_PARAMETER;
-// }
-//
+ if (unlikely(count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ)) {
+ /* It's not a SMB2 request */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
-// struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
+ struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
const uint8_t *inhdr = NULL;
bool ok;
-// if (unlikely(hdr->iov_len != SMB2_HDR_BODY)) {
-// return NT_STATUS_INVALID_PARAMETER;
-// }
-//
-// if (unlikely(body->iov_len < 2)) {
-// return NT_STATUS_INVALID_PARAMETER;
-// }
-//
+ if (unlikely(hdr->iov_len != SMB2_HDR_BODY)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (unlikely(body->iov_len < 2)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
inhdr = (const uint8_t *)hdr->iov_base;
-//
-// /* Check the SMB2 header */
-// if (unlikely(IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC)) {
-// return NT_STATUS_INVALID_PARAMETER;
-// }
+
+ /* Check the SMB2 header */
+ if (unlikely(IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
ok = smb2_validate_message_id(req->sconn, inhdr);
if (unlikely(!ok)) {
credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
-//
-// SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted);
-//
-// if (unlikely(sconn->smb2.max_credits < credit_charge)) {
-// smbd_server_connection_terminate(sconn,
-// "client error: credit charge > max credits\n");
-// return;
-// }
-//
-// if (out_flags & SMB2_HDR_FLAG_ASYNC) {
-// /*
-// * In case we already send an async interim
-// * response, we should not grant
-// * credits on the final response.
-// */
-// credits_granted = 0;
-// } else if (credits_requested > 0) {
-// uint16_t additional_max = 0;
-// uint16_t additional_credits = credits_requested - 1;
-//
-// switch (cmd) {
-// case SMB2_OP_NEGPROT:
-// break;
-// case SMB2_OP_SESSSETUP:
-// /*
-// * Windows 2012 RC1 starts to grant
-// * additional credits
-// * with a successful session setup
-// */
-// if (NT_STATUS_IS_OK(out_status)) {
-// additional_max = 32;
-// }
-// break;
-// default:
-// /*
-// * We match windows and only grant additional credits
-// * in chunks of 32.
-// */
-// additional_max = 32;
-// break;
-// }
-//
-// additional_credits = MIN(additional_credits, additional_max);
-//
-// credits_granted = credit_charge + additional_credits;
-// } else if (sconn->smb2.credits_granted == 0) {
-// /*
-// * Make sure the client has always at least one credit
-// */
-// credits_granted = 1;
-// }
-//
-// /*
-// * sequence numbers should not wrap
-// *
-// * 1. calculate the possible credits until
-// * the sequence numbers start to wrap on 64-bit.
-// *
-// * 2. UINT64_MAX is used for Break Notifications.
-// *
-// * 2. truncate the possible credits to the maximum
-// * credits we want to grant to the client in total.
-// *
-// * 3. remove the range we'll already granted to the client
-// * this makes sure the client consumes the lowest sequence
-// * number, before we can grant additional credits.
-// */
-// credits_possible = UINT64_MAX - sconn->smb2.seqnum_low;
-// if (credits_possible > 0) {
-// /* remove UINT64_MAX */
-// credits_possible -= 1;
-// }
-// credits_possible = MIN(credits_possible, current_max_credits);
-// credits_possible -= sconn->smb2.seqnum_range;
-//
-// credits_granted = MIN(credits_granted, credits_possible);
-//
+
+ SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted);
+
+ if (unlikely(sconn->smb2.max_credits < credit_charge)) {
+ smbd_server_connection_terminate(sconn,
+ "client error: credit charge > max credits\n");
+ return;
+ }
+
+ if (out_flags & SMB2_HDR_FLAG_ASYNC) {
+ /*
+ * In case we already send an async interim
+ * response, we should not grant
+ * credits on the final response.
+ */
+ credits_granted = 0;
+ } else if (credits_requested > 0) {
+ uint16_t additional_max = 0;
+ uint16_t additional_credits = credits_requested - 1;
+
switch (cmd) {
- case SMB2_OP_WRITE:
- credits_granted = MAX(2,credit_charge);
+ case SMB2_OP_NEGPROT:
+ break;
+ case SMB2_OP_SESSSETUP:
+ /*
+ * Windows 2012 RC1 starts to grant
+ * additional credits
+ * with a successful session setup
+ */
+ if (NT_STATUS_IS_OK(out_status)) {
+ additional_max = 32;
+ }
break;
default:
- credits_granted = MAX(1,credit_charge);
+ /*
+ * We match windows and only grant additional credits
+ * in chunks of 32.
+ */
+ additional_max = 32;
break;
}
+ additional_credits = MIN(additional_credits, additional_max);
+
+ credits_granted = credit_charge + additional_credits;
+ } else if (sconn->smb2.credits_granted == 0) {
+ /*
+ * Make sure the client has always at least one credit
+ */
+ credits_granted = 1;
+ }
+
+ /*
+ * sequence numbers should not wrap
+ *
+ * 1. calculate the possible credits until
+ * the sequence numbers start to wrap on 64-bit.
+ *
+ * 2. UINT64_MAX is used for Break Notifications.
+ *
+ * 2. truncate the possible credits to the maximum
+ * credits we want to grant to the client in total.
+ *
+ * 3. remove the range we'll already granted to the client
+ * this makes sure the client consumes the lowest sequence
+ * number, before we can grant additional credits.
+ */
+ credits_possible = UINT64_MAX - sconn->smb2.seqnum_low;
+ if (credits_possible > 0) {
+ /* remove UINT64_MAX */
+ credits_possible -= 1;
+ }
+ credits_possible = MIN(credits_possible, current_max_credits);
+ credits_possible -= sconn->smb2.seqnum_range;
+
+ credits_granted = MIN(credits_granted, credits_possible);
+
SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
sconn->smb2.credits_granted += credits_granted;
sconn->smb2.seqnum_range += credits_granted;
DLIST_ADD_END(nreq->sconn->smb2.send_queue, &nreq->queue_entry, NULL);
nreq->sconn->smb2.send_queue_len++;
- status = smbd_smb2_flush_send_queue(sconn);//smbd_smb2_io_handler(sconn, TEVENT_FD_WRITE);
+ status = smbd_smb2_io_handler(sconn, TEVENT_FD_WRITE);
if (unlikely(!NT_STATUS_IS_OK(status))) {
return status;
}
DLIST_ADD_END(sconn->smb2.send_queue, &state->queue_entry, NULL);
sconn->smb2.send_queue_len++;
- status = smbd_smb2_flush_send_queue(sconn);//smbd_smb2_io_handler(sconn, TEVENT_FD_WRITE);
+ status = smbd_smb2_io_handler(sconn, TEVENT_FD_WRITE);
if (unlikely(!NT_STATUS_IS_OK(status))) {
smbd_server_connection_terminate(sconn,
nt_errstr(status));
DLIST_ADD_END(req->sconn->smb2.send_queue, &req->queue_entry, NULL);
req->sconn->smb2.send_queue_len++;
- status = smbd_smb2_flush_send_queue(sconn);//smbd_smb2_io_handler(sconn, TEVENT_FD_WRITE);
+ status = smbd_smb2_io_handler(sconn, TEVENT_FD_WRITE);
if (unlikely(!NT_STATUS_IS_OK(status))) {
return status;
}
DLIST_ADD_END(state->sconn->smb2.send_queue, &state->queue_entry, NULL);
state->sconn->smb2.send_queue_len++;
- status = smbd_smb2_flush_send_queue(sconn);//smbd_smb2_io_handler(sconn, TEVENT_FD_WRITE);
+ status = smbd_smb2_io_handler(sconn, TEVENT_FD_WRITE);
if (unlikely(!NT_STATUS_IS_OK(status))) {
return status;
}
return;
}
- status = NT_STATUS_OK;//smbd_smb2_request_validate(req);
+ status = smbd_smb2_request_validate(req);
if (unlikely(!NT_STATUS_IS_OK(status))) {
smbd_server_connection_terminate(sconn, nt_errstr(status));
return;
* This triggers the sendfile path via
* the destructor.
*/
- e->sendfile_fn(e->sendfile_private);
talloc_free(e->mem_ctx);
continue;
}
DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
req->current_idx, req->in.vector_count));
- status = NT_STATUS_OK;//smbd_smb2_request_validate(req);
+ status = smbd_smb2_request_validate(req);
if (unlikely(!NT_STATUS_IS_OK(status))) {
return status;
}
uint8_t *in_dyn_ptr = NULL;
struct tevent_req *subreq;
- status = NT_STATUS_OK;//smbd_smb2_request_verify_sizes(req, 0x31);
+ status = smbd_smb2_request_verify_sizes(req, 0x31);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
in_data_buffer.data = in_dyn_ptr;
in_data_buffer.length = in_data_length;
- status = NT_STATUS_OK;//smbd_smb2_request_verify_creditcharge(req, in_data_length);
+ status = smbd_smb2_request_verify_creditcharge(req, in_data_length);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
if (subreq == NULL) {
return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
}
- //tevent_req_set_callback(subreq, smbd_smb2_request_write_done, req);
+ tevent_req_set_callback(subreq, smbd_smb2_request_write_done, req);
- smbd_smb2_request_write_done(req);
- return NT_STATUS_OK;
return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_write_done(struct tevent_req *subreq)
{
- struct smbd_smb2_request *req = subreq;//tevent_req_callback_data(subreq,
- //struct smbd_smb2_request);
- subreq = NULL;
+ struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
+ struct smbd_smb2_request);
DATA_BLOB outbody;
DATA_BLOB outdyn;
uint32_t out_count = 0;
uint64_t in_offset;
uint32_t out_count;
};
-static struct smbd_smb2_write_state _state;
static void smbd_smb2_write_pipe_done(struct tevent_req *subreq);
bool do_sync)
{
NTSTATUS status;
- struct smbd_smb2_write_state *state = &_state;//tevent_req_data(req,
- //struct smbd_smb2_write_state);
+ struct smbd_smb2_write_state *state = tevent_req_data(req,
+ struct smbd_smb2_write_state);
files_struct *fsp = state->fsp;
if (nwritten == -1) {
static bool smbd_smb2_write_cancel(struct tevent_req *req)
{
- struct smbd_smb2_write_state *state = &_state;
- //tevent_req_data(req,
- //struct smbd_smb2_write_state);
+ struct smbd_smb2_write_state *state =
+ tevent_req_data(req,
+ struct smbd_smb2_write_state);
return cancel_smb2_aio(state->smbreq);
}
uint32_t in_flags)
{
NTSTATUS status;
- //struct tevent_req *req = NULL;
+ struct tevent_req *req = NULL;
struct smbd_smb2_write_state *state = NULL;
struct smb_request *smbreq = NULL;
connection_struct *conn = smb2req->tcon->compat;
ssize_t nwritten;
struct lock_struct lock;
-// req = tevent_req_create(mem_ctx, &state,
-// struct smbd_smb2_write_state);
-// if (req == NULL) {
-// return NULL;
-// }
- ZERO_STRUCT(_state);
- state = &_state;
+ req = tevent_req_create(mem_ctx, &state,
+ struct smbd_smb2_write_state);
+ if (req == NULL) {
+ return NULL;
+ }
state->smb2req = smb2req;
if (in_flags & SMB2_WRITEFLAG_WRITE_THROUGH) {
state->write_through = true;
fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));
smbreq = smbd_smb2_fake_smb_request(smb2req);
-// if (tevent_req_nomem(smbreq, req)) {
-// return tevent_req_post(req, ev);
-// }
+ if (tevent_req_nomem(smbreq, req)) {
+ return tevent_req_post(req, ev);
+ }
state->smbreq = smbreq;
state->fsp = fsp;
-// if (IS_IPC(smbreq->conn)) {
-// struct tevent_req *subreq = NULL;
-//
-// if (!fsp_is_np(fsp)) {
-// tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
-// return tevent_req_post(req, ev);
-// }
-//
-// if (smbreq->unread_bytes > 0) {
-// /*
-// * Note: in_data.data is NULL in this case.
-// */
-// tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
-// return tevent_req_post(req, ev);
-// }
-//
-// subreq = np_write_send(state, ev,
-// fsp->fake_file_handle,
-// in_data.data,
-// in_data.length);
-// if (tevent_req_nomem(subreq, req)) {
-// return tevent_req_post(req, ev);
-// }
-// tevent_req_set_callback(subreq,
-// smbd_smb2_write_pipe_done,
-// req);
-// return req;
-// }
-//
-// if (!CHECK_WRITE(fsp)) {
-// tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
-// return tevent_req_post(req, ev);
-// }
+ if (IS_IPC(smbreq->conn)) {
+ struct tevent_req *subreq = NULL;
+
+ if (!fsp_is_np(fsp)) {
+ tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
+ return tevent_req_post(req, ev);
+ }
+
+ if (smbreq->unread_bytes > 0) {
+ /*
+ * Note: in_data.data is NULL in this case.
+ */
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = np_write_send(state, ev,
+ fsp->fake_file_handle,
+ in_data.data,
+ in_data.length);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq,
+ smbd_smb2_write_pipe_done,
+ req);
+ return req;
+ }
+
+ if (!CHECK_WRITE(fsp)) {
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return tevent_req_post(req, ev);
+ }
/* Try and do an asynchronous write. */
status = schedule_aio_smb2_write(conn,
in_offset,
in_data,
state->write_through);
-//
-// if (NT_STATUS_IS_OK(status)) {
-// /*
-// * Doing an async write, allow this
-// * request to be canceled
-// */
-// tevent_req_set_cancel_fn(req, smbd_smb2_write_cancel);
-// return req;
-// }
-//
-// if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
-// /* Real error in setting up aio. Fail. */
-// tevent_req_nterror(req, status);
-// return tevent_req_post(req, ev);
-// }
+
+ if (NT_STATUS_IS_OK(status)) {
+ /*
+ * Doing an async write, allow this
+ * request to be canceled
+ */
+ tevent_req_set_cancel_fn(req, smbd_smb2_write_cancel);
+ return req;
+ }
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
+ /* Real error in setting up aio. Fail. */
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
/* Fallback to synchronous. */
init_strict_lock_struct(fsp,
&lock);
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
-// tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
-// return tevent_req_post(req, ev);
+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+ return tevent_req_post(req, ev);
}
/*
in_offset,
in_data.length);
- status = smb2_write_complete(NULL, nwritten, errno);
+ status = smb2_write_complete(req, nwritten, errno);
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
(unsigned int)in_data.length,
(unsigned int)nwritten ));
-// if (!NT_STATUS_IS_OK(status)) {
-// tevent_req_nterror(req, status);
-// } else {
-// /* Success. */
-// tevent_req_done(req);
-// }
-return state;
- //return req;//tevent_req_post(req, ev);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ } else {
+ /* Success. */
+ tevent_req_done(req);
+ }
+
+ return req;//tevent_req_post(req, ev);
}
static void smbd_smb2_write_pipe_done(struct tevent_req *subreq)
uint32_t *out_count)
{
NTSTATUS status;
- struct smbd_smb2_write_state *state = &_state;//tevent_req_data(req,
- // struct smbd_smb2_write_state);
-//
-// if (tevent_req_is_nterror(req, &status)) {
-// tevent_req_received(req);
-// return status;
-// }
-//
+ struct smbd_smb2_write_state *state = tevent_req_data(req,
+ struct smbd_smb2_write_state);
+
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+
*out_count = state->out_count;
-// tevent_req_received(req);
- ZERO_STRUCTP(state);
+ tevent_req_received(req);
return NT_STATUS_OK;
}