Page MenuHomeFreeBSD

D25088.id72496.diff
No OneTemporary

D25088.id72496.diff

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

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)

Event Timeline