* Build hash lists of net addresses and hang them off the mount point. * Called by vfs_export() to set up the lists of export addresses. */
| 102 | * Called by vfs_export() to set up the lists of export addresses. |
| 103 | */ |
| 104 | static int |
| 105 | vfs_hang_addrlist(struct mount *mp, struct netexport *nep, |
| 106 | struct export_args *argp) |
| 107 | { |
| 108 | struct netcred *np; |
| 109 | struct radix_node_head *rnh; |
| 110 | int i; |
| 111 | struct radix_node *rn; |
| 112 | struct sockaddr *saddr, *smask = NULL; |
| 113 | #if defined(INET6) || defined(INET) |
| 114 | int off; |
| 115 | #endif |
| 116 | int error; |
| 117 | |
| 118 | KASSERT(argp->ex_numsecflavors > 0, |
| 119 | ("%s: numsecflavors <= 0", __func__)); |
| 120 | KASSERT(argp->ex_numsecflavors < MAXSECFLAVORS, |
| 121 | ("%s: numsecflavors >= MAXSECFLAVORS", __func__)); |
| 122 | |
| 123 | /* |
| 124 | * XXX: This routine converts from a uid plus gid list |
| 125 | * to a `struct ucred' (np->netc_anon). This |
| 126 | * operation is questionable; for example, what should be done |
| 127 | * with fields like cr_uidinfo and cr_prison? Currently, this |
| 128 | * routine does not touch them (leaves them as NULL). |
| 129 | */ |
| 130 | if (argp->ex_addrlen == 0) { |
| 131 | if (mp->mnt_flag & MNT_DEFEXPORTED) { |
| 132 | vfs_mount_error(mp, |
| 133 | "MNT_DEFEXPORTED already set for mount %p", mp); |
| 134 | return (EPERM); |
| 135 | } |
| 136 | np = &nep->ne_defexported; |
| 137 | np->netc_exflags = argp->ex_flags; |
| 138 | np->netc_anon = crget(); |
| 139 | np->netc_anon->cr_uid = argp->ex_uid; |
| 140 | crsetgroups(np->netc_anon, argp->ex_ngroups, |
| 141 | argp->ex_groups); |
| 142 | np->netc_anon->cr_prison = &prison0; |
| 143 | prison_hold(np->netc_anon->cr_prison); |
| 144 | np->netc_numsecflavors = argp->ex_numsecflavors; |
| 145 | bcopy(argp->ex_secflavors, np->netc_secflavors, |
| 146 | sizeof(np->netc_secflavors)); |
| 147 | MNT_ILOCK(mp); |
| 148 | mp->mnt_flag |= MNT_DEFEXPORTED; |
| 149 | MNT_IUNLOCK(mp); |
| 150 | return (0); |
| 151 | } |
| 152 | |
| 153 | #if MSIZE <= 256 |
| 154 | if (argp->ex_addrlen > MLEN) { |
| 155 | vfs_mount_error(mp, "ex_addrlen %d is greater than %d", |
| 156 | argp->ex_addrlen, MLEN); |
| 157 | return (EINVAL); |
| 158 | } |
| 159 | #endif |
| 160 | |
| 161 | i = sizeof(struct netcred) + argp->ex_addrlen + argp->ex_masklen; |
no test coverage detected