From 135aca21ff01dcfa4c347366260597bcfd16f94b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2013 15:17:26 -0800 Subject: [PATCH 1/3] s3-smbd: smbclient shows no error if deleting a directory with del failed BUG: https://bugzilla.samba.org/show_bug.cgi?id=10260 Remove unneeded conn argument to dir_check_ftype(). Move to correct uint32_t types. Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider (cherry picked from commit 7d8e22c7c1cf0041fa638f3bb345e00fc339486b) --- source3/smbd/dir.c | 6 +++--- source3/smbd/proto.h | 2 +- source3/smbd/reply.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index d99eec2..6b7cce2 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -966,9 +966,9 @@ struct dptr_struct *dptr_fetch_lanman2(struct smbd_server_connection *sconn, Check that a file matches a particular file type. ****************************************************************************/ -bool dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) +bool dir_check_ftype(uint32_t mode, uint32_t dirtype) { - uint32 mask; + uint32_t mask; /* Check the "may have" search bits. */ if (((mode & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)) != 0) @@ -1106,7 +1106,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, continue; } - if (!dir_check_ftype(conn, mode, dirtype)) { + if (!dir_check_ftype(mode, dirtype)) { DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n", fname, (unsigned int)mode, (unsigned int)dirtype)); TALLOC_FREE(dname); diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 9c76609..91ef3ed 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -218,7 +218,7 @@ struct dptr_struct *dptr_fetch(struct smbd_server_connection *sconn, char *buf,int *num); struct dptr_struct *dptr_fetch_lanman2(struct smbd_server_connection *sconn, int dptr_num); -bool dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype); +bool dir_check_ftype(uint32_t mode, uint32_t dirtype); bool get_dir_entry(TALLOC_CTX *ctx, struct dptr_struct *dirptr, const char *mask, diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 2ae3ff4..03c8414 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2655,7 +2655,7 @@ static NTSTATUS do_unlink(connection_struct *conn, return NT_STATUS_NO_SUCH_FILE; } - if (!dir_check_ftype(conn, fattr, dirtype)) { + if (!dir_check_ftype(fattr, dirtype)) { if (fattr & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } -- 1.8.4.1 From f14953badb197c7cecb3f99e0d2b7756f5d45792 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2013 15:32:42 -0800 Subject: [PATCH 2/3] s3-lib: smbclient shows no error if deleting a directory with del failed BUG: https://bugzilla.samba.org/show_bug.cgi?id=10260 Move dir_check_ftype() to util.c Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider (cherry picked from commit fc611dd6e849537aa4817504275cdbf48f6f1e79) --- source3/include/proto.h | 1 + source3/lib/util.c | 42 ++++++++++++++++++++++++++++++++++++++++++ source3/smbd/dir.c | 26 -------------------------- source3/smbd/proto.h | 1 - 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index acf013b..ddf3fab 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -480,6 +480,7 @@ bool map_open_params_to_ntcreate(const char *smb_base_fname, uint32 *pcreate_options, uint32_t *pprivate_flags); struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok); +bool dir_check_ftype(uint32_t mode, uint32_t dirtype); void init_modules(void); /* The following definitions come from lib/util_builtin.c */ diff --git a/source3/lib/util.c b/source3/lib/util.c index 5168092..551beab 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2393,3 +2393,45 @@ struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct securi } return cpy; } + +/**************************************************************************** + Check that a file matches a particular file type. +****************************************************************************/ + +bool dir_check_ftype(uint32_t mode, uint32_t dirtype) +{ + uint32_t mask; + + /* Check the "may have" search bits. */ + if (((mode & ~dirtype) & + (FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_DIRECTORY)) != 0) { + return false; + } + + /* Check the "must have" bits, + which are the may have bits shifted eight */ + /* If must have bit is set, the file/dir can + not be returned in search unless the matching + file attribute is set */ + mask = ((dirtype >> 8) & (FILE_ATTRIBUTE_DIRECTORY| + FILE_ATTRIBUTE_ARCHIVE| + FILE_ATTRIBUTE_READONLY| + FILE_ATTRIBUTE_HIDDEN| + FILE_ATTRIBUTE_SYSTEM)); /* & 0x37 */ + if(mask) { + if((mask & (mode & (FILE_ATTRIBUTE_DIRECTORY| + FILE_ATTRIBUTE_ARCHIVE| + FILE_ATTRIBUTE_READONLY| + FILE_ATTRIBUTE_HIDDEN| + FILE_ATTRIBUTE_SYSTEM))) == mask) { + /* check if matching attribute present */ + return true; + } else { + return false; + } + } + + return true; +} diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 6b7cce2..8fa320b 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -962,32 +962,6 @@ struct dptr_struct *dptr_fetch_lanman2(struct smbd_server_connection *sconn, return(dptr); } -/**************************************************************************** - Check that a file matches a particular file type. -****************************************************************************/ - -bool dir_check_ftype(uint32_t mode, uint32_t dirtype) -{ - uint32_t mask; - - /* Check the "may have" search bits. */ - if (((mode & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)) != 0) - return False; - - /* Check the "must have" bits, which are the may have bits shifted eight */ - /* If must have bit is set, the file/dir can not be returned in search unless the matching - file attribute is set */ - mask = ((dirtype >> 8) & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)); /* & 0x37 */ - if(mask) { - if((mask & (mode & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) == mask) /* check if matching attribute present */ - return True; - else - return False; - } - - return True; -} - static bool mangle_mask_match(connection_struct *conn, const char *filename, const char *mask) diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 91ef3ed..1e0d06d 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -218,7 +218,6 @@ struct dptr_struct *dptr_fetch(struct smbd_server_connection *sconn, char *buf,int *num); struct dptr_struct *dptr_fetch_lanman2(struct smbd_server_connection *sconn, int dptr_num); -bool dir_check_ftype(uint32_t mode, uint32_t dirtype); bool get_dir_entry(TALLOC_CTX *ctx, struct dptr_struct *dirptr, const char *mask, -- 1.8.4.1 From 4016f2c9f5386acfb3c06577ffa7ea65bbdb18b3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2013 15:55:51 -0800 Subject: [PATCH 3/3] 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 (cherry picked from commit 4ee4a7e96e71cee27c30d23610a7f83d968a8ba0) --- 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 202000f..d10e1d2 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 0068686..a5cae25 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 ed970cd..3080fb8 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(); -- 1.8.4.1