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);