# HG changeset patch # Parent 3c70b85155564f1cfad8dd5e44a34a752997141a add scripting hooks for compatibility with xdm/gdm diff --git a/data/lightdm.conf b/data/lightdm.conf --- a/data/lightdm.conf +++ b/data/lightdm.conf @@ -41,6 +41,9 @@ user-authority-in-system-dir=true # allow-guest = True if guest login is allowed # guest-session = Session to load for guests (overrides user-session) # session-wrapper = Wrapper script to run session with +# greeter-startup-script = Script to run when starting a greeter session (runs as root) +# session-startup-script = Script to run when starting a user session (runs as root) +# session-reset-script = Script to run when quitting a user session (runs as root) # autologin-guest = True to log in as guest by default # autologin-user = User to log in with by default (overrides autologin-guest) # autologin-user-timeout = Number of seconds to wait before loading default user diff --git a/src/display.c b/src/display.c --- a/src/display.c +++ b/src/display.c @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include #include #include "display.h" @@ -63,6 +66,15 @@ struct DisplayPrivate /* Program to run sessions through */ gchar *session_wrapper; + /* Script to run when starting the greeter */ + gchar *greeter_startup_script; + + /* Script to run when starting a user session */ + gchar *session_startup_script; + + /* Script to run when quitting a user session */ + gchar *session_reset_script; + /* PAM service to authenticate against */ gchar *pam_service; @@ -162,6 +174,30 @@ display_set_session_wrapper (Display *di } void +display_set_greeter_startup_script (Display *display, const gchar *greeter_startup_script) +{ + g_return_if_fail (display != NULL); + g_free (display->priv->greeter_startup_script); + display->priv->greeter_startup_script = g_strdup (greeter_startup_script); +} + +void +display_set_session_startup_script (Display *display, const gchar *session_startup_script) +{ + g_return_if_fail (display != NULL); + g_free (display->priv->session_startup_script); + display->priv->session_startup_script = g_strdup (session_startup_script); +} + +void +display_set_session_reset_script (Display *display, const gchar *session_reset_script) +{ + g_return_if_fail (display != NULL); + g_free (display->priv->session_reset_script); + display->priv->session_reset_script = g_strdup (session_reset_script); +} + +void display_set_allow_guest (Display *display, gboolean allow_guest) { g_return_if_fail (display != NULL); @@ -226,6 +262,103 @@ get_guest_username (Display *display) return username; } +static gboolean +run_script (Display *display, const gchar *script_name, const gchar *username) +{ + GPtrArray *env_array; + struct passwd *pw; + gchar **argv; + gchar **envp; + gchar *hostname, *xauthority_path, *env, *command; + gint exit_status; + GError *error = NULL; + + if (getuid () != 0) + return TRUE; + + if (!(g_file_test (script_name, G_FILE_TEST_IS_REGULAR) && + g_file_test (script_name, G_FILE_TEST_IS_EXECUTABLE))) + { + g_warning ("Could not execute %s", script_name); + return FALSE; + } + + if (!g_shell_parse_argv (script_name, NULL, &argv, &error)) { + g_warning ("Could not parse %s: %s", script_name, error->message); + g_error_free (error); + return FALSE; + } + + env_array = g_ptr_array_sized_new (10); + if (!env_array) + return FALSE; + + g_ptr_array_add (env_array, g_strdup ("SHELL=/bin/sh")); + g_ptr_array_add (env_array, g_strdup ("PATH=/usr/local/bin:/usr/bin:/bin")); + + if (username && (pw = getpwnam (username))) + { + gchar *dir = (pw->pw_dir && *pw->pw_dir != '\0') ? pw->pw_dir : "/"; + + g_ptr_array_add (env_array, g_strdup_printf ("USER=%s", username)); + g_ptr_array_add (env_array, g_strdup_printf ("USERNAME=%s", username)); + g_ptr_array_add (env_array, g_strdup_printf ("LOGNAME=%s", username)); + g_ptr_array_add (env_array, g_strdup_printf ("HOME=%s", dir)); + } + else + { + g_ptr_array_add (env_array, g_strdup ("HOME=/")); + } + + g_ptr_array_add (env_array, g_strdup_printf ("DISPLAY=%s", xserver_get_address (XSERVER (display->priv->display_server)))); + + if (!IS_XSERVER_LOCAL (display->priv->display_server) && + (hostname = xserver_get_hostname (XSERVER (display->priv->display_server)))) + { + g_ptr_array_add (env_array, g_strdup_printf ("REMOTE_HOST=%s", hostname)); + g_free (hostname); + } + + if (IS_XSERVER_LOCAL (display->priv->display_server) && + (xauthority_path = xserver_local_get_authority_file_path (XSERVER (display->priv->display_server)))) + { + g_ptr_array_add (env_array, g_strdup_printf ("XAUTHORITY=%s", xauthority_path)); + g_free (xauthority_path); + } + + g_ptr_array_add (env_array, NULL); + envp = (gchar **) g_ptr_array_free (env_array, FALSE); + + env = g_strjoinv (" ", envp); + command = g_strjoin (" ", env, script_name, NULL); + g_debug ("Executing script: %s", command); + g_free (env); + g_free (command); + if (!g_spawn_sync (NULL, + argv, + envp, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + NULL, + &exit_status, + &error)) + { + g_warning ("Error executing %s: %s", script_name, error->message); + g_error_free (error); + } + g_strfreev (argv); + g_strfreev (envp); + + if (WIFEXITED (exit_status)) { + g_debug ("Exit status of %s: %d", script_name, WEXITSTATUS (exit_status)); + return WEXITSTATUS (exit_status) == EXIT_SUCCESS; + } + + return FALSE; +} + static gchar * start_ck_session (Display *display, const gchar *session_type, User *user) { @@ -523,6 +656,9 @@ user_session_stopped_cb (Session *sessio { g_debug ("User session quit"); + if (display->priv->session_reset_script) + run_script (display, display->priv->session_reset_script, user_get_name (pam_session_get_user (session_get_authentication (session)))); + g_signal_emit (display, signals[SESSION_STOPPED], 0); if (cleanup_after_session (display)) @@ -742,6 +878,9 @@ start_greeter_session (Display *display) greeter_set_hint (display->priv->greeter, "has-guest-account", display->priv->allow_guest ? "true" : "false"); greeter_set_hint (display->priv->greeter, "hide-users", display->priv->greeter_hide_users ? "true" : "false"); + if (display->priv->greeter_startup_script) + run_script (display, display->priv->greeter_startup_script, NULL); + result = greeter_start (display->priv->greeter); if (result) { @@ -793,6 +932,9 @@ start_user_session (Display *display, PA display->priv->session = create_session (display, authentication, display->priv->user_session, FALSE, log_filename); g_free (log_filename); + if (display->priv->session_startup_script) + run_script (display, display->priv->session_startup_script, user_get_name (user)); + if (display->priv->session) { g_signal_emit (display, signals[SESSION_CREATED], 0, display->priv->session); @@ -1025,6 +1167,9 @@ display_finalize (GObject *object) if (self->priv->greeter) g_object_unref (self->priv->greeter); g_free (self->priv->session_wrapper); + g_free (self->priv->greeter_startup_script); + g_free (self->priv->session_startup_script); + g_free (self->priv->session_reset_script); g_free (self->priv->pam_service); g_free (self->priv->pam_autologin_service); if (self->priv->session) diff --git a/src/display.h b/src/display.h --- a/src/display.h +++ b/src/display.h @@ -64,6 +64,12 @@ void display_set_greeter_session (Displa void display_set_session_wrapper (Display *display, const gchar *session_wrapper); +void display_set_xserver_startup_script (Display *display, const gchar *xserver_startup_script); + +void display_set_session_startup_script (Display *display, const gchar *session_startup_script); + +void display_set_session_reset_script (Display *display, const gchar *session_reset_script); + void display_set_allow_guest (Display *display, gboolean allow_guest); void display_set_autologin_user (Display *display, const gchar *username, gboolean is_guest, gint timeout); diff --git a/src/seat.c b/src/seat.c --- a/src/seat.c +++ b/src/seat.c @@ -329,6 +329,9 @@ switch_to_user_or_start_greeter (Seat *s g_signal_connect (new_display, "stopped", G_CALLBACK (display_stopped_cb), seat); display_set_greeter_session (new_display, seat_get_string_property (seat, "greeter-session")); display_set_session_wrapper (new_display, seat_get_string_property (seat, "session-wrapper")); + display_set_greeter_startup_script (new_display, seat_get_string_property (seat, "greeter-startup-script")); + display_set_session_startup_script (new_display, seat_get_string_property (seat, "session-startup-script")); + display_set_session_reset_script (new_display, seat_get_string_property (seat, "session-reset-script")); display_set_hide_users_hint (new_display, seat_get_boolean_property (seat, "greeter-hide-users")); display_set_allow_guest (new_display, seat_get_allow_guest (seat)); if (autologin) diff --git a/src/xserver-local.c b/src/xserver-local.c --- a/src/xserver-local.c +++ b/src/xserver-local.c @@ -196,6 +196,15 @@ xserver_local_get_vt (XServerLocal *serv return server->priv->vt; } +gchar * +xserver_local_get_authority_file_path (XServerLocal *server) +{ + g_return_val_if_fail (server != NULL, 0); + if (server->priv->authority_file) + return g_file_get_path (server->priv->authority_file); + return NULL; +} + static gchar * get_absolute_command (const gchar *command) { diff --git a/src/xserver-local.h b/src/xserver-local.h --- a/src/xserver-local.h +++ b/src/xserver-local.h @@ -57,6 +57,8 @@ void xserver_local_set_xdmcp_key (XServe gint xserver_local_get_vt (XServerLocal *server); +gchar *xserver_local_get_authority_file_path (XServerLocal *server); + G_END_DECLS #endif /* _XSERVER_LOCAL_H_ */