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