Page MenuHomeFreeBSD

cron: Implement full PAM session lifecycle for user jobs
ClosedPublic

Authored by delphij on Tue, Dec 30, 5:10 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Jan 22, 1:12 PM
Unknown Object (File)
Wed, Jan 21, 12:54 PM
Unknown Object (File)
Wed, Jan 21, 12:23 AM
Unknown Object (File)
Tue, Jan 20, 8:32 AM
Unknown Object (File)
Mon, Jan 19, 9:18 AM
Unknown Object (File)
Fri, Jan 16, 7:51 AM
Unknown Object (File)
Tue, Jan 13, 8:31 PM
Unknown Object (File)
Mon, Jan 12, 7:56 AM
Subscribers

Details

Summary

Extend PAM integration beyond account checks to include credential
establishment and session management, allowing PAM modules to configure
the execution environment for user cron jobs.

Previously, cron only called pam_acct_mgmt() to verify account validity
but immediately terminated the PAM handle before job execution. This
prevented PAM modules from establishing sessions, setting credentials
(e.g., Kerberos tickets), or exporting environment variables needed by
jobs.

The PAM handle now persists in the intermediate process throughout the
job execution, enabling proper session open/close pairing. Credentials
are established and sessions opened while still running as root, before
dropping privileges in the grandchild. PAM environment variables are
exported in the job process with user crontab variables taking precedence.

A session rule (pam_permit.so) is added to /etc/pam.d/cron to enable
session support without changing default behavior. Administrators can
replace this with other modules as needed.

System crontab entries continue to bypass all PAM operations.

MFC after: 2 weeks

Test Plan

Test with pam_deny.so as session provider: system crontab continues to work and user crontab fails.
Test with pam_xdg.so as session provider: env shall show XDG_RUNTIME_DIR set, while not showing it before.
Test with pam_lastlog.so: pam_open_session and pam_close_session were called.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

usr.sbin/cron/cron/do_command.c
487

There is a ton of unnecessary complexity here which seems to arise from a desire to have cron's environment variables override the ones provided by PAM. You could avoid all that complexity by simply applying the PAM environment first.

delphij added inline comments.
usr.sbin/cron/cron/do_command.c
487

Thanks for catching this.

delphij marked an inline comment as done.

Address des@'s comment: Move application of PAM environment to a better place.

usr.sbin/cron/cron/do_command.c
455–474

None of this is needed, you can just putenv(*pp)

Address des@'s review: Use putenv() instead of duplicating the work.

delphij added inline comments.
usr.sbin/cron/cron/do_command.c
455–474

I think new code is expected to use setenv() but probably not worth the added complexity right now so I've changed the code to use putenv() instead.

des added inline comments.
usr.sbin/cron/cron/do_command.c
467

You are right not to free the individual strings, but you can safely free pam_envp itself since it's just an array of pointers to the actual strings.

This revision is now accepted and ready to land.Tue, Jan 20, 1:03 PM
delphij marked an inline comment as done.