From 428653ef7257240e9318f5fed71869f0124ff379 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 29 Jul 2003 18:07:13 +0000 Subject: Add NT quotas support. Users allowed now to manage quotas on systems with sysquotas interface detected (Linux at least) using native Windows tools. Also move default quota support for NT quotas to VFS module default_quota. Code by Metze (This used to be commit e856a96c2c42c39843e5e1a3a6b0d538e7179900) --- source3/modules/vfs_default_quota.c | 180 ++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 source3/modules/vfs_default_quota.c (limited to 'source3/modules') diff --git a/source3/modules/vfs_default_quota.c b/source3/modules/vfs_default_quota.c new file mode 100644 index 0000000000..1294a51533 --- /dev/null +++ b/source3/modules/vfs_default_quota.c @@ -0,0 +1,180 @@ +/* + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + +#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, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) +{ + int ret = -1; + + if ((ret=SMB_VFS_NEXT_GET_QUOTA(handle, conn, 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 qflags = dq->qflags; + qid.uid = DEFAULT_QUOTA_UID(handle); + SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq); + dq->qflags = qflags; + } + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + { + unid_t qid; + uint32 qflags = dq->qflags; + qid.gid = DEFAULT_QUOTA_GID(handle); + SMB_VFS_NEXT_GET_QUOTA(handle, conn, 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, connection_struct *conn, 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, conn, 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, conn, 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, conn, SMB_GROUP_QUOTA_TYPE, qid, dq); + } + break; +#endif /* HAVE_GROUP_QUOTA */ + default: + errno = ENOSYS; + return -1; + break; + } + + return ret; +} + +/* VFS operations structure */ + +static vfs_op_tuple default_quota_ops[] = { + {SMB_VFS_OP(default_quota_get_quota), SMB_VFS_OP_GET_QUOTA, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(default_quota_set_quota), SMB_VFS_OP_SET_QUOTA, SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_default_quota_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, DEFAULT_QUOTA_NAME, default_quota_ops); +} -- cgit