Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/cddl/osnet Take a first whack at making zfs permiss...
details: https://anonhg.NetBSD.org/src/rev/52e9ba28ba97
branches: trunk
changeset: 782149:52e9ba28ba97
user: riastradh <riastradh%NetBSD.org@localhost>
date: Thu Oct 18 14:22:57 2012 +0000
description:
Take a first whack at making zfs permissions work.
zfs_access uses secpolicy_vnode_access, so it makes no sense for the
latter to call VOP_ACCESS!
Everything seems to return EACCES instead of EPERM, probably because
that's what kauth returns. This should be fixed, but that may
require some nontrivial surgery to zfs's calls to secpolicy_*, which
is where kauth gets involved.
This commit imports some code from illumos to implement the routine
secpolicy_vnode_setattr. This shouldn't be outside dist/, but for
now it is expedient to do so. We ought to fix that, along with all
the other CDDL code outside dist/, when we next import a newer
version of zfs.
diffstat:
external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c | 49 ++-
external/cddl/osnet/sys/kern/policy.c | 228 +++++++++++++---
external/cddl/osnet/sys/sys/policy.h | 47 +-
3 files changed, 236 insertions(+), 88 deletions(-)
diffs (truncated from 492 to 300 lines):
diff -r 48e890f38f40 -r 52e9ba28ba97 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c Thu Oct 18 10:41:44 2012 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c Thu Oct 18 14:22:57 2012 +0000
@@ -1422,7 +1422,8 @@
* Create a new file object and update the directory
* to reference it.
*/
- if (error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr)) {
+ error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr);
+ if (error) {
goto out;
}
@@ -4779,22 +4780,34 @@
static int
zfs_netbsd_access(void *v)
{
- struct vop_access_args *ap = v;
+ struct vop_access_args /* {
+ struct vnode *a_vp;
+ int a_mode;
+ kauth_cred_t a_cred;
+ } */ *ap = v;
+ struct vnode *vp = ap->a_vp;
+ int mode = ap->a_mode;
+ mode_t zfs_mode = 0;
+ kauth_cred_t cred = ap->a_cred;
+ int error;
/*
- * ZFS itself only knowns about VREAD, VWRITE and VEXEC, the rest
- * we have to handle by calling vaccess().
+ * XXX This is really random, especially the left shift by six,
+ * and it exists only because of randomness in zfs_unix_to_v4
+ * and zfs_zaccess_rwx in zfs_acl.c.
*/
- if ((ap->a_mode & ~(VREAD|VWRITE|VEXEC)) != 0) {
- vnode_t *vp = ap->a_vp;
- znode_t *zp = VTOZ(vp);
- znode_phys_t *zphys = zp->z_phys;
-
- return (vaccess(vp->v_type, zphys->zp_mode, zphys->zp_uid,
- zphys->zp_gid, ap->a_mode, ap->a_cred));
- }
-
- return (zfs_access(ap->a_vp, ap->a_mode, 0, ap->a_cred, NULL));
+ if (mode & VREAD)
+ zfs_mode |= S_IROTH;
+ if (mode & VWRITE)
+ zfs_mode |= S_IWOTH;
+ if (mode & VEXEC)
+ zfs_mode |= S_IXOTH;
+ zfs_mode <<= 6;
+
+ KASSERT(VOP_ISLOCKED(vp));
+ error = zfs_access(vp, zfs_mode, 0, cred, NULL);
+
+ return (error);
}
static int
@@ -4849,13 +4862,19 @@
NULL, NULL);
/*
- * Translate errors to match our namei insanity.
+ * Translate errors to match our namei insanity. Also, if the
+ * caller wants to create an entry here, it's apparently our
+ * responsibility as lookup to make sure that's permissible.
+ * Go figure.
*/
if (cnp->cn_flags & ISLASTCN) {
switch (cnp->cn_nameiop) {
case CREATE:
case RENAME:
if (error == ENOENT) {
+ error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
+ if (error)
+ break;
error = EJUSTRETURN;
break;
}
diff -r 48e890f38f40 -r 52e9ba28ba97 external/cddl/osnet/sys/kern/policy.c
--- a/external/cddl/osnet/sys/kern/policy.c Thu Oct 18 10:41:44 2012 +0000
+++ b/external/cddl/osnet/sys/kern/policy.c Thu Oct 18 14:22:57 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: policy.c,v 1.3 2012/10/15 22:50:25 riastradh Exp $ */
+/* $NetBSD: policy.c,v 1.4 2012/10/18 14:22:58 riastradh Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -55,6 +55,31 @@
* SUCH DAMAGE.
*/
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, Joyent, Inc. All rights reserved.
+ */
+
#include <sys/param.h>
#include <sys/priv.h>
#include <sys/vnode.h>
@@ -84,7 +109,7 @@
}
int
-secpolicy_fs_mount(kauth_cred_t cred, vnode_t *mvp, struct mount *vfsp)
+secpolicy_fs_mount(kauth_cred_t cred, struct vnode *mvp, struct mount *vfsp)
{
return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT,
@@ -113,7 +138,7 @@
secpolicy_vnode_stky_modify(kauth_cred_t cred)
{
- return (EPERM);
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
}
int
@@ -125,80 +150,69 @@
int
-secpolicy_vnode_owner(cred_t *cred, uid_t owner)
+secpolicy_vnode_owner(kauth_cred_t cred, uid_t owner)
{
- uid_t uid;
- uid = crgetuid(cred);
-
- if (owner == uid)
- return (0);
+ if (owner == kauth_cred_getuid(cred))
+ return (0);
- return 0;
-// return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT,
-// KAUTH_REQ_SYSTEM_MOUNT_NEW, vfsp, NULL, NULL);
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
}
int
-secpolicy_vnode_access(kauth_cred_t cred, struct vnode *vp, uint64_t owner,
+secpolicy_vnode_access(kauth_cred_t cred, struct vnode *vp, uid_t owner,
int mode)
{
- (void)owner; /* XXX ignore? */
- KASSERT(VOP_ISLOCKED(vp));
- return VOP_ACCESS(vp, mode, cred);
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
}
-/*
- * Check privileges for setting xvattr attributes
- */
int
-secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype)
+secpolicy_xvattr(xvattr_t *xvap, uid_t owner, kauth_cred_t cred, vtype_t vtype)
{
-/* return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT,
- KAUTH_REQ_SYSTEM_MOUNT_UPDATE, vfsp, NULL, NULL);*/
- return 0;
+
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
}
int
secpolicy_vnode_setid_retain(kauth_cred_t cred, boolean_t issuidroot __unused)
{
- return (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL));
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
}
int
secpolicy_vnode_setids_setgids(kauth_cred_t cred, gid_t gid)
{
- if (!groupmember(gid, cred))
- return (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
- NULL));
- return (0);
+ if (groupmember(gid, cred))
+ return (0);
+
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
+}
+
+int
+secpolicy_vnode_chown(kauth_cred_t cred, boolean_t check_self)
+{
+
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
}
int
-secpolicy_vnode_chown(struct kauth_cred *cred, boolean_t check_self)
+secpolicy_vnode_create_gid(kauth_cred_t cred)
{
- return (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
- NULL));
- /* return (priv_check_cred(cred, PRIV_VFS_CHOWN, 0)); */
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
}
int
-secpolicy_vnode_create_gid(struct kauth_cred *cred)
+secpolicy_vnode_setdac(kauth_cred_t cred, uid_t owner)
{
- return (EPERM);
-}
+ if (owner == kauth_cred_getuid(cred))
+ return (0);
-int
-secpolicy_vnode_setdac(struct kauth_cred *cred, uid_t owner)
-{
-
- return 0;
- /*return (priv_check_cred(cred, PRIV_VFS_ADMIN, 0));*/
+ return kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
}
int
@@ -211,7 +225,7 @@
* is not a member of. Both of these are allowed in jail(8).
*/
if (vp->v_type != VDIR && (vap->va_mode & S_ISTXT)) {
- if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) != 0)
+ if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL))
return (EFTYPE);
}
/*
@@ -220,17 +234,131 @@
*/
if ((vap->va_mode & S_ISGID) != 0)
return (secpolicy_vnode_setids_setgids(cred, ovap->va_gid));
-
+
return (0);
}
+/*
+ * XXX Copied from illumos. Should not be here; should be under
+ * external/cddl/osnet/dist. Not sure why it is even in illumos's
+ * policy.c rather than somewhere in vnode.c or something.
+ */
int
secpolicy_vnode_setattr(kauth_cred_t cred, struct vnode *vp, struct vattr *vap,
const struct vattr *ovap, int flags,
- int unlocked_access(void *, int, kauth_cred_t ), void *node)
+ int unlocked_access(void *, int, kauth_cred_t), void *node)
{
+ int mask = vap->va_mask;
+ int error = 0;
+ boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
- return 0;
+ if (mask & AT_SIZE) {
+ if (vp->v_type == VDIR) {
+ error = EISDIR;
+ goto out;
+ }
+
+ /*
+ * If ATTR_NOACLCHECK is set in the flags, then we don't
+ * perform the secondary unlocked_access() call since the
+ * ACL (if any) is being checked there.
+ */
+ if (skipaclchk == B_FALSE) {
+ error = unlocked_access(node, VWRITE, cred);
+ if (error)
+ goto out;
+ }
+ }
Home |
Main Index |
Thread Index |
Old Index