#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
-static int dfq_get_quota(struct vfs_handle_struct *handle, const char *path,
- enum SMB_QUOTA_TYPE qtype, unid_t id,
- SMB_DISK_QUOTA *qt);
+static int dfq_get_quota(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ enum SMB_QUOTA_TYPE qtype,
+ unid_t id,
+ SMB_DISK_QUOTA *qt);
static uint64_t dfq_load_param(int snum, const char *path, const char *section,
const char *param, uint64_t def_val)
return ret;
}
-static uint64_t dfq_disk_free(vfs_handle_struct *handle, const char *path,
- uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
+static uint64_t dfq_disk_free(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uint64_t *bsize,
+ uint64_t *dfree,
+ uint64_t *dsize)
{
uint64_t free_1k;
int snum = SNUM(handle->conn);
uint64_t dfq_bsize = 0;
- char *rpath = NULL;
+ struct smb_filename *rpath_fname = NULL;
/* look up the params based on real path to be resilient
* to refactoring of path<->realpath
*/
- rpath = SMB_VFS_NEXT_REALPATH(handle, path);
- if (rpath != NULL) {
- dfq_bsize = dfq_load_param(snum, rpath, "df", "block size", 0);
+ rpath_fname = SMB_VFS_NEXT_REALPATH(handle, talloc_tos(), smb_fname);
+ if (rpath_fname != NULL) {
+ dfq_bsize = dfq_load_param(snum, rpath_fname->base_name,
+ "df", "block size", 0);
}
if (dfq_bsize == 0) {
- SAFE_FREE(rpath);
- return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree,
+ TALLOC_FREE(rpath_fname);
+ return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree,
dsize);
}
*bsize = dfq_bsize;
- *dfree = dfq_load_param(snum, rpath, "df", "disk free", 0);
- *dsize = dfq_load_param(snum, rpath, "df", "disk size", 0);
+ *dfree = dfq_load_param(snum, rpath_fname->base_name,
+ "df", "disk free", 0);
+ *dsize = dfq_load_param(snum, rpath_fname->base_name,
+ "df", "disk size", 0);
if ((*bsize) < 1024) {
free_1k = (*dfree) / (1024 / (*bsize));
free_1k = ((*bsize) / 1024) * (*dfree);
}
- SAFE_FREE(rpath);
+ TALLOC_FREE(rpath_fname);
return free_1k;
}
-static int dfq_get_quota(struct vfs_handle_struct *handle, const char *path,
- enum SMB_QUOTA_TYPE qtype, unid_t id,
- SMB_DISK_QUOTA *qt)
+static int dfq_get_quota(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ enum SMB_QUOTA_TYPE qtype,
+ unid_t id,
+ SMB_DISK_QUOTA *qt)
{
int rc = 0;
int save_errno;
char *section = NULL;
int snum = SNUM(handle->conn);
uint64_t bsize = 0;
- char *rpath = NULL;
+ struct smb_filename *rpath_fname = NULL;
- rpath = SMB_VFS_NEXT_REALPATH(handle, path);
- if (rpath == NULL) {
+ rpath_fname = SMB_VFS_NEXT_REALPATH(handle, talloc_tos(), smb_fname);
+ if (rpath_fname == NULL) {
goto dflt;
}
goto dflt;
}
- bsize = dfq_load_param(snum, rpath, section, "block size", 4096);
+ bsize = dfq_load_param(snum, rpath_fname->base_name,
+ section, "block size", 4096);
if (bsize == 0) {
goto dflt;
}
- if (dfq_load_param(snum, rpath, section, "err", 0) != 0) {
+ if (dfq_load_param(snum, rpath_fname->base_name,
+ section, "err", 0) != 0) {
errno = ENOTSUP;
rc = -1;
goto out;
}
- if (dfq_load_param(snum, rpath, section, "nosys", 0) != 0) {
+ if (dfq_load_param(snum, rpath_fname->base_name,
+ section, "nosys", 0) != 0) {
errno = ENOSYS;
rc = -1;
goto out;
ZERO_STRUCTP(qt);
qt->bsize = bsize;
- qt->hardlimit = dfq_load_param(snum, rpath, section, "hard limit", 0);
- qt->softlimit = dfq_load_param(snum, rpath, section, "soft limit", 0);
- qt->curblocks = dfq_load_param(snum, rpath, section, "cur blocks", 0);
+ qt->hardlimit = dfq_load_param(snum, rpath_fname->base_name,
+ section, "hard limit", 0);
+ qt->softlimit = dfq_load_param(snum, rpath_fname->base_name,
+ section, "soft limit", 0);
+ qt->curblocks = dfq_load_param(snum, rpath_fname->base_name,
+ section, "cur blocks", 0);
qt->ihardlimit =
- dfq_load_param(snum, rpath, section, "inode hard limit", 0);
+ dfq_load_param(snum, rpath_fname->base_name,
+ section, "inode hard limit", 0);
qt->isoftlimit =
- dfq_load_param(snum, rpath, section, "inode soft limit", 0);
- qt->curinodes = dfq_load_param(snum, rpath, section, "cur inodes", 0);
- qt->qflags = dfq_load_param(snum, rpath, section, "qflags", QUOTAS_DENY_DISK);
+ dfq_load_param(snum, rpath_fname->base_name,
+ section, "inode soft limit", 0);
+ qt->curinodes = dfq_load_param(snum, rpath_fname->base_name,
+ section, "cur inodes", 0);
+ qt->qflags = dfq_load_param(snum, rpath_fname->base_name,
+ section, "qflags", QUOTAS_DENY_DISK);
goto out;
dflt:
- rc = SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, qt);
+ rc = SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, qt);
out:
save_errno = errno;
TALLOC_FREE(section);
- SAFE_FREE(rpath);
+ TALLOC_FREE(rpath_fname);
errno = save_errno;
return rc;
}
+static void dfq_fake_stat(struct vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ SMB_STRUCT_STAT *sbuf)
+{
+ int snum = SNUM(handle->conn);
+ char *full_path = NULL;
+ char *to_free = NULL;
+ char path[PATH_MAX + 1];
+ int len;
+ gid_t gid;
+
+ len = full_path_tos(handle->conn->cwd_fsp->fsp_name->base_name,
+ smb_fname->base_name,
+ path, sizeof(path),
+ &full_path, &to_free);
+ if (len == -1) {
+ DBG_ERR("Could not allocate memory in full_path_tos.\n");
+ return;
+ }
+
+ gid = dfq_load_param(snum, full_path, "stat", "sgid", 0);
+ if (gid != 0) {
+ sbuf->st_ex_gid = gid;
+ sbuf->st_ex_mode |= S_ISGID;
+ }
+
+ TALLOC_FREE(to_free);
+}
+
+static int dfq_stat(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname)
+{
+ int ret;
+
+ ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
+ if (ret == -1) {
+ return ret;
+ }
+
+ dfq_fake_stat(handle, smb_fname, &smb_fname->st);
+
+ return 0;
+}
+
+static int dfq_fstat(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf)
+{
+ int ret;
+
+ ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+ if (ret == -1) {
+ return ret;
+ }
+
+ dfq_fake_stat(handle, fsp->fsp_name, sbuf);
+
+ return 0;
+}
+
+static int dfq_lstat(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname)
+{
+ int ret;
+
+ ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
+ if (ret == -1) {
+ return ret;
+ }
+
+ dfq_fake_stat(handle, smb_fname, &smb_fname->st);
+
+ return 0;
+}
+
struct vfs_fn_pointers vfs_fake_dfq_fns = {
/* Disk operations */
.disk_free_fn = dfq_disk_free,
.get_quota_fn = dfq_get_quota,
+
+ .stat_fn = dfq_stat,
+ .fstat_fn = dfq_fstat,
+ .lstat_fn = dfq_lstat,
};
static_decl_vfs;