diff --git a/src/common/fe.h b/src/common/fe.h index 27ea3a26..2790dfa7 100644 --- a/src/common/fe.h +++ b/src/common/fe.h @@ -70,6 +70,9 @@ void fe_add_rawlog (struct server *serv, char *text, int len, int outbound); #define FE_MSG_ERROR 8 #define FE_MSG_MARKUP 16 void fe_message (char *msg, int flags); +#ifdef __linux__ +void fe_root_warning (void); +#endif #define FIA_READ 1 #define FIA_WRITE 2 #define FIA_EX 4 diff --git a/src/common/zoitechat.c b/src/common/zoitechat.c index 16c2a5ed..22d97dc5 100644 --- a/src/common/zoitechat.c +++ b/src/common/zoitechat.c @@ -95,6 +95,7 @@ int zoitechat_is_quitting = FALSE; /* command-line args */ int arg_dont_autoconnect = FALSE; int arg_skip_plugins = FALSE; +gint arg_run_as_root = FALSE; char *arg_url = NULL; char **arg_urls = NULL; char *arg_command = NULL; @@ -1175,6 +1176,25 @@ main (int argc, char *argv[]) HRESULT coinit_result; #endif +#ifdef __linux__ + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "--") == 0) + break; + if (strcmp (argv[i], "--run-as-root") == 0) + { + arg_run_as_root = TRUE; + break; + } + } + + if (geteuid () == 0 && !arg_run_as_root) + { + fe_root_warning (); + return EXIT_FAILURE; + } +#endif + srand ((unsigned int) time (NULL)); /* CL: do this only once! */ /* We must check for the config dir parameter, otherwise load_config() will behave incorrectly. @@ -1263,7 +1283,7 @@ main (int argc, char *argv[]) #ifndef WIN32 #ifndef __EMX__ /* OS/2 uses UID 0 all the time */ - if (getuid () == 0) + if (getuid () == 0 && !arg_run_as_root) fe_message (_("* Running IRC as root is stupid! You should\n" " create a User Account and use that to login.\n"), FE_MSG_WARN|FE_MSG_WAIT); #endif diff --git a/src/common/zoitechatc.h b/src/common/zoitechatc.h index 6cd65eb8..8fb65970 100644 --- a/src/common/zoitechatc.h +++ b/src/common/zoitechatc.h @@ -25,6 +25,7 @@ extern struct zoitechatprefs prefs; extern int zoitechat_is_quitting; extern gint arg_skip_plugins; /* command-line args */ extern gint arg_dont_autoconnect; +extern gint arg_run_as_root; extern char *arg_url; extern char **arg_urls; extern char *arg_command; diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index ff9e21a6..f4d38494 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -90,6 +90,9 @@ static const GOptionEntry gopt_entries[] = {"no-auto", 'a', 0, G_OPTION_ARG_NONE, &arg_dont_autoconnect, N_("Don't auto connect to servers"), NULL}, {"cfgdir", 'd', 0, G_OPTION_ARG_STRING, &arg_cfgdir, N_("Use a different config directory"), "PATH"}, {"no-plugins", 'n', 0, G_OPTION_ARG_NONE, &arg_skip_plugins, N_("Don't auto load any plugins"), NULL}, +#ifdef __linux__ + {"run-as-root", 0, 0, G_OPTION_ARG_NONE, &arg_run_as_root, N_("Allow ZoiteChat to run as root (unsafe)"), NULL}, +#endif {"plugindir", 'p', 0, G_OPTION_ARG_NONE, &arg_show_autoload, N_("Show plugin/script auto-load directory"), NULL}, {"configdir", 'u', 0, G_OPTION_ARG_NONE, &arg_show_config, N_("Show user config directory"), NULL}, {"url", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &arg_url, N_("Open an irc://server:port/channel?key URL"), "URL"}, @@ -103,6 +106,33 @@ static const GOptionEntry gopt_entries[] = {NULL} }; +#ifdef __linux__ +void +fe_root_warning (void) +{ + const char *message = + "ZoiteChat refuses to run as root on Linux.\n\n" + "Run it as a normal user, or pass --run-as-root to override this protection."; + GtkWidget *dialog; + + g_printerr ("%s\n", message); + + /* A graphical session may not be accessible to root, particularly under + * Wayland. Keep stderr as the fallback if GTK cannot open the display. */ + if (!gtk_init_check (NULL, NULL)) + return; + + dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "%s", message); + gtk_window_set_title (GTK_WINDOW (dialog), "ZoiteChat"); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} +#endif + #ifdef WIN32 static void create_msg_dialog (gchar *title, gchar *message) diff --git a/src/fe-text/fe-text.c b/src/fe-text/fe-text.c index 1bc792ba..d6855ce9 100644 --- a/src/fe-text/fe-text.c +++ b/src/fe-text/fe-text.c @@ -467,6 +467,9 @@ static const GOptionEntry gopt_entries[] = {"no-auto", 'a', 0, G_OPTION_ARG_NONE, &arg_dont_autoconnect, N_("Don't auto connect to servers"), NULL}, {"cfgdir", 'd', 0, G_OPTION_ARG_STRING, &arg_cfgdir, N_("Use a different config directory"), "PATH"}, {"no-plugins", 'n', 0, G_OPTION_ARG_NONE, &arg_skip_plugins, N_("Don't auto load any plugins"), NULL}, +#ifdef __linux__ + {"run-as-root", 0, 0, G_OPTION_ARG_NONE, &arg_run_as_root, N_("Allow ZoiteChat to run as root (unsafe)"), NULL}, +#endif {"plugindir", 'p', 0, G_OPTION_ARG_NONE, &arg_show_autoload, N_("Show plugin/script auto-load directory"), NULL}, {"configdir", 'u', 0, G_OPTION_ARG_NONE, &arg_show_config, N_("Show user config directory"), NULL}, {"url", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &arg_url, N_("Open an irc://server:port/channel URL"), "URL"}, @@ -475,6 +478,16 @@ static const GOptionEntry gopt_entries[] = {NULL} }; +#ifdef __linux__ +void +fe_root_warning (void) +{ + fputs ("ZoiteChat refuses to run as root on Linux.\n" + "Run it as a normal user, or pass --run-as-root to override this protection.\n", + stderr); +} +#endif + int fe_args (int argc, char *argv[]) {