Make DFS work over SMB2.
authorJeremy Allison <jra@samba.org>
Fri, 21 May 2010 23:56:10 +0000 (16:56 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 21 May 2010 23:56:10 +0000 (16:56 -0700)
Jeremy.

libcli/smb/smb2_constants.h
source3/include/smb.h
source3/param/loadparm.c
source3/smbd/msdfs.c
source3/smbd/smb2_create.c
source3/smbd/smb2_tcon.c

index 3047809b74e7e3ec9d11437ebdd55e5b283ad631..a3885f9b7dcd9c7819df7ad330c5b6aae16bdd83 100644 (file)
@@ -81,6 +81,7 @@
 /* SMB2 capabilities - only 1 so far. I'm sure more will be added */
 #define SMB2_CAP_DFS                     0x00000001
 #define SMB2_CAP_LEASING                 0x00000002 /* only in dialect 0x210 */
+#define SMB2_CAP_LARGE_MTU              0x00000004 /* only in dialect 0x210 */
 /* so we can spot new caps as added */
 #define SMB2_CAP_ALL                     SMB2_CAP_DFS
 
 #define SMB2_SESSION_FLAG_IS_GUEST       0x0001
 #define SMB2_SESSION_FLAG_IS_NULL        0x0002
 
+/* SMB2 sharetype flags */
+#define SMB2_SHARE_TYPE_DISK           0x1
+#define SMB2_SHARE_TYPE_PIPE           0x2
+#define SMB2_SHARE_TYPE_PRINT          0x3
+
 /* SMB2 share flags */
 #define SMB2_SHAREFLAG_MANUAL_CACHING                    0x0000
 #define SMB2_SHAREFLAG_AUTO_CACHING                      0x0010
 #define SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM       0x0800
 #define SMB2_SHAREFLAG_ALL                               0x0F33
 
+/* SMB2 share capafilities */
+#define SMB2_SHARE_CAP_DFS             0x8
+
 /* SMB2 create security flags */
 #define SMB2_SECURITY_DYNAMIC_TRACKING                   0x01
 #define SMB2_SECURITY_EFFECTIVE_ONLY                     0x02
index 93e7323ba84c8b0aa2dc94f5f0a35b2b09802c50..1ceb54b7926976b33900365e021d7f7e4a90d48c 100644 (file)
@@ -1976,4 +1976,10 @@ struct child_pid {
 /* Used to keep track of deferred opens. */
 struct deferred_open_record;
 
+/* Client-side offline caching policy types */
+#define CSC_POLICY_MANUAL 0
+#define CSC_POLICY_DOCUMENTS 1
+#define CSC_POLICY_PROGRAMS 2
+#define CSC_POLICY_DISABLE 3
+
 #endif /* _SMB_H */
index a78bede2aabd7e81a0eea1c88da3a1c69e68a41e..ba9d816429a1e3ab4e4e0e6cbd27e4557350d870 100644 (file)
@@ -827,12 +827,6 @@ static const struct enum_list enum_bool_auto[] = {
        {-1, NULL}
 };
 
-/* Client-side offline caching policy types */
-#define CSC_POLICY_MANUAL 0
-#define CSC_POLICY_DOCUMENTS 1
-#define CSC_POLICY_PROGRAMS 2
-#define CSC_POLICY_DISABLE 3
-
 static const struct enum_list enum_csc_policy[] = {
        {CSC_POLICY_MANUAL, "manual"},
        {CSC_POLICY_DOCUMENTS, "documents"},
index 6dfa88692e2b61eeab31254bf39eef1d27ebef11..92c3e0ebad4c3bbb7f9c1001600f627f44d8ee58 100644 (file)
@@ -50,6 +50,7 @@ static NTSTATUS parse_dfs_path(connection_struct *conn,
                                struct dfs_path *pdp, /* MUST BE TALLOCED */
                                bool *ppath_contains_wcard)
 {
+       struct smbd_server_connection *sconn = smbd_server_conn;
        char *pathname_local;
        char *p,*temp;
        char *servicename;
@@ -77,7 +78,7 @@ static NTSTATUS parse_dfs_path(connection_struct *conn,
 
        sepchar = pdp->posix_path ? '/' : '\\';
 
-       if (*pathname != sepchar) {
+       if (!sconn->allow_smb2 && (*pathname != sepchar)) {
                DEBUG(10,("parse_dfs_path: path %s doesn't start with %c\n",
                        pathname, sepchar ));
                /*
index 31813cc82ebc52bd24f5126ae47e7444d1ac15e7..b4b265b9f5eb3d532338bf9405e2fc90df3c8764 100644 (file)
@@ -673,11 +673,18 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
                in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
 
-               /* convert '\\' into '/' */
-               status = check_path_syntax(fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       tevent_req_nterror(req, status);
-                       return tevent_req_post(req, ev);
+                /*
+                * For a DFS path the function parse_dfs_path()
+                * will do the path processing.
+                */
+
+               if (!smb1req->flags2 & FLAGS2_DFS_PATHNAMES) {
+                       /* convert '\\' into '/' */
+                       status = check_path_syntax(fname);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               tevent_req_nterror(req, status);
+                               return tevent_req_post(req, ev);
+                       }
                }
 
                status = filename_convert(req,
index f3e3037bdb6baf7df60daf4b1abcc302ba0e226b..e1b6775ced89ce2d8f68f83ec8cf775259c90f14 100644 (file)
@@ -227,14 +227,38 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
        tcon->compat_conn->cnum = tcon->tid;
 
        if (IS_PRINT(tcon->compat_conn)) {
-               *out_share_type = 0x03;
+               *out_share_type = SMB2_SHARE_TYPE_PRINT;
        } else if (IS_IPC(tcon->compat_conn)) {
-               *out_share_type = 0x02;
+               *out_share_type = SMB2_SHARE_TYPE_PIPE;
        } else {
-               *out_share_type = 0x01;
+               *out_share_type = SMB2_SHARE_TYPE_DISK;
        }
-       *out_share_flags = SMB2_SHAREFLAG_ALL;
-       *out_capabilities = 0;
+
+       *out_share_flags = SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING;
+
+       if (lp_msdfs_root(SNUM(tcon->compat_conn)) && lp_host_msdfs()) {
+               *out_share_flags |= (SMB2_SHAREFLAG_DFS|SMB2_SHAREFLAG_DFS_ROOT);
+               *out_capabilities = SMB2_SHARE_CAP_DFS;
+       } else {
+               *out_capabilities = 0;
+       }
+
+       switch(lp_csc_policy(SNUM(tcon->compat_conn))) {
+       case CSC_POLICY_MANUAL:
+               break;
+       case CSC_POLICY_DOCUMENTS:
+               *out_share_flags |= SMB2_SHAREFLAG_AUTO_CACHING;
+               break;
+       case CSC_POLICY_PROGRAMS:
+               *out_share_flags |= SMB2_SHAREFLAG_VDO_CACHING;
+               break;
+       case CSC_POLICY_DISABLE:
+               *out_share_flags |= SMB2_SHAREFLAG_NO_CACHING;
+               break;
+       default:
+               break;
+       }
+
        *out_maximal_access = FILE_GENERIC_ALL;
 
        *out_tree_id = tcon->tid;