From 4ee4a7e96e71cee27c30d23610a7f83d968a8ba0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2013 15:55:51 -0800 Subject: [PATCH] s3-client: smbclient shows no error if deleting a directory with del failed BUG: https://bugzilla.samba.org/show_bug.cgi?id=10260 In SMB1 the server filters by attribute requested, in SMB2 there is no attribute sent. Emulate this on the client to provide the same ABI to callers. In SMB1 the server returns NT_STATUS_NO_SUCH_FILE if FindFirst finds no files. Emulate this on the client. Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Thu Nov 14 21:23:07 CET 2013 on sn-devel-104 --- source3/libsmb/cli_smb2_fnum.c | 29 ++++++++++++++++++++++++++--- source3/libsmb/cli_smb2_fnum.h | 1 + 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 202000fbbf5..d10e1d274c4 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 00686866361..a5cae25a2ba 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 ed970cd896e..3080fb883dd 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(); -- 2.11.4.GIT