diff options
-rw-r--r-- | source3/libsmb/cli_smb2_fnum.c | 29 | ||||
-rw-r--r-- | source3/libsmb/cli_smb2_fnum.h | 1 | ||||
-rw-r--r-- | source3/libsmb/clilist.c | 2 |
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(); |