1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28
#include <sys/types.h>
38
#include <glib/gi18n.h>
39
#include <glib/gstdio.h>
40
#include <glib-object.h>
43
#include "gdm-manager.h"
45
#include "gdm-common.h"
46
#include "gdm-signal-handler.h"
48
#include "gdm-settings.h"
49
#include "gdm-settings-direct.h"
50
#include "gdm-settings-keys.h"
52
#define GDM_DBUS_NAME "org.gnome.DisplayManager"
54
static GDBusConnection *get_system_bus (void);
55
static gboolean bus_reconnect (void);
57
extern char **environ;
59
static GdmManager *manager = NULL;
60
static int name_id = -1;
61
static GdmSettings *settings = NULL;
62
static uid_t gdm_uid = -1;
63
static gid_t gdm_gid = -1;
66
timed_exit_cb (GMainLoop *loop)
68
g_main_loop_quit (loop);
73
bus_connection_closed (void)
75
g_debug ("Disconnected from D-Bus");
77
if (manager == NULL) {
78
/* probably shutting down or something */
82
g_clear_object (&manager);
84
g_timeout_add_seconds (3, (GSourceFunc)bus_reconnect, NULL);
87
static GDBusConnection *
94
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
96
g_warning ("Couldn't connect to system bus: %s",
102
g_signal_connect (bus, "closed",
103
G_CALLBACK (bus_connection_closed), NULL);
104
g_dbus_connection_set_exit_on_close (bus, FALSE);
113
g_unlink (GDM_PID_FILE);
124
pf = open (GDM_PID_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
126
g_warning (_("Cannot write PID file %s: possibly out of disk space: %s"),
133
snprintf (pid, sizeof (pid), "%lu\n", (long unsigned) getpid ());
135
written = write (pf, pid, strlen (pid));
139
g_warning (_("Cannot write PID file %s: possibly out of disk space: %s"),
153
const char *log_path;
157
r = g_stat (log_path, &statbuf);
158
if (r < 0 || ! S_ISDIR (statbuf.st_mode)) {
159
if (g_mkdir (log_path, 0755) < 0) {
160
gdm_fail (_("Logdir %s does not exist or isn't a directory."),
163
g_chmod (log_path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
168
check_servauthdir (const char *auth_path,
169
struct stat *statbuf)
173
/* Enter paranoia mode */
174
r = g_stat (auth_path, statbuf);
176
gdm_fail (_("Authdir %s does not exist. Aborting."), auth_path);
179
if (! S_ISDIR (statbuf->st_mode)) {
180
gdm_fail (_("Authdir %s is not a directory. Aborting."), auth_path);
185
set_effective_user (uid_t uid)
191
if (geteuid () != uid) {
196
g_error ("Cannot set uid to %d: %s",
203
set_effective_group (gid_t gid)
208
if (getegid () != gid) {
213
g_error ("Cannot set gid to %d: %s",
220
set_effective_user_group (uid_t uid,
223
set_effective_user (0);
224
set_effective_group (gid);
226
set_effective_user (0);
231
gdm_daemon_check_permissions (uid_t uid,
235
const char *auth_path;
239
/* Enter paranoia mode */
240
check_servauthdir (auth_path, &statbuf);
242
set_effective_user_group (0, 0);
244
/* Now set things up for us as */
245
chown (auth_path, 0, gid);
246
g_chmod (auth_path, (S_IRWXU|S_IRWXG|S_ISVTX));
248
set_effective_user_group (uid, gid);
251
check_servauthdir (auth_path, &statbuf);
253
if G_UNLIKELY (statbuf.st_uid != 0 || statbuf.st_gid != gid) {
254
gdm_fail (_("Authdir %s is not owned by user %d, group %d. Aborting."),
260
if G_UNLIKELY (statbuf.st_mode != (S_IFDIR|S_IRWXU|S_IRWXG|S_ISVTX)) {
261
gdm_fail (_("Authdir %s has wrong permissions %o. Should be %o. Aborting."),
264
(S_IRWXU|S_IRWXG|S_ISVTX));
269
gdm_daemon_change_user (uid_t *uidp,
276
struct passwd *pwent;
284
gdm_settings_direct_get_string (GDM_KEY_USER, &username);
285
gdm_settings_direct_get_string (GDM_KEY_GROUP, &groupname);
287
if (username == NULL || groupname == NULL) {
291
g_debug ("Changing user:group to %s:%s", username, groupname);
293
/* Lookup user and groupid for the GDM user */
294
gdm_get_pwent_for_name (username, &pwent);
296
/* Set uid and gid */
297
if G_UNLIKELY (pwent == NULL) {
298
gdm_fail (_("Can't find the GDM user '%s'. Aborting!"), username);
303
if G_UNLIKELY (uid == 0) {
304
gdm_fail (_("The GDM user should not be root. Aborting!"));
307
grent = getgrnam (groupname);
309
if G_UNLIKELY (grent == NULL) {
310
gdm_fail (_("Can't find the GDM group '%s'. Aborting!"), groupname);
315
if G_UNLIKELY (gid == 0) {
316
gdm_fail (_("The GDM group should not be root. Aborting!"));
319
/* gid remains 'gdm' */
320
set_effective_user_group (uid, gid);
335
signal_cb (int signo,
340
g_debug ("Got callback for signal %d", signo);
347
/* let the fatal signals interrupt us */
348
g_debug ("Caught signal %d, shutting down abnormally.", signo);
355
/* let the fatal signals interrupt us */
356
g_debug ("Caught signal %d, shutting down normally.", signo);
362
g_debug ("Got HUP signal");
363
/* Reread config stuff like system config files, VPN service
366
g_object_unref (settings);
367
settings = gdm_settings_new ();
368
if (settings != NULL) {
369
if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) {
370
g_warning ("Unable to initialize settings");
379
g_debug ("Got USR1 signal");
381
* Play with log levels or something
385
gdm_log_toggle_debug ();
390
g_debug ("Caught unhandled signal %d", signo);
402
gboolean debug = FALSE;
404
/* enable debugging for unstable builds */
405
if (gdm_is_version_unstable ()) {
409
gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug);
417
GMainLoop *main_loop;
418
GOptionContext *context;
422
GdmSignalHandler *signal_handler;
423
static gboolean do_timed_exit = FALSE;
424
static gboolean print_version = FALSE;
425
static gboolean fatal_warnings = FALSE;
426
static GOptionEntry entries [] = {
427
{ "fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &fatal_warnings, N_("Make all warnings fatal"), NULL },
428
{ "timed-exit", 0, 0, G_OPTION_ARG_NONE, &do_timed_exit, N_("Exit after a time (for debugging)"), NULL },
429
{ "version", 0, 0, G_OPTION_ARG_NONE, &print_version, N_("Print GDM version"), NULL },
434
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
435
textdomain (GETTEXT_PACKAGE);
436
setlocale (LC_ALL, "");
442
context = g_option_context_new (_("GNOME Display Manager"));
443
g_option_context_add_main_entries (context, entries, NULL);
444
g_option_context_set_ignore_unknown_options (context, TRUE);
447
res = g_option_context_parse (context, &argc, &argv, &error);
448
g_option_context_free (context);
450
g_warning ("%s", error->message);
451
g_error_free (error);
456
g_print ("GDM %s\n", VERSION);
460
if (fatal_warnings) {
461
GLogLevelFlags fatal_mask;
463
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
464
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
465
g_log_set_always_fatal (fatal_mask);
470
settings = gdm_settings_new ();
471
if (settings == NULL) {
472
g_warning ("Unable to initialize settings");
476
if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) {
477
g_warning ("Unable to initialize settings");
481
gdm_log_set_debug (is_debug_set ());
483
gdm_daemon_change_user (&gdm_uid, &gdm_gid);
484
gdm_daemon_check_permissions (gdm_uid, gdm_gid);
486
set_effective_user_group (0, 0);
489
/* XDM compliant error message */
490
if (getuid () != 0) {
491
/* make sure the pid file doesn't get wiped */
492
g_warning (_("Only the root user can run GDM"));
496
/* Connect to the bus, own the name and start the manager */
505
main_loop = g_main_loop_new (NULL, FALSE);
507
signal_handler = gdm_signal_handler_new ();
508
gdm_signal_handler_set_fatal_func (signal_handler,
509
(GDestroyNotify)g_main_loop_quit,
511
gdm_signal_handler_add_fatal (signal_handler);
512
gdm_signal_handler_add (signal_handler, SIGTERM, signal_cb, NULL);
513
gdm_signal_handler_add (signal_handler, SIGINT, signal_cb, NULL);
514
gdm_signal_handler_add (signal_handler, SIGFPE, signal_cb, NULL);
515
gdm_signal_handler_add (signal_handler, SIGHUP, signal_cb, NULL);
516
gdm_signal_handler_add (signal_handler, SIGUSR1, signal_cb, NULL);
519
g_timeout_add_seconds (30, (GSourceFunc) timed_exit_cb, main_loop);
522
g_main_loop_run (main_loop);
524
g_debug ("GDM finished, cleaning up...");
526
g_clear_object (&manager);
527
g_clear_object (&settings);
528
g_clear_object (&signal_handler);
530
gdm_settings_direct_shutdown ();
533
g_main_loop_unref (main_loop);
543
on_name_acquired (GDBusConnection *bus,
547
gboolean xdmcp_enabled;
548
gboolean show_local_greeter;
550
manager = gdm_manager_new ();
551
if (manager == NULL) {
552
g_warning ("Could not construct manager object");
556
g_debug ("Successfully connected to D-Bus");
558
gdm_manager_start (manager);
560
show_local_greeter = TRUE;
561
gdm_settings_direct_get_boolean (GDM_KEY_SHOW_LOCAL_GREETER, &show_local_greeter);
562
gdm_manager_set_show_local_greeter (manager, show_local_greeter);
564
xdmcp_enabled = FALSE;
565
gdm_settings_direct_get_boolean (GDM_KEY_XDMCP_ENABLE, &xdmcp_enabled);
566
gdm_manager_set_xdmcp_enabled (manager, xdmcp_enabled);
570
on_name_lost (GDBusConnection *bus,
574
g_debug ("Lost GDM name on bus");
576
bus_connection_closed ();
582
GDBusConnection *bus;
587
bus = get_system_bus ();
592
name_id = g_bus_own_name_on_connection (bus,
594
G_BUS_NAME_OWNER_FLAGS_NONE,