Compare commits
10 Commits
5586d9746f
...
1464e2aa89
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1464e2aa89 | ||
|
|
0192cb1539 | ||
|
|
62dbe58826 | ||
|
|
3ca21e680b | ||
|
|
bc4f8f1c9d | ||
|
|
49fcb733f9 | ||
|
|
b9b7bc382e | ||
|
|
3668b34161 | ||
|
|
679adfbd46 | ||
|
|
ff013004bc |
@ -0,0 +1,42 @@
|
|||||||
|
From 817fea974287bdea8686ced43f708531148d98bc Mon Sep 17 00:00:00 2001
|
||||||
|
From: liuxinhao <liuxinhao@kylinos.com.cn>
|
||||||
|
Date: Tue, 25 Jan 2022 15:41:57 +0800
|
||||||
|
Subject: [PATCH] fix(translator): fixed the issue that lightdm's PAM messages
|
||||||
|
were not translated
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
- 修复lightdm返回的PAM消息未经过翻译,并将翻译指定为UTF-8编码,避免lightdm-qt5接口之中乱码问题
|
||||||
|
|
||||||
|
Signed-off-by: liuxinhao <liuxinhao@kylinos.com.cn>
|
||||||
|
---
|
||||||
|
src/lightdm.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/lightdm.c b/src/lightdm.c
|
||||||
|
index 81b9117..2df2f9f 100644
|
||||||
|
--- a/src/lightdm.c
|
||||||
|
+++ b/src/lightdm.c
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
+#include <locale.h>
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "display-manager.h"
|
||||||
|
@@ -551,6 +552,10 @@ main (int argc, char **argv)
|
||||||
|
sigaction (SIGPIPE, &action, NULL);
|
||||||
|
sigaction (SIGHUP, &action, NULL);
|
||||||
|
|
||||||
|
+ setlocale(LC_CTYPE,"");
|
||||||
|
+ setlocale(LC_MESSAGES,"");
|
||||||
|
+ bind_textdomain_codeset("Linux-PAM", "UTF-8");
|
||||||
|
+
|
||||||
|
/* When lightdm starts sessions it needs to run itself in a new mode */
|
||||||
|
if (argc >= 2 && strcmp (argv[1], "--session-child") == 0)
|
||||||
|
return session_child_run (argc, argv);
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
153
1002-fix-x-server-Avoid-reusing-the-local-X-server-if-the.patch
Normal file
153
1002-fix-x-server-Avoid-reusing-the-local-X-server-if-the.patch
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
From 00730089ab023e91c3da06897f7c461d8c89369d Mon Sep 17 00:00:00 2001
|
||||||
|
From: liuxinhao <liuxinhao@kylinsec.com.cn>
|
||||||
|
Date: Sat, 13 May 2023 10:02:48 +0800
|
||||||
|
Subject: [PATCH] fix(x-server): Avoid reusing the local X server if the
|
||||||
|
hostname
|
||||||
|
|
||||||
|
- If the hostname has changed while using a local seat, we will fail to connect and return to the greeter. Avoid this behavior by recreating the server, upstream commit: https://github.com/canonical/lightdm/pull/288/commits/7aa342e9f78fd276c7c47cfd6a28faf9c0e20a69
|
||||||
|
---
|
||||||
|
src/seat-local.c | 4 +---
|
||||||
|
src/seat-xvnc.c | 4 +---
|
||||||
|
src/x-authority.c | 8 --------
|
||||||
|
src/x-authority.h | 2 --
|
||||||
|
src/x-server.c | 34 +++++++++++++++++++++++++++++++++-
|
||||||
|
src/x-server.h | 2 ++
|
||||||
|
6 files changed, 37 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/seat-local.c b/src/seat-local.c
|
||||||
|
index aa6a0b0..90bb145 100644
|
||||||
|
--- a/src/seat-local.c
|
||||||
|
+++ b/src/seat-local.c
|
||||||
|
@@ -175,9 +175,7 @@ create_x_server (SeatLocal *seat)
|
||||||
|
if (command)
|
||||||
|
x_server_local_set_command (x_server, command);
|
||||||
|
|
||||||
|
- g_autofree gchar *number = g_strdup_printf ("%d", x_server_get_display_number (X_SERVER (x_server)));
|
||||||
|
- g_autoptr(XAuthority) cookie = x_authority_new_local_cookie (number);
|
||||||
|
- x_server_set_authority (X_SERVER (x_server), cookie);
|
||||||
|
+ x_server_set_local_authority (X_SERVER (x_server));
|
||||||
|
|
||||||
|
const gchar *layout = seat_get_string_property (SEAT (seat), "xserver-layout");
|
||||||
|
if (layout)
|
||||||
|
diff --git a/src/seat-xvnc.c b/src/seat-xvnc.c
|
||||||
|
index a726a9d..47658df 100644
|
||||||
|
--- a/src/seat-xvnc.c
|
||||||
|
+++ b/src/seat-xvnc.c
|
||||||
|
@@ -57,9 +57,7 @@ seat_xvnc_create_display_server (Seat *seat, Session *session)
|
||||||
|
|
||||||
|
g_autoptr(XServerXVNC) x_server = x_server_xvnc_new ();
|
||||||
|
priv->x_server = g_object_ref (x_server);
|
||||||
|
- g_autofree gchar *number = g_strdup_printf ("%d", x_server_get_display_number (X_SERVER (x_server)));
|
||||||
|
- g_autoptr(XAuthority) cookie = x_authority_new_local_cookie (number);
|
||||||
|
- x_server_set_authority (X_SERVER (x_server), cookie);
|
||||||
|
+ x_server_set_local_authority (X_SERVER (x_server));
|
||||||
|
x_server_xvnc_set_socket (x_server, g_socket_get_fd (priv->connection));
|
||||||
|
|
||||||
|
const gchar *command = config_get_string (config_get_instance (), "VNCServer", "command");
|
||||||
|
diff --git a/src/x-authority.c b/src/x-authority.c
|
||||||
|
index baaf4be..a1500bd 100644
|
||||||
|
--- a/src/x-authority.c
|
||||||
|
+++ b/src/x-authority.c
|
||||||
|
@@ -65,14 +65,6 @@ x_authority_new_cookie (guint16 family, const guint8 *address, gsize address_len
|
||||||
|
return x_authority_new (family, address, address_length, number, "MIT-MAGIC-COOKIE-1", cookie, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
-XAuthority *
|
||||||
|
-x_authority_new_local_cookie (const gchar *number)
|
||||||
|
-{
|
||||||
|
- gchar hostname[1024];
|
||||||
|
- gethostname (hostname, 1024);
|
||||||
|
- return x_authority_new_cookie (XAUTH_FAMILY_LOCAL, (guint8 *) hostname, strlen (hostname), number);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void
|
||||||
|
x_authority_set_family (XAuthority *auth, guint16 family)
|
||||||
|
{
|
||||||
|
diff --git a/src/x-authority.h b/src/x-authority.h
|
||||||
|
index 1ddb852..d9f0e0b 100644
|
||||||
|
--- a/src/x-authority.h
|
||||||
|
+++ b/src/x-authority.h
|
||||||
|
@@ -55,8 +55,6 @@ XAuthority *x_authority_new (guint16 family, const guint8 *address, gsize addres
|
||||||
|
|
||||||
|
XAuthority *x_authority_new_cookie (guint16 family, const guint8 *address, gsize address_length, const gchar *number);
|
||||||
|
|
||||||
|
-XAuthority *x_authority_new_local_cookie (const gchar *number);
|
||||||
|
-
|
||||||
|
void x_authority_set_family (XAuthority *auth, guint16 family);
|
||||||
|
|
||||||
|
guint16 x_authority_get_family (XAuthority *auth);
|
||||||
|
diff --git a/src/x-server.c b/src/x-server.c
|
||||||
|
index ae64808..a6ab5ef 100644
|
||||||
|
--- a/src/x-server.c
|
||||||
|
+++ b/src/x-server.c
|
||||||
|
@@ -27,6 +27,9 @@ typedef struct
|
||||||
|
/* Authority */
|
||||||
|
XAuthority *authority;
|
||||||
|
|
||||||
|
+ /* Cached hostname for the authority */
|
||||||
|
+ gchar local_hostname[1024];
|
||||||
|
+
|
||||||
|
/* Connection to this X server */
|
||||||
|
xcb_connection_t *connection;
|
||||||
|
} XServerPrivate;
|
||||||
|
@@ -91,6 +94,23 @@ x_server_set_authority (XServer *server, XAuthority *authority)
|
||||||
|
priv->authority = g_object_ref (authority);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+x_server_set_local_authority (XServer *server)
|
||||||
|
+{
|
||||||
|
+ XServerPrivate *priv = NULL;
|
||||||
|
+ char display_number[12];
|
||||||
|
+
|
||||||
|
+ g_return_if_fail (server != NULL);
|
||||||
|
+
|
||||||
|
+ priv = x_server_get_instance_private (server);
|
||||||
|
+
|
||||||
|
+ gethostname (priv->local_hostname, sizeof(priv->local_hostname));
|
||||||
|
+
|
||||||
|
+ g_clear_object (&priv->authority);
|
||||||
|
+ g_snprintf(display_number, sizeof(display_number), "%d", x_server_get_display_number (server));
|
||||||
|
+ priv->authority = x_authority_new_cookie (XAUTH_FAMILY_LOCAL, (guint8 *) priv->local_hostname, strlen (priv->local_hostname), display_number);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
XAuthority *
|
||||||
|
x_server_get_authority (XServer *server)
|
||||||
|
{
|
||||||
|
@@ -108,7 +128,19 @@ x_server_get_session_type (DisplayServer *server)
|
||||||
|
static gboolean
|
||||||
|
x_server_get_can_share (DisplayServer *server)
|
||||||
|
{
|
||||||
|
- return TRUE;
|
||||||
|
+ XServerPrivate *priv = NULL;
|
||||||
|
+ gchar actual_local_hostname[1024];
|
||||||
|
+
|
||||||
|
+ g_return_val_if_fail (server != NULL, FALSE);
|
||||||
|
+
|
||||||
|
+ priv = x_server_get_instance_private ((XServer*) server);
|
||||||
|
+ if (priv->local_hostname[0] == '\0')
|
||||||
|
+ return TRUE;
|
||||||
|
+
|
||||||
|
+ /* The XAuthority depends on the hostname so we can't share the display
|
||||||
|
+ * server if the hostname has been changed */
|
||||||
|
+ gethostname (actual_local_hostname, sizeof(actual_local_hostname));
|
||||||
|
+ return g_strcmp0 (actual_local_hostname, priv->local_hostname) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
diff --git a/src/x-server.h b/src/x-server.h
|
||||||
|
index 18b9163..4d125b2 100644
|
||||||
|
--- a/src/x-server.h
|
||||||
|
+++ b/src/x-server.h
|
||||||
|
@@ -55,6 +55,8 @@ gsize x_server_get_authentication_data_length (XServer *server);
|
||||||
|
|
||||||
|
void x_server_set_authority (XServer *server, XAuthority *authority);
|
||||||
|
|
||||||
|
+void x_server_set_local_authority (XServer *server);
|
||||||
|
+
|
||||||
|
XAuthority *x_server_get_authority (XServer *server);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
527
9001-multi-pipe-mode.patch
Normal file
527
9001-multi-pipe-mode.patch
Normal file
@ -0,0 +1,527 @@
|
|||||||
|
From 709db95bff5d88ed2d9d5911e8050cacb4f46921 Mon Sep 17 00:00:00 2001
|
||||||
|
From: panchenbo <panchenbo@uniontech.com>
|
||||||
|
Date: Sun, 25 Apr 2021 18:28:22 +0800
|
||||||
|
Subject: [PATCH] multi-pipe mode
|
||||||
|
|
||||||
|
---
|
||||||
|
liblightdm-gobject/greeter.c | 5 +-
|
||||||
|
src/greeter.c | 9 ++--
|
||||||
|
src/session-child.c | 100 ++++++++++++++++++++++++++++++-----
|
||||||
|
src/session.c | 100 +++++++++++++++++++++++++++++++++--
|
||||||
|
src/session.h | 7 +++
|
||||||
|
5 files changed, 200 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c
|
||||||
|
index fd1763c..78c3981 100644
|
||||||
|
--- a/liblightdm-gobject/greeter.c
|
||||||
|
+++ b/liblightdm-gobject/greeter.c
|
||||||
|
@@ -652,7 +652,6 @@ handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize me
|
||||||
|
|
||||||
|
g_list_free_full (priv->responses_received, g_free);
|
||||||
|
priv->responses_received = NULL;
|
||||||
|
- priv->n_responses_waiting = 0;
|
||||||
|
|
||||||
|
guint32 n_messages = read_int (message, message_length, offset);
|
||||||
|
g_debug ("Prompt user with %d message(s)", n_messages);
|
||||||
|
@@ -713,6 +712,8 @@ handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize messa
|
||||||
|
priv->is_authenticated = (return_code == 0);
|
||||||
|
|
||||||
|
priv->in_authentication = FALSE;
|
||||||
|
+ // reset
|
||||||
|
+ priv->n_responses_waiting = 0;
|
||||||
|
g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1330,6 +1331,8 @@ lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username, GE
|
||||||
|
priv->cancelling_authentication = FALSE;
|
||||||
|
priv->authenticate_sequence_number++;
|
||||||
|
priv->in_authentication = TRUE;
|
||||||
|
+ // reset
|
||||||
|
+ priv->n_responses_waiting = 0;
|
||||||
|
priv->is_authenticated = FALSE;
|
||||||
|
if (username != priv->authentication_user)
|
||||||
|
{
|
||||||
|
diff --git a/src/greeter.c b/src/greeter.c
|
||||||
|
index 383e1f8..fc4850d 100644
|
||||||
|
--- a/src/greeter.c
|
||||||
|
+++ b/src/greeter.c
|
||||||
|
@@ -394,6 +394,7 @@ pam_messages_cb (Session *session, Greeter *greeter)
|
||||||
|
}
|
||||||
|
write_message (greeter, message, offset);
|
||||||
|
|
||||||
|
+ g_debug ("Prompt greeter with %d n_prompts", n_prompts);
|
||||||
|
/* Continue immediately if nothing to respond with */
|
||||||
|
// FIXME: Should probably give the greeter a chance to ack the message
|
||||||
|
if (n_prompts == 0)
|
||||||
|
@@ -645,8 +646,8 @@ handle_continue_authentication (Greeter *greeter, gchar **secrets)
|
||||||
|
if (priv->authentication_session == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- int messages_length = session_get_messages_length (priv->authentication_session);
|
||||||
|
- const struct pam_message *messages = session_get_messages (priv->authentication_session);
|
||||||
|
+ int messages_length = session_get_prompt_messages_length (priv->authentication_session);
|
||||||
|
+ const struct pam_message *messages = session_get_prompt_messages (priv->authentication_session);
|
||||||
|
|
||||||
|
/* Check correct number of responses */
|
||||||
|
int n_prompts = 0;
|
||||||
|
@@ -658,7 +659,7 @@ handle_continue_authentication (Greeter *greeter, gchar **secrets)
|
||||||
|
}
|
||||||
|
if (g_strv_length (secrets) != n_prompts)
|
||||||
|
{
|
||||||
|
- session_respond_error (priv->authentication_session, PAM_CONV_ERR);
|
||||||
|
+ session_prompt_respond_error (priv->authentication_session, PAM_CONV_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -678,7 +679,7 @@ handle_continue_authentication (Greeter *greeter, gchar **secrets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- session_respond (priv->authentication_session, response);
|
||||||
|
+ session_prompt_respond (priv->authentication_session, response);
|
||||||
|
|
||||||
|
for (int i = 0; i < messages_length; i++)
|
||||||
|
secure_free (greeter, response[i].resp);
|
||||||
|
diff --git a/src/session-child.c b/src/session-child.c
|
||||||
|
index eef51e4..64716b2 100644
|
||||||
|
--- a/src/session-child.c
|
||||||
|
+++ b/src/session-child.c
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
#include <utmp.h>
|
||||||
|
#include <utmpx.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
|
||||||
|
#if HAVE_LIBAUDIT
|
||||||
|
#include <libaudit.h>
|
||||||
|
@@ -37,6 +38,8 @@ static GPid child_pid = 0;
|
||||||
|
/* Pipe to communicate with daemon */
|
||||||
|
static int from_daemon_output = 0;
|
||||||
|
static int to_daemon_input = 0;
|
||||||
|
+/* Pipe to prompt with daemon */
|
||||||
|
+static int from_daemon_output_prompt = 0;
|
||||||
|
|
||||||
|
static gboolean is_interactive;
|
||||||
|
static gboolean do_authenticate;
|
||||||
|
@@ -72,6 +75,16 @@ read_data (void *buf, size_t count)
|
||||||
|
return n_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static ssize_t
|
||||||
|
+read_prompt_data (void *buf, size_t count)
|
||||||
|
+{
|
||||||
|
+ ssize_t n_read = read (from_daemon_output_prompt, buf, count);
|
||||||
|
+ if (n_read < 0)
|
||||||
|
+ g_printerr ("Error reading prompt from daemon: %s\n", strerror (errno));
|
||||||
|
+
|
||||||
|
+ return n_read;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gchar *
|
||||||
|
read_string_full (void* (*alloc_fn)(size_t n))
|
||||||
|
{
|
||||||
|
@@ -93,12 +106,34 @@ read_string_full (void* (*alloc_fn)(size_t n))
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static gchar *
|
||||||
|
+read_prompt_string_full (void* (*alloc_fn)(size_t n))
|
||||||
|
+{
|
||||||
|
+ int length;
|
||||||
|
+ if (read_prompt_data (&length, sizeof (length)) <= 0)
|
||||||
|
+ return NULL;
|
||||||
|
+ if (length < 0)
|
||||||
|
+ return NULL;
|
||||||
|
+ if (length > MAX_STRING_LENGTH)
|
||||||
|
+ {
|
||||||
|
+ g_printerr ("Invalid string length %d from daemon\n", length);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ gchar *value = (*alloc_fn) (sizeof (gchar) * (length + 1));
|
||||||
|
+ read_prompt_data (value, length);
|
||||||
|
+ value[length] = '\0';
|
||||||
|
+
|
||||||
|
+ return value;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gchar *
|
||||||
|
read_string (void)
|
||||||
|
{
|
||||||
|
return read_string_full (g_malloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
+pthread_mutex_t mutex_msg;
|
||||||
|
static int
|
||||||
|
pam_conv_cb (int msg_length, const struct pam_message **msg, struct pam_response **resp, void *app_data)
|
||||||
|
{
|
||||||
|
@@ -106,18 +141,26 @@ pam_conv_cb (int msg_length, const struct pam_message **msg, struct pam_response
|
||||||
|
if (authentication_complete)
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
|
||||||
|
- /* Cancel authentication if requiring input */
|
||||||
|
- if (!is_interactive)
|
||||||
|
+ // 将普通消息和PAM_PROMPT_ECHO_X的消息分开,从lightdm中读取回复内容时使用不同的管道
|
||||||
|
+ // 因为在lightdm的实现中处理PAM_PROMPT_ECHO_X时会一直等待greeter的消息,而其他消息则会立即给出响应结果
|
||||||
|
+ int n_prompts = 0;
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < msg_length; i++)
|
||||||
|
{
|
||||||
|
- for (int i = 0; i < msg_length; i++)
|
||||||
|
+ if (msg[i]->msg_style == PAM_PROMPT_ECHO_ON || msg[i]->msg_style == PAM_PROMPT_ECHO_OFF)
|
||||||
|
{
|
||||||
|
- if (msg[i]->msg_style == PAM_PROMPT_ECHO_ON || msg[i]->msg_style == PAM_PROMPT_ECHO_OFF)
|
||||||
|
+ /* Cancel authentication if requiring input */
|
||||||
|
+ if (!is_interactive)
|
||||||
|
{
|
||||||
|
g_printerr ("Stopping PAM conversation, interaction requested but not supported\n");
|
||||||
|
return PAM_CONV_ERR;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
+ ++n_prompts;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!is_interactive)
|
||||||
|
+ {
|
||||||
|
/* Ignore informational messages */
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
@@ -125,6 +168,10 @@ pam_conv_cb (int msg_length, const struct pam_message **msg, struct pam_response
|
||||||
|
/* Check if we changed user */
|
||||||
|
gchar *username = NULL;
|
||||||
|
pam_get_item (pam_handle, PAM_USER, (const void **) &username);
|
||||||
|
+
|
||||||
|
+ // lock for pam
|
||||||
|
+ // 在pam模块中可能使用多线程调用此函数,加锁是为了保证消息在管道中的相对顺序
|
||||||
|
+ pthread_mutex_lock(&mutex_msg);
|
||||||
|
|
||||||
|
/* Notify the daemon */
|
||||||
|
write_string (username);
|
||||||
|
@@ -140,17 +187,39 @@ pam_conv_cb (int msg_length, const struct pam_message **msg, struct pam_response
|
||||||
|
|
||||||
|
/* Get response */
|
||||||
|
int error;
|
||||||
|
- read_data (&error, sizeof (error));
|
||||||
|
- if (error != PAM_SUCCESS)
|
||||||
|
+ if (n_prompts) {
|
||||||
|
+ // 只为普通消息加锁,如果 PAM_PROMPT_ECHO_X 类型的消息也从多个线程发送则可能存在风险
|
||||||
|
+ // unlock for read message
|
||||||
|
+ pthread_mutex_unlock(&mutex_msg);
|
||||||
|
+ read_prompt_data (&error, sizeof (error));
|
||||||
|
+ } else {
|
||||||
|
+ read_data (&error, sizeof (error));
|
||||||
|
+ }
|
||||||
|
+ if (error != PAM_SUCCESS) {
|
||||||
|
+ if (!n_prompts) {
|
||||||
|
+ // unlock for read message
|
||||||
|
+ pthread_mutex_unlock(&mutex_msg);
|
||||||
|
+ }
|
||||||
|
return error;
|
||||||
|
+ }
|
||||||
|
struct pam_response *response = calloc (msg_length, sizeof (struct pam_response));
|
||||||
|
for (int i = 0; i < msg_length; i++)
|
||||||
|
{
|
||||||
|
struct pam_response *r = &response[i];
|
||||||
|
// callers of this function inside pam will expect to be able to call
|
||||||
|
// free() on the strings we give back. So alloc with malloc.
|
||||||
|
- r->resp = read_string_full (malloc);
|
||||||
|
- read_data (&r->resp_retcode, sizeof (r->resp_retcode));
|
||||||
|
+ if (n_prompts) {
|
||||||
|
+ r->resp = read_prompt_string_full (malloc);
|
||||||
|
+ read_prompt_data (&r->resp_retcode, sizeof (r->resp_retcode));
|
||||||
|
+ } else {
|
||||||
|
+ r->resp = read_string_full (malloc);
|
||||||
|
+ read_data (&r->resp_retcode, sizeof (r->resp_retcode));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!n_prompts) {
|
||||||
|
+ // unlock for read message
|
||||||
|
+ pthread_mutex_unlock(&mutex_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
*resp = response;
|
||||||
|
@@ -262,22 +331,24 @@ session_child_run (int argc, char **argv)
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
/* Get the pipe from the daemon */
|
||||||
|
- if (argc != 4)
|
||||||
|
+ if (argc != 5)
|
||||||
|
{
|
||||||
|
- g_printerr ("Usage: lightdm --session-child INPUTFD OUTPUTFD\n");
|
||||||
|
+ g_printerr ("Usage: lightdm --session-child INPUTFD OUTPUTFD INPUTFD_PROMPT\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
from_daemon_output = atoi (argv[2]);
|
||||||
|
to_daemon_input = atoi (argv[3]);
|
||||||
|
- if (from_daemon_output == 0 || to_daemon_input == 0)
|
||||||
|
+ from_daemon_output_prompt = atoi (argv[4]);
|
||||||
|
+ if (from_daemon_output == 0 || to_daemon_input == 0 || from_daemon_output_prompt == 0)
|
||||||
|
{
|
||||||
|
- g_printerr ("Invalid file descriptors %s %s\n", argv[2], argv[3]);
|
||||||
|
+ g_printerr ("Invalid file descriptors %s %s %s\n", argv[2], argv[3], argv[4]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't let these pipes leak to the command we will run */
|
||||||
|
fcntl (from_daemon_output, F_SETFD, FD_CLOEXEC);
|
||||||
|
fcntl (to_daemon_input, F_SETFD, FD_CLOEXEC);
|
||||||
|
+ fcntl (from_daemon_output_prompt, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
/* Read a version number so we can handle upgrades (i.e. a newer version of session child is run for an old daemon */
|
||||||
|
int version;
|
||||||
|
@@ -330,7 +401,10 @@ session_child_run (int argc, char **argv)
|
||||||
|
{
|
||||||
|
const gchar *new_username;
|
||||||
|
|
||||||
|
+ // init mutex for pam_conv_cb
|
||||||
|
+ pthread_mutex_init(&mutex_msg, 0);
|
||||||
|
authentication_result = pam_authenticate (pam_handle, 0);
|
||||||
|
+ pthread_mutex_destroy(&mutex_msg);
|
||||||
|
|
||||||
|
/* See what user we ended up as */
|
||||||
|
if (pam_get_item (pam_handle, PAM_USER, (const void **) &new_username) != PAM_SUCCESS)
|
||||||
|
diff --git a/src/session.c b/src/session.c
|
||||||
|
index 2ea9352..12ae60a 100644
|
||||||
|
--- a/src/session.c
|
||||||
|
+++ b/src/session.c
|
||||||
|
@@ -52,6 +52,7 @@ typedef struct
|
||||||
|
/* Pipes to talk to child */
|
||||||
|
int to_child_input;
|
||||||
|
int from_child_output;
|
||||||
|
+ int to_child_prompt_input;
|
||||||
|
GIOChannel *from_child_channel;
|
||||||
|
guint from_child_watch;
|
||||||
|
guint child_watch;
|
||||||
|
@@ -77,6 +78,9 @@ typedef struct
|
||||||
|
/* Messages being requested by PAM */
|
||||||
|
int messages_length;
|
||||||
|
struct pam_message *messages;
|
||||||
|
+ /* Prompt Messages being requested by PAM */
|
||||||
|
+ int prompt_messages_length;
|
||||||
|
+ struct pam_message *prompt_messages;
|
||||||
|
|
||||||
|
/* Authentication result from PAM */
|
||||||
|
gboolean authentication_started;
|
||||||
|
@@ -382,6 +386,14 @@ write_data (Session *session, const void *buf, size_t count)
|
||||||
|
l_warning (session, "Error writing to session: %s", strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+write_prompt_data (Session *session, const void *buf, size_t count)
|
||||||
|
+{
|
||||||
|
+ SessionPrivate *priv = session_get_instance_private (session);
|
||||||
|
+ if (write (priv->to_child_prompt_input, buf, count) != count)
|
||||||
|
+ l_warning (session, "Error writing prompt to session: %s", strerror (errno));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
write_string (Session *session, const char *value)
|
||||||
|
{
|
||||||
|
@@ -391,6 +403,15 @@ write_string (Session *session, const char *value)
|
||||||
|
write_data (session, value, sizeof (char) * length);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+write_prompt_string (Session *session, const char *value)
|
||||||
|
+{
|
||||||
|
+ int length = value ? strlen (value) : -1;
|
||||||
|
+ write_prompt_data (session, &length, sizeof (length));
|
||||||
|
+ if (value)
|
||||||
|
+ write_prompt_data (session, value, sizeof (char) * length);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
write_xauth (Session *session, XAuthority *x_authority)
|
||||||
|
{
|
||||||
|
@@ -534,6 +555,8 @@ from_child_cb (GIOChannel *source, GIOCondition condition, gpointer data)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
+ gboolean n_prompts = 0;
|
||||||
|
+
|
||||||
|
priv->messages_length = 0;
|
||||||
|
read_from_child (session, &priv->messages_length, sizeof (priv->messages_length));
|
||||||
|
priv->messages = calloc (priv->messages_length, sizeof (struct pam_message));
|
||||||
|
@@ -542,6 +565,13 @@ from_child_cb (GIOChannel *source, GIOCondition condition, gpointer data)
|
||||||
|
struct pam_message *m = &priv->messages[i];
|
||||||
|
read_from_child (session, &m->msg_style, sizeof (m->msg_style));
|
||||||
|
m->msg = read_string_from_child (session);
|
||||||
|
+ if (m->msg_style == PAM_PROMPT_ECHO_OFF || m->msg_style == PAM_PROMPT_ECHO_ON)
|
||||||
|
+ ++n_prompts;
|
||||||
|
+ }
|
||||||
|
+ // for prompt message
|
||||||
|
+ if (n_prompts) {
|
||||||
|
+ priv->prompt_messages_length = priv->messages_length;
|
||||||
|
+ priv->prompt_messages = priv->messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
l_debug (session, "Got %d message(s) from PAM", priv->messages_length);
|
||||||
|
@@ -585,15 +615,17 @@ session_real_start (Session *session)
|
||||||
|
display_server_connect_session (priv->display_server, session);
|
||||||
|
|
||||||
|
/* Create pipes to talk to the child */
|
||||||
|
- int to_child_pipe[2], from_child_pipe[2];
|
||||||
|
- if (pipe (to_child_pipe) < 0 || pipe (from_child_pipe) < 0)
|
||||||
|
+ int to_child_pipe[2], from_child_pipe[2], to_child_prompt_pipe[2];
|
||||||
|
+ if (pipe (to_child_pipe) < 0 || pipe (from_child_pipe) < 0 || pipe (to_child_prompt_pipe) < 0)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to create pipe to communicate with session process: %s", strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
int to_child_output = to_child_pipe[0];
|
||||||
|
+ int to_child_prompt_output = to_child_prompt_pipe[0];
|
||||||
|
priv->to_child_input = to_child_pipe[1];
|
||||||
|
priv->from_child_output = from_child_pipe[0];
|
||||||
|
+ priv->to_child_prompt_input = to_child_prompt_pipe[1];
|
||||||
|
int from_child_input = from_child_pipe[1];
|
||||||
|
priv->from_child_channel = g_io_channel_unix_new (priv->from_child_output);
|
||||||
|
priv->from_child_watch = g_io_add_watch (priv->from_child_channel, G_IO_IN | G_IO_HUP, from_child_cb, session);
|
||||||
|
@@ -601,6 +633,7 @@ session_real_start (Session *session)
|
||||||
|
/* Don't allow the daemon end of the pipes to be accessed in child processes */
|
||||||
|
fcntl (priv->to_child_input, F_SETFD, FD_CLOEXEC);
|
||||||
|
fcntl (priv->from_child_output, F_SETFD, FD_CLOEXEC);
|
||||||
|
+ fcntl (priv->to_child_prompt_input, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
/* Create the guest account if it is one */
|
||||||
|
if (priv->is_guest && priv->username == NULL)
|
||||||
|
@@ -613,6 +646,7 @@ session_real_start (Session *session)
|
||||||
|
/* Run the child */
|
||||||
|
g_autofree gchar *arg0 = g_strdup_printf ("%d", to_child_output);
|
||||||
|
g_autofree gchar *arg1 = g_strdup_printf ("%d", from_child_input);
|
||||||
|
+ g_autofree gchar *arg2 = g_strdup_printf ("%d", to_child_prompt_output);
|
||||||
|
priv->pid = fork ();
|
||||||
|
if (priv->pid == 0)
|
||||||
|
{
|
||||||
|
@@ -620,7 +654,7 @@ session_real_start (Session *session)
|
||||||
|
execlp ("lightdm",
|
||||||
|
"lightdm",
|
||||||
|
"--session-child",
|
||||||
|
- arg0, arg1, NULL);
|
||||||
|
+ arg0, arg1, arg2, NULL);
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -642,6 +676,7 @@ session_real_start (Session *session)
|
||||||
|
/* Close the ends of the pipes we don't need */
|
||||||
|
close (to_child_output);
|
||||||
|
close (from_child_input);
|
||||||
|
+ close (to_child_prompt_output);
|
||||||
|
|
||||||
|
/* Indicate what version of the protocol we are using */
|
||||||
|
int version = 3;
|
||||||
|
@@ -702,6 +737,11 @@ session_respond (Session *session, struct pam_response *response)
|
||||||
|
write_data (session, &response[i].resp_retcode, sizeof (response[i].resp_retcode));
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (priv->messages == priv->prompt_messages) {
|
||||||
|
+ l_warning (session, "%s", "Current message is prompt message");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Delete the old messages */
|
||||||
|
for (int i = 0; i < priv->messages_length; i++)
|
||||||
|
g_free ((char *) priv->messages[i].msg);
|
||||||
|
@@ -710,6 +750,35 @@ session_respond (Session *session, struct pam_response *response)
|
||||||
|
priv->messages_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+session_prompt_respond (Session *session, struct pam_response *response)
|
||||||
|
+{
|
||||||
|
+ SessionPrivate *priv = session_get_instance_private (session);
|
||||||
|
+
|
||||||
|
+ g_return_if_fail (session != NULL);
|
||||||
|
+
|
||||||
|
+ int error = PAM_SUCCESS;
|
||||||
|
+ write_prompt_data (session, &error, sizeof (error));
|
||||||
|
+ for (int i = 0; i < priv->prompt_messages_length; i++)
|
||||||
|
+ {
|
||||||
|
+ write_prompt_string (session, response[i].resp);
|
||||||
|
+ write_prompt_data (session, &response[i].resp_retcode, sizeof (response[i].resp_retcode));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // clear
|
||||||
|
+ if (priv->messages == priv->prompt_messages) {
|
||||||
|
+ priv->messages = NULL;
|
||||||
|
+ priv->messages_length = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Delete the old messages */
|
||||||
|
+ for (int i = 0; i < priv->prompt_messages_length; i++)
|
||||||
|
+ g_free ((char *) priv->prompt_messages[i].msg);
|
||||||
|
+ g_free (priv->prompt_messages);
|
||||||
|
+ priv->prompt_messages = NULL;
|
||||||
|
+ priv->prompt_messages_length = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
session_respond_error (Session *session, int error)
|
||||||
|
{
|
||||||
|
@@ -719,6 +788,15 @@ session_respond_error (Session *session, int error)
|
||||||
|
write_data (session, &error, sizeof (error));
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+session_prompt_respond_error (Session *session, int error)
|
||||||
|
+{
|
||||||
|
+ g_return_if_fail (session != NULL);
|
||||||
|
+ g_return_if_fail (error != PAM_SUCCESS);
|
||||||
|
+
|
||||||
|
+ write_prompt_data (session, &error, sizeof (error));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
session_get_messages_length (Session *session)
|
||||||
|
{
|
||||||
|
@@ -727,6 +805,22 @@ session_get_messages_length (Session *session)
|
||||||
|
return priv->messages_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int
|
||||||
|
+session_get_prompt_messages_length(Session *session)
|
||||||
|
+{
|
||||||
|
+ SessionPrivate *priv = session_get_instance_private (session);
|
||||||
|
+ g_return_val_if_fail (session != NULL, 0);
|
||||||
|
+ return priv->prompt_messages_length;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct pam_message *
|
||||||
|
+session_get_prompt_messages(Session *session)
|
||||||
|
+{
|
||||||
|
+ SessionPrivate *priv = session_get_instance_private (session);
|
||||||
|
+ g_return_val_if_fail (session != NULL, NULL);
|
||||||
|
+ return priv->prompt_messages;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const struct pam_message *
|
||||||
|
session_get_messages (Session *session)
|
||||||
|
{
|
||||||
|
diff --git a/src/session.h b/src/session.h
|
||||||
|
index 350cf3b..de15ae4 100644
|
||||||
|
--- a/src/session.h
|
||||||
|
+++ b/src/session.h
|
||||||
|
@@ -124,12 +124,19 @@ const gchar *session_get_console_kit_cookie (Session *session);
|
||||||
|
|
||||||
|
void session_respond (Session *session, struct pam_response *response);
|
||||||
|
|
||||||
|
+void session_prompt_respond (Session *session, struct pam_response *response);
|
||||||
|
+
|
||||||
|
void session_respond_error (Session *session, int error);
|
||||||
|
|
||||||
|
+void session_prompt_respond_error (Session *session, int error);
|
||||||
|
+
|
||||||
|
int session_get_messages_length (Session *session);
|
||||||
|
|
||||||
|
const struct pam_message *session_get_messages (Session *session);
|
||||||
|
|
||||||
|
+int session_get_prompt_messages_length (Session *session);
|
||||||
|
+const struct pam_message *session_get_prompt_messages (Session *session);
|
||||||
|
+
|
||||||
|
gboolean session_get_is_authenticated (Session *session);
|
||||||
|
|
||||||
|
int session_get_authentication_result (Session *session);
|
||||||
|
--
|
||||||
|
2.20.1
|
||||||
|
|
||||||
91
9002-dm-tool-lock-function-patch.patch
Normal file
91
9002-dm-tool-lock-function-patch.patch
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
From 60a7f41c675d0c99f697b1e2479feea0e78b9b0f Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?=E6=9B=B9=E5=A8=81?= <caowei@uniontech.com>
|
||||||
|
Date: Sat, 30 May 2020 14:35:45 +0800
|
||||||
|
Subject: [PATCH] dm-tool lock function patch
|
||||||
|
|
||||||
|
---
|
||||||
|
src/dm-tool.c | 60 +++++++++++++++++++++++++++++++++++++++++++--------
|
||||||
|
1 file changed, 51 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/dm-tool.c b/src/dm-tool.c
|
||||||
|
index 5060109..8190aa9 100644
|
||||||
|
--- a/src/dm-tool.c
|
||||||
|
+++ b/src/dm-tool.c
|
||||||
|
@@ -16,6 +16,41 @@
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
+#define LOCKFRONT_NAME "com.deepin.dde.lockFront"
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_call_lock_front()
|
||||||
|
+{
|
||||||
|
+ g_autoptr(GError) pLockError = NULL;
|
||||||
|
+ GDBusProxy *pLockFront = g_dbus_proxy_new_for_bus_sync(
|
||||||
|
+ G_BUS_TYPE_SESSION,
|
||||||
|
+ G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
+ NULL,
|
||||||
|
+ LOCKFRONT_NAME,
|
||||||
|
+ "/com/deepin/dde/lockFront",
|
||||||
|
+ LOCKFRONT_NAME,
|
||||||
|
+ NULL,
|
||||||
|
+ &pLockError);
|
||||||
|
+ if (!pLockFront)
|
||||||
|
+ {
|
||||||
|
+ g_printerr("something error happend. %s. %s, %d", LOCKFRONT_NAME, pLockError->message, pLockError->code);
|
||||||
|
+ return EXIT_FAILURE;
|
||||||
|
+ }
|
||||||
|
+ if (!g_dbus_proxy_call_sync(
|
||||||
|
+ pLockFront,
|
||||||
|
+ "Show",
|
||||||
|
+ g_variant_new("()"),
|
||||||
|
+ G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
+ -1,
|
||||||
|
+ NULL,
|
||||||
|
+ &pLockError))
|
||||||
|
+ {
|
||||||
|
+ g_printerr("something error happend. %s. %s, %d", LOCKFRONT_NAME, pLockError->message, pLockError->code);
|
||||||
|
+ return EXIT_FAILURE;
|
||||||
|
+ }
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static GBusType bus_type = G_BUS_TYPE_SYSTEM;
|
||||||
|
static GDBusProxy *dm_proxy, *seat_proxy = NULL;
|
||||||
|
|
||||||
|
@@ -259,16 +294,23 @@ main (int argc, char **argv)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!g_dbus_proxy_call_sync (get_seat_proxy (),
|
||||||
|
- "Lock",
|
||||||
|
- g_variant_new ("()"),
|
||||||
|
- G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
- -1,
|
||||||
|
- NULL,
|
||||||
|
- &error))
|
||||||
|
+ if (g_file_test("/etc/deepin-version", G_FILE_TEST_EXISTS))
|
||||||
|
{
|
||||||
|
- g_printerr ("Unable to lock seat: %s\n", error->message);
|
||||||
|
- return EXIT_FAILURE;
|
||||||
|
+ return handle_call_lock_front();
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ if (!g_dbus_proxy_call_sync(get_seat_proxy(),
|
||||||
|
+ "Lock",
|
||||||
|
+ g_variant_new("()"),
|
||||||
|
+ G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
+ -1,
|
||||||
|
+ NULL,
|
||||||
|
+ &error))
|
||||||
|
+ {
|
||||||
|
+ g_printerr("Unable to lock seat: %s\n", error->message);
|
||||||
|
+ return EXIT_FAILURE;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.20.1
|
||||||
|
|
||||||
29
lightdm.spec
29
lightdm.spec
@ -7,7 +7,7 @@
|
|||||||
Name: lightdm
|
Name: lightdm
|
||||||
Summary: A cross-desktop Display Manager
|
Summary: A cross-desktop Display Manager
|
||||||
Version: 1.30.0
|
Version: 1.30.0
|
||||||
Release: 9
|
Release: 14
|
||||||
|
|
||||||
# library/bindings are LGPLv2 or LGPLv3, the rest GPLv3+
|
# library/bindings are LGPLv2 or LGPLv3, the rest GPLv3+
|
||||||
License: (LGPLv2 or LGPLv3) and GPLv3+
|
License: (LGPLv2 or LGPLv3) and GPLv3+
|
||||||
@ -38,6 +38,14 @@ Patch0: lightdm-1.25.1-disable_dmrc.patch
|
|||||||
|
|
||||||
# Upstream commits
|
# Upstream commits
|
||||||
|
|
||||||
|
# UnionTech patchs
|
||||||
|
Patch9001: 9001-multi-pipe-mode.patch
|
||||||
|
Patch9002: 9002-dm-tool-lock-function-patch.patch
|
||||||
|
|
||||||
|
# kylin
|
||||||
|
Patch1001: 1001-fix-translator-fixed-the-issue-that-lightdm-s-PAM-me.patch
|
||||||
|
Patch1002: 1002-fix-x-server-Avoid-reusing-the-local-X-server-if-the.patch
|
||||||
|
|
||||||
BuildRequires: gettext
|
BuildRequires: gettext
|
||||||
BuildRequires: gnome-common
|
BuildRequires: gnome-common
|
||||||
BuildRequires: gtk-doc itstool
|
BuildRequires: gtk-doc itstool
|
||||||
@ -63,10 +71,10 @@ BuildRequires: vala
|
|||||||
Requires: %{name}-gobject%{?_isa} = %{version}-%{release}
|
Requires: %{name}-gobject%{?_isa} = %{version}-%{release}
|
||||||
Requires: accountsservice
|
Requires: accountsservice
|
||||||
Requires: dbus-x11
|
Requires: dbus-x11
|
||||||
%if 0%{?openEuler}
|
%if 0%{?openEuler}
|
||||||
Requires: polkit-js-engine
|
Requires: polkit-js-engine
|
||||||
%endif
|
%endif
|
||||||
Requires: systemd
|
Requires: systemd systemd-pam
|
||||||
Requires: xorg-x11-xinit
|
Requires: xorg-x11-xinit
|
||||||
|
|
||||||
#Requires: (lightdm-greeter = 1.2 if xorg-x11-server-Xorg)
|
#Requires: (lightdm-greeter = 1.2 if xorg-x11-server-Xorg)
|
||||||
@ -307,6 +315,21 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon May 08 2023 liuxinhao <liuxinhao@kylinsec.com.cn> - 1.30.0-14
|
||||||
|
- x-server: Avoid reusing the local X server if the hostname
|
||||||
|
|
||||||
|
* Thu Feb 24 2022 Wenlong.Ding <wenlong.ding@turbolinux.com.cn> - 1.30.0-13
|
||||||
|
- Fixed the problem that lightdm.service start with not found systemd-pam.so error.
|
||||||
|
|
||||||
|
* Tue Jan 25 2022 liuxinhao <liuxinhao@kylinos.com.cn> - 1.30.0-12
|
||||||
|
- Fixed the problem that the PAM message returned by lightdm was not translated
|
||||||
|
|
||||||
|
* Mon Sep 13 2021 zhaoshuang <zhaoshuang@uniontech.com> - 1.30.0-11
|
||||||
|
- Add a uniontech patch to fix dm-tool
|
||||||
|
|
||||||
|
* Fri Jul 30 2021 zhaoshuang <zhaoshuang@uniontech.com> - 1.30.0-10
|
||||||
|
- Add a uniontech patch to support multi-pipe mode
|
||||||
|
|
||||||
* Tun Jun 08 2021 zhanglin <lin.zhang@turbolinux.com.cn> - 1.30.0-9
|
* Tun Jun 08 2021 zhanglin <lin.zhang@turbolinux.com.cn> - 1.30.0-9
|
||||||
- Remove pam_console dependency
|
- Remove pam_console dependency
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user