[PATCH] s3:smb2_find: Return that timestamps do not exist as directories
Christof Schmitt
christof.schmitt at us.ibm.com
Mon Sep 9 23:33:47 CEST 2013
The attached patch solves problem when querying filesystem snapshots through
the "previous versions" dialog. When a share contains many entries (more than
583 subdirectories in my test, frame 164), the Windows client issues a FIND
request, asking for a @GMT timestamp. This does not make sense, and a Windows
server responds with STATUS_NO_SUCH_FILE (frame 167). After this, the query
works as expected:
78 2.009991000 10.0.100.9 -> 10.0.100.90 SMB2 Ioctl Request FSCTL_GET_SHADOW_COPY_DATA File: 2.009991000 0.009541000 52529 microsoft-ds
79 2.010492000 10.0.100.90 -> 10.0.100.9 SMB2 Ioctl Response FSCTL_GET_SHADOW_COPY_DATA File: 2.010492000 0.000501000 microsoft-ds 52529
80 2.022120000 10.0.100.9 -> 10.0.100.90 SMB2 Ioctl Request FSCTL_GET_SHADOW_COPY_DATA File: 2.022120000 0.011628000 52529 microsoft-ds
81 2.022521000 10.0.100.90 -> 10.0.100.9 SMB2 Ioctl Response FSCTL_GET_SHADOW_COPY_DATA File: 2.022521000 0.000401000 microsoft-ds 52529
82 2.022665000 10.0.100.9 -> 10.0.100.90 SMB2 GetInfo Request FILE_INFO/SMB2_FILE_EA_INFO File: 2.022665000 0.000144000 52529 microsoft-ds
83 2.023028000 10.0.100.90 -> 10.0.100.9 SMB2 GetInfo Response 2.023028000 0.000363000 microsoft-ds 52529
84 2.023243000 10.0.100.9 -> 10.0.100.90 SMB2 Ioctl Request FSCTL_GET_REPARSE_POINT File: 2.023243000 0.000215000 52529 microsoft-ds
85 2.023698000 10.0.100.90 -> 10.0.100.9 SMB2 Ioctl Response, Error: STATUS_NOT_A_REPARSE_POINT 2.023698000 0.000455000 microsoft-ds 52529
86 2.023933000 10.0.100.9 -> 10.0.100.90 SMB2 Ioctl Request FSCTL_GET_REPARSE_POINT File: 2.023933000 0.000235000 52529 microsoft-ds
87 2.024355000 10.0.100.90 -> 10.0.100.9 SMB2 Ioctl Response, Error: STATUS_NOT_A_REPARSE_POINT 2.024355000 0.000422000 microsoft-ds 52529
88 2.024690000 10.0.100.9 -> 10.0.100.90 SMB2 Create Request File: @ 2.024690000 0.000335000 52529 microsoft-ds
89 2.025357000 10.0.100.90 -> 10.0.100.9 SMB2 Create Response File: 2.025357000 0.000667000 microsoft-ds 52529
90 2.025539000 10.0.100.9 -> 10.0.100.90 SMB2 GetInfo Request FILE_INFO/SMB2_FILE_NETWORK_OPEN_INFO File: 2.025539000 0.000182000 52529 microsoft-ds
91 2.026015000 10.0.100.90 -> 10.0.100.9 SMB2 GetInfo Response 2.026015000 0.000476000 microsoft-ds 52529
92 2.026113000 10.0.100.9 -> 10.0.100.90 SMB2 Close Request File: 2.026113000 0.000098000 52529 microsoft-ds
93 2.026497000 10.0.100.90 -> 10.0.100.9 SMB2 Close Response 2.026497000 0.000384000 microsoft-ds 52529
94 2.026955000 10.0.100.9 -> 10.0.100.90 SMB2 Create Request File: 2.026955000 0.000458000 52529 microsoft-ds
95 2.027479000 10.0.100.90 -> 10.0.100.9 SMB2 Create Response File: 2.027479000 0.000524000 microsoft-ds 52529
96 2.027643000 10.0.100.9 -> 10.0.100.90 SMB2 Find Request File: SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: *;Find Request File: SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: * 2.027643000 0.000164000 52529 microsoft-ds
164 2.063609000 10.0.100.90 -> 10.0.100.9 SMB2 Find Response SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: *;Find Response SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: * 2.063609000 0.035966000 microsoft-ds 52529
166 2.064996000 10.0.100.9 -> 10.0.100.90 SMB2 Find Request File: SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: @GMT-2013.08.28-19.49.46 2.064996000 0.001387000 52529 microsoft-ds
167 2.065371000 10.0.100.90 -> 10.0.100.9 SMB2 Find Response, Error: STATUS_NO_SUCH_FILE SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: @GMT-2013.08.28-19.49.46 2.065371000 0.000375000 microsoft-ds 52529
168 2.065492000 10.0.100.9 -> 10.0.100.90 SMB2 Close Request File: 2.065492000 0.000121000 52529 microsoft-ds
169 2.065813000 10.0.100.90 -> 10.0.100.9 SMB2 Close Response 2.065813000 0.000321000 microsoft-ds 52529
170 2.065961000 10.0.100.9 -> 10.0.100.90 SMB2 Create Request File: @ 2.065961000 0.000148000 52529 microsoft-ds
171 2.066310000 10.0.100.90 -> 10.0.100.9 SMB2 Create Response File: 2.066310000 0.000349000 microsoft-ds 52529
Without the attached patch and the shadow_copy2 module, Samba returns that that
a directory with the @GMT name exists, and that seems to confuse the Windows
client. It continues issuing FIND requests for the snapshot timestamps, and the
"previous versions" dialog on the client displays the timestamps instead of the
directories:
72 6.133792000 10.0.100.9 -> 10.0.100.133 SMB2 Ioctl Request FSCTL_GET_SHADOW_COPY_DATA File: 6.133792000 0.000189000 52523 microsoft-ds
73 6.134517000 10.0.100.133 -> 10.0.100.9 SMB2 Ioctl Response FSCTL_GET_SHADOW_COPY_DATA File: 6.134517000 0.000725000 microsoft-ds 52523
74 6.134659000 10.0.100.9 -> 10.0.100.133 SMB2 Ioctl Request FSCTL_GET_SHADOW_COPY_DATA File: 6.134659000 0.000142000 52523 microsoft-ds
75 6.135322000 10.0.100.133 -> 10.0.100.9 SMB2 Ioctl Response FSCTL_GET_SHADOW_COPY_DATA File: 6.135322000 0.000663000 microsoft-ds 52523
76 6.135478000 10.0.100.9 -> 10.0.100.133 SMB2 GetInfo Request FILE_INFO/SMB2_FILE_EA_INFO File: 6.135478000 0.000156000 52523 microsoft-ds
77 6.135969000 10.0.100.133 -> 10.0.100.9 SMB2 GetInfo Response 6.135969000 0.000491000 microsoft-ds 52523
78 6.136164000 10.0.100.9 -> 10.0.100.133 SMB2 Ioctl Request FSCTL_GET_REPARSE_POINT File: 6.136164000 0.000195000 52523 microsoft-ds
79 6.136580000 10.0.100.133 -> 10.0.100.9 SMB2 Ioctl Response, Error: STATUS_NOT_A_REPARSE_POINT 6.136580000 0.000416000 microsoft-ds 52523
80 6.136826000 10.0.100.9 -> 10.0.100.133 SMB2 Ioctl Request FSCTL_GET_REPARSE_POINT File: 6.136826000 0.000246000 52523 microsoft-ds
81 6.137186000 10.0.100.133 -> 10.0.100.9 SMB2 Ioctl Response, Error: STATUS_NOT_A_REPARSE_POINT 6.137186000 0.000360000 microsoft-ds 52523
82 6.137433000 10.0.100.9 -> 10.0.100.133 SMB2 Create Request File: @ 6.137433000 0.000247000 52523 microsoft-ds
83 6.139981000 10.0.100.133 -> 10.0.100.9 SMB2 Create Response File: 6.139981000 0.002548000 microsoft-ds 52523
84 6.140144000 10.0.100.9 -> 10.0.100.133 SMB2 GetInfo Request FILE_INFO/SMB2_FILE_NETWORK_OPEN_INFO File: 6.140144000 0.000163000 52523 microsoft-ds
85 6.140734000 10.0.100.133 -> 10.0.100.9 SMB2 GetInfo Response 6.140734000 0.000590000 microsoft-ds 52523
86 6.140823000 10.0.100.9 -> 10.0.100.133 SMB2 Close Request File: 6.140823000 0.000089000 52523 microsoft-ds
87 6.141326000 10.0.100.133 -> 10.0.100.9 SMB2 Close Response 6.141326000 0.000503000 microsoft-ds 52523
88 6.141929000 10.0.100.9 -> 10.0.100.133 SMB2 Create Request File: 6.141929000 0.000603000 52523 microsoft-ds
89 6.143024000 10.0.100.133 -> 10.0.100.9 SMB2 Create Response File: 6.143024000 0.001095000 microsoft-ds 52523
90 6.146329000 10.0.100.9 -> 10.0.100.133 SMB2 Find Request File: SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: *;Find Request File: SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: * 6.146329000 0.003305000 52523 microsoft-ds
178 6.952212000 10.0.100.133 -> 10.0.100.9 SMB2 Find Response SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: *;Find Response SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: * 6.952212000 0.805883000 microsoft-ds 52523
180 6.953016000 10.0.100.9 -> 10.0.100.133 SMB2 Find Request File: SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: @GMT-2013.08.28-19.28.26 6.953016000 0.000804000 52523 microsoft-ds
182 6.954676000 10.0.100.133 -> 10.0.100.9 SMB2 Find Response SMB2_FIND_ID_BOTH_DIRECTORY_INFO Pattern: @GMT-2013.08.28-19.28.26 6.954676000 0.001660000 microsoft-ds 52523
The best way to fix this seems to be in smb2_find.c. The shadow_copy2 module
only sees a stat call, and cannot decide if the stat legitimate or if it should
be rejected.
--
Christof Schmitt || IBM || SONAS System Development || Tucson, AZ
christof.schmitt at us.ibm.com || +1-520-799-2469 (T/L: 321-2469)
-------------- next part --------------
>From 15cf3e1de3cd26abbd26d001ca6dad7107d76030 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <christof.schmitt at us.ibm.com>
Date: Thu, 29 Aug 2013 19:36:00 +0200
Subject: [PATCH] s3:smb2_find: Return that timestamps do not exist as directories
When a Windows client receives a large directory listing while
querying snapshots, it sends a find request asking for the
timestamp as a directory. A Windows server returns NO_SUCH_FILE,
so make sure Samba returns the same. Otherwise the client will
get confused and display timestamps in the 'previous versions' dialog.
Signed-off-by: Christof Schmitt <christof.schmitt at us.ibm.com>
---
source3/include/smb.h | 3 +++
source3/modules/vfs_shadow_copy2.c | 3 ---
source3/smbd/smb2_find.c | 13 +++++++++++++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/source3/include/smb.h b/source3/include/smb.h
index b6b04a4..1288222 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -567,6 +567,9 @@ Offset Data length.
#define NOTIFY_ACTION_REMOVED_STREAM 7
#define NOTIFY_ACTION_MODIFIED_STREAM 8
+/* timestamp format used in "previous versions" */
+#define GMT_NAME_LEN 24 /* length of a @GMT- name */
+#define GMT_FORMAT "@GMT-%Y.%m.%d-%H.%M.%S"
/* where to find the base of the SMB packet proper */
#define smb_base(buf) (((const char *)(buf))+4)
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 60f9628..aa7e50f 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -107,9 +107,6 @@
#include <ccan/hash/hash.h>
#include "util_tdb.h"
-#define GMT_NAME_LEN 24 /* length of a @GMT- name */
-#define GMT_FORMAT "@GMT-%Y.%m.%d-%H.%M.%S"
-
static bool shadow_copy2_find_slashes(TALLOC_CTX *mem_ctx, const char *str,
size_t **poffsets,
unsigned *pnum_offsets)
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index c2c0559..c39a35d 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -224,6 +224,8 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
uint32_t dirtype = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY;
bool dont_descend = false;
bool ask_sharemode = true;
+ struct tm tm;
+ char *p;
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_find_state);
@@ -259,6 +261,17 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
+ p = strptime(in_file_name, GMT_FORMAT, &tm);
+ if ((p != NULL) && (*p =='\0')) {
+ /*
+ * Bogus find that asks for a shadow copy timestamp as a
+ * directory. The correct response is that it does not exist as
+ * a directory.
+ */
+ tevent_req_nterror(req, NT_STATUS_NO_SUCH_FILE);
+ return tevent_req_post(req, ev);
+ }
+
if (in_output_buffer_length > smb2req->sconn->smb2.max_trans) {
DEBUG(2,("smbd_smb2_find_send: "
"client ignored max trans:%s: 0x%08X: 0x%08X\n",
--
1.7.1
More information about the samba-technical
mailing list