summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/raw/interfaces.h13
-rw-r--r--source4/libcli/smb2/connect.c2
-rw-r--r--source4/libcli/smb2/smb2.h22
-rw-r--r--source4/libcli/smb2/smb2_calls.h2
-rw-r--r--source4/libcli/smb2/tcon.c16
-rw-r--r--source4/ntvfs/ntvfs.h8
-rw-r--r--source4/smb_server/smb2/tcon.c28
7 files changed, 58 insertions, 33 deletions
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 4211dadb2d..ddbddf4c59 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 */
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/smb2.h b/source4/libcli/smb2/smb2.h
index 60cf3e0173..549b477ffd 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -195,6 +195,28 @@ 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
+
/*
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);
}
diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h
index fe5f956426..a708dbff51 100644
--- a/source4/ntvfs/ntvfs.h
+++ b/source4/ntvfs/ntvfs.h
@@ -32,9 +32,11 @@ struct ntvfs_module_context;
struct ntvfs_request;
/* each backend has to be one one of the following 3 basic types. In
- * earlier versions of Samba backends needed to handle all types, now
- * we implement them separately. */
-enum ntvfs_type {NTVFS_DISK, NTVFS_PRINT, NTVFS_IPC};
+ earlier versions of Samba backends needed to handle all types, now
+ we implement them separately.
+ The values 1..3 match the SMB2 SMB2_SHARE_TYPE_* values
+ */
+enum ntvfs_type {NTVFS_DISK=1, NTVFS_IPC=2, NTVFS_PRINT=3};
/* the ntvfs operations structure - contains function pointers to
the backend implementations of each operation */
diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c
index 824a57b4a1..b375ce6b4b 100644
--- a/source4/smb_server/smb2/tcon.c
+++ b/source4/smb_server/smb2/tcon.c
@@ -240,8 +240,6 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon
struct smbsrv_tcon *tcon;
NTSTATUS status;
enum ntvfs_type type;
- uint16_t type_smb2;
- uint32_t unknown2;
const char *service = io->smb2.in.path;
struct share_config *scfg;
const char *sharetype;
@@ -270,16 +268,10 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon
sharetype = share_string_option(scfg, SHARE_TYPE, "DISK");
if (sharetype && strcmp(sharetype, "IPC") == 0) {
type = NTVFS_IPC;
- type_smb2 = 0x0002;
- unknown2 = 0x00000030;
} else if (sharetype && strcmp(sharetype, "PRINTER") == 0) {
type = NTVFS_PRINT;
- type_smb2 = 0x0003;
- unknown2 = 0x00000000;
} else {
type = NTVFS_DISK;
- type_smb2 = 0x0001;
- unknown2 = 0x00000800;
}
tcon = smbsrv_smb2_tcon_new(req->session, scfg->name);
@@ -344,10 +336,11 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon
goto failed;
}
- io->smb2.out.unknown1 = type_smb2; /* 1 - DISK, 2 - Print, 3 - IPC */
- io->smb2.out.unknown2 = unknown2;
- io->smb2.out.unknown3 = 0x00000000;
- io->smb2.out.access_mask= SEC_RIGHTS_FILE_ALL;
+ io->smb2.out.share_type = (unsigned)type; /* 1 - DISK, 2 - Print, 3 - IPC */
+ io->smb2.out.reserved = 0;
+ io->smb2.out.flags = 0x00000000;
+ io->smb2.out.capabilities = 0;
+ io->smb2.out.access_mask = SEC_RIGHTS_FILE_ALL;
io->smb2.out.tid = tcon->tid;
@@ -367,7 +360,7 @@ static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io)
smb2srv_send_error(req, req->status);
return;
}
- if (io->smb2.out.unknown1 == 0x0002) {
+ if (io->smb2.out.share_type == NTVFS_IPC) {
/* if it's an IPC share vista returns 0x0005 */
credit = 0x0005;
} else {
@@ -379,9 +372,10 @@ static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io)
SIVAL(req->out.hdr, SMB2_HDR_TID, io->smb2.out.tid);
SSVAL(req->out.hdr, SMB2_HDR_CREDIT,credit);
- SSVAL(req->out.body, 0x02, io->smb2.out.unknown1);
- SIVAL(req->out.body, 0x04, io->smb2.out.unknown2);
- SIVAL(req->out.body, 0x08, io->smb2.out.unknown3);
+ SCVAL(req->out.body, 0x02, io->smb2.out.share_type);
+ SCVAL(req->out.body, 0x03, io->smb2.out.reserved);
+ SIVAL(req->out.body, 0x04, io->smb2.out.flags);
+ SIVAL(req->out.body, 0x08, io->smb2.out.capabilities);
SIVAL(req->out.body, 0x0C, io->smb2.out.access_mask);
smb2srv_send_reply(req);
@@ -395,7 +389,7 @@ void smb2srv_tcon_recv(struct smb2srv_request *req)
SMB2SRV_TALLOC_IO_PTR(io, union smb_tcon);
io->smb2.level = RAW_TCON_SMB2;
- io->smb2.in.unknown1 = SVAL(req->in.body, 0x02);
+ io->smb2.in.reserved = SVAL(req->in.body, 0x02);
SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, io, req->in.body+0x04, &io->smb2.in.path));
req->status = smb2srv_tcon_backend(req, io);