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 * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
28 */
29
30 /*
31 * zlogin provides three types of login which allow users in the global
32 * zone to access non-global zones.
33 *
34 * - "interactive login" is similar to rlogin(1); for example, the user could
35 * issue 'zlogin my-zone' or 'zlogin -e ^ -l me my-zone'. The user is
36 * granted a new pty (which is then shoved into the zone), and an I/O
37 * loop between parent and child processes takes care of the interactive
38 * session. In this mode, login(1) (and its -c option, which means
39 * "already authenticated") is employed to take care of the initialization
40 * of the user's session.
41 *
42 * - "non-interactive login" is similar to su(1M); the user could issue
43 * 'zlogin my-zone ls -l' and the command would be run as specified.
44 * In this mode, zlogin sets up pipes as the communication channel, and
45 * 'su' is used to do the login setup work.
46 *
47 * - "console login" is the equivalent to accessing the tip line for a
98 static struct termios save_termios;
99 static struct termios effective_termios;
100 static int save_fd;
101 static struct winsize winsize;
102 static volatile int dead;
103 static volatile pid_t child_pid = -1;
104 static int interactive = 0;
105 static priv_set_t *dropprivs;
106
107 static int nocmdchar = 0;
108 static int failsafe = 0;
109 static int disconnect = 0;
110 static char cmdchar = '~';
111 static int quiet = 0;
112
113 static int pollerr = 0;
114
115 static const char *pname;
116 static char *username;
117
118 extern int __xpg4; /* 0 if not an xpg4/6-compiled program */
119
120 /*
121 * When forced_login is true, the user is not prompted
122 * for an authentication password in the target zone.
123 */
124 static boolean_t forced_login = B_FALSE;
125
126 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
127 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
128 #endif
129
130 #define SUPATH "/usr/bin/su"
131 #define FAILSAFESHELL "/sbin/sh"
132 #define DEFAULTSHELL "/sbin/sh"
133 #define DEF_PATH "/usr/sbin:/usr/bin"
134
135 #define CLUSTER_BRAND_NAME "cluster"
136
137 /*
138 * The ZLOGIN_BUFSIZ is larger than PIPE_BUF so we can be sure we're clearing
139 * out the pipe when the child is exiting. The ZLOGIN_RDBUFSIZ must be less
753 return (-1);
754
755 return (0);
756 }
757
758 /*
759 * Write the output from the application running in the zone. We can get
760 * a signal during the write (usually it would be SIGCHLD when the application
761 * has exited) so we loop to make sure we have written all of the data we read.
762 */
763 static int
764 process_output(int in_fd, int out_fd)
765 {
766 int wrote = 0;
767 int cc;
768 char ibuf[ZLOGIN_BUFSIZ];
769
770 cc = read(in_fd, ibuf, ZLOGIN_BUFSIZ);
771 if (cc == -1 && (errno != EINTR || dead))
772 return (-1);
773 if (cc == 0) {
774 /*
775 * A return value of 0 when calling read() on a terminal
776 * indicates end-of-file pre-XPG4 and no data available
777 * for XPG4 and above.
778 */
779 if (__xpg4 == 0)
780 return (-1);
781 return (0);
782 }
783 if (cc == -1) /* The read was interrupted. */
784 return (0);
785
786 do {
787 int len;
788
789 len = write(out_fd, ibuf + wrote, cc - wrote);
790 if (len == -1 && errno != EINTR)
791 return (-1);
792 if (len != -1)
793 wrote += len;
794 } while (wrote < cc);
795
796 return (0);
797 }
798
799 /*
800 * This is the main I/O loop, and is shared across all zlogin modes.
801 * Parameters:
802 * stdin_fd: The fd representing 'stdin' for the slave side; input to
|
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 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
28 */
29
30 /*
31 * zlogin provides three types of login which allow users in the global
32 * zone to access non-global zones.
33 *
34 * - "interactive login" is similar to rlogin(1); for example, the user could
35 * issue 'zlogin my-zone' or 'zlogin -e ^ -l me my-zone'. The user is
36 * granted a new pty (which is then shoved into the zone), and an I/O
37 * loop between parent and child processes takes care of the interactive
38 * session. In this mode, login(1) (and its -c option, which means
39 * "already authenticated") is employed to take care of the initialization
40 * of the user's session.
41 *
42 * - "non-interactive login" is similar to su(1M); the user could issue
43 * 'zlogin my-zone ls -l' and the command would be run as specified.
44 * In this mode, zlogin sets up pipes as the communication channel, and
45 * 'su' is used to do the login setup work.
46 *
47 * - "console login" is the equivalent to accessing the tip line for a
98 static struct termios save_termios;
99 static struct termios effective_termios;
100 static int save_fd;
101 static struct winsize winsize;
102 static volatile int dead;
103 static volatile pid_t child_pid = -1;
104 static int interactive = 0;
105 static priv_set_t *dropprivs;
106
107 static int nocmdchar = 0;
108 static int failsafe = 0;
109 static int disconnect = 0;
110 static char cmdchar = '~';
111 static int quiet = 0;
112
113 static int pollerr = 0;
114
115 static const char *pname;
116 static char *username;
117
118 /*
119 * When forced_login is true, the user is not prompted
120 * for an authentication password in the target zone.
121 */
122 static boolean_t forced_login = B_FALSE;
123
124 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
125 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
126 #endif
127
128 #define SUPATH "/usr/bin/su"
129 #define FAILSAFESHELL "/sbin/sh"
130 #define DEFAULTSHELL "/sbin/sh"
131 #define DEF_PATH "/usr/sbin:/usr/bin"
132
133 #define CLUSTER_BRAND_NAME "cluster"
134
135 /*
136 * The ZLOGIN_BUFSIZ is larger than PIPE_BUF so we can be sure we're clearing
137 * out the pipe when the child is exiting. The ZLOGIN_RDBUFSIZ must be less
751 return (-1);
752
753 return (0);
754 }
755
756 /*
757 * Write the output from the application running in the zone. We can get
758 * a signal during the write (usually it would be SIGCHLD when the application
759 * has exited) so we loop to make sure we have written all of the data we read.
760 */
761 static int
762 process_output(int in_fd, int out_fd)
763 {
764 int wrote = 0;
765 int cc;
766 char ibuf[ZLOGIN_BUFSIZ];
767
768 cc = read(in_fd, ibuf, ZLOGIN_BUFSIZ);
769 if (cc == -1 && (errno != EINTR || dead))
770 return (-1);
771 if (cc == 0)
772 return (-1); /* EOF */
773 if (cc == -1) /* The read was interrupted. */
774 return (0);
775
776 do {
777 int len;
778
779 len = write(out_fd, ibuf + wrote, cc - wrote);
780 if (len == -1 && errno != EINTR)
781 return (-1);
782 if (len != -1)
783 wrote += len;
784 } while (wrote < cc);
785
786 return (0);
787 }
788
789 /*
790 * This is the main I/O loop, and is shared across all zlogin modes.
791 * Parameters:
792 * stdin_fd: The fd representing 'stdin' for the slave side; input to
|