summaryrefslogtreecommitdiff
path: root/source4/smb_server/smb2
diff options
context:
space:
mode:
Diffstat (limited to 'source4/smb_server/smb2')
-rw-r--r--source4/smb_server/smb2/config.mk19
-rw-r--r--source4/smb_server/smb2/fileinfo.c4
-rw-r--r--source4/smb_server/smb2/fileio.c4
-rw-r--r--source4/smb_server/smb2/find.c3
-rw-r--r--source4/smb_server/smb2/negprot.c18
-rw-r--r--source4/smb_server/smb2/receive.c11
-rw-r--r--source4/smb_server/smb2/sesssetup.c30
-rw-r--r--source4/smb_server/smb2/tcon.c12
-rw-r--r--source4/smb_server/smb2/wscript_build8
9 files changed, 57 insertions, 52 deletions
diff --git a/source4/smb_server/smb2/config.mk b/source4/smb_server/smb2/config.mk
deleted file mode 100644
index f0c3739926..0000000000
--- a/source4/smb_server/smb2/config.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#######################
-# Start SUBSYSTEM SMB2_PROTOCOL
-[SUBSYSTEM::SMB2_PROTOCOL]
-PUBLIC_DEPENDENCIES = \
- ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec
-# End SUBSYSTEM SMB2_PROTOCOL
-#######################
-
-SMB2_PROTOCOL_OBJ_FILES = $(addprefix $(smb_serversrcdir)/smb2/, \
- receive.o \
- negprot.o \
- sesssetup.o \
- tcon.o \
- fileio.o \
- fileinfo.o \
- find.o \
- keepalive.o)
-
-$(eval $(call proto_header_template,$(smb_serversrcdir)/smb2/smb2_proto.h,$(SMB2_PROTOCOL_OBJ_FILES:.o=.c)))
diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c
index 3084236355..5e4f35e02b 100644
--- a/source4/smb_server/smb2/fileinfo.c
+++ b/source4/smb_server/smb2/fileinfo.c
@@ -150,7 +150,7 @@ static NTSTATUS smb2srv_getinfo_security_send(struct smb2srv_getinfo_op *op)
union smb_fileinfo *io = talloc_get_type(op->io_ptr, union smb_fileinfo);
enum ndr_err_code ndr_err;
- ndr_err = ndr_push_struct_blob(&op->info->out.blob, op->req, NULL,
+ ndr_err = ndr_push_struct_blob(&op->info->out.blob, op->req,
io->query_secdesc.out.sd,
(ndr_push_flags_fn_t)ndr_push_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -316,7 +316,7 @@ static NTSTATUS smb2srv_setinfo_security(struct smb2srv_setinfo_op *op, uint8_t
io->set_secdesc.in.sd = talloc(io, struct security_descriptor);
NT_STATUS_HAVE_NO_MEMORY(io->set_secdesc.in.sd);
- ndr_err = ndr_pull_struct_blob(&op->info->in.blob, io, NULL,
+ ndr_err = ndr_pull_struct_blob(&op->info->in.blob, io,
io->set_secdesc.in.sd,
(ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
diff --git a/source4/smb_server/smb2/fileio.c b/source4/smb_server/smb2/fileio.c
index 497a6c531b..f6460e0ee7 100644
--- a/source4/smb_server/smb2/fileio.c
+++ b/source4/smb_server/smb2/fileio.c
@@ -109,7 +109,7 @@ void smb2srv_create_recv(struct smb2srv_request *req)
smb2srv_send_error(req, NT_STATUS_NO_MEMORY);
return;
}
- ndr_err = ndr_pull_struct_blob(&io->smb2.in.blobs.blobs[i].data, io, NULL,
+ ndr_err = ndr_pull_struct_blob(&io->smb2.in.blobs.blobs[i].data, io,
io->smb2.in.sec_desc,
(ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -345,7 +345,7 @@ void smb2srv_lock_recv(struct smb2srv_request *req)
io->smb2.level = RAW_LOCK_SMB2;
io->smb2.in.lock_count = SVAL(req->in.body, 0x02);
- io->smb2.in.reserved = IVAL(req->in.body, 0x04);
+ io->smb2.in.lock_sequence = IVAL(req->in.body, 0x04);
io->smb2.in.file.ntvfs = smb2srv_pull_handle(req, req->in.body, 0x08);
if (req->in.body_size < 24 + 24*(uint64_t)io->smb2.in.lock_count) {
DEBUG(0,("%s: lock buffer too small\n", __location__));
diff --git a/source4/smb_server/smb2/find.c b/source4/smb_server/smb2/find.c
index cd52872a1c..17f09e15ae 100644
--- a/source4/smb_server/smb2/find.c
+++ b/source4/smb_server/smb2/find.c
@@ -130,9 +130,6 @@ static NTSTATUS smb2srv_find_backend(struct smb2srv_find_state *state)
return ntvfs_search_next(state->req->ntvfs, state->fn, state, smb2srv_find_callback);
}
-
- /* should not be reached */
- return NT_STATUS_INTERNAL_ERROR;
}
void smb2srv_find_recv(struct smb2srv_request *req)
diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c
index 5283a0db6e..da60676322 100644
--- a/source4/smb_server/smb2/negprot.c
+++ b/source4/smb_server/smb2/negprot.c
@@ -119,7 +119,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
boot_time = timeval_current(); /* TODO: fix me */
ZERO_STRUCT(io->out);
- switch (lp_server_signing(req->smb_conn->lp_ctx)) {
+ switch (lpcfg_server_signing(req->smb_conn->lp_ctx)) {
case SMB_SIGNING_OFF:
io->out.security_mode = 0;
break;
@@ -135,11 +135,11 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
}
io->out.dialect_revision = dialect;
io->out.capabilities = 0;
- io->out.max_transact_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL,
+ io->out.max_transact_size = lpcfg_parm_ulong(req->smb_conn->lp_ctx, NULL,
"smb2", "max transaction size", 0x10000);
- io->out.max_read_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL,
+ io->out.max_read_size = lpcfg_parm_ulong(req->smb_conn->lp_ctx, NULL,
"smb2", "max read size", 0x10000);
- io->out.max_write_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL,
+ io->out.max_write_size = lpcfg_parm_ulong(req->smb_conn->lp_ctx, NULL,
"smb2", "max write size", 0x10000);
io->out.system_time = timeval_to_nttime(&current_time);
io->out.server_start_time = timeval_to_nttime(&boot_time);
@@ -153,7 +153,6 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negprot *io)
{
NTSTATUS status;
- enum ndr_err_code ndr_err;
if (NT_STATUS_IS_ERR(req->status)) {
smb2srv_send_error(req, req->status); /* TODO: is this correct? */
@@ -170,8 +169,8 @@ static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negpro
SSVAL(req->out.body, 0x02, io->out.security_mode);
SIVAL(req->out.body, 0x04, io->out.dialect_revision);
SIVAL(req->out.body, 0x06, io->out.reserved);
- ndr_err = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid);
+ if (!NT_STATUS_IS_OK(status)) {
smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
talloc_free(req);
return;
@@ -197,7 +196,6 @@ void smb2srv_negprot_recv(struct smb2srv_request *req)
{
struct smb2_negprot *io;
int i;
- enum ndr_err_code ndr_err;
if (req->in.body_size < 0x26) {
smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot");
@@ -215,8 +213,8 @@ void smb2srv_negprot_recv(struct smb2srv_request *req)
io->in.security_mode = SVAL(req->in.body, 0x04);
io->in.reserved = SVAL(req->in.body, 0x06);
io->in.capabilities = IVAL(req->in.body, 0x08);
- ndr_err = smbcli_pull_guid(req->in.body, 0xC, &io->in.client_guid);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ req->status = smbcli_pull_guid(req->in.body, 0xC, &io->in.client_guid);
+ if (!NT_STATUS_IS_OK(req->status)) {
smbsrv_terminate_connection(req->smb_conn, "Bad GUID in SMB2 negprot");
talloc_free(req);
return;
diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c
index abcf172738..40a57b88f1 100644
--- a/source4/smb_server/smb2/receive.c
+++ b/source4/smb_server/smb2/receive.c
@@ -322,13 +322,16 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req)
uid = BVAL(req->in.hdr, SMB2_HDR_SESSION_ID);
flags = IVAL(req->in.hdr, SMB2_HDR_FLAGS);
- if (req->smb_conn->highest_smb2_seqnum != 0 &&
+ if (opcode != SMB2_OP_CANCEL &&
+ req->smb_conn->highest_smb2_seqnum != 0 &&
req->seqnum <= req->smb_conn->highest_smb2_seqnum) {
smbsrv_terminate_connection(req->smb_conn, "Invalid SMB2 sequence number");
return NT_STATUS_INVALID_PARAMETER;
}
- req->smb_conn->highest_smb2_seqnum = req->seqnum;
-
+ if (opcode != SMB2_OP_CANCEL) {
+ req->smb_conn->highest_smb2_seqnum = req->seqnum;
+ }
+
req->session = smbsrv_session_find(req->smb_conn, uid, req->request_time);
req->tcon = smbsrv_smb2_tcon_find(req->session, tid, req->request_time);
@@ -656,7 +659,7 @@ NTSTATUS smbsrv_init_smb2_connection(struct smbsrv_connection *smb_conn)
/* this is the size that w2k uses, and it appears to be important for
good performance */
- smb_conn->negotiate.max_recv = lp_max_xmit(smb_conn->lp_ctx);
+ smb_conn->negotiate.max_recv = lpcfg_max_xmit(smb_conn->lp_ctx);
smb_conn->negotiate.zone_offset = get_time_zone(time(NULL));
diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c
index 58090305a0..94fe0da9fa 100644
--- a/source4/smb_server/smb2/sesssetup.c
+++ b/source4/smb_server/smb2/sesssetup.c
@@ -19,6 +19,7 @@
*/
#include "includes.h"
+#include <tevent.h>
#include "auth/gensec/gensec.h"
#include "auth/auth.h"
#include "libcli/smb2/smb2.h"
@@ -26,6 +27,7 @@
#include "smb_server/smb_server.h"
#include "smb_server/smb2/smb2_server.h"
#include "smbd/service_stream.h"
+#include "lib/stream/packet.h"
static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io)
{
@@ -57,9 +59,9 @@ struct smb2srv_sesssetup_callback_ctx {
struct smbsrv_session *smb_sess;
};
-static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void *private_data)
+static void smb2srv_sesssetup_callback(struct tevent_req *subreq)
{
- struct smb2srv_sesssetup_callback_ctx *ctx = talloc_get_type(private_data,
+ struct smb2srv_sesssetup_callback_ctx *ctx = tevent_req_callback_data(subreq,
struct smb2srv_sesssetup_callback_ctx);
struct smb2srv_request *req = ctx->req;
union smb_sesssetup *io = ctx->io;
@@ -67,7 +69,10 @@ static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void
struct auth_session_info *session_info = NULL;
NTSTATUS status;
- status = gensec_update_recv(greq, req, &io->smb2.out.secblob);
+ packet_recv_enable(req->smb_conn->packet);
+
+ status = gensec_update_recv(subreq, req, &io->smb2.out.secblob);
+ TALLOC_FREE(subreq);
if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
goto done;
} else if (!NT_STATUS_IS_OK(status)) {
@@ -94,7 +99,7 @@ static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void
done:
io->smb2.out.uid = smb_sess->vuid;
failed:
- req->status = auth_nt_status_squash(status);
+ req->status = nt_status_squash(status);
smb2srv_sesssetup_send(req, io);
if (!NT_STATUS_IS_OK(status) && !
NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -108,6 +113,7 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
struct smb2srv_sesssetup_callback_ctx *callback_ctx;
struct smbsrv_session *smb_sess = NULL;
uint64_t vuid;
+ struct tevent_req *subreq;
io->smb2.out.session_flags = 0;
io->smb2.out.uid = 0;
@@ -174,8 +180,12 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
callback_ctx->io = io;
callback_ctx->smb_sess = smb_sess;
- gensec_update_send(smb_sess->gensec_ctx, io->smb2.in.secblob,
- smb2srv_sesssetup_callback, callback_ctx);
+ subreq = gensec_update_send(callback_ctx,
+ req->smb_conn->connection->event.ctx,
+ smb_sess->gensec_ctx,
+ io->smb2.in.secblob);
+ if (!subreq) goto nomem;
+ tevent_req_set_callback(subreq, smb2srv_sesssetup_callback, callback_ctx);
/* note that we ignore SMB2_NEGOTIATE_SIGNING_ENABLED from the client.
This is deliberate as windows does not set it even when it does
@@ -192,12 +202,18 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
goto failed;
}
+ /* disable receipt of more packets on this socket until we've
+ finished with the session setup. This avoids a problem with
+ crashes if we get EOF on the socket while processing a session
+ setup */
+ packet_recv_disable(req->smb_conn->packet);
+
return;
nomem:
status = NT_STATUS_NO_MEMORY;
failed:
talloc_free(smb_sess);
- req->status = auth_nt_status_squash(status);
+ req->status = nt_status_squash(status);
smb2srv_sesssetup_send(req, io);
}
diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c
index d802146128..0dac29cf57 100644
--- a/source4/smb_server/smb2/tcon.c
+++ b/source4/smb_server/smb2/tcon.c
@@ -84,7 +84,7 @@ static NTSTATUS smb2srv_send_oplock_break(void *p, struct ntvfs_handle *h, uint8
return NT_STATUS_OK;
}
-struct ntvfs_handle *smb2srv_pull_handle(struct smb2srv_request *req, const uint8_t *base, uint_t offset)
+struct ntvfs_handle *smb2srv_pull_handle(struct smb2srv_request *req, const uint8_t *base, unsigned int offset)
{
struct smbsrv_tcon *tcon;
struct smbsrv_handle *handle;
@@ -160,7 +160,7 @@ struct ntvfs_handle *smb2srv_pull_handle(struct smb2srv_request *req, const uint
return handle->ntvfs;
}
-void smb2srv_push_handle(uint8_t *base, uint_t offset, struct ntvfs_handle *ntvfs)
+void smb2srv_push_handle(uint8_t *base, unsigned int offset, struct ntvfs_handle *ntvfs)
{
struct smbsrv_handle *handle = talloc_get_type(ntvfs->frontend_data.private_data,
struct smbsrv_handle);
@@ -304,9 +304,11 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon
goto failed;
}
- status = ntvfs_set_addr_callbacks(tcon->ntvfs, smbsrv_get_my_addr, smbsrv_get_peer_addr, req->smb_conn);
+ status = ntvfs_set_addresses(tcon->ntvfs,
+ req->smb_conn->connection->local_address,
+ req->smb_conn->connection->remote_address);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("smb2srv_tcon_backend: NTVFS failed to set the addr callbacks!\n"));
+ DEBUG(0,("smb2srv_tcon_backend: NTVFS failed to set the address!\n"));
goto failed;
}
@@ -343,7 +345,7 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon
/* Invoke NTVFS connection hook */
status = ntvfs_connect(req->ntvfs, io);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("smb2srv_tcon_backend: NTVFS ntvfs_connect() failed!\n"));
+ DEBUG(0,("smb2srv_tcon_backend: NTVFS ntvfs_connect() failed: %s!\n", nt_errstr(status)));
goto failed;
}
diff --git a/source4/smb_server/smb2/wscript_build b/source4/smb_server/smb2/wscript_build
new file mode 100644
index 0000000000..fd140eb8e2
--- /dev/null
+++ b/source4/smb_server/smb2/wscript_build
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+bld.SAMBA_SUBSYSTEM('SMB2_PROTOCOL',
+ source='receive.c negprot.c sesssetup.c tcon.c fileio.c fileinfo.c find.c keepalive.c',
+ autoproto='smb2_proto.h',
+ public_deps='ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec NDR_DFSBLOBS'
+ )
+