[systemd-devel] Crond session, pam_access and pam_systemd
Mantas Mikulėnas
grawity at gmail.com
Fri Oct 16 11:22:27 UTC 2020
On Fri, Oct 16, 2020 at 1:41 PM Thomas HUMMEL <thomas.hummel at pasteur.fr>
wrote:
> Hello,
>
> if I try to sum up all of your answers, I come to the following
> understanding :
>
> - sessions are always created via the pam_systemd module
> - which is, in my case called (sshd, crond) via the password-auth stack
> include
> - so crond, through pam_systemd will cause a session to be created
>
If you specifically mean systemd-logind sessions, yes.
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.
> - such session is created via the sd-pam helper responsible for
> pam_open_session() and pam_close_session() calls
>
Not exactly. For cron and sshd, all those PAM functions are called directly
by cron or sshd themselves.
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.
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()
systemd-logind
└ receives CreateSession(uid=1000)
├ DBus call to systemd: Start(user at 1000.service)
└ DBus call to systemd: StartTransientUnit(session-1234.scope)
systemd (pid1)
└ user at 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 at .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.
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 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'.
> - so a user crontab will ultimately cause the use of the already running
> systemd --user instance of the user (because his logged in or is
> lingered) OR the creation of a systemd --user instance for the purpose
> of the crond session creation
>
Yes, more or less.
>
> What I still don't quite get is :
>
> - is it sd-pam or systemd --user or user@<uid>.service holding them
> which uses the systemd-user pam service name ?
>
user@<uid>.service is where the name is configured, but sd-pam is the
process which actually calls PAM for that service name.
systemd --user on its own doesn't talk to PAM at all. (See what I wrote
above about the sd-pam worker.)
>
> - my understanding was that pam service name is passed to pam_start() :
> in the user crontab case, my guess is that crond does this call with the
> crond service name (so pam knows what module stacks to run).
> So this would mean something like the user@<uid>.service (or sd-pam)
> would itself call pam_start(systemd-user, ...) when called by pam_systemd ?
>
Yes.
>
> So basically pam_systemd module would trigger another service which
> itself would go through pam with the systemd-user service name ?
>
Yes.
>
> - again, why is a first ssh login session able to create the user
> session without the user having to be listed for systemd-user in
> access.conf whereas crond semmes to need it (givent no systemd --user
> was previously running in both cases) ?
>
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 at .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`.
--
Mantas Mikulėnas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20201016/2da8655b/attachment.htm>
More information about the systemd-devel
mailing list