From 8daa83a594a2e98f39d764422bfbdbc62c9efd44 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 19:20:00 +0200 Subject: Adding upstream version 2:4.20.0+dfsg. Signed-off-by: Daniel Baumann --- source3/modules/vfs_default_quota.c | 236 ++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 source3/modules/vfs_default_quota.c (limited to 'source3/modules/vfs_default_quota.c') diff --git a/source3/modules/vfs_default_quota.c b/source3/modules/vfs_default_quota.c new file mode 100644 index 0000000..326eb8c --- /dev/null +++ b/source3/modules/vfs_default_quota.c @@ -0,0 +1,236 @@ +/* + * Store default Quotas in a specified quota record + * + * Copyright (C) Stefan (metze) Metzmacher 2003 + * + * 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 . + */ + +/* + * This module allows the default quota values, + * in the windows explorer GUI, to be stored on a samba server. + * The problem is that linux filesystems only store quotas + * for users and groups, but no default quotas. + * + * Samba returns NO_LIMIT as the default quotas by default + * and refuses to update them. + * + * With this module you can store the default quotas that are reported to + * a windows client, in the quota record of a user. By default the root user + * is taken because quota limits for root are typically not enforced. + * + * This module takes 2 parametric parameters in smb.conf: + * (the default prefix for them is 'default_quota', + * it can be overwrittem when you load the module in + * the 'vfs objects' parameter like this: + * vfs objects = default_quota:myprefix) + * + * ":uid" parameter takes a integer argument, + * it specifies the uid of the quota record, that will be taken for + * storing the default USER-quotas. + * + * - default value: '0' (for root user) + * - e.g.: default_quota:uid = 65534 + * + * ":uid nolimit" parameter takes a boolean argument, + * it specifies if we should report the stored default quota values, + * also for the user record, or if you should just report NO_LIMIT + * to the windows client for the user specified by the ":uid" parameter. + * + * - default value: yes (that means to report NO_LIMIT) + * - e.g.: default_quota:uid nolimit = no + * + * ":gid" parameter takes a integer argument, + * it's just like ":uid" but for group quotas. + * (NOTE: group quotas are not supported from the windows explorer!) + * + * - default value: '0' (for root group) + * - e.g.: default_quota:gid = 65534 + * + * ":gid nolimit" parameter takes a boolean argument, + * it's just like ":uid nolimit" but for group quotas. + * (NOTE: group quotas are not supported from the windows explorer!) + * + * - default value: yes (that means to report NO_LIMIT) + * - e.g.: default_quota:uid nolimit = no + * + */ + +#include "includes.h" +#include "smbd/smbd.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_QUOTA + +#define DEFAULT_QUOTA_NAME "default_quota" + +#define DEFAULT_QUOTA_UID_DEFAULT 0 +#define DEFAULT_QUOTA_UID_NOLIMIT_DEFAULT True +#define DEFAULT_QUOTA_GID_DEFAULT 0 +#define DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT True + +#define DEFAULT_QUOTA_UID(handle) \ + (uid_t)lp_parm_int(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"uid",DEFAULT_QUOTA_UID_DEFAULT) + +#define DEFAULT_QUOTA_UID_NOLIMIT(handle) \ + lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"uid nolimit",DEFAULT_QUOTA_UID_NOLIMIT_DEFAULT) + +#define DEFAULT_QUOTA_GID(handle) \ + (gid_t)lp_parm_int(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid",DEFAULT_QUOTA_GID_DEFAULT) + +#define DEFAULT_QUOTA_GID_NOLIMIT(handle) \ + lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid nolimit",DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT) + +static int default_quota_get_quota(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + enum SMB_QUOTA_TYPE qtype, + unid_t id, + SMB_DISK_QUOTA *dq) +{ + int ret = -1; + + if ((ret = SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, + qtype, id, dq)) != 0) { + return ret; + } + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + /* we use id.uid == 0 for default quotas */ + if ((id.uid==DEFAULT_QUOTA_UID(handle)) && + DEFAULT_QUOTA_UID_NOLIMIT(handle)) { + SMB_QUOTAS_SET_NO_LIMIT(dq); + } + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_QUOTA_TYPE: + /* we use id.gid == 0 for default quotas */ + if ((id.gid==DEFAULT_QUOTA_GID(handle)) && + DEFAULT_QUOTA_GID_NOLIMIT(handle)) { + SMB_QUOTAS_SET_NO_LIMIT(dq); + } + break; +#endif /* HAVE_GROUP_QUOTA */ + case SMB_USER_FS_QUOTA_TYPE: + { + unid_t qid; + uint32_t qflags = dq->qflags; + qid.uid = DEFAULT_QUOTA_UID(handle); + SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, + SMB_USER_QUOTA_TYPE, qid, dq); + dq->qflags = qflags; + } + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + { + unid_t qid; + uint32_t qflags = dq->qflags; + qid.gid = DEFAULT_QUOTA_GID(handle); + SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, + SMB_GROUP_QUOTA_TYPE, + qid, dq); + dq->qflags = qflags; + } + break; +#endif /* HAVE_GROUP_QUOTA */ + default: + errno = ENOSYS; + return -1; + break; + } + + return ret; +} + +static int default_quota_set_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) +{ + int ret = -1; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + /* we use id.uid == 0 for default quotas */ + if ((id.uid==DEFAULT_QUOTA_UID(handle)) && + DEFAULT_QUOTA_UID_NOLIMIT(handle)) { + return -1; + } + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_QUOTA_TYPE: + /* we use id.gid == 0 for default quotas */ + if ((id.gid==DEFAULT_QUOTA_GID(handle)) && + DEFAULT_QUOTA_GID_NOLIMIT(handle)) { + return -1; + } + break; +#endif /* HAVE_GROUP_QUOTA */ + case SMB_USER_FS_QUOTA_TYPE: + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + break; +#endif /* HAVE_GROUP_QUOTA */ + default: + errno = ENOSYS; + return -1; + break; + } + + if ((ret=SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, dq))!=0) { + return ret; + } + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_QUOTA_TYPE: + break; +#endif /* HAVE_GROUP_QUOTA */ + case SMB_USER_FS_QUOTA_TYPE: + { + unid_t qid; + qid.uid = DEFAULT_QUOTA_UID(handle); + ret = SMB_VFS_NEXT_SET_QUOTA(handle, SMB_USER_QUOTA_TYPE, qid, dq); + } + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + { + unid_t qid; + qid.gid = DEFAULT_QUOTA_GID(handle); + ret = SMB_VFS_NEXT_SET_QUOTA(handle, SMB_GROUP_QUOTA_TYPE, qid, dq); + } + break; +#endif /* HAVE_GROUP_QUOTA */ + default: + errno = ENOSYS; + return -1; + break; + } + + return ret; +} + +static struct vfs_fn_pointers vfs_default_quota_fns = { + .get_quota_fn = default_quota_get_quota, + .set_quota_fn = default_quota_set_quota +}; + +static_decl_vfs; +NTSTATUS vfs_default_quota_init(TALLOC_CTX *ctx) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, DEFAULT_QUOTA_NAME, + &vfs_default_quota_fns); +} -- cgit v1.2.3