summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorThomas Haynes <Thomas.Haynes@Sun.COM>2009-03-24 00:52:12 -0500
committerThomas Haynes <Thomas.Haynes@Sun.COM>2009-03-24 00:52:12 -0500
commit546a399722fe82dc300c308a8fb86a11d2ca3ba3 (patch)
tree6354898ab7461743e148e7cd242ec2aa97065bd1 /usr/src
parent438076eb789b90b4483862b49c4b9c62ba84ed6a (diff)
downloadillumos-gate-546a399722fe82dc300c308a8fb86a11d2ca3ba3.tar.gz
6775211 mirror mounts use the zcred; should use caller's cr augmented w/ PRIV_SYS_MOUNT
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c62
-rw-r--r--usr/src/uts/common/os/cred.c23
-rw-r--r--usr/src/uts/common/sys/cred.h5
3 files changed, 55 insertions, 35 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c b/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c
index ea10794da9..187bf6f198 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -95,6 +95,8 @@
#include <sys/sunddi.h>
+#include <sys/priv_names.h>
+
/*
* The automatic unmounter thread stuff!
*/
@@ -197,7 +199,7 @@ extern int nfs4_getsecattr(vnode_t *, vsecattr_t *, int, cred_t *,
extern int nfs4_fid(vnode_t *, fid_t *, caller_context_t *);
extern int nfs4_realvp(vnode_t *, vnode_t **, caller_context_t *);
-static int nfs4_trigger_mount(vnode_t *, vnode_t **);
+static int nfs4_trigger_mount(vnode_t *, cred_t *, vnode_t **);
static int nfs4_trigger_domount(vnode_t *, domount_args_t *, vfs_t **,
cred_t *);
static domount_args_t *nfs4_trigger_domount_args_create(vnode_t *);
@@ -356,7 +358,7 @@ nfs4_trigger_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
int error;
vnode_t *newvp;
- error = nfs4_trigger_mount(*vpp, &newvp);
+ error = nfs4_trigger_mount(*vpp, cr, &newvp);
if (error)
return (error);
@@ -386,7 +388,7 @@ nfs4_trigger_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
if (flags & ATTR_TRIGGER) {
vnode_t *newvp;
- error = nfs4_trigger_mount(vp, &newvp);
+ error = nfs4_trigger_mount(vp, cr, &newvp);
if (error)
return (error);
@@ -406,7 +408,7 @@ nfs4_trigger_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
int error;
vnode_t *newvp;
- error = nfs4_trigger_mount(vp, &newvp);
+ error = nfs4_trigger_mount(vp, cr, &newvp);
if (error)
return (error);
@@ -423,7 +425,7 @@ nfs4_trigger_access(vnode_t *vp, int mode, int flags, cred_t *cr,
int error;
vnode_t *newvp;
- error = nfs4_trigger_mount(vp, &newvp);
+ error = nfs4_trigger_mount(vp, cr, &newvp);
if (error)
return (error);
@@ -456,7 +458,7 @@ nfs4_trigger_lookup(vnode_t *dvp, char *nm, vnode_t **vpp,
return (nfs4_lookup(dvp, nm, vpp, pnp, flags, rdir, cr,
ct, deflags, rpnp));
- error = nfs4_trigger_mount(dvp, &newdvp);
+ error = nfs4_trigger_mount(dvp, cr, &newdvp);
if (error)
return (error);
@@ -475,7 +477,7 @@ nfs4_trigger_create(vnode_t *dvp, char *nm, struct vattr *va,
int error;
vnode_t *newdvp;
- error = nfs4_trigger_mount(dvp, &newdvp);
+ error = nfs4_trigger_mount(dvp, cr, &newdvp);
if (error)
return (error);
@@ -493,7 +495,7 @@ nfs4_trigger_remove(vnode_t *dvp, char *nm, cred_t *cr, caller_context_t *ct,
int error;
vnode_t *newdvp;
- error = nfs4_trigger_mount(dvp, &newdvp);
+ error = nfs4_trigger_mount(dvp, cr, &newdvp);
if (error)
return (error);
@@ -510,7 +512,7 @@ nfs4_trigger_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr,
int error;
vnode_t *newtdvp;
- error = nfs4_trigger_mount(tdvp, &newtdvp);
+ error = nfs4_trigger_mount(tdvp, cr, &newtdvp);
if (error)
return (error);
@@ -551,7 +553,7 @@ nfs4_trigger_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
if (RP_ISSTUB(tdrp) && !VN_CMP(sdvp, tdvp))
return (EXDEV);
- error = nfs4_trigger_mount(sdvp, &newsdvp);
+ error = nfs4_trigger_mount(sdvp, cr, &newsdvp);
if (error)
return (error);
@@ -570,7 +572,7 @@ nfs4_trigger_mkdir(vnode_t *dvp, char *nm, struct vattr *va, vnode_t **vpp,
int error;
vnode_t *newdvp;
- error = nfs4_trigger_mount(dvp, &newdvp);
+ error = nfs4_trigger_mount(dvp, cr, &newdvp);
if (error)
return (error);
@@ -587,7 +589,7 @@ nfs4_trigger_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr,
int error;
vnode_t *newdvp;
- error = nfs4_trigger_mount(dvp, &newdvp);
+ error = nfs4_trigger_mount(dvp, cr, &newdvp);
if (error)
return (error);
@@ -604,7 +606,7 @@ nfs4_trigger_symlink(vnode_t *dvp, char *lnm, struct vattr *tva, char *tnm,
int error;
vnode_t *newdvp;
- error = nfs4_trigger_mount(dvp, &newdvp);
+ error = nfs4_trigger_mount(dvp, cr, &newdvp);
if (error)
return (error);
@@ -621,7 +623,7 @@ nfs4_trigger_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr,
int error;
vnode_t *newvp;
- error = nfs4_trigger_mount(vp, &newvp);
+ error = nfs4_trigger_mount(vp, cr, &newvp);
if (error)
return (error);
@@ -633,7 +635,6 @@ nfs4_trigger_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr,
/* end of trigger vnode ops */
-
/*
* Mount upon a trigger vnode; for mirror-mounts, etc.
*
@@ -647,7 +648,7 @@ nfs4_trigger_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr,
* The caller is responsible for passing the VOP onto the covering fs.
*/
static int
-nfs4_trigger_mount(vnode_t *vp, vnode_t **newvpp)
+nfs4_trigger_mount(vnode_t *vp, cred_t *cr, vnode_t **newvpp)
{
int error;
vfs_t *vfsp;
@@ -660,7 +661,7 @@ nfs4_trigger_mount(vnode_t *vp, vnode_t **newvpp)
bool_t must_unlock = FALSE;
bool_t is_building = FALSE;
- cred_t *zcred;
+ cred_t *mcred = NULL;
nfs4_trigger_globals_t *ntg;
@@ -767,22 +768,23 @@ nfs4_trigger_mount(vnode_t *vp, vnode_t **newvpp)
}
/*
- * Need to be root for this call to make mount work.
* Note that since we define mirror mounts to work
- * for any user, we allow the mount to proceed. And
- * we realize that the server will perform security
- * checks to make sure that the client is allowed
- * access. Finally, once the mount takes place,
- * directory permissions will ensure that the
- * content is secure.
+ * for any user, we simply extend the privileges of
+ * the user's credentials to allow the mount to
+ * proceed.
*/
- zcred = zone_get_kcred(getzoneid());
- ASSERT(zcred != NULL);
+ mcred = crdup(cr);
+ if (mcred == NULL) {
+ error = EINVAL;
+ goto done;
+ }
+
+ crset_zone_privall(mcred);
- error = nfs4_trigger_domount(vp, dma, &vfsp, zcred);
+ error = nfs4_trigger_domount(vp, dma, &vfsp, mcred);
nfs4_trigger_domount_args_destroy(dma, vp);
- crfree(zcred);
+ crfree(mcred);
if (!error)
error = VFS_ROOT(vfsp, newvpp);
@@ -1230,12 +1232,14 @@ nfs4_trigger_domount(vnode_t *stubvp, domount_args_t *dma, vfs_t **vfsp,
retval = EINVAL;
goto done;
}
+
/* domount() expects us to count the trailing NUL */
uap->optlen = strlen(uap->optptr) + 1;
retval = domount(NULL, uap, stubvp, cr, vfsp);
if (retval == 0)
VFS_RELE(*vfsp);
+
done:
if (uap->optptr)
nfs4_trigger_destroy_mntopts(uap->optptr);
diff --git a/usr/src/uts/common/os/cred.c b/usr/src/uts/common/os/cred.c
index b0bf2cb36a..59e856efbf 100644
--- a/usr/src/uts/common/os/cred.c
+++ b/usr/src/uts/common/os/cred.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,8 +36,6 @@
* contributors.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/param.h>
@@ -1280,6 +1278,25 @@ crsetpriv(cred_t *cr, ...)
return (0);
}
+/*
+ * Interface to effectively set the PRIV_ALL for
+ * a credential; this interface does no security checks and is
+ * intended for kernel (file)servers to extend the user credentials
+ * to be ALL, like either kcred or zcred.
+ */
+void
+crset_zone_privall(cred_t *cr)
+{
+ zone_t *zone = crgetzone(cr);
+
+ priv_fillset(&CR_LPRIV(cr));
+ CR_EPRIV(cr) = CR_PPRIV(cr) = CR_IPRIV(cr) = CR_LPRIV(cr);
+ priv_intersect(zone->zone_privset, &CR_LPRIV(cr));
+ priv_intersect(zone->zone_privset, &CR_EPRIV(cr));
+ priv_intersect(zone->zone_privset, &CR_IPRIV(cr));
+ priv_intersect(zone->zone_privset, &CR_PPRIV(cr));
+}
+
struct credklpd *
crgetcrklpd(const cred_t *cr)
{
diff --git a/usr/src/uts/common/sys/cred.h b/usr/src/uts/common/sys/cred.h
index e84f1e0430..1b07a5d6f3 100644
--- a/usr/src/uts/common/sys/cred.h
+++ b/usr/src/uts/common/sys/cred.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,8 +34,6 @@
#ifndef _SYS_CRED_H
#define _SYS_CRED_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#ifdef __cplusplus
@@ -79,6 +77,7 @@ extern cred_t *crdup(cred_t *);
extern void crdup_to(cred_t *, cred_t *);
extern cred_t *crgetcred(void);
extern void crset(struct proc *, cred_t *);
+extern void crset_zone_privall(cred_t *);
extern int groupmember(gid_t, const cred_t *);
extern int supgroupmember(gid_t, const cred_t *);
extern int hasprocperm(const cred_t *, const cred_t *);