summaryrefslogtreecommitdiffstats
path: root/source4
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-05-30 17:26:42 +1000
committerAndrew Bartlett <abartlet@samba.org>2008-05-30 17:26:42 +1000
commitbe1927cd80838a6807827cef4431c03160d52582 (patch)
tree759fdea9f2c65277f56209494511d24b6f7f1270 /source4
parent9c1519c065a4411b3eb37e8d7738269238950227 (diff)
parentbeaa01e403dda7557a6acdf0181d79d58a33bbbe (diff)
downloadsamba-be1927cd80838a6807827cef4431c03160d52582.tar.gz
samba-be1927cd80838a6807827cef4431c03160d52582.tar.xz
samba-be1927cd80838a6807827cef4431c03160d52582.zip
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into 4-0-local
(This used to be commit 31308caad0a83a487341307e4e810a69c08ff371)
Diffstat (limited to 'source4')
-rw-r--r--source4/lib/messaging/pymessaging.c15
-rw-r--r--source4/libcli/smb2/cancel.c6
-rw-r--r--source4/libcli/smb2/config.mk2
-rw-r--r--source4/libcli/smb2/connect.c54
-rw-r--r--source4/libcli/smb2/notify.c6
-rw-r--r--source4/libcli/smb2/session.c17
-rw-r--r--source4/libcli/smb2/signing.c165
-rw-r--r--source4/libcli/smb2/smb2.h22
-rw-r--r--source4/libcli/smb2/transport.c49
-rw-r--r--source4/librpc/rpc/dcerpc_connect.c6
-rw-r--r--source4/librpc/rpc/dcerpc_smb2.c2
-rw-r--r--source4/ntvfs/smb2/vfs_smb2.c6
-rw-r--r--source4/torture/gentest.c7
-rw-r--r--source4/torture/smb2/read.c1
-rw-r--r--source4/torture/smb2/scan.c11
-rw-r--r--source4/torture/smb2/util.c5
16 files changed, 318 insertions, 56 deletions
diff --git a/source4/lib/messaging/pymessaging.c b/source4/lib/messaging/pymessaging.c
index 1c22fb431a..41c9c82b1f 100644
--- a/source4/lib/messaging/pymessaging.c
+++ b/source4/lib/messaging/pymessaging.c
@@ -127,12 +127,15 @@ static PyObject *py_messaging_send(PyObject *self, PyObject *args, PyObject *kwa
NTSTATUS status;
struct server_id server;
const char *kwnames[] = { "target", "msg_type", "data", NULL };
+ int length;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ois#|:send",
- discard_const_p(char *, kwnames), &target, &msg_type, &data.data, &data.length)) {
+ discard_const_p(char *, kwnames), &target, &msg_type, &data.data, &length)) {
return NULL;
}
+ data.length = length;
+
if (!server_id_from_py(target, &server))
return NULL;
@@ -159,11 +162,11 @@ static void py_msg_callback_wrapper(struct messaging_context *msg, void *private
static PyObject *py_messaging_register(PyObject *self, PyObject *args, PyObject *kwargs)
{
messaging_Object *iface = (messaging_Object *)self;
- uint32_t msg_type = -1;
+ int msg_type = -1;
PyObject *callback;
NTSTATUS status;
const char *kwnames[] = { "callback", "msg_type", NULL };
-
+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:send",
discard_const_p(char *, kwnames), &callback, &msg_type)) {
return NULL;
@@ -172,8 +175,10 @@ static PyObject *py_messaging_register(PyObject *self, PyObject *args, PyObject
Py_INCREF(callback);
if (msg_type == -1) {
+ uint32_t msg_type32 = msg_type;
status = messaging_register_tmp(iface->msg_ctx, callback,
- py_msg_callback_wrapper, &msg_type);
+ py_msg_callback_wrapper, &msg_type32);
+ msg_type = msg_type32;
} else {
status = messaging_register(iface->msg_ctx, callback,
msg_type, py_msg_callback_wrapper);
@@ -189,7 +194,7 @@ static PyObject *py_messaging_register(PyObject *self, PyObject *args, PyObject
static PyObject *py_messaging_deregister(PyObject *self, PyObject *args, PyObject *kwargs)
{
messaging_Object *iface = (messaging_Object *)self;
- uint32_t msg_type = -1;
+ int msg_type = -1;
PyObject *callback;
const char *kwnames[] = { "callback", "msg_type", NULL };
diff --git a/source4/libcli/smb2/cancel.c b/source4/libcli/smb2/cancel.c
index 80127feea5..65f02187c1 100644
--- a/source4/libcli/smb2/cancel.c
+++ b/source4/libcli/smb2/cancel.c
@@ -61,10 +61,10 @@ NTSTATUS smb2_cancel(struct smb2_request *r)
SSVAL(c->out.body, 0x02, 0);
- old_timeout = c->transport->options.timeout;
- c->transport->options.timeout = 0;
+ old_timeout = c->transport->options.request_timeout;
+ c->transport->options.request_timeout = 0;
smb2_transport_send(c);
- c->transport->options.timeout = old_timeout;
+ c->transport->options.request_timeout = old_timeout;
if (c->state == SMB2_REQUEST_ERROR) {
status = c->status;
diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk
index 00b6305def..322bca1416 100644
--- a/source4/libcli/smb2/config.mk
+++ b/source4/libcli/smb2/config.mk
@@ -5,6 +5,6 @@ LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/smb2/, \
transport.o request.o negprot.o session.o tcon.o \
create.o close.o connect.o getinfo.o write.o read.o \
setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \
- lock.o notify.o cancel.o keepalive.o break.o util.o)
+ lock.o notify.o cancel.o keepalive.o break.o util.o signing.o)
$(eval $(call proto_header_template,$(libclisrcdir)/smb2/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c)))
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index eabfa410ad..cdb5e3b5d4 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -33,6 +33,7 @@ struct smb2_connect_state {
struct resolve_context *resolve_ctx;
const char *host;
const char *share;
+ struct smbcli_options options;
struct smb2_negprot negprot;
struct smb2_tree_connect tcon;
struct smb2_session *session;
@@ -103,6 +104,34 @@ static void continue_negprot(struct smb2_request *req)
transport->negotiate.system_time = state->negprot.out.system_time;
transport->negotiate.server_start_time = state->negprot.out.server_start_time;
+ transport->negotiate.security_mode = state->negprot.out.security_mode;
+
+ switch (transport->options.signing) {
+ case SMB_SIGNING_OFF:
+ if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
+ composite_error(c, NT_STATUS_ACCESS_DENIED);
+ return;
+ }
+ transport->signing.doing_signing = false;
+ break;
+ case SMB_SIGNING_SUPPORTED:
+ case SMB_SIGNING_AUTO:
+ if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
+ transport->signing.doing_signing = true;
+ } else {
+ transport->signing.doing_signing = false;
+ }
+ break;
+ case SMB_SIGNING_REQUIRED:
+ if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) {
+ transport->signing.doing_signing = true;
+ } else {
+ composite_error(c, NT_STATUS_ACCESS_DENIED);
+ return;
+ }
+ break;
+ }
+
state->session = smb2_session_init(transport, global_loadparm, state, true);
if (composite_nomem(state->session, c)) return;
@@ -129,12 +158,24 @@ static void continue_socket(struct composite_context *creq)
c->status = smbcli_sock_connect_recv(creq, state, &sock);
if (!composite_is_ok(c)) return;
- transport = smb2_transport_init(sock, state);
+ transport = smb2_transport_init(sock, state, &state->options);
if (composite_nomem(transport, c)) return;
ZERO_STRUCT(state->negprot);
state->negprot.in.dialect_count = 2;
- state->negprot.in.security_mode = 0;
+ switch (transport->options.signing) {
+ case SMB_SIGNING_OFF:
+ state->negprot.in.security_mode = 0;
+ break;
+ case SMB_SIGNING_SUPPORTED:
+ case SMB_SIGNING_AUTO:
+ state->negprot.in.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
+ break;
+ case SMB_SIGNING_REQUIRED:
+ state->negprot.in.security_mode =
+ SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
+ break;
+ }
state->negprot.in.capabilities = 0;
unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
dialects[0] = 0;
@@ -178,7 +219,8 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx,
const char *share,
struct resolve_context *resolve_ctx,
struct cli_credentials *credentials,
- struct event_context *ev)
+ struct event_context *ev,
+ struct smbcli_options *options)
{
struct composite_context *c;
struct smb2_connect_state *state;
@@ -193,6 +235,7 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx,
c->private_data = state;
state->credentials = credentials;
+ state->options = *options;
state->host = talloc_strdup(c, host);
if (composite_nomem(state->host, c)) return c;
state->share = talloc_strdup(c, share);
@@ -232,10 +275,11 @@ NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx,
struct resolve_context *resolve_ctx,
struct cli_credentials *credentials,
struct smb2_tree **tree,
- struct event_context *ev)
+ struct event_context *ev,
+ struct smbcli_options *options)
{
struct composite_context *c = smb2_connect_send(mem_ctx, host, share,
resolve_ctx,
- credentials, ev);
+ credentials, ev, options);
return smb2_connect_recv(c, mem_ctx, tree);
}
diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c
index 096d790a31..ef7341cae8 100644
--- a/source4/libcli/smb2/notify.c
+++ b/source4/libcli/smb2/notify.c
@@ -44,10 +44,10 @@ struct smb2_request *smb2_notify_send(struct smb2_tree *tree, struct smb2_notify
SIVAL(req->out.body, 0x18, io->in.completion_filter);
SIVAL(req->out.body, 0x1C, io->in.unknown);
- old_timeout = req->transport->options.timeout;
- req->transport->options.timeout = 0;
+ old_timeout = req->transport->options.request_timeout;
+ req->transport->options.request_timeout = 0;
smb2_transport_send(req);
- req->transport->options.timeout = old_timeout;
+ req->transport->options.request_timeout = old_timeout;
return req;
}
diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c
index 29af6652f2..54915d8535 100644
--- a/source4/libcli/smb2/session.c
+++ b/source4/libcli/smb2/session.c
@@ -164,8 +164,8 @@ static void session_request_handler(struct smb2_request *req)
session_key_err = gensec_session_key(session->gensec, &session_key);
if (NT_STATUS_IS_OK(session_key_err)) {
- session->session_key = session_key;
- }
+ session->transport->signing.session_key = session_key;
+ }
}
session->uid = state->io.out.uid;
@@ -187,6 +187,14 @@ static void session_request_handler(struct smb2_request *req)
return;
}
+ if (session->transport->signing.doing_signing) {
+ c->status = smb2_start_signing(session->transport);
+ if (!NT_STATUS_IS_OK(c->status)) {
+ composite_error(c, c->status);
+ return;
+ }
+ }
+
composite_done(c);
}
@@ -208,7 +216,10 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se
ZERO_STRUCT(state->io);
state->io.in.vc_number = 0;
- state->io.in.security_mode = 0;
+ if (session->transport->signing.doing_signing) {
+ state->io.in.security_mode =
+ SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
+ }
state->io.in.capabilities = 0;
state->io.in.channel = 0;
state->io.in.previous_sessionid = 0;
diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c
new file mode 100644
index 0000000000..01f7576134
--- /dev/null
+++ b/source4/libcli/smb2/signing.c
@@ -0,0 +1,165 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ SMB2 Signing Code
+
+ Copyright (C) Andrew Tridgell <tridge@samba.org> 2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+#include "heimdal/lib/hcrypto/sha.h"
+
+/*
+ NOTE: this code does not yet interoperate with the windows SMB2
+ implementation. We are waiting on feedback on the docs to find out
+ why
+ */
+
+
+/*
+ setup signing on a transport
+ */
+NTSTATUS smb2_start_signing(struct smb2_transport *transport)
+{
+ if (transport->signing.session_key.length != 16) {
+ DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
+ (unsigned)transport->signing.session_key.length));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ transport->signing.signing_started = true;
+ return NT_STATUS_OK;
+}
+
+/*
+ sign an outgoing message
+ */
+NTSTATUS smb2_sign_message(struct smb2_request *req)
+{
+ struct smb2_request_buffer *buf = &req->out;
+ uint64_t session_id;
+ SHA256_CTX m;
+ uint8_t res[32];
+
+ if (!req->transport->signing.doing_signing ||
+ !req->transport->signing.signing_started) {
+ return NT_STATUS_OK;
+ }
+
+ if (buf->size < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) {
+ /* can't sign non-SMB2 messages */
+ return NT_STATUS_OK;
+ }
+
+ session_id = BVAL(buf->hdr, SMB2_HDR_SESSION_ID);
+ if (session_id == 0) {
+ /* we don't sign messages with a zero session_id. See
+ MS-SMB2 3.2.4.1.1 */
+ return NT_STATUS_OK;
+ }
+
+ if (req->transport->signing.session_key.length != 16) {
+ DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
+ (unsigned)req->transport->signing.session_key.length));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16);
+
+ SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
+
+ ZERO_STRUCT(m);
+ SHA256_Init(&m);
+ SHA256_Update(&m, req->transport->signing.session_key.data,
+ req->transport->signing.session_key.length);
+ SHA256_Update(&m, buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE);
+ SHA256_Final(res, &m);
+
+ DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE));
+
+ memcpy(buf->hdr + SMB2_HDR_SIGNATURE, res, 16);
+
+ if (DEBUGLVL(5)) {
+ /* check our own signature */
+ smb2_check_signature(req->transport, buf->buffer, buf->size);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ check an incoming signature
+ */
+NTSTATUS smb2_check_signature(struct smb2_transport *transport,
+ uint8_t *buffer, uint_t length)
+{
+ uint64_t session_id;
+ SHA256_CTX m;
+ uint8_t res[SHA256_DIGEST_LENGTH];
+ uint8_t sig[16];
+
+ if (!transport->signing.signing_started ||
+ !transport->signing.doing_signing) {
+ return NT_STATUS_OK;
+ }
+
+ if (length < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) {
+ /* can't check non-SMB2 messages */
+ return NT_STATUS_OK;
+ }
+
+ session_id = BVAL(buffer+NBT_HDR_SIZE, SMB2_HDR_SESSION_ID);
+ if (session_id == 0) {
+ /* don't sign messages with a zero session_id. See
+ MS-SMB2 3.2.4.1.1 */
+ return NT_STATUS_OK;
+ }
+
+ if (transport->signing.session_key.length == 0) {
+ /* we don't have the session key yet */
+ return NT_STATUS_OK;
+ }
+
+ if (transport->signing.session_key.length != 16) {
+ DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
+ (unsigned)transport->signing.session_key.length));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ memcpy(sig, buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, 16);
+
+ memset(buffer + NBT_HDR_SIZE + SMB2_HDR_SIGNATURE, 0, 16);
+
+ ZERO_STRUCT(m);
+ SHA256_Init(&m);
+ SHA256_Update(&m, transport->signing.session_key.data, 16);
+ SHA256_Update(&m, buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE);
+ SHA256_Final(res, &m);
+
+ memcpy(buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, sig, 16);
+
+ if (memcmp(res, sig, 16) != 0) {
+ DEBUG(0,("Bad SMB2 signature for message of size %u\n", length));
+ dump_data(0, sig, 16);
+ dump_data(0, res, 16);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_OK;
+}
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index b55da05e21..0903509528 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -23,20 +23,24 @@
#define __LIBCLI_SMB2_SMB2_H__
#include "libcli/raw/request.h"
+#include "libcli/raw/libcliraw.h"
struct smb2_handle;
-struct smb2_options {
- uint32_t timeout;
+struct smb2_signing_context {
+ bool doing_signing;
+ bool signing_started;
+ DATA_BLOB session_key;
};
/*
- information returned from the negotiate response
+ information returned from the negotiate process
*/
struct smb2_negotiate {
DATA_BLOB secblob;
NTTIME system_time;
NTTIME server_start_time;
+ uint16_t security_mode;
};
/* this is the context for the smb2 transport layer */
@@ -44,7 +48,6 @@ struct smb2_transport {
/* socket level info */
struct smbcli_socket *socket;
- struct smb2_options options;
struct smb2_negotiate negotiate;
/* next seqnum to allocate */
@@ -74,6 +77,9 @@ struct smb2_transport {
/* private data passed to the oplock handler */
void *private_data;
} oplock;
+
+ struct smbcli_options options;
+ struct smb2_signing_context signing;
};
@@ -92,7 +98,6 @@ struct smb2_session {
struct smb2_transport *transport;
struct gensec_security *gensec;
uint64_t uid;
- DATA_BLOB session_key;
};
@@ -193,6 +198,13 @@ struct smb2_request {
#define SMB2_HDR_SIGNATURE 0x30 /* 16 bytes */
#define SMB2_HDR_BODY 0x40
+/* header flags */
+#define SMB2_HDR_FLAG_REDIRECT 0x01
+#define SMB2_HDR_FLAG_ASYNC 0x02
+#define SMB2_HDR_FLAG_CHAINED 0x04
+#define SMB2_HDR_FLAG_SIGNED 0x08
+#define SMB2_HDR_FLAG_DFS 0x10000000
+
/* SMB2 opcodes */
#define SMB2_OP_NEGPROT 0x00
#define SMB2_OP_SESSSETUP 0x01
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index 8eb60a06f1..561b6e528e 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -74,7 +74,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob);
create a transport structure based on an established socket
*/
struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
- TALLOC_CTX *parent_ctx)
+ TALLOC_CTX *parent_ctx,
+ struct smbcli_options *options)
{
struct smb2_transport *transport;
@@ -82,6 +83,7 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
if (!transport) return NULL;
transport->socket = talloc_steal(transport, sock);
+ transport->options = *options;
/* setup the stream -> packet parser */
transport->packet = packet_init(transport);
@@ -112,8 +114,6 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
talloc_set_destructor(transport, transport_destructor);
- transport->options.timeout = 30;
-
return transport;
}
@@ -140,27 +140,24 @@ void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status)
}
}
-static bool smb2_handle_oplock_break(struct smb2_transport *transport,
- const DATA_BLOB *blob)
+static NTSTATUS smb2_handle_oplock_break(struct smb2_transport *transport,
+ const DATA_BLOB *blob)
{
uint8_t *hdr;
uint16_t opcode;
- uint64_t seqnum;
hdr = blob->data+NBT_HDR_SIZE;
if (blob->length < (SMB2_MIN_SIZE+0x18)) {
DEBUG(1,("Discarding smb2 oplock reply of size %u\n",
- blob->length));
- return false;
+ (unsigned)blob->length));
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
opcode = SVAL(hdr, SMB2_HDR_OPCODE);
- seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
- if ((opcode != SMB2_OP_BREAK) ||
- (seqnum != UINT64_MAX)) {
- return false;
+ if (opcode != SMB2_OP_BREAK) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
if (transport->oplock.handler) {
@@ -173,9 +170,11 @@ static bool smb2_handle_oplock_break(struct smb2_transport *transport,
transport->oplock.handler(transport, &h, level,
transport->oplock.private_data);
+ } else {
+ DEBUG(5,("Got SMB2 oplock break with no handler\n"));
}
- return true;
+ return NT_STATUS_OK;
}
/*
@@ -194,6 +193,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
uint16_t buffer_code;
uint32_t dynamic_size;
uint32_t i;
+ NTSTATUS status;
buffer = blob.data;
len = blob.length;
@@ -205,14 +205,20 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
goto error;
}
- if (smb2_handle_oplock_break(transport, &blob)) {
+ status = smb2_check_signature(transport, buffer, len);
+ if (!NT_STATUS_IS_OK(status)) {
talloc_free(buffer);
- return NT_STATUS_OK;
+ return status;
}
-
+
flags = IVAL(hdr, SMB2_HDR_FLAGS);
seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
+ /* see MS-SMB2 3.2.5.19 */
+ if (seqnum == UINT64_MAX) {
+ return smb2_handle_oplock_break(transport, &blob);
+ }
+
/* match the incoming request against the list of pending requests */
for (req=transport->pending_recv; req; req=req->next) {
if (req->seqnum == seqnum) break;
@@ -340,6 +346,13 @@ void smb2_transport_send(struct smb2_request *req)
return;
}
+ status = smb2_sign_message(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ req->state = SMB2_REQUEST_ERROR;
+ req->status = status;
+ return;
+ }
+
blob = data_blob_const(req->out.buffer, req->out.size);
status = packet_send(req->transport->packet, blob);
if (!NT_STATUS_IS_OK(status)) {
@@ -352,9 +365,9 @@ void smb2_transport_send(struct smb2_request *req)
DLIST_ADD(req->transport->pending_recv, req);
/* add a timeout */
- if (req->transport->options.timeout) {
+ if (req->transport->options.request_timeout) {
event_add_timed(req->transport->socket->event.ctx, req,
- timeval_current_ofs(req->transport->options.timeout, 0),
+ timeval_current_ofs(req->transport->options.request_timeout, 0),
smb2_timeout_handler, req);
}
diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c
index a22cad9a4a..318b8fe36d 100644
--- a/source4/librpc/rpc/dcerpc_connect.c
+++ b/source4/librpc/rpc/dcerpc_connect.c
@@ -218,6 +218,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send(
struct composite_context *c;
struct pipe_np_smb2_state *s;
struct composite_context *conn_req;
+ struct smbcli_options options;
/* composite context allocation and setup */
c = composite_create(mem_ctx, io->pipe->conn->event_ctx);
@@ -240,11 +241,14 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send(
cli_credentials_guess(s->io.creds, lp_ctx);
}
+ lp_smbcli_options(lp_ctx, &options);
+
/* send smb2 connect request */
conn_req = smb2_connect_send(mem_ctx, s->io.binding->host, "IPC$",
s->io.resolve_ctx,
s->io.creds,
- c->event_ctx);
+ c->event_ctx,
+ &options);
composite_continue(c, conn_req, continue_smb2_connect, c);
return c;
}
diff --git a/source4/librpc/rpc/dcerpc_smb2.c b/source4/librpc/rpc/dcerpc_smb2.c
index 4767165fba..211015a4cf 100644
--- a/source4/librpc/rpc/dcerpc_smb2.c
+++ b/source4/librpc/rpc/dcerpc_smb2.c
@@ -376,7 +376,7 @@ static NTSTATUS smb2_session_key(struct dcerpc_connection *c, DATA_BLOB *session
{
struct smb2_private *smb = talloc_get_type(c->transport.private_data,
struct smb2_private);
- *session_key = smb->tree->session->session_key;
+ *session_key = smb->tree->session->transport->signing.session_key;
if (session_key->data == NULL) {
return NT_STATUS_NO_USER_SESSION_KEY;
}
diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c
index cc09daf83f..68b475a084 100644
--- a/source4/ntvfs/smb2/vfs_smb2.c
+++ b/source4/ntvfs/smb2/vfs_smb2.c
@@ -162,9 +162,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
struct composite_context *creq;
struct share_config *scfg = ntvfs->ctx->config;
struct smb2_tree *tree;
-
struct cli_credentials *credentials;
bool machine_account;
+ struct smbcli_options options;
/* Here we need to determine which server to connect to.
* For now we use parametric options, type cifs.
@@ -224,10 +224,12 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_PARAMETER;
}
+ lp_smbcli_options(ntvfs->ctx->lp_ctx, &options);
+
creq = smb2_connect_send(private, host, remote_share,
lp_resolve_context(ntvfs->ctx->lp_ctx),
credentials,
- ntvfs->ctx->event_ctx);
+ ntvfs->ctx->event_ctx, &options);
status = smb2_connect_recv(creq, private, &tree);
NT_STATUS_NOT_OK_RETURN(status);
diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c
index fd6bd5cc0a..07d394fad6 100644
--- a/source4/torture/gentest.c
+++ b/source4/torture/gentest.c
@@ -213,6 +213,9 @@ static bool connect_servers(struct event_context *ev,
for (i=0;i<NSERVERS;i++) {
for (j=0;j<NINSTANCES;j++) {
NTSTATUS status;
+ struct smbcli_options smb_options;
+ lp_smbcli_options(lp_ctx, &smb_options);
+
printf("Connecting to \\\\%s\\%s as %s - instance %d\n",
servers[i].server_name, servers[i].share_name,
servers[i].credentials->username, j);
@@ -226,10 +229,8 @@ static bool connect_servers(struct event_context *ev,
lp_resolve_context(lp_ctx),
servers[i].credentials,
&servers[i].smb2_tree[j],
- ev);
+ ev, &smb_options);
} else {
- struct smbcli_options smb_options;
- lp_smbcli_options(lp_ctx, &smb_options);
status = smbcli_tree_full_connection(NULL,
&servers[i].smb_tree[j],
servers[i].server_name,
diff --git a/source4/torture/smb2/read.c b/source4/torture/smb2/read.c
index 1f306028f6..548bd1ce61 100644
--- a/source4/torture/smb2/read.c
+++ b/source4/torture/smb2/read.c
@@ -180,7 +180,6 @@ static bool test_read_dir(struct torture_context *torture, struct smb2_tree *tre
bool ret = true;
NTSTATUS status;
struct smb2_handle h;
- uint8_t buf[100];
struct smb2_read rd;
TALLOC_CTX *tmp_ctx = talloc_new(tree);
diff --git a/source4/torture/smb2/scan.c b/source4/torture/smb2/scan.c
index 889d343a49..1ce796be4d 100644
--- a/source4/torture/smb2/scan.c
+++ b/source4/torture/smb2/scan.c
@@ -203,17 +203,20 @@ bool torture_smb2_scan(struct torture_context *torture)
NTSTATUS status;
int opcode;
struct smb2_request *req;
+ struct smbcli_options options;
+
+ lp_smbcli_options(torture->lp_ctx, &options);
status = smb2_connect(mem_ctx, host, share,
lp_resolve_context(torture->lp_ctx),
credentials, &tree,
- torture->ev);
+ torture->ev, &options);
if (!NT_STATUS_IS_OK(status)) {
printf("Connection failed - %s\n", nt_errstr(status));
return false;
}
- tree->session->transport->options.timeout = 3;
+ tree->session->transport->options.request_timeout = 3;
for (opcode=0;opcode<1000;opcode++) {
req = smb2_request_init_tree(tree, opcode, 2, false, 0);
@@ -224,12 +227,12 @@ bool torture_smb2_scan(struct torture_context *torture)
status = smb2_connect(mem_ctx, host, share,
lp_resolve_context(torture->lp_ctx),
credentials, &tree,
- torture->ev);
+ torture->ev, &options);
if (!NT_STATUS_IS_OK(status)) {
printf("Connection failed - %s\n", nt_errstr(status));
return false;
}
- tree->session->transport->options.timeout = 3;
+ tree->session->transport->options.request_timeout = 3;
} else {
status = smb2_request_destroy(req);
printf("active opcode %4d gave status %s\n", opcode, nt_errstr(status));
diff --git a/source4/torture/smb2/util.c b/source4/torture/smb2/util.c
index af4f345104..3a437acbab 100644
--- a/source4/torture/smb2/util.c
+++ b/source4/torture/smb2/util.c
@@ -270,11 +270,14 @@ bool torture_smb2_connection(struct torture_context *tctx, struct smb2_tree **tr
const char *host = torture_setting_string(tctx, "host", NULL);
const char *share = torture_setting_string(tctx, "share", NULL);
struct cli_credentials *credentials = cmdline_credentials;
+ struct smbcli_options options;
+
+ lp_smbcli_options(tctx->lp_ctx, &options);
status = smb2_connect(tctx, host, share,
lp_resolve_context(tctx->lp_ctx),
credentials, tree,
- tctx->ev);
+ tctx->ev, &options);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
host, share, nt_errstr(status));