1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-05 21:57:51 +03:00

r11665: started to put some meat on the structure used for the SMB2 library

the call definitions will be in smb2_calls.h, which will play a
similar role that smb_interfaces.h plays for the old SMB protocol
This commit is contained in:
Andrew Tridgell 2005-11-11 05:53:54 +00:00 committed by Gerald (Jerry) Carter
parent 1f97dccd52
commit 4ef3902a8a
9 changed files with 213 additions and 50 deletions

View File

@ -336,3 +336,4 @@ struct _krb5_krb_auth_data;
struct smb2_request;
struct smb2_transport;
struct smb2_negprot;

View File

@ -2,5 +2,6 @@
OBJ_FILES = \
transport.o \
request.o \
negprot.o
negprot.o \
session.o
REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET

View File

@ -23,19 +23,23 @@
#include "includes.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
/*
send a negprot request
*/
struct smb2_request *smb2_negprot_send(struct smb2_transport *transport)
struct smb2_request *smb2_negprot_send(struct smb2_transport *transport,
struct smb2_negprot *io)
{
struct smb2_request *req;
req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26);
if (req == NULL) return NULL;
memset(req->out.body, 0, 0x26);
SIVAL(req->out.body, 0, 0x00010024); /* unknown */
SIVAL(req->out.body, 0x00, io->in.unknown1);
SSVAL(req->out.body, 0x04, io->in.unknown2);
memcpy(req->out.body+0x06, io->in.unknown3, 32);
smb2_transport_send(req);
@ -45,29 +49,35 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport)
/*
recv a negprot reply
*/
NTSTATUS smb2_negprot_recv(struct smb2_request *req)
NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
struct smb2_negprot *io)
{
NTTIME t1, t2;
DATA_BLOB secblob;
struct GUID guid;
NTSTATUS status;
uint16_t blobsize;
if (!smb2_request_receive(req) ||
smb2_request_is_error(req)) {
return smb2_request_destroy(req);
}
t1 = smbcli_pull_nttime(req->in.body, 0x28);
t2 = smbcli_pull_nttime(req->in.body, 0x30);
if (req->in.body_size < 0x40) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
secblob = smb2_pull_blob(req, req->in.body+0x40, req->in.body_size - 0x40);
status = smb2_pull_guid(req, req->in.body+0x08, &guid);
NT_STATUS_NOT_OK_RETURN(status);
printf("Negprot reply:\n");
printf("t1 =%s\n", nt_time_string(req, t1));
printf("t2 =%s\n", nt_time_string(req, t2));
printf("guid=%s\n", GUID_string(req, &guid));
io->out.unknown1 = IVAL(req->in.body, 0x00);
io->out.unknown2 = IVAL(req->in.body, 0x04);
memcpy(io->out.sessid, req->in.body + 0x08, 16);
io->out.unknown3 = IVAL(req->in.body, 0x18);
io->out.unknown4 = SVAL(req->in.body, 0x1C);
io->out.unknown5 = IVAL(req->in.body, 0x1E);
io->out.unknown6 = IVAL(req->in.body, 0x22);
io->out.unknown7 = SVAL(req->in.body, 0x26);
io->out.current_time = smbcli_pull_nttime(req->in.body, 0x28);
io->out.boot_time = smbcli_pull_nttime(req->in.body, 0x30);
io->out.unknown8 = SVAL(req->in.body, 0x38);
blobsize = SVAL(req->in.body, 0x3A);
io->out.unknown9 = IVAL(req->in.body, 0x3C);
io->out.secblob = smb2_pull_blob(req, req->in.body+0x40, blobsize);
talloc_steal(mem_ctx, io->out.secblob.data);
return smb2_request_destroy(req);
}
@ -75,8 +85,9 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req)
/*
sync negprot request
*/
NTSTATUS smb2_negprot(struct smb2_transport *transport)
NTSTATUS smb2_negprot(struct smb2_transport *transport,
TALLOC_CTX *mem_ctx, struct smb2_negprot *io)
{
struct smb2_request *req = smb2_negprot_send(transport);
return smb2_negprot_recv(req);
struct smb2_request *req = smb2_negprot_send(transport, io);
return smb2_negprot_recv(req, mem_ctx, io);
}

View File

@ -25,7 +25,6 @@
#include "libcli/smb2/smb2.h"
#include "include/dlinklist.h"
#include "lib/events/events.h"
#include "librpc/gen_ndr/ndr_misc.h"
/*
initialise a smb2 request
@ -154,18 +153,3 @@ DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size)
return data_blob_talloc(req, ptr, size);
}
/*
pull a guid from the reply body
*/
NTSTATUS smb2_pull_guid(struct smb2_request *req, uint8_t *ptr, struct GUID *guid)
{
NTSTATUS status;
DATA_BLOB blob = smb2_pull_blob(req, ptr, 16);
if (blob.data == NULL) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
status = ndr_pull_struct_blob(&blob, req, guid,
(ndr_pull_flags_fn_t)ndr_pull_GUID);
data_blob_free(&blob);
return status;
}

View File

@ -0,0 +1,47 @@
/*
Unix SMB/CIFS implementation.
SMB2 client session handling
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/smb2/smb2.h"
/*
initialise a smb2_session structure
*/
struct smb2_session *smb2_session_init(struct smb2_transport *transport,
TALLOC_CTX *parent_ctx, BOOL primary)
{
struct smb2_session *session;
session = talloc_zero(parent_ctx, struct smb2_session);
if (!session) {
return NULL;
}
if (primary) {
session->transport = talloc_steal(session, transport);
} else {
session->transport = talloc_reference(session, transport);
}
return session;
}

View File

@ -29,7 +29,6 @@ struct smb2_options {
*/
struct smb2_negotiate {
DATA_BLOB secblob;
};
/* this is the context for the smb2 transport layer */
@ -52,6 +51,13 @@ struct smb2_transport {
};
/*
SMB2 session context
*/
struct smb2_session {
struct smb2_transport *transport;
};
struct smb2_request_buffer {
/* the raw SMB2 buffer, including the 4 byte length header */
uint8_t *buffer;

View File

@ -0,0 +1,63 @@
/*
Unix SMB/CIFS implementation.
SMB2 client calls
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
struct smb2_negprot {
struct {
uint32_t unknown1; /* 0x00010024 */
uint16_t unknown2; /* 0x00 */
uint8_t unknown3[32]; /* all zero */
} in;
struct {
uint32_t unknown1; /* 0x41 */
uint32_t unknown2; /* 0x06 */
uint8_t sessid[16];
uint32_t unknown3; /* 0x0d */
uint16_t unknown4; /* 0x00 */
uint32_t unknown5; /* 0x01 */
uint32_t unknown6; /* 0x01 */
uint16_t unknown7; /* 0x01 */
NTTIME current_time;
NTTIME boot_time;
uint16_t unknown8; /* 0x80 */
/* uint16_t secblob size here */
uint32_t unknown9; /* 0x204d4c20 */
DATA_BLOB secblob;
} out;
};
struct smb2_session_setup {
struct {
uint32_t unknown1; /* 0x11 */
uint32_t unknown2; /* 0xF */
uint32_t unknown3; /* 0x00 */
uint16_t unknown4; /* 0x50 */
/* uint16_t secblob size here */
DATA_BLOB secblob;
} in;
struct {
uint32_t unknown1; /* 0x09 */
uint16_t unknown2; /* 0x48 */
/* uint16_t secblob size here */
DATA_BLOB secblob;
} out;
};

View File

@ -183,6 +183,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
req->in.ptr = req->in.body;
req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS));
dump_data(0, req->in.body, req->in.body_size);
/* if this request has an async handler then call that to
notify that the reply has been received. This might destroy
the request so it must happen last */

View File

@ -23,6 +23,7 @@
#include "includes.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "lib/cmdline/popt_common.h"
#include "lib/events/events.h"
@ -37,17 +38,16 @@
goto done; \
}} while (0)
/*
basic testing of SMB2 connection calls
*/
BOOL torture_smb2_connect(void)
/*
send a negotiate
*/
static struct smb2_transport *torture_smb2_negprot(TALLOC_CTX *mem_ctx, const char *host)
{
TALLOC_CTX *mem_ctx = talloc_new(NULL);
struct smbcli_socket *socket;
struct smb2_transport *transport;
const char *host = lp_parm_string(-1, "torture", "host");
BOOL ret = True;
NTSTATUS status;
struct smb2_negprot io;
socket = smbcli_sock_connect_byname(host, 445, mem_ctx, NULL);
if (socket == NULL) {
@ -56,19 +56,67 @@ BOOL torture_smb2_connect(void)
}
transport = smb2_transport_init(socket, mem_ctx);
if (socket == NULL) {
if (transport == NULL) {
printf("Failed to setup smb2 transport\n");
return False;
}
ZERO_STRUCT(io);
io.in.unknown1 = 0x010024;
/* send a negprot */
status = smb2_negprot(transport);
status = smb2_negprot(transport, mem_ctx, &io);
if (!NT_STATUS_IS_OK(status)) {
printf("negprot failed - %s\n", nt_errstr(status));
return False;
return NULL;
}
printf("Negprot reply:\n");
printf("current_time = %s\n", nt_time_string(mem_ctx, io.out.current_time));
printf("boot_time = %s\n", nt_time_string(mem_ctx, io.out.boot_time));
return transport;
}
#if 0
/*
send a session setup
*/
static struct smb2_session *torture_smb2_session(struct smb2_transport *transport,
struct cli_credentials *credentials)
{
struct smb2_session *session;
NTSTATUS status;
session = smb2_session_init(transport);
status = smb2_session_setup(session, credentials)
if (!NT_STATUS_IS_OK(status)) {
printf("session setup failed - %s\n", nt_errstr(status));
return NULL;
}
return session;
}
#endif
/*
basic testing of SMB2 connection calls
*/
BOOL torture_smb2_connect(void)
{
TALLOC_CTX *mem_ctx = talloc_new(NULL);
struct smb2_transport *transport;
struct smb2_session *session;
const char *host = lp_parm_string(-1, "torture", "host");
struct cli_credentials *credentials = cmdline_credentials;
transport = torture_smb2_negprot(mem_ctx, host);
#if 0
session = torture_smb2_session(transport, credentials);
#endif
talloc_free(mem_ctx);
return ret;
return True;
}