source: proiecte/PPPP/gdm/debian/patches/14_guest_session.patch @ 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: 13.6 KB
RevLine 
[134]1#
2# Description: Add a new D-Bus operation StartGuestSession().
3#  If setup/teardown scripts are available in
4#  /usr/share/gdm/guest-session/ (shipped by separate gdm-guest-user
5#  package), run a guest session without requiring a password.
6#  Guest sessions call /usr/share/gdm/guest-session/Xsession instead of
7#  /etc/gdm/Xsession, so that we can wrap AppArmor (or other MAC
8#  system) rules around it.
9# Ubuntu: https://wiki.ubuntu.com/DesktopTeam/Specs/Intrepid/GuestAccount
10#
11diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-local-display-factory.c gdm-2.28.0.new/daemon/gdm-local-display-factory.c
12--- gdm-2.28.0/daemon/gdm-local-display-factory.c       2009-09-22 06:05:27.000000000 +1000
13+++ gdm-2.28.0.new/daemon/gdm-local-display-factory.c   2009-10-14 14:39:13.000000000 +1100
14@@ -22,6 +22,8 @@
15 
16 #include <stdlib.h>
17 #include <stdio.h>
18+#include <errno.h>
19+#include <pwd.h>
20 
21 #include <glib.h>
22 #include <glib/gi18n.h>
23@@ -51,6 +53,8 @@
24 #define HAL_DBUS_DEVICE_INTERFACE               "org.freedesktop.Hal.Device"
25 #define SEAT_PCI_DEVICE_CLASS                   3
26 
27+#define GUEST_USERNAME                          "guest"
28+
29 #define MAX_DISPLAY_FAILURES 5
30 
31 struct GdmLocalDisplayFactoryPrivate
32@@ -234,6 +238,269 @@
33         return ret;
34 }
35 
36+/* GdmGuestDisplay */
37+
38+typedef struct
39+{
40+        GdmTransientDisplayClass   parent_class;
41+} GdmGuestDisplayClass;
42+
43+typedef struct
44+{
45+        GdmTransientDisplay        parent;
46+        GdmTransientDisplayPrivate *priv;
47+} GdmGuestDisplay;
48+
49+#define GDM_TYPE_GUEST_DISPLAY         (gdm_guest_display_get_type ())
50+#define GDM_GUEST_DISPLAY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_GUEST_DISPLAY, GdmGuestDisplayClass))
51+GType           gdm_guest_display_get_type     (void);
52+static void     gdm_guest_display_class_init   (GdmGuestDisplayClass *klass);
53+static void     gdm_guest_display_init         (GdmGuestDisplay      *display) {}
54+GdmDisplay *    gdm_guest_display_new          (int display_number);
55+static gboolean gdm_guest_display_finish       (GdmDisplay           *display);
56+
57+G_DEFINE_TYPE (GdmGuestDisplay, gdm_guest_display, GDM_TYPE_TRANSIENT_DISPLAY);
58+
59+/* override timed_login_details for guest session */
60+static void
61+gdm_guest_display_get_timed_login_details (GdmDisplay *display,
62+                                           gboolean   *enabledp,
63+                                           char      **usernamep,
64+                                           int        *delayp)
65+{
66+       g_debug ("GdmLocalDisplayFactory: Getting guest timed login details");
67+       *enabledp = TRUE;
68+       *usernamep = g_strdup(GUEST_USERNAME);
69+       *delayp = 0;
70+}
71+
72+static void
73+gdm_guest_display_class_init (GdmGuestDisplayClass *klass)
74+{
75+        GdmDisplayClass *display_class = GDM_DISPLAY_CLASS (klass);
76+
77+        display_class->get_timed_login_details = gdm_guest_display_get_timed_login_details;
78+        display_class->finish = gdm_guest_display_finish;
79+}
80+
81+GdmDisplay *
82+gdm_guest_display_new (int display_number)
83+{
84+        GObject *object;
85+        char    *x11_display;
86+
87+        x11_display = g_strdup_printf (":%d", display_number);
88+        object = g_object_new (GDM_TYPE_GUEST_DISPLAY,
89+                               "x11-display-number", display_number,
90+                               "x11-display-name", x11_display,
91+                               NULL);
92+        g_free (x11_display);
93+
94+        return GDM_DISPLAY (object);
95+}
96+
97+static
98+gboolean
99+gdm_guest_display_finish (GdmDisplay *display)
100+{
101+        GError *err = NULL;
102+        gboolean result;
103+        gint status;
104+        struct sigaction dfl, old_act;
105+        const char* argv[] = {
106+            "/usr/share/gdm/guest-session/guest-session-cleanup.sh",
107+            GUEST_USERNAME, NULL};
108+
109+        /* temporarily reset SIGCHLD, we need it for g_spawn_sync */
110+        dfl.sa_handler = SIG_DFL;
111+        dfl.sa_flags = SA_RESTART|SA_NOCLDSTOP;
112+        sigemptyset (&dfl.sa_mask);
113+        g_assert (sigaction (SIGCHLD, &dfl, &old_act) == 0);
114+
115+        /* destroy guest user again */
116+        result = g_spawn_sync ("/", (gchar**) argv, NULL, 0, NULL, NULL, NULL,
117+                NULL, &status, &err);
118+
119+        g_assert (sigaction (SIGCHLD, &old_act, NULL) == 0);
120+
121+        if (!result) {
122+                g_warning ("gdm_guest_display_finish: Calling '%s %s' failed: %s", argv[0],
123+                           argv[1], err->message);
124+                g_error_free (err);
125+        }
126+
127+        return GDM_DISPLAY_CLASS (gdm_guest_display_parent_class)->finish (display);
128+}
129+
130+/* End GdmGuestDisplay */
131+
132+static gboolean
133+gdm_local_display_factory_setup_guest_account ()
134+{
135+        GError *err = NULL;
136+        gboolean result;
137+        gchar *sout, *serr;
138+        char *username;
139+        gint status;
140+        int len;
141+        struct sigaction dfl, old_act;
142+        const char* argv[] = {
143+            "/usr/share/gdm/guest-session/guest-session-setup.sh",
144+            NULL, NULL}; /* leave enough room for one argument */
145+       
146+        g_debug ("gdm_local_display_factory_setup_guest_account: Calling guest-session-setup.sh");
147+       
148+        /* temporarily reset SIGCHLD, we need it for g_spawn_sync */
149+        dfl.sa_handler = SIG_DFL;
150+        dfl.sa_flags = SA_RESTART|SA_NOCLDSTOP;
151+        sigemptyset (&dfl.sa_mask);
152+        if (sigaction (SIGCHLD, &dfl, &old_act) < 0) {
153+            g_warning("gdm_local_display_factory_setup_guest_account: failure to temporarily restore SIGCHLD: %s",
154+                strerror(errno));
155+                return FALSE;
156+        }
157+       
158+        /* call guest setup script */
159+        result = g_spawn_sync ("/", (gchar**) argv, NULL, 0, NULL, NULL, &sout,
160+                               &serr, &status, &err);
161+        g_assert (sigaction (SIGCHLD, &old_act, NULL) == 0);
162+        if (!result) {
163+                g_warning ("gdm_local_display_factory_setup_guest_account: Calling %s failed: %s", argv[0],
164+                           err->message);
165+                g_error_free (err);
166+                return FALSE;
167+        }
168+        if (status != 0) {
169+                g_warning ("gdm_local_display_factory_setup_guest_account: %s failed with status %i:\n%s\n%s",
170+                           argv[0], status, sout, serr);
171+                g_free(sout);
172+                g_free(serr);
173+                return FALSE;
174+        }
175+        g_free (serr);
176+       
177+        /* extract user name from stdout */
178+        len = strlen (sout);
179+        if (sout[len-1] == '\n')
180+                sout[len-1] = 0;
181+        username = strrchr (sout, '\n');
182+        if (!username || strcmp (username + 1, GUEST_USERNAME)) {
183+                g_warning ("gdm_local_display_factory_setup_guest_account: no output, last line of stdout must have username; or username is not 'guest'");
184+                g_free (sout);
185+                return FALSE;
186+        }
187+        g_debug ("gdm_local_display_factory_setup_guest_account: %s succeeded, username: '%s'", argv[0], username+1);
188+        /* if we ever need to pass it to outside: */
189+        /* username = g_strdup (username + 1); */
190+        g_free (sout);
191+       
192+        return TRUE;
193+}
194+
195+static gboolean
196+switch_to_guest_display (GdmLocalDisplayFactory *factory)
197+{
198+        struct passwd *password;
199+        DBusGProxy *proxy;
200+        GPtrArray *sessions = NULL;
201+        GError *error = NULL;
202+        gboolean result = FALSE;
203+
204+        password = getpwnam (GUEST_USERNAME);
205+        if (!password) {
206+                return FALSE;
207+        }
208+
209+        proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
210+                                           "org.freedesktop.ConsoleKit",
211+                                           "/org/freedesktop/ConsoleKit/Manager",
212+                                           "org.freedesktop.ConsoleKit.Manager");
213+   
214+        dbus_g_proxy_call (proxy, "GetSessionsForUnixUser", &error,
215+                           G_TYPE_UINT, password->pw_uid, G_TYPE_INVALID,
216+                           dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions, G_TYPE_INVALID);
217+        g_object_unref(proxy);
218+        if (error != NULL) {
219+                g_warning ("Error getting guest sessions: %s", error->message);
220+                g_error_free (error);
221+        }
222+   
223+        if (sessions && sessions->len > 0) {
224+                gchar *session_id = sessions->pdata[0];
225+
226+                g_debug ("GdmLocalDisplayFactory: Switching to guest session %s", session_id);
227+
228+                proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
229+                                                   "org.freedesktop.ConsoleKit",
230+                                                   session_id,
231+                                                   "org.freedesktop.ConsoleKit.Session");
232+                result = dbus_g_proxy_call (proxy, "Activate", &error, G_TYPE_INVALID, G_TYPE_INVALID);
233+                g_object_unref (proxy);
234+                if (error != NULL)
235+                {
236+                        g_warning ("Error activating guest session: %s", error->message);
237+                        g_error_free (error);
238+                }
239+        }
240+       
241+        if (sessions != NULL) {
242+                gint i;
243+                for (i = 0; i < sessions->len; i++) {
244+                        g_free (sessions->pdata[i]);
245+                }
246+                g_ptr_array_free (sessions, TRUE);
247+        }
248+
249+        return result;
250+}
251+
252+gboolean
253+gdm_local_display_factory_start_guest_session (GdmLocalDisplayFactory *factory,
254+                                               char                  **id,
255+                                               GError                **error)
256+{
257+        GdmDisplay      *display = NULL;
258+        guint32          num;
259+
260+        g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
261+
262+        /* Switch to existing guest display */
263+        if (switch_to_guest_display (factory)) {
264+                /* FIXME: How to return the ID of the guest display?  It should
265+                 *        be easy but I can't find how to get it */
266+                /*if (id != NULL) {
267+                        *id = g_strdup ("FIXME");
268+                }*/
269+
270+                /* FIXME: We should return TRUE here but this causes GDM to go
271+                 *        crazy.  Luckily we can return FALSE as we don't need
272+                 *        any values returned from this call */
273+                return FALSE;
274+        }
275+
276+        if (!gdm_local_display_factory_setup_guest_account()) {
277+                return FALSE;
278+        }
279+
280+        num = take_next_display_number (factory);
281+
282+        g_debug ("GdmLocalDisplayFactory: Starting Guest Session %d", num);
283+
284+        display = gdm_guest_display_new (num);
285+
286+        /* FIXME: don't hardcode seat1? */
287+        g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
288+
289+        store_display (factory, num, display);
290+
291+        if (! gdm_display_manage (display) || ! gdm_display_get_id (display, id, NULL)) {
292+                return FALSE;
293+        } else {
294+                g_object_unref (display);
295+                return TRUE;
296+        }
297+}
298+
299 gboolean
300 gdm_local_display_factory_create_product_display (GdmLocalDisplayFactory *factory,
301                                                   const char             *parent_display_id,
302diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-local-display-factory.h gdm-2.28.0.new/daemon/gdm-local-display-factory.h
303--- gdm-2.28.0/daemon/gdm-local-display-factory.h       2009-09-22 06:05:27.000000000 +1000
304+++ gdm-2.28.0.new/daemon/gdm-local-display-factory.h   2009-10-14 14:34:31.000000000 +1100
305@@ -65,6 +65,10 @@
306                                                                                char                  **id,
307                                                                                GError                **error);
308 
309+gboolean                   gdm_local_display_factory_start_guest_session       (GdmLocalDisplayFactory *factory,
310+                                                                                char                  **id,
311+                                                                                GError                **error);
312+
313 gboolean                   gdm_local_display_factory_create_product_display   (GdmLocalDisplayFactory *factory,
314                                                                                const char             *parent_display_id,
315                                                                                const char             *relay_address,
316diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-local-display-factory.xml gdm-2.28.0.new/daemon/gdm-local-display-factory.xml
317--- gdm-2.28.0/daemon/gdm-local-display-factory.xml     2009-09-22 06:05:27.000000000 +1000
318+++ gdm-2.28.0.new/daemon/gdm-local-display-factory.xml 2009-10-14 14:34:31.000000000 +1100
319@@ -9,5 +9,8 @@
320     <method name="CreateTransientDisplay">
321       <arg name="id" direction="out" type="o"/>
322     </method>
323+    <method name="StartGuestSession">
324+      <arg name="id" direction="out" type="o"/>
325+    </method>
326   </interface>
327 </node>
328diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/data/gdm.conf.in gdm-2.28.0.new/data/gdm.conf.in
329--- gdm-2.28.0/data/gdm.conf.in 2009-10-14 14:34:30.000000000 +1100
330+++ gdm-2.28.0.new/data/gdm.conf.in     2009-10-14 14:34:31.000000000 +1100
331@@ -68,6 +68,9 @@
332     <allow send_destination="org.gnome.DisplayManager"
333            send_interface="org.gnome.DisplayManager.LocalDisplayFactory"
334            send_member="CreateTransientDisplay"/>
335+    <allow send_destination="org.gnome.DisplayManager"
336+           send_interface="org.gnome.DisplayManager.LocalDisplayFactory"
337+           send_member="StartGuestSession"/>
338 
339     <allow send_destination="org.gnome.DisplayManager"
340            send_interface="org.gnome.DisplayManager.Manager"
Note: See TracBrowser for help on using the repository browser.