From d91f56278ea1f797aca8361d13831ec7960f4d73 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 14 Jun 2012 12:07:33 -0700 Subject: [PATCH] Fix for bug #8998 - Notify code can miss a ChDir. --- source3/smbd/notify.c | 55 ++++++++++++++++++++++++++++++++++++------------ 1 files changed, 41 insertions(+), 14 deletions(-) diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index a53f3fb..1f664d0 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -366,28 +366,55 @@ 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; char *parent; const char *name; + char *oldwd; - if (path[0] == '.' && path[1] == '/') { - path += 2; + if (!parent_dirname(talloc_tos(), path, &parent, &name)) { + DEBUG(1, ("Can't get parent dirname, giving up\n")); + return; } - if (parent_dirname(talloc_tos(), path, &parent, &name)) { - struct smb_filename smb_fname_parent; - ZERO_STRUCT(smb_fname_parent); - smb_fname_parent.base_name = parent; + ZERO_STRUCT(smb_fname_parent); + smb_fname_parent.base_name = parent; - 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); - } + oldwd = vfs_GetWd(parent, conn); + if (oldwd == NULL) { + DEBUG(1, ("vfs_GetWd failed!\n")); + goto done; + } + if (vfs_ChDir(conn, conn->connectpath) == -1) { + DEBUG(1, ("Could not chdir to connect path!\n")); + 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); +} + +void notify_fname(connection_struct *conn, uint32 action, uint32 filter, + const char *path) +{ + char *fullpath = NULL; + + 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.7.3