s4:smb_server/smb: remove a request from the list before adding the next one in a...
[samba.git] / source4 / smb_server / smb / receive.c
index 0afa3a652d5d02486fe4da10490c237b8325fa55..b100757b551e5382aa6782205c2c51b0d832053f 100644 (file)
 #include "system/time.h"
 #include "smbd/service_stream.h"
 #include "smb_server/smb_server.h"
-#include "smb_server/service_smb_proto.h"
-#include "ntvfs/ntvfs.h"
 #include "system/filesys.h"
 #include "param/param.h"
-
+#include "cluster/cluster.h"
 
 /*
   send an oplock break request to a client
@@ -105,7 +103,7 @@ static const struct smb_message_struct
 /* 0x0d */ { "SMBunlock",      smbsrv_reply_unlock,            NEED_SESS|NEED_TCON },
 /* 0x0e */ { "SMBctemp",       smbsrv_reply_ctemp,             NEED_SESS|NEED_TCON },
 /* 0x0f */ { "SMBmknew",       smbsrv_reply_mknew,             NEED_SESS|NEED_TCON }, 
-/* 0x10 */ { "SMBchkpth",      smbsrv_reply_chkpth,            NEED_SESS|NEED_TCON },
+/* 0x10 */ { "SMBcheckpath",   smbsrv_reply_chkpth,            NEED_SESS|NEED_TCON },
 /* 0x11 */ { "SMBexit",                smbsrv_reply_exit,              NEED_SESS },
 /* 0x12 */ { "SMBlseek",       smbsrv_reply_lseek,             NEED_SESS|NEED_TCON },
 /* 0x13 */ { "SMBlockread",    smbsrv_reply_lockread,          NEED_SESS|NEED_TCON },
@@ -351,9 +349,9 @@ static const struct smb_message_struct
 receive a SMB request header from the wire, forming a request_context
 from the result
 ****************************************************************************/
-NTSTATUS smbsrv_recv_smb_request(void *private, DATA_BLOB blob)
+NTSTATUS smbsrv_recv_smb_request(void *private_data, DATA_BLOB blob)
 {
-       struct smbsrv_connection *smb_conn = talloc_get_type(private, struct smbsrv_connection);
+       struct smbsrv_connection *smb_conn = talloc_get_type(private_data, struct smbsrv_connection);
        struct smbsrv_request *req;
        struct timeval cur_time = timeval_current();
        uint8_t command;
@@ -407,19 +405,14 @@ NTSTATUS smbsrv_recv_smb_request(void *private, DATA_BLOB blob)
                req->in.data = req->in.vwv + VWV(req->in.wct) + 2;
                req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct));
 
-               /* the bcc length is only 16 bits, but some packets
-                  (such as SMBwriteX) can be much larger than 64k. We
-                  detect this by looking for a large non-chained NBT
-                  packet (at least 64k bigger than what is
-                  specified). If it is detected then the NBT size is
-                  used instead of the bcc size */
-               if (req->in.data_size + 0x10000 <= 
-                   req->in.size - PTR_DIFF(req->in.data, req->in.buffer) &&
-                       ( message_flags(command) & LARGE_REQUEST) &&
-                       ( !(message_flags(command) & AND_X) ||
-                     (req->in.wct < 1 || SVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE) )
-                       ) {
-                       /* its an oversized packet! fun for all the family */
+               /* special handling for oversize calls. Windows seems
+                  to take the maximum of the BCC value and the
+                  computed buffer size. This handles oversized writeX
+                  calls, and possibly oversized SMBtrans calls */
+               if ((message_flags(command) & LARGE_REQUEST) &&
+                   ( !(message_flags(command) & AND_X) ||
+                     (req->in.wct < 1 || SVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE)) &&
+                   req->in.data_size < req->in.size - PTR_DIFF(req->in.data,req->in.buffer)) {
                        req->in.data_size = req->in.size - PTR_DIFF(req->in.data,req->in.buffer);
                }
        }
@@ -478,6 +471,7 @@ static void switch_message(int type, struct smbsrv_request *req)
        int flags;
        struct smbsrv_connection *smb_conn = req->smb_conn;
        NTSTATUS status;
+       char *task_id;
 
        type &= 0xff;
 
@@ -498,18 +492,13 @@ static void switch_message(int type, struct smbsrv_request *req)
                   hasn't already been initialised (to cope with SMB
                   chaining) */
 
-               /* In share mode security we must ignore the vuid. */
-               if (smb_conn->config.security == SEC_SHARE) {
-                       if (req->tcon) {
-                               req->session = req->tcon->sec_share.session;
-                       }
-               } else {
-                       req->session = smbsrv_session_find(req->smb_conn, SVAL(req->in.hdr,HDR_UID), req->request_time);
-               }
+               req->session = smbsrv_session_find(req->smb_conn, SVAL(req->in.hdr,HDR_UID), req->request_time);
        }
 
-       DEBUG(5,("switch message %s (task_id %u)\n",
-                smb_fn_name(type), (unsigned)req->smb_conn->connection->server_id.id));
+       task_id = server_id_str(NULL, &req->smb_conn->connection->server_id);
+       DEBUG(5,("switch message %s (task_id %s)\n",
+                smb_fn_name(type), task_id));
+       talloc_free(task_id);
 
        /* this must be called before we do any reply */
        if (flags & SIGNING_NO_REPLY) {
@@ -644,6 +633,7 @@ void smbsrv_chain_reply(struct smbsrv_request *req)
        SSVAL(req->out.vwv, VWV(1), req->out.size - NBT_HDR_SIZE);
 
        /* cleanup somestuff for the next request */
+       DLIST_REMOVE(req->smb_conn->requests, req);
        talloc_free(req->ntvfs);
        req->ntvfs = NULL;
        talloc_free(req->io_ptr);
@@ -670,12 +660,11 @@ NTSTATUS smbsrv_init_smb_connection(struct smbsrv_connection *smb_conn, struct l
 
        /* this is the size that w2k uses, and it appears to be important for
           good performance */
-       smb_conn->negotiate.max_recv = lp_max_xmit(lp_ctx);
+       smb_conn->negotiate.max_recv = lpcfg_max_xmit(lp_ctx);
 
        smb_conn->negotiate.zone_offset = get_time_zone(time(NULL));
 
-       smb_conn->config.security = lp_security(lp_ctx);
-       smb_conn->config.nt_status_support = lp_nt_status_support(lp_ctx);
+       smb_conn->config.nt_status_support = lpcfg_nt_status_support(lp_ctx);
 
        status = smbsrv_init_sessions(smb_conn, UINT16_MAX);
        NT_STATUS_NOT_OK_RETURN(status);