Mon Mar 16 02:18:39 2009 UTC ()
fix sign-compare issue


(lukem)
diff -r1.38 -r1.39 src/libexec/rlogind/rlogind.c

cvs diff -r1.38 -r1.39 src/libexec/rlogind/rlogind.c (switch to unified diff)

--- src/libexec/rlogind/rlogind.c 2008/07/20 01:09:07 1.38
+++ src/libexec/rlogind/rlogind.c 2009/03/16 02:18:39 1.39
@@ -1,771 +1,771 @@ @@ -1,771 +1,771 @@
1/* $NetBSD: rlogind.c,v 1.38 2008/07/20 01:09:07 lukem Exp $ */ 1/* $NetBSD: rlogind.c,v 1.39 2009/03/16 02:18:39 lukem Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1998 WIDE Project. 4 * Copyright (C) 1998 WIDE Project.
5 * All rights reserved. 5 * All rights reserved.
6 *  6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by WIDE Project and 17 * This product includes software developed by WIDE Project and
18 * its contributors. 18 * its contributors.
19 * 4. Neither the name of the project nor the names of its contributors 19 * 4. Neither the name of the project nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 21 * without specific prior written permission.
22 *  22 *
23 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 23 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 */ 34 */
35 35
36/*- 36/*-
37 * Copyright (c) 1983, 1988, 1989, 1993 37 * Copyright (c) 1983, 1988, 1989, 1993
38 * The Regents of the University of California. All rights reserved. 38 * The Regents of the University of California. All rights reserved.
39 * 39 *
40 * Redistribution and use in source and binary forms, with or without 40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions 41 * modification, are permitted provided that the following conditions
42 * are met: 42 * are met:
43 * 1. Redistributions of source code must retain the above copyright 43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer. 44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright 45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the 46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution. 47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors 48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software 49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission. 50 * without specific prior written permission.
51 * 51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE. 62 * SUCH DAMAGE.
63 */ 63 */
64 64
65#include <sys/cdefs.h> 65#include <sys/cdefs.h>
66#ifndef lint 66#ifndef lint
67__COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1989, 1993\ 67__COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1989, 1993\
68 The Regents of the University of California. All rights reserved."); 68 The Regents of the University of California. All rights reserved.");
69#if 0 69#if 0
70static char sccsid[] = "@(#)rlogind.c 8.2 (Berkeley) 4/28/95"; 70static char sccsid[] = "@(#)rlogind.c 8.2 (Berkeley) 4/28/95";
71#else 71#else
72__RCSID("$NetBSD: rlogind.c,v 1.38 2008/07/20 01:09:07 lukem Exp $"); 72__RCSID("$NetBSD: rlogind.c,v 1.39 2009/03/16 02:18:39 lukem Exp $");
73#endif 73#endif
74#endif /* not lint */ 74#endif /* not lint */
75 75
76/* 76/*
77 * remote login server: 77 * remote login server:
78 * \0 78 * \0
79 * remuser\0 79 * remuser\0
80 * locuser\0 80 * locuser\0
81 * terminal_type/speed\0 81 * terminal_type/speed\0
82 * data 82 * data
83 */ 83 */
84 84
85#include <sys/param.h> 85#include <sys/param.h>
86#include <sys/stat.h> 86#include <sys/stat.h>
87#include <sys/ioctl.h> 87#include <sys/ioctl.h>
88#include <signal.h> 88#include <signal.h>
89#include <termios.h> 89#include <termios.h>
90#include <poll.h> 90#include <poll.h>
91#include <vis.h> 91#include <vis.h>
92 92
93#include <sys/socket.h> 93#include <sys/socket.h>
94#include <netinet/in.h> 94#include <netinet/in.h>
95#include <netinet/in_systm.h> 95#include <netinet/in_systm.h>
96#include <netinet/ip.h> 96#include <netinet/ip.h>
97#include <arpa/inet.h> 97#include <arpa/inet.h>
98#include <netdb.h> 98#include <netdb.h>
99 99
100#include <pwd.h> 100#include <pwd.h>
101#include <syslog.h> 101#include <syslog.h>
102#include <errno.h> 102#include <errno.h>
103#include <stdio.h> 103#include <stdio.h>
104#include <unistd.h> 104#include <unistd.h>
105#include <stdlib.h> 105#include <stdlib.h>
106#include <string.h> 106#include <string.h>
107#include <util.h> 107#include <util.h>
108#include "pathnames.h" 108#include "pathnames.h"
109 109
110#ifndef TIOCPKT_WINDOW 110#ifndef TIOCPKT_WINDOW
111#define TIOCPKT_WINDOW 0x80 111#define TIOCPKT_WINDOW 0x80
112#endif 112#endif
113 113
114#define OPTIONS "alnL" 114#define OPTIONS "alnL"
115 115
116char *env[2]; 116char *env[2];
117#define NMAX 30 117#define NMAX 30
118char lusername[NMAX+1], rusername[NMAX+1]; 118char lusername[NMAX+1], rusername[NMAX+1];
119static char term[64] = "TERM="; 119static char term[64] = "TERM=";
120#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ 120#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */
121int keepalive = 1; 121int keepalive = 1;
122int check_all = 0; 122int check_all = 0;
123int log_success = 0; 123int log_success = 0;
124 124
125struct passwd *pwd; 125struct passwd *pwd;
126 126
127void doit __P((int, struct sockaddr_storage *)); 127void doit __P((int, struct sockaddr_storage *));
128int control __P((int, char *, int)); 128int control __P((int, char *, int));
129void protocol __P((int, int)); 129void protocol __P((int, int));
130void cleanup __P((int)); 130void cleanup __P((int));
131void fatal __P((int, const char *, int)); 131void fatal __P((int, const char *, int));
132int do_rlogin __P((struct sockaddr *, char *)); 132int do_rlogin __P((struct sockaddr *, char *));
133void getstr __P((char *, int, const char *)); 133void getstr __P((char *, int, const char *));
134void setup_term __P((int)); 134void setup_term __P((int));
135#if 0 135#if 0
136int do_krb_login __P((union sockunion *)); 136int do_krb_login __P((union sockunion *));
137#endif 137#endif
138void usage __P((void)); 138void usage __P((void));
139int local_domain __P((char *)); 139int local_domain __P((char *));
140char *topdomain __P((char *)); 140char *topdomain __P((char *));
141int main __P((int, char *[])); 141int main __P((int, char *[]));
142 142
143extern int __check_rhosts_file; 143extern int __check_rhosts_file;
144extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c */ 144extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c */
145extern char **environ; 145extern char **environ;
146 146
147int 147int
148main(argc, argv) 148main(argc, argv)
149 int argc; 149 int argc;
150 char *argv[]; 150 char *argv[];
151{ 151{
152 struct sockaddr_storage from; 152 struct sockaddr_storage from;
153 int ch, on; 153 int ch, on;
154 socklen_t fromlen = sizeof(from); 154 socklen_t fromlen = sizeof(from);
155 155
156 openlog("rlogind", LOG_PID, LOG_AUTH); 156 openlog("rlogind", LOG_PID, LOG_AUTH);
157 157
158 opterr = 0; 158 opterr = 0;
159 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 159 while ((ch = getopt(argc, argv, OPTIONS)) != -1)
160 switch (ch) { 160 switch (ch) {
161 case 'a': 161 case 'a':
162 check_all = 1; 162 check_all = 1;
163 break; 163 break;
164 case 'l': 164 case 'l':
165 __check_rhosts_file = 0; 165 __check_rhosts_file = 0;
166 break; 166 break;
167 case 'n': 167 case 'n':
168 keepalive = 0; 168 keepalive = 0;
169 break; 169 break;
170 case 'L': 170 case 'L':
171 log_success = 1; 171 log_success = 1;
172 break; 172 break;
173 case '?': 173 case '?':
174 default: 174 default:
175 usage(); 175 usage();
176 break; 176 break;
177 } 177 }
178 argc -= optind; 178 argc -= optind;
179 argv += optind; 179 argv += optind;
180 180
181 if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) { 181 if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
182 syslog(LOG_ERR,"Can't get peer name of remote host: %m"); 182 syslog(LOG_ERR,"Can't get peer name of remote host: %m");
183 fatal(STDERR_FILENO, "Can't get peer name of remote host", 1); 183 fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
184 } 184 }
185#ifdef INET6 185#ifdef INET6
186 if (from.ss_family == AF_INET6 && 186 if (from.ss_family == AF_INET6 &&
187 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&from)->sin6_addr) && 187 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&from)->sin6_addr) &&
188 sizeof(struct sockaddr_in) <= sizeof(from)) { 188 sizeof(struct sockaddr_in) <= sizeof(from)) {
189 struct sockaddr_in sin4; 189 struct sockaddr_in sin4;
190 struct sockaddr_in6 *sin6; 190 struct sockaddr_in6 *sin6;
191 const int off = sizeof(struct sockaddr_in6) - 191 const int off = sizeof(struct sockaddr_in6) -
192 sizeof(struct sockaddr_in); 192 sizeof(struct sockaddr_in);
193 193
194 sin6 = (struct sockaddr_in6 *)&from; 194 sin6 = (struct sockaddr_in6 *)&from;
195 memset(&sin4, 0, sizeof(sin4)); 195 memset(&sin4, 0, sizeof(sin4));
196 sin4.sin_family = AF_INET; 196 sin4.sin_family = AF_INET;
197 sin4.sin_len = sizeof(struct sockaddr_in); 197 sin4.sin_len = sizeof(struct sockaddr_in);
198 memcpy(&sin4.sin_addr, &sin6->sin6_addr.s6_addr[off], 198 memcpy(&sin4.sin_addr, &sin6->sin6_addr.s6_addr[off],
199 sizeof(sin4.sin_addr)); 199 sizeof(sin4.sin_addr));
200 memcpy(&from, &sin4, sizeof(sin4)); 200 memcpy(&from, &sin4, sizeof(sin4));
201 } 201 }
202#else 202#else
203 if (from.ss_family == AF_INET6 && 203 if (from.ss_family == AF_INET6 &&
204 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&from)->sin6_addr)) { 204 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&from)->sin6_addr)) {
205 char hbuf[NI_MAXHOST]; 205 char hbuf[NI_MAXHOST];
206 if (getnameinfo((struct sockaddr *)&from, fromlen, hbuf, 206 if (getnameinfo((struct sockaddr *)&from, fromlen, hbuf,
207 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) { 207 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) {
208 strlcpy(hbuf, "invalid", sizeof(hbuf)); 208 strlcpy(hbuf, "invalid", sizeof(hbuf));
209 } 209 }
210 syslog(LOG_ERR, "malformed \"from\" address (v4 mapped, %s)\n", 210 syslog(LOG_ERR, "malformed \"from\" address (v4 mapped, %s)\n",
211 hbuf); 211 hbuf);
212 exit(1); 212 exit(1);
213 } 213 }
214#endif 214#endif
215 on = 1; 215 on = 1;
216 if (keepalive && 216 if (keepalive &&
217 setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) 217 setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
218 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 218 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
219#if defined(IP_TOS) 219#if defined(IP_TOS)
220 if (from.ss_family == AF_INET) { 220 if (from.ss_family == AF_INET) {
221 on = IPTOS_LOWDELAY; 221 on = IPTOS_LOWDELAY;
222 if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) 222 if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
223 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); 223 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
224 } 224 }
225#endif 225#endif
226 doit(0, &from); 226 doit(0, &from);
227 /* NOTREACHED */ 227 /* NOTREACHED */
228#ifdef __GNUC__ 228#ifdef __GNUC__
229 exit(0); 229 exit(0);
230#endif 230#endif
231} 231}
232 232
233int child; 233int child;
234int netf; 234int netf;
235char line[MAXPATHLEN]; 235char line[MAXPATHLEN];
236int confirmed; 236int confirmed;
237 237
238struct winsize win = { 0, 0, 0, 0 }; 238struct winsize win = { 0, 0, 0, 0 };
239 239
240 240
241void 241void
242doit(f, fromp) 242doit(f, fromp)
243 int f; 243 int f;
244 struct sockaddr_storage *fromp; 244 struct sockaddr_storage *fromp;
245{ 245{
246 int master, pid, on = 1; 246 int master, pid, on = 1;
247 int authenticated = 0; 247 int authenticated = 0;
248 char *hostname; 248 char *hostname;
249 char hostnamebuf[2 * MAXHOSTNAMELEN + 1]; 249 char hostnamebuf[2 * MAXHOSTNAMELEN + 1];
250 char hostaddrbuf[sizeof(*fromp) * 4 + 1]; 250 char hostaddrbuf[sizeof(*fromp) * 4 + 1];
251 char c; 251 char c;
252 char naddr[NI_MAXHOST]; 252 char naddr[NI_MAXHOST];
253 char saddr[NI_MAXHOST]; 253 char saddr[NI_MAXHOST];
254 char raddr[NI_MAXHOST]; 254 char raddr[NI_MAXHOST];
255 int af = fromp->ss_family; 255 int af = fromp->ss_family;
256 u_int16_t *portp; 256 u_int16_t *portp;
257 struct addrinfo hints, *res, *res0; 257 struct addrinfo hints, *res, *res0;
258 int gaierror; 258 int gaierror;
259 socklen_t fromlen = fromp->ss_len > sizeof(*fromp) 259 socklen_t fromlen = fromp->ss_len > sizeof(*fromp)
260 ? sizeof(*fromp) : fromp->ss_len; 260 ? sizeof(*fromp) : fromp->ss_len;
261 const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; 261 const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
262 262
263 alarm(60); 263 alarm(60);
264 read(f, &c, 1); 264 read(f, &c, 1);
265 265
266 if (c != 0) 266 if (c != 0)
267 exit(1); 267 exit(1);
268 268
269 alarm(0); 269 alarm(0);
270 switch (af) { 270 switch (af) {
271 case AF_INET: 271 case AF_INET:
272 portp = &((struct sockaddr_in *)fromp)->sin_port; 272 portp = &((struct sockaddr_in *)fromp)->sin_port;
273 break; 273 break;
274#ifdef INET6 274#ifdef INET6
275 case AF_INET6: 275 case AF_INET6:
276 portp = &((struct sockaddr_in6 *)fromp)->sin6_port; 276 portp = &((struct sockaddr_in6 *)fromp)->sin6_port;
277 break; 277 break;
278#endif 278#endif
279 default: 279 default:
280 syslog(LOG_ERR, "malformed \"from\" address (af %d)\n", af); 280 syslog(LOG_ERR, "malformed \"from\" address (af %d)\n", af);
281 exit(1); 281 exit(1);
282 } 282 }
283 if (getnameinfo((struct sockaddr *)fromp, fromlen, 283 if (getnameinfo((struct sockaddr *)fromp, fromlen,
284 naddr, sizeof(naddr), NULL, 0, niflags) != 0) { 284 naddr, sizeof(naddr), NULL, 0, niflags) != 0) {
285 syslog(LOG_ERR, "malformed \"from\" address (af %d)\n", af); 285 syslog(LOG_ERR, "malformed \"from\" address (af %d)\n", af);
286 exit(1); 286 exit(1);
287 } 287 }
288 288
289 if (getnameinfo((struct sockaddr *)fromp, fromlen, 289 if (getnameinfo((struct sockaddr *)fromp, fromlen,
290 saddr, sizeof(saddr), NULL, 0, NI_NAMEREQD) == 0) { 290 saddr, sizeof(saddr), NULL, 0, NI_NAMEREQD) == 0) {
291 /* 291 /*
292 * If name returned by getnameinfo is in our domain, 292 * If name returned by getnameinfo is in our domain,
293 * attempt to verify that we haven't been fooled by someone 293 * attempt to verify that we haven't been fooled by someone
294 * in a remote net; look up the name and check that this 294 * in a remote net; look up the name and check that this
295 * address corresponds to the name. 295 * address corresponds to the name.
296 */ 296 */
297 hostname = saddr; 297 hostname = saddr;
298 res0 = NULL; 298 res0 = NULL;
299 if (check_all || local_domain(saddr)) { 299 if (check_all || local_domain(saddr)) {
300 strlcpy(hostnamebuf, saddr, sizeof(hostnamebuf)); 300 strlcpy(hostnamebuf, saddr, sizeof(hostnamebuf));
301 memset(&hints, 0, sizeof(hints)); 301 memset(&hints, 0, sizeof(hints));
302 hints.ai_family = fromp->ss_family; 302 hints.ai_family = fromp->ss_family;
303 hints.ai_socktype = SOCK_STREAM; 303 hints.ai_socktype = SOCK_STREAM;
304 hints.ai_flags = AI_CANONNAME; 304 hints.ai_flags = AI_CANONNAME;
305 gaierror = getaddrinfo(hostnamebuf, "0", &hints, &res0); 305 gaierror = getaddrinfo(hostnamebuf, "0", &hints, &res0);
306 if (gaierror) { 306 if (gaierror) {
307 syslog(LOG_NOTICE, 307 syslog(LOG_NOTICE,
308 "Couldn't look up address for %s: %s", 308 "Couldn't look up address for %s: %s",
309 hostnamebuf, gai_strerror(gaierror)); 309 hostnamebuf, gai_strerror(gaierror));
310 hostname = naddr; 310 hostname = naddr;
311 } else { 311 } else {
312 for (res = res0; res; res = res->ai_next) { 312 for (res = res0; res; res = res->ai_next) {
313 if (res->ai_family != fromp->ss_family) 313 if (res->ai_family != fromp->ss_family)
314 continue; 314 continue;
315 if (res->ai_addrlen != fromp->ss_len) 315 if (res->ai_addrlen != fromp->ss_len)
316 continue; 316 continue;
317 if (getnameinfo(res->ai_addr, 317 if (getnameinfo(res->ai_addr,
318 res->ai_addrlen, 318 res->ai_addrlen,
319 raddr, sizeof(raddr), NULL, 0, 319 raddr, sizeof(raddr), NULL, 0,
320 niflags) == 0 320 niflags) == 0
321 && strcmp(naddr, raddr) == 0) { 321 && strcmp(naddr, raddr) == 0) {
322 hostname = res->ai_canonname 322 hostname = res->ai_canonname
323 ? res->ai_canonname 323 ? res->ai_canonname
324 : saddr; 324 : saddr;
325 break; 325 break;
326 } 326 }
327 } 327 }
328 if (res == NULL) { 328 if (res == NULL) {
329 syslog(LOG_NOTICE, 329 syslog(LOG_NOTICE,
330 "Host addr %s not listed for host %s", 330 "Host addr %s not listed for host %s",
331 naddr, res0->ai_canonname 331 naddr, res0->ai_canonname
332 ? res0->ai_canonname 332 ? res0->ai_canonname
333 : saddr); 333 : saddr);
334 hostname = naddr; 334 hostname = naddr;
335 } 335 }
336 } 336 }
337 } 337 }
338 strlcpy(hostnamebuf, hostname, sizeof(hostnamebuf)); 338 strlcpy(hostnamebuf, hostname, sizeof(hostnamebuf));
339 hostname = hostnamebuf; 339 hostname = hostnamebuf;
340 if (res0) 340 if (res0)
341 freeaddrinfo(res0); 341 freeaddrinfo(res0);
342 } else { 342 } else {
343 strlcpy(hostnamebuf, naddr, sizeof(hostnamebuf)); 343 strlcpy(hostnamebuf, naddr, sizeof(hostnamebuf));
344 hostname = hostnamebuf; 344 hostname = hostnamebuf;
345 } 345 }
346 346
347 if (ntohs(*portp) >= IPPORT_RESERVED || 347 if (ntohs(*portp) >= IPPORT_RESERVED ||
348 ntohs(*portp) < IPPORT_RESERVED/2) { 348 ntohs(*portp) < IPPORT_RESERVED/2) {
349 syslog(LOG_NOTICE, "Connection from %s on illegal port", 349 syslog(LOG_NOTICE, "Connection from %s on illegal port",
350 naddr); 350 naddr);
351 fatal(f, "Permission denied", 0); 351 fatal(f, "Permission denied", 0);
352 } 352 }
353#ifdef IP_OPTIONS 353#ifdef IP_OPTIONS
354 if (fromp->ss_family == AF_INET) { 354 if (fromp->ss_family == AF_INET) {
355 u_char optbuf[BUFSIZ/3], *cp; 355 u_char optbuf[BUFSIZ/3], *cp;
356 char lbuf[BUFSIZ], *lp, *ep; 356 char lbuf[BUFSIZ], *lp, *ep;
357 socklen_t optsize = sizeof(optbuf); 357 socklen_t optsize = sizeof(optbuf);
358 int ipproto; 358 int ipproto;
359 struct protoent *ip; 359 struct protoent *ip;
360 360
361 if ((ip = getprotobyname("ip")) != NULL) 361 if ((ip = getprotobyname("ip")) != NULL)
362 ipproto = ip->p_proto; 362 ipproto = ip->p_proto;
363 else 363 else
364 ipproto = IPPROTO_IP; 364 ipproto = IPPROTO_IP;
365 if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, 365 if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf,
366 &optsize) == 0 && optsize != 0) { 366 &optsize) == 0 && optsize != 0) {
367 lp = lbuf; 367 lp = lbuf;
368 ep = lbuf + sizeof(lbuf); 368 ep = lbuf + sizeof(lbuf);
369 for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3) 369 for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
370 snprintf(lp, ep - lp, " %2.2x", *cp); 370 snprintf(lp, ep - lp, " %2.2x", *cp);
371 syslog(LOG_NOTICE, 371 syslog(LOG_NOTICE,
372 "Connection received using IP options (ignored):%s", 372 "Connection received using IP options (ignored):%s",
373 lbuf); 373 lbuf);
374 if (setsockopt(0, ipproto, IP_OPTIONS, 374 if (setsockopt(0, ipproto, IP_OPTIONS,
375 (char *)NULL, optsize) != 0) { 375 (char *)NULL, optsize) != 0) {
376 syslog(LOG_ERR, 376 syslog(LOG_ERR,
377 "setsockopt IP_OPTIONS NULL: %m"); 377 "setsockopt IP_OPTIONS NULL: %m");
378 exit(1); 378 exit(1);
379 } 379 }
380 } 380 }
381 } 381 }
382#endif 382#endif
383 if (do_rlogin((struct sockaddr *)fromp, hostname) == 0) 383 if (do_rlogin((struct sockaddr *)fromp, hostname) == 0)
384 authenticated++; 384 authenticated++;
385 if (confirmed == 0) { 385 if (confirmed == 0) {
386 write(f, "", 1); 386 write(f, "", 1);
387 confirmed = 1; /* we sent the null! */ 387 confirmed = 1; /* we sent the null! */
388 } 388 }
389 netf = f; 389 netf = f;
390 390
391 pid = forkpty(&master, line, NULL, &win); 391 pid = forkpty(&master, line, NULL, &win);
392 if (pid < 0) { 392 if (pid < 0) {
393 if (errno == ENOENT) 393 if (errno == ENOENT)
394 fatal(f, "Out of ptys", 0); 394 fatal(f, "Out of ptys", 0);
395 else 395 else
396 fatal(f, "Forkpty", 1); 396 fatal(f, "Forkpty", 1);
397 } 397 }
398 if (pid == 0) { 398 if (pid == 0) {
399 if (f > 2) /* f should always be 0, but... */ 399 if (f > 2) /* f should always be 0, but... */
400 (void) close(f); 400 (void) close(f);
401 setup_term(0); 401 setup_term(0);
402 (void)strvisx(hostaddrbuf, (const char *)(const void *)fromp, 402 (void)strvisx(hostaddrbuf, (const char *)(const void *)fromp,
403 sizeof(*fromp), VIS_WHITE); 403 sizeof(*fromp), VIS_WHITE);
404 if (authenticated) 404 if (authenticated)
405 execl(_PATH_LOGIN, "login", "-p", 405 execl(_PATH_LOGIN, "login", "-p",
406 "-h", hostname, "-a", hostaddrbuf, 406 "-h", hostname, "-a", hostaddrbuf,
407 "-f", "--", lusername, (char *)0); 407 "-f", "--", lusername, (char *)0);
408 else 408 else
409 execl(_PATH_LOGIN, "login", "-p", 409 execl(_PATH_LOGIN, "login", "-p",
410 "-h", hostname, "-a", hostaddrbuf, 410 "-h", hostname, "-a", hostaddrbuf,
411 "--", lusername, (char *)0); 411 "--", lusername, (char *)0);
412 fatal(STDERR_FILENO, _PATH_LOGIN, 1); 412 fatal(STDERR_FILENO, _PATH_LOGIN, 1);
413 /*NOTREACHED*/ 413 /*NOTREACHED*/
414 } 414 }
415 ioctl(f, FIONBIO, &on); 415 ioctl(f, FIONBIO, &on);
416 ioctl(master, FIONBIO, &on); 416 ioctl(master, FIONBIO, &on);
417 ioctl(master, TIOCPKT, &on); 417 ioctl(master, TIOCPKT, &on);
418 signal(SIGCHLD, cleanup); 418 signal(SIGCHLD, cleanup);
419 protocol(f, master); 419 protocol(f, master);
420 signal(SIGCHLD, SIG_IGN); 420 signal(SIGCHLD, SIG_IGN);
421 cleanup(0); 421 cleanup(0);
422} 422}
423 423
424char magic[2] = { 0377, 0377 }; 424char magic[2] = { 0377, 0377 };
425char oobdata[] = {TIOCPKT_WINDOW}; 425char oobdata[] = {TIOCPKT_WINDOW};
426 426
427/* 427/*
428 * Handle a "control" request (signaled by magic being present) 428 * Handle a "control" request (signaled by magic being present)
429 * in the data stream. For now, we are only willing to handle 429 * in the data stream. For now, we are only willing to handle
430 * window size changes. 430 * window size changes.
431 */ 431 */
432int 432int
433control(pty, cp, n) 433control(pty, cp, n)
434 int pty; 434 int pty;
435 char *cp; 435 char *cp;
436 int n; 436 int n;
437{ 437{
438 struct winsize w; 438 struct winsize w;
439 439
440 if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') 440 if (n < (int)(4+sizeof (w)) || cp[2] != 's' || cp[3] != 's')
441 return (0); 441 return (0);
442 oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ 442 oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */
443 memmove(&w, cp+4, sizeof(w)); 443 memmove(&w, cp+4, sizeof(w));
444 w.ws_row = ntohs(w.ws_row); 444 w.ws_row = ntohs(w.ws_row);
445 w.ws_col = ntohs(w.ws_col); 445 w.ws_col = ntohs(w.ws_col);
446 w.ws_xpixel = ntohs(w.ws_xpixel); 446 w.ws_xpixel = ntohs(w.ws_xpixel);
447 w.ws_ypixel = ntohs(w.ws_ypixel); 447 w.ws_ypixel = ntohs(w.ws_ypixel);
448 (void)ioctl(pty, TIOCSWINSZ, &w); 448 (void)ioctl(pty, TIOCSWINSZ, &w);
449 return (4+sizeof (w)); 449 return (4+sizeof (w));
450} 450}
451 451
452/* 452/*
453 * rlogin "protocol" machine. 453 * rlogin "protocol" machine.
454 */ 454 */
455void 455void
456protocol(f, p) 456protocol(f, p)
457 int f, p; 457 int f, p;
458{ 458{
459 char pibuf[1024+1], fibuf[1024], *pbp = NULL, *fbp = NULL; 459 char pibuf[1024+1], fibuf[1024], *pbp = NULL, *fbp = NULL;
460 /* XXX gcc above */ 460 /* XXX gcc above */
461 int pcc = 0, fcc = 0; 461 int pcc = 0, fcc = 0;
462 int cc, nfd; 462 int cc, nfd;
463 char cntl; 463 char cntl;
464 struct pollfd set[2]; 464 struct pollfd set[2];
465 465
466 /* 466 /*
467 * Must ignore SIGTTOU, otherwise we'll stop 467 * Must ignore SIGTTOU, otherwise we'll stop
468 * when we try and set slave pty's window shape 468 * when we try and set slave pty's window shape
469 * (our controlling tty is the master pty). 469 * (our controlling tty is the master pty).
470 */ 470 */
471 (void) signal(SIGTTOU, SIG_IGN); 471 (void) signal(SIGTTOU, SIG_IGN);
472 send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ 472 send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */
473 set[0].fd = p; 473 set[0].fd = p;
474 set[1].fd = f; 474 set[1].fd = f;
475 for (;;) { 475 for (;;) {
476 set[0].events = POLLPRI; 476 set[0].events = POLLPRI;
477 set[1].events = 0; 477 set[1].events = 0;
478 if (fcc) 478 if (fcc)
479 set[0].events |= POLLOUT; 479 set[0].events |= POLLOUT;
480 else 480 else
481 set[1].events |= POLLIN; 481 set[1].events |= POLLIN;
482 if (pcc >= 0) { 482 if (pcc >= 0) {
483 if (pcc) 483 if (pcc)
484 set[1].events |= POLLOUT; 484 set[1].events |= POLLOUT;
485 else 485 else
486 set[0].events |= POLLIN; 486 set[0].events |= POLLIN;
487 } 487 }
488 if ((nfd = poll(set, 2, INFTIM)) < 0) { 488 if ((nfd = poll(set, 2, INFTIM)) < 0) {
489 if (errno == EINTR) 489 if (errno == EINTR)
490 continue; 490 continue;
491 fatal(f, "poll", 1); 491 fatal(f, "poll", 1);
492 } 492 }
493 if (nfd == 0) { 493 if (nfd == 0) {
494 /* shouldn't happen... */ 494 /* shouldn't happen... */
495 sleep(5); 495 sleep(5);
496 continue; 496 continue;
497 } 497 }
498#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) 498#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
499 if (set[0].revents & POLLPRI) { 499 if (set[0].revents & POLLPRI) {
500 cc = read(p, &cntl, 1); 500 cc = read(p, &cntl, 1);
501 if (cc == 1 && pkcontrol(cntl)) { 501 if (cc == 1 && pkcontrol(cntl)) {
502 cntl |= oobdata[0]; 502 cntl |= oobdata[0];
503 send(f, &cntl, 1, MSG_OOB); 503 send(f, &cntl, 1, MSG_OOB);
504 if (cntl & TIOCPKT_FLUSHWRITE) 504 if (cntl & TIOCPKT_FLUSHWRITE)
505 pcc = 0; 505 pcc = 0;
506 } 506 }
507 } 507 }
508 if (set[1].revents & POLLIN) { 508 if (set[1].revents & POLLIN) {
509 fcc = read(f, fibuf, sizeof(fibuf)); 509 fcc = read(f, fibuf, sizeof(fibuf));
510 if (fcc < 0 && errno == EWOULDBLOCK) 510 if (fcc < 0 && errno == EWOULDBLOCK)
511 fcc = 0; 511 fcc = 0;
512 else { 512 else {
513 char *cp; 513 char *cp;
514 int left, n; 514 int left, n;
515 515
516 if (fcc <= 0) 516 if (fcc <= 0)
517 break; 517 break;
518 fbp = fibuf; 518 fbp = fibuf;
519 519
520 top: 520 top:
521 for (cp = fibuf; cp < fibuf+fcc-1; cp++) 521 for (cp = fibuf; cp < fibuf+fcc-1; cp++)
522 if (cp[0] == magic[0] && 522 if (cp[0] == magic[0] &&
523 cp[1] == magic[1]) { 523 cp[1] == magic[1]) {
524 left = fcc - (cp-fibuf); 524 left = fcc - (cp-fibuf);
525 n = control(p, cp, left); 525 n = control(p, cp, left);
526 if (n) { 526 if (n) {
527 left -= n; 527 left -= n;
528 if (left > 0) 528 if (left > 0)
529 memmove(cp, 529 memmove(cp,
530 cp+n, 530 cp+n,
531 left); 531 left);
532 fcc -= n; 532 fcc -= n;
533 goto top; /* n^2 */ 533 goto top; /* n^2 */
534 } 534 }
535 } 535 }
536 } 536 }
537 } 537 }
538 538
539 if (set[0].revents & POLLOUT && fcc > 0) { 539 if (set[0].revents & POLLOUT && fcc > 0) {
540 cc = write(p, fbp, fcc); 540 cc = write(p, fbp, fcc);
541 if (cc > 0) { 541 if (cc > 0) {
542 fcc -= cc; 542 fcc -= cc;
543 fbp += cc; 543 fbp += cc;
544 } 544 }
545 } 545 }
546 546
547 if (set[0].revents & POLLIN) { 547 if (set[0].revents & POLLIN) {
548 pcc = read(p, pibuf, sizeof (pibuf)); 548 pcc = read(p, pibuf, sizeof (pibuf));
549 pbp = pibuf; 549 pbp = pibuf;
550 if (pcc < 0 && errno == EWOULDBLOCK) 550 if (pcc < 0 && errno == EWOULDBLOCK)
551 pcc = 0; 551 pcc = 0;
552 else if (pcc <= 0) 552 else if (pcc <= 0)
553 break; 553 break;
554 else if (pibuf[0] == 0) { 554 else if (pibuf[0] == 0) {
555 pbp++, pcc--; 555 pbp++, pcc--;
556 } else { 556 } else {
557 if (pkcontrol(pibuf[0])) { 557 if (pkcontrol(pibuf[0])) {
558 pibuf[0] |= oobdata[0]; 558 pibuf[0] |= oobdata[0];
559 send(f, &pibuf[0], 1, MSG_OOB); 559 send(f, &pibuf[0], 1, MSG_OOB);
560 } 560 }
561 pcc = 0; 561 pcc = 0;
562 } 562 }
563 } 563 }
564 if (set[1].revents & POLLOUT && pcc > 0) { 564 if (set[1].revents & POLLOUT && pcc > 0) {
565 cc = write(f, pbp, pcc); 565 cc = write(f, pbp, pcc);
566 if (cc > 0) { 566 if (cc > 0) {
567 pcc -= cc; 567 pcc -= cc;
568 pbp += cc; 568 pbp += cc;
569 } 569 }
570 } 570 }
571 } 571 }
572} 572}
573 573
574void 574void
575cleanup(signo) 575cleanup(signo)
576 int signo; 576 int signo;
577{ 577{
578 char *p, c; 578 char *p, c;
579 579
580 p = line + sizeof(_PATH_DEV) - 1; 580 p = line + sizeof(_PATH_DEV) - 1;
581#ifdef SUPPORT_UTMP 581#ifdef SUPPORT_UTMP
582 if (logout(p)) 582 if (logout(p))
583 logwtmp(p, "", ""); 583 logwtmp(p, "", "");
584#endif 584#endif
585#ifdef SUPPORT_UTMPX 585#ifdef SUPPORT_UTMPX
586 if (logoutx(p, 0, DEAD_PROCESS)) 586 if (logoutx(p, 0, DEAD_PROCESS))
587 logwtmpx(p, "", "", 0, DEAD_PROCESS); 587 logwtmpx(p, "", "", 0, DEAD_PROCESS);
588#endif 588#endif
589 (void)chmod(line, 0666); 589 (void)chmod(line, 0666);
590 (void)chown(line, 0, 0); 590 (void)chown(line, 0, 0);
591 c = *p; *p = 'p'; 591 c = *p; *p = 'p';
592 (void)chmod(line, 0666); 592 (void)chmod(line, 0666);
593 (void)chown(line, 0, 0); 593 (void)chown(line, 0, 0);
594 *p = c; 594 *p = c;
595 if (ttyaction(line, "rlogind", "root")) 595 if (ttyaction(line, "rlogind", "root"))
596 syslog(LOG_ERR, "%s: ttyaction failed", line); 596 syslog(LOG_ERR, "%s: ttyaction failed", line);
597 shutdown(netf, 2); 597 shutdown(netf, 2);
598 exit(1); 598 exit(1);
599} 599}
600 600
601void 601void
602fatal(f, msg, syserr) 602fatal(f, msg, syserr)
603 int f; 603 int f;
604 const char *msg; 604 const char *msg;
605 int syserr; 605 int syserr;
606{ 606{
607 int len; 607 int len;
608 char buf[BUFSIZ], *bp, *ep; 608 char buf[BUFSIZ], *bp, *ep;
609 609
610 bp = buf; 610 bp = buf;
611 ep = buf + sizeof(buf); 611 ep = buf + sizeof(buf);
612 612
613 /* 613 /*
614 * Prepend binary one to message if we haven't sent 614 * Prepend binary one to message if we haven't sent
615 * the magic null as confirmation. 615 * the magic null as confirmation.
616 */ 616 */
617 if (!confirmed) 617 if (!confirmed)
618 *bp++ = '\001'; /* error indicator */ 618 *bp++ = '\001'; /* error indicator */
619 if (syserr) 619 if (syserr)
620 len = snprintf(bp, ep - bp, "rlogind: %s: %s.\r\n", 620 len = snprintf(bp, ep - bp, "rlogind: %s: %s.\r\n",
621 msg, strerror(errno)); 621 msg, strerror(errno));
622 else 622 else
623 len = snprintf(bp, ep - bp, "rlogind: %s.\r\n", msg); 623 len = snprintf(bp, ep - bp, "rlogind: %s.\r\n", msg);
624 (void) write(f, buf, bp + len - buf); 624 (void) write(f, buf, bp + len - buf);
625 exit(1); 625 exit(1);
626} 626}
627 627
628int 628int
629do_rlogin(dest, host) 629do_rlogin(dest, host)
630 struct sockaddr *dest; 630 struct sockaddr *dest;
631 char *host; 631 char *host;
632{ 632{
633 int retval; 633 int retval;
634 634
635 getstr(rusername, sizeof(rusername), "remuser too long"); 635 getstr(rusername, sizeof(rusername), "remuser too long");
636 getstr(lusername, sizeof(lusername), "locuser too long"); 636 getstr(lusername, sizeof(lusername), "locuser too long");
637 getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); 637 getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long");
638 638
639 pwd = getpwnam(lusername); 639 pwd = getpwnam(lusername);
640 if (pwd == NULL) { 640 if (pwd == NULL) {
641 syslog(LOG_INFO, 641 syslog(LOG_INFO,
642 "%s@%s as %s: unknown login.", rusername, host, lusername); 642 "%s@%s as %s: unknown login.", rusername, host, lusername);
643 return (-1); 643 return (-1);
644 } 644 }
645 645
646 retval = iruserok_sa(dest, dest->sa_len, pwd->pw_uid == 0, rusername, 646 retval = iruserok_sa(dest, dest->sa_len, pwd->pw_uid == 0, rusername,
647 lusername); 647 lusername);
648/* XXX put inet_ntoa(dest->sin_addr.s_addr) into all messages below */ 648/* XXX put inet_ntoa(dest->sin_addr.s_addr) into all messages below */
649 if (retval == 0) { 649 if (retval == 0) {
650 if (log_success) 650 if (log_success)
651 syslog(LOG_INFO, "%s@%s as %s: iruserok succeeded", 651 syslog(LOG_INFO, "%s@%s as %s: iruserok succeeded",
652 rusername, host, lusername); 652 rusername, host, lusername);
653 } else { 653 } else {
654 if (__rcmd_errstr) 654 if (__rcmd_errstr)
655 syslog(LOG_INFO, "%s@%s as %s: iruserok failed (%s)", 655 syslog(LOG_INFO, "%s@%s as %s: iruserok failed (%s)",
656 rusername, host, lusername, __rcmd_errstr); 656 rusername, host, lusername, __rcmd_errstr);
657 else 657 else
658 syslog(LOG_INFO, "%s@%s as %s: iruserok failed", 658 syslog(LOG_INFO, "%s@%s as %s: iruserok failed",
659 rusername, host, lusername); 659 rusername, host, lusername);
660 } 660 }
661 return(retval); 661 return(retval);
662} 662}
663 663
664void 664void
665getstr(buf, cnt, errmsg) 665getstr(buf, cnt, errmsg)
666 char *buf; 666 char *buf;
667 int cnt; 667 int cnt;
668 const char *errmsg; 668 const char *errmsg;
669{ 669{
670 char c; 670 char c;
671 671
672 do { 672 do {
673 if (read(0, &c, 1) != 1) 673 if (read(0, &c, 1) != 1)
674 exit(1); 674 exit(1);
675 if (--cnt < 0) 675 if (--cnt < 0)
676 fatal(STDOUT_FILENO, errmsg, 0); 676 fatal(STDOUT_FILENO, errmsg, 0);
677 *buf++ = c; 677 *buf++ = c;
678 } while (c != 0); 678 } while (c != 0);
679} 679}
680 680
681 681
682void 682void
683setup_term(fd) 683setup_term(fd)
684 int fd; 684 int fd;
685{ 685{
686 char *cp = index(term+ENVSIZE, '/'); 686 char *cp = index(term+ENVSIZE, '/');
687 char *speed; 687 char *speed;
688 struct termios tt; 688 struct termios tt;
689 689
690#ifndef notyet 690#ifndef notyet
691 tcgetattr(fd, &tt); 691 tcgetattr(fd, &tt);
692 if (cp) { 692 if (cp) {
693 *cp++ = '\0'; 693 *cp++ = '\0';
694 speed = cp; 694 speed = cp;
695 cp = index(speed, '/'); 695 cp = index(speed, '/');
696 if (cp) 696 if (cp)
697 *cp++ = '\0'; 697 *cp++ = '\0';
698 cfsetspeed(&tt, atoi(speed)); 698 cfsetspeed(&tt, atoi(speed));
699 } 699 }
700 700
701 tt.c_iflag = TTYDEF_IFLAG; 701 tt.c_iflag = TTYDEF_IFLAG;
702 tt.c_oflag = TTYDEF_OFLAG; 702 tt.c_oflag = TTYDEF_OFLAG;
703 tt.c_lflag = TTYDEF_LFLAG; 703 tt.c_lflag = TTYDEF_LFLAG;
704 tcsetattr(fd, TCSAFLUSH, &tt); 704 tcsetattr(fd, TCSAFLUSH, &tt);
705#else 705#else
706 if (cp) { 706 if (cp) {
707 *cp++ = '\0'; 707 *cp++ = '\0';
708 speed = cp; 708 speed = cp;
709 cp = index(speed, '/'); 709 cp = index(speed, '/');
710 if (cp) 710 if (cp)
711 *cp++ = '\0'; 711 *cp++ = '\0';
712 tcgetattr(fd, &tt); 712 tcgetattr(fd, &tt);
713 cfsetspeed(&tt, atoi(speed)); 713 cfsetspeed(&tt, atoi(speed));
714 tcsetattr(fd, TCSAFLUSH, &tt); 714 tcsetattr(fd, TCSAFLUSH, &tt);
715 } 715 }
716#endif 716#endif
717 717
718 env[0] = term; 718 env[0] = term;
719 env[1] = 0; 719 env[1] = 0;
720 environ = env; 720 environ = env;
721} 721}
722 722
723 723
724void 724void
725usage() 725usage()
726{ 726{
727 syslog(LOG_ERR, "usage: rlogind [-alnL]"); 727 syslog(LOG_ERR, "usage: rlogind [-alnL]");
728} 728}
729 729
730/* 730/*
731 * Check whether host h is in our local domain, 731 * Check whether host h is in our local domain,
732 * defined as sharing the last two components of the domain part, 732 * defined as sharing the last two components of the domain part,
733 * or the entire domain part if the local domain has only one component. 733 * or the entire domain part if the local domain has only one component.
734 * If either name is unqualified (contains no '.'), 734 * If either name is unqualified (contains no '.'),
735 * assume that the host is local, as it will be 735 * assume that the host is local, as it will be
736 * interpreted as such. 736 * interpreted as such.
737 */ 737 */
738int 738int
739local_domain(h) 739local_domain(h)
740 char *h; 740 char *h;
741{ 741{
742 char localhost[MAXHOSTNAMELEN + 1]; 742 char localhost[MAXHOSTNAMELEN + 1];
743 char *p1, *p2; 743 char *p1, *p2;
744 744
745 localhost[0] = 0; 745 localhost[0] = 0;
746 (void) gethostname(localhost, sizeof(localhost)); 746 (void) gethostname(localhost, sizeof(localhost));
747 localhost[sizeof(localhost) - 1] = '\0'; 747 localhost[sizeof(localhost) - 1] = '\0';
748 p1 = topdomain(localhost); 748 p1 = topdomain(localhost);
749 p2 = topdomain(h); 749 p2 = topdomain(h);
750 if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) 750 if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2))
751 return (1); 751 return (1);
752 return (0); 752 return (0);
753} 753}
754 754
755char * 755char *
756topdomain(h) 756topdomain(h)
757 char *h; 757 char *h;
758{ 758{
759 char *p; 759 char *p;
760 char *maybe = NULL; 760 char *maybe = NULL;
761 int dots = 0; 761 int dots = 0;
762 762
763 for (p = h + strlen(h); p >= h; p--) { 763 for (p = h + strlen(h); p >= h; p--) {
764 if (*p == '.') { 764 if (*p == '.') {
765 if (++dots == 2) 765 if (++dots == 2)
766 return (p); 766 return (p);
767 maybe = p; 767 maybe = p;
768 } 768 }
769 } 769 }
770 return (maybe); 770 return (maybe);
771} 771}