37 #include <sys/cdefs.h>
40 #include <sys/param.h>
41 #include <sys/dirent.h>
42 #include <sys/domain.h>
44 #include <sys/kernel.h>
46 #include <sys/malloc.h>
48 #include <sys/mount.h>
49 #include <sys/mutex.h>
50 #include <sys/rwlock.h>
51 #include <sys/refcount.h>
52 #include <sys/signalvar.h>
53 #include <sys/socket.h>
54 #include <sys/systm.h>
55 #include <sys/vnode.h>
57 #include <net/radix.h>
59 static MALLOC_DEFINE(M_NETADDR,
"export_host",
"Export host address structure");
64 struct export_args *argp);
92 struct export_args *argp)
95 register struct radix_node_head *rnh;
97 struct radix_node *rn;
98 struct sockaddr *saddr, *smask = 0;
109 if (argp->ex_anon.cr_version != XUCRED_VERSION) {
111 argp->ex_anon.cr_version, XUCRED_VERSION);
115 if (argp->ex_addrlen == 0) {
116 if (mp->mnt_flag & MNT_DEFEXPORTED) {
118 "MNT_DEFEXPORTED already set for mount %p", mp);
124 np->
netc_anon->cr_uid = argp->ex_anon.cr_uid;
126 argp->ex_anon.cr_groups);
133 mp->mnt_flag |= MNT_DEFEXPORTED;
139 if (argp->ex_addrlen > MLEN) {
141 argp->ex_addrlen, MLEN);
146 i =
sizeof(
struct netcred) + argp->ex_addrlen + argp->ex_masklen;
147 np = (
struct netcred *)
malloc(i, M_NETADDR, M_WAITOK | M_ZERO);
148 saddr = (
struct sockaddr *) (np + 1);
149 if ((error = copyin(argp->ex_addr, saddr, argp->ex_addrlen)))
151 if (saddr->sa_family == AF_UNSPEC || saddr->sa_family > AF_MAX) {
156 if (saddr->sa_len > argp->ex_addrlen)
157 saddr->sa_len = argp->ex_addrlen;
158 if (argp->ex_masklen) {
159 smask = (
struct sockaddr *)((caddr_t)saddr + argp->ex_addrlen);
160 error = copyin(argp->ex_mask, smask, argp->ex_masklen);
163 if (smask->sa_len > argp->ex_masklen)
164 smask->sa_len = argp->ex_masklen;
166 i = saddr->sa_family;
172 for (dom =
domains; dom; dom = dom->dom_next) {
173 KASSERT(((i == AF_INET) || (i == AF_INET6)),
174 (
"unexpected protocol in vfs_hang_addrlist"));
175 if (dom->dom_family == i && dom->dom_rtattach) {
194 "Unable to initialize radix node head ",
195 "for address family", i);
199 RADIX_NODE_HEAD_LOCK(rnh);
200 rn = (*rnh->rnh_addaddr)(saddr, smask, rnh, np->netc_rnodes);
201 RADIX_NODE_HEAD_UNLOCK(rnh);
202 if (rn == NULL || np != (
struct netcred *)rn) {
208 np->netc_exflags = argp->ex_flags;
210 np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
211 crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
212 argp->ex_anon.cr_groups);
213 np->netc_anon->cr_prison = &
prison0;
215 np->netc_numsecflavors = argp->ex_numsecflavors;
217 sizeof(np->netc_secflavors));
229 struct radix_node_head *rnh = (
struct radix_node_head *) w;
232 (*rnh->rnh_deladdr) (rn->rn_key, rn->rn_mask, rnh);
233 cred = ((
struct netcred *)rn)->netc_anon;
247 struct radix_node_head *rnh;
250 for (i = 0; i <= AF_MAX; i++) {
252 RADIX_NODE_HEAD_LOCK(rnh);
254 RADIX_NODE_HEAD_UNLOCK(rnh);
255 RADIX_NODE_HEAD_DESTROY(rnh);
278 if (argp->ex_numsecflavors < 0
279 || argp->ex_numsecflavors >= MAXSECFLAVORS)
283 lockmgr(&mp->mnt_explock, LK_EXCLUSIVE, NULL);
284 nep = mp->mnt_export;
285 if (argp->ex_flags & MNT_DELEXPORT) {
290 if (mp->mnt_flag & MNT_EXPUBLIC) {
293 mp->mnt_flag &= ~MNT_EXPUBLIC;
297 mp->mnt_export = NULL;
301 mp->mnt_flag &= ~(MNT_EXPORTED | MNT_DEFEXPORTED);
304 if (argp->ex_flags & MNT_EXPORTED) {
307 mp->mnt_export = nep;
309 if (argp->ex_flags & MNT_EXPUBLIC) {
313 mp->mnt_flag |= MNT_EXPUBLIC;
319 mp->mnt_flag |= MNT_EXPORTED;
324 lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
344 struct export_args *argp)
356 if (nfs_pub.np_valid) {
357 nfs_pub.np_valid = 0;
358 if (nfs_pub.np_index != NULL) {
359 free(nfs_pub.np_index, M_TEMP);
360 nfs_pub.np_index = NULL;
369 if (nfs_pub.np_valid != 0 && mp != nfs_pub.np_mount)
375 bzero(&nfs_pub.np_handle,
sizeof(nfs_pub.np_handle));
376 nfs_pub.np_handle.fh_fsid = mp->mnt_stat.f_fsid;
378 if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rvp)))
381 if ((error = VOP_VPTOFH(rvp, &nfs_pub.np_handle.fh_fid)))
389 if (argp->ex_indexfile != NULL) {
390 if (nfs_pub.np_index != NULL)
391 nfs_pub.np_index =
malloc(MAXNAMLEN + 1, M_TEMP,
393 error = copyinstr(argp->ex_indexfile, nfs_pub.np_index,
394 MAXNAMLEN, (
size_t *)0);
399 for (cp = nfs_pub.np_index; *cp; cp++) {
407 free(nfs_pub.np_index, M_TEMP);
408 nfs_pub.np_index = NULL;
413 nfs_pub.np_mount = mp;
414 nfs_pub.np_valid = 1;
429 register struct radix_node_head *rnh;
430 struct sockaddr *saddr;
432 nep = mp->mnt_export;
436 if (mp->mnt_flag & MNT_EXPORTED) {
444 RADIX_NODE_HEAD_RLOCK(rnh);
446 (*rnh->rnh_matchaddr)(saddr, rnh);
447 RADIX_NODE_HEAD_RUNLOCK(rnh);
455 if (np == NULL && mp->mnt_flag & MNT_DEFEXPORTED)
472 struct ucred **credanonp,
int *numsecflavors,
int **secflavors)
476 lockmgr(&mp->mnt_explock, LK_SHARED, NULL);
479 lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
484 if ((*credanonp = np->
netc_anon) != NULL)
490 lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
struct netcred ne_defexported
void vfs_deleteopt(struct vfsoptlist *opts, const char *name)
int vfs_export(struct mount *mp, struct export_args *argp)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
struct radix_node_head * ne_rtable[AF_MAX+1]
void vfs_mount_error(struct mount *mp, const char *fmt,...)
int vfs_setpublicfs(struct mount *mp, struct netexport *nep, struct export_args *argp)
struct radix_node netc_rnodes[2]
static int vfs_hang_addrlist(struct mount *mp, struct netexport *nep, struct export_args *argp)
void vput(struct vnode *vp)
void crfree(struct ucred *cr)
void prison_hold(struct prison *pr)
static struct netcred * vfs_export_lookup(struct mount *, struct sockaddr *)
static void vfs_free_addrlist(struct netexport *nep)
static MALLOC_DEFINE(M_NETADDR,"export_host","Export host address structure")
int netc_secflavors[MAXSECFLAVORS]
struct ucred * crhold(struct ucred *cr)
void free(void *addr, struct malloc_type *mtp)
void crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
int vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, struct ucred **credanonp, int *numsecflavors, int **secflavors)
static int vfs_free_netcred(struct radix_node *rn, void *w)
struct ucred * crget(void)