diff --git a/recipes-extended/pam/libpam/0001-pam_unix_passwd-allow-blank-passwords.patch b/recipes-extended/pam/libpam/0001-pam_unix_passwd-allow-blank-passwords.patch new file mode 100644 index 000000000..c67f8247d --- /dev/null +++ b/recipes-extended/pam/libpam/0001-pam_unix_passwd-allow-blank-passwords.patch @@ -0,0 +1,77 @@ +From f285df521f3a63515615d6e7ad39a3cd5e18d88f Mon Sep 17 00:00:00 2001 +From: Erick Shepherd +Date: Mon, 17 Aug 2026 11:36:50 -0500 +Subject: [PATCH] pam_unix_passwd: Allow empty password to be set + +Upstream-Status: Inappropriate [NI specific] + +Allow users to set a blank password using linux-pam by no longer +setting blank passwords to NULL and making their shadow file entry +blank. This is toggled by the nullok option. + +Signed-off-by: Erick Shepherd +--- + modules/pam_unix/pam_unix.8.xml | 4 ++-- + modules/pam_unix/pam_unix_passwd.c | 10 ++++++++-- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml +index d2cd198f..7f95beeb 100644 +--- a/modules/pam_unix/pam_unix.8.xml ++++ b/modules/pam_unix/pam_unix.8.xml +@@ -155,8 +155,8 @@ + + + The default action of this module is to not permit the +- user access to a service if their official password is blank. +- The argument overrides this default. ++ user access to a service if their official password is blank ++ or allow blank passwords to be set during password changes. + + + +diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c +index c01fd56b..b8ac9688 100644 +--- a/modules/pam_unix/pam_unix_passwd.c ++++ b/modules/pam_unix/pam_unix_passwd.c +@@ -593,6 +593,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) + int remember = -1; + int rounds = 0; + int pass_min_len = 0; ++ int nullok_enabled = 0; + struct passwd *pwd; + + /* */ +@@ -605,6 +606,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) + + ctrl = _set_ctrl(pamh, flags, &remember, &rounds, &pass_min_len, + argc, argv); ++ nullok_enabled = off(UNIX__NONULL, ctrl); + + /* + * First get the name of a user +@@ -772,7 +774,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) + * password is acceptable. + */ + +- if (*pass_new == '\0') { /* "\0" password = NULL */ ++ if (!nullok_enabled && pass_new != NULL && *pass_new == '\0') { + pass_new = NULL; + } + retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, +@@ -828,7 +830,11 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) + * First we encrypt the new password. + */ + +- tpass = create_password_hash(pamh, pass_new, ctrl, rounds); ++ if (pass_new != NULL && *pass_new == '\0') { ++ tpass = strdup(""); ++ } else { ++ tpass = create_password_hash(pamh, pass_new, ctrl, rounds); ++ } + if (tpass == NULL) { + pam_syslog(pamh, LOG_CRIT, + "crypt() failure or out of memory for password"); +-- +2.51.0 + diff --git a/recipes-extended/pam/libpam_1.%.bbappend b/recipes-extended/pam/libpam_1.%.bbappend index eee710fd4..0dd48fa4f 100644 --- a/recipes-extended/pam/libpam_1.%.bbappend +++ b/recipes-extended/pam/libpam_1.%.bbappend @@ -3,6 +3,7 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" RDEPENDS:${PN} += "ni-acctsync pam-plugin-exec" SRC_URI += "\ + file://0001-pam_unix_passwd-allow-blank-passwords.patch \ file://security/faillock.conf \ file://scripts/ni-acctsync-pam \ " @@ -10,6 +11,8 @@ SRC_URI += "\ do_install:append() { install -m 644 ${UNPACKDIR}/security/faillock.conf ${D}${sysconfdir}/security/faillock.conf install -m 700 ${UNPACKDIR}/scripts/ni-acctsync-pam ${D}${sbindir}/ni-acctsync-pam + grep -qE 'pam_unix\.so.*[[:space:]]nullok([[:space:]]|$)' "${D}${sysconfdir}/pam.d/common-password" || \ + sed -i -E '/pam_unix\.so/ s/(pam_unix\.so)([[:space:]]+)/\1\2nullok /' "${D}${sysconfdir}/pam.d/common-password" sed -E -i '/^password[[:space:]]+requisite[[:space:]]+pam_deny\.so$/a password\toptional\t\t\tpam_exec.so /usr/sbin/ni-acctsync-pam' "${D}${sysconfdir}/pam.d/common-password" }