Print this page
12306 XPG4v2 slave pty behaviour should generally be disabled
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Change-ID: I7ccd399c22866f34dd20c6bb9d28e77ba4e24c67


   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