s3:smbd: fix the logic for compounded requests
[ira/wip.git] / source3 / smbd / smb2_server.c
index 75e86e0d3166261493595047b9b3294e85b3d78e..0413832f905c85bd0be1756ccca4481a3929a43d 100644 (file)
@@ -245,7 +245,8 @@ 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);
+               /* Make up a number for now... JRA. FIXME ! FIXME !*/
+               SSVAL(outhdr, SMB2_HDR_CREDIT,          20);
                SIVAL(outhdr, SMB2_HDR_FLAGS,           SMB2_HDR_FLAG_REDIRECT);
                SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND,    next_command_ofs);
                SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
@@ -276,10 +277,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);
 }
 
@@ -378,7 +381,7 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *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:
                if (!NT_STATUS_IS_OK(session_status)) {
@@ -388,7 +391,7 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *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:
                if (!NT_STATUS_IS_OK(session_status)) {
@@ -398,7 +401,7 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *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:
                if (!NT_STATUS_IS_OK(session_status)) {
@@ -408,7 +411,7 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *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:
                if (!NT_STATUS_IS_OK(session_status)) {
@@ -428,7 +431,7 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *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);
@@ -511,7 +514,7 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
 
        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,
@@ -584,14 +587,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;
 
@@ -618,15 +623,10 @@ NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
        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;
@@ -634,10 +634,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);
@@ -662,8 +663,7 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
                        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;
+                       /* the dyn section is already initialized */
                }
        } else {
                req->out.vector[i+2].iov_base = NULL;
@@ -688,12 +688,6 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
        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;