The branch, master has been updated via ef64048 s3:wscript_build: remove unused variable via 960310b s3:selftest: run SMB2-BASIC via 67ac266 s3:torture: add SMB2-BASIC via fdd6c4e s3:libsmb: add smb2cli_query_directory*() via 548f7d3 s3:libsmb: add smb2cli_write*() via 22859b0 s3:libsmb: add smb2cli_read*() via d82be95 s3:libsmb: add smb2cli_flush*() via 40ecdeb s3:libsmb: add smb2cli_close*() via 2abc34c s3:libsmb: add smb2cli_create*() via f217207 s3:libsmb: add smb2cli_tcon*() and smb2cli_tdis*() via 4efc85c s3:libsmb: add smb2cli_sesssetup*() and smb2cli_logoff*() via ab913d1 s3:libsmb: add smb2cli_negprot*() via a0cf7ba s3:libsmb: add basic smb2 client infrastructure from 8dc7029 Fix bug #8293 - SMB2 doesn't rotate the log files often enough.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit ef64048038cf6aa706bcbc5d6a17ec86ee6247e9 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 7 19:48:43 2011 +0200 s3:wscript_build: remove unused variable metze Autobuild-User: Stefan Metzmacher <me...@samba.org> Autobuild-Date: Fri Jul 8 02:43:22 CEST 2011 on sn-devel-104 commit 960310b68d1e57e89ec8ddd0a35ba99c0f2e2aeb Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jul 8 01:03:49 2011 +0200 s3:selftest: run SMB2-BASIC metze commit 67ac266ae85b57c5580a4f4dc1f49396d5ffc707 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:torture: add SMB2-BASIC Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit fdd6c4e673daa21cbf59bce023cfbd753974f48a Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_query_directory*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit 548f7d3f36583421c095051290753ed04bebe3c2 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_write*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit 22859b0e89e78de92bbf8f0c517475e0fefae623 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_read*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit d82be9588add6d80012ffde7aaf38f8b0a6930c6 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_flush*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit 40ecdeb3fb1abad44d0a42edc651edbcceeebbc9 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_close*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit 2abc34cb4a45d83bfee49a0fb881ba9cbe271249 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_create*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit f21720773fc24424921b6731d0b07df38d00d3e0 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_tcon*() and smb2cli_tdis*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit 4efc85c6f152ef8cf93e76389659fd8eb019a0ee Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_sesssetup*() and smb2cli_logoff*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit ab913d17681183d57f21faf7871ba30b5ae41239 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add smb2cli_negprot*() Based on the initial patch from Volker Lendecke <v...@samba.org>. metze commit a0cf7bae60fed5a30a16a99697f74b431456029e Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 5 18:12:07 2011 +0200 s3:libsmb: add basic smb2 client infrastructure Based on the initial patch from Volker Lendecke <v...@samba.org>. metze ----------------------------------------------------------------------- Summary of changes: source3/Makefile.in | 15 +- source3/include/client.h | 23 ++ source3/libsmb/smb2cli.h | 175 ++++++++++ source3/libsmb/smb2cli_base.c | 531 ++++++++++++++++++++++++++++++ source3/libsmb/smb2cli_base.h | 47 +++ source3/libsmb/smb2cli_close.c | 117 +++++++ source3/libsmb/smb2cli_create.c | 253 ++++++++++++++ source3/libsmb/smb2cli_flush.c | 116 +++++++ source3/libsmb/smb2cli_negprot.c | 163 +++++++++ source3/libsmb/smb2cli_query_directory.c | 179 ++++++++++ source3/libsmb/smb2cli_read.c | 163 +++++++++ source3/libsmb/smb2cli_session.c | 387 ++++++++++++++++++++++ source3/libsmb/smb2cli_tcon.c | 229 +++++++++++++ source3/libsmb/smb2cli_write.c | 134 ++++++++ source3/selftest/tests.py | 2 +- source3/torture/proto.h | 2 + source3/torture/test_smb2.c | 133 ++++++++ source3/torture/torture.c | 16 +- source3/wscript_build | 13 +- 19 files changed, 2692 insertions(+), 6 deletions(-) create mode 100644 source3/libsmb/smb2cli.h create mode 100644 source3/libsmb/smb2cli_base.c create mode 100644 source3/libsmb/smb2cli_base.h create mode 100644 source3/libsmb/smb2cli_close.c create mode 100644 source3/libsmb/smb2cli_create.c create mode 100644 source3/libsmb/smb2cli_flush.c create mode 100644 source3/libsmb/smb2cli_negprot.c create mode 100644 source3/libsmb/smb2cli_query_directory.c create mode 100644 source3/libsmb/smb2cli_read.c create mode 100644 source3/libsmb/smb2cli_session.c create mode 100644 source3/libsmb/smb2cli_tcon.c create mode 100644 source3/libsmb/smb2cli_write.c create mode 100644 source3/torture/test_smb2.c Changeset truncated at 500 lines: diff --git a/source3/Makefile.in b/source3/Makefile.in index 8dc5153..92613ab 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -600,6 +600,17 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clioplock.o libsmb/clirap2.o \ libsmb/smb_seal.o libsmb/async_smb.o \ libsmb/read_smb.o \ + libsmb/smb2cli_base.o \ + libsmb/smb2cli_negprot.o \ + libsmb/smb2cli_session.o \ + libsmb/smb2cli_tcon.o \ + libsmb/smb2cli_create.o \ + ../libcli/smb/smb2_create_blob.o \ + libsmb/smb2cli_close.o \ + libsmb/smb2cli_flush.o \ + libsmb/smb2cli_read.o \ + libsmb/smb2cli_write.o \ + libsmb/smb2cli_query_directory.o \ libsmb/cli_np_tstream.o \ libsmb/smbsock_connect.o \ $(LIBSAMBA_OBJ) \ @@ -936,7 +947,6 @@ SMBD_OBJ_SRV = smbd/server_reload.o \ smbd/smb2_getinfo.o \ smbd/smb2_setinfo.o \ smbd/smb2_break.o \ - ../libcli/smb/smb2_create_blob.o \ $(MANGLE_OBJ) @VFS_STATIC@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ @@ -1242,7 +1252,8 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta torture/test_notify_online.o \ torture/test_addrchange.o \ torture/test_case_insensitive.o \ - torture/test_posix_append.o + torture/test_posix_append.o \ + torture/test_smb2.o SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) $(TLDAP_OBJ) \ $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ diff --git a/source3/include/client.h b/source3/include/client.h index 6486c76..2f8a572 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -139,6 +139,29 @@ struct cli_state { struct tevent_queue *outgoing; struct tevent_req **pending; + + struct { + uint64_t mid; + uint32_t pid; + uint32_t tid; + uint64_t uid; + + /* SMB2 negprot */ + uint16_t security_mode; + uint16_t dialect_revision; + struct GUID server_guid; + uint16_t server_capabilities; + uint32_t max_transact_size; + uint32_t max_read_size; + uint32_t max_write_size; + struct timespec system_time; + struct timespec server_start_time; + + /* SMB2 tcon */ + uint8_t share_type; + uint32_t share_flags; + uint32_t maximal_access; + } smb2; }; struct file_info { diff --git a/source3/libsmb/smb2cli.h b/source3/libsmb/smb2cli.h new file mode 100644 index 0000000..5db481f --- /dev/null +++ b/source3/libsmb/smb2cli.h @@ -0,0 +1,175 @@ +/* + Unix SMB/CIFS implementation. + smb2 client routines + Copyright (C) Volker Lendecke 2011 + + 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/>. +*/ + +#ifndef __SMB2CLI_H__ +#define __SMB2CLI_H__ + +struct tevent_req *smb2cli_negprot_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS smb2cli_negprot_recv(struct tevent_req *req); +NTSTATUS smb2cli_negprot(struct cli_state *cli); + +struct tevent_req *smb2cli_sesssetup_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *user, + const char *domain, + const char *pass); +NTSTATUS smb2cli_sesssetup_recv(struct tevent_req *req); +NTSTATUS smb2cli_sesssetup(struct cli_state *cli, const char *user, + const char *domain, const char *pass); + +struct tevent_req *smb2cli_logoff_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS smb2cli_logoff_recv(struct tevent_req *req); +NTSTATUS smb2cli_logoff(struct cli_state *cli); + +struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *share); +NTSTATUS smb2cli_tcon_recv(struct tevent_req *req); +NTSTATUS smb2cli_tcon(struct cli_state *cli, const char *share); + +struct tevent_req *smb2cli_tdis_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS smb2cli_tdis_recv(struct tevent_req *req); +NTSTATUS smb2cli_tdis(struct cli_state *cli); + +struct tevent_req *smb2cli_create_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *filename, + uint8_t oplock_level, /* SMB2_OPLOCK_LEVEL_* */ + uint32_t impersonation_level, /* SMB2_IMPERSONATION_* */ + uint32_t desired_access, + uint32_t file_attributes, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options, + struct smb2_create_blobs *blobs); +NTSTATUS smb2cli_create_recv(struct tevent_req *req, + uint64_t *fid_persistent, + uint64_t *fid_volatile); +NTSTATUS smb2cli_create(struct cli_state *cli, + const char *filename, + uint8_t oplock_level, /* SMB2_OPLOCK_LEVEL_* */ + uint32_t impersonation_level, /* SMB2_IMPERSONATION_* */ + uint32_t desired_access, + uint32_t file_attributes, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options, + struct smb2_create_blobs *blobs, + uint64_t *fid_persistent, + uint64_t *fid_volatile); + +struct tevent_req *smb2cli_close_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint16_t flags, + uint64_t fid_persistent, + uint64_t fid_volatile); +NTSTATUS smb2cli_close_recv(struct tevent_req *req); +NTSTATUS smb2cli_close(struct cli_state *cli, uint16_t flags, + uint64_t fid_persistent, uint64_t fid_volatile); + +struct tevent_req *smb2cli_flush_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint64_t fid_persistent, + uint64_t fid_volatile); +NTSTATUS smb2cli_flush_recv(struct tevent_req *req); +NTSTATUS smb2cli_flush(struct cli_state *cli, + uint64_t fid_persistent, + uint64_t fid_volatile); + +struct tevent_req *smb2cli_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint32_t length, + uint64_t offset, + uint64_t fid_persistent, + uint64_t fid_volatile, + uint64_t minimum_count, + uint64_t remaining_bytes); +NTSTATUS smb2cli_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **data, uint32_t *data_length); +NTSTATUS smb2cli_read(struct cli_state *cli, + uint32_t length, + uint64_t offset, + uint64_t fid_persistent, + uint64_t fid_volatile, + uint64_t minimum_count, + uint64_t remaining_bytes, + TALLOC_CTX *mem_ctx, + uint8_t **data, + uint32_t *data_length); + +struct tevent_req *smb2cli_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint32_t length, + uint64_t offset, + uint64_t fid_persistent, + uint64_t fid_volatile, + uint32_t remaining_bytes, + uint32_t flags, + const uint8_t *data); +NTSTATUS smb2cli_write_recv(struct tevent_req *req); +NTSTATUS smb2cli_write(struct cli_state *cli, + uint32_t length, + uint64_t offset, + uint64_t fid_persistent, + uint64_t fid_volatile, + uint32_t remaining_bytes, + uint32_t flags, + const uint8_t *data); + +struct tevent_req *smb2cli_query_directory_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint8_t level, + uint8_t flags, + uint32_t file_index, + uint64_t fid_persistent, + uint64_t fid_volatile, + const char *mask, + uint32_t outbuf_len); +NTSTATUS smb2cli_query_directory_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + uint8_t **data, + uint32_t *data_length); +NTSTATUS smb2cli_query_directory(struct cli_state *cli, + uint8_t level, + uint8_t flags, + uint32_t file_index, + uint64_t fid_persistent, + uint64_t fid_volatile, + const char *mask, + uint32_t outbuf_len, + TALLOC_CTX *mem_ctx, + uint8_t **data, + uint32_t *data_length); + +#endif /* __SMB2CLI_H__ */ diff --git a/source3/libsmb/smb2cli_base.c b/source3/libsmb/smb2cli_base.c new file mode 100644 index 0000000..318f1a2 --- /dev/null +++ b/source3/libsmb/smb2cli_base.c @@ -0,0 +1,531 @@ +/* + Unix SMB/CIFS implementation. + smb2 lib + Copyright (C) Volker Lendecke 2011 + + 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 "client.h" +#include "read_smb.h" +#include "smb2cli_base.h" +#include "lib/async_req/async_sock.h" +#include "lib/util/tevent_ntstatus.h" + +struct smb2cli_req_state { + struct tevent_context *ev; + struct cli_state *cli; + + const uint8_t *fixed; + uint16_t fixed_len; + const uint8_t *dyn; + uint16_t dyn_len; + + uint8_t nbt[4]; + uint8_t hdr[64]; + uint8_t pad[7]; /* padding space for compounding */ + + uint8_t *inbuf; + struct iovec *recv_iov; +}; + +static void smb2cli_req_unset_pending(struct tevent_req *req) +{ + struct smb2cli_req_state *state = + tevent_req_data(req, + struct smb2cli_req_state); + struct cli_state *cli = state->cli; + int num_pending = talloc_array_length(cli->pending); + int i; + + if (num_pending == 1) { + /* + * The pending read_smb tevent_req is a child of + * cli->pending. So if nothing is pending anymore, we need to + * delete the socket read fde. + */ + TALLOC_FREE(cli->pending); + return; + } + + for (i=0; i<num_pending; i++) { + if (req == cli->pending[i]) { + break; + } + } + if (i == num_pending) { + /* + * Something's seriously broken. Just returning here is the + * right thing nevertheless, the point of this routine is to + * remove ourselves from cli->pending. + */ + return; + } + + /* + * Remove ourselves from the cli->pending array + */ + if (num_pending > 1) { + cli->pending[i] = cli->pending[num_pending-1]; + } + + /* + * No NULL check here, we're shrinking by sizeof(void *), and + * talloc_realloc just adjusts the size for this. + */ + cli->pending = talloc_realloc(NULL, cli->pending, struct tevent_req *, + num_pending - 1); + return; +} + +static int smb2cli_req_destructor(struct tevent_req *req) +{ + smb2cli_req_unset_pending(req); + return 0; +} + +static void smb2cli_inbuf_received(struct tevent_req *subreq); + +static bool smb2cli_req_set_pending(struct tevent_req *req) +{ + struct smb2cli_req_state *state = + tevent_req_data(req, + struct smb2cli_req_state); + struct cli_state *cli; + struct tevent_req **pending; + int num_pending; + struct tevent_req *subreq; + + cli = state->cli; + num_pending = talloc_array_length(cli->pending); + + pending = talloc_realloc(cli, cli->pending, struct tevent_req *, + num_pending+1); + if (pending == NULL) { + return false; + } + pending[num_pending] = req; + cli->pending = pending; + talloc_set_destructor(req, smb2cli_req_destructor); + + if (num_pending > 0) { + return true; + } + + /* + * We're the first ones, add the read_smb request that waits for the + * answer from the server + */ + subreq = read_smb_send(cli->pending, state->ev, cli->fd); + if (subreq == NULL) { + smb2cli_req_unset_pending(req); + return false; + } + tevent_req_set_callback(subreq, smb2cli_inbuf_received, cli); + return true; +} + +struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint16_t cmd, + uint32_t flags, + const uint8_t *fixed, + uint16_t fixed_len, + const uint8_t *dyn, + uint16_t dyn_len) +{ + struct tevent_req *result; + struct smb2cli_req_state *state; + + result = tevent_req_create(mem_ctx, &state, + struct smb2cli_req_state); + if (result == NULL) { + return NULL; + } + state->ev = ev; + state->cli = cli; + + state->fixed = fixed; + state->fixed_len = fixed_len; + state->dyn = dyn; + state->dyn_len = dyn_len; + + SIVAL(state->hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC); + SSVAL(state->hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); + SSVAL(state->hdr, SMB2_HDR_EPOCH, 1); + SIVAL(state->hdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_OK)); + SSVAL(state->hdr, SMB2_HDR_OPCODE, cmd); + SSVAL(state->hdr, SMB2_HDR_CREDIT, 31); + SIVAL(state->hdr, SMB2_HDR_FLAGS, flags); + SIVAL(state->hdr, SMB2_HDR_PID, cli->smb2.pid); + SIVAL(state->hdr, SMB2_HDR_TID, cli->smb2.tid); + SBVAL(state->hdr, SMB2_HDR_SESSION_ID, cli->smb2.uid); + + return result; +} + +static void smb2cli_writev_done(struct tevent_req *subreq); + +NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs, + int num_reqs) +{ + struct smb2cli_req_state *state; + struct tevent_req *subreq; + struct iovec *iov; + int i, num_iov, nbt_len; + + /* + * 1 for the nbt length + * per request: HDR, fixed, dyn, padding + * -1 because the last one does not need padding + */ + + iov = talloc_array(reqs[0], struct iovec, 1 + 4*num_reqs - 1); + if (iov == NULL) { + return NT_STATUS_NO_MEMORY; + } + + num_iov = 1; + nbt_len = 0; + + for (i=0; i<num_reqs; i++) { + size_t reqlen; + bool ret; + + state = tevent_req_data(reqs[i], struct smb2cli_req_state); + + SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, state->cli->smb2.mid++); + + iov[num_iov].iov_base = state->hdr; + iov[num_iov].iov_len = sizeof(state->hdr); + num_iov += 1; + + iov[num_iov].iov_base = discard_const(state->fixed); + iov[num_iov].iov_len = state->fixed_len; + num_iov += 1; + + if (state->dyn != NULL) { + iov[num_iov].iov_base = discard_const(state->dyn); + iov[num_iov].iov_len = state->dyn_len; + num_iov += 1; + } + + reqlen = sizeof(state->hdr) + state->fixed_len + + state->dyn_len; + + if (i < num_reqs-1) { + if ((reqlen % 8) > 0) { + uint8_t pad = 8 - (reqlen % 8); + iov[num_iov].iov_base = state->pad; + iov[num_iov].iov_len = pad; + num_iov += 1; + reqlen += pad; + } + SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND, reqlen); + } + nbt_len += reqlen; -- Samba Shared Repository