From 9681c16aa9fae4dd158d29377f4b61f42fbbe96c Mon Sep 17 00:00:00 2001 From: Erick Shepherd Date: Mon, 17 Aug 2026 11:49:20 -0500 Subject: [PATCH] libpam: Add a patch to allow null passwords Add a patch to linux-pam that allows users to set a blank password when using the passwd command and when updating an expired password. This is done by not setting "\0" passwords to NULL and setting the password hash to be blank for "\0" passwords. The change is toggled using the existing nullok option for linux-pam. Signed-off-by: Erick Shepherd --- ...am_unix_passwd-allow-blank-passwords.patch | 77 +++++++++++++++++++ recipes-extended/pam/libpam_1.%.bbappend | 3 + 2 files changed, 80 insertions(+) create mode 100644 recipes-extended/pam/libpam/0001-pam_unix_passwd-allow-blank-passwords.patch 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" }