1: #ifndef lint
   2: static char sccsid[] = "@(#)uucpd.c	5.4 (Berkeley) 6/23/85";
   3: #endif
   4: 
   5: /*
   6:  * 4.2BSD or 2.9BSD TCP/IP server for uucico
   7:  * uucico's TCP channel causes this server to be run at the remote end.
   8:  */
   9: 
  10: #include "uucp.h"
  11: #include <netdb.h>
  12: #ifdef BSD2_9
  13: #include <sys/localopts.h>
  14: #include <sys/file.h>
  15: #endif BSD2_9
  16: #include <signal.h>
  17: #include <errno.h>
  18: #include <sys/socket.h>
  19: #include <netinet/in.h>
  20: #include <sys/wait.h>
  21: #include <sys/ioctl.h>
  22: #include <pwd.h>
  23: #include <lastlog.h>
  24: 
  25: #if !defined(BSD4_2) && !defined(BSD2_9)
  26: --- You must have either BSD4_2 or BSD2_9 defined for this to work
  27: #endif !BSD4_2 && !BSD2_9
  28: #if defined(BSD4_2) && defined(BSD2_9)
  29: --- You may not have both BSD4_2 and BSD2_9 defined for this to work
  30: #endif	/* check for stupidity */
  31: 
  32: char lastlog[] = "/usr/adm/lastlog";
  33: struct  sockaddr_in hisctladdr;
  34: int hisaddrlen = sizeof hisctladdr;
  35: struct  sockaddr_in myctladdr;
  36: int mypid;
  37: 
  38: char Username[64];
  39: char *nenv[] = {
  40:     Username,
  41:     NULL,
  42: };
  43: extern char **environ;
  44: 
  45: main(argc, argv)
  46: int argc;
  47: char **argv;
  48: {
  49: #ifndef BSDINETD
  50:     register int s, tcp_socket;
  51:     struct servent *sp;
  52: #endif !BSDINETD
  53:     extern int errno;
  54:     int dologout();
  55: 
  56:     environ = nenv;
  57: #ifdef BSDINETD
  58:     close(1); close(2);
  59:     dup(0); dup(0);
  60:     hisaddrlen = sizeof (hisctladdr);
  61:     if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) {
  62:         fprintf(stderr, "%s: ", argv[0]);
  63:         perror("getpeername");
  64:         _exit(1);
  65:     }
  66:     if (fork() == 0)
  67:         doit(&hisctladdr);
  68:     dologout();
  69:     exit(1);
  70: #else !BSDINETD
  71:     sp = getservbyname("uucp", "tcp");
  72:     if (sp == NULL){
  73:         perror("uucpd: getservbyname");
  74:         exit(1);
  75:     }
  76:     if (fork())
  77:         exit(0);
  78:     if ((s=open("/dev/tty", 2)) >= 0){
  79:         ioctl(s, TIOCNOTTY, (char *)0);
  80:         close(s);
  81:     }
  82: 
  83:     bzero((char *)&myctladdr, sizeof (myctladdr));
  84:     myctladdr.sin_family = AF_INET;
  85:     myctladdr.sin_port = sp->s_port;
  86: #ifdef BSD4_2
  87:     tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
  88:     if (tcp_socket < 0) {
  89:         perror("uucpd: socket");
  90:         exit(1);
  91:     }
  92:     if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) {
  93:         perror("uucpd: bind");
  94:         exit(1);
  95:     }
  96:     listen(tcp_socket, 3);  /* at most 3 simultaneuos uucp connections */
  97:     signal(SIGCHLD, dologout);
  98: 
  99:     for(;;) {
 100:         s = accept(tcp_socket, &hisctladdr, &hisaddrlen);
 101:         if (s < 0){
 102:             if (errno == EINTR)
 103:                 continue;
 104:             perror("uucpd: accept");
 105:             exit(1);
 106:         }
 107:         if (fork() == 0) {
 108:             close(0); close(1); close(2);
 109:             dup(s); dup(s); dup(s);
 110:             close(tcp_socket); close(s);
 111:             doit(&hisctladdr);
 112:             exit(1);
 113:         }
 114:         close(s);
 115:     }
 116: #endif BSD4_2
 117: 
 118: #ifdef BSD2_9
 119:     for(;;) {
 120:         signal(SIGCHLD, dologout);
 121:         s = socket(SOCK_STREAM, 0,  &myctladdr,
 122:             SO_ACCEPTCONN|SO_KEEPALIVE);
 123:         if (s < 0) {
 124:             perror("uucpd: socket");
 125:             exit(1);
 126:         }
 127:         if (accept(s, &hisctladdr) < 0) {
 128:             if (errno == EINTR) {
 129:                 close(s);
 130:                 continue;
 131:             }
 132:             perror("uucpd: accept");
 133:             exit(1);
 134:         }
 135:         if (fork() == 0) {
 136:             close(0); close(1); close(2);
 137:             dup(s); dup(s); dup(s);
 138:             close(s);
 139:             doit(&hisctladdr);
 140:             exit(1);
 141:         }
 142:     }
 143: #endif BSD2_9
 144: #endif	!BSDINETD
 145: }
 146: 
 147: doit(sinp)
 148: struct sockaddr_in *sinp;
 149: {
 150:     char user[64], passwd[64];
 151:     char *xpasswd, *crypt();
 152:     struct passwd *pw, *getpwnam();
 153: 
 154:     alarm(60);
 155:     printf("login: "); fflush(stdout);
 156:     if (readline(user, sizeof user) < 0) {
 157:         fprintf(stderr, "user read\n");
 158:         return;
 159:     }
 160:     /* truncate username to 8 characters */
 161:     user[8] = '\0';
 162:     pw = getpwnam(user);
 163:     if (pw == NULL) {
 164:         fprintf(stderr, "user unknown\n");
 165:         return;
 166:     }
 167:     if (strcmp(pw->pw_shell, UUCICO)) {
 168:         fprintf(stderr, "Login incorrect.");
 169:         return;
 170:     }
 171:     if (pw->pw_passwd && *pw->pw_passwd != '\0') {
 172:         printf("Password: "); fflush(stdout);
 173:         if (readline(passwd, sizeof passwd) < 0) {
 174:             fprintf(stderr, "passwd read\n");
 175:             return;
 176:         }
 177:         xpasswd = crypt(passwd, pw->pw_passwd);
 178:         if (strcmp(xpasswd, pw->pw_passwd)) {
 179:             fprintf(stderr, "Login incorrect.");
 180:             return;
 181:         }
 182:     }
 183:     alarm(0);
 184:     sprintf(Username, "USER=%s", user);
 185:     dologin(pw, sinp);
 186:     setgid(pw->pw_gid);
 187: #ifdef BSD4_2
 188:     initgroups(pw->pw_name, pw->pw_gid);
 189: #endif BSD4_2
 190:     chdir(pw->pw_dir);
 191:     setuid(pw->pw_uid);
 192: #ifdef BSD4_2
 193:     execl(UUCICO, "uucico", (char *)0);
 194: #endif BSD4_2
 195: #ifdef BSD2_9
 196:     sprintf(passwd, "-h%s", inet_ntoa(sinp->sin_addr));
 197:     execl(UUCICO, "uucico", passwd, (char *)0);
 198: #endif BSD2_9
 199:     perror("uucico server: execl");
 200: }
 201: 
 202: readline(p, n)
 203: register char *p;
 204: register int n;
 205: {
 206:     char c;
 207: 
 208:     while (n-- > 0) {
 209:         if (read(0, &c, 1) <= 0)
 210:             return(-1);
 211:         c &= 0177;
 212:         if (c == '\n' || c == '\r') {
 213:             *p = '\0';
 214:             return(0);
 215:         }
 216:         *p++ = c;
 217:     }
 218:     return(-1);
 219: }
 220: 
 221: #include <utmp.h>
 222: #ifdef BSD4_2
 223: #include <fcntl.h>
 224: #endif BSD4_2
 225: 
 226: #ifdef BSD2_9
 227: #define O_APPEND    0 /* kludge */
 228: #define wait3(a,b,c)    wait2(a,b)
 229: #endif BSD2_9
 230: 
 231: #define SCPYN(a, b) strncpy(a, b, sizeof (a))
 232: 
 233: struct  utmp utmp;
 234: 
 235: dologout()
 236: {
 237:     union wait status;
 238:     int pid, wtmp;
 239: 
 240: #ifdef BSDINETD
 241:     while ((pid=wait(&status)) > 0) {
 242: #else  !BSDINETD
 243:     while ((pid=wait3(&status,WNOHANG,0)) > 0) {
 244: #endif !BSDINETD
 245:         wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
 246:         if (wtmp >= 0) {
 247:             sprintf(utmp.ut_line, "uucp%.4d", pid);
 248:             SCPYN(utmp.ut_name, "");
 249:             SCPYN(utmp.ut_host, "");
 250:             (void) time(&utmp.ut_time);
 251: #ifdef BSD2_9
 252:             (void) lseek(wtmp, 0L, 2);
 253: #endif BSD2_9
 254:             (void) write(wtmp, (char *)&utmp, sizeof (utmp));
 255:             (void) close(wtmp);
 256:         }
 257:     }
 258: }
 259: 
 260: /*
 261:  * Record login in wtmp file.
 262:  */
 263: dologin(pw, sin)
 264: struct passwd *pw;
 265: struct sockaddr_in *sin;
 266: {
 267:     char line[32];
 268:     char remotehost[32];
 269:     int wtmp, f;
 270:     struct hostent *hp = gethostbyaddr(&sin->sin_addr,
 271:         sizeof (struct in_addr), AF_INET);
 272: 
 273:     if (hp) {
 274:         strncpy(remotehost, hp->h_name, sizeof (remotehost));
 275:         endhostent();
 276:     } else
 277:         strncpy(remotehost, inet_ntoa(sin->sin_addr),
 278:             sizeof (remotehost));
 279:     wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
 280:     if (wtmp >= 0) {
 281:         /* hack, but must be unique and no tty line */
 282:         sprintf(line, "uucp%.4d", getpid());
 283:         SCPYN(utmp.ut_line, line);
 284:         SCPYN(utmp.ut_name, pw->pw_name);
 285:         SCPYN(utmp.ut_host, remotehost);
 286:         time(&utmp.ut_time);
 287: #ifdef BSD2_9
 288:         (void) lseek(wtmp, 0L, 2);
 289: #endif BSD2_9
 290:         (void) write(wtmp, (char *)&utmp, sizeof (utmp));
 291:         (void) close(wtmp);
 292:     }
 293:     if ((f = open(lastlog, 2)) >= 0) {
 294:         struct lastlog ll;
 295: 
 296:         time(&ll.ll_time);
 297:         lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0);
 298:         strcpy(line, remotehost);
 299:         SCPYN(ll.ll_line, line);
 300:         SCPYN(ll.ll_host, remotehost);
 301:         (void) write(f, (char *) &ll, sizeof ll);
 302:         (void) close(f);
 303:     }
 304: }

Defined functions

doit defined in line 147; used 3 times
dologin defined in line 263; used 1 times
dologout defined in line 235; used 4 times
main defined in line 45; never used
readline defined in line 202; used 2 times

Defined variables

Username defined in line 38; used 2 times
hisaddrlen defined in line 34; used 3 times
hisctladdr defined in line 33; used 8 times
lastlog defined in line 32; used 1 times
myctladdr defined in line 35; used 7 times
mypid defined in line 36; never used
nenv defined in line 39; used 1 times
  • in line 56
sccsid defined in line 2; never used
utmp defined in line 233; used 12 times

Defined macros

O_APPEND defined in line 227; used 2 times
SCPYN defined in line 231; used 7 times
wait3 defined in line 228; used 1 times
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1618
Valid CSS Valid XHTML 1.0 Strict