source: MondoRescue/branches/3.3/mindi-busybox/loginutils/vlock.c@ 3803

Last change on this file since 3803 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 3.4 KB
RevLine 
[821]1/* vi: set sw=4 ts=4: */
2/*
3 * vlock implementation for busybox
4 *
5 * Copyright (C) 2000 by spoon <spoon@ix.netcom.com>
6 * Written by spoon <spon@ix.netcom.com>
7 *
[2725]8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
[821]9 */
10
11/* Shoutz to Michael K. Johnson <johnsonm@redhat.com>, author of the
12 * original vlock. I snagged a bunch of his code to write this
13 * minimalistic vlock.
14 */
15/* Fixed by Erik Andersen to do passwords the tinylogin way...
[3621]16 * It now works with md5, sha1, etc passwords.
17 */
18//config:config VLOCK
19//config: bool "vlock"
20//config: default y
21//config: help
22//config: Build the "vlock" applet which allows you to lock (virtual) terminals.
23//config:
24//config: Note that Busybox binary must be setuid root for this applet to
25//config: work properly.
[821]26
[3621]27//applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */
28//applet:IF_VLOCK(APPLET(vlock, BB_DIR_USR_BIN, BB_SUID_REQUIRE))
29
30//kbuild:lib-$(CONFIG_VLOCK) += vlock.o
31
[3232]32//usage:#define vlock_trivial_usage
33//usage: "[-a]"
34//usage:#define vlock_full_usage "\n\n"
35//usage: "Lock a virtual terminal. A password is required to unlock.\n"
36//usage: "\n -a Lock all VTs"
37
[1765]38#include "libbb.h"
[2725]39
40#ifdef __linux__
[821]41#include <sys/vt.h>
42
[2725]43static void release_vt(int signo UNUSED_PARAM)
[821]44{
[2725]45 /* If -a, param is 0, which means:
46 * "no, kernel, we don't allow console switch away from us!" */
47 ioctl(STDIN_FILENO, VT_RELDISP, (unsigned long) !option_mask32);
[821]48}
49
[2725]50static void acquire_vt(int signo UNUSED_PARAM)
[821]51{
[2725]52 /* ACK to kernel that switch to console is successful */
53 ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ);
[821]54}
[2725]55#endif
[821]56
[2725]57int vlock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
58int vlock_main(int argc UNUSED_PARAM, char **argv)
[821]59{
[2725]60#ifdef __linux__
[821]61 struct vt_mode vtm;
[2725]62 struct vt_mode ovtm;
63#endif
[821]64 struct termios term;
[2725]65 struct termios oterm;
66 struct passwd *pw;
[821]67
[2725]68 pw = xgetpwuid(getuid());
69 opt_complementary = "=0"; /* no params! */
70 getopt32(argv, "a");
[1765]71
[2725]72 /* Ignore some signals so that we don't get killed by them */
73 bb_signals(0
74 + (1 << SIGTSTP)
75 + (1 << SIGTTIN)
76 + (1 << SIGTTOU)
77 + (1 << SIGHUP )
78 + (1 << SIGCHLD) /* paranoia :) */
79 + (1 << SIGQUIT)
80 + (1 << SIGINT )
81 , SIG_IGN);
[821]82
[2725]83#ifdef __linux__
84 /* We will use SIGUSRx for console switch control: */
85 /* 1: set handlers */
86 signal_SA_RESTART_empty_mask(SIGUSR1, release_vt);
87 signal_SA_RESTART_empty_mask(SIGUSR2, acquire_vt);
88 /* 2: unmask them */
89 sig_unblock(SIGUSR1);
90 sig_unblock(SIGUSR2);
91#endif
[821]92
[2725]93 /* Revert stdin/out to our controlling tty
94 * (or die if we have none) */
95 xmove_fd(xopen(CURRENT_TTY, O_RDWR), STDIN_FILENO);
96 xdup2(STDIN_FILENO, STDOUT_FILENO);
[821]97
[2725]98#ifdef __linux__
99 xioctl(STDIN_FILENO, VT_GETMODE, &vtm);
[821]100 ovtm = vtm;
[2725]101 /* "console switches are controlled by us, not kernel!" */
[821]102 vtm.mode = VT_PROCESS;
103 vtm.relsig = SIGUSR1;
104 vtm.acqsig = SIGUSR2;
[2725]105 ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
106#endif
[821]107
108 tcgetattr(STDIN_FILENO, &oterm);
109 term = oterm;
110 term.c_iflag &= ~BRKINT;
111 term.c_iflag |= IGNBRK;
112 term.c_lflag &= ~ISIG;
113 term.c_lflag &= ~(ECHO | ECHOCTL);
[2725]114 tcsetattr_stdin_TCSANOW(&term);
[821]115
[3232]116 while (1) {
[2725]117 printf("Virtual console%s locked by %s.\n",
[3232]118 /* "s" if -a, else "": */ "s" + !option_mask32,
119 pw->pw_name
120 );
[3621]121 if (ask_and_check_password(pw) > 0) {
[821]122 break;
123 }
[3232]124 bb_do_delay(LOGIN_FAIL_DELAY);
125 puts("Incorrect password");
126 }
[2725]127
128#ifdef __linux__
129 ioctl(STDIN_FILENO, VT_SETMODE, &ovtm);
130#endif
131 tcsetattr_stdin_TCSANOW(&oterm);
132 fflush_stdout_and_exit(EXIT_SUCCESS);
[821]133}
Note: See TracBrowser for help on using the repository browser.