1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 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) 2013 Gary Mills 23 * 24 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 25 */ 26 27 /* 28 * zlogin provides three types of login which allow users in the global 29 * zone to access non-global zones. 30 * 31 * - "interactive login" is similar to rlogin(1); for example, the user could 32 * issue 'zlogin my-zone' or 'zlogin -e ^ -l me my-zone'. The user is 33 * granted a new pty (which is then shoved into the zone), and an I/O 34 * loop between parent and child processes takes care of the interactive 35 * session. In this mode, login(1) (and its -c option, which means 36 * "already authenticated") is employed to take care of the initialization 37 * of the user's session. 38 * 39 * - "non-interactive login" is similar to su(1M); the user could issue 40 * 'zlogin my-zone ls -l' and the command would be run as specified. 41 * In this mode, zlogin sets up pipes as the communication channel, and 42 * 'su' is used to do the login setup work. 43 * 44 * - "console login" is the equivalent to accessing the tip line for a 45 * zone. For example, the user can issue 'zlogin -C my-zone'. 46 * In this mode, zlogin contacts the zoneadmd process via unix domain 47 * socket. If zoneadmd is not running, it starts it. This allows the 48 * console to be available anytime the zone is installed, regardless of 49 * whether it is running. 50 */ 51 52 #include <sys/socket.h> 53 #include <sys/termios.h> 54 #include <sys/utsname.h> 55 #include <sys/stat.h> 56 #include <sys/types.h> 57 #include <sys/contract/process.h> 58 #include <sys/ctfs.h> 59 #include <sys/brand.h> 60 #include <sys/wait.h> 61 #include <alloca.h> 62 #include <assert.h> 63 #include <ctype.h> 64 #include <door.h> 65 #include <errno.h> 66 #include <nss_dbdefs.h> 67 #include <poll.h> 68 #include <priv.h> 69 #include <pwd.h> 70 #include <unistd.h> 71 #include <utmpx.h> 72 #include <sac.h> 73 #include <signal.h> 74 #include <stdarg.h> 75 #include <stdio.h> 76 #include <stdlib.h> 77 #include <string.h> 78 #include <strings.h> 79 #include <stropts.h> 80 #include <wait.h> 81 #include <zone.h> 82 #include <fcntl.h> 83 #include <libdevinfo.h> 84 #include <libintl.h> 85 #include <locale.h> 86 #include <libzonecfg.h> 87 #include <libcontract.h> 88 #include <libbrand.h> 89 #include <auth_list.h> 90 #include <auth_attr.h> 91 #include <secdb.h> 92 93 #ifdef LOGNAME_MAX_ILLUMOS 94 #define _LOGNAME_MAX LOGNAME_MAX_ILLUMOS 95 #else /* LOGNAME_MAX_ILLUMOS */ 96 #define _LOGNAME_MAX LOGNAME_MAX 97 #endif /* LOGNAME_MAX_ILLUMOS */ 98 99 static int masterfd; 100 static struct termios save_termios; 101 static struct termios effective_termios; 102 static int save_fd; 103 static struct winsize winsize; 104 static volatile int dead; 105 static volatile pid_t child_pid = -1; 106 static int interactive = 0; 107 static priv_set_t *dropprivs; 108 109 static int nocmdchar = 0; 110 static int failsafe = 0; 111 static char cmdchar = '~'; 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 138 * than ZLOGIN_BUFSIZ (because we share the buffer in doio). This value is 139 * also chosen in conjunction with the HI_WATER setting to make sure we 140 * don't fill up the pipe. We can write FIFOHIWAT (16k) into the pipe before 141 * blocking. By having ZLOGIN_RDBUFSIZ set to 1k and HI_WATER set to 8k, we 142 * know we can always write a ZLOGIN_RDBUFSIZ chunk into the pipe when there 143 * is less than HI_WATER data already in the pipe. 144 */ 145 #define ZLOGIN_BUFSIZ 8192 146 #define ZLOGIN_RDBUFSIZ 1024 147 #define HI_WATER 8192 148 149 /* 150 * See canonify() below. CANONIFY_LEN is the maximum length that a 151 * "canonical" sequence will expand to (backslash, three octal digits, NUL). 152 */ 153 #define CANONIFY_LEN 5 154 155 static void 156 usage(void) 157 { 158 (void) fprintf(stderr, gettext("usage: %s [ -CES ] [ -e cmdchar ] " 159 "[-l user] zonename [command [args ...] ]\n"), pname); 160 exit(2); 161 } 162 163 static const char * 164 getpname(const char *arg0) 165 { 166 const char *p = strrchr(arg0, '/'); 167 168 if (p == NULL) 169 p = arg0; 170 else 171 p++; 172 173 pname = p; 174 return (p); 175 } 176 177 static void 178 zerror(const char *fmt, ...) 179 { 180 va_list alist; 181 182 (void) fprintf(stderr, "%s: ", pname); 183 va_start(alist, fmt); 184 (void) vfprintf(stderr, fmt, alist); 185 va_end(alist); 186 (void) fprintf(stderr, "\n"); 187 } 188 189 static void 190 zperror(const char *str) 191 { 192 const char *estr; 193 194 if ((estr = strerror(errno)) != NULL) 195 (void) fprintf(stderr, "%s: %s: %s\n", pname, str, estr); 196 else 197 (void) fprintf(stderr, "%s: %s: errno %d\n", pname, str, errno); 198 } 199 200 /* 201 * The first part of our privilege dropping scheme needs to be called before 202 * fork(), since we must have it for security; we don't want to be surprised 203 * later that we couldn't allocate the privset. 204 */ 205 static int 206 prefork_dropprivs() 207 { 208 if ((dropprivs = priv_allocset()) == NULL) 209 return (1); 210 211 priv_basicset(dropprivs); 212 (void) priv_delset(dropprivs, PRIV_PROC_INFO); 213 (void) priv_delset(dropprivs, PRIV_PROC_FORK); 214 (void) priv_delset(dropprivs, PRIV_PROC_EXEC); 215 (void) priv_delset(dropprivs, PRIV_FILE_LINK_ANY); 216 217 /* 218 * We need to keep the basic privilege PROC_SESSION and all unknown 219 * basic privileges as well as the privileges PROC_ZONE and 220 * PROC_OWNER in order to query session information and 221 * send signals. 222 */ 223 if (interactive == 0) { 224 (void) priv_addset(dropprivs, PRIV_PROC_ZONE); 225 (void) priv_addset(dropprivs, PRIV_PROC_OWNER); 226 } else { 227 (void) priv_delset(dropprivs, PRIV_PROC_SESSION); 228 } 229 230 return (0); 231 } 232 233 /* 234 * The second part of the privilege drop. We are paranoid about being attacked 235 * by the zone, so we drop all privileges. This should prevent a compromise 236 * which gets us to fork(), exec(), symlink(), etc. 237 */ 238 static void 239 postfork_dropprivs() 240 { 241 if ((setppriv(PRIV_SET, PRIV_PERMITTED, dropprivs)) == -1) { 242 zperror(gettext("Warning: could not set permitted privileges")); 243 } 244 if ((setppriv(PRIV_SET, PRIV_LIMIT, dropprivs)) == -1) { 245 zperror(gettext("Warning: could not set limit privileges")); 246 } 247 if ((setppriv(PRIV_SET, PRIV_INHERITABLE, dropprivs)) == -1) { 248 zperror(gettext("Warning: could not set inheritable " 249 "privileges")); 250 } 251 } 252 253 /* 254 * Create the unix domain socket and call the zoneadmd server; handshake 255 * with it to determine whether it will allow us to connect. 256 */ 257 static int 258 get_console_master(const char *zname) 259 { 260 int sockfd = -1; 261 struct sockaddr_un servaddr; 262 char clientid[MAXPATHLEN]; 263 char handshake[MAXPATHLEN], c; 264 int msglen; 265 int i = 0, err = 0; 266 267 if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 268 zperror(gettext("could not create socket")); 269 return (-1); 270 } 271 272 bzero(&servaddr, sizeof (servaddr)); 273 servaddr.sun_family = AF_UNIX; 274 (void) snprintf(servaddr.sun_path, sizeof (servaddr.sun_path), 275 "%s/%s.console_sock", ZONES_TMPDIR, zname); 276 277 if (connect(sockfd, (struct sockaddr *)&servaddr, 278 sizeof (servaddr)) == -1) { 279 zperror(gettext("Could not connect to zone console")); 280 goto bad; 281 } 282 masterfd = sockfd; 283 284 msglen = snprintf(clientid, sizeof (clientid), "IDENT %lu %s\n", 285 getpid(), setlocale(LC_MESSAGES, NULL)); 286 287 if (msglen >= sizeof (clientid) || msglen < 0) { 288 zerror("protocol error"); 289 goto bad; 290 } 291 292 if (write(masterfd, clientid, msglen) != msglen) { 293 zerror("protocol error"); 294 goto bad; 295 } 296 297 bzero(handshake, sizeof (handshake)); 298 299 /* 300 * Take care not to accumulate more than our fill, and leave room for 301 * the NUL at the end. 302 */ 303 while ((err = read(masterfd, &c, 1)) == 1) { 304 if (i >= (sizeof (handshake) - 1)) 305 break; 306 if (c == '\n') 307 break; 308 handshake[i] = c; 309 i++; 310 } 311 312 /* 313 * If something went wrong during the handshake we bail; perhaps 314 * the server died off. 315 */ 316 if (err == -1) { 317 zperror(gettext("Could not connect to zone console")); 318 goto bad; 319 } 320 321 if (strncmp(handshake, "OK", sizeof (handshake)) == 0) 322 return (0); 323 324 zerror(gettext("Console is already in use by process ID %s."), 325 handshake); 326 bad: 327 (void) close(sockfd); 328 masterfd = -1; 329 return (-1); 330 } 331 332 333 /* 334 * Routines to handle pty creation upon zone entry and to shuttle I/O back 335 * and forth between the two terminals. We also compute and store the 336 * name of the slave terminal associated with the master side. 337 */ 338 static int 339 get_master_pty() 340 { 341 if ((masterfd = open("/dev/ptmx", O_RDWR|O_NONBLOCK)) < 0) { 342 zperror(gettext("failed to obtain a pseudo-tty")); 343 return (-1); 344 } 345 if (tcgetattr(STDIN_FILENO, &save_termios) == -1) { 346 zperror(gettext("failed to get terminal settings from stdin")); 347 return (-1); 348 } 349 (void) ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&winsize); 350 351 return (0); 352 } 353 354 /* 355 * This is a bit tricky; normally a pts device will belong to the zone it 356 * is granted to. But in the case of "entering" a zone, we need to establish 357 * the pty before entering the zone so that we can vector I/O to and from it 358 * from the global zone. 359 * 360 * We use the zonept() call to let the ptm driver know what we are up to; 361 * the only other hairy bit is the setting of zoneslavename (which happens 362 * above, in get_master_pty()). 363 */ 364 static int 365 init_slave_pty(zoneid_t zoneid, char *devroot) 366 { 367 int slavefd = -1; 368 char *slavename, zoneslavename[MAXPATHLEN]; 369 370 /* 371 * Set slave permissions, zone the pts, then unlock it. 372 */ 373 if (grantpt(masterfd) != 0) { 374 zperror(gettext("grantpt failed")); 375 return (-1); 376 } 377 378 if (unlockpt(masterfd) != 0) { 379 zperror(gettext("unlockpt failed")); 380 return (-1); 381 } 382 383 /* 384 * We must open the slave side before zoning this pty; otherwise 385 * the kernel would refuse us the open-- zoning a pty makes it 386 * inaccessible to the global zone. Note we are trying to open 387 * the device node via the $ZONEROOT/dev path for this pty. 388 * 389 * Later we'll close the slave out when once we've opened it again 390 * from within the target zone. Blarg. 391 */ 392 if ((slavename = ptsname(masterfd)) == NULL) { 393 zperror(gettext("failed to get name for pseudo-tty")); 394 return (-1); 395 } 396 397 (void) snprintf(zoneslavename, sizeof (zoneslavename), "%s%s", 398 devroot, slavename); 399 400 if ((slavefd = open(zoneslavename, O_RDWR)) < 0) { 401 zerror(gettext("failed to open %s: %s"), zoneslavename, 402 strerror(errno)); 403 return (-1); 404 } 405 406 /* 407 * Push hardware emulation (ptem), line discipline (ldterm), 408 * and V7/4BSD/Xenix compatibility (ttcompat) modules. 409 */ 410 if (ioctl(slavefd, I_PUSH, "ptem") == -1) { 411 zperror(gettext("failed to push ptem module")); 412 if (!failsafe) 413 goto bad; 414 } 415 416 /* 417 * Anchor the stream to prevent malicious I_POPs; we prefer to do 418 * this prior to entering the zone so that we can detect any errors 419 * early, and so that we can set the anchor from the global zone. 420 */ 421 if (ioctl(slavefd, I_ANCHOR) == -1) { 422 zperror(gettext("failed to set stream anchor")); 423 if (!failsafe) 424 goto bad; 425 } 426 427 if (ioctl(slavefd, I_PUSH, "ldterm") == -1) { 428 zperror(gettext("failed to push ldterm module")); 429 if (!failsafe) 430 goto bad; 431 } 432 if (ioctl(slavefd, I_PUSH, "ttcompat") == -1) { 433 zperror(gettext("failed to push ttcompat module")); 434 if (!failsafe) 435 goto bad; 436 } 437 438 /* 439 * Propagate terminal settings from the external term to the new one. 440 */ 441 if (tcsetattr(slavefd, TCSAFLUSH, &save_termios) == -1) { 442 zperror(gettext("failed to set terminal settings")); 443 if (!failsafe) 444 goto bad; 445 } 446 (void) ioctl(slavefd, TIOCSWINSZ, (char *)&winsize); 447 448 if (zonept(masterfd, zoneid) != 0) { 449 zperror(gettext("could not set zoneid of pty")); 450 goto bad; 451 } 452 453 return (slavefd); 454 455 bad: 456 (void) close(slavefd); 457 return (-1); 458 } 459 460 /* 461 * Place terminal into raw mode. 462 */ 463 static int 464 set_tty_rawmode(int fd) 465 { 466 struct termios term; 467 if (tcgetattr(fd, &term) < 0) { 468 zperror(gettext("failed to get user terminal settings")); 469 return (-1); 470 } 471 472 /* Stash for later, so we can revert back to previous mode */ 473 save_termios = term; 474 save_fd = fd; 475 476 /* disable 8->7 bit strip, start/stop, enable any char to restart */ 477 term.c_iflag &= ~(ISTRIP|IXON|IXANY); 478 /* disable NL->CR, CR->NL, ignore CR, UPPER->lower */ 479 term.c_iflag &= ~(INLCR|ICRNL|IGNCR|IUCLC); 480 /* disable output post-processing */ 481 term.c_oflag &= ~OPOST; 482 /* disable canonical mode, signal chars, echo & extended functions */ 483 term.c_lflag &= ~(ICANON|ISIG|ECHO|IEXTEN); 484 485 term.c_cc[VMIN] = 1; /* byte-at-a-time */ 486 term.c_cc[VTIME] = 0; 487 488 if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term)) { 489 zperror(gettext("failed to set user terminal to raw mode")); 490 return (-1); 491 } 492 493 /* 494 * We need to know the value of VEOF so that we can properly process for 495 * client-side ~<EOF>. But we have obliterated VEOF in term, 496 * because VMIN overloads the same array slot in non-canonical mode. 497 * Stupid @&^%! 498 * 499 * So here we construct the "effective" termios from the current 500 * terminal settings, and the corrected VEOF and VEOL settings. 501 */ 502 if (tcgetattr(STDIN_FILENO, &effective_termios) < 0) { 503 zperror(gettext("failed to get user terminal settings")); 504 return (-1); 505 } 506 effective_termios.c_cc[VEOF] = save_termios.c_cc[VEOF]; 507 effective_termios.c_cc[VEOL] = save_termios.c_cc[VEOL]; 508 509 return (0); 510 } 511 512 /* 513 * Copy terminal window size from our terminal to the pts. 514 */ 515 /*ARGSUSED*/ 516 static void 517 sigwinch(int s) 518 { 519 struct winsize ws; 520 521 if (ioctl(0, TIOCGWINSZ, &ws) == 0) 522 (void) ioctl(masterfd, TIOCSWINSZ, &ws); 523 } 524 525 static volatile int close_on_sig = -1; 526 527 static void 528 /*ARGSUSED*/ 529 sigcld(int s) 530 { 531 int status; 532 pid_t pid; 533 534 /* 535 * Peek at the exit status. If this isn't the process we cared 536 * about, then just reap it. 537 */ 538 if ((pid = waitpid(child_pid, &status, WNOHANG|WNOWAIT)) != -1) { 539 if (pid == child_pid && 540 (WIFEXITED(status) || WIFSIGNALED(status))) { 541 dead = 1; 542 if (close_on_sig != -1) { 543 (void) write(close_on_sig, "a", 1); 544 (void) close(close_on_sig); 545 close_on_sig = -1; 546 } 547 } else { 548 (void) waitpid(pid, &status, WNOHANG); 549 } 550 } 551 } 552 553 /* 554 * Some signals (currently, SIGINT) must be forwarded on to the process 555 * group of the child process. 556 */ 557 static void 558 sig_forward(int s) 559 { 560 if (child_pid != -1) { 561 pid_t pgid = getpgid(child_pid); 562 if (pgid != -1) 563 (void) sigsend(P_PGID, pgid, s); 564 } 565 } 566 567 /* 568 * reset terminal settings for global environment 569 */ 570 static void 571 reset_tty() 572 { 573 (void) tcsetattr(save_fd, TCSADRAIN, &save_termios); 574 } 575 576 /* 577 * Convert character to printable representation, for display with locally 578 * echoed command characters (like when we need to display ~^D) 579 */ 580 static void 581 canonify(char c, char *cc) 582 { 583 if (isprint(c)) { 584 cc[0] = c; 585 cc[1] = '\0'; 586 } else if (c >= 0 && c <= 31) { /* ^@ through ^_ */ 587 cc[0] = '^'; 588 cc[1] = c + '@'; 589 cc[2] = '\0'; 590 } else { 591 cc[0] = '\\'; 592 cc[1] = ((c >> 6) & 7) + '0'; 593 cc[2] = ((c >> 3) & 7) + '0'; 594 cc[3] = (c & 7) + '0'; 595 cc[4] = '\0'; 596 } 597 } 598 599 /* 600 * process_user_input watches the input stream for the escape sequence for 601 * 'quit' (by default, tilde-period). Because we might be fed just one 602 * keystroke at a time, state associated with the user input (are we at the 603 * beginning of the line? are we locally echoing the next character?) is 604 * maintained by beginning_of_line and local_echo across calls to the routine. 605 * If the write to outfd fails, we'll try to read from infd in an attempt 606 * to prevent deadlock between the two processes. 607 * 608 * This routine returns -1 when the 'quit' escape sequence has been issued, 609 * or an error is encountered, 1 if stdin is EOF, and 0 otherwise. 610 */ 611 static int 612 process_user_input(int outfd, int infd) 613 { 614 static boolean_t beginning_of_line = B_TRUE; 615 static boolean_t local_echo = B_FALSE; 616 char ibuf[ZLOGIN_BUFSIZ]; 617 int nbytes; 618 char *buf = ibuf; 619 char c = *buf; 620 621 nbytes = read(STDIN_FILENO, ibuf, ZLOGIN_RDBUFSIZ); 622 if (nbytes == -1 && (errno != EINTR || dead)) 623 return (-1); 624 625 if (nbytes == -1) /* The read was interrupted. */ 626 return (0); 627 628 /* 0 read means EOF, close the pipe to the child */ 629 if (nbytes == 0) 630 return (1); 631 632 for (c = *buf; nbytes > 0; c = *buf, --nbytes) { 633 buf++; 634 if (beginning_of_line && !nocmdchar) { 635 beginning_of_line = B_FALSE; 636 if (c == cmdchar) { 637 local_echo = B_TRUE; 638 continue; 639 } 640 } else if (local_echo) { 641 local_echo = B_FALSE; 642 if (c == '.' || c == effective_termios.c_cc[VEOF]) { 643 char cc[CANONIFY_LEN]; 644 645 canonify(c, cc); 646 (void) write(STDOUT_FILENO, &cmdchar, 1); 647 (void) write(STDOUT_FILENO, cc, strlen(cc)); 648 return (-1); 649 } 650 } 651 retry: 652 if (write(outfd, &c, 1) <= 0) { 653 /* 654 * Since the fd we are writing to is opened with 655 * O_NONBLOCK it is possible to get EAGAIN if the 656 * pipe is full. One way this could happen is if we 657 * are writing a lot of data into the pipe in this loop 658 * and the application on the other end is echoing that 659 * data back out to its stdout. The output pipe can 660 * fill up since we are stuck here in this loop and not 661 * draining the other pipe. We can try to read some of 662 * the data to see if we can drain the pipe so that the 663 * application can continue to make progress. The read 664 * is non-blocking so we won't hang here. We also wait 665 * a bit before retrying since there could be other 666 * reasons why the pipe is full and we don't want to 667 * continuously retry. 668 */ 669 if (errno == EAGAIN) { 670 struct timespec rqtp; 671 int ln; 672 char obuf[ZLOGIN_BUFSIZ]; 673 674 if ((ln = read(infd, obuf, ZLOGIN_BUFSIZ)) > 0) 675 (void) write(STDOUT_FILENO, obuf, ln); 676 677 /* sleep for 10 milliseconds */ 678 rqtp.tv_sec = 0; 679 rqtp.tv_nsec = 10 * (NANOSEC / MILLISEC); 680 (void) nanosleep(&rqtp, NULL); 681 if (!dead) 682 goto retry; 683 } 684 685 return (-1); 686 } 687 beginning_of_line = (c == '\r' || c == '\n' || 688 c == effective_termios.c_cc[VKILL] || 689 c == effective_termios.c_cc[VEOL] || 690 c == effective_termios.c_cc[VSUSP] || 691 c == effective_termios.c_cc[VINTR]); 692 } 693 return (0); 694 } 695 696 /* 697 * This function prevents deadlock between zlogin and the application in the 698 * zone that it is talking to. This can happen when we read from zlogin's 699 * stdin and write the data down the pipe to the application. If the pipe 700 * is full, we'll block in the write. Because zlogin could be blocked in 701 * the write, it would never read the application's stdout/stderr so the 702 * application can then block on those writes (when the pipe fills up). If the 703 * the application gets blocked this way, it can never get around to reading 704 * its stdin so that zlogin can unblock from its write. Once in this state, 705 * the two processes are deadlocked. 706 * 707 * To prevent this, we want to verify that we can write into the pipe before we 708 * read from our stdin. If the pipe already is pretty full, we bypass the read 709 * for now. We'll circle back here again after the poll() so that we can 710 * try again. When this function is called, we already know there is data 711 * ready to read on STDIN_FILENO. We return -1 if there is a problem, 1 if 712 * stdin is EOF, and 0 if everything is ok (even though we might not have 713 * read/written any data into the pipe on this iteration). 714 */ 715 static int 716 process_raw_input(int stdin_fd, int appin_fd) 717 { 718 int cc; 719 struct stat64 sb; 720 char ibuf[ZLOGIN_RDBUFSIZ]; 721 722 /* Check how much data is already in the pipe */ 723 if (fstat64(appin_fd, &sb) == -1) { 724 perror("stat failed"); 725 return (-1); 726 } 727 728 if (dead) 729 return (-1); 730 731 /* 732 * The pipe already has a lot of data in it, don't write any more 733 * right now. 734 */ 735 if (sb.st_size >= HI_WATER) 736 return (0); 737 738 cc = read(STDIN_FILENO, ibuf, ZLOGIN_RDBUFSIZ); 739 if (cc == -1 && (errno != EINTR || dead)) 740 return (-1); 741 742 if (cc == -1) /* The read was interrupted. */ 743 return (0); 744 745 /* 0 read means EOF, close the pipe to the child */ 746 if (cc == 0) 747 return (1); 748 749 /* 750 * stdin_fd is stdin of the target; so, the thing we'll write the user 751 * data *to*. 752 */ 753 if (write(stdin_fd, ibuf, cc) == -1) 754 return (-1); 755 756 return (0); 757 } 758 759 /* 760 * Write the output from the application running in the zone. We can get 761 * a signal during the write (usually it would be SIGCHLD when the application 762 * has exited) so we loop to make sure we have written all of the data we read. 763 */ 764 static int 765 process_output(int in_fd, int out_fd) 766 { 767 int wrote = 0; 768 int cc; 769 char ibuf[ZLOGIN_BUFSIZ]; 770 771 cc = read(in_fd, ibuf, ZLOGIN_BUFSIZ); 772 if (cc == -1 && (errno != EINTR || dead)) 773 return (-1); 774 if (cc == 0) /* EOF */ 775 return (-1); 776 if (cc == -1) /* The read was interrupted. */ 777 return (0); 778 779 do { 780 int len; 781 782 len = write(out_fd, ibuf + wrote, cc - wrote); 783 if (len == -1 && errno != EINTR) 784 return (-1); 785 if (len != -1) 786 wrote += len; 787 } while (wrote < cc); 788 789 return (0); 790 } 791 792 /* 793 * This is the main I/O loop, and is shared across all zlogin modes. 794 * Parameters: 795 * stdin_fd: The fd representing 'stdin' for the slave side; input to 796 * the zone will be written here. 797 * 798 * appin_fd: The fd representing the other end of the 'stdin' pipe (when 799 * we're running non-interactive); used in process_raw_input 800 * to ensure we don't fill up the application's stdin pipe. 801 * 802 * stdout_fd: The fd representing 'stdout' for the slave side; output 803 * from the zone will arrive here. 804 * 805 * stderr_fd: The fd representing 'stderr' for the slave side; output 806 * from the zone will arrive here. 807 * 808 * raw_mode: If TRUE, then no processing (for example, for '~.') will 809 * be performed on the input coming from STDIN. 810 * 811 * stderr_fd may be specified as -1 if there is no stderr (only non-interactive 812 * mode supplies a stderr). 813 * 814 */ 815 static void 816 doio(int stdin_fd, int appin_fd, int stdout_fd, int stderr_fd, int sig_fd, 817 boolean_t raw_mode) 818 { 819 struct pollfd pollfds[4]; 820 char ibuf[ZLOGIN_BUFSIZ]; 821 int cc, ret; 822 823 /* read from stdout of zone and write to stdout of global zone */ 824 pollfds[0].fd = stdout_fd; 825 pollfds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; 826 827 /* read from stderr of zone and write to stderr of global zone */ 828 pollfds[1].fd = stderr_fd; 829 pollfds[1].events = pollfds[0].events; 830 831 /* read from stdin of global zone and write to stdin of zone */ 832 pollfds[2].fd = STDIN_FILENO; 833 pollfds[2].events = pollfds[0].events; 834 835 /* read from signalling pipe so we know when child dies */ 836 pollfds[3].fd = sig_fd; 837 pollfds[3].events = pollfds[0].events; 838 839 for (;;) { 840 pollfds[0].revents = pollfds[1].revents = 841 pollfds[2].revents = pollfds[3].revents = 0; 842 843 if (dead) 844 break; 845 846 /* 847 * There is a race condition here where we can receive the 848 * child death signal, set the dead flag, but since we have 849 * passed the test above, we would go into poll and hang. 850 * To avoid this we use the sig_fd as an additional poll fd. 851 * The signal handler writes into the other end of this pipe 852 * when the child dies so that the poll will always see that 853 * input and proceed. We just loop around at that point and 854 * then notice the dead flag. 855 */ 856 857 ret = poll(pollfds, 858 sizeof (pollfds) / sizeof (struct pollfd), -1); 859 860 if (ret == -1 && errno != EINTR) { 861 perror("poll failed"); 862 break; 863 } 864 865 if (errno == EINTR && dead) { 866 break; 867 } 868 869 /* event from master side stdout */ 870 if (pollfds[0].revents) { 871 if (pollfds[0].revents & 872 (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { 873 if (process_output(stdout_fd, STDOUT_FILENO) 874 != 0) 875 break; 876 } else { 877 pollerr = pollfds[0].revents; 878 break; 879 } 880 } 881 882 /* event from master side stderr */ 883 if (pollfds[1].revents) { 884 if (pollfds[1].revents & 885 (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { 886 if (process_output(stderr_fd, STDERR_FILENO) 887 != 0) 888 break; 889 } else { 890 pollerr = pollfds[1].revents; 891 break; 892 } 893 } 894 895 /* event from user STDIN side */ 896 if (pollfds[2].revents) { 897 if (pollfds[2].revents & 898 (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { 899 /* 900 * stdin fd is stdin of the target; so, 901 * the thing we'll write the user data *to*. 902 * 903 * Also, unlike on the output side, we 904 * close the pipe on a zero-length message. 905 */ 906 int res; 907 908 if (raw_mode) 909 res = process_raw_input(stdin_fd, 910 appin_fd); 911 else 912 res = process_user_input(stdin_fd, 913 stdout_fd); 914 915 if (res < 0) 916 break; 917 if (res > 0) { 918 /* EOF (close) child's stdin_fd */ 919 pollfds[2].fd = -1; 920 while ((res = close(stdin_fd)) != 0 && 921 errno == EINTR) 922 ; 923 if (res != 0) 924 break; 925 } 926 927 } else if (raw_mode && pollfds[2].revents & POLLHUP) { 928 /* 929 * It's OK to get a POLLHUP on STDIN-- it 930 * always happens if you do: 931 * 932 * echo foo | zlogin <zone> <command> 933 * 934 * We reset fd to -1 in this case to clear 935 * the condition and close the pipe (EOF) to 936 * the other side in order to wrap things up. 937 */ 938 int res; 939 940 pollfds[2].fd = -1; 941 while ((res = close(stdin_fd)) != 0 && 942 errno == EINTR) 943 ; 944 if (res != 0) 945 break; 946 } else { 947 pollerr = pollfds[2].revents; 948 break; 949 } 950 } 951 } 952 953 /* 954 * We are in the midst of dying, but try to poll with a short 955 * timeout to see if we can catch the last bit of I/O from the 956 * children. 957 */ 958 retry: 959 pollfds[0].revents = pollfds[1].revents = 0; 960 (void) poll(pollfds, 2, 100); 961 if (pollfds[0].revents & 962 (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { 963 if ((cc = read(stdout_fd, ibuf, ZLOGIN_BUFSIZ)) > 0) { 964 (void) write(STDOUT_FILENO, ibuf, cc); 965 goto retry; 966 } 967 } 968 if (pollfds[1].revents & 969 (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { 970 if ((cc = read(stderr_fd, ibuf, ZLOGIN_BUFSIZ)) > 0) { 971 (void) write(STDERR_FILENO, ibuf, cc); 972 goto retry; 973 } 974 } 975 } 976 977 /* 978 * Fetch the user_cmd brand hook for getting a user's passwd(4) entry. 979 */ 980 static const char * 981 zone_get_user_cmd(brand_handle_t bh, const char *login, char *user_cmd, 982 size_t len) 983 { 984 bzero(user_cmd, sizeof (user_cmd)); 985 if (brand_get_user_cmd(bh, login, user_cmd, len) != 0) 986 return (NULL); 987 988 return (user_cmd); 989 } 990 991 /* From libc */ 992 extern int str2passwd(const char *, int, void *, char *, int); 993 994 /* 995 * exec() the user_cmd brand hook, and convert the output string to a 996 * struct passwd. This is to be called after zone_enter(). 997 * 998 */ 999 static struct passwd * 1000 zone_get_user_pw(const char *user_cmd, struct passwd *pwent, char *pwbuf, 1001 int pwbuflen) 1002 { 1003 char pwline[NSS_BUFLEN_PASSWD]; 1004 char *cin = NULL; 1005 FILE *fin; 1006 int status; 1007 1008 assert(getzoneid() != GLOBAL_ZONEID); 1009 1010 if ((fin = popen(user_cmd, "r")) == NULL) 1011 return (NULL); 1012 1013 while (cin == NULL && !feof(fin)) 1014 cin = fgets(pwline, sizeof (pwline), fin); 1015 1016 if (cin == NULL) { 1017 (void) pclose(fin); 1018 return (NULL); 1019 } 1020 1021 status = pclose(fin); 1022 if (!WIFEXITED(status)) 1023 return (NULL); 1024 if (WEXITSTATUS(status) != 0) 1025 return (NULL); 1026 1027 if (str2passwd(pwline, sizeof (pwline), pwent, pwbuf, pwbuflen) == 0) 1028 return (pwent); 1029 else 1030 return (NULL); 1031 } 1032 1033 static char ** 1034 zone_login_cmd(brand_handle_t bh, const char *login) 1035 { 1036 static char result_buf[ARG_MAX]; 1037 char **new_argv, *ptr, *lasts; 1038 int n, a; 1039 1040 /* Get the login command for the target zone. */ 1041 bzero(result_buf, sizeof (result_buf)); 1042 1043 if (forced_login) { 1044 if (brand_get_forcedlogin_cmd(bh, login, 1045 result_buf, sizeof (result_buf)) != 0) 1046 return (NULL); 1047 } else { 1048 if (brand_get_login_cmd(bh, login, 1049 result_buf, sizeof (result_buf)) != 0) 1050 return (NULL); 1051 } 1052 1053 /* 1054 * We got back a string that we'd like to execute. But since 1055 * we're not doing the execution via a shell we'll need to convert 1056 * the exec string to an array of strings. We'll do that here 1057 * but we're going to be very simplistic about it and break stuff 1058 * up based on spaces. We're not even going to support any kind 1059 * of quoting or escape characters. It's truly amazing that 1060 * there is no library function in OpenSolaris to do this for us. 1061 */ 1062 1063 /* 1064 * Be paranoid. Since we're deliniating based on spaces make 1065 * sure there are no adjacent spaces. 1066 */ 1067 if (strstr(result_buf, " ") != NULL) 1068 return (NULL); 1069 1070 /* Remove any trailing whitespace. */ 1071 n = strlen(result_buf); 1072 if (result_buf[n - 1] == ' ') 1073 result_buf[n - 1] = '\0'; 1074 1075 /* Count how many elements there are in the exec string. */ 1076 ptr = result_buf; 1077 for (n = 2; ((ptr = strchr(ptr + 1, (int)' ')) != NULL); n++) 1078 ; 1079 1080 /* Allocate the argv array that we're going to return. */ 1081 if ((new_argv = malloc(sizeof (char *) * n)) == NULL) 1082 return (NULL); 1083 1084 /* Tokenize the exec string and return. */ 1085 a = 0; 1086 new_argv[a++] = result_buf; 1087 if (n > 2) { 1088 (void) strtok_r(result_buf, " ", &lasts); 1089 while ((new_argv[a++] = strtok_r(NULL, " ", &lasts)) != NULL) 1090 ; 1091 } else { 1092 new_argv[a++] = NULL; 1093 } 1094 assert(n == a); 1095 return (new_argv); 1096 } 1097 1098 /* 1099 * Prepare argv array for exec'd process; if we're passing commands to the 1100 * new process, then use su(1M) to do the invocation. Otherwise, use 1101 * 'login -z <from_zonename> -f' (-z is an undocumented option which tells 1102 * login that we're coming from another zone, and to disregard its CONSOLE 1103 * checks). 1104 */ 1105 static char ** 1106 prep_args(brand_handle_t bh, const char *login, char **argv) 1107 { 1108 int argc = 0, a = 0, i, n = -1; 1109 char **new_argv; 1110 1111 if (argv != NULL) { 1112 size_t subshell_len = 1; 1113 char *subshell; 1114 1115 while (argv[argc] != NULL) 1116 argc++; 1117 1118 for (i = 0; i < argc; i++) { 1119 subshell_len += strlen(argv[i]) + 1; 1120 } 1121 if ((subshell = calloc(1, subshell_len)) == NULL) 1122 return (NULL); 1123 1124 for (i = 0; i < argc; i++) { 1125 (void) strcat(subshell, argv[i]); 1126 (void) strcat(subshell, " "); 1127 } 1128 1129 if (failsafe) { 1130 n = 4; 1131 if ((new_argv = malloc(sizeof (char *) * n)) == NULL) 1132 return (NULL); 1133 1134 new_argv[a++] = FAILSAFESHELL; 1135 } else { 1136 n = 5; 1137 if ((new_argv = malloc(sizeof (char *) * n)) == NULL) 1138 return (NULL); 1139 1140 new_argv[a++] = SUPATH; 1141 if (strcmp(login, "root") != 0) { 1142 new_argv[a++] = "-"; 1143 n++; 1144 } 1145 new_argv[a++] = (char *)login; 1146 } 1147 new_argv[a++] = "-c"; 1148 new_argv[a++] = subshell; 1149 new_argv[a++] = NULL; 1150 assert(a == n); 1151 } else { 1152 if (failsafe) { 1153 n = 2; 1154 if ((new_argv = malloc(sizeof (char *) * n)) == NULL) 1155 return (NULL); 1156 new_argv[a++] = FAILSAFESHELL; 1157 new_argv[a++] = NULL; 1158 assert(n == a); 1159 } else { 1160 new_argv = zone_login_cmd(bh, login); 1161 } 1162 } 1163 1164 return (new_argv); 1165 } 1166 1167 /* 1168 * Helper routine for prep_env below. 1169 */ 1170 static char * 1171 add_env(char *name, char *value) 1172 { 1173 size_t sz = strlen(name) + strlen(value) + 2; /* name, =, value, NUL */ 1174 char *str; 1175 1176 if ((str = malloc(sz)) == NULL) 1177 return (NULL); 1178 1179 (void) snprintf(str, sz, "%s=%s", name, value); 1180 return (str); 1181 } 1182 1183 /* 1184 * Prepare envp array for exec'd process. 1185 */ 1186 static char ** 1187 prep_env() 1188 { 1189 int e = 0, size = 1; 1190 char **new_env, *estr; 1191 char *term = getenv("TERM"); 1192 1193 size++; /* for $PATH */ 1194 if (term != NULL) 1195 size++; 1196 1197 /* 1198 * In failsafe mode we set $HOME, since '-l' isn't valid in this mode. 1199 * We also set $SHELL, since neither login nor su will be around to do 1200 * it. 1201 */ 1202 if (failsafe) 1203 size += 2; 1204 1205 if ((new_env = malloc(sizeof (char *) * size)) == NULL) 1206 return (NULL); 1207 1208 if ((estr = add_env("PATH", DEF_PATH)) == NULL) 1209 return (NULL); 1210 new_env[e++] = estr; 1211 1212 if (term != NULL) { 1213 if ((estr = add_env("TERM", term)) == NULL) 1214 return (NULL); 1215 new_env[e++] = estr; 1216 } 1217 1218 if (failsafe) { 1219 if ((estr = add_env("HOME", "/")) == NULL) 1220 return (NULL); 1221 new_env[e++] = estr; 1222 1223 if ((estr = add_env("SHELL", FAILSAFESHELL)) == NULL) 1224 return (NULL); 1225 new_env[e++] = estr; 1226 } 1227 1228 new_env[e++] = NULL; 1229 1230 assert(e == size); 1231 1232 return (new_env); 1233 } 1234 1235 /* 1236 * Finish the preparation of the envp array for exec'd non-interactive 1237 * zlogins. This is called in the child process *after* we zone_enter(), since 1238 * it derives things we can only know within the zone, such as $HOME, $SHELL, 1239 * etc. We need only do this in the non-interactive, mode, since otherwise 1240 * login(1) will do it. We don't do this in failsafe mode, since it presents 1241 * additional ways in which the command could fail, and we'd prefer to avoid 1242 * that. 1243 */ 1244 static char ** 1245 prep_env_noninteractive(const char *user_cmd, char **env) 1246 { 1247 size_t size; 1248 char **new_env; 1249 int e, i; 1250 char *estr; 1251 char varmail[_LOGNAME_MAX + 11]; /* strlen(/var/mail/) = 10, NUL */ 1252 char pwbuf[NSS_BUFLEN_PASSWD + 1]; 1253 struct passwd pwent; 1254 struct passwd *pw = NULL; 1255 1256 assert(env != NULL); 1257 assert(failsafe == 0); 1258 1259 /* 1260 * Exec the "user_cmd" brand hook to get a pwent for the 1261 * login user. If this fails, HOME will be set to "/", SHELL 1262 * will be set to $DEFAULTSHELL, and we will continue to exec 1263 * SUPATH <login> -c <cmd>. 1264 */ 1265 pw = zone_get_user_pw(user_cmd, &pwent, pwbuf, sizeof (pwbuf)); 1266 1267 /* 1268 * Get existing envp size. 1269 */ 1270 for (size = 0; env[size] != NULL; size++) 1271 ; 1272 1273 e = size; 1274 1275 /* 1276 * Finish filling out the environment; we duplicate the environment 1277 * setup described in login(1), for lack of a better precedent. 1278 */ 1279 if (pw != NULL) 1280 size += 3; /* LOGNAME, HOME, MAIL */ 1281 else 1282 size += 1; /* HOME */ 1283 1284 size++; /* always fill in SHELL */ 1285 size++; /* terminating NULL */ 1286 1287 if ((new_env = malloc(sizeof (char *) * size)) == NULL) 1288 goto malloc_fail; 1289 1290 /* 1291 * Copy existing elements of env into new_env. 1292 */ 1293 for (i = 0; env[i] != NULL; i++) { 1294 if ((new_env[i] = strdup(env[i])) == NULL) 1295 goto malloc_fail; 1296 } 1297 assert(e == i); 1298 1299 if (pw != NULL) { 1300 if ((estr = add_env("LOGNAME", pw->pw_name)) == NULL) 1301 goto malloc_fail; 1302 new_env[e++] = estr; 1303 1304 if ((estr = add_env("HOME", pw->pw_dir)) == NULL) 1305 goto malloc_fail; 1306 new_env[e++] = estr; 1307 1308 if (chdir(pw->pw_dir) != 0) 1309 zerror(gettext("Could not chdir to home directory " 1310 "%s: %s"), pw->pw_dir, strerror(errno)); 1311 1312 (void) snprintf(varmail, sizeof (varmail), "/var/mail/%s", 1313 pw->pw_name); 1314 if ((estr = add_env("MAIL", varmail)) == NULL) 1315 goto malloc_fail; 1316 new_env[e++] = estr; 1317 } else { 1318 if ((estr = add_env("HOME", "/")) == NULL) 1319 goto malloc_fail; 1320 new_env[e++] = estr; 1321 } 1322 1323 if (pw != NULL && strlen(pw->pw_shell) > 0) { 1324 if ((estr = add_env("SHELL", pw->pw_shell)) == NULL) 1325 goto malloc_fail; 1326 new_env[e++] = estr; 1327 } else { 1328 if ((estr = add_env("SHELL", DEFAULTSHELL)) == NULL) 1329 goto malloc_fail; 1330 new_env[e++] = estr; 1331 } 1332 1333 new_env[e++] = NULL; /* add terminating NULL */ 1334 1335 assert(e == size); 1336 return (new_env); 1337 1338 malloc_fail: 1339 zperror(gettext("failed to allocate memory for process environment")); 1340 return (NULL); 1341 } 1342 1343 static int 1344 close_func(void *slavefd, int fd) 1345 { 1346 if (fd != *(int *)slavefd) 1347 (void) close(fd); 1348 return (0); 1349 } 1350 1351 static void 1352 set_cmdchar(char *cmdcharstr) 1353 { 1354 char c; 1355 long lc; 1356 1357 if ((c = *cmdcharstr) != '\\') { 1358 cmdchar = c; 1359 return; 1360 } 1361 1362 c = cmdcharstr[1]; 1363 if (c == '\0' || c == '\\') { 1364 cmdchar = '\\'; 1365 return; 1366 } 1367 1368 if (c < '0' || c > '7') { 1369 zerror(gettext("Unrecognized escape character option %s"), 1370 cmdcharstr); 1371 usage(); 1372 } 1373 1374 lc = strtol(cmdcharstr + 1, NULL, 8); 1375 if (lc < 0 || lc > 255) { 1376 zerror(gettext("Octal escape character '%s' too large"), 1377 cmdcharstr); 1378 usage(); 1379 } 1380 cmdchar = (char)lc; 1381 } 1382 1383 static int 1384 setup_utmpx(char *slavename) 1385 { 1386 struct utmpx ut; 1387 1388 bzero(&ut, sizeof (ut)); 1389 (void) strncpy(ut.ut_user, ".zlogin", sizeof (ut.ut_user)); 1390 (void) strncpy(ut.ut_line, slavename, sizeof (ut.ut_line)); 1391 ut.ut_pid = getpid(); 1392 ut.ut_id[0] = 'z'; 1393 ut.ut_id[1] = ut.ut_id[2] = ut.ut_id[3] = (char)SC_WILDC; 1394 ut.ut_type = LOGIN_PROCESS; 1395 (void) time(&ut.ut_tv.tv_sec); 1396 1397 if (makeutx(&ut) == NULL) { 1398 zerror(gettext("makeutx failed")); 1399 return (-1); 1400 } 1401 return (0); 1402 } 1403 1404 static void 1405 release_lock_file(int lockfd) 1406 { 1407 (void) close(lockfd); 1408 } 1409 1410 static int 1411 grab_lock_file(const char *zone_name, int *lockfd) 1412 { 1413 char pathbuf[PATH_MAX]; 1414 struct flock flock; 1415 1416 if (mkdir(ZONES_TMPDIR, S_IRWXU) < 0 && errno != EEXIST) { 1417 zerror(gettext("could not mkdir %s: %s"), ZONES_TMPDIR, 1418 strerror(errno)); 1419 return (-1); 1420 } 1421 (void) chmod(ZONES_TMPDIR, S_IRWXU); 1422 (void) snprintf(pathbuf, sizeof (pathbuf), "%s/%s.zoneadm.lock", 1423 ZONES_TMPDIR, zone_name); 1424 1425 if ((*lockfd = open(pathbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) { 1426 zerror(gettext("could not open %s: %s"), pathbuf, 1427 strerror(errno)); 1428 return (-1); 1429 } 1430 /* 1431 * Lock the file to synchronize with other zoneadmds 1432 */ 1433 flock.l_type = F_WRLCK; 1434 flock.l_whence = SEEK_SET; 1435 flock.l_start = (off_t)0; 1436 flock.l_len = (off_t)0; 1437 if (fcntl(*lockfd, F_SETLKW, &flock) < 0) { 1438 zerror(gettext("unable to lock %s: %s"), pathbuf, 1439 strerror(errno)); 1440 release_lock_file(*lockfd); 1441 return (-1); 1442 } 1443 return (Z_OK); 1444 } 1445 1446 static int 1447 start_zoneadmd(const char *zone_name) 1448 { 1449 pid_t retval; 1450 int pstatus = 0, error = -1, lockfd, doorfd; 1451 struct door_info info; 1452 char doorpath[MAXPATHLEN]; 1453 1454 (void) snprintf(doorpath, sizeof (doorpath), ZONE_DOOR_PATH, zone_name); 1455 1456 if (grab_lock_file(zone_name, &lockfd) != Z_OK) 1457 return (-1); 1458 /* 1459 * We must do the door check with the lock held. Otherwise, we 1460 * might race against another zoneadm/zlogin process and wind 1461 * up with two processes trying to start zoneadmd at the same 1462 * time. zoneadmd will detect this, and fail, but we prefer this 1463 * to be as seamless as is practical, from a user perspective. 1464 */ 1465 if ((doorfd = open(doorpath, O_RDONLY)) < 0) { 1466 if (errno != ENOENT) { 1467 zerror("failed to open %s: %s", doorpath, 1468 strerror(errno)); 1469 goto out; 1470 } 1471 } else { 1472 /* 1473 * Seems to be working ok. 1474 */ 1475 if (door_info(doorfd, &info) == 0 && 1476 ((info.di_attributes & DOOR_REVOKED) == 0)) { 1477 error = 0; 1478 goto out; 1479 } 1480 } 1481 1482 if ((child_pid = fork()) == -1) { 1483 zperror(gettext("could not fork")); 1484 goto out; 1485 } else if (child_pid == 0) { 1486 /* child process */ 1487 (void) execl("/usr/lib/zones/zoneadmd", "zoneadmd", "-z", 1488 zone_name, NULL); 1489 zperror(gettext("could not exec zoneadmd")); 1490 _exit(1); 1491 } 1492 1493 /* parent process */ 1494 do { 1495 retval = waitpid(child_pid, &pstatus, 0); 1496 } while (retval != child_pid); 1497 if (WIFSIGNALED(pstatus) || 1498 (WIFEXITED(pstatus) && WEXITSTATUS(pstatus) != 0)) { 1499 zerror(gettext("could not start %s"), "zoneadmd"); 1500 goto out; 1501 } 1502 error = 0; 1503 out: 1504 release_lock_file(lockfd); 1505 (void) close(doorfd); 1506 return (error); 1507 } 1508 1509 static int 1510 init_template(void) 1511 { 1512 int fd; 1513 int err = 0; 1514 1515 fd = open64(CTFS_ROOT "/process/template", O_RDWR); 1516 if (fd == -1) 1517 return (-1); 1518 1519 /* 1520 * zlogin doesn't do anything with the contract. 1521 * Deliver no events, don't inherit, and allow it to be orphaned. 1522 */ 1523 err |= ct_tmpl_set_critical(fd, 0); 1524 err |= ct_tmpl_set_informative(fd, 0); 1525 err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR); 1526 err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT); 1527 if (err || ct_tmpl_activate(fd)) { 1528 (void) close(fd); 1529 return (-1); 1530 } 1531 1532 return (fd); 1533 } 1534 1535 static int 1536 noninteractive_login(char *zonename, const char *user_cmd, zoneid_t zoneid, 1537 char **new_args, char **new_env) 1538 { 1539 pid_t retval; 1540 int stdin_pipe[2], stdout_pipe[2], stderr_pipe[2], dead_child_pipe[2]; 1541 int child_status; 1542 int tmpl_fd; 1543 sigset_t block_cld; 1544 1545 if ((tmpl_fd = init_template()) == -1) { 1546 reset_tty(); 1547 zperror(gettext("could not create contract")); 1548 return (1); 1549 } 1550 1551 if (pipe(stdin_pipe) != 0) { 1552 zperror(gettext("could not create STDIN pipe")); 1553 return (1); 1554 } 1555 /* 1556 * When the user types ^D, we get a zero length message on STDIN. 1557 * We need to echo that down the pipe to send it to the other side; 1558 * but by default, pipes don't propagate zero-length messages. We 1559 * toggle that behavior off using I_SWROPT. See streamio(7i). 1560 */ 1561 if (ioctl(stdin_pipe[0], I_SWROPT, SNDZERO) != 0) { 1562 zperror(gettext("could not configure STDIN pipe")); 1563 return (1); 1564 1565 } 1566 if (pipe(stdout_pipe) != 0) { 1567 zperror(gettext("could not create STDOUT pipe")); 1568 return (1); 1569 } 1570 if (pipe(stderr_pipe) != 0) { 1571 zperror(gettext("could not create STDERR pipe")); 1572 return (1); 1573 } 1574 1575 if (pipe(dead_child_pipe) != 0) { 1576 zperror(gettext("could not create signalling pipe")); 1577 return (1); 1578 } 1579 close_on_sig = dead_child_pipe[0]; 1580 1581 /* 1582 * If any of the pipe FD's winds up being less than STDERR, then we 1583 * have a mess on our hands-- and we are lacking some of the I/O 1584 * streams we would expect anyway. So we bail. 1585 */ 1586 if (stdin_pipe[0] <= STDERR_FILENO || 1587 stdin_pipe[1] <= STDERR_FILENO || 1588 stdout_pipe[0] <= STDERR_FILENO || 1589 stdout_pipe[1] <= STDERR_FILENO || 1590 stderr_pipe[0] <= STDERR_FILENO || 1591 stderr_pipe[1] <= STDERR_FILENO || 1592 dead_child_pipe[0] <= STDERR_FILENO || 1593 dead_child_pipe[1] <= STDERR_FILENO) { 1594 zperror(gettext("process lacks valid STDIN, STDOUT, STDERR")); 1595 return (1); 1596 } 1597 1598 if (prefork_dropprivs() != 0) { 1599 zperror(gettext("could not allocate privilege set")); 1600 return (1); 1601 } 1602 1603 (void) sigset(SIGCLD, sigcld); 1604 (void) sigemptyset(&block_cld); 1605 (void) sigaddset(&block_cld, SIGCLD); 1606 (void) sigprocmask(SIG_BLOCK, &block_cld, NULL); 1607 1608 if ((child_pid = fork()) == -1) { 1609 (void) ct_tmpl_clear(tmpl_fd); 1610 (void) close(tmpl_fd); 1611 zperror(gettext("could not fork")); 1612 return (1); 1613 } else if (child_pid == 0) { /* child process */ 1614 (void) ct_tmpl_clear(tmpl_fd); 1615 1616 /* 1617 * Do a dance to get the pipes hooked up as FD's 0, 1 and 2. 1618 */ 1619 (void) close(STDIN_FILENO); 1620 (void) close(STDOUT_FILENO); 1621 (void) close(STDERR_FILENO); 1622 (void) dup2(stdin_pipe[1], STDIN_FILENO); 1623 (void) dup2(stdout_pipe[1], STDOUT_FILENO); 1624 (void) dup2(stderr_pipe[1], STDERR_FILENO); 1625 (void) closefrom(STDERR_FILENO + 1); 1626 1627 (void) sigset(SIGCLD, SIG_DFL); 1628 (void) sigprocmask(SIG_UNBLOCK, &block_cld, NULL); 1629 /* 1630 * In case any of stdin, stdout or stderr are streams, 1631 * anchor them to prevent malicious I_POPs. 1632 */ 1633 (void) ioctl(STDIN_FILENO, I_ANCHOR); 1634 (void) ioctl(STDOUT_FILENO, I_ANCHOR); 1635 (void) ioctl(STDERR_FILENO, I_ANCHOR); 1636 1637 if (zone_enter(zoneid) == -1) { 1638 zerror(gettext("could not enter zone %s: %s"), 1639 zonename, strerror(errno)); 1640 _exit(1); 1641 } 1642 1643 /* 1644 * For non-native zones, tell libc where it can find locale 1645 * specific getttext() messages. 1646 */ 1647 if (access("/.SUNWnative/usr/lib/locale", R_OK) == 0) 1648 (void) bindtextdomain(TEXT_DOMAIN, 1649 "/.SUNWnative/usr/lib/locale"); 1650 else if (access("/native/usr/lib/locale", R_OK) == 0) 1651 (void) bindtextdomain(TEXT_DOMAIN, 1652 "/native/usr/lib/locale"); 1653 1654 if (!failsafe) 1655 new_env = prep_env_noninteractive(user_cmd, new_env); 1656 1657 if (new_env == NULL) { 1658 _exit(1); 1659 } 1660 1661 /* 1662 * Move into a new process group; the zone_enter will have 1663 * placed us into zsched's session, and we want to be in 1664 * a unique process group. 1665 */ 1666 (void) setpgid(getpid(), getpid()); 1667 1668 /* 1669 * The child needs to run as root to 1670 * execute the su program. 1671 */ 1672 if (setuid(0) == -1) { 1673 zperror(gettext("insufficient privilege")); 1674 return (1); 1675 } 1676 1677 (void) execve(new_args[0], new_args, new_env); 1678 zperror(gettext("exec failure")); 1679 _exit(1); 1680 } 1681 /* parent */ 1682 1683 /* close pipe sides written by child */ 1684 (void) close(stdout_pipe[1]); 1685 (void) close(stderr_pipe[1]); 1686 1687 (void) sigset(SIGINT, sig_forward); 1688 1689 postfork_dropprivs(); 1690 1691 (void) ct_tmpl_clear(tmpl_fd); 1692 (void) close(tmpl_fd); 1693 1694 (void) sigprocmask(SIG_UNBLOCK, &block_cld, NULL); 1695 doio(stdin_pipe[0], stdin_pipe[1], stdout_pipe[0], stderr_pipe[0], 1696 dead_child_pipe[1], B_TRUE); 1697 do { 1698 retval = waitpid(child_pid, &child_status, 0); 1699 if (retval == -1) { 1700 child_status = 0; 1701 } 1702 } while (retval != child_pid && errno != ECHILD); 1703 1704 return (WEXITSTATUS(child_status)); 1705 } 1706 1707 static char * 1708 get_username() 1709 { 1710 uid_t uid; 1711 struct passwd *nptr; 1712 1713 /* 1714 * Authorizations are checked to restrict access based on the 1715 * requested operation and zone name, It is assumed that the 1716 * program is running with all privileges, but that the real 1717 * user ID is that of the user or role on whose behalf we are 1718 * operating. So we start by getting the username that will be 1719 * used for subsequent authorization checks. 1720 */ 1721 1722 uid = getuid(); 1723 if ((nptr = getpwuid(uid)) == NULL) { 1724 zerror(gettext("could not get user name.")); 1725 _exit(1); 1726 } 1727 return (nptr->pw_name); 1728 } 1729 1730 int 1731 main(int argc, char **argv) 1732 { 1733 int arg, console = 0; 1734 zoneid_t zoneid; 1735 zone_state_t st; 1736 char *login = "root"; 1737 int lflag = 0; 1738 char *zonename = NULL; 1739 char **proc_args = NULL; 1740 char **new_args, **new_env; 1741 sigset_t block_cld; 1742 char devroot[MAXPATHLEN]; 1743 char *slavename, slaveshortname[MAXPATHLEN]; 1744 priv_set_t *privset; 1745 int tmpl_fd; 1746 char zonebrand[MAXNAMELEN]; 1747 char default_brand[MAXNAMELEN]; 1748 struct stat sb; 1749 char kernzone[ZONENAME_MAX]; 1750 brand_handle_t bh; 1751 char user_cmd[MAXPATHLEN]; 1752 char authname[MAXAUTHS]; 1753 1754 (void) setlocale(LC_ALL, ""); 1755 (void) textdomain(TEXT_DOMAIN); 1756 1757 (void) getpname(argv[0]); 1758 username = get_username(); 1759 1760 while ((arg = getopt(argc, argv, "ECR:Se:l:")) != EOF) { 1761 switch (arg) { 1762 case 'C': 1763 console = 1; 1764 break; 1765 case 'E': 1766 nocmdchar = 1; 1767 break; 1768 case 'R': /* undocumented */ 1769 if (*optarg != '/') { 1770 zerror(gettext("root path must be absolute.")); 1771 exit(2); 1772 } 1773 if (stat(optarg, &sb) == -1 || !S_ISDIR(sb.st_mode)) { 1774 zerror( 1775 gettext("root path must be a directory.")); 1776 exit(2); 1777 } 1778 zonecfg_set_root(optarg); 1779 break; 1780 case 'S': 1781 failsafe = 1; 1782 break; 1783 case 'e': 1784 set_cmdchar(optarg); 1785 break; 1786 case 'l': 1787 login = optarg; 1788 lflag = 1; 1789 break; 1790 default: 1791 usage(); 1792 } 1793 } 1794 1795 if (console != 0 && lflag != 0) { 1796 zerror(gettext("-l may not be specified for console login")); 1797 usage(); 1798 } 1799 1800 if (console != 0 && failsafe != 0) { 1801 zerror(gettext("-S may not be specified for console login")); 1802 usage(); 1803 } 1804 1805 if (console != 0 && zonecfg_in_alt_root()) { 1806 zerror(gettext("-R may not be specified for console login")); 1807 exit(2); 1808 } 1809 1810 if (failsafe != 0 && lflag != 0) { 1811 zerror(gettext("-l may not be specified for failsafe login")); 1812 usage(); 1813 } 1814 1815 if (optind == (argc - 1)) { 1816 /* 1817 * zone name, no process name; this should be an interactive 1818 * as long as STDIN is really a tty. 1819 */ 1820 if (isatty(STDIN_FILENO)) 1821 interactive = 1; 1822 zonename = argv[optind]; 1823 } else if (optind < (argc - 1)) { 1824 if (console) { 1825 zerror(gettext("Commands may not be specified for " 1826 "console login.")); 1827 usage(); 1828 } 1829 /* zone name and process name, and possibly some args */ 1830 zonename = argv[optind]; 1831 proc_args = &argv[optind + 1]; 1832 interactive = 0; 1833 } else { 1834 usage(); 1835 } 1836 1837 if (getzoneid() != GLOBAL_ZONEID) { 1838 zerror(gettext("'%s' may only be used from the global zone"), 1839 pname); 1840 return (1); 1841 } 1842 1843 if (strcmp(zonename, GLOBAL_ZONENAME) == 0) { 1844 zerror(gettext("'%s' not applicable to the global zone"), 1845 pname); 1846 return (1); 1847 } 1848 1849 if (zone_get_state(zonename, &st) != Z_OK) { 1850 zerror(gettext("zone '%s' unknown"), zonename); 1851 return (1); 1852 } 1853 1854 if (st < ZONE_STATE_INSTALLED) { 1855 zerror(gettext("cannot login to a zone which is '%s'"), 1856 zone_state_str(st)); 1857 return (1); 1858 } 1859 1860 /* 1861 * In both console and non-console cases, we require all privs. 1862 * In the console case, because we may need to startup zoneadmd. 1863 * In the non-console case in order to do zone_enter(2), zonept() 1864 * and other tasks. 1865 */ 1866 1867 if ((privset = priv_allocset()) == NULL) { 1868 zperror(gettext("priv_allocset failed")); 1869 return (1); 1870 } 1871 1872 if (getppriv(PRIV_EFFECTIVE, privset) != 0) { 1873 zperror(gettext("getppriv failed")); 1874 priv_freeset(privset); 1875 return (1); 1876 } 1877 1878 if (priv_isfullset(privset) == B_FALSE) { 1879 zerror(gettext("You lack sufficient privilege to run " 1880 "this command (all privs required)")); 1881 priv_freeset(privset); 1882 return (1); 1883 } 1884 priv_freeset(privset); 1885 1886 /* 1887 * Check if user is authorized for requested usage of the zone 1888 */ 1889 1890 (void) snprintf(authname, MAXAUTHS, "%s%s%s", 1891 ZONE_MANAGE_AUTH, KV_OBJECT, zonename); 1892 if (chkauthattr(authname, username) == 0) { 1893 if (console) { 1894 zerror(gettext("%s is not authorized for console " 1895 "access to %s zone."), 1896 username, zonename); 1897 return (1); 1898 } else { 1899 (void) snprintf(authname, MAXAUTHS, "%s%s%s", 1900 ZONE_LOGIN_AUTH, KV_OBJECT, zonename); 1901 if (failsafe || !interactive) { 1902 zerror(gettext("%s is not authorized for " 1903 "failsafe or non-interactive login " 1904 "to %s zone."), username, zonename); 1905 return (1); 1906 } else if (chkauthattr(authname, username) == 0) { 1907 zerror(gettext("%s is not authorized " 1908 " to login to %s zone."), 1909 username, zonename); 1910 return (1); 1911 } 1912 } 1913 } else { 1914 forced_login = B_TRUE; 1915 } 1916 1917 /* 1918 * The console is a separate case from the rest of the code; handle 1919 * it first. 1920 */ 1921 if (console) { 1922 /* 1923 * Ensure that zoneadmd for this zone is running. 1924 */ 1925 if (start_zoneadmd(zonename) == -1) 1926 return (1); 1927 1928 /* 1929 * Make contact with zoneadmd. 1930 */ 1931 if (get_console_master(zonename) == -1) 1932 return (1); 1933 1934 (void) printf(gettext("[Connected to zone '%s' console]\n"), 1935 zonename); 1936 1937 if (set_tty_rawmode(STDIN_FILENO) == -1) { 1938 reset_tty(); 1939 zperror(gettext("failed to set stdin pty to raw mode")); 1940 return (1); 1941 } 1942 1943 (void) sigset(SIGWINCH, sigwinch); 1944 (void) sigwinch(0); 1945 1946 /* 1947 * Run the I/O loop until we get disconnected. 1948 */ 1949 doio(masterfd, -1, masterfd, -1, -1, B_FALSE); 1950 reset_tty(); 1951 (void) printf(gettext("\n[Connection to zone '%s' console " 1952 "closed]\n"), zonename); 1953 1954 return (0); 1955 } 1956 1957 if (st != ZONE_STATE_RUNNING && st != ZONE_STATE_MOUNTED) { 1958 zerror(gettext("login allowed only to running zones " 1959 "(%s is '%s')."), zonename, zone_state_str(st)); 1960 return (1); 1961 } 1962 1963 (void) strlcpy(kernzone, zonename, sizeof (kernzone)); 1964 if (zonecfg_in_alt_root()) { 1965 FILE *fp = zonecfg_open_scratch("", B_FALSE); 1966 1967 if (fp == NULL || zonecfg_find_scratch(fp, zonename, 1968 zonecfg_get_root(), kernzone, sizeof (kernzone)) == -1) { 1969 zerror(gettext("cannot find scratch zone %s"), 1970 zonename); 1971 if (fp != NULL) 1972 zonecfg_close_scratch(fp); 1973 return (1); 1974 } 1975 zonecfg_close_scratch(fp); 1976 } 1977 1978 if ((zoneid = getzoneidbyname(kernzone)) == -1) { 1979 zerror(gettext("failed to get zoneid for zone '%s'"), 1980 zonename); 1981 return (1); 1982 } 1983 1984 /* 1985 * We need the zone root path only if we are setting up a pty. 1986 */ 1987 if (zone_get_devroot(zonename, devroot, sizeof (devroot)) == -1) { 1988 zerror(gettext("could not get dev path for zone %s"), 1989 zonename); 1990 return (1); 1991 } 1992 1993 if (zone_get_brand(zonename, zonebrand, sizeof (zonebrand)) != Z_OK) { 1994 zerror(gettext("could not get brand for zone %s"), zonename); 1995 return (1); 1996 } 1997 /* 1998 * In the alternate root environment, the only supported 1999 * operations are mount and unmount. In this case, just treat 2000 * the zone as native if it is cluster. Cluster zones can be 2001 * native for the purpose of LU or upgrade, and the cluster 2002 * brand may not exist in the miniroot (such as in net install 2003 * upgrade). 2004 */ 2005 if (zonecfg_default_brand(default_brand, 2006 sizeof (default_brand)) != Z_OK) { 2007 zerror(gettext("unable to determine default brand")); 2008 return (1); 2009 } 2010 if (zonecfg_in_alt_root() && 2011 strcmp(zonebrand, CLUSTER_BRAND_NAME) == 0) { 2012 (void) strlcpy(zonebrand, default_brand, sizeof (zonebrand)); 2013 } 2014 2015 if ((bh = brand_open(zonebrand)) == NULL) { 2016 zerror(gettext("could not open brand for zone %s"), zonename); 2017 return (1); 2018 } 2019 2020 if ((new_args = prep_args(bh, login, proc_args)) == NULL) { 2021 zperror(gettext("could not assemble new arguments")); 2022 brand_close(bh); 2023 return (1); 2024 } 2025 /* 2026 * Get the brand specific user_cmd. This command is used to get 2027 * a passwd(4) entry for login. 2028 */ 2029 if (!interactive && !failsafe) { 2030 if (zone_get_user_cmd(bh, login, user_cmd, 2031 sizeof (user_cmd)) == NULL) { 2032 zerror(gettext("could not get user_cmd for zone %s"), 2033 zonename); 2034 brand_close(bh); 2035 return (1); 2036 } 2037 } 2038 brand_close(bh); 2039 2040 if ((new_env = prep_env()) == NULL) { 2041 zperror(gettext("could not assemble new environment")); 2042 return (1); 2043 } 2044 2045 if (!interactive) 2046 return (noninteractive_login(zonename, user_cmd, zoneid, 2047 new_args, new_env)); 2048 2049 if (zonecfg_in_alt_root()) { 2050 zerror(gettext("cannot use interactive login with scratch " 2051 "zone")); 2052 return (1); 2053 } 2054 2055 /* 2056 * Things are more complex in interactive mode; we get the 2057 * master side of the pty, then place the user's terminal into 2058 * raw mode. 2059 */ 2060 if (get_master_pty() == -1) { 2061 zerror(gettext("could not setup master pty device")); 2062 return (1); 2063 } 2064 2065 /* 2066 * Compute the "short name" of the pts. /dev/pts/2 --> pts/2 2067 */ 2068 if ((slavename = ptsname(masterfd)) == NULL) { 2069 zperror(gettext("failed to get name for pseudo-tty")); 2070 return (1); 2071 } 2072 if (strncmp(slavename, "/dev/", strlen("/dev/")) == 0) 2073 (void) strlcpy(slaveshortname, slavename + strlen("/dev/"), 2074 sizeof (slaveshortname)); 2075 else 2076 (void) strlcpy(slaveshortname, slavename, 2077 sizeof (slaveshortname)); 2078 2079 (void) printf(gettext("[Connected to zone '%s' %s]\n"), zonename, 2080 slaveshortname); 2081 2082 if (set_tty_rawmode(STDIN_FILENO) == -1) { 2083 reset_tty(); 2084 zperror(gettext("failed to set stdin pty to raw mode")); 2085 return (1); 2086 } 2087 2088 if (prefork_dropprivs() != 0) { 2089 reset_tty(); 2090 zperror(gettext("could not allocate privilege set")); 2091 return (1); 2092 } 2093 2094 /* 2095 * We must mask SIGCLD until after we have coped with the fork 2096 * sufficiently to deal with it; otherwise we can race and receive the 2097 * signal before child_pid has been initialized (yes, this really 2098 * happens). 2099 */ 2100 (void) sigset(SIGCLD, sigcld); 2101 (void) sigemptyset(&block_cld); 2102 (void) sigaddset(&block_cld, SIGCLD); 2103 (void) sigprocmask(SIG_BLOCK, &block_cld, NULL); 2104 2105 /* 2106 * We activate the contract template at the last minute to 2107 * avoid intermediate functions that could be using fork(2) 2108 * internally. 2109 */ 2110 if ((tmpl_fd = init_template()) == -1) { 2111 reset_tty(); 2112 zperror(gettext("could not create contract")); 2113 return (1); 2114 } 2115 2116 if ((child_pid = fork()) == -1) { 2117 (void) ct_tmpl_clear(tmpl_fd); 2118 reset_tty(); 2119 zperror(gettext("could not fork")); 2120 return (1); 2121 } else if (child_pid == 0) { /* child process */ 2122 int slavefd, newslave; 2123 2124 (void) ct_tmpl_clear(tmpl_fd); 2125 (void) close(tmpl_fd); 2126 2127 (void) sigprocmask(SIG_UNBLOCK, &block_cld, NULL); 2128 2129 if ((slavefd = init_slave_pty(zoneid, devroot)) == -1) 2130 return (1); 2131 2132 /* 2133 * Close all fds except for the slave pty. 2134 */ 2135 (void) fdwalk(close_func, &slavefd); 2136 2137 /* 2138 * Temporarily dup slavefd to stderr; that way if we have 2139 * to print out that zone_enter failed, the output will 2140 * have somewhere to go. 2141 */ 2142 if (slavefd != STDERR_FILENO) 2143 (void) dup2(slavefd, STDERR_FILENO); 2144 2145 if (zone_enter(zoneid) == -1) { 2146 zerror(gettext("could not enter zone %s: %s"), 2147 zonename, strerror(errno)); 2148 return (1); 2149 } 2150 2151 if (slavefd != STDERR_FILENO) 2152 (void) close(STDERR_FILENO); 2153 2154 /* 2155 * We take pains to get this process into a new process 2156 * group, and subsequently a new session. In this way, 2157 * we'll have a session which doesn't yet have a controlling 2158 * terminal. When we open the slave, it will become the 2159 * controlling terminal; no PIDs concerning pgrps or sids 2160 * will leak inappropriately into the zone. 2161 */ 2162 (void) setpgrp(); 2163 2164 /* 2165 * We need the slave pty to be referenced from the zone's 2166 * /dev in order to ensure that the devt's, etc are all 2167 * correct. Otherwise we break ttyname and the like. 2168 */ 2169 if ((newslave = open(slavename, O_RDWR)) == -1) { 2170 (void) close(slavefd); 2171 return (1); 2172 } 2173 (void) close(slavefd); 2174 slavefd = newslave; 2175 2176 /* 2177 * dup the slave to the various FDs, so that when the 2178 * spawned process does a write/read it maps to the slave 2179 * pty. 2180 */ 2181 (void) dup2(slavefd, STDIN_FILENO); 2182 (void) dup2(slavefd, STDOUT_FILENO); 2183 (void) dup2(slavefd, STDERR_FILENO); 2184 if (slavefd != STDIN_FILENO && slavefd != STDOUT_FILENO && 2185 slavefd != STDERR_FILENO) { 2186 (void) close(slavefd); 2187 } 2188 2189 /* 2190 * In failsafe mode, we don't use login(1), so don't try 2191 * setting up a utmpx entry. 2192 */ 2193 if (!failsafe) 2194 if (setup_utmpx(slaveshortname) == -1) 2195 return (1); 2196 2197 /* 2198 * The child needs to run as root to 2199 * execute the brand's login program. 2200 */ 2201 if (setuid(0) == -1) { 2202 zperror(gettext("insufficient privilege")); 2203 return (1); 2204 } 2205 2206 (void) execve(new_args[0], new_args, new_env); 2207 zperror(gettext("exec failure")); 2208 return (1); 2209 } 2210 2211 (void) ct_tmpl_clear(tmpl_fd); 2212 (void) close(tmpl_fd); 2213 2214 /* 2215 * The rest is only for the parent process. 2216 */ 2217 (void) sigset(SIGWINCH, sigwinch); 2218 2219 postfork_dropprivs(); 2220 2221 (void) sigprocmask(SIG_UNBLOCK, &block_cld, NULL); 2222 doio(masterfd, -1, masterfd, -1, -1, B_FALSE); 2223 2224 reset_tty(); 2225 (void) fprintf(stderr, 2226 gettext("\n[Connection to zone '%s' %s closed]\n"), zonename, 2227 slaveshortname); 2228 2229 if (pollerr != 0) { 2230 (void) fprintf(stderr, gettext("Error: connection closed due " 2231 "to unexpected pollevents=0x%x.\n"), pollerr); 2232 return (1); 2233 } 2234 2235 return (0); 2236 }