The branch, master has been updated
via 6d71edab5a7 smbd: use fsctl_get_reparse_point() in
smb3_file_posix_information_init()
via b51a827e474 smbd: move calling fsctl_get_reparse_tag() into
smb3_file_posix_information_init()
via a10755881e7 smbd: simplify smb3_file_posix_information_init()
via 306d4e7fffe smbd: fix DOS attributes for reparse points in
fdos_mode()
via 21ef00d0f00 tests: test POSIX file type on reparse point
via 26e81055183 tests: check reparse tag and POSIX file type from
query-file with POSIX infolevel
via 44a2458ca4f tests: fix test teardown/cleanup of
test_create_reparse_directory()
via 8c468c6e5c8 tests: prepare reparsepoints.py for using POSIX on the
SMB2 connection
via d46bfc5d50e tests: move wire_mode_to_unix() to libsmb.py
via 02cc280710d pylibsmb: implement getinfo level
FSCC_FILE_POSIX_INFORMATION
via 239d8f463bf smbd: rename SMB2_FS_POSIX_INFORMATION to
FSCC_FS_POSIX_INFORMATION
via 27198998eda smbd: rename SMB2_FILE_POSIX_INFORMATION to
FSCC_FILE_POSIX_INFORMATION
via 8eccfbea7dc smbd: use NT_PASSTHROUGH_OFFSET in a few places
from a882e861047 gitlab-ci: Fix building debian 32bit images
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 6d71edab5a70ab5c62e08ed5a6bb000259e18f21
Author: Ralph Boehme <[email protected]>
Date: Wed Nov 27 14:35:32 2024 +0100
smbd: use fsctl_get_reparse_point() in smb3_file_posix_information_init()
This allows returning the POSIX type info from fsctl_get_reparse_point().
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Autobuild-User(master): Ralph Böhme <[email protected]>
Autobuild-Date(master): Wed Nov 27 19:32:45 UTC 2024 on atb-devel-224
commit b51a827e4745f3c330fa24fd876ee190b0519e67
Author: Ralph Boehme <[email protected]>
Date: Wed Nov 27 15:27:14 2024 +0100
smbd: move calling fsctl_get_reparse_tag() into
smb3_file_posix_information_init()
This already fixes SMB2-GETINFO with POSIX infolevel to return the reparse
tag
of reparse points.
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit a10755881e7ab3292a688ca9ccf205bf0dca6070
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 07:49:15 2024 +0100
smbd: simplify smb3_file_posix_information_init()
The dos attributes are already setup by fdos_mode(). Still assert
FILE_ATTRIBUTE_REPARSE_POINT is correctly set just in case.
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 306d4e7fffe3a0b2311cbf5c3cc658af5660cb5f
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 18:21:32 2024 +0100
smbd: fix DOS attributes for reparse points in fdos_mode()
Reparse have only FILE_ATTRIBUTE_REPARSE_POINT set, but never
FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_DIRECTORY at the same time.
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 21ef00d0f00fa2852e41019a796005c1a06ae418
Author: Ralph Boehme <[email protected]>
Date: Wed Nov 27 15:14:32 2024 +0100
tests: test POSIX file type on reparse point
Create a symlink reparse point over SMB2. Then query file info over SMB2 and
check the POSIX file type is correctly assigned in the POSIX info levels.
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 26e81055183a3cb1e02138de18bc61f5dcd914fb
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 14:54:29 2024 +0100
tests: check reparse tag and POSIX file type from query-file with POSIX
infolevel
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 44a2458ca4f02aece3ef7a3c98056bdcd78db4b9
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 17:06:06 2024 +0100
tests: fix test teardown/cleanup of test_create_reparse_directory()
This kept failing in a local make test not being able to cleanup the test
directory in the *subsequent* test test_create_reparse_nonempty_directory().
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 8c468c6e5c8bb3f1b8e8b2d65a5a68db158a03c7
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 14:53:45 2024 +0100
tests: prepare reparsepoints.py for using POSIX on the SMB2 connection
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit d46bfc5d50e3d382eec28d09ca92d0b107c0e2db
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 14:52:52 2024 +0100
tests: move wire_mode_to_unix() to libsmb.py
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 02cc280710de1e6d007e19f12701b55854916570
Author: Ralph Boehme <[email protected]>
Date: Fri Nov 22 19:39:22 2024 +0100
pylibsmb: implement getinfo level FSCC_FILE_POSIX_INFORMATION
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 239d8f463bf6a81f7101b86afe7a931a0584bae4
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 20:00:01 2024 +0100
smbd: rename SMB2_FS_POSIX_INFORMATION to FSCC_FS_POSIX_INFORMATION
Streamline the info-level defines. Also get rid of
SMB2_FS_POSIX_INFORMATION_INTERNAL which is not needed for an info-level
that
is exclusive to SMB2.
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 27198998eda788ff0b4790036bb81480ae4319c1
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 19:44:13 2024 +0100
smbd: rename SMB2_FILE_POSIX_INFORMATION to FSCC_FILE_POSIX_INFORMATION
Streamline the info-level defines. Also get rid of
SMB2_FILE_POSIX_INFORMATION_INTERNAL which is not needed for an info-level
that
is exclusive to SMB2.
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
commit 8eccfbea7dc4ab7de7fe41d1a844f1eaaf2f64fd
Author: Ralph Boehme <[email protected]>
Date: Tue Nov 26 19:32:00 2024 +0100
smbd: use NT_PASSTHROUGH_OFFSET in a few places
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
-----------------------------------------------------------------------
Summary of changes:
libcli/smb/smb_unix_ext.h | 2 +-
python/samba/tests/libsmb.py | 8 ++
python/samba/tests/reparsepoints.py | 54 ++++++++++++--
python/samba/tests/smb3unix.py | 7 --
source3/include/trans2.h | 8 +-
source3/libsmb/cli_smb2_fnum.c | 2 +-
source3/libsmb/pylibsmb.c | 125 +++++++++++++++++++++++++++++++
source3/smbd/dosmode.c | 9 ++-
source3/smbd/proto.h | 5 +-
source3/smbd/smb2_getinfo.c | 17 +++--
source3/smbd/smb2_posix.c | 145 ++++++++++++++++++++++++++++++------
source3/smbd/smb2_query_directory.c | 2 +-
source3/smbd/smb2_trans2.c | 35 ++++-----
13 files changed, 346 insertions(+), 73 deletions(-)
Changeset truncated at 500 lines:
diff --git a/libcli/smb/smb_unix_ext.h b/libcli/smb/smb_unix_ext.h
index ca0470672ab..72944d475af 100644
--- a/libcli/smb/smb_unix_ext.h
+++ b/libcli/smb/smb_unix_ext.h
@@ -417,6 +417,6 @@ enum smb_whoami_flags {
#define INFO_LEVEL_IS_UNIX(level) ((((level) >= MIN_UNIX_INFO_LEVEL) && \
((level) <= MAX_UNIX_INFO_LEVEL)) || \
- ((level) == SMB2_FILE_POSIX_INFORMATION_INTERNAL))
+ ((level) == FSCC_FILE_POSIX_INFORMATION))
#endif /* __SMB_UNIX_EXT_H__ */
diff --git a/python/samba/tests/libsmb.py b/python/samba/tests/libsmb.py
index cb632d0e3a7..3ac1b68a59b 100644
--- a/python/samba/tests/libsmb.py
+++ b/python/samba/tests/libsmb.py
@@ -24,6 +24,7 @@ from samba import credentials
from samba import (ntstatus,NTSTATUSError)
import samba.tests
import os
+import stat
class LibsmbTests(samba.tests.TestCase):
@@ -53,3 +54,10 @@ class LibsmbTests(samba.tests.TestCase):
elif not (e.args[0] == ntstatus.NT_STATUS_OBJECT_NAME_NOT_FOUND or
e.args[0] == ntstatus.NT_STATUS_OBJECT_PATH_NOT_FOUND):
raise
+
+ def wire_mode_to_unix(self, wire):
+ mode = libsmb.wire_mode_to_unix(wire)
+ type = stat.S_IFMT(mode)
+ perms = mode & (stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO|
+ stat.S_ISUID|stat.S_ISGID|stat.S_ISVTX)
+ return (type, perms)
diff --git a/python/samba/tests/reparsepoints.py
b/python/samba/tests/reparsepoints.py
index 40d7de3f63b..a5568616021 100644
--- a/python/samba/tests/reparsepoints.py
+++ b/python/samba/tests/reparsepoints.py
@@ -22,9 +22,12 @@ from samba import reparse_symlink
import samba.tests.libsmb
import stat
+def posix_context(mode):
+ return (libsmb.SMB2_CREATE_TAG_POSIX, mode.to_bytes(4, 'little'))
+
class ReparsePoints(samba.tests.libsmb.LibsmbTests):
- def connection(self):
+ def connection(self, posix=False):
share = samba.tests.env_get_var_value("SHARENAME", allow_missing=True)
if not share:
share = "tmp"
@@ -34,6 +37,7 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
share,
self.lp,
self.creds,
+ posix=posix,
force_smb1=smb1)
return conn
@@ -233,10 +237,14 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
err = e.args[0]
if (err != ntstatus.NT_STATUS_ACCESS_DENIED):
raise
+ finally:
+ conn.close(dir_fd)
+ self.clean_file(conn, dirname)
if (err == ntstatus.NT_STATUS_ACCESS_DENIED):
self.fail("Could not set reparse point on directory")
- conn.delete_on_close(fd, 1)
+ conn.close(dir_fd)
+ self.clean_file(conn, dirname)
return
with self.assertRaises(NTSTATUSError) as e:
@@ -397,22 +405,30 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
def do_test_nfs_reparse(self, filename, filetype, nfstype):
"""Test special file reparse tag"""
- smb2 = self.connection()
+ smb2 = self.connection(posix=True)
smb1 = self.connection_posix()
self.clean_file(smb2, filename)
smb1.mknod(filename, filetype | 0o755)
- fd = smb2.create(
+ fd,_,_ = smb2.create_ex(
filename,
DesiredAccess=sec.SEC_FILE_READ_ATTRIBUTE|sec.SEC_STD_DELETE,
CreateOptions=libsmb.FILE_OPEN_REPARSE_POINT,
- CreateDisposition=libsmb.FILE_OPEN)
+ CreateDisposition=libsmb.FILE_OPEN,
+
ShareAccess=(libsmb.FILE_SHARE_READ|libsmb.FILE_SHARE_WRITE|libsmb.FILE_SHARE_DELETE),
+ CreateContexts=[posix_context(0o600)])
smb2.delete_on_close(fd, 1)
info = smb2.qfileinfo(fd, libsmb.FSCC_FILE_ATTRIBUTE_TAG_INFORMATION);
self.assertEqual(info['tag'], libsmb.IO_REPARSE_TAG_NFS)
+ info = smb2.qfileinfo(fd, libsmb.FSCC_FILE_POSIX_INFORMATION);
+ self.assertEqual(info['reparse_tag'], libsmb.IO_REPARSE_TAG_NFS)
+
+ type, perms = self.wire_mode_to_unix(info['perms'])
+ self.assertEqual(type, filetype)
+
reparse = smb2.fsctl(fd, libsmb.FSCTL_GET_REPARSE_POINT, b'', 1024)
(tag, ) = reparse_symlink.get(reparse)
self.assertEqual(tag, nfstype)
@@ -425,6 +441,34 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
"""Test SOCK reparse tag"""
self.do_test_nfs_reparse('sock', stat.S_IFSOCK, 'NFS_SPECFILE_SOCK')
+ def test_reparsepoint_posix_type(self):
+ conn = self.connection(posix=True)
+ filename = 'reparse'
+ self.clean_file(conn, filename)
+
+ fd,_,_ = conn.create_ex(
+ filename,
+ DesiredAccess=sec.SEC_FILE_WRITE_ATTRIBUTE,
+ CreateDisposition=libsmb.FILE_CREATE,
+ CreateContexts=[posix_context(0o600)])
+ b = reparse_symlink.symlink_put("y", "y", 0, 0)
+ conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b, 0)
+ conn.close(fd)
+
+ dirents = conn.list("",
filename,info_level=libsmb.SMB2_FIND_POSIX_INFORMATION)
+ self.assertEqual(
+ dirents[0]["attrib"],
+ libsmb.FILE_ATTRIBUTE_REPARSE_POINT|
+ libsmb.FILE_ATTRIBUTE_ARCHIVE)
+ self.assertEqual(
+ dirents[0]["reparse_tag"],
+ libsmb.IO_REPARSE_TAG_SYMLINK)
+
+ type, perms = self.wire_mode_to_unix(dirents[0]['perms'])
+ self.assertEqual(type, stat.S_IFLNK)
+
+ self.clean_file(conn, filename)
+
if __name__ == '__main__':
import unittest
unittest.main()
diff --git a/python/samba/tests/smb3unix.py b/python/samba/tests/smb3unix.py
index df845d9e0c0..7d2529ad747 100644
--- a/python/samba/tests/smb3unix.py
+++ b/python/samba/tests/smb3unix.py
@@ -70,13 +70,6 @@ class Smb3UnixTests(samba.tests.libsmb.LibsmbTests):
return (conn1, conn2)
- def wire_mode_to_unix(self, wire):
- mode = libsmb.wire_mode_to_unix(wire)
- type = stat.S_IFMT(mode)
- perms = mode & (stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO|
- stat.S_ISUID|stat.S_ISGID|stat.S_ISVTX)
- return (type, perms)
-
def test_negotiate_context_posix(self):
c = libsmb.Conn(
self.server_ip,
diff --git a/source3/include/trans2.h b/source3/include/trans2.h
index 69b60d8a250..21b2a3588e8 100644
--- a/source3/include/trans2.h
+++ b/source3/include/trans2.h
@@ -341,8 +341,7 @@ Byte offset Type name description
#define FSCC_FILE_MAXIMUM_INFORMATION 55
/* As yet undefined FSCC_ code for POSIX info level. */
-#define SMB2_FILE_POSIX_INFORMATION 100
-#define SMB2_FS_POSIX_INFORMATION 100
+#define FSCC_FILE_POSIX_INFORMATION 100
/* MS-FSCC 2.4 File System Information Classes */
@@ -356,6 +355,9 @@ Byte offset Type name description
#define FSCC_FS_OBJECTID_INFORMATION 8
#define FSCC_FS_SECTOR_SIZE_INFORMATION 11
+/* As yet undefined FSCC_ code for POSIX info level. */
+#define FSCC_FS_POSIX_INFORMATION 100
+
/* NT passthrough levels... */
#define NT_PASSTHROUGH_OFFSET 1000
@@ -412,8 +414,6 @@ Byte offset Type name description
#define SMB2_FILE_RENAME_INFORMATION_INTERNAL
(FSCC_FILE_RENAME_INFORMATION + SMB2_INFO_SPECIAL)
#define SMB2_FILE_FULL_EA_INFORMATION
(FSCC_FILE_FULL_EA_INFORMATION + SMB2_INFO_SPECIAL)
#define SMB2_FILE_ALL_INFORMATION
(FSCC_FILE_ALL_INFORMATION + SMB2_INFO_SPECIAL)
-#define SMB2_FILE_POSIX_INFORMATION_INTERNAL
(SMB2_FILE_POSIX_INFORMATION + SMB2_INFO_SPECIAL)
-#define SMB2_FS_POSIX_INFORMATION_INTERNAL 1100
/* NT passthrough levels for qfsinfo. */
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index f9a82089709..155bc6ae353 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -5145,7 +5145,7 @@ static void cli_smb2_get_posix_fs_info_opened(struct
tevent_req *subreq)
state->cli,
state->fnum,
SMB2_0_INFO_FILESYSTEM, /* in_info_type */
- SMB2_FS_POSIX_INFORMATION, /* in_file_info_class */
+ FSCC_FS_POSIX_INFORMATION, /* in_file_info_class */
0xFFFF, /* in_max_output_length */
NULL, /* in_input_buffer */
0, /* in_additional_info */
diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c
index b002d0edb0e..7dc739897ad 100644
--- a/source3/libsmb/pylibsmb.c
+++ b/source3/libsmb/pylibsmb.c
@@ -60,6 +60,7 @@ c = libsmb.Conn("127.0.0.1",
#include "trans2.h"
#include "libsmb/clirap.h"
#include "librpc/rpc/pyrpc_util.h"
+#include "librpc/gen_ndr/ndr_security.h"
#define LIST_ATTRIBUTE_MASK \
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN)
@@ -1388,6 +1389,129 @@ static PyObject *py_cli_qfileinfo(struct py_cli_state
*self, PyObject *args)
(unsigned long long)tag);
break;
}
+ case FSCC_FILE_POSIX_INFORMATION: {
+ size_t data_off = 0;
+ time_t btime;
+ time_t atime;
+ time_t mtime;
+ time_t ctime;
+ uint64_t size;
+ uint64_t alloc_size;
+ uint32_t attr;
+ uint64_t ino;
+ uint32_t dev;
+ uint32_t nlinks;
+ uint32_t reparse_tag;
+ uint32_t mode;
+ size_t sid_size;
+ enum ndr_err_code ndr_err;
+ struct dom_sid owner, group;
+ struct dom_sid_buf owner_buf, group_buf;
+
+ if (num_rdata < 80) {
+ PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return NULL;
+ }
+
+ btime = nt_time_to_unix(PULL_LE_U64(rdata, data_off));
+ data_off += 8;
+ atime = nt_time_to_unix(PULL_LE_U64(rdata, data_off));
+ data_off += 8;
+ mtime = nt_time_to_unix(PULL_LE_U64(rdata, data_off));
+ data_off += 8;
+ ctime = nt_time_to_unix(PULL_LE_U64(rdata, data_off));
+ data_off += 8;
+ size = PULL_LE_U64(rdata, data_off);
+ data_off += 8;
+ alloc_size = PULL_LE_U64(rdata, data_off);
+ data_off += 8;
+ attr = PULL_LE_U32(rdata, data_off);
+ data_off += 4;
+ ino = PULL_LE_U64(rdata, data_off);
+ data_off += 8;
+ dev = PULL_LE_U32(rdata, data_off);
+ data_off += 4;
+ /* 4 bytes reserved */
+ data_off += 4;
+ nlinks = PULL_LE_U32(rdata, data_off);
+ data_off += 4;
+ reparse_tag = PULL_LE_U32(rdata, data_off);
+ data_off += 4;
+ mode = PULL_LE_U32(rdata, data_off);
+ data_off += 4;
+
+ ndr_err = ndr_pull_struct_blob_noalloc(
+ rdata + data_off,
+ num_rdata - data_off,
+ &owner,
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid,
+ &sid_size);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return NULL;
+ }
+ if (data_off + sid_size < data_off ||
+ data_off + sid_size > num_rdata)
+ {
+ PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return NULL;
+ }
+ data_off += sid_size;
+
+ ndr_err = ndr_pull_struct_blob_noalloc(
+ rdata + data_off,
+ num_rdata - data_off,
+ &group,
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid,
+ &sid_size);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return NULL;
+ }
+
+ result = Py_BuildValue(
+ "{s:i," /* attr */
+ "s:K,s:K,s:K,s:K," /* dates */
+ "s:K,s:K," /* sizes */
+ "s:K,s:K,s:K," /* ino, dev, nlinks */
+ "s:K,s:K," /* tag, mode */
+ "s:s,s:s}", /* owner, group */
+
+ "attrib",
+ attr,
+
+ "btime",
+ (unsigned long long)btime,
+ "atime",
+ (unsigned long long)atime,
+ "mtime",
+ (unsigned long long)mtime,
+ "ctime",
+ (unsigned long long)ctime,
+
+ "allocation_size",
+ (unsigned long long)alloc_size,
+ "size",
+ (unsigned long long)size,
+
+ "ino",
+ (unsigned long long)ino,
+ "dev",
+ (unsigned long long)dev,
+ "nlink",
+ (unsigned long long)nlinks,
+
+ "reparse_tag",
+ (unsigned long long)reparse_tag,
+ "perms",
+ (unsigned long long)mode,
+
+ "owner_sid",
+ dom_sid_str_buf(&owner, &owner_buf),
+ "group_sid",
+ dom_sid_str_buf(&group, &group_buf));
+ break;
+ }
default:
result = PyBytes_FromStringAndSize((char *)rdata, num_rdata);
break;
@@ -3222,6 +3346,7 @@ MODULE_INIT_FUNC(libsmb_samba_cwrapper)
ADD_FLAGS(FSCC_FILE_ID_GLOBAL_TX_DIRECTORY_INFORMATION);
ADD_FLAGS(FSCC_FILE_STANDARD_LINK_INFORMATION);
ADD_FLAGS(FSCC_FILE_MAXIMUM_INFORMATION);
+ ADD_FLAGS(FSCC_FILE_POSIX_INFORMATION);
#define ADD_STRING(val) PyModule_AddObject(m, #val, PyBytes_FromString(val))
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 0de348883e4..9a8ecf6e0a7 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -687,7 +687,9 @@ static uint32_t dos_mode_post(uint32_t dosmode,
dosmode |= dos_mode_from_name(fsp->conn, smb_fname->base_name, dosmode);
if (S_ISDIR(smb_fname->st.st_ex_mode)) {
- dosmode |= FILE_ATTRIBUTE_DIRECTORY;
+ if (!(dosmode & FILE_ATTRIBUTE_REPARSE_POINT)) {
+ dosmode |= FILE_ATTRIBUTE_DIRECTORY;
+ }
} else if (dosmode == 0) {
dosmode = FILE_ATTRIBUTE_NORMAL;
}
@@ -736,13 +738,12 @@ uint32_t fdos_mode(struct files_struct *fsp)
* Everybody else wants to see symlinks as
* reparse points
*/
- result = FILE_ATTRIBUTE_NORMAL |
- FILE_ATTRIBUTE_REPARSE_POINT;
+ result = FILE_ATTRIBUTE_REPARSE_POINT;
}
break;
default:
- return FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_REPARSE_POINT;
+ return FILE_ATTRIBUTE_REPARSE_POINT;
break;
}
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index fe2ad67a03b..e7de9df4683 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1223,10 +1223,9 @@ NTSTATUS vfs_default_durable_reconnect(struct
connection_struct *conn,
DATA_BLOB *new_cookie);
struct smb3_file_posix_information;
-void smb3_file_posix_information_init(
+NTSTATUS smb3_file_posix_information_init(
connection_struct *conn,
- const struct stat_ex *st,
- uint32_t reparse_tag,
+ const struct smb_filename *smb_fname,
uint32_t dos_attributes,
struct smb3_file_posix_information *dst);
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 2a61f963516..7264263a121 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -338,17 +338,17 @@ static struct tevent_req
*smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
file_info_level = SMB2_FILE_ALL_INFORMATION;
break;
- case SMB2_FILE_POSIX_INFORMATION:
+ case FSCC_FILE_POSIX_INFORMATION:
if (!fsp->fsp_flags.posix_open) {
tevent_req_nterror(req,
NT_STATUS_INVALID_LEVEL);
return tevent_req_post(req, ev);
}
- file_info_level = SMB2_FILE_POSIX_INFORMATION_INTERNAL;
+ file_info_level = in_file_info_class;
break;
default:
/* the levels directly map to the passthru levels */
- file_info_level = in_file_info_class + 1000;
+ file_info_level = in_file_info_class +
NT_PASSTHROUGH_OFFSET;
break;
}
@@ -465,8 +465,15 @@ static struct tevent_req
*smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
int data_size = 0;
size_t fixed_portion;
- /* the levels directly map to the passthru levels */
- file_info_level = in_file_info_class + 1000;
+ switch (in_file_info_class) {
+ case FSCC_FS_POSIX_INFORMATION:
+ file_info_level = in_file_info_class;
+ break;
+ default:
+ /* the levels directly map to the passthru levels */
+ file_info_level = in_file_info_class +
NT_PASSTHROUGH_OFFSET;
+ break;
+ }
status = smbd_do_qfsinfo(smb2req->xconn, conn, state,
file_info_level,
diff --git a/source3/smbd/smb2_posix.c b/source3/smbd/smb2_posix.c
index 72bdac65043..8797b266260 100644
--- a/source3/smbd/smb2_posix.c
+++ b/source3/smbd/smb2_posix.c
@@ -23,14 +23,132 @@
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/smb3posix.h"
#include "libcli/security/security.h"
+#include "source3/modules/util_reparse.h"
+#include "libcli/smb/reparse.h"
-void smb3_file_posix_information_init(
+static NTSTATUS reparse_buffer_parse_posix_type(uint32_t reparse_tag,
+ uint8_t *data,
+ uint32_t len,
+ mode_t *type)
+{
+ struct reparse_data_buffer *reparse = NULL;
+ NTSTATUS status;
+
+ if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
+ *type = S_IFLNK;
+ return NT_STATUS_OK;
+ }
+ if (reparse_tag != IO_REPARSE_TAG_NFS) {
+ /*
+ * Clients can create reparse points with arbitrary tags, return
+ * anything that is not a NFS one (or symlink) as S_IFREG.
+ */
+ DBG_INFO("Unhandled NFS reparse tag: 0x%" PRIx32 "\n",
+ reparse->tag);
+ *type = S_IFREG;
+ return NT_STATUS_OK;
+ }
+
+ reparse = talloc_zero(talloc_tos(), struct reparse_data_buffer);
+ if (reparse == NULL) {
+ DBG_ERR("talloc_zero() failed\n");
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = reparse_data_buffer_parse(reparse, reparse, data, len);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(reparse);
+ return status;
+ }
+
+ switch (reparse->parsed.nfs.type) {
+ case NFS_SPECFILE_CHR:
--
Samba Shared Repository