1*6446Swnj #ifndef lint 2*6446Swnj static char sccsid[] = "@(#)rlogind.c 4.1 82/04/02"; 3*6446Swnj #endif 4*6446Swnj 5*6446Swnj #include <stdio.h> 6*6446Swnj #include <sys/types.h> 7*6446Swnj #include <sys/stat.h> 8*6446Swnj #include <sys/socket.h> 9*6446Swnj #include <net/in.h> 10*6446Swnj #include <errno.h> 11*6446Swnj #include <pwd.h> 12*6446Swnj #include <wait.h> 13*6446Swnj #include <signal.h> 14*6446Swnj #include <sgtty.h> 15*6446Swnj #include <stdio.h> 16*6446Swnj 17*6446Swnj extern errno; 18*6446Swnj struct passwd *getpwnam(); 19*6446Swnj char *crypt(), *rindex(), *index(), *malloc(), *raddr(); 20*6446Swnj int options = SO_ACCEPTCONN|SO_KEEPALIVE; 21*6446Swnj struct sockaddr_in sin = { AF_INET, IPPORT_LOGINSERVER }; 22*6446Swnj /* 23*6446Swnj * remote login server: 24*6446Swnj * remuser\0 25*6446Swnj * locuser\0 26*6446Swnj * terminal type\0 27*6446Swnj * data 28*6446Swnj */ 29*6446Swnj main(argc, argv) 30*6446Swnj int argc; 31*6446Swnj char **argv; 32*6446Swnj { 33*6446Swnj union wait status; 34*6446Swnj int f, debug = 0; 35*6446Swnj struct sockaddr_in from; 36*6446Swnj 37*6446Swnj #ifndef DEBUG 38*6446Swnj if (fork()) 39*6446Swnj exit(0); 40*6446Swnj for (f = 0; f < 10; f++) 41*6446Swnj (void) close(f); 42*6446Swnj (void) open("/", 0); 43*6446Swnj (void) dup2(0, 1); 44*6446Swnj (void) dup2(0, 2); 45*6446Swnj { int tt = open("/dev/tty", 2); 46*6446Swnj if (tt > 0) { 47*6446Swnj ioctl(tt, TIOCNOTTY, 0); 48*6446Swnj close(tt); 49*6446Swnj } 50*6446Swnj } 51*6446Swnj #endif 52*6446Swnj #if vax 53*6446Swnj sin.sin_port = htons(sin.sin_port); 54*6446Swnj #endif 55*6446Swnj argc--, argv++; 56*6446Swnj if (argc > 0 && !strcmp(argv[0], "-d")) 57*6446Swnj options |= SO_DEBUG; 58*6446Swnj for (;;) { 59*6446Swnj f = socket(SOCK_STREAM, 0, &sin, options); 60*6446Swnj if (f < 0) { 61*6446Swnj perror("socket"); 62*6446Swnj sleep(5); 63*6446Swnj continue; 64*6446Swnj } 65*6446Swnj if (accept(f, &from) < 0) { 66*6446Swnj perror("accept"); 67*6446Swnj close(f); 68*6446Swnj sleep(1); 69*6446Swnj continue; 70*6446Swnj } 71*6446Swnj if (fork() == 0) 72*6446Swnj doit(f, &from); 73*6446Swnj close(f); 74*6446Swnj while (wait3(status, WNOHANG, 0) > 0) 75*6446Swnj continue; 76*6446Swnj } 77*6446Swnj } 78*6446Swnj 79*6446Swnj char locuser[32], remuser[32]; 80*6446Swnj char buf[BUFSIZ]; 81*6446Swnj int child; 82*6446Swnj int cleanup(); 83*6446Swnj int netf; 84*6446Swnj extern errno; 85*6446Swnj char *line; 86*6446Swnj 87*6446Swnj doit(f, fromp) 88*6446Swnj int f; 89*6446Swnj struct sockaddr_in *fromp; 90*6446Swnj { 91*6446Swnj char c, *rhost; 92*6446Swnj int i, p, cc, t; 93*6446Swnj int stop = TIOCPKT_DOSTOP; 94*6446Swnj 95*6446Swnj alarm(60); 96*6446Swnj read(f, &c, 1); 97*6446Swnj if (c != 0) 98*6446Swnj exit(1); 99*6446Swnj alarm(0); 100*6446Swnj #if vax 101*6446Swnj fromp->sin_port = htons(fromp->sin_port); 102*6446Swnj #endif 103*6446Swnj rhost = raddr(fromp->sin_addr.s_addr); 104*6446Swnj if (fromp->sin_family != AF_INET || 105*6446Swnj fromp->sin_port >= IPPORT_RESERVED || 106*6446Swnj rhost == 0) { 107*6446Swnj write(f, "\01Permission denied.\n", 20); 108*6446Swnj exit(1); 109*6446Swnj } 110*6446Swnj write(f, "", 1); 111*6446Swnj for (c = 'p'; c <= 's'; c++) { 112*6446Swnj struct stat stb; 113*6446Swnj line = "/dev/ptyXX"; 114*6446Swnj line[strlen("/dev/pty")] = c; 115*6446Swnj line[strlen("/dev/ptyp")] = '0'; 116*6446Swnj if (stat(line, &stb) < 0) 117*6446Swnj break; 118*6446Swnj for (i = 0; i < 16; i++) { 119*6446Swnj line[strlen("/dev/ptyp")] = "0123456789abcdef"[i]; 120*6446Swnj p = open(line, 2); 121*6446Swnj if (p > 0) 122*6446Swnj goto gotpty; 123*6446Swnj } 124*6446Swnj } 125*6446Swnj dup2(f, 1); 126*6446Swnj printf("All network ports in use.\r\n"); 127*6446Swnj exit(1); 128*6446Swnj gotpty: 129*6446Swnj dup2(f, 0); 130*6446Swnj line[strlen("/dev/")] = 't'; 131*6446Swnj #ifdef DEBUG 132*6446Swnj { int tt = open("/dev/tty", 2); 133*6446Swnj if (tt > 0) { 134*6446Swnj ioctl(tt, TIOCNOTTY, 0); 135*6446Swnj close(tt); 136*6446Swnj } 137*6446Swnj } 138*6446Swnj #endif 139*6446Swnj t = open(line, 2); 140*6446Swnj if (t < 0) { 141*6446Swnj dup2(f, 2); 142*6446Swnj perror(line); 143*6446Swnj exit(1); 144*6446Swnj } 145*6446Swnj { struct sgttyb b; 146*6446Swnj gtty(t, &b); b.sg_flags = RAW|ANYP; stty(t, &b); 147*6446Swnj } 148*6446Swnj if (fork()) { 149*6446Swnj char pibuf[1024], fibuf[1024], *pbp, *fbp; 150*6446Swnj int pcc = 0, fcc = 0, on = 1; 151*6446Swnj /* FILE *console = fopen("/dev/console", "w"); */ 152*6446Swnj /* setbuf(console, 0); */ 153*6446Swnj 154*6446Swnj /* fprintf(console, "f %d p %d\r\n", f, p); */ 155*6446Swnj ioctl(f, FIONBIO, &on); 156*6446Swnj ioctl(p, FIONBIO, &on); 157*6446Swnj ioctl(p, TIOCPKT, &on); 158*6446Swnj signal(SIGTSTP, SIG_IGN); 159*6446Swnj sigset(SIGCHLD, cleanup); 160*6446Swnj for (;;) { 161*6446Swnj int ibits = 0, obits = 0; 162*6446Swnj if (fcc) obits |= (1<<p); else ibits |= (1<<f); 163*6446Swnj if (pcc >= 0) 164*6446Swnj if (pcc) obits |= (1<<f); else ibits |= (1<<p); 165*6446Swnj if (fcc < 0 && pcc < 0) break; 166*6446Swnj /* fprintf(console, "ibits from %d obits from %d\r\n", ibits, obits); */ 167*6446Swnj select(32, &ibits, &obits, 10000000); 168*6446Swnj /* fprintf(console, "ibits %d obits %d\r\n", ibits, obits); */ 169*6446Swnj if (ibits == 0 && obits == 0) { 170*6446Swnj sleep(5); 171*6446Swnj continue; 172*6446Swnj } 173*6446Swnj if (ibits & (1<<f)) { 174*6446Swnj fcc = read(f, fibuf, sizeof (fibuf)); 175*6446Swnj /* fprintf(console, "%d from f\r\n", fcc); */ 176*6446Swnj if (fcc < 0 && errno == EWOULDBLOCK) 177*6446Swnj fcc = 0; 178*6446Swnj else { 179*6446Swnj if (fcc <= 0) 180*6446Swnj break; 181*6446Swnj fbp = fibuf; 182*6446Swnj } 183*6446Swnj } 184*6446Swnj if (ibits & (1<<p)) { 185*6446Swnj pcc = read(p, pibuf, sizeof (pibuf)); 186*6446Swnj /* fprintf(console, "%d from p, buf[0] %x, errno %d\r\n", pcc, buf[0], errno); */ 187*6446Swnj pbp = pibuf; 188*6446Swnj if (pcc < 0 && errno == EWOULDBLOCK) 189*6446Swnj pcc = 0; 190*6446Swnj else if (pcc <= 0) 191*6446Swnj pcc = -1; 192*6446Swnj else if (pibuf[0] == 0) 193*6446Swnj pbp++, pcc--; 194*6446Swnj else { 195*6446Swnj if (pibuf[0]&(TIOCPKT_FLUSHWRITE| 196*6446Swnj TIOCPKT_NOSTOP| 197*6446Swnj TIOCPKT_DOSTOP)) { 198*6446Swnj int nstop = pibuf[0] & 199*6446Swnj (TIOCPKT_NOSTOP| 200*6446Swnj TIOCPKT_DOSTOP); 201*6446Swnj if (nstop) 202*6446Swnj stop = nstop; 203*6446Swnj pibuf[0] |= nstop; 204*6446Swnj ioctl(f,SIOCSENDOOB,&pibuf[0]); 205*6446Swnj } 206*6446Swnj pcc = 0; 207*6446Swnj } 208*6446Swnj } 209*6446Swnj if ((obits & (1<<f)) && pcc > 0) { 210*6446Swnj cc = write(f, pbp, pcc); 211*6446Swnj /* fprintf(console, "%d of %d to f\r\n", cc, pcc); */ 212*6446Swnj if (cc > 0) { 213*6446Swnj pcc -= cc; 214*6446Swnj pbp += cc; 215*6446Swnj } 216*6446Swnj } 217*6446Swnj if ((obits & (1<<p)) && fcc > 0) { 218*6446Swnj cc = write(p, fbp, fcc); 219*6446Swnj /* fprintf(console, "%d of %d to p\r\n", cc, fcc); */ 220*6446Swnj if (cc > 0) { 221*6446Swnj fcc -= cc; 222*6446Swnj fbp += cc; 223*6446Swnj } 224*6446Swnj } 225*6446Swnj } 226*6446Swnj cleanup(); 227*6446Swnj } 228*6446Swnj close(f); 229*6446Swnj close(p); 230*6446Swnj dup2(t, 0); 231*6446Swnj dup2(t, 1); 232*6446Swnj dup2(t, 2); 233*6446Swnj close(t); 234*6446Swnj execl("/bin/login", "login", "-r", rhost, 0); 235*6446Swnj perror("/bin/login"); 236*6446Swnj exit(1); 237*6446Swnj } 238*6446Swnj 239*6446Swnj cleanup() 240*6446Swnj { 241*6446Swnj int how = 2; 242*6446Swnj 243*6446Swnj rmut(); 244*6446Swnj ioctl(netf, SIOCDONE, &how); 245*6446Swnj kill(0, SIGKILL); 246*6446Swnj exit(1); 247*6446Swnj } 248*6446Swnj 249*6446Swnj #include <utmp.h> 250*6446Swnj 251*6446Swnj struct utmp wtmp; 252*6446Swnj char wtmpf[] = "/usr/adm/wtmp"; 253*6446Swnj char utmp[] = "/etc/utmp"; 254*6446Swnj #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 255*6446Swnj #define SCMPN(a, b) strncmp(a, b, sizeof(a)) 256*6446Swnj 257*6446Swnj rmut() 258*6446Swnj { 259*6446Swnj register f; 260*6446Swnj int found = 0; 261*6446Swnj 262*6446Swnj f = open(utmp, 2); 263*6446Swnj if (f >= 0) { 264*6446Swnj while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) { 265*6446Swnj if (SCMPN(wtmp.ut_line, line+5) || wtmp.ut_name[0]==0) 266*6446Swnj continue; 267*6446Swnj lseek(f, -(long)sizeof(wtmp), 1); 268*6446Swnj SCPYN(wtmp.ut_name, ""); 269*6446Swnj time(&wtmp.ut_time); 270*6446Swnj write(f, (char *)&wtmp, sizeof(wtmp)); 271*6446Swnj found++; 272*6446Swnj } 273*6446Swnj close(f); 274*6446Swnj } 275*6446Swnj if (found) { 276*6446Swnj f = open(wtmpf, 1); 277*6446Swnj if (f >= 0) { 278*6446Swnj SCPYN(wtmp.ut_line, line+5); 279*6446Swnj SCPYN(wtmp.ut_name, ""); 280*6446Swnj time(&wtmp.ut_time); 281*6446Swnj lseek(f, (long)0, 2); 282*6446Swnj write(f, (char *)&wtmp, sizeof(wtmp)); 283*6446Swnj close(f); 284*6446Swnj } 285*6446Swnj } 286*6446Swnj chmod(line, 0666); 287*6446Swnj chown(line, 0, 0); 288*6446Swnj line[strlen("/dev/")] = 'p'; 289*6446Swnj chmod(line, 0666); 290*6446Swnj chown(line, 0, 0); 291*6446Swnj } 292