~siretart/lightdm/fix.877766

« back to all changes in this revision

Viewing changes to src/display.c

  • Committer: Reinhard Tartler
  • Date: 2012-03-05 18:03:45 UTC
  • mfrom: (45.2.4 oneiric-updates)
  • Revision ID: siretart@tauware.de-20120305180345-qeezueuvewkcwuki
* SECURITY UPDATE: file descriptor leak to child processes (LP: #927060)
  - debian/patches/12_dont-leak-fds.patch: clean up file descriptors in
    src/*.c, add tests to tests/*.
  - CVE number pending
* debian/patches/06_translate_prompt_label.patch:
  Enable translation of prompt_label (LP: #897166).
[ Gunnar Hjalmarsson ]
* debian/lightdm-gtk-greeter-ubuntu.conf and
  debian/patches/09_show_lang_chooser_option.patch:
  - Disclose the option to enable the language chooser.
* debian/patches/10_available_languages.patch:
  - If available, show a list of installed translations in the
    language chooser instead of a 'locale -a' list (LP: #868346).
  - Use nl_langinfo() to get language and country names for the
    language chooser labels.
  - Translate language and country names.
  - Handle @variants properly.
* debian/patches/11_set_language_in_accountsservice.patch:
  - Save item that is selected from the language chooser also when
    AccountsService is in use (LP: #868346).
* SECURITY UPDATE: file contents disclosure via hard link
  - debian/patches/04_CVE-2011-4105.patch: make sure file isn't a symlink
    or a hard link before doing the chown on it.
  - CVE-2011-4105
* SECURITY UPDATE: file contents disclosure via links (LP: #883865)
  - debian/patches/05_CVE-2011-3153.patch: drop privileges before
    accessing file.
  - CVE-2011-3153
[ Martin Pitt ]
* debian/lightdm.upstart: Put back check for "text" in kernel command line,
  for inhibiting automatic lightdm start. Check $JOB to still allow a manual
  "start lightdm" command to work. (LP: #873334)
[ Robert Ancell ]
* New upstream release:
  - Use lchown for correcting ownership of ~/.Xauthority instead of chown
* New upstream release.
  [1.0.5]
  - Relax AppArmor guest profile to allow compiz to start
  - Connect up VNC settings for width, height, depth
  [1.0.4]
  - Fix --enable-gtk-greeter=yes not working
  - Fix X sessions with arguments in Exec not working
  - Use previous session for automatic login or if greeter does not request
    one. (LP: #834515)
  - Correct ownership of ~/.Xauthority if upgrading from buggy version of
    LightDM that had it root owned. (LP: #871667)
  - Set default resolution of VNC to 1024x768, add settings for width, height,
    depth into lightdm.conf.
  - AppArmor profile: Fix broken gnome-keyring and dbus/gwibber, and quiesce
    annoying kernel audit messages for privileges that we definitively do not
    want to grant. (LP: #877736) (LP: #874635)
  - Set LOGNAME environment variable (LP: #875705)
  - Mark strings as translatable in GTK greeter (LP: #868613)
  [ 1.0.3]
  - Fix reference counting issue in ConsoleKit code
  - Really add the lightdm-guest-session-wrapper
  [ 1.0.2 ]
  - Fix daemon from blocking if Accounts Service does not exist
  - Fix greeter log file not being written
  - Don't set LANG environment variable if using Accounts Service.
  - Fix gdmflexiserver not working due to it not being in PATH
  - Don't authenticate the greeter user
  - Allow greeters to be disabled in configure flags
  - Fix over allocation of read buffer in greeter protocol
  - Make sure objects are cleaned up on exit
  - Fix minor memory leaks
  - Fix hugely oversized allocation in greeter buffer.  Can trigger
    crashes when entering very long passwords.
* debian/patches/00bzr_guest_session_wrapper.diff:
* debian/patches/07_long_password_crash.patch:
* debian/patches/08_correct_ck_ref.patch:
  - Applied upstream
* New upstream release.
* don't start on graphics-device-added; reintroducing this reverted the fix
  for bug #615549 from maverick without explanation.
* clean up the completely illegible start rule for debian/lightdm.upstart,
  killing off the unnecessary parentheses
* debian/lightdm.upstart: when lightdm is shut down by a runlevel call,
  emit an upstart event that can be caught by plymouth so it can
  distinguish between the DM shutting down for a runlevel change vs.
  other causes.  LP: #854329.

Show diffs side-by-side

added added

removed removed

Lines of Context:
257
257
 
258
258
    if (result == PAM_SUCCESS)
259
259
    {
 
260
        const gchar *session_name;
 
261
     
260
262
        g_debug ("User %s authorized", pam_session_get_username (authentication));
 
263
 
 
264
        session_name = user_get_xsession (pam_session_get_user (authentication));
 
265
        if (session_name)
 
266
        {
 
267
            g_debug ("Using session %s", session_name);
 
268
            display_set_user_session (display, session_name);
 
269
        }
 
270
 
261
271
        started_session = start_user_session (display, authentication);
262
272
        if (!started_session)
263
273
            g_debug ("Failed to start autologin session");
391
401
}
392
402
 
393
403
static Session *
394
 
create_session (Display *display, PAMSession *authentication, const gchar *session_name, gboolean is_greeter, const gchar *log_filename)
 
404
create_session (Display *display, PAMSession *authentication, const gchar *session_name, gboolean is_greeter)
395
405
{
396
406
    gchar *sessions_dir, *filename, *path, *command = NULL;
397
407
    GKeyFile *session_desktop_file;
 
408
    gint argc;
 
409
    gchar **argv;
398
410
    Session *session;
399
411
    gboolean result;
400
412
    GError *error = NULL;
401
413
 
402
 
    g_debug ("Starting session %s as user %s logging to %s", session_name, pam_session_get_username (authentication), log_filename);
 
414
    g_debug ("Starting session %s as user %s", session_name, pam_session_get_username (authentication));
403
415
 
404
416
    // FIXME: This is X specific, move into xsession.c
405
417
    if (is_greeter)
426
438
    g_free (path);
427
439
    if (!command)
428
440
        return NULL;
 
441
 
 
442
    result = g_shell_parse_argv (command, &argc, &argv, &error);
 
443
    if (error)
 
444
        g_debug ("Invalid session command '%s': %s", command, error->message);
 
445
    g_clear_error (&error);
 
446
    g_free (command);
 
447
    if (!result)
 
448
        return NULL;
 
449
 
 
450
    /* Convert to full path */
 
451
    path = g_find_program_in_path (argv[0]);
 
452
    if (path)
 
453
    {
 
454
        g_free (argv[0]);
 
455
        argv[0] = path;
 
456
    }
 
457
    command = g_strjoinv (" ", argv);
 
458
 
429
459
    if (display->priv->session_wrapper && !is_greeter)
430
460
    {
431
461
        gchar *wrapper;
440
470
        }
441
471
    }
442
472
 
 
473
    /* for a guest session, run command through the wrapper covered by MAC */
 
474
    if (display->priv->autologin_guest)
 
475
    {
 
476
        gchar *t = command;
 
477
        command = g_strdup_printf (LIBEXEC_DIR "/lightdm-guest-session-wrapper %s", command);
 
478
        g_debug("Guest session, running session command through wrapper: %s", command);
 
479
        g_free (t);
 
480
    }
 
481
 
443
482
    g_signal_emit (display, signals[CREATE_SESSION], 0, &session);
444
483
    g_return_val_if_fail (session != NULL, NULL);
445
484
 
450
489
    session_set_is_greeter (session, is_greeter);
451
490
    session_set_authentication (session, authentication);
452
491
    session_set_command (session, command);
 
492
    g_free (command);
453
493
 
454
494
    session_set_env (session, "DESKTOP_SESSION", session_name); // FIXME: Apparently deprecated?
455
495
    session_set_env (session, "GDMSESSION", session_name); // FIXME: Not cross-desktop
456
496
 
457
 
    session_set_log_file (session, log_filename);
458
 
 
459
497
    /* Connect using the session bus */
460
498
    if (getuid () != 0)
461
499
    {
507
545
static gboolean
508
546
greeter_start_session_cb (Greeter *greeter, const gchar *session_name, Display *display)
509
547
{
510
 
    /* Store the session to use, use the default if none was requested */
 
548
    /* If no session requested, use the previous one */
 
549
    if (!session_name && !greeter_get_guest_authenticated (greeter))
 
550
    {
 
551
        User *user;
 
552
 
 
553
        user = pam_session_get_user (greeter_get_authentication (greeter));
 
554
        session_name = user_get_xsession (user);
 
555
    }
 
556
 
 
557
    /* If a session was requested, override the default */
511
558
    if (session_name)
512
559
    {
513
 
        g_free (display->priv->user_session);
514
 
        display->priv->user_session = g_strdup (session_name);
 
560
        g_debug ("Using session %s", session_name);
 
561
        display_set_user_session (display, session_name);
515
562
    }
516
563
 
517
564
    /* Stop this display if that session already exists and can switch to it */
537
584
    return TRUE;
538
585
}
539
586
 
540
 
static void
541
 
greeter_pam_messages_cb (PAMSession *authentication, int num_msg, const struct pam_message **msg, Display *display)
542
 
{
543
 
    g_debug ("Greeter user got prompt, aborting authentication");
544
 
    pam_session_cancel (authentication);
545
 
}
546
 
 
547
 
static void
548
 
greeter_authentication_result_cb (PAMSession *authentication, int result, Display *display)
549
 
{
550
 
    gboolean start_result = FALSE;
551
 
 
552
 
    if (result == PAM_SUCCESS)
553
 
        g_signal_emit (display, signals[START_GREETER], 0, &start_result);
554
 
    else
555
 
        g_debug ("Greeter user failed authentication");
556
 
 
557
 
    if (start_result)
558
 
        display_stop (display);
559
 
}
560
 
 
561
587
static gboolean
562
588
start_greeter_session (Display *display)
563
589
{
564
590
    User *user;
565
591
    gchar *log_dir, *filename, *log_filename;
566
592
    PAMSession *authentication;
567
 
    gboolean result;
568
 
    GError *error = NULL;
 
593
    gboolean start_result;
 
594
 
 
595
    g_return_val_if_fail (display->priv->session == NULL, FALSE);
 
596
    g_return_val_if_fail (display->priv->greeter == NULL, FALSE);
569
597
 
570
598
    g_debug ("Starting greeter session");
571
599
 
591
619
    }
592
620
    display->priv->in_user_session = FALSE;
593
621
 
 
622
    /* Authenticate as the requested user */
 
623
    authentication = pam_session_new (display->priv->pam_service, user_get_name (user));
 
624
    g_object_unref (user);
 
625
 
 
626
    display->priv->session = create_session (display, authentication, display->priv->greeter_session, TRUE);
 
627
    g_object_unref (authentication);
 
628
  
 
629
    if (!display->priv->session)
 
630
        return FALSE;
 
631
 
594
632
    log_dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
595
633
    filename = g_strdup_printf ("%s-greeter.log", display_server_get_name (display->priv->display_server));
596
634
    log_filename = g_build_filename (log_dir, filename, NULL);
597
635
    g_free (log_dir);
598
636
    g_free (filename);
599
 
  
600
 
    /* Authenticate as the requested user */
601
 
    authentication = pam_session_new (display->priv->pam_autologin_service, user_get_name (user));
602
 
    g_signal_connect (G_OBJECT (authentication), "got-messages", G_CALLBACK (greeter_pam_messages_cb), display);
603
 
    g_signal_connect (G_OBJECT (authentication), "authentication-result", G_CALLBACK (greeter_authentication_result_cb), display);
604
 
    g_object_unref (user);
605
637
 
606
 
    display->priv->session = create_session (display, authentication, display->priv->greeter_session, TRUE, log_filename);
607
 
    g_object_unref (authentication);
 
638
    g_debug ("Logging to %s", log_filename);
 
639
    session_set_log_file (display->priv->session, log_filename, FALSE);
608
640
    g_free (log_filename);
609
641
 
610
 
    if (!display->priv->session)
611
 
        return FALSE;
612
 
 
613
642
    display->priv->greeter = greeter_new (display->priv->session);
614
643
    g_signal_connect (G_OBJECT (display->priv->greeter), "connected", G_CALLBACK (greeter_connected_cb), display);
615
644
    g_signal_connect (G_OBJECT (display->priv->greeter), "start-authentication", G_CALLBACK (greeter_start_authentication_cb), display);
633
662
    greeter_set_hint (display->priv->greeter, "has-guest-account", display->priv->allow_guest ? "true" : "false");
634
663
    greeter_set_hint (display->priv->greeter, "hide-users", display->priv->greeter_hide_users ? "true" : "false");
635
664
 
636
 
    result = pam_session_authenticate (session_get_authentication (display->priv->session), &error);
637
 
    if (error)
638
 
        g_debug ("Error authenticating greeter user: %s", error->message);
639
 
    g_clear_error (&error);
 
665
    start_result = FALSE;
 
666
    g_signal_emit (display, signals[START_GREETER], 0, &start_result);
640
667
 
641
 
    return result;
 
668
    return !start_result;
642
669
}
643
670
 
644
671
static gboolean
671
698
    gchar *log_filename;
672
699
    gboolean result;
673
700
 
 
701
    g_return_val_if_fail (display->priv->session == NULL, FALSE);
 
702
 
674
703
    g_debug ("Starting user session");
675
704
 
676
705
    user = pam_session_get_user (authentication);
677
706
 
678
707
    /* Update user's xsession setting */
679
708
    user_set_xsession (user, display->priv->user_session);
 
709
 
 
710
    display->priv->session = create_session (display, authentication, display->priv->user_session, FALSE);
 
711
 
 
712
    if (!display->priv->session)
 
713
        return FALSE;
680
714
 
681
715
    // FIXME: Copy old error file
682
716
    log_filename = g_build_filename (user_get_home_directory (user), ".xsession-errors", NULL);
 
717
  
 
718
    /* Delete existing log file if it exists - a bug in 1.0.0 would cause this file to be written as root */
 
719
    unlink (log_filename);
683
720
 
684
 
    display->priv->session = create_session (display, authentication, display->priv->user_session, FALSE, log_filename);
 
721
    g_debug ("Logging to %s", log_filename);    
 
722
    session_set_log_file (display->priv->session, log_filename, TRUE);
685
723
    g_free (log_filename);
686
724
 
687
 
    if (!display->priv->session)
688
 
        return FALSE;
689
 
 
690
725
    g_signal_emit (display, signals[START_SESSION], 0, &result);
691
 
 
692
 
    return !result;
 
726
    result = !result;
 
727
 
 
728
    if (!result)
 
729
    {
 
730
        g_object_unref (display->priv->session);
 
731
        display->priv->session = NULL;
 
732
    }
 
733
 
 
734
    return result;
693
735
}
694
736
 
695
737
static gboolean