6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2013 DEY Storage Systems, Inc.
24 * Copyright (c) 2014 Gary Mills
25 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
26 */
27
28 /*
29 * zlogin provides three types of login which allow users in the global
30 * zone to access non-global zones.
31 *
32 * - "interactive login" is similar to rlogin(1); for example, the user could
33 * issue 'zlogin my-zone' or 'zlogin -e ^ -l me my-zone'. The user is
34 * granted a new pty (which is then shoved into the zone), and an I/O
35 * loop between parent and child processes takes care of the interactive
36 * session. In this mode, login(1) (and its -c option, which means
37 * "already authenticated") is employed to take care of the initialization
38 * of the user's session.
39 *
40 * - "non-interactive login" is similar to su(1M); the user could issue
41 * 'zlogin my-zone ls -l' and the command would be run as specified.
42 * In this mode, zlogin sets up pipes as the communication channel, and
43 * 'su' is used to do the login setup work.
44 *
45 * - "console login" is the equivalent to accessing the tip line for a
595 /*
596 * process_user_input watches the input stream for the escape sequence for
597 * 'quit' (by default, tilde-period). Because we might be fed just one
598 * keystroke at a time, state associated with the user input (are we at the
599 * beginning of the line? are we locally echoing the next character?) is
600 * maintained by beginning_of_line and local_echo across calls to the routine.
601 * If the write to outfd fails, we'll try to read from infd in an attempt
602 * to prevent deadlock between the two processes.
603 *
604 * This routine returns -1 when the 'quit' escape sequence has been issued,
605 * or an error is encountered, 1 if stdin is EOF, and 0 otherwise.
606 */
607 static int
608 process_user_input(int outfd, int infd)
609 {
610 static boolean_t beginning_of_line = B_TRUE;
611 static boolean_t local_echo = B_FALSE;
612 char ibuf[ZLOGIN_BUFSIZ];
613 int nbytes;
614 char *buf = ibuf;
615 char c = *buf;
616
617 nbytes = read(STDIN_FILENO, ibuf, ZLOGIN_RDBUFSIZ);
618 if (nbytes == -1 && (errno != EINTR || dead))
619 return (-1);
620
621 if (nbytes == -1) /* The read was interrupted. */
622 return (0);
623
624 /* 0 read means EOF, close the pipe to the child */
625 if (nbytes == 0)
626 return (1);
627
628 for (c = *buf; nbytes > 0; c = *buf, --nbytes) {
629 buf++;
630 if (beginning_of_line && !nocmdchar) {
631 beginning_of_line = B_FALSE;
632 if (c == cmdchar) {
633 local_echo = B_TRUE;
634 continue;
635 }
636 } else if (local_echo) {
637 local_echo = B_FALSE;
638 if (c == '.' || c == effective_termios.c_cc[VEOF]) {
639 char cc[CANONIFY_LEN];
640
641 canonify(c, cc);
642 (void) write(STDOUT_FILENO, &cmdchar, 1);
643 (void) write(STDOUT_FILENO, cc, strlen(cc));
644 return (-1);
645 }
646 }
647 retry:
648 if (write(outfd, &c, 1) <= 0) {
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2013 DEY Storage Systems, Inc.
24 * Copyright (c) 2014 Gary Mills
25 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
26 * Copyright 2019 Joyent, Inc.
27 */
28
29 /*
30 * zlogin provides three types of login which allow users in the global
31 * zone to access non-global zones.
32 *
33 * - "interactive login" is similar to rlogin(1); for example, the user could
34 * issue 'zlogin my-zone' or 'zlogin -e ^ -l me my-zone'. The user is
35 * granted a new pty (which is then shoved into the zone), and an I/O
36 * loop between parent and child processes takes care of the interactive
37 * session. In this mode, login(1) (and its -c option, which means
38 * "already authenticated") is employed to take care of the initialization
39 * of the user's session.
40 *
41 * - "non-interactive login" is similar to su(1M); the user could issue
42 * 'zlogin my-zone ls -l' and the command would be run as specified.
43 * In this mode, zlogin sets up pipes as the communication channel, and
44 * 'su' is used to do the login setup work.
45 *
46 * - "console login" is the equivalent to accessing the tip line for a
596 /*
597 * process_user_input watches the input stream for the escape sequence for
598 * 'quit' (by default, tilde-period). Because we might be fed just one
599 * keystroke at a time, state associated with the user input (are we at the
600 * beginning of the line? are we locally echoing the next character?) is
601 * maintained by beginning_of_line and local_echo across calls to the routine.
602 * If the write to outfd fails, we'll try to read from infd in an attempt
603 * to prevent deadlock between the two processes.
604 *
605 * This routine returns -1 when the 'quit' escape sequence has been issued,
606 * or an error is encountered, 1 if stdin is EOF, and 0 otherwise.
607 */
608 static int
609 process_user_input(int outfd, int infd)
610 {
611 static boolean_t beginning_of_line = B_TRUE;
612 static boolean_t local_echo = B_FALSE;
613 char ibuf[ZLOGIN_BUFSIZ];
614 int nbytes;
615 char *buf = ibuf;
616
617 nbytes = read(STDIN_FILENO, ibuf, ZLOGIN_RDBUFSIZ);
618 if (nbytes == -1 && (errno != EINTR || dead))
619 return (-1);
620
621 if (nbytes == -1) /* The read was interrupted. */
622 return (0);
623
624 /* 0 read means EOF, close the pipe to the child */
625 if (nbytes == 0)
626 return (1);
627
628 for (char c = *buf; nbytes > 0; c = *buf, --nbytes) {
629 buf++;
630 if (beginning_of_line && !nocmdchar) {
631 beginning_of_line = B_FALSE;
632 if (c == cmdchar) {
633 local_echo = B_TRUE;
634 continue;
635 }
636 } else if (local_echo) {
637 local_echo = B_FALSE;
638 if (c == '.' || c == effective_termios.c_cc[VEOF]) {
639 char cc[CANONIFY_LEN];
640
641 canonify(c, cc);
642 (void) write(STDOUT_FILENO, &cmdchar, 1);
643 (void) write(STDOUT_FILENO, cc, strlen(cc));
644 return (-1);
645 }
646 }
647 retry:
648 if (write(outfd, &c, 1) <= 0) {
|