1 | #!/usr/bin/python |
---|
2 | """getty replacement for Debathena |
---|
3 | |
---|
4 | Debathena clusters only allow logins through X, in order to avoid a |
---|
5 | user logging into a tty, then switching away from that tty, and |
---|
6 | walking away from their session. |
---|
7 | |
---|
8 | This replacement for getty clears the screen, and offers to switch the |
---|
9 | user back to their session if they press any key. |
---|
10 | """ |
---|
11 | |
---|
12 | |
---|
13 | import curses |
---|
14 | import getopt |
---|
15 | import os |
---|
16 | import pwd |
---|
17 | import sys |
---|
18 | |
---|
19 | import dbus |
---|
20 | |
---|
21 | |
---|
22 | CK_NAME = 'org.freedesktop.ConsoleKit' |
---|
23 | CK_MANAGER_PATH = '/org/freedesktop/ConsoleKit/Manager' |
---|
24 | CK_MANAGER_IFACE = 'org.freedesktop.ConsoleKit.Manager' |
---|
25 | CK_SESSION_IFACE = 'org.freedesktop.ConsoleKit.Session' |
---|
26 | KIOSK_USER = None |
---|
27 | |
---|
28 | |
---|
29 | def find_tty(args): |
---|
30 | """Find the tty in a set of getty arguments. |
---|
31 | |
---|
32 | Given the command line arguments one might pass to getty, find and |
---|
33 | return the argument that is the tty to use. |
---|
34 | |
---|
35 | find_tty uses the getopt option specifier and tty identifying |
---|
36 | logic from util-linux 2.13.1.1. |
---|
37 | |
---|
38 | Note that all other arguments will be ignored, making this getty |
---|
39 | useless for gettys that are not on normal ttys. |
---|
40 | """ |
---|
41 | opts, args = getopt.getopt(args, '8I:LH:f:hil:mt:wUn') |
---|
42 | |
---|
43 | # Accept both "tty baudrate" and "baudrate tty" |
---|
44 | if '0' <= args[0][0] <= '9': |
---|
45 | return args[1] |
---|
46 | else: |
---|
47 | return args[0] |
---|
48 | |
---|
49 | |
---|
50 | def activate_session(): |
---|
51 | """Seek out and activate what should be the current session. |
---|
52 | |
---|
53 | Using ConsoleKit, activate_session first looks to see if there is |
---|
54 | an active kiosk-mode browsing session, and if so, switches to |
---|
55 | that. Otherwise, it picks the first local session it can find and |
---|
56 | assumes that's the user's session. |
---|
57 | |
---|
58 | With the exception of the kiosk-mode session, it should be |
---|
59 | impossible to have more than one session running simultaneously, |
---|
60 | so blindly using the first session shouldn't be a problem. |
---|
61 | """ |
---|
62 | global KIOSK_USER |
---|
63 | if KIOSK_USER is None: |
---|
64 | try: |
---|
65 | KIOSK_USER = pwd.getpwnam('kiosk@mit').pw_uid |
---|
66 | except KeyError: |
---|
67 | # There is no kiosk user |
---|
68 | KIOSK_USER = False |
---|
69 | |
---|
70 | bus = dbus.SystemBus() |
---|
71 | manager = dbus.Interface(bus.get_object(CK_NAME, CK_MANAGER_PATH), |
---|
72 | CK_MANAGER_IFACE) |
---|
73 | |
---|
74 | session = None |
---|
75 | if KIOSK_USER: |
---|
76 | sessions = manager.GetSessionsForUnixUser(KIOSK_USER) |
---|
77 | if sessions: |
---|
78 | session = dbus.Interface(bus.get_object(CK_NAME, sessions[0]), |
---|
79 | CK_SESSION_IFACE) |
---|
80 | if not session: |
---|
81 | # Find the first session that identifies itself as local |
---|
82 | sessions = manager.GetSessions() |
---|
83 | for s in sessions: |
---|
84 | session = dbus.Interface(bus.get_object(CK_NAME, s), |
---|
85 | CK_SESSION_IFACE) |
---|
86 | if session.IsLocal(): |
---|
87 | break |
---|
88 | else: |
---|
89 | session = None |
---|
90 | |
---|
91 | if session: |
---|
92 | session.Activate() |
---|
93 | |
---|
94 | |
---|
95 | def main(): |
---|
96 | tty_name = find_tty(sys.argv[1:]) |
---|
97 | tty = open(os.path.join('/dev', tty_name), 'a+') |
---|
98 | # We want to set TERM for a tty, not for whatever TERM was set to |
---|
99 | # on getty's controlling terminal. |
---|
100 | curses.setupterm("linux", tty.fileno()) |
---|
101 | |
---|
102 | CLEAR = curses.tigetstr('clear') |
---|
103 | |
---|
104 | while True: |
---|
105 | tty.write(CLEAR) |
---|
106 | tty.write('Please press Enter to return to your session\n') |
---|
107 | tty.readline() |
---|
108 | |
---|
109 | activate_session() |
---|
110 | |
---|
111 | |
---|
112 | if __name__ == '__main__': |
---|
113 | main() |
---|