source: proiecte/PPPP/gdm/daemon/gdm-session-record.c @ 134

Last change on this file since 134 was 134, checked in by (none), 14 years ago

gdm sources with the modifications for webcam

File size: 11.5 KB
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2006 Ray Strode <rstrode@redhat.com>
4 * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include "config.h"
23
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
27
28#if defined(HAVE_UTMPX_H)
29#include <utmpx.h>
30#endif
31
32#if defined(HAVE_UTMP_H)
33#include <utmp.h>
34#endif
35
36#include <glib.h>
37#include <glib/gi18n.h>
38#include <glib/gstdio.h>
39
40#include "gdm-session-record.h"
41
42#ifndef GDM_BAD_SESSION_RECORDS_FILE
43#define GDM_BAD_SESSION_RECORDS_FILE "/var/log/btmp"
44#endif
45
46#if !defined(GDM_NEW_SESSION_RECORDS_FILE)
47#    if defined(WTMPX_FILE)
48#        define GDM_NEW_SESSION_RECORDS_FILE WTMPX_FILE
49#    elif defined(_PATH_WTMPX)
50#        define GDM_NEW_SESSION_RECORDS_FILE _PATH_WTMPX
51#    elif defined(WTMPX_FILENAME)
52#        define GDM_NEW_SESSION_RECORDS_FILE WTMPX_FILENAME
53#    elif defined(WTMP_FILE)
54#        define GDM_NEW_SESSION_RECORDS_FILE WTMP_FILE
55#    elif defined(_PATH_WTMP) /* BSD systems */
56#        define GDM_NEW_SESSION_RECORDS_FILE _PATH_WTMP
57#    else
58#        define GDM_NEW_SESSION_RECORDS_FILE "/var/log/wtmp"
59#    endif
60#endif
61
62static void
63record_set_username (UTMP       *u,
64                     const char *user_name)
65{
66        const char *username;
67
68        /*
69         * It is possible that PAM failed before it mapped the user
70         * input into a valid username, so we fallback to try using
71         * "(unknown)"
72         */
73        if (user_name != NULL) {
74                username = user_name;
75        } else {
76                username = "(unknown)";
77        }
78
79#if defined(HAVE_UT_UT_USER)
80        strncpy (u->ut_user,
81                 username,
82                 sizeof (u->ut_user));
83        g_debug ("using ut_user %.*s",
84                 (int) sizeof (u->ut_user),
85                 u->ut_user);
86#elif defined(HAVE_UT_UT_NAME)
87        strncpy (u->ut_name,
88                 username,
89                 sizeof (u->ut_name));
90        g_debug ("using ut_name %.*s",
91                 (int) sizeof (u->ut_name),
92                 u->ut_name);
93#endif
94}
95
96static void
97record_set_timestamp (UTMP *u)
98{
99#if defined(HAVE_UT_UT_TV)
100        GTimeVal    now = { 0 };
101
102        /* Set time in TV format */
103        g_get_current_time (&now);
104        u->ut_tv.tv_sec  = now.tv_sec;
105        u->ut_tv.tv_usec = now.tv_usec;
106        g_debug ("using ut_tv time %ld",
107                 (glong) u->ut_tv.tv_sec);
108#elif defined(HAVE_UT_UT_TIME)
109        /* Set time in time format */
110        time (&u->ut_time);
111        g_debug ("using ut_time %ld",
112                 (glong) u->ut_time);
113#endif
114}
115
116static void
117record_set_pid (UTMP *u,
118                GPid  pid)
119{
120#if defined(HAVE_UT_UT_PID)
121        /* Set pid */
122        if (pid != 0) {
123                u->ut_pid = pid;
124        }
125        g_debug ("using ut_pid %d", (int) u->ut_pid);
126#endif
127}
128
129static void
130record_set_id (UTMP       *u,
131               const char *id)
132{
133#if defined(HAVE_UT_UT_ID)
134        strncpy (u->ut_id, id, sizeof (u->ut_id));
135        g_debug ("using ut_id %.*s", (int) sizeof (u->ut_id), u->ut_id);
136#endif
137}
138
139static void
140record_set_host (UTMP       *u,
141                 const char *x11_display_name,
142                 const char *host_name)
143{
144        char *hostname;
145
146#if defined(HAVE_UT_UT_HOST)
147        hostname = NULL;
148
149        /*
150         * Set ut_host to hostname:$DISPLAY if remote, otherwise set
151         * to $DISPLAY
152         */
153        if (host_name != NULL
154            && x11_display_name != NULL
155            && g_str_has_prefix (x11_display_name, ":")) {
156                hostname = g_strdup_printf ("%s%s", host_name, x11_display_name);
157        } else {
158                hostname = g_strdup (x11_display_name);
159        }
160
161        if (hostname != NULL) {
162                strncpy (u->ut_host, hostname, sizeof (u->ut_host));
163                g_debug ("using ut_host %.*s", (int) sizeof (u->ut_host), u->ut_host);
164                g_free (hostname);
165
166#ifdef HAVE_UT_UT_SYSLEN
167                u->ut_syslen = MIN (strlen (hostname), sizeof (u->ut_host));
168#endif
169        }
170#endif
171}
172
173static void
174record_set_line (UTMP       *u,
175                 const char *display_device,
176                 const char *x11_display_name)
177{
178        /*
179         * Set ut_line to the device name associated with this display
180         * but remove the "/dev/" prefix.  If no device, then use the
181         * $DISPLAY value.
182         */
183        if (display_device != NULL
184            && g_str_has_prefix (display_device, "/dev/")) {
185                strncpy (u->ut_line,
186                         display_device + strlen ("/dev/"),
187                         sizeof (u->ut_line));
188        } else if (x11_display_name != NULL
189                   && g_str_has_prefix (x11_display_name, ":")) {
190                strncpy (u->ut_line,
191                         x11_display_name,
192                         sizeof (u->ut_line));
193        }
194
195        g_debug ("using ut_line %.*s", (int) sizeof (u->ut_line), u->ut_line);
196}
197
198void
199gdm_session_record_login (GPid                  session_pid,
200                          const char           *user_name,
201                          const char           *host_name,
202                          const char           *x11_display_name,
203                          const char           *display_device)
204{
205        UTMP        session_record = { 0 };
206        UTMP       *u;
207
208        record_set_username (&session_record, user_name);
209
210        g_debug ("Writing login record");
211
212#if defined(HAVE_UT_UT_TYPE)
213        session_record.ut_type = USER_PROCESS;
214        g_debug ("using ut_type USER_PROCESS");
215#endif
216
217        record_set_timestamp (&session_record);
218        record_set_pid (&session_record, session_pid);
219
220        /* Set ut_id to the $DISPLAY value */
221        record_set_id (&session_record, x11_display_name);
222        record_set_host (&session_record, x11_display_name, host_name);
223        record_set_line (&session_record, display_device, x11_display_name);
224
225        /* Handle wtmp */
226        g_debug ("Writing wtmp session record to " GDM_NEW_SESSION_RECORDS_FILE);
227#if defined(HAVE_UPDWTMPX)
228        updwtmpx (GDM_NEW_SESSION_RECORDS_FILE, &session_record);
229#elif defined(HAVE_UPDWTMP)
230        updwtmp (GDM_NEW_SESSION_RECORDS_FILE, &session_record);
231#elif defined(HAVE_LOGWTMP) && defined(HAVE_UT_UT_HOST)
232#if defined(HAVE_UT_UT_USER)
233        logwtmp (session_record.ut_line, session_record.ut_user, session_record.ut_host);
234#elif defined(HAVE_UT_UT_NAME)
235        logwtmp (session_record.ut_line, session_record.ut_name, session_record.ut_host);
236#endif
237#endif
238
239        /*
240         * Handle utmp
241         * Update if entry already exists
242         */
243#if defined(HAVE_GETUTXENT)
244        setutxent ();
245
246        while ((u = getutxent ()) != NULL) {
247                if (u->ut_type == USER_PROCESS &&
248                    (session_record.ut_line != NULL &&
249                     (strncmp (u->ut_line, session_record.ut_line,
250                               sizeof (u->ut_line)) == 0 ||
251                      u->ut_pid == session_record.ut_pid))) {
252                        g_debug ("Updating existing utmp record");
253                        pututxline (&session_record);
254                        break;
255                }
256        }
257        endutxent ();
258
259        /* Add new entry if update did not work */
260        if (u == NULL) {
261                g_debug ("Adding new utmp record");
262                pututxline (&session_record);
263        }
264#elif defined(HAVE_LOGIN)
265        login (&session_record);
266#endif
267}
268
269void
270gdm_session_record_logout (GPid                  session_pid,
271                           const char           *user_name,
272                           const char           *host_name,
273                           const char           *x11_display_name,
274                           const char           *display_device)
275{
276        UTMP        session_record = { 0 };
277        UTMP       *u;
278
279        g_debug ("Writing logout record");
280
281#if defined(HAVE_UT_UT_TYPE)
282        session_record.ut_type = DEAD_PROCESS;
283        g_debug ("using ut_type DEAD_PROCESS");
284#endif
285
286        record_set_timestamp (&session_record);
287        record_set_pid (&session_record, session_pid);
288        /* Set ut_id to the $DISPLAY value */
289        record_set_id (&session_record, x11_display_name);
290        record_set_host (&session_record, x11_display_name, host_name);
291        record_set_line (&session_record, display_device, x11_display_name);
292
293
294        /* Handle wtmp */
295        g_debug ("Writing wtmp logout record to " GDM_NEW_SESSION_RECORDS_FILE);
296#if defined(HAVE_UPDWTMPX)
297        updwtmpx (GDM_NEW_SESSION_RECORDS_FILE, &session_record);
298#elif defined (HAVE_UPDWTMP)
299        updwtmp (GDM_NEW_SESSION_RECORDS_FILE, &session_record);
300#elif defined(HAVE_LOGWTMP)
301        logwtmp (session_record.ut_line, "", "");
302#endif
303
304        /* Handle utmp */
305#if defined(HAVE_GETUTXENT)
306        setutxent ();
307
308        while ((u = getutxent ()) != NULL &&
309               (u = getutxid (&session_record)) != NULL) {
310
311                g_debug ("Removing utmp record");
312                if (u->ut_pid == session_pid &&
313                    u->ut_type == DEAD_PROCESS) {
314                        /* Already done */
315                        break;
316                }
317
318                u->ut_type = DEAD_PROCESS;
319#if defined(HAVE_UT_UT_TV)
320                u->ut_tv.tv_sec  = session_record.ut_tv.tv_sec;
321                u->ut_tv.tv_usec = session_record.ut_tv.tv_usec;
322#elif defined(HAVE_UT_UT_TIME)
323                u->ut_time = session_record.ut_time;
324#endif
325#ifdef HAVE_UT_UT_EXIT_E_TERMINATION
326                u->ut_exit.e_termination = 0;
327                u->ut_exit.e_exit = 0;
328#endif
329
330                pututxline (u);
331
332                break;
333        }
334
335        endutxent ();
336#elif defined(HAVE_LOGOUT)
337        logout (session_record.ut_line);
338#endif
339}
340
341void
342gdm_session_record_failed (GPid                  session_pid,
343                           const char           *user_name,
344                           const char           *host_name,
345                           const char           *x11_display_name,
346                           const char           *display_device)
347{
348        UTMP        session_record = { 0 };
349
350        record_set_username (&session_record, user_name);
351
352        g_debug ("Writing failed session attempt record");
353
354#if defined(HAVE_UT_UT_TYPE)
355        session_record.ut_type = USER_PROCESS;
356        g_debug ("using ut_type USER_PROCESS");
357#endif
358
359        record_set_timestamp (&session_record);
360        record_set_pid (&session_record, session_pid);
361        /* Set ut_id to the $DISPLAY value */
362        record_set_id (&session_record, x11_display_name);
363        record_set_host (&session_record, x11_display_name, host_name);
364        record_set_line (&session_record, display_device, x11_display_name);
365
366        /* Handle btmp */
367        g_debug ("Writing btmp failed session attempt record to "
368                 GDM_BAD_SESSION_RECORDS_FILE);
369
370#if defined(HAVE_UPDWTMPX)
371        updwtmpx (GDM_BAD_SESSION_RECORDS_FILE, &session_record);
372#elif defined(HAVE_UPDWTMP)
373        updwtmp(GDM_BAD_SESSION_RECORDS_FILE, &session_record);
374#endif
375
376}
Note: See TracBrowser for help on using the repository browser.