Re: Crond session, pam_access and pam_systemd

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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




[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux