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