1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-defs

Conflicts:

	source/samba4-skip
(This used to be commit 7b0e0eb346)
This commit is contained in:
Jelmer Vernooij 2008-05-30 12:18:07 +02:00
commit 5107f093c2
44 changed files with 2204 additions and 2862 deletions

View File

@ -208,9 +208,9 @@ sub Binary($$)
$self->_prepare_list($ctx, "LINK_FLAGS");
if (defined($ctx->{USE_HOSTCC}) && $ctx->{USE_HOSTCC} eq "YES") {
$self->output("\$(call host_binary_link_template, $ctx->{RESULT_BINARY}, \$($ctx->{NAME}_DEPEND_LIST) \$($ctx->{NAME}_FULL_OBJ_LIST), \$($ctx->{NAME}_LINK_FLAGS))\n");
$self->output("\$(call host_binary_link_template, $ctx->{RESULT_BINARY}, \$($ctx->{NAME}_FULL_OBJ_LIST) \$($ctx->{NAME}_DEPEND_LIST), \$($ctx->{NAME}_LINK_FLAGS))\n");
} else {
$self->output("\$(call binary_link_template, $ctx->{RESULT_BINARY}, \$($ctx->{NAME}_DEPEND_LIST) \$($ctx->{NAME}_FULL_OBJ_LIST), \$($ctx->{NAME}_LINK_FLAGS))\n");
$self->output("\$(call binary_link_template, $ctx->{RESULT_BINARY}, \$($ctx->{NAME}_FULL_OBJ_LIST) \$($ctx->{NAME}_DEPEND_LIST), \$($ctx->{NAME}_LINK_FLAGS))\n");
}
}

View File

@ -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 };

View File

@ -1354,7 +1354,7 @@ union smb_open {
break; \
} \
} while (0)
/* SMBNTCreateX interface */
/* SMBNTCreateX, nttrans and generic interface */
struct {
enum smb_open_level level;
struct {
@ -1377,6 +1377,9 @@ union smb_open {
NTTRANS varient of the call */
struct security_descriptor *sec_desc;
struct smb_ea_list *ea_list;
/* some optional parameters from the SMB2 varient */
bool query_maximal_access;
} in;
struct {
union smb_handle file;
@ -1392,6 +1395,10 @@ union smb_open {
uint16_t file_type;
uint16_t ipc_state;
uint8_t is_directory;
/* optional return values matching SMB2 tagged
values in the call */
uint32_t maximal_access;
} out;
} ntcreatex, nttrans, generic;

View File

@ -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;

View File

@ -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)))

View File

@ -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);
}

View File

@ -387,12 +387,13 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
/* pull out the parsed blobs */
for (i=0;i<io->out.blobs.num_blobs;i++) {
if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) {
/* why 8 bytes not 4?? */
/* TODO: this also contains a status field in
first 4 bytes */
if (io->out.blobs.blobs[i].data.length != 8) {
smb2_request_destroy(req);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 0);
io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 4);
}
if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) {
if (io->out.blobs.blobs[i].data.length != 32) {

View File

@ -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;
}

View File

@ -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;

View 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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -233,6 +233,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
io->smb2.out.size = io2->generic.out.size;
io->smb2.out.file_attr = io2->generic.out.attrib;
io->smb2.out.reserved2 = 0;
io->smb2.out.maximal_access = io2->generic.out.maximal_access;
break;
default:
@ -522,6 +523,7 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
io2->generic.in.fname = io->smb2.in.fname;
io2->generic.in.sec_desc = io->smb2.in.sec_desc;
io2->generic.in.ea_list = &io->smb2.in.eas;
io2->generic.in.query_maximal_access = io->smb2.in.query_maximal_access;
/* we don't support timewarp yet */
if (io->smb2.in.timewarp != 0) {

View File

@ -464,7 +464,11 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
return NT_STATUS_ACCESS_DENIED;
}
*access_mask |= SEC_FILE_READ_ATTRIBUTE;
if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
/* on SMB, this bit is always granted, even if not
asked for */
*access_mask |= SEC_FILE_READ_ATTRIBUTE;
}
return NT_STATUS_OK;
}
@ -496,7 +500,9 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
/* expand the generic access bits to file specific bits */
*access_mask = pvfs_translate_mask(*access_mask);
*access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
*access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
}
status = pvfs_acl_load(pvfs, name, -1, acl);
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
@ -518,8 +524,11 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
/* check the acl against the required access mask */
status = sec_access_check(sd, token, *access_mask, access_mask);
/* this bit is always granted, even if not asked for */
*access_mask |= SEC_FILE_READ_ATTRIBUTE;
if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
/* on SMB, this bit is always granted, even if not
asked for */
*access_mask |= SEC_FILE_READ_ATTRIBUTE;
}
talloc_free(acl);
@ -800,3 +809,15 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
return status;
}
/*
return the maximum allowed access mask
*/
NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
struct ntvfs_request *req,
struct pvfs_filename *name,
uint32_t *maximal_access)
{
*maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
return pvfs_access_check(pvfs, req, name, maximal_access);
}

View File

@ -73,7 +73,8 @@ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs,
case RAW_IOCTL_SMB2:
case RAW_IOCTL_SMB2_NO_HANDLE:
return NT_STATUS_FS_DRIVER_REQUIRED;
/* see WSPP SMB2 test 46 */
return NT_STATUS_INVALID_DEVICE_REQUEST;
}
return NT_STATUS_INVALID_LEVEL;

View File

@ -68,13 +68,8 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs,
int i,
NTSTATUS status)
{
/* in SMB2 mode we also try to unlock failing lock */
if (req->ctx->protocol != PROTOCOL_SMB2) {
i--;
}
/* undo the locks we just did */
for (;i>=0;i--) {
for (i--;i>=0;i--) {
brl_unlock(pvfs->brl_context,
f->brl_handle,
locks[i].pid,
@ -390,12 +385,9 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
DLIST_ADD(f->pending_list, pending);
return NT_STATUS_OK;
}
/* in SMB2 mode we also try to unlock failing lock */
if (req->ctx->protocol != PROTOCOL_SMB2) {
i--;
}
/* undo the locks we just did */
for (;i>=0;i--) {
for (i--;i>=0;i--) {
brl_unlock(pvfs->brl_context,
f->brl_handle,
locks[i].pid,

View File

@ -252,8 +252,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
} else {
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
}
if (!NT_STATUS_IS_OK(status)) {
return status;
NT_STATUS_NOT_OK_RETURN(status);
if (io->generic.in.query_maximal_access) {
status = pvfs_access_maximal_allowed(pvfs, req, name,
&io->generic.out.maximal_access);
NT_STATUS_NOT_OK_RETURN(status);
}
f->ntvfs = h;
@ -578,6 +582,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
NT_STATUS_NOT_OK_RETURN(status);
if (io->generic.in.query_maximal_access) {
status = pvfs_access_maximal_allowed(pvfs, req, name,
&io->generic.out.maximal_access);
NT_STATUS_NOT_OK_RETURN(status);
}
/* check that the parent isn't opened with delete on close set */
status = pvfs_resolve_parent(pvfs, req, name, &parent);
if (NT_STATUS_IS_OK(status)) {
@ -1122,6 +1132,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
uint32_t create_options;
uint32_t share_access;
uint32_t access_mask;
uint32_t create_action = NTCREATEX_ACTION_EXISTED;
bool del_on_close;
bool stream_existed, stream_truncate=false;
uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
@ -1134,6 +1145,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return ntvfs_map_open(ntvfs, req, io);
}
ZERO_STRUCT(io->generic.out);
create_options = io->generic.in.create_options;
share_access = io->generic.in.share_access;
access_mask = io->generic.in.access_mask;
@ -1169,6 +1182,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_PARAMETER;
}
/* we ignore some file_attr bits */
io->ntcreatex.in.file_attr &= ~(FILE_ATTRIBUTE_NONINDEXED |
FILE_ATTRIBUTE_COMPRESSED |
FILE_ATTRIBUTE_REPARSE_POINT |
FILE_ATTRIBUTE_SPARSE |
FILE_ATTRIBUTE_NORMAL);
/* resolve the cifs name to a posix name */
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
PVFS_RESOLVE_STREAMS, &name);
@ -1210,6 +1230,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
} else {
stream_truncate = true;
}
create_action = NTCREATEX_ACTION_TRUNCATED;
break;
case NTCREATEX_DISP_OPEN:
@ -1228,6 +1249,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
} else {
stream_truncate = true;
}
create_action = NTCREATEX_ACTION_TRUNCATED;
break;
case NTCREATEX_DISP_CREATE:
@ -1272,8 +1294,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
/* check the security descriptor */
status = pvfs_access_check(pvfs, req, name, &access_mask);
if (!NT_STATUS_IS_OK(status)) {
return status;
NT_STATUS_NOT_OK_RETURN(status);
if (io->generic.in.query_maximal_access) {
status = pvfs_access_maximal_allowed(pvfs, req, name,
&io->generic.out.maximal_access);
NT_STATUS_NOT_OK_RETURN(status);
}
status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
@ -1487,7 +1513,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
io->generic.out.oplock_level = oplock_granted;
io->generic.out.file.ntvfs = h;
io->generic.out.create_action = stream_existed?
NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED;
create_action:NTCREATEX_ACTION_CREATED;
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
io->generic.out.write_time = name->dos.write_time;

View File

@ -41,6 +41,10 @@ static uint32_t pvfs_fileinfo_access(union smb_fileinfo *info)
needed = 0;
break;
case RAW_FILEINFO_ACCESS_INFORMATION:
needed = 0;
break;
case RAW_FILEINFO_SEC_DESC:
needed = 0;
if (info->query_secdesc.in.secinfo_flags & (SECINFO_OWNER|SECINFO_GROUP)) {
@ -216,6 +220,10 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs,
case RAW_FILEINFO_NAME_INFO:
case RAW_FILEINFO_NAME_INFORMATION:
if (req->ctx->protocol == PROTOCOL_SMB2) {
/* strange that SMB2 doesn't have this */
return NT_STATUS_NOT_SUPPORTED;
}
info->name_info.out.fname.s = name->original_name;
return NT_STATUS_OK;

View File

@ -457,7 +457,12 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
/* possibly change the attribute */
if (newstats.dos.attrib != h->name->dos.attrib) {
mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
mode_t mode;
if ((newstats.dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
return NT_STATUS_INVALID_PARAMETER;
}
mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
if (!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
if (fchmod(h->fd, mode) == -1) {
return pvfs_map_errno(pvfs, errno);

View File

@ -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);

View File

@ -61,3 +61,4 @@ nss.test # Fails
samba4.samba3sam.python # Conversion from EJS not yet finished
raw.offline # Samba 4 doesn't have much offline support yet
winreg* #Does not authenticate against the target server
^samba4.samdb.python #Not working yet

View File

@ -930,8 +930,9 @@ def provision(setup_dir, message, session_info,
if aci is None:
aci = "# no aci for local ldb"
if smbconf is None:
os.makedirs(os.path.join(targetdir, "etc"))
if targetdir is not None:
if (not os.path.exists(os.path.join(targetdir, "etc"))):
os.makedirs(os.path.join(targetdir, "etc"))
smbconf = os.path.join(targetdir, "etc", "smb.conf")
# only install a new smb.conf if there isn't one there already

View File

@ -20,27 +20,28 @@
from samba.dcerpc import ClientConnection
from unittest import TestCase
from samba.tests import cmdline_loadparm
class BareTestCase(TestCase):
def test_bare(self):
# Connect to the echo pipe
x = ClientConnection("ncalrpc:localhost[DEFAULT]",
("60a15ec5-4de8-11d7-a637-005056a20182", 1))
("60a15ec5-4de8-11d7-a637-005056a20182", 1), lp_ctx=cmdline_loadparm)
self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4))
def test_alter_context(self):
x = ClientConnection("ncalrpc:localhost[DEFAULT]",
("12345778-1234-abcd-ef00-0123456789ac", 1))
("12345778-1234-abcd-ef00-0123456789ac", 1), lp_ctx=cmdline_loadparm)
y = ClientConnection("ncalrpc:localhost",
("60a15ec5-4de8-11d7-a637-005056a20182", 1),
basis_connection=x)
basis_connection=x, lp_ctx=cmdline_loadparm)
x.alter_context(("60a15ec5-4de8-11d7-a637-005056a20182", 1))
# FIXME: self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4))
def test_two_connections(self):
x = ClientConnection("ncalrpc:localhost[DEFAULT]",
("60a15ec5-4de8-11d7-a637-005056a20182", 1))
("60a15ec5-4de8-11d7-a637-005056a20182", 1), lp_ctx=cmdline_loadparm)
y = ClientConnection("ncalrpc:localhost",
("60a15ec5-4de8-11d7-a637-005056a20182", 1),
basis_connection=x)
basis_connection=x, lp_ctx=cmdline_loadparm)
self.assertEquals("\x01\x00\x00\x00", y.request(0, chr(0) * 4))

View File

@ -27,7 +27,7 @@ class RpcEchoTests(RpcInterfaceTestCase):
self.conn = echo.rpcecho("ncalrpc:", self.get_loadparm())
def test_two_contexts(self):
self.conn2 = echo.rpcecho("ncalrpc:", basis_connection=self.conn)
self.conn2 = echo.rpcecho("ncalrpc:", self.get_loadparm(), basis_connection=self.conn)
self.assertEquals(3, self.conn2.AddOne(2))
def test_abstract_syntax(self):

View File

@ -19,12 +19,13 @@
from samba.auth import system_session
from samba.credentials import Credentials
import os
from samba.provision import setup_samdb, guess_names, setup_templatesdb
from samba.provision import setup_samdb, guess_names, setup_templatesdb, make_smbconf
from samba.samdb import SamDB
from samba.tests import cmdline_loadparm, TestCaseInTempDir
from samba import security
from unittest import TestCase
import uuid
import param
class SamDBTestCase(TestCaseInTempDir):
def setUp(self):
@ -43,9 +44,22 @@ class SamDBTestCase(TestCaseInTempDir):
hostguid = str(uuid.uuid4())
path = os.path.join(self.tempdir, "samdb.ldb")
session_info = system_session()
names = guess_names(lp=cmdline_loadparm, hostname="foo",
domain="EXAMPLE.COM", dnsdomain="example.com",
serverrole="domain controller",
hostname="foo"
domain="EXAMPLE"
dnsdomain="example.com"
serverrole="domain controller"
smbconf = os.path.join(self.tempdir, "smb.conf")
make_smbconf(smbconf, setup_path, hostname, domain, dnsdomain, serverrole,
self.tempdir)
lp = param.LoadParm()
lp.load(smbconf)
names = guess_names(lp=lp, hostname=hostname,
domain=domain, dnsdomain=dnsdomain,
serverrole=severrole,
domaindn=self.domaindn, configdn=configdn,
schemadn=schemadn)
setup_templatesdb(os.path.join(self.tempdir, "templates.ldb"),
@ -58,9 +72,10 @@ class SamDBTestCase(TestCaseInTempDir):
policyguid, False, "secret",
"secret", "secret", invocationid,
"secret", "domain controller")
def tearDown(self):
for f in ['templates.ldb', 'schema.ldb', 'configuration.ldb',
'users.ldb', 'samdb.ldb']:
'users.ldb', 'samdb.ldb', 'smb.conf']:
os.remove(os.path.join(self.tempdir, f))
super(SamDBTestCase, self).tearDown()

View File

@ -352,6 +352,6 @@ rm -rf $PREFIX/upgrade
plantest "blackbox.upgrade" none $PYTHON setup/upgrade $CONFIGURATION --targetdir=$PREFIX/upgrade ../testdata/samba3 ../testdata/samba3/smb.conf
rm -rf $PREFIX/provision
mkdir $PREFIX/provision
plantest "blackbox.provision.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_provision.sh "$PREFIX/provision" "$CONFIGURATION"
plantest "blackbox.setpassword.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_setpassword.sh "$PREFIX/provision" "$CONFIGURATION"
plantest "blackbox.newuser.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_newuser.sh "$PREFIX/provision" "$CONFIGURATION"
plantest "blackbox.provision.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_provision.sh "$PREFIX/provision"
plantest "blackbox.setpassword.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_setpassword.sh "$PREFIX/provision"
plantest "blackbox.newuser.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_newuser.sh "$PREFIX/provision"

View File

@ -521,6 +521,7 @@ sub provision($$$$$$)
my $ncalrpcdir = "$prefix_abs/ncalrpc";
my $lockdir = "$prefix_abs/lockdir";
my $winbindd_socket_dir = "$prefix_abs/winbind_socket";
my $ntp_signd_socket_dir = "$prefix_abs/ntp_signd_socket";
my $winbindd_priv_pipe_dir = "$privatedir/smbd.tmp/winbind_pipe";
my $nsswrap_passwd = "$etcdir/passwd";
my $nsswrap_group = "$etcdir/group";
@ -556,6 +557,7 @@ sub provision($$$$$$)
modules dir = $self->{bindir}/modules
js include = $srcdir/scripting/libjs
winbindd socket directory = $winbindd_socket_dir
ntp signd socket directory = $ntp_signd_socket_dir
winbind separator = /
name resolve order = bcast
interfaces = $interfaces

View File

@ -1,20 +1,19 @@
#!/bin/sh
if [ $# -lt 2 ]; then
if [ $# -lt 1 ]; then
cat <<EOF
Usage: blackbox_newuser.sh PREFIX CONFIGURATION
Usage: blackbox_newuser.sh PREFIX
EOF
exit 1;
fi
PREFIX="$1"
CONFIGURATION="$2"
shift 2
shift 1
. `dirname $0`/../../../testprogs/blackbox/subunit.sh
testit "simple-dc" $PYTHON ./setup/provision $CONFIGURATION --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/simple-dc
testit "simple-dc" $PYTHON ./setup/provision --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/simple-dc
testit "newuser" $PYTHON ./setup/newuser --configfile=$PREFIX/simple-dc/etc/smb.conf testuser testpass

View File

@ -1,28 +1,27 @@
#!/bin/sh
if [ $# -lt 2 ]; then
if [ $# -lt 1 ]; then
cat <<EOF
Usage: blackbox_provision.sh PREFIX CONFIGURATION
Usage: blackbox_provision.sh PREFIX
EOF
exit 1;
fi
PREFIX="$1"
CONFIGURATION="$2"
shift 2
shift 1
. `dirname $0`/../../../testprogs/blackbox/subunit.sh
testit "simple-default" $PYTHON ./setup/provision $CONFIGURATION --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-default
testit "simple-dc" $PYTHON ./setup/provision $CONFIGURATION --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/simple-dc
testit "simple-member" $PYTHON ./setup/provision $CONFIGURATION --server-role="member" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-member
testit "simple-standalone" $PYTHON ./setup/provision $CONFIGURATION --server-role="standalone" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-standalone
testit "blank-dc" $PYTHON ./setup/provision $CONFIGURATION --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/blank-dc --blank
testit "partitions-only-dc" $PYTHON ./setup/provision $CONFIGURATION --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/partitions-only-dc --partitions-only
testit "simple-default" $PYTHON ./setup/provision --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-default
testit "simple-dc" $PYTHON ./setup/provision --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/simple-dc
testit "simple-member" $PYTHON ./setup/provision --server-role="member" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-member
testit "simple-standalone" $PYTHON ./setup/provision --server-role="standalone" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-standalone
testit "blank-dc" $PYTHON ./setup/provision --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/blank-dc --blank
testit "partitions-only-dc" $PYTHON ./setup/provision --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/partitions-only-dc --partitions-only
reprovision() {
$PYTHON ./setup/provision $CONFIGURATION --domain=FOO --realm=foo.example.com --targetdir="$PREFIX/reprovision"
$PYTHON ./setup/provision $CONFIGURATION --domain=FOO --realm=foo.example.com --targetdir="$PREFIX/reprovision"
$PYTHON ./setup/provision --domain=FOO --realm=foo.example.com --targetdir="$PREFIX/reprovision"
$PYTHON ./setup/provision --domain=FOO --realm=foo.example.com --targetdir="$PREFIX/reprovision"
}
testit "reprovision" reprovision

View File

@ -1,19 +1,18 @@
#!/bin/sh
if [ $# -lt 2 ]; then
if [ $# -lt 1 ]; then
cat <<EOF
Usage: blackbox_setpassword.sh PREFIX CONFIGURATION
Usage: blackbox_setpassword.sh PREFIX
EOF
exit 1;
fi
PREFIX="$1"
CONFIGURATION="$2"
shift 2
shift 1
. `dirname $0`/../../../testprogs/blackbox/subunit.sh
testit "simple-dc" $PYTHON ./setup/provision $CONFIGURATION --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/simple-dc
testit "simple-dc" $PYTHON ./setup/provision --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/simple-dc
testit "newuser" $PYTHON ./setup/newuser --configfile=$PREFIX/simple-dc/etc/smb.conf testuser testpass

View File

@ -55,8 +55,7 @@ static void smb2srv_getinfo_send(struct ntvfs_request *ntvfs)
SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, op->info->out.blob.length));
/* TODO: this is maybe a o16s32_blob */
SMB2SRV_CHECK(smb2_push_o16s16_blob(&req->out, 0x02, op->info->out.blob));
SMB2SRV_CHECK(smb2_push_o16s32_blob(&req->out, 0x02, op->info->out.blob));
SSVAL(req->out.body, 0x06, 0);
smb2srv_send_reply(req);

View File

@ -36,6 +36,18 @@ static void smb2srv_create_send(struct ntvfs_request *ntvfs)
DATA_BLOB blob;
SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open);
/* setup the blobs we should give in the reply */
if (io->smb2.out.maximal_access != 0) {
uint32_t data[2];
SIVAL(data, 0, 0);
SIVAL(data, 4, io->smb2.out.maximal_access);
SMB2SRV_CHECK(smb2_create_blob_add(req, &io->smb2.out.blobs,
SMB2_CREATE_TAG_MXAC,
data_blob_const(data, 8)));
}
SMB2SRV_CHECK(smb2_create_blob_push(req, &blob, io->smb2.out.blobs));
SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, true, blob.length));

View File

@ -158,7 +158,8 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
}
if (!smb_sess) {
status = NT_STATUS_USER_SESSION_DELETED;
/* see WSPP test suite - test 11 */
status = NT_STATUS_REQUEST_NOT_ACCEPTED;
goto failed;
}

View File

@ -264,23 +264,6 @@ gentest_OBJ_FILES = $(torturesrcdir)/gentest.o
MANPAGES += $(torturesrcdir)/man/gentest.1
#################################
# Start BINARY gentest_smb2
[BINARY::gentest_smb2]
INSTALLDIR = BINDIR
PRIVATE_DEPENDENCIES = \
LIBSAMBA-HOSTCONFIG \
LIBSAMBA-UTIL \
LIBPOPT \
POPT_SAMBA \
POPT_CREDENTIALS \
LIBCLI_SMB \
LIBCLI_RAW
# End BINARY gentest_smb2
#################################
gentest_smb2_OBJ_FILES = $(torturesrcdir)/gentest_smb2.o
#################################
# Start BINARY masktest
[BINARY::masktest]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,7 @@
if (v != correct) { \
printf("(%s) Incorrect value for %s 0x%08llx - should be 0x%08llx\n", \
__location__, #v, (unsigned long long)v, (unsigned long long)correct); \
return false; \
return false; \
}} while (0)
/*
@ -52,7 +52,8 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
struct smb2_create io;
NTSTATUS status;
TALLOC_CTX *tmp_ctx = talloc_new(tree);
uint32_t access_mask, file_attributes, denied_mask;
uint32_t access_mask, file_attributes, file_attributes_set, denied_mask;
union smb_fileinfo q;
ZERO_STRUCT(io);
io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
@ -115,7 +116,8 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
for (i=0;i<32;i++) {
io.in.desired_access = 1<<i;
status = smb2_create(tree, tmp_ctx, &io);
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
access_mask |= io.in.desired_access;
} else {
CHECK_STATUS(status, NT_STATUS_OK);
@ -131,6 +133,7 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
io.in.file_attributes = 0;
file_attributes = 0;
file_attributes_set = 0;
denied_mask = 0;
{
int i;
@ -146,12 +149,14 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_util_close(tree, io.out.file.handle);
CHECK_STATUS(status, NT_STATUS_OK);
file_attributes_set |= io.out.file_attr;
}
}
}
CHECK_EQUAL(file_attributes, 0xffff8048);
CHECK_EQUAL(denied_mask, 0x4000);
CHECK_EQUAL(file_attributes_set, 0x00001127);
smb2_deltree(tree, FNAME);
@ -177,6 +182,20 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
status = smb2_create(tree, tmp_ctx, &io);
CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
io.in.fname = FNAME;
io.in.file_attributes = 0;
io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA;
io.in.query_maximal_access = true;
status = smb2_create(tree, tmp_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
q.access_information.in.file.handle = io.out.file.handle;
status = smb2_getinfo_file(tree, tmp_ctx, &q);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_EQUAL(q.access_information.out.access_flags, io.in.desired_access);
talloc_free(tmp_ctx);
smb2_deltree(tree, FNAME);
@ -237,6 +256,7 @@ static bool test_create_blob(struct torture_context *torture, struct smb2_tree *
io.in.query_maximal_access = true;
status = smb2_create(tree, tmp_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
status = smb2_util_close(tree, io.out.file.handle);
CHECK_STATUS(status, NT_STATUS_OK);

View File

@ -106,7 +106,11 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
lck.in.reserved = 0x123ab3;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
CHECK_VALUE(lck.out.reserved, 0);
lck.in.reserved = 0x123ab4;
@ -115,7 +119,11 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
lck.in.reserved = 0x123ab5;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
CHECK_VALUE(lck.out.reserved, 0);
lck.in.lock_count = 0x0001;
@ -133,14 +141,22 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
CHECK_VALUE(lck.out.reserved, 0);
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
CHECK_VALUE(lck.out.reserved, 0);
el[0].flags = 0x00000000;
@ -473,6 +489,51 @@ static bool test_lock_rw_exclusiv(struct torture_context *torture, struct smb2_t
return test_lock_read_write(torture, tree, &s);
}
static bool test_lock_auto_unlock(struct torture_context *torture, struct smb2_tree *tree)
{
bool ret = true;
NTSTATUS status;
struct smb2_handle h;
uint8_t buf[200];
struct smb2_lock lck;
struct smb2_lock_element el[2];
ZERO_STRUCT(buf);
status = torture_smb2_testfile(tree, "autounlock.txt", &h);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
CHECK_STATUS(status, NT_STATUS_OK);
ZERO_STRUCT(lck);
lck.in.locks = el;
lck.in.lock_count = 0x0001;
lck.in.file.handle = h;
el[0].offset = 0;
el[0].length = 1;
el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
status = smb2_lock(tree, &lck);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
done:
return ret;
}
/* basic testing of SMB2 locking
*/
struct torture_suite *torture_smb2_lock_init(void)
@ -483,6 +544,7 @@ struct torture_suite *torture_smb2_lock_init(void)
torture_suite_add_1smb2_test(suite, "RW-NONE", test_lock_rw_none);
torture_suite_add_1smb2_test(suite, "RW-SHARED", test_lock_rw_shared);
torture_suite_add_1smb2_test(suite, "RW-EXCLUSIV", test_lock_rw_exclusiv);
torture_suite_add_1smb2_test(suite, "AUTO-UNLOCK", test_lock_auto_unlock);
suite->description = talloc_strdup(suite, "SMB2-LOCK tests");

View File

@ -44,6 +44,9 @@
goto done; \
}} while (0)
#define FNAME "smb2_readtest.dat"
#define DNAME "smb2_readtest.dir"
static bool test_read_eof(struct torture_context *torture, struct smb2_tree *tree)
{
bool ret = true;
@ -55,7 +58,7 @@ static bool test_read_eof(struct torture_context *torture, struct smb2_tree *tre
ZERO_STRUCT(buf);
status = torture_smb2_testfile(tree, "lock1.txt", &h);
status = torture_smb2_testfile(tree, FNAME, &h);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
@ -139,7 +142,7 @@ static bool test_read_position(struct torture_context *torture, struct smb2_tree
ZERO_STRUCT(buf);
status = torture_smb2_testfile(tree, "lock1.txt", &h);
status = torture_smb2_testfile(tree, FNAME, &h);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
@ -172,6 +175,58 @@ done:
return ret;
}
static bool test_read_dir(struct torture_context *torture, struct smb2_tree *tree)
{
bool ret = true;
NTSTATUS status;
struct smb2_handle h;
struct smb2_read rd;
TALLOC_CTX *tmp_ctx = talloc_new(tree);
status = torture_smb2_testdir(tree, DNAME, &h);
if (!NT_STATUS_IS_OK(status)) {
printf(__location__ " Unable to create test directory '%s' - %s\n", DNAME, nt_errstr(status));
return false;
}
ZERO_STRUCT(rd);
rd.in.file.handle = h;
rd.in.length = 10;
rd.in.offset = 0;
rd.in.min_count = 1;
status = smb2_read(tree, tmp_ctx, &rd);
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
rd.in.min_count = 11;
status = smb2_read(tree, tmp_ctx, &rd);
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
rd.in.length = 0;
rd.in.min_count = 2592;
status = smb2_read(tree, tmp_ctx, &rd);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
} else {
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
}
rd.in.length = 0;
rd.in.min_count = 0;
rd.in.channel = 0;
status = smb2_read(tree, tmp_ctx, &rd);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
}
done:
talloc_free(tmp_ctx);
return ret;
}
/*
basic testing of SMB2 read
*/
@ -181,6 +236,7 @@ struct torture_suite *torture_smb2_read_init(void)
torture_suite_add_1smb2_test(suite, "EOF", test_read_eof);
torture_suite_add_1smb2_test(suite, "POSITION", test_read_position);
torture_suite_add_1smb2_test(suite, "DIR", test_read_dir);
suite->description = talloc_strdup(suite, "SMB2-READ tests");

View File

@ -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));

View File

@ -175,6 +175,10 @@ bool torture_smb2_setinfo(struct torture_context *torture)
CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);
printf("can't change a file to a directory\n");
sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
CHECK_CALL(BASIC_INFORMATION, NT_STATUS_INVALID_PARAMETER);
printf("restore attribute\n");
sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);

View File

@ -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));