1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00
samba-mirror/source3/modules/vfs_fake_dfq.c
Uri Simchoni 8078e5f15b vfs_fake_dfq - remove support for generating EDQUOT
Remove the option to retrieve valid user/group quota while
returning -1 and EDQUOT errno - this is no longer part of the
protocol between the quota backend and smbd.

Signed-off-by: Uri Simchoni <uri@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
2016-06-01 00:57:32 +02:00

183 lines
4.6 KiB
C

/*
* Fake Disk-Free and Quota VFS module. Implements passthrough operation
* of all VFS calls, except for "disk free" and "get quota" which
* are handled by reading a text file named ".dfq" in the current directory.
*
* This module is intended for testing purposes.
*
* Copyright (C) Uri Simchoni, 2016
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "smbd/smbd.h"
#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 uint64_t dfq_load_param(int snum, const char *path, const char *section,
const char *param, uint64_t def_val)
{
uint64_t ret;
char *option =
talloc_asprintf(talloc_tos(), "%s/%s/%s", section, param, path);
if (option == NULL) {
return def_val;
}
ret = (uint64_t)lp_parm_ulonglong(snum, "fake_dfq", option,
(unsigned long long)def_val);
TALLOC_FREE(option);
return ret;
}
static uint64_t dfq_disk_free(vfs_handle_struct *handle, const char *path,
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;
/* 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);
}
if (dfq_bsize == 0) {
SAFE_FREE(rpath);
return SMB_VFS_NEXT_DISK_FREE(handle, path, 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);
if ((*bsize) < 1024) {
free_1k = (*dfree) / (1024 / (*bsize));
} else {
free_1k = ((*bsize) / 1024) * (*dfree);
}
SAFE_FREE(rpath);
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)
{
int rc = 0;
int save_errno;
char *section = NULL;
int snum = SNUM(handle->conn);
uint64_t bsize = 0;
char *rpath = NULL;
rpath = SMB_VFS_NEXT_REALPATH(handle, path);
if (rpath == NULL) {
goto dflt;
}
switch (qtype) {
case SMB_USER_QUOTA_TYPE:
section = talloc_asprintf(talloc_tos(), "u%llu",
(unsigned long long)id.uid);
break;
case SMB_GROUP_QUOTA_TYPE:
section = talloc_asprintf(talloc_tos(), "g%llu",
(unsigned long long)id.gid);
break;
case SMB_USER_FS_QUOTA_TYPE:
section = talloc_strdup(talloc_tos(), "udflt");
break;
case SMB_GROUP_FS_QUOTA_TYPE:
section = talloc_strdup(talloc_tos(), "gdflt");
break;
default:
break;
}
if (section == NULL) {
goto dflt;
}
bsize = dfq_load_param(snum, rpath, section, "block size", 4096);
if (bsize == 0) {
goto dflt;
}
if (dfq_load_param(snum, rpath, section, "err", 0) != 0) {
errno = ENOTSUP;
rc = -1;
goto out;
}
if (dfq_load_param(snum, rpath, 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->ihardlimit =
dfq_load_param(snum, rpath, 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);
goto out;
dflt:
rc = SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, qt);
out:
save_errno = errno;
TALLOC_FREE(section);
SAFE_FREE(rpath);
errno = save_errno;
return rc;
}
struct vfs_fn_pointers vfs_fake_dfq_fns = {
/* Disk operations */
.disk_free_fn = dfq_disk_free,
.get_quota_fn = dfq_get_quota,
};
static_decl_vfs;
NTSTATUS vfs_fake_dfq_init(void)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "fake_dfq",
&vfs_fake_dfq_fns);
}