updated SMB2 tcon as per WSPP docs
authorAndrew Tridgell <tridge@samba.org>
Tue, 12 Feb 2008 23:13:28 +0000 (10:13 +1100)
committerAndrew Tridgell <tridge@samba.org>
Tue, 12 Feb 2008 23:13:28 +0000 (10:13 +1100)
(This used to be commit 5913e3e549e71affc66c28cacb6563331fb0c790)

source4/libcli/raw/interfaces.h
source4/libcli/smb2/connect.c
source4/libcli/smb2/smb2.h
source4/libcli/smb2/smb2_calls.h
source4/libcli/smb2/tcon.c
source4/ntvfs/ntvfs.h
source4/smb_server/smb2/tcon.c

index 4211dadb2d406ab5540c41810664dfd55086a70f..ddbddf4c59e3c3c5c79efcebee19381b52a49616 100644 (file)
@@ -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 */
index a2ae828fa57b62bbba58198e4affa12a9e3584ca..535df11d9de8f880445138b59b084c2363a5a2b1 100644 (file)
@@ -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;
index 60cf3e0173fa54789562042896ce7bc0287c4fa6..549b477ffd2808afd229ace03a80b86e1c52ac9e 100644 (file)
@@ -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
 */
index 423d9d15792aa0ca3b4677f55309f9c21a031443..f2e3019d83df072364bcbddbf81036b62e921949 100644 (file)
@@ -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;
index 5a09970584a2fa69aef896350e2729f5a2e261e3..db35669d41958a20e236d3535de321257dd51e41 100644 (file)
@@ -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);
 }
index fe5f956426306245f3c9f986ffebd9638ac0fe7c..a708dbff51aad366864585b2950432d952ecbf4a 100644 (file)
@@ -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 */
index 824a57b4a1e0bc4142670d040de20f11b5652bce..b375ce6b4ba5677f27a2698a77fc5dd3314f3a0a 100644 (file)
@@ -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);