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