+ if (NFS_BITMAP_ISSET(mattrs, NFS_MATTR_LOCAL_NFS_PORT)) {
+ if (nmp->nm_nfsport) {
+ error = EINVAL;
+ NFS_VFS_DBG("Can't have ports specified over incompatible socket families");
+ }
+ nfsmerr_if(error);
+ xb_get_32(error, &xb, len);
+ if (!error && ((len < 1) || (len > sizeof(((struct sockaddr_un *)0)->sun_path)))) {
+ error = EINVAL;
+ }
+ nfsmerr_if(error);
+ MALLOC(nmp->nm_nfs_localport, char *, len + 1, M_TEMP, M_WAITOK | M_ZERO);
+ if (!nmp->nm_nfs_localport) {
+ error = ENOMEM;
+ }
+ nfsmerr_if(error);
+ error = xb_get_bytes(&xb, nmp->nm_nfs_localport, len, 0);
+ nmp->nm_sofamily = AF_LOCAL;
+ nmp->nm_nfsport = 1; /* We use the now deprecated tpcmux port to indcate that we have an AF_LOCAL port */
+ NFS_VFS_DBG("Setting nfs local port %s (%d)\n", nmp->nm_nfs_localport, nmp->nm_nfsport);
+ }
+ if (NFS_BITMAP_ISSET(mattrs, NFS_MATTR_LOCAL_MOUNT_PORT)) {
+ if (nmp->nm_mountport) {
+ error = EINVAL;
+ NFS_VFS_DBG("Can't have ports specified over mulitple socket families");
+ }
+ nfsmerr_if(error);
+ xb_get_32(error, &xb, len);
+ if (!error && ((len < 1) || (len > sizeof(((struct sockaddr_un *)0)->sun_path)))) {
+ error = EINVAL;
+ }
+ nfsmerr_if(error);
+ MALLOC(nmp->nm_mount_localport, char *, len + 1, M_TEMP, M_WAITOK | M_ZERO);
+ if (!nmp->nm_mount_localport) {
+ error = ENOMEM;
+ }
+ nfsmerr_if(error);
+ error = xb_get_bytes(&xb, nmp->nm_mount_localport, len, 0);
+ nmp->nm_sofamily = AF_LOCAL;
+ nmp->nm_mountport = 1; /* We use the now deprecated tpcmux port to indcate that we have an AF_LOCAL port */
+ NFS_VFS_DBG("Setting mount local port %s (%d)\n", nmp->nm_mount_localport, nmp->nm_mountport);
+ }
+ if (NFS_BITMAP_ISSET(mattrs, NFS_MATTR_SET_MOUNT_OWNER)) {
+ xb_get_32(error, &xb, set_owner);
+ nfsmerr_if(error);
+ error = vfs_context_suser(ctx);
+ /*
+ * root can set owner to whatever, user can set owner to self
+ */
+ if ((error) && (set_owner == kauth_cred_getuid(vfs_context_ucred(ctx)))) {
+ /* ok for non-root can set owner to self */
+ error = 0;
+ }
+ nfsmerr_if(error);
+ }
+