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