From b2a7ad8c951562d1aea6663064784da0b0a98565 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 May 2010 16:56:10 -0700 Subject: [PATCH] Make DFS work over SMB2. Jeremy. --- libcli/smb/smb2_constants.h | 9 +++++++++ source3/include/smb.h | 6 ++++++ source3/param/loadparm.c | 6 ------ source3/smbd/msdfs.c | 3 ++- source3/smbd/smb2_create.c | 17 ++++++++++++----- source3/smbd/smb2_tcon.c | 34 +++++++++++++++++++++++++++++----- 6 files changed, 58 insertions(+), 17 deletions(-) diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h index 3047809b74e..a3885f9b7dc 100644 --- a/libcli/smb/smb2_constants.h +++ b/libcli/smb/smb2_constants.h @@ -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 @@ -88,6 +89,11 @@ #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 @@ -101,6 +107,9 @@ #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 diff --git a/source3/include/smb.h b/source3/include/smb.h index 93e7323ba84..1ceb54b7926 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -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 */ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index a78bede2aab..ba9d816429a 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -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"}, diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index 6dfa88692e2..92c3e0ebad4 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -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 )); /* diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 31813cc82eb..b4b265b9f5e 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -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, diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c index f3e3037bdb6..e1b6775ced8 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -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; -- 2.11.4.GIT