r11724: - move checks packet size and protocol version,
authorStefan Metzmacher <metze@samba.org>
Mon, 14 Nov 2005 13:50:56 +0000 (13:50 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:18 +0000 (13:46 -0500)
  before we create the request structure
- move code into one function

metze

source/include/smb.h
source/smb_server/smb_server.c

index fcde3848dcbeb2f1520635fe5778e326e01b06c5..cb59adb84c869c40130ec33053d68acc890a8f7f 100644 (file)
@@ -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
 
index 8f6accb370fc1489b9e09a3784066ef66547d3d3..340674b8df44c4f0fe14d9a126a4001522287360 100644 (file)
@@ -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