Unofficial fixes for several nfs related problems:
1 - RFC1094 does not clarify what the semantics of a create rpc should be
on the server when the file already exists. It appears that some recent
versions of SunOS expect the file to be truncated to length 0 only if
the size field of the setattr has been specified. (This semantic has
not been clarified by anyone within Sun ONC engineering, although I
have tried mailing them.)
2 - IBM AIX3.2 NFS clients expect a server to reply RPCPROG_MISMATCH to
an rpc request sent to the nfs port (2049), but not nfs, in order to
identify an AIX server. (The 386bsd.01 server simply dropped these
requests on the floor, confusing AIX clients.)
3 - Some servers require that the nfs client use a reserved port number,
which the 386bsd.01 client did not. (The is a crock, since requiring
a reserved port number does not enhance nfs security significantly.)
AUTHOR: Rick "gopher I" (root@snowhite.cis.uoguelph.ca)
386BSD-Patchkit: patch00053
*
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
* -------------------- ----- ----------------------
*
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
* -------------------- ----- ----------------------
- * CURRENT PATCH LEVEL: 1 00016
+ * CURRENT PATCH LEVEL: 2 00053
* -------------------- ----- ----------------------
*
* -------------------- ----- ----------------------
*
+ * 08 Sep 92 Rick "gopher I" Fix "truncate" (conflicting?)
* 28 Aug 92 Arne Henrik Juul Fixed NFS "create" bug
*/
* 28 Aug 92 Arne Henrik Juul Fixed NFS "create" bug
*/
vput(nd.ni_dvp);
VOP_ABORTOP(&nd);
vap->va_size = fxdr_unsigned(long, *(tl+3)); /* 28 Aug 92*/
vput(nd.ni_dvp);
VOP_ABORTOP(&nd);
vap->va_size = fxdr_unsigned(long, *(tl+3)); /* 28 Aug 92*/
- if (error = VOP_SETATTR(vp, vap, cred, p)) {
+/* 08 Sep 92*/ if (vap->va_size != -1 && (error = VOP_SETATTR(vp, vap, cred, p))) {
vput(vp);
nfsm_reply(0);
}
vput(vp);
nfsm_reply(0);
}
struct proc *p;
{
caddr_t bpos;
struct proc *p;
{
caddr_t bpos;
+ int error; /* 08 Sep 92*/
+ if (*repstat) /* 08 Sep 92*/
+ error = *repstat;
+ else
+ error = EPROCUNAVAIL;
nfsm_reply(0);
return (error);
}
nfsm_reply(0);
return (error);
}
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 7.23 (Berkeley) 4/20/91
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 7.23 (Berkeley) 4/20/91
+ *
+ * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
+ * -------------------- ----- ----------------------
+ * CURRENT PATCH LEVEL: 1 00053
+ * -------------------- ----- ----------------------
+ *
+ * 08 Sep 92 Rick "gopher I" Fix "reserved port" bug, fixed for
+ * AIX3.2 NFS clients
register struct nfsmount *nmp;
{
register struct socket *so;
register struct nfsmount *nmp;
{
register struct socket *so;
+ struct sockaddr *saddr; /* 08 Sep 92*/
int s, error, bufsize;
struct mbuf *m;
int s, error, bufsize;
struct mbuf *m;
+ struct sockaddr_in *sin; /* 08 Sep 92*/
+ u_short tport; /* 08 Sep 92*/
nmp->nm_so = (struct socket *)0;
nmp->nm_so = (struct socket *)0;
- if (error = socreate(mtod(nmp->nm_nam, struct sockaddr *)->sa_family,
+ saddr = mtod(nmp->nm_nam, struct sockaddr *); /* 08 Sep 92*/
+ if (error = socreate(saddr->sa_family, /* 08 Sep 92*/
&nmp->nm_so, nmp->nm_sotype, nmp->nm_soproto))
goto bad;
so = nmp->nm_so;
nmp->nm_soflags = so->so_proto->pr_flags;
&nmp->nm_so, nmp->nm_sotype, nmp->nm_soproto))
goto bad;
so = nmp->nm_so;
nmp->nm_soflags = so->so_proto->pr_flags;
+ /*
+ * 08 Sep 92
+ *
+ * Some servers require that the client port be a reserved port number.
+ */
+ if (saddr->sa_family == AF_INET) {
+ MGET(m, M_WAIT, MT_SONAME);
+ sin = mtod(m, struct sockaddr_in *);
+ sin->sin_len = m->m_len = sizeof (struct sockaddr_in);
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_ANY;
+ tport = IPPORT_RESERVED - 1;
+ sin->sin_port = htons(tport);
+ while (sobind(so, m) == EADDRINUSE &&
+ --tport > IPPORT_RESERVED / 2)
+ sin->sin_port = htons(tport);
+ m_freem(m);
+ }
+
if (nmp->nm_sotype == SOCK_DGRAM)
bufsize = min(4 * (nmp->nm_wsize + NFS_MAXPKTHDR),
NFS_MAXPACKET);
if (nmp->nm_sotype == SOCK_DGRAM)
bufsize = min(4 * (nmp->nm_wsize + NFS_MAXPKTHDR),
NFS_MAXPACKET);
* - fill in the cred struct.
*/
nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr,
* - fill in the cred struct.
*/
nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr,
+ msk, mtch, wascomp, repstat) /* 08 Aug 92*/
struct socket *so;
u_long prog;
u_long vers;
struct socket *so;
u_long prog;
u_long vers;
u_long *procnum;
register struct ucred *cr;
struct mbuf *msk, *mtch;
u_long *procnum;
register struct ucred *cr;
struct mbuf *msk, *mtch;
+ int *wascomp, *repstat; /* 08 Aug 92*/
{
register int i;
register u_long *tl;
{
register int i;
register u_long *tl;
struct mbuf *mrep, *md;
int len;
struct mbuf *mrep, *md;
int len;
+ *repstat = 0; /* 08 Aug 92*/
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
error = nfs_receive(so, nam, &mrep, (struct nfsreq *)0);
} else {
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
error = nfs_receive(so, nam, &mrep, (struct nfsreq *)0);
} else {
dpos = mtod(mrep, caddr_t);
nfsm_disect(tl, u_long *, 10*NFSX_UNSIGNED);
*retxid = *tl++;
dpos = mtod(mrep, caddr_t);
nfsm_disect(tl, u_long *, 10*NFSX_UNSIGNED);
*retxid = *tl++;
- if (*tl++ != rpc_call) {
- m_freem(mrep);
- return (ERPCMISMATCH);
- }
- if (*tl++ != rpc_vers) {
- m_freem(mrep);
- return (ERPCMISMATCH);
+ if (*tl++ != rpc_call || *tl++ != rpc_vers) { /* 08 Aug 92*/
+ *mrp = mrep;
+ *procnum = NFSPROC_NOOP;
+ *repstat = ERPCMISMATCH;
+ return (0);
- m_freem(mrep);
- return (EPROGUNAVAIL);
+ *mrp = mrep; /* 08 Aug 92*/
+ *procnum = NFSPROC_NOOP;
+ *repstat = EPROGUNAVAIL;
+ return (0);
- m_freem(mrep);
- return (EPROGMISMATCH);
+ *mrp = mrep; /* 08 Aug 92*/
+ *procnum = NFSPROC_NOOP;
+ *repstat = EPROGMISMATCH;
+ return (0);
}
*procnum = fxdr_unsigned(u_long, *tl++);
if (*procnum == NFSPROC_NULL) {
}
*procnum = fxdr_unsigned(u_long, *tl++);
if (*procnum == NFSPROC_NULL) {
return (0);
}
if (*procnum > maxproc || *tl++ != rpc_auth_unix) {
return (0);
}
if (*procnum > maxproc || *tl++ != rpc_auth_unix) {
- m_freem(mrep);
- return (EPROCUNAVAIL);
+ *mrp = mrep; /* 08 Aug 92*/
+ *procnum = NFSPROC_NOOP;
+ *repstat = EPROCUNAVAIL;
+ return (0);
}
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
}
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 7.26 (Berkeley) 4/16/91
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 7.26 (Berkeley) 4/16/91
+ *
+ * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
+ * -------------------- ----- ----------------------
+ * CURRENT PATCH LEVEL: 1 00053
+ * -------------------- ----- ----------------------
+ *
+ * 08 Sep 92 Rick "gopher I" Fix "reserved port" bug, fixed for
+ * AIX3.2 NFS clients
for (;;) {
if (error = nfs_getreq(so, nfs_prog, nfs_vers, NFS_NPROCS-1,
&nam, &mrep, &md, &dpos, &retxid, &procid, cr,
for (;;) {
if (error = nfs_getreq(so, nfs_prog, nfs_vers, NFS_NPROCS-1,
&nam, &mrep, &md, &dpos, &retxid, &procid, cr,
- &msk, &mtch, &wascomp)) {
+/* 08 Sep 92*/ &msk, &mtch, &wascomp, &repstat)) {
if (nam)
m_freem(nam);
if (error == EPIPE || error == EINTR ||
if (nam)
m_freem(nam);
if (error == EPIPE || error == EINTR ||
* SUCH DAMAGE.
*
* @(#)nfsv2.h 7.8 (Berkeley) 6/28/90
* SUCH DAMAGE.
*
* @(#)nfsv2.h 7.8 (Berkeley) 6/28/90
+ *
+ * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
+ * -------------------- ----- ----------------------
+ * CURRENT PATCH LEVEL: 1 00053
+ * -------------------- ----- ----------------------
+ *
+ * 08 Sep 92 Rick "gopher I" Fix "reserved port" bug, fixed for
+ * AIX3.2 NFS clients
#define NFSPROC_GETATTR 1
#define NFSPROC_SETATTR 2
#define NFSPROC_ROOT 3 /* Obsolete */
#define NFSPROC_GETATTR 1
#define NFSPROC_SETATTR 2
#define NFSPROC_ROOT 3 /* Obsolete */
+#define NFSPROC_NOOP 3 /* Fake for err returns XXX 08 Sep 92*/
#define NFSPROC_LOOKUP 4
#define NFSPROC_READLINK 5
#define NFSPROC_READ 6
#define NFSPROC_LOOKUP 4
#define NFSPROC_READLINK 5
#define NFSPROC_READ 6