DF-3243 / df3243.c
/* DF-3243: ufs_quotactl Q_GETQUOTA self-auth is quota-type-blind. * Usage: df3243 set <mnt> <gid> (root: install a distinctive group quota) * df3243 get <mnt> <id> (as a user: try to read group quota <id>) */ #include <sys/types.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/mount.h> #include <vfs/ufs/quota.h> static int getquota(const char *mnt, int type, long id) { struct ufs_dqblk dq; int rc; memset(&dq, 0, sizeof(dq)); errno = 0; rc = quotactl(mnt, QCMD(Q_GETQUOTA, type), (uid_t)id, (caddr_t)&dq); printf(" quotactl(QCMD(Q_GETQUOTA, %s), %s, %ld) = %d errno=%d (%s)\n", type == USRQUOTA ? "USRQUOTA" : "GRPQUOTA", mnt, id, rc, errno, rc ? strerror(errno) : "success"); if (rc == 0) printf(" -> dqb_bhardlimit=%u dqb_bsoftlimit=%u dqb_curblocks=%u\n", dq.dqb_bhardlimit, dq.dqb_bsoftlimit, dq.dqb_curblocks); return rc; } int main(int argc, char **argv) { if (!strcmp(argv[1], "set")) { struct ufs_dqblk dq; memset(&dq, 0, sizeof(dq)); dq.dqb_bhardlimit = 50000; /* 50MB, distinctive */ dq.dqb_bsoftlimit = 40000; dq.dqb_ihardlimit = 1000; printf("root: installing group quota gid=%s bhard=50000\n", argv[3]); return quotactl(argv[2], QCMD(Q_SETQUOTA, GRPQUOTA), (uid_t)atol(argv[3]), (caddr_t)&dq); } printf("uid=%d euid=%d\n", (int)getuid(), (int)geteuid()); int rc = getquota(argv[2], GRPQUOTA, atol(argv[3])); return (rc == 0) ? 2 : 0; /* reading a group record via uid match == bug */ } |