Discussion:
Create a new logind session from a systemd --user unit
(too old to reply)
Abdó Roig-Maranges
2013-07-27 19:47:13 UTC
Permalink
Hello,

I'm happily using systemd 204 user instance to handle my desktop (xorg, awesome
wm, mpd, etc.) in Arch. I started experimenting with systemd 206 trying to adapt
my setup to the changes in cgroups, slices, and all that.

In 206, systemd user session is started automatically by pam_systemd when I
login to a tty. Then, I want to manually launch my window manager, in a new
logind session for my user, on a different tty.

I tried adding User and PAMName to my window manager unit awesome.service:

[Unit]
Description=Awesome window manager
After=***@0.service
Requisite=***@0.service
Requires=dbus.socket

[Service]
User=abdo
PAMName=login
TTYPath=/dev/tty7

Type=simple
SyslogIdentifier=awesome
Environment=DISPLAY=:0
ExecStart=/home/abdo/.config/systemd/scripts/awesome.sh start
KillSignal=SIGINT
TimeoutSec=15


However, as soon as I start the service with

systemctl --user start awesome.service

The unit fails with message

systemd[21209]: Failed at step GROUP spawning /home/abdo/.config/systemd/scripts/awesome.sh: Operation not permitted

Running the same service from the system systemd instance (with an already
running user-owned xorg), works as expected, creating a new session.

I think it fails setting the group for the process, it does not even get to the
PAM stuff. The user abdo is the same for which the systemd user instance is
running, of course.

Is this a bug in systemd or it's me missing something?

Thanks!

Abdó.
Abdó Roig-Maranges
2013-07-29 16:19:07 UTC
Permalink
Hi,
Then, I want to manually launch my window manager, in a new logind session for
my user, on a different tty.
I tried adding User and PAMName to my window manager unit awesome.service
<...>
The unit fails with message
systemd[21209]: Failed at step GROUP spawning /home/abdo/.config/systemd/scripts/awesome.sh: Operation not permitted
Ok, more to the point.

I think initgroups in core/execute.c always needs privileges. It is always
called when User=blah is set on a service file and always fails on systemd user
instances for unprivileged users. This prevents from using PAM within a systemd
user instance, for example.

I attach a patch that makes a call to initgroups only when we ask for a
different user than the one for the running instance (when the group access list
may be different). I'm not certain whether this would break something else,
though...

Also, there is dbus policy preventing from accessing the CreateSession method
in logind1.Manager from unprivileged users. Is this intentional?

Thanks,

Abdó Roig.
Lennart Poettering
2013-07-29 23:04:29 UTC
Permalink
Post by Abdó Roig-Maranges
Also, there is dbus policy preventing from accessing the CreateSession method
in logind1.Manager from unprivileged users. Is this intentional?
Yes it is. CreateSession()/ReleaseSession() are only used by
pam_systemd, by nobody else, and that's documented here:

http://www.freedesktop.org/wiki/Software/systemd/logind/

Lennart
--
Lennart Poettering - Red Hat, Inc.
Lennart Poettering
2013-07-29 23:06:59 UTC
Permalink
Post by Abdó Roig-Maranges
I think initgroups in core/execute.c always needs privileges. It is always
called when User=blah is set on a service file and always fails on systemd user
instances for unprivileged users. This prevents from using PAM within a systemd
user instance, for example.
Not following here. initgroups() is called before dropping prvis, so it
should always work. Can you elaborate?

Lennart
--
Lennart Poettering - Red Hat, Inc.
Abdó Roig-Maranges
2013-07-30 00:43:29 UTC
Permalink
Hi,

Thanks a lot for your explanations!
Post by Lennart Poettering
Either use a display manager or simply "update" your existing session's
tty to graphical temporarily, rather then placing things on a new
tty. (Note that the Fedora startx script does this implicitly this way)
I figured I could use a systemd unit as a sort of very thin display manager to
create a second session for my own user. I'll try using the same tty, without
extra sessions, then.
Post by Lennart Poettering
We are working on this bit by bit. If you want this to go faster, then
please work with us, and write patches for libX11 and D-Bus.
Well, this is just for my home PC... I tried managing user daemons, X, etc. via
systemd --user some time ago, and loved it! I'm just trying to do it in a way
that will not break much as the thing evolves.
Post by Lennart Poettering
Post by Abdó Roig-Maranges
I think initgroups in core/execute.c always needs privileges. It is always
called when User=blah is set on a service file and always fails on systemd user
instances for unprivileged users. This prevents from using PAM within a systemd
user instance, for example.
Not following here. initgroups() is called before dropping prvis, so it
should always work. Can you elaborate?
I was referring to the systemd --user instance running as user abdo via the
***@.service unit. Then when I started a systemd --user unit containing

User=abdo
PAMName=login

I got the GROUP error I reported. In this case the initgroups() is called as my
unprivileged user abdo because it is the user for which the systemd --user
process is running. Did I miss something? I didn't look at it very carefully,
just guessed the problem and tested a solultion that happened to work.

I understand I shouldn't do the PAM stuff from a systemd --user unit, but the
problem with group privs I encountered in systemd --user instances may still be
an issue.

Abdó Roig.
Lennart Poettering
2013-07-29 23:02:10 UTC
Permalink
Post by Abdó Roig-Maranges
Hello,
I'm happily using systemd 204 user instance to handle my desktop (xorg, awesome
wm, mpd, etc.) in Arch. I started experimenting with systemd 206 trying to adapt
my setup to the changes in cgroups, slices, and all that.
In 206, systemd user session is started automatically by pam_systemd when I
login to a tty. Then, I want to manually launch my window manager, in a new
logind session for my user, on a different tty.
This is not supported by logind. You cannot allocate sessions from other
sessions, only from the system daemon. This is because we try to keep the
various session definitions in sync, for example the audit session which
is nowadays "sealed" off by the kernel.

Either use a display manager or simply "update" your existing session's
tty to graphical temporarily, rather then placing things on a new
tty. (Note that the Fedora startx script does this implicitly this way)

Note that "systemd --user" is WIP (which is why you find very little
documentation about it from us, except the most basic reference in the
man pages). It was never supposed to be run from login sessions (it's
not called "systemd --session" but "systemd --user" for a reason) except
for debugging purposes. Recent systemd versions make this a bit harder
than before since for security reasons normal user sessions do not get
write access to their cgroup tree anymore, only ***@.service gets.

Now, ***@.service is not complete yet. To be fully useful we need some
support from X11, so that it can connect to the X11 display via
$XDG_RUNTIME_DIR/display, rather than relying on $DISPLAY. Also, D-Bus
needs to look for the bus socket in $XDG_RUNTIME_DIR too.

We are working on this bit by bit. If you want this to go faster, then
please work with us, and write patches for libX11 and D-Bus.

If you need an quick solution immediately I suggest you simply chown the
sessions cgroup tree to your own user. That's a hack, and requires
privileges, but is what I do for testing purposes.

Lennart
--
Lennart Poettering - Red Hat, Inc.
Lennart Poettering
2013-07-29 23:08:38 UTC
Permalink
Post by Lennart Poettering
Either use a display manager or simply "update" your existing session's
tty to graphical temporarily, rather then placing things on a new
tty. (Note that the Fedora startx script does this implicitly this way)
To elaborate a bit on this: this is also necessary since sessions can
only be assigned to a single TTY. However, you need the proper
tty-to-session assignment since otherwise logind+udev's device ACL
management won't work and your X session will then lack access to audio
devices, drm, or video4linux and similar...

Lennart
--
Lennart Poettering - Red Hat, Inc.
Simon McVittie
2013-07-30 19:47:32 UTC
Permalink
Also, D-Bus needs to look for the bus socket in $XDG_RUNTIME_DIR too.
If you want this to happen ("you" in general, but especially Lennart who
is a D-Bus reviewer), please review, test and/or "adopt"
<https://bugs.freedesktop.org/show_bug.cgi?id=61303>. I am unlikely to
have time to write further code for that bug any time soon, but if you
suggested additional patches I'd review them.

S
Colin Walters
2013-08-04 14:46:44 UTC
Permalink
Post by Lennart Poettering
We are working on this bit by bit. If you want this to go faster, then
please work with us, and write patches for libX11 and D-Bus.
Ok, some hacking on the plane on the way to GUADEC got me really far on
this; then we had a quick face to face to work through some conceptual
issues.

In the new user@ model, it's very important to note there is only one
"stub" process per session (at least graphical ones - whether we change
getty is a whole other topic). So for graphical, everything is launched
from ***@.service. The side effect of this is twofold:

1) Pretty much all the user processes are no longer inside a session
at all.
2) It is now much harder to log in multiple times graphically; this
is kind of a crazy thing to do, but it's still *possible*. To do
so, you wire up your userspace code to set
the pile of usual environment variables to override (DISPLAY,
DBUS_SESSION_BUS_ADDRESS, etc.) I can say though at least for
GNOME we haven't supported this for years, so it's really not
a change.

For for adapting to 1), we agreed on adding the concept of a "primary"
session, which is basically the first non-tty login. I've added a small
API to systemd to look this up, and the patched GNOME to use it
(although we partially still respect XDG_SESSION_ID).

My current patches are here:

https://people.gnome.org/~walters/user-session-patches

I've been hacking on it using gnome-ostree; if there's interest I can
toss up a VM.

Before I spend too much time polishing the patches, I'd like to be sure
the high level architecture makes sense. So please take a look at the
patches at that level; I'll split them up cleanly with better commit
messages after.

Obligatory screenshot:
Loading Image...
Oleksii Shevchuk
2013-08-04 18:02:24 UTC
Permalink
What about logind/polkit? I.e. if i start nm-applet from ***@user,
than polkit doesn't authenticate it, as it not belong to active session
Colin Walters
2013-08-04 20:20:56 UTC
Permalink
Post by Oleksii Shevchuk
than polkit doesn't authenticate it, as it not belong to active session
https://bugs.freedesktop.org/show_bug.cgi?id=67728
Colin Walters
2013-08-05 18:04:02 UTC
Permalink
Post by Oleksii Shevchuk
than polkit doesn't authenticate it, as it not belong to active session
Ok, I tossed up:

https://people.gnome.org/~walters/user-session-patches/polkit/

With this and another systemd change, I can now "pkexec bash" as I
usually do.
Simon McVittie
2013-08-05 11:24:23 UTC
Permalink
Post by Colin Walters
1) Pretty much all the user processes are no longer inside a session
at all.
2) It is now much harder to log in multiple times graphically; this
is kind of a crazy thing to do, but it's still *possible*.
How (if at all) does this cope with gdm multi-seat? Even if it isn't
possible for the same "real user" to be on more than one seat
simultaneously, if I understand it correctly, I think a multi-seat gdm
setup still wants to be running the greeter (as a system user, e.g.
Debian-gdm on Debian) on each seat.

(One possibility is to have some way for gdm to synthesize new uids, but
that needs OS-integrator-level support, e.g. a reserved uid range;
another is for each seat's greeter to set the necessary pile of extra
environment variables to avoid using the XDG_RUNTIME_DIR much, or at all.)

S
Colin Walters
2013-08-05 13:18:36 UTC
Permalink
Post by Simon McVittie
Post by Colin Walters
1) Pretty much all the user processes are no longer inside a session
at all.
2) It is now much harder to log in multiple times graphically; this
is kind of a crazy thing to do, but it's still *possible*.
How (if at all) does this cope with gdm multi-seat? Even if it isn't
possible for the same "real user" to be on more than one seat
simultaneously, if I understand it correctly, I think a multi-seat gdm
setup still wants to be running the greeter (as a system user, e.g.
Debian-gdm on Debian) on each seat.
With my current patches, GDM still launches the greeter itself in the
same way it was before - I believe multi-seat will still work, becuase
gdm sets the environment variables for each greeter session.

Doing the greeter session multiseat would probably be something like
gnome-***@seat0.service, which in turn would really require breaking
up gnome-session into component parts and having
org.gnome.SessionManager.seat0 because with the user bus because there's
only one org.gnome.SessionManager bus name...but then...ugh.

Ok, maybe you're right that dynamically generating uids would be easier.

But honestly, rearchitecting the greeter session is really low on my
priority list - the most important thing is to get applications in
cgroups. So we can just leave it as is for the near future.
Colin Walters
2013-08-05 19:55:35 UTC
Permalink
Post by Colin Walters
https://people.gnome.org/~walters/user-session-patches
Now updated with various bugfixes. PolicyKit works, the lock screen
works, etc.

However...let me call out one particular change:

diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 7b9bd20..2fab003 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -485,6 +485,10 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) {
}

r = manager_get_session_by_pid(m, leader, &session);
+ if (!session) {
+ /* Fall back to the primary session */
+ r = manager_get_primary_session_by_pid(m, leader, &session);
+ }
if (session) {
_cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
_cleanup_free_ char *path = NULL;

I had to patch logind itself to have pkexec work (and similar would
apply to su/sudo). At this point I think I've patched pretty much all
the interesting session lookup calls to fall back to primary. Perhaps
that's not wrong, but it does give one pause. I could just change
sd_pid_get_session() to do that by default...

Or maybe we should spawn ***@.service from inside the first session,
and treat that as primary; add a new state like "user-linger" that
occurs if the user logs in twice, then closes the first one.

It would feel a lot less architecturally weird too if we changed getty
and ssh logins to behave the same way as gdm - i.e. we have
***@.service, and keep around a dummy process.

So...dunno, it does feel hacky in some ways.

On the other hand, I'm *really* looking forward to being able to just
ssh/VT login into a machine and be able to run e.g. "gdbus monitor" and
"gsettings".
Kok, Auke-jan H
2013-08-05 22:38:14 UTC
Permalink
Post by Colin Walters
Post by Colin Walters
https://people.gnome.org/~walters/user-session-patches
Now updated with various bugfixes. PolicyKit works, the lock screen
works, etc.
just chiming in here... it's like you knew it was my birthday this week! :^)
Post by Colin Walters
and treat that as primary; add a new state like "user-linger" that
occurs if the user logs in twice, then closes the first one.
It would feel a lot less architecturally weird too if we changed getty
and ssh logins to behave the same way as gdm - i.e. we have
So...dunno, it does feel hacky in some ways.
On the other hand, I'm *really* looking forward to being able to just
ssh/VT login into a machine and be able to run e.g. "gdbus monitor" and
"gsettings".
so, most of the patches look very reasonable to me, and I don't see
anything wrong. I wondered, just like Simon, if multi-user is still
working as well

Other than that, please keep up the good work, this is something I've
been looking forward to seeing for over a year now.

Auke
Tom Gundersen
2014-01-05 14:31:27 UTC
Permalink
Hi Colin,

I realise this thread may be out-of-date by now, so please excuse me
if I'm commenting on something which has later changed.
Post by Colin Walters
Post by Lennart Poettering
We are working on this bit by bit. If you want this to go faster, then
please work with us, and write patches for libX11 and D-Bus.
Ok, some hacking on the plane on the way to GUADEC got me really far on
this; then we had a quick face to face to work through some conceptual
issues.
"stub" process per session (at least graphical ones - whether we change
getty is a whole other topic). So for graphical, everything is launched
1) Pretty much all the user processes are no longer inside a session
at all.
2) It is now much harder to log in multiple times graphically; this
is kind of a crazy thing to do, but it's still *possible*. To do
so, you wire up your userspace code to set
the pile of usual environment variables to override (DISPLAY,
DBUS_SESSION_BUS_ADDRESS, etc.) I can say though at least for
GNOME we haven't supported this for years, so it's really not
a change.
For for adapting to 1), we agreed on adding the concept of a "primary"
session, which is basically the first non-tty login. I've added a small
API to systemd to look this up, and the patched GNOME to use it
(although we partially still respect XDG_SESSION_ID).
Hm, I'm not really happy with the notion of a "primary" session,
particularly as it relies on distinguishing between graphical and
non-graphical sessions (where does the line go between a traditional
VT, systemd-consoled, kmscon, wayland, X,...). And also relying on
something being the "first" sounds like it may become confusing for
the user.

Have you considered taking things one step further, and simply force
at most one logind session per user? This would mean that logging in
as the same user the second time means the new login will join the
already existing session. We then get:

* If at most one of the logins is associated with a seat (and the
rest are remote), things will work just as now.

* If two logins (of the same user) are associated with different
seats, this is not really supported at the moment, so we could ban it,
or we could simply allow it and temporarily merge the two seats and
let the session controller (window manager) deal with how that should
be presented to the user. This would probably mean that we want
logind's interfaces for getting hardware devices should be per-user,
and not per-session.

* If two logins (of the same user) are both associated with the same
seat, we'll have to allow switching between the two apps being the
session controller within the same session (this is a common use-case
for when you login once with consoled and once with mutter, or
something like that).

Cheers,

Tom
Colin Walters
2014-01-08 15:29:20 UTC
Permalink
[ I'm going to trim the CC, I'm pretty sure everyone who has commented
so far is on systemd-devel ]
This basically defeats the whole purpose of a session.
A lot of it, yes. The session becomes:

* A refcount on the ***@.service
* A claim of particular devices (tty, X server)
If you now do
session.kill(), you kill both logins. That's not intentional, I guess.
No. The only process actually in the session cgroup would be a stub.
Asking logind to kill it would cause it to release the fd and hence drop
Post by Tom Gundersen
* If two logins (of the same user) are associated with different
seats, this is not really supported at the moment, so we could ban it,
or we could simply allow it and temporarily merge the two seats and
let the session controller (window manager) deal with how that should
be presented to the user. This would probably mean that we want
logind's interfaces for getting hardware devices should be per-user,
and not per-session.
Yeah...this bit is tricky. For the case of GNOME where it's simply
not supported to log in multiple times, all we need is a mechanism to
discover the X server that gdm spawned (not as part of the session or
***@.service).

The way that works in my prototype patches is that GDM sets the
x11-display property via PAM, and then systemd writes that to
$XDG_RUNTIME_DIR.

Continue reading on narkive:
Loading...