summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/raw/interfaces.h38
-rw-r--r--source4/libcli/smb2/connect.c2
-rw-r--r--source4/libcli/smb2/create.c52
-rw-r--r--source4/libcli/smb2/smb2.h50
-rw-r--r--source4/libcli/smb2/smb2_calls.h2
-rw-r--r--source4/libcli/smb2/tcon.c16
6 files changed, 109 insertions, 51 deletions
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 4211dadb2d..ce6323f2e5 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -260,20 +260,19 @@ union smb_tcon {
struct {
/* static body buffer 8 (0x08) bytes */
- /* uint16_t buffer_code; 0x09 = 0x08 + 1 */
- uint16_t unknown1; /* 0x0000 */
+ uint16_t reserved;
/* uint16_t path_ofs */
/* uint16_t path_size */
-
- /* dynamic body */
+ /* dynamic body */
const char *path; /* as non-terminated UTF-16 on the wire */
} in;
struct {
/* static body buffer 16 (0x10) bytes */
/* uint16_t buffer_code; 0x10 */
- uint16_t unknown1; /* 0x02 */
- uint32_t unknown2; /* 0x00 */
- uint32_t unknown3; /* 0x00 */
+ uint8_t share_type;
+ uint8_t reserved;
+ uint32_t flags;
+ uint32_t capabilities;
uint32_t access_mask;
/* extracted from the SMB2 header */
@@ -1553,16 +1552,16 @@ union smb_open {
enum smb_open_level level;
struct {
/* static body buffer 56 (0x38) bytes */
- /* uint16_t buffer_code; 0x39 = 0x38 + 1 */
- uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */
- uint32_t impersonation;
- uint32_t unknown3[4];
- uint32_t access_mask;
-
- uint32_t file_attr;
- uint32_t share_access;
- uint32_t open_disposition;
- uint32_t create_options;
+ uint8_t security_flags; /* SMB2_SECURITY_* */
+ uint8_t oplock_level; /* SMB2_OPLOCK_LEVEL_* */
+ uint32_t impersonation_level; /* SMB2_IMPERSONATION_* */
+ uint64_t create_flags;
+ uint64_t reserved;
+ uint32_t desired_access;
+ uint32_t file_attributes;
+ uint32_t share_access; /* NTCREATEX_SHARE_ACCESS_* */
+ uint32_t create_disposition; /* NTCREATEX_DISP_* */
+ uint32_t create_options; /* NTCREATEX_OPTIONS_* */
/* uint16_t fname_ofs */
/* uint16_t fname_size */
@@ -1580,7 +1579,8 @@ union smb_open {
/* static body buffer 88 (0x58) bytes */
/* uint16_t buffer_code; 0x59 = 0x58 + 1 */
- uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */
+ uint8_t oplock_level;
+ uint8_t reserved;
uint32_t create_action;
NTTIME create_time;
NTTIME access_time;
@@ -1589,7 +1589,7 @@ union smb_open {
uint64_t alloc_size;
uint64_t size;
uint32_t file_attr;
- uint32_t _pad;
+ uint32_t reserved2;
/* struct smb2_handle handle;*/
/* uint32_t blob_ofs; */
/* uint32_t blob_size; */
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index a2ae828fa5..535df11d9d 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -73,7 +73,7 @@ static void continue_session(struct composite_context *creq)
state->tree = smb2_tree_init(state->session, state, true);
if (composite_nomem(state->tree, c)) return;
- state->tcon.in.unknown1 = 0x09;
+ state->tcon.in.reserved = 0;
state->tcon.in.path = talloc_asprintf(state, "\\\\%s\\%s",
state->host, state->share);
if (composite_nomem(state->tcon.in.path, c)) return;
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index ba11c22e87..cca83a040c 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -24,34 +24,33 @@
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
-#define CREATE_TAG_EXTA 0x41747845 /* "ExtA" */
-#define CREATE_TAG_MXAC 0x6341784D /* "MxAc" */
-
/*
add a blob to a smb2_create attribute blob
*/
NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
- uint32_t tag,
+ const char *tag,
DATA_BLOB add, bool last)
{
uint32_t ofs = blob->length;
- uint8_t pad = smb2_padding_size(add.length, 8);
- if (!data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad))
+ size_t tag_length = strlen(tag);
+ uint8_t pad = smb2_padding_size(add.length+tag_length, 8);
+ if (!data_blob_realloc(mem_ctx, blob,
+ blob->length + 0x14 + tag_length + add.length + pad))
return NT_STATUS_NO_MEMORY;
if (last) {
SIVAL(blob->data, ofs+0x00, 0);
} else {
- SIVAL(blob->data, ofs+0x00, 0x18 + add.length + pad);
+ SIVAL(blob->data, ofs+0x00, 0x14 + tag_length + add.length + pad);
}
SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */
- SIVAL(blob->data, ofs+0x06, 0x04); /* tag length */
- SSVAL(blob->data, ofs+0x0A, 0x18); /* offset of data */
+ SIVAL(blob->data, ofs+0x06, tag_length); /* tag length */
+ SSVAL(blob->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */
SIVAL(blob->data, ofs+0x0C, add.length);
- SIVAL(blob->data, ofs+0x10, tag);
- SIVAL(blob->data, ofs+0x14, 0); /* pad? */
- memcpy(blob->data+ofs+0x18, add.data, add.length);
- memset(blob->data+ofs+0x18+add.length, 0, pad);
+ memcpy(blob->data+ofs+0x10, tag, tag_length);
+ SIVAL(blob->data, ofs+0x10+tag_length, 0); /* pad? */
+ memcpy(blob->data+ofs+0x14+tag_length, add.data, add.length);
+ memset(blob->data+ofs+0x14+tag_length+add.length, 0, pad);
return NT_STATUS_OK;
}
@@ -68,16 +67,15 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0);
if (req == NULL) return NULL;
- SSVAL(req->out.body, 0x02, io->in.oplock_flags);
- SIVAL(req->out.body, 0x04, io->in.impersonation);
- SIVAL(req->out.body, 0x08, io->in.unknown3[0]);
- SIVAL(req->out.body, 0x0C, io->in.unknown3[1]);
- SIVAL(req->out.body, 0x10, io->in.unknown3[2]);
- SIVAL(req->out.body, 0x14, io->in.unknown3[3]);
- SIVAL(req->out.body, 0x18, io->in.access_mask);
- SIVAL(req->out.body, 0x1C, io->in.file_attr);
+ SCVAL(req->out.body, 0x02, io->in.security_flags);
+ SCVAL(req->out.body, 0x03, io->in.oplock_level);
+ SIVAL(req->out.body, 0x04, io->in.impersonation_level);
+ SBVAL(req->out.body, 0x08, io->in.create_flags);
+ SBVAL(req->out.body, 0x10, io->in.reserved);
+ SIVAL(req->out.body, 0x18, io->in.desired_access);
+ SIVAL(req->out.body, 0x1C, io->in.file_attributes);
SIVAL(req->out.body, 0x20, io->in.share_access);
- SIVAL(req->out.body, 0x24, io->in.open_disposition);
+ SIVAL(req->out.body, 0x24, io->in.create_disposition);
SIVAL(req->out.body, 0x28, io->in.create_options);
status = smb2_push_o16s16_string(&req->out, 0x2C, io->in.fname);
@@ -90,7 +88,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
DATA_BLOB b = data_blob_talloc(req, NULL,
ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas));
ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas);
- status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, false);
+ status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_EXTA, b, false);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
return NULL;
@@ -100,7 +98,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
/* an empty MxAc tag seems to be used to ask the server to
return the maximum access mask allowed on the file */
- status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), true);
+ status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_MXAC,
+ data_blob(NULL, 0), true);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
@@ -132,7 +131,8 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
SMB2_CHECK_PACKET_RECV(req, 0x58, true);
- io->out.oplock_flags = SVAL(req->in.body, 0x02);
+ io->out.oplock_level = CVAL(req->in.body, 0x02);
+ io->out.reserved = CVAL(req->in.body, 0x03);
io->out.create_action = IVAL(req->in.body, 0x04);
io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08);
io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10);
@@ -141,7 +141,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
io->out.alloc_size = BVAL(req->in.body, 0x28);
io->out.size = BVAL(req->in.body, 0x30);
io->out.file_attr = IVAL(req->in.body, 0x38);
- io->out._pad = IVAL(req->in.body, 0x3C);
+ io->out.reserved2 = IVAL(req->in.body, 0x3C);
smb2_pull_handle(req->in.body+0x40, &io->out.file.handle);
status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index 60cf3e0173..db13ab69b3 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -195,6 +195,56 @@ struct smb2_request {
#define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */
+/* SMB2 negotiate security_mode */
+#define SMB2_NEGOTIATE_SIGNING_ENABLED 0x01
+#define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x02
+
+/* SMB2 capabilities - only 1 so far. I'm sure more will be added */
+#define SMB2_CAP_DFS 0x0
+/* so we can spot new caps as added */
+#define SMB2_CAP_ALL SMB2_CAP_DFS
+
+/* SMB2 share flags */
+#define SMB2_SHAREFLAG_MANUAL_CACHING 0x0000
+#define SMB2_SHAREFLAG_AUTO_CACHING 0x0010
+#define SMB2_SHAREFLAG_VDO_CACHING 0x0020
+#define SMB2_SHAREFLAG_NO_CACHING 0x0030
+#define SMB2_SHAREFLAG_DFS 0x0001
+#define SMB2_SHAREFLAG_DFS_ROOT 0x0002
+#define SMB2_SHAREFLAG_RESTRICT_EXCLUSIVE_OPENS 0x0100
+#define SMB2_SHAREFLAG_FORCE_SHARED_DELETE 0x0200
+#define SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING 0x0400
+#define SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM 0x0800
+#define SMB2_SHAREFLAG_ALL 0x0F33
+
+/* SMB2 create security flags */
+#define SMB2_SECURITY_DYNAMIC_TRACKING 0x01
+#define SMB2_SECURITY_EFFECTIVE_ONLY 0x02
+
+/* SMB2 requested oplock levels */
+#define SMB2_OPLOCK_LEVEL_NONE 0x00
+#define SMB2_OPLOCK_LEVEL_II 0x01
+#define SMB2_OPLOCK_LEVEL_EXCLUSIVE 0x08
+#define SMB2_OPLOCK_LEVEL_BATCH 0x09
+
+/* SMB2 impersonation levels */
+#define SMB2_IMPERSONATION_ANONYMOUS 0x00
+#define SMB2_IMPERSONATION_IDENTIFICATION 0x01
+#define SMB2_IMPERSONATION_IMPERSONATION 0x02
+#define SMB2_IMPERSONATION_DELEGATE 0x03
+
+/* SMB2 create tags */
+#define SMB2_CREATE_TAG_EXTA "ExtA"
+#define SMB2_CREATE_TAG_MXAC "MxAc"
+#define SMB2_CREATE_TAG_SECD "SecD"
+#define SMB2_CREATE_TAG_DHNQ "DHnQ"
+#define SMB2_CREATE_TAG_DHNC "DHnC"
+#define SMB2_CREATE_TAG_ALSI "AlSi"
+#define SMB2_CREATE_TAG_TWRP "TWrp"
+#define SMB2_CREATE_TAG_QFID "QFid"
+
+
+
/*
check that a body has the expected size
*/
diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h
index 423d9d1579..f2e3019d83 100644
--- a/source4/libcli/smb2/smb2_calls.h
+++ b/source4/libcli/smb2/smb2_calls.h
@@ -35,7 +35,7 @@ struct smb2_negprot {
struct {
/* static body buffer 64 (0x40) bytes */
/* uint16_t buffer_code; 0x41 = 0x40 + 1 */
- uint16_t security_mode;
+ uint16_t security_mode; /* SMB2_NEGOTIATE_SIGNING_* */
uint16_t dialect_revision;
uint16_t reserved;
struct GUID server_guid;
diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c
index 5a09970584..db35669d41 100644
--- a/source4/libcli/smb2/tcon.c
+++ b/source4/libcli/smb2/tcon.c
@@ -58,7 +58,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree,
SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, tree->session->uid);
- SSVAL(req->out.body, 0x02, io->in.unknown1);
+ SSVAL(req->out.body, 0x02, io->in.reserved);
status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
@@ -85,10 +85,18 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne
io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID);
- io->out.unknown1 = SVAL(req->in.body, 0x02);
- io->out.unknown2 = IVAL(req->in.body, 0x04);
- io->out.unknown3 = IVAL(req->in.body, 0x08);
+ io->out.share_type = CVAL(req->in.body, 0x02);
+ io->out.reserved = CVAL(req->in.body, 0x03);
+ io->out.flags = IVAL(req->in.body, 0x04);
+ io->out.capabilities= IVAL(req->in.body, 0x08);
io->out.access_mask = IVAL(req->in.body, 0x0C);
+
+ if (io->out.capabilities & ~SMB2_CAP_ALL) {
+ DEBUG(0,("Unknown capabilities mask 0x%x\n", io->out.capabilities));
+ }
+ if (io->out.flags & ~SMB2_SHAREFLAG_ALL) {
+ DEBUG(0,("Unknown tcon shareflag 0x%x\n", io->out.flags));
+ }
return smb2_request_destroy(req);
}