From c6e9b3084db932ae473fb087bcf08f14d92443dd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Jun 2020 13:55:10 -0700 Subject: [PATCH 1/7] s3: libsmb: Info level SMB2_FIND_ID_BOTH_DIRECTORY_INFO encodes attibutes as a uint32, not a uint8. Fix the SMB2 parsing code. Cast to a uint16_t for now after pulling the information as finfo->mode is currently only 16 bits. We will need this to detect FILE_ATTRIBUTE_REPARSE_POINT in a later commit. Signed-off-by: Jeremy Allison --- source3/libsmb/cli_smb2_fnum.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index 8c8b33f49ed..4edeefc117d 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -1236,7 +1236,8 @@ static NTSTATUS parse_finfo_id_both_directory_info(uint8_t *dir_data, finfo->ctime_ts = interpret_long_date((const char *)dir_data + 32); finfo->size = IVAL2_TO_SMB_BIG_UINT(dir_data + 40, 0); finfo->allocated_size = IVAL2_TO_SMB_BIG_UINT(dir_data + 48, 0); - finfo->mode = CVAL(dir_data + 56, 0); + /* NB. We need to enlarge finfo->mode to be 32-bits. */ + finfo->mode = (uint16_t)IVAL(dir_data + 56, 0); finfo->ino = IVAL2_TO_SMB_BIG_UINT(dir_data + 96, 0); namelen = IVAL(dir_data + 60,0); if (namelen > (dir_data_length - 104)) { -- 2.20.1 From 854562727f2b4d86d92a8187a5e90bf585193558 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Jun 2020 11:36:03 -0700 Subject: [PATCH 2/7] s3: libsmb: Info level SMB_FIND_FILE_BOTH_DIRECTORY_INFO encodes attibutes as a uint32, not a uint8. Cast to a uint16_t for now after pulling the information as finfo->mode is currently only 16 bits. We will need this to detect FILE_ATTRIBUTE_REPARSE_POINT in a later commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391 Signed-off-by: Jeremy Allison --- source3/libsmb/clilist.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f9444bc401c..a78678f4532 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -257,7 +257,8 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); + /* NB. We need to enlarge finfo->mode to be 32-bits. */ + finfo->mode = (uint16_t)IVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; -- 2.20.1 From 460284cd50f21b04a4938b9bc7f5cbd6febd19a9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Jun 2020 12:01:13 -0700 Subject: [PATCH 3/7] s3: libsmb: Info level SMB_FIND_INFO_STANDARD encodes attibutes as a uint16, not a uint8. We will need this to detect FILE_ATTRIBUTE_REPARSE_POINT in a later commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391 Signed-off-by: Jeremy Allison --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a78678f4532..deeb794ffe5 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -152,7 +152,7 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, finfo->mtime_ts = convert_time_t_to_timespec( make_unix_date2(p+12, smb1cli_conn_server_time_zone(cli->conn))); finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); + finfo->mode = SVAL(p,24); len = CVAL(p, 26); p += 27; if (recv_flags2 & FLAGS2_UNICODE_STRINGS) { -- 2.20.1 From bca0cf8ccdcd553442d91ca187c8264d33de7ffd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Jun 2020 11:33:13 -0700 Subject: [PATCH 4/7] s3: libsmb: Info level SMB_FIND_EA_SIZE encodes attibutes as a uint16, not a uint8. We will need this to detect FILE_ATTRIBUTE_REPARSE_POINT in a later commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391 Signed-off-by: Jeremy Allison --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index deeb794ffe5..4a32fc45fa6 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -211,7 +211,7 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, finfo->mtime_ts = convert_time_t_to_timespec( make_unix_date2(p+12, smb1cli_conn_server_time_zone(cli->conn))); finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); + finfo->mode = SVAL(p,24); len = CVAL(p, 30); p += 31; /* check for unisys! */ -- 2.20.1 From 311eb6cd28e2614100a32ac20554db9da431b5fc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Jun 2020 12:08:17 -0700 Subject: [PATCH 5/7] s3: torture: Add a MSDFS-ATTRIBUTE test. Framework to drive comes next. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391 Signed-off-by: Jeremy Allison --- source3/torture/torture.c | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index f07a0adf115..56258d3d2ad 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -11405,6 +11405,81 @@ static bool run_large_readx(int dummy) return correct; } +static NTSTATUS msdfs_attribute_list_fn(const char *mnt, + struct file_info *finfo, + const char *mask, + void *private_data) +{ + uint16_t *p_mode = (uint16_t *)private_data; + + if (strequal(finfo->name, test_filename)) { + *p_mode = finfo->mode; + } + + return NT_STATUS_OK; +} + +static bool run_msdfs_attribute(int dummy) +{ + static struct cli_state *cli; + bool correct = false; + uint16_t mode = 0; + NTSTATUS status; + + printf("Starting MSDFS-ATTRIBUTE test\n"); + + if (test_filename == NULL || test_filename[0] == '\0') { + printf("MSDFS-ATTRIBUTE test " + "needs -f filename-of-msdfs-link\n"); + return false; + } + + /* + * NB. We use torture_open_connection_flags() not + * torture_open_connection() as the latter forces + * SMB1. + */ + if (!torture_open_connection_flags(&cli, 0, 0)) { + return false; + } + + smbXcli_conn_set_sockopt(cli->conn, sockops); + + status = cli_list(cli, + "*", + FILE_ATTRIBUTE_DIRECTORY, + msdfs_attribute_list_fn, + &mode); + + if (!NT_STATUS_IS_OK(status)) { + printf("cli_list failed with %s\n", + nt_errstr(status)); + goto out; + } + if ((mode & FILE_ATTRIBUTE_REPARSE_POINT) == 0) { + printf("file %s should have " + "FILE_ATTRIBUTE_REPARSE_POINT set. attr = 0x%x\n", + test_filename, + (unsigned int)mode); + goto out; + } + + if ((mode & FILE_ATTRIBUTE_DIRECTORY) == 0) { + printf("file %s should have " + "FILE_ATTRIBUTE_DIRECTORY set. attr = 0x%x\n", + test_filename, + (unsigned int)mode); + goto out; + } + + correct = true; + + out: + + torture_close_connection(cli); + return correct; +} + static bool run_cli_echo(int dummy) { struct cli_state *cli; @@ -14539,6 +14614,10 @@ static struct { .name = "LARGE_READX", .fn = run_large_readx, }, + { + .name = "MSDFS-ATTRIBUTE", + .fn = run_msdfs_attribute, + }, { .name = "NTTRANS-CREATE", .fn = run_nttrans_create, -- 2.20.1 From 3f261fa1be84449cd88aad9173a4eb30d462333c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Jun 2020 13:45:28 -0700 Subject: [PATCH 6/7] s3: torture: Add test for getting attibutes on an MSDFS link. Mark as knownfail for now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391 Signed-off-by: Jeremy Allison --- selftest/knownfail.d/msdfs-attr | 3 +++ source3/selftest/tests.py | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 selftest/knownfail.d/msdfs-attr diff --git a/selftest/knownfail.d/msdfs-attr b/selftest/knownfail.d/msdfs-attr new file mode 100644 index 00000000000..a8a77ec2719 --- /dev/null +++ b/selftest/knownfail.d/msdfs-attr @@ -0,0 +1,3 @@ +samba3.smbtorture_s3.smb2.MSDFS-ATTRIBUTE +samba3.smbtorture_s3.smb1.MSDFS-ATTRIBUTE + diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 72bca263c0b..005d6f453b1 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -162,6 +162,33 @@ plantestsuite("samba3.smbtorture_s3.hidenewfiles(simpleserver)", "", "-l $LOCAL_PATH"]) +# +# MSDFS attribute tests. +# +plantestsuite("samba3.smbtorture_s3.smb2.MSDFS-ATTRIBUTE", + "fileserver", + [os.path.join(samba3srcdir, + "script/tests/test_smbtorture_s3.sh"), + 'MSDFS-ATTRIBUTE', + '//$SERVER_IP/msdfs-share', + '$USERNAME', + '$PASSWORD', + smbtorture3, + "-mSMB2", + "-f msdfs-src1"]) + +plantestsuite("samba3.smbtorture_s3.smb1.MSDFS-ATTRIBUTE", + "fileserver", + [os.path.join(samba3srcdir, + "script/tests/test_smbtorture_s3.sh"), + 'MSDFS-ATTRIBUTE', + '//$SERVER_IP/msdfs-share', + '$USERNAME', + '$PASSWORD', + smbtorture3, + "-mNT1", + "-f msdfs-src1"]) + shares = [ "vfs_aio_pthread_async_dosmode_default1", "vfs_aio_pthread_async_dosmode_default2", -- 2.20.1 From e7cae7bb21b1394bd73821d4babf5344823bebf7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Jun 2020 14:09:54 -0700 Subject: [PATCH 7/7] s3: msdfs: Fix missing struct stat return on msdfs links by doing an LSTAT call. This (unfortunately) re-exposes the fact the msdfs links are symlinks, bit fixing this correctly requires a VFS ABI change which we can't do for a released stream. Remove the knownfail.d/msdfs-attr file. Everything now passes. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391 Signed-off-by: Jeremy Allison --- selftest/knownfail.d/msdfs-attr | 3 --- source3/smbd/msdfs.c | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 selftest/knownfail.d/msdfs-attr diff --git a/selftest/knownfail.d/msdfs-attr b/selftest/knownfail.d/msdfs-attr deleted file mode 100644 index a8a77ec2719..00000000000 --- a/selftest/knownfail.d/msdfs-attr +++ /dev/null @@ -1,3 +0,0 @@ -samba3.smbtorture_s3.smb2.MSDFS-ATTRIBUTE -samba3.smbtorture_s3.smb1.MSDFS-ATTRIBUTE - diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index cc32ebc9d29..bbf8aebb9b3 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -633,6 +633,12 @@ bool is_msdfs_link(connection_struct *conn, smb_fname, NULL, NULL); + if (NT_STATUS_IS_OK(status)) { + int ret = SMB_VFS_LSTAT(conn, smb_fname); + if (ret < 0) { + status = map_nt_error_from_unix(errno); + } + } return (NT_STATUS_IS_OK(status)); } -- 2.20.1