~darkxst/ubuntu/saucy/gdm/lp1212408

« back to all changes in this revision

Viewing changes to daemon/slave.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2008-09-02 10:37:20 UTC
  • mfrom: (1.4.27 upstream)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: james.westby@ubuntu.com-20080902103720-p810vv530hqj45wg
Tags: 2.20.7-3
* Install the debian-moreblue-orbit theme, thanks Andre Luiz Rodrigues 
  Ferreira. Closes: #497440.
* 35_gdm.conf.patch: make it the default.
* copyright: fix encoding.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <login_cap.h>
36
36
#endif
37
37
#include <fcntl.h>
 
38
#if defined(HAVE_SYS_PARAM_H)
 
39
#include <sys/param.h>
 
40
#endif
38
41
#include <sys/types.h>
39
42
#include <sys/stat.h>
40
43
#include <sys/wait.h>
44
47
#include <sys/socket.h>
45
48
#include <netinet/in.h>
46
49
#include <arpa/inet.h>
 
50
#include <string.h>
 
51
#if defined(HAVE_UTMPX_H)
 
52
#include <utmpx.h>
 
53
#endif
 
54
#if defined(HAVE_UTMP_H)
 
55
#include <utmp.h>
 
56
#endif
 
57
#if defined(HAVE_LIBUTIL_H)
 
58
#include <libutil.h>
 
59
#endif
 
60
 
 
61
#if !defined (MAXPATHLEN) && defined (PATH_MAX)
 
62
#define MAXPATHLEN PATH_MAX
 
63
#elif !defined (MAXPATHLEN)
 
64
#error "MAXPATHLEN or PATH_MAX undefined"
 
65
#endif
47
66
 
48
67
#include <X11/Xlib.h>
49
68
#include <X11/Xatom.h>
 
69
 
50
70
#ifdef HAVE_XFREE_XINERAMA
51
71
#include <X11/extensions/Xinerama.h>
52
72
#elif HAVE_SOLARIS_XINERAMA
62
82
#include <grp.h>
63
83
#include <errno.h>
64
84
#include <time.h>
65
 
#include <syslog.h>
66
85
 
67
86
#ifdef HAVE_TSOL
68
87
#include <user_attr.h>
88
107
#include "getvt.h"
89
108
#include "errorgui.h"
90
109
#include "cookie.h"
91
 
#include "gdmconfig.h"
92
 
 
93
 
/* Some per slave globals */
94
 
static GdmDisplay *d = 0;
95
 
static gchar *login = NULL;
96
 
static gboolean greet = FALSE;
97
 
static gboolean configurator = FALSE;
98
 
static gboolean remanage_asap = FALSE;
99
 
static gboolean got_xfsz_signal = FALSE;
100
 
static gboolean do_timed_login = FALSE; /* if this is true,
101
 
                                           login the timed login */
102
 
static gboolean do_configurator = FALSE; /* if this is true, login as root
103
 
                                          * and start the configurator */
104
 
static gboolean do_cancel = FALSE; /* if this is true, go back to 
105
 
                                      username entry & unselect face
106
 
                                      browser (if present) */
107
 
static gboolean do_restart_greeter = FALSE; /* if this is true, whack the
108
 
                                               greeter and try again */
109
 
static gboolean restart_greeter_now = FALSE; /* restart_greeter_when the
110
 
                                                SIGCHLD hits */
111
 
static gboolean gdm_wait_for_ack = TRUE; /* wait for ack on all messages to
112
 
                                      * the daemon */
113
 
static int in_session_stop = 0;
114
 
static int in_usr2_signal = 0;
 
110
#include "display.h"
 
111
 
 
112
#include "gdm-common.h"
 
113
#include "gdm-log.h"
 
114
#include "gdm-daemon-config.h"
 
115
 
 
116
#include "gdm-socket-protocol.h"
 
117
 
 
118
#ifdef WITH_CONSOLE_KIT
 
119
#include "gdmconsolekit.h"
 
120
#endif
 
121
 
 
122
#ifndef GDM_BAD_RECORDS_FILE
 
123
#define GDM_BAD_RECORDS_FILE "/var/log/btmp"
 
124
#endif
 
125
 
 
126
#ifndef GDM_NEW_RECORDS_FILE
 
127
#define GDM_NEW_RECORDS_FILE "/var/log/wtmp"
 
128
#endif
 
129
 
 
130
/* Per-slave globals */
 
131
 
 
132
static GdmDisplay *d                   = 0;
 
133
static gchar *login_user               = NULL;
 
134
static gboolean greet                  = FALSE;
 
135
static gboolean configurator           = FALSE;
 
136
static gboolean remanage_asap          = FALSE;
 
137
static gboolean got_xfsz_signal        = FALSE;
 
138
static gboolean do_timed_login         = FALSE; /* If this is true, login the
 
139
                                                   timed login */
 
140
static gboolean do_configurator        = FALSE; /* If this is true, login as 
 
141
                                                 * root and start the
 
142
                                                 * configurator */
 
143
static gboolean do_cancel              = FALSE; /* If this is true, go back to
 
144
                                                   username entry & unselect
 
145
                                                   face browser (if present) */
 
146
static gboolean do_restart_greeter     = FALSE; /* If this is true, whack the
 
147
                                                   greeter and try again */
 
148
static gboolean restart_greeter_now    = FALSE; /* Restart_greeter_when the
 
149
                                                   SIGCHLD hits */
 
150
static gboolean always_restart_greeter = FALSE; /* Always restart greeter when
 
151
                                                   the user accepts restarts. */
 
152
static gboolean gdm_wait_for_ack       = TRUE;  /* Wait for ack on all messages
 
153
                                                   to the daemon */
 
154
static int in_session_stop             = 0;
 
155
static int in_usr2_signal              = 0;
115
156
static gboolean need_to_quit_after_session_stop = FALSE;
116
 
static int exit_code_to_use = DISPLAY_REMANAGE;
117
 
static gboolean session_started = FALSE;
118
 
static gboolean greeter_disabled = FALSE;
119
 
static gboolean greeter_no_focus = FALSE;
120
 
 
121
 
static uid_t logged_in_uid = -1;
122
 
static gid_t logged_in_gid = -1;
123
 
 
124
 
static gboolean interrupted = FALSE;
125
 
static gchar *ParsedAutomaticLogin = NULL;
126
 
static gchar *ParsedTimedLogin = NULL;
127
 
 
128
 
static int greeter_fd_out = -1;
129
 
static int greeter_fd_in = -1;
 
157
static int exit_code_to_use            = DISPLAY_REMANAGE;
 
158
static gboolean session_started        = FALSE;
 
159
static gboolean greeter_disabled       = FALSE;
 
160
static gboolean greeter_no_focus       = FALSE;
 
161
 
 
162
#ifdef __sun
 
163
/*
 
164
 * On Solaris uid_t and gid_t are unsigned ints, so you cannot
 
165
 * set them to -1.  These globals are just used for bookkeeping
 
166
 * so using a signed long works.
 
167
 */
 
168
static long logged_in_uid              = -1;
 
169
static long logged_in_gid              = -1;
 
170
#else
 
171
static uid_t logged_in_uid             = -1;
 
172
static gid_t logged_in_gid             = -1;
 
173
#endif
 
174
 
 
175
static int greeter_fd_out              = -1;
 
176
static int greeter_fd_in               = -1;
 
177
 
 
178
static gboolean interrupted            = FALSE;
 
179
static gchar *ParsedAutomaticLogin     = NULL;
 
180
static gchar *ParsedTimedLogin         = NULL;
 
181
 
 
182
static int gdm_in_signal               = 0;
 
183
static int gdm_normal_runlevel         = -1;
 
184
static pid_t extra_process             = 0;
 
185
static int extra_status                = 0;
130
186
 
131
187
#ifdef HAVE_TSOL
132
188
static gboolean have_suntsol_extension = FALSE;
133
189
#endif
134
190
 
135
 
typedef struct {
136
 
        pid_t pid;
137
 
} GdmWaitPid;
138
 
 
139
 
static int slave_waitpid_r = -1;
140
 
static int slave_waitpid_w = -1;
141
 
static GSList *slave_waitpids = NULL;
 
191
static int slave_waitpid_r             = -1;
 
192
static int slave_waitpid_w             = -1;
 
193
static GSList *slave_waitpids          = NULL;
142
194
 
143
195
extern gboolean gdm_first_login;
144
 
extern gboolean gdm_emergency_server;
145
 
extern pid_t extra_process;
146
 
extern int extra_status;
147
 
extern int gdm_in_signal;
148
 
extern int gdm_normal_runlevel;
149
196
 
150
 
extern int slave_fifo_pipe_fd; /* the slavepipe (like fifo) connection, this is the write end */
 
197
/* The slavepipe (like fifo) connection, this is the write end */
 
198
extern int slave_fifo_pipe_fd;
151
199
 
152
200
/* wait for a GO in the SOP protocol */
153
201
extern gboolean gdm_wait_for_go;
154
202
 
 
203
extern char *gdm_system_locale;
 
204
 
 
205
typedef struct {
 
206
        pid_t pid;
 
207
} GdmWaitPid;
 
208
 
155
209
/* Local prototypes */
156
 
static gint     gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt);
157
 
static gint     gdm_slave_xioerror_handler (Display *disp);
158
 
static gint     gdm_slave_ignore_xioerror_handler (Display *disp);
159
 
static void     gdm_slave_run (GdmDisplay *display);
160
 
static void     gdm_slave_wait_for_login (void);
161
 
static void     gdm_slave_greeter (void);
162
 
static void     gdm_slave_chooser (void);
163
 
static void     gdm_slave_session_start (void);
164
 
static void     gdm_slave_session_stop (gboolean run_post_session,
 
210
static gint   gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt);
 
211
static gint   gdm_slave_xioerror_handler (Display *disp);
 
212
static void   gdm_slave_run (GdmDisplay *display);
 
213
static void   gdm_slave_wait_for_login (void);
 
214
static void   gdm_slave_greeter (void);
 
215
static void   gdm_slave_chooser (void);
 
216
static void   gdm_slave_session_start (void);
 
217
static void   gdm_slave_session_stop (gboolean run_post_session,
165
218
                                        gboolean no_shutdown_check);
166
 
static void     gdm_slave_alrm_handler (int sig);
167
 
static void     gdm_slave_term_handler (int sig);
168
 
static void     gdm_slave_usr2_handler (int sig);
169
 
static void     gdm_slave_quick_exit (gint status);
170
 
static void     gdm_slave_exit (gint status, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
171
 
static void     gdm_child_exit (gint status, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
172
 
static gint     gdm_slave_exec_script (GdmDisplay *d, const gchar *dir,
 
219
static void   gdm_slave_alrm_handler (int sig);
 
220
static void   gdm_slave_term_handler (int sig);
 
221
static void   gdm_slave_usr2_handler (int sig);
 
222
static void   gdm_slave_quick_exit (gint status);
 
223
static void   gdm_slave_exit (gint status, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
 
224
static void   gdm_child_exit (gint status, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
 
225
static gint   gdm_slave_exec_script (GdmDisplay *d, const gchar *dir,
173
226
                                       const char *login, struct passwd *pwent,
174
227
                                       gboolean pass_stdout);
175
 
static gchar *  gdm_parse_enriched_login (const gchar *s, GdmDisplay *display);
176
 
static void     gdm_slave_handle_usr2_message (void);
177
 
static void     gdm_slave_handle_notify (const char *msg);
178
 
static void     create_temp_auth_file (void);
179
 
static void     set_xnest_parent_stuff (void);
180
 
static void     check_notifies_now (void);
181
 
static void     restart_the_greeter (void);
 
228
static gchar *gdm_slave_parse_enriched_login (GdmDisplay *d, const gchar *s);
 
229
static void   gdm_slave_handle_usr2_message (void);
 
230
static void   gdm_slave_handle_notify (const char *msg);
 
231
static void   create_temp_auth_file (void);
 
232
static void   set_xnest_parent_stuff (void);
 
233
static void   check_notifies_now (void);
 
234
static void   restart_the_greeter (void);
182
235
 
183
236
#ifdef HAVE_TSOL
184
237
static gboolean gdm_can_i_assume_root_role (struct passwd *pwent);
190
243
static gboolean x_error_occurred = FALSE;
191
244
static gboolean gdm_got_ack = FALSE;
192
245
static char * gdm_ack_response = NULL;
 
246
char * gdm_ack_question_response = NULL;
193
247
static GList *unhandled_notifies = NULL;
194
248
 
195
 
 
196
249
/* for signals that want to exit */
197
250
static Jmp_buf slave_start_jmp;
198
 
/* for handling xioerror during ctl-alt-bs */
199
 
static Jmp_buf ignore_xioerror_jmp;
200
251
static gboolean return_to_slave_start_jmp = FALSE;
201
252
static gboolean already_in_slave_start_jmp = FALSE;
202
253
static char *slave_start_jmp_error_to_print = NULL;
205
256
        JMP_SESSION_STOP_AND_QUIT = 1,
206
257
        JMP_JUST_QUIT_QUICKLY = 2
207
258
};
 
259
#define DEFAULT_LANGUAGE "Default"
208
260
#define SIGNAL_EXIT_WITH_JMP(d,how) \
209
261
   {                                                                                    \
210
262
        if ((d)->slavepid == getpid () && return_to_slave_start_jmp) {                  \
219
271
        }                                                                               \
220
272
   }
221
273
 
222
 
/* notify all waitpids, make waitpids check notifies */
 
274
/* Notify all waitpids, make waitpids check notifies */
223
275
static void
224
276
slave_waitpid_notify (void)
225
277
{
235
287
        gdm_sigchld_block_pop ();
236
288
}
237
289
 
238
 
/* make sure to wrap this call with sigchld blocks */
 
290
/* Make sure to wrap this call with sigchld blocks */
239
291
static GdmWaitPid *
240
292
slave_waitpid_setpid (pid_t pid)
241
293
{
268
320
        int r, written;
269
321
        uid_t old;
270
322
        gid_t oldg;
271
 
        
 
323
 
272
324
        old = geteuid ();
273
325
        oldg = getegid ();
274
326
 
348
400
                if G_UNLIKELY (d->xsession_errors_bytes >= MAX_XSESSION_ERRORS_BYTES &&
349
401
                               ! got_xfsz_signal) {
350
402
                        VE_IGNORE_EINTR (write (d->xsession_errors_fd,
351
 
                                             "\n...Too much output, ignoring rest...\n",
352
 
                                             strlen ("\n...Too much output, ignoring rest...\n")));
 
403
                                                "\n...Too much output, ignoring rest...\n",
 
404
                                                strlen ("\n...Too much output, ignoring rest...\n")));
353
405
                }
354
406
 
355
407
                /* there wasn't more then buf available, so no need to try reading
645
697
        /* only if we're not hanging in session stop and getting a
646
698
           TERM signal again */
647
699
        if (in_session_stop == 0 && session_started)
648
 
                gdm_slave_session_stop (d->logged_in && login != NULL,
 
700
                gdm_slave_session_stop (d->logged_in && login_user != NULL,
649
701
                                        TRUE /* no_shutdown_check */);
650
702
 
651
703
        gdm_debug ("term_session_stop_and_quit: Final cleanup");
714
766
}
715
767
#endif /* SIGXFSZ */
716
768
 
717
 
void 
 
769
 
 
770
static int
 
771
get_runlevel (void)
 
772
{
 
773
        int rl;
 
774
 
 
775
        rl = -1;
 
776
#ifdef __linux__
 
777
        /* on linux we get our current runlevel, for use later
 
778
         * to detect a shutdown going on, and not mess up. */
 
779
        if (g_access ("/sbin/runlevel", X_OK) == 0) {
 
780
                char ign;
 
781
                int rnl;
 
782
                FILE *fp = popen ("/sbin/runlevel", "r");
 
783
                if (fp != NULL) {
 
784
                        if (fscanf (fp, "%c %d", &ign, &rnl) == 2) {
 
785
                                rl = rnl;
 
786
                        }
 
787
                        pclose (fp);
 
788
                }
 
789
        }
 
790
#endif /* __linux__ */
 
791
        return rl;
 
792
}
 
793
 
 
794
void
718
795
gdm_slave_start (GdmDisplay *display)
719
 
{  
 
796
{
720
797
        time_t first_time;
721
798
        int death_count;
722
799
        struct sigaction alrm, term, child, usr2;
724
801
        struct sigaction xfsz;
725
802
#endif /* SIGXFSZ */
726
803
        sigset_t mask;
727
 
        int pinginterval = gdm_get_value_int (GDM_KEY_PING_INTERVAL);
 
804
        int pinginterval = gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL);
728
805
 
729
806
        /*
730
807
         * Set d global to display before setting signal handlers,
734
811
         */
735
812
        d = display;
736
813
 
 
814
        gdm_normal_runlevel = get_runlevel ();
 
815
 
737
816
        /* Ignore SIGUSR1/SIGPIPE, and especially ignore it
738
817
           before the Setjmp */
739
818
        gdm_signal_ignore (SIGUSR1);
814
893
        sigemptyset (&child.sa_mask);
815
894
        sigaddset (&child.sa_mask, SIGCHLD);
816
895
 
817
 
        if G_UNLIKELY (sigaction (SIGCHLD, &child, NULL) < 0) 
 
896
        if G_UNLIKELY (sigaction (SIGCHLD, &child, NULL) < 0)
818
897
                gdm_slave_exit (DISPLAY_ABORT, _("%s: Error setting up %s signal handler: %s"),
819
898
                                "gdm_slave_start", "CHLD", strerror (errno));
820
899
 
874
953
 
875
954
                gdm_debug ("gdm_slave_start: Reinitializing things");
876
955
 
877
 
                if (gdm_get_value_bool (GDM_KEY_ALWAYS_RESTART_SERVER)) {
878
 
                        /* Whack the server if we want to restart it next time
879
 
                         * we run gdm_slave_run */
880
 
                        gdm_server_stop (display);
881
 
                        gdm_slave_send_num (GDM_SOP_XPID, 0);
882
 
                } else {
883
 
                        /* OK about to start again so rebake our cookies and reinit
884
 
                         * the server */
885
 
                        if G_UNLIKELY ( ! gdm_auth_secure_display (d)) {
886
 
                                gdm_slave_quick_exit (DISPLAY_REMANAGE);
887
 
                        }
888
 
                        gdm_slave_send_string (GDM_SOP_COOKIE, d->cookie);
889
 
                        gdm_slave_send_string (GDM_SOP_AUTHFILE, d->authfile);
890
 
 
891
 
                        if G_UNLIKELY ( ! gdm_server_reinit (d)) {
892
 
                                gdm_error ("Error reinitilizing server");
893
 
                                gdm_slave_quick_exit (DISPLAY_REMANAGE);
894
 
                        }
895
 
                }
 
956
                /* Whack the server because we want to restart it next
 
957
                 * time we run gdm_slave_run */
 
958
                gdm_server_stop (display);
 
959
                gdm_slave_send_num (GDM_SOP_XPID, 0);
896
960
        }
897
961
        /* very very very evil, should never break, we can't return from
898
962
           here sanely */
903
967
setup_automatic_session (GdmDisplay *display, const char *name)
904
968
{
905
969
        char *new_login;
906
 
        g_free (login);
907
 
        login = g_strdup (name);
 
970
        g_free (login_user);
 
971
        login_user = g_strdup (name);
908
972
 
909
973
        greet = FALSE;
910
 
        gdm_debug ("setup_automatic_session: Automatic login: %s", login);
 
974
        gdm_debug ("setup_automatic_session: Automatic login: %s", login_user);
911
975
 
912
976
        /* Run the init script. gdmslave suspends until script
913
977
         * has terminated */
914
 
        gdm_slave_exec_script (display, gdm_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
 
978
        gdm_slave_exec_script (display, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
915
979
                               NULL, NULL, FALSE /* pass_stdout */);
916
980
 
917
981
        gdm_debug ("setup_automatic_session: DisplayInit script finished");
918
982
 
919
983
        new_login = NULL;
920
 
        if ( ! gdm_verify_setup_user (display, login,
921
 
                                      display->name, &new_login))
 
984
        if ( ! gdm_verify_setup_user (display, login_user, &new_login))
922
985
                return FALSE;
923
986
 
924
987
        if (new_login != NULL) {
925
 
                g_free (login);
926
 
                login = g_strdup (new_login);
 
988
                g_free (login_user);
 
989
                login_user = g_strdup (new_login);
927
990
        }
928
991
 
929
992
        gdm_debug ("setup_automatic_session: Automatic login successful");
941
1004
        int firsterror;
942
1005
 
943
1006
        have_suntsol_extension = XQueryExtension (display->dsp,
944
 
                        "SUN_TSOL",
945
 
                        &opcode,
946
 
                        &firstevent,
947
 
                        &firsterror);
 
1007
                                                  "SUN_TSOL",
 
1008
                                                  &opcode,
 
1009
                                                  &firstevent,
 
1010
                                                  &firsterror);
948
1011
}
949
1012
#endif
950
1013
 
951
 
static void 
952
 
gdm_screen_init (GdmDisplay *display) 
 
1014
static void
 
1015
gdm_screen_init (GdmDisplay *display)
953
1016
{
954
1017
#ifdef HAVE_XFREE_XINERAMA
955
1018
        int (* old_xerror_handler) (Display *, XErrorEvent *);
977
1040
                if G_UNLIKELY (screen_num <= 0)
978
1041
                        gdm_fail ("Xinerama active, but <= 0 screens?");
979
1042
 
980
 
                if (screen_num <= gdm_get_value_int (GDM_KEY_XINERAMA_SCREEN))
981
 
                        gdm_set_value_int (GDM_KEY_XINERAMA_SCREEN, 0);
 
1043
                if (screen_num <= gdm_daemon_config_get_value_int (GDM_KEY_XINERAMA_SCREEN))
 
1044
                        gdm_daemon_config_set_value_int (GDM_KEY_XINERAMA_SCREEN, 0);
982
1045
 
983
 
                xineramascreen = gdm_get_value_int (GDM_KEY_XINERAMA_SCREEN);
 
1046
                xineramascreen = gdm_daemon_config_get_value_int (GDM_KEY_XINERAMA_SCREEN);
984
1047
 
985
1048
                display->screenx = xscreens[xineramascreen].x_org;
986
1049
                display->screeny = xscreens[xineramascreen].y_org;
999
1062
                XFree (xscreens);
1000
1063
        } else
1001
1064
#elif HAVE_SOLARIS_XINERAMA
1002
 
 /* This code from GDK, Copyright (C) 2002 Sun Microsystems */
1003
 
        int opcode;
 
1065
                /* This code from GDK, Copyright (C) 2002 Sun Microsystems, Inc. */
 
1066
                int opcode;
1004
1067
        int firstevent;
1005
1068
        int firsterror;
1006
1069
        int n_monitors = 0;
1007
1070
 
1008
1071
        gboolean have_xinerama = FALSE;
1009
1072
        have_xinerama = XQueryExtension (display->dsp,
1010
 
                        "XINERAMA",
1011
 
                        &opcode,
1012
 
                        &firstevent,
1013
 
                        &firsterror);
 
1073
                                         "XINERAMA",
 
1074
                                         &opcode,
 
1075
                                         &firstevent,
 
1076
                                         &firsterror);
1014
1077
 
1015
1078
        if (have_xinerama) {
1016
 
        
 
1079
 
1017
1080
                int result;
1018
1081
                XRectangle monitors[MAXFRAMEBUFFERS];
1019
1082
                unsigned char  hints[16];
1020
1083
                int xineramascreen;
1021
 
                
 
1084
 
1022
1085
                result = XineramaGetInfo (display->dsp, 0, monitors, hints, &n_monitors);
1023
 
                /* Yes I know it should be Success but the current implementation 
 
1086
                /* Yes I know it should be Success but the current implementation
1024
1087
                 * returns the num of monitor
1025
1088
                 */
1026
1089
                if G_UNLIKELY (result <= 0)
1027
1090
                        gdm_fail ("Xinerama active, but <= 0 screens?");
1028
1091
 
1029
 
                if (n_monitors <= gdm_get_value_int (GDM_KEY_XINERAMA_SCREEN))
1030
 
                        gdm_set_value_int (GDM_KEY_XINERAMA_SCREEN, 0);
 
1092
                if (n_monitors <= gdm_daemon_config_get_value_int (GDM_KEY_XINERAMA_SCREEN))
 
1093
                        gdm_daemon_config_set_value_int (GDM_KEY_XINERAMA_SCREEN, 0);
1031
1094
 
1032
 
                xineramascreen = gdm_get_value_int (GDM_KEY_XINERAMA_SCREEN);
 
1095
                xineramascreen = gdm_daemon_config_get_value_int (GDM_KEY_XINERAMA_SCREEN);
1033
1096
                display->screenx = monitors[xineramascreen].x;
1034
1097
                display->screeny = monitors[xineramascreen].y;
1035
1098
                display->screenwidth = monitors[xineramascreen].width;
1046
1109
 
1047
1110
        } else
1048
1111
#endif
1049
 
        {
1050
 
                display->screenx = 0;
1051
 
                display->screeny = 0;
1052
 
                display->screenwidth = 0; /* we'll use the gdk size */
1053
 
                display->screenheight = 0;
1054
 
 
1055
 
                display->lrh_offsetx = 0;
1056
 
                display->lrh_offsety = 0;
 
1112
                {
 
1113
                        display->screenx = 0;
 
1114
                        display->screeny = 0;
 
1115
                        display->screenwidth = 0; /* we'll use the gdk size */
 
1116
                        display->screenheight = 0;
 
1117
 
 
1118
                        display->lrh_offsetx = 0;
 
1119
                        display->lrh_offsety = 0;
 
1120
                }
 
1121
}
 
1122
 
 
1123
static void
 
1124
gdm_window_path (GdmDisplay *d)
 
1125
{
 
1126
        /* setting WINDOWPATH for clients */
 
1127
        const char *windowpath;
 
1128
        char *newwindowpath;
 
1129
        char nums[10];
 
1130
        int numn;
 
1131
 
 
1132
        if (d->vtnum != -1) {
 
1133
                windowpath = getenv ("WINDOWPATH");
 
1134
                numn = snprintf (nums, sizeof (nums), "%d", d->vtnum);
 
1135
                if (!windowpath) {
 
1136
                        newwindowpath = malloc (numn + 1);
 
1137
                        sprintf (newwindowpath, "%s", nums);
 
1138
                } else {
 
1139
                        newwindowpath = malloc (strlen (windowpath) + 1 + numn + 1);
 
1140
                        sprintf (newwindowpath, "%s:%s", windowpath, nums);
 
1141
                }
 
1142
                free (d->windowpath);
 
1143
                d->windowpath = newwindowpath;
1057
1144
        }
1058
1145
}
1059
1146
 
1131
1218
        int   r;
1132
1219
        char *msg;
1133
1220
        char *but[4];
 
1221
        char *askbuttons_msg;
 
1222
 
 
1223
        /*
 
1224
         * If migratable and ALWAYS_LOGIN_CURRENT_SESSION is true, then avoid 
 
1225
         * the dialog.
 
1226
         */
 
1227
        if (migrate_to != NULL &&
 
1228
            gdm_daemon_config_get_value_bool (GDM_KEY_ALWAYS_LOGIN_CURRENT_SESSION)) {
 
1229
                return 1;
 
1230
        }
 
1231
 
 
1232
        /*
 
1233
         * Avoid dialog if DOUBLE_LOGIN_WARNING is false.  In this case
 
1234
         * ALWAYS_LOGIN_CURRENT_SESSION is false, so assume new session.
 
1235
         */
 
1236
        if (!gdm_daemon_config_get_value_bool (GDM_KEY_DOUBLE_LOGIN_WARNING)) {
 
1237
                return 0;
 
1238
        }
1134
1239
 
1135
1240
        but[0] = _("Log in anyway");
1136
1241
        if (migrate_to != NULL) {
1140
1245
                        "login");
1141
1246
                but[1] = _("Return to previous login");
1142
1247
                but[2] = _("Abort login");
1143
 
                but[3] = NULL;
 
1248
                but[3] = "NIL";
1144
1249
        } else {
1145
1250
                msg = _("You are already logged in.  "
1146
1251
                        "You can log in anyway or abort this "
1147
1252
                        "login");
1148
1253
                but[1] = _("Abort login");
1149
 
                but[2] = NULL;
 
1254
                but[2] = "NIL";
 
1255
                but[3] = "NIL";
1150
1256
        }
1151
1257
 
1152
1258
        if (greet)
1153
1259
                gdm_slave_greeter_ctl_no_ret (GDM_DISABLE, "");
1154
1260
 
1155
 
        r = gdm_failsafe_ask_buttons (d, msg, but);
 
1261
        askbuttons_msg = g_strdup_printf ("askbuttons_msg=%s$$options_msg1=%s$$options_msg2=%s$$options_msg3=%s$$options_msg4=%s", msg, but[0], but[1], but[2], but[3]);
 
1262
 
 
1263
 
 
1264
        gdm_slave_send_string (GDM_SOP_SHOW_ASKBUTTONS_DIALOG, askbuttons_msg);
 
1265
 
 
1266
        r = atoi (gdm_ack_response);
 
1267
 
 
1268
        g_free (askbuttons_msg);
 
1269
        g_free (gdm_ack_response);
 
1270
        gdm_ack_response = NULL;
1156
1271
 
1157
1272
        if (greet)
1158
1273
                gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, "");
1177
1292
 
1178
1293
        gdm_slave_send_string (GDM_SOP_QUERYLOGIN, user);
1179
1294
        if G_LIKELY (ve_string_empty (gdm_ack_response))
1180
 
               return TRUE;     
 
1295
                return TRUE;
1181
1296
        vec = g_strsplit (gdm_ack_response, ",", -1);
1182
1297
        if (vec == NULL)
1183
1298
                return TRUE;
1201
1316
        if (d->type != TYPE_XDMCP_PROXY) {
1202
1317
                int r;
1203
1318
 
1204
 
                if (!gdm_get_value_bool (GDM_KEY_DOUBLE_LOGIN_WARNING)) {
1205
 
                        g_free (migrate_to);
1206
 
                        return TRUE;
1207
 
                }
1208
 
 
1209
 
                if (gdm_get_value_bool (GDM_KEY_ALWAYS_LOGIN_CURRENT_SESSION))
1210
 
                        r = 1;
1211
 
                else
1212
 
                        r = ask_migrate (migrate_to);
 
1319
                r = ask_migrate (migrate_to);
1213
1320
 
1214
1321
                if (r <= 0) {
1215
1322
                        g_free (migrate_to);
1216
1323
                        return TRUE;
1217
1324
                }
1218
1325
 
 
1326
                /*
 
1327
                 * migrate_to should never be NULL here, since
 
1328
                 * ask_migrate will always return 0 or 1 if migrate_to
 
1329
                 * is NULL.
 
1330
                 */
1219
1331
                if (migrate_to == NULL ||
1220
1332
                    (migrate_to != NULL && r == 2)) {
1221
1333
                        g_free (migrate_to);
1222
1334
                        return FALSE;
1223
1335
                }
1224
1336
 
1225
 
                /* Must be that r == 1, that is
1226
 
                   return to previous login */
 
1337
                /* Must be that r == 1, that is return to previous login */
1227
1338
 
1228
1339
                if (d->type == TYPE_FLEXI) {
1229
1340
                        gdm_slave_whack_greeter ();
1233
1344
                        /* wait for a few seconds to avoid any vt changing race
1234
1345
                         */
1235
1346
                        gdm_sleep_no_signal (1);
1236
 
 
1237
 
                        gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
1238
 
                        g_free (migrate_to);
1239
 
 
 
1347
                }
 
1348
 
 
1349
#ifdef WITH_CONSOLE_KIT
 
1350
                unlock_ck_session (user, migrate_to);
 
1351
#endif
 
1352
                gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
 
1353
                g_free (migrate_to);
 
1354
 
 
1355
                if (d->type == TYPE_FLEXI) {
1240
1356
                        /* we are no longer needed so just die.
1241
1357
                           REMANAGE == ABORT here really */
1242
1358
                        gdm_slave_quick_exit (DISPLAY_REMANAGE);
1243
1359
                }
1244
 
 
1245
 
                gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
1246
 
                g_free (migrate_to);
1247
1360
        } else {
1248
1361
                Display *parent_dsp;
1249
1362
 
1250
1363
                if (migrate_to == NULL)
1251
1364
                        return TRUE;
1252
 
                
 
1365
 
1253
1366
                gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
1254
1367
                g_free (migrate_to);
1255
1368
 
1281
1394
 
1282
1395
static gboolean do_xfailed_on_xio_error = FALSE;
1283
1396
 
1284
 
static void 
 
1397
static void
1285
1398
gdm_slave_run (GdmDisplay *display)
1286
 
{  
1287
 
    gint openretries = 0;
1288
 
    gint maxtries = 0;
1289
 
    gint pinginterval = gdm_get_value_int (GDM_KEY_PING_INTERVAL);
1290
 
    
1291
 
    /* Reset d since gdm_slave_run is called in a loop */
1292
 
    d = display;
1293
 
 
1294
 
    gdm_random_tick ();
1295
 
 
1296
 
    if (d->sleep_before_run > 0) {
1297
 
            gdm_debug ("gdm_slave_run: Sleeping %d seconds before server start", d->sleep_before_run);
1298
 
            gdm_sleep_no_signal (d->sleep_before_run);
1299
 
            d->sleep_before_run = 0;
1300
 
 
1301
 
            check_notifies_now ();
1302
 
    }
1303
 
 
1304
 
    /* set it before we run the server, it may be that we're using
1305
 
     * the XOpenDisplay to find out if a server is ready (as with Xnest) */
1306
 
    d->dsp = NULL;
1307
 
 
1308
 
    /* if this is local display start a server if one doesn't
1309
 
     * exist */
1310
 
    if (SERVER_IS_LOCAL (d) &&
1311
 
        d->servpid <= 0) {
1312
 
            if G_UNLIKELY ( ! gdm_server_start (d,
1313
 
                                                TRUE /* try_again_if_busy */,
1314
 
                                                FALSE /* treat_as_flexi */,
1315
 
                                                20 /* min_flexi_disp */,
1316
 
                                                5 /* flexi_retries */)) {
1317
 
                    /* We're really not sure what is going on,
1318
 
                     * so we throw up our hands and tell the user
1319
 
                     * that we've given up.  The error is likely something
1320
 
                     * internal. */
1321
 
                    gdm_text_message_dialog
1322
 
                            (C_(N_("Could not start the X\n"
1323
 
                                   "server (your graphical environment)\n"
1324
 
                                   "due to some internal error.\n"
1325
 
                                   "Please contact your system administrator\n"
1326
 
                                   "or check your syslog to diagnose.\n"
1327
 
                                   "In the meantime this display will be\n"
1328
 
                                   "disabled.  Please restart GDM when\n"
1329
 
                                   "the problem is corrected.")));
1330
 
                    gdm_slave_quick_exit (DISPLAY_ABORT);
1331
 
            }
1332
 
            gdm_slave_send_num (GDM_SOP_XPID, d->servpid);
1333
 
 
1334
 
            check_notifies_now ();
1335
 
    }
1336
 
 
1337
 
    /* We can use d->handled from now on on this display,
1338
 
     * since the lookup was done in server start */
1339
 
    
1340
 
    g_setenv ("DISPLAY", d->name, TRUE);
1341
 
    g_unsetenv ("XAUTHORITY"); /* just in case it's set */
1342
 
 
1343
 
    gdm_auth_set_local_auth (d);
1344
 
 
1345
 
    if (d->handled) {
1346
 
            /* Now the display name and hostname is final */
1347
 
 
1348
 
            char *automaticlogin = gdm_get_value_string (GDM_KEY_AUTOMATIC_LOGIN);
1349
 
            char *timedlogin     = gdm_get_value_string (GDM_KEY_TIMED_LOGIN);
1350
 
 
1351
 
            if (gdm_get_value_bool (GDM_KEY_AUTOMATIC_LOGIN_ENABLE) && 
1352
 
                ! ve_string_empty (automaticlogin)) {
1353
 
                    g_free (ParsedAutomaticLogin);
1354
 
                    ParsedAutomaticLogin = gdm_parse_enriched_login (automaticlogin,
1355
 
                                                                     display);
1356
 
            }
1357
 
 
1358
 
            if (gdm_get_value_bool (GDM_KEY_TIMED_LOGIN_ENABLE) &&
1359
 
                ! ve_string_empty (timedlogin)) {
1360
 
                    g_free (ParsedTimedLogin);
1361
 
                    ParsedTimedLogin = gdm_parse_enriched_login (timedlogin,
1362
 
                                                                 display);
1363
 
            }
1364
 
    }
1365
 
    
1366
 
    /* X error handlers to avoid the default one (i.e. exit (1)) */
1367
 
    do_xfailed_on_xio_error = TRUE;
1368
 
    XSetErrorHandler (gdm_slave_xerror_handler);
1369
 
    XSetIOErrorHandler (gdm_slave_xioerror_handler);
1370
 
    
1371
 
    /* We keep our own (windowless) connection (dsp) open to avoid the
1372
 
     * X server resetting due to lack of active connections. */
1373
 
 
1374
 
    gdm_debug ("gdm_slave_run: Opening display %s", d->name);
1375
 
 
1376
 
    /* if local then the the server should be ready for openning, so
1377
 
     * don't try so long before killing it and trying again */
1378
 
    if (SERVER_IS_LOCAL (d))
1379
 
            maxtries = 2;
1380
 
    else
1381
 
            maxtries = 10;
1382
 
    
1383
 
    while (d->handled &&
1384
 
           openretries < maxtries &&
1385
 
           d->dsp == NULL &&
1386
 
           ( ! SERVER_IS_LOCAL (d) || d->servpid > 1)) {
1387
 
        d->dsp = XOpenDisplay (d->name);
1388
 
        
1389
 
        if G_UNLIKELY (d->dsp == NULL) {
1390
 
            gdm_debug ("gdm_slave_run: Sleeping %d on a retry", 1+openretries*2);
1391
 
            gdm_sleep_no_signal (1+openretries*2);
1392
 
            openretries++;
1393
 
        }
1394
 
    }
1395
 
 
1396
 
    /* Really this will only be useful for the first local server,
1397
 
       since that's the only time this can really be on */
1398
 
    while G_UNLIKELY (gdm_wait_for_go) {
1399
 
            struct timeval tv;
1400
 
            /* Wait 1 second. */
1401
 
            tv.tv_sec = 1;
1402
 
            tv.tv_usec = 0;
1403
 
            select (0, NULL, NULL, NULL, &tv);
1404
 
            /* don't want to use sleep since we're using alarm
1405
 
               for pinging */
1406
 
            check_notifies_now ();
1407
 
    }
1408
 
 
1409
 
    /* Set the busy cursor */
1410
 
    if (d->dsp != NULL) {
1411
 
            Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH);
1412
 
            XDefineCursor (d->dsp,
1413
 
                           DefaultRootWindow (d->dsp),
1414
 
                           xcursor);
1415
 
            XFreeCursor (d->dsp, xcursor);
1416
 
            XSync (d->dsp, False);
1417
 
    }
1418
 
 
1419
 
    /* Just a race avoiding sleep, probably not necessary though,
1420
 
     * but doesn't hurt anything */
1421
 
    if ( ! d->handled)
1422
 
            gdm_sleep_no_signal (1);
1423
 
 
1424
 
    if (SERVER_IS_LOCAL (d)) {
1425
 
            gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE);
1426
 
    }
1427
 
 
1428
 
    check_notifies_now ();
1429
 
 
1430
 
    /* something may have gone wrong, try xfailed, if local (non-flexi),
1431
 
     * the toplevel loop of death will handle us */ 
1432
 
    if G_UNLIKELY (d->handled && d->dsp == NULL) {
1433
 
            if (d->type == TYPE_STATIC)
1434
 
                    gdm_slave_quick_exit (DISPLAY_XFAILED);
1435
 
            else
1436
 
                    gdm_slave_quick_exit (DISPLAY_ABORT);
1437
 
    }
1438
 
 
1439
 
    /* OK from now on it's really the user whacking us most likely,
1440
 
     * we have already started up well */
1441
 
    do_xfailed_on_xio_error = FALSE;
1442
 
 
1443
 
    /* If XDMCP setup pinging */
1444
 
    if ( ! SERVER_IS_LOCAL (d) && pinginterval > 0) {
1445
 
            alarm (pinginterval);
1446
 
    }
1447
 
 
1448
 
    /* checkout xinerama */
1449
 
    if (d->handled)
1450
 
            gdm_screen_init (d);
 
1399
{
 
1400
        gint openretries = 0;
 
1401
        gint maxtries = 0;
 
1402
        gint pinginterval = gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL);
 
1403
 
 
1404
        gdm_reset_locale ();
 
1405
 
 
1406
        /* Reset d since gdm_slave_run is called in a loop */
 
1407
        d = display;
 
1408
 
 
1409
        gdm_random_tick ();
 
1410
 
 
1411
        if (d->sleep_before_run > 0) {
 
1412
                gdm_debug ("gdm_slave_run: Sleeping %d seconds before server start", d->sleep_before_run);
 
1413
                gdm_sleep_no_signal (d->sleep_before_run);
 
1414
                d->sleep_before_run = 0;
 
1415
 
 
1416
                check_notifies_now ();
 
1417
        }
 
1418
 
 
1419
        /*
 
1420
         * Set it before we run the server, it may be that we're using
 
1421
         * the XOpenDisplay to find out if a server is ready (as with
 
1422
         * nested display)
 
1423
         */
 
1424
        d->dsp = NULL;
 
1425
 
 
1426
        /* if this is local display start a server if one doesn't
 
1427
         * exist */
 
1428
        if (SERVER_IS_LOCAL (d) &&
 
1429
            d->servpid <= 0) {
 
1430
                if G_UNLIKELY ( ! gdm_server_start (d,
 
1431
                                                    TRUE /* try_again_if_busy */,
 
1432
                                                    FALSE /* treat_as_flexi */,
 
1433
                                                    20 /* min_flexi_disp */,
 
1434
                                                    5 /* flexi_retries */)) {
 
1435
                        /* We're really not sure what is going on,
 
1436
                         * so we throw up our hands and tell the user
 
1437
                         * that we've given up.  The error is likely something
 
1438
                         * internal. */
 
1439
                        gdm_text_message_dialog
 
1440
                                (C_(N_("Could not start the X\n"
 
1441
                                       "server (your graphical environment)\n"
 
1442
                                       "due to some internal error.\n"
 
1443
                                       "Please contact your system administrator\n"
 
1444
                                       "or check your syslog to diagnose.\n"
 
1445
                                       "In the meantime this display will be\n"
 
1446
                                       "disabled.  Please restart GDM when\n"
 
1447
                                       "the problem is corrected.")));
 
1448
                        gdm_slave_quick_exit (DISPLAY_ABORT);
 
1449
                }
 
1450
                gdm_slave_send_num (GDM_SOP_XPID, d->servpid);
 
1451
 
 
1452
                check_notifies_now ();
 
1453
        }
 
1454
 
 
1455
        /* We can use d->handled from now on on this display,
 
1456
         * since the lookup was done in server start */
 
1457
 
 
1458
        g_setenv ("DISPLAY", d->name, TRUE);
 
1459
        if (d->windowpath)
 
1460
                g_setenv ("WINDOWPATH", d->windowpath, TRUE);
 
1461
        g_unsetenv ("XAUTHORITY"); /* just in case it's set */
 
1462
 
 
1463
        gdm_auth_set_local_auth (d);
 
1464
 
 
1465
        if (d->handled) {
 
1466
                /* Now the display name and hostname is final */
 
1467
 
 
1468
                const char *automaticlogin = gdm_daemon_config_get_value_string (GDM_KEY_AUTOMATIC_LOGIN);
 
1469
                const char *timedlogin     = gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN);
 
1470
 
 
1471
                if (gdm_daemon_config_get_value_bool (GDM_KEY_AUTOMATIC_LOGIN_ENABLE) &&
 
1472
                    ! ve_string_empty (automaticlogin)) {
 
1473
                        g_free (ParsedAutomaticLogin);
 
1474
                        ParsedAutomaticLogin = gdm_slave_parse_enriched_login (display,
 
1475
                                                                               automaticlogin);
 
1476
                }
 
1477
 
 
1478
                if (gdm_daemon_config_get_value_bool (GDM_KEY_TIMED_LOGIN_ENABLE) &&
 
1479
                    ! ve_string_empty (timedlogin)) {
 
1480
                        g_free (ParsedTimedLogin);
 
1481
                        ParsedTimedLogin = gdm_slave_parse_enriched_login (display,
 
1482
                                                                           timedlogin);
 
1483
                }
 
1484
        }
 
1485
 
 
1486
        /* X error handlers to avoid the default one (i.e. exit (1)) */
 
1487
        do_xfailed_on_xio_error = TRUE;
 
1488
        XSetErrorHandler (gdm_slave_xerror_handler);
 
1489
        XSetIOErrorHandler (gdm_slave_xioerror_handler);
 
1490
 
 
1491
        /* We keep our own (windowless) connection (dsp) open to avoid the
 
1492
         * X server resetting due to lack of active connections. */
 
1493
 
 
1494
        gdm_debug ("gdm_slave_run: Opening display %s", d->name);
 
1495
 
 
1496
        /* if local then the the server should be ready for openning, so
 
1497
         * don't try so long before killing it and trying again */
 
1498
        if (SERVER_IS_LOCAL (d))
 
1499
                maxtries = 2;
 
1500
        else
 
1501
                maxtries = 10;
 
1502
 
 
1503
        while (d->handled &&
 
1504
               openretries < maxtries &&
 
1505
               d->dsp == NULL &&
 
1506
               ( ! SERVER_IS_LOCAL (d) || d->servpid > 1)) {
 
1507
 
 
1508
                gdm_sigchld_block_push ();
 
1509
                d->dsp = XOpenDisplay (d->name);
 
1510
                gdm_sigchld_block_pop ();
 
1511
 
 
1512
                if G_UNLIKELY (d->dsp == NULL) {
 
1513
                        gdm_debug ("gdm_slave_run: Sleeping %d on a retry", 1+openretries*2);
 
1514
                        gdm_sleep_no_signal (1+openretries*2);
 
1515
                        openretries++;
 
1516
                }
 
1517
        }
 
1518
 
 
1519
        /* Really this will only be useful for the first local server,
 
1520
           since that's the only time this can really be on */
 
1521
        while G_UNLIKELY (gdm_wait_for_go) {
 
1522
                struct timeval tv;
 
1523
                /* Wait 1 second. */
 
1524
                tv.tv_sec = 1;
 
1525
                tv.tv_usec = 0;
 
1526
                select (0, NULL, NULL, NULL, &tv);
 
1527
                /* don't want to use sleep since we're using alarm
 
1528
                   for pinging */
 
1529
                check_notifies_now ();
 
1530
        }
 
1531
 
 
1532
        /* Set the busy cursor */
 
1533
        if (d->dsp != NULL) {
 
1534
                Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH);
 
1535
                XDefineCursor (d->dsp,
 
1536
                               DefaultRootWindow (d->dsp),
 
1537
                               xcursor);
 
1538
                XFreeCursor (d->dsp, xcursor);
 
1539
                XSync (d->dsp, False);
 
1540
        }
 
1541
 
 
1542
        /* Just a race avoiding sleep, probably not necessary though,
 
1543
         * but doesn't hurt anything */
 
1544
        if ( ! d->handled)
 
1545
                gdm_sleep_no_signal (1);
 
1546
 
 
1547
        if (SERVER_IS_LOCAL (d)) {
 
1548
                gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE);
 
1549
        }
 
1550
 
 
1551
        check_notifies_now ();
 
1552
 
 
1553
        /* something may have gone wrong, try xfailed, if local (non-flexi),
 
1554
         * the toplevel loop of death will handle us */ 
 
1555
        if G_UNLIKELY (d->handled && d->dsp == NULL) {
 
1556
                if (d->type == TYPE_STATIC)
 
1557
                        gdm_slave_quick_exit (DISPLAY_XFAILED);
 
1558
                else
 
1559
                        gdm_slave_quick_exit (DISPLAY_ABORT);
 
1560
        }
 
1561
 
 
1562
        /* OK from now on it's really the user whacking us most likely,
 
1563
         * we have already started up well */
 
1564
        do_xfailed_on_xio_error = FALSE;
 
1565
 
 
1566
        /* If XDMCP setup pinging */
 
1567
        if ( ! SERVER_IS_LOCAL (d) && pinginterval > 0) {
 
1568
                alarm (pinginterval);
 
1569
        }
 
1570
 
 
1571
        /* checkout xinerama */
 
1572
        if (d->handled)
 
1573
                gdm_screen_init (d);
1451
1574
 
1452
1575
#ifdef HAVE_TSOL
1453
1576
        /* Check out Solaris Trusted Xserver extension */
1455
1578
                gdm_tsol_init (d);
1456
1579
#endif
1457
1580
 
1458
 
    /* check log stuff for the server, this is done here
1459
 
     * because it's really a race */
1460
 
    if (SERVER_IS_LOCAL (d))
1461
 
            gdm_server_checklog (d);
1462
 
 
1463
 
    if ( ! d->handled) {
1464
 
            /* yay, we now wait for the server to die */
1465
 
            while (d->servpid > 0) {
1466
 
                    pause ();
1467
 
            }
1468
 
            gdm_slave_quick_exit (DISPLAY_REMANAGE);
1469
 
    } else if (d->use_chooser) {
1470
 
            /* this usually doesn't return */
1471
 
            gdm_slave_chooser ();  /* Run the chooser */
1472
 
            return;
1473
 
    } else if (d->type == TYPE_STATIC &&
1474
 
               gdm_first_login &&
1475
 
               ! ve_string_empty (ParsedAutomaticLogin) &&
1476
 
               strcmp (ParsedAutomaticLogin, gdm_root_user ()) != 0) {
1477
 
            gdm_first_login = FALSE;
1478
 
 
1479
 
            d->logged_in = TRUE;
1480
 
            gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
1481
 
            gdm_slave_send_string (GDM_SOP_LOGIN, ParsedAutomaticLogin);
1482
 
 
1483
 
            if (setup_automatic_session (d, ParsedAutomaticLogin)) {
1484
 
                    gdm_slave_session_start ();
1485
 
            }
1486
 
 
1487
 
            gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
1488
 
            d->logged_in = FALSE;
1489
 
            gdm_slave_send_string (GDM_SOP_LOGIN, "");
1490
 
            logged_in_uid = -1;
1491
 
            logged_in_gid = -1;
1492
 
 
1493
 
            gdm_debug ("gdm_slave_run: Automatic login done");
1494
 
            
1495
 
            if (remanage_asap) {
1496
 
                    gdm_slave_quick_exit (DISPLAY_REMANAGE);
1497
 
            }
1498
 
 
1499
 
            /* return to gdm_slave_start so that the server
1500
 
             * can be reinitted and all that kind of fun stuff. */
1501
 
            return;
1502
 
    }
1503
 
 
1504
 
    if (gdm_first_login)
1505
 
            gdm_first_login = FALSE;
1506
 
 
1507
 
    do {
1508
 
            check_notifies_now ();
1509
 
 
1510
 
            if ( ! greet) {
1511
 
                    gdm_slave_greeter ();  /* Start the greeter */
1512
 
                    greeter_no_focus = FALSE;
1513
 
                    greeter_disabled = FALSE;
1514
 
            }
1515
 
 
1516
 
            gdm_slave_wait_for_login (); /* wait for a password */
1517
 
 
1518
 
            d->logged_in = TRUE;
1519
 
            gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
1520
 
 
1521
 
            if (do_timed_login) {
1522
 
                    /* timed out into a timed login */
1523
 
                    do_timed_login = FALSE;
1524
 
                    if (setup_automatic_session (d, ParsedTimedLogin)) {
1525
 
                            gdm_slave_send_string (GDM_SOP_LOGIN,
1526
 
                                                   ParsedTimedLogin);
1527
 
                            gdm_slave_session_start ();
1528
 
                    }
1529
 
            } else {
1530
 
                    gdm_slave_send_string (GDM_SOP_LOGIN, login);
1531
 
                    gdm_slave_session_start ();
1532
 
            }
1533
 
 
1534
 
            gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
1535
 
            d->logged_in = FALSE;
1536
 
            gdm_slave_send_string (GDM_SOP_LOGIN, "");
1537
 
            logged_in_uid = -1;
1538
 
            logged_in_gid = -1;
1539
 
 
1540
 
            if (remanage_asap) {
1541
 
                    gdm_slave_quick_exit (DISPLAY_REMANAGE);
1542
 
            }
1543
 
 
1544
 
            if (greet) {
1545
 
                    greeter_no_focus = FALSE;
1546
 
                    gdm_slave_greeter_ctl_no_ret (GDM_FOCUS, "");
1547
 
                    greeter_disabled = FALSE;
1548
 
                    gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, "");
1549
 
                    gdm_slave_greeter_ctl_no_ret (GDM_RESETOK, "");
1550
 
            }
1551
 
            /* Note that greet is only true if the above was no 'login',
1552
 
             * so no need to reinit the server nor rebake cookies
1553
 
             * nor such nonsense */
1554
 
    } while (greet);
1555
 
 
1556
 
    /* If XDMCP stop pinging */
1557
 
    if ( ! SERVER_IS_LOCAL (d))
1558
 
            alarm (0);
 
1581
        /*
 
1582
         * Find out the VT number of the display.  VT's could be started by some
 
1583
         * other mechanism than by running gdmflexiserver, so need to check the
 
1584
         * Atom.  Do this before starting the greeter so that the user does not
 
1585
         * have the ability to modify the atom.
 
1586
         */
 
1587
        d->vtnum = gdm_get_current_vtnum (d->dsp);
 
1588
 
 
1589
        /* checkout window number */
 
1590
        gdm_window_path (d);
 
1591
 
 
1592
        /* check log stuff for the server, this is done here
 
1593
         * because it's really a race */
 
1594
        if (SERVER_IS_LOCAL (d))
 
1595
                gdm_server_checklog (d);
 
1596
 
 
1597
        if ( ! d->handled) {
 
1598
                /* yay, we now wait for the server to die */
 
1599
                while (d->servpid > 0) {
 
1600
                        pause ();
 
1601
                }
 
1602
                gdm_slave_quick_exit (DISPLAY_REMANAGE);
 
1603
        } else if (d->use_chooser) {
 
1604
                /* this usually doesn't return */
 
1605
                gdm_slave_chooser ();  /* Run the chooser */
 
1606
                return;
 
1607
        } else if (d->type == TYPE_STATIC &&
 
1608
                   gdm_first_login &&
 
1609
                   ! ve_string_empty (ParsedAutomaticLogin) &&
 
1610
                   strcmp (ParsedAutomaticLogin, gdm_root_user ()) != 0) {
 
1611
                gdm_first_login = FALSE;
 
1612
 
 
1613
                d->logged_in = TRUE;
 
1614
                gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
 
1615
                gdm_slave_send_string (GDM_SOP_LOGIN, ParsedAutomaticLogin);
 
1616
 
 
1617
                if (setup_automatic_session (d, ParsedAutomaticLogin)) {
 
1618
                        gdm_slave_session_start ();
 
1619
                }
 
1620
 
 
1621
                gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
 
1622
                d->logged_in = FALSE;
 
1623
                gdm_slave_send_string (GDM_SOP_LOGIN, "");
 
1624
                logged_in_uid = -1;
 
1625
                logged_in_gid = -1;
 
1626
 
 
1627
                gdm_debug ("gdm_slave_run: Automatic login done");
 
1628
 
 
1629
                if (remanage_asap) {
 
1630
                        gdm_slave_quick_exit (DISPLAY_REMANAGE);
 
1631
                }
 
1632
 
 
1633
                /* return to gdm_slave_start so that the server
 
1634
                 * can be reinitted and all that kind of fun stuff. */
 
1635
                return;
 
1636
        }
 
1637
 
 
1638
        if (gdm_first_login)
 
1639
                gdm_first_login = FALSE;
 
1640
 
 
1641
        do {
 
1642
                check_notifies_now ();
 
1643
 
 
1644
                if ( ! greet) {
 
1645
                        gdm_slave_greeter ();  /* Start the greeter */
 
1646
                        greeter_no_focus = FALSE;
 
1647
                        greeter_disabled = FALSE;
 
1648
                }
 
1649
 
 
1650
                gdm_slave_wait_for_login (); /* wait for a password */
 
1651
 
 
1652
                d->logged_in = TRUE;
 
1653
                gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
 
1654
 
 
1655
                if (do_timed_login) {
 
1656
                        /* timed out into a timed login */
 
1657
                        do_timed_login = FALSE;
 
1658
                        if (setup_automatic_session (d, ParsedTimedLogin)) {
 
1659
                                gdm_slave_send_string (GDM_SOP_LOGIN,
 
1660
                                                       ParsedTimedLogin);
 
1661
                                gdm_slave_session_start ();
 
1662
                        }
 
1663
                } else {
 
1664
                        gdm_slave_send_string (GDM_SOP_LOGIN, login_user);
 
1665
                        gdm_slave_session_start ();
 
1666
                }
 
1667
 
 
1668
                gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
 
1669
                d->logged_in = FALSE;
 
1670
                gdm_slave_send_string (GDM_SOP_LOGIN, "");
 
1671
                logged_in_uid = -1;
 
1672
                logged_in_gid = -1;
 
1673
 
 
1674
                if (remanage_asap) {
 
1675
                        gdm_slave_quick_exit (DISPLAY_REMANAGE);
 
1676
                }
 
1677
 
 
1678
                if (greet) {
 
1679
                        greeter_no_focus = FALSE;
 
1680
                        gdm_slave_greeter_ctl_no_ret (GDM_FOCUS, "");
 
1681
                        greeter_disabled = FALSE;
 
1682
                        gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, "");
 
1683
                        gdm_slave_greeter_ctl_no_ret (GDM_RESETOK, "");
 
1684
                }
 
1685
                /* Note that greet is only true if the above was no 'login',
 
1686
                 * so no need to reinit the server nor rebake cookies
 
1687
                 * nor such nonsense */
 
1688
        } while (greet);
 
1689
 
 
1690
        /* If XDMCP stop pinging */
 
1691
        if ( ! SERVER_IS_LOCAL (d))
 
1692
                alarm (0);
1559
1693
}
1560
1694
 
1561
1695
/* A hack really, this will wait around until the first mapped window
1573
1707
                p[1] = -1;
1574
1708
        }
1575
1709
 
 
1710
        gdm_debug ("Forking process to focus first X11 window");
 
1711
 
1576
1712
        pid = fork ();
1577
1713
        if G_UNLIKELY (pid < 0) {
1578
1714
                if (p[0] != -1)
1607
1743
 
1608
1744
        gdm_unset_signals ();
1609
1745
 
1610
 
        closelog ();
 
1746
        gdm_log_shutdown ();
1611
1747
 
1612
1748
        gdm_close_all_descriptors (0 /* from */, p[1] /* except */, -1 /* except2 */);
1613
1749
 
1617
1753
        gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
1618
1754
        gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
1619
1755
 
1620
 
        openlog ("gdm", LOG_PID, LOG_DAEMON);
 
1756
        gdm_log_init ();
1621
1757
 
1622
1758
        /* just in case it's set */
1623
1759
        g_unsetenv ("XAUTHORITY");
1624
1760
 
1625
1761
        gdm_auth_set_local_auth (d);
1626
1762
 
 
1763
        gdm_sigchld_block_push ();
1627
1764
        disp = XOpenDisplay (d->name);
 
1765
        gdm_sigchld_block_pop ();
1628
1766
        if G_UNLIKELY (disp == NULL) {
1629
1767
                gdm_error (_("%s: cannot open display %s"),
1630
1768
                           "focus_first_x_window",
1688
1826
{
1689
1827
        pid_t pid;
1690
1828
 
 
1829
        /* Lets check if custom.conf exists. If not there
 
1830
           is no point in launching gdmsetup as it will fail.
 
1831
           We don't need to worry about defaults.conf as
 
1832
           the daemon wont start without it
 
1833
        */
 
1834
        if (gdm_daemon_config_get_custom_config_file () == NULL) {
 
1835
                gdm_errorgui_error_box (d,
 
1836
                               GTK_MESSAGE_ERROR,
 
1837
                               _("Could not access configuration file (custom.conf). "
 
1838
                                 "Make sure that the file exists before launching "
 
1839
                                 " login manager config utility."));
 
1840
                return;
 
1841
        }
 
1842
 
1691
1843
        /* Set the busy cursor */
1692
1844
        if (d->dsp != NULL) {
1693
1845
                Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH);
1698
1850
                XSync (d->dsp, False);
1699
1851
        }
1700
1852
 
 
1853
        gdm_debug ("Forking GDM configuration process");
 
1854
 
1701
1855
        gdm_sigchld_block_push ();
1702
1856
        gdm_sigterm_block_push ();
1703
1857
        pid = d->sesspid = fork ();
1712
1866
 
1713
1867
                /* Can't fork */
1714
1868
                display->sesspid = 0;
1715
 
               
 
1869
 
1716
1870
                xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR);
1717
1871
                XDefineCursor (d->dsp,
1718
1872
                               DefaultRootWindow (d->dsp),
1724
1878
        }
1725
1879
 
1726
1880
        if (pid == 0) {
1727
 
                char **argv;
 
1881
                char **argv = NULL;
 
1882
                const char *s;
 
1883
 
1728
1884
                /* child */
1729
1885
 
1730
1886
                setsid ();
1737
1893
 
1738
1894
                /* setup environment */
1739
1895
                gdm_restoreenv ();
 
1896
                gdm_reset_locale ();
1740
1897
 
1741
1898
                /* root here */
1742
1899
                g_setenv ("XAUTHORITY", GDM_AUTHFILE (display), TRUE);
1743
1900
                g_setenv ("DISPLAY", display->name, TRUE);
 
1901
                if (d->windowpath)
 
1902
                        g_setenv ("WINDOWPATH", d->windowpath, TRUE);
1744
1903
                g_setenv ("LOGNAME", pwent->pw_name, TRUE);
1745
1904
                g_setenv ("USER", pwent->pw_name, TRUE);
1746
1905
                g_setenv ("USERNAME", pwent->pw_name, TRUE);
1747
1906
                g_setenv ("HOME", pwent->pw_dir, TRUE);
1748
1907
                g_setenv ("SHELL", pwent->pw_shell, TRUE);
1749
 
                g_setenv ("PATH", gdm_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
 
1908
                g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
1750
1909
                g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
1751
1910
                if ( ! ve_string_empty (display->theme_name))
1752
1911
                        g_setenv ("GDM_GTK_THEME", display->theme_name, TRUE);
1753
1912
 
1754
 
                closelog ();
 
1913
                gdm_log_shutdown ();
1755
1914
 
1756
 
                gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */);
 
1915
                gdm_close_all_descriptors (0 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
1757
1916
 
1758
1917
                /* No error checking here - if it's messed the best response
1759
1918
                 * is to ignore & try to continue */
1761
1920
                gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
1762
1921
                gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
1763
1922
 
1764
 
                openlog ("gdm", LOG_PID, LOG_DAEMON);
 
1923
                gdm_log_init ();
1765
1924
 
1766
1925
                VE_IGNORE_EINTR (g_chdir (pwent->pw_dir));
1767
1926
                if G_UNLIKELY (errno != 0)
1768
1927
                        VE_IGNORE_EINTR (g_chdir ("/"));
1769
1928
 
1770
1929
                /* exec the configurator */
1771
 
                argv = ve_split (gdm_get_value_string (GDM_KEY_CONFIGURATOR));
 
1930
                s = gdm_daemon_config_get_value_string (GDM_KEY_CONFIGURATOR);
 
1931
                if (s != NULL) {
 
1932
                        g_shell_parse_argv (s, NULL, &argv, NULL);
 
1933
                }
 
1934
 
1772
1935
                if G_LIKELY (argv != NULL &&
1773
1936
                             argv[0] != NULL &&
1774
 
                             g_access (argv[0], X_OK) == 0)
1775
 
                        VE_IGNORE_EINTR (execv (argv[0], argv));
1776
 
 
1777
 
                gdm_error_box (d,
1778
 
                               GTK_MESSAGE_ERROR,
1779
 
                               _("Could not execute the configuration "
1780
 
                                 "application.  Make sure its path is set "
1781
 
                                 "correctly in the configuration file.  "
1782
 
                                 "Attempting to start it from the default "
1783
 
                                 "location."));
1784
 
 
1785
 
                argv = ve_split
1786
 
                        (LIBEXECDIR
1787
 
                         "/gdmsetup --disable-sound --disable-crash-dialog");
1788
 
                if (g_access (argv[0], X_OK) == 0)
1789
 
                        VE_IGNORE_EINTR (execv (argv[0], argv));
1790
 
 
1791
 
                gdm_error_box (d,
1792
 
                               GTK_MESSAGE_ERROR,
1793
 
                               _("Could not execute the configuration "
1794
 
                                 "application.  Make sure its path is set "
1795
 
                                 "correctly in the configuration file."));
 
1937
                             g_access (argv[0], X_OK) == 0) {
 
1938
                        VE_IGNORE_EINTR (execv (argv[0], argv));
 
1939
                }
 
1940
 
 
1941
                g_strfreev (argv);
 
1942
 
 
1943
                gdm_errorgui_error_box (d,
 
1944
                                        GTK_MESSAGE_ERROR,
 
1945
                                        _("Could not execute the configuration "
 
1946
                                          "application.  Make sure its path is set "
 
1947
                                          "correctly in the configuration file.  "
 
1948
                                          "Attempting to start it from the default "
 
1949
                                          "location."));
 
1950
                s = LIBEXECDIR "/gdmsetup --disable-sound --disable-crash-dialog";
 
1951
                argv = NULL;
 
1952
                g_shell_parse_argv (s, NULL, &argv, NULL);
 
1953
 
 
1954
                if (g_access (argv[0], X_OK) == 0) {
 
1955
                        VE_IGNORE_EINTR (execv (argv[0], argv));
 
1956
                }
 
1957
 
 
1958
                g_strfreev (argv);
 
1959
 
 
1960
                gdm_errorgui_error_box (d,
 
1961
                                        GTK_MESSAGE_ERROR,
 
1962
                                        _("Could not execute the configuration "
 
1963
                                          "application.  Make sure its path is set "
 
1964
                                          "correctly in the configuration file."));
1796
1965
 
1797
1966
                _exit (0);
1798
1967
        } else {
1799
1968
                GdmWaitPid *wp;
1800
 
                
 
1969
 
1801
1970
                configurator = TRUE;
1802
1971
 
1803
1972
                gdm_sigchld_block_push ();
1822
1991
        gdm_slave_desensitize_config ();
1823
1992
 
1824
1993
        /* no login */
1825
 
        g_free (login);
1826
 
        login = NULL;
 
1994
        g_free (login_user);
 
1995
        login_user = NULL;
1827
1996
 
1828
1997
        /* Now restart it */
1829
1998
        if (greet) {
1861
2030
static gboolean
1862
2031
play_login_sound (const char *sound_file)
1863
2032
{
1864
 
        char *soundprogram = gdm_get_value_string (GDM_KEY_SOUND_PROGRAM);
 
2033
        const char *soundprogram = gdm_daemon_config_get_value_string (GDM_KEY_SOUND_PROGRAM);
1865
2034
        pid_t pid;
1866
2035
 
1867
2036
        if (ve_string_empty (soundprogram) ||
1873
2042
        gdm_sigchld_block_push ();
1874
2043
        gdm_sigterm_block_push ();
1875
2044
 
 
2045
        gdm_debug ("Forking sound program: %s", soundprogram);
 
2046
 
1876
2047
        pid = fork ();
1877
2048
        if (pid == 0)
1878
2049
                gdm_unset_signals ();
1897
2068
static void
1898
2069
gdm_slave_wait_for_login (void)
1899
2070
{
1900
 
        char *successsound;
1901
 
        g_free (login);
1902
 
        login = NULL;
 
2071
        const char *successsound;
 
2072
        char *username;
 
2073
        g_free (login_user);
 
2074
        login_user = NULL;
1903
2075
 
1904
2076
        /* Chat with greeter */
1905
 
        while (login == NULL) {
 
2077
        while (login_user == NULL) {
1906
2078
                /* init to a sane value */
1907
2079
                do_timed_login = FALSE;
1908
2080
                do_configurator = FALSE;
1922
2094
                NEVER_FAILS_root_set_euid_egid (0, 0);
1923
2095
 
1924
2096
                gdm_debug ("gdm_slave_wait_for_login: In loop");
1925
 
                login = gdm_verify_user (d /* the display */,
1926
 
                                         NULL /* username*/,
1927
 
                                         d->name /* display name */,
1928
 
                                         d->attached /* display attached? (bool) */);
 
2097
                username = d->preset_user;
 
2098
                d->preset_user = NULL;
 
2099
                login_user = gdm_verify_user (d /* the display */,
 
2100
                                              username /* username */,
 
2101
                                              TRUE /* allow retry */);
 
2102
                g_free (username);
 
2103
 
1929
2104
                gdm_debug ("gdm_slave_wait_for_login: end verify for '%s'",
1930
 
                           ve_sure_string (login));
 
2105
                           ve_sure_string (login_user));
1931
2106
 
1932
2107
                /* Complex, make sure to always handle the do_configurator
1933
2108
                 * do_timed_login and do_restart_greeter after any call
1934
2109
                 * to gdm_verify_user */
1935
2110
 
1936
2111
                if G_UNLIKELY (do_restart_greeter) {
1937
 
                        g_free (login);
1938
 
                        login = NULL;
 
2112
                        g_free (login_user);
 
2113
                        login_user = NULL;
1939
2114
                        do_restart_greeter = FALSE;
1940
2115
                        restart_the_greeter ();
1941
2116
                        continue;
1948
2123
                        gboolean oldAllowRoot;
1949
2124
 
1950
2125
                        do_configurator = FALSE;
1951
 
                        g_free (login);
1952
 
                        login = NULL;
 
2126
                        g_free (login_user);
 
2127
                        login_user = NULL;
1953
2128
                        /* clear any error */
1954
2129
                        gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, "");
1955
2130
                        gdm_slave_greeter_ctl_no_ret
1957
2132
                                 _("You must authenticate as root to run configuration."));
1958
2133
 
1959
2134
                        /* we always allow root for this */
1960
 
                        oldAllowRoot = gdm_get_value_bool (GDM_KEY_ALLOW_ROOT);
1961
 
                        gdm_set_value_bool (GDM_KEY_ALLOW_ROOT, TRUE);
 
2135
                        oldAllowRoot = gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_ROOT);
 
2136
                        gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_ROOT, TRUE);
1962
2137
 
1963
2138
                        pwent = getpwuid (0);
1964
2139
                        if G_UNLIKELY (pwent == NULL) {
1968
2143
                        }
1969
2144
 
1970
2145
                        gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, pwent->pw_name);
1971
 
                        login = gdm_verify_user (d,
1972
 
                                                 pwent->pw_name,
1973
 
                                                 d->name,
1974
 
                                                 d->attached);
1975
 
                        gdm_set_value_bool (GDM_KEY_ALLOW_ROOT, oldAllowRoot);
 
2146
                        login_user = gdm_verify_user (d,
 
2147
                                                      pwent->pw_name,
 
2148
                                                      FALSE);
 
2149
                        gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_ROOT, oldAllowRoot);
1976
2150
 
1977
2151
                        /* Clear message */
1978
2152
                        gdm_slave_greeter_ctl_no_ret (GDM_MSG, "");
1979
2153
 
1980
2154
                        if G_UNLIKELY (do_restart_greeter) {
1981
 
                                g_free (login);
1982
 
                                login = NULL;
 
2155
                                g_free (login_user);
 
2156
                                login_user = NULL;
1983
2157
                                do_restart_greeter = FALSE;
1984
2158
                                restart_the_greeter ();
1985
2159
                                continue;
1988
2162
                        check_notifies_now ();
1989
2163
 
1990
2164
                        /* The user can't remember his password */
1991
 
                        if (login == NULL) {
 
2165
                        if (login_user == NULL) {
1992
2166
                                gdm_debug ("gdm_slave_wait_for_login: No login/Bad login");
1993
2167
                                gdm_slave_greeter_ctl_no_ret (GDM_RESET, "");
1994
2168
                                continue;
1995
2169
                        }
1996
2170
 
1997
2171
                        /* Wipe the login */
1998
 
                        g_free (login);
1999
 
                        login = NULL;
 
2172
                        g_free (login_user);
 
2173
                        login_user = NULL;
2000
2174
 
2001
2175
                        /* Note that this can still fall through to
2002
2176
                         * the timed login if the user doesn't type in the
2075
2249
                        break;
2076
2250
                }
2077
2251
 
2078
 
                if (login == NULL) {
2079
 
                        char *failuresound = gdm_get_value_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE);
 
2252
                if (login_user == NULL) {
 
2253
                        const char *failuresound = gdm_daemon_config_get_value_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE);
2080
2254
 
2081
2255
                        gdm_debug ("gdm_slave_wait_for_login: No login/Bad login");
2082
2256
                        gdm_slave_greeter_ctl_no_ret (GDM_RESET, "");
2083
2257
 
2084
2258
                        /* Play sounds if specified for a failed login */
2085
2259
                        if (d->attached && failuresound &&
2086
 
                            gdm_get_value_bool (GDM_KEY_SOUND_ON_LOGIN_FAILURE) &&
 
2260
                            gdm_daemon_config_get_value_bool (GDM_KEY_SOUND_ON_LOGIN_FAILURE) &&
2087
2261
                            ! play_login_sound (failuresound)) {
2088
2262
                                gdm_error (_("Login sound requested on non-local display or the play "
2089
2263
                                             "software cannot be run or the sound does not exist."));
2093
2267
 
2094
2268
        /* The user timed out into a timed login during the conversation */
2095
2269
        if (do_timed_login) {
2096
 
                g_free (login);
2097
 
                login = NULL;
 
2270
                g_free (login_user);
 
2271
                login_user = NULL;
2098
2272
                /* timed login is automatic, thus no need for greeter,
2099
2273
                 * we'll take default values */
2100
2274
                gdm_slave_whack_greeter ();
2102
2276
                gdm_debug ("gdm_slave_wait_for_login: Timed Login");
2103
2277
        }
2104
2278
 
2105
 
        successsound = gdm_get_value_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE);
 
2279
        successsound = gdm_daemon_config_get_value_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE);
2106
2280
        /* Play sounds if specified for a successful login */
2107
 
        if (login != NULL && successsound &&
2108
 
            gdm_get_value_bool (GDM_KEY_SOUND_ON_LOGIN_SUCCESS) &&
 
2281
        if (login_user != NULL && successsound &&
 
2282
            gdm_daemon_config_get_value_bool (GDM_KEY_SOUND_ON_LOGIN_SUCCESS) &&
2109
2283
            d->attached &&
2110
2284
            ! play_login_sound (successsound)) {
2111
2285
                gdm_error (_("Login sound requested on non-local display or the play software "
2113
2287
        }
2114
2288
 
2115
2289
        gdm_debug ("gdm_slave_wait_for_login: got_login for '%s'",
2116
 
                   ve_sure_string (login));
 
2290
                   ve_sure_string (login_user));
2117
2291
 
2118
2292
 
2119
2293
}
2154
2328
                NEVER_FAILS_seteuid (0);
2155
2329
                if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
2156
2330
                               seteuid (pwent->pw_uid) != 0) {
2157
 
                        NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
 
2331
                        NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
2158
2332
                        gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
2159
2333
                        continue;
2160
2334
                }
2161
2335
 
2162
 
                picfile = gdm_get_facefile_from_home (pwent->pw_dir, pwent->pw_uid);
 
2336
                picfile = gdm_daemon_config_get_facefile_from_home (pwent->pw_dir, pwent->pw_uid);
2163
2337
 
2164
2338
                if (! picfile)
2165
 
                        picfile = gdm_get_facefile_from_global (pwent->pw_name, pwent->pw_uid);
 
2339
                        picfile = gdm_daemon_config_get_facefile_from_global (pwent->pw_name, pwent->pw_uid);
2166
2340
 
2167
2341
                if (! picfile) {
2168
 
                        NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
 
2342
                        NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
2169
2343
                        gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
2170
2344
                        continue;
2171
2345
                }
2172
2346
 
2173
2347
                VE_IGNORE_EINTR (r = g_stat (picfile, &s));
2174
 
                if G_UNLIKELY (r < 0 || s.st_size > gdm_get_value_int (GDM_KEY_USER_MAX_FILE)) {
2175
 
                        NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
 
2348
                if G_UNLIKELY (r < 0 || s.st_size > gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE)) {
 
2349
                        NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
2176
2350
 
2177
2351
                        gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
2178
2352
                        continue;
2181
2355
                VE_IGNORE_EINTR (fp = fopen (picfile, "r"));
2182
2356
                g_free (picfile);
2183
2357
                if G_UNLIKELY (fp == NULL) {
2184
 
                        NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
 
2358
                        NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
2185
2359
 
2186
2360
                        gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
2187
2361
                        continue;
2195
2369
                        VE_IGNORE_EINTR (fclose (fp));
2196
2370
                        g_free (ret);
2197
2371
 
2198
 
                        NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
 
2372
                        NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
2199
2373
 
2200
2374
                        continue;
2201
2375
                }
2220
2394
                        int written;
2221
2395
 
2222
2396
                        VE_IGNORE_EINTR (bytes = fread (buf, sizeof (char),
2223
 
                                                     max_write, fp));
 
2397
                                                        max_write, fp));
2224
2398
 
2225
2399
                        if (bytes <= 0)
2226
2400
                                break;
2270
2444
                        if (bytes > 0)
2271
2445
                                i += bytes;
2272
2446
                }
2273
 
                        
 
2447
 
2274
2448
                gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "done");
2275
2449
 
2276
 
                NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
 
2450
                NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
2277
2451
        }
2278
2452
        g_free (response); /* not reached */
2279
2453
}
2292
2466
        int cnt;
2293
2467
 
2294
2468
        NEVER_FAILS_seteuid (0);
2295
 
        NEVER_FAILS_setegid (gdm_get_gdmgid ());
 
2469
        NEVER_FAILS_setegid (gdm_daemon_config_get_gdmgid ());
2296
2470
 
2297
2471
        if G_UNLIKELY (seteuid (fromuid) != 0) {
2298
2472
                NEVER_FAILS_root_set_euid_egid (old, oldg);
2309
2483
                errno = 0;
2310
2484
                fromfd = open (file, O_RDONLY
2311
2485
#ifdef O_NOCTTY
2312
 
                                     |O_NOCTTY
 
2486
                               |O_NOCTTY
2313
2487
#endif
2314
2488
#ifdef O_NOFOLLOW
2315
 
                                     |O_NOFOLLOW
 
2489
                               |O_NOFOLLOW
2316
2490
#endif
2317
 
                                    );
 
2491
                               );
2318
2492
        } while G_UNLIKELY (errno == EINTR);
2319
2493
 
2320
2494
        if G_UNLIKELY (fromfd < 0) {
2324
2498
 
2325
2499
        NEVER_FAILS_root_set_euid_egid (0, 0);
2326
2500
 
2327
 
        name = gdm_make_filename (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR),
2328
 
                d->name, ".XnestAuth");
 
2501
        name = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
 
2502
                                  d->name, ".XnestAuth");
2329
2503
 
2330
2504
        VE_IGNORE_EINTR (g_unlink (name));
2331
2505
        VE_IGNORE_EINTR (authfd = open (name, O_EXCL|O_TRUNC|O_WRONLY|O_CREAT, 0600));
2376
2550
                cnt = cnt + written;
2377
2551
                /* this should never occur (we check above)
2378
2552
                   but we're paranoid) */
2379
 
                if G_UNLIKELY (cnt > gdm_get_value_int (GDM_KEY_USER_MAX_FILE))
 
2553
                if G_UNLIKELY (cnt > gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE))
2380
2554
                        return NULL;
2381
2555
        }
2382
2556
 
2391
2565
static void
2392
2566
exec_command (const char *command, const char *extra_arg)
2393
2567
{
2394
 
        char **argv = ve_split (command);
 
2568
        char **argv;
 
2569
        int argc;
 
2570
 
 
2571
        if (! g_shell_parse_argv (command, &argc, &argv, NULL)) {
 
2572
                return;
 
2573
        }
2395
2574
 
2396
2575
        if (argv == NULL ||
2397
2576
            ve_string_empty (argv[0]))
2401
2580
                return;
2402
2581
 
2403
2582
        if (extra_arg != NULL) {
2404
 
                char **new_argv;
2405
 
                int i;
2406
 
                for (i = 0; argv[i] != NULL; i++)
2407
 
                        ;
2408
 
                new_argv = g_new0 (char *, i+2);
2409
 
                for (i = 0; argv[i] != NULL; i++)
2410
 
                        new_argv[i] = argv[i];
2411
 
                new_argv[i++] = (char *)extra_arg;
2412
 
                new_argv[i++] = NULL;
2413
2583
 
2414
 
                argv = new_argv;
 
2584
                argv           = g_renew (char *, argv, argc + 2);
 
2585
                argv[argc]     = g_strdup (extra_arg);
 
2586
                argv[argc + 1] = NULL;
2415
2587
        }
2416
2588
 
2417
2589
        VE_IGNORE_EINTR (execv (argv[0], argv));
 
2590
        g_strfreev (argv);
2418
2591
}
2419
2592
 
2420
2593
static void
2421
2594
gdm_slave_greeter (void)
2422
2595
{
2423
 
    gint pipe1[2], pipe2[2];  
2424
 
    struct passwd *pwent;
2425
 
    pid_t pid;
2426
 
    char *command;
2427
 
    char *defaultpath;
2428
 
    char *gdmuser;
2429
 
    char *moduleslist;
2430
 
    
2431
 
    gdm_debug ("gdm_slave_greeter: Running greeter on %s", d->name);
2432
 
    
2433
 
    /* Run the init script. gdmslave suspends until script has terminated */
2434
 
    gdm_slave_exec_script (d, gdm_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
2435
 
                           NULL, NULL, FALSE /* pass_stdout */);
2436
 
 
2437
 
    /* Open a pipe for greeter communications */
2438
 
    if G_UNLIKELY (pipe (pipe1) < 0)
2439
 
        gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"),
2440
 
                        "gdm_slave_greeter");
2441
 
    if G_UNLIKELY (pipe (pipe2) < 0) {
2442
 
        VE_IGNORE_EINTR (close (pipe1[0]));
2443
 
        VE_IGNORE_EINTR (close (pipe1[1]));
2444
 
        gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"),
2445
 
                        "gdm_slave_greeter");
2446
 
    }
2447
 
 
2448
 
    /* hackish ain't it */
2449
 
    create_temp_auth_file ();
2450
 
    
2451
 
    /* Fork. Parent is gdmslave, child is greeter process. */
2452
 
    gdm_sigchld_block_push ();
2453
 
    gdm_sigterm_block_push ();
2454
 
    greet = TRUE;
2455
 
    pid = d->greetpid = fork ();
2456
 
    if (pid == 0)
2457
 
            gdm_unset_signals ();
2458
 
    gdm_sigterm_block_pop ();
2459
 
    gdm_sigchld_block_pop ();
2460
 
 
2461
 
    switch (pid) {
2462
 
        
2463
 
    case 0:
2464
 
        setsid ();
2465
 
 
2466
 
        gdm_unset_signals ();
2467
 
 
2468
 
        /* Plumbing */
2469
 
        VE_IGNORE_EINTR (close (pipe1[1]));
2470
 
        VE_IGNORE_EINTR (close (pipe2[0]));
2471
 
 
2472
 
        VE_IGNORE_EINTR (dup2 (pipe1[0], STDIN_FILENO));
2473
 
        VE_IGNORE_EINTR (dup2 (pipe2[1], STDOUT_FILENO));
2474
 
 
2475
 
        closelog ();
2476
 
 
2477
 
        /*
2478
 
         * Leave stderr open to the log
2479
 
         */
2480
 
        gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
2481
 
 
2482
 
        openlog ("gdm", LOG_PID, LOG_DAEMON);
2483
 
        
2484
 
        if G_UNLIKELY (setgid (gdm_get_gdmgid ()) < 0) 
2485
 
            gdm_child_exit (DISPLAY_ABORT,
2486
 
                            _("%s: Couldn't set groupid to %d"),
2487
 
                            "gdm_slave_greeter", gdm_get_gdmgid ());
2488
 
 
2489
 
        gdmuser = gdm_get_value_string (GDM_KEY_USER);
2490
 
        if G_UNLIKELY (initgroups (gdmuser, gdm_get_gdmgid ()) < 0)
2491
 
            gdm_child_exit (DISPLAY_ABORT,
2492
 
                            _("%s: initgroups () failed for %s"),
2493
 
                            "gdm_slave_greeter", gdmuser);
2494
 
        
2495
 
        if G_UNLIKELY (setuid (gdm_get_gdmuid ()) < 0) 
2496
 
            gdm_child_exit (DISPLAY_ABORT,
2497
 
                            _("%s: Couldn't set userid to %d"),
2498
 
                            "gdm_slave_greeter", gdm_get_gdmuid ());
2499
 
 
2500
 
        gdm_restoreenv ();
2501
 
        
2502
 
        g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
2503
 
        g_setenv ("DISPLAY", d->name, TRUE);
 
2596
        gint pipe1[2], pipe2[2];
 
2597
        struct passwd *pwent;
 
2598
        pid_t pid;
 
2599
        const char *command;
 
2600
        const char *defaultpath;
 
2601
        const char *gdmuser;
 
2602
        const char *moduleslist;
 
2603
        const char *gdmlang;
 
2604
 
 
2605
        gdm_debug ("gdm_slave_greeter: Running greeter on %s", d->name);
 
2606
 
 
2607
        /* Run the init script. gdmslave suspends until script has terminated */
 
2608
        gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
 
2609
                               NULL, NULL, FALSE /* pass_stdout */);
 
2610
 
 
2611
        /* Open a pipe for greeter communications */
 
2612
        if G_UNLIKELY (pipe (pipe1) < 0)
 
2613
                gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"),
 
2614
                                "gdm_slave_greeter");
 
2615
        if G_UNLIKELY (pipe (pipe2) < 0) {
 
2616
                VE_IGNORE_EINTR (close (pipe1[0]));
 
2617
                VE_IGNORE_EINTR (close (pipe1[1]));
 
2618
                gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"),
 
2619
                                "gdm_slave_greeter");
 
2620
        }
2504
2621
 
2505
2622
        /* hackish ain't it */
2506
 
        set_xnest_parent_stuff ();
2507
 
 
2508
 
        g_setenv ("LOGNAME", gdmuser, TRUE);
2509
 
        g_setenv ("USER", gdmuser, TRUE);
2510
 
        g_setenv ("USERNAME", gdmuser, TRUE);
2511
 
        g_setenv ("GDM_GREETER_PROTOCOL_VERSION",
2512
 
                      GDM_GREETER_PROTOCOL_VERSION, TRUE);
2513
 
        g_setenv ("GDM_VERSION", VERSION, TRUE);
2514
 
 
2515
 
        pwent = getpwnam (gdmuser);
2516
 
        if G_LIKELY (pwent != NULL) {
2517
 
                /* Note that usually this doesn't exist */
2518
 
                if (pwent->pw_dir != NULL &&
2519
 
                    g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS))
2520
 
                        g_setenv ("HOME", pwent->pw_dir, TRUE);
2521
 
                else
2522
 
                        g_setenv ("HOME",
2523
 
                                ve_sure_string (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR)),
2524
 
                                TRUE); /* Hack */
2525
 
                g_setenv ("SHELL", pwent->pw_shell, TRUE);
2526
 
        } else {
2527
 
                g_setenv ("HOME",
2528
 
                         ve_sure_string (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR)),
2529
 
                         TRUE); /* Hack */
2530
 
                g_setenv ("SHELL", "/bin/sh", TRUE);
2531
 
        }
2532
 
 
2533
 
        defaultpath = gdm_get_value_string (GDM_KEY_PATH);
2534
 
        if (ve_string_empty (g_getenv ("PATH"))) {
2535
 
                g_setenv ("PATH", defaultpath, TRUE);
2536
 
        } else if ( ! ve_string_empty (defaultpath)) {
2537
 
                g_setenv ("PATH", g_strconcat (g_getenv ("PATH"), ":", defaultpath, NULL), TRUE);
2538
 
        }
2539
 
        g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
2540
 
        if ( ! ve_string_empty (d->theme_name))
2541
 
                g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
2542
 
 
2543
 
        if (gdm_get_value_bool (GDM_KEY_DEBUG_GESTURES)) {
2544
 
                g_setenv ("GDM_DEBUG_GESTURES", "true", TRUE);
2545
 
        }
2546
 
 
2547
 
        /* Note that this is just informative, the slave will not listen to
2548
 
         * the greeter even if it does something it shouldn't on a non-local
2549
 
         * display so it's not a security risk */
2550
 
        if (d->attached) {
2551
 
                g_setenv ("GDM_IS_LOCAL", "yes", TRUE);
2552
 
        } else {
2553
 
                g_unsetenv ("GDM_IS_LOCAL");
2554
 
        }
2555
 
 
2556
 
        /* this is again informal only, if the greeter does time out it will
2557
 
         * not actually login a user if it's not enabled for this display */
2558
 
        if (d->timed_login_ok) {
2559
 
                if (ParsedTimedLogin == NULL)
2560
 
                        g_setenv ("GDM_TIMED_LOGIN_OK", " ", TRUE);
2561
 
                else
2562
 
                        g_setenv ("GDM_TIMED_LOGIN_OK", ParsedTimedLogin, TRUE);
2563
 
        } else {
2564
 
                g_unsetenv ("GDM_TIMED_LOGIN_OK");
2565
 
        }
2566
 
 
2567
 
        if (SERVER_IS_FLEXI (d)) {
2568
 
                g_setenv ("GDM_FLEXI_SERVER", "yes", TRUE);
2569
 
        } else {
2570
 
                g_unsetenv ("GDM_FLEXI_SERVER");
2571
 
        }
2572
 
 
2573
 
        if G_UNLIKELY (gdm_emergency_server) {
2574
 
                gdm_error_box (d,
2575
 
                               GTK_MESSAGE_ERROR,
2576
 
                               _("No servers were defined in the "
2577
 
                                 "configuration file and XDMCP was "
2578
 
                                 "disabled.  This can only be a "
2579
 
                                 "configuration error.  GDM has started "
2580
 
                                 "a single server for you.  You should "
2581
 
                                 "log in and fix the configuration.  "
2582
 
                                 "Note that automatic and timed logins "
2583
 
                                 "are disabled now."));
2584
 
                g_unsetenv ("GDM_TIMED_LOGIN_OK");
2585
 
        }
2586
 
 
2587
 
        if G_UNLIKELY (d->failsafe_xserver) {
2588
 
                gdm_error_box (d,
2589
 
                               GTK_MESSAGE_ERROR,
2590
 
                               _("Could not start the regular X "
2591
 
                                 "server (your graphical environment) "
2592
 
                                 "and so this is a failsafe X server.  "
2593
 
                                 "You should log in and properly "
2594
 
                                 "configure the X server."));
2595
 
        }
2596
 
 
2597
 
        if G_UNLIKELY (d->busy_display) {
2598
 
                char *msg = g_strdup_printf
2599
 
                        (_("The specified display number was busy, so "
2600
 
                           "this server was started on display %s."),
2601
 
                         d->name);
2602
 
                gdm_error_box (d, GTK_MESSAGE_ERROR, msg);
2603
 
                g_free (msg);
2604
 
        }
 
2623
        create_temp_auth_file ();
2605
2624
 
2606
2625
        if (d->attached)
2607
 
                command = gdm_get_value_string (GDM_KEY_GREETER);
 
2626
                command = gdm_daemon_config_get_value_string (GDM_KEY_GREETER);
2608
2627
        else
2609
 
                command = gdm_get_value_string (GDM_KEY_REMOTE_GREETER);
2610
 
 
2611
 
        if G_UNLIKELY (d->try_different_greeter) {
2612
 
                /* FIXME: we should also really be able to do standalone failsafe
2613
 
                   login, but that requires some work and is perhaps an overkill. */
2614
 
                /* This should handle mostly the case where gdmgreeter is crashing
2615
 
                   and we'd want to start gdmlogin for the user so that at least
2616
 
                   something works instead of a flickering screen */
2617
 
                gdm_error_box (d,
2618
 
                               GTK_MESSAGE_ERROR,
2619
 
                               _("The greeter application appears to be crashing.\n"
2620
 
                                 "Attempting to use a different one."));
2621
 
                if (strstr (command, "gdmlogin") != NULL) {
2622
 
                        /* in case it is gdmlogin that's crashing
2623
 
                           try the themed greeter for luck */
2624
 
                        command = LIBEXECDIR "/gdmgreeter";
2625
 
                } else {
2626
 
                        /* in all other cases, try the gdmlogin (standard greeter)
2627
 
                           proggie */
2628
 
                        command = LIBEXECDIR "/gdmlogin";
2629
 
                }
2630
 
        }
2631
 
 
2632
 
        moduleslist = gdm_get_value_string (GDM_KEY_GTK_MODULES_LIST);
2633
 
 
2634
 
        if (gdm_get_value_bool (GDM_KEY_ADD_GTK_MODULES) &&
2635
 
            ! ve_string_empty (moduleslist) &&
2636
 
            /* don't add modules if we're trying to prevent crashes,
2637
 
               perhaps it's the modules causing the problem in the first place */
2638
 
            ! d->try_different_greeter) {
2639
 
                gchar *modules = g_strdup_printf ("--gtk-module=%s", moduleslist);
2640
 
                exec_command (command, modules);
2641
 
                /* Something went wrong */
2642
 
                gdm_error (_("%s: Cannot start greeter with gtk modules: %s. Trying without modules"),
 
2628
                command = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER);
 
2629
 
 
2630
#ifdef __sun
 
2631
        /*
 
2632
         * Set access control for audio device so that GDM owned programs can
 
2633
         * play audio and work with accessibility programs that require audio.
 
2634
         */
 
2635
        system ("/usr/bin/setfacl -m user:gdm:rwx,mask:rwx /dev/audio");
 
2636
        system ("/usr/bin/setfacl -m user:gdm:rwx,mask:rwx /dev/audioctl");
 
2637
#endif
 
2638
        gdm_debug ("Forking greeter process: %s", command);
 
2639
 
 
2640
        /* Fork. Parent is gdmslave, child is greeter process. */
 
2641
        gdm_sigchld_block_push ();
 
2642
        gdm_sigterm_block_push ();
 
2643
        greet = TRUE;
 
2644
        pid = d->greetpid = fork ();
 
2645
        if (pid == 0)
 
2646
                gdm_unset_signals ();
 
2647
        gdm_sigterm_block_pop ();
 
2648
        gdm_sigchld_block_pop ();
 
2649
 
 
2650
        switch (pid) {
 
2651
 
 
2652
        case 0:
 
2653
                setsid ();
 
2654
 
 
2655
                gdm_unset_signals ();
 
2656
 
 
2657
                /* Plumbing */
 
2658
                VE_IGNORE_EINTR (close (pipe1[1]));
 
2659
                VE_IGNORE_EINTR (close (pipe2[0]));
 
2660
 
 
2661
                VE_IGNORE_EINTR (dup2 (pipe1[0], STDIN_FILENO));
 
2662
                VE_IGNORE_EINTR (dup2 (pipe2[1], STDOUT_FILENO));
 
2663
 
 
2664
                gdm_log_shutdown ();
 
2665
 
 
2666
                gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd/* except */, d->slave_notify_fd/* except2 */);
 
2667
 
 
2668
                gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
2669
 
 
2670
                gdm_log_init ();
 
2671
 
 
2672
                if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0)
 
2673
                        gdm_child_exit (DISPLAY_ABORT,
 
2674
                                        _("%s: Couldn't set groupid to %d"),
 
2675
                                        "gdm_slave_greeter", gdm_daemon_config_get_gdmgid ());
 
2676
 
 
2677
                gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER);
 
2678
                if G_UNLIKELY (initgroups (gdmuser, gdm_daemon_config_get_gdmgid ()) < 0)
 
2679
                        gdm_child_exit (DISPLAY_ABORT,
 
2680
                                        _("%s: initgroups () failed for %s"),
 
2681
                                        "gdm_slave_greeter", gdmuser);
 
2682
 
 
2683
                if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0)
 
2684
                        gdm_child_exit (DISPLAY_ABORT,
 
2685
                                        _("%s: Couldn't set userid to %d"),
 
2686
                                        "gdm_slave_greeter", gdm_daemon_config_get_gdmuid ());
 
2687
 
 
2688
                gdm_restoreenv ();
 
2689
                gdm_reset_locale ();
 
2690
 
 
2691
                g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
 
2692
                g_setenv ("DISPLAY", d->name, TRUE);
 
2693
                if (d->windowpath)
 
2694
                        g_setenv ("WINDOWPATH", d->windowpath, TRUE);
 
2695
 
 
2696
                /* hackish ain't it */
 
2697
                set_xnest_parent_stuff ();
 
2698
 
 
2699
                g_setenv ("LOGNAME", gdmuser, TRUE);
 
2700
                g_setenv ("USER", gdmuser, TRUE);
 
2701
                g_setenv ("USERNAME", gdmuser, TRUE);
 
2702
                g_setenv ("GDM_GREETER_PROTOCOL_VERSION",
 
2703
                          GDM_GREETER_PROTOCOL_VERSION, TRUE);
 
2704
                g_setenv ("GDM_VERSION", VERSION, TRUE);
 
2705
 
 
2706
                pwent = getpwnam (gdmuser);
 
2707
                if G_LIKELY (pwent != NULL) {
 
2708
                        /* Note that usually this doesn't exist */
 
2709
                        if (pwent->pw_dir != NULL &&
 
2710
                            g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS))
 
2711
                                g_setenv ("HOME", pwent->pw_dir, TRUE);
 
2712
                        else
 
2713
                                g_setenv ("HOME",
 
2714
                                          ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
 
2715
                                          TRUE); /* Hack */
 
2716
                        g_setenv ("SHELL", pwent->pw_shell, TRUE);
 
2717
                } else {
 
2718
                        g_setenv ("HOME",
 
2719
                                  ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
 
2720
                                  TRUE); /* Hack */
 
2721
                        g_setenv ("SHELL", "/bin/sh", TRUE);
 
2722
                }
 
2723
 
 
2724
                defaultpath = gdm_daemon_config_get_value_string (GDM_KEY_PATH);
 
2725
                if (ve_string_empty (g_getenv ("PATH"))) {
 
2726
                        g_setenv ("PATH", defaultpath, TRUE);
 
2727
                } else if ( ! ve_string_empty (defaultpath)) {
 
2728
                        gchar *temp_string = g_strconcat (g_getenv ("PATH"),
 
2729
                                                          ":", defaultpath, NULL);
 
2730
                        g_setenv ("PATH", temp_string, TRUE);
 
2731
                        g_free (temp_string);
 
2732
                }
 
2733
                g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
 
2734
                if ( ! ve_string_empty (d->theme_name))
 
2735
                        g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
 
2736
 
 
2737
                if (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG_GESTURES)) {
 
2738
                        g_setenv ("GDM_DEBUG_GESTURES", "true", TRUE);
 
2739
                }
 
2740
 
 
2741
                /* Note that this is just informative, the slave will not listen to
 
2742
                 * the greeter even if it does something it shouldn't on a non-local
 
2743
                 * display so it's not a security risk */
 
2744
                if (d->attached) {
 
2745
                        g_setenv ("GDM_IS_LOCAL", "yes", TRUE);
 
2746
                } else {
 
2747
                        g_unsetenv ("GDM_IS_LOCAL");
 
2748
                }
 
2749
 
 
2750
                /* this is again informal only, if the greeter does time out it will
 
2751
                 * not actually login a user if it's not enabled for this display */
 
2752
                if (d->timed_login_ok) {
 
2753
                        if (ParsedTimedLogin == NULL)
 
2754
                                g_setenv ("GDM_TIMED_LOGIN_OK", " ", TRUE);
 
2755
                        else
 
2756
                                g_setenv ("GDM_TIMED_LOGIN_OK", ParsedTimedLogin, TRUE);
 
2757
                } else {
 
2758
                        g_unsetenv ("GDM_TIMED_LOGIN_OK");
 
2759
                }
 
2760
 
 
2761
                if (SERVER_IS_FLEXI (d)) {
 
2762
                        g_setenv ("GDM_FLEXI_SERVER", "yes", TRUE);
 
2763
                } else {
 
2764
                        g_unsetenv ("GDM_FLEXI_SERVER");
 
2765
                }
 
2766
 
 
2767
                if G_UNLIKELY (d->is_emergency_server) {
 
2768
                        gdm_errorgui_error_box (d,
 
2769
                                                GTK_MESSAGE_ERROR,
 
2770
                                                _("No servers were defined in the "
 
2771
                                                  "configuration file and XDMCP was "
 
2772
                                                  "disabled.  This can only be a "
 
2773
                                                  "configuration error.  GDM has started "
 
2774
                                                  "a single server for you.  You should "
 
2775
                                                  "log in and fix the configuration.  "
 
2776
                                                  "Note that automatic and timed logins "
 
2777
                                                  "are disabled now."));
 
2778
                        g_unsetenv ("GDM_TIMED_LOGIN_OK");
 
2779
                }
 
2780
 
 
2781
                if G_UNLIKELY (d->failsafe_xserver) {
 
2782
                        gdm_errorgui_error_box (d,
 
2783
                                                GTK_MESSAGE_ERROR,
 
2784
                                                _("Could not start the regular X "
 
2785
                                                  "server (your graphical environment) "
 
2786
                                                  "and so this is a failsafe X server.  "
 
2787
                                                  "You should log in and properly "
 
2788
                                                  "configure the X server."));
 
2789
                }
 
2790
 
 
2791
                if G_UNLIKELY (d->busy_display) {
 
2792
                        char *msg = g_strdup_printf
 
2793
                                (_("The specified display number was busy, so "
 
2794
                                   "this server was started on display %s."),
 
2795
                                 d->name);
 
2796
                        gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, msg);
 
2797
                        g_free (msg);
 
2798
                }
 
2799
 
 
2800
                if G_UNLIKELY (d->try_different_greeter) {
 
2801
                        /* FIXME: we should also really be able to do standalone failsafe
 
2802
                           login, but that requires some work and is perhaps an overkill. */
 
2803
                        /* This should handle mostly the case where gdmgreeter is crashing
 
2804
                           and we'd want to start gdmlogin for the user so that at least
 
2805
                           something works instead of a flickering screen */
 
2806
                        gdm_errorgui_error_box (d,
 
2807
                                       GTK_MESSAGE_ERROR,
 
2808
                                       _("The greeter application appears to be crashing. "
 
2809
                                         "Attempting to use a different one."));
 
2810
                        if (strstr (command, "gdmlogin") != NULL) {
 
2811
                                /* in case it is gdmlogin that's crashing
 
2812
                                   try the themed greeter for luck */
 
2813
                                command = LIBEXECDIR "/gdmgreeter";
 
2814
                        } else {
 
2815
                                /* in all other cases, try the gdmlogin (standard greeter)
 
2816
                                   proggie */
 
2817
                                command = LIBEXECDIR "/gdmlogin";
 
2818
                        }
 
2819
                }
 
2820
 
 
2821
                moduleslist = gdm_daemon_config_get_value_string (GDM_KEY_GTK_MODULES_LIST);
 
2822
 
 
2823
                if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES) &&
 
2824
                    ! ve_string_empty (moduleslist) &&
 
2825
                    /* don't add modules if we're trying to prevent crashes,
 
2826
                       perhaps it's the modules causing the problem in the first place */
 
2827
                    ! d->try_different_greeter) {
 
2828
                        gchar *modules = g_strdup_printf ("--gtk-module=%s", moduleslist);
 
2829
                        exec_command (command, modules);
 
2830
                        /* Something went wrong */
 
2831
                        gdm_error (_("%s: Cannot start greeter with gtk modules: %s. Trying without modules"),
 
2832
                                   "gdm_slave_greeter",
 
2833
                                   moduleslist);
 
2834
                        g_free (modules);
 
2835
                }
 
2836
                exec_command (command, NULL);
 
2837
 
 
2838
                gdm_error (_("%s: Cannot start greeter trying default: %s"),
2643
2839
                           "gdm_slave_greeter",
2644
 
                           moduleslist);
2645
 
                g_free (modules);
 
2840
                           LIBEXECDIR "/gdmlogin");
 
2841
 
 
2842
                g_setenv ("GDM_WHACKED_GREETER_CONFIG", "true", TRUE);
 
2843
 
 
2844
                exec_command (LIBEXECDIR "/gdmlogin", NULL);
 
2845
 
 
2846
                VE_IGNORE_EINTR (execl (LIBEXECDIR "/gdmlogin", LIBEXECDIR "/gdmlogin", NULL));
 
2847
 
 
2848
                gdm_errorgui_error_box (d,
 
2849
                               GTK_MESSAGE_ERROR,
 
2850
                               _("Cannot start the greeter application; "
 
2851
                                 "you will not be able to log in.  "
 
2852
                                 "This display will be disabled.  "
 
2853
                                 "Try logging in by other means and "
 
2854
                                 "editing the configuration file"));
 
2855
 
 
2856
                /* If no greeter we really have to disable the display */
 
2857
                gdm_child_exit (DISPLAY_ABORT, _("%s: Error starting greeter on display %s"), "gdm_slave_greeter", d->name);
 
2858
 
 
2859
        case -1:
 
2860
                d->greetpid = 0;
 
2861
                gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't fork gdmgreeter process"), "gdm_slave_greeter");
 
2862
 
 
2863
        default:
 
2864
                VE_IGNORE_EINTR (close (pipe1[0]));
 
2865
                VE_IGNORE_EINTR (close (pipe2[1]));
 
2866
 
 
2867
                whack_greeter_fds ();
 
2868
 
 
2869
                greeter_fd_out = pipe1[1];
 
2870
                greeter_fd_in = pipe2[0];
 
2871
 
 
2872
                gdm_debug ("gdm_slave_greeter: Greeter on pid %d", (int)pid);
 
2873
 
 
2874
                gdm_slave_send_num (GDM_SOP_GREETPID, d->greetpid);
 
2875
                run_pictures (); /* Append pictures to greeter if browsing is on */
 
2876
 
 
2877
                if (always_restart_greeter)
 
2878
                        gdm_slave_greeter_ctl_no_ret (GDM_ALWAYS_RESTART, "Y");
 
2879
                else
 
2880
                        gdm_slave_greeter_ctl_no_ret (GDM_ALWAYS_RESTART, "N");
 
2881
                gdmlang = g_getenv ("GDM_LANG");
 
2882
                if (gdmlang)
 
2883
                        gdm_slave_greeter_ctl_no_ret (GDM_SETLANG, gdmlang);
 
2884
 
 
2885
 
 
2886
                check_notifies_now ();
 
2887
                break;
2646
2888
        }
2647
 
        exec_command (command, NULL);
2648
 
 
2649
 
        gdm_error (_("%s: Cannot start greeter trying default: %s"),
2650
 
                   "gdm_slave_greeter",
2651
 
                   LIBEXECDIR "/gdmlogin");
2652
 
 
2653
 
        g_setenv ("GDM_WHACKED_GREETER_CONFIG", "true", TRUE);
2654
 
 
2655
 
        exec_command (LIBEXECDIR "/gdmlogin", NULL);
2656
 
 
2657
 
        VE_IGNORE_EINTR (execl (LIBEXECDIR "/gdmlogin", LIBEXECDIR "/gdmlogin", NULL));
2658
 
 
2659
 
        gdm_error_box (d,
2660
 
                       GTK_MESSAGE_ERROR,
2661
 
                       _("Cannot start the greeter application; "
2662
 
                         "you will not be able to log in.  "
2663
 
                         "This display will be disabled.  "
2664
 
                         "Try logging in by other means and "
2665
 
                         "editing the configuration file"));
2666
 
        
2667
 
        /* If no greeter we really have to disable the display */
2668
 
        gdm_child_exit (DISPLAY_ABORT, _("%s: Error starting greeter on display %s"), "gdm_slave_greeter", d->name);
2669
 
        
2670
 
    case -1:
2671
 
        d->greetpid = 0;
2672
 
        gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't fork gdmgreeter process"), "gdm_slave_greeter");
2673
 
        
2674
 
    default:
2675
 
        VE_IGNORE_EINTR (close (pipe1[0]));
2676
 
        VE_IGNORE_EINTR (close (pipe2[1]));
2677
 
 
2678
 
        whack_greeter_fds ();
2679
 
 
2680
 
        greeter_fd_out = pipe1[1];
2681
 
        greeter_fd_in = pipe2[0];
2682
 
        
2683
 
        gdm_debug ("gdm_slave_greeter: Greeter on pid %d", (int)pid);
2684
 
 
2685
 
        gdm_slave_send_num (GDM_SOP_GREETPID, d->greetpid);
2686
 
 
2687
 
        run_pictures (); /* Append pictures to greeter if browsing is on */
2688
 
 
2689
 
        check_notifies_now ();
2690
 
        break;
2691
 
    }
2692
2889
}
2693
2890
 
2694
2891
/* This should not call anything that could cause a syslog in case we
2711
2908
        }
2712
2909
 
2713
2910
        /* ensure this is sent from the actual slave with the pipe always, this is anal I know */
2714
 
        if G_LIKELY (d->slavepid == getpid ()) {
 
2911
        if (G_LIKELY (d->slavepid == getppid ()) || G_LIKELY (d->slavepid == getpid ())) {
2715
2912
                fd = slave_fifo_pipe_fd;
2716
2913
        } else {
2717
2914
                fd = -1;
2723
2920
                   these functions.  And if the pipe creation failed
2724
2921
                   in main daemon just abort the main daemon.  */
2725
2922
                /* Use the fifo as a fallback only now that we have a pipe */
2726
 
                fifopath = g_build_filename (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR),
2727
 
                        ".gdmfifo", NULL);
 
2923
                fifopath = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
 
2924
                                             ".gdmfifo", NULL);
2728
2925
                old = geteuid ();
2729
2926
                if (old != 0)
2730
2927
                        seteuid (0);
2758
2955
        }
2759
2956
#endif
2760
2957
 
2761
 
        for (i = 0;
2762
 
             wait_for_ack &&
2763
 
             ! gdm_got_ack &&
2764
 
             parent_exists () &&
2765
 
             i < 10;
2766
 
             i++) {
2767
 
                if (in_usr2_signal > 0) {
 
2958
        /* Wait till you get a response from the daemon */
 
2959
        if (strncmp (str, "opcode="GDM_SOP_SHOW_ERROR_DIALOG,
 
2960
                     strlen ("opcode="GDM_SOP_SHOW_ERROR_DIALOG)) == 0 ||
 
2961
            strncmp (str, "opcode="GDM_SOP_SHOW_YESNO_DIALOG,
 
2962
                     strlen ("opcode="GDM_SOP_SHOW_YESNO_DIALOG)) == 0 ||
 
2963
            strncmp (str, "opcode="GDM_SOP_SHOW_QUESTION_DIALOG,
 
2964
                     strlen ("opcode="GDM_SOP_SHOW_QUESTION_DIALOG)) == 0 ||
 
2965
            strncmp (str, "opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG,
 
2966
                     strlen ("opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG)) == 0) {
 
2967
 
 
2968
                for (; wait_for_ack && !gdm_got_ack ; ) {
2768
2969
                        fd_set rfds;
2769
 
                        struct timeval tv;
2770
2970
 
2771
2971
                        FD_ZERO (&rfds);
2772
2972
                        FD_SET (d->slave_notify_fd, &rfds);
2773
2973
 
2774
 
                        /* Wait up to 1 second. */
2775
 
                        tv.tv_sec = 1;
2776
 
                        tv.tv_usec = 0;
2777
 
 
2778
 
                        if (select (d->slave_notify_fd+1, &rfds, NULL, NULL, &tv) > 0) {
 
2974
                        if (select (d->slave_notify_fd+1, &rfds, NULL, NULL, NULL) > 0) {
2779
2975
                                gdm_slave_handle_usr2_message ();
2780
2976
                        }
2781
 
                } else {
2782
 
                        struct timeval tv;
2783
 
                        /* Wait 1 second. */
2784
 
                        tv.tv_sec = 1;
2785
 
                        tv.tv_usec = 0;
2786
 
                        select (0, NULL, NULL, NULL, &tv);
2787
 
                        /* don't want to use sleep since we're using alarm
2788
 
                           for pinging */
 
2977
                }
 
2978
        } else {
 
2979
                for (i = 0;
 
2980
                     wait_for_ack &&
 
2981
                             ! gdm_got_ack &&
 
2982
                             parent_exists () &&
 
2983
                             i < 10;
 
2984
                     i++) {
 
2985
                        if (in_usr2_signal > 0) {
 
2986
                                fd_set rfds;
 
2987
                                struct timeval tv;
 
2988
 
 
2989
                                FD_ZERO (&rfds);
 
2990
                                FD_SET (d->slave_notify_fd, &rfds);
 
2991
 
 
2992
                                /* Wait up to 1 second. */
 
2993
                                tv.tv_sec = 1;
 
2994
                                tv.tv_usec = 0;
 
2995
 
 
2996
                                if (select (d->slave_notify_fd+1, &rfds, NULL, NULL, &tv) > 0) {
 
2997
                                        gdm_slave_handle_usr2_message ();
 
2998
                                }
 
2999
                        } else {
 
3000
                                struct timeval tv;
 
3001
                                /* Wait 1 second. */
 
3002
                                tv.tv_sec = 1;
 
3003
                                tv.tv_usec = 0;
 
3004
                                select (0, NULL, NULL, NULL, &tv);
 
3005
                                /* don't want to use sleep since we're using alarm
 
3006
                                   for pinging */
 
3007
                        }
2789
3008
                }
2790
3009
        }
2791
3010
 
2829
3048
{
2830
3049
        char *msg;
2831
3050
 
2832
 
        if G_UNLIKELY (gdm_get_value_bool (GDM_KEY_DEBUG) && gdm_in_signal == 0) {
 
3051
        if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG) && gdm_in_signal == 0) {
2833
3052
                gdm_debug ("Sending %s == <secret> for slave %ld",
2834
3053
                           opcode,
2835
3054
                           (long)getpid ());
2836
3055
        }
2837
3056
 
2838
 
        msg = g_strdup_printf ("%s %ld %s", opcode,
2839
 
                               (long)getpid (), ve_sure_string (str));
 
3057
        if (strcmp (opcode, GDM_SOP_SHOW_ERROR_DIALOG) == 0 ||
 
3058
            strcmp (opcode, GDM_SOP_SHOW_YESNO_DIALOG) == 0 ||
 
3059
            strcmp (opcode, GDM_SOP_SHOW_QUESTION_DIALOG) == 0 ||
 
3060
            strcmp (opcode, GDM_SOP_SHOW_ASKBUTTONS_DIALOG) == 0) {
 
3061
                msg = g_strdup_printf ("opcode=%s$$pid=%ld$$%s", opcode,
 
3062
                                       (long)d->slavepid, ve_sure_string (str));
 
3063
        } else {
 
3064
                msg = g_strdup_printf ("%s %ld %s", opcode,
 
3065
                                       (long)getpid (), ve_sure_string (str));
 
3066
        }
2840
3067
 
2841
3068
        gdm_slave_send (msg, TRUE);
2842
3069
 
2844
3071
}
2845
3072
 
2846
3073
static void
2847
 
send_chosen_host (GdmDisplay *disp, const char *hostname)
 
3074
send_chosen_host (GdmDisplay *disp,
 
3075
                  const char *hostname)
2848
3076
{
2849
 
        GdmHostent *host;
2850
 
        struct in_addr ia;
2851
 
#ifdef ENABLE_IPV6
 
3077
        GdmHostent *hostent;
2852
3078
        struct sockaddr_storage ss;
2853
 
#endif
2854
3079
        char *str = NULL;
2855
 
 
2856
 
        host = gdm_gethostbyname (hostname);
2857
 
 
2858
 
        if G_UNLIKELY (host->addrs == NULL) {
 
3080
        char *host;
 
3081
 
 
3082
        hostent = gdm_gethostbyname (hostname);
 
3083
 
 
3084
        if G_UNLIKELY (hostent->addrs == NULL) {
2859
3085
                gdm_error ("Cannot get address of host '%s'", hostname);
2860
 
                gdm_hostent_free (host);
 
3086
                gdm_hostent_free (hostent);
2861
3087
                return;
2862
3088
        }
 
3089
 
2863
3090
        /* take first address */
2864
 
#ifdef ENABLE_IPV6
2865
 
        memcpy (&ss, &host->addrs[0], sizeof (struct sockaddr_storage));
2866
 
        if (ss.ss_family == AF_INET6) {
2867
 
                struct in6_addr ia6;
2868
 
                char buffer6[INET6_ADDRSTRLEN];
2869
 
 
2870
 
                memcpy (&ia6, &((struct sockaddr_in6 *)&ss)->sin6_addr, sizeof (struct in6_addr));
2871
 
                gdm_hostent_free (host);
2872
 
                gdm_debug ("Sending chosen host address (%s) %s", hostname, inet_ntop (AF_INET6, &ia6, buffer6, sizeof (buffer6)));
2873
 
                str = g_strdup_printf ("%s %d %s", GDM_SOP_CHOSEN, disp->indirect_id, buffer6);
2874
 
        }
2875
 
        else if (ss.ss_family == AF_INET) {
2876
 
                char buffer[INET_ADDRSTRLEN];
2877
 
 
2878
 
                memcpy (&ia, &((struct sockaddr_in *)&ss)->sin_addr, sizeof (struct in_addr));
2879
 
                gdm_hostent_free (host);
2880
 
                gdm_debug ("Sending chosen host address (%s) %s", hostname, inet_ntop (AF_INET, &ia, buffer, sizeof (buffer)));
2881
 
                str = g_strdup_printf ("%s %d %s", GDM_SOP_CHOSEN, disp->indirect_id, buffer);
2882
 
        }
2883
 
#else
2884
 
        ia = host->addrs[0];
2885
 
        gdm_hostent_free (host);
2886
 
 
2887
 
        gdm_debug ("Sending chosen host address (%s) %s",
2888
 
                   hostname, inet_ntoa (ia));
2889
 
 
2890
 
        str = g_strdup_printf ("%s %d %s", GDM_SOP_CHOSEN,
2891
 
                               disp->indirect_id,
2892
 
                               inet_ntoa (ia));
2893
 
 
2894
 
#endif
 
3091
        memcpy (&ss, &hostent->addrs[0], sizeof (struct sockaddr_storage));
 
3092
 
 
3093
        gdm_address_get_info (&ss, &host, NULL);
 
3094
        gdm_hostent_free (hostent);
 
3095
 
 
3096
        gdm_debug ("Sending chosen host address (%s) %s", hostname, host);
 
3097
        str = g_strdup_printf ("%s %d %s", GDM_SOP_CHOSEN, disp->indirect_id, host);
2895
3098
        gdm_slave_send (str, FALSE);
2896
3099
 
2897
3100
        g_free (str);
2905
3108
        struct passwd *pwent;
2906
3109
        pid_t pid;
2907
3110
        GdmWaitPid *wp;
2908
 
        char *defaultpath;
2909
 
        char *gdmuser;
2910
 
        char *moduleslist;
 
3111
        const char *defaultpath;
 
3112
        const char *gdmuser;
 
3113
        const char *moduleslist;
2911
3114
 
2912
3115
        gdm_debug ("gdm_slave_chooser: Running chooser on %s", d->name);
2913
3116
 
2916
3119
                gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmchooser"), "gdm_slave_chooser");
2917
3120
 
2918
3121
        /* Run the init script. gdmslave suspends until script has terminated */
2919
 
        gdm_slave_exec_script (d, gdm_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
 
3122
        gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
2920
3123
                               NULL, NULL, FALSE /* pass_stdout */);
2921
3124
 
 
3125
        gdm_debug ("Forking chooser process: %s", gdm_daemon_config_get_value_string (GDM_KEY_CHOOSER));
 
3126
 
2922
3127
        /* Fork. Parent is gdmslave, child is greeter process. */
2923
3128
        gdm_sigchld_block_push ();
2924
3129
        gdm_sigterm_block_push ();
2938
3143
                /* Plumbing */
2939
3144
                VE_IGNORE_EINTR (close (p[0]));
2940
3145
 
2941
 
                if (p[1] != STDOUT_FILENO) 
 
3146
                if (p[1] != STDOUT_FILENO)
2942
3147
                        VE_IGNORE_EINTR (dup2 (p[1], STDOUT_FILENO));
2943
3148
 
2944
 
                closelog ();
 
3149
                gdm_log_shutdown ();
2945
3150
 
2946
3151
                VE_IGNORE_EINTR (close (0));
2947
 
                gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
 
3152
                gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
2948
3153
 
2949
3154
                gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
2950
 
 
2951
 
                openlog ("gdm", LOG_PID, LOG_DAEMON);
2952
 
 
2953
 
                if G_UNLIKELY (setgid (gdm_get_gdmgid ()) < 0) 
 
3155
                gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
3156
 
 
3157
                gdm_log_init ();
 
3158
 
 
3159
                if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0)
2954
3160
                        gdm_child_exit (DISPLAY_ABORT,
2955
3161
                                        _("%s: Couldn't set groupid to %d"),
2956
 
                                        "gdm_slave_chooser", gdm_get_gdmgid ());
 
3162
                                        "gdm_slave_chooser", gdm_daemon_config_get_gdmgid ());
2957
3163
 
2958
 
                gdmuser = gdm_get_value_string (GDM_KEY_USER);
2959
 
                if G_UNLIKELY (initgroups (gdmuser, gdm_get_gdmgid ()) < 0)
 
3164
                gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER);
 
3165
                if G_UNLIKELY (initgroups (gdmuser, gdm_daemon_config_get_gdmgid ()) < 0)
2960
3166
                        gdm_child_exit (DISPLAY_ABORT,
2961
3167
                                        _("%s: initgroups () failed for %s"),
2962
3168
                                        "gdm_slave_chooser", gdmuser);
2963
3169
 
2964
 
                if G_UNLIKELY (setuid (gdm_get_gdmuid ()) < 0) 
 
3170
                if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0)
2965
3171
                        gdm_child_exit (DISPLAY_ABORT,
2966
3172
                                        _("%s: Couldn't set userid to %d"),
2967
 
                                        "gdm_slave_chooser", gdm_get_gdmuid ());
 
3173
                                        "gdm_slave_chooser", gdm_daemon_config_get_gdmuid ());
2968
3174
 
2969
3175
                gdm_restoreenv ();
 
3176
                gdm_reset_locale ();
2970
3177
 
2971
3178
                g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
2972
3179
                g_setenv ("DISPLAY", d->name, TRUE);
 
3180
                if (d->windowpath)
 
3181
                        g_setenv ("WINDOWPATH", d->windowpath, TRUE);
2973
3182
 
2974
3183
                g_setenv ("LOGNAME", gdmuser, TRUE);
2975
3184
                g_setenv ("USER", gdmuser, TRUE);
2984
3193
                                g_setenv ("HOME", pwent->pw_dir, TRUE);
2985
3194
                        else
2986
3195
                                g_setenv ("HOME",
2987
 
                                        ve_sure_string (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR)),
2988
 
                                        TRUE); /* Hack */
 
3196
                                          ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
 
3197
                                          TRUE); /* Hack */
2989
3198
                        g_setenv ("SHELL", pwent->pw_shell, TRUE);
2990
3199
                } else {
2991
3200
                        g_setenv ("HOME",
2992
 
                                ve_sure_string (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR)),
2993
 
                                TRUE); /* Hack */
 
3201
                                  ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
 
3202
                                  TRUE); /* Hack */
2994
3203
                        g_setenv ("SHELL", "/bin/sh", TRUE);
2995
3204
                }
2996
3205
 
2997
 
                defaultpath = gdm_get_value_string (GDM_KEY_PATH);
 
3206
                defaultpath = gdm_daemon_config_get_value_string (GDM_KEY_PATH);
2998
3207
                if (ve_string_empty (g_getenv ("PATH"))) {
2999
3208
                        g_setenv ("PATH", defaultpath, TRUE);
3000
3209
                } else if ( ! ve_string_empty (defaultpath)) {
3001
 
                        g_setenv ("PATH", g_strconcat (g_getenv ("PATH"), ":", defaultpath, NULL), TRUE);
 
3210
                        gchar *temp_string = g_strconcat (g_getenv ("PATH"),
 
3211
                                                          ":", defaultpath, NULL);
 
3212
                        g_setenv ("PATH", temp_string, TRUE);
 
3213
                        g_free (temp_string);
3002
3214
                }
3003
3215
                g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
3004
3216
                if ( ! ve_string_empty (d->theme_name))
3005
3217
                        g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
3006
3218
 
3007
 
                moduleslist = gdm_get_value_string (GDM_KEY_GTK_MODULES_LIST);
3008
 
                if (gdm_get_value_bool (GDM_KEY_ADD_GTK_MODULES) &&
 
3219
                moduleslist = gdm_daemon_config_get_value_string (GDM_KEY_GTK_MODULES_LIST);
 
3220
                if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES) &&
3009
3221
                    ! ve_string_empty (moduleslist)) {
3010
3222
                        char *modules = g_strdup_printf ("--gtk-module=%s", moduleslist);
3011
 
                        exec_command (gdm_get_value_string (GDM_KEY_CHOOSER), modules);
 
3223
                        exec_command (gdm_daemon_config_get_value_string (GDM_KEY_CHOOSER), modules);
3012
3224
                }
3013
3225
 
3014
 
                exec_command (gdm_get_value_string (GDM_KEY_CHOOSER), NULL);
 
3226
                exec_command (gdm_daemon_config_get_value_string (GDM_KEY_CHOOSER), NULL);
3015
3227
 
3016
 
                gdm_error_box (d,
 
3228
                gdm_errorgui_error_box (d,
3017
3229
                               GTK_MESSAGE_ERROR,
3018
3230
                               _("Cannot start the chooser application. "
3019
3231
                                 "You will probably not be able to log in.  "
3094
3306
            strcmp (session_name, GDM_SESSION_FAILSAFE_XTERM) == 0)
3095
3307
                return TRUE;
3096
3308
 
3097
 
        if (ve_string_empty (gdm_get_value_string (GDM_KEY_SESSION_DESKTOP_DIR)))
 
3309
        if (ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_SESSION_DESKTOP_DIR)))
3098
3310
                return gdm_is_session_magic (session_name);
3099
3311
 
3100
 
        exec = gdm_get_session_exec (session_name, TRUE /* check_try_exec */);
 
3312
        exec = gdm_daemon_config_get_session_exec (session_name, TRUE /* check_try_exec */);
3101
3313
        if (exec == NULL)
3102
3314
                ret = FALSE;
3103
3315
        g_free (exec);
3123
3335
        };
3124
3336
        int i;
3125
3337
        char *session;
3126
 
        char *defaultsession = gdm_get_value_string (GDM_KEY_DEFAULT_SESSION);
 
3338
        const char *defaultsession = gdm_daemon_config_get_value_string (GDM_KEY_DEFAULT_SESSION);
3127
3339
 
3128
3340
        if (!ve_string_empty (defaultsession) &&
3129
3341
            is_session_ok (defaultsession))
3145
3357
        int i;
3146
3358
        char *try[] = {
3147
3359
                "/usr/bin/X11/",
3148
 
                "/usr/X11R6/bin/",
 
3360
                "/usr/local/bin/",
3149
3361
                "/opt/X11R6/bin/",
3150
3362
                "/usr/bin/",
3151
3363
                "/usr/openwin/bin/",
3301
3513
        int ret=-1;
3302
3514
        char *seuser=NULL;
3303
3515
        char *level=NULL;
3304
 
 
 
3516
 
3305
3517
        /* If selinux is not enabled, then we don't do anything */
3306
3518
        if (is_selinux_enabled () <= 0)
3307
3519
                return TRUE;
3321
3533
 
3322
3534
        if (setexeccon (scontext) != 0) {
3323
3535
                gdm_error ("SELinux gdm login: unable to set executable context %s.",
3324
 
                          (char *)scontext);
 
3536
                           (char *)scontext);
3325
3537
                gdm_fdprintf (2, "SELinux gdm login: unable to set executable context %s.",
3326
3538
                              (char *)scontext);
3327
3539
                freecon (scontext);
3340
3552
                   gboolean failsafe,
3341
3553
                   const char *home_dir,
3342
3554
                   gboolean home_dir_ok,
 
3555
#ifdef WITH_CONSOLE_KIT
 
3556
                   const char *ck_session_cookie,
 
3557
#endif
3343
3558
                   const char *session,
3344
3559
                   const char *save_session,
3345
3560
                   const char *language,
3348
3563
                   gboolean savesess,
3349
3564
                   gboolean savelang)
3350
3565
{
3351
 
        char *exec;
 
3566
        const char *old_system_data_dirs;
 
3567
        char *sessionexec = NULL;
 
3568
        GString *fullexec = NULL;
3352
3569
        const char *shell = NULL;
3353
 
        char *greeter;
 
3570
        const char *greeter;
3354
3571
        gint result;
3355
 
#ifndef HAVE_TSOL
3356
 
        char *argv[4];
3357
 
#else
3358
 
        char *argv[7];
3359
 
#endif
 
3572
        gchar **argv = NULL;
3360
3573
 
3361
3574
#ifdef CAN_USE_SETPENV
3362
3575
        extern char **newenv;
3397
3610
        /* Determine default greeter type so the PreSession */
3398
3611
        /* script can set the appropriate background color. */
3399
3612
        if (d->attached) {
3400
 
                greeter = gdm_get_value_string (GDM_KEY_GREETER);
 
3613
                greeter = gdm_daemon_config_get_value_string (GDM_KEY_GREETER);
3401
3614
        } else {
3402
 
                greeter = gdm_get_value_string (GDM_KEY_REMOTE_GREETER);                
 
3615
                greeter = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER);
3403
3616
        }
3404
 
        
 
3617
 
3405
3618
        if (strstr (greeter, "gdmlogin") != NULL) {
3406
 
                g_setenv ("GDM_GREETER_TYPE", "PLAIN", TRUE);   
 
3619
                g_setenv ("GDM_GREETER_TYPE", "PLAIN", TRUE);
3407
3620
        } else if (strstr (greeter, "gdmgreeter") != NULL) {
3408
 
                g_setenv ("GDM_GREETER_TYPE", "THEMED", TRUE);  
 
3621
                g_setenv ("GDM_GREETER_TYPE", "THEMED", TRUE);
3409
3622
        } else {
3410
3623
                /* huh? */
3411
3624
                g_setenv ("GDM_GREETER_TYPE", "unknown", TRUE);
3412
3625
        }
3413
3626
 
3414
3627
        /* Run the PreSession script */
3415
 
        if G_UNLIKELY (gdm_slave_exec_script (d, gdm_get_value_string (GDM_KEY_PRESESSION),
 
3628
        if G_UNLIKELY (gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_PRESESSION),
3416
3629
                                              pwent->pw_name, pwent,
3417
3630
                                              TRUE /* pass_stdout */) != EXIT_SUCCESS &&
3418
3631
                       /* ignore errors in failsafe modes */
3419
 
                       ! failsafe) 
 
3632
                       ! failsafe)
3420
3633
                /* If script fails reset X server and restart greeter */
3421
3634
                gdm_child_exit (DISPLAY_REMANAGE,
3422
3635
                                _("%s: Execution of PreSession script returned > 0. Aborting."), "session_child_run");
3423
3636
 
3424
 
        gdm_clearenv ();
 
3637
        old_system_data_dirs = g_getenv ("XDG_DATA_DIRS") ?
 
3638
                               g_getenv ("XDG_DATA_DIRS") :
 
3639
                               "/usr/local/share/:/usr/share/";
 
3640
 
 
3641
        ve_clearenv ();
3425
3642
 
3426
3643
        /* Prepare user session */
3427
3644
        g_setenv ("XAUTHORITY", d->userauth, TRUE);
3428
3645
        g_setenv ("DISPLAY", d->name, TRUE);
 
3646
        if (d->windowpath)
 
3647
                g_setenv ("WINDOWPATH", d->windowpath, TRUE);
3429
3648
        g_setenv ("LOGNAME", pwent->pw_name, TRUE);
3430
3649
        g_setenv ("USER", pwent->pw_name, TRUE);
3431
3650
        g_setenv ("USERNAME", pwent->pw_name, TRUE);
3432
3651
        g_setenv ("HOME", home_dir, TRUE);
 
3652
#ifdef WITH_CONSOLE_KIT
 
3653
        if (ck_session_cookie != NULL) {
 
3654
                g_setenv ("XDG_SESSION_COOKIE", ck_session_cookie, TRUE);
 
3655
        }
 
3656
#endif
3433
3657
        g_setenv ("PWD", home_dir, TRUE);
3434
3658
        g_setenv ("GDMSESSION", session, TRUE);
3435
3659
        g_setenv ("DESKTOP_SESSION", session, TRUE);
3455
3679
 
3456
3680
        /* Special PATH for root */
3457
3681
        if (pwent->pw_uid == 0)
3458
 
                g_setenv ("PATH", gdm_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
 
3682
                g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
3459
3683
        else
3460
 
                g_setenv ("PATH", gdm_get_value_string (GDM_KEY_PATH), TRUE);
 
3684
                g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_PATH), TRUE);
 
3685
 
 
3686
        /*
 
3687
         * Install GDM desktop files to a non-default desktop file 
 
3688
         * location (/usr/share/gdm/applications) and GDM appends 
 
3689
         * this directory to the end of the XDG_DATA_DIR environment
 
3690
         * variable.  This way, GDM menu choices never appear if
 
3691
         * using a different display manager.
 
3692
         */
 
3693
        {
 
3694
                char *new_system_data_dirs;
 
3695
 
 
3696
                new_system_data_dirs = g_build_path (":",
 
3697
                         old_system_data_dirs, DATADIR "/gdm/", NULL);
 
3698
 
 
3699
                g_setenv ("XDG_DATA_DIRS", new_system_data_dirs, TRUE);
 
3700
 
 
3701
                g_free (new_system_data_dirs);
 
3702
        }
3461
3703
 
3462
3704
        /* Eeeeek, this no lookie as a correct language code,
3463
3705
         * just use the system default */
3465
3707
                        ! ve_locale_exists (language)) {
3466
3708
                char *msg = g_strdup_printf (_("Language %s does not exist; using %s"),
3467
3709
                                             language, _("System default"));
3468
 
                gdm_error_box (d, GTK_MESSAGE_ERROR, msg);
 
3710
                gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, msg);
3469
3711
                language = NULL;
3470
3712
                g_free (msg);
3471
3713
        }
3475
3717
        VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640));
3476
3718
 
3477
3719
        setpgid (0, 0);
3478
 
        
 
3720
 
3479
3721
        umask (022);
3480
 
        
 
3722
 
3481
3723
        /* setup the verify env vars */
3482
3724
        if G_UNLIKELY ( ! gdm_verify_setup_env (d))
3483
3725
                gdm_child_exit (DISPLAY_REMANAGE,
3484
3726
                                _("%s: Could not setup environment for %s. "
3485
3727
                                  "Aborting."),
3486
 
                                "session_child_run", login);
 
3728
                                "session_child_run", login_user);
3487
3729
 
3488
3730
        /* setup euid/egid to the correct user,
3489
3731
         * not to leave the egid around.  It's
3500
3742
                struct stat s0, s1, s2;
3501
3743
                gint        s0_ret, s1_ret, s2_ret;
3502
3744
                gint        iceauth_fd;
3503
 
 
3504
 
                 NEVER_FAILS_root_set_euid_egid (0, 0);
 
3745
 
 
3746
                NEVER_FAILS_root_set_euid_egid (0, 0);
3505
3747
 
3506
3748
                iceauth_fd = open (".ICEauthority", O_RDONLY);
3507
 
 
 
3749
 
3508
3750
                s0_ret = stat (home_dir, &s0);
3509
3751
                s1_ret = lstat (".ICEauthority", &s1);
3510
3752
                s2_ret = fstat (iceauth_fd, &s2);
3511
 
 
 
3753
 
3512
3754
                if (iceauth_fd >= 0 &&
3513
3755
                    s0_ret == 0 &&
3514
3756
                    s0.st_uid == pwent->pw_uid &&
3535
3777
                                pwent->pw_gid);
3536
3778
                        fchmod (iceauth_fd, S_IRUSR | S_IWUSR);
3537
3779
                }
3538
 
 
 
3780
 
3539
3781
                if (iceauth_fd >= 0)
3540
3782
                        close (iceauth_fd);
3541
3783
        }
3552
3794
                                  "Aborting."), "session_child_run",
3553
3795
                                login);
3554
3796
#else
3555
 
        if G_UNLIKELY (setuid (pwent->pw_uid) < 0) 
 
3797
        if G_UNLIKELY (setuid (pwent->pw_uid) < 0)
3556
3798
                gdm_child_exit (DISPLAY_REMANAGE,
3557
 
                                _("%s: Could not become %s. Aborting."), "session_child_run", login);
 
3799
                                _("%s: Could not become %s. Aborting."), "session_child_run", login_user);
3558
3800
#endif
3559
3801
 
3560
3802
        /* Only force GDM_LANG to something if there is other then
3567
3809
 
3568
3810
        /* just in case there is some weirdness going on */
3569
3811
        VE_IGNORE_EINTR (g_chdir (home_dir));
3570
 
        
 
3812
 
3571
3813
        if (usrcfgok && home_dir_ok)
3572
 
                gdm_set_user_session_lang (savesess, savelang, home_dir, save_session, language);
3573
 
        
3574
 
        closelog ();
3575
 
 
3576
 
        gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
3577
 
 
3578
 
        openlog ("gdm", LOG_PID, LOG_DAEMON);
3579
 
        
3580
 
        argv[0] = NULL;
3581
 
        argv[1] = NULL;
3582
 
        argv[2] = NULL;
3583
 
        argv[3] = NULL;
3584
 
#ifdef HAVE_TSOL
3585
 
        argv[4] = NULL;
3586
 
        argv[5] = NULL;
3587
 
        argv[6] = NULL;
3588
 
#endif
3589
 
 
3590
 
        exec = NULL;
 
3814
                gdm_daemon_config_set_user_session_lang (savesess, savelang, home_dir, save_session, language);
 
3815
 
 
3816
        gdm_log_shutdown ();
 
3817
 
 
3818
        gdm_close_all_descriptors (3 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
 
3819
 
 
3820
        gdm_log_init ();
 
3821
 
 
3822
        sessionexec = NULL;
3591
3823
        if (strcmp (session, GDM_SESSION_FAILSAFE_XTERM) != 0 &&
3592
3824
            strcmp (session, GDM_SESSION_FAILSAFE_GNOME) != 0) {
3593
 
                exec = gdm_get_session_exec (session,
 
3825
 
 
3826
                sessionexec = gdm_daemon_config_get_session_exec (session,
3594
3827
                        FALSE /* check_try_exec */);
3595
3828
 
3596
 
                if G_UNLIKELY (exec == NULL) {
 
3829
                if G_UNLIKELY (sessionexec == NULL) {
3597
3830
                        gchar *msg = g_strdup_printf (
3598
 
                                _("No Exec line in the session file: %s.  Running the GNOME failsafe session instead"),
3599
 
                                session);
 
3831
                                                      _("No Exec line in the session file: %s.  Running the GNOME failsafe session instead"),
 
3832
                                                      session);
3600
3833
 
3601
3834
                        gdm_error (_("%s: %s"), "session_child_run", msg);
3602
 
                        gdm_error_box (d, GTK_MESSAGE_ERROR, msg);
 
3835
                        gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, msg);
3603
3836
                        g_free (msg);
3604
3837
 
3605
3838
                        session = GDM_SESSION_FAILSAFE_GNOME;
3606
3839
                } else {
3607
3840
                        /* HACK!, if failsafe, we really wish to run the
3608
3841
                           internal one */
3609
 
                        if (strcmp (exec, "failsafe") == 0) {
 
3842
                        if (strcmp (sessionexec, "failsafe") == 0) {
3610
3843
                                session = GDM_SESSION_FAILSAFE_XTERM;
3611
 
                                exec    = NULL;
 
3844
                                sessionexec    = NULL;
3612
3845
                        }
3613
3846
                }
3614
3847
        }
3615
3848
 
3616
 
        if (exec != NULL) {
3617
 
                char *basexsession = gdm_get_value_string (GDM_KEY_BASE_XSESSION);
 
3849
        fullexec = g_string_new (NULL);
 
3850
 
 
3851
#ifdef HAVE_CTRUN
 
3852
        g_string_append (fullexec, "/usr/bin/ctrun -l child -i none ");
 
3853
#endif
 
3854
 
 
3855
        if (sessionexec != NULL) {
 
3856
                const char *basexsession = gdm_daemon_config_get_value_string (GDM_KEY_BASE_XSESSION);
 
3857
                char **bxvec = g_strsplit (basexsession, " ", -1);
3618
3858
 
3619
3859
                /* cannot be possibly failsafe */
3620
 
                if G_UNLIKELY (g_access (basexsession, X_OK) != 0) {
 
3860
                if G_UNLIKELY (bxvec == NULL || g_access (bxvec[0], X_OK) != 0) {
3621
3861
                        gdm_error (_("%s: Cannot find or run the base Xsession script.  Running the GNOME failsafe session instead."),
3622
3862
                                   "session_child_run");
3623
3863
                        session = GDM_SESSION_FAILSAFE_GNOME;
3624
 
                        exec = NULL;
3625
 
                        gdm_error_box
 
3864
                        sessionexec = NULL;
 
3865
                        gdm_errorgui_error_box
3626
3866
                                (d, GTK_MESSAGE_ERROR,
3627
3867
                                 _("Cannot find or run the base session script.  Running the GNOME failsafe session instead."));
3628
3868
                } else {
3629
 
                        /* This is where everything is OK, and note that
3630
 
                           we really DON'T care about leaks, we are going to
3631
 
                           exec in just a bit */
3632
 
#ifdef HAVE_TSOL
3633
 
                        if (have_suntsol_extension) {
3634
 
                                argv[0] = basexsession;
3635
 
                                argv[1] = g_strdup ("/usr/bin/tsoljdslabel");
3636
 
                                argv[2] = exec;
3637
 
                                argv[3] = argv[4] = argv[5] = argv[6] = NULL;
3638
 
                        } else {
3639
 
#endif
3640
 
                        argv[0] = basexsession;
3641
 
                        argv[1] = exec;
3642
 
                        argv[2] = NULL;
3643
 
#ifdef HAVE_TSOL
3644
 
                        argv[3] = argv[4] = argv[5] = argv[6] = NULL;
3645
 
                        }
3646
 
#endif
 
3869
                        /*
 
3870
                         * This is where the session is OK, and note that
 
3871
                         * we really DON'T care about leaks, we are going to
 
3872
                         * exec in just a bit
 
3873
                         */
 
3874
                        g_string_append (fullexec, bxvec[0]);
 
3875
                        g_string_append (fullexec, " ");
 
3876
 
 
3877
#ifdef HAVE_TSOL
 
3878
                        if (have_suntsol_extension)
 
3879
                                g_string_append (fullexec, "/usr/bin/tsoljdslabel ");
 
3880
#endif
 
3881
                        g_string_append (fullexec, sessionexec);
3647
3882
                }
 
3883
                g_strfreev (bxvec);
3648
3884
        }
3649
3885
 
3650
3886
        if (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0) {
 
3887
                gchar *test_exec = NULL;
 
3888
 
3651
3889
#ifdef HAVE_TSOL
3652
 
                if (have_suntsol_extension == TRUE) {
3653
 
                        /* Trusted Path will be preserved as long as the sys admin
3654
 
                     * doesn't put anything stupid in gdm.conf */
3655
 
                        argv[0] = g_strdup ("/usr/bin/tsoljdslabel");
3656
 
                        argv[1] = find_prog ("gnome-session");
3657
 
                        if G_UNLIKELY (argv[1] == NULL) {
3658
 
                                /* yaikes */
3659
 
                                gdm_error (_("%s: gnome-session not found for a failsafe GNOME session, trying xterm"),
3660
 
                                           "session_child_run");
3661
 
                                session = GDM_SESSION_FAILSAFE_XTERM;
3662
 
                                gdm_error_box
3663
 
                                        (d, GTK_MESSAGE_ERROR,
3664
 
                                         _("Could not find the GNOME installation, "
3665
 
                                           "will try running the \"Failsafe xterm\" "
3666
 
                                           "session."));
3667
 
                        } else {
3668
 
                                argv[2] = "--failsafe";
3669
 
                                argv[3] = NULL;
3670
 
                                gdm_error_box
3671
 
                                        (d, GTK_MESSAGE_INFO,
3672
 
                                         _("This is the Failsafe GNOME session.  "
3673
 
                                   "You will be logged into the 'Default' "
3674
 
                                   "session of GNOME without the startup scripts "
3675
 
                                   "being run.  This should be used to fix problems "
3676
 
                                   "in your installation."));
3677
 
                        }
3678
 
                } else {
 
3890
                /*
 
3891
                 * Trusted Path will be preserved as long as the sys admin
 
3892
                 * doesn't put anything stupid in gdm.conf
 
3893
                 */
 
3894
                if (have_suntsol_extension == TRUE)
 
3895
                        g_string_append (fullexec, "/usr/bin/tsoljdslabel ");
3679
3896
#endif
3680
 
                argv[0] = find_prog ("gnome-session");
3681
 
                if G_UNLIKELY (argv[0] == NULL) {
 
3897
 
 
3898
                test_exec = find_prog ("gnome-session");
 
3899
                if G_UNLIKELY (test_exec == NULL) {
3682
3900
                        /* yaikes */
3683
 
                        gdm_error (_("%s: gnome-session not found for a failsafe GNOME session; trying xterm"),
 
3901
                        gdm_error (_("%s: gnome-session not found for a failsafe GNOME session, trying xterm"),
3684
3902
                                   "session_child_run");
3685
3903
                        session = GDM_SESSION_FAILSAFE_XTERM;
3686
 
                        gdm_error_box
 
3904
                        gdm_errorgui_error_box
3687
3905
                                (d, GTK_MESSAGE_ERROR,
3688
 
                                 _("Could not find the GNOME installation.  "
3689
 
                                   "Running the \"Failsafe xterm\" "
3690
 
                                   "session instead."));
 
3906
                                 _("Could not find the GNOME installation, "
 
3907
                                   "will try running the \"Failsafe xterm\" "
 
3908
                                   "session."));
3691
3909
                } else {
3692
 
                        argv[1] = "--failsafe";
3693
 
                        argv[2] = NULL;
3694
 
                        gdm_error_box
 
3910
                        g_string_append (fullexec, test_exec);
 
3911
                        g_string_append (fullexec, " --failsafe");
 
3912
                        gdm_errorgui_error_box
3695
3913
                                (d, GTK_MESSAGE_INFO,
3696
3914
                                 _("This is the Failsafe GNOME session.  "
3697
3915
                                   "You will be logged into the 'Default' "
3699
3917
                                   "being run.  This should be used to fix problems "
3700
3918
                                   "in your installation."));
3701
3919
                }
3702
 
#ifdef HAVE_TSOL
3703
 
                }
3704
 
#endif
3705
3920
                failsafe = TRUE;
3706
3921
        }
3707
3922
 
3708
 
        /* an if and not an else, we could have done a fall-through
 
3923
        /* This is an if and not an else, we could have done a fall-through
3709
3924
         * to here in the above code if we can't find gnome-session */
3710
3925
        if (strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0) {
3711
 
                argv[0] = find_prog ("xterm");
3712
 
                if (argv[0] == NULL) {
3713
 
                        gdm_error_box (d, GTK_MESSAGE_ERROR,
 
3926
                gchar *test_exec;
 
3927
                gchar *geometry = g_strdup_printf (" -geometry 80x24-%d-%d",
 
3928
                                                   d->lrh_offsetx,
 
3929
                                                   d->lrh_offsety);
 
3930
                test_exec = find_prog ("xterm");
 
3931
                if (test_exec == NULL) {
 
3932
                        gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR,
3714
3933
                                       _("Cannot find \"xterm\" to start "
3715
3934
                                         "a failsafe session."));
3716
3935
                        /* nyah nyah nyah nyah nyah */
3717
3936
                        /* 66 means no "session crashed" examine .xsession-errors dialog */
3718
3937
                        _exit (66);
 
3938
                } else {
 
3939
                        gchar *failsafe_msg = NULL;
 
3940
                        g_string_append (fullexec, test_exec);
 
3941
                        g_string_append (fullexec, geometry);
 
3942
 
 
3943
                        failsafe_msg = _("This is the Failsafe xterm session.  "
 
3944
                                         "You will be logged into a terminal "
 
3945
                                         "console so that you may fix your system "
 
3946
                                         "if you cannot log in any other way.  "
 
3947
                                         "To exit the terminal emulator, type "
 
3948
                                         "'exit' and an enter into the window.");
3719
3949
#ifdef HAVE_TSOL
3720
 
                } else if (have_suntsol_extension) {
3721
 
                        argv[1] = "-geometry";
3722
 
                        argv[2] = g_strdup_printf ("80x24-%d-%d",
3723
 
                                                   d->lrh_offsetx,
3724
 
                                                   d->lrh_offsety);
3725
 
                        /*
3726
 
                         * In a Solaris Trusted Extensions environment, failsafe xterms should
3727
 
                         * be restricted to the root user, or users who have the root role.
3728
 
                         * This is necessary to prevent normal users and evil terrorists
3729
 
                         * bypassing their assigned clearance and getting direct access
3730
 
                         * to the global zone.
3731
 
                         */
3732
 
                        if (pwent->pw_uid == 0) {
3733
 
                                argv[3] = argv[4] = argv[5] = argv[6] = NULL;
3734
 
                                gdm_error_box
3735
 
                                        (d, GTK_MESSAGE_INFO,
3736
 
                                        _("This is the Failsafe xterm session.  "
3737
 
                                          "You will be logged into a terminal "
3738
 
                                          "console so that you may fix your system "
3739
 
                                          "if you cannot log in any other way.  "
3740
 
                                          "To exit the terminal emulator, type "
3741
 
                                          "'exit' and an enter into the window."));
3742
 
                                focus_first_x_window ("xterm");
3743
 
                        } else if (gdm_can_i_assume_root_role (pwent) == TRUE) {
3744
 
                                argv[3] = "-C";
3745
 
                                argv[4] = "-e";
3746
 
                                argv[5] = "su";
3747
 
                                argv[6] = NULL;
3748
 
                                gdm_error_box
3749
 
                                        (d, GTK_MESSAGE_INFO,
3750
 
                                        _("This is the Failsafe xterm session.  "
3751
 
                                          "You will be logged into a terminal "
3752
 
                                          "console and be prompted to enter the "
3753
 
                                          "password for root so that you may fix "
3754
 
                                          "your system if you cannot log in any "
3755
 
                                          "other way. To exit the terminal "
3756
 
                                          "emulator, type 'exit' and an enter "
3757
 
                                          "into the window."));
3758
 
                                focus_first_x_window ("xterm");
3759
 
                        } else {
3760
 
                                /* Normal user without root role - get lost */
3761
 
                                gdm_error_box
3762
 
                                        (d, GTK_MESSAGE_INFO,
3763
 
                                        _("The failsafe session is restricted to "
3764
 
                                          "users who have been assigned the root "
3765
 
                                          "role. If you cannot log in any other "
3766
 
                                          "way please contact your system "
3767
 
                                          "administrator"));
3768
 
                                _exit (66);
 
3950
                        if (have_suntsol_extension) {
 
3951
                                /*
 
3952
                                 * In a Solaris Trusted Extensions environment, failsafe
 
3953
                                 * xterms should be restricted to the root user, or
 
3954
                                 * users who have the root role.  This is necessary to
 
3955
                                 * prevent normal users and evil terrorists bypassing
 
3956
                                 * their assigned clearance and getting direct access
 
3957
                                 * to the global zone.
 
3958
                                 */
 
3959
                                if (pwent->pw_uid != 0 &&
 
3960
                                    gdm_can_i_assume_root_role (pwent) == TRUE) {
 
3961
                                        g_string_append (fullexec, " -C -e su");
 
3962
                                        failsafe_msg =  _("This is the Failsafe xterm session.  "
 
3963
                                                          "You will be logged into a terminal "
 
3964
                                                          "console and be prompted to enter the "
 
3965
                                                          "password for root so that you may fix "
 
3966
                                                          "your system if you cannot log in any "
 
3967
                                                          "other way. To exit the terminal "
 
3968
                                                          "emulator, type 'exit' and an enter "
 
3969
                                                          "into the window.");
 
3970
                                } else {
 
3971
                                        /* Normal user without root role - get lost */
 
3972
                                        gdm_errorgui_error_box
 
3973
                                                (d, GTK_MESSAGE_INFO,
 
3974
                                                 _("The failsafe session is restricted to "
 
3975
                                                   "users who have been assigned the root "
 
3976
                                                   "role. If you cannot log in any other "
 
3977
                                                   "way please contact your system "
 
3978
                                                   "administrator"));
 
3979
                                        _exit (66);
 
3980
                                }
3769
3981
                        }
3770
3982
#endif /* HAVE_TSOL */
3771
 
                } else {
3772
 
                        argv[1] = "-geometry";
3773
 
                        argv[2] = g_strdup_printf ("80x24-%d-%d",
3774
 
                                                   d->lrh_offsetx,
3775
 
                                                   d->lrh_offsety);
3776
 
                        argv[3] = NULL;
3777
 
#ifdef HAVE_TSOL
3778
 
                        argv[4] = argv[5] = argv[6] = NULL;
3779
 
#endif
3780
 
                        gdm_error_box
3781
 
                                (d, GTK_MESSAGE_INFO,
3782
 
                                 _("This is the Failsafe xterm session.  "
3783
 
                                   "You will be logged into a terminal "
3784
 
                                   "console so that you may fix your system "
3785
 
                                   "if you cannot log in any other way.  "
3786
 
                                   "To exit the terminal emulator, type "
3787
 
                                   "'exit' and an enter into the window."));
 
3983
 
 
3984
                        gdm_errorgui_error_box (d, GTK_MESSAGE_INFO, failsafe_msg);
3788
3985
                        focus_first_x_window ("xterm");
3789
3986
                }
 
3987
                g_free (geometry);
3790
3988
                failsafe = TRUE;
3791
 
        } 
 
3989
        }
3792
3990
 
3793
 
#ifdef HAVE_TSOL
3794
 
        gdm_debug ("Running %s %s %s %s %s %s for %s on %s",
3795
 
                   argv[0],
3796
 
                   ve_sure_string (argv[1]),
3797
 
                   ve_sure_string (argv[2]),
3798
 
                   ve_sure_string (argv[3]),
3799
 
                   ve_sure_string (argv[4]),
3800
 
                   ve_sure_string (argv[5]),
3801
 
                   login, d->name);
3802
 
#else
3803
 
        gdm_debug ("Running %s %s %s for %s on %s",
3804
 
                   argv[0],
3805
 
                   ve_sure_string (argv[1]),
3806
 
                   ve_sure_string (argv[2]),
3807
 
                   login, d->name);
3808
 
#endif
 
3991
        gdm_debug ("Running %s for %s on %s", fullexec->str, login_user, d->name);
3809
3992
 
3810
3993
        if ( ! ve_string_empty (pwent->pw_shell)) {
3811
3994
                shell = pwent->pw_shell;
3814
3997
        }
3815
3998
 
3816
3999
        /* just a stupid test */
3817
 
        if (strcmp (shell, "/sbin/nologin") == 0 ||
 
4000
        if (strcmp (shell, NOLOGIN) == 0 ||
3818
4001
            strcmp (shell, "/bin/false") == 0 ||
3819
4002
            strcmp (shell, "/bin/true") == 0) {
3820
4003
                gdm_error (_("%s: User not allowed to log in"),
3821
4004
                           "session_child_run");
3822
 
                gdm_error_box (d, GTK_MESSAGE_ERROR,
 
4005
                gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR,
3823
4006
                               _("The system administrator has "
3824
4007
                                 "disabled your account."));
3825
4008
                /* ends as if nothing bad happened */
3831
4014
#ifdef CAN_USE_SETPENV
3832
4015
        /* Call the function setpenv which instanciates the extern variable "newenv" */
3833
4016
        setpenv (login, (PENV_INIT | PENV_NOEXEC), NULL, NULL);
3834
 
        
 
4017
 
3835
4018
        /* Add the content of the "newenv" variable to the environment */
3836
4019
        for (i=0; newenv != NULL && newenv[i] != NULL; i++) {
3837
4020
                char *env_str = g_strdup (newenv[i]);
3850
4033
        if ( ! gdm_selinux_setup (pwent->pw_name)) {
3851
4034
                /* 66 means no "session crashed" examine .xsession-errors
3852
4035
                   dialog */
3853
 
                gdm_error_box (d, GTK_MESSAGE_ERROR,
 
4036
                gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR,
3854
4037
                               _("Error! Unable to set executable context."));
3855
4038
                _exit (66);
3856
4039
        }
3857
4040
#endif
3858
4041
 
 
4042
        g_shell_parse_argv (fullexec->str, NULL, &argv, NULL);
3859
4043
        VE_IGNORE_EINTR (execv (argv[0], argv));
 
4044
        g_strfreev (argv);
3860
4045
 
3861
4046
        /* will go to .xsession-errors */
3862
 
#ifdef HAVE_TSOL
3863
 
        fprintf (stderr, _("%s: Could not exec %s %s %s %s %s %s"), 
3864
 
                 "session_child_run",
3865
 
                 argv[0],
3866
 
                 ve_sure_string (argv[1]),
3867
 
                 ve_sure_string (argv[2]),
3868
 
                 ve_sure_string (argv[3]),
3869
 
                 ve_sure_string (argv[4]),
3870
 
                 ve_sure_string (argv[5]));
3871
 
 
3872
 
        gdm_error ( _("%s: Could not exec %s %s %s %s %s %s"), 
3873
 
                 "session_child_run",
3874
 
                 argv[0],
3875
 
                 ve_sure_string (argv[1]),
3876
 
                 ve_sure_string (argv[2]),
3877
 
                 ve_sure_string (argv[3]),
3878
 
                 ve_sure_string (argv[4]),
3879
 
                 ve_sure_string (argv[5]));
3880
 
#else
3881
 
        fprintf (stderr, _("%s: Could not exec %s %s %s"), 
3882
 
                 "session_child_run",
3883
 
                 argv[0],
3884
 
                 ve_sure_string (argv[1]),
3885
 
                 ve_sure_string (argv[2]));
3886
 
        gdm_error ( _("%s: Could not exec %s %s %s"), 
3887
 
                 "session_child_run",
3888
 
                 argv[0],
3889
 
                 ve_sure_string (argv[1]),
3890
 
                 ve_sure_string (argv[2]));
3891
 
#endif
 
4047
        fprintf (stderr, _("%s: Could not exec %s"),
 
4048
                 "session_child_run", fullexec->str);
 
4049
        gdm_error ( _("%s: Could not exec %s"),
 
4050
                    "session_child_run", fullexec->str);
 
4051
        g_string_free (fullexec, TRUE);
3892
4052
 
3893
4053
        /* if we can't read and exec the session, then make a nice
3894
4054
         * error dialog */
3895
 
        gdm_error_box
 
4055
        gdm_errorgui_error_box
3896
4056
                (d, GTK_MESSAGE_ERROR,
3897
4057
                 /* we can't really be any more specific */
3898
4058
                 _("Cannot start the session due to some "
3899
4059
                   "internal error."));
3900
 
        
 
4060
 
3901
4061
        /* ends as if nothing bad happened */
3902
4062
        _exit (0);
3903
4063
}
3919
4079
        }
3920
4080
}
3921
4081
 
 
4082
static GString *
 
4083
gdm_slave_parse_enriched_string (GdmDisplay *d, const gchar *s)
 
4084
{
 
4085
        GString *str = g_string_new (NULL);
 
4086
        gchar cmd;
 
4087
 
 
4088
        while (s[0] != '\0') {
 
4089
 
 
4090
                if (s[0] == '%' && s[1] != 0) {
 
4091
                        cmd = s[1];
 
4092
                        s++;
 
4093
 
 
4094
                        switch (cmd) {
 
4095
 
 
4096
                        case 'h':
 
4097
                                g_string_append (str, d->hostname);
 
4098
                                break;
 
4099
 
 
4100
                        case 'd':
 
4101
                                g_string_append (str, d->name);
 
4102
                                break;
 
4103
 
 
4104
                        case '%':
 
4105
                                g_string_append_c (str, '%');
 
4106
                                break;
 
4107
 
 
4108
                        default:
 
4109
                                break;
 
4110
                        };
 
4111
                } else {
 
4112
                        g_string_append_c (str, *s);
 
4113
                }
 
4114
                s++;
 
4115
        }
 
4116
        return (str);
 
4117
}
 
4118
 
 
4119
static gchar *
 
4120
gdm_slave_update_pseudo_device (GdmDisplay *d, const char *device_in)
 
4121
{
 
4122
        GString *str;
 
4123
        struct stat st;
 
4124
        gchar *device;
 
4125
 
 
4126
        /* If not a valid device, then do not update */
 
4127
        if (device_in == NULL || strncmp (device_in, "/dev/", 5) != 0) {
 
4128
                gdm_debug ("Warning, invalid device %s", device_in);
 
4129
                return NULL;
 
4130
        }
 
4131
 
 
4132
        /* Parse the string, changing %d to display or %h to hostname, etc. */
 
4133
        str = gdm_slave_parse_enriched_string (d, device_in);
 
4134
        device = g_strdup (str->str);
 
4135
        g_string_free (str, TRUE);
 
4136
 
 
4137
        /* If using pseudo-devices, setup symlink if it does not exist */
 
4138
        if (device != NULL &&
 
4139
            gdm_daemon_config_get_value_bool (GDM_KEY_UTMP_PSEUDO_DEVICE)) {
 
4140
                gchar buf[MAXPATHLEN + 1];
 
4141
 
 
4142
                memset (buf, 0, sizeof (gchar) * (MAXPATHLEN + 1));
 
4143
 
 
4144
                if (stat (device, &st) != 0) {
 
4145
                        gdm_debug ("Creating pseudo-device %s", device);
 
4146
                        symlink ("/dev/null", device);
 
4147
                } else if (readlink (device, buf, MAXPATHLEN) > 0) {
 
4148
                        if (strcmp (buf, "/dev/null") == 0) {
 
4149
                                /* Touch symlink */
 
4150
                                struct utimbuf  timebuf;
 
4151
 
 
4152
                                timebuf.modtime = time ((time_t *) 0);
 
4153
                                timebuf.actime  = timebuf.modtime;
 
4154
 
 
4155
                                if ((utime (device, &timebuf)) != 0)
 
4156
                                        gdm_debug ("Problem updating access time of pseudo-device %s", device);
 
4157
                                else
 
4158
                                        gdm_debug ("Touching pseudo-device %s",
 
4159
                                                device);
 
4160
                        } else {
 
4161
                                gdm_debug ("Device %s points to %s", device, buf);
 
4162
                        }
 
4163
                } else {
 
4164
                        gdm_debug ("Device %s is not a symlink", device);
 
4165
                }
 
4166
        }
 
4167
        return (device);
 
4168
}
 
4169
 
 
4170
gchar *
 
4171
gdm_slave_get_display_device (GdmDisplay *d)
 
4172
{
 
4173
        gchar *device_name = NULL;
 
4174
 
 
4175
        if (d->attached) {
 
4176
                if (d->vtnum != -1)
 
4177
                        device_name = gdm_get_vt_device (d->vtnum);
 
4178
 
 
4179
                /*
 
4180
                 * Default to the value in the GDM configuration for the
 
4181
                 * display number.  Allow pseudo devices.
 
4182
                 */
 
4183
                if (device_name == NULL && d->device_name != NULL) {
 
4184
                        device_name = gdm_slave_update_pseudo_device (d,
 
4185
                                d->device_name);
 
4186
                }
 
4187
 
 
4188
                /* If not VT, then use default local value from configuration */
 
4189
                if (device_name == NULL) {
 
4190
                        const char *dev_local =
 
4191
                                gdm_daemon_config_get_value_string (GDM_KEY_UTMP_LINE_ATTACHED);
 
4192
 
 
4193
                        if (dev_local != NULL) {
 
4194
                                device_name = gdm_slave_update_pseudo_device (d,
 
4195
                                        dev_local);
 
4196
                        }
 
4197
                }
 
4198
        } else {
 
4199
                /*
 
4200
                 * If a remote display, then use default remote value from
 
4201
                 * configuration
 
4202
                 */
 
4203
                const char *dev_remote =
 
4204
                        gdm_daemon_config_get_value_string (GDM_KEY_UTMP_LINE_REMOTE);
 
4205
                if (dev_remote != NULL) {
 
4206
                        device_name = gdm_slave_update_pseudo_device (d,
 
4207
                                dev_remote);
 
4208
                }
 
4209
        }
 
4210
 
 
4211
        gdm_debug ("Display device is %s for display %s", device_name, d->name);
 
4212
        return (device_name);
 
4213
}
 
4214
        
 
4215
void
 
4216
gdm_slave_write_utmp_wtmp_record (GdmDisplay *d,
 
4217
                        GdmSessionRecordType record_type,
 
4218
                        const gchar *username,
 
4219
                        GPid  pid)
 
4220
{
 
4221
#if defined(HAVE_UTMPX_H)
 
4222
        struct utmpx record = { 0 };
 
4223
        struct utmpx *u = NULL;
 
4224
#else
 
4225
        struct utmp record = { 0 };
 
4226
#endif
 
4227
        GTimeVal now = { 0 };
 
4228
        gchar *device_name = NULL;
 
4229
        gchar *host;
 
4230
 
 
4231
        device_name = gdm_slave_get_display_device (d);
 
4232
 
 
4233
        gdm_debug ("Writing %s utmp-wtmp record",
 
4234
               record_type == GDM_SESSION_RECORD_TYPE_LOGIN ? "session" :
 
4235
               record_type == GDM_SESSION_RECORD_TYPE_LOGOUT ?  "logout" :
 
4236
               "failed session attempt");
 
4237
 
 
4238
        if (record_type != GDM_SESSION_RECORD_TYPE_LOGOUT) {
 
4239
                /*
 
4240
                 * It is possible that PAM failed before
 
4241
                 * it mapped the user input into a valid username
 
4242
                 * so we fallback to try using "(unknown)".  We
 
4243
                 * don't ever log user input directly, because
 
4244
                 * we don't want passwords entered into the 
 
4245
                 * username entry to accidently get logged.
 
4246
                 */
 
4247
                if (username != NULL) {
 
4248
#if defined(HAVE_UT_UT_USER)
 
4249
                        strncpy (record.ut_user,
 
4250
                                 username, 
 
4251
                                 sizeof (record.ut_user));
 
4252
#elif defined(HAVE_UT_UT_NAME)
 
4253
                        strncpy (record.ut_name,
 
4254
                                 username,
 
4255
                                 sizeof (record.ut_name));
 
4256
#endif
 
4257
                } else {
 
4258
                        g_assert (record_type == GDM_SESSION_RECORD_TYPE_FAILED_ATTEMPT);
 
4259
#if defined(HAVE_UT_UT_USER)
 
4260
                        strncpy (record.ut_user,
 
4261
                                 "(unknown)",
 
4262
                                 sizeof (record.ut_user));
 
4263
#elif defined(HAVE_UT_UT_NAME)
 
4264
                        strncpy (record.ut_name,
 
4265
                                 "(unknown)",
 
4266
                                 sizeof (record.ut_name));
 
4267
#endif
 
4268
                }
 
4269
 
 
4270
#if defined(HAVE_UT_UT_USER)
 
4271
                gdm_debug ("utmp-wtmp: Using username %*s",
 
4272
                           (int) sizeof (record.ut_user),
 
4273
                           record.ut_user);
 
4274
#elif defined(HAVE_UT_UT_NAME)
 
4275
                gdm_debug ("utmp-wtmp: Using username %*s",
 
4276
                           (int) sizeof (record.ut_name),
 
4277
                           record.ut_name);
 
4278
#endif
 
4279
        }
 
4280
 
 
4281
#if defined(HAVE_UT_UT_TYPE)
 
4282
        if (record_type == GDM_SESSION_RECORD_TYPE_LOGOUT) {
 
4283
                record.ut_type = DEAD_PROCESS;
 
4284
                gdm_debug ("utmp-wtmp: Using type DEAD_PROCESS"); 
 
4285
        } else  {
 
4286
                record.ut_type = USER_PROCESS;
 
4287
                gdm_debug ("utmp-wtmp: Using type USER_PROCESS"); 
 
4288
        }
 
4289
#endif
 
4290
 
 
4291
#if defined(HAVE_UT_UT_PID)
 
4292
        record.ut_pid = pid;
 
4293
        gdm_debug ("utmp-wtmp: Using pid %d", (gint)record.ut_pid);
 
4294
#endif
 
4295
 
 
4296
#if defined(HAVE_UT_UT_TV)
 
4297
        g_get_current_time (&now);
 
4298
        record.ut_tv.tv_sec = now.tv_sec;
 
4299
        gdm_debug ("utmp-wtmp: Using time %ld", (glong) record.ut_tv.tv_sec);
 
4300
#elif defined(HAVE_UT_UT_TIME)
 
4301
        time (&record.ut_time);
 
4302
#endif
 
4303
 
 
4304
#if defined(HAVE_UT_UT_ID)
 
4305
        strncpy (record.ut_id, d->name, sizeof (record.ut_id));
 
4306
        gdm_debug ("utmp-wtmp: Using id %*s",
 
4307
               (int) sizeof (record.ut_id),
 
4308
               record.ut_id);
 
4309
#endif
 
4310
 
 
4311
        if (device_name != NULL) {
 
4312
                g_assert (g_str_has_prefix (device_name, "/dev/"));
 
4313
                strncpy (record.ut_line, device_name + strlen ("/dev/"),
 
4314
                         sizeof (record.ut_line));
 
4315
                g_free (device_name);
 
4316
                device_name = NULL;
 
4317
        }
 
4318
 
 
4319
        gdm_debug ("utmp-wtmp: Using line %*s",
 
4320
               (int) sizeof (record.ut_line),
 
4321
               record.ut_line);
 
4322
 
 
4323
#if defined(HAVE_UT_UT_HOST)
 
4324
        host = NULL;
 
4325
        if (! d->attached && g_str_has_prefix (d->name, ":")) {
 
4326
                host = g_strdup_printf ("%s%s",
 
4327
                                        d->hostname,
 
4328
                                        d->name);
 
4329
        } else {
 
4330
                host = g_strdup (d->name);
 
4331
        }
 
4332
 
 
4333
        if (host) {
 
4334
                strncpy (record.ut_host, host, sizeof (record.ut_host));
 
4335
                g_free (host);
 
4336
 
 
4337
                gdm_debug ("utmp-wtmp: Using hostname %*s",
 
4338
                   (int) sizeof (record.ut_host),
 
4339
                   record.ut_host);
 
4340
 
 
4341
#ifdef HAVE_UT_SYSLEN
 
4342
                record.ut_syslen = MIN (strlen (host), sizeof (record.ut_host));
 
4343
#endif
 
4344
        } 
 
4345
#endif
 
4346
 
 
4347
        switch (record_type)
 
4348
        {
 
4349
        case GDM_SESSION_RECORD_TYPE_LOGIN:
 
4350
                gdm_debug ("Login utmp/wtmp record");
 
4351
#if defined(HAVE_UPDWTMPX)
 
4352
                updwtmpx (GDM_NEW_RECORDS_FILE, &record);
 
4353
#elif defined(HAVE_LOGWTMP) && defined(HAVE_UT_UT_HOST) && !defined(HAVE_LOGIN)
 
4354
#if defined(HAVE_UT_UT_USER)
 
4355
                logwtmp (record.ut_line, record.ut_user, record.ut_host);
 
4356
#elif defined(HAVE_UT_UT_NAME)
 
4357
                logwtmp (record.ut_line, record.ut_name, record.ut_host);
 
4358
#endif
 
4359
#endif
 
4360
 
 
4361
#if defined(HAVE_GETUTXENT)
 
4362
                /* Update if entry already exists */
 
4363
                while ((u = getutxent ()) != NULL) {
 
4364
                        if (u->ut_type == USER_PROCESS &&
 
4365
                           (record.ut_line != NULL &&
 
4366
                           (strncmp (u->ut_line, record.ut_line,
 
4367
                                     sizeof (u->ut_line)) == 0 ||
 
4368
                            u->ut_pid == record.ut_pid))) {
 
4369
 
 
4370
                                gdm_debug ("Updating existing utmp record");
 
4371
                                pututxline (&record);
 
4372
                                break;
 
4373
                        }
 
4374
                }
 
4375
                endutxent ();
 
4376
 
 
4377
                /* Add new entry if update did not work */
 
4378
                if (u == (struct utmpx *)NULL) {
 
4379
                        gdm_debug ("Adding new utmp record");
 
4380
                        pututxline (&record);
 
4381
                }
 
4382
#elif defined(HAVE_LOGIN)
 
4383
                login (&record);
 
4384
#endif
 
4385
 
 
4386
                break;
 
4387
 
 
4388
        case GDM_SESSION_RECORD_TYPE_LOGOUT: 
 
4389
                gdm_debug ("Logout utmp/wtmp record");
 
4390
 
 
4391
#if defined(HAVE_UPDWTMPX)
 
4392
                updwtmpx (GDM_NEW_RECORDS_FILE, &record);
 
4393
#elif defined(HAVE_LOGWTMP)
 
4394
                logwtmp (record.ut_line, "", "");
 
4395
#endif
 
4396
 
 
4397
#if defined(HAVE_GETUTXENT)
 
4398
                setutxent ();
 
4399
 
 
4400
                while ((u = getutxent ()) != NULL &&
 
4401
                       (u = getutxid (&record)) != NULL) {
 
4402
 
 
4403
                        gdm_debug ("Removing utmp record");
 
4404
                        if (u->ut_pid == pid &&
 
4405
                            u->ut_type == DEAD_PROCESS) {
 
4406
                                /* Already done */
 
4407
                                break;
 
4408
                        }
 
4409
 
 
4410
                        u->ut_type = DEAD_PROCESS;
 
4411
                        u->ut_tv.tv_sec = record.ut_tv.tv_sec;
 
4412
                        u->ut_exit.e_termination = 0;
 
4413
                        u->ut_exit.e_exit = 0;
 
4414
 
 
4415
                        pututxline (u);
 
4416
 
 
4417
                        break;
 
4418
                }
 
4419
 
 
4420
                endutxent ();
 
4421
#elif defined(HAVE_LOGOUT)
 
4422
                logout (record.ut_line);
 
4423
#endif
 
4424
                break;
 
4425
 
 
4426
        case GDM_SESSION_RECORD_TYPE_FAILED_ATTEMPT:
 
4427
#if defined(HAVE_UPDWTMPX)
 
4428
                gdm_debug ("Writing failed session attempt record to " 
 
4429
                           GDM_BAD_RECORDS_FILE);
 
4430
                updwtmpx (GDM_BAD_RECORDS_FILE, &record);
 
4431
#endif
 
4432
                break;
 
4433
        }
 
4434
}
 
4435
 
3922
4436
static void
3923
4437
gdm_slave_session_start (void)
3924
4438
{
3925
 
    struct passwd *pwent;
3926
 
    const char *home_dir = NULL;
3927
 
    char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang;
3928
 
    char *gnome_session = NULL;
3929
 
    char *tmp;
3930
 
    gboolean savesess = FALSE, savelang = FALSE;
3931
 
    gboolean usrcfgok = FALSE, authok = FALSE;
3932
 
    gboolean home_dir_ok = FALSE;
3933
 
    gboolean failsafe = FALSE;
3934
 
    time_t session_start_time, end_time; 
3935
 
    pid_t pid;
3936
 
    GdmWaitPid *wp;
3937
 
    uid_t uid;
3938
 
    gid_t gid;
3939
 
    int logpipe[2];
3940
 
    int logfilefd;
3941
 
 
3942
 
    gdm_debug ("gdm_slave_session_start: Attempting session for user '%s'",
3943
 
               login);
3944
 
 
3945
 
    pwent = getpwnam (login);
3946
 
 
3947
 
    if G_UNLIKELY (pwent == NULL)  {
3948
 
            /* This is sort of an "assert", this should NEVER happen */
3949
 
            if (greet)
3950
 
                    gdm_slave_whack_greeter ();
3951
 
            gdm_slave_exit (DISPLAY_REMANAGE,
3952
 
                            _("%s: User passed auth but getpwnam (%s) failed!"), "gdm_slave_session_start", login);
3953
 
    }
3954
 
 
3955
 
    logged_in_uid = uid = pwent->pw_uid;
3956
 
    logged_in_gid = gid = pwent->pw_gid;
3957
 
 
3958
 
    /* Run the PostLogin script */
3959
 
    if G_UNLIKELY (gdm_slave_exec_script (d, gdm_get_value_string (GDM_KEY_POSTLOGIN),
3960
 
                                          login, pwent,
3961
 
                                          TRUE /* pass_stdout */) != EXIT_SUCCESS &&
3962
 
                   /* ignore errors in failsafe modes */
3963
 
                   ! failsafe) {
3964
 
            gdm_verify_cleanup (d);
3965
 
            gdm_error (_("%s: Execution of PostLogin script returned > 0. Aborting."), "gdm_slave_session_start");
3966
 
            /* script failed so just try again */
3967
 
            return;
3968
 
                
3969
 
 
3970
 
    }
3971
 
 
3972
 
    /*
3973
 
     * Set euid, gid to user before testing for user's $HOME since root
3974
 
     * does not always have access to the user's $HOME directory.
3975
 
     */
3976
 
    if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
3977
 
                   seteuid (pwent->pw_uid) != 0) {
3978
 
            gdm_error ("Cannot set effective user/group id");
3979
 
            gdm_verify_cleanup (d);
3980
 
            session_started = FALSE;
3981
 
            return;
3982
 
    }
3983
 
 
3984
 
    if G_UNLIKELY (pwent->pw_dir == NULL ||
3985
 
                   ! g_file_test (pwent->pw_dir, G_FILE_TEST_IS_DIR)) {
3986
 
            char *msg = g_strdup_printf (
3987
 
                     _("Your home directory is listed as:\n'%s'\n"
3988
 
                       "but it does not appear to exist.  "
3989
 
                       "Do you want to log in with the / (root) "
3990
 
                       "directory as your home directory?\n\n"
3991
 
                       "It is unlikely anything will work unless "
3992
 
                       "you use a failsafe session."),
3993
 
                     ve_sure_string (pwent->pw_dir));
3994
 
 
3995
 
            /* Set euid, egid to root:gdm to manage user interaction */
3996
 
            seteuid (0);
3997
 
            setegid (gdm_get_gdmgid ());
3998
 
 
3999
 
            gdm_error (_("%s: Home directory for %s: '%s' does not exist!"),
4000
 
                       "gdm_slave_session_start",
4001
 
                       login,
4002
 
                       ve_sure_string (pwent->pw_dir));
4003
 
 
4004
 
            /* Check what the user wants to do */
4005
 
            if ( ! gdm_failsafe_yesno (d, msg)) {
4006
 
                    g_free (msg);
4007
 
                    gdm_verify_cleanup (d);
4008
 
                    session_started = FALSE;
4009
 
                    return;
4010
 
            }
4011
 
 
4012
 
            g_free (msg);
4013
 
 
4014
 
            /* Reset euid, egid back to user */
4015
 
            if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
4016
 
                           seteuid (pwent->pw_uid) != 0) {
4017
 
                    gdm_error ("Cannot set effective user/group id");
4018
 
                    gdm_verify_cleanup (d);
4019
 
                    session_started = FALSE;
4020
 
                    return;
4021
 
            }
4022
 
 
4023
 
            home_dir_ok = FALSE;
4024
 
            home_dir = "/";
4025
 
    } else {
4026
 
            home_dir_ok = TRUE;
4027
 
            home_dir = pwent->pw_dir;
4028
 
    }
4029
 
 
4030
 
    if G_LIKELY (home_dir_ok) {
4031
 
            /* Sanity check on ~user/.dmrc */
4032
 
            usrcfgok = gdm_file_check ("gdm_slave_session_start", pwent->pw_uid,
4033
 
                                       home_dir, ".dmrc", TRUE, FALSE,
4034
 
                                       gdm_get_value_int (GDM_KEY_USER_MAX_FILE),
4035
 
                                       gdm_get_value_int (GDM_KEY_RELAX_PERM));
4036
 
    } else {
4037
 
            usrcfgok = FALSE;
4038
 
    }
4039
 
 
4040
 
    if G_LIKELY (usrcfgok) {
4041
 
            gdm_get_user_session_lang (&usrsess, &usrlang, home_dir, &savesess);
4042
 
    } else {
4043
 
        /* This won't get displayed if the .dmrc file simply doesn't
4044
 
         * exist since we pass absentok=TRUE when we call gdm_file_check
4045
 
         */
4046
 
        gdm_error_box (d,
4047
 
                GTK_MESSAGE_WARNING,
4048
 
                _("User's $HOME/.dmrc file is being ignored.  "
4049
 
                  "This prevents the default session "
4050
 
                  "and language from being saved.  File "
4051
 
                  "should be owned by user and have 644 "
4052
 
                  "permissions.  User's $HOME directory "
4053
 
                  "must be owned by user and not writable "
4054
 
                  "by other users."));
4055
 
        usrsess = g_strdup ("");
4056
 
        usrlang = g_strdup ("");
4057
 
    }
4058
 
 
4059
 
    NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
4060
 
 
4061
 
    if (greet) {
4062
 
            tmp = gdm_ensure_extension (usrsess, ".desktop");
4063
 
            session = gdm_slave_greeter_ctl (GDM_SESS, tmp);
4064
 
            g_free (tmp);
4065
 
 
4066
 
            if (session != NULL &&
4067
 
                strcmp (session, GDM_RESPONSE_CANCEL) == 0) {
4068
 
                    gdm_debug ("User canceled login");
4069
 
                    gdm_verify_cleanup (d);
4070
 
                    session_started = FALSE;
4071
 
                    g_free (usrlang);
4072
 
                    return;
4073
 
            }
4074
 
 
4075
 
            language = gdm_slave_greeter_ctl (GDM_LANG, usrlang);
4076
 
            if (language != NULL && 
4077
 
                strcmp (language, GDM_RESPONSE_CANCEL) == 0) {
4078
 
                    gdm_debug ("User canceled login");
4079
 
                    gdm_verify_cleanup (d);
4080
 
                    session_started = FALSE;
4081
 
                    g_free (usrlang);
4082
 
                    return;
4083
 
            }
4084
 
    } else {
4085
 
            session = g_strdup (usrsess);
4086
 
            language = g_strdup (usrlang);
4087
 
    }
4088
 
 
4089
 
    tmp = gdm_strip_extension (session, ".desktop");
4090
 
    g_free (session);
4091
 
    session = tmp;
4092
 
 
4093
 
    if (ve_string_empty (session)) {
4094
 
            g_free (session);
4095
 
            session = find_a_session ();
4096
 
            if (session == NULL) {
4097
 
                    /* we're running out of options */
4098
 
                    session = g_strdup (GDM_SESSION_FAILSAFE_GNOME);
4099
 
            }
4100
 
    }
4101
 
 
4102
 
    if G_LIKELY (ve_string_empty (language)) {
4103
 
            g_free (language);
4104
 
            language = NULL;
4105
 
    }
4106
 
 
4107
 
    g_free (usrsess);
4108
 
    g_free (usrlang);
4109
 
 
4110
 
    gdm_debug ("Initial setting: session: '%s' language: '%s'\n",
4111
 
               session, ve_sure_string (language));
4112
 
 
4113
 
    /* save this session as the users session */
4114
 
    save_session = g_strdup (session);
4115
 
 
4116
 
    if (greet) {
4117
 
            char *ret = gdm_slave_greeter_ctl (GDM_SSESS, "");
4118
 
            if ( ! ve_string_empty (ret))
4119
 
                    savesess = TRUE;
4120
 
            g_free (ret);
4121
 
 
4122
 
            ret = gdm_slave_greeter_ctl (GDM_SLANG, "");
4123
 
            if ( ! ve_string_empty (ret))
4124
 
                    savelang = TRUE;
4125
 
            g_free (ret);
4126
 
 
4127
 
            gdm_debug ("gdm_slave_session_start: Authentication completed. Whacking greeter");
4128
 
 
4129
 
            gdm_slave_whack_greeter ();
4130
 
    }
4131
 
 
4132
 
    if (gdm_get_value_bool (GDM_KEY_KILL_INIT_CLIENTS))
4133
 
            gdm_server_whack_clients (d->dsp);
4134
 
 
4135
 
    /* Now that we will set up the user authorization we will
4136
 
       need to run session_stop to whack it */
4137
 
    session_started = TRUE;
4138
 
 
4139
 
    /* Setup cookie -- We need this information during cleanup, thus
4140
 
     * cookie handling is done before fork()ing */
4141
 
 
4142
 
    if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
4143
 
                   seteuid (pwent->pw_uid) != 0) {
4144
 
            gdm_error ("Cannot set effective user/group id");
4145
 
            gdm_slave_quick_exit (DISPLAY_REMANAGE);
4146
 
    }
4147
 
 
4148
 
    authok = gdm_auth_user_add (d, pwent->pw_uid,
4149
 
                                /* Only pass the home_dir if
4150
 
                                 * it was ok */
4151
 
                                home_dir_ok ? home_dir : NULL);
4152
 
 
4153
 
    /* FIXME: this should be smarter and only do this on out-of-diskspace
4154
 
     * errors */
4155
 
    if G_UNLIKELY ( ! authok && home_dir_ok) {
4156
 
            /* try wiping the .xsession-errors file (and perhaps other things)
4157
 
               in an attempt to gain disk space */
4158
 
            if (wipe_xsession_errors (pwent, home_dir, home_dir_ok)) {
4159
 
                    gdm_error ("Tried wiping some old user session errors files "
4160
 
                               "to make disk space and will try adding user auth "
4161
 
                               "files again");
4162
 
                    /* Try again */
4163
 
                    authok = gdm_auth_user_add (d, pwent->pw_uid,
4164
 
                                                /* Only pass the home_dir if
4165
 
                                                 * it was ok */
4166
 
                                                home_dir_ok ? home_dir : NULL);
4167
 
            }
4168
 
    }
4169
 
 
4170
 
    NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
4171
 
    
4172
 
    if G_UNLIKELY ( ! authok) {
4173
 
            gdm_debug ("gdm_slave_session_start: Auth not OK");
4174
 
 
4175
 
            gdm_error_box (d,
4176
 
                           GTK_MESSAGE_ERROR,
4177
 
                           _("GDM could not write to your authorization "
4178
 
                             "file.  This could mean that you are out of "
4179
 
                             "disk space or that your home directory could "
4180
 
                             "not be opened for writing.  In any case, it "
4181
 
                             "is not possible to log in.  Please contact "
4182
 
                             "your system administrator"));
4183
 
 
4184
 
            gdm_slave_session_stop (FALSE /* run_post_session */,
4185
 
                                    FALSE /* no_shutdown_check */);
4186
 
 
4187
 
            gdm_slave_quick_exit (DISPLAY_REMANAGE);
4188
 
    }
4189
 
 
4190
 
    if G_UNLIKELY (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0 ||
4191
 
                   strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0 ||
4192
 
                   g_ascii_strcasecmp (session, "failsafe") == 0 /* hack */)
4193
 
            failsafe = TRUE;
4194
 
 
4195
 
    if G_LIKELY ( ! failsafe) {
4196
 
            char *exec = gdm_get_session_exec (session, FALSE /* check_try_exec */);
4197
 
            if ( ! ve_string_empty (exec) &&
4198
 
                strcmp (exec, "failsafe") == 0)
4199
 
                    failsafe = TRUE;
4200
 
            g_free (exec);
4201
 
    }
4202
 
 
4203
 
    /* Write out the Xservers file */
4204
 
    gdm_slave_send_num (GDM_SOP_WRITE_X_SERVERS, 0 /* bogus */);
4205
 
 
4206
 
    if G_LIKELY (d->dsp != NULL) {
4207
 
            Cursor xcursor;
4208
 
 
4209
 
            XSetInputFocus (d->dsp, PointerRoot,
4210
 
                            RevertToPointerRoot, CurrentTime);
4211
 
 
4212
 
            /* return left pointer */
4213
 
            xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR);
4214
 
            XDefineCursor (d->dsp,
4215
 
                           DefaultRootWindow (d->dsp),
4216
 
                           xcursor);
4217
 
            XFreeCursor (d->dsp, xcursor);
4218
 
            XSync (d->dsp, False);
4219
 
    }
4220
 
 
4221
 
    /* Init the ~/.xsession-errors stuff */
4222
 
    d->xsession_errors_bytes = 0;
4223
 
    d->xsession_errors_fd = -1;
4224
 
    d->session_output_fd = -1;
4225
 
 
4226
 
    logfilefd = open_xsession_errors (pwent,
4227
 
                                      failsafe,
4228
 
                                      home_dir,
4229
 
                                      home_dir_ok);
4230
 
    if G_UNLIKELY (logfilefd < 0 ||
4231
 
                   pipe (logpipe) != 0) {
4232
 
            if (logfilefd >= 0)
4233
 
                    VE_IGNORE_EINTR (close (logfilefd));
4234
 
            logfilefd = -1;
4235
 
    }
4236
 
 
4237
 
    /* don't completely rely on this, the user
4238
 
     * could reset time or do other crazy things */
4239
 
    session_start_time = time (NULL);
4240
 
 
4241
 
    /* Start user process */
4242
 
    gdm_sigchld_block_push ();
4243
 
    gdm_sigterm_block_push ();
4244
 
    pid = d->sesspid = fork ();
4245
 
    if (pid == 0)
4246
 
            gdm_unset_signals ();
4247
 
    gdm_sigterm_block_pop ();
4248
 
    gdm_sigchld_block_pop ();
4249
 
 
4250
 
    switch (pid) {
4251
 
        
4252
 
    case -1:
4253
 
        gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Error forking user session"), "gdm_slave_session_start");
4254
 
        
4255
 
    case 0:
4256
 
        if G_LIKELY (logfilefd >= 0) {
4257
 
                VE_IGNORE_EINTR (close (logpipe[0]));
4258
 
        }
4259
 
        /* Never returns */
4260
 
        session_child_run (pwent,
4261
 
                           logpipe[1],
4262
 
                           failsafe,
4263
 
                           home_dir,
4264
 
                           home_dir_ok,
4265
 
                           session,
4266
 
                           save_session,
4267
 
                           language,
4268
 
                           gnome_session,
4269
 
                           usrcfgok,
4270
 
                           savesess,
4271
 
                           savelang);
4272
 
        gdm_assert_not_reached ();
4273
 
        
4274
 
    default:
4275
 
        break;
4276
 
    }
4277
 
    
4278
 
    /* this clears internal cache */
4279
 
    gdm_get_session_exec (NULL, FALSE);
4280
 
 
4281
 
    if G_LIKELY (logfilefd >= 0)  {
4282
 
            d->xsession_errors_fd = logfilefd;
4283
 
            d->session_output_fd = logpipe[0];
4284
 
            /* make the output read fd non-blocking */
4285
 
            fcntl (d->session_output_fd, F_SETFL, O_NONBLOCK);
4286
 
            VE_IGNORE_EINTR (close (logpipe[1]));
4287
 
    }
4288
 
 
4289
 
    /* We must be root for this, and we are, but just to make sure */
4290
 
    NEVER_FAILS_root_set_euid_egid (0, gdm_get_gdmgid ());
4291
 
    /* Reset all the process limits, pam may have set some up for our process and that
4292
 
       is quite evil.  But pam is generally evil, so this is to be expected. */
4293
 
    gdm_reset_limits ();
4294
 
 
4295
 
    g_free (session);
4296
 
    g_free (save_session);
4297
 
    g_free (language);
4298
 
    g_free (gnome_session);
4299
 
 
4300
 
    gdm_slave_send_num (GDM_SOP_SESSPID, pid);
4301
 
 
4302
 
    gdm_sigchld_block_push ();
4303
 
    wp = slave_waitpid_setpid (d->sesspid);
4304
 
    gdm_sigchld_block_pop ();
4305
 
 
4306
 
    slave_waitpid (wp);
4307
 
 
4308
 
    d->sesspid = 0;
4309
 
 
4310
 
    /* finish reading the session output if any of it is still there */
4311
 
    finish_session_output (TRUE);
4312
 
 
4313
 
    /* Now still as root make the system authfile readable by others,
4314
 
       and therefore by the gdm user */
4315
 
    VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0644));
4316
 
 
4317
 
    end_time = time (NULL);
4318
 
 
4319
 
    gdm_debug ("Session: start_time: %ld end_time: %ld",
4320
 
               (long)session_start_time, (long)end_time);
4321
 
 
4322
 
    /* 66 is a very magical number signifying failure in GDM */
4323
 
    if G_UNLIKELY ((d->last_sess_status != 66) &&
4324
 
                   (/* sanity */ end_time >= session_start_time) &&
4325
 
                   (end_time - 10 <= session_start_time) &&
4326
 
                   /* only if the X server still exist! */
4327
 
                   d->servpid > 1) {
4328
 
            gdm_debug ("Session less than 10 seconds!");
4329
 
 
4330
 
            /* FIXME: perhaps do some checking to display a better error,
4331
 
             * such as gnome-session missing and such things. */
4332
 
            gdm_error_box_full (d,
4333
 
                                GTK_MESSAGE_WARNING,
4334
 
                                _("Your session only lasted less than "
4335
 
                                  "10 seconds.  If you have not logged out "
4336
 
                                  "yourself, this could mean that there is "
4337
 
                                  "some installation problem or that you may "
4338
 
                                  "be out of diskspace.  Try logging in with "
4339
 
                                  "one of the failsafe sessions to see if you "
4340
 
                                  "can fix this problem."),
4341
 
                                (d->xsession_errors_filename != NULL) ?
4342
 
                                  _("View details (~/.xsession-errors file)") :
4343
 
                                  NULL,
4344
 
                                d->xsession_errors_filename,
4345
 
                                uid, gid);
4346
 
    }
4347
 
 
4348
 
    gdm_slave_session_stop (pid != 0 /* run_post_session */,
4349
 
                            FALSE /* no_shutdown_check */);
4350
 
 
4351
 
    gdm_debug ("gdm_slave_session_start: Session ended OK (now all finished)");
 
4439
        struct passwd *pwent;
 
4440
        const char *home_dir = NULL;
 
4441
        char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang;
 
4442
        char *gnome_session = NULL;
 
4443
#ifdef WITH_CONSOLE_KIT
 
4444
        char *ck_session_cookie;
 
4445
#endif
 
4446
        char *tmp;
 
4447
        gboolean savesess = FALSE, savelang = FALSE;
 
4448
        gboolean usrcfgok = FALSE, authok = FALSE;
 
4449
        gboolean home_dir_ok = FALSE;
 
4450
        gboolean failsafe = FALSE;
 
4451
        time_t session_start_time, end_time; 
 
4452
        pid_t pid;
 
4453
        GdmWaitPid *wp;
 
4454
        uid_t uid;
 
4455
        gid_t gid;
 
4456
        int logpipe[2];
 
4457
        int logfilefd;
 
4458
 
 
4459
        gdm_debug ("gdm_slave_session_start: Attempting session for user '%s'",
 
4460
                   login_user);
 
4461
 
 
4462
        pwent = getpwnam (login_user);
 
4463
 
 
4464
        if G_UNLIKELY (pwent == NULL)  {
 
4465
                /* This is sort of an "assert", this should NEVER happen */
 
4466
                if (greet)
 
4467
                        gdm_slave_whack_greeter ();
 
4468
                gdm_slave_exit (DISPLAY_REMANAGE,
 
4469
                                _("%s: User passed auth but getpwnam (%s) failed!"), "gdm_slave_session_start", login_user);
 
4470
        }
 
4471
 
 
4472
        logged_in_uid = uid = pwent->pw_uid;
 
4473
        logged_in_gid = gid = pwent->pw_gid;
 
4474
 
 
4475
        /* Run the PostLogin script */
 
4476
        if G_UNLIKELY (gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTLOGIN),
 
4477
                                              login_user, pwent,
 
4478
                                              TRUE /* pass_stdout */) != EXIT_SUCCESS &&
 
4479
                       /* ignore errors in failsafe modes */
 
4480
                       ! failsafe) {
 
4481
                gdm_verify_cleanup (d);
 
4482
                gdm_error (_("%s: Execution of PostLogin script returned > 0. Aborting."), "gdm_slave_session_start");
 
4483
                /* script failed so just try again */
 
4484
                return;
 
4485
        }
 
4486
 
 
4487
        /*
 
4488
         * Set euid, gid to user before testing for user's $HOME since root
 
4489
         * does not always have access to the user's $HOME directory.
 
4490
         */
 
4491
        if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
 
4492
                       seteuid (pwent->pw_uid) != 0) {
 
4493
                gdm_error ("Cannot set effective user/group id");
 
4494
                gdm_verify_cleanup (d);
 
4495
                session_started = FALSE;
 
4496
                return;
 
4497
        }
 
4498
 
 
4499
        if G_UNLIKELY (pwent->pw_dir == NULL ||
 
4500
                       ! g_file_test (pwent->pw_dir, G_FILE_TEST_IS_DIR)) {
 
4501
                char *yesno_msg;
 
4502
                char *msg = g_strdup_printf (
 
4503
                                             _("Your home directory is listed as: '%s' "
 
4504
                                               "but it does not appear to exist.  "
 
4505
                                               "Do you want to log in with the / (root) "
 
4506
                                               "directory as your home directory? "
 
4507
                                               "It is unlikely anything will work unless "
 
4508
                                               "you use a failsafe session."),
 
4509
                                             ve_sure_string (pwent->pw_dir));
 
4510
 
 
4511
                /* Set euid, egid to root:gdm to manage user interaction */
 
4512
                seteuid (0);
 
4513
                setegid (gdm_daemon_config_get_gdmgid ());
 
4514
 
 
4515
                gdm_error (_("%s: Home directory for %s: '%s' does not exist!"),
 
4516
                           "gdm_slave_session_start",
 
4517
                           login_user,
 
4518
                           ve_sure_string (pwent->pw_dir));
 
4519
 
 
4520
                /* Check what the user wants to do */
 
4521
                yesno_msg = g_strdup_printf ("yesno_msg=%s", msg);
 
4522
                gdm_slave_send_string (GDM_SOP_SHOW_YESNO_DIALOG, yesno_msg);
 
4523
 
 
4524
                g_free (yesno_msg);
 
4525
 
 
4526
                if (strcmp (gdm_ack_response, "no") == 0) {
 
4527
                        gdm_verify_cleanup (d);
 
4528
                        session_started = FALSE;
 
4529
 
 
4530
                        g_free (msg);
 
4531
                        g_free (gdm_ack_response);
 
4532
                        gdm_ack_response = NULL;
 
4533
                        return;
 
4534
                }
 
4535
 
 
4536
                g_free (msg);
 
4537
                g_free (gdm_ack_response);
 
4538
                gdm_ack_response = NULL;
 
4539
 
 
4540
                /* Reset euid, egid back to user */
 
4541
                if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
 
4542
                               seteuid (pwent->pw_uid) != 0) {
 
4543
                        gdm_error ("Cannot set effective user/group id");
 
4544
                        gdm_verify_cleanup (d);
 
4545
                        session_started = FALSE;
 
4546
                        return;
 
4547
                }
 
4548
 
 
4549
                home_dir_ok = FALSE;
 
4550
                home_dir = "/";
 
4551
        } else {
 
4552
                home_dir_ok = TRUE;
 
4553
                home_dir = pwent->pw_dir;
 
4554
        }
 
4555
 
 
4556
        if G_LIKELY (home_dir_ok) {
 
4557
                /* Sanity check on ~user/.dmrc */
 
4558
                usrcfgok = gdm_file_check ("gdm_slave_session_start", pwent->pw_uid,
 
4559
                                           home_dir, ".dmrc", TRUE, FALSE,
 
4560
                                           gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE),
 
4561
                                           gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM));
 
4562
        } else {
 
4563
                usrcfgok = FALSE;
 
4564
        }
 
4565
 
 
4566
        if G_LIKELY (usrcfgok) {
 
4567
                gdm_daemon_config_get_user_session_lang (&usrsess, &usrlang, home_dir, &savesess);
 
4568
        } else {
 
4569
                /* This won't get displayed if the .dmrc file simply doesn't
 
4570
                 * exist since we pass absentok=TRUE when we call gdm_file_check
 
4571
                 */
 
4572
                gdm_errorgui_error_box (d,
 
4573
                               GTK_MESSAGE_WARNING,
 
4574
                               _("User's $HOME/.dmrc file is being ignored.  "
 
4575
                                 "This prevents the default session "
 
4576
                                 "and language from being saved.  File "
 
4577
                                 "should be owned by user and have 644 "
 
4578
                                 "permissions.  User's $HOME directory "
 
4579
                                 "must be owned by user and not writable "
 
4580
                                 "by other users."));
 
4581
                usrsess = g_strdup ("");
 
4582
                usrlang = g_strdup ("");
 
4583
        }
 
4584
 
 
4585
        NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
 
4586
 
 
4587
        if (greet) {
 
4588
                tmp = gdm_ensure_extension (usrsess, ".desktop");
 
4589
                session = gdm_slave_greeter_ctl (GDM_SESS, tmp);
 
4590
                g_free (tmp);
 
4591
 
 
4592
                if (session != NULL &&
 
4593
                    strcmp (session, GDM_RESPONSE_CANCEL) == 0) {
 
4594
                        gdm_debug ("User canceled login");
 
4595
                        gdm_verify_cleanup (d);
 
4596
                        session_started = FALSE;
 
4597
                        g_free (usrlang);
 
4598
                        return;
 
4599
                }
 
4600
 
 
4601
                language = gdm_slave_greeter_ctl (GDM_LANG, usrlang);
 
4602
                if (language != NULL &&
 
4603
                    strcmp (language, GDM_RESPONSE_CANCEL) == 0) {
 
4604
                        gdm_debug ("User canceled login");
 
4605
                        gdm_verify_cleanup (d);
 
4606
                        session_started = FALSE;
 
4607
                        g_free (usrlang);
 
4608
                        return;
 
4609
                }
 
4610
        } else {
 
4611
                session = g_strdup (usrsess);
 
4612
                language = g_strdup (usrlang);
 
4613
        }
 
4614
 
 
4615
        tmp = gdm_strip_extension (session, ".desktop");
 
4616
        g_free (session);
 
4617
        session = tmp;
 
4618
 
 
4619
        if (ve_string_empty (session)) {
 
4620
                g_free (session);
 
4621
                session = find_a_session ();
 
4622
                if (session == NULL) {
 
4623
                        /* we're running out of options */
 
4624
                        session = g_strdup (GDM_SESSION_FAILSAFE_GNOME);
 
4625
                }
 
4626
        }
 
4627
 
 
4628
        if G_LIKELY (ve_string_empty (language)) {
 
4629
                g_free (language);
 
4630
                language = NULL;
 
4631
        }
 
4632
 
 
4633
        g_free (usrsess);
 
4634
 
 
4635
        gdm_debug ("Initial setting: session: '%s' language: '%s'\n",
 
4636
                   session, ve_sure_string (language));
 
4637
 
 
4638
        /* save this session as the users session */
 
4639
        save_session = g_strdup (session);
 
4640
 
 
4641
        if (greet) {
 
4642
                char *ret = gdm_slave_greeter_ctl (GDM_SSESS, "");
 
4643
                if ( ! ve_string_empty (ret))
 
4644
                        savesess = TRUE;
 
4645
                g_free (ret);
 
4646
 
 
4647
                ret = gdm_slave_greeter_ctl (GDM_SLANG, "");
 
4648
                if ( ! ve_string_empty (ret))
 
4649
                        savelang = TRUE;
 
4650
                g_free (ret);
 
4651
 
 
4652
                gdm_debug ("gdm_slave_session_start: Authentication completed. Whacking greeter");
 
4653
 
 
4654
                gdm_slave_whack_greeter ();
 
4655
        }
 
4656
 
 
4657
        if (gdm_daemon_config_get_value_bool (GDM_KEY_KILL_INIT_CLIENTS))
 
4658
                gdm_server_whack_clients (d->dsp);
 
4659
 
 
4660
        /*
 
4661
         * If the desktop file specifies that there are special Xserver
 
4662
         * arguments to use, then restart the Xserver with them.
 
4663
         */
 
4664
        d->xserver_session_args = gdm_daemon_config_get_session_xserver_args (session);
 
4665
        if (d->xserver_session_args) {
 
4666
                gdm_server_stop (d);
 
4667
                gdm_slave_send_num (GDM_SOP_XPID, 0);
 
4668
                gdm_server_start (d, TRUE, FALSE, 20, 5);
 
4669
                gdm_slave_send_num (GDM_SOP_XPID, d->servpid);
 
4670
                g_free (d->xserver_session_args);
 
4671
                d->xserver_session_args = NULL;
 
4672
        }
 
4673
 
 
4674
        /* Now that we will set up the user authorization we will
 
4675
           need to run session_stop to whack it */
 
4676
        session_started = TRUE;
 
4677
 
 
4678
        /* Setup cookie -- We need this information during cleanup, thus
 
4679
         * cookie handling is done before fork()ing */
 
4680
 
 
4681
        if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
 
4682
                       seteuid (pwent->pw_uid) != 0) {
 
4683
                gdm_error ("Cannot set effective user/group id");
 
4684
                gdm_slave_quick_exit (DISPLAY_REMANAGE);
 
4685
        }
 
4686
 
 
4687
        authok = gdm_auth_user_add (d, pwent->pw_uid,
 
4688
                                    /* Only pass the home_dir if
 
4689
                                     * it was ok */
 
4690
                                    home_dir_ok ? home_dir : NULL);
 
4691
 
 
4692
        /* FIXME: this should be smarter and only do this on out-of-diskspace
 
4693
         * errors */
 
4694
        if G_UNLIKELY ( ! authok && home_dir_ok) {
 
4695
                /* try wiping the .xsession-errors file (and perhaps other things)
 
4696
                   in an attempt to gain disk space */
 
4697
                if (wipe_xsession_errors (pwent, home_dir, home_dir_ok)) {
 
4698
                        gdm_error ("Tried wiping some old user session errors files "
 
4699
                                   "to make disk space and will try adding user auth "
 
4700
                                   "files again");
 
4701
                        /* Try again */
 
4702
                        authok = gdm_auth_user_add (d, pwent->pw_uid,
 
4703
                                                    /* Only pass the home_dir if
 
4704
                                                     * it was ok */
 
4705
                                                    home_dir_ok ? home_dir : NULL);
 
4706
                }
 
4707
        }
 
4708
 
 
4709
        NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
 
4710
 
 
4711
        if G_UNLIKELY ( ! authok) {
 
4712
                gdm_debug ("gdm_slave_session_start: Auth not OK");
 
4713
 
 
4714
                gdm_errorgui_error_box (d,
 
4715
                               GTK_MESSAGE_ERROR,
 
4716
                               _("GDM could not write to your authorization "
 
4717
                                 "file.  This could mean that you are out of "
 
4718
                                 "disk space or that your home directory could "
 
4719
                                 "not be opened for writing.  In any case, it "
 
4720
                                 "is not possible to log in.  Please contact "
 
4721
                                 "your system administrator"));
 
4722
 
 
4723
                gdm_slave_session_stop (FALSE /* run_post_session */,
 
4724
                                        FALSE /* no_shutdown_check */);
 
4725
 
 
4726
                gdm_slave_quick_exit (DISPLAY_REMANAGE);
 
4727
        }
 
4728
 
 
4729
        if G_UNLIKELY (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0 ||
 
4730
                       strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0 ||
 
4731
                       g_ascii_strcasecmp (session, "failsafe") == 0 /* hack */)
 
4732
                failsafe = TRUE;
 
4733
 
 
4734
        if G_LIKELY ( ! failsafe) {
 
4735
                char *exec = gdm_daemon_config_get_session_exec (session, FALSE /* check_try_exec */);
 
4736
                if ( ! ve_string_empty (exec) &&
 
4737
                     strcmp (exec, "failsafe") == 0)
 
4738
                        failsafe = TRUE;
 
4739
                g_free (exec);
 
4740
        }
 
4741
 
 
4742
        /* Write out the Xservers file */
 
4743
        gdm_slave_send_num (GDM_SOP_WRITE_X_SERVERS, 0 /* bogus */);
 
4744
 
 
4745
        if G_LIKELY (d->dsp != NULL) {
 
4746
                Cursor xcursor;
 
4747
 
 
4748
                XSetInputFocus (d->dsp, PointerRoot,
 
4749
                                RevertToPointerRoot, CurrentTime);
 
4750
 
 
4751
                /* return left pointer */
 
4752
                xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR);
 
4753
                XDefineCursor (d->dsp,
 
4754
                               DefaultRootWindow (d->dsp),
 
4755
                               xcursor);
 
4756
                XFreeCursor (d->dsp, xcursor);
 
4757
                XSync (d->dsp, False);
 
4758
        }
 
4759
 
 
4760
        /* Init the ~/.xsession-errors stuff */
 
4761
        d->xsession_errors_bytes = 0;
 
4762
        d->xsession_errors_fd = -1;
 
4763
        d->session_output_fd = -1;
 
4764
 
 
4765
        logfilefd = open_xsession_errors (pwent,
 
4766
                                          failsafe,
 
4767
                                          home_dir,
 
4768
                                          home_dir_ok);
 
4769
        if G_UNLIKELY (logfilefd < 0 ||
 
4770
                       pipe (logpipe) != 0) {
 
4771
                if (logfilefd >= 0)
 
4772
                        VE_IGNORE_EINTR (close (logfilefd));
 
4773
                logfilefd = -1;
 
4774
        }
 
4775
 
 
4776
        /* don't completely rely on this, the user
 
4777
         * could reset time or do other crazy things */
 
4778
        session_start_time = time (NULL);
 
4779
 
 
4780
#ifdef WITH_CONSOLE_KIT
 
4781
        ck_session_cookie = open_ck_session (pwent, d, session);
 
4782
#endif
 
4783
 
 
4784
        gdm_debug ("Forking user session");
 
4785
 
 
4786
        /* Start user process */
 
4787
        gdm_sigchld_block_push ();
 
4788
        gdm_sigterm_block_push ();
 
4789
        pid = d->sesspid = fork ();
 
4790
        if (pid == 0)
 
4791
                gdm_unset_signals ();
 
4792
        gdm_sigterm_block_pop ();
 
4793
        gdm_sigchld_block_pop ();
 
4794
 
 
4795
        switch (pid) {
 
4796
 
 
4797
        case -1:
 
4798
                gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Error forking user session"), "gdm_slave_session_start");
 
4799
 
 
4800
        case 0:
 
4801
                {
 
4802
                        const char *lang;
 
4803
                        gboolean    has_language;
 
4804
 
 
4805
                        has_language = (language != NULL) && (language[0] != '\0');
 
4806
 
 
4807
                        if ((gdm_system_locale != NULL) && (!has_language)) {
 
4808
                                lang = gdm_system_locale;
 
4809
                        } else {
 
4810
                                lang = language;
 
4811
                        }
 
4812
 
 
4813
                        if G_LIKELY (logfilefd >= 0) {
 
4814
                                VE_IGNORE_EINTR (close (logpipe[0]));
 
4815
                        }
 
4816
                        /* Never returns */
 
4817
                        session_child_run (pwent,
 
4818
                                           logpipe[1],
 
4819
                                           failsafe,
 
4820
                                           home_dir,
 
4821
                                           home_dir_ok,
 
4822
#ifdef WITH_CONSOLE_KIT
 
4823
                                           ck_session_cookie,
 
4824
#endif
 
4825
                                           session,
 
4826
                                           save_session,
 
4827
                                           lang,
 
4828
                                           gnome_session,
 
4829
                                           usrcfgok,
 
4830
                                           savesess,
 
4831
                                           savelang);
 
4832
                        g_assert_not_reached ();
 
4833
                }
 
4834
 
 
4835
        default:
 
4836
                always_restart_greeter = FALSE;
 
4837
                if (!savelang && language && strcmp (usrlang, language)) {
 
4838
                        if (gdm_system_locale != NULL) {
 
4839
                                g_setenv ("LANG", gdm_system_locale, TRUE);
 
4840
                                setlocale (LC_ALL, "");
 
4841
                                g_unsetenv ("GDM_LANG");
 
4842
                                /* for "GDM_LANG" */
 
4843
                                gdm_clearenv_no_lang ();
 
4844
                                gdm_saveenv ();
 
4845
                        }
 
4846
                        gdm_slave_greeter_ctl_no_ret (GDM_SETLANG, DEFAULT_LANGUAGE);
 
4847
                }
 
4848
                break;
 
4849
        }
 
4850
 
 
4851
        /* this clears internal cache */
 
4852
        gdm_daemon_config_get_session_exec (NULL, FALSE);
 
4853
 
 
4854
        if G_LIKELY (logfilefd >= 0)  {
 
4855
                d->xsession_errors_fd = logfilefd;
 
4856
                d->session_output_fd = logpipe[0];
 
4857
                /* make the output read fd non-blocking */
 
4858
                fcntl (d->session_output_fd, F_SETFL, O_NONBLOCK);
 
4859
                VE_IGNORE_EINTR (close (logpipe[1]));
 
4860
        }
 
4861
 
 
4862
        /* We must be root for this, and we are, but just to make sure */
 
4863
        NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
 
4864
        /* Reset all the process limits, pam may have set some up for our process and that
 
4865
           is quite evil.  But pam is generally evil, so this is to be expected. */
 
4866
        gdm_reset_limits ();
 
4867
 
 
4868
        g_free (session);
 
4869
        g_free (save_session);
 
4870
        g_free (language);
 
4871
        g_free (gnome_session);
 
4872
 
 
4873
        gdm_slave_write_utmp_wtmp_record (d,
 
4874
                                GDM_SESSION_RECORD_TYPE_LOGIN,
 
4875
                                pwent->pw_name,
 
4876
                                pid);
 
4877
 
 
4878
        gdm_slave_send_num (GDM_SOP_SESSPID, pid);
 
4879
 
 
4880
        gdm_sigchld_block_push ();
 
4881
        wp = slave_waitpid_setpid (d->sesspid);
 
4882
        gdm_sigchld_block_pop ();
 
4883
 
 
4884
        slave_waitpid (wp);
 
4885
 
 
4886
        d->sesspid = 0;
 
4887
 
 
4888
        /* finish reading the session output if any of it is still there */
 
4889
        finish_session_output (TRUE);
 
4890
 
 
4891
        /* Now still as root make the system authfile readable by others,
 
4892
           and therefore by the gdm user */
 
4893
        VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0644));
 
4894
 
 
4895
        end_time = time (NULL);
 
4896
 
 
4897
        gdm_debug ("Session: start_time: %ld end_time: %ld",
 
4898
                   (long)session_start_time, (long)end_time);
 
4899
 
 
4900
        /* Sync to get notified in the case the X server died
 
4901
         */
 
4902
        XSync (d->dsp, False);
 
4903
 
 
4904
        /* 66 is a very magical number signifying failure in GDM */
 
4905
        if G_UNLIKELY ((d->last_sess_status != 66) &&
 
4906
                       (/* sanity */ end_time >= session_start_time) &&
 
4907
                       (end_time - 10 <= session_start_time) &&
 
4908
                       /* only if the X server still exist! */
 
4909
                       d->servpid > 1) {
 
4910
                char *msg_string;
 
4911
                char *error_msg =
 
4912
                        _("Your session only lasted less than "
 
4913
                          "10 seconds.  If you have not logged out "
 
4914
                          "yourself, this could mean that there is "
 
4915
                          "some installation problem or that you may "
 
4916
                          "be out of diskspace.  Try logging in with "
 
4917
                          "one of the failsafe sessions to see if you "
 
4918
                          "can fix this problem.");
 
4919
 
 
4920
                /* FIXME: perhaps do some checking to display a better error,
 
4921
                 * such as gnome-session missing and such things. */
 
4922
                gdm_debug ("Session less than 10 seconds!");
 
4923
                msg_string = g_strdup_printf ("type=%d$$error_msg=%s$$details_label=%s$$details_file=%s$$uid=%d$$gid=%d",
 
4924
                                              GTK_MESSAGE_WARNING,error_msg, 
 
4925
                                              (d->xsession_errors_filename != NULL) ?
 
4926
                                              _("View details (~/.xsession-errors file)") :
 
4927
                                              NULL,
 
4928
                                              d->xsession_errors_filename,
 
4929
                                              0, 0);
 
4930
 
 
4931
                gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, msg_string);
 
4932
 
 
4933
                g_free (msg_string);
 
4934
 
 
4935
        }
 
4936
 
 
4937
#ifdef WITH_CONSOLE_KIT
 
4938
        if (ck_session_cookie != NULL) {
 
4939
                close_ck_session (ck_session_cookie);
 
4940
                g_free (ck_session_cookie);
 
4941
        }
 
4942
#endif
 
4943
 
 
4944
        if ((pid != 0) && (d->last_sess_status != -1)) {
 
4945
                gdm_debug ("session '%d' exited with status '%d', recording logout",
 
4946
                pid, d->last_sess_status);
 
4947
                gdm_slave_write_utmp_wtmp_record (d,
 
4948
                                        GDM_SESSION_RECORD_TYPE_LOGOUT,
 
4949
                                        pwent->pw_name,
 
4950
                                        pid);
 
4951
        }
 
4952
 
 
4953
        gdm_slave_session_stop (pid != 0 /* run_post_session */,
 
4954
                                FALSE /* no_shutdown_check */);
 
4955
 
 
4956
        gdm_debug ("gdm_slave_session_start: Session ended OK (now all finished)");
4352
4957
}
4353
4958
 
4354
4959
 
4357
4962
gdm_slave_session_stop (gboolean run_post_session,
4358
4963
                        gboolean no_shutdown_check)
4359
4964
{
4360
 
    struct passwd *pwent;
4361
 
    char *x_servers_file;
4362
 
    char *local_login;
4363
 
 
4364
 
    in_session_stop++;
4365
 
 
4366
 
    session_started = FALSE;
4367
 
 
4368
 
    local_login = login;
4369
 
    login = NULL;
4370
 
 
4371
 
    /* don't use NEVER_FAILS_ here this can be called from places
4372
 
       kind of exiting and it's ok if this doesn't work (when shouldn't
4373
 
       it work anyway? */
4374
 
    seteuid (0);
4375
 
    setegid (0);
4376
 
 
4377
 
    gdm_slave_send_num (GDM_SOP_SESSPID, 0);
4378
 
 
4379
 
    /* Now still as root make the system authfile not readable by others,
4380
 
       and therefore not by the gdm user */
4381
 
    if (GDM_AUTHFILE (d) != NULL) {
4382
 
            VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640));
4383
 
    }
4384
 
 
4385
 
    gdm_debug ("gdm_slave_session_stop: %s on %s", local_login, d->name);
4386
 
 
4387
 
    /* Note we use the info in the structure here since if we get passed
4388
 
     * a 0 that means the process is already dead.
4389
 
     * FIXME: Maybe we should waitpid here, note make sure this will
4390
 
     * not create a hang! */
4391
 
    gdm_sigchld_block_push ();
4392
 
    if (d->sesspid > 1)
4393
 
            kill (- (d->sesspid), SIGTERM);
4394
 
    gdm_sigchld_block_pop ();
4395
 
 
4396
 
    /* HACK:
4397
 
       This is to fix #126071, that is kill processes that may still hold open
4398
 
       fd's in the home directory to allow a clean unmount.  However note of course
4399
 
       that this is a race. */
4400
 
    /* FIX HACK: We will get an xioerror out of whack clients if the user crashed
4401
 
       X with ctl-alt-backspace.  So, we need to ignore xioerror while we do this.
4402
 
       Otherwise, we end up in a longjmp to quick_exit which will prevent things
4403
 
       like PostSession scripts from processing */
4404
 
    switch (Setjmp (ignore_xioerror_jmp)) {
4405
 
    case 0:
4406
 
       /* Having just set the jump point, activate the error handler that returns
4407
 
          us to the next case */
4408
 
       XSetIOErrorHandler (gdm_slave_ignore_xioerror_handler);
4409
 
       break;
4410
 
    default:
4411
 
       /* Here means we saw an xioerror and ignored it. */
4412
 
       /* xioerror will cause this to drop back into whack_clients, but I think
4413
 
          that is okay because I haven't seen it do so more than once */
4414
 
       gdm_debug ("gdm_slave_session_stop: back here from xioerror");
4415
 
       break;
4416
 
    }
4417
 
 
4418
 
    gdm_server_whack_clients (d->dsp);
4419
 
 
4420
 
    /* Now we should care about xioerror once again??? */
4421
 
    XSetIOErrorHandler (gdm_slave_xioerror_handler);
4422
 
 
4423
 
#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
4424
 
    /* let the other processes die perhaps or whatnot */
4425
 
    sched_yield ();
4426
 
#endif
4427
 
 
4428
 
    finish_session_output (run_post_session /* do_read */);
4429
 
    
4430
 
    if (local_login == NULL)
4431
 
            pwent = NULL;
4432
 
    else
4433
 
            pwent = getpwnam (local_login);     /* PAM overwrites our pwent */
4434
 
 
4435
 
    x_servers_file = gdm_make_filename (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR),
4436
 
                                        d->name, ".Xservers");
4437
 
 
4438
 
    /* if there was a session that ran, run the PostSession script */
4439
 
    if (run_post_session) {
4440
 
            /* Execute post session script */
4441
 
            gdm_debug ("gdm_slave_session_stop: Running post session script");
4442
 
            gdm_slave_exec_script (d, gdm_get_value_string (GDM_KEY_POSTSESSION), local_login, pwent,
4443
 
                                   FALSE /* pass_stdout */);
4444
 
    }
4445
 
 
4446
 
    VE_IGNORE_EINTR (g_unlink (x_servers_file));
4447
 
    g_free (x_servers_file);
4448
 
 
4449
 
    g_free (local_login);
4450
 
 
4451
 
    if (pwent != NULL) {
4452
 
            seteuid (0); /* paranoia */
4453
 
            /* Remove display from ~user/.Xauthority */
4454
 
            if G_LIKELY (setegid (pwent->pw_gid) == 0 &&
4455
 
                         seteuid (pwent->pw_uid) == 0) {
4456
 
                    gdm_auth_user_remove (d, pwent->pw_uid);
4457
 
            }
4458
 
 
4459
 
            /* don't use NEVER_FAILS_ here this can be called from places
4460
 
               kind of exiting and it's ok if this doesn't work (when shouldn't
4461
 
               it work anyway? */
4462
 
            seteuid (0);
4463
 
            setegid (0);
4464
 
    }
4465
 
 
4466
 
    logged_in_uid = -1;
4467
 
    logged_in_gid = -1;
4468
 
 
4469
 
    /* things are going to be killed, so ignore errors */
4470
 
    XSetErrorHandler (ignore_xerror_handler);
4471
 
 
4472
 
    gdm_verify_cleanup (d);
4473
 
 
4474
 
    in_session_stop --;
4475
 
 
4476
 
    if (need_to_quit_after_session_stop) {
4477
 
            gdm_debug ("gdm_slave_session_stop: Final cleanup");
4478
 
 
4479
 
            gdm_slave_quick_exit (exit_code_to_use);
4480
 
    }
 
4965
        struct passwd *pwent;
 
4966
        char *x_servers_file;
 
4967
        char *local_login;
 
4968
 
 
4969
        in_session_stop++;
 
4970
 
 
4971
        session_started = FALSE;
 
4972
 
 
4973
        local_login = login_user;
 
4974
        login_user  = NULL;
 
4975
 
 
4976
        /* don't use NEVER_FAILS_ here this can be called from places
 
4977
           kind of exiting and it's ok if this doesn't work (when shouldn't
 
4978
           it work anyway? */
 
4979
        seteuid (0);
 
4980
        setegid (0);
 
4981
 
 
4982
        gdm_slave_send_num (GDM_SOP_SESSPID, 0);
 
4983
 
 
4984
        /* Now still as root make the system authfile not readable by others,
 
4985
           and therefore not by the gdm user */
 
4986
        if (GDM_AUTHFILE (d) != NULL) {
 
4987
                VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640));
 
4988
        }
 
4989
 
 
4990
        gdm_debug ("gdm_slave_session_stop: %s on %s", local_login, d->name);
 
4991
 
 
4992
        /* Note we use the info in the structure here since if we get passed
 
4993
         * a 0 that means the process is already dead.
 
4994
         * FIXME: Maybe we should waitpid here, note make sure this will
 
4995
         * not create a hang! */
 
4996
        gdm_sigchld_block_push ();
 
4997
        if (d->sesspid > 1)
 
4998
                kill (- (d->sesspid), SIGTERM);
 
4999
        gdm_sigchld_block_pop ();
 
5000
 
 
5001
        finish_session_output (run_post_session /* do_read */);
 
5002
 
 
5003
        if (local_login == NULL)
 
5004
                pwent = NULL;
 
5005
        else
 
5006
                pwent = getpwnam (local_login); /* PAM overwrites our pwent */
 
5007
 
 
5008
        x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
 
5009
                                            d->name, ".Xservers");
 
5010
 
 
5011
        /* if there was a session that ran, run the PostSession script */
 
5012
        if (run_post_session) {
 
5013
                /* Execute post session script */
 
5014
                gdm_debug ("gdm_slave_session_stop: Running post session script");
 
5015
                gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTSESSION), local_login, pwent,
 
5016
                                       FALSE /* pass_stdout */);
 
5017
        }
 
5018
 
 
5019
        VE_IGNORE_EINTR (g_unlink (x_servers_file));
 
5020
        g_free (x_servers_file);
 
5021
 
 
5022
        g_free (local_login);
 
5023
 
 
5024
        if (pwent != NULL) {
 
5025
                seteuid (0); /* paranoia */
 
5026
                /* Remove display from ~user/.Xauthority */
 
5027
                if G_LIKELY (setegid (pwent->pw_gid) == 0 &&
 
5028
                             seteuid (pwent->pw_uid) == 0) {
 
5029
                        gdm_auth_user_remove (d, pwent->pw_uid);
 
5030
                }
 
5031
 
 
5032
                /* don't use NEVER_FAILS_ here this can be called from places
 
5033
                   kind of exiting and it's ok if this doesn't work (when shouldn't
 
5034
                   it work anyway? */
 
5035
                seteuid (0);
 
5036
                setegid (0);
 
5037
        }
 
5038
 
 
5039
        logged_in_uid = -1;
 
5040
        logged_in_gid = -1;
 
5041
 
 
5042
        /* things are going to be killed, so ignore errors */
 
5043
        XSetErrorHandler (ignore_xerror_handler);
 
5044
 
 
5045
        gdm_verify_cleanup (d);
 
5046
 
 
5047
        in_session_stop --;
 
5048
 
 
5049
        if (need_to_quit_after_session_stop) {
 
5050
                gdm_debug ("gdm_slave_session_stop: Final cleanup");
 
5051
 
 
5052
                gdm_slave_quick_exit (exit_code_to_use);
 
5053
        }
4481
5054
 
4482
5055
#ifdef __linux__
4483
 
    /* If on Linux and the runlevel is 0 or 6 and not the runlevel that
4484
 
       we were started in, then we are restarting or halting the machine.
4485
 
       Probably the user selected halt or restart from the logout
4486
 
       menu.  In this case we can really just sleep for a few seconds and
4487
 
       basically wait to be killed.  I will set the default for 30 seconds
4488
 
       and let people yell at me if this breaks something.  It shouldn't.
4489
 
       In fact it should fix things so that the login screen is not brought
4490
 
       up again and then whacked.  Waiting is safer then DISPLAY_ABORT,
4491
 
       since if we really do get this wrong, then at the worst case the
4492
 
       user will wait for a few moments. */
4493
 
    if ( ! need_to_quit_after_session_stop &&
4494
 
         ! no_shutdown_check &&
4495
 
        g_access ("/sbin/runlevel", X_OK) == 0) {
4496
 
            char ign;
4497
 
            int rnl;
4498
 
            FILE *fp = popen ("/sbin/runlevel", "r");
4499
 
            if (fp != NULL &&
4500
 
                fscanf (fp, "%c %d", &ign, &rnl) == 2 &&
4501
 
                (rnl == 0 || rnl == 6) &&
4502
 
                rnl != gdm_normal_runlevel) {
4503
 
                    /* this is a stupid loop, but we may be getting signals,
4504
 
                       so we don't want to just do sleep (30) */
4505
 
                    time_t c = time (NULL);
4506
 
                    gdm_info (_("GDM detected a halt or restart "
4507
 
                                "in progress."));
4508
 
                    pclose (fp);
4509
 
                    while (c + 30 >= time (NULL)) {
4510
 
                            struct timeval tv;
4511
 
                            /* Wait 30 seconds. */
4512
 
                            tv.tv_sec = 30;
4513
 
                            tv.tv_usec = 0;
4514
 
                            select (0, NULL, NULL, NULL, &tv);
4515
 
                            /* don't want to use sleep since we're using alarm
4516
 
                               for pinging */
4517
 
                    }
4518
 
                    /* hmm, didn't get TERM, weird */
4519
 
            } else if (fp != NULL) {
4520
 
                    pclose (fp);
4521
 
            }
4522
 
    }
 
5056
        /* If on Linux and the runlevel is 0 or 6 and not the runlevel that
 
5057
           we were started in, then we are restarting or halting the machine.
 
5058
           Probably the user selected halt or restart from the logout
 
5059
           menu.  In this case we can really just sleep for a few seconds and
 
5060
           basically wait to be killed.  I will set the default for 30 seconds
 
5061
           and let people yell at me if this breaks something.  It shouldn't.
 
5062
           In fact it should fix things so that the login screen is not brought
 
5063
           up again and then whacked.  Waiting is safer then DISPLAY_ABORT,
 
5064
           since if we really do get this wrong, then at the worst case the
 
5065
           user will wait for a few moments. */
 
5066
        if ( ! need_to_quit_after_session_stop &&
 
5067
             ! no_shutdown_check &&
 
5068
             g_access ("/sbin/runlevel", X_OK) == 0) {
 
5069
                int rnl = get_runlevel ();
 
5070
                if ((rnl == 0 || rnl == 6) && rnl != gdm_normal_runlevel) {
 
5071
                        /* this is a stupid loop, but we may be getting signals,
 
5072
                           so we don't want to just do sleep (30) */
 
5073
                        time_t c = time (NULL);
 
5074
                        gdm_info (_("GDM detected a halt or restart "
 
5075
                                    "in progress."));
 
5076
                        while (c + 30 >= time (NULL)) {
 
5077
                                struct timeval tv;
 
5078
                                /* Wait 30 seconds. */
 
5079
                                tv.tv_sec = 30;
 
5080
                                tv.tv_usec = 0;
 
5081
                                select (0, NULL, NULL, NULL, &tv);
 
5082
                                /* don't want to use sleep since we're using alarm
 
5083
                                   for pinging */
 
5084
                        }
 
5085
                        /* hmm, didn't get TERM, weird */
 
5086
                }
 
5087
        }
4523
5088
#endif /* __linux__ */
4524
5089
}
4525
5090
 
4604
5169
        in_ping = TRUE;
4605
5170
 
4606
5171
        /* schedule next alarm */
4607
 
        alarm (gdm_get_value_int (GDM_KEY_PING_INTERVAL));
 
5172
        alarm (gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL));
4608
5173
 
4609
5174
        XSync (d->dsp, True);
4610
5175
 
4614
5179
}
4615
5180
 
4616
5181
/* Called on every SIGCHLD */
4617
 
void 
 
5182
void
4618
5183
gdm_slave_child_handler (int sig)
4619
5184
{
4620
 
    gint status;
4621
 
    pid_t pid;
4622
 
    uid_t old;
4623
 
 
4624
 
    if G_UNLIKELY (already_in_slave_start_jmp)
4625
 
            return;
4626
 
 
4627
 
    gdm_in_signal++;
4628
 
 
4629
 
    old = geteuid ();
4630
 
    if (old != 0)
4631
 
            seteuid (0);
4632
 
    
4633
 
    while ((pid = waitpid (-1, &status, WNOHANG)) > 0) {
4634
 
        GSList *li;
4635
 
 
4636
 
        for (li = slave_waitpids; li != NULL; li = li->next) {
4637
 
                GdmWaitPid *wp = li->data;
4638
 
                if (wp->pid == pid) {
4639
 
                        wp->pid = -1;
4640
 
                        if (slave_waitpid_w >= 0) {
4641
 
                                VE_IGNORE_EINTR (write (slave_waitpid_w, "!", 1));
 
5185
        gint status;
 
5186
        pid_t pid;
 
5187
        uid_t old;
 
5188
 
 
5189
        if G_UNLIKELY (already_in_slave_start_jmp)
 
5190
                return;
 
5191
 
 
5192
        gdm_in_signal++;
 
5193
 
 
5194
        old = geteuid ();
 
5195
        if (old != 0)
 
5196
                seteuid (0);
 
5197
 
 
5198
        while ((pid = waitpid (-1, &status, WNOHANG)) > 0) {
 
5199
                GSList *li;
 
5200
 
 
5201
                for (li = slave_waitpids; li != NULL; li = li->next) {
 
5202
                        GdmWaitPid *wp = li->data;
 
5203
                        if (wp->pid == pid) {
 
5204
                                wp->pid = -1;
 
5205
                                if (slave_waitpid_w >= 0) {
 
5206
                                        VE_IGNORE_EINTR (write (slave_waitpid_w, "!", 1));
 
5207
                                }
4642
5208
                        }
4643
5209
                }
4644
 
        }
4645
 
        
4646
 
        if (pid == d->greetpid && greet) {
4647
 
                if (WIFEXITED (status) &&
4648
 
                    WEXITSTATUS (status) == DISPLAY_RESTARTGREETER) {
4649
 
                        /* FIXME: shouldn't do this from
4650
 
                           a signal handler */
4651
 
                        /*gdm_slave_desensitize_config ();*/
4652
 
 
4653
 
                        greet = FALSE;
4654
 
                        d->greetpid = 0;
 
5210
 
 
5211
                if (pid == d->greetpid && greet) {
 
5212
                        if (WIFEXITED (status) &&
 
5213
                            WEXITSTATUS (status) == DISPLAY_RESTARTGREETER) {
 
5214
                                /* FIXME: shouldn't do this from
 
5215
                                   a signal handler */
 
5216
                                /*gdm_slave_desensitize_config ();*/
 
5217
 
 
5218
                                greet = FALSE;
 
5219
                                d->greetpid = 0;
 
5220
                                whack_greeter_fds ();
 
5221
                                gdm_slave_send_num (GDM_SOP_GREETPID, 0);
 
5222
 
 
5223
                                do_restart_greeter = TRUE;
 
5224
                                if (restart_greeter_now) {
 
5225
                                        slave_waitpid_notify ();
 
5226
                                } else {
 
5227
                                        interrupted = TRUE;
 
5228
                                }
 
5229
                                continue;
 
5230
                        }
 
5231
 
4655
5232
                        whack_greeter_fds ();
4656
 
                        gdm_slave_send_num (GDM_SOP_GREETPID, 0);
4657
 
 
4658
 
                        do_restart_greeter = TRUE;
4659
 
                        if (restart_greeter_now) {
4660
 
                                slave_waitpid_notify ();
4661
 
                        } else {
4662
 
                                interrupted = TRUE;
4663
 
                        }
4664
 
                        continue;
4665
 
                }
4666
 
 
4667
 
                whack_greeter_fds ();
4668
 
 
4669
 
                /* if greet is TRUE, then the greeter died outside of our
4670
 
                 * control really, so clean up and die, something is wrong
4671
 
                 * The greeter is only allowed to pass back these
4672
 
                 * exit codes, else we'll just remanage */
4673
 
                if (WIFEXITED (status) &&
4674
 
                    (WEXITSTATUS (status) == DISPLAY_ABORT ||
4675
 
                     WEXITSTATUS (status) == DISPLAY_REBOOT ||
4676
 
                     WEXITSTATUS (status) == DISPLAY_HALT ||
4677
 
                     WEXITSTATUS (status) == DISPLAY_SUSPEND ||
4678
 
                     WEXITSTATUS (status) == DISPLAY_RUN_CHOOSER ||
4679
 
                     WEXITSTATUS (status) == DISPLAY_RESTARTGDM ||
4680
 
                     WEXITSTATUS (status) == DISPLAY_GREETERFAILED)) {
4681
 
                        exit_code_to_use = WEXITSTATUS (status);
4682
 
                        SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
4683
 
                } else {
4684
 
                        if (WIFSIGNALED (status) &&
4685
 
                            (WTERMSIG (status) == SIGSEGV ||
4686
 
                             WTERMSIG (status) == SIGABRT ||
4687
 
                             WTERMSIG (status) == SIGPIPE ||
4688
 
                             WTERMSIG (status) == SIGBUS)) {
4689
 
                                exit_code_to_use = DISPLAY_GREETERFAILED;
 
5233
 
 
5234
                        /* if greet is TRUE, then the greeter died outside of our
 
5235
                         * control really, so clean up and die, something is wrong
 
5236
                         * The greeter is only allowed to pass back these
 
5237
                         * exit codes, else we'll just remanage */
 
5238
                        if (WIFEXITED (status) &&
 
5239
                            (WEXITSTATUS (status) == DISPLAY_ABORT ||
 
5240
                             WEXITSTATUS (status) == DISPLAY_REBOOT ||
 
5241
                             WEXITSTATUS (status) == DISPLAY_HALT ||
 
5242
                             WEXITSTATUS (status) == DISPLAY_SUSPEND ||
 
5243
                             WEXITSTATUS (status) == DISPLAY_RUN_CHOOSER ||
 
5244
                             WEXITSTATUS (status) == DISPLAY_RESTARTGDM ||
 
5245
                             WEXITSTATUS (status) == DISPLAY_GREETERFAILED)) {
 
5246
                                exit_code_to_use = WEXITSTATUS (status);
4690
5247
                                SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
4691
5248
                        } else {
4692
 
                                /* weird error return, interpret as failure */
4693
 
                                if (WIFEXITED (status) &&
4694
 
                                    WEXITSTATUS (status) == 1)
 
5249
                                if (WIFSIGNALED (status) &&
 
5250
                                    (WTERMSIG (status) == SIGSEGV ||
 
5251
                                     WTERMSIG (status) == SIGABRT ||
 
5252
                                     WTERMSIG (status) == SIGPIPE ||
 
5253
                                     WTERMSIG (status) == SIGBUS)) {
4695
5254
                                        exit_code_to_use = DISPLAY_GREETERFAILED;
4696
 
                                SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
4697
 
                        }
4698
 
                }
4699
 
        } else if (pid != 0 && pid == d->sesspid) {
4700
 
                d->sesspid = 0;
4701
 
                if (WIFEXITED (status))
4702
 
                        d->last_sess_status = WEXITSTATUS (status);
4703
 
                else
4704
 
                        d->last_sess_status = -1;
4705
 
        } else if (pid != 0 && pid == d->chooserpid) {
4706
 
                d->chooserpid = 0;
4707
 
        } else if (pid != 0 && pid == d->servpid) {
4708
 
                if (d->servstat == SERVER_RUNNING)
4709
 
                        gdm_server_whack_lockfile (d);
4710
 
                d->servstat = SERVER_DEAD;
4711
 
                d->servpid = 0;
4712
 
                gdm_server_wipe_cookies (d);
4713
 
                gdm_slave_whack_temp_auth_file ();
4714
 
 
4715
 
                gdm_slave_send_num (GDM_SOP_XPID, 0);
4716
 
 
4717
 
                /* whack the session good */
4718
 
                if (d->sesspid > 1) {
4719
 
                        gdm_slave_send_num (GDM_SOP_SESSPID, 0);
4720
 
                        kill (- (d->sesspid), SIGTERM);
4721
 
                }
4722
 
                if (d->greetpid > 1) {
4723
 
                        gdm_slave_send_num (GDM_SOP_GREETPID, 0);
4724
 
                        kill (d->greetpid, SIGTERM);
4725
 
                }
4726
 
                if (d->chooserpid > 1) {
4727
 
                        gdm_slave_send_num (GDM_SOP_CHOOSERPID, 0);
4728
 
                        kill (d->chooserpid, SIGTERM);
4729
 
                }
4730
 
 
4731
 
                /* just in case we restart again wait at least
4732
 
                   one sec to avoid races */
4733
 
                if (d->sleep_before_run < 1)
4734
 
                        d->sleep_before_run = 1;
4735
 
        } else if (pid == extra_process) {
4736
 
                /* an extra process died, yay! */
4737
 
                extra_process = 0;
4738
 
                extra_status = status;
 
5255
                                        SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
 
5256
                                } else {
 
5257
                                        /* weird error return, interpret as failure */
 
5258
                                        if (WIFEXITED (status) &&
 
5259
                                            WEXITSTATUS (status) == 1)
 
5260
                                                exit_code_to_use = DISPLAY_GREETERFAILED;
 
5261
                                        SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
 
5262
                                }
 
5263
                        }
 
5264
                } else if (pid != 0 && pid == d->sesspid) {
 
5265
                        d->sesspid = 0;
 
5266
                        if (WIFEXITED (status))
 
5267
                                d->last_sess_status = WEXITSTATUS (status);
 
5268
                        else
 
5269
                                d->last_sess_status = -1;
 
5270
                } else if (pid != 0 && pid == d->chooserpid) {
 
5271
                        d->chooserpid = 0;
 
5272
                } else if (pid != 0 && pid == d->servpid) {
 
5273
                        if (d->servstat == SERVER_RUNNING)
 
5274
                                gdm_server_whack_lockfile (d);
 
5275
                        d->servstat = SERVER_DEAD;
 
5276
                        d->servpid = 0;
 
5277
                        gdm_server_wipe_cookies (d);
 
5278
                        gdm_slave_whack_temp_auth_file ();
 
5279
 
 
5280
                        gdm_slave_send_num (GDM_SOP_XPID, 0);
 
5281
 
 
5282
                        /* whack the session good */
 
5283
                        if (d->sesspid > 1) {
 
5284
                                gdm_slave_send_num (GDM_SOP_SESSPID, 0);
 
5285
                                kill (- (d->sesspid), SIGTERM);
 
5286
                        }
 
5287
                        if (d->greetpid > 1) {
 
5288
                                gdm_slave_send_num (GDM_SOP_GREETPID, 0);
 
5289
                                kill (d->greetpid, SIGTERM);
 
5290
                        }
 
5291
                        if (d->chooserpid > 1) {
 
5292
                                gdm_slave_send_num (GDM_SOP_CHOOSERPID, 0);
 
5293
                                kill (d->chooserpid, SIGTERM);
 
5294
                        }
 
5295
 
 
5296
                        /* just in case we restart again wait at least
 
5297
                           one sec to avoid races */
 
5298
                        if (d->sleep_before_run < 1)
 
5299
                                d->sleep_before_run = 1;
 
5300
                } else if (pid == extra_process) {
 
5301
                        /* an extra process died, yay! */
 
5302
                        extra_process = 0;
 
5303
                        extra_status = status;
 
5304
                }
4739
5305
        }
4740
 
    }
4741
 
    if (old != 0)
4742
 
            seteuid (old);
 
5306
        if (old != 0)
 
5307
                seteuid (old);
4743
5308
 
4744
 
    gdm_in_signal--;
 
5309
        gdm_in_signal--;
4745
5310
}
4746
5311
 
4747
5312
static void
4808
5373
                        } else if (strcmp (&s[1], GDM_NOTIFY_TWIDDLE_POINTER) == 0) {
4809
5374
                                gdm_twiddle_pointer (d);
4810
5375
                        }
 
5376
                } else if (s[0] == GDM_SLAVE_NOTIFY_RESPONSE) {
 
5377
                        gdm_got_ack = TRUE;
 
5378
                        if (gdm_ack_response)
 
5379
                                g_free (gdm_ack_response);
 
5380
 
 
5381
                        if (s[1] == GDM_SLAVE_NOTIFY_YESNO_RESPONSE) {
 
5382
                                if (s[2] == '0') {
 
5383
                                        gdm_ack_response =  g_strdup ("no");
 
5384
                                } else {
 
5385
                                        gdm_ack_response =  g_strdup ("yes");
 
5386
                                }
 
5387
                        } else if (s[1] == GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE) {
 
5388
                                gdm_ack_response = g_strdup (&s[2]);
 
5389
                        } else if (s[1] == GDM_SLAVE_NOTIFY_QUESTION_RESPONSE) {
 
5390
                                gdm_ack_question_response = g_strdup (&s[2]);
 
5391
                        } else if (s[1] == GDM_SLAVE_NOTIFY_ERROR_RESPONSE) {
 
5392
                                if (s[2] != '\0') {
 
5393
                                        gdm_ack_response = g_strdup (&s[2]);
 
5394
                                } else {
 
5395
                                        gdm_ack_response = NULL;
 
5396
                                }
 
5397
                        }
4811
5398
                }
4812
5399
        }
4813
5400
 
4830
5417
static gint
4831
5418
gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt)
4832
5419
{
4833
 
    gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond");
4834
 
    return (0);
4835
 
}
4836
 
 
4837
 
/* Ignore fatal X errors when user did ctl-alt-backspace */
4838
 
static gint
4839
 
gdm_slave_ignore_xioerror_handler (Display *disp)
4840
 
{
4841
 
    gdm_debug ("Fatal X error detected.  Ignoring same during session shut down.");
4842
 
    Longjmp (ignore_xioerror_jmp, 1);
 
5420
        gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond");
 
5421
        return (0);
4843
5422
}
4844
5423
 
4845
5424
/* We usually respond to fatal errors by restarting the display */
4908
5487
                         * it is allowed for this display (it's only allowed
4909
5488
                         * for the first local display) and if it's set up
4910
5489
                         * correctly */
4911
 
                        if ((d->attached || gdm_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN)) 
 
5490
                        if ((d->attached || gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN))
4912
5491
                            && d->timed_login_ok &&
4913
5492
                            ! ve_string_empty (ParsedTimedLogin) &&
4914
5493
                            strcmp (ParsedTimedLogin, gdm_root_user ()) != 0 &&
4915
 
                            gdm_get_value_int (GDM_KEY_TIMED_LOGIN_DELAY) > 0) {
 
5494
                            gdm_daemon_config_get_value_int (GDM_KEY_TIMED_LOGIN_DELAY) > 0) {
4916
5495
                                do_timed_login = TRUE;
4917
5496
                        }
4918
5497
                        break;
4919
5498
                case GDM_INTERRUPT_CONFIGURE:
4920
5499
                        if (d->attached &&
4921
 
                            gdm_get_value_bool_per_display (d->name, GDM_KEY_CONFIG_AVAILABLE) &&
4922
 
                            gdm_get_value_bool_per_display (d->name, GDM_KEY_SYSTEM_MENU) &&
4923
 
                            ! ve_string_empty (gdm_get_value_string (GDM_KEY_CONFIGURATOR))) {
 
5500
                            gdm_daemon_config_get_value_bool_per_display (GDM_KEY_CONFIG_AVAILABLE, d->name) &&
 
5501
                            gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, d->name) &&
 
5502
                            ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_CONFIGURATOR))) {
4924
5503
                                do_configurator = TRUE;
4925
5504
                        }
4926
5505
                        break;
4927
5506
                case GDM_INTERRUPT_SUSPEND:
4928
5507
                        if (d->attached &&
4929
 
                            gdm_get_value_bool_per_display (d->name, GDM_KEY_SYSTEM_MENU) &&
4930
 
                            ! ve_string_empty (gdm_get_value_string (GDM_KEY_SUSPEND))) {
 
5508
                            gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, d->name) &&
 
5509
                            ! ve_string_empty (gdm_daemon_config_get_value_string_array (GDM_KEY_SUSPEND))) {
4931
5510
                                gchar *msg = g_strdup_printf ("%s %ld", 
4932
 
                                        GDM_SOP_SUSPEND_MACHINE,
4933
 
                                        (long)getpid ());
 
5511
                                                              GDM_SOP_SUSPEND_MACHINE,
 
5512
                                                              (long)getpid ());
4934
5513
 
4935
5514
                                gdm_slave_send (msg, FALSE /* wait_for_ack */);
4936
5515
                                g_free (msg);
4940
5519
                        return TRUE;
4941
5520
                case GDM_INTERRUPT_LOGIN_SOUND:
4942
5521
                        if (d->attached &&
4943
 
                            ! play_login_sound (gdm_get_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE))) {
 
5522
                            ! play_login_sound (gdm_daemon_config_get_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE))) {
4944
5523
                                gdm_error (_("Login sound requested on non-local display or the play software "
4945
5524
                                             "cannot be run or the sound does not exist"));
4946
5525
                        }
4951
5530
                case GDM_INTERRUPT_CANCEL:
4952
5531
                        do_cancel = TRUE;
4953
5532
                        break;
 
5533
                case GDM_INTERRUPT_CUSTOM_CMD:
 
5534
                        if (d->attached &&
 
5535
                            ! ve_string_empty (&msg[2])) {
 
5536
                                gchar *message = g_strdup_printf ("%s %ld %s", 
 
5537
                                                                  GDM_SOP_CUSTOM_CMD,
 
5538
                                                                  (long)getpid (), &msg[2]);
 
5539
 
 
5540
                                gdm_slave_send (message, TRUE);
 
5541
                                g_free (message);
 
5542
                        }
 
5543
                        return TRUE;
4954
5544
                case GDM_INTERRUPT_THEME:
4955
5545
                        g_free (d->theme_name);
4956
5546
                        d->theme_name = NULL;
4958
5548
                                d->theme_name = g_strdup (&msg[2]);
4959
5549
                        gdm_slave_send_string (GDM_SOP_CHOSEN_THEME, &msg[2]);
4960
5550
                        return TRUE;
 
5551
                case GDM_INTERRUPT_SELECT_LANG:
 
5552
                        if (msg + 2) {
 
5553
                                const char *locale;
 
5554
 
 
5555
                                locale = (gchar*)(msg + 3);
 
5556
 
 
5557
                                always_restart_greeter = (gboolean)(*(msg + 2));
 
5558
                                ve_clearenv ();
 
5559
                                if (!strcmp (locale, DEFAULT_LANGUAGE)) {
 
5560
                                        locale = gdm_system_locale;
 
5561
                                }
 
5562
                                g_setenv ("GDM_LANG", locale, TRUE);
 
5563
                                g_setenv ("LANG", locale, TRUE);
 
5564
                                g_unsetenv ("LC_ALL");
 
5565
                                g_unsetenv ("LC_MESSAGES");
 
5566
                                setlocale (LC_ALL, "");
 
5567
                                setlocale (LC_MESSAGES, "");
 
5568
                                gdm_saveenv ();
 
5569
 
 
5570
                                do_restart_greeter = TRUE;
 
5571
                        }
 
5572
                        break;
4961
5573
                default:
4962
5574
                        break;
4963
5575
                }
4973
5585
}
4974
5586
 
4975
5587
 
4976
 
char * 
 
5588
char *
4977
5589
gdm_slave_greeter_ctl (char cmd, const char *str)
4978
5590
{
4979
 
    char *buf = NULL;
4980
 
    int c;
4981
 
 
4982
 
    /* There is no spoon^H^H^H^H^Hgreeter */
4983
 
    if G_UNLIKELY ( ! greet)
4984
 
            return NULL;
4985
 
 
4986
 
    check_notifies_now ();
4987
 
 
4988
 
    if ( ! ve_string_empty (str)) {
4989
 
            gdm_fdprintf (greeter_fd_out, "%c%c%s\n", STX, cmd, str);
4990
 
    } else {
4991
 
            gdm_fdprintf (greeter_fd_out, "%c%c\n", STX, cmd);
4992
 
    }
 
5591
        char *buf = NULL;
 
5592
        int c;
 
5593
 
 
5594
        /* There is no spoon^H^H^H^H^Hgreeter */
 
5595
        if G_UNLIKELY ( ! greet)
 
5596
                return NULL;
 
5597
 
 
5598
        check_notifies_now ();
 
5599
 
 
5600
        if ( ! ve_string_empty (str)) {
 
5601
                gdm_fdprintf (greeter_fd_out, "%c%c%s\n", STX, cmd, str);
 
5602
        } else {
 
5603
                gdm_fdprintf (greeter_fd_out, "%c%c\n", STX, cmd);
 
5604
        }
4993
5605
 
4994
5606
#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
4995
 
    /* let the other process (greeter) do its stuff */
4996
 
    sched_yield ();
 
5607
        /* let the other process (greeter) do its stuff */
 
5608
        sched_yield ();
4997
5609
#endif
4998
5610
 
4999
 
    do {
5000
 
      g_free (buf);
5001
 
      buf = NULL;
5002
 
      /* Skip random junk that might have accumulated */
5003
 
      do {
5004
 
            c = gdm_fdgetc (greeter_fd_in);
5005
 
      } while (c != EOF && c != STX);
5006
 
    
5007
 
      if (c == EOF ||
5008
 
          (buf = gdm_fdgets (greeter_fd_in)) == NULL) {
5009
 
              interrupted = TRUE;
5010
 
              /* things don't seem well with the greeter, it probably died */
5011
 
              return NULL;
5012
 
      }
5013
 
    } while (check_for_interruption (buf) && ! interrupted);
5014
 
 
5015
 
    /* user responses take kind of random amount of time */
5016
 
    gdm_random_tick ();
5017
 
 
5018
 
    if ( ! ve_string_empty (buf)) {
5019
 
            return buf;
5020
 
    } else {
5021
 
            g_free (buf);
5022
 
            return NULL;
5023
 
    }
 
5611
        do {
 
5612
                g_free (buf);
 
5613
                buf = NULL;
 
5614
                /* Skip random junk that might have accumulated */
 
5615
                do {
 
5616
                        c = gdm_fdgetc (greeter_fd_in);
 
5617
                } while (c != EOF && c != STX);
 
5618
 
 
5619
                if (c == EOF ||
 
5620
                    (buf = gdm_fdgets (greeter_fd_in)) == NULL) {
 
5621
                        interrupted = TRUE;
 
5622
                        /* things don't seem well with the greeter, it probably died */
 
5623
                        return NULL;
 
5624
                }
 
5625
        } while (check_for_interruption (buf) && ! interrupted);
 
5626
 
 
5627
        /* user responses take kind of random amount of time */
 
5628
        gdm_random_tick ();
 
5629
 
 
5630
        if ( ! ve_string_empty (buf)) {
 
5631
                return buf;
 
5632
        } else {
 
5633
                g_free (buf);
 
5634
                return NULL;
 
5635
        }
5024
5636
}
5025
5637
 
5026
5638
void
5029
5641
        g_free (gdm_slave_greeter_ctl (cmd, str));
5030
5642
}
5031
5643
 
5032
 
static void 
 
5644
static void
5033
5645
gdm_slave_quick_exit (gint status)
5034
5646
{
5035
 
    /* just for paranoia's sake */
5036
 
    /* don't use NEVER_FAILS_ here this can be called from places
5037
 
       kind of exiting and it's ok if this doesn't work (when shouldn't
5038
 
       it work anyway? */
5039
 
    seteuid (0);
5040
 
    setegid (0);
5041
 
 
5042
 
    if (d != NULL) {
5043
 
            gdm_debug ("gdm_slave_quick_exit: Will kill everything from the display");
5044
 
 
5045
 
            /* just in case we do get the XIOError,
5046
 
               don't run session_stop since we've
5047
 
               requested a quick exit */
5048
 
            session_started = FALSE;
5049
 
 
5050
 
            /* No need to send the PIDS to the daemon
5051
 
             * since we'll just exit cleanly */
5052
 
 
5053
 
            /* Push and never pop */
5054
 
            gdm_sigchld_block_push ();
5055
 
 
5056
 
            /* Kill children where applicable */
5057
 
            if (d->greetpid > 1)
5058
 
                    kill (d->greetpid, SIGTERM);
5059
 
            d->greetpid = 0;
5060
 
 
5061
 
            if (d->chooserpid > 1)
5062
 
                    kill (d->chooserpid, SIGTERM);
5063
 
            d->chooserpid = 0;
5064
 
 
5065
 
            if (d->sesspid > 1)
5066
 
                    kill (-(d->sesspid), SIGTERM);
5067
 
            d->sesspid = 0;
5068
 
 
5069
 
            if (extra_process > 1)
5070
 
                    kill (-(extra_process), SIGTERM);
5071
 
            extra_process = 0;
5072
 
 
5073
 
            gdm_verify_cleanup (d);
5074
 
            gdm_server_stop (d);
5075
 
 
5076
 
            if (d->servpid > 1)
5077
 
                    kill (d->servpid, SIGTERM);
5078
 
            d->servpid = 0;
5079
 
 
5080
 
            gdm_debug ("gdm_slave_quick_exit: Killed everything from the display");
5081
 
    }
5082
 
 
5083
 
    _exit (status);
 
5647
        /* just for paranoia's sake */
 
5648
        /* don't use NEVER_FAILS_ here this can be called from places
 
5649
           kind of exiting and it's ok if this doesn't work (when shouldn't
 
5650
           it work anyway? */
 
5651
        seteuid (0);
 
5652
        setegid (0);
 
5653
 
 
5654
        if (d != NULL) {
 
5655
                gdm_debug ("gdm_slave_quick_exit: Will kill everything from the display");
 
5656
 
 
5657
                /* just in case we do get the XIOError,
 
5658
                   don't run session_stop since we've
 
5659
                   requested a quick exit */
 
5660
                session_started = FALSE;
 
5661
 
 
5662
                /* No need to send the PIDS to the daemon
 
5663
                 * since we'll just exit cleanly */
 
5664
 
 
5665
                /* Push and never pop */
 
5666
                gdm_sigchld_block_push ();
 
5667
 
 
5668
                /* Kill children where applicable */
 
5669
                if (d->greetpid > 1)
 
5670
                        kill (d->greetpid, SIGTERM);
 
5671
                d->greetpid = 0;
 
5672
 
 
5673
                if (d->chooserpid > 1)
 
5674
                        kill (d->chooserpid, SIGTERM);
 
5675
                d->chooserpid = 0;
 
5676
 
 
5677
                if (d->sesspid > 1)
 
5678
                        kill (-(d->sesspid), SIGTERM);
 
5679
                d->sesspid = 0;
 
5680
 
 
5681
                if (extra_process > 1)
 
5682
                        kill (-(extra_process), SIGTERM);
 
5683
                extra_process = 0;
 
5684
 
 
5685
                gdm_verify_cleanup (d);
 
5686
                gdm_server_stop (d);
 
5687
 
 
5688
                if (d->servpid > 1)
 
5689
                        kill (d->servpid, SIGTERM);
 
5690
                d->servpid = 0;
 
5691
 
 
5692
                gdm_debug ("gdm_slave_quick_exit: Killed everything from the display");
 
5693
        }
 
5694
 
 
5695
        _exit (status);
5084
5696
}
5085
5697
 
5086
 
static void 
 
5698
static void
5087
5699
gdm_slave_exit (gint status, const gchar *format, ...)
5088
5700
{
5089
 
    va_list args;
5090
 
    gchar *s;
5091
 
 
5092
 
    va_start (args, format);
5093
 
    s = g_strdup_vprintf (format, args);
5094
 
    va_end (args);
5095
 
    
5096
 
    gdm_error ("%s", s);
5097
 
    
5098
 
    g_free (s);
5099
 
 
5100
 
    gdm_slave_quick_exit (status);
 
5701
        va_list args;
 
5702
        gchar *s;
 
5703
 
 
5704
        va_start (args, format);
 
5705
        s = g_strdup_vprintf (format, args);
 
5706
        va_end (args);
 
5707
 
 
5708
        gdm_error ("%s", s);
 
5709
 
 
5710
        g_free (s);
 
5711
 
 
5712
        gdm_slave_quick_exit (status);
5101
5713
}
5102
5714
 
5103
 
static void 
 
5715
static void
5104
5716
gdm_child_exit (gint status, const gchar *format, ...)
5105
5717
{
5106
 
    va_list args;
5107
 
    gchar *s;
5108
 
 
5109
 
    va_start (args, format);
5110
 
    s = g_strdup_vprintf (format, args);
5111
 
    va_end (args);
5112
 
    
5113
 
    syslog (LOG_ERR, "%s", s);
5114
 
    
5115
 
    g_free (s);
5116
 
 
5117
 
    _exit (status);
 
5718
        va_list args;
 
5719
        gchar *s;
 
5720
 
 
5721
        va_start (args, format);
 
5722
        s = g_strdup_vprintf (format, args);
 
5723
        va_end (args);
 
5724
 
 
5725
        g_error ("%s", s);
 
5726
 
 
5727
        g_free (s);
 
5728
 
 
5729
        _exit (status);
5118
5730
}
5119
5731
 
5120
5732
void
5145
5757
                g_free (d->parent_temp_auth_file);
5146
5758
                d->parent_temp_auth_file =
5147
5759
                        copy_auth_file (d->server_uid,
5148
 
                                        gdm_get_gdmuid (),
 
5760
                                        gdm_daemon_config_get_gdmuid (),
5149
5761
                                        d->parent_auth_file);
5150
5762
        }
5151
5763
}
5157
5769
                g_setenv ("GDM_PARENT_DISPLAY", d->parent_disp, TRUE);
5158
5770
                if (d->parent_temp_auth_file != NULL) {
5159
5771
                        g_setenv ("GDM_PARENT_XAUTHORITY",
5160
 
                                      d->parent_temp_auth_file, TRUE);
 
5772
                                  d->parent_temp_auth_file, TRUE);
5161
5773
                        g_free (d->parent_temp_auth_file);
5162
5774
                        d->parent_temp_auth_file = NULL;
5163
5775
                }
5165
5777
}
5166
5778
 
5167
5779
static gint
5168
 
gdm_slave_exec_script (GdmDisplay *d, const gchar *dir, const char *login,
5169
 
                       struct passwd *pwent, gboolean pass_stdout)
 
5780
gdm_slave_exec_script (GdmDisplay *d,
 
5781
                       const gchar *dir,
 
5782
                       const char *login,
 
5783
                       struct passwd *pwent,
 
5784
                       gboolean pass_stdout)
5170
5785
{
5171
 
    pid_t pid;
5172
 
    char *script;
5173
 
    gchar **argv;
5174
 
    gint status;
5175
 
    char *x_servers_file;
5176
 
 
5177
 
    if G_UNLIKELY (!d || ve_string_empty (dir))
5178
 
        return EXIT_SUCCESS;
5179
 
 
5180
 
    script = g_build_filename (dir, d->name, NULL);
5181
 
    if (g_access (script, R_OK|X_OK) != 0) {
5182
 
            g_free (script);
5183
 
            script = NULL;
5184
 
    }
5185
 
    if (script == NULL &&
5186
 
        ! ve_string_empty (d->hostname)) {
5187
 
            script = g_build_filename (dir, d->hostname, NULL);
5188
 
            if (g_access (script, R_OK|X_OK) != 0) {
5189
 
                    g_free (script);
5190
 
                    script = NULL;
5191
 
            }
5192
 
    }
5193
 
    if (script == NULL &&
5194
 
        SERVER_IS_XDMCP (d)) {
5195
 
            script = g_build_filename (dir, "XDMCP", NULL);
5196
 
            if (g_access (script, R_OK|X_OK) != 0) {
5197
 
                    g_free (script);
5198
 
                    script = NULL;
5199
 
            }
5200
 
    }
5201
 
    if (script == NULL &&
5202
 
        SERVER_IS_FLEXI (d)) {
5203
 
            script = g_build_filename (dir, "Flexi", NULL);
5204
 
            if (g_access (script, R_OK|X_OK) != 0) {
5205
 
                    g_free (script);
5206
 
                    script = NULL;
5207
 
            }
5208
 
    }
5209
 
    if (script == NULL) {
5210
 
            script = g_build_filename (dir, "Default", NULL);
5211
 
            if (g_access (script, R_OK|X_OK) != 0) {
5212
 
                    g_free (script);
5213
 
                    script = NULL;
5214
 
            }
5215
 
    }
5216
 
    
5217
 
    if (script == NULL) {
5218
 
            return EXIT_SUCCESS;
5219
 
    }
5220
 
 
5221
 
    create_temp_auth_file ();
5222
 
 
5223
 
    pid = gdm_fork_extra ();
5224
 
 
5225
 
    switch (pid) {
5226
 
            
5227
 
    case 0:
5228
 
        closelog ();
5229
 
 
5230
 
        VE_IGNORE_EINTR (close (0));
5231
 
        gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
5232
 
 
5233
 
        if ( ! pass_stdout) {
5234
 
                VE_IGNORE_EINTR (close (1));
5235
 
                VE_IGNORE_EINTR (close (2));
5236
 
                /* No error checking here - if it's messed the best response
5237
 
                 * is to ignore & try to continue */
5238
 
                gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
5239
 
                gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
5240
 
        }
5241
 
 
5242
 
        gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
5243
 
 
5244
 
        openlog ("gdm", LOG_PID, LOG_DAEMON);
5245
 
 
5246
 
        if (login != NULL) {
5247
 
                g_setenv ("LOGNAME", login, TRUE);
5248
 
                g_setenv ("USER", login, TRUE);
5249
 
                g_setenv ("USERNAME", login, TRUE);
5250
 
        } else {
5251
 
                char *gdmuser = gdm_get_value_string (GDM_KEY_USER);
5252
 
                g_setenv ("LOGNAME", gdmuser, TRUE);
5253
 
                g_setenv ("USER", gdmuser, TRUE);
5254
 
                g_setenv ("USERNAME", gdmuser, TRUE);
5255
 
        }
5256
 
        if (pwent != NULL) {
5257
 
                if (ve_string_empty (pwent->pw_dir)) {
 
5786
        pid_t pid;
 
5787
        char *script;
 
5788
        gchar **argv = NULL;
 
5789
        gint status;
 
5790
        char *x_servers_file;
 
5791
#ifdef HAVE_CTRUN
 
5792
        char *ctrun;
 
5793
#endif
 
5794
 
 
5795
        if G_UNLIKELY (!d || ve_string_empty (dir))
 
5796
                return EXIT_SUCCESS;
 
5797
 
 
5798
        script = g_build_filename (dir, d->name, NULL);
 
5799
        if (g_access (script, R_OK|X_OK) != 0) {
 
5800
                g_free (script);
 
5801
                script = NULL;
 
5802
        }
 
5803
        if (script == NULL &&
 
5804
            ! ve_string_empty (d->hostname)) {
 
5805
                script = g_build_filename (dir, d->hostname, NULL);
 
5806
                if (g_access (script, R_OK|X_OK) != 0) {
 
5807
                        g_free (script);
 
5808
                        script = NULL;
 
5809
                }
 
5810
        }
 
5811
        if (script == NULL &&
 
5812
            SERVER_IS_XDMCP (d)) {
 
5813
                script = g_build_filename (dir, "XDMCP", NULL);
 
5814
                if (g_access (script, R_OK|X_OK) != 0) {
 
5815
                        g_free (script);
 
5816
                        script = NULL;
 
5817
                }
 
5818
        }
 
5819
        if (script == NULL &&
 
5820
            SERVER_IS_FLEXI (d)) {
 
5821
                script = g_build_filename (dir, "Flexi", NULL);
 
5822
                if (g_access (script, R_OK|X_OK) != 0) {
 
5823
                        g_free (script);
 
5824
                        script = NULL;
 
5825
                }
 
5826
        }
 
5827
        if (script == NULL) {
 
5828
                script = g_build_filename (dir, "Default", NULL);
 
5829
                if (g_access (script, R_OK|X_OK) != 0) {
 
5830
                        g_free (script);
 
5831
                        script = NULL;
 
5832
                }
 
5833
        }
 
5834
 
 
5835
        if (script == NULL) {
 
5836
                return EXIT_SUCCESS;
 
5837
        }
 
5838
 
 
5839
        create_temp_auth_file ();
 
5840
 
 
5841
        gdm_debug ("Forking extra process: %s", script);
 
5842
 
 
5843
        extra_process = pid = gdm_fork_extra ();
 
5844
 
 
5845
        switch (pid) {
 
5846
        case 0:
 
5847
                gdm_log_shutdown ();
 
5848
 
 
5849
                VE_IGNORE_EINTR (close (0));
 
5850
                gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
 
5851
 
 
5852
                if ( ! pass_stdout) {
 
5853
                        VE_IGNORE_EINTR (close (1));
 
5854
                        VE_IGNORE_EINTR (close (2));
 
5855
                        /* No error checking here - if it's messed the best response
 
5856
                         * is to ignore & try to continue */
 
5857
                        gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
 
5858
                        gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
5859
                }
 
5860
 
 
5861
                gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
 
5862
 
 
5863
                gdm_log_init ();
 
5864
 
 
5865
                if (login != NULL) {
 
5866
                        g_setenv ("LOGNAME", login, TRUE);
 
5867
                        g_setenv ("USER", login, TRUE);
 
5868
                        g_setenv ("USERNAME", login, TRUE);
 
5869
                } else {
 
5870
                        const char *gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER);
 
5871
                        g_setenv ("LOGNAME", gdmuser, TRUE);
 
5872
                        g_setenv ("USER", gdmuser, TRUE);
 
5873
                        g_setenv ("USERNAME", gdmuser, TRUE);
 
5874
                }
 
5875
                if (pwent != NULL) {
 
5876
                        if (ve_string_empty (pwent->pw_dir)) {
 
5877
                                g_setenv ("HOME", "/", TRUE);
 
5878
                                g_setenv ("PWD", "/", TRUE);
 
5879
                                VE_IGNORE_EINTR (g_chdir ("/"));
 
5880
                        } else {
 
5881
                                g_setenv ("HOME", pwent->pw_dir, TRUE);
 
5882
                                g_setenv ("PWD", pwent->pw_dir, TRUE);
 
5883
                                VE_IGNORE_EINTR (g_chdir (pwent->pw_dir));
 
5884
                                if (errno != 0) {
 
5885
                                        VE_IGNORE_EINTR (g_chdir ("/"));
 
5886
                                        g_setenv ("PWD", "/", TRUE);
 
5887
                                }
 
5888
                        }
 
5889
                        g_setenv ("SHELL", pwent->pw_shell, TRUE);
 
5890
                } else {
5258
5891
                        g_setenv ("HOME", "/", TRUE);
5259
5892
                        g_setenv ("PWD", "/", TRUE);
5260
5893
                        VE_IGNORE_EINTR (g_chdir ("/"));
5261
 
                } else {
5262
 
                        g_setenv ("HOME", pwent->pw_dir, TRUE);
5263
 
                        g_setenv ("PWD", pwent->pw_dir, TRUE);
5264
 
                        VE_IGNORE_EINTR (g_chdir (pwent->pw_dir));
5265
 
                        if (errno != 0) {
5266
 
                                VE_IGNORE_EINTR (g_chdir ("/"));
5267
 
                                g_setenv ("PWD", "/", TRUE);
5268
 
                        }
 
5894
                        g_setenv ("SHELL", "/bin/sh", TRUE);
5269
5895
                }
5270
 
                g_setenv ("SHELL", pwent->pw_shell, TRUE);
5271
 
        } else {
5272
 
                g_setenv ("HOME", "/", TRUE);
5273
 
                g_setenv ("PWD", "/", TRUE);
5274
 
                VE_IGNORE_EINTR (g_chdir ("/"));
5275
 
                g_setenv ("SHELL", "/bin/sh", TRUE);
5276
 
        }
5277
 
 
5278
 
        set_xnest_parent_stuff ();
5279
 
 
5280
 
        /* some env for use with the Pre and Post scripts */
5281
 
        x_servers_file = gdm_make_filename (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR),
5282
 
                                            d->name, ".Xservers");
5283
 
        g_setenv ("X_SERVERS", x_servers_file, TRUE);
5284
 
        g_free (x_servers_file);
5285
 
        if (SERVER_IS_XDMCP (d))
5286
 
                g_setenv ("REMOTE_HOST", d->hostname, TRUE);
5287
 
 
5288
 
        /* Runs as root */
5289
 
        if (GDM_AUTHFILE (d) != NULL)
5290
 
                g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
5291
 
        else
5292
 
                g_unsetenv ("XAUTHORITY");
5293
 
        g_setenv ("DISPLAY", d->name, TRUE);
5294
 
        g_setenv ("PATH", gdm_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
5295
 
        g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
5296
 
        if ( ! ve_string_empty (d->theme_name))
5297
 
                g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
5298
 
        argv = ve_split (script);
5299
 
        VE_IGNORE_EINTR (execv (argv[0], argv));
5300
 
        syslog (LOG_ERR, _("%s: Failed starting: %s"), "gdm_slave_exec_script",
5301
 
                script);
5302
 
        _exit (EXIT_SUCCESS);
5303
 
            
5304
 
    case -1:
5305
 
        gdm_slave_whack_temp_auth_file ();
5306
 
        g_free (script);
5307
 
        syslog (LOG_ERR, _("%s: Can't fork script process!"), "gdm_slave_exec_script");
5308
 
        return EXIT_SUCCESS;
5309
 
        
5310
 
    default:
5311
 
        gdm_wait_for_extra (&status);
5312
 
 
5313
 
        gdm_slave_whack_temp_auth_file ();
5314
 
 
5315
 
        g_free (script);
5316
 
 
5317
 
        if (WIFEXITED (status))
5318
 
            return WEXITSTATUS (status);
5319
 
        else
5320
 
            return EXIT_SUCCESS;
5321
 
    }
 
5896
 
 
5897
                set_xnest_parent_stuff ();
 
5898
 
 
5899
                /* some env for use with the Pre and Post scripts */
 
5900
                x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
 
5901
                                                    d->name, ".Xservers");
 
5902
                g_setenv ("X_SERVERS", x_servers_file, TRUE);
 
5903
                g_free (x_servers_file);
 
5904
                if (SERVER_IS_XDMCP (d))
 
5905
                        g_setenv ("REMOTE_HOST", d->hostname, TRUE);
 
5906
 
 
5907
                /* Runs as root */
 
5908
                if (GDM_AUTHFILE (d) != NULL)
 
5909
                        g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
 
5910
                else
 
5911
                        g_unsetenv ("XAUTHORITY");
 
5912
                g_setenv ("DISPLAY", d->name, TRUE);
 
5913
                if (d->windowpath)
 
5914
                        g_setenv ("WINDOWPATH", d->windowpath, TRUE);
 
5915
                g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
 
5916
                g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
 
5917
                if ( ! ve_string_empty (d->theme_name))
 
5918
                        g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
 
5919
 
 
5920
#ifdef HAVE_CTRUN
 
5921
                ctrun = g_strdup_printf (
 
5922
                        "/bin/sh -c \"/usr/bin/ctrun -l child -i none %s\"",
 
5923
                        script);
 
5924
                g_shell_parse_argv (ctrun, NULL, &argv, NULL);
 
5925
                g_free (ctrun);
 
5926
#else
 
5927
                g_shell_parse_argv (script, NULL, &argv, NULL);
 
5928
#endif
 
5929
 
 
5930
                VE_IGNORE_EINTR (execv (argv[0], argv));
 
5931
                g_strfreev (argv);
 
5932
                g_error (_("%s: Failed starting: %s"),
 
5933
                         "gdm_slave_exec_script",
 
5934
                         script);
 
5935
                _exit (EXIT_SUCCESS);
 
5936
 
 
5937
        case -1:
 
5938
                gdm_slave_whack_temp_auth_file ();
 
5939
                g_free (script);
 
5940
                g_error (_("%s: Can't fork script process!"), "gdm_slave_exec_script");
 
5941
                return EXIT_SUCCESS;
 
5942
 
 
5943
        default:
 
5944
                gdm_wait_for_extra (extra_process, &status);
 
5945
 
 
5946
                gdm_slave_whack_temp_auth_file ();
 
5947
 
 
5948
                g_free (script);
 
5949
 
 
5950
                if (WIFEXITED (status))
 
5951
                        return WEXITSTATUS (status);
 
5952
                else
 
5953
                        return EXIT_SUCCESS;
 
5954
        }
5322
5955
}
5323
5956
 
5324
5957
gboolean
5344
5977
        return TRUE;
5345
5978
}
5346
5979
 
5347
 
/* The user name for automatic/timed login may be parameterized by 
 
5980
/* The user name for automatic/timed login may be parameterized by
5348
5981
   host/display. */
5349
5982
 
5350
5983
static gchar *
5351
 
gdm_parse_enriched_login (const gchar *s, GdmDisplay *display)
 
5984
gdm_slave_parse_enriched_login (GdmDisplay *d, const gchar *s)
5352
5985
{
5353
 
    gchar cmd, in_buffer[20];
5354
 
    GString *str;
5355
 
    gint pipe1[2], in_buffer_len;  
5356
 
    gchar **argv;
5357
 
    pid_t pid;
5358
 
 
5359
 
    if (s == NULL)
5360
 
        return (NULL);
5361
 
 
5362
 
    str = g_string_new (NULL);
5363
 
 
5364
 
    while (s[0] != '\0') {
5365
 
 
5366
 
        if (s[0] == '%' && s[1] != 0) {
5367
 
                cmd = s[1];
5368
 
                s++;
5369
 
 
5370
 
                switch (cmd) {
5371
 
 
5372
 
                case 'h': 
5373
 
                        g_string_append (str, display->hostname);
5374
 
                        break;
5375
 
 
5376
 
                case 'd': 
5377
 
                        g_string_append (str, display->name);
5378
 
                        break;
5379
 
 
5380
 
                case '%':
5381
 
                        g_string_append_c (str, '%');
5382
 
                        break;
5383
 
 
5384
 
                default:
5385
 
                        break;
5386
 
                };
5387
 
        } else {
5388
 
                g_string_append_c (str, *s);
 
5986
        GString *str;
 
5987
        gchar in_buffer[20];
 
5988
        gint pipe1[2], in_buffer_len;
 
5989
        gchar **argv = NULL;
 
5990
        pid_t pid;
 
5991
 
 
5992
        if (s == NULL)
 
5993
                return (NULL);
 
5994
 
 
5995
        str = gdm_slave_parse_enriched_string (d, s);
 
5996
 
 
5997
        /* Sometimes it is not convenient to use the display or hostname as
 
5998
           user name. A script may be used to generate the automatic/timed
 
5999
           login name based on the display/host by ending the name with the
 
6000
           pipe symbol '|'. */
 
6001
 
 
6002
        if (str->len > 0 && str->str[str->len - 1] == '|') {
 
6003
                g_string_truncate (str, str->len - 1);
 
6004
                if G_UNLIKELY (pipe (pipe1) < 0) {
 
6005
                        gdm_error (_("%s: Failed creating pipe"),
 
6006
                                   "gdm_slave_parse_enriched_login");
 
6007
                } else {
 
6008
                        gdm_debug ("Forking extra process: %s", str->str);
 
6009
 
 
6010
                        extra_process = pid = gdm_fork_extra ();
 
6011
 
 
6012
                        switch (pid) {
 
6013
                        case 0:
 
6014
                                /* The child will write the username to stdout based on the DISPLAY
 
6015
                                   environment variable. */
 
6016
 
 
6017
                                VE_IGNORE_EINTR (close (pipe1[0]));
 
6018
                                if G_LIKELY (pipe1[1] != STDOUT_FILENO)  {
 
6019
                                        VE_IGNORE_EINTR (dup2 (pipe1[1], STDOUT_FILENO));
 
6020
                                }
 
6021
 
 
6022
                                gdm_log_shutdown ();
 
6023
 
 
6024
                                gdm_close_all_descriptors (3 /* from */, pipe1[1] /* except */, -1 /* except2 */);
 
6025
 
 
6026
                                gdm_log_init ();
 
6027
 
 
6028
                                /* runs as root */
 
6029
                                if (GDM_AUTHFILE (d) != NULL)
 
6030
                                        g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
 
6031
                                else
 
6032
                                        g_unsetenv ("XAUTHORITY");
 
6033
                                g_setenv ("DISPLAY", d->name, TRUE);
 
6034
                                if (d->windowpath)
 
6035
                                        g_setenv ("WINDOWPATH", d->windowpath, TRUE);
 
6036
                                if (SERVER_IS_XDMCP (d))
 
6037
                                        g_setenv ("REMOTE_HOST", d->hostname, TRUE);
 
6038
                                g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
 
6039
                                g_setenv ("SHELL", "/bin/sh", TRUE);
 
6040
                                g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
 
6041
                                if ( ! ve_string_empty (d->theme_name))
 
6042
                                        g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
 
6043
 
 
6044
                                g_shell_parse_argv (str->str, NULL, &argv, NULL);
 
6045
 
 
6046
                                VE_IGNORE_EINTR (execv (argv[0], argv));
 
6047
                                g_strfreev (argv);
 
6048
                                gdm_error (_("%s: Failed executing: %s"),
 
6049
                                           "gdm_slave_parse_enriched_login",
 
6050
                                           str->str);
 
6051
                                _exit (EXIT_SUCCESS);
 
6052
 
 
6053
                        case -1:
 
6054
                                gdm_error (_("%s: Can't fork script process!"),
 
6055
                                           "gdm_slave_parse_enriched_login");
 
6056
                                VE_IGNORE_EINTR (close (pipe1[0]));
 
6057
                                VE_IGNORE_EINTR (close (pipe1[1]));
 
6058
                                break;
 
6059
 
 
6060
                        default:
 
6061
                                /* The parent reads username from the pipe a chunk at a time */
 
6062
                                VE_IGNORE_EINTR (close (pipe1[1]));
 
6063
                                g_string_truncate (str, 0);
 
6064
                                do {
 
6065
                                        VE_IGNORE_EINTR (in_buffer_len = read (pipe1[0], in_buffer,
 
6066
                                                                               sizeof (in_buffer) - 1));
 
6067
                                        if (in_buffer_len > 0) {
 
6068
                                                in_buffer[in_buffer_len] = '\0';
 
6069
                                                g_string_append (str, in_buffer);
 
6070
                                        }
 
6071
                                } while (in_buffer_len > 0);
 
6072
 
 
6073
                                if (str->len > 0 && str->str[str->len - 1] == '\n')
 
6074
                                        g_string_truncate (str, str->len - 1);
 
6075
 
 
6076
                                VE_IGNORE_EINTR (close (pipe1[0]));
 
6077
 
 
6078
                                gdm_wait_for_extra (extra_process, NULL);
 
6079
                        }
 
6080
                }
5389
6081
        }
5390
 
        s++;
5391
 
    }
5392
 
 
5393
 
    /* Sometimes it is not convenient to use the display or hostname as
5394
 
       user name. A script may be used to generate the automatic/timed
5395
 
       login name based on the display/host by ending the name with the
5396
 
       pipe symbol '|'. */
5397
 
 
5398
 
    if (str->len > 0 && str->str[str->len - 1] == '|') {
5399
 
      g_string_truncate (str, str->len - 1);
5400
 
      if G_UNLIKELY (pipe (pipe1) < 0) {
5401
 
        gdm_error (_("%s: Failed creating pipe"),
5402
 
                   "gdm_parse_enriched_login");
5403
 
      } else {
5404
 
        pid = gdm_fork_extra ();
5405
 
 
5406
 
        switch (pid) {
5407
 
            
5408
 
        case 0:
5409
 
            /* The child will write the username to stdout based on the DISPLAY
5410
 
               environment variable. */
5411
 
 
5412
 
            VE_IGNORE_EINTR (close (pipe1[0]));
5413
 
            if G_LIKELY (pipe1[1] != STDOUT_FILENO)  {
5414
 
              VE_IGNORE_EINTR (dup2 (pipe1[1], STDOUT_FILENO));
5415
 
            }
5416
 
 
5417
 
            closelog ();
5418
 
 
5419
 
            gdm_close_all_descriptors (3 /* from */, pipe1[1] /* except */, -1 /* except2 */);
5420
 
 
5421
 
            openlog ("gdm", LOG_PID, LOG_DAEMON);
5422
 
 
5423
 
            /* runs as root */
5424
 
            if (GDM_AUTHFILE (display) != NULL)
5425
 
                    g_setenv ("XAUTHORITY", GDM_AUTHFILE (display), TRUE);
5426
 
            else
5427
 
                    g_unsetenv ("XAUTHORITY");
5428
 
            g_setenv ("DISPLAY", display->name, TRUE);
5429
 
            if (SERVER_IS_XDMCP (display))
5430
 
                    g_setenv ("REMOTE_HOST", display->hostname, TRUE);
5431
 
            g_setenv ("PATH", gdm_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
5432
 
            g_setenv ("SHELL", "/bin/sh", TRUE);
5433
 
            g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
5434
 
            if ( ! ve_string_empty (d->theme_name))
5435
 
                    g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
5436
 
 
5437
 
            argv = ve_split (str->str);
5438
 
            VE_IGNORE_EINTR (execv (argv[0], argv));
5439
 
            gdm_error (_("%s: Failed executing: %s"),
5440
 
                       "gdm_parse_enriched_login",
5441
 
                       str->str);
5442
 
            _exit (EXIT_SUCCESS);
5443
 
            
5444
 
        case -1:
5445
 
            gdm_error (_("%s: Can't fork script process!"),
5446
 
                       "gdm_parse_enriched_login");
5447
 
            VE_IGNORE_EINTR (close (pipe1[0]));
5448
 
            VE_IGNORE_EINTR (close (pipe1[1]));
5449
 
            break;
5450
 
        
5451
 
        default:
5452
 
            /* The parent reads username from the pipe a chunk at a time */
5453
 
            VE_IGNORE_EINTR (close (pipe1[1]));
5454
 
            g_string_truncate (str, 0);
5455
 
            do {
5456
 
                    VE_IGNORE_EINTR (in_buffer_len = read (pipe1[0], in_buffer,
5457
 
                                                        sizeof (in_buffer) - 1));
5458
 
                    if (in_buffer_len > 0) {
5459
 
                            in_buffer[in_buffer_len] = '\0';
5460
 
                            g_string_append (str, in_buffer);
5461
 
                    }
5462
 
            } while (in_buffer_len > 0);
5463
 
 
5464
 
            if (str->len > 0 && str->str[str->len - 1] == '\n')
5465
 
              g_string_truncate (str, str->len - 1);
5466
 
 
5467
 
            VE_IGNORE_EINTR (close (pipe1[0]));
5468
 
 
5469
 
            gdm_wait_for_extra (NULL);
5470
 
        }
5471
 
      }
5472
 
    }
5473
 
 
5474
 
    if (!ve_string_empty(str->str) && gdm_is_user_valid(str->str))
5475
 
            return g_string_free (str, FALSE);
5476
 
    else
5477
 
    {
5478
 
        /* "If an empty or otherwise invalid username is returned [by the script]
5479
 
         *  automatic login [and timed login] is not performed." -- GDM manual 
5480
 
         */
5481
 
        /* fixme: also turn off automatic login */
5482
 
        gdm_set_value_bool(GDM_KEY_TIMED_LOGIN_ENABLE, FALSE);
5483
 
        d->timed_login_ok = FALSE;
5484
 
        do_timed_login = FALSE;
5485
 
        g_string_free(str, TRUE);
5486
 
        return NULL;
5487
 
    }
 
6082
 
 
6083
        if (!ve_string_empty(str->str) && gdm_is_user_valid(str->str))
 
6084
                return g_string_free (str, FALSE);
 
6085
        else
 
6086
                {
 
6087
                        /* "If an empty or otherwise invalid username is returned [by the script]
 
6088
                         *  automatic login [and timed login] is not performed." -- GDM manual 
 
6089
                         */
 
6090
                        /* fixme: also turn off automatic login */
 
6091
                        gdm_daemon_config_set_value_bool(GDM_KEY_TIMED_LOGIN_ENABLE, FALSE);
 
6092
                        d->timed_login_ok = FALSE;
 
6093
                        do_timed_login = FALSE;
 
6094
                        g_string_free (str, TRUE);
 
6095
                        return NULL;
 
6096
                }
5488
6097
}
5489
6098
 
5490
6099
static void
5495
6104
        gdm_debug ("Handling slave notify: '%s'", msg);
5496
6105
 
5497
6106
        if (sscanf (msg, GDM_NOTIFY_ALLOW_ROOT " %d", &val) == 1) {
5498
 
                gdm_set_value_bool (GDM_KEY_ALLOW_ROOT, val);
 
6107
                gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_ROOT, val);
5499
6108
        } else if (sscanf (msg, GDM_NOTIFY_ALLOW_REMOTE_ROOT " %d", &val) == 1) {
5500
 
                gdm_set_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT, val);
 
6109
                gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT, val);
5501
6110
        } else if (sscanf (msg, GDM_NOTIFY_ALLOW_REMOTE_AUTOLOGIN " %d", &val) == 1) {
5502
 
                gdm_set_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN, val);
 
6111
                gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN, val);
5503
6112
        } else if (sscanf (msg, GDM_NOTIFY_SYSTEM_MENU " %d", &val) == 1) {
5504
 
                gdm_set_value_bool (GDM_KEY_SYSTEM_MENU, val);
 
6113
                gdm_daemon_config_set_value_bool (GDM_KEY_SYSTEM_MENU, val);
5505
6114
                if (d->greetpid > 1)
5506
6115
                        kill (d->greetpid, SIGHUP);
5507
6116
        } else if (sscanf (msg, GDM_NOTIFY_CONFIG_AVAILABLE " %d", &val) == 1) {
5508
 
                gdm_set_value_bool (GDM_KEY_CONFIG_AVAILABLE, val);
 
6117
                gdm_daemon_config_set_value_bool (GDM_KEY_CONFIG_AVAILABLE, val);
5509
6118
                if (d->greetpid > 1)
5510
6119
                        kill (d->greetpid, SIGHUP);
5511
6120
        } else if (sscanf (msg, GDM_NOTIFY_CHOOSER_BUTTON " %d", &val) == 1) {
5512
 
                gdm_set_value_bool (GDM_KEY_CHOOSER_BUTTON, val);
 
6121
                gdm_daemon_config_set_value_bool (GDM_KEY_CHOOSER_BUTTON, val);
5513
6122
                if (d->greetpid > 1)
5514
6123
                        kill (d->greetpid, SIGHUP);
5515
6124
        } else if (sscanf (msg, GDM_NOTIFY_RETRY_DELAY " %d", &val) == 1) {
5516
 
                gdm_set_value_int (GDM_KEY_RETRY_DELAY, val);
 
6125
                gdm_daemon_config_set_value_int (GDM_KEY_RETRY_DELAY, val);
5517
6126
        } else if (sscanf (msg, GDM_NOTIFY_DISALLOW_TCP " %d", &val) == 1) {
5518
 
                gdm_set_value_bool (GDM_KEY_DISALLOW_TCP, val);
 
6127
                gdm_daemon_config_set_value_bool (GDM_KEY_DISALLOW_TCP, val);
5519
6128
                remanage_asap = TRUE;
5520
6129
        } else if (strncmp (msg, GDM_NOTIFY_GREETER " ",
5521
6130
                            strlen (GDM_NOTIFY_GREETER) + 1) == 0) {
5522
 
                gdm_set_value_string (GDM_KEY_GREETER, ((gchar *)&msg[strlen (GDM_NOTIFY_GREETER) + 1]));
 
6131
                gdm_daemon_config_set_value_string (GDM_KEY_GREETER, ((gchar *)&msg[strlen (GDM_NOTIFY_GREETER) + 1]));
5523
6132
 
5524
6133
                if (d->attached) {
5525
6134
                        do_restart_greeter = TRUE;
5535
6144
                                }
5536
6145
                        }
5537
6146
                }
 
6147
        } else if (strncmp (msg, GDM_NOTIFY_CUSTOM_CMD_TEMPLATE,
 
6148
                            strlen (GDM_NOTIFY_CUSTOM_CMD_TEMPLATE)) == 0) {
 
6149
                if (sscanf (msg, GDM_NOTIFY_CUSTOM_CMD_TEMPLATE "%d", &val) == 1) {
 
6150
                        gchar * key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, val);
 
6151
                        /* This assumes that the number of commands is < 100, i.e two digits
 
6152
                           if that is not the case then this will fail */
 
6153
                        gdm_daemon_config_set_value_string (key_string, ((gchar *)&msg[strlen (GDM_NOTIFY_CUSTOM_CMD_TEMPLATE) + 2]));
 
6154
                        g_free(key_string);
 
6155
 
 
6156
                        if (d->attached) {
 
6157
                                do_restart_greeter = TRUE;
 
6158
                                if (restart_greeter_now) {
 
6159
                                        ; /* will get restarted later */
 
6160
                                } else if (d->type == TYPE_STATIC) {
 
6161
                                        /* FIXME: can't handle flexi servers like this
 
6162
                                         * without going all cranky */
 
6163
                                        if ( ! d->logged_in) {
 
6164
                                                gdm_slave_quick_exit (DISPLAY_REMANAGE);
 
6165
                                        } else {
 
6166
                                                remanage_asap = TRUE;
 
6167
                                        }
 
6168
                                }
 
6169
                        }
 
6170
                }
5538
6171
        } else if (strncmp (msg, GDM_NOTIFY_REMOTE_GREETER " ",
5539
6172
                            strlen (GDM_NOTIFY_REMOTE_GREETER) + 1) == 0) {
5540
 
                gdm_set_value_string (GDM_KEY_REMOTE_GREETER,
5541
 
                        (gchar *)(&msg[strlen (GDM_NOTIFY_REMOTE_GREETER) + 1]));
 
6173
                gdm_daemon_config_set_value_string (GDM_KEY_REMOTE_GREETER,
 
6174
                                                    (gchar *)(&msg[strlen (GDM_NOTIFY_REMOTE_GREETER) + 1]));
5542
6175
                if ( ! d->attached) {
5543
6176
                        do_restart_greeter = TRUE;
5544
6177
                        if (restart_greeter_now) {
5571
6204
                }
5572
6205
        } else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FILE " ",
5573
6206
                            strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1) == 0) {
5574
 
                gdm_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE,
5575
 
                        (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1]));
 
6207
                gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE,
 
6208
                                                    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1]));
5576
6209
                if (d->greetpid > 1)
5577
6210
                        kill (d->greetpid, SIGHUP);
5578
6211
        } else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE " ",
5579
6212
                            strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1) == 0) {
5580
 
                gdm_set_value_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE,
5581
 
                        (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1]));
 
6213
                gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE,
 
6214
                                                    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1]));
5582
6215
                if (d->greetpid > 1)
5583
6216
                        kill (d->greetpid, SIGHUP);
5584
6217
        } else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE " ",
5585
6218
                            strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1) == 0) {
5586
 
                gdm_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE,
5587
 
                        (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1]));
 
6219
                gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE,
 
6220
                                                    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1]));
5588
6221
                if (d->greetpid > 1)
5589
6222
                        kill (d->greetpid, SIGHUP);
5590
6223
        } else if (strncmp (msg, GDM_NOTIFY_GTK_MODULES_LIST " ",
5591
6224
                            strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1) == 0) {
5592
 
                gdm_set_value_string (GDM_KEY_GTK_MODULES_LIST,
5593
 
                        (gchar *)(&msg[strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1]));
 
6225
                gdm_daemon_config_set_value_string (GDM_KEY_GTK_MODULES_LIST,
 
6226
                                                    (gchar *)(&msg[strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1]));
5594
6227
 
5595
 
                if (gdm_get_value_bool (GDM_KEY_ADD_GTK_MODULES)) {
 
6228
                if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES)) {
5596
6229
                        do_restart_greeter = TRUE;
5597
6230
                        if (restart_greeter_now) {
5598
6231
                                ; /* will get restarted later */
5607
6240
                        }
5608
6241
                }
5609
6242
        } else if (sscanf (msg, GDM_NOTIFY_ADD_GTK_MODULES " %d", &val) == 1) {
5610
 
                gdm_set_value_bool (GDM_KEY_ADD_GTK_MODULES, val);
 
6243
                gdm_daemon_config_set_value_bool (GDM_KEY_ADD_GTK_MODULES, val);
5611
6244
 
5612
6245
                do_restart_greeter = TRUE;
5613
6246
                if (restart_greeter_now) {
5650
6283
                return FALSE;
5651
6284
 
5652
6285
        freeroles = roles = g_strdup (kva_match (uattr->attr, USERATTR_ROLES_KW));
5653
 
    if (roles == NULL) {
 
6286
        if (roles == NULL) {
5654
6287
                return FALSE;
5655
6288
        }
5656
6289
 
5673
6306
gboolean
5674
6307
gdm_is_user_valid (const char *username)
5675
6308
{
5676
 
    return (NULL != getpwnam (username));
 
6309
        return (NULL != getpwnam (username));
5677
6310
}
5678
 
/* EOF */
 
6311