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
  • daemon/gdm-local-display-factory.c

    #
    # Description: Add a new D-Bus operation StartGuestSession().
    #  If setup/teardown scripts are available in
    #  /usr/share/gdm/guest-session/ (shipped by separate gdm-guest-user
    #  package), run a guest session without requiring a password. 
    #  Guest sessions call /usr/share/gdm/guest-session/Xsession instead of
    #  /etc/gdm/Xsession, so that we can wrap AppArmor (or other MAC
    #  system) rules around it.
    # Ubuntu: https://wiki.ubuntu.com/DesktopTeam/Specs/Intrepid/GuestAccount
    #
    diff -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
    old new  
    2222
    2323#include <stdlib.h>
    2424#include <stdio.h>
     25#include <errno.h>
     26#include <pwd.h>
    2527
    2628#include <glib.h>
    2729#include <glib/gi18n.h>
     
    5153#define HAL_DBUS_DEVICE_INTERFACE               "org.freedesktop.Hal.Device"
    5254#define SEAT_PCI_DEVICE_CLASS                   3
    5355
     56#define GUEST_USERNAME                          "guest"
     57
    5458#define MAX_DISPLAY_FAILURES 5
    5559
    5660struct GdmLocalDisplayFactoryPrivate
     
    234238        return ret;
    235239}
    236240
     241/* GdmGuestDisplay */
     242
     243typedef struct
     244{
     245        GdmTransientDisplayClass   parent_class;
     246} GdmGuestDisplayClass;
     247
     248typedef struct
     249{
     250        GdmTransientDisplay        parent;
     251        GdmTransientDisplayPrivate *priv;
     252} GdmGuestDisplay;
     253
     254#define GDM_TYPE_GUEST_DISPLAY         (gdm_guest_display_get_type ())
     255#define GDM_GUEST_DISPLAY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_GUEST_DISPLAY, GdmGuestDisplayClass))
     256GType           gdm_guest_display_get_type     (void);
     257static void     gdm_guest_display_class_init   (GdmGuestDisplayClass *klass);
     258static void     gdm_guest_display_init         (GdmGuestDisplay      *display) {}
     259GdmDisplay *    gdm_guest_display_new          (int display_number);
     260static gboolean gdm_guest_display_finish       (GdmDisplay           *display);
     261
     262G_DEFINE_TYPE (GdmGuestDisplay, gdm_guest_display, GDM_TYPE_TRANSIENT_DISPLAY);
     263
     264/* override timed_login_details for guest session */
     265static void
     266gdm_guest_display_get_timed_login_details (GdmDisplay *display,
     267                                           gboolean   *enabledp,
     268                                           char      **usernamep,
     269                                           int        *delayp)
     270{
     271        g_debug ("GdmLocalDisplayFactory: Getting guest timed login details");
     272        *enabledp = TRUE;
     273        *usernamep = g_strdup(GUEST_USERNAME);
     274        *delayp = 0;
     275}
     276
     277static void
     278gdm_guest_display_class_init (GdmGuestDisplayClass *klass)
     279{
     280        GdmDisplayClass *display_class = GDM_DISPLAY_CLASS (klass);
     281
     282        display_class->get_timed_login_details = gdm_guest_display_get_timed_login_details;
     283        display_class->finish = gdm_guest_display_finish;
     284}
     285
     286GdmDisplay *
     287gdm_guest_display_new (int display_number)
     288{
     289        GObject *object;
     290        char    *x11_display;
     291
     292        x11_display = g_strdup_printf (":%d", display_number);
     293        object = g_object_new (GDM_TYPE_GUEST_DISPLAY,
     294                               "x11-display-number", display_number,
     295                               "x11-display-name", x11_display,
     296                               NULL);
     297        g_free (x11_display);
     298
     299        return GDM_DISPLAY (object);
     300}
     301
     302static
     303gboolean
     304gdm_guest_display_finish (GdmDisplay *display)
     305{
     306        GError *err = NULL;
     307        gboolean result;
     308        gint status;
     309        struct sigaction dfl, old_act;
     310        const char* argv[] = {
     311            "/usr/share/gdm/guest-session/guest-session-cleanup.sh",
     312            GUEST_USERNAME, NULL};
     313
     314        /* temporarily reset SIGCHLD, we need it for g_spawn_sync */
     315        dfl.sa_handler = SIG_DFL;
     316        dfl.sa_flags = SA_RESTART|SA_NOCLDSTOP;
     317        sigemptyset (&dfl.sa_mask);
     318        g_assert (sigaction (SIGCHLD, &dfl, &old_act) == 0);
     319
     320        /* destroy guest user again */
     321        result = g_spawn_sync ("/", (gchar**) argv, NULL, 0, NULL, NULL, NULL,
     322                NULL, &status, &err);
     323
     324        g_assert (sigaction (SIGCHLD, &old_act, NULL) == 0);
     325
     326        if (!result) {
     327                g_warning ("gdm_guest_display_finish: Calling '%s %s' failed: %s", argv[0],
     328                           argv[1], err->message);
     329                g_error_free (err);
     330        }
     331
     332        return GDM_DISPLAY_CLASS (gdm_guest_display_parent_class)->finish (display);
     333}
     334
     335/* End GdmGuestDisplay */
     336
     337static gboolean
     338gdm_local_display_factory_setup_guest_account ()
     339{
     340        GError *err = NULL;
     341        gboolean result;
     342        gchar *sout, *serr;
     343        char *username;
     344        gint status;
     345        int len;
     346        struct sigaction dfl, old_act;
     347        const char* argv[] = {
     348            "/usr/share/gdm/guest-session/guest-session-setup.sh",
     349            NULL, NULL}; /* leave enough room for one argument */
     350       
     351        g_debug ("gdm_local_display_factory_setup_guest_account: Calling guest-session-setup.sh");
     352       
     353        /* temporarily reset SIGCHLD, we need it for g_spawn_sync */
     354        dfl.sa_handler = SIG_DFL;
     355        dfl.sa_flags = SA_RESTART|SA_NOCLDSTOP;
     356        sigemptyset (&dfl.sa_mask);
     357        if (sigaction (SIGCHLD, &dfl, &old_act) < 0) {
     358            g_warning("gdm_local_display_factory_setup_guest_account: failure to temporarily restore SIGCHLD: %s",
     359                strerror(errno));
     360                return FALSE;
     361        }
     362       
     363        /* call guest setup script */
     364        result = g_spawn_sync ("/", (gchar**) argv, NULL, 0, NULL, NULL, &sout,
     365                               &serr, &status, &err);
     366        g_assert (sigaction (SIGCHLD, &old_act, NULL) == 0);
     367        if (!result) {
     368                g_warning ("gdm_local_display_factory_setup_guest_account: Calling %s failed: %s", argv[0],
     369                           err->message);
     370                g_error_free (err);
     371                return FALSE;
     372        }
     373        if (status != 0) {
     374                g_warning ("gdm_local_display_factory_setup_guest_account: %s failed with status %i:\n%s\n%s",
     375                           argv[0], status, sout, serr);
     376                g_free(sout);
     377                g_free(serr);
     378                return FALSE;
     379        }
     380        g_free (serr);
     381       
     382        /* extract user name from stdout */
     383        len = strlen (sout);
     384        if (sout[len-1] == '\n')
     385                sout[len-1] = 0;
     386        username = strrchr (sout, '\n');
     387        if (!username || strcmp (username + 1, GUEST_USERNAME)) {
     388                g_warning ("gdm_local_display_factory_setup_guest_account: no output, last line of stdout must have username; or username is not 'guest'");
     389                g_free (sout);
     390                return FALSE;
     391        }
     392        g_debug ("gdm_local_display_factory_setup_guest_account: %s succeeded, username: '%s'", argv[0], username+1);
     393        /* if we ever need to pass it to outside: */
     394        /* username = g_strdup (username + 1); */
     395        g_free (sout);
     396       
     397        return TRUE;
     398}
     399
     400static gboolean
     401switch_to_guest_display (GdmLocalDisplayFactory *factory)
     402{
     403        struct passwd *password;
     404        DBusGProxy *proxy;
     405        GPtrArray *sessions = NULL;
     406        GError *error = NULL;
     407        gboolean result = FALSE;
     408
     409        password = getpwnam (GUEST_USERNAME);
     410        if (!password) {
     411                return FALSE;
     412        }
     413
     414        proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
     415                                           "org.freedesktop.ConsoleKit",
     416                                           "/org/freedesktop/ConsoleKit/Manager",
     417                                           "org.freedesktop.ConsoleKit.Manager");
     418   
     419        dbus_g_proxy_call (proxy, "GetSessionsForUnixUser", &error,
     420                           G_TYPE_UINT, password->pw_uid, G_TYPE_INVALID,
     421                           dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions, G_TYPE_INVALID);
     422        g_object_unref(proxy);
     423        if (error != NULL) {
     424                g_warning ("Error getting guest sessions: %s", error->message);
     425                g_error_free (error);
     426        }
     427   
     428        if (sessions && sessions->len > 0) {
     429                gchar *session_id = sessions->pdata[0];
     430
     431                g_debug ("GdmLocalDisplayFactory: Switching to guest session %s", session_id);
     432
     433                proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
     434                                                   "org.freedesktop.ConsoleKit",
     435                                                   session_id,
     436                                                   "org.freedesktop.ConsoleKit.Session");
     437                result = dbus_g_proxy_call (proxy, "Activate", &error, G_TYPE_INVALID, G_TYPE_INVALID);
     438                g_object_unref (proxy);
     439                if (error != NULL)
     440                {
     441                        g_warning ("Error activating guest session: %s", error->message);
     442                        g_error_free (error);
     443                }
     444        }
     445       
     446        if (sessions != NULL) {
     447                gint i;
     448                for (i = 0; i < sessions->len; i++) {
     449                        g_free (sessions->pdata[i]);
     450                }
     451                g_ptr_array_free (sessions, TRUE);
     452        }
     453
     454        return result;
     455}
     456
     457gboolean
     458gdm_local_display_factory_start_guest_session (GdmLocalDisplayFactory *factory,
     459                                               char                  **id,
     460                                               GError                **error)
     461{
     462        GdmDisplay      *display = NULL;
     463        guint32          num;
     464
     465        g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
     466
     467        /* Switch to existing guest display */
     468        if (switch_to_guest_display (factory)) {
     469                /* FIXME: How to return the ID of the guest display?  It should
     470                 *        be easy but I can't find how to get it */
     471                /*if (id != NULL) {
     472                        *id = g_strdup ("FIXME");
     473                }*/
     474
     475                /* FIXME: We should return TRUE here but this causes GDM to go
     476                 *        crazy.  Luckily we can return FALSE as we don't need
     477                 *        any values returned from this call */
     478                return FALSE;
     479        }
     480
     481        if (!gdm_local_display_factory_setup_guest_account()) {
     482                return FALSE;
     483        }
     484
     485        num = take_next_display_number (factory);
     486
     487        g_debug ("GdmLocalDisplayFactory: Starting Guest Session %d", num);
     488
     489        display = gdm_guest_display_new (num);
     490
     491        /* FIXME: don't hardcode seat1? */
     492        g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
     493
     494        store_display (factory, num, display);
     495
     496        if (! gdm_display_manage (display) || ! gdm_display_get_id (display, id, NULL)) {
     497                return FALSE;
     498        } else {
     499                g_object_unref (display);
     500                return TRUE;
     501        }
     502}
     503
    237504gboolean
    238505gdm_local_display_factory_create_product_display (GdmLocalDisplayFactory *factory,
    239506                                                  const char             *parent_display_id,
  • daemon/gdm-local-display-factory.h

    diff -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
    old new  
    6565                                                                               char                  **id,
    6666                                                                               GError                **error);
    6767
     68gboolean                   gdm_local_display_factory_start_guest_session       (GdmLocalDisplayFactory *factory,
     69                                                                                char                  **id,
     70                                                                                GError                **error);
     71
    6872gboolean                   gdm_local_display_factory_create_product_display   (GdmLocalDisplayFactory *factory,
    6973                                                                               const char             *parent_display_id,
    7074                                                                               const char             *relay_address,
  • daemon/gdm-local-display-factory.xml

    diff -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
    old new  
    99    <method name="CreateTransientDisplay">
    1010      <arg name="id" direction="out" type="o"/>
    1111    </method>
     12    <method name="StartGuestSession">
     13      <arg name="id" direction="out" type="o"/>
     14    </method>
    1215  </interface>
    1316</node>
  • data/gdm.conf.in

    diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/data/gdm.conf.in gdm-2.28.0.new/data/gdm.conf.in
    old new  
    6868    <allow send_destination="org.gnome.DisplayManager"
    6969           send_interface="org.gnome.DisplayManager.LocalDisplayFactory"
    7070           send_member="CreateTransientDisplay"/>
     71    <allow send_destination="org.gnome.DisplayManager"
     72           send_interface="org.gnome.DisplayManager.LocalDisplayFactory"
     73           send_member="StartGuestSession"/>
    7174
    7275    <allow send_destination="org.gnome.DisplayManager"
    7376           send_interface="org.gnome.DisplayManager.Manager"
Note: See TracBrowser for help on using the repository browser.