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