]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libsmbclient: Intercept "smb311_posix.statinfo" attribute
authorVolker Lendecke <vl@samba.org>
Tue, 10 Jun 2025 17:10:42 +0000 (19:10 +0200)
committerRalph Boehme <slow@samba.org>
Mon, 16 Jun 2025 16:08:20 +0000 (16:08 +0000)
Directly get a "struct stat" plus a 32-bit uint32 for the dosatts

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Mon Jun 16 16:08:20 UTC 2025 on atb-devel-224

source3/libsmb/libsmb_xattr.c

index 79e520d470d0463cad755235478a6ea144ef55ab..d07f9bee5693ae831d153d9b0561b0aab2c0f445 100644 (file)
@@ -33,6 +33,7 @@
 #include "rpc_client/cli_lsarpc.h"
 #include "../libcli/security/security.h"
 #include "lib/util/string_wrappers.h"
+#include "source3/include/trans2.h"
 
 /*
  * Find an lsa pipe handle associated with a cli struct.
@@ -2251,6 +2252,70 @@ SMBC_fgetxattr_ctx(SMBCCTX *context,
                return len;
        }
 
+       if (strequal(name, "smb311_posix.statinfo")) {
+               struct stat st = {};
+               struct timespec t = {};
+               DATA_BLOB out = {};
+               uint32_t *_attrs = NULL;
+               NTSTATUS status;
+
+               if (size != (sizeof(struct stat) + 4)) {
+                       TALLOC_FREE(frame);
+                       errno = EINVAL;
+                       return -1;
+               }
+
+               status = cli_smb2_query_info_fnum(file->targetcli,
+                                                 file->cli_fd,
+                                                 SMB2_0_INFO_FILE,
+                                                 FSCC_FILE_POSIX_INFORMATION,
+                                                 65536,
+                                                 NULL,
+                                                 0,
+                                                 0,
+                                                 frame,
+                                                 &out);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(frame);
+                       errno = map_errno_from_nt_status(status);
+                       return -1;
+               }
+
+               if (out.length < 80) {
+                       TALLOC_FREE(frame);
+                       errno = EIO;
+                       return -1;
+               }
+
+               t = nt_time_to_unix_timespec(PULL_LE_U64(out.data, 8));
+               st.st_atime = t.tv_sec;
+               set_atimensec(&st, t.tv_nsec);
+
+               t = nt_time_to_unix_timespec(PULL_LE_U64(out.data, 16));
+               st.st_mtime = t.tv_sec;
+               set_mtimensec(&st, t.tv_nsec);
+
+               t = nt_time_to_unix_timespec(PULL_LE_U64(out.data, 24));
+               st.st_ctime = t.tv_sec;
+               set_ctimensec(&st, t.tv_nsec);
+
+               st.st_size = PULL_LE_U64(out.data, 32);
+               st.st_ino = PULL_LE_U64(out.data, 52);
+               st.st_dev = PULL_LE_U32(out.data, 60);
+               st.st_nlink = PULL_LE_U32(out.data, 68);
+               st.st_mode = PULL_LE_U32(out.data, 76);
+
+               memcpy(discard_const_p(char, value), &st, sizeof(struct stat));
+
+               _attrs = (uint32_t *)(discard_const_p(char, value) +
+                                     sizeof(struct stat));
+               *_attrs = PULL_LE_U32(out.data, 48);
+
+               TALLOC_FREE(frame);
+
+               return sizeof(struct stat);
+       }
+
        ret = SMBC_getxattr_ctx(context, file->fname, name, value, size);
 
        {