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"),
149
ensure_dir_with_perms (const char *path,
155
gboolean ret = FALSE;
157
if (g_mkdir_with_parents (path, 0755) == -1) {
158
g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno), g_strerror (errno));
161
if (g_chmod (path, mode) == -1) {
162
g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno), g_strerror (errno));
165
if (chown (path, uid, gid) == -1) {
166
g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno), g_strerror (errno));
176
gdm_daemon_ensure_dirs (uid_t uid,
179
GError *error = NULL;
181
/* Set up /var/gdm */
182
if (!ensure_dir_with_perms (AUTHDIR, uid, gid, (S_IRWXU | S_IRWXG | S_ISVTX), &error)) {
183
gdm_fail (_("Failed to create AuthDir %s: %s"),
184
AUTHDIR, error->message);
187
/* Set up /var/log/gdm */
188
if (!ensure_dir_with_perms (LOGDIR, 0, gid, (S_IRWXU | S_IRWXG | S_ISVTX), &error)) {
189
gdm_fail (_("Failed to create LogDir %s: %s"),
190
LOGDIR, error->message);
195
gdm_daemon_lookup_user (uid_t *uidp,
202
struct passwd *pwent;
210
gdm_settings_direct_get_string (GDM_KEY_USER, &username);
211
gdm_settings_direct_get_string (GDM_KEY_GROUP, &groupname);
213
if (username == NULL || groupname == NULL) {
217
g_debug ("Changing user:group to %s:%s", username, groupname);
219
/* Lookup user and groupid for the GDM user */
220
gdm_get_pwent_for_name (username, &pwent);
222
/* Set uid and gid */
223
if G_UNLIKELY (pwent == NULL) {
224
gdm_fail (_("Can't find the GDM user '%s'. Aborting!"), username);
229
if G_UNLIKELY (uid == 0) {
230
gdm_fail (_("The GDM user should not be root. Aborting!"));
233
grent = getgrnam (groupname);
235
if G_UNLIKELY (grent == NULL) {
236
gdm_fail (_("Can't find the GDM group '%s'. Aborting!"), groupname);
241
if G_UNLIKELY (gid == 0) {
242
gdm_fail (_("The GDM group should not be root. Aborting!"));
258
signal_cb (int signo,
263
g_debug ("Got callback for signal %d", signo);
270
/* let the fatal signals interrupt us */
271
g_debug ("Caught signal %d, shutting down abnormally.", signo);
278
/* let the fatal signals interrupt us */
279
g_debug ("Caught signal %d, shutting down normally.", signo);
285
g_debug ("Got HUP signal");
286
/* Reread config stuff like system config files, VPN service
289
g_object_unref (settings);
290
settings = gdm_settings_new ();
291
if (settings != NULL) {
292
if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) {
293
g_warning ("Unable to initialize settings");
302
g_debug ("Got USR1 signal");
304
* Play with log levels or something
308
gdm_log_toggle_debug ();
313
g_debug ("Caught unhandled signal %d", signo);
325
gboolean debug = FALSE;
327
/* enable debugging for unstable builds */
328
if (gdm_is_version_unstable ()) {
332
gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug);
340
GMainLoop *main_loop;
341
GOptionContext *context;
342
GError *error = NULL;
345
GdmSignalHandler *signal_handler;
346
static gboolean do_timed_exit = FALSE;
347
static gboolean print_version = FALSE;
348
static gboolean fatal_warnings = FALSE;
349
static GOptionEntry entries [] = {
350
{ "fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &fatal_warnings, N_("Make all warnings fatal"), NULL },
351
{ "timed-exit", 0, 0, G_OPTION_ARG_NONE, &do_timed_exit, N_("Exit after a time (for debugging)"), NULL },
352
{ "version", 0, 0, G_OPTION_ARG_NONE, &print_version, N_("Print GDM version"), NULL },
357
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
358
textdomain (GETTEXT_PACKAGE);
359
setlocale (LC_ALL, "");
365
context = g_option_context_new (_("GNOME Display Manager"));
366
g_option_context_add_main_entries (context, entries, NULL);
367
g_option_context_set_ignore_unknown_options (context, TRUE);
370
res = g_option_context_parse (context, &argc, &argv, &error);
371
g_option_context_free (context);
373
g_warning ("%s", error->message);
374
g_error_free (error);
379
g_print ("GDM %s\n", VERSION);
383
if (fatal_warnings) {
384
GLogLevelFlags fatal_mask;
386
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
387
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
388
g_log_set_always_fatal (fatal_mask);
393
settings = gdm_settings_new ();
394
if (settings == NULL) {
395
g_warning ("Unable to initialize settings");
399
if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) {
400
g_warning ("Unable to initialize settings");
404
gdm_log_set_debug (is_debug_set ());
406
gdm_daemon_lookup_user (&gdm_uid, &gdm_gid);
408
gdm_daemon_ensure_dirs (gdm_uid, gdm_gid);
410
/* XDM compliant error message */
411
if (getuid () != 0) {
412
/* make sure the pid file doesn't get wiped */
413
g_warning (_("Only the root user can run GDM"));
417
/* Connect to the bus, own the name and start the manager */
426
main_loop = g_main_loop_new (NULL, FALSE);
428
signal_handler = gdm_signal_handler_new ();
429
gdm_signal_handler_set_fatal_func (signal_handler,
430
(GDestroyNotify)g_main_loop_quit,
432
gdm_signal_handler_add_fatal (signal_handler);
433
gdm_signal_handler_add (signal_handler, SIGTERM, signal_cb, NULL);
434
gdm_signal_handler_add (signal_handler, SIGINT, signal_cb, NULL);
435
gdm_signal_handler_add (signal_handler, SIGFPE, signal_cb, NULL);
436
gdm_signal_handler_add (signal_handler, SIGHUP, signal_cb, NULL);
437
gdm_signal_handler_add (signal_handler, SIGUSR1, signal_cb, NULL);
440
g_timeout_add_seconds (30, (GSourceFunc) timed_exit_cb, main_loop);
443
g_main_loop_run (main_loop);
445
g_debug ("GDM finished, cleaning up...");
447
g_clear_object (&manager);
448
g_clear_object (&settings);
449
g_clear_object (&signal_handler);
451
gdm_settings_direct_shutdown ();
454
g_main_loop_unref (main_loop);
460
g_printerr ("%s\n", error->message);
461
g_clear_error (&error);
467
on_name_acquired (GDBusConnection *bus,
471
gboolean xdmcp_enabled;
472
gboolean show_local_greeter;
474
manager = gdm_manager_new ();
475
if (manager == NULL) {
476
g_warning ("Could not construct manager object");
480
g_debug ("Successfully connected to D-Bus");
482
gdm_manager_start (manager);
484
show_local_greeter = TRUE;
485
gdm_settings_direct_get_boolean (GDM_KEY_SHOW_LOCAL_GREETER, &show_local_greeter);
486
gdm_manager_set_show_local_greeter (manager, show_local_greeter);
488
xdmcp_enabled = FALSE;
489
gdm_settings_direct_get_boolean (GDM_KEY_XDMCP_ENABLE, &xdmcp_enabled);
490
gdm_manager_set_xdmcp_enabled (manager, xdmcp_enabled);
494
on_name_lost (GDBusConnection *bus,
498
g_debug ("Lost GDM name on bus");
500
bus_connection_closed ();
506
GDBusConnection *bus;
511
bus = get_system_bus ();
516
name_id = g_bus_own_name_on_connection (bus,
518
G_BUS_NAME_OWNER_FLAGS_NONE,