Annotation of src/libexec/telnetd/sys_term.c, Revision 1.44
1.44 ! hubertf 1: /* $NetBSD: sys_term.c,v 1.43 2005/05/05 01:28:57 lukem Exp $ */
1.8 thorpej 2:
1.1 cgd 3: /*
1.3 cgd 4: * Copyright (c) 1989, 1993
5: * The Regents of the University of California. All rights reserved.
1.1 cgd 6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.39 agc 15: * 3. Neither the name of the University nor the names of its contributors
1.1 cgd 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
1.11 mrg 32: #include <sys/cdefs.h>
1.1 cgd 33: #ifndef lint
1.8 thorpej 34: #if 0
35: static char sccsid[] = "@(#)sys_term.c 8.4+1 (Berkeley) 5/30/95";
36: #else
1.44 ! hubertf 37: __RCSID("$NetBSD: sys_term.c,v 1.43 2005/05/05 01:28:57 lukem Exp $");
1.8 thorpej 38: #endif
1.1 cgd 39: #endif /* not lint */
40:
41: #include "telnetd.h"
42: #include "pathnames.h"
43:
1.11 mrg 44: #include <util.h>
1.41 christos 45: #include <vis.h>
1.11 mrg 46:
1.31 wiz 47: #include <utmp.h>
1.1 cgd 48: struct utmp wtmp;
49:
50: #define SCPYN(a, b) (void) strncpy(a, b, sizeof(a))
51: #define SCMPN(a, b) strncmp(a, b, sizeof(a))
52:
53: struct termios termbuf, termbuf2; /* pty control structure */
54:
1.42 perry 55: void getptyslave(void);
56: int cleanopen(char *);
57: char **addarg(char **, char *);
58: void scrub_env(void);
59: int getent(char *, char *);
60: char *getstr(const char *, char **);
1.16 aidan 61: #ifdef KRB5
1.42 perry 62: extern void kerberos5_cleanup(void);
1.16 aidan 63: #endif
1.11 mrg 64:
1.1 cgd 65: /*
66: * init_termbuf()
67: * copy_termbuf(cp)
68: * set_termbuf()
69: *
70: * These three routines are used to get and set the "termbuf" structure
71: * to and from the kernel. init_termbuf() gets the current settings.
72: * copy_termbuf() hands in a new "termbuf" to write to the kernel, and
73: * set_termbuf() writes the structure into the kernel.
74: */
75:
1.36 itojun 76: void
1.42 perry 77: init_termbuf(void)
1.1 cgd 78: {
79: (void) tcgetattr(pty, &termbuf);
80: termbuf2 = termbuf;
81: }
82:
83: #if defined(LINEMODE) && defined(TIOCPKT_IOCTL)
1.36 itojun 84: void
1.42 perry 85: copy_termbuf(char *cp, int len)
1.1 cgd 86: {
87: if (len > sizeof(termbuf))
88: len = sizeof(termbuf);
1.6 jtk 89: memmove((char *)&termbuf, cp, len);
1.1 cgd 90: termbuf2 = termbuf;
91: }
92: #endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
93:
1.36 itojun 94: void
1.42 perry 95: set_termbuf(void)
1.1 cgd 96: {
97: /*
98: * Only make the necessary changes.
99: */
1.6 jtk 100: if (memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
1.1 cgd 101: (void) tcsetattr(pty, TCSANOW, &termbuf);
102: }
103:
104:
105: /*
106: * spcset(func, valp, valpp)
107: *
108: * This function takes various special characters (func), and
109: * sets *valp to the current value of that character, and
110: * *valpp to point to where in the "termbuf" structure that
111: * value is kept.
112: *
113: * It returns the SLC_ level of support for this function.
114: */
115:
116:
1.36 itojun 117: int
1.42 perry 118: spcset(int func, cc_t *valp, cc_t **valpp)
1.1 cgd 119: {
120:
121: #define setval(a, b) *valp = termbuf.c_cc[a]; \
122: *valpp = &termbuf.c_cc[a]; \
123: return(b);
124: #define defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);
125:
126: switch(func) {
127: case SLC_EOF:
128: setval(VEOF, SLC_VARIABLE);
129: case SLC_EC:
130: setval(VERASE, SLC_VARIABLE);
131: case SLC_EL:
132: setval(VKILL, SLC_VARIABLE);
133: case SLC_IP:
134: setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
135: case SLC_ABORT:
136: setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
137: case SLC_XON:
138: setval(VSTART, SLC_VARIABLE);
139: case SLC_XOFF:
140: setval(VSTOP, SLC_VARIABLE);
141: case SLC_EW:
142: setval(VWERASE, SLC_VARIABLE);
143: case SLC_RP:
144: setval(VREPRINT, SLC_VARIABLE);
145: case SLC_LNEXT:
146: setval(VLNEXT, SLC_VARIABLE);
147: case SLC_AO:
148: setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
149: case SLC_SUSP:
150: setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
151: case SLC_FORW1:
152: setval(VEOL, SLC_VARIABLE);
153: case SLC_FORW2:
154: setval(VEOL2, SLC_VARIABLE);
155: case SLC_AYT:
156: setval(VSTATUS, SLC_VARIABLE);
157:
158: case SLC_BRK:
159: case SLC_SYNCH:
160: case SLC_EOR:
161: defval(0);
162:
163: default:
164: *valp = 0;
165: *valpp = 0;
166: return(SLC_NOSUPPORT);
167: }
168: }
169:
170:
171: /*
172: * getpty()
173: *
174: * Allocate a pty. As a side effect, the external character
175: * array "line" contains the name of the slave side.
176: *
177: * Returns the file descriptor of the opened pty.
178: */
179: #ifndef __GNUC__
1.19 christos 180: char *line = NULL16STR;
1.1 cgd 181: #else
1.19 christos 182: static char Xline[] = NULL16STR;
1.1 cgd 183: char *line = Xline;
184: #endif
185:
1.13 perry 186:
187: static int ptyslavefd; /* for cleanopen() */
188:
189: int
1.42 perry 190: getpty(int *ptynum)
1.44 ! hubertf 191: {
1.13 perry 192: int ptyfd;
193:
194: ptyfd = openpty(ptynum, &ptyslavefd, line, NULL, NULL);
195: if (ptyfd == 0)
196: return *ptynum;
197: ptyslavefd = -1;
198: return (-1);
199: }
1.1 cgd 200:
201: #ifdef LINEMODE
202: /*
203: * tty_flowmode() Find out if flow control is enabled or disabled.
204: * tty_linemode() Find out if linemode (external processing) is enabled.
205: * tty_setlinemod(on) Turn on/off linemode.
206: * tty_isecho() Find out if echoing is turned on.
207: * tty_setecho(on) Enable/disable character echoing.
208: * tty_israw() Find out if terminal is in RAW mode.
209: * tty_binaryin(on) Turn on/off BINARY on input.
210: * tty_binaryout(on) Turn on/off BINARY on output.
211: * tty_isediting() Find out if line editing is enabled.
212: * tty_istrapsig() Find out if signal trapping is enabled.
213: * tty_setedit(on) Turn on/off line editing.
214: * tty_setsig(on) Turn on/off signal trapping.
215: * tty_issofttab() Find out if tab expansion is enabled.
216: * tty_setsofttab(on) Turn on/off soft tab expansion.
217: * tty_islitecho() Find out if typed control chars are echoed literally
218: * tty_setlitecho() Turn on/off literal echo of control chars
219: * tty_tspeed(val) Set transmit speed to val.
220: * tty_rspeed(val) Set receive speed to val.
221: */
222:
223:
1.36 itojun 224: int
1.42 perry 225: tty_linemode(void)
1.1 cgd 226: {
227: return(termbuf.c_lflag & EXTPROC);
228: }
229:
1.36 itojun 230: void
1.42 perry 231: tty_setlinemode(int on)
1.1 cgd 232: {
233: set_termbuf();
234: (void) ioctl(pty, TIOCEXT, (char *)&on);
235: init_termbuf();
236: }
1.3 cgd 237: #endif /* LINEMODE */
1.1 cgd 238:
1.36 itojun 239: int
1.42 perry 240: tty_isecho(void)
1.1 cgd 241: {
242: return (termbuf.c_lflag & ECHO);
243: }
1.3 cgd 244:
1.36 itojun 245: int
1.42 perry 246: tty_flowmode(void)
1.3 cgd 247: {
248: return((termbuf.c_iflag & IXON) ? 1 : 0);
249: }
250:
1.36 itojun 251: int
1.42 perry 252: tty_restartany(void)
1.3 cgd 253: {
254: return((termbuf.c_iflag & IXANY) ? 1 : 0);
255: }
1.1 cgd 256:
1.36 itojun 257: void
1.42 perry 258: tty_setecho(int on)
1.1 cgd 259: {
260: if (on)
261: termbuf.c_lflag |= ECHO;
262: else
263: termbuf.c_lflag &= ~ECHO;
264: }
265:
1.36 itojun 266: int
1.42 perry 267: tty_israw(void)
1.1 cgd 268: {
269: return(!(termbuf.c_lflag & ICANON));
270: }
1.3 cgd 271:
1.36 itojun 272: void
1.42 perry 273: tty_binaryin(int on)
1.1 cgd 274: {
275: if (on) {
276: termbuf.c_iflag &= ~ISTRIP;
277: } else {
278: termbuf.c_iflag |= ISTRIP;
279: }
280: }
281:
1.36 itojun 282: void
1.42 perry 283: tty_binaryout(int on)
1.1 cgd 284: {
285: if (on) {
286: termbuf.c_cflag &= ~(CSIZE|PARENB);
287: termbuf.c_cflag |= CS8;
288: termbuf.c_oflag &= ~OPOST;
289: } else {
290: termbuf.c_cflag &= ~CSIZE;
291: termbuf.c_cflag |= CS7|PARENB;
292: termbuf.c_oflag |= OPOST;
293: }
294: }
295:
1.36 itojun 296: int
1.42 perry 297: tty_isbinaryin(void)
1.1 cgd 298: {
299: return(!(termbuf.c_iflag & ISTRIP));
300: }
301:
1.36 itojun 302: int
1.42 perry 303: tty_isbinaryout(void)
1.1 cgd 304: {
305: return(!(termbuf.c_oflag&OPOST));
306: }
307:
308: #ifdef LINEMODE
1.36 itojun 309: int
1.42 perry 310: tty_isediting(void)
1.1 cgd 311: {
312: return(termbuf.c_lflag & ICANON);
313: }
314:
1.36 itojun 315: int
1.42 perry 316: tty_istrapsig(void)
1.1 cgd 317: {
318: return(termbuf.c_lflag & ISIG);
319: }
320:
1.36 itojun 321: void
1.42 perry 322: tty_setedit(int on)
1.1 cgd 323: {
324: if (on)
325: termbuf.c_lflag |= ICANON;
326: else
327: termbuf.c_lflag &= ~ICANON;
328: }
329:
1.36 itojun 330: void
1.42 perry 331: tty_setsig(int on)
1.1 cgd 332: {
333: if (on)
334: termbuf.c_lflag |= ISIG;
335: else
336: termbuf.c_lflag &= ~ISIG;
337: }
338: #endif /* LINEMODE */
339:
1.36 itojun 340: int
1.42 perry 341: tty_issofttab(void)
1.1 cgd 342: {
343: # ifdef OXTABS
344: return (termbuf.c_oflag & OXTABS);
345: # endif
346: # ifdef TABDLY
347: return ((termbuf.c_oflag & TABDLY) == TAB3);
348: # endif
349: }
350:
1.36 itojun 351: void
1.42 perry 352: tty_setsofttab(int on)
1.1 cgd 353: {
354: if (on) {
355: # ifdef OXTABS
356: termbuf.c_oflag |= OXTABS;
357: # endif
358: # ifdef TABDLY
359: termbuf.c_oflag &= ~TABDLY;
360: termbuf.c_oflag |= TAB3;
361: # endif
362: } else {
363: # ifdef OXTABS
364: termbuf.c_oflag &= ~OXTABS;
365: # endif
366: # ifdef TABDLY
367: termbuf.c_oflag &= ~TABDLY;
368: termbuf.c_oflag |= TAB0;
369: # endif
370: }
371: }
372:
1.36 itojun 373: int
1.42 perry 374: tty_islitecho(void)
1.1 cgd 375: {
376: # ifdef ECHOCTL
377: return (!(termbuf.c_lflag & ECHOCTL));
378: # endif
379: # ifdef TCTLECH
380: return (!(termbuf.c_lflag & TCTLECH));
381: # endif
382: # if !defined(ECHOCTL) && !defined(TCTLECH)
383: return (0); /* assumes ctl chars are echoed '^x' */
384: # endif
385: }
386:
1.36 itojun 387: void
1.42 perry 388: tty_setlitecho(int on)
1.1 cgd 389: {
390: # ifdef ECHOCTL
391: if (on)
392: termbuf.c_lflag &= ~ECHOCTL;
393: else
394: termbuf.c_lflag |= ECHOCTL;
395: # endif
396: # ifdef TCTLECH
397: if (on)
398: termbuf.c_lflag &= ~TCTLECH;
399: else
400: termbuf.c_lflag |= TCTLECH;
401: # endif
402: }
403:
1.36 itojun 404: int
1.42 perry 405: tty_iscrnl(void)
1.1 cgd 406: {
407: return (termbuf.c_iflag & ICRNL);
408: }
409:
1.36 itojun 410: void
1.42 perry 411: tty_tspeed(int val)
1.1 cgd 412: {
1.6 jtk 413: cfsetospeed(&termbuf, val);
1.1 cgd 414: }
415:
1.36 itojun 416: void
1.42 perry 417: tty_rspeed(int val)
1.1 cgd 418: {
1.6 jtk 419: cfsetispeed(&termbuf, val);
1.1 cgd 420: }
421:
422:
423:
424:
425: /*
426: * getptyslave()
427: *
428: * Open the slave side of the pty, and do any initialization
429: * that is necessary. The return value is a file descriptor
430: * for the slave side.
431: */
1.22 christos 432: extern int def_tspeed, def_rspeed;
433: extern int def_row, def_col;
434:
1.42 perry 435: void
436: getptyslave(void)
1.1 cgd 437: {
1.42 perry 438: int t = -1;
1.1 cgd 439:
1.31 wiz 440: #ifdef LINEMODE
1.1 cgd 441: int waslm;
1.31 wiz 442: #endif
1.1 cgd 443: struct winsize ws;
444: /*
445: * Opening the slave side may cause initilization of the
446: * kernel tty structure. We need remember the state of
447: * if linemode was turned on
448: * terminal window size
449: * terminal speed
450: * so that we can re-set them if we need to.
451: */
1.31 wiz 452: #ifdef LINEMODE
1.1 cgd 453: waslm = tty_linemode();
1.31 wiz 454: #endif
1.1 cgd 455:
456: /*
457: * Make sure that we don't have a controlling tty, and
458: * that we are the session (process group) leader.
459: */
460: t = open(_PATH_TTY, O_RDWR);
461: if (t >= 0) {
462: (void) ioctl(t, TIOCNOTTY, (char *)0);
463: (void) close(t);
464: }
465:
466:
467:
468: t = cleanopen(line);
469: if (t < 0)
470: fatalperror(net, line);
471:
1.3 cgd 472:
1.1 cgd 473: /*
474: * set up the tty modes as we like them to be.
475: */
476: init_termbuf();
477: if (def_row || def_col) {
1.6 jtk 478: memset((char *)&ws, 0, sizeof(ws));
1.1 cgd 479: ws.ws_col = def_col;
480: ws.ws_row = def_row;
481: (void)ioctl(t, TIOCSWINSZ, (char *)&ws);
482: }
483:
484: /*
485: * Settings for sgtty based systems
486: */
487:
488: /*
489: * Settings for all other termios/termio based
490: * systems, other than 4.4BSD. In 4.4BSD the
491: * kernel does the initial terminal setup.
492: */
493: tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
494: tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
1.31 wiz 495: #ifdef LINEMODE
1.1 cgd 496: if (waslm)
497: tty_setlinemode(1);
1.31 wiz 498: #endif /* LINEMODE */
1.1 cgd 499:
500: /*
501: * Set the tty modes, and make this our controlling tty.
502: */
503: set_termbuf();
504: if (login_tty(t) == -1)
505: fatalperror(net, "login_tty");
506: if (net > 2)
507: (void) close(net);
1.3 cgd 508: if (pty > 2) {
1.1 cgd 509: (void) close(pty);
1.3 cgd 510: pty = -1;
511: }
1.1 cgd 512: }
513:
514: /*
515: * Open the specified slave side of the pty,
516: * making sure that we have a clean tty.
517: */
1.36 itojun 518: int
1.42 perry 519: cleanopen(char *ttyline)
1.1 cgd 520: {
1.13 perry 521: return ptyslavefd;
1.1 cgd 522: }
523:
524: /*
525: * startslave(host)
526: *
527: * Given a hostname, do whatever
528: * is necessary to startup the login process on the slave side of the pty.
529: */
530:
531: /* ARGSUSED */
1.36 itojun 532: void
1.42 perry 533: startslave(char *host, int autologin, char *autoname)
1.1 cgd 534: {
1.42 perry 535: int i;
1.1 cgd 536:
1.36 itojun 537: #ifdef AUTHENTICATION
1.1 cgd 538: if (!autoname || !autoname[0])
539: autologin = 0;
540:
541: if (autologin < auth_level) {
542: fatal(net, "Authorization failed");
543: exit(1);
544: }
545: #endif
546:
547:
548: if ((i = fork()) < 0)
549: fatalperror(net, "fork");
550: if (i) {
551: } else {
1.11 mrg 552: getptyslave();
1.1 cgd 553: start_login(host, autologin, autoname);
554: /*NOTREACHED*/
555: }
556: }
557:
558: char *envinit[3];
559:
1.36 itojun 560: void
1.42 perry 561: init_env(void)
1.1 cgd 562: {
563: char **envp;
564:
565: envp = envinit;
1.11 mrg 566: if ((*envp = getenv("TZ")))
1.1 cgd 567: *envp++ -= 3;
568: *envp = 0;
569: environ = envinit;
570: }
571:
572:
573: /*
574: * start_login(host)
575: *
576: * Assuming that we are now running as a child processes, this
577: * function will turn us into the login process.
578: */
1.22 christos 579: extern char *gettyname;
1.1 cgd 580:
1.36 itojun 581: void
1.42 perry 582: start_login(char *host, int autologin, char *name)
1.1 cgd 583: {
1.42 perry 584: char **argv;
1.9 tls 585: #define TABBUFSIZ 512
586: char defent[TABBUFSIZ];
587: char defstrs[TABBUFSIZ];
588: #undef TABBUFSIZ
1.23 itojun 589: const char *loginprog = NULL;
1.41 christos 590: extern struct sockaddr_storage from;
591: char buf[sizeof(from) * 4 + 1];
1.1 cgd 592:
1.6 jtk 593: scrub_env();
594:
1.1 cgd 595: /*
1.41 christos 596: * -a : pass on the address of the host.
1.1 cgd 597: * -h : pass on name of host.
1.41 christos 598: * WARNING: -h and -a are accepted by login
599: * if and only if getuid() == 0.
1.1 cgd 600: * -p : don't clobber the environment (so terminal type stays set).
601: *
602: * -f : force this login, he has already been authenticated
603: */
604: argv = addarg(0, "login");
1.3 cgd 605:
1.41 christos 606: argv = addarg(argv, "-a");
607: (void)strvisx(buf, (const char *)(const void *)&from, sizeof(from),
608: VIS_WHITE);
609: argv = addarg(argv, buf);
610:
611: argv = addarg(argv, "-h");
612: argv = addarg(argv, host);
613:
1.1 cgd 614: argv = addarg(argv, "-p");
1.6 jtk 615: #ifdef LINEMODE
616: /*
617: * Set the environment variable "LINEMODE" to either
618: * "real" or "kludge" if we are operating in either
619: * real or kludge linemode.
620: */
621: if (lmodetype == REAL_LINEMODE)
622: setenv("LINEMODE", "real", 1);
623: # ifdef KLUDGELINEMODE
624: else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK)
625: setenv("LINEMODE", "kludge", 1);
626: # endif
627: #endif
1.36 itojun 628: #ifdef SECURELOGIN
1.1 cgd 629: /*
630: * don't worry about the -f that might get sent.
631: * A -s is supposed to override it anyhow.
632: */
1.15 dean 633: if (require_secure_login)
1.1 cgd 634: argv = addarg(argv, "-s");
635: #endif
1.36 itojun 636: #ifdef AUTHENTICATION
1.1 cgd 637: if (auth_level >= 0 && autologin == AUTH_VALID) {
638: argv = addarg(argv, "-f");
1.5 mycroft 639: argv = addarg(argv, "--");
1.3 cgd 640: argv = addarg(argv, name);
1.1 cgd 641: } else
642: #endif
643: if (getenv("USER")) {
1.5 mycroft 644: argv = addarg(argv, "--");
1.1 cgd 645: argv = addarg(argv, getenv("USER"));
1.3 cgd 646: /*
647: * Assume that login will set the USER variable
648: * correctly. For SysV systems, this means that
649: * USER will no longer be set, just LOGNAME by
650: * login. (The problem is that if the auto-login
651: * fails, and the user then specifies a different
652: * account name, he can get logged in with both
653: * LOGNAME and USER in his environment, but the
654: * USER value will be wrong.
655: */
656: unsetenv("USER");
1.1 cgd 657: }
1.9 tls 658: if (getent(defent, gettyname) == 1) {
659: char *cp = defstrs;
660:
661: loginprog = getstr("lo", &cp);
662: }
663: if (loginprog == NULL)
664: loginprog = _PATH_LOGIN;
1.1 cgd 665: closelog();
1.6 jtk 666: /*
667: * This sleep(1) is in here so that telnetd can
668: * finish up with the tty. There's a race condition
669: * the login banner message gets lost...
670: */
671: sleep(1);
1.9 tls 672: execv(loginprog, argv);
1.1 cgd 673:
1.25 wiz 674: syslog(LOG_ERR, "%s: %m", loginprog);
1.9 tls 675: fatalperror(net, loginprog);
1.1 cgd 676: /*NOTREACHED*/
677: }
678:
1.42 perry 679: char **
680: addarg(char **argv, char *val)
1.1 cgd 681: {
1.42 perry 682: char **cpp;
1.40 itojun 683: char **nargv;
1.1 cgd 684:
685: if (argv == NULL) {
686: /*
687: * 10 entries, a leading length, and a null
688: */
689: argv = (char **)malloc(sizeof(*argv) * 12);
690: if (argv == NULL)
691: return(NULL);
692: *argv++ = (char *)10;
693: *argv = (char *)0;
694: }
695: for (cpp = argv; *cpp; cpp++)
696: ;
1.7 jtk 697: if (cpp == &argv[(long)argv[-1]]) {
1.1 cgd 698: --argv;
1.40 itojun 699: nargv = (char **)realloc(argv,
700: sizeof(*argv) * ((long)(*argv) + 10 + 2));
1.18 tron 701: if (argv == NULL) {
702: fatal(net, "not enough memory");
703: /*NOTREACHED*/
704: }
1.40 itojun 705: argv = nargv;
706: *argv = (char *)((long)(*argv) + 10);
1.1 cgd 707: argv++;
1.7 jtk 708: cpp = &argv[(long)argv[-1] - 10];
1.1 cgd 709: }
710: *cpp++ = val;
711: *cpp = 0;
712: return(argv);
713: }
714:
715: /*
1.6 jtk 716: * scrub_env()
717: *
1.20 assar 718: * We only accept the environment variables listed below.
1.6 jtk 719: */
1.20 assar 720:
1.11 mrg 721: void
1.42 perry 722: scrub_env(void)
1.6 jtk 723: {
1.20 assar 724: static const char *reject[] = {
725: "TERMCAP=/",
726: NULL
727: };
728:
1.27 wiz 729: static const char *acceptstr[] = {
1.20 assar 730: "XAUTH=", "XAUTHORITY=", "DISPLAY=",
731: "TERM=",
732: "EDITOR=",
733: "PAGER=",
734: "LOGNAME=",
735: "POSIXLY_CORRECT=",
736: "TERMCAP=",
737: "PRINTER=",
738: NULL
739: };
740:
741: char **cpp, **cpp2;
742: const char **p;
1.6 jtk 743:
744: for (cpp2 = cpp = environ; *cpp; cpp++) {
1.20 assar 745: int reject_it = 0;
746:
747: for(p = reject; *p; p++)
748: if(strncmp(*cpp, *p, strlen(*p)) == 0) {
749: reject_it = 1;
750: break;
751: }
752: if (reject_it)
753: continue;
754:
1.27 wiz 755: for(p = acceptstr; *p; p++)
1.20 assar 756: if(strncmp(*cpp, *p, strlen(*p)) == 0)
757: break;
758: if(*p != NULL)
1.6 jtk 759: *cpp2++ = *cpp;
760: }
1.20 assar 761: *cpp2 = NULL;
1.6 jtk 762: }
763:
764: /*
1.1 cgd 765: * cleanup()
766: *
767: * This is the routine to call when we are all through, to
768: * clean up anything that needs to be cleaned up.
769: */
1.36 itojun 770: /* ARGSUSED */
771: void
1.42 perry 772: cleanup(int sig)
1.1 cgd 773: {
1.14 tsarna 774: char *p, c;
1.1 cgd 775:
1.43 lukem 776: p = line + sizeof(_PATH_DEV) - 1;
1.32 christos 777: #ifdef SUPPORT_UTMP
1.1 cgd 778: if (logout(p))
779: logwtmp(p, "", "");
1.32 christos 780: #endif
781: #ifdef SUPPORT_UTMPX
782: if (logoutx(p, 0, DEAD_PROCESS))
783: logwtmpx(p, "", "", 0, DEAD_PROCESS);
784: #endif
1.1 cgd 785: (void)chmod(line, 0666);
786: (void)chown(line, 0, 0);
1.14 tsarna 787: c = *p; *p = 'p';
1.1 cgd 788: (void)chmod(line, 0666);
789: (void)chown(line, 0, 0);
1.14 tsarna 790: *p = c;
791: if (ttyaction(line, "telnetd", "root"))
792: syslog(LOG_ERR, "%s: ttyaction failed", line);
1.1 cgd 793: (void) shutdown(net, 2);
794: exit(1);
795: }
CVSweb <webmaster@jp.NetBSD.org>