uint32_t in_create_options,
const char *in_name,
struct smb2_create_blobs in_context_blobs);
-static NTSTATUS smbd_smb2_create_recv(struct tevent_req *treq,
+static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
uint8_t *out_oplock_level,
uint32_t *out_create_action,
return smbd_smb2_request_pending_queue(smb2req, tsubreq);
}
+static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
+{
+ uint8_t *reqhdr = (uint8_t *)smb2req->out.vector[smb2req->current_idx].iov_base;
+ return BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
+}
+
static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
{
struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq,
NTSTATUS status;
NTSTATUS error; /* transport error */
+ if (smb2req->cancelled) {
+ uint64_t mid = get_mid_from_smb2req(smb2req);
+ DEBUG(10,("smbd_smb2_request_create_done: cancelled mid %llu\n",
+ (unsigned long long)mid ));
+ error = smbd_smb2_request_error(smb2req, NT_STATUS_CANCELLED);
+ if (!NT_STATUS_IS_OK(error)) {
+ smbd_server_connection_terminate(smb2req->sconn,
+ nt_errstr(error));
+ return;
+ }
+ return;
+ }
+
status = smbd_smb2_create_recv(tsubreq,
smb2req,
&out_oplock_level,
struct smb_request *smb1req;
struct timed_event *te;
struct timeval request_time;
+ struct file_id id;
DATA_BLOB private_data;
uint8_t out_oplock_level;
uint32_t out_create_action;
const char *in_name,
struct smb2_create_blobs in_context_blobs)
{
- struct tevent_req *treq = NULL;
+ struct tevent_req *req = NULL;
struct smbd_smb2_create_state *state = NULL;
NTSTATUS status;
struct smb_request *smb1req = NULL;
if (!smb2req->async) {
/* New create call. */
- treq = tevent_req_create(mem_ctx, &state,
+ req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_create_state);
- if (treq == NULL) {
+ if (req == NULL) {
return NULL;
}
state->smb2req = smb2req;
- smb2req->subreq = treq; /* So we can find this when going async. */
+ smb2req->subreq = req; /* So we can find this when going async. */
smb1req = smbd_smb2_fake_smb_request(smb2req);
- if (tevent_req_nomem(smb1req, treq)) {
- return tevent_req_post(treq, ev);
+ if (tevent_req_nomem(smb1req, req)) {
+ return tevent_req_post(req, ev);
}
state->smb1req = smb1req;
DEBUG(10,("smbd_smb2_create: name[%s]\n",
in_name));
} else {
/* Re-entrant create call. */
- treq = smb2req->subreq;
- state = tevent_req_data(treq,
+ req = smb2req->subreq;
+ state = tevent_req_data(req,
struct smbd_smb2_create_state);
smb1req = state->smb1req;
DEBUG(10,("smbd_smb2_create_send: reentrant for file %s\n",
const char *pipe_name = in_name;
if (!lp_nt_pipe_support()) {
- tevent_req_nterror(treq, NT_STATUS_ACCESS_DENIED);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return tevent_req_post(req, ev);
}
/* Strip \\ off the name. */
status = open_np_file(smb1req, pipe_name, &result);
if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(treq, status);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
info = FILE_WAS_OPENED;
} else if (CAN_PRINT(smb1req->conn)) {
status = file_new(smb1req, smb1req->conn, &result);
if(!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(treq, status);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
status = print_fsp_open(smb1req,
result);
if (!NT_STATUS_IS_OK(status)) {
file_free(smb1req, result);
- tevent_req_nterror(treq, status);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
info = FILE_WAS_CREATED;
} else {
SMB2_CREATE_TAG_QFID);
fname = talloc_strdup(state, in_name);
- if (tevent_req_nomem(fname, treq)) {
- return tevent_req_post(treq, ev);
+ if (tevent_req_nomem(fname, req)) {
+ return tevent_req_post(req, ev);
}
if (exta) {
if (dhnc) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
ea_list = read_nttrans_ea_list(mem_ctx,
(const char *)exta->data.data, exta->data.length);
if (!ea_list) {
DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
}
if (mxac) {
if (dhnc) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
if (mxac->data.length == 0) {
} else if (mxac->data.length == 8) {
max_access_time = BVAL(mxac->data.data, 0);
} else {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
}
enum ndr_err_code ndr_err;
if (dhnc) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
sec_desc = talloc_zero(state, struct security_descriptor);
- if (tevent_req_nomem(sec_desc, treq)) {
- return tevent_req_post(treq, ev);
+ if (tevent_req_nomem(sec_desc, req)) {
+ return tevent_req_post(req, ev);
}
ndr_err = ndr_pull_struct_blob(&secd->data,
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
ndr_errstr(ndr_err)));
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
}
if (dhnq) {
if (dhnc) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
if (dhnq->data.length != 16) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
/*
* we don't support durable handles yet
if (dhnc) {
if (dhnc->data.length != 16) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
/* we don't support durable handles yet */
- tevent_req_nterror(treq, NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return tevent_req_post(req, ev);
}
if (alsi) {
if (dhnc) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
if (alsi->data.length != 8) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
allocation_size = BVAL(alsi->data.data, 0);
}
struct tm *tm;
if (dhnc) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
if (twrp->data.length != 8) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
nttime = BVAL(twrp->data.data, 0);
tm->tm_min,
tm->tm_sec,
in_name);
- if (tevent_req_nomem(fname, treq)) {
- return tevent_req_post(treq, ev);
+ if (tevent_req_nomem(fname, req)) {
+ return tevent_req_post(req, ev);
}
}
if (qfid) {
if (qfid->data.length != 0) {
- tevent_req_nterror(treq, NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
}
/* convert '\\' into '/' */
status = check_path_syntax(fname);
if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(treq, status);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
- status = filename_convert(treq,
+ status = filename_convert(req,
smb1req->conn,
smb1req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(treq, status);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
status = SMB_VFS_CREATE_FILE(smb1req->conn,
&info);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(smb1req->mid)) {
- return treq;
+ return req;
}
- tevent_req_nterror(treq, status);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
if (mxac) {
SMB2_CREATE_TAG_MXAC,
blob);
if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(treq, status);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
}
}
SMB2_CREATE_TAG_QFID,
blob);
if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(treq, status);
- return tevent_req_post(treq, ev);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
}
}
}
state->out_file_id_volatile = result->fnum;
state->out_context_blobs = out_context_blobs;
- tevent_req_done(treq);
- return tevent_req_post(treq, ev);
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
}
-static NTSTATUS smbd_smb2_create_recv(struct tevent_req *treq,
+static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
uint8_t *out_oplock_level,
uint32_t *out_create_action,
struct smb2_create_blobs *out_context_blobs)
{
NTSTATUS status;
- struct smbd_smb2_create_state *state = tevent_req_data(treq,
+ struct smbd_smb2_create_state *state = tevent_req_data(req,
struct smbd_smb2_create_state);
- if (tevent_req_is_nterror(treq, &status)) {
- tevent_req_received(treq);
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
return status;
}
talloc_steal(mem_ctx, state->out_context_blobs.blobs);
- tevent_req_received(treq);
+ tevent_req_received(req);
return NT_STATUS_OK;
}
void **pp_state)
{
struct smbd_smb2_create_state *state = NULL;
- struct tevent_req *treq = NULL;
+ struct tevent_req *req = NULL;
if (!smb2req) {
return false;
if (!smb2req->async) {
return false;
}
- treq = smb2req->subreq;
- if (!treq) {
+ req = smb2req->subreq;
+ if (!req) {
return false;
}
- state = tevent_req_data(treq, struct smbd_smb2_create_state);
+ state = tevent_req_data(req, struct smbd_smb2_create_state);
if (!state) {
return false;
}
struct smbd_smb2_request *smb2req;
for (smb2req = sconn->smb2.requests; smb2req; smb2req = smb2req->next) {
- uint8_t *reqhdr = (uint8_t *)smb2req->out.vector[smb2req->current_idx].iov_base;
- uint64_t message_id = BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
+ uint64_t message_id = get_mid_from_smb2req(smb2req);
if (message_id == mid) {
return smb2req;
}
return true;
}
-void remove_deferred_open_message_smb2(uint64_t mid)
+static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
+ uint64_t mid)
{
struct smbd_smb2_create_state *state = NULL;
- struct smbd_smb2_request *smb2req = find_open_smb2req(mid);
- if (!smb2req) {
- DEBUG(10,("remove_deferred_open_message_smb2: "
- "can't find mid %llu\n",
- (unsigned long long)mid ));
- return;
- }
if (!smb2req->subreq) {
return;
}
return;
}
- DEBUG(10,("remove_deferred_open_message_smb2: "
+ DEBUG(10,("remove_deferred_open_message_smb2_internal: "
"mid %llu\n",
(unsigned long long)mid ));
TALLOC_FREE(state->te);
}
+void remove_deferred_open_message_smb2(uint64_t mid)
+{
+ struct smbd_smb2_request *smb2req = find_open_smb2req(mid);
+
+ if (!smb2req) {
+ DEBUG(10,("remove_deferred_open_message_smb2: "
+ "can't find mid %llu\n",
+ (unsigned long long)mid ));
+ return;
+ }
+ remove_deferred_open_message_smb2_internal(smb2req, mid);
+}
+
void schedule_deferred_open_message_smb2(uint64_t mid)
{
struct tevent_immediate *im = NULL;
}
}
+static bool smbd_smb2_create_cancel(struct tevent_req *req)
+{
+ struct smbd_smb2_request *smb2req = NULL;
+ struct smbd_smb2_create_state *state = tevent_req_data(req,
+ struct smbd_smb2_create_state);
+ uint64_t mid;
+
+ if (!state) {
+ return false;
+ }
+
+ if (!state->smb2req) {
+ return false;
+ }
+
+ smb2req = state->smb2req;
+ mid = get_mid_from_smb2req(smb2req);
+
+ remove_deferred_open_entry(state->id, mid);
+ remove_deferred_open_message_smb2_internal(smb2req, mid);
+ smb2req->cancelled = true;
+
+ tevent_req_done(req);
+ return true;
+}
+
bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
struct timeval request_time,
struct timeval timeout,
+ struct file_id id,
char *private_data,
size_t priv_len)
{
- struct tevent_req *treq = NULL;
+ struct tevent_req *req = NULL;
struct smbd_smb2_create_state *state = NULL;
struct timeval end_time;
if (!smb2req) {
return false;
}
- treq = smb2req->subreq;
- if (!treq) {
+ req = smb2req->subreq;
+ if (!req) {
return false;
}
- state = tevent_req_data(treq, struct smbd_smb2_create_state);
+ state = tevent_req_data(req, struct smbd_smb2_create_state);
if (!state) {
return false;
}
+ state->id = id;
state->request_time = request_time;
state->private_data = data_blob_talloc(state, private_data,
priv_len);
if (!state->te) {
return false;
}
+
+ /* allow this request to be canceled */
+ tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
+
return true;
}