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

Reply via email to