mirror of
https://github.com/samba-team/samba.git
synced 2025-05-28 21:05:48 +03:00
implemented client side SMB2 signing
This doessn't work against Windows yet, and I've submitted a WSPP request for clarification of the docs to try and find out why. Meanwhile this is no worse than what we had, as it only gets used when the server demands signing, and we didn't work then anyway. (This used to be commit b788096add3586d7277efcd3bf5ca7f3a604cb7a)
This commit is contained in:
parent
27f465619b
commit
beaa01e403
@ -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;
|
||||
|
@ -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)))
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
165
source4/libcli/smb2/signing.c
Normal file
165
source4/libcli/smb2/signing.c
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user