o Change fake line from uucp%d to uu%d, because it produce wrong
[unix-history] / libexec / uucpd / uucpd.c
CommitLineData
15637ed4
RG
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 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38char copyright[] =
39"@(#) Copyright (c) 1985 The Regents of the University of California.\n\
40 All rights reserved.\n";
41#endif /* not lint */
42
43#ifndef lint
44static char sccsid[] = "@(#)uucpd.c 5.10 (Berkeley) 2/26/91";
45#endif /* not lint */
46
47/*
48 * 4.2BSD TCP/IP server for uucico
49 * uucico's TCP channel causes this server to be run at the remote end.
50 */
51
52#include <sys/types.h>
53#include <sys/wait.h>
54#include <sys/ioctl.h>
55#include <sys/socket.h>
56#include <netinet/in.h>
57#include <arpa/inet.h>
58#include <netdb.h>
59#include <signal.h>
60#include <fcntl.h>
61#include <time.h>
62#include <pwd.h>
63#include <unistd.h>
64#include <errno.h>
65#include <stdio.h>
66#include <stdlib.h>
67#include <string.h>
8704204b
AC
68#include <utmp.h>
69#include <syslog.h>
70#include <varargs.h>
15637ed4
RG
71#include "pathnames.h"
72
8704204b
AC
73#define SCPYN(a, b) strncpy(a, b, sizeof (a))
74
75struct utmp utmp;
76
65497975 77struct sockaddr hisctladdr;
15637ed4 78int hisaddrlen = sizeof hisctladdr;
65497975 79struct sockaddr myctladdr;
15637ed4
RG
80int mypid;
81
82char Username[64];
83char *nenv[] = {
84 Username,
85 NULL,
86};
87extern char **environ;
88
89main(argc, argv)
90int argc;
91char **argv;
92{
15637ed4
RG
93 extern int errno;
94 int dologout();
95
96 environ = nenv;
15637ed4
RG
97 close(1); close(2);
98 dup(0); dup(0);
99 hisaddrlen = sizeof (hisctladdr);
8704204b 100 openlog("uucpd", LOG_PID, LOG_DAEMON);
15637ed4 101 if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) {
8704204b 102 syslog(LOG_ERR, "getpeername: %m");
15637ed4
RG
103 _exit(1);
104 }
8704204b 105 doit(&hisctladdr);
15637ed4 106 dologout();
8704204b 107 _exit(0);
15637ed4
RG
108}
109
65497975
AC
110login_incorrect()
111{
112 char passwd[64];
113
114 printf("Password: "); fflush(stdout);
115 if (readline(passwd, sizeof passwd, 1) < 0) {
8704204b
AC
116 syslog(LOG_WARNING, "passwd read");
117 _exit(1);
65497975
AC
118 }
119 fprintf(stderr, "Login incorrect.\n");
8704204b 120 exit(1);
65497975
AC
121}
122
15637ed4 123doit(sinp)
8704204b 124struct sockaddr *sinp;
15637ed4 125{
8f019d31 126 char user[64], passwd[64], ubuf[64];
15637ed4
RG
127 char *xpasswd, *crypt();
128 struct passwd *pw, *getpwnam();
8704204b 129 int s;
15637ed4
RG
130
131 alarm(60);
132 printf("login: "); fflush(stdout);
65497975 133 if (readline(user, sizeof user, 0) < 0) {
8704204b
AC
134 syslog(LOG_WARNING, "login read");
135 _exit(1);
15637ed4
RG
136 }
137 /* truncate username to 8 characters */
138 user[8] = '\0';
139 pw = getpwnam(user);
8704204b 140 if (pw == NULL)
65497975 141 login_incorrect();
8704204b 142 if (strcmp(pw->pw_shell, _PATH_UUCICO))
65497975 143 login_incorrect();
15637ed4
RG
144 if (pw->pw_passwd && *pw->pw_passwd != '\0') {
145 printf("Password: "); fflush(stdout);
65497975 146 if (readline(passwd, sizeof passwd, 1) < 0) {
8704204b
AC
147 syslog(LOG_WARNING, "passwd read");
148 _exit(1);
15637ed4
RG
149 }
150 xpasswd = crypt(passwd, pw->pw_passwd);
151 if (strcmp(xpasswd, pw->pw_passwd)) {
65497975 152 fprintf(stderr, "Login incorrect.\n");
8704204b 153 exit(1);
15637ed4
RG
154 }
155 }
156 alarm(0);
8704204b 157 sprintf(Username, "USER=%s", pw->pw_name);
8f019d31 158 sprintf(ubuf, "-u%s", pw->pw_name);
8704204b
AC
159 if ((s = fork()) < 0) {
160 syslog(LOG_ERR, "fork: %m");
161 _exit(1);
162 } else if (s == 0) {
163 dologin(pw, sinp);
164 setgid(pw->pw_gid);
165 initgroups(pw->pw_name, pw->pw_gid);
166 chdir(pw->pw_dir);
167 setuid(pw->pw_uid);
168 execl(pw->pw_shell, "uucico", ubuf, NULL);
169 syslog(LOG_ERR, "execl: %m");
170 _exit(1);
171 }
15637ed4
RG
172}
173
65497975
AC
174readline(start, num, pass)
175char start[];
176int num, pass;
15637ed4
RG
177{
178 char c;
65497975
AC
179 register char *p = start;
180 register int n = num;
15637ed4
RG
181
182 while (n-- > 0) {
183 if (read(0, &c, 1) <= 0)
184 return(-1);
185 c &= 0177;
8704204b 186 if (c == '\n' || c == '\r' || c == '\0') {
65497975
AC
187 if (p == start && pass) {
188 n++;
189 continue;
190 }
15637ed4
RG
191 *p = '\0';
192 return(0);
193 }
65497975
AC
194 if (c == 025) {
195 n = num;
196 p = start;
197 continue;
198 }
15637ed4
RG
199 *p++ = c;
200 }
201 return(-1);
202}
203
15637ed4
RG
204
205dologout()
206{
207 union wait status;
8704204b
AC
208 int pid;
209 char line[32];
15637ed4 210
15637ed4 211 while ((pid=wait((int *)&status)) > 0) {
2836d485
AC
212 sprintf(line, "uu%d", pid);
213 logout(line);
8704204b 214 logwtmp(line, "", "");
15637ed4
RG
215 }
216}
217
218/*
219 * Record login in wtmp file.
220 */
221dologin(pw, sin)
222struct passwd *pw;
223struct sockaddr_in *sin;
224{
225 char line[32];
226 char remotehost[32];
8704204b 227 int f;
2836d485 228 time_t cur_time;
15637ed4
RG
229 struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
230 sizeof (struct in_addr), AF_INET);
231
232 if (hp) {
233 strncpy(remotehost, hp->h_name, sizeof (remotehost));
234 endhostent();
235 } else
236 strncpy(remotehost, inet_ntoa(sin->sin_addr),
237 sizeof (remotehost));
2836d485 238 sprintf(line, "uu%d", getpid());
8704204b 239 /* hack, but must be unique and no tty line */
2836d485 240 time(&cur_time);
15637ed4
RG
241 if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) {
242 struct lastlog ll;
243
2836d485 244 ll.ll_time = cur_time;
8704204b 245 lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), L_SET);
15637ed4
RG
246 SCPYN(ll.ll_line, line);
247 SCPYN(ll.ll_host, remotehost);
248 (void) write(f, (char *) &ll, sizeof ll);
249 (void) close(f);
250 }
2836d485
AC
251 utmp.ut_time = cur_time;
252 SCPYN(utmp.ut_line, line);
253 SCPYN(utmp.ut_name, pw->pw_name);
254 SCPYN(utmp.ut_host, remotehost);
255 login(&utmp);
15637ed4 256}