summaryrefslogtreecommitdiff
path: root/source4/smb_server/smb2/tcon.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/smb_server/smb2/tcon.c')
-rw-r--r--source4/smb_server/smb2/tcon.c124
1 files changed, 122 insertions, 2 deletions
diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c
index af9632eadc..fb84aa6fdc 100644
--- a/source4/smb_server/smb2/tcon.c
+++ b/source4/smb_server/smb2/tcon.c
@@ -21,14 +21,134 @@
#include "includes.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
+#include "smb_server/smb_server.h"
#include "smb_server/smb2/smb2_server.h"
+static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, struct smb2_tree_connect *io)
+{
+ struct smbsrv_tcon *tcon;
+
+ tcon = smbsrv_tcon_new(req->smb_conn);
+ NT_STATUS_HAVE_NO_MEMORY(tcon);
+
+ /* TODO: do real tree connect */
+
+ io->out.unknown1 = 0;
+ io->out.unknown2 = 0;
+ io->out.unknown3 = 0;
+ io->out.access_mask = 0;
+
+ io->out.tid = tcon->tid;
+
+ req->tcon = tcon;
+ return NT_STATUS_OK;
+}
+
+static void smb2srv_tcon_send(struct smb2srv_request *req, struct smb2_tree_connect *io)
+{
+ NTSTATUS status;
+
+ if (NT_STATUS_IS_ERR(req->status)) {
+ smb2srv_send_error(req, req->status);
+ return;
+ }
+
+ status = smb2srv_setup_reply(req, 0x10, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
+ talloc_free(req);
+ return;
+ }
+
+ SBVAL(req->out.hdr, SMB2_HDR_TID, io->out.tid);
+
+ SSVAL(req->out.body, 0x02, io->out.unknown1);
+ SIVAL(req->out.body, 0x04, io->out.unknown2);
+ SIVAL(req->out.body, 0x08, io->out.unknown3);
+ SIVAL(req->out.body, 0x0C, io->out.access_mask);
+
+ smb2srv_send_reply(req);
+}
+
void smb2srv_tcon_recv(struct smb2srv_request *req)
{
- smb2srv_send_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ struct smb2_tree_connect *io;
+ NTSTATUS status;
+
+ if (req->in.body_size < 0x08) {
+ smb2srv_send_error(req, NT_STATUS_FOOBAR);
+ return;
+ }
+
+ io = talloc(req, struct smb2_tree_connect);
+ if (!io) {
+ smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY));
+ talloc_free(req);
+ return;
+ }
+
+ io->in.unknown1 = SVAL(req->in.body, 0x02);
+ status = smb2_pull_o16s16_string(&req->in, io, req->in.body+0x04, &io->in.path);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
+ talloc_free(req);
+ return;
+ }
+
+ req->status = smb2srv_tcon_backend(req, io);
+
+ if (req->control_flags & SMB2SRV_REQ_CTRL_FLAG_NOT_REPLY) {
+ talloc_free(req);
+ return;
+ }
+ smb2srv_tcon_send(req, io);
+}
+
+static NTSTATUS smb2srv_tdis_backend(struct smb2srv_request *req)
+{
+ /* TODO: call ntvfs backends to close file of this tcon */
+ talloc_free(req->tcon);
+ req->tcon = NULL;
+ return NT_STATUS_OK;
+}
+
+static void smb2srv_tdis_send(struct smb2srv_request *req)
+{
+ NTSTATUS status;
+
+ if (NT_STATUS_IS_ERR(req->status)) {
+ smb2srv_send_error(req, req->status);
+ return;
+ }
+
+ status = smb2srv_setup_reply(req, 0x04, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
+ talloc_free(req);
+ return;
+ }
+
+ SSVAL(req->out.body, 0x02, 0);
+
+ smb2srv_send_reply(req);
}
void smb2srv_tdis_recv(struct smb2srv_request *req)
{
- smb2srv_send_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ uint16_t _pad;
+
+ if (req->in.body_size < 0x04) {
+ smb2srv_send_error(req, NT_STATUS_FOOBAR);
+ return;
+ }
+
+ _pad = SVAL(req->in.body, 0x02);
+
+ req->status = smb2srv_tdis_backend(req);
+
+ if (req->control_flags & SMB2SRV_REQ_CTRL_FLAG_NOT_REPLY) {
+ talloc_free(req);
+ return;
+ }
+ smb2srv_tdis_send(req);
}