diff --git a/playbook/pxe_server_setup.yml b/playbook/pxe_server_setup.yml index 1d074df..6698e07 100644 --- a/playbook/pxe_server_setup.yml +++ b/playbook/pxe_server_setup.yml @@ -400,16 +400,24 @@ the Blancco preferences). Fix them in playbook/site-vars.yml and re-run. quiet: yes + # MATCH / DIFF / UNKNOWN: does pxe's shadow hash match $PW? crypt() + # handles every scheme (the autoinstall hash is $6$, chpasswd and passwd + # write yescrypt $y$). Used by the two Admin tasks below. - name: "Admin: is the Linux pxe login still the shipped password?" - shell: | - h=$(getent shadow pxe | cut -d: -f2) - case "$h" in - '$6$'*) salt=$(printf '%s' "$h" | cut -d'$' -f3) - if [ "$(printf 'pxe' | openssl passwd -6 -salt "$salt" -stdin)" = "$h" ]; then echo DEFAULT; else echo SITE; fi ;; - *) echo UNKNOWN ;; - esac - args: - executable: /bin/bash + shell: &pxe_pw_compare | + python3 -W ignore - <<'PY' + import os, subprocess + try: + import crypt + except ImportError: + print("UNKNOWN"); raise SystemExit + h = subprocess.run(["getent", "shadow", "pxe"], capture_output=True, text=True).stdout.split(":") + h = h[1] if len(h) > 1 else "" + print("MATCH" if h.startswith("$") and crypt.crypt(os.environ["PW"], h) == h else + "DIFF" if h.startswith("$") else "UNKNOWN") + PY + environment: + PW: "pxe" register: pxe_admin_state changed_when: false @@ -417,7 +425,7 @@ assert: that: - pxe_admin_password is string - - pxe_admin_password | length > 0 or pxe_admin_state.stdout != 'DEFAULT' + - pxe_admin_password | length > 0 or pxe_admin_state.stdout != 'MATCH' - pxe_admin_password | length == 0 or (pxe_admin_password | length >= 8 and pxe_admin_password | length <= 128) - pxe_admin_password | length == 0 or pxe_admin_password is not search('[\x00-\x1f]') - pxe_admin_password != 'pxe' @@ -1551,24 +1559,22 @@ changed_when: "'created' in smb_users.stdout" no_log: true - - name: "Admin: set the Linux pxe password from pxe_admin_password" - shell: | - h=$(getent shadow pxe | cut -d: -f2) - salt=$(printf '%s' "$h" | cut -d'$' -f3) - if [ -n "$salt" ] && [ "$(printf '%s' "$PW" | openssl passwd -6 -salt "$salt" -stdin)" = "$h" ]; then - echo UNCHANGED - else - printf 'pxe:%s\n' "$PW" | chpasswd && echo CHANGED - fi + - name: "Admin: does the Linux pxe password already match pxe_admin_password?" + shell: *pxe_pw_compare environment: PW: "{{ pxe_admin_password }}" - args: - executable: /bin/bash - register: pxe_admin_set - changed_when: "'CHANGED' in pxe_admin_set.stdout" + register: pxe_admin_cur + changed_when: false when: pxe_admin_password | length > 0 no_log: true + - name: "Admin: set the Linux pxe password from pxe_admin_password" + shell: printf 'pxe:%s\n' "$PW" | chpasswd + environment: + PW: "{{ pxe_admin_password }}" + when: pxe_admin_password | length > 0 and pxe_admin_cur.stdout != 'MATCH' + no_log: true + - name: "Deploy nf_conntrack TCP timeout sysctl for PXE workload" copy: src: "{{ usb_mount }}/pxe-server-helpers/99-pxe-conntrack.conf" diff --git a/webapp/services/blancco_update.py b/webapp/services/blancco_update.py index f61d376..3407e4c 100644 --- a/webapp/services/blancco_update.py +++ b/webapp/services/blancco_update.py @@ -1011,10 +1011,15 @@ def refresh_live_prefs(): ours = f.read() try: new = patch_config_img(cfg, ours) - except (StageBlocked, ValueError) as e: - warning = (f"the live config.img (BIOS boot) was not updated: {e} " + except StageBlocked: + live = prefs_version(cpio_member(cfg, "preferences.xml") or b"") or "?" + warning = (f"the live config.img (BIOS boot) is Blancco {live}, older than our " + f"{prefs_version(ours) or '?'} preferences, so it was not updated. " "Stage a current release on Updates > Blancco releases.") new = cfg + except ValueError as e: + warning = f"the live config.img (BIOS boot) was not updated: {e}" + new = cfg if new != cfg: _atomic_write(cfg_path, new) changed = True diff --git a/webapp/tests/test_share_accounts.py b/webapp/tests/test_share_accounts.py index 53560c2..3e5f33b 100644 --- a/webapp/tests/test_share_accounts.py +++ b/webapp/tests/test_share_accounts.py @@ -190,7 +190,8 @@ class ShareAccounts(Fixture): with open(os.path.join(BU.blancco_root(), "config.img"), "wb") as f: f.write(cfg) done = SA.set_password("blancco", PW) - self.assertTrue(any("WARNING" in d and "config.img" in d for d in done), done) + self.assertTrue(any("WARNING" in d and "config.img (BIOS boot) is Blancco 7.15" in d + and "older than our 7.20" in d for d in done), done) with open(BP.served_prefs_path(), "rb") as f: self.assertEqual(self.prefs_share_pw(f.read()), PW) with open(os.path.join(BU.blancco_root(), "config.img"), "rb") as f: