[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