s3:smbd: implement SMB2 Tree Disconnect
authorStefan Metzmacher <metze@samba.org>
Fri, 22 May 2009 10:42:24 +0000 (12:42 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 22 May 2009 12:03:14 +0000 (14:03 +0200)
metze

source3/smbd/globals.h
source3/smbd/smb2_server.c
source3/smbd/smb2_tcon.c

index a26311e7dad41f7f49127621b1300ae4e9e64c6d..9d5eead93976dbfefc9cd55ad9e8c1cc5d2aedcd 100644 (file)
@@ -229,6 +229,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_tcon(struct smbd_smb2_request *req);
+NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req);
 
 struct smbd_smb2_request {
index a11ffd76249d89448bdaa163c71758675187b77d..32bb5543aeeff3c4d33fa8287ce8a8b9ec6daf3f 100644 (file)
@@ -326,7 +326,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_tdis(req);
 
        case SMB2_OP_CREATE:
                status = smbd_smb2_request_check_session(req);
index 895677c9845395cd2c5b3411183594045dd6e542..f74d1bcca75f2580aa4c63a9afd63238d24518fd 100644 (file)
@@ -194,3 +194,39 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
        req->tcon = tcon;
        return NT_STATUS_OK;
 }
+
+NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req)
+{
+       const uint8_t *inbody;
+       int i = req->current_idx;
+       DATA_BLOB outbody;
+       size_t expected_body_size = 0x04;
+       size_t body_size;
+
+       if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
+               return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+       }
+
+       inbody = (const uint8_t *)req->in.vector[i+1].iov_base;
+
+       body_size = SVAL(inbody, 0x00);
+       if (body_size != expected_body_size) {
+               return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+       }
+
+       /*
+        * TODO: cancel all outstanding requests on the tcon
+        *       and delete all file handles.
+        */
+       TALLOC_FREE(req->tcon);
+
+       outbody = data_blob_talloc(req->out.vector, NULL, 0x04);
+       if (outbody.data == NULL) {
+               return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+       }
+
+       SSVAL(outbody.data, 0x00, 0x04);        /* struct size */
+       SSVAL(outbody.data, 0x02, 0);           /* reserved */
+
+       return smbd_smb2_request_done(req, outbody, NULL);
+}