Exemplo n.º 1
0
void *
needchk(struct fstab *fs)
{
	struct quotaname *qnp;
	char *qfnp;

	if (strcmp(fs->fs_vfstype, "ufs") ||
	    strcmp(fs->fs_type, FSTAB_RW))
		return (NULL);
	if ((qnp = malloc(sizeof(*qnp))) == NULL)
		errx(1, "malloc failed");
	qnp->flags = 0;
	if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) {
		strcpy(qnp->grpqfname, qfnp);
		qnp->flags |= HASGRP;
	}
	if (uflag && hasquota(fs, USRQUOTA, &qfnp)) {
		strcpy(qnp->usrqfname, qfnp);
		qnp->flags |= HASUSR;
	}
	if (qnp->flags)
		return (qnp);
	free(qnp);
	return (NULL);
}
Exemplo n.º 2
0
void *
needchk(struct fstab *fs)
{
	struct quotaname *qnp;
	char *qfnp;

	if (fs->fs_passno == 0)
		return NULL;
	if (strcmp(fs->fs_type, FSTAB_RW))
		return (NULL);
	if (strcmp(fs->fs_vfstype, "ffs") &&
	    strcmp(fs->fs_vfstype, "ufs") &&
	    strcmp(fs->fs_vfstype, "mfs"))
		return (NULL);
	if ((qnp = malloc(sizeof(*qnp))) == NULL)
		err(1, "%s", strerror(errno));
	qnp->flags = 0;
	if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) {
		strlcpy(qnp->grpqfname, qfnp, sizeof qnp->grpqfname);
		qnp->flags |= HASGRP;
	}
	if (uflag && hasquota(fs, USRQUOTA, &qfnp)) {
		strlcpy(qnp->usrqfname, qfnp, sizeof qnp->usrqfname);
		qnp->flags |= HASUSR;
	}
	if (qnp->flags)
		return (qnp);
	free(qnp);
	return (NULL);
}
Exemplo n.º 3
0
void displayquota(Quota * const quota_)
{
    Quota quota;
    double pct;

    if (hasquota() != 0) {
        return;
    }
    if (quota_ == NULL) {
        if (quota_update(&quota, 0LL, 0LL, NULL) != 0) {
            return;
        }
    } else {
        quota = *quota_;
    }
    if (user_quota_files < ULONG_LONG_MAX) {
        pct = (double) quota.files * 100.0 / (double) user_quota_files;
        addreply(0, MSG_QUOTA_FILES, quota.files, (int) pct,
                 (unsigned long long) user_quota_files);
    }
    if (user_quota_size < ULONG_LONG_MAX) {
        pct = (double) quota.size * 100.0 / (double) user_quota_size;
        addreply(0, MSG_QUOTA_SIZE,
                 quota.size / 1024ULL, (int) pct,
                 (unsigned long long) user_quota_size / 1024ULL);
    }
}
Exemplo n.º 4
0
int quota_update(Quota *quota,
                 const long long files_add,
                 const long long size_add,
                 int *overflow)
{
    int fd;
    Quota old_quota = { 0ULL, 0ULL };
    Quota dummy_quota;
    struct flock lock;
    ssize_t readnb;
    int err = -1;
    char buf[84];
    char *bufpnt = buf;
    int dummy_overflow;
    ssize_t left = (ssize_t) (sizeof buf - 1U);
    size_t buf_len;

    if (hasquota() != 0 || chrooted == 0) {
        return -2;
    }
    if (overflow == NULL) {
        overflow = &dummy_overflow;
    }
    if (quota == NULL) {
        quota = &dummy_quota;
    }
    *overflow = 0;
    *quota = old_quota;
    if ((fd = open("/" QUOTA_FILE, O_RDWR | O_CREAT | O_NOFOLLOW,
                   (mode_t) 0600)) == -1) {
        return -1;
    }
    lock.l_whence = SEEK_SET;
    lock.l_start = (off_t) 0;
    lock.l_len = (off_t) 0;
    lock.l_pid = getpid();
    lock.l_type = F_WRLCK;
    while (fcntl(fd, F_SETLKW, &lock) < 0) {
        if (errno != EINTR) {
            goto byenounlock;
        }
    }
    do {
        while ((readnb = read(fd, bufpnt, left)) < (ssize_t) 0 &&
               errno == EINTR);
        if (readnb < (ssize_t) 0) {
            goto bye;
        }
        bufpnt += readnb;
        left -= readnb;
    } while (left > (ssize_t) 0 && readnb != (ssize_t) 0);
    *bufpnt = 0;
    if ((bufpnt = strchr(buf, ' ')) == NULL) {
        goto skipparse;
    }
    *bufpnt = 0;
    old_quota.files = quota->files = strtoull(buf, NULL, 10);
    old_quota.size = quota->size = strtoull(bufpnt + 1, NULL, 10);
    skipparse:
    if ((files_add | size_add) == 0LL) {
        goto okbye;
    }
    if (files_add < 0LL) {
        if (quota->files > (unsigned long long) -files_add) {
            quota->files -= (unsigned long long) (-files_add);
        } else {
            quota->files = 0ULL;
        }
    } else if (files_add >= 0LL) {
        quota->files += (unsigned long long) files_add;
        if (quota->files > user_quota_files) {
            *overflow = 1;
        }
    }
    if (size_add < 0LL) {
        if (quota->size > (unsigned long long) -size_add) {
            quota->size -= (unsigned long long) (-size_add);
        } else {
            quota->size = 0ULL;
        }
    } else if (size_add >= 0LL) {
        quota->size += size_add;
        if (quota->size > user_quota_size) {
            *overflow = 2;
        }
    }
    if ((old_quota.size != quota->size || old_quota.files != quota->files) &&
        !SNCHECK(snprintf(buf, sizeof buf, "%llu %llu\n",
                          quota->files, quota->size), sizeof buf) &&
        lseek(fd, (off_t) 0, SEEK_SET) != (off_t) -1 &&
        ftruncate(fd, (off_t) 0) == 0) {

        buf_len = strlen(buf);
        if (safe_write(fd, buf, buf_len, -1) != (ssize_t) buf_len) {
            (void) ftruncate(fd, (off_t) 0);
            goto bye;
        }
    }
    okbye:
    err = 0;

    bye:
    lock.l_type = F_UNLCK;
    while (fcntl(fd, F_SETLK, &lock) < 0 && errno == EINTR);
    byenounlock:
    close(fd);

    return err;
}
Exemplo n.º 5
0
/*
 * Collect the requested quota information.
 */
struct quotause *
getprivs(long id, int quotatype, char *fspath)
{
	struct fstab *fs;
	struct quotause *qup, *quptail;
	struct quotause *quphead;
	int qcmd, qupsize, fd;
	char *qfpathname;
	static int warned = 0;

	setfsent();
	quphead = quptail = NULL;
	qcmd = QCMD(Q_GETQUOTA, quotatype);
	while ((fs = getfsent())) {
		if (fspath && *fspath && strcmp(fspath, fs->fs_spec) &&
		    strcmp(fspath, fs->fs_file))
			continue;
		if (strcmp(fs->fs_vfstype, "ufs"))
			continue;
		if (!hasquota(fs, quotatype, &qfpathname))
			continue;
		qupsize = sizeof(*qup) + strlen(qfpathname);
		if ((qup = (struct quotause *)malloc(qupsize)) == NULL)
			errx(2, "out of memory");
		if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) {
	    		if (errno == EOPNOTSUPP && !warned) {
				warned++;
		warnx("warning: quotas are not compiled into this kernel");
				sleep(3);
			}
			if ((fd = open(qfpathname, O_RDONLY)) < 0) {
				fd = open(qfpathname, O_RDWR|O_CREAT, 0640);
				if (fd < 0 && errno != ENOENT) {
					warn("%s", qfpathname);
					free(qup);
					continue;
				}
				warnx("creating quota file %s", qfpathname);
				sleep(3);
				fchown(fd, getuid(),
				    getentry(quotagroup, GRPQUOTA));
				fchmod(fd, 0640);
			}
			lseek(fd, (long)(id * sizeof(struct ufs_dqblk)), L_SET);
			switch (read(fd, &qup->dqblk, sizeof(struct ufs_dqblk))) {
			case 0:			/* EOF */
				/*
				 * Convert implicit 0 quota (EOF)
				 * into an explicit one (zero'ed dqblk)
				 */
				bzero((caddr_t)&qup->dqblk,
				    sizeof(struct ufs_dqblk));
				break;

			case sizeof(struct ufs_dqblk):	/* OK */
				break;

			default:		/* ERROR */
				warn("read error in %s", qfpathname);
				close(fd);
				free(qup);
				continue;
			}
			close(fd);
		}
		strcpy(qup->qfname, qfpathname);
		strcpy(qup->fsname, fs->fs_file);
		if (quphead == NULL)
			quphead = qup;
		else
			quptail->next = qup;
		quptail = qup;
		qup->next = NULL;
	}
	endfsent();
	return (quphead);
}
Exemplo n.º 6
0
int
main(int argc, char **argv)
{
	struct fstab *fs;
	struct passwd *pw;
	struct group *gr;
	int gflag = 0, uflag = 0, errs = 0;
	long i, argnum, done = 0;
	char ch, *qfnp;

	while ((ch = getopt(argc, argv, "aguv")) != -1) {
		switch(ch) {
		case 'a':
			aflag++;
			break;
		case 'g':
			gflag++;
			break;
		case 'u':
			uflag++;
			break;
		case 'v':
			vflag++;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (argc == 0 && !aflag)
		usage();
	if (!gflag && !uflag) {
		if (aflag)
			gflag++;
		uflag++;
	}
	if (gflag) {
		setgrent();
		while ((gr = getgrent()) != 0)
			addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name);
		endgrent();
	}
	if (uflag) {
		setpwent();
		while ((pw = getpwent()) != 0)
			addid((u_long)pw->pw_uid, USRQUOTA, pw->pw_name);
		endpwent();
	}
	setfsent();
	while ((fs = getfsent()) != NULL) {
		if (strcmp(fs->fs_vfstype, "ufs"))
			continue;
		if (aflag) {
			if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
				errs += repquota(fs, GRPQUOTA, qfnp);
			if (uflag && hasquota(fs, USRQUOTA, &qfnp))
				errs += repquota(fs, USRQUOTA, qfnp);
			continue;
		}
		if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
		    (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
			done |= 1 << argnum;
			if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
				errs += repquota(fs, GRPQUOTA, qfnp);
			if (uflag && hasquota(fs, USRQUOTA, &qfnp))
				errs += repquota(fs, USRQUOTA, qfnp);
		}
	}
	endfsent();
	for (i = 0; i < argc; i++)
		if ((done & (1 << i)) == 0)
			warnx("%s not found in fstab", argv[i]);
	exit(errs);
}
Exemplo n.º 7
0
struct quotafile *
quota_open(struct fstab *fs, int quotatype, int openflags)
{
	struct quotafile *qf;
	struct dqhdr64 dqh;
	struct group *grp;
	struct stat st;
	int qcmd, serrno;

	if (strcmp(fs->fs_vfstype, "ufs"))
		return (NULL);
	if ((qf = calloc(1, sizeof(*qf))) == NULL)
		return (NULL);
	qf->fd = -1;
	qf->quotatype = quotatype;
	strncpy(qf->fsname, fs->fs_file, sizeof(qf->fsname));
	if (stat(qf->fsname, &st) != 0)
		goto error;
	qf->dev = st.st_dev;
	serrno = hasquota(fs, quotatype, qf->qfname, sizeof(qf->qfname));
	qcmd = QCMD(Q_GETQUOTASIZE, quotatype);
	if (quotactl(qf->fsname, qcmd, 0, &qf->wordsize) == 0)
		return (qf);
	if (serrno == 0) {
		errno = EOPNOTSUPP;
		goto error;
	}
	qf->accmode = openflags & O_ACCMODE;
	if ((qf->fd = open(qf->qfname, qf->accmode)) < 0 &&
	    (openflags & O_CREAT) != O_CREAT)
		goto error;
	/* File open worked, so process it */
	if (qf->fd != -1) {
		qf->wordsize = 32;
		switch (read(qf->fd, &dqh, sizeof(dqh))) {
		case -1:
			goto error;
		case sizeof(dqh):
			if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) != 0) {
				/* no magic, assume 32 bits */
				qf->wordsize = 32;
				return (qf);
			}
			if (be32toh(dqh.dqh_version) != Q_DQHDR64_VERSION ||
			    be32toh(dqh.dqh_hdrlen) != sizeof(struct dqhdr64) ||
			    be32toh(dqh.dqh_reclen) != sizeof(struct dqblk64)) {
				/* correct magic, wrong version / lengths */
				errno = EINVAL;
				goto error;
			}
			qf->wordsize = 64;
			return (qf);
		default:
			qf->wordsize = 32;
			return (qf);
		}
		/* not reached */
	}
	/* open failed, but O_CREAT was specified, so create a new file */
	if ((qf->fd = open(qf->qfname, O_RDWR|O_CREAT|O_TRUNC, 0)) < 0)
		goto error;
	qf->wordsize = 64;
	memset(&dqh, 0, sizeof(dqh));
	memcpy(dqh.dqh_magic, Q_DQHDR64_MAGIC, sizeof(dqh.dqh_magic));
	dqh.dqh_version = htobe32(Q_DQHDR64_VERSION);
	dqh.dqh_hdrlen = htobe32(sizeof(struct dqhdr64));
	dqh.dqh_reclen = htobe32(sizeof(struct dqblk64));
	if (write(qf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) {
		/* it was one we created ourselves */
		unlink(qf->qfname);
		goto error;
	}
	grp = getgrnam(QUOTAGROUP);
	fchown(qf->fd, 0, grp ? grp->gr_gid : 0);
	fchmod(qf->fd, 0640);
	return (qf);
error:
	serrno = errno;
	/* did we have an open file? */
	if (qf->fd != -1)
		close(qf->fd);
	free(qf);
	errno = serrno;
	return (NULL);
}
Exemplo n.º 8
0
/*
 * Collect the requested quota information.
 */
struct quotause *
getprivs(u_int id, int quotatype)
{
	struct fstab *fs;
	struct quotause *qup, *quptail;
	struct quotause *quphead;
	int qcmd, qupsize, fd;
	u_int mid;
	char *qfpathname;
	static int warned = 0;
	size_t qfpathnamelen;

	setfsent();
	quphead = NULL;
	qcmd = QCMD(Q_GETQUOTA, quotatype);
	while ((fs = getfsent())) {
		if (strcmp(fs->fs_vfstype, "ffs") &&
		    strcmp(fs->fs_vfstype, "ufs") &&
		    strcmp(fs->fs_vfstype, "mfs"))
			continue;
		if (!hasquota(fs, quotatype, &qfpathname))
			continue;
		qfpathnamelen = strlen(qfpathname);
		qupsize = sizeof(*qup) + qfpathnamelen;
		if ((qup = (struct quotause *)malloc(qupsize)) == NULL)
			errx(2, "out of memory");
		if (quotactl(fs->fs_file, qcmd, id, (char *)&qup->dqblk) != 0) {
	    		if (errno == EOPNOTSUPP && !warned) {
				warned++;
				(void)fprintf(stderr, "Warning: %s\n",
				    "Quotas are not compiled into this kernel");
				sleep(3);
			}
			if (getentry(quotagroup, GRPQUOTA, &mid) == -1) {
				warned++;
				(void)fprintf(stderr, "Warning: "
				    "group %s not known, skipping %s\n",
				    quotagroup, fs->fs_file);
			}
			if ((fd = open(qfpathname, O_RDONLY)) < 0) {
				fd = open(qfpathname, O_RDWR|O_CREAT, 0640);
				if (fd < 0 && errno != ENOENT) {
					perror(qfpathname);
					free(qup);
					continue;
				}
				(void)fprintf(stderr, "Creating quota file %s\n",
				    qfpathname);
				sleep(3);
				(void)fchown(fd, getuid(), mid);
				(void)fchmod(fd, 0640);
			}
			lseek(fd, (off_t)(id * sizeof(struct dqblk)), SEEK_SET);
			switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) {
			case 0:			/* EOF */
				/*
				 * Convert implicit 0 quota (EOF)
				 * into an explicit one (zero'ed dqblk)
				 */
				bzero((caddr_t)&qup->dqblk,
				    sizeof(struct dqblk));
				break;

			case sizeof(struct dqblk):	/* OK */
				break;

			default:		/* ERROR */
				warn("read error in %s", qfpathname);
				close(fd);
				free(qup);
				continue;
			}
			close(fd);
		}
		strlcpy(qup->qfname, qfpathname, qfpathnamelen + 1);
		strlcpy(qup->fsname, fs->fs_file, sizeof qup->fsname);
		if (quphead == NULL)
			quphead = qup;
		else
			quptail->next = qup;
		quptail = qup;
		qup->next = NULL;
	}
	endfsent();
	return(quphead);
}