1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2  *
3  * Copyright (C) 2004, 2008 Sun Microsystems, Inc.
4  * Copyright (C) 2005, 2008 Red Hat, Inc.
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., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  *
21  * Written by: Brian A. Cameron <Brian.Cameron@sun.com>
22  *             Gary Winiger <Gary.Winiger@sun.com>
23  *             Ray Strode <rstrode@redhat.com>
24  *             Steve Grubb <sgrubb@redhat.com>
25  */
26 #include "config.h"
27 #include "gdm-session-linux-auditor.h"
28 
29 #include <fcntl.h>
30 #include <pwd.h>
31 #include <syslog.h>
32 #include <unistd.h>
33 
34 #include <libaudit.h>
35 
36 #include <glib.h>
37 
38 #include "gdm-common.h"
39 
40 struct _GdmSessionLinuxAuditorPrivate
41 {
42         int audit_fd;
43 };
44 
45 static void gdm_session_linux_auditor_finalize (GObject *object);
46 
G_DEFINE_TYPE(GdmSessionLinuxAuditor,gdm_session_linux_auditor,GDM_TYPE_SESSION_AUDITOR)47 G_DEFINE_TYPE (GdmSessionLinuxAuditor, gdm_session_linux_auditor, GDM_TYPE_SESSION_AUDITOR)
48 
49 static void
50 log_user_message (GdmSessionAuditor *auditor,
51                   gint               type,
52                   gint               result)
53 {
54         GdmSessionLinuxAuditor   *linux_auditor;
55         char                      buf[512];
56         char                     *username;
57         char                     *hostname;
58         char                     *display_device;
59         struct passwd            *pw;
60 
61         linux_auditor = GDM_SESSION_LINUX_AUDITOR (auditor);
62 
63         g_object_get (G_OBJECT (auditor), "username", &username, NULL);
64         g_object_get (G_OBJECT (auditor), "hostname", &hostname, NULL);
65         g_object_get (G_OBJECT (auditor), "display-device", &display_device, NULL);
66 
67         if (username != NULL) {
68                 gdm_get_pwent_for_name (username, &pw);
69         } else {
70                 username = g_strdup ("unknown");
71                 pw = NULL;
72         }
73 
74         if (pw != NULL) {
75                 g_snprintf (buf, sizeof (buf), "uid=%d", pw->pw_uid);
76                 audit_log_user_message (linux_auditor->priv->audit_fd, type,
77                                         buf, hostname, NULL, display_device,
78                                         result);
79         } else {
80                 g_snprintf (buf, sizeof (buf), "acct=%s", username);
81                 audit_log_user_message (linux_auditor->priv->audit_fd, type,
82                                         buf, hostname, NULL, display_device,
83                                         result);
84         }
85 
86         g_free (username);
87         g_free (hostname);
88         g_free (display_device);
89 }
90 
91 static void
gdm_session_linux_auditor_report_login(GdmSessionAuditor * auditor)92 gdm_session_linux_auditor_report_login (GdmSessionAuditor *auditor)
93 {
94         log_user_message (auditor, AUDIT_USER_LOGIN, 1);
95 }
96 
97 static void
gdm_session_linux_auditor_report_login_failure(GdmSessionAuditor * auditor,int pam_error_code,const char * pam_error_string)98 gdm_session_linux_auditor_report_login_failure (GdmSessionAuditor *auditor,
99                                                   int                pam_error_code,
100                                                   const char        *pam_error_string)
101 {
102         log_user_message (auditor, AUDIT_USER_LOGIN, 0);
103 }
104 
105 static void
gdm_session_linux_auditor_report_logout(GdmSessionAuditor * auditor)106 gdm_session_linux_auditor_report_logout (GdmSessionAuditor *auditor)
107 {
108         log_user_message (auditor, AUDIT_USER_LOGOUT, 1);
109 }
110 
111 static void
gdm_session_linux_auditor_class_init(GdmSessionLinuxAuditorClass * klass)112 gdm_session_linux_auditor_class_init (GdmSessionLinuxAuditorClass *klass)
113 {
114         GObjectClass           *object_class;
115         GdmSessionAuditorClass *auditor_class;
116 
117         object_class = G_OBJECT_CLASS (klass);
118         auditor_class = GDM_SESSION_AUDITOR_CLASS (klass);
119 
120         object_class->finalize = gdm_session_linux_auditor_finalize;
121 
122         auditor_class->report_login = gdm_session_linux_auditor_report_login;
123         auditor_class->report_login_failure = gdm_session_linux_auditor_report_login_failure;
124         auditor_class->report_logout = gdm_session_linux_auditor_report_logout;
125 
126         g_type_class_add_private (auditor_class, sizeof (GdmSessionLinuxAuditorPrivate));
127 }
128 
129 static void
gdm_session_linux_auditor_init(GdmSessionLinuxAuditor * auditor)130 gdm_session_linux_auditor_init (GdmSessionLinuxAuditor *auditor)
131 {
132         auditor->priv = G_TYPE_INSTANCE_GET_PRIVATE (auditor,
133                                                      GDM_TYPE_SESSION_LINUX_AUDITOR,
134                                                      GdmSessionLinuxAuditorPrivate);
135 
136         auditor->priv->audit_fd = audit_open ();
137 }
138 
139 static void
gdm_session_linux_auditor_finalize(GObject * object)140 gdm_session_linux_auditor_finalize (GObject *object)
141 {
142         GdmSessionLinuxAuditor *linux_auditor;
143         GObjectClass *parent_class;
144 
145         linux_auditor = GDM_SESSION_LINUX_AUDITOR (object);
146 
147         close (linux_auditor->priv->audit_fd);
148 
149         parent_class = G_OBJECT_CLASS (gdm_session_linux_auditor_parent_class);
150         if (parent_class->finalize != NULL) {
151                 parent_class->finalize (object);
152         }
153 }
154 
155 
156 GdmSessionAuditor *
gdm_session_linux_auditor_new(const char * hostname,const char * display_device)157 gdm_session_linux_auditor_new (const char *hostname,
158                                const char *display_device)
159 {
160         GObject *auditor;
161 
162         auditor = g_object_new (GDM_TYPE_SESSION_LINUX_AUDITOR,
163                                 "hostname", hostname,
164                                 "display-device", display_device,
165                                 NULL);
166 
167         return GDM_SESSION_AUDITOR (auditor);
168 }
169 
170 
171