On 16/10/2020 13:22, Mantas Mikulėnas wrote:
But I think you're still confusing the two different kinds of "sessions"
that exist here. PAM open_session creates a PAM session, which
eventually *causes* a systemd-logind session to be created, but isn't
100% the same thing.
Yes I probably did.
My undestanding is that a pam session is anything pam modules do between
pam_open_session() and pam_close_session(), which could be things like
write to /var/run/utmp for instance and a systemd-logind session is just
a scope holding all a user processes between his login and logout
Not exactly. For cron and sshd, all those PAM functions are called
directly by cron or sshd themselves.
Ok. That's indeed what I thought initially, being later confused by the
sd-pam thing.
The sd-pam helper only does this task when systemd pid1 (the service
manager) needs to call PAM for a service that has PAMName= set in its unit.
https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PAMName=
describes sd-pam as a pam session handler when a service unit uses
PAMNane= indeed (sorry, I didn't read it before - hence the confusion)
[By the way I don't know how a child process can wait for its parent -
waiting for its parent to send a signal ?]
As far as I could figure out, the entire process works like this:
sshd (listener)
└ sshd (connection worker)
├ pam_start(sshd, ...)
├ pam_acct_mgmt()
│ └ pam_access.so
├ pam_open_session()
│ └ pam_systemd.so
│ └ DBus call to systemd-logind: CreateSession(service=sshd, uid=1000)
├ fork login shell
│ └ /bin/bash
└ pam_close_session()
Ok. So pam_systemd registers a (systemd-logind) session via dbus to
systemd-logind. This session will contain the ssh login shell and so on.
systemd-logind
└ receives CreateSession(uid=1000)
├ DBus call to systemd: Start(user@1000.service)
└ DBus call to systemd: StartTransientUnit(session-1234.scope)
See comment at the end.
systemd (pid1)
└ user@1000.service
└ sd-pam
├ pam_start(systemd-user, ...)
├ pam_acct_mgmt()
│ └ pam_access.so
├ pam_open_session()
├ fork sd-pam child
│ └ sd-pam (waits for parent to exit)
│ └ pam_close_session()
└ exec systemd --user
- such a worker is started by a systemd --user instance
No, it's actually started by the systemd system manager itself, because
user@.service has PAMName= set. It only *appears* to be a child of
systemd --user, because it is a child of the process which first forked
sd-pam, then exec'd systemd --user.
So basically user@<uid>.service is a service using PAMName=systemd-user
with an sd-pam pam session handler and which main process (similar to an
ExecStart in a standard service unit) is systemd --user correct ?
Why has it got to work the other way around compared to as service
wainting for its child to finish to call pam_close_session() as you said ?
Most tools (sudo, sshd, crond) handle all PAM calls in the parent
process, just forking your shell or cronjob as a child, then waiting for
the child to exit before they can call pam_close_session(). Systemd does
it the other way around – it also forks, but the *child* waits for the
parent to exit before calling pam_close_session(), whereas the parent
directly execs the ExecStart command.
So the second sd-pam you mentionned in your tree above is this handler
mentionnend in the doc I mentionned and waiting for systemd --user to
finish to take proper action when closing the pam session ?
So if you had a basic unit with "ExecStart=/bin/sleep 1h", if it also
had User= and PAMName=, then you would see 'sd-pam' as a child of 'sleep
1h'.
Ok.
user@<uid>.service is where the name is configured, but sd-pam is the
process which actually calls PAM for that service name.
Ok.
I don't know why you're seeing the different behavior between crond and
sshd.
However, a systemd-logind session doesn't actually *need* user@.service
(systemd --user), it can be created without. So even if
user@<uid>.service could not be started due to PAM not authorizing it
(or due to some other reason), this will still not prevent pam_systemd
from registering the session and creating user-<uid>.slice and making it
appear in `loginctl`.
Ok.
Regarding the following part :
> systemd-logind
> └ receives CreateSession(uid=1000)
> ├ DBus call to systemd: Start(user@1000.service)
> └ DBus call to systemd: StartTransientUnit(session-1234.scope)
Since you said systemd-logind does not need systemd --user to creates
the session I guess the second job (start transient unit) can be done
without it. So can I conclude that this is just the way systemd-logind
is designed : when instructed to create a session, it also start the
user@<uid>.service just for the user to be able to use its own systemd
instance (which in my case of user crontab is not used) ?
I all of my guesses are correct I still have to figure out the exact
problem I had when the user (who had a crontab) was not allowed to
access systemd-user pam service.
Thanks for your help
--
Thomas HUMMEL
_______________________________________________
systemd-devel mailing list
systemd-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/systemd-devel