projects
/
unix-history
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
turn on keep alives
[unix-history]
/
usr
/
src
/
libexec
/
rshd
/
rshd.c
diff --git
a/usr/src/libexec/rshd/rshd.c
b/usr/src/libexec/rshd/rshd.c
index
9c207f8
..
f88ad8e
100644
(file)
--- a/
usr/src/libexec/rshd/rshd.c
+++ b/
usr/src/libexec/rshd/rshd.c
@@
-1,5
+1,5
@@
#ifndef lint
#ifndef lint
-static char sccsid[] = "@(#)rshd.c 4.
6 82/12/25
";
+static char sccsid[] = "@(#)rshd.c 4.
15 83/05/03
";
#endif
#include <sys/ioctl.h>
#endif
#include <sys/ioctl.h>
@@
-16,10
+16,11
@@
static char sccsid[] = "@(#)rshd.c 4.6 82/12/25";
#include <netdb.h>
int errno;
#include <netdb.h>
int errno;
+int reapchild();
struct sockaddr_in sin = { AF_INET };
struct passwd *getpwnam();
char *index(), *rindex(), *sprintf();
struct sockaddr_in sin = { AF_INET };
struct passwd *getpwnam();
char *index(), *rindex(), *sprintf();
-int options
= SO_ACCEPTCONN|SO_KEEPALIVE
;
+int options;
/* VARARGS 1 */
int error();
/*
/* VARARGS 1 */
int error();
/*
@@
-33,7
+34,6
@@
main(argc, argv)
int argc;
char **argv;
{
int argc;
char **argv;
{
- union wait status;
int f;
struct sockaddr_in from;
struct servent *sp;
int f;
struct sockaddr_in from;
struct servent *sp;
@@
-61,6
+61,10
@@
main(argc, argv)
sin.sin_port = sp->s_port;
argc--, argv++;
if (argc > 0 && !strcmp(argv[0], "-d")) {
sin.sin_port = sp->s_port;
argc--, argv++;
if (argc > 0 && !strcmp(argv[0], "-d")) {
+ options |= SO_DEBUG;
+ argc--, argv++;
+ }
+ if (argc > 0) {
int port = atoi(argv[0]);
if (port < 0) {
int port = atoi(argv[0]);
if (port < 0) {
@@
-75,30
+79,43
@@
main(argc, argv)
perror("rshd: socket");
exit(1);
}
perror("rshd: socket");
exit(1);
}
+ if (options & SO_DEBUG && setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
+ perror("rshd: setsockopt (SO_DEBUG)");
+ if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
+ perror("rshd: setsockopt (SO_KEEPALIVE)");
if (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
perror("rshd: bind");
exit(1);
}
if (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
perror("rshd: bind");
exit(1);
}
+ sigset(SIGCHLD, reapchild);
listen(f, 10);
for (;;) {
int g, len = sizeof (from);
g = accept(f, &from, &len, 0);
if (g < 0) {
listen(f, 10);
for (;;) {
int g, len = sizeof (from);
g = accept(f, &from, &len, 0);
if (g < 0) {
- perror("accept");
- sleep(1);
+ if (errno == EINTR)
+ continue;
+ perror("rshd: accept");
continue;
}
if (fork() == 0) {
continue;
}
if (fork() == 0) {
+ signal(SIGCHLD, SIG_IGN);
close(f);
doit(g, &from);
}
close(g);
close(f);
doit(g, &from);
}
close(g);
- while (wait3(status, WNOHANG, 0) > 0)
- continue;
}
}
}
}
+reapchild()
+{
+ union wait status;
+
+ while (wait3(&status, WNOHANG, 0) > 0)
+ ;
+}
+
char username[20] = "USER=";
char homedir[64] = "HOME=";
char shell[64] = "SHELL=";
char username[20] = "USER=";
char homedir[64] = "HOME=";
char shell[64] = "SHELL=";
@@
-113,7
+130,7
@@
doit(f, fromp)
char cmdbuf[NCARGS+1], *cp;
char locuser[16], remuser[16];
struct passwd *pwd;
char cmdbuf[NCARGS+1], *cp;
char locuser[16], remuser[16];
struct passwd *pwd;
- int s;
+ int s
, backoff
;
struct hostent *hp;
short port;
int pv[2], pid, ready, readfrom, cc;
struct hostent *hp;
short port;
int pv[2], pid, ready, readfrom, cc;
@@
-131,37
+148,46
@@
doit(f, fromp)
}
}
#endif
}
}
#endif
- dup2(f, 0);
- dup2(f, 1);
- dup2(f, 2);
fromp->sin_port = ntohs((u_short)fromp->sin_port);
if (fromp->sin_family != AF_INET ||
fromp->sin_port = ntohs((u_short)fromp->sin_port);
if (fromp->sin_family != AF_INET ||
- fromp->sin_port >= IPPORT_RESERVED)
+ fromp->sin_port >= IPPORT_RESERVED) {
+ fprintf(stderr, "rshd: malformed from address\n");
exit(1);
exit(1);
+ }
(void) alarm(60);
port = 0;
for (;;) {
char c;
(void) alarm(60);
port = 0;
for (;;) {
char c;
- if (read(f, &c, 1) != 1)
+ if (read(f, &c, 1) != 1) {
+ perror("rshd: read");
+ shutdown(f, 1+1);
exit(1);
exit(1);
+ }
if (c == 0)
break;
port = port * 10 + c - '0';
}
(void) alarm(0);
if (port != 0) {
if (c == 0)
break;
port = port * 10 + c - '0';
}
(void) alarm(0);
if (port != 0) {
- int lport = IPPORT_RESERVED - 1;
- s = rresvport(0, &lport);
- if (s < 0)
+ int lport = IPPORT_RESERVED - 1, retryshift;
+ s = rresvport(&lport);
+ if (s < 0) {
+ perror("rshd: can't get stderr port");
+ exit(1);
+ }
+ if (port >= IPPORT_RESERVED) {
+ fprintf(stderr, "rshd: 2nd port not reserved\n");
exit(1);
exit(1);
- if (port >= IPPORT_RESERVED)
- goto protofail;
- (void) alarm(60);
+ }
fromp->sin_port = htons((u_short)port);
fromp->sin_port = htons((u_short)port);
- if (connect(s, fromp, sizeof (*fromp), 0) < 0)
+ if (connect(s, fromp, sizeof (*fromp), 0) < 0) {
+ perror("rshd: connect");
exit(1);
exit(1);
- (void) alarm(0);
+ }
}
}
+ dup2(f, 0);
+ dup2(f, 1);
+ dup2(f, 2);
hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
fromp->sin_family);
if (hp == 0) {
hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
fromp->sin_family);
if (hp == 0) {
@@
-182,7
+208,7
@@
doit(f, fromp)
error("No remote directory.\n");
exit(1);
}
error("No remote directory.\n");
exit(1);
}
- if (ruserok(hp->h_name, remuser, locuser) < 0) {
+ if (ruserok(hp->h_name,
pwd->pw_uid == 0,
remuser, locuser) < 0) {
error("Permission denied.\n");
exit(1);
}
error("Permission denied.\n");
exit(1);
}
@@
-214,10
+240,10
@@
doit(f, fromp)
killpg(pid, sig);
}
if (ready & (1<<pv[0])) {
killpg(pid, sig);
}
if (ready & (1<<pv[0])) {
+ errno = 0;
cc = read(pv[0], buf, sizeof (buf));
if (cc <= 0) {
cc = read(pv[0], buf, sizeof (buf));
if (cc <= 0) {
- int done = 1+1;
- ioctl(s, SIOCDONE, (char *)&done);
+ shutdown(s, 1+1);
readfrom &= ~(1<<pv[0]);
} else
(void) write(s, buf, cc);
readfrom &= ~(1<<pv[0]);
} else
(void) write(s, buf, cc);
@@
-233,8
+259,8
@@
doit(f, fromp)
pwd->pw_shell = "/bin/sh";
(void) close(f);
initgroups(pwd->pw_name, pwd->pw_gid);
pwd->pw_shell = "/bin/sh";
(void) close(f);
initgroups(pwd->pw_name, pwd->pw_gid);
- (void) setuid(pwd->pw_uid);
(void) setgid(pwd->pw_gid);
(void) setgid(pwd->pw_gid);
+ (void) setuid(pwd->pw_uid);
environ = envinit;
strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
strncat(shell, pwd->pw_shell, sizeof(shell)-7);
environ = envinit;
strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
strncat(shell, pwd->pw_shell, sizeof(shell)-7);