Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/vfs_export.c
Show First 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | static int vfs_hang_addrlist(struct mount *mp, struct netexport *nep, | ||||
struct export_args *argp); | struct export_args *argp); | ||||
static struct netcred *vfs_export_lookup(struct mount *, struct sockaddr *); | static struct netcred *vfs_export_lookup(struct mount *, struct sockaddr *); | ||||
/* | /* | ||||
* Network address lookup element | * Network address lookup element | ||||
*/ | */ | ||||
struct netcred { | struct netcred { | ||||
struct radix_node netc_rnodes[2]; | struct radix_node netc_rnodes[2]; | ||||
int netc_exflags; | uint64_t netc_exflags; | ||||
struct ucred *netc_anon; | struct ucred *netc_anon; | ||||
int netc_numsecflavors; | int netc_numsecflavors; | ||||
int netc_secflavors[MAXSECFLAVORS]; | int netc_secflavors[MAXSECFLAVORS]; | ||||
}; | }; | ||||
/* | /* | ||||
* Network export information | * Network export information | ||||
*/ | */ | ||||
Show All 22 Lines | #endif | ||||
int error; | int error; | ||||
KASSERT(argp->ex_numsecflavors > 0, | KASSERT(argp->ex_numsecflavors > 0, | ||||
("%s: numsecflavors <= 0", __func__)); | ("%s: numsecflavors <= 0", __func__)); | ||||
KASSERT(argp->ex_numsecflavors < MAXSECFLAVORS, | KASSERT(argp->ex_numsecflavors < MAXSECFLAVORS, | ||||
("%s: numsecflavors >= MAXSECFLAVORS", __func__)); | ("%s: numsecflavors >= MAXSECFLAVORS", __func__)); | ||||
/* | /* | ||||
* XXX: This routine converts from a `struct xucred' | * XXX: This routine converts from a uid plus gid list | ||||
* (argp->ex_anon) to a `struct ucred' (np->netc_anon). This | * to a `struct ucred' (np->netc_anon). This | ||||
* operation is questionable; for example, what should be done | * operation is questionable; for example, what should be done | ||||
* with fields like cr_uidinfo and cr_prison? Currently, this | * with fields like cr_uidinfo and cr_prison? Currently, this | ||||
* routine does not touch them (leaves them as NULL). | * 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 (argp->ex_addrlen == 0) { | ||||
if (mp->mnt_flag & MNT_DEFEXPORTED) { | if (mp->mnt_flag & MNT_DEFEXPORTED) { | ||||
vfs_mount_error(mp, | vfs_mount_error(mp, | ||||
"MNT_DEFEXPORTED already set for mount %p", mp); | "MNT_DEFEXPORTED already set for mount %p", mp); | ||||
return (EPERM); | return (EPERM); | ||||
} | } | ||||
np = &nep->ne_defexported; | np = &nep->ne_defexported; | ||||
np->netc_exflags = argp->ex_flags; | np->netc_exflags = argp->ex_flags; | ||||
np->netc_anon = crget(); | np->netc_anon = crget(); | ||||
np->netc_anon->cr_uid = argp->ex_anon.cr_uid; | np->netc_anon->cr_uid = argp->ex_uid; | ||||
crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups, | crsetgroups(np->netc_anon, argp->ex_ngroups, | ||||
argp->ex_anon.cr_groups); | argp->ex_groups); | ||||
np->netc_anon->cr_prison = &prison0; | np->netc_anon->cr_prison = &prison0; | ||||
prison_hold(np->netc_anon->cr_prison); | prison_hold(np->netc_anon->cr_prison); | ||||
np->netc_numsecflavors = argp->ex_numsecflavors; | np->netc_numsecflavors = argp->ex_numsecflavors; | ||||
bcopy(argp->ex_secflavors, np->netc_secflavors, | bcopy(argp->ex_secflavors, np->netc_secflavors, | ||||
sizeof(np->netc_secflavors)); | sizeof(np->netc_secflavors)); | ||||
MNT_ILOCK(mp); | MNT_ILOCK(mp); | ||||
mp->mnt_flag |= MNT_DEFEXPORTED; | mp->mnt_flag |= MNT_DEFEXPORTED; | ||||
MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | #endif | ||||
if (rn == NULL || np != (struct netcred *)rn) { /* already exists */ | if (rn == NULL || np != (struct netcred *)rn) { /* already exists */ | ||||
error = EPERM; | error = EPERM; | ||||
vfs_mount_error(mp, | vfs_mount_error(mp, | ||||
"netcred already exists for given addr/mask"); | "netcred already exists for given addr/mask"); | ||||
goto out; | goto out; | ||||
} | } | ||||
np->netc_exflags = argp->ex_flags; | np->netc_exflags = argp->ex_flags; | ||||
np->netc_anon = crget(); | np->netc_anon = crget(); | ||||
np->netc_anon->cr_uid = argp->ex_anon.cr_uid; | np->netc_anon->cr_uid = argp->ex_uid; | ||||
crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups, | crsetgroups(np->netc_anon, argp->ex_ngroups, | ||||
argp->ex_anon.cr_groups); | argp->ex_groups); | ||||
np->netc_anon->cr_prison = &prison0; | np->netc_anon->cr_prison = &prison0; | ||||
prison_hold(np->netc_anon->cr_prison); | prison_hold(np->netc_anon->cr_prison); | ||||
np->netc_numsecflavors = argp->ex_numsecflavors; | np->netc_numsecflavors = argp->ex_numsecflavors; | ||||
bcopy(argp->ex_secflavors, np->netc_secflavors, | bcopy(argp->ex_secflavors, np->netc_secflavors, | ||||
sizeof(np->netc_secflavors)); | sizeof(np->netc_secflavors)); | ||||
return (0); | return (0); | ||||
out: | out: | ||||
free(np, M_NETADDR); | free(np, M_NETADDR); | ||||
▲ Show 20 Lines • Show All 275 Lines • ▼ Show 20 Lines | |||||
* XXX: and may not entirely apply, but lacking something better: | * XXX: and may not entirely apply, but lacking something better: | ||||
* This is the generic part of fhtovp called after the underlying | * This is the generic part of fhtovp called after the underlying | ||||
* filesystem has validated the file handle. | * filesystem has validated the file handle. | ||||
* | * | ||||
* Verify that a host should have access to a filesystem. | * Verify that a host should have access to a filesystem. | ||||
*/ | */ | ||||
int | int | ||||
vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, | vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, uint64_t *extflagsp, | ||||
struct ucred **credanonp, int *numsecflavors, int **secflavors) | struct ucred **credanonp, int *numsecflavors, int *secflavors) | ||||
{ | { | ||||
struct netcred *np; | struct netcred *np; | ||||
lockmgr(&mp->mnt_explock, LK_SHARED, NULL); | lockmgr(&mp->mnt_explock, LK_SHARED, NULL); | ||||
np = vfs_export_lookup(mp, nam); | np = vfs_export_lookup(mp, nam); | ||||
if (np == NULL) { | if (np == NULL) { | ||||
lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); | lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); | ||||
*credanonp = NULL; | *credanonp = NULL; | ||||
return (EACCES); | return (EACCES); | ||||
} | } | ||||
*extflagsp = np->netc_exflags; | *extflagsp = np->netc_exflags; | ||||
if ((*credanonp = np->netc_anon) != NULL) | if ((*credanonp = np->netc_anon) != NULL) | ||||
crhold(*credanonp); | crhold(*credanonp); | ||||
if (numsecflavors) { | if (numsecflavors) { | ||||
*numsecflavors = np->netc_numsecflavors; | *numsecflavors = np->netc_numsecflavors; | ||||
KASSERT(*numsecflavors > 0, | KASSERT(*numsecflavors > 0, | ||||
("%s: numsecflavors <= 0", __func__)); | ("%s: numsecflavors <= 0", __func__)); | ||||
KASSERT(*numsecflavors < MAXSECFLAVORS, | KASSERT(*numsecflavors < MAXSECFLAVORS, | ||||
("%s: numsecflavors >= MAXSECFLAVORS", __func__)); | ("%s: numsecflavors >= MAXSECFLAVORS", __func__)); | ||||
} | } | ||||
if (secflavors) | if (secflavors && np->netc_numsecflavors > 0) | ||||
*secflavors = np->netc_secflavors; | memcpy(secflavors, np->netc_secflavors, np->netc_numsecflavors * | ||||
sizeof(int)); | |||||
lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); | lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); | ||||
return (0); | return (0); | ||||
} | } | ||||