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
+ 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,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-struct smb2_options {
- uint32_t timeout;
-};
+#ifndef __LIBCLI_SMB2_SMB2_H__
+#define __LIBCLI_SMB2_SMB2_H__
+
+#include "libcli/raw/request.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/smb2/smb2_constants.h"
+
+struct smb2_handle;
+struct smb2_lease_break;
/*
- 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;
+ uint16_t dialect_revision;
};
/* this is the context for the smb2 transport layer */
/* socket level info */
struct smbcli_socket *socket;
- struct smb2_options options;
struct smb2_negotiate negotiate;
/* next seqnum to allocate */
/* context of the stream -> packet parser */
struct packet_context *packet;
+
+ /* an idle function - if this is defined then it will be
+ called once every period microseconds while we are waiting
+ for a packet */
+ struct {
+ void (*func)(struct smb2_transport *, void *);
+ void *private_data;
+ uint_t period;
+ } idle;
+
+ struct {
+ /* a oplock break request handler */
+ bool (*handler)(struct smb2_transport *transport,
+ const struct smb2_handle *handle,
+ uint8_t level, void *private_data);
+ /* private data passed to the oplock handler */
+ void *private_data;
+ } oplock;
+
+ struct {
+ /* a lease break request handler */
+ bool (*handler)(struct smb2_transport *transport,
+ const struct smb2_lease_break *lease_break,
+ void *private_data);
+ /* private data passed to the oplock handler */
+ void *private_data;
+ } lease;
+
+ struct smbcli_options options;
+
+ bool signing_required;
+};
+
+
+/*
+ SMB2 tree context
+*/
+struct smb2_tree {
+ struct smb2_session *session;
+ uint32_t tid;
+};
+
+/*
+ SMB2 session context
+*/
+struct smb2_session {
+ struct smb2_transport *transport;
+ struct gensec_security *gensec;
+ uint64_t uid;
+ DATA_BLOB session_key;
+ bool signing_active;
};
uint8_t *buffer;
/* the size of the raw buffer, including 4 byte header */
- uint_t size;
+ size_t size;
/* how much has been allocated - on reply the buffer is over-allocated to
prevent too many realloc() calls
*/
- uint_t allocated;
+ size_t allocated;
/* the start of the SMB2 header - this is always buffer+4 */
uint8_t *hdr;
/* the packet body */
uint8_t *body;
- uint_t body_size;
-
- /* ptr is used as a moving pointer into the data area
- * of the packet. The reason its here and not a local
- * variable in each function is that when a realloc of
- * a send packet is done we need to move this
- * pointer */
- uint8_t *ptr;
+ size_t body_fixed;
+ size_t body_size;
+
+ /* this point to the next dynamic byte that can be used
+ * this will be moved when some dynamic data is pushed
+ */
+ uint8_t *dynamic;
+
+ /* this is used to range check and align strings and buffers */
+ struct request_bufinfo bufinfo;
};
enum smb2_request_state state;
struct smb2_transport *transport;
+ struct smb2_session *session;
+ struct smb2_tree *tree;
uint64_t seqnum;
+ struct {
+ bool do_cancel;
+ bool can_cancel;
+ uint32_t pending_id;
+ } cancel;
+
/* the NT status for this request. Set by packet receive code
or code detecting error. */
NTSTATUS status;
*/
struct {
void (*fn)(struct smb2_request *);
- void *private;
+ void *private_data;
} async;
};
-#define SMB2_MIN_SIZE 0x40
-
-/* offsets into header elements */
-#define SMB2_HDR_LENGTH 0x04
-#define SMB2_HDR_PAD1 0x06
-#define SMB2_HDR_STATUS 0x08
-#define SMB2_HDR_OPCODE 0x0c
-#define SMB2_HDR_PAD2 0x0e
-#define SMB2_HDR_FLAGS 0x10
-#define SMB2_HDR_UNKNOWN 0x14
-#define SMB2_HDR_SEQNUM 0x18
-#define SMB2_HDR_PID 0x20
-#define SMB2_HDR_TID 0x24
-#define SMB2_HDR_UID 0x28
-#define SMB2_HDR_UID2 0x2c /* whats this? */
-#define SMB2_HDR_SIG 0x30 /* guess ... */
-#define SMB2_HDR_BODY 0x40
-
-/* SMB2 opcodes */
-#define SMB2_OP_NEGPROT 0x00
-#define SMB2_OP_SESSSETUP 0x01
-#define SMB2_OP_TCON 0x03
-#define SMB2_OP_TDIS 0x04
-#define SMB2_OP_CREATE 0x05
-#define SMB2_OP_CLOSE 0x06
-#define SMB2_OP_READ 0x08
-#define SMB2_OP_WRITE 0x09
-#define SMB2_OP_FIND 0x0e
-
-#define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */
+#define SMB2_MIN_SIZE 0x42
+#define SMB2_MIN_SIZE_NO_BODY 0x40
+/*
+ check that a body has the expected size
+*/
+#define SMB2_CHECK_PACKET_RECV(req, size, dynamic) do { \
+ size_t is_size = req->in.body_size; \
+ uint16_t field_size = SVAL(req->in.body, 0); \
+ uint16_t want_size = ((dynamic)?(size)+1:(size)); \
+ if (is_size < (size)) { \
+ DEBUG(0,("%s: buffer too small 0x%x. Expected 0x%x\n", \
+ __location__, (unsigned)is_size, (unsigned)want_size)); \
+ return NT_STATUS_BUFFER_TOO_SMALL; \
+ }\
+ if (field_size != want_size) { \
+ DEBUG(0,("%s: unexpected fixed body size 0x%x. Expected 0x%x\n", \
+ __location__, (unsigned)field_size, (unsigned)want_size)); \
+ return NT_STATUS_INVALID_PARAMETER; \
+ } \
+} while (0)
+
+#endif