toddb@tekcrl.UUCP (Todd Brunhoff) (01/27/86)
Thanks to everyone for contributing time to fix up RFS! Joe Othmer at Bell Labs found the problems related to the execution of a remote binary. The reason that ksh tended to fail on all remote executions seemed to be a particular sequence of system calls. The problem was that if a file was remote, u.u_count was not initialized, but it was used. Here's the fix for 4.2 /sys/sys/kern_exec.c: *************** *** 128,133 u.u_count = resid; #ifdef REMOTEFS } remote_again: --- 128,135 ----- u.u_count = resid; #ifdef REMOTEFS } + else + u.u_count = 0; remote_again: And Here's the same fix for 4.3 /sys/sys/kern_exec.c (4.3 uses resid instead of u.u_count): *************** *** 129,133 #ifdef REMOTEFS } remote_again: --- 129,135 ----- #ifdef REMOTEFS } + else + resid = 0; remote_again: The reason that you could execute all remote files, reguardless of their mode was due to the wrong error being returned in the server. Joe also found the fix for this in remote/serversyscall.c in the routine s_execinfo(): There error returned should be EACCES. *************** *** 441,447 if ((st.st_mode & S_IFMT) != S_IFREG || ! myaccess(&st, proc->p_ruser->r_user, X_OK)) { ! err = ENOEXEC; debug12("%s mode=0%o %sreg file, %sexecutable\n", path, st.st_mode, (st.st_mode & S_IFMT) != S_IFREG ? "not " : "", --- 441,457 ----- if ((st.st_mode & S_IFMT) != S_IFREG || ! myaccess(&st, proc->p_ruser->r_user, X_OK)) { ! err = EACCES; debug12("%s mode=0%o %sreg file, %sexecutable\n", path, st.st_mode, (st.st_mode & S_IFMT) != S_IFREG ? "not " : "", Bill Sommerfeld at MIT has found that the server code is not compatible with the BIND nameserver. No fix for this... but he said using the old compatibility routines works fine. He also found that in later 4.3 beta releases, the names of one of the structure elements used by the server conflicts with a define in /usr/include/netdb.h; specifically, h_addr. The following diffs show where the changes need to be made to change h_addr to h_iaddr (for "internet address"). Note that not all of the occurences of h_addr can be changed. ------ remote/find.c -------- *************** *** 102,108 debug4("find %s...\n", inet_ntoa(*addr)); for(h=hostlist; h; h=h->h_next) ! if (bcmp(addr, &h->h_addr, sizeof(struct in_addr)) == 0) { toplist(&hostlist, h); debug4("\tis %s (%s)\n", --- 102,108 ----- debug4("find %s...\n", inet_ntoa(*addr)); for(h=hostlist; h; h=h->h_next) ! if (bcmp(addr, &h->h_iaddr, sizeof(struct in_addr)) == 0) { toplist(&hostlist, h); debug4("\tis %s (%s)\n", *************** *** 106,112 { toplist(&hostlist, h); debug4("\tis %s (%s)\n", ! h->h_names[0], inet_ntoa(h->h_addr)); return(h); } else --- 106,112 ----- { toplist(&hostlist, h); debug4("\tis %s (%s)\n", ! h->h_names[0], inet_ntoa(h->h_iaddr)); return(h); } else *************** *** 111,117 } else debug4("\tnot %s (%s)\n", ! h->h_names[0], inet_ntoa(h->h_addr)); log("no host entry for %s, continuing anyway.\n", inet_ntoa(*addr)); /* * Kludge up a hosts structure for this guy --- 111,117 ----- } else debug4("\tnot %s (%s)\n", ! h->h_names[0], inet_ntoa(h->h_iaddr)); log("no host entry for %s, continuing anyway.\n", inet_ntoa(*addr)); /* * Kludge up a hosts structure for this guy *************** *** 118,124 */ h = newhost(); h->h_names = newname(NULL, BOGUSHOST); ! bcopy(addr, &h->h_addr, sizeof(struct in_addr)); addlist(&hostlist, h); return(h); } --- 118,124 ----- */ h = newhost(); h->h_names = newname(NULL, BOGUSHOST); ! bcopy(addr, &h->h_iaddr, sizeof(struct in_addr)); addlist(&hostlist, h); return(h); } --- remote/info.c ------ *************** *** 320,326 sin = &sinbuf; debug6("path %s mapped to host %s\n", path, h->h_names[0]); bzero((char *)sin, sizeof (struct sockaddr_in)); ! bcopy(&h->h_addr, (char *)&sin->sin_addr, sizeof(struct in_addr)); sin->sin_family = AF_INET; sin->sin_port = serviceport; --- 320,326 ----- sin = &sinbuf; debug6("path %s mapped to host %s\n", path, h->h_names[0]); bzero((char *)sin, sizeof (struct sockaddr_in)); ! bcopy(&h->h_iaddr, (char *)&sin->sin_addr, sizeof(struct in_addr)); sin->sin_family = AF_INET; sin->sin_port = serviceport; --- remote/init.c ------ *************** *** 210,216 hst->h_names = newname(hst->h_names, h->h_aliases[ i ]); ! hst->h_addr = *((struct in_addr *)(h->h_addr)); addlist(&hostlist, hst); /* --- 210,216 ----- hst->h_names = newname(hst->h_names, h->h_aliases[ i ]); ! hst->h_iaddr = *((struct in_addr *)(h->h_addr)); addlist(&hostlist, hst); /* *************** *** 234,240 hst->h_default_user = user; debug2("default user for host %s (%s) is %s\n", hst->h_names[ 0 ], ! inet_ntoa(hst->h_addr), user->u_name); } ruser = hst->h_default_ruser = newruser(); if (user) --- 234,240 ----- hst->h_default_user = user; debug2("default user for host %s (%s) is %s\n", hst->h_names[ 0 ], ! inet_ntoa(hst->h_iaddr), user->u_name); } ruser = hst->h_default_ruser = newruser(); if (user) --- remote/serverio.c *************** *** 131,137 register long s; bzero((char *)&sin, sizeof (sin)); ! bcopy(&h->h_addr, (char *)&sin.sin_addr, sizeof(struct in_addr)); sin.sin_family = AF_INET; sin.sin_port = serviceport; s = socket(AF_INET, SOCK_STREAM, 0); --- 131,137 ----- register long s; bzero((char *)&sin, sizeof (sin)); ! bcopy(&h->h_iaddr, (char *)&sin.sin_addr, sizeof(struct in_addr)); sin.sin_family = AF_INET; sin.sin_port = serviceport; s = socket(AF_INET, SOCK_STREAM, 0); --- remote/server.h ----- *************** *** 207,213 long h_portnum; /* port number that we connected on */ char *h_mntpt; /* mount point for this machine */ process *h_proclist; /* processes we know about on this host */ ! struct in_addr h_addr; /* network address */ union h_bytes { long hu_mounted; /* non-zero if host has been mounted */ u_char hu_byteorder[4]; /* byte order for this host */ --- 207,213 ----- long h_portnum; /* port number that we connected on */ char *h_mntpt; /* mount point for this machine */ process *h_proclist; /* processes we know about on this host */ ! struct in_addr h_iaddr;/* internet address */ union h_bytes { long hu_mounted; /* non-zero if host has been mounted */ u_char hu_byteorder[4]; /* byte order for this host */ "bruce" @ think noticed that new kernel include file, remotefs.h, contained an interesting octal constant: 08000. Fortunately pcc interprets this the way I meant it as 010000. The following is the context diff for that change. --- /sys/remote/remotefs.h ----- *************** *** 85,91 #if vax || magnolia || P4400 #define SREMOTE 0x08000000 /* proc.h: activity has occured */ #define SNOREMOTE 0x10000000 /* proc.h: disallow remote access */ ! #define FREMOTE 08000 /* file.h: this is a remote file */ #endif vax || magnolia || P4400 /* --- 85,91 ----- #if vax || magnolia || P4400 #define SREMOTE 0x08000000 /* proc.h: activity has occured */ #define SNOREMOTE 0x10000000 /* proc.h: disallow remote access */ ! #define FREMOTE 010000 /* file.h: this is a remote file */ #endif vax || magnolia || P4400 /*