summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2017-07-21 18:59:55 +0200
committerRalph Boehme <slow@samba.org>2017-10-21 14:00:11 +0200
commit18a7ea8c0f76fa9c969e6e8563d1f8ad8c65a9c2 (patch)
tree164b17ecf382ca5a69c93134582b4e3c97024fa7 /source3/smbd
parente55949c415b5acbeadb463f5eae1ad5782531748 (diff)
downloadsamba-18a7ea8c0f76fa9c969e6e8563d1f8ad8c65a9c2.tar.gz
s3/smbd: use early returns in smbd_smb2_create_send
Now that we have the nice smbd_smb2_create_after_exec() and smbd_smb2_create_finish() functions, use early returns for the create replay and durable handle reconnect case. No change in behaviour, best viewed with $ git show -w COMMIT Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/smb2_create.c190
1 files changed, 103 insertions, 87 deletions
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index c7ec95209c8..41bfe9ccd88 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -624,6 +624,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
struct smbd_smb2_create_state *state = NULL;
NTSTATUS status;
struct smb_request *smb1req = NULL;
+ struct smb_filename *smb_fname = NULL;
+ uint32_t ucf_flags;
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_create_state);
@@ -757,6 +759,15 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
state->result->op = state->op;
state->update_open = false;
state->info = state->op->create_action;
+
+ smbd_smb2_create_after_exec(req);
+ if (!tevent_req_is_in_progress(req)) {
+ return req;
+ }
+
+ smbd_smb2_create_finish(req);
+ return req;
+
} else if (state->do_durable_reconnect) {
DATA_BLOB new_cookie = data_blob_null;
NTTIME now = timeval_to_nttime(&smb2req->request_time);
@@ -830,109 +841,114 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
state->update_open = true;
state->info = FILE_WAS_OPENED;
- } else {
- struct smb_filename *smb_fname = NULL;
- uint32_t ucf_flags;
- if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
- if (state->lease_ptr == NULL) {
- state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
- }
- } else {
- state->lease_ptr = NULL;
+ smbd_smb2_create_after_exec(req);
+ if (!tevent_req_is_in_progress(req)) {
+ return req;
}
- /*
- * For a DFS path the function parse_dfs_path()
- * will do the path processing.
- */
+ smbd_smb2_create_finish(req);
+ return req;
+ }
- if (!(smb1req->flags2 & FLAGS2_DFS_PATHNAMES)) {
- /* convert '\\' into '/' */
- status = check_path_syntax(state->fname);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return tevent_req_post(req, state->ev);
- }
+ if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
+ if (state->lease_ptr == NULL) {
+ state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
}
+ } else {
+ state->lease_ptr = NULL;
+ }
- ucf_flags = filename_create_ucf_flags(
- smb1req, state->in_create_disposition);
- status = filename_convert(req,
- smb1req->conn,
- state->fname,
- ucf_flags,
- NULL, /* ppath_contains_wcards */
- &smb_fname);
+ /*
+ * For a DFS path the function parse_dfs_path()
+ * will do the path processing.
+ */
+
+ if (!(smb1req->flags2 & FLAGS2_DFS_PATHNAMES)) {
+ /* convert '\\' into '/' */
+ status = check_path_syntax(state->fname);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return tevent_req_post(req, state->ev);
}
+ }
- /*
- * MS-SMB2: 2.2.13 SMB2 CREATE Request
- * ImpersonationLevel ... MUST contain one of the
- * following values. The server MUST validate this
- * field, but otherwise ignore it.
- *
- * NB. The source4/torture/smb2/durable_open.c test
- * shows this check is only done on real opens, not
- * on durable handle-reopens.
- */
+ ucf_flags = filename_create_ucf_flags(
+ smb1req, state->in_create_disposition);
+ status = filename_convert(req,
+ smb1req->conn,
+ state->fname,
+ ucf_flags,
+ NULL, /* ppath_contains_wcards */
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, state->ev);
+ }
- if (in_impersonation_level >
- SMB2_IMPERSONATION_DELEGATE) {
- tevent_req_nterror(req,
- NT_STATUS_BAD_IMPERSONATION_LEVEL);
- return tevent_req_post(req, state->ev);
- }
+ /*
+ * MS-SMB2: 2.2.13 SMB2 CREATE Request
+ * ImpersonationLevel ... MUST contain one of the
+ * following values. The server MUST validate this
+ * field, but otherwise ignore it.
+ *
+ * NB. The source4/torture/smb2/durable_open.c test
+ * shows this check is only done on real opens, not
+ * on durable handle-reopens.
+ */
- /*
- * We know we're going to do a local open, so now
- * we must be protocol strict. JRA.
- *
- * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
- * If the file name length is greater than zero and the
- * first character is a path separator character, the
- * server MUST fail the request with
- * STATUS_INVALID_PARAMETER.
- */
- if (in_name[0] == '\\' || in_name[0] == '/') {
- tevent_req_nterror(req,
- NT_STATUS_INVALID_PARAMETER);
- return tevent_req_post(req, state->ev);
- }
+ if (in_impersonation_level >
+ SMB2_IMPERSONATION_DELEGATE) {
+ tevent_req_nterror(req,
+ NT_STATUS_BAD_IMPERSONATION_LEVEL);
+ return tevent_req_post(req, state->ev);
+ }
- status = SMB_VFS_CREATE_FILE(smb1req->conn,
- smb1req,
- 0, /* root_dir_fid */
- smb_fname,
- in_desired_access,
- in_share_access,
- state->in_create_disposition,
- in_create_options,
- in_file_attributes,
- map_smb2_oplock_levels_to_samba(
- state->requested_oplock_level),
- state->lease_ptr,
- state->allocation_size,
- 0, /* private_flags */
- state->sec_desc,
- state->ea_list,
- &state->result,
- &state->info,
- &in_context_blobs,
- state->out_context_blobs);
- if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
- SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
- return req;
- }
- tevent_req_nterror(req, status);
- return tevent_req_post(req, state->ev);
+ /*
+ * We know we're going to do a local open, so now
+ * we must be protocol strict. JRA.
+ *
+ * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
+ * If the file name length is greater than zero and the
+ * first character is a path separator character, the
+ * server MUST fail the request with
+ * STATUS_INVALID_PARAMETER.
+ */
+ if (in_name[0] == '\\' || in_name[0] == '/') {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, state->ev);
+ }
+
+ status = SMB_VFS_CREATE_FILE(smb1req->conn,
+ smb1req,
+ 0, /* root_dir_fid */
+ smb_fname,
+ in_desired_access,
+ in_share_access,
+ state->in_create_disposition,
+ in_create_options,
+ in_file_attributes,
+ map_smb2_oplock_levels_to_samba(
+ state->requested_oplock_level),
+ state->lease_ptr,
+ state->allocation_size,
+ 0, /* private_flags */
+ state->sec_desc,
+ state->ea_list,
+ &state->result,
+ &state->info,
+ &in_context_blobs,
+ state->out_context_blobs);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
+ SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
+ return req;
}
- state->op = state->result->op;
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, state->ev);
}
+ state->op = state->result->op;
smbd_smb2_create_after_exec(req);
if (!tevent_req_is_in_progress(req)) {