s4:smb_server/smb2: always grant the requested credits
authorStefan Metzmacher <metze@samba.org>
Mon, 31 Oct 2011 12:43:01 +0000 (13:43 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 31 Oct 2011 18:39:03 +0000 (19:39 +0100)
At least one credit, if the client asked for 0.

metze

source4/smb_server/smb2/receive.c
source4/smb_server/smb2/sesssetup.c
source4/smb_server/smb2/tcon.c

index f3402c8c98089b86e61967beb8f20eef8c48be97..7463712cd423373e36d52ff21e767b68626454b5 100644 (file)
@@ -80,6 +80,11 @@ NTSTATUS smb2srv_setup_reply(struct smb2srv_request *req, uint16_t body_fixed_si
        uint32_t flags = IVAL(req->in.hdr, SMB2_HDR_FLAGS);
        uint32_t pid = IVAL(req->in.hdr, SMB2_HDR_PID);
        uint32_t tid = IVAL(req->in.hdr, SMB2_HDR_TID);
+       uint16_t credits = SVAL(req->in.hdr, SMB2_HDR_CREDIT);
+
+       if (credits == 0) {
+               credits = 1;
+       }
 
        flags |= SMB2_HDR_FLAG_REDIRECT;
 
@@ -87,6 +92,7 @@ NTSTATUS smb2srv_setup_reply(struct smb2srv_request *req, uint16_t body_fixed_si
                flags |= SMB2_HDR_FLAG_ASYNC;
                pid = req->pending_id;
                tid = 0;
+               credits = 0;
        }
 
        if (body_dynamic_present) {
@@ -116,7 +122,7 @@ NTSTATUS smb2srv_setup_reply(struct smb2srv_request *req, uint16_t body_fixed_si
              SVAL(req->in.hdr, SMB2_HDR_CREDIT_CHARGE));
        SIVAL(req->out.hdr, SMB2_HDR_STATUS,            NT_STATUS_V(req->status));
        SSVAL(req->out.hdr, SMB2_HDR_OPCODE,            SVAL(req->in.hdr, SMB2_HDR_OPCODE));
-       SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            0x0001);
+       SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            credits);
        SIVAL(req->out.hdr, SMB2_HDR_FLAGS,             flags);
        SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND,      0);
        SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID,        req->seqnum);
@@ -573,11 +579,21 @@ NTSTATUS smb2srv_queue_pending(struct smb2srv_request *req)
        NTSTATUS status;
        bool signing_used = false;
        int id;
+       uint16_t credits = SVAL(req->in.hdr, SMB2_HDR_CREDIT);
+
+       if (credits == 0) {
+               credits = 1;
+       }
 
        if (req->pending_id) {
                return NT_STATUS_INTERNAL_ERROR;
        }
 
+       if (req->smb_conn->connection->event.fde == NULL) {
+               /* the socket has been destroyed - no point trying to send an error! */
+               return NT_STATUS_REMOTE_DISCONNECT;
+       }
+
        id = idr_get_new_above(req->smb_conn->requests2.idtree_req, req, 
                               1, req->smb_conn->requests2.idtree_limit);
        if (id == -1) {
@@ -587,11 +603,6 @@ NTSTATUS smb2srv_queue_pending(struct smb2srv_request *req)
        DLIST_ADD_END(req->smb_conn->requests2.list, req, struct smb2srv_request *);
        req->pending_id = id;
 
-       if (req->smb_conn->connection->event.fde == NULL) {
-               /* the socket has been destroyed - no point trying to send an error! */
-               return NT_STATUS_REMOTE_DISCONNECT;
-       }
-
        talloc_set_destructor(req, smb2srv_request_deny_destructor);
 
        status = smb2srv_setup_reply(req, 8, true, 0);
@@ -600,6 +611,7 @@ NTSTATUS smb2srv_queue_pending(struct smb2srv_request *req)
        }
 
        SIVAL(req->out.hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
+       SSVAL(req->out.hdr, SMB2_HDR_CREDIT, credits);
 
        SSVAL(req->out.body, 0x02, 0);
        SIVAL(req->out.body, 0x04, 0);
index 243765fb9f51db964d87878fe079bf734aa05629..41f629b978f159df17a0689ff3c319a10c112d36 100644 (file)
 
 static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io)
 {
-       uint16_t credit;
-
        if (NT_STATUS_IS_OK(req->status)) {
-               credit = 0x0003;
+               /* nothing */
        } else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-               credit = 0x0002;
+               /* nothing */
        } else {
                smb2srv_send_error(req, req->status);
                return;
@@ -44,7 +42,6 @@ static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sessse
 
        SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, io->smb2.out.secblob.length));
 
-       SSVAL(req->out.hdr, SMB2_HDR_CREDIT,    credit);
        SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID,        io->smb2.out.uid);
 
        SSVAL(req->out.body, 0x02, io->smb2.out.session_flags);
index 0dac29cf57a4248252e615e8448317dbcec326b6..6ee2eb5f8ece4bab5b14ee25c74448458950a478 100644 (file)
@@ -359,23 +359,14 @@ failed:
 
 static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io)
 {
-       uint16_t credit;
-
        if (!NT_STATUS_IS_OK(req->status)) {
                smb2srv_send_error(req, req->status);
                return;
        }
-       if (io->smb2.out.share_type == NTVFS_IPC) {
-               /* if it's an IPC share vista returns 0x0005 */
-               credit = 0x0005;
-       } else {
-               credit = 0x0001;
-       }
 
        SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x10, false, 0));
 
        SIVAL(req->out.hdr,     SMB2_HDR_TID,   io->smb2.out.tid);
-       SSVAL(req->out.hdr,     SMB2_HDR_CREDIT,credit);
 
        SCVAL(req->out.body,    0x02,           io->smb2.out.share_type);
        SCVAL(req->out.body,    0x03,           io->smb2.out.reserved);