From: Anoop C S Date: Tue, 24 Sep 2024 05:36:58 +0000 (+0530) Subject: s3/smbd: Add a helper to fetch fs capabilities X-Git-Tag: samba-4.21.5~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8c7d9f39d9fca3d846cc3a8f348af3788c25fd0d;p=thirdparty%2Fsamba.git s3/smbd: Add a helper to fetch fs capabilities We create a new helper function to retrieve the fs capabilties via STATVFS call. Additionally set other capabilities based on specific parametric options. This is 99.9% taken from SMB_VFS_FS_CAPABILITIES implementation of vfs_default in preparation to be called from any required vfs module. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15822 Signed-off-by: Anoop C S Reviewed-by: Ralph Boehme (cherry picked from commit b1fbaefc665a7fb0413a26bd0304f97356fda414) --- diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 90387aeb6c3..093c60adcfa 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -1176,6 +1176,8 @@ NTSTATUS vfs_fstreaminfo(struct files_struct *fsp, void init_smb_file_time(struct smb_file_time *ft); int vfs_fake_fd(void); int vfs_fake_fd_close(int fd); +uint32_t vfs_get_fs_capabilities(struct connection_struct *conn, + enum timestamp_set_resolution *ts_res); /* The following definitions come from smbd/avahi_register.c */ diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 13b3ba61cea..388a5a90fc6 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1300,6 +1300,78 @@ NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +uint32_t vfs_get_fs_capabilities(struct connection_struct *conn, + enum timestamp_set_resolution *ts_res) +{ + const struct loadparm_substitution *lp_sub = + loadparm_s3_global_substitution(); + uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES; + struct smb_filename *smb_fname_cpath = NULL; + struct vfs_statvfs_struct statbuf; + int ret; + + smb_fname_cpath = synthetic_smb_fname(talloc_tos(), + conn->connectpath, + NULL, + NULL, + 0, + 0); + if (smb_fname_cpath == NULL) { + return caps; + } + + ZERO_STRUCT(statbuf); + ret = SMB_VFS_STATVFS(conn, smb_fname_cpath, &statbuf); + if (ret == 0) { + caps = statbuf.FsCapabilities; + } + + if (lp_nt_acl_support(SNUM(conn))) { + caps |= FILE_PERSISTENT_ACLS; + } + + caps |= lp_parm_int(SNUM(conn), "share", "fake_fscaps", 0); + + *ts_res = TIMESTAMP_SET_SECONDS; + + /* Work out what timestamp resolution we can + * use when setting a timestamp. */ + + ret = SMB_VFS_STAT(conn, smb_fname_cpath); + if (ret == -1) { + TALLOC_FREE(smb_fname_cpath); + return caps; + } + + if (smb_fname_cpath->st.st_ex_mtime.tv_nsec || + smb_fname_cpath->st.st_ex_atime.tv_nsec || + smb_fname_cpath->st.st_ex_ctime.tv_nsec) { + /* If any of the normal UNIX directory timestamps + * have a non-zero tv_nsec component assume + * we might be able to set sub-second timestamps. + * See what filetime set primitives we have. + */ +#if defined(HAVE_UTIMENSAT) + *ts_res = TIMESTAMP_SET_NT_OR_BETTER; +#elif defined(HAVE_UTIMES) + /* utimes allows msec timestamps to be set. */ + *ts_res = TIMESTAMP_SET_MSEC; +#elif defined(HAVE_UTIME) + /* utime only allows sec timestamps to be set. */ + *ts_res = TIMESTAMP_SET_SECONDS; +#endif + + DBG_DEBUG("vfs_get_fs_capabilities: timestamp " + "resolution of %s " + "available on share %s, directory %s\n", + *ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec", + lp_servicename(talloc_tos(), lp_sub, conn->params->service), + conn->connectpath ); + } + TALLOC_FREE(smb_fname_cpath); + return caps; +} + static struct smb_vfs_deny_state *smb_vfs_deny_global; void smb_vfs_assert_allowed(void)