s3:smbd: implement SMB2 Tree Disconnect
[ira/wip.git] / source3 / smbd / smb2_tcon.c
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);
+}