mirror of
https://github.com/systemd/systemd.git
synced 2024-10-28 03:25:31 +03:00
pam_systemd: Check also abstract socket for X11
It seems that `pam_systemd` was the only thing left that wanted to use sockets in file system path `/tmp/.X11-unix/X*`. X11 apps actually prefer using the abstract socket version. This allows running Xserver with `-nolisten tcp -nolisten unix`, which makes the server only listen to an abstract socket. Also in my setup, Xserver is running as a separate system service instead of starting from display manager service, and now `PrivateTmp=yes` can be used for both. The file system of the display manager service is inherited by user apps and now their `/tmp` will be separate from `/tmp` of PID1 namespace as well as `/tmp` of Xserver.
This commit is contained in:
parent
64a05587ce
commit
ddf127cda4
@ -199,35 +199,60 @@ static bool display_is_local(const char *display) {
|
|||||||
display[1] <= '9';
|
display[1] <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socket_from_display(const char *display, char **path) {
|
static int socket_from_display(const char *display) {
|
||||||
|
_cleanup_free_ char *f = NULL;
|
||||||
size_t k;
|
size_t k;
|
||||||
char *f, *c;
|
char *c;
|
||||||
|
union sockaddr_union sa;
|
||||||
|
socklen_t sa_len;
|
||||||
|
_cleanup_close_ int fd = -1;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(display);
|
assert(display);
|
||||||
assert(path);
|
|
||||||
|
|
||||||
if (!display_is_local(display))
|
if (!display_is_local(display))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
k = strspn(display+1, "0123456789");
|
k = strspn(display+1, "0123456789");
|
||||||
|
|
||||||
f = new(char, STRLEN("/tmp/.X11-unix/X") + k + 1);
|
/* Try abstract socket first. */
|
||||||
|
f = new(char, STRLEN("@/tmp/.X11-unix/X") + k + 1);
|
||||||
if (!f)
|
if (!f)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
c = stpcpy(f, "/tmp/.X11-unix/X");
|
c = stpcpy(f, "@/tmp/.X11-unix/X");
|
||||||
memcpy(c, display+1, k);
|
memcpy(c, display+1, k);
|
||||||
c[k] = 0;
|
c[k] = 0;
|
||||||
|
|
||||||
*path = f;
|
r = sockaddr_un_set_path(&sa.un, f);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
sa_len = r;
|
||||||
|
|
||||||
return 0;
|
fd = RET_NERRNO(socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0));
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
r = RET_NERRNO(connect(fd, &sa.sa, sa_len));
|
||||||
|
if (r >= 0)
|
||||||
|
return TAKE_FD(fd);
|
||||||
|
if (r != -ECONNREFUSED)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* Try also non-abstract socket. */
|
||||||
|
r = sockaddr_un_set_path(&sa.un, f + 1);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
sa_len = r;
|
||||||
|
|
||||||
|
r = RET_NERRNO(connect(fd, &sa.sa, sa_len));
|
||||||
|
if (r >= 0)
|
||||||
|
return TAKE_FD(fd);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) {
|
static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) {
|
||||||
union sockaddr_union sa;
|
_cleanup_free_ char *sys_path = NULL, *tty = NULL;
|
||||||
socklen_t sa_len;
|
|
||||||
_cleanup_free_ char *p = NULL, *sys_path = NULL, *tty = NULL;
|
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
struct ucred ucred;
|
struct ucred ucred;
|
||||||
int v, r;
|
int v, r;
|
||||||
@ -242,20 +267,9 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_
|
|||||||
* the seat and the virtual terminal. Sounds ugly, is only
|
* the seat and the virtual terminal. Sounds ugly, is only
|
||||||
* semi-ugly. */
|
* semi-ugly. */
|
||||||
|
|
||||||
r = socket_from_display(display, &p);
|
fd = socket_from_display(display);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
r = sockaddr_un_set_path(&sa.un, p);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
sa_len = r;
|
|
||||||
|
|
||||||
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
return fd;
|
||||||
|
|
||||||
if (connect(fd, &sa.sa, sa_len) < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
r = getpeercred(fd, &ucred);
|
r = getpeercred(fd, &ucred);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user