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