diff options
Diffstat (limited to 'winsup/cygwin/quotactl.cc')
-rw-r--r-- | winsup/cygwin/quotactl.cc | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/winsup/cygwin/quotactl.cc b/winsup/cygwin/quotactl.cc deleted file mode 100644 index 96c6134e8..000000000 --- a/winsup/cygwin/quotactl.cc +++ /dev/null @@ -1,340 +0,0 @@ -/* quotactl.cc: code for manipulating disk quotas - - Copyright 2014 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include "winsup.h" -#include "cygtls.h" -#include "security.h" -#include "path.h" -#include "fhandler.h" -#include "dtable.h" -#include "cygheap.h" -#include "ntdll.h" -#include "tls_pbuf.h" -#include <sys/mount.h> -#include <sys/quota.h> - -#define PGQI_SIZE (sizeof (FILE_GET_QUOTA_INFORMATION) + SECURITY_MAX_SID_SIZE) -#define PFQI_SIZE (sizeof (FILE_QUOTA_INFORMATION) + SECURITY_MAX_SID_SIZE) - -/* Modelled after the Linux quotactl function. */ -extern "C" int -quotactl (int cmd, const char *special, int id, caddr_t addr) -{ - ACCESS_MASK access = FILE_READ_DATA; - cygsid sid; - path_conv pc; - tmp_pathbuf tp; - UNICODE_STRING path; - OBJECT_ATTRIBUTES attr; - NTSTATUS status; - HANDLE fh; - IO_STATUS_BLOCK io; - FILE_FS_CONTROL_INFORMATION ffci; - int ret = 0; - - uint32_t subcmd = (uint32_t) cmd >> SUBCMDSHIFT; - uint32_t type = (uint32_t) cmd & SUBCMDMASK; - - if (type != USRQUOTA && type != GRPQUOTA) - { - set_errno (EINVAL); - return -1; - } - switch (subcmd) - { - case Q_SYNC: - if (!special) - return 0; - access |= FILE_WRITE_DATA; - break; - case Q_QUOTAON: - if (id < QFMT_VFS_OLD || id > QFMT_VFS_V1) - { - set_errno (EINVAL); - return -1; - } - /*FALLTHRU*/ - case Q_QUOTAOFF: - case Q_SETINFO: - access |= FILE_WRITE_DATA; - break; - case Q_GETFMT: - case Q_GETINFO: - break; - case Q_SETQUOTA: - access |= FILE_WRITE_DATA; - /*FALLTHRU*/ - case Q_GETQUOTA: - /* Windows feature: Default limits. Get or set them with id == -1. */ - if (id != -1) - { - struct passwd *pw = NULL; - struct group *gr = NULL; - - if (type == USRQUOTA) - pw = internal_getpwuid (id); - else - gr = internal_getgrgid (id); - if (pw) - sid.getfrompw (pw); - else if (gr) - sid.getfromgr (gr); - else - { - set_errno (EINVAL); - return -1; - } - } - break; - default: - set_errno (EINVAL); - return -1; - } - /* Check path */ - pc.check (special, PC_SYM_FOLLOW | PC_NOWARN, stat_suffixes); - if (pc.error) - { - set_errno (pc.error); - return -1; - } - if (!pc.exists ()) - { - set_errno (ENOENT); - return -1; - } - if (!S_ISBLK (pc.dev.mode)) - { - set_errno (ENOTBLK); - return -1; - } - pc.get_object_attr (attr, sec_none_nih); - /* For the following functions to work, we must attach the virtual path to - the quota file to the device path. - - FIXME: Note that this is NTFS-specific. Adding ReFS in another step. */ - tp.u_get (&path); - RtlCopyUnicodeString (&path, attr.ObjectName); - RtlAppendUnicodeToString (&path, L"\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION"); - attr.ObjectName = &path; - - /* Open filesystem */ - status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_VALID_FLAGS, 0); - if (NT_SUCCESS (status)) - switch (subcmd) - { - case Q_SYNC: - /* No sync, just report success. */ - status = STATUS_SUCCESS; - break; - case Q_QUOTAON: - case Q_QUOTAOFF: - /* Ignore filename in addr. */ - status = NtQueryVolumeInformationFile (fh, &io, &ffci, sizeof ffci, - FileFsControlInformation); - if (!NT_SUCCESS (status)) - break; - ffci.FileSystemControlFlags &= ~FILE_VC_QUOTA_ENFORCE - & ~FILE_VC_QUOTA_TRACK - & ~FILE_VC_QUOTAS_INCOMPLETE - & ~FILE_VC_QUOTAS_REBUILDING; - if (subcmd == Q_QUOTAON) - ffci.FileSystemControlFlags |= FILE_VC_QUOTA_ENFORCE; - status = NtSetVolumeInformationFile (fh, &io, &ffci, sizeof ffci, - FileFsControlInformation); - break; - case Q_GETFMT: - __try - { - uint32_t *retval = (uint32_t *) addr; - - /* Always fake the latest format. */ - *retval = QFMT_VFS_V1; - } - __except (EFAULT) - { - ret = -1; - break; - } - __endtry - status = STATUS_SUCCESS; - break; - case Q_GETINFO: - __try - { - struct dqinfo *dqi = (struct dqinfo *) addr; - - dqi->dqi_bgrace = dqi->dqi_igrace = UINT64_MAX; - dqi->dqi_flags = 0; - dqi->dqi_valid = IIF_BGRACE | IIF_IGRACE; - } - __except (EFAULT) - { - ret = -1; - break; - } - __endtry - status = STATUS_SUCCESS; - break; - case Q_SETINFO: - /* No settings possible, just report success. */ - status = STATUS_SUCCESS; - break; - case Q_GETQUOTA: - /* Windows feature: Default limits. Get or set them with id == -1. */ - if (id == -1) - { - status = NtQueryVolumeInformationFile (fh, &io, &ffci, sizeof ffci, - FileFsControlInformation); - if (!NT_SUCCESS (status)) - break; - __try - { - struct dqblk *dq = (struct dqblk *) addr; - - dq->dqb_bhardlimit = (uint64_t) ffci.DefaultQuotaLimit.QuadPart; - if (dq->dqb_bhardlimit != UINT64_MAX) - dq->dqb_bhardlimit /= BLOCK_SIZE; - dq->dqb_bsoftlimit = - (uint64_t) ffci.DefaultQuotaThreshold.QuadPart; - if (dq->dqb_bsoftlimit != UINT64_MAX) - dq->dqb_bsoftlimit /= BLOCK_SIZE; - dq->dqb_curspace = 0; - dq->dqb_ihardlimit = UINT64_MAX; - dq->dqb_isoftlimit = UINT64_MAX; - dq->dqb_curinodes = 0; - dq->dqb_btime = UINT64_MAX; - dq->dqb_itime = UINT64_MAX; - dq->dqb_valid = QIF_BLIMITS; - } - __except (EFAULT) - { - ret = -1; - break; - } - __endtry - } - else - { - PFILE_GET_QUOTA_INFORMATION pgqi = (PFILE_GET_QUOTA_INFORMATION) - alloca (PGQI_SIZE); - PFILE_QUOTA_INFORMATION pfqi = (PFILE_QUOTA_INFORMATION) - alloca (PFQI_SIZE); - - pgqi->NextEntryOffset = 0; - pgqi->SidLength = RtlLengthSid (sid); - RtlCopySid (RtlLengthSid (sid), &pgqi->Sid, sid); - status = NtQueryQuotaInformationFile (fh, &io, pfqi, PFQI_SIZE, - TRUE, pgqi, PGQI_SIZE, - NULL, TRUE); - if (!NT_SUCCESS (status)) - break; - __try - { - struct dqblk *dq = (struct dqblk *) addr; - - dq->dqb_bhardlimit = (uint64_t) pfqi->QuotaLimit.QuadPart; - if (dq->dqb_bhardlimit != UINT64_MAX) - dq->dqb_bhardlimit /= BLOCK_SIZE; - dq->dqb_bsoftlimit = (uint64_t) pfqi->QuotaThreshold.QuadPart; - if (dq->dqb_bsoftlimit != UINT64_MAX) - dq->dqb_bsoftlimit /= BLOCK_SIZE; - dq->dqb_curspace = (uint64_t) pfqi->QuotaUsed.QuadPart; - if (dq->dqb_curspace != UINT64_MAX) - dq->dqb_curspace /= BLOCK_SIZE; - dq->dqb_ihardlimit = UINT64_MAX; - dq->dqb_isoftlimit = UINT64_MAX; - dq->dqb_curinodes = 0; - dq->dqb_btime = UINT64_MAX; - dq->dqb_itime = UINT64_MAX; - dq->dqb_valid = QIF_BLIMITS | QIF_SPACE; - } - __except (EFAULT) - { - ret = -1; - break; - } - __endtry - } - break; - case Q_SETQUOTA: - /* Windows feature: Default limits. Get or set them with id == -1. */ - if (id == -1) - { - status = NtQueryVolumeInformationFile (fh, &io, &ffci, sizeof ffci, - FileFsControlInformation); - if (!NT_SUCCESS (status)) - break; - __try - { - struct dqblk *dq = (struct dqblk *) addr; - - if (!(dq->dqb_valid & QIF_BLIMITS)) - break; - ffci.DefaultQuotaLimit.QuadPart = dq->dqb_bhardlimit; - if (ffci.DefaultQuotaLimit.QuadPart != -1) - ffci.DefaultQuotaLimit.QuadPart *= BLOCK_SIZE; - ffci.DefaultQuotaThreshold.QuadPart = dq->dqb_bsoftlimit; - if (ffci.DefaultQuotaThreshold.QuadPart != -1) - ffci.DefaultQuotaThreshold.QuadPart *= BLOCK_SIZE; - } - __except (EFAULT) - { - ret = -1; - break; - } - __endtry - status = NtSetVolumeInformationFile (fh, &io, &ffci, sizeof ffci, - FileFsControlInformation); - } - else - { - PFILE_GET_QUOTA_INFORMATION pgqi = (PFILE_GET_QUOTA_INFORMATION) - alloca (PGQI_SIZE); - PFILE_QUOTA_INFORMATION pfqi = (PFILE_QUOTA_INFORMATION) - alloca (PFQI_SIZE); - - pgqi->NextEntryOffset = 0; - pgqi->SidLength = RtlLengthSid (sid); - RtlCopySid (RtlLengthSid (sid), &pgqi->Sid, sid); - status = NtQueryQuotaInformationFile (fh, &io, pfqi, PFQI_SIZE, - TRUE, pgqi, PGQI_SIZE, - NULL, TRUE); - if (!NT_SUCCESS (status)) - break; - __try - { - struct dqblk *dq = (struct dqblk *) addr; - - if (!(dq->dqb_valid & QIF_BLIMITS)) - break; - pfqi->QuotaLimit.QuadPart = dq->dqb_bhardlimit; - if (pfqi->QuotaLimit.QuadPart != -1) - pfqi->QuotaLimit.QuadPart *= BLOCK_SIZE; - pfqi->QuotaThreshold.QuadPart = dq->dqb_bsoftlimit; - if (pfqi->QuotaThreshold.QuadPart != -1) - pfqi->QuotaThreshold.QuadPart *= BLOCK_SIZE; - } - __except (EFAULT) - { - ret = -1; - break; - } - __endtry - status = NtSetQuotaInformationFile (fh, &io, pfqi, PFQI_SIZE); - } - break; - } - if (!NT_SUCCESS (status)) - { - __seterrno_from_nt_status (status); - ret = -1; - } - return ret; -} |