Module Name:    src
Committed By:   elad
Date:           Thu May  7 19:26:09 UTC 2009

Modified Files:
        src/share/man/man9: kauth.9
        src/sys/secmodel/bsd44: secmodel_bsd44_suser.c
        src/sys/sys: kauth.h
        src/sys/ufs/ext2fs: ext2fs_alloc.c
        src/sys/ufs/ffs: ffs_alloc.c
        src/sys/ufs/ufs: ufs_quota.c ufs_vfsops.c

Log Message:
Introduce several actions/requests for authorizing file-system related
operations, specifically quota and block allocation from reserved space.

Modify ufs_quotactl() to accomodate passing "mp" earlier by vfs_busy()ing
it a little bit higher.

Mailing list reference:

        http://mail-index.netbsd.org/tech-kern/2009/04/26/msg004936.html

Note that the umapfs request mentioned in this thread was NOT added as
there is still on-going discussion regarding the proper implementation.


To generate a diff of this commit:
cvs rdiff -u -r1.82 -r1.83 src/share/man/man9/kauth.9
cvs rdiff -u -r1.65 -r1.66 src/sys/secmodel/bsd44/secmodel_bsd44_suser.c
cvs rdiff -u -r1.57 -r1.58 src/sys/sys/kauth.h
cvs rdiff -u -r1.38 -r1.39 src/sys/ufs/ext2fs/ext2fs_alloc.c
cvs rdiff -u -r1.123 -r1.124 src/sys/ufs/ffs/ffs_alloc.c
cvs rdiff -u -r1.61 -r1.62 src/sys/ufs/ufs/ufs_quota.c
cvs rdiff -u -r1.39 -r1.40 src/sys/ufs/ufs/ufs_vfsops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man9/kauth.9
diff -u src/share/man/man9/kauth.9:1.82 src/share/man/man9/kauth.9:1.83
--- src/share/man/man9/kauth.9:1.82	Thu May  7 18:01:56 2009
+++ src/share/man/man9/kauth.9	Thu May  7 19:26:08 2009
@@ -1,4 +1,4 @@
-.\" $NetBSD: kauth.9,v 1.82 2009/05/07 18:01:56 elad Exp $
+.\" $NetBSD: kauth.9,v 1.83 2009/05/07 19:26:08 elad Exp $
 .\"
 .\" Copyright (c) 2005, 2006 Elad Efrat <[email protected]>
 .\" All rights reserved.
@@ -203,6 +203,37 @@
 .El
 .It Dv KAUTH_SYSTEM_FILEHANDLE
 Check if filehandle operations allowed.
+.It Dv KAUTH_SYSTEM_FS_QUOTA
+Check if file-system quota operations are allowed.
+.Pp
+.Ar arg1
+is a
+.Ft struct mount *
+describing the file-system mount in question.
+.Ar req
+can be one of the following:
+.Bl -tag -width compact
+.It Dv KAUTH_REQ_SYSTEM_FS_QUOTA_GET
+Check if retrieving quota information is allowed.
+.Pp
+.Ar arg2
+is a
+.Ft uid_t
+with the user-id of the user whose quota information is to be retrieved.
+.It Dv KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF
+Check if turning quota on/off is allowed.
+.It Dv KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE
+Check if managing the quota by setting the quota/quota use is allowed.
+.Pp
+.Ar arg2
+is a
+.Ft uid_t
+with the user-id of the user whose quota/quota use is to be set.
+.It Dv KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT
+Check if bypassing the quota (not enforcing it) is allwoed.
+.El
+.It Dv KAUTH_SYSTEM_FS_RESERVEDSPACE
+Check if using the file-system reserved space is allowed.
 .It Dv KAUTH_SYSTEM_MODULE
 Check if a module request is allowed.
 .Pp

Index: src/sys/secmodel/bsd44/secmodel_bsd44_suser.c
diff -u src/sys/secmodel/bsd44/secmodel_bsd44_suser.c:1.65 src/sys/secmodel/bsd44/secmodel_bsd44_suser.c:1.66
--- src/sys/secmodel/bsd44/secmodel_bsd44_suser.c:1.65	Thu May  7 18:01:56 2009
+++ src/sys/secmodel/bsd44/secmodel_bsd44_suser.c	Thu May  7 19:26:09 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: secmodel_bsd44_suser.c,v 1.65 2009/05/07 18:01:56 elad Exp $ */
+/* $NetBSD: secmodel_bsd44_suser.c,v 1.66 2009/05/07 19:26:09 elad Exp $ */
 /*-
  * Copyright (c) 2006 Elad Efrat <[email protected]>
  * All rights reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_suser.c,v 1.65 2009/05/07 18:01:56 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_suser.c,v 1.66 2009/05/07 19:26:09 elad Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -172,6 +172,27 @@
 
 		break;
 
+	case KAUTH_SYSTEM_FS_QUOTA:
+		switch (req) {
+		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
+		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
+		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
+		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
+			if (isroot)
+				result = KAUTH_RESULT_ALLOW;
+			break;
+
+		default:
+			break;
+		}
+
+		break;
+
+	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
+		if (isroot)
+			result = KAUTH_RESULT_ALLOW;
+		break;
+
 	case KAUTH_SYSTEM_MOUNT:
 		switch (req) {
 		case KAUTH_REQ_SYSTEM_MOUNT_GET:

Index: src/sys/sys/kauth.h
diff -u src/sys/sys/kauth.h:1.57 src/sys/sys/kauth.h:1.58
--- src/sys/sys/kauth.h:1.57	Thu May  7 18:01:56 2009
+++ src/sys/sys/kauth.h	Thu May  7 19:26:08 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: kauth.h,v 1.57 2009/05/07 18:01:56 elad Exp $ */
+/* $NetBSD: kauth.h,v 1.58 2009/05/07 19:26:08 elad Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Elad Efrat <[email protected]>  
@@ -94,7 +94,9 @@
 	KAUTH_SYSTEM_SWAPCTL,
 	KAUTH_SYSTEM_SYSCTL,
 	KAUTH_SYSTEM_TIME,
-	KAUTH_SYSTEM_MODULE
+	KAUTH_SYSTEM_MODULE,
+	KAUTH_SYSTEM_FS_RESERVEDSPACE,
+	KAUTH_SYSTEM_FS_QUOTA,
 };
 
 /*
@@ -122,7 +124,11 @@
 	KAUTH_REQ_SYSTEM_TIME_NTPADJTIME,
 	KAUTH_REQ_SYSTEM_TIME_RTCOFFSET,
 	KAUTH_REQ_SYSTEM_TIME_SYSTEM,
-	KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS
+	KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS,
+	KAUTH_REQ_SYSTEM_FS_QUOTA_GET,
+	KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE,
+	KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT,
+	KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF,
 };	
 
 /*

Index: src/sys/ufs/ext2fs/ext2fs_alloc.c
diff -u src/sys/ufs/ext2fs/ext2fs_alloc.c:1.38 src/sys/ufs/ext2fs/ext2fs_alloc.c:1.39
--- src/sys/ufs/ext2fs/ext2fs_alloc.c:1.38	Sun Jan 11 02:45:56 2009
+++ src/sys/ufs/ext2fs/ext2fs_alloc.c	Thu May  7 19:26:08 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_alloc.c,v 1.38 2009/01/11 02:45:56 christos Exp $	*/
+/*	$NetBSD: ext2fs_alloc.c,v 1.39 2009/05/07 19:26:08 elad Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_alloc.c,v 1.38 2009/01/11 02:45:56 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_alloc.c,v 1.39 2009/05/07 19:26:08 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -128,7 +128,8 @@
 #endif /* DIAGNOSTIC */
 	if (fs->e2fs.e2fs_fbcount == 0)
 		goto nospace;
-	if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) != 0 &&
+	if (kauth_authorize_system(cred, KAUTH_SYSTEM_FS_RESERVEDSPACE, 0, NULL,
+	    NULL, NULL) != 0 &&
 	    freespace(fs) <= 0)
 		goto nospace;
 	if (bpref >= fs->e2fs.e2fs_bcount)

Index: src/sys/ufs/ffs/ffs_alloc.c
diff -u src/sys/ufs/ffs/ffs_alloc.c:1.123 src/sys/ufs/ffs/ffs_alloc.c:1.124
--- src/sys/ufs/ffs/ffs_alloc.c:1.123	Sat Apr 25 08:32:32 2009
+++ src/sys/ufs/ffs/ffs_alloc.c	Thu May  7 19:26:09 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffs_alloc.c,v 1.123 2009/04/25 08:32:32 sborrill Exp $	*/
+/*	$NetBSD: ffs_alloc.c,v 1.124 2009/05/07 19:26:09 elad Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.123 2009/04/25 08:32:32 sborrill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.124 2009/05/07 19:26:09 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -216,7 +216,8 @@
 	if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0)
 		goto nospace;
 	if (freespace(fs, fs->fs_minfree) <= 0 &&
-	    kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) != 0)
+	    kauth_authorize_system(cred, KAUTH_SYSTEM_FS_RESERVEDSPACE, 0, NULL,
+	    NULL, NULL) != 0)
 		goto nospace;
 #ifdef QUOTA
 	mutex_exit(&ump->um_lock);
@@ -323,7 +324,8 @@
 		panic("ffs_realloccg: missing credential");
 #endif /* DIAGNOSTIC */
 	if (freespace(fs, fs->fs_minfree) <= 0 &&
-	    kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) != 0) {
+	    kauth_authorize_system(cred, KAUTH_SYSTEM_FS_RESERVEDSPACE, 0, NULL,
+	    NULL, NULL) != 0) {
 		mutex_exit(&ump->um_lock);
 		goto nospace;
 	}

Index: src/sys/ufs/ufs/ufs_quota.c
diff -u src/sys/ufs/ufs/ufs_quota.c:1.61 src/sys/ufs/ufs/ufs_quota.c:1.62
--- src/sys/ufs/ufs/ufs_quota.c:1.61	Sun Dec 21 10:48:10 2008
+++ src/sys/ufs/ufs/ufs_quota.c	Thu May  7 19:26:09 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_quota.c,v 1.61 2008/12/21 10:48:10 ad Exp $	*/
+/*	$NetBSD: ufs_quota.c,v 1.62 2009/05/07 19:26:09 elad Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.61 2008/12/21 10:48:10 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.62 2009/05/07 19:26:09 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -221,7 +221,8 @@
 		return (0);
 	}
 	if ((flags & FORCE) == 0 &&
-	    kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) != 0) {
+	    kauth_authorize_system(cred, KAUTH_SYSTEM_FS_QUOTA,
+	    KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, NULL, NULL, NULL) != 0) {
 		for (i = 0; i < MAXQUOTAS; i++) {
 			if ((dq = ip->i_dquot[i]) == NODQUOT)
 				continue;
@@ -325,8 +326,9 @@
 		}
 		return (0);
 	}
-	if ((flags & FORCE) == 0 && kauth_authorize_generic(cred,
-	    KAUTH_GENERIC_ISSUSER, NULL) != 0) {
+	if ((flags & FORCE) == 0 && kauth_authorize_system(cred,
+	    KAUTH_SYSTEM_FS_QUOTA, KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, NULL,
+	    NULL, NULL) != 0) {
 		for (i = 0; i < MAXQUOTAS; i++) {
 			if ((dq = ip->i_dquot[i]) == NODQUOT)
 				continue;

Index: src/sys/ufs/ufs/ufs_vfsops.c
diff -u src/sys/ufs/ufs/ufs_vfsops.c:1.39 src/sys/ufs/ufs/ufs_vfsops.c:1.40
--- src/sys/ufs/ufs/ufs_vfsops.c:1.39	Tue May  6 18:43:45 2008
+++ src/sys/ufs/ufs/ufs_vfsops.c	Thu May  7 19:26:09 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_vfsops.c,v 1.39 2008/05/06 18:43:45 ad Exp $	*/
+/*	$NetBSD: ufs_vfsops.c,v 1.40 2009/05/07 19:26:09 elad Exp $	*/
 
 /*
  * Copyright (c) 1991, 1993, 1994
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.39 2008/05/06 18:43:45 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.40 2009/05/07 19:26:09 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -117,25 +117,55 @@
 		uid = kauth_cred_getuid(l->l_cred);
 	cmd = cmds >> SUBCMDSHIFT;
 
+	/* Mark the mount busy, as we're passing it to kauth(9). */
+	error = vfs_busy(mp, NULL);
+	if (error)
+		return (error);
+
 	switch (cmd) {
 	case Q_SYNC:
 		break;
+
 	case Q_GETQUOTA:
+		/* The user can always query about his own quota. */
 		if (uid == kauth_cred_getuid(l->l_cred))
 			break;
-		/* fall through */
+
+		error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA,
+		    KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, KAUTH_ARG(uid), NULL);
+
+		break;
+
+	case Q_QUOTAON:
+	case Q_QUOTAOFF:
+		error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA,
+		    KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF, mp, NULL, NULL);
+
+		break;
+
+	case Q_SETQUOTA:
+	case Q_SETUSE:
+		error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA,
+		    KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE, mp, KAUTH_ARG(uid), NULL);
+
+		break;
+
 	default:
-		if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
-		    NULL)) != 0)
-			return (error);
+		error = EINVAL;
+		break;
 	}
 
 	type = cmds & SUBCMDMASK;
-	if ((u_int)type >= MAXQUOTAS)
-		return (EINVAL);
-	error = vfs_busy(mp, NULL);
-	if (error != 0)
+	if (!error) {
+		/* Only check if there was no error above. */
+		if ((u_int)type >= MAXQUOTAS)
+			error = EINVAL;
+	}
+
+	if (error) {
+		vfs_unbusy(mp, false, NULL);
 		return (error);
+	}
 
 	mutex_enter(&mp->mnt_updating);
 	switch (cmd) {

Reply via email to