From 7dd6e5fe9250b0e8653dd40cc3a84a23f2f71d5a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Nov 2005 13:50:56 +0000 Subject: r11724: - move checks packet size and protocol version, before we create the request structure - move code into one function metze (This used to be commit 96345b1c465c6cdf480f6e49d3c437cfe4d93c2c) --- source4/include/smb.h | 2 + source4/smb_server/smb_server.c | 107 ++++++++++++++++++++-------------------- 2 files changed, 56 insertions(+), 53 deletions(-) diff --git a/source4/include/smb.h b/source4/include/smb.h index fcde3848dc..cb59adb84c 100644 --- a/source4/include/smb.h +++ b/source4/include/smb.h @@ -204,6 +204,8 @@ struct data_blob_list_item { /* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30, 4 byte aligned */ typedef uint64_t NTTIME; +#define SMB_MAGIC 0x424D53FF /* 0xFF 'S' 'M' 'B' */ + /* the basic packet size, assuming no words or bytes. Does not include the NBT header */ #define MIN_SMB_SIZE 35 diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c index 8f6accb370..340674b8df 100644 --- a/source4/smb_server/smb_server.c +++ b/source4/smb_server/smb_server.c @@ -62,8 +62,7 @@ BOOL req_send_oplock_break(struct smbsrv_tcon *tcon, uint16_t fnum, uint8_t leve return True; } - -static void construct_reply(struct smbsrv_request *req); +static void switch_message(int type, struct smbsrv_request *req); /**************************************************************************** receive a SMB request header from the wire, forming a request_context @@ -73,12 +72,40 @@ static NTSTATUS receive_smb_request(void *private, DATA_BLOB blob) { struct smbsrv_connection *smb_conn = talloc_get_type(private, struct smbsrv_connection); struct smbsrv_request *req; + uint8_t command; - req = init_smb_request(smb_conn); - if (req == NULL) { - return NT_STATUS_NO_MEMORY; + /* see if its a special NBT packet */ + if (CVAL(blob.data, 0) != 0) { + req = init_smb_request(smb_conn); + NT_STATUS_HAVE_NO_MEMORY(req); + + ZERO_STRUCT(req->in); + + req->in.buffer = talloc_steal(req, blob.data); + req->in.size = blob.length; + req->request_time = timeval_current(); + + reply_special(req); + return NT_STATUS_OK; } + if ((NBT_HDR_SIZE + MIN_SMB_SIZE) > blob.length) { + DEBUG(2,("Invalid SMB packet: length %d\n", blob.length)); + smbsrv_terminate_connection(smb_conn, "Invalid SMB packet"); + return NT_STATUS_OK; + } + + /* Make sure this is an SMB packet */ + if (IVAL(blob.data, NBT_HDR_SIZE) != SMB_MAGIC) { + DEBUG(2,("Non-SMB packet of length %d. Terminating connection\n", + blob.length)); + smbsrv_terminate_connection(smb_conn, "Non-SMB packet"); + return NT_STATUS_OK; + } + + req = init_smb_request(smb_conn); + NT_STATUS_HAVE_NO_MEMORY(req); + req->in.buffer = talloc_steal(req, blob.data); req->in.size = blob.length; req->request_time = timeval_current(); @@ -105,8 +132,29 @@ static NTSTATUS receive_smb_request(void *private, DATA_BLOB blob) } } - construct_reply(req); + if (NBT_HDR_SIZE + MIN_SMB_SIZE + 2*req->in.wct > req->in.size) { + DEBUG(2,("Invalid SMB word count %d\n", req->in.wct)); + smbsrv_terminate_connection(req->smb_conn, "Invalid SMB packet"); + return NT_STATUS_OK; + } + + if (NBT_HDR_SIZE + MIN_SMB_SIZE + 2*req->in.wct + req->in.data_size > req->in.size) { + DEBUG(2,("Invalid SMB buffer length count %d\n", req->in.data_size)); + smbsrv_terminate_connection(req->smb_conn, "Invalid SMB packet"); + return NT_STATUS_OK; + } + + req->flags = CVAL(req->in.hdr, HDR_FLG); + req->flags2 = SVAL(req->in.hdr, HDR_FLG2); + req->smbpid = SVAL(req->in.hdr, HDR_PID); + if (!req_signing_check_incoming(req)) { + req_reply_error(req, NT_STATUS_ACCESS_DENIED); + return NT_STATUS_OK; + } + + command = CVAL(req->in.hdr, HDR_COM); + switch_message(command, req); return NT_STATUS_OK; } @@ -514,53 +562,6 @@ static void switch_message(int type, struct smbsrv_request *req) smb_messages[type].fn(req); } - -/**************************************************************************** - Construct a reply to the incoming packet. -****************************************************************************/ -static void construct_reply(struct smbsrv_request *req) -{ - uint8_t type = CVAL(req->in.hdr,HDR_COM); - - /* see if its a special NBT packet */ - if (CVAL(req->in.buffer,0) != 0) { - reply_special(req); - return; - } - - /* Make sure this is an SMB packet */ - if (memcmp(req->in.hdr,"\377SMB",4) != 0) { - DEBUG(2,("Non-SMB packet of length %d. Terminating connection\n", - req->in.size)); - smbsrv_terminate_connection(req->smb_conn, "Non-SMB packet"); - return; - } - - if (NBT_HDR_SIZE + MIN_SMB_SIZE + 2*req->in.wct > req->in.size) { - DEBUG(2,("Invalid SMB word count %d\n", req->in.wct)); - smbsrv_terminate_connection(req->smb_conn, "Invalid SMB packet"); - return; - } - - if (NBT_HDR_SIZE + MIN_SMB_SIZE + 2*req->in.wct + req->in.data_size > req->in.size) { - DEBUG(2,("Invalid SMB buffer length count %d\n", req->in.data_size)); - smbsrv_terminate_connection(req->smb_conn, "Invalid SMB packet"); - return; - } - - req->flags = CVAL(req->in.hdr, HDR_FLG); - req->flags2 = SVAL(req->in.hdr, HDR_FLG2); - req->smbpid = SVAL(req->in.hdr,HDR_PID); - - if (!req_signing_check_incoming(req)) { - req_reply_error(req, NT_STATUS_ACCESS_DENIED); - return; - } - - switch_message(type, req); -} - - /* we call this when first first part of a possibly chained request has been completed and we need to call the 2nd part, if any -- cgit