return -1;
}
+static int skel_fchflags(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint flags)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static struct file_id skel_file_id_create(vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf)
{
.mknodat_fn = skel_mknodat,
.realpath_fn = skel_realpath,
.chflags_fn = skel_chflags,
+ .fchflags_fn = skel_fchflags,
.file_id_create_fn = skel_file_id_create,
.fs_file_id_fn = skel_fs_file_id,
.offload_read_send_fn = skel_offload_read_send,
return SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
}
+static int skel_fchflags(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint flags)
+{
+ return SMB_VFS_NEXT_FCHFLAGS(handle, fsp, flags);
+}
+
static struct file_id skel_file_id_create(vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf)
{
.mknodat_fn = skel_mknodat,
.realpath_fn = skel_realpath,
.chflags_fn = skel_chflags,
+ .fchflags_fn = skel_fchflags,
.file_id_create_fn = skel_file_id_create,
.fs_file_id_fn = skel_fs_file_id,
.offload_read_send_fn = skel_offload_read_send,
* Version 45 - Remove SMB_VFS_GET_NT_ACL_AT
* Version 45 - Remove SYS_ACL_GET_FILE
* Version 45 - Remove SYS_ACL_BLOB_GET_FILE
+ * Version 45 - Add SMB_VFS_FCHFLAGS
*/
#define SMB_VFS_INTERFACE_VERSION 45
int (*chflags_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
unsigned int flags);
+ int (*fchflags_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ unsigned int flags);
struct file_id (*file_id_create_fn)(struct vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf);
uint64_t (*fs_file_id_fn)(struct vfs_handle_struct *handle,
int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
unsigned int flags);
+int smb_vfs_call_fchflags(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ unsigned int flags);
struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf);
uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
int vfs_not_implemented_chflags(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
uint flags);
+int vfs_not_implemented_fchflags(vfs_handle_struct *handle,
+ struct files_struct *fst,
+ uint flags);
struct file_id vfs_not_implemented_file_id_create(vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf);
uint64_t vfs_not_implemented_fs_file_id(vfs_handle_struct *handle,
#define SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags) \
smb_vfs_call_chflags((handle)->next, (smb_fname), (flags))
+#define SMB_VFS_FCHFLAGS(fsp, flags) \
+ smb_vfs_call_fchflags((fsp)->conn->vfs_handles, (fsp), (flags))
+#define SMB_VFS_NEXT_FCHFLAGS(handle, fsp, flags) \
+ smb_vfs_call_fchflags((handle)->next, (fsp), (flags))
+
#define SMB_VFS_FILE_ID_CREATE(conn, sbuf) \
smb_vfs_call_file_id_create((conn)->vfs_handles, (sbuf))
#define SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf) \
#endif
}
+static int vfswrap_fchflags(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ unsigned int flags)
+{
+#ifdef HAVE_FCHFLAGS
+ int fd = fsp_get_pathref_fd(fsp);
+
+ if (!fsp->fsp_flags.is_pathref) {
+ return fchflags(fd, flags);
+ }
+
+ if (fsp->fsp_flags.have_proc_fds) {
+ const char *p = NULL;
+ char buf[PATH_MAX];
+
+ p = sys_proc_fd_path(fd, buf, sizeof(buf));
+ if (p == NULL) {
+ return -1;
+ }
+
+ return chflags(p, flags);
+ }
+
+ /*
+ * This is no longer a handle based call.
+ */
+ return chflags(fsp->fsp_name->base_name, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf)
{
.mknodat_fn = vfswrap_mknodat,
.realpath_fn = vfswrap_realpath,
.chflags_fn = vfswrap_chflags,
+ .fchflags_fn = vfswrap_fchflags,
.file_id_create_fn = vfswrap_file_id_create,
.fs_file_id_fn = vfswrap_fs_file_id,
.fstreaminfo_fn = vfswrap_fstreaminfo,
SMB_VFS_OP_MKNODAT,
SMB_VFS_OP_REALPATH,
SMB_VFS_OP_CHFLAGS,
+ SMB_VFS_OP_FCHFLAGS,
SMB_VFS_OP_FILE_ID_CREATE,
SMB_VFS_OP_FS_FILE_ID,
SMB_VFS_OP_FSTREAMINFO,
{ SMB_VFS_OP_MKNODAT, "mknodat" },
{ SMB_VFS_OP_REALPATH, "realpath" },
{ SMB_VFS_OP_CHFLAGS, "chflags" },
+ { SMB_VFS_OP_FCHFLAGS, "fchflags" },
{ SMB_VFS_OP_FILE_ID_CREATE, "file_id_create" },
{ SMB_VFS_OP_FS_FILE_ID, "fs_file_id" },
{ SMB_VFS_OP_FSTREAMINFO, "fstreaminfo" },
return result;
}
+static int smb_full_audit_fchflags(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ unsigned int flags)
+{
+ int result;
+
+ result = SMB_VFS_NEXT_FCHFLAGS(handle, fsp, flags);
+
+ do_log(SMB_VFS_OP_FCHFLAGS,
+ (result != 0),
+ handle,
+ "%s",
+ smb_fname_str_do_log(handle->conn, fsp->fsp_name));
+
+ return result;
+}
+
static struct file_id smb_full_audit_file_id_create(struct vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf)
{
.mknodat_fn = smb_full_audit_mknodat,
.realpath_fn = smb_full_audit_realpath,
.chflags_fn = smb_full_audit_chflags,
+ .fchflags_fn = smb_full_audit_fchflags,
.file_id_create_fn = smb_full_audit_file_id_create,
.fs_file_id_fn = smb_full_audit_fs_file_id,
.offload_read_send_fn = smb_full_audit_offload_read_send,
return -1;
}
+int vfs_not_implemented_fchflags(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint flags)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
struct file_id vfs_not_implemented_file_id_create(vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf)
{
.mknodat_fn = vfs_not_implemented_mknodat,
.realpath_fn = vfs_not_implemented_realpath,
.chflags_fn = vfs_not_implemented_chflags,
+ .fchflags_fn = vfs_not_implemented_fchflags,
.file_id_create_fn = vfs_not_implemented_file_id_create,
.fs_file_id_fn = vfs_not_implemented_fs_file_id,
.offload_read_send_fn = vfs_not_implemented_offload_read_send,
return result;
}
+static int smb_time_audit_fchflags(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ unsigned int flags)
+{
+ int result;
+ struct timespec ts1,ts2;
+ double timediff;
+
+ clock_gettime_mono(&ts1);
+ result = SMB_VFS_NEXT_FCHFLAGS(handle, fsp, flags);
+ clock_gettime_mono(&ts2);
+ timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+ if (timediff > audit_timeout) {
+ smb_time_audit_log_smb_fname("chflags",
+ timediff,
+ fsp->fsp_name);
+ }
+
+ return result;
+}
+
static struct file_id smb_time_audit_file_id_create(struct vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf)
{
.mknodat_fn = smb_time_audit_mknodat,
.realpath_fn = smb_time_audit_realpath,
.chflags_fn = smb_time_audit_chflags,
+ .fchflags_fn = smb_time_audit_fchflags,
.file_id_create_fn = smb_time_audit_file_id_create,
.fs_file_id_fn = smb_time_audit_fs_file_id,
.offload_read_send_fn = smb_time_audit_offload_read_send,
return handle->fns->chflags_fn(handle, smb_fname, flags);
}
+int smb_vfs_call_fchflags(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ unsigned int flags)
+{
+ VFS_FIND(fchflags);
+ return handle->fns->fchflags_fn(handle, fsp, flags);
+}
+
struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
const SMB_STRUCT_STAT *sbuf)
{
conf.CHECK_HEADERS('linux/falloc.h linux/ioctl.h')
conf.CHECK_FUNCS('getcwd fchown chmod fchmod mknod mknodat')
- conf.CHECK_FUNCS('strtol strchr strupr chflags')
+ conf.CHECK_FUNCS('strtol strchr strupr chflags fchflags')
conf.CHECK_FUNCS('getrlimit fsync setpgid')
conf.CHECK_FUNCS('setsid glob strpbrk crypt16 getauthuid')
conf.CHECK_FUNCS('innetgr')
DNSServiceRegister
atexit
chflags
+fchflags
chmod
crypt16
devnm