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