Print this page
3091 add -n to zlogin so its more compatible with rsh command line

@@ -19,10 +19,11 @@
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2013 DEY Storage Systems, Inc.
+ * Copyright (c) 2014 Gary Mills
  */
 
 /*
  * zlogin provides three types of login which allow users in the global
  * zone to access non-global zones.

@@ -58,10 +59,11 @@
 #include <sys/brand.h>
 #include <sys/wait.h>
 #include <alloca.h>
 #include <assert.h>
 #include <ctype.h>
+#include <paths.h>
 #include <door.h>
 #include <errno.h>
 #include <nss_dbdefs.h>
 #include <poll.h>
 #include <priv.h>

@@ -147,11 +149,11 @@
 #define CANONIFY_LEN 5
 
 static void
 usage(void)
 {
-        (void) fprintf(stderr, gettext("usage: %s [ -QCES ] [ -e cmdchar ] "
+        (void) fprintf(stderr, gettext("usage: %s [ -nQCES ] [ -e cmdchar ] "
             "[-l user] zonename [command [args ...] ]\n"), pname);
         exit(2);
 }
 
 static const char *

@@ -1727,10 +1729,11 @@
         int arg, console = 0;
         zoneid_t zoneid;
         zone_state_t st;
         char *login = "root";
         int lflag = 0;
+        int nflag = 0;
         char *zonename = NULL;
         char **proc_args = NULL;
         char **new_args, **new_env;
         sigset_t block_cld;
         char devroot[MAXPATHLEN];

@@ -1749,11 +1752,11 @@
         (void) textdomain(TEXT_DOMAIN);
 
         (void) getpname(argv[0]);
         username = get_username();
 
-        while ((arg = getopt(argc, argv, "ECR:Se:l:Q")) != EOF) {
+        while ((arg = getopt(argc, argv, "nECR:Se:l:Q")) != EOF) {
                 switch (arg) {
                 case 'C':
                         console = 1;
                         break;
                 case 'E':

@@ -1782,30 +1785,46 @@
                         break;
                 case 'l':
                         login = optarg;
                         lflag = 1;
                         break;
+                case 'n':
+                        nflag = 1;
+                        break;
                 default:
                         usage();
                 }
         }
 
-        if (console != 0 && lflag != 0) {
-                zerror(gettext("-l may not be specified for console login"));
+        if (console != 0) {
+
+                if (lflag != 0) {
+                        zerror(gettext(
+                            "-l may not be specified for console login"));
                 usage();
         }
 
-        if (console != 0 && failsafe != 0) {
-                zerror(gettext("-S may not be specified for console login"));
+                if (nflag != 0) {
+                        zerror(gettext(
+                            "-n may not be specified for console login"));
                 usage();
         }
 
-        if (console != 0 && zonecfg_in_alt_root()) {
-                zerror(gettext("-R may not be specified for console login"));
+                if (failsafe != 0) {
+                        zerror(gettext(
+                            "-S may not be specified for console login"));
+                        usage();
+                }
+
+                if (zonecfg_in_alt_root()) {
+                        zerror(gettext(
+                            "-R may not be specified for console login"));
                 exit(2);
         }
 
+        }
+
         if (failsafe != 0 && lflag != 0) {
                 zerror(gettext("-l may not be specified for failsafe login"));
                 usage();
         }
 

@@ -1812,10 +1831,15 @@
         if (optind == (argc - 1)) {
                 /*
                  * zone name, no process name; this should be an interactive
                  * as long as STDIN is really a tty.
                  */
+                if (nflag != 0) {
+                        zerror(gettext(
+                            "-n may not be specified for interactive login"));
+                        usage();
+                }
                 if (isatty(STDIN_FILENO))
                         interactive = 1;
                 zonename = argv[optind];
         } else if (optind < (argc - 1)) {
                 if (console) {

@@ -2041,13 +2065,31 @@
         if ((new_env = prep_env()) == NULL) {
                 zperror(gettext("could not assemble new environment"));
                 return (1);
         }
 
-        if (!interactive)
+        if (!interactive) {
+                if (nflag) {
+                        int nfd;
+
+                        if ((nfd = open(_PATH_DEVNULL, O_RDONLY)) < 0) {
+                                zperror(gettext("failed to open null device"));
+                                return (1);
+                        }
+                        if (nfd != STDIN_FILENO) {
+                                if (dup2(nfd, STDIN_FILENO) < 0) {
+                                        zperror(gettext(
+                                            "failed to dup2 null device"));
+                                        return (1);
+                                }
+                                (void) close(nfd);
+                        }
+                        /* /dev/null is now standard input */
+                }
                 return (noninteractive_login(zonename, user_cmd, zoneid,
                     new_args, new_env));
+        }
 
         if (zonecfg_in_alt_root()) {
                 zerror(gettext("cannot use interactive login with scratch "
                     "zone"));
                 return (1);