fix(pam): pass profile names to pam-auth-update --remove#376
Conversation
pam-auth-update --remove matches pam-config filenames under /usr/share/pam-configs/, but prerm and postrm passed $DPKG_MAINTSCRIPT_PACKAGE -- the package name security-misc-shared -- which matches no profile and is silently ignored. The prerm early-disable was therefore dead: on removal, /etc/pam.d/common-* kept referencing helper scripts under /usr/libexec/security-misc/ that dpkg then deleted, risking failed authentication (block-unsafe-logins is a Priority 1100 requisite entry). prerm now passes the eight profile filenames explicitly, guarded by command -v so a bulk purge cannot abort under set -e. postrm drops the ineffective --remove for a plain reconciliation scoped to remove|purge|disappear, so it never strips live hardening during an upgrade or abort.
|
Have you been able to reproduce this bug - what bug exactly? And was this PR tested and known to fix the issue? |
|
Looking at the pam-update-auth documentation, I think this change is probably good, though I need to make sure that the arguments being checked for in prerm make sense. @adrelanos The bug is:
The solution is to remove PAM configuration from
An easy way to reproduce the issue is to make if [ "${DPKG_MAINTSCRIPT_PACKAGE}" = 'security-misc-shared' ] \
&& [ "${DPKG_MAINTSCRIPT_NAME}" = 'postrm' ] \
&& [[ "${1}" =~ ^(remove|purge) ]]; then
exit 1
fiThen run So if this PR doesn't break anything and does fix the above, it's good. |
| ## config files are still present and '--remove' would strip live hardening | ||
| ## mid-transaction, so those states are deliberately not matched here. | ||
| case "$1" in | ||
| remove|purge|disappear) |
There was a problem hiding this comment.
Should we match failed-upgrade, abort-install, and abort-upgrade too? (See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#summary-of-ways-maintainer-scripts-are-called, specifically the subsection about how the postrm script may be called.) I don't think this will be problematic for any of these (or for upgrade, for that matter), and it might not be redundant in any of those situations. (It is redundant for upgrade though, since the postinst will have already called pam-auth-update.)
Summary
The
prerm/postrmscripts try to disable this package's PAM profiles when thepackage is removed, but they pass the package name to
pam-auth-update --remove,which matches profile filenames — so the removal was silently a no-op. This
restores the intended early-disable and hardens the removal path across dpkg states.
Changes
pam-auth-update --removematches the config filenames in/usr/share/pam-configs/(readdir basenames), never the package name. Bothscripts passed
$DPKG_MAINTSCRIPT_PACKAGE(security-misc-shared), matching noprofile, so nothing was removed. An unknown target is not validated and never
errors, so it failed silently. The
prermearly-disable was therefore dead:on removal,
/etc/pam.d/common-*kept referencing helper scripts under/usr/libexec/security-misc/that dpkg then deleted — andblock-unsafe-loginsis a Priority 1100
requisite, so a dangling reference fails all logins.prerm: pass the 8 actual profile filenames to--remove, guarded bycommand -v pam-auth-update. This is the man-page-documented purpose of--remove: strip profiles before the modules they reference leave disk.postrm: replace the inert--remove <pkg>with a plainpam-auth-update --packagereconciliation scoped toremove|purge|disappear,so
upgrade/abort-*never strip live hardening mid-transaction.Testing
security-misc-shared.deb (the actual profiles, the referencedhelper scripts, and these maintainer scripts) and ran install →
dpkg -r→dpkg -Pindebian:stable-slim— 11/11 checks passed. Crux: same tree,only the
--removeargument differs —--remove security-misc-sharedleft theprofile in
common-auth(old no-op reproduced), while--remove <8 filenames>removed it with the files still on disk;
dpkg -r/-Pexited 0 withcommon-*cleaned before the helper was deleted.postrminvoked pam-auth-update only forremove/purge/disappear(notupgrade/abort-upgrade/abort-install/failed-upgrade/deconfigure), andpostrm purgeexited 0 withpam-auth-update absent from
PATH.bash -npasses on both scripts;shellcheckis clean on the changed blocks.Notes for reviewers
reconciliation already drops the profiles once their files are gone. This fix
restores the
prermearly-disable that closes the window wherecommon-authreferences a just-deleted module; it is a correctness/robustness fix, not a
fix for a failure users currently hit.
postrmkeeps a plain--package(rather than dropping the call)as a safety net for profile-list drift and the
disappearstate, whereprermnever runs. A real
--remove <profiles>there was deliberately avoided — itwould strip live hardening during
upgrade/abort-*.prermmust stay in sync withdebian/security-misc-shared.installandusr/share/pam-configs/; a forgottenprofile is still reconciled away by the
postrmnet within the same dpkg run.