diff --git a/components/desktop/mate/mate-control-center/Makefile b/components/desktop/mate/mate-control-center/Makefile index e80daea9a37..e98d00b890b 100644 --- a/components/desktop/mate/mate-control-center/Makefile +++ b/components/desktop/mate/mate-control-center/Makefile @@ -18,7 +18,7 @@ include ../../../../make-rules/shared-macros.mk COMPONENT_NAME= mate-control-center COMPONENT_MJR_VERSION= 1.20 COMPONENT_MNR_VERSION= 3 -COMPONENT_REVISION= 1 +COMPONENT_REVISION= 2 COMPONENT_VERSION= $(COMPONENT_MJR_VERSION).$(COMPONENT_MNR_VERSION) COMPONENT_PROJECT_URL= http://www.mate-desktop.org COMPONENT_SUMMARY= MATE desktop wide preference configuration tools diff --git a/components/desktop/mate/mate-control-center/patches/04-passwd-pty.patch b/components/desktop/mate/mate-control-center/patches/04-passwd-pty.patch new file mode 100644 index 00000000000..9395fb5415a --- /dev/null +++ b/components/desktop/mate/mate-control-center/patches/04-passwd-pty.patch @@ -0,0 +1,295 @@ +diff --git a/capplets/about-me/mate-about-me-password.c b/capplets/about-me/mate-about-me-password.c +index abac117..5a82566 100644 +--- a/capplets/about-me/mate-about-me-password.c ++++ b/capplets/about-me/mate-about-me-password.c +@@ -27,6 +27,14 @@ + # include + #endif + ++/* This is needed to get ptmx-related functions in GLIBC */ ++#ifndef _XOPEN_SOURCE ++#define _XOPEN_SOURCE 600 ++#endif ++ ++/* This is needed to get pipe2() in GLIBC */ ++#define _GNU_SOURCE ++ + /* Are all of these needed? */ + #include + #include +@@ -35,6 +43,16 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++ ++#define PASSWD "/usr/bin/passwd" ++#define PTMX "/dev/ptmx" ++ ++/* /dev/pts/N */ ++#define PTY_MAX_NAME 20 + + #if __sun + #include +@@ -85,6 +103,9 @@ typedef struct { + /* Buffer size for backend output */ + #define BUFSIZE 64 + ++/* Bufffer size for backend error messages */ ++#define ERRBUFSIZE 1024 ++ + /* + * Error handling {{ + */ +@@ -170,85 +191,178 @@ static gboolean + spawn_passwd (PasswordDialog *pdialog, GError **error) + { + gchar *argv[2]; +- gchar *envp[1]; +- gint my_stdin, my_stdout, my_stderr; ++ int pid, pty_m, err_pipe[2]; ++ char slave_name[PTY_MAX_NAME]; ++ char *name; + +- argv[0] = "/usr/bin/passwd"; /* Is it safe to rely on a hard-coded path? */ ++ argv[0] = PASSWD; /* Is it safe to rely on a hard-coded path? */ + argv[1] = NULL; + +- envp[0] = NULL; /* If we pass an empty array as the environment, +- * will the childs environment be empty, and the +- * locales set to the C default? From the manual: +- * "If envp is NULL, the child inherits its +- * parent'senvironment." +- * If I'm wrong here, we somehow have to set +- * the locales here. +- */ +- +- if (!g_spawn_async_with_pipes (NULL, /* Working directory */ +- argv, /* Argument vector */ +- envp, /* Environment */ +- G_SPAWN_DO_NOT_REAP_CHILD, /* Flags */ +- NULL, /* Child setup */ +- NULL, /* Data to child setup */ +- &pdialog->backend_pid, /* PID */ +- &my_stdin, /* Stdin */ +- &my_stdout, /* Stdout */ +- &my_stderr, /* Stderr */ +- error)) { /* GError */ +- +- /* An error occurred */ +- free_passwd_resources (pdialog); +- ++ pty_m = open(PTMX, O_RDWR|O_NOCTTY); ++ if (pty_m > 0) { ++ name = ptsname(pty_m); ++ if (name && (strlen(name) < PTY_MAX_NAME)) { ++ strncpy(slave_name, name, PTY_MAX_NAME); ++ } else { ++ g_set_error(error, ++ PASSDLG_ERROR, ++ PASSDLG_ERROR_BACKEND, ++ _("Couldn't get slave_name of pty")); ++ close(pty_m); ++ return FALSE; ++ } ++ } else { ++ g_set_error (error, ++ PASSDLG_ERROR, ++ PASSDLG_ERROR_BACKEND, ++ _("Couldn't open pseudo-tty")); + return FALSE; + } + +- /* 2>&1 */ +- if (dup2 (my_stderr, my_stdout) == -1) { +- /* Failed! */ ++ if (grantpt(pty_m) < 0) { + g_set_error (error, +- PASSDLG_ERROR, +- PASSDLG_ERROR_BACKEND, +- "%s", +- strerror (errno)); +- +- /* Clean up */ +- stop_passwd (pdialog); +- ++ PASSDLG_ERROR, ++ PASSDLG_ERROR_BACKEND, ++ _("Couldn't set permission on slave device: %s"), ++ strerror(errno)); ++ close(pty_m); + return FALSE; + } + +- /* Open IO Channels */ +- pdialog->backend_stdin = g_io_channel_unix_new (my_stdin); +- pdialog->backend_stdout = g_io_channel_unix_new (my_stdout); +- +- /* Set raw encoding */ +- /* Set nonblocking mode */ +- if (g_io_channel_set_encoding (pdialog->backend_stdin, NULL, error) != G_IO_STATUS_NORMAL || +- g_io_channel_set_encoding (pdialog->backend_stdout, NULL, error) != G_IO_STATUS_NORMAL || +- g_io_channel_set_flags (pdialog->backend_stdin, G_IO_FLAG_NONBLOCK, error) != G_IO_STATUS_NORMAL || +- g_io_channel_set_flags (pdialog->backend_stdout, G_IO_FLAG_NONBLOCK, error) != G_IO_STATUS_NORMAL ) { ++ if (unlockpt(pty_m) < 0) { ++ g_set_error (error, ++ PASSDLG_ERROR, ++ PASSDLG_ERROR_BACKEND, ++ _("Couldn't unlock slave device: %s"), ++ strerror(errno)); ++ close(pty_m); ++ return FALSE; ++ } + +- /* Clean up */ +- stop_passwd (pdialog); ++ if (pipe2(err_pipe, O_CLOEXEC) < 0) { ++ g_set_error (error, ++ PASSDLG_ERROR, ++ PASSDLG_ERROR_BACKEND, ++ _("Couldn't create error reporting pipe: %s"), ++ strerror(errno)); ++ close(pty_m); + return FALSE; + } ++ ++ pid = fork(); ++ if (pid == 0) { ++ /* Child */ ++ int pty_s, len; ++ char buf[ERRBUFSIZE]; ++ close(err_pipe[0]); ++ ++ close(pty_m); ++ if (setsid() < 0) { ++ len = snprintf(buf, ERRBUFSIZE, _("Couldn't create new process group: %s"), strerror(errno)); ++ write(err_pipe[1], buf, (len>ERRBUFSIZE) ? ERRBUFSIZE : len ); ++ exit(1); ++ } + +- /* Turn off buffering */ +- g_io_channel_set_buffered (pdialog->backend_stdin, FALSE); +- g_io_channel_set_buffered (pdialog->backend_stdout, FALSE); ++ /* Now we are a session leader, on System V first open tty will become controlling tty */ ++ pty_s = open(slave_name, O_RDWR); + +- /* Add IO Channel watcher */ +- pdialog->backend_stdout_watch_id = g_io_add_watch (pdialog->backend_stdout, +- G_IO_IN | G_IO_PRI, +- (GIOFunc) io_watch_stdout, pdialog); ++ if (pty_s < 0) { ++ len = snprintf(buf, ERRBUFSIZE, _("Couldn't open slave terminal device: %s"), strerror(errno)); ++ write(err_pipe[1], buf, (len>ERRBUFSIZE) ? ERRBUFSIZE : len ); ++ exit(1); ++ } ++ ++#if defined(TIOCSCTTY) && !defined(__sun) ++ /* BSD systems need to set controlling tty explicitly. Solaris/illumos can export ++ TIOCSCTTY when __EXTENSIONS__ are defined, but doesn't need this. */ ++ if (ioctl(pty_s,TIOCSCTTY, NULL) < 0) { ++ close(pty_s); ++ len=snprintf(buf, ERRBUFSIZE, _("Couldn't establish controlling terminal: %s"), strerror(errno)); ++ write(err_pipe[1], buf, (len>ERRBUFSIZE) ? ERRBUFSIZE : len ); ++ exit(1); ++ } ++#endif ++ ++ /* Set stdin, stdout, stderr to our tty */ ++ dup2(pty_s, 0); ++ dup2(pty_s, 1); ++ dup2(pty_s, 2); ++ ++ execvp(argv[0], argv); ++ ++ /* Error */ ++ close(pty_s); ++ len=snprintf(buf, ERRBUFSIZE, _("Couldn't exec passwd: %s"), strerror(errno)); ++ write(err_pipe[1], buf, (len>ERRBUFSIZE) ? ERRBUFSIZE : len ); ++ exit(1); ++ } else if (pid > 0) { ++ int rb, pos = 0; ++ char buf[ERRBUFSIZE]; ++ ++ ++ close(err_pipe[1]); ++ /* Wait for child to run exec() and read possible error message */ ++ while (pos < ERRBUFSIZE - 1 && ((rb=read(err_pipe[0], &buf[pos], ERRBUFSIZE-1-pos)) > 0)) { ++ pos += rb; ++ } ++ close(err_pipe[0]); ++ if (pos > 0) { ++ /* There were messages in err_pipe */ ++ buf[pos+1] = '\0'; ++ g_set_error (error, ++ PASSDLG_ERROR, ++ PASSDLG_ERROR_BACKEND, ++ buf); ++ ++ stop_passwd(pdialog); ++ return FALSE; ++ } ++ ++ /* Open IO Channels */ ++ pdialog->backend_stdin = g_io_channel_unix_new (pty_m); ++ /* g_io_channel_shutdown(pdialog->backend_stdin) will close associated file descriptor (pty_m), ++ but this will generate warning on g_io_channel_shutdown(pdialog->backend_stdout). ++ To avoid it, dup() file descriptor */ ++ pdialog->backend_stdout = g_io_channel_unix_new (dup(pty_m)); ++ pdialog->backend_pid = pid; ++ ++ /* Set raw encoding */ ++ /* Set nonblocking mode */ ++ if (g_io_channel_set_encoding (pdialog->backend_stdin, NULL, error) != G_IO_STATUS_NORMAL || ++ g_io_channel_set_encoding (pdialog->backend_stdout, NULL, error) != G_IO_STATUS_NORMAL || ++ g_io_channel_set_flags (pdialog->backend_stdin, G_IO_FLAG_NONBLOCK, error) != G_IO_STATUS_NORMAL || ++ g_io_channel_set_flags (pdialog->backend_stdout, G_IO_FLAG_NONBLOCK, error) != G_IO_STATUS_NORMAL ) { ++ ++ /* Clean up */ ++ stop_passwd (pdialog); ++ return FALSE; ++ } + +- /* Add child watcher */ +- pdialog->backend_child_watch_id = g_child_watch_add (pdialog->backend_pid, (GChildWatchFunc) child_watch_cb, pdialog); ++ /* Turn off buffering */ ++ g_io_channel_set_buffered (pdialog->backend_stdin, FALSE); ++ g_io_channel_set_buffered (pdialog->backend_stdout, FALSE); + +- /* Success! */ ++ /* Add IO Channel watcher */ ++ pdialog->backend_stdout_watch_id = g_io_add_watch (pdialog->backend_stdout, ++ G_IO_IN | G_IO_PRI, ++ (GIOFunc) io_watch_stdout, pdialog); ++ ++ /* Add child watcher */ ++ pdialog->backend_child_watch_id = g_child_watch_add (pdialog->backend_pid, (GChildWatchFunc) child_watch_cb, pdialog); + +- return TRUE; ++ /* Success! */ ++ ++ return TRUE; ++ } else { ++ /* Error */ ++ g_set_error(error, ++ PASSDLG_ERROR, ++ PASSDLG_ERROR_BACKEND, ++ _("Couldn't fork: %s"), ++ strerror(errno)); ++ close(pty_m); ++ return FALSE; ++ } + } + + /* Stop passwd backend */ +@@ -822,7 +936,7 @@ passdlg_spawn_passwd (PasswordDialog *pdialog) + + /* translators: Unable to launch : */ + details = g_strdup_printf (_("Unable to launch %s: %s"), +- "/usr/bin/passwd", error->message); ++ PASSWD, error->message); + + passdlg_error_dialog (GTK_WINDOW (parent), + _("Unable to launch backend"), diff --git a/components/desktop/mate/mate-control-center/patches/05-additional-pam-errors.patch b/components/desktop/mate/mate-control-center/patches/05-additional-pam-errors.patch new file mode 100644 index 00000000000..b7efad6b6ff --- /dev/null +++ b/components/desktop/mate/mate-control-center/patches/05-additional-pam-errors.patch @@ -0,0 +1,32 @@ +--- mate-control-center-1.20.3/capplets/about-me/mate-about-me-password.c.~2~ 2018-11-08 15:25:28.053932491 +0000 ++++ mate-control-center-1.20.3/capplets/about-me/mate-about-me-password.c 2018-11-08 15:31:15.902591210 +0000 +@@ -562,6 +564,11 @@ + "match", + "1 numeric or special", + "failure", ++ "must contain", ++ "must differ", ++ "are not allowed", ++ "repeating characters", ++ "history", + NULL)) { + + /* What response did we get? */ +@@ -586,12 +593,17 @@ + g_strrstr (str->str, "longer") != NULL) { + msg = g_strdup (_("The password is too short.")); + } else if (g_strrstr (str->str, "palindrome") != NULL || ++ g_strrstr (str->str, "must contain") != NULL || ++ g_strrstr (str->str, "are not allowed") != NULL || ++ g_strrstr (str->str, "repeating characters") != NULL || ++ g_strrstr (str->str, "history") != NULL || + g_strrstr (str->str, "simpl") != NULL || + g_strrstr (str->str, "dictionary") != NULL) { + msg = g_strdup (_("The password is too simple.")); + } else if (g_strrstr (str->str, "similar") != NULL || + g_strrstr (str->str, "different") != NULL || + g_strrstr (str->str, "case") != NULL || ++ g_strrstr (str->str, "must differ") != NULL || + g_strrstr (str->str, "wrapped") != NULL) { + msg = g_strdup (_("The old and new passwords are too similar.")); + } else if (g_strrstr (str->str, "1 numeric or special") != NULL) { diff --git a/components/desktop/mate/mate-control-center/patches/06-dont-crash-on-EOF.patch b/components/desktop/mate/mate-control-center/patches/06-dont-crash-on-EOF.patch new file mode 100644 index 00000000000..9282d3ae398 --- /dev/null +++ b/components/desktop/mate/mate-control-center/patches/06-dont-crash-on-EOF.patch @@ -0,0 +1,15 @@ +--- mate-control-center-1.20.3/capplets/about-me/mate-about-me-password.c.~4~ 2018-11-13 23:22:52.988738173 +0000 ++++ mate-control-center-1.20.3/capplets/about-me/mate-about-me-password.c 2018-11-13 23:30:47.042446380 +0000 +@@ -550,8 +550,10 @@ + } + + if (g_io_channel_read_chars (source, buf, BUFSIZE, &bytes_read, &error) != G_IO_STATUS_NORMAL) { +- g_warning ("IO Channel read error: %s", error->message); +- g_error_free (error); ++ if (error) { ++ g_warning ("IO Channel read error: %s", error->message); ++ g_error_free (error); ++ } + + return TRUE; + }