summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source3/libsmb/cli_smb2_fnum.c29
-rw-r--r--source3/libsmb/cli_smb2_fnum.h1
-rw-r--r--source3/libsmb/clilist.c2
3 files changed, 28 insertions, 4 deletions
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 202000fbbf..d10e1d274c 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -486,6 +486,7 @@ static bool windows_parent_dirname(TALLOC_CTX *mem_ctx,
NTSTATUS cli_smb2_list(struct cli_state *cli,
const char *pathname,
+ uint16_t attribute,
NTSTATUS (*fn)(const char *,
struct file_info *,
const char *,
@@ -497,6 +498,7 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
char *parent_dir = NULL;
const char *mask = NULL;
struct smb2_hnd *ph = NULL;
+ bool processed_file = false;
TALLOC_CTX *frame = talloc_stackframe();
TALLOC_CTX *subframe = NULL;
@@ -590,13 +592,26 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
goto fail;
}
- status = fn(cli->dfs_mountpoint,
+ if (dir_check_ftype((uint32_t)finfo->mode,
+ (uint32_t)attribute)) {
+ /*
+ * Only process if attributes match.
+ * On SMB1 server does this, so on
+ * SMB2 we need to emulate in the
+ * client.
+ *
+ * https://bugzilla.samba.org/show_bug.cgi?id=10260
+ */
+ processed_file = true;
+
+ status = fn(cli->dfs_mountpoint,
finfo,
pathname,
state);
- if (!NT_STATUS_IS_OK(status)) {
- break;
+ if (!NT_STATUS_IS_OK(status)) {
+ break;
+ }
}
TALLOC_FREE(finfo);
@@ -616,6 +631,14 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
status = NT_STATUS_OK;
}
+ if (NT_STATUS_IS_OK(status) && !processed_file) {
+ /*
+ * In SMB1 findfirst returns NT_STATUS_NO_SUCH_FILE
+ * if no files match. Emulate this in the client.
+ */
+ status = NT_STATUS_NO_SUCH_FILE;
+ }
+
fail:
if (fnum != 0xffff) {
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index 0068686636..a5cae25a2b 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -42,6 +42,7 @@ NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dirname);
NTSTATUS cli_smb2_unlink(struct cli_state *cli,const char *fname);
NTSTATUS cli_smb2_list(struct cli_state *cli,
const char *pathname,
+ uint16_t attribute,
NTSTATUS (*fn)(const char *,
struct file_info *,
const char *,
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index ed970cd896..3080fb883d 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -942,7 +942,7 @@ NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint16 attribute,
uint16_t info_level;
if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
- return cli_smb2_list(cli, mask, fn, state);
+ return cli_smb2_list(cli, mask, attribute, fn, state);
}
frame = talloc_stackframe();