X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source3%2Fsmbd%2Fsmb2_server.c;h=c889555a1cbaf5c37196c4ea0f8c6da8c657d84a;hb=cf7c41b841d03ecbe09ee531f6dd73be17948ac1;hp=32bb5543aeeff3c4d33fa8287ce8a8b9ec6daf3f;hpb=202509a3479b7bba9a5dfce58270fb8f46cc496a;p=nivanova%2Fsamba-autobuild%2F.git diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 32bb5543aee..c889555a1cb 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -41,7 +41,7 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *conn) NTSTATUS status; int ret; - TALLOC_FREE(conn->fde); + TALLOC_FREE(conn->smb1.fde); conn->smb2.event_ctx = smbd_event_context(); @@ -59,7 +59,7 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *conn) if (conn->smb2.sessions.idtree == NULL) { return NT_STATUS_NO_MEMORY; } - conn->smb2.sessions.limit = 0x00FFFFFF; + conn->smb2.sessions.limit = 0x0000FFFE; conn->smb2.sessions.list = NULL; ret = tstream_bsd_existing_socket(conn, smbd_server_fd(), @@ -186,6 +186,86 @@ static NTSTATUS smbd_smb2_request_create(struct smbd_server_connection *conn, return NT_STATUS_OK; } +static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req) +{ + int count; + int idx; + bool compound_related = false; + + count = req->in.vector_count; + + if (count < 4) { + /* It's not a SMB2 request */ + return NT_STATUS_INVALID_PARAMETER; + } + + for (idx=1; idx < count; idx += 3) { + const uint8_t *inhdr = NULL; + uint32_t flags; + + if (req->in.vector[idx].iov_len != SMB2_HDR_BODY) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (req->in.vector[idx+1].iov_len < 2) { + return NT_STATUS_INVALID_PARAMETER; + } + + inhdr = (const uint8_t *)req->in.vector[idx].iov_base; + + /* setup the SMB2 header */ + if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) { + return NT_STATUS_INVALID_PARAMETER; + } + + flags = IVAL(inhdr, SMB2_HDR_FLAGS); + if (idx == 1) { + /* + * the 1st request should never have the + * SMB2_HDR_FLAG_CHAINED flag set + */ + if (flags & SMB2_HDR_FLAG_CHAINED) { + req->next_status = NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_OK; + } + } else if (idx == 4) { + /* + * the 2nd request triggers related vs. unrelated + * compounded requests + */ + if (flags & SMB2_HDR_FLAG_CHAINED) { + compound_related = true; + } + } else if (idx > 4) { +#if 0 + /* + * It seems the this tests are wrong + * see the SMB2-COMPOUND test + */ + + /* + * all other requests should match the 2nd one + */ + if (flags & SMB2_HDR_FLAG_CHAINED) { + if (!compound_related) { + req->next_status = + NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_OK; + } + } else { + if (compound_related) { + req->next_status = + NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_OK; + } + } +#endif + } + } + + return NT_STATUS_OK; +} + static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) { struct iovec *vector; @@ -204,29 +284,27 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) for (idx=1; idx < count; idx += 3) { const uint8_t *inhdr = NULL; + uint32_t in_flags; uint8_t *outhdr = NULL; uint8_t *outbody = NULL; - uint8_t *outdyn = NULL; - size_t outdyn_size = 1; uint32_t next_command_ofs = 0; struct iovec *current = &vector[idx]; if ((idx + 3) < count) { /* we have a next command */ - next_command_ofs = SMB2_HDR_BODY + 8 + 8; - outdyn_size = 8; + next_command_ofs = SMB2_HDR_BODY + 8; } inhdr = (const uint8_t *)req->in.vector[idx].iov_base; + in_flags = IVAL(inhdr, SMB2_HDR_FLAGS); outhdr = talloc_array(vector, uint8_t, - SMB2_HDR_BODY + 8 + outdyn_size); + SMB2_HDR_BODY + 8); if (outhdr == NULL) { return NT_STATUS_NO_MEMORY; } outbody = outhdr + SMB2_HDR_BODY; - outdyn = outbody + 8; current[0].iov_base = (void *)outhdr; current[0].iov_len = SMB2_HDR_BODY; @@ -234,8 +312,8 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) current[1].iov_base = (void *)outbody; current[1].iov_len = 8; - current[2].iov_base = (void *)outdyn; - current[2].iov_len = outdyn_size; + current[2].iov_base = NULL; + current[2].iov_len = 0; /* setup the SMB2 header */ SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC); @@ -245,8 +323,10 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) NT_STATUS_V(NT_STATUS_INTERNAL_ERROR)); SSVAL(outhdr, SMB2_HDR_OPCODE, SVAL(inhdr, SMB2_HDR_OPCODE)); - SSVAL(outhdr, SMB2_HDR_CREDIT, 0); - SIVAL(outhdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT); + /* Make up a number for now... JRA. FIXME ! FIXME !*/ + SSVAL(outhdr, SMB2_HDR_CREDIT, 20); + SIVAL(outhdr, SMB2_HDR_FLAGS, + IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT); SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs); SBVAL(outhdr, SMB2_HDR_MESSAGE_ID, BVAL(inhdr, SMB2_HDR_MESSAGE_ID)); @@ -259,12 +339,9 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) memset(outhdr + SMB2_HDR_SIGNATURE, 0, 16); /* setup error body header */ - SSVAL(outbody, 0x00, 9); + SSVAL(outbody, 0x00, 0x08 + 1); SSVAL(outbody, 0x02, 0); SIVAL(outbody, 0x04, 0); - - /* setup the dynamic part */ - SCVAL(outdyn, 0x00, 0); } req->out.vector = vector; @@ -276,10 +353,12 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) return NT_STATUS_OK; } -static void smbd_server_connection_terminate(struct smbd_server_connection *conn, - const char *reason) +void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, + const char *reason, + const char *location) { - DEBUG(10,("smbd_server_connection_terminate: reason[%s]\n", reason)); + DEBUG(10,("smbd_server_connection_terminate_ex: reason[%s] at %s\n", + reason, location)); exit_server_cleanly(reason); } @@ -288,14 +367,60 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) const uint8_t *inhdr; int i = req->current_idx; uint16_t opcode; + uint32_t flags; NTSTATUS status; + NTSTATUS session_status; inhdr = (const uint8_t *)req->in.vector[i].iov_base; /* TODO: verify more things */ + flags = IVAL(inhdr, SMB2_HDR_FLAGS); opcode = IVAL(inhdr, SMB2_HDR_OPCODE); DEBUG(10,("smbd_smb2_request_dispatch: opcode[%u]\n", opcode)); + +#define TMP_SMB2_ALLOWED_FLAGS ( \ + SMB2_HDR_FLAG_CHAINED | \ + SMB2_HDR_FLAG_SIGNED | \ + SMB2_HDR_FLAG_DFS) + if ((flags & ~TMP_SMB2_ALLOWED_FLAGS) != 0) { + return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); + } +#undef TMP_SMB2_ALLOWED_FLAGS + + session_status = smbd_smb2_request_check_session(req); + + req->do_signing = false; + if (flags & SMB2_HDR_FLAG_SIGNED) { + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); + } + + req->do_signing = true; + status = smb2_signing_check_pdu(req->session->session_key, + &req->in.vector[i], 3); + if (!NT_STATUS_IS_OK(status)) { + return smbd_smb2_request_error(req, status); + } + } else if (req->session && req->session->do_signing) { + return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); + } + + if (flags & SMB2_HDR_FLAG_CHAINED) { + /* + * This check is mostly for giving the correct error code + * for compounded requests. + * + * TODO: we may need to move this after the session + * and tcon checks. + */ + if (!NT_STATUS_IS_OK(req->next_status)) { + return smbd_smb2_request_error(req, req->next_status); + } + } else { + req->compat_chain_fsp = NULL; + } + switch (opcode) { case SMB2_OP_NEGPROT: return smbd_smb2_request_process_negprot(req); @@ -304,13 +429,15 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_process_sesssetup(req); case SMB2_OP_LOGOFF: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } return smbd_smb2_request_process_logoff(req); case SMB2_OP_TCON: + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); + } status = smbd_smb2_request_check_session(req); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); @@ -318,9 +445,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_process_tcon(req); case SMB2_OP_TDIS: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -329,64 +455,58 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_process_tdis(req); case SMB2_OP_CREATE: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } - return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); + return smbd_smb2_request_process_create(req); case SMB2_OP_CLOSE: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } - return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); + return smbd_smb2_request_process_close(req); case SMB2_OP_FLUSH: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } - return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); + return smbd_smb2_request_process_flush(req); case SMB2_OP_READ: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } - return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); + return smbd_smb2_request_process_read(req); case SMB2_OP_WRITE: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } - return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); + return smbd_smb2_request_process_write(req); case SMB2_OP_LOCK: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -395,15 +515,14 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_IOCTL: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } - return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); + return smbd_smb2_request_process_ioctl(req); case SMB2_OP_CANCEL: return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); @@ -412,9 +531,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_process_keepalive(req); case SMB2_OP_FIND: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -423,9 +541,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_NOTIFY: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -434,9 +551,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_GETINFO: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -445,9 +561,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_SETINFO: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -456,9 +571,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_BREAK: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -477,13 +591,21 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) { struct tevent_req *subreq; - /* TODO: sign the response here */ - smb2_setup_nbt_length(req->out.vector, req->out.vector_count); + if (req->do_signing) { + int i = req->current_idx; + NTSTATUS status; + status = smb2_signing_sign_pdu(req->session->session_key, + &req->out.vector[i], 3); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + req->current_idx += 3; - if (req->current_idx > req->in.vector_count) { + if (req->current_idx < req->out.vector_count) { struct timeval zero = timeval_zero(); subreq = tevent_wakeup_send(req, req->conn->smb2.event_ctx, @@ -556,14 +678,16 @@ static void smbd_smb2_request_writev_done(struct tevent_req *subreq) NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req, NTSTATUS status, - DATA_BLOB *info) + DATA_BLOB *info, + const char *location) { uint8_t *outhdr; uint8_t *outbody; int i = req->current_idx; - DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s]%s\n", - i, nt_errstr(status), info ? " +info" : "")); + DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| at %s\n", + i, nt_errstr(status), info ? " +info" : "", + location)); outhdr = (uint8_t *)req->out.vector[i].iov_base; @@ -579,26 +703,23 @@ NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req, req->out.vector[i+2].iov_base = (void *)info->data; req->out.vector[i+2].iov_len = info->length; } else { - req->out.vector[i+2].iov_base = (void *)(outbody + 8); - req->out.vector[i+2].iov_len = 1; + req->out.vector[i+2].iov_base = NULL; + req->out.vector[i+2].iov_len = 0; } - /* the error packet is the last response in the chain */ - SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0); - req->out.vector_count = req->current_idx + 3; + /* + * if a request fails, all other remaining + * compounded requests should fail too + */ + req->next_status = NT_STATUS_INVALID_PARAMETER; return smbd_smb2_request_reply(req); } -NTSTATUS smbd_smb2_request_error(struct smbd_smb2_request *req, - NTSTATUS status) -{ - return smbd_smb2_request_error_ex(req, status, NULL); -} - NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req, NTSTATUS status, - DATA_BLOB body, DATA_BLOB *dyn) + DATA_BLOB body, DATA_BLOB *dyn, + const char *location) { uint8_t *outhdr; uint8_t *outdyn; @@ -606,10 +727,11 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req, uint32_t next_command_ofs; DEBUG(10,("smbd_smb2_request_done_ex: " - "idx[%d] status[%s] body[%u] dyn[%s:%u]\n", + "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n", i, nt_errstr(status), (unsigned int)body.length, dyn ? "yes": "no", - (unsigned int)(dyn ? dyn->length : 0))); + (unsigned int)(dyn ? dyn->length : 0), + location)); if (body.length < 2) { return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR); @@ -630,13 +752,8 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req, req->out.vector[i+1].iov_len = body.length; if (dyn) { - if (dyn->length > 0) { - req->out.vector[i+2].iov_base = (void *)dyn->data; - req->out.vector[i+2].iov_len = dyn->length; - } else { - req->out.vector[i+2].iov_base = (void *)outdyn; - req->out.vector[i+2].iov_len = 1; - } + req->out.vector[i+2].iov_base = (void *)dyn->data; + req->out.vector[i+2].iov_len = dyn->length; } else { req->out.vector[i+2].iov_base = NULL; req->out.vector[i+2].iov_len = 0; @@ -649,23 +766,61 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req, next_command_ofs += req->out.vector[i+2].iov_len; } - /* TODO: we need to add padding ... */ if ((next_command_ofs % 8) != 0) { - return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR); + size_t pad_size = 8 - (next_command_ofs % 8); + if (req->out.vector[i+2].iov_len == 0) { + /* + * if the dyn buffer is empty + * we can use it to add padding + */ + uint8_t *pad; + + pad = talloc_zero_array(req->out.vector, + uint8_t, pad_size); + if (pad == NULL) { + return smbd_smb2_request_error(req, + NT_STATUS_NO_MEMORY); + } + + req->out.vector[i+2].iov_base = (void *)pad; + req->out.vector[i+2].iov_len = pad_size; + } else { + /* + * For now we copy the dynamic buffer + * and add the padding to the new buffer + */ + size_t old_size; + uint8_t *old_dyn; + size_t new_size; + uint8_t *new_dyn; + + old_size = req->out.vector[i+2].iov_len; + old_dyn = (uint8_t *)req->out.vector[i+2].iov_base; + + new_size = old_size + pad_size; + new_dyn = talloc_array(req->out.vector, + uint8_t, new_size); + if (new_dyn == NULL) { + return smbd_smb2_request_error(req, + NT_STATUS_NO_MEMORY); + } + + memcpy(new_dyn, old_dyn, old_size); + memset(new_dyn + old_size, 0, pad_size); + + req->out.vector[i+2].iov_base = (void *)new_dyn; + req->out.vector[i+2].iov_len = new_size; + + TALLOC_FREE(old_dyn); + } + next_command_ofs += pad_size; } - /* the error packet is the last response in the chain */ SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs); return smbd_smb2_request_reply(req); } -NTSTATUS smbd_smb2_request_done(struct smbd_smb2_request *req, - DATA_BLOB body, DATA_BLOB *dyn) -{ - return smbd_smb2_request_done_ex(req, NT_STATUS_OK, body, dyn); -} - struct smbd_smb2_request_read_state { size_t missing; bool asked_for_header; @@ -1097,12 +1252,25 @@ static void smbd_smb2_request_incoming(struct tevent_req *subreq) return; } - /* TODO: validate the incoming request */ + if (req->in.nbt_hdr[0] != 0x00) { + DEBUG(1,("smbd_smb2_request_incoming: ignore NBT[0x%02X] msg\n", + req->in.nbt_hdr[0])); + talloc_free(req->mem_pool); + req = NULL; + goto next; + } + req->current_idx = 1; DEBUG(10,("smbd_smb2_request_incoming: idx[%d] of %d vectors\n", req->current_idx, req->in.vector_count)); + status = smbd_smb2_request_validate(req); + if (!NT_STATUS_IS_OK(status)) { + smbd_server_connection_terminate(conn, nt_errstr(status)); + return; + } + status = smbd_smb2_request_setup_out(req); if (!NT_STATUS_IS_OK(status)) { smbd_server_connection_terminate(conn, nt_errstr(status)); @@ -1115,6 +1283,7 @@ static void smbd_smb2_request_incoming(struct tevent_req *subreq) return; } +next: /* ask for the next request (this constructs the main loop) */ subreq = smbd_smb2_request_read_send(conn,conn->smb2.event_ctx, conn); if (subreq == NULL) {