summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-05-08 21:31:49 -0700
committerStefan Metzmacher <metze@samba.org>2014-05-09 23:10:07 +0200
commitb2ce2441a35ed68c39791168217d159352b5143c (patch)
tree173c6790a854d2cee5d190f90231c7386998ebbd
parent3d8ba9b34e34c1f3e0c1c231d6b772994b45eeaf (diff)
downloadsamba-b2ce2441a35ed68c39791168217d159352b5143c.tar.gz
samba-b2ce2441a35ed68c39791168217d159352b5143c.tar.xz
samba-b2ce2441a35ed68c39791168217d159352b5143c.zip
s3: libsmbclient: Work around bugs in SLES cifsd and Apple smbx SMB1 servers.
SLES's cifsd and Apple's smbx do not correctly handle FILE_NON_DIRECTORY_FILE which prevents recursive copies in gvfs from working correctly [1] since GVFS tries to open the directory, expecting ENOTDIR, but it suceeds and appears as a zero byte file. This fix adds code to the cli_open() open code that checks if CreateOptions was requested with FILE_NON_DIRECTORY_FILE set, and if the attributes returned include FILE_ATTRIBUTE_DIRECTORY we synchronously close the file handle just opened, and return NT_STATUS_FILE_IS_A_DIRECTORY to the caller. Depends on the previous API update to cli_ntcreate() to add returned attributes. Fixes bug #10587 - Opening directories on SLES's cifsd and Apple's smbx succeeds. https://bugzilla.samba.org/show_bug.cgi?id=10587 Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r--source3/libsmb/clifile.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 7f562a8061a..70b769d1bd8 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -2387,6 +2387,7 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags,
unsigned int openfn = 0;
unsigned int dos_deny = 0;
uint32_t access_mask, share_mode, create_disposition, create_options;
+ struct smb_create_returns cr;
/* Do the initial mapping into OpenX parameters. */
if (flags & O_CREAT) {
@@ -2468,7 +2469,7 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags,
create_options,
0,
pfnum,
- NULL);
+ &cr);
/* Try and cope will all varients of "we don't do this call"
and fall back to openX. */
@@ -2485,6 +2486,25 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags,
goto try_openx;
}
+ if (NT_STATUS_IS_OK(status) &&
+ (create_options & FILE_NON_DIRECTORY_FILE) &&
+ (cr.file_attributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ /*
+ * Some (broken) servers return a valid handle
+ * for directories even if FILE_NON_DIRECTORY_FILE
+ * is set. Just close the handle and set the
+ * error explicitly to NT_STATUS_FILE_IS_A_DIRECTORY.
+ */
+ status = cli_close(cli, *pfnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ status = NT_STATUS_FILE_IS_A_DIRECTORY;
+ /* Set this so libsmbclient can retrieve it. */
+ cli->raw_status = status;
+ }
+
return status;
try_openx: