We are seeing timed event problems with chdir that suggest event ordering and chdir issues in Samba 3.5.15 and possibly other versions of Samba

Volker Lendecke Volker.Lendecke at SerNet.DE
Tue Jun 12 03:12:18 MDT 2012


On Mon, Jun 11, 2012 at 01:28:36PM -0700, Richard Sharpe wrote:
> We are seeing issues in one of our VFSes where relative path names are
> causing confusion. We are capturing chdir requests in the VFS and
> saving the path and if we see a relative path name we prepend the
> captured path name.

Possibly you need the attached patch (on top of v3-6-test).
It is completely untested, but I can perfectly see a problem
in this code path.

With master, the implementation has changed significantly,
so this particular problem should not happen anymore.

With best regards,

Volker Lendecke

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
>From c7ce96d81c36c180341da25c317f85c6a3d1ea11 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 12 Jun 2012 09:01:29 +0200
Subject: [PATCH 1/2] s3: Factor out notify_parent_dir

---
 source3/smbd/notify.c |   38 ++++++++++++++++++++++++--------------
 1 Datei geändert, 24 Zeilen hinzugefügt(+), 14 Zeilen entfernt(-)

diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index 24385c9..702671c 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -345,28 +345,38 @@ void remove_pending_change_notify_requests_by_fid(files_struct *fsp,
 	}
 }
 
-void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
-		  const char *path)
+static void notify_parent_dir(connection_struct *conn,
+			      uint32 action, uint32 filter,
+			      const char *path)
 {
-	char *fullpath;
+	struct smb_filename smb_fname_parent = { 0, };
 	char *parent;
 	const char *name;
 
-	if (path[0] == '.' && path[1] == '/') {
-		path += 2;
+	if (!parent_dirname(talloc_tos(), path, &parent, &name)) {
+		return;
+	}
+	smb_fname_parent.base_name = parent;
+
+	if (SMB_VFS_STAT(conn, &smb_fname_parent) == -1) {
+		goto done;
 	}
-	if (parent_dirname(talloc_tos(), path, &parent, &name)) {
-		struct smb_filename smb_fname_parent;
+	notify_onelevel(conn->notify_ctx, action, filter,
+			SMB_VFS_FILE_ID_CREATE(conn, &smb_fname_parent.st),
+			name);
+done:
+	TALLOC_FREE(parent);
+}
 
-		ZERO_STRUCT(smb_fname_parent);
-		smb_fname_parent.base_name = parent;
+void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
+		  const char *path)
+{
+	char *fullpath;
 
-		if (SMB_VFS_STAT(conn, &smb_fname_parent) != -1) {
-			notify_onelevel(conn->notify_ctx, action, filter,
-			    SMB_VFS_FILE_ID_CREATE(conn, &smb_fname_parent.st),
-			    name);
-		}
+	if (path[0] == '.' && path[1] == '/') {
+		path += 2;
 	}
+	notify_parent_dir(conn, action, filter, path);
 
 	fullpath = talloc_asprintf(talloc_tos(), "%s/%s", conn->connectpath,
 				   path);
-- 
1.7.10.3


>From 092fe32dc9b65df7b8c303a26d7c7bcabc505620 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 12 Jun 2012 09:09:57 +0200
Subject: [PATCH 2/2] s3: Do a ChDir for notify_onelevel

---
 source3/smbd/notify.c |   13 ++++++++++++-
 1 Datei geändert, 12 Zeilen hinzugefügt(+), 1 Zeile entfernt(-)

diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index 702671c..a653ab9 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -352,18 +352,29 @@ static void notify_parent_dir(connection_struct *conn,
 	struct smb_filename smb_fname_parent = { 0, };
 	char *parent;
 	const char *name;
+	char *oldwd;
 
 	if (!parent_dirname(talloc_tos(), path, &parent, &name)) {
 		return;
 	}
 	smb_fname_parent.base_name = parent;
 
-	if (SMB_VFS_STAT(conn, &smb_fname_parent) == -1) {
+	oldwd = vfs_GetWd(parent, conn);
+	if (oldwd == NULL) {
+		goto done;
+	}
+	if (vfs_ChDir(conn, conn->connectpath) == -1) {
 		goto done;
 	}
+
+	if (SMB_VFS_STAT(conn, &smb_fname_parent) == -1) {
+		goto chdir_done;
+	}
 	notify_onelevel(conn->notify_ctx, action, filter,
 			SMB_VFS_FILE_ID_CREATE(conn, &smb_fname_parent.st),
 			name);
+chdir_done:
+	vfs_ChDir(conn, oldwd);
 done:
 	TALLOC_FREE(parent);
 }
-- 
1.7.10.3



More information about the samba-technical mailing list