summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Prouty <tprouty@samba.org>2009-08-06 15:53:33 -0700
committerTim Prouty <tprouty@samba.org>2009-08-06 17:07:50 -0700
commit457191e9f396898b8a511cf860f24986f36fd879 (patch)
treea963611eeb986e120bdbd86c91930efeb79886d2
parent09e9904f18634b135944f466c48c4be1a43b4272 (diff)
downloadsamba-457191e9f396898b8a511cf860f24986f36fd879.tar.gz
samba-457191e9f396898b8a511cf860f24986f36fd879.tar.bz2
samba-457191e9f396898b8a511cf860f24986f36fd879.zip
s3: Fix a bug in renames of directories
Recently code was added to match windows semantics of denying the rename of a directory if there are open files underneath it. This does partly match windows semantics, but it turns out the rename should be allowed if the open file handle is for the directory being renamed, or for a stream on the directory being renamed. This patch refines the check to better follow these rename semantics.
-rw-r--r--source3/smbd/files.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index a170f774fe..146d809738 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -404,14 +404,15 @@ bool file_find_subpath(files_struct *dir_fsp)
{
files_struct *fsp;
size_t dlen;
- char *d_fullname;
+ char *d_fullname = NULL;
+ bool ret = false;
d_fullname = talloc_asprintf(talloc_tos(), "%s/%s",
dir_fsp->conn->connectpath,
dir_fsp->fsp_name->base_name);
if (!d_fullname) {
- return false;
+ goto out;
}
dlen = strlen(d_fullname);
@@ -429,15 +430,27 @@ bool file_find_subpath(files_struct *dir_fsp)
fsp->fsp_name->base_name);
if (strnequal(d_fullname, d1_fullname, dlen)) {
- TALLOC_FREE(d_fullname);
+ int d1_len = strlen(d1_fullname);
+
+ /*
+ * If the open file is a second file handle to the
+ * same name or is a stream on the original file, then
+ * don't return true.
+ */
+ if (d1_len == dlen) {
+ TALLOC_FREE(d1_fullname);
+ continue;
+ }
+
TALLOC_FREE(d1_fullname);
- return true;
+ ret = true;
+ goto out;
}
TALLOC_FREE(d1_fullname);
}
-
+ out:
TALLOC_FREE(d_fullname);
- return false;
+ return ret;
}
/****************************************************************************