Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F169267824
D25088.id72496.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
28 KB
Referenced Files
None
Subscribers
None
D25088.id72496.diff
View Options
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -101,8 +101,8 @@
static int zfs_statfs(vfs_t *vfsp, struct statfs *statp);
static int zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp);
static int zfs_sync(vfs_t *vfsp, int waitfor);
-static int zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp,
- struct ucred **credanonp, int *numsecflavors, int **secflavors);
+static int zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, uint64_t *extflagsp,
+ struct ucred **credanonp, int *numsecflavors, int *secflavors);
static int zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp);
static void zfs_objset_close(zfsvfs_t *zfsvfs);
static void zfs_freevfs(vfs_t *vfsp);
@@ -2268,8 +2268,8 @@
}
static int
-zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp,
- struct ucred **credanonp, int *numsecflavors, int **secflavors)
+zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, uint64_t *extflagsp,
+ struct ucred **credanonp, int *numsecflavors, int *secflavors)
{
zfsvfs_t *zfsvfs = vfsp->vfs_data;
Index: sys/fs/cd9660/cd9660_vfsops.c
===================================================================
--- sys/fs/cd9660/cd9660_vfsops.c
+++ sys/fs/cd9660/cd9660_vfsops.c
@@ -101,7 +101,7 @@
cd9660_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
struct iso_args args;
- struct export_args exp;
+ struct o2export_args exp;
int error;
error = copyin(data, &args, sizeof args);
Index: sys/fs/msdosfs/msdosfs_vfsops.c
===================================================================
--- sys/fs/msdosfs/msdosfs_vfsops.c
+++ sys/fs/msdosfs/msdosfs_vfsops.c
@@ -190,7 +190,7 @@
msdosfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
struct msdosfs_args args;
- struct export_args exp;
+ struct o2export_args exp;
int error;
if (data == NULL)
Index: sys/fs/nfs/nfsdport.h
===================================================================
--- sys/fs/nfs/nfsdport.h
+++ sys/fs/nfs/nfsdport.h
@@ -54,7 +54,7 @@
* needs to be returned by nfsd_fhtovp().
*/
struct nfsexstuff {
- int nes_exflag; /* export flags */
+ uint64_t nes_exflag; /* export flags */
int nes_numsecflavor; /* # of security flavors */
int nes_secflavors[MAXSECFLAVORS]; /* and the flavors */
};
Index: sys/fs/nfs/nfsport.h
===================================================================
--- sys/fs/nfs/nfsport.h
+++ sys/fs/nfs/nfsport.h
@@ -1081,6 +1081,11 @@
struct export_args export;
};
+struct nfsex_oldargs {
+ char *fspec;
+ struct o2export_args export;
+};
+
/*
* These export flags should be defined, but there are no bits left.
* Maybe a separate mnt_exflag field could be added or the mnt_flag
Index: sys/fs/nfsserver/nfs_nfsdport.c
===================================================================
--- sys/fs/nfsserver/nfs_nfsdport.c
+++ sys/fs/nfsserver/nfs_nfsdport.c
@@ -3056,10 +3056,10 @@
nfsvno_checkexp(struct mount *mp, struct sockaddr *nam, struct nfsexstuff *exp,
struct ucred **credp)
{
- int i, error, *secflavors;
+ int i, error, secflavors[MAXSECFLAVORS];
error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
- &exp->nes_numsecflavor, &secflavors);
+ &exp->nes_numsecflavor, secflavors);
if (error) {
if (nfs_rootfhset) {
exp->nes_exflag = 0;
@@ -3088,7 +3088,7 @@
int lktype, struct vnode **vpp, struct nfsexstuff *exp,
struct ucred **credp)
{
- int i, error, *secflavors;
+ int i, error, secflavors[MAXSECFLAVORS];
*credp = NULL;
exp->nes_numsecflavor = 0;
@@ -3098,7 +3098,7 @@
error = ESTALE;
if (nam && !error) {
error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
- &exp->nes_numsecflavor, &secflavors);
+ &exp->nes_numsecflavor, secflavors);
if (error) {
if (nfs_rootfhset) {
exp->nes_exflag = 0;
@@ -3415,10 +3415,11 @@
nfsvno_v4rootexport(struct nfsrv_descript *nd)
{
struct ucred *credanon;
- int exflags, error = 0, numsecflavor, *secflavors, i;
+ int error = 0, numsecflavor, secflavors[MAXSECFLAVORS], i;
+ uint64_t exflags;
error = vfs_stdcheckexp(&nfsv4root_mnt, nd->nd_nam, &exflags,
- &credanon, &numsecflavor, &secflavors);
+ &credanon, &numsecflavor, secflavors);
if (error) {
error = NFSERR_PROGUNAVAIL;
goto out;
@@ -3656,8 +3657,9 @@
nfssvc_srvcall(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
{
struct nfsex_args export;
+ struct nfsex_oldargs oexp;
struct file *fp = NULL;
- int stablefd, len;
+ int stablefd, i, len;
struct nfsd_clid adminrevoke;
struct nfsd_dumplist dumplist;
struct nfsd_dumpclients *dumpclients;
@@ -3667,6 +3669,7 @@
vnode_t vp;
int error = EINVAL, igotlock;
struct proc *procp;
+ gid_t *grps;
static int suspend_nfsd = 0;
if (uap->flag & NFSSVC_PUBLICFH) {
@@ -3676,11 +3679,65 @@
&nfs_pubfh.nfsrvfh_data, sizeof (fhandle_t));
if (!error)
nfs_pubfhset = 1;
- } else if (uap->flag & NFSSVC_V4ROOTEXPORT) {
+ } else if ((uap->flag & (NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT)) ==
+ (NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT)) {
error = copyin(uap->argp,(caddr_t)&export,
sizeof (struct nfsex_args));
- if (!error)
+ if (!error) {
+ if (export.export.ex_ngroups > 0) {
+ if (export.export.ex_ngroups > NGROUPS_MAX)
+ export.export.ex_ngroups = NGROUPS_MAX;
+ grps = malloc(export.export.ex_ngroups *
+ sizeof(gid_t), M_TEMP, M_WAITOK);
+ error = copyin(export.export.ex_groups, grps,
+ export.export.ex_ngroups * sizeof(gid_t));
+ export.export.ex_groups = grps;
+ } else {
+ export.export.ex_ngroups = 0;
+ export.export.ex_groups = NULL;
+ }
+ if (!error)
+ error = nfsrv_v4rootexport(&export, cred, p);
+ free(export.export.ex_groups, M_TEMP);
+ }
+ } else if ((uap->flag & (NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT)) ==
+ NFSSVC_V4ROOTEXPORT) {
+ error = copyin(uap->argp,(caddr_t)&oexp,
+ sizeof (struct nfsex_oldargs));
+ if (!error) {
+ memset(&export.export, 0, sizeof(export.export));
+ export.export.ex_flags = (uint64_t)oexp.export.ex_flags;
+ export.export.ex_root = oexp.export.ex_root;
+ export.export.ex_uid = oexp.export.ex_anon.cr_uid;
+ export.export.ex_ngroups =
+ oexp.export.ex_anon.cr_ngroups;
+ if (export.export.ex_ngroups > 0) {
+ if (export.export.ex_ngroups > XU_NGROUPS)
+ export.export.ex_ngroups = XU_NGROUPS;
+ export.export.ex_groups = malloc(
+ export.export.ex_ngroups * sizeof(gid_t),
+ M_TEMP, M_WAITOK);
+ for (i = 0; i < export.export.ex_ngroups; i++)
+ export.export.ex_groups[i] =
+ oexp.export.ex_anon.cr_groups[i];
+ } else {
+ export.export.ex_ngroups = 0;
+ export.export.ex_groups = NULL;
+ }
+ export.export.ex_addr = oexp.export.ex_addr;
+ export.export.ex_addrlen = oexp.export.ex_addrlen;
+ export.export.ex_mask = oexp.export.ex_mask;
+ export.export.ex_masklen = oexp.export.ex_masklen;
+ export.export.ex_indexfile = oexp.export.ex_indexfile;
+ export.export.ex_numsecflavors =
+ oexp.export.ex_numsecflavors;
+ for (i = 0; i < export.export.ex_numsecflavors; i++)
+ export.export.ex_secflavors[i] =
+ oexp.export.ex_secflavors[i];
+ export.fspec = oexp.fspec;
error = nfsrv_v4rootexport(&export, cred, p);
+ free(export.export.ex_groups, M_TEMP);
+ }
} else if (uap->flag & NFSSVC_NOPUBLICFH) {
nfs_pubfhset = 0;
error = 0;
Index: sys/fs/unionfs/union_vfsops.c
===================================================================
--- sys/fs/unionfs/union_vfsops.c
+++ sys/fs/unionfs/union_vfsops.c
@@ -466,8 +466,8 @@
}
static int
-unionfs_checkexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
- struct ucred **credanonp, int *numsecflavors, int **secflavors)
+unionfs_checkexp(struct mount *mp, struct sockaddr *nam, uint64_t *extflagsp,
+ struct ucred **credanonp, int *numsecflavors, int *secflavors)
{
return (EOPNOTSUPP);
}
Index: sys/kern/vfs_export.c
===================================================================
--- sys/kern/vfs_export.c
+++ sys/kern/vfs_export.c
@@ -79,7 +79,7 @@
*/
struct netcred {
struct radix_node netc_rnodes[2];
- int netc_exflags;
+ uint64_t netc_exflags;
struct ucred *netc_anon;
int netc_numsecflavors;
int netc_secflavors[MAXSECFLAVORS];
@@ -118,18 +118,12 @@
("%s: numsecflavors >= MAXSECFLAVORS", __func__));
/*
- * XXX: This routine converts from a `struct xucred'
- * (argp->ex_anon) to a `struct ucred' (np->netc_anon). This
+ * XXX: This routine converts from a uid plus gid list
+ * to a `struct ucred' (np->netc_anon). This
* operation is questionable; for example, what should be done
* with fields like cr_uidinfo and cr_prison? Currently, this
* routine does not touch them (leaves them as NULL).
*/
- if (argp->ex_anon.cr_version != XUCRED_VERSION) {
- vfs_mount_error(mp, "ex_anon.cr_version: %d != %d",
- argp->ex_anon.cr_version, XUCRED_VERSION);
- return (EINVAL);
- }
-
if (argp->ex_addrlen == 0) {
if (mp->mnt_flag & MNT_DEFEXPORTED) {
vfs_mount_error(mp,
@@ -139,9 +133,9 @@
np = &nep->ne_defexported;
np->netc_exflags = argp->ex_flags;
np->netc_anon = crget();
- np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
- crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
- argp->ex_anon.cr_groups);
+ np->netc_anon->cr_uid = argp->ex_uid;
+ crsetgroups(np->netc_anon, argp->ex_ngroups,
+ argp->ex_groups);
np->netc_anon->cr_prison = &prison0;
prison_hold(np->netc_anon->cr_prison);
np->netc_numsecflavors = argp->ex_numsecflavors;
@@ -218,9 +212,9 @@
}
np->netc_exflags = argp->ex_flags;
np->netc_anon = crget();
- np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
- crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
- argp->ex_anon.cr_groups);
+ np->netc_anon->cr_uid = argp->ex_uid;
+ crsetgroups(np->netc_anon, argp->ex_ngroups,
+ argp->ex_groups);
np->netc_anon->cr_prison = &prison0;
prison_hold(np->netc_anon->cr_prison);
np->netc_numsecflavors = argp->ex_numsecflavors;
@@ -512,8 +506,8 @@
*/
int
-vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
- struct ucred **credanonp, int *numsecflavors, int **secflavors)
+vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, uint64_t *extflagsp,
+ struct ucred **credanonp, int *numsecflavors, int *secflavors)
{
struct netcred *np;
@@ -534,8 +528,9 @@
KASSERT(*numsecflavors < MAXSECFLAVORS,
("%s: numsecflavors >= MAXSECFLAVORS", __func__));
}
- if (secflavors)
- *secflavors = np->netc_secflavors;
+ if (secflavors && np->netc_numsecflavors > 0)
+ memcpy(secflavors, np->netc_secflavors, np->netc_numsecflavors *
+ sizeof(int));
lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
return (0);
}
Index: sys/kern/vfs_init.c
===================================================================
--- sys/kern/vfs_init.c
+++ sys/kern/vfs_init.c
@@ -268,8 +268,8 @@
}
static int
-vfs_checkexp_sigdefer(struct mount *mp, struct sockaddr *nam, int *exflg,
- struct ucred **credp, int *numsecflavors, int **secflavors)
+vfs_checkexp_sigdefer(struct mount *mp, struct sockaddr *nam, uint64_t *exflg,
+ struct ucred **credp, int *numsecflavors, int *secflavors)
{
int prev_stops, rc;
Index: sys/kern/vfs_mount.c
===================================================================
--- sys/kern/vfs_mount.c
+++ sys/kern/vfs_mount.c
@@ -1038,11 +1038,13 @@
)
{
struct export_args export;
+ struct o2export_args o2export;
struct vnode *rootvp;
void *bufp;
struct mount *mp;
- int error, export_error, len;
+ int error, export_error, i, len;
uint64_t flag;
+ gid_t *grps;
ASSERT_VOP_ELOCKED(vp, __func__);
KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here"));
@@ -1125,11 +1127,58 @@
/* Assume that there is only 1 ABI for each length. */
switch (len) {
case (sizeof(struct oexport_args)):
- bzero(&export, sizeof(export));
+ bzero(&o2export, sizeof(o2export));
/* FALLTHROUGH */
+ case (sizeof(o2export)):
+ bcopy(bufp, &o2export, len);
+ export.ex_flags = (uint64_t)o2export.ex_flags;
+ export.ex_root = o2export.ex_root;
+ export.ex_uid = o2export.ex_anon.cr_uid;
+ export.ex_ngroups = o2export.ex_anon.cr_ngroups;
+ if (export.ex_ngroups > 0) {
+ if (export.ex_ngroups > XU_NGROUPS)
+ export.ex_ngroups = XU_NGROUPS;
+ export.ex_groups = malloc(export.ex_ngroups *
+ sizeof(gid_t), M_TEMP, M_WAITOK);
+ for (i = 0; i < export.ex_ngroups; i++)
+ export.ex_groups[i] =
+ o2export.ex_anon.cr_groups[i];
+ } else {
+ export.ex_ngroups = 0;
+ export.ex_groups = NULL;
+ }
+ export.ex_addr = o2export.ex_addr;
+ export.ex_addrlen = o2export.ex_addrlen;
+ export.ex_mask = o2export.ex_mask;
+ export.ex_masklen = o2export.ex_masklen;
+ export.ex_indexfile = o2export.ex_indexfile;
+ export.ex_numsecflavors = o2export.ex_numsecflavors;
+ for (i = 0; i < export.ex_numsecflavors; i++)
+ export.ex_secflavors[i] =
+ o2export.ex_secflavors[i];
+ export_error = vfs_export(mp, &export);
+ free(export.ex_groups, M_TEMP);
+ break;
case (sizeof(export)):
bcopy(bufp, &export, len);
- export_error = vfs_export(mp, &export);
+ export_error = 0;
+ grps = NULL;
+ if (export.ex_ngroups > 0) {
+ if (export.ex_ngroups > NGROUPS)
+ export.ex_ngroups = NGROUPS;
+ grps = malloc(export.ex_ngroups * sizeof(gid_t),
+ M_TEMP, M_WAITOK);
+ export_error = copyin(export.ex_groups, grps,
+ export.ex_ngroups * sizeof(gid_t));
+ if (export_error == 0)
+ export.ex_groups = grps;
+ } else if (export.ex_ngroups == 0)
+ export.ex_groups = NULL;
+ else
+ export_error = EINVAL;
+ if (export_error == 0)
+ export_error = vfs_export(mp, &export);
+ free(grps, M_TEMP);
break;
default:
export_error = EINVAL;
@@ -2344,7 +2393,7 @@
}
void
-vfs_oexport_conv(const struct oexport_args *oexp, struct export_args *exp)
+vfs_oexport_conv(const struct oexport_args *oexp, struct o2export_args *exp)
{
bcopy(oexp, exp, sizeof(*oexp));
Index: sys/nlm/nlm_prot_impl.c
===================================================================
--- sys/nlm/nlm_prot_impl.c
+++ sys/nlm/nlm_prot_impl.c
@@ -1735,7 +1735,8 @@
nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp,
fhandle_t *fhp, struct vfs_state *vs, accmode_t accmode)
{
- int error, exflags;
+ int error;
+ uint64_t exflags;
struct ucred *cred = NULL, *credanon = NULL;
memset(vs, 0, sizeof(*vs));
Index: sys/sys/mount.h
===================================================================
--- sys/sys/mount.h
+++ sys/sys/mount.h
@@ -494,10 +494,10 @@
};
/*
- * Export arguments for local filesystem mount calls.
+ * Not quite so old export arguments with 32bit ex_flags and xucred ex_anon.
*/
#define MAXSECFLAVORS 5
-struct export_args {
+struct o2export_args {
int ex_flags; /* export related flags */
uid_t ex_root; /* mapping for root uid */
struct xucred ex_anon; /* mapping for anonymous user */
@@ -511,6 +511,25 @@
};
/*
+ * Export arguments for local filesystem mount calls.
+ */
+#define MAXSECFLAVORS 5
+struct export_args {
+ uint64_t ex_flags; /* export related flags */
+ uid_t ex_root; /* mapping for root uid */
+ uid_t ex_uid; /* mapping for anonymous user */
+ int ex_ngroups;
+ gid_t *ex_groups;
+ struct sockaddr *ex_addr; /* net address to which exported */
+ u_char ex_addrlen; /* and the net address length */
+ struct sockaddr *ex_mask; /* mask of valid bits in saddr */
+ u_char ex_masklen; /* and the smask length */
+ char *ex_indexfile; /* index file for WebNFS URLs */
+ int ex_numsecflavors; /* security flavor count */
+ int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
+};
+
+/*
* Structure holding information for a publicly exported filesystem
* (WebNFS). Currently the specs allow just for one such filesystem.
*/
@@ -689,8 +708,8 @@
typedef int vfs_fhtovp_t(struct mount *mp, struct fid *fhp,
int flags, struct vnode **vpp);
typedef int vfs_checkexp_t(struct mount *mp, struct sockaddr *nam,
- int *extflagsp, struct ucred **credanonp,
- int *numsecflavors, int **secflavors);
+ uint64_t *extflagsp, struct ucred **credanonp,
+ int *numsecflavors, int *secflavors);
typedef int vfs_init_t(struct vfsconf *);
typedef int vfs_uninit_t(struct vfsconf *);
typedef int vfs_extattrctl_t(struct mount *mp, int cmd,
@@ -924,7 +943,7 @@
void vfs_mountedfrom(struct mount *, const char *from);
void vfs_notify_upper(struct vnode *, int);
void vfs_oexport_conv(const struct oexport_args *oexp,
- struct export_args *exp);
+ struct o2export_args *exp);
void vfs_ref(struct mount *);
void vfs_rel(struct mount *);
struct mount *vfs_mount_alloc(struct vnode *, struct vfsconf *, const char *,
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
--- sys/ufs/ffs/ffs_vfsops.c
+++ sys/ufs/ffs/ffs_vfsops.c
@@ -589,7 +589,7 @@
ffs_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
struct ufs_args args;
- struct export_args exp;
+ struct o2export_args exp;
int error;
if (data == NULL)
Index: usr.sbin/mountd/mountd.c
===================================================================
--- usr.sbin/mountd/mountd.c
+++ usr.sbin/mountd/mountd.c
@@ -112,6 +112,15 @@
#define DP_DEFSET 0x1
#define DP_HOSTSET 0x2
+/*
+ * maproot/mapall credentials.
+ */
+struct expcred {
+ uid_t cr_uid;
+ int cr_ngroups;
+ gid_t cr_groups[NGROUPS];
+};
+
struct exportlist {
struct dirlist *ex_dirl;
struct dirlist *ex_defdir;
@@ -120,8 +129,8 @@
fsid_t ex_fs;
char *ex_fsdir;
char *ex_indexfile;
- struct xucred ex_defanon;
- int ex_defexflags;
+ struct expcred ex_defanon;
+ uint64_t ex_defexflags;
int ex_numsecflavors;
int ex_secflavors[MAXSECFLAVORS];
int ex_defnumsecflavors;
@@ -152,8 +161,8 @@
int gr_type;
union grouptypes gr_ptr;
struct grouplist *gr_next;
- struct xucred gr_anon;
- int gr_exflags;
+ struct expcred gr_anon;
+ uint64_t gr_exflags;
int gr_flag;
int gr_numsecflavors;
int gr_secflavors[MAXSECFLAVORS];
@@ -188,7 +197,7 @@
static char *add_expdir(struct dirlist **, char *, int);
static void add_dlist(struct dirlist **, struct dirlist *,
struct grouplist *, int, struct exportlist *,
- struct xucred *, int);
+ struct expcred *, uint64_t);
static void add_mlist(char *, char *);
static int check_dirpath(char *);
static int check_options(struct dirlist *);
@@ -202,10 +211,10 @@
static void del_mlist(char *hostp, char *dirp);
static struct dirlist *dirp_search(struct dirlist *, char *);
static int do_export_mount(struct exportlist *, struct statfs *);
-static int do_mount(struct exportlist *, struct grouplist *, int,
- struct xucred *, char *, int, struct statfs *, int, int *);
+static int do_mount(struct exportlist *, struct grouplist *, uint64_t,
+ struct expcred *, char *, int, struct statfs *, int, int *);
static int do_opt(char **, char **, struct exportlist *,
- struct grouplist *, int *, int *, struct xucred *);
+ struct grouplist *, int *, uint64_t *, struct expcred *);
static struct exportlist *ex_search(fsid_t *, struct exportlisthead *);
static struct exportlist *get_exp(void);
static void free_dir(struct dirlist *);
@@ -220,7 +229,7 @@
static void read_exportfile(int);
static int compare_nmount_exportlist(struct iovec *, int, char *);
static int compare_export(struct exportlist *, struct exportlist *);
-static int compare_cred(struct xucred *, struct xucred *);
+static int compare_cred(struct expcred *, struct expcred *);
static int compare_secflavor(int *, int *, int);
static void delete_export(struct iovec *, int, struct statfs *, char *);
static int get_host(char *, struct grouplist *, struct grouplist *);
@@ -231,13 +240,13 @@
static void getexp_err(struct exportlist *, struct grouplist *, const char *);
static struct grouplist *get_grp(void);
static void hang_dirp(struct dirlist *, struct grouplist *,
- struct exportlist *, int, struct xucred *, int);
+ struct exportlist *, int, struct expcred *, uint64_t);
static void huphandler(int sig);
static int makemask(struct sockaddr_storage *ssp, int bitlen);
static void mntsrv(struct svc_req *, SVCXPRT *);
static void nextfield(char **, char **);
static void out_of_mem(void);
-static void parsecred(char *, struct xucred *);
+static void parsecred(char *, struct expcred *);
static int parsesec(char *, struct exportlist *);
static int put_exlist(struct dirlist *, XDR *, struct dirlist *,
int *, int);
@@ -253,6 +262,7 @@
static int xdr_fhs(XDR *, caddr_t);
static int xdr_mlist(XDR *, caddr_t);
static void terminate(int);
+static void cp_cred(struct expcred *, struct expcred *);
#define EXPHASH(f) (fnv_32_buf((f), sizeof(fsid_t), 0) % exphashsize)
static struct exportlisthead *exphead = NULL;
@@ -262,13 +272,6 @@
static char *exnames_default[2] = { _PATH_EXPORTS, NULL };
static char **exnames;
static char **hosts = NULL;
-static struct xucred def_anon = {
- XUCRED_VERSION,
- (uid_t)65534,
- 1,
- { (gid_t)65533 },
- { NULL }
-};
static int force_v2 = 0;
static int resvport_only = 1;
static int nhosts = 0;
@@ -1463,9 +1466,10 @@
struct grouplist *grp, *tgrp, *savgrp;
struct dirlist *dirhead;
struct statfs fsb;
- struct xucred anon;
+ struct expcred anon;
char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
- int len, has_host, exflags, got_nondir, dirplen, netgrp;
+ int len, has_host, got_nondir, dirplen, netgrp;
+ uint64_t exflags;
v4root_phase = 0;
dirhead = (struct dirlist *)NULL;
@@ -1481,7 +1485,9 @@
* Set defaults.
*/
has_host = FALSE;
- anon = def_anon;
+ anon.cr_uid = 65534;
+ anon.cr_ngroups = 1;
+ anon.cr_groups[0] = 65533;
exflags = MNT_EXPORTED;
got_nondir = 0;
opt_flags = 0;
@@ -1700,7 +1706,7 @@
grp = tgrp;
do {
grp->gr_exflags = exflags;
- grp->gr_anon = anon;
+ cp_cred(&grp->gr_anon, &anon);
if (v4root_phase == 2 && passno == 0)
LOGDEBUG("do_mount v4root");
if (passno == 0 && do_mount(ep, grp, exflags, &anon,
@@ -1840,7 +1846,7 @@
*/
bzero(&eargs, sizeof (eargs));
eargs.export.ex_flags = MNT_DELEXPORT;
- if (nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&eargs) < 0 &&
+ if (nfssvc(NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT, (caddr_t)&eargs) < 0 &&
errno != ENOENT)
syslog(LOG_ERR, "Can't delete exports for V4:");
@@ -2220,10 +2226,10 @@
} while (0)
/*
- * Compare to struct xucred's. Return 0 if the same and 1 otherwise.
+ * Compare two struct expcred's. Return 0 if the same and 1 otherwise.
*/
static int
-compare_cred(struct xucred *cr0, struct xucred *cr1)
+compare_cred(struct expcred *cr0, struct expcred *cr1)
{
if (cr0->cr_uid != cr1->cr_uid || cr0->cr_ngroups != cr1->cr_ngroups)
@@ -2389,7 +2395,7 @@
*/
static void
hang_dirp(struct dirlist *dp, struct grouplist *grp, struct exportlist *ep,
- int flags, struct xucred *anoncrp, int exflags)
+ int flags, struct expcred *anoncrp, uint64_t exflags)
{
struct hostlist *hp;
struct dirlist *dp2;
@@ -2407,7 +2413,7 @@
if (ep->ex_numsecflavors > 0)
memcpy(ep->ex_defsecflavors, ep->ex_secflavors,
sizeof(ep->ex_secflavors));
- ep->ex_defanon = *anoncrp;
+ cp_cred(&ep->ex_defanon, anoncrp);
ep->ex_defexflags = exflags;
} else while (grp) {
hp = get_ht();
@@ -2441,7 +2447,8 @@
*/
static void
add_dlist(struct dirlist **dpp, struct dirlist *newdp, struct grouplist *grp,
- int flags, struct exportlist *ep, struct xucred *anoncrp, int exflags)
+ int flags, struct exportlist *ep, struct expcred *anoncrp,
+ uint64_t exflags)
{
struct dirlist *dp;
struct hostlist *hp;
@@ -2490,7 +2497,7 @@
if (ep->ex_numsecflavors > 0)
memcpy(ep->ex_defsecflavors, ep->ex_secflavors,
sizeof(ep->ex_secflavors));
- ep->ex_defanon = *anoncrp;
+ cp_cred(&ep->ex_defanon, anoncrp);
ep->ex_defexflags = exflags;
}
}
@@ -2662,7 +2669,7 @@
*/
static int
do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp,
- int *has_hostp, int *exflagsp, struct xucred *cr)
+ int *has_hostp, uint64_t *exflagsp, struct expcred *cr)
{
char *cpoptarg, *cpoptend;
char *cp, *endcp, *cpopt, savedc, savedc2;
@@ -2924,7 +2931,7 @@
defgrp.gr_type = GT_DEFAULT;
defgrp.gr_next = NULL;
/* We have an entry for all other hosts/nets. */
- LOGDEBUG("ex_defexflags=0x%x", ep->ex_defexflags);
+ LOGDEBUG("ex_defexflags=0x%jx", (uintmax_t)ep->ex_defexflags);
ret = do_mount(ep, &defgrp, ep->ex_defexflags, &ep->ex_defanon,
ep->ex_fsdir, dirlen, fsp, ep->ex_defnumsecflavors,
ep->ex_defsecflavors);
@@ -2935,8 +2942,8 @@
/* Do a mount for each group. */
grp = ep->ex_grphead;
while (grp != NULL) {
- LOGDEBUG("do mount gr_type=0x%x gr_exflags=0x%x",
- grp->gr_type, grp->gr_exflags);
+ LOGDEBUG("do mount gr_type=0x%x gr_exflags=0x%jx",
+ grp->gr_type, (uintmax_t)grp->gr_exflags);
ret = do_mount(ep, grp, grp->gr_exflags, &grp->gr_anon,
ep->ex_fsdir, dirlen, fsp, grp->gr_numsecflavors,
grp->gr_secflavors);
@@ -2952,8 +2959,8 @@
* the kernel.
*/
static int
-do_mount(struct exportlist *ep, struct grouplist *grp, int exflags,
- struct xucred *anoncrp, char *dirp, int dirplen, struct statfs *fsb,
+do_mount(struct exportlist *ep, struct grouplist *grp, uint64_t exflags,
+ struct expcred *anoncrp, char *dirp, int dirplen, struct statfs *fsb,
int numsecflavors, int *secflavors)
{
struct statfs fsb1;
@@ -2979,8 +2986,14 @@
bzero(eap, sizeof (struct export_args));
bzero(errmsg, sizeof(errmsg));
eap->ex_flags = exflags;
- eap->ex_anon = *anoncrp;
- LOGDEBUG("do_mount exflags=0x%x", exflags);
+ eap->ex_uid = anoncrp->cr_uid;
+ eap->ex_ngroups = anoncrp->cr_ngroups;
+ if (eap->ex_ngroups > 0) {
+ eap->ex_groups = malloc(eap->ex_ngroups * sizeof(gid_t));
+ memcpy(eap->ex_groups, anoncrp->cr_groups, eap->ex_ngroups *
+ sizeof(gid_t));
+ }
+ LOGDEBUG("do_mount exflags=0x%jx", (uintmax_t)exflags);
eap->ex_indexfile = ep->ex_indexfile;
if (grp->gr_type == GT_HOST)
ai = grp->gr_ptr.gt_addrinfo;
@@ -3050,9 +3063,11 @@
*/
if (v4root_phase == 2) {
nfsea.fspec = v4root_dirpath;
- if (nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&nfsea) < 0) {
+ if (nfssvc(NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT,
+ (caddr_t)&nfsea) < 0) {
syslog(LOG_ERR, "Exporting V4: failed");
- return (2);
+ ret = 2;
+ goto error_exit;
}
} else {
/*
@@ -3168,6 +3183,7 @@
if (cp)
*cp = savedc;
error_exit:
+ free(eap->ex_groups);
/* free strings allocated by strdup() in getmntopts.c */
if (iov != NULL) {
free(iov[0].iov_base); /* fstype */
@@ -3394,17 +3410,14 @@
* Parse a description of a credential.
*/
static void
-parsecred(char *namelist, struct xucred *cr)
+parsecred(char *namelist, struct expcred *cr)
{
char *name;
int cnt;
char *names;
struct passwd *pw;
struct group *gr;
- gid_t groups[XU_NGROUPS + 1];
- int ngroups;
- cr->cr_version = XUCRED_VERSION;
/*
* Set up the unprivileged user.
*/
@@ -3430,19 +3443,19 @@
return;
}
cr->cr_uid = pw->pw_uid;
- ngroups = XU_NGROUPS + 1;
- if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups)) {
+ cr->cr_ngroups = NGROUPS;
+ if (getgrouplist(pw->pw_name, pw->pw_gid, cr->cr_groups,
+ &cr->cr_ngroups)) {
syslog(LOG_ERR, "too many groups");
- ngroups = XU_NGROUPS + 1;
+ cr->cr_ngroups = NGROUPS;
}
/*
* Compress out duplicate.
*/
- cr->cr_ngroups = ngroups - 1;
- cr->cr_groups[0] = groups[0];
- for (cnt = 2; cnt < ngroups; cnt++)
- cr->cr_groups[cnt - 1] = groups[cnt];
+ for (cnt = 2; cnt < cr->cr_ngroups; cnt++)
+ cr->cr_groups[cnt - 1] = cr->cr_groups[cnt];
+ cr->cr_ngroups--;
return;
}
/*
@@ -3458,7 +3471,7 @@
return;
}
cr->cr_ngroups = 0;
- while (names != NULL && *names != '\0' && cr->cr_ngroups < XU_NGROUPS) {
+ while (names != NULL && *names != '\0' && cr->cr_ngroups < NGROUPS_MAX) {
name = strsep_quote(&names, ":");
if (isdigit(*name) || *name == '-') {
cr->cr_groups[cr->cr_ngroups++] = atoi(name);
@@ -3470,7 +3483,7 @@
cr->cr_groups[cr->cr_ngroups++] = gr->gr_gid;
}
}
- if (names != NULL && *names != '\0' && cr->cr_ngroups == XU_NGROUPS)
+ if (names != NULL && *names != '\0' && cr->cr_ngroups == NGROUPS_MAX)
syslog(LOG_ERR, "too many groups");
}
@@ -3790,4 +3803,14 @@
rpcb_unset(MOUNTPROG, MOUNTVERS, NULL);
rpcb_unset(MOUNTPROG, MOUNTVERS3, NULL);
exit (0);
+}
+
+static void
+cp_cred(struct expcred *outcr, struct expcred *incr)
+{
+
+ outcr->cr_uid = incr->cr_uid;
+ outcr->cr_ngroups = incr->cr_ngroups;
+ memcpy(outcr->cr_groups, incr->cr_groups, incr->cr_ngroups *
+ sizeof(gid_t));
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Sep 2, 2:35 AM (18 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37850230
Default Alt Text
D25088.id72496.diff (28 KB)
Attached To
Mode
D25088: fix export_args flags field to be 64bits and handle more than 16 groups for the mapped user
Attached
Detach File
Event Timeline
Log In to Comment