|
|
researchv9-SUN3(old)
#ifndef lint
static char sccsid[] = "@(#)rogind.c 4.18 83/07/01";
#endif
#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <sgtty.h>
#include <stdio.h>
#include <wait.h>
#include <sys/inet/in.h>
#include <sys/inet/tcp_user.h>
#include "config.h"
extern errno;
int reapchild();
int alrmcatch();
struct passwd *getpwnam();
struct passwd *pwd;
struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" };
char *crypt(), *rindex(), *index(), *malloc();
extern char **environ;
char term[20] = "TERM=";
static char *envinit[] = {
term,
0
};
/*
* remote login server:
* remuser\0
* locuser\0
* terminal type\0
* data
*/
main(argc, argv)
int argc;
char **argv;
{
int f;
struct tcpuser tu;
struct in_service *sp;
sp = in_service("login", "tcp", 0);
if(sp == 0){
fprintf(stderr, "rogind: tcp/rogin: unknown service\n");
exit(1);
}
tu.laddr = 0;
tu.lport = sp->port;
close(3);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
f = tcp_sock();
if (f < 0) {
perror("rogind: socket");
exit(1);
}
signal(SIGCHLD, reapchild);
signal(SIGALRM, alrmcatch);
tu.fport = 0;
tu.faddr = 0;
tu.param = 0;
tcp_listen(f, &tu);
for (;;) {
int s;
tu.lport = 0;
tu.laddr = 0;
tu.fport = 0;
tu.faddr = 0;
tu.param = 0;
s = tcp_accept(f, &tu);
if (s < 0) {
if (errno == EINTR)
continue;
perror("rogind: accept");
continue;
}
doit(s, tu.faddr, tu.fport, tu.param);
close(s);
}
}
reapchild()
{
union wait status;
int pid;
signal(SIGCHLD, SIG_IGN);
while((pid = wait3(&status, WNOHANG, 0)) > 0)
rmut(pid);
signal(SIGCHLD, reapchild);
}
char rusername[32], lusername[32];
char buf[BUFSIZ];
int child;
int cleanup();
int netf;
extern errno;
doit(f, faddr, fport, dev)
int f;
unsigned long faddr;
{
extern tty_ld;
extern char *ttyname();
char c;
int pid, ret;
char *host, line[32];
sprintf(line, "/dev/tcp%02d", dev);
alarm(20);
c = 1;
read(f, &c, 1);
alarm(0);
if(c != 0){
fprintf(stderr, "non-zero initial read from %x %d\n", faddr, fport);
return;
}
host = (char *)in_host(faddr);
if (host == 0) {
msg(f, "Don't know your host name\n");
fprintf(stderr, "didn't know his host name\n");
return;
}
if(fport >= 1024){
msg(f, "Permission denied\n");
fprintf(stderr, "rogind: denied him permission\n");
return;
}
if(access(line, 0) < 0){
msg(f, "No tty\n");
fprintf(stderr, "rogind: couldn't access line %s\n", line);
return;
}
pid = fork();
if (pid < 0){
msg(f, "Fork problem\n");
fprintf(stderr, "rogind: fork problen\n");
return;
}
if (pid) {
record(pid, line);
return;
}
write(f, "", 1);
signal(SIGCHLD, SIG_IGN);
signal(SIGHUP, SIG_DFL);
signal(SIGALRM, SIG_DFL);
dup2(f, 0);
dup2(f, 1);
dup2(f, 2);
dup2(0, 3);
close(f);
ioctl(0, TIOCSPGRP, 0);
ioctl(0, TCPIOHUP, 0);
environ = envinit;
ret = doremotelogin(host);
ioctl(0, FIOPUSHLD, &tty_ld);
sttyek(0);
if(ret < 0)
execl(LOGIN, "login", 0);
else
execl(LOGIN, "login", "-f", pwd->pw_name, 0);
printf("%s not found\n", LOGIN);
exit(1);
/*NOTREACHED*/
}
struct foo{
int pid;
char line[16];
};
#define NFOO 50
struct foo foo[NFOO];
record(pid, line)
char *line;
{
int i;
for(i = 0; i < NFOO; i++){
if(foo[i].pid == 0){
foo[i].pid = pid;
strncpy(foo[i].line, line+5, 8);
return;
}
}
}
#include <utmp.h>
struct utmp wtmp;
char wtmpf[] = "/usr/adm/wtmp";
char utmp[] = UTMP;
#define SCPYN(a, b) strncpy(a, b, sizeof(a))
#define SCMPN(a, b) strncmp(a, b, sizeof(a))
rmut(pid)
{
register f;
int found = 0;
char *line;
int i;
char file[32];
for(i = 0; i < NFOO; i++){
if(pid == foo[i].pid){
line = foo[i].line;
foo[i].pid = 0;
break;
}
}
if(i >= NFOO)
return;
f = open(utmp, 2);
if (f >= 0) {
while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
if (SCMPN(wtmp.ut_line, line) || wtmp.ut_name[0]==0)
continue;
lseek(f, -(long)sizeof(wtmp), 1);
SCPYN(wtmp.ut_name, "");
time(&wtmp.ut_time);
write(f, (char *)&wtmp, sizeof(wtmp));
found++;
}
close(f);
}
if (found) {
f = open(wtmpf, 1);
if (f >= 0) {
SCPYN(wtmp.ut_line, line);
SCPYN(wtmp.ut_name, "");
time(&wtmp.ut_time);
lseek(f, (long)0, 2);
write(f, (char *)&wtmp, sizeof(wtmp));
close(f);
}
}
sprintf(file, "/dev/%s", line);
chmod(file, 0600);
chown(file, 0, 0);
}
msg(fd, s)
char *s;
{
write(fd, "\001", 1);
write(fd, s, strlen(s));
}
alrmcatch()
{
signal(SIGALRM, alrmcatch);
return(-1);
}
sttyek(fd)
{
struct sgttyb vec;
gtty(fd, &vec);
vec.sg_erase = '#';
vec.sg_kill = '@';
vec.sg_flags |= XTABS;
stty(fd, &vec);
}
doremotelogin(host)
char *host;
{
FILE *hostf;
int first = 1;
char *p;
getstr(rusername, sizeof (rusername), "remuser");
getstr(lusername, sizeof (lusername), "locuser");
getstr(term+5, sizeof(term)-5, "Terminal type");
if(p = (char *)rindex(term, '/'))
*p = '\0';
if (getuid()) {
pwd = &nouser;
goto bad;
}
setpwent();
pwd = getpwnam(lusername);
endpwent();
if (pwd == NULL) {
pwd = &nouser;
goto bad;
}
hostf = pwd->pw_uid ? fopen(EQUIV, "r") : 0;
again:
if (hostf) {
char ahost[32];
while (fgets(ahost, sizeof (ahost), hostf)) {
char *user;
if ((user = index(ahost, '\n')) != 0)
*user++ = '\0';
if ((user = index(ahost, ' ')) != 0)
*user++ = '\0';
if (!strcmp(host, ahost) &&
!strcmp(rusername, user ? user : lusername)) {
fclose(hostf);
return (1);
}
}
fclose(hostf);
}
if (first == 1) {
char *rhosts = ".rhosts";
struct stat sbuf;
first = 0;
if (chdir(pwd->pw_dir) < 0)
goto again;
if (lstat(rhosts, &sbuf) < 0)
goto again;
if ((sbuf.st_mode & S_IFMT) == S_IFLNK) {
printf("login: .rhosts is a soft link.\r\n");
goto bad;
}
hostf = fopen(rhosts, "r");
fstat(fileno(hostf), &sbuf);
if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
printf("login: Bad .rhosts ownership.\r\n");
fclose(hostf);
goto bad;
}
goto again;
}
bad:
return (-1);
}
getstr(buf, cnt, err)
char *buf;
int cnt;
char *err;
{
char c;
do {
if (read(0, &c, 1) != 1)
exit(1);
if (--cnt < 0) {
printf("%s too long\r\n", err);
exit(1);
}
*buf++ = c;
} while (c != 0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.