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 /* 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * vtdaemon is responsible for the session secure switch via hotkeys. 28 * 29 * vtdaemon itself, like ttymon(8), is also running on a virtual 30 * console device (/dev/vt/1), and provides a text console session 31 * for password input and authentication. The /dev/vt/1 special text 32 * console is reserved and end users cannot switch to it via hotkeys. 33 * 34 * 35 * The hotkey event request can come from either kernel or Xserver, 36 * and a door server is setup to handle the request: 37 * 38 * 1) All text console hotkeys (e.g. "Alt + F#") are intercepted by 39 * the kernel console driver which sends a door upcall to the 40 * vtdaemon via door_upcall (target_vt). 41 * 42 * 2) All Xserver hotkeys ("Alt + Ctrl + F#") are intercepted by 43 * Xserver which sends a door call to the vtdaemon via 44 * door_call (target_vt). 45 * 46 * 47 * server_for_door receives and handles any door server requests: 48 * 49 * Firstly, check source session: 50 * 51 * . If it's from kernel for a text console source session, 52 * then directly go to check the target session. 53 * 54 * . If it's from Xserver for a graphical source session and the vt 55 * associated with the Xserver is currently active: 56 * check if a user has logged in, if true, issue an internal 57 * VT_EV_LOCK event to the main thread to request lock for 58 * the graphical source session; else, directly go to check 59 * the target session. 60 * 61 * . otherwise, discard this request. 62 * 63 * 64 * Secondly, check the target session 65 * 66 * . if the target session is a text one that no one has logged in 67 * or a graphical one, issue an internal VT_EV_ACTIVATE event to 68 * the main thread to request the actual VT switch. 69 * 70 * . otherwise, the target session is a text one that someone has 71 * logged in, issue an internal VT_EV_AUTH event to the main 72 * thread to request authentication for the target session. 73 * 74 * 75 * The main thread of vtdaemon is a loop waiting for internal events 76 * which come from door call threads: 77 * 78 * 1) VT_EV_AUTH to authenticate for target session: 79 * 80 * firstly switch to the vtdaemon special text console; 81 * then prompt for password (target_owner on target_vt), 82 * e.g. "User Bob's password on vt/#: ". 83 * 84 * if the password is correct (authentication succeeds), 85 * then actually issue the VT switch; otherwise, ignore 86 * the request. 87 * 88 * 2) VT_EV_LOCK to lock the graphical source session: 89 * 90 * activate screenlock for this graphical session. 91 * vtdaemon just invokes existing front-end command line 92 * tools (e.g. xscreensaver-command -lock for JDS) to 93 * lock the display. 94 * 95 * 3) VT_EV_ACTIVATE to directly switch to the target session 96 * 97 * 98 * There is a system/vtdaemon:default SMF service for vtdaemon. 99 * 100 * There's a "hotkeys" property (BOOLEAN) in the 101 * system/vtdaemon:default SMF service, which allows authorized 102 * users to dynamically enable or disable VT switch via hotkeys. 103 * Its default value is TRUE (enabled). 104 * 105 * There's a "secure" property (BOOLEAN) in the 106 * system/vtdaemon:default SMF service, which allows authorized 107 * users to dynamically enable or disable hotkeys are secure. 108 * If disabled, the user can freely switch to any session without 109 * authentication. Its default value is TRUE (enabled). 110 * 111 * 112 * By default, there's only 16 virtual console device nodes (from 113 * /dev/vt/0 to /dev/vt/15). There's a property "nodecount" 114 * (default value is 16) in the system/vtdaemon:default SMF 115 * service, so authorized users can configure it to have more 116 * or less virtual console device nodes. 117 * 118 * Xserver needs to switch back to previous active vt via VT_EV_X_EXIT 119 * door event request when it's exiting, so vtdaemon always needs to 120 * be there even if the hotkeys switch is disabled, otherwise the screen 121 * will be just blank when Xserver exits. 122 */ 123 124 #include <sys/param.h> 125 #include <sys/mman.h> 126 #include <sys/types.h> 127 #include <sys/wait.h> 128 #include <sys/stat.h> 129 #include <sys/sysmacros.h> 130 #include <syslog.h> 131 #include <deflt.h> 132 133 #include <bsm/adt.h> 134 #include <bsm/adt_event.h> 135 136 #include <alloca.h> 137 #include <assert.h> 138 #include <errno.h> 139 #include <door.h> 140 #include <fcntl.h> 141 #include <signal.h> 142 #include <stdarg.h> 143 #include <stdio.h> 144 #include <stdlib.h> 145 #include <string.h> 146 #include <strings.h> 147 #include <synch.h> 148 #include <thread.h> 149 #include <unistd.h> 150 #include <wait.h> 151 #include <limits.h> 152 #include <zone.h> 153 #include <priv.h> 154 #include <pwd.h> 155 #include <utmpx.h> 156 #include <procfs.h> 157 #include <poll.h> 158 #include <termio.h> 159 #include <security/pam_appl.h> 160 #include <time.h> 161 #include <sys/console.h> 162 #include <assert.h> 163 #include <syslog.h> 164 165 #include <sys/vt.h> 166 #include <sys/vtdaemon.h> 167 168 /* 169 * The door file /var/run/vt/vtdaemon_door 170 */ 171 #define VT_TMPDIR "/var/run/vt" 172 173 #define VT_DAEMON_ARG 0 174 #define VT_DAEMON_CONSOLE_FILE "/dev/vt/1" 175 176 #define VT_IS_SYSTEM_CONSOLE(vtno) ((vtno) == 1) 177 178 /* Defaults for updating expired passwords */ 179 #define DEF_ATTEMPTS 3 180 181 int daemonfd; 182 183 static boolean_t vt_hotkeys = B_TRUE; /* '-k' option to disable */ 184 static boolean_t vt_secure = B_TRUE; /* '-s' option to disable */ 185 186 static char vt_door_path[MAXPATHLEN]; 187 static int vt_door = -1; 188 189 /* protecting vt_hotkeys_pending and vt_auth_doing */ 190 static mutex_t vt_mutex = DEFAULTMUTEX; 191 192 static boolean_t vt_hotkeys_pending = B_FALSE; 193 static boolean_t vt_auth_doing = B_FALSE; 194 195 static adt_session_data_t **vt_ah_array = NULL; 196 static int vtnodecount = 0; 197 198 static int vt_audit_start(adt_session_data_t **, pid_t); 199 static void vt_audit_event(adt_session_data_t *, au_event_t, int); 200 static void vt_check_source_audit(void); 201 202 static int 203 vt_setup_signal(int signo, int mask) 204 { 205 sigset_t set; 206 207 (void) sigemptyset(&set); 208 (void) sigaddset(&set, signo); 209 210 if (mask) 211 return (sigprocmask(SIG_BLOCK, &set, NULL)); 212 else 213 return (sigprocmask(SIG_UNBLOCK, &set, NULL)); 214 } 215 216 static void 217 do_activate_screenlock(int display_num) 218 { 219 char dpy[16]; 220 221 (void) snprintf(dpy, sizeof (dpy), "%d", display_num); 222 (void) execl("/usr/lib/vtxlock", "vtxlock", dpy, NULL); 223 } 224 225 static void 226 vt_activate_screenlock(int display) 227 { 228 pid_t pid; 229 230 if ((pid = fork()) == -1) 231 return; 232 233 if (pid == 0) { /* child */ 234 do_activate_screenlock(display); 235 exit(0); 236 } 237 238 /* parent */ 239 while (waitpid(pid, (int *)0, 0) != pid) 240 continue; 241 } 242 243 /* 244 * Find the login process and user logged in on the target vt. 245 */ 246 static void 247 vt_read_utx(int target_vt, pid_t *pid, char name[]) 248 { 249 struct utmpx *u; 250 char ttyntail[sizeof (u->ut_line)]; 251 252 *pid = (pid_t)-1; 253 254 if (VT_IS_SYSTEM_CONSOLE(target_vt)) /* system console */ 255 (void) snprintf(ttyntail, sizeof (ttyntail), 256 "%s", "console"); 257 else 258 (void) snprintf(ttyntail, sizeof (ttyntail), 259 "%s%d", "vt/", target_vt); 260 261 setutxent(); 262 while ((u = getutxent()) != NULL) 263 /* see if this is the entry we want */ 264 if ((u->ut_type == USER_PROCESS) && 265 (!nonuserx(*u)) && 266 (u->ut_host[0] == '\0') && 267 (strncmp(u->ut_line, ttyntail, sizeof (u->ut_line)) == 0)) { 268 269 *pid = u->ut_pid; 270 if (name != NULL) { 271 (void) strncpy(name, u->ut_user, 272 sizeof (u->ut_user)); 273 name[sizeof (u->ut_user)] = '\0'; 274 } 275 break; 276 } 277 278 endutxent(); 279 } 280 281 static boolean_t 282 vt_is_tipline(void) 283 { 284 static int is_tipline = 0; 285 int fd; 286 static char termbuf[MAX_TERM_TYPE_LEN]; 287 static struct cons_getterm cons_term = { sizeof (termbuf), termbuf}; 288 289 if (is_tipline != 0) 290 return (is_tipline == 1); 291 292 if ((fd = open("/dev/console", O_RDONLY)) < 0) 293 return (B_FALSE); 294 295 if (ioctl(fd, CONS_GETTERM, &cons_term) != 0 && 296 errno == ENODEV) { 297 is_tipline = 1; 298 } else { 299 is_tipline = -1; 300 } 301 302 (void) close(fd); 303 return (is_tipline == 1); 304 } 305 306 static int 307 validate_target_vt(int target_vt) 308 { 309 int fd; 310 struct vt_stat state; 311 312 if (target_vt < 1) 313 return (-1); 314 315 if ((fd = open(VT_DAEMON_CONSOLE_FILE, O_WRONLY)) < 0) 316 return (-1); 317 318 if (ioctl(fd, VT_GETSTATE, &state) != 0) { 319 (void) close(fd); 320 return (-1); 321 } 322 323 (void) close(fd); 324 325 if (state.v_active == target_vt) { 326 return (1); /* it's current active vt */ 327 } 328 329 if (target_vt == 1) { 330 /* 331 * In tipline case, the system console is always 332 * available, so ignore this request. 333 */ 334 if (vt_is_tipline()) 335 return (-1); 336 337 target_vt = 0; 338 } 339 340 /* 341 * The hotkey request and corresponding target_vt number can come 342 * from either kernel or Xserver (or other user applications). 343 * In kernel we've validated the hotkey request, but Xserver (or 344 * other user applications) cannot do it, so here we still try 345 * to validate it. 346 * 347 * VT_GETSTATE is only valid for first 16 VTs for historical reasons. 348 * Fortunately, in practice, Xserver can only send the hotkey 349 * request of target_vt number from 1 to 12 (Ctrl + Alt + F1 to F2). 350 */ 351 if (target_vt < 8 * sizeof (state.v_state)) { 352 if ((state.v_state & (1 << target_vt)) != 0) { 353 return (0); 354 } else { 355 return (-1); 356 } 357 } 358 359 return (0); 360 } 361 362 static void 363 vt_do_activate(int target_vt) 364 { 365 (void) ioctl(daemonfd, VT_ACTIVATE, target_vt); 366 (void) mutex_lock(&vt_mutex); 367 vt_hotkeys_pending = B_FALSE; 368 (void) mutex_unlock(&vt_mutex); 369 } 370 371 /* events written to fd 0 and read from fd 1 */ 372 #define VT_EV_AUTH 1 373 #define VT_EV_LOCK 2 374 #define VT_EV_ACTIVATE 3 375 376 /* events written to fd 1 and read from fd 0 */ 377 #define VT_EV_TERMINATE_AUTH 4 378 379 typedef struct vt_evt { 380 int ve_cmd; 381 int ve_info; /* vtno or display num */ 382 } vt_evt_t; 383 384 static int eventstream[2]; 385 386 boolean_t 387 eventstream_init(void) 388 { 389 if (pipe(eventstream) == -1) 390 return (B_FALSE); 391 return (B_TRUE); 392 } 393 394 void 395 eventstream_write(int channel, vt_evt_t *pevt) 396 { 397 (void) write(eventstream[channel], pevt, sizeof (vt_evt_t)); 398 } 399 400 static boolean_t 401 eventstream_read(int channel, vt_evt_t *pevt) 402 { 403 ssize_t rval; 404 405 rval = read(eventstream[channel], pevt, sizeof (vt_evt_t)); 406 return (rval > 0); 407 } 408 409 static void 410 vt_ev_request(int cmd, int info) 411 { 412 int channel; 413 vt_evt_t ve; 414 415 ve.ve_cmd = cmd; 416 ve.ve_info = info; 417 418 channel = (cmd == VT_EV_TERMINATE_AUTH) ? 1 : 0; 419 eventstream_write(channel, &ve); 420 } 421 422 static void 423 vt_clear_events(void) 424 { 425 int rval = 0; 426 struct stat buf; 427 vt_evt_t evt; 428 429 while (rval == 0) { 430 rval = fstat(eventstream[0], &buf); 431 if (rval != -1 && buf.st_size > 0) 432 (void) eventstream_read(0, &evt); 433 else 434 break; 435 } 436 } 437 438 static int vt_conv(int, struct pam_message **, 439 struct pam_response **, void *); 440 441 /*ARGSUSED*/ 442 static void 443 catch(int x) 444 { 445 (void) signal(SIGINT, catch); 446 } 447 448 /* 449 * The SIGINT (ctl_c) will restart the authentication, and re-prompt 450 * the end user to input the password. 451 */ 452 static int 453 vt_poll() 454 { 455 struct pollfd pollfds[2]; 456 vt_evt_t ve; 457 int ret; 458 459 pollfds[0].fd = eventstream[0]; 460 pollfds[1].fd = daemonfd; 461 pollfds[0].events = pollfds[1].events = 462 POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; 463 464 for (;;) { 465 pollfds[0].revents = pollfds[1].revents = 0; 466 467 ret = poll(pollfds, 468 sizeof (pollfds) / sizeof (struct pollfd), -1); 469 if (ret == -1 && errno != EINTR) { 470 continue; 471 } 472 473 if (ret == -1 && errno == EINTR) 474 return (-1); 475 476 if (pollfds[0].revents) { 477 (void) eventstream_read(0, &ve); 478 return (0); 479 } 480 481 if (pollfds[1].revents) 482 return (1); 483 484 return (0); 485 486 } 487 } 488 489 static char 490 vt_getchar(int fd) 491 { 492 char c; 493 int cnt; 494 495 cnt = read(fd, &c, 1); 496 if (cnt > 0) { 497 return (c); 498 } 499 500 return (EOF); 501 } 502 503 static char * 504 vt_getinput(int noecho) 505 { 506 int c; 507 int i = 0; 508 struct termio tty; 509 tcflag_t tty_flags; 510 char input[PAM_MAX_RESP_SIZE]; 511 512 if (noecho) { 513 (void) ioctl(daemonfd, TCGETA, &tty); 514 tty_flags = tty.c_lflag; 515 tty.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 516 (void) ioctl(daemonfd, TCSETAF, &tty); 517 } 518 519 while ((vt_poll()) == 1) { 520 if ((c = vt_getchar(daemonfd)) != '\n' && c != '\r' && 521 c != EOF && (i < PAM_MAX_RESP_SIZE - 1)) 522 input[i++] = (char)c; 523 else 524 break; 525 } 526 527 input[i] = '\0'; 528 529 if (noecho) { 530 tty.c_lflag = tty_flags; 531 (void) ioctl(daemonfd, TCSETAW, &tty); 532 (void) fputc('\n', stdout); 533 } 534 535 return (strdup(input)); 536 } 537 538 /* 539 * vt_conv: vtdaemon PAM conversation function. 540 * SIGINT/EINTR is handled in vt_getinput()/vt_poll(). 541 */ 542 543 /*ARGSUSED*/ 544 static int 545 vt_conv(int num_msg, struct pam_message **msg, 546 struct pam_response **response, void *appdata_ptr) 547 { 548 struct pam_message *m; 549 struct pam_response *r; 550 int i, k; 551 552 if (num_msg >= PAM_MAX_NUM_MSG) { 553 syslog(LOG_ERR, "too many messages %d >= %d", 554 num_msg, PAM_MAX_NUM_MSG); 555 *response = NULL; 556 return (PAM_CONV_ERR); 557 } 558 559 *response = calloc(num_msg, sizeof (struct pam_response)); 560 if (*response == NULL) 561 return (PAM_BUF_ERR); 562 563 m = *msg; 564 r = *response; 565 for (i = 0; i < num_msg; i++) { 566 int echo_off = 0; 567 568 /* Bad message */ 569 if (m->msg == NULL) { 570 syslog(LOG_ERR, "message[%d]: %d/NULL\n", 571 i, m->msg_style); 572 goto err; 573 } 574 575 /* 576 * Fix up final newline: 577 * remove from prompts, add back for messages. 578 */ 579 if (m->msg[strlen(m->msg)] == '\n') 580 m->msg[strlen(m->msg)] = '\0'; 581 582 r->resp = NULL; 583 r->resp_retcode = 0; 584 585 switch (m->msg_style) { 586 587 case PAM_PROMPT_ECHO_OFF: 588 echo_off = 1; 589 /* FALLTHROUGH */ 590 591 case PAM_PROMPT_ECHO_ON: 592 (void) fputs(m->msg, stdout); 593 594 r->resp = vt_getinput(echo_off); 595 break; 596 597 case PAM_ERROR_MSG: 598 /* the user may want to see this */ 599 (void) fputs(m->msg, stdout); 600 (void) fputs("\n", stdout); 601 break; 602 603 case PAM_TEXT_INFO: 604 (void) fputs(m->msg, stdout); 605 (void) fputs("\n", stdout); 606 break; 607 608 default: 609 syslog(LOG_ERR, "message[%d]: unknown type" 610 "%d/val=\"%s\"", i, m->msg_style, m->msg); 611 612 /* error, service module won't clean up */ 613 goto err; 614 } 615 616 /* Next message/response */ 617 m++; 618 r++; 619 620 } 621 return (PAM_SUCCESS); 622 623 err: 624 /* 625 * Service modules don't clean up responses if an error is returned. 626 * Free responses here. 627 */ 628 r = *response; 629 for (k = 0; k < i; k++, r++) { 630 if (r->resp) { 631 /* Clear before freeing -- maybe a password */ 632 bzero(r->resp, strlen(r->resp)); 633 free(r->resp); 634 r->resp = NULL; 635 } 636 } 637 638 free(*response); 639 *response = NULL; 640 return (PAM_CONV_ERR); 641 } 642 643 #define DEF_FILE "/etc/default/login" 644 645 /* Get PASSREQ from default file */ 646 static boolean_t 647 vt_default(void) 648 { 649 int flags; 650 char *ptr; 651 boolean_t retval = B_FALSE; 652 653 if ((defopen(DEF_FILE)) == 0) { 654 /* ignore case */ 655 flags = defcntl(DC_GETFLAGS, 0); 656 TURNOFF(flags, DC_CASE); 657 (void) defcntl(DC_SETFLAGS, flags); 658 659 if ((ptr = defread("PASSREQ=")) != NULL && 660 strcasecmp("YES", ptr) == 0) 661 retval = B_TRUE; 662 663 (void) defopen(NULL); 664 } 665 666 return (retval); 667 } 668 669 /* 670 * VT_CLEAR_SCREEN_STR is the console terminal escape sequence used to 671 * clear the current screen. The vt special console (/dev/vt/1) is 672 * just reserved for vtdaemon, and the TERM/termcap of it is always 673 * the local sun-color, which is always supported by our kernel terminal 674 * emulator. 675 */ 676 #define VT_CLEAR_SCREEN_STR "\033[2J\033[1;1H" 677 678 static void 679 vt_do_auth(int target_vt) 680 { 681 char user_name[sizeof (((struct utmpx *)0)->ut_line) + 1] = {'\0'}; 682 pam_handle_t *vt_pamh; 683 int err; 684 int pam_flag = 0; 685 int chpasswd_tries; 686 struct pam_conv pam_conv = {vt_conv, NULL}; 687 pid_t pid; 688 adt_session_data_t *ah; 689 690 vt_read_utx(target_vt, &pid, user_name); 691 692 if (pid == (pid_t)-1 || user_name[0] == '\0') 693 return; 694 695 if ((err = pam_start("vtdaemon", user_name, &pam_conv, 696 &vt_pamh)) != PAM_SUCCESS) 697 return; 698 699 /* 700 * firstly switch to the vtdaemon special console 701 * and clear the current screen 702 */ 703 (void) ioctl(daemonfd, VT_ACTIVATE, VT_DAEMON_ARG); 704 (void) write(daemonfd, VT_CLEAR_SCREEN_STR, 705 strlen(VT_CLEAR_SCREEN_STR)); 706 (void) ioctl(daemonfd, VT_SET_TARGET, target_vt); 707 708 (void) mutex_lock(&vt_mutex); 709 vt_auth_doing = B_TRUE; 710 vt_hotkeys_pending = B_FALSE; 711 (void) mutex_unlock(&vt_mutex); 712 713 /* 714 * Fetch audit handle. 715 */ 716 ah = vt_ah_array[target_vt - 1]; 717 718 if (vt_default()) 719 pam_flag = PAM_DISALLOW_NULL_AUTHTOK; 720 721 do { 722 if (VT_IS_SYSTEM_CONSOLE(target_vt)) 723 (void) fprintf(stdout, 724 "\nUnlock user %s on the system console\n", 725 user_name); 726 else 727 (void) fprintf(stdout, 728 "\nUnlock user %s on vt/%d\n", user_name, 729 target_vt); 730 731 err = pam_authenticate(vt_pamh, pam_flag); 732 733 (void) mutex_lock(&vt_mutex); 734 if (vt_hotkeys_pending) { 735 (void) mutex_unlock(&vt_mutex); 736 break; 737 } 738 (void) mutex_unlock(&vt_mutex); 739 740 if (err == PAM_SUCCESS) { 741 err = pam_acct_mgmt(vt_pamh, pam_flag); 742 743 (void) mutex_lock(&vt_mutex); 744 if (vt_hotkeys_pending) { 745 (void) mutex_unlock(&vt_mutex); 746 break; 747 } 748 (void) mutex_unlock(&vt_mutex); 749 750 if (err == PAM_NEW_AUTHTOK_REQD) { 751 chpasswd_tries = 0; 752 753 do { 754 err = pam_chauthtok(vt_pamh, 755 PAM_CHANGE_EXPIRED_AUTHTOK); 756 chpasswd_tries++; 757 758 (void) mutex_lock(&vt_mutex); 759 if (vt_hotkeys_pending) { 760 (void) mutex_unlock(&vt_mutex); 761 break; 762 } 763 (void) mutex_unlock(&vt_mutex); 764 765 } while ((err == PAM_AUTHTOK_ERR || 766 err == PAM_TRY_AGAIN) && 767 chpasswd_tries < DEF_ATTEMPTS); 768 769 (void) mutex_lock(&vt_mutex); 770 if (vt_hotkeys_pending) { 771 (void) mutex_unlock(&vt_mutex); 772 break; 773 } 774 (void) mutex_unlock(&vt_mutex); 775 776 vt_audit_event(ah, ADT_passwd, err); 777 } 778 } 779 780 /* 781 * Only audit failed unlock here, successful unlock 782 * will be audited after switching to target vt. 783 */ 784 if (err != PAM_SUCCESS) { 785 (void) fprintf(stdout, "%s", 786 pam_strerror(vt_pamh, err)); 787 788 vt_audit_event(ah, ADT_screenunlock, err); 789 } 790 791 (void) mutex_lock(&vt_mutex); 792 if (vt_hotkeys_pending) { 793 (void) mutex_unlock(&vt_mutex); 794 break; 795 } 796 (void) mutex_unlock(&vt_mutex); 797 798 } while (err != PAM_SUCCESS); 799 800 (void) mutex_lock(&vt_mutex); 801 if (!vt_hotkeys_pending) { 802 /* 803 * Should be PAM_SUCCESS to reach here. 804 */ 805 (void) ioctl(daemonfd, VT_ACTIVATE, target_vt); 806 807 vt_audit_event(ah, ADT_screenunlock, err); 808 809 /* 810 * Free audit handle. 811 */ 812 (void) adt_end_session(ah); 813 vt_ah_array[target_vt - 1] = NULL; 814 } 815 (void) mutex_unlock(&vt_mutex); 816 817 (void) pam_end(vt_pamh, err); 818 819 (void) mutex_lock(&vt_mutex); 820 vt_auth_doing = B_FALSE; 821 vt_clear_events(); 822 (void) mutex_unlock(&vt_mutex); 823 } 824 825 /* main thread (lock and auth) */ 826 static void __NORETURN 827 vt_serve_events(void) 828 { 829 struct pollfd pollfds[1]; 830 int ret; 831 vt_evt_t ve; 832 833 pollfds[0].fd = eventstream[1]; 834 pollfds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; 835 836 for (;;) { 837 pollfds[0].revents = 0; 838 ret = poll(pollfds, 839 sizeof (pollfds) / sizeof (struct pollfd), -1); 840 if (ret == -1 && errno == EINTR) { 841 continue; 842 } 843 844 if (pollfds[0].revents && eventstream_read(1, &ve)) { 845 /* new request */ 846 switch (ve.ve_cmd) { 847 case VT_EV_AUTH: 848 vt_do_auth(ve.ve_info); 849 break; 850 851 case VT_EV_LOCK: 852 vt_activate_screenlock(ve.ve_info); 853 break; 854 855 case VT_EV_ACTIVATE: 856 /* directly activate target vt */ 857 vt_do_activate(ve.ve_info); 858 break; 859 } 860 } 861 } 862 } 863 864 static void 865 vt_check_target_session(uint32_t target_vt) 866 { 867 pid_t pid = (pid_t)-1; 868 869 if (!vt_secure) { 870 vt_ev_request(VT_EV_ACTIVATE, target_vt); 871 return; 872 } 873 874 /* check the target session */ 875 vt_read_utx(target_vt, &pid, NULL); 876 if (pid == (pid_t)-1) { 877 vt_ev_request(VT_EV_ACTIVATE, target_vt); 878 return; 879 } 880 881 vt_ev_request(VT_EV_AUTH, target_vt); 882 } 883 884 static boolean_t 885 vt_get_active_disp_info(struct vt_dispinfo *vd) 886 { 887 int fd; 888 struct vt_stat state; 889 char vtname[16]; 890 891 if ((fd = open(VT_DAEMON_CONSOLE_FILE, O_RDONLY)) < 0) 892 return (B_FALSE); 893 894 if (ioctl(fd, VT_GETSTATE, &state) != 0) { 895 (void) close(fd); 896 return (B_FALSE); 897 } 898 (void) close(fd); 899 900 (void) snprintf(vtname, sizeof (vtname), "/dev/vt/%d", state.v_active); 901 if ((fd = open(vtname, O_RDONLY)) < 0) 902 return (B_FALSE); 903 904 if (ioctl(fd, VT_GETDISPINFO, vd) != 0) { 905 (void) close(fd); 906 return (B_FALSE); 907 } 908 909 (void) close(fd); 910 return (B_TRUE); 911 } 912 913 /* 914 * Xserver registers its pid into kernel to associate it with 915 * its vt upon startup for each graphical display. So here we can 916 * check if the pid is of the Xserver for the current active 917 * display when we receive a special VT_EV_X_EXIT request from 918 * a process. If the request does not come from the current 919 * active Xserver, it is discarded. 920 */ 921 static boolean_t 922 vt_check_disp_active(pid_t x_pid) 923 { 924 struct vt_dispinfo vd; 925 926 if (vt_get_active_disp_info(&vd) && 927 vd.v_pid == x_pid) 928 return (B_TRUE); 929 930 return (B_FALSE); 931 } 932 933 /* 934 * check if the pid is of the Xserver for the current active display, 935 * return true when it is, and then also return other associated 936 * information with the Xserver. 937 */ 938 static boolean_t 939 vt_get_disp_info(pid_t x_pid, int *logged_in, int *display_num) 940 { 941 struct vt_dispinfo vd; 942 943 if (!vt_get_active_disp_info(&vd) || 944 vd.v_pid != x_pid) 945 return (B_FALSE); 946 947 *logged_in = vd.v_login; 948 *display_num = vd.v_dispnum; 949 return (B_TRUE); 950 } 951 952 static void 953 vt_terminate_auth(void) 954 { 955 struct timespec sleeptime; 956 957 sleeptime.tv_sec = 0; 958 sleeptime.tv_nsec = 1000000; /* 1ms */ 959 960 (void) mutex_lock(&vt_mutex); 961 while (vt_auth_doing) { 962 vt_ev_request(VT_EV_TERMINATE_AUTH, 0); 963 964 if (vt_auth_doing) { 965 (void) mutex_unlock(&vt_mutex); 966 (void) nanosleep(&sleeptime, NULL); 967 sleeptime.tv_nsec *= 2; 968 (void) mutex_lock(&vt_mutex); 969 } 970 } 971 (void) mutex_unlock(&vt_mutex); 972 } 973 974 static void 975 vt_do_hotkeys(pid_t pid, uint32_t target_vt) 976 { 977 int logged_in; 978 int display_num; 979 980 if (validate_target_vt(target_vt) != 0) 981 return; 982 983 /* 984 * Maybe last switch action is being taken and the lock is ongoing, 985 * here we must reject the newly request. 986 */ 987 (void) mutex_lock(&vt_mutex); 988 if (vt_hotkeys_pending) { 989 (void) mutex_unlock(&vt_mutex); 990 return; 991 } 992 993 /* cleared in vt_do_active and vt_do_auth */ 994 vt_hotkeys_pending = B_TRUE; 995 (void) mutex_unlock(&vt_mutex); 996 997 vt_terminate_auth(); 998 999 /* check source session for this hotkeys request */ 1000 if (pid == 0) { 1001 /* ok, it comes from kernel. */ 1002 if (vt_secure) 1003 vt_check_source_audit(); 1004 1005 /* then only need to check target session */ 1006 vt_check_target_session(target_vt); 1007 return; 1008 } 1009 1010 /* 1011 * check if it comes from current active X graphical session, 1012 * if not, ignore this request. 1013 */ 1014 if (!vt_get_disp_info(pid, &logged_in, &display_num)) { 1015 (void) mutex_lock(&vt_mutex); 1016 vt_hotkeys_pending = B_FALSE; 1017 (void) mutex_unlock(&vt_mutex); 1018 return; 1019 } 1020 1021 if (logged_in && vt_secure) 1022 vt_ev_request(VT_EV_LOCK, display_num); 1023 1024 vt_check_target_session(target_vt); 1025 } 1026 1027 /* 1028 * The main routine for the door server that deals with secure hotkeys 1029 */ 1030 /* ARGSUSED */ 1031 static void 1032 server_for_door(void *cookie, char *args, size_t alen, door_desc_t *dp, 1033 uint_t n_desc) 1034 { 1035 ucred_t *uc = NULL; 1036 vt_cmd_arg_t *vtargp; 1037 1038 /* LINTED E_BAD_PTR_CAST_ALIGN */ 1039 vtargp = (vt_cmd_arg_t *)args; 1040 1041 if (vtargp == NULL || 1042 alen != sizeof (vt_cmd_arg_t) || 1043 door_ucred(&uc) != 0) { 1044 (void) door_return(NULL, 0, NULL, 0); 1045 return; 1046 } 1047 1048 switch (vtargp->vt_ev) { 1049 case VT_EV_X_EXIT: 1050 /* 1051 * Xserver will issue this event requesting to switch back 1052 * to previous active vt when it's exiting and the associated 1053 * vt is currently active. 1054 */ 1055 if (vt_check_disp_active(ucred_getpid(uc))) 1056 vt_do_hotkeys(0, vtargp->vt_num); 1057 break; 1058 1059 case VT_EV_HOTKEYS: 1060 if (!vt_hotkeys) /* hotkeys are disabled? */ 1061 break; 1062 1063 vt_do_hotkeys(ucred_getpid(uc), vtargp->vt_num); 1064 break; 1065 1066 default: 1067 break; 1068 } 1069 1070 ucred_free(uc); 1071 (void) door_return(NULL, 0, NULL, 0); 1072 } 1073 1074 static boolean_t 1075 setup_door(void) 1076 { 1077 if ((vt_door = door_create(server_for_door, NULL, 1078 DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) < 0) { 1079 syslog(LOG_ERR, "door_create failed: %s", strerror(errno)); 1080 return (B_FALSE); 1081 } 1082 1083 (void) fdetach(vt_door_path); 1084 1085 if (fattach(vt_door, vt_door_path) != 0) { 1086 syslog(LOG_ERR, "fattach to %s failed: %s", 1087 vt_door_path, strerror(errno)); 1088 (void) door_revoke(vt_door); 1089 (void) fdetach(vt_door_path); 1090 vt_door = -1; 1091 return (B_FALSE); 1092 } 1093 1094 return (B_TRUE); 1095 } 1096 1097 /* 1098 * check to see if vtdaemon is already running. 1099 * 1100 * The idea here is that we want to open the path to which we will 1101 * attach our door, lock it, and then make sure that no-one has beat us 1102 * to fattach(3c)ing onto it. 1103 * 1104 * fattach(3c) is really a mount, so there are actually two possible 1105 * vnodes we could be dealing with. Our strategy is as follows: 1106 * 1107 * - If the file we opened is a regular file (common case): 1108 * There is no fattach(3c)ed door, so we have a chance of becoming 1109 * the running vtdaemon. We attempt to lock the file: if it is 1110 * already locked, that means someone else raced us here, so we 1111 * lose and give up. 1112 * 1113 * - If the file we opened is a namefs file: 1114 * This means there is already an established door fattach(3c)'ed 1115 * to the rendezvous path. We've lost the race, so we give up. 1116 * Note that in this case we also try to grab the file lock, and 1117 * will succeed in acquiring it since the vnode locked by the 1118 * "winning" vtdaemon was a regular one, and the one we locked was 1119 * the fattach(3c)'ed door node. At any rate, no harm is done. 1120 */ 1121 static boolean_t 1122 make_daemon_exclusive(void) 1123 { 1124 int doorfd = -1; 1125 boolean_t ret = B_FALSE; 1126 struct stat st; 1127 struct flock flock; 1128 1129 top: 1130 if ((doorfd = open(vt_door_path, O_CREAT|O_RDWR, 1131 S_IREAD|S_IWRITE|S_IRGRP|S_IROTH)) < 0) { 1132 syslog(LOG_ERR, "failed to open %s", vt_door_path); 1133 goto out; 1134 } 1135 if (fstat(doorfd, &st) < 0) { 1136 syslog(LOG_ERR, "failed to stat %s", vt_door_path); 1137 goto out; 1138 } 1139 /* 1140 * Lock the file to synchronize 1141 */ 1142 flock.l_type = F_WRLCK; 1143 flock.l_whence = SEEK_SET; 1144 flock.l_start = (off_t)0; 1145 flock.l_len = (off_t)0; 1146 if (fcntl(doorfd, F_SETLK, &flock) < 0) { 1147 /* 1148 * Someone else raced us here and grabbed the lock file 1149 * first. A warning here and exit. 1150 */ 1151 syslog(LOG_ERR, "vtdaemon is already running!"); 1152 goto out; 1153 } 1154 1155 if (strcmp(st.st_fstype, "namefs") == 0) { 1156 struct door_info info; 1157 1158 /* 1159 * There is already something fattach()'ed to this file. 1160 * Lets see what the door is up to. 1161 */ 1162 if (door_info(doorfd, &info) == 0 && info.di_target != -1) { 1163 syslog(LOG_ERR, "vtdaemon is already running!"); 1164 goto out; 1165 } 1166 1167 (void) fdetach(vt_door_path); 1168 (void) close(doorfd); 1169 goto top; 1170 } 1171 1172 ret = setup_door(); 1173 1174 out: 1175 (void) close(doorfd); 1176 return (ret); 1177 } 1178 1179 static boolean_t 1180 mkvtdir(void) 1181 { 1182 struct stat st; 1183 /* 1184 * We must create and lock everyone but root out of VT_TMPDIR 1185 * since anyone can open any UNIX domain socket, regardless of 1186 * its file system permissions. 1187 */ 1188 if (mkdir(VT_TMPDIR, S_IRWXU|S_IROTH|S_IXOTH|S_IRGRP|S_IXGRP) < 0 && 1189 errno != EEXIST) { 1190 syslog(LOG_ERR, "could not mkdir '%s'", VT_TMPDIR); 1191 return (B_FALSE); 1192 } 1193 /* paranoia */ 1194 if ((stat(VT_TMPDIR, &st) < 0) || !S_ISDIR(st.st_mode)) { 1195 syslog(LOG_ERR, "'%s' is not a directory", VT_TMPDIR); 1196 return (B_FALSE); 1197 } 1198 (void) chmod(VT_TMPDIR, S_IRWXU|S_IROTH|S_IXOTH|S_IRGRP|S_IXGRP); 1199 return (B_TRUE); 1200 } 1201 1202 int 1203 main(int argc, char *argv[]) 1204 { 1205 int i; 1206 int opt; 1207 priv_set_t *privset; 1208 int active; 1209 1210 openlog("vtdaemon", LOG_PID | LOG_CONS, 0); 1211 1212 /* 1213 * Check that we have all privileges. It would be nice to pare 1214 * this down, but this is at least a first cut. 1215 */ 1216 if ((privset = priv_allocset()) == NULL) { 1217 syslog(LOG_ERR, "priv_allocset failed"); 1218 return (1); 1219 } 1220 1221 if (getppriv(PRIV_EFFECTIVE, privset) != 0) { 1222 syslog(LOG_ERR, "getppriv failed", "getppriv"); 1223 priv_freeset(privset); 1224 return (1); 1225 } 1226 1227 if (priv_isfullset(privset) == B_FALSE) { 1228 syslog(LOG_ERR, "You lack sufficient privilege " 1229 "to run this command (all privs required)"); 1230 priv_freeset(privset); 1231 return (1); 1232 } 1233 priv_freeset(privset); 1234 1235 while ((opt = getopt(argc, argv, "ksrc:")) != EOF) { 1236 switch (opt) { 1237 case 'k': 1238 vt_hotkeys = B_FALSE; 1239 break; 1240 case 's': 1241 vt_secure = B_FALSE; 1242 break; 1243 case 'c': 1244 vtnodecount = atoi(optarg); 1245 break; 1246 default: 1247 break; 1248 } 1249 } 1250 1251 (void) vt_setup_signal(SIGINT, 1); 1252 1253 if (!mkvtdir()) 1254 return (1); 1255 1256 if (!eventstream_init()) 1257 return (1); 1258 1259 (void) snprintf(vt_door_path, sizeof (vt_door_path), 1260 VT_TMPDIR "/vtdaemon_door"); 1261 1262 if (!make_daemon_exclusive()) 1263 return (1); 1264 1265 /* only the main thread accepts SIGINT */ 1266 (void) vt_setup_signal(SIGINT, 0); 1267 (void) sigset(SIGPIPE, SIG_IGN); 1268 (void) signal(SIGQUIT, SIG_IGN); 1269 (void) signal(SIGINT, catch); 1270 1271 for (i = 0; i < 3; i++) 1272 (void) close(i); 1273 (void) setsid(); 1274 1275 if ((daemonfd = open(VT_DAEMON_CONSOLE_FILE, O_RDWR)) < 0) { 1276 return (1); 1277 } 1278 1279 if (daemonfd != 0) 1280 (void) dup2(daemonfd, STDIN_FILENO); 1281 if (daemonfd != 1) 1282 (void) dup2(daemonfd, STDOUT_FILENO); 1283 1284 if (vtnodecount >= 2) 1285 (void) ioctl(daemonfd, VT_CONFIG, vtnodecount); 1286 1287 if ((vt_ah_array = calloc(vtnodecount - 1, 1288 sizeof (adt_session_data_t *))) == NULL) 1289 return (1); 1290 1291 (void) ioctl(daemonfd, VT_GETACTIVE, &active); 1292 1293 if (active == 1) { 1294 /* 1295 * This is for someone who restarts vtdaemon while vtdaemon 1296 * is doing authentication on /dev/vt/1. 1297 * A better way is to continue the authentication, but there 1298 * are chances that the status of the target VT has changed. 1299 * So we just clear the screen here. 1300 */ 1301 (void) write(daemonfd, VT_CLEAR_SCREEN_STR, 1302 strlen(VT_CLEAR_SCREEN_STR)); 1303 } 1304 1305 vt_serve_events(); 1306 /*NOTREACHED*/ 1307 } 1308 1309 static int 1310 vt_audit_start(adt_session_data_t **ah, pid_t pid) 1311 { 1312 ucred_t *uc; 1313 1314 if (adt_start_session(ah, NULL, 0)) 1315 return (-1); 1316 1317 if ((uc = ucred_get(pid)) == NULL) { 1318 (void) adt_end_session(*ah); 1319 return (-1); 1320 } 1321 1322 if (adt_set_from_ucred(*ah, uc, ADT_NEW)) { 1323 ucred_free(uc); 1324 (void) adt_end_session(*ah); 1325 return (-1); 1326 } 1327 1328 ucred_free(uc); 1329 return (0); 1330 } 1331 1332 /* 1333 * Write audit event 1334 */ 1335 static void 1336 vt_audit_event(adt_session_data_t *ah, au_event_t event_id, int status) 1337 { 1338 adt_event_data_t *event; 1339 1340 1341 if ((event = adt_alloc_event(ah, event_id)) == NULL) { 1342 return; 1343 } 1344 1345 (void) adt_put_event(event, 1346 status == PAM_SUCCESS ? ADT_SUCCESS : ADT_FAILURE, 1347 status == PAM_SUCCESS ? ADT_SUCCESS : ADT_FAIL_PAM + status); 1348 1349 adt_free_event(event); 1350 } 1351 1352 static void 1353 vt_check_source_audit(void) 1354 { 1355 int fd; 1356 int source_vt; 1357 int real_vt; 1358 struct vt_stat state; 1359 pid_t pid; 1360 adt_session_data_t *ah; 1361 1362 if ((fd = open(VT_DAEMON_CONSOLE_FILE, O_WRONLY)) < 0) 1363 return; 1364 1365 if (ioctl(fd, VT_GETSTATE, &state) != 0 || 1366 ioctl(fd, VT_GETACTIVE, &real_vt) != 0) { 1367 (void) close(fd); 1368 return; 1369 } 1370 1371 source_vt = state.v_active; /* 1..n */ 1372 (void) close(fd); 1373 1374 /* check if it's already locked */ 1375 if (real_vt == 1) /* vtdaemon is taking over the screen */ 1376 return; 1377 1378 vt_read_utx(source_vt, &pid, NULL); 1379 if (pid == (pid_t)-1) 1380 return; 1381 1382 if (vt_audit_start(&ah, pid) != 0) { 1383 syslog(LOG_ERR, "audit start failed "); 1384 return; 1385 } 1386 1387 /* 1388 * In case the previous session terminated abnormally. 1389 */ 1390 if (vt_ah_array[source_vt - 1] != NULL) 1391 (void) adt_end_session(vt_ah_array[source_vt - 1]); 1392 1393 vt_ah_array[source_vt - 1] = ah; 1394 1395 vt_audit_event(ah, ADT_screenlock, PAM_SUCCESS); 1396 } 1397