xref: /titanic_50/usr/src/cmd/vt/vtdaemon.c (revision ea2722793e684f62dd496ede6243eacea967b82e)
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