Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package himmelblau for openSUSE:Factory 
checked in at 2026-06-12 19:27:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/himmelblau (Old)
 and      /work/SRC/openSUSE:Factory/.himmelblau.new.1981 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "himmelblau"

Fri Jun 12 19:27:01 2026 rev:50 rq:1358755 version:3.1.7+git0.f4e43ca0

Changes:
--------
--- /work/SRC/openSUSE:Factory/himmelblau/himmelblau.changes    2026-06-11 
17:29:15.567106808 +0200
+++ /work/SRC/openSUSE:Factory/.himmelblau.new.1981/himmelblau.changes  
2026-06-12 19:27:38.298476638 +0200
@@ -1,0 +2,15 @@
+Thu Jun 11 15:47:43 UTC 2026 - David Mulder <[email protected]>
+
+- Update to version 3.1.7+git0.f4e43ca0:
+  * cargo vet
+  * Version 3.1.7
+  * sso: fix Chrome ExtensionInstallForcelist missing update URL
+  * Continue the never-ending chase for SELinux support
+  * Respect configured remote service deny list
+  * Retry enrollment with MFA on strong auth errors
+  * nss: reject non-directory names before GetCredentialType probe
+  * Update libhimmelblau to latest version
+  * deps(rust): bump the all-cargo-updates group across 1 directory with 10 
updates
+  * ci: automate OBS stable branch submissions
+
+-------------------------------------------------------------------

Old:
----
  himmelblau-3.1.6+git0.102ee045.tar.bz2

New:
----
  himmelblau-3.1.7+git0.f4e43ca0.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ himmelblau.spec ++++++
--- /var/tmp/diff_new_pack.CDAKrC/_old  2026-06-12 19:27:45.802790634 +0200
+++ /var/tmp/diff_new_pack.CDAKrC/_new  2026-06-12 19:27:45.802790634 +0200
@@ -30,7 +30,7 @@
 %endif
 
 Name:           himmelblau
-Version:        3.1.6+git0.102ee045
+Version:        3.1.7+git0.f4e43ca0
 Release:        0
 Summary:        Interoperability suite for Microsoft Azure Entra Id
 License:        GPL-3.0-or-later

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.CDAKrC/_old  2026-06-12 19:27:45.866793312 +0200
+++ /var/tmp/diff_new_pack.CDAKrC/_new  2026-06-12 19:27:45.886794149 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/himmelblau-idm/himmelblau.git</param>
-              <param 
name="changesrevision">102ee045d192c2317af90461ea76f188e3728f0a</param></service></servicedata>
+              <param 
name="changesrevision">f4e43ca0f7c296027c9b26ec0cff3d385626c179</param></service></servicedata>
 (No newline at EOF)
 

++++++ himmelblau-3.1.6+git0.102ee045.tar.bz2 -> 
himmelblau-3.1.7+git0.f4e43ca0.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/himmelblau-3.1.6+git0.102ee045/Cargo.lock 
new/himmelblau-3.1.7+git0.f4e43ca0/Cargo.lock
--- old/himmelblau-3.1.6+git0.102ee045/Cargo.lock       2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/Cargo.lock       2026-06-11 
17:46:50.000000000 +0200
@@ -4,7 +4,7 @@
 
 [[package]]
 name = "aad-tool"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "anyhow",
  "broker-client",
@@ -504,7 +504,7 @@
  "quote",
  "regex",
  "rustc-hash",
- "shlex",
+ "shlex 1.3.0",
  "syn",
 ]
 
@@ -611,7 +611,7 @@
 
 [[package]]
 name = "broker"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "dbus",
  "himmelblau_unix_common",
@@ -622,13 +622,22 @@
 
 [[package]]
 name = "broker-client"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "serde_json",
  "zbus",
 ]
 
 [[package]]
+name = "bs58"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
 name = "bumpalo"
 version = "3.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -698,14 +707,14 @@
 
 [[package]]
 name = "cc"
-version = "1.2.61"
+version = "1.2.63"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
+checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f"
 dependencies = [
  "find-msvc-tools",
  "jobserver",
  "libc",
- "shlex",
+ "shlex 2.0.1",
 ]
 
 [[package]]
@@ -805,9 +814,9 @@
 
 [[package]]
 name = "clap_complete"
-version = "4.6.3"
+version = "4.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "660c0520455b1013b9bcb0393d5f643d7e4454fb69c915b8d6d2aa0e9a45acc3"
+checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772"
 dependencies = [
  "clap",
 ]
@@ -1994,9 +2003,9 @@
 
 [[package]]
 name = "hashbrown"
-version = "0.17.0"
+version = "0.17.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
 dependencies = [
  "allocator-api2",
  "equivalent",
@@ -2050,7 +2059,7 @@
 
 [[package]]
 name = "himmelblau-fuzz"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "arbitrary",
  "himmelblau_unix_common",
@@ -2062,7 +2071,7 @@
 
 [[package]]
 name = "himmelblau_policies"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -2084,7 +2093,7 @@
 
 [[package]]
 name = "himmelblau_unix_common"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -2096,7 +2105,7 @@
  "csv",
  "der 0.8.0",
  "futures",
- "hashbrown 0.17.0",
+ "hashbrown 0.17.1",
  "hostname",
  "idmap",
  "kanidm-hsm-crypto",
@@ -2133,7 +2142,7 @@
 
 [[package]]
 name = "himmelblaud"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "async-trait",
  "base64 0.22.1",
@@ -2522,7 +2531,7 @@
 
 [[package]]
 name = "idmap"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "bindgen",
  "cc",
@@ -2881,9 +2890,9 @@
 
 [[package]]
 name = "libhimmelblau"
-version = "0.8.20"
+version = "0.8.22"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c0aced2dc4e76ba0a04043e9b9eb87569fc7e9f9bebe89ce734986cf3ac0df49"
+checksum = "c7700c683c5b50b51fcc3e616a6e97e6c913773bce34091017f777b0bcabe413"
 dependencies = [
  "base64 0.22.1",
  "cbindgen",
@@ -2896,7 +2905,7 @@
  "libkrimes",
  "openssl",
  "os-release",
- "paste",
+ "pastey 0.2.3",
  "pem-rfc7468",
  "percent-encoding",
  "picky-asn1",
@@ -3071,7 +3080,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "8a860605968fce16869fd239cf4237a82f3ac470723415db603b0e8b6c8d4fb9"
 dependencies = [
- "hashbrown 0.17.0",
+ "hashbrown 0.17.1",
 ]
 
 [[package]]
@@ -3274,7 +3283,7 @@
 
 [[package]]
 name = "nss_himmelblau"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "himmelblau_unix_common",
  "lazy_static",
@@ -3380,7 +3389,7 @@
 
 [[package]]
 name = "o365"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "anyhow",
  "reqwest 0.12.24",
@@ -3667,7 +3676,7 @@
 
 [[package]]
 name = "pam_himmelblau"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "himmelblau_unix_common",
  "libc",
@@ -3722,7 +3731,7 @@
 name = "paste"
 version = "1.0.15"
 dependencies = [
- "pastey 0.2.2",
+ "pastey 0.2.3",
 ]
 
 [[package]]
@@ -3733,9 +3742,9 @@
 
 [[package]]
 name = "pastey"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c5a797f0e07bdf071d15742978fc3128ec6c22891c31a3a931513263904c982a"
+checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4"
 
 [[package]]
 name = "pbkdf2"
@@ -4116,7 +4125,7 @@
 
 [[package]]
 name = "qr-greeter"
-version = "3.1.6"
+version = "3.1.7"
 
 [[package]]
 name = "qrcodegen"
@@ -4467,9 +4476,9 @@
 
 [[package]]
 name = "rpassword"
-version = "7.5.2"
+version = "7.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5ac5b223d9738ef56e0b98305410be40fa0941bf6036c56f1506751e43552d64"
+checksum = "2da316a15f47e3d053de9cb2c439650bd8fa4aaeb9365f2e5f27f492ff73c196"
 dependencies = [
  "libc",
  "rtoolbox",
@@ -4819,7 +4828,7 @@
 
 [[package]]
 name = "selinux"
-version = "3.1.6"
+version = "3.1.7"
 
 [[package]]
 name = "semver"
@@ -4906,9 +4915,9 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.149"
+version = "1.0.150"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
+checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
 dependencies = [
  "itoa",
  "memchr",
@@ -4971,11 +4980,12 @@
 
 [[package]]
 name = "serde_with"
-version = "3.19.0"
+version = "3.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f05839ce67618e14a09b286535c0d9c94e85ef25469b0e13cb4f844e5593eb19"
+checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2"
 dependencies = [
  "base64 0.22.1",
+ "bs58",
  "chrono",
  "hex",
  "indexmap 1.9.3",
@@ -4990,9 +5000,9 @@
 
 [[package]]
 name = "serde_with_macros"
-version = "3.19.0"
+version = "3.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "cf2ebbe86054f9b45bc3881e865683ccfaccce97b9b4cb53f3039d67f355a334"
+checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac"
 dependencies = [
  "darling",
  "proc-macro2",
@@ -5076,6 +5086,12 @@
 checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
 [[package]]
+name = "shlex"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
+
+[[package]]
 name = "signal-hook-registry"
 version = "1.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -5180,7 +5196,7 @@
 
 [[package]]
 name = "sshd-config"
-version = "3.1.6"
+version = "3.1.7"
 
 [[package]]
 name = "sshkey-attest"
@@ -5191,7 +5207,7 @@
 
 [[package]]
 name = "sso"
-version = "3.1.6"
+version = "3.1.7"
 dependencies = [
  "broker-client",
  "clap",
@@ -5203,7 +5219,7 @@
 
 [[package]]
 name = "sso-policies"
-version = "3.1.6"
+version = "3.1.7"
 
 [[package]]
 name = "stable_deref_trait"
@@ -5322,7 +5338,7 @@
 checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
 dependencies = [
  "fastrand",
- "getrandom 0.3.3",
+ "getrandom 0.4.1",
  "once_cell",
  "rustix 1.1.4",
  "windows-sys 0.61.2",
@@ -5935,9 +5951,9 @@
 
 [[package]]
 name = "uuid"
-version = "1.23.1"
+version = "1.23.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
+checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7"
 dependencies = [
  "getrandom 0.4.1",
  "js-sys",
@@ -6688,9 +6704,9 @@
 
 [[package]]
 name = "zbus"
-version = "5.15.0"
+version = "5.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1"
+checksum = "eee682d202a77e4a9f3b2c2bdf48a7b28af5c08c34ddf66f98c93e5e39464285"
 dependencies = [
  "async-broadcast",
  "async-executor",
@@ -6723,9 +6739,9 @@
 
 [[package]]
 name = "zbus_macros"
-version = "5.15.0"
+version = "5.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff"
+checksum = "adf1bd45a81a103745b1757754762a26e8cd01e4532e4d6c8ec431624b80d1d6"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -6850,9 +6866,9 @@
 
 [[package]]
 name = "zvariant"
-version = "5.11.0"
+version = "5.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee"
+checksum = "a192a0bde63360d77a7523c833d4b4ce6070a927e2c53246e4c540b1a3e27be0"
 dependencies = [
  "endi",
  "enumflags2",
@@ -6864,9 +6880,9 @@
 
 [[package]]
 name = "zvariant_derive"
-version = "5.11.0"
+version = "5.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda"
+checksum = "90bc6cde9c01c511074be97f7ccb6c19d0da89e3f8662e812e999dcfd4638737"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -6877,9 +6893,9 @@
 
 [[package]]
 name = "zvariant_utils"
-version = "3.3.1"
+version = "3.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691"
+checksum = "1e8535915cfa75547e559d8c68e8139909a4aeee076831e4ef7fc59d8172c4d6"
 dependencies = [
  "proc-macro2",
  "quote",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/himmelblau-3.1.6+git0.102ee045/Cargo.toml 
new/himmelblau-3.1.7+git0.f4e43ca0/Cargo.toml
--- old/himmelblau-3.1.6+git0.102ee045/Cargo.toml       2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/Cargo.toml       2026-06-11 
17:46:50.000000000 +0200
@@ -35,7 +35,7 @@
 ldap3_proto = { path = "src/overrides/ldap3_proto/0.6.2" }
 
 [workspace.package]
-version = "3.1.6"
+version = "3.1.7"
 authors = [
     "David Mulder <[email protected]>"
 ]
@@ -51,13 +51,13 @@
 lazy_static = "^1.4.0"
 paste = "^1.0.12"
 serde = { version = "^1.0.228", features = ["derive"] }
-serde_json = "^1.0.149"
+serde_json = "^1.0.150"
 tracing-subscriber = "^0.3.23"
 tracing = "^0.1.37"
 himmelblau_unix_common = { path = "src/common" }
 libhimmelblau = { version = "0.8.20", features = ["broker", "changepassword", 
"on_behalf_of", "mfa_method_selection", "optional_mfa", 
"intune_portal_vers_selection", "set_timeout"] }
 clap = { version = "^4.6", features = ["derive", "env"] }
-clap_complete = "^4.6.3"
+clap_complete = "^4.6.5"
 reqwest = { version = "^0.12.24", features = ["json"] }
 anyhow = "^1.0.102"
 tokio = { version = "^1.50.0", features = ["rt", "macros", "sync", "time", 
"net", "io-util", "signal", "rt-multi-thread"] }
@@ -70,7 +70,7 @@
 jsonwebtoken = "^9.2.0"
 zeroize = "^1.8.2"
 idmap = { path = "src/idmap" }
-identity_dbus_broker = "0.1.4"
+identity_dbus_broker = "^0.1"
 rustls = ">=0.23.19" # CVE-2024-11738
 console-subscriber = "0.5.0"
 broker-client = { path = "src/broker-client" }
@@ -84,11 +84,11 @@
 hex = "^0.4.3"
 num_enum = "^0.7.6"
 scim_proto = "^1.6.4"
-serde_with = "3.19.0"
+serde_with = "3.20.0"
 time = { version = "^0.3.44", features = ["formatting", "local-offset"] }
 url = "^2.4.0"
 urlencoding = "2.1.3"
-uuid = { version = "^1.23.1", features = ["v4", "v5"] }
+uuid = { version = "^1.23.2", features = ["v4", "v5"] }
 webauthn-rs-proto = "0.5.0"
 kanidm_proto = "1.8.1"
 openssl-sys = "^0.9"
@@ -98,7 +98,7 @@
 sketching = "1.10.0"
 tracing-forest = "^0.1.6"
 rusqlite = "^0.37.0"
-hashbrown = { version = "0.17.0", features = ["serde", "inline-more"] }
+hashbrown = { version = "0.17.1", features = ["serde", "inline-more"] }
 lru = "^0.18.0"
 kanidm_lib_crypto = "1.10.0"
 kanidm_utils_users = "1.8.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/himmelblau-3.1.6+git0.102ee045/fuzz/Cargo.toml 
new/himmelblau-3.1.7+git0.f4e43ca0/fuzz/Cargo.toml
--- old/himmelblau-3.1.6+git0.102ee045/fuzz/Cargo.toml  2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/fuzz/Cargo.toml  2026-06-11 
17:46:50.000000000 +0200
@@ -18,7 +18,7 @@
 idmap = { workspace = true }
 arbitrary = { version = "1.4.2", features = ["derive"] }
 tempfile = "3.27.0"
-uuid = "1.23.1"
+uuid = "1.23.2"
 
 [[bin]]
 name = "config"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/broker-client/Cargo.toml 
new/himmelblau-3.1.7+git0.f4e43ca0/src/broker-client/Cargo.toml
--- old/himmelblau-3.1.6+git0.102ee045/src/broker-client/Cargo.toml     
2026-05-28 23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/broker-client/Cargo.toml     
2026-06-11 17:46:50.000000000 +0200
@@ -10,4 +10,4 @@
 
 [dependencies]
 serde_json.workspace = true
-zbus = "^5.15"
+zbus = "^5.16"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/himmelblau-3.1.6+git0.102ee045/src/cli/Cargo.toml 
new/himmelblau-3.1.7+git0.f4e43ca0/src/cli/Cargo.toml
--- old/himmelblau-3.1.6+git0.102ee045/src/cli/Cargo.toml       2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/cli/Cargo.toml       2026-06-11 
17:46:50.000000000 +0200
@@ -25,7 +25,7 @@
 anyhow = { workspace = true }
 uzers = "^0.12.2"
 sketching = { workspace = true }
-rpassword = "^7.5.2"
+rpassword = "^7.5.4"
 libc.workspace = true
 libhimmelblau.workspace = true
 kanidm-hsm-crypto.workspace = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/himmelblau-3.1.6+git0.102ee045/src/cli/src/main.rs 
new/himmelblau-3.1.7+git0.f4e43ca0/src/cli/src/main.rs
--- old/himmelblau-3.1.6+git0.102ee045/src/cli/src/main.rs      2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/cli/src/main.rs      2026-06-11 
17:46:50.000000000 +0200
@@ -1539,7 +1539,13 @@
             };
 
             // Map the name
-            let account_id = cfg.map_name_to_upn(&account_id);
+            let account_id = match cfg.map_name_to_upn(&account_id) {
+                Some(upn) => upn,
+                None => {
+                    error!("'{}' is not a valid directory user", account_id);
+                    return ExitCode::FAILURE;
+                }
+            };
 
             let opts = Options::default();
             let msg_printer = Arc::new(SimpleMessagePrinter::default());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/himmelblau-3.1.6+git0.102ee045/src/common/Cargo.toml 
new/himmelblau-3.1.7+git0.f4e43ca0/src/common/Cargo.toml
--- old/himmelblau-3.1.6+git0.102ee045/src/common/Cargo.toml    2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/common/Cargo.toml    2026-06-11 
17:46:50.000000000 +0200
@@ -53,7 +53,7 @@
 sha2 = "0.11.0-rc"
 base64.workspace = true
 authenticator = { version = "0.5.0", default-features = false, features = 
["crypto_openssl"] }
-rpassword = "7.5.2"
+rpassword = "7.5.4"
 der = "0.8.0"
 openidconnect = "4.0.1"
 oauth2 = "5.0.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/common/src/config.rs 
new/himmelblau-3.1.7+git0.f4e43ca0/src/common/src/config.rs
--- old/himmelblau-3.1.6+git0.102ee045/src/common/src/config.rs 2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/common/src/config.rs 2026-06-11 
17:46:50.000000000 +0200
@@ -37,7 +37,8 @@
     DEFAULT_PASSWORD_ONLY_REMOTE_SERVICES_DENY_LIST, DEFAULT_POLICIES_DB_DIR,
     DEFAULT_REQUEST_TIMEOUT, DEFAULT_SELINUX, DEFAULT_SFA_FALLBACK_ENABLED, 
DEFAULT_SHELL,
     DEFAULT_SOCK_PATH, DEFAULT_TASK_SOCK_PATH, DEFAULT_TPM_TCTI_NAME, 
DEFAULT_USER_MAP_FILE,
-    DEFAULT_USE_ETC_SKEL, MAPPED_NAME_CACHE, SERVER_CONFIG_PATH,
+    DEFAULT_USE_ETC_SKEL, MAPPED_NAME_CACHE, NSS_IGNORE_EXACT, 
NSS_IGNORE_PREFIX,
+    SERVER_CONFIG_PATH,
 };
 use crate::mapping::{MappedNameCache, Mode};
 use crate::unix_config::{HomeAttr, HsmType};
@@ -698,17 +699,26 @@
         None
     }
 
-    /// This function attempts to convert a username to a valid UPN. On 
failure it
-    /// will leave the name as-is, and respond with the original input. 
Himmelblau
-    /// will reject the authentication attempt if the username isn't a valid 
UPN.
-    pub fn map_name_to_upn(&self, account_id: &str) -> String {
+    /// Convert a login name to a UPN, or `None` if it cannot be a directory 
user
+    /// (empty, or a known local-only name). Callers treat `None` as 
user-unknown
+    /// and must not look it up against Entra. See 
himmelblau-idm/himmelblau#1392.
+    pub fn map_name_to_upn(&self, account_id: &str) -> Option<String> {
+        self.map_name_to_upn_impl(account_id, "/etc/passwd")
+    }
+
+    /// Inner impl with an injectable passwd path for hermetic unit tests.
+    fn map_name_to_upn_impl(&self, account_id: &str, passwd_path: &str) -> 
Option<String> {
         let name_mapping_script = self.get_name_mapping_script();
         let cn_name_mapping = self.get_cn_name_mapping();
         let domains = self.get_configured_domains();
 
+        if account_id.trim().is_empty() {
+            return None;
+        }
+
         // Make sure this account_id isn't a local user
         let mut contents = vec![];
-        if let Ok(mut file) = File::open("/etc/passwd") {
+        if let Ok(mut file) = File::open(passwd_path) {
             let _ = file.read_to_end(&mut contents);
         }
         let local_users = 
parse_etc_passwd(contents.as_slice()).unwrap_or_default();
@@ -718,11 +728,19 @@
             .collect::<Vec<String>>()
             .contains(&account_id.to_string())
         {
-            return account_id.to_string();
+            return Some(account_id.to_string());
+        }
+
+        // Local-only names probed by systemd/GDM at boot; never directory 
users.
+        if NSS_IGNORE_EXACT.contains(&account_id)
+            || NSS_IGNORE_PREFIX
+                .iter()
+                .any(|prefix| account_id.starts_with(prefix))
+        {
+            return None;
         }
 
-        // The name mapping script is expected to convert the input name to a 
UPN
-        // if a name is supplied, or to a name if the UPN is supplied.
+        // Empty script output signals "not a directory user" -> None.
         if !account_id.contains('@') {
             if let Some(name_mapping_script) = &name_mapping_script {
                 let name_cache = MappedNameCache::new(MAPPED_NAME_CACHE, 
&Mode::ReadWrite).ok();
@@ -733,11 +751,14 @@
                     Ok(output) => {
                         if output.status.success() {
                             let upn = 
String::from_utf8_lossy(&output.stdout).trim().to_string();
+                            if upn.is_empty() {
+                                return None;
+                            }
                             if let Some(name_cache) = &name_cache {
                                 // Failing to insert a name map is not a 
critical failure.
                                 let _ = name_cache.insert_mapping(&upn, 
account_id);
                             }
-                            return upn;
+                            return Some(upn);
                         } else {
                             error!("Script execution failed with error: {:?}", 
output.status);
                         }
@@ -759,9 +780,9 @@
             }
         }
         if cn_name_mapping && !account_id.contains('@') && !domains.is_empty() 
{
-            return format!("{}@{}", account_id, domains[0]);
+            return Some(format!("{}@{}", account_id, domains[0]));
         }
-        account_id.to_string()
+        Some(account_id.to_string())
     }
 
     /// This function maps a UPN to a mapped name. If a mapping script is
@@ -860,6 +881,13 @@
         file_path
     }
 
+    // Throwaway passwd file so map_name_to_upn_impl can be tested 
hermetically.
+    fn create_temp_passwd(contents: &str) -> String {
+        let file_path = format!("/tmp/himmelblau_test_passwd_{}", 
uuid::Uuid::new_v4());
+        fs::write(&file_path, contents).expect("Failed to write temporary 
passwd file");
+        file_path
+    }
+
     // Helper function to create an empty config (to test defaults without 
system config interference)
     fn create_empty_config() -> HimmelblauConfig {
         let temp_file = create_temp_config("");
@@ -1690,74 +1718,153 @@
         assert_eq!(config_missing.get_name_mapping_script(), None);
     }
 
+    const PASSWD_MINIMAL: &str = "root:x:0:0:root:/root:/bin/bash\n";
+
     #[test]
     fn test_map_name_to_upn_script_execution_success() {
-        let config_data = r#"
+        let config = HimmelblauConfig::new(Some(&create_temp_config(
+            r#"
         [global]
         name_mapping_script = ../../scripts/test_script_echo.sh
         domains = example.com
-        "#;
-
-        let temp_file = create_temp_config(config_data);
-        let config = HimmelblauConfig::new(Some(&temp_file)).unwrap();
-
-        let account_id = "user";
-        let expected_output = "user";
-
+        "#,
+        )))
+        .unwrap();
+        let passwd = create_temp_passwd(PASSWD_MINIMAL);
         assert_eq!(
-            config.map_name_to_upn(account_id),
-            expected_output.to_string()
+            config.map_name_to_upn_impl("user", &passwd),
+            Some("user".to_string())
         );
     }
 
     #[test]
     fn test_map_name_to_upn_local_user() {
-        // Simulate a local user in /etc/passwd
-        let account_id = "localuser";
-
-        let config_data = r#"
+        let config = HimmelblauConfig::new(Some(&create_temp_config(
+            r#"
         [global]
-        "#;
-
-        let temp_file = create_temp_config(config_data);
-        let config = HimmelblauConfig::new(Some(&temp_file)).unwrap();
+        domains = example.com
+        "#,
+        )))
+        .unwrap();
+        let passwd = create_temp_passwd(&format!(
+            "{}localuser:x:1000:1000::/home/localuser:/bin/bash\n",
+            PASSWD_MINIMAL
+        ));
+        assert_eq!(
+            config.map_name_to_upn_impl("localuser", &passwd),
+            Some("localuser".to_string())
+        );
+    }
 
-        // Simulating presence of local user
-        assert_eq!(config.map_name_to_upn(account_id), account_id.to_string());
+    #[test]
+    fn test_map_name_to_upn_local_user_wins_over_ignore_list() {
+        let config = HimmelblauConfig::new(Some(&create_temp_config(
+            r#"
+        [global]
+        domains = example.com
+        "#,
+        )))
+        .unwrap();
+        let passwd = create_temp_passwd(&format!(
+            "{}systemd-coredump:x:999:999::/run/systemd:/usr/sbin/nologin\n",
+            PASSWD_MINIMAL
+        ));
+        assert_eq!(
+            config.map_name_to_upn_impl("systemd-coredump", &passwd),
+            Some("systemd-coredump".to_string())
+        );
     }
 
     #[test]
     fn test_map_name_to_upn_add_domain() {
-        let config_data = r#"
+        let config = HimmelblauConfig::new(Some(&create_temp_config(
+            r#"
         [global]
         cn_to_upn_mapping = true
         domains = example.com
-        "#;
+        "#,
+        )))
+        .unwrap();
+        let passwd = create_temp_passwd(PASSWD_MINIMAL);
+        assert_eq!(
+            config.map_name_to_upn_impl("user", &passwd),
+            Some("[email protected]".to_string())
+        );
+    }
 
-        let temp_file = create_temp_config(config_data);
-        let config = HimmelblauConfig::new(Some(&temp_file)).unwrap();
+    #[test]
+    fn test_map_name_to_upn_empty_is_none() {
+        let config = HimmelblauConfig::new(Some(&create_temp_config(
+            r#"
+        [global]
+        domains = example.com
+        "#,
+        )))
+        .unwrap();
+        let passwd = create_temp_passwd(PASSWD_MINIMAL);
+        assert_eq!(config.map_name_to_upn_impl("", &passwd), None);
+        assert_eq!(config.map_name_to_upn_impl("   ", &passwd), None);
+    }
 
-        let account_id = "user";
-        let expected_output = "[email protected]";
+    #[test]
+    fn test_map_name_to_upn_ignored_names_are_none() {
+        let config = HimmelblauConfig::new(Some(&create_temp_config(
+            r#"
+        [global]
+        domains = example.com
+        "#,
+        )))
+        .unwrap();
+        let passwd = create_temp_passwd(PASSWD_MINIMAL);
+        for name in [
+            "gdm",
+            "sssd",
+            "systemd-coredump",
+            "gnome-initial-setup",
+            "gdm-greeter",
+            "gdm-greeter-2",
+            "gdm-greeter-9",
+            "pam_unix_non_existent",
+            "pam_unix_non_existent:",
+        ] {
+            assert_eq!(
+                config.map_name_to_upn_impl(name, &passwd),
+                None,
+                "{name} should be None"
+            );
+        }
+    }
 
+    #[test]
+    fn test_map_name_to_upn_prefix_does_not_overmatch() {
+        // A real user whose name merely starts with "gdm" must NOT be ignored.
+        let config = HimmelblauConfig::new(Some(&create_temp_config(
+            r#"
+        [global]
+        domains = example.com
+        "#,
+        )))
+        .unwrap();
+        let passwd = create_temp_passwd(PASSWD_MINIMAL);
         assert_eq!(
-            config.map_name_to_upn(account_id),
-            expected_output.to_string()
+            config.map_name_to_upn_impl("gdmitrij.popov", &passwd),
+            Some("[email protected]".to_string())
         );
     }
 
     #[test]
     fn test_map_name_to_upn_no_mapping() {
-        let config_data = r#"
+        let config = HimmelblauConfig::new(Some(&create_temp_config(
+            r#"
         [global]
-        "#;
-
-        let temp_file = create_temp_config(config_data);
-        let config = HimmelblauConfig::new(Some(&temp_file)).unwrap();
-
-        let account_id = "user";
-
-        assert_eq!(config.map_name_to_upn(account_id), account_id.to_string());
+        "#,
+        )))
+        .unwrap();
+        let passwd = create_temp_passwd(PASSWD_MINIMAL);
+        assert_eq!(
+            config.map_name_to_upn_impl("user", &passwd),
+            Some("user".to_string())
+        );
     }
 
     #[test]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/common/src/constants.rs 
new/himmelblau-3.1.7+git0.f4e43ca0/src/common/src/constants.rs
--- old/himmelblau-3.1.6+git0.102ee045/src/common/src/constants.rs      
2026-05-28 23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/common/src/constants.rs      
2026-06-11 17:46:50.000000000 +0200
@@ -58,6 +58,10 @@
 pub const BROKER_APP_ID: &str = "29d9ed98-a469-4536-ade2-f981bc1d605e";
 pub const BROKER_CLIENT_IDENT: &str = "38aa3b87-a06d-4817-b275-7a316988d93b";
 pub const CN_NAME_MAPPING: bool = true;
+// Local-only names that must never be mapped to a UPN / looked up in Entra.
+// See himmelblau-idm/himmelblau#1392.
+pub const NSS_IGNORE_EXACT: &[&str] = &["gdm", "sssd", "systemd-coredump", 
"gnome-initial-setup"];
+pub const NSS_IGNORE_PREFIX: &[&str] = &["gdm-greeter", 
"pam_unix_non_existent"]; // variable suffix
 pub const DEFAULT_HELLO_PIN_MIN_LEN: usize = 6;
 pub const DEFAULT_HELLO_PIN_RETRY_COUNT: u32 = 3;
 pub const DEFAULT_KERBEROS_CONF_DIR: &str = "/etc/krb5.conf.d/";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/common/src/idprovider/himmelblau.rs 
new/himmelblau-3.1.7+git0.f4e43ca0/src/common/src/idprovider/himmelblau.rs
--- old/himmelblau-3.1.6+git0.102ee045/src/common/src/idprovider/himmelblau.rs  
2026-05-28 23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/common/src/idprovider/himmelblau.rs  
2026-06-11 17:46:50.000000000 +0200
@@ -90,6 +90,8 @@
 const CONSENT_REQUIRED: u32 = 65002;
 // AADSTS50125: PasswordResetRegistrationRequiredInterrupt
 const PASSWORD_RESET_REGISTRATION_REQUIRED: u32 = 50125;
+// AADSTS50072/50074/50076: Strong auth/MFA is required for this request.
+const MFA_REQUIRED_FOR_ENROLLMENT: [u32; 3] = [50072, 50074, 50076];
 
 fn is_unavailable_mfa_method_error(msg: &str, requested_method: &str) -> bool {
     let expected_prefix =
@@ -97,6 +99,20 @@
     msg.starts_with(&expected_prefix)
 }
 
+fn is_mfa_required_for_enrollment(e: &MsalError) -> bool {
+    match e {
+        MsalError::AcquireTokenFailed(resp) => resp
+            .error_codes
+            .iter()
+            .any(|code| MFA_REQUIRED_FOR_ENROLLMENT.contains(code)),
+        MsalError::AADSTSError(aadsts_err) => {
+            MFA_REQUIRED_FOR_ENROLLMENT.contains(&aadsts_err.code)
+        }
+        MsalError::MFARequired => true,
+        _ => false,
+    }
+}
+
 /// Convert an MsalError to a short, user-friendly message for PAM display.
 /// This intentionally ignores the internal string contents of error variants
 /// to avoid leaking verbose or sensitive information to the user.
@@ -1973,10 +1989,67 @@
             };
         }
         macro_rules! enroll_and_obtain_enrolled_token {
-            ($token:ident) => {{
+            ($token:ident, $cred:expr) => {{
                 if !self.is_domain_joined(keystore).await {
                     debug!("Device is not enrolled. Enrolling now.");
                     if let Err(e) = self.join_domain(tpm, &$token, keystore, 
machine_key).await {
+                        if is_mfa_required_for_enrollment(&e) {
+                            info!("Device enrollment requires MFA; restarting 
authentication with ForceMFA.");
+
+                            let (
+                                console_password_only,
+                                remote_services,
+                                enable_experimental_passwordless_fido,
+                                mfa_method,
+                            ) = {
+                                let cfg = self.config.lock().await;
+                                (
+                                    cfg.get_allow_console_password_only(),
+                                    
cfg.get_password_only_remote_services_deny_list(),
+                                    
cfg.get_enable_experimental_passwordless_fido(),
+                                    cfg.get_mfa_method(),
+                                )
+                            };
+                            let is_remote_service = 
service.starts_with("remote:")
+                                || remote_services
+                                    .iter()
+                                    .any(|s| !s.is_empty() && 
service.contains(s));
+                            let mut auth_options = vec![AuthOption::ForceMFA, 
AuthOption::Passwordless];
+                            if !is_remote_service {
+                                auth_options.push(AuthOption::Fido);
+                                if enable_experimental_passwordless_fido {
+                                    
auth_options.push(AuthOption::PasswordlessFido);
+                                }
+                            }
+                            if is_remote_service {
+                                auth_options.push(AuthOption::RemoteSession);
+                            } else if console_password_only {
+                                debug!(
+                                    "Forcing MFA for device enrollment despite 
console password-only mode."
+                                );
+                            }
+
+                            let enrollment_cred: Option<String> = $cred;
+                            let flow = net_down_check!(
+                                self.initiate_mfa_flow_with_fallback(
+                                    account_id,
+                                    enrollment_cred.as_deref(),
+                                    &auth_options,
+                                    None,
+                                    mfa_method,
+                                )
+                                .await,
+                                Ok(flow) => flow,
+                                Err(e) => {
+                                    error!("MFA flow initiation failed after 
enrollment MFA demand: {:?}", e);
+                                    return Ok((
+                                        
AuthResult::Denied(msal_error_to_user_message(&e)),
+                                        AuthCacheAction::None,
+                                    ));
+                                }
+                            );
+                            nested_auth_handle_mfa_resp!(flow, enrollment_cred)
+                        }
                         error!("Failed to join domain: {:?}", e);
                         return Ok((
                             AuthResult::Denied("Failed to join domain. Please 
contact your administrator.".to_string()),
@@ -3019,10 +3092,11 @@
             }};
         }
         macro_rules! nested_auth_handle_mfa_resp {
-            ($resp:ident, $cred:ident) => {
+            ($resp:ident, $cred:expr) => {
                 nested_auth_handle_mfa_resp!($resp, $cred, None)
             };
-            ($resp:ident, $cred:ident, $reauth_hello_pin:expr) => {{
+            ($resp:ident, $cred:expr, $reauth_hello_pin:expr) => {{
+                let password: Option<String> = $cred.into();
                 let reauth_hello_pin: Option<Zeroizing<String>> = 
$reauth_hello_pin;
                 auth_handle_mfa_resp!(
                     $resp,
@@ -3049,17 +3123,19 @@
                                 ));
                             }
                         };
+                        let action = match (
+                            
self.config.lock().await.get_offline_breakglass_enabled(),
+                            password.as_ref(),
+                        ) {
+                            (true, Some(cred)) => 
AuthCacheAction::PasswordHashUpdate { cred: cred.clone() },
+                            _ => AuthCacheAction::None,
+                        };
                         *cred_handler = AuthCredHandler::MFA {
                             flow: Box::new($resp),
-                            password: Some($cred.clone()),
+                            password,
                             extra_data: None,
                             reauth_hello_pin: reauth_hello_pin.clone(),
                         };
-                        let action = if 
self.config.lock().await.get_offline_breakglass_enabled() {
-                            AuthCacheAction::PasswordHashUpdate { $cred }
-                        } else {
-                            AuthCacheAction::None
-                        };
                         return Ok((
                             AuthResult::Next(AuthRequest::Fido {
                                 fido_allow_list,
@@ -3073,17 +3149,19 @@
                     // PROMPT
                     {
                         let msg = $resp.msg.clone();
+                        let action = match (
+                            
self.config.lock().await.get_offline_breakglass_enabled(),
+                            password.as_ref(),
+                        ) {
+                            (true, Some(cred)) => 
AuthCacheAction::PasswordHashUpdate { cred: cred.clone() },
+                            _ => AuthCacheAction::None,
+                        };
                         *cred_handler = AuthCredHandler::MFA {
                             flow: Box::new($resp),
-                            password: Some($cred.clone()),
+                            password,
                             extra_data: None,
                             reauth_hello_pin: reauth_hello_pin.clone(),
                         };
-                        let action = if 
self.config.lock().await.get_offline_breakglass_enabled() {
-                            AuthCacheAction::PasswordHashUpdate { $cred }
-                        } else {
-                            AuthCacheAction::None
-                        };
                         return Ok((
                             AuthResult::Next(AuthRequest::MFACode { msg }),
                             /* Cache the offline password hash for breakglass
@@ -3095,17 +3173,19 @@
                     {
                         let msg = $resp.msg.clone();
                         let polling_interval = 
$resp.polling_interval.unwrap_or(5000);
+                        let action = match (
+                            
self.config.lock().await.get_offline_breakglass_enabled(),
+                            password.as_ref(),
+                        ) {
+                            (true, Some(cred)) => 
AuthCacheAction::PasswordHashUpdate { cred: cred.clone() },
+                            _ => AuthCacheAction::None,
+                        };
                         *cred_handler = AuthCredHandler::MFA {
                             flow: Box::new($resp),
-                            password: Some($cred.clone()),
+                            password,
                             extra_data: None,
                             reauth_hello_pin: reauth_hello_pin.clone(),
                         };
-                        let action = if 
self.config.lock().await.get_offline_breakglass_enabled() {
-                            AuthCacheAction::PasswordHashUpdate { $cred }
-                        } else {
-                            AuthCacheAction::None
-                        };
                         return Ok((
                             AuthResult::Next(AuthRequest::MFAPoll {
                                 msg,
@@ -3344,7 +3424,7 @@
                     Some(Ok(token)) => {
                         // Password validated and no MFA required - return 
success
                         debug!("ROPC succeeded - no MFA required");
-                        let token2 = enroll_and_obtain_enrolled_token!(token);
+                        let token2 = enroll_and_obtain_enrolled_token!(token, 
Some(cred.clone()));
                         return match self.token_validate(account_id, &token2, 
None).await {
                             Ok(AuthResult::Success { token }) => {
                                 let action =
@@ -3527,12 +3607,10 @@
                 // Check if this is a remote service:
                 // - Service starts with "remote:" (set by PAM module when 
PAM_RHOST is set)
                 // - Service name contains any entry from 
remote_services_deny_list
-                // - Service name or TTY contains "ssh" (fallback check)
                 let is_remote_service = service.starts_with("remote:")
                     || remote_services
                         .iter()
-                        .any(|s| !s.is_empty() && service.contains(s))
-                    || service.to_lowercase().contains("ssh");
+                        .any(|s| !s.is_empty() && service.contains(s));
                 let console_password_only =
                     self.config.lock().await.get_allow_console_password_only();
                 if !is_remote_service {
@@ -3657,7 +3735,7 @@
                                 return Ok((AuthResult::Denied(e.to_string()), 
AuthCacheAction::None));
                             }
                         };
-                        let token2 = enroll_and_obtain_enrolled_token!(token);
+                        let token2 = enroll_and_obtain_enrolled_token!(token, 
Some(cred.clone()));
                         return match self.token_validate(account_id, &token2, 
None).await {
                             Ok(AuthResult::Success { token }) => {
                                 // STOP! If we just enrolled with an SFA 
token, then we
@@ -3719,7 +3797,7 @@
                         }
                     }
                 );
-                let token2 = enroll_and_obtain_enrolled_token!(token);
+                let token2 = enroll_and_obtain_enrolled_token!(token, 
password.clone());
                 match self.token_validate(account_id, &token2, None).await {
                     Ok(AuthResult::Success { token: token3 }) => {
                         reseal_prt_with_existing_hello_key_on_success!(
@@ -3849,7 +3927,7 @@
                 let token2 = if msa_tenant {
                     token.clone()
                 } else {
-                    enroll_and_obtain_enrolled_token!(token)
+                    enroll_and_obtain_enrolled_token!(token, password.clone())
                 };
                 match self.token_validate(account_id, &token2, None).await {
                     Ok(AuthResult::Success { token: token3 }) => {
@@ -3940,7 +4018,7 @@
                         }
                     }
                 );
-                let token2 = enroll_and_obtain_enrolled_token!(token);
+                let token2 = enroll_and_obtain_enrolled_token!(token, 
password.clone());
                 match self.token_validate(account_id, &token2, None).await {
                     Ok(AuthResult::Success { token: token3 }) => {
                         reseal_prt_with_existing_hello_key_on_success!(
@@ -5141,7 +5219,10 @@
 
 #[cfg(test)]
 mod tests {
-    use super::is_unavailable_mfa_method_error;
+    use super::{
+        is_mfa_required_for_enrollment, is_unavailable_mfa_method_error, 
CONSENT_REQUIRED,
+    };
+    use himmelblau::error::{AADSTSError, ErrorResponse, MsalError, 
DEVICE_AUTH_FAIL};
 
     #[test]
     fn unavailable_mfa_method_error_requires_exact_requested_method() {
@@ -5159,4 +5240,46 @@
             "FidoKey"
         ));
     }
+
+    #[test]
+    fn enrollment_mfa_classifier_matches_strong_auth_demands() {
+        for code in [50072, 50074, 50076] {
+            assert!(is_mfa_required_for_enrollment(
+                &MsalError::AcquireTokenFailed(ErrorResponse {
+                    error: "invalid_grant".to_string(),
+                    error_description: format!("AADSTS{code}: MFA required"),
+                    suberror: None,
+                    error_codes: vec![code],
+                })
+            ));
+            assert!(is_mfa_required_for_enrollment(&MsalError::AADSTSError(
+                AADSTSError::new(code, None)
+            )));
+        }
+
+        assert!(is_mfa_required_for_enrollment(&MsalError::MFARequired));
+    }
+
+    #[test]
+    fn enrollment_mfa_classifier_ignores_unrelated_errors() {
+        assert!(!is_mfa_required_for_enrollment(
+            &MsalError::AcquireTokenFailed(ErrorResponse {
+                error: "invalid_grant".to_string(),
+                error_description: "device auth failed".to_string(),
+                suberror: None,
+                error_codes: vec![DEVICE_AUTH_FAIL],
+            })
+        ));
+        assert!(!is_mfa_required_for_enrollment(
+            &MsalError::AcquireTokenFailed(ErrorResponse {
+                error: "invalid_grant".to_string(),
+                error_description: "consent required".to_string(),
+                suberror: None,
+                error_codes: vec![CONSENT_REQUIRED],
+            })
+        ));
+        assert!(!is_mfa_required_for_enrollment(&MsalError::RequestFailed(
+            "network down".to_string()
+        )));
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/himmelblau-3.1.6+git0.102ee045/src/idmap/Cargo.toml 
new/himmelblau-3.1.7+git0.f4e43ca0/src/idmap/Cargo.toml
--- old/himmelblau-3.1.6+git0.102ee045/src/idmap/Cargo.toml     2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/idmap/Cargo.toml     2026-06-11 
17:46:50.000000000 +0200
@@ -19,5 +19,5 @@
 uuid.workspace = true
 
 [build-dependencies]
-cc = "1.2.61"
+cc = "1.2.63"
 bindgen = "0.72.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/nss/src/implementation.rs 
new/himmelblau-3.1.7+git0.f4e43ca0/src/nss/src/implementation.rs
--- old/himmelblau-3.1.6+git0.102ee045/src/nss/src/implementation.rs    
2026-05-28 23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/nss/src/implementation.rs    
2026-06-11 17:46:50.000000000 +0200
@@ -223,7 +223,10 @@
             (name.to_lowercase(), Some(local))
         } else {
             // No mapping - use standard cn_name_mapping
-            (cfg.map_name_to_upn(&name), None)
+            match cfg.map_name_to_upn(&name) {
+                Some(upn) => (upn, None),
+                None => return Response::NotFound,
+            }
         };
 
         let req = ClientRequest::NssAccountByName(upn.clone());
@@ -375,7 +378,10 @@
         if is_local_group(&cfg.map_upn_to_name(&name)) {
             return Response::NotFound;
         }
-        let upn = cfg.map_name_to_upn(&name);
+        let upn = match cfg.map_name_to_upn(&name) {
+            Some(upn) => upn,
+            None => return Response::NotFound,
+        };
         let mut daemon_client = match 
DaemonClientBlocking::new(cfg.get_socket_path().as_str()) {
             Ok(dc) => dc,
             Err(_) => {
@@ -532,7 +538,10 @@
     let user_map = UserMap::new(&cfg.get_user_map_file());
     let account_id = match user_map.get_upn_from_local(c_user) {
         Some(upn) => upn,
-        None => cfg.map_name_to_upn(c_user),
+        None => match cfg.map_name_to_upn(c_user) {
+            Some(upn) => upn,
+            None => return NSS_STATUS_NOTFOUND,
+        },
     };
     let req = ClientRequest::NssInitgroups(account_id);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/pam/src/pam/mod.rs 
new/himmelblau-3.1.7+git0.f4e43ca0/src/pam/src/pam/mod.rs
--- old/himmelblau-3.1.6+git0.102ee045/src/pam/src/pam/mod.rs   2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/pam/src/pam/mod.rs   2026-06-11 
17:46:50.000000000 +0200
@@ -265,7 +265,10 @@
         let user_map = UserMap::new(&cfg.get_user_map_file());
         let account_id = match user_map.get_upn_from_local(&account_id) {
             Some(account_id) => account_id,
-            None => cfg.map_name_to_upn(&account_id),
+            None => match cfg.map_name_to_upn(&account_id) {
+                Some(upn) => upn,
+                None => return PamResultCode::PAM_IGNORE,
+            },
         };
         let req = ClientRequest::PamAccountAllowed(account_id);
         // PamResultCode::PAM_IGNORE
@@ -377,7 +380,10 @@
         let user_map = UserMap::new(&cfg.get_user_map_file());
         let account_id = match user_map.get_upn_from_local(&account_id) {
             Some(account_id) => account_id,
-            None => cfg.map_name_to_upn(&account_id),
+            None => match cfg.map_name_to_upn(&account_id) {
+                Some(upn) => upn,
+                None => return PamResultCode::PAM_IGNORE,
+            },
         };
 
         let authtok = match pamh.get_authtok() {
@@ -472,7 +478,10 @@
         let user_map = UserMap::new(&cfg.get_user_map_file());
         let account_id = match user_map.get_upn_from_local(&account_id) {
             Some(account_id) => account_id,
-            None => cfg.map_name_to_upn(&account_id),
+            None => match cfg.map_name_to_upn(&account_id) {
+                Some(upn) => upn,
+                None => return PamResultCode::PAM_IGNORE,
+            },
         };
 
         // Local user (no UPN): not a Himmelblau/Entra account. Skip before 
touching the
@@ -952,7 +961,10 @@
         let user_map = UserMap::new(&cfg.get_user_map_file());
         let account_id = match user_map.get_upn_from_local(&account_id) {
             Some(account_id) => account_id,
-            None => cfg.map_name_to_upn(&account_id),
+            None => match cfg.map_name_to_upn(&account_id) {
+                Some(upn) => upn,
+                None => return PamResultCode::PAM_IGNORE,
+            },
         };
 
         let req = ClientRequest::PamAccountBeginSession(account_id);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/himmelblau-3.1.6+git0.102ee045/src/paste/Cargo.toml 
new/himmelblau-3.1.7+git0.f4e43ca0/src/paste/Cargo.toml
--- old/himmelblau-3.1.6+git0.102ee045/src/paste/Cargo.toml     2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/paste/Cargo.toml     2026-06-11 
17:46:50.000000000 +0200
@@ -14,4 +14,4 @@
 #proc-macro = true
 
 [dependencies]
-pastey = "0.2.2"
+pastey = "0.2.3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/selinux/src/himmelblaud.te 
new/himmelblau-3.1.7+git0.f4e43ca0/src/selinux/src/himmelblaud.te
--- old/himmelblau-3.1.6+git0.102ee045/src/selinux/src/himmelblaud.te   
2026-05-28 23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/selinux/src/himmelblaud.te   
2026-06-11 17:46:50.000000000 +0200
@@ -358,8 +358,7 @@
        allow himmelblaud_tasks_t systemd_unit_file_t:dir getattr;
        allow himmelblaud_tasks_t init_var_run_t:sock_file write;
        allow himmelblaud_tasks_t init_t:process { rlimitinh siginh noatsecure 
};
-       allow himmelblaud_tasks_t root_t:dir search;
-       allow himmelblaud_tasks_t root_t:dir getattr;
+       allow himmelblaud_tasks_t root_t:dir { search getattr open read };
        allow himmelblaud_tasks_t bin_t:dir search;
        allow himmelblaud_tasks_t himmelblaud_tasks_exec_t:file { getattr open 
read execute map };
        allow himmelblaud_tasks_t himmelblaud_t:unix_stream_socket connectto;
@@ -917,6 +916,8 @@
                type postfix_pickup_t;
        }
        allow postfix_pickup_t himmelblau_etc_t:dir search;
+       allow postfix_pickup_t himmelblau_etc_t:file { getattr };
+       allow postfix_pickup_t himmelblau_var_cache_t:dir search;
        allow postfix_pickup_t himmelblau_var_cache_t:lnk_file read;
 }
 
@@ -927,6 +928,8 @@
                type postfix_qmgr_t;
        }
        allow postfix_qmgr_t himmelblau_etc_t:dir search;
+       allow postfix_qmgr_t himmelblau_etc_t:file { getattr };
+       allow postfix_qmgr_t himmelblau_var_cache_t:dir search;
        allow postfix_qmgr_t himmelblau_var_cache_t:lnk_file read;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/sso/src/chrome/policies.json 
new/himmelblau-3.1.7+git0.f4e43ca0/src/sso/src/chrome/policies.json
--- old/himmelblau-3.1.6+git0.102ee045/src/sso/src/chrome/policies.json 
2026-05-28 23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/src/sso/src/chrome/policies.json 
2026-06-11 17:46:50.000000000 +0200
@@ -1,5 +1,5 @@
 {
   "ExtensionInstallForcelist": [
-    "jlnfnnolkbjieggibinobhkjdfbpcohn"
+    
"jlnfnnolkbjieggibinobhkjdfbpcohn;https://clients2.google.com/service/update2/crx";
   ]
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/src/sso-policies/src/chrome/policies.json 
new/himmelblau-3.1.7+git0.f4e43ca0/src/sso-policies/src/chrome/policies.json
--- 
old/himmelblau-3.1.6+git0.102ee045/src/sso-policies/src/chrome/policies.json    
    2026-05-28 23:36:26.000000000 +0200
+++ 
new/himmelblau-3.1.7+git0.f4e43ca0/src/sso-policies/src/chrome/policies.json    
    2026-06-11 17:46:50.000000000 +0200
@@ -1,5 +1,5 @@
 {
   "ExtensionInstallForcelist": [
-    "jlnfnnolkbjieggibinobhkjdfbpcohn"
+    
"jlnfnnolkbjieggibinobhkjdfbpcohn;https://clients2.google.com/service/update2/crx";
   ]
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/supply-chain/audits.toml 
new/himmelblau-3.1.7+git0.f4e43ca0/supply-chain/audits.toml
--- old/himmelblau-3.1.6+git0.102ee045/supply-chain/audits.toml 2026-05-28 
23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/supply-chain/audits.toml 2026-06-11 
17:46:50.000000000 +0200
@@ -104,6 +104,11 @@
 criteria = "safe-to-deploy"
 delta = "0.11.0 -> 0.12.0"
 
+[[audits.bs58]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+version = "0.5.0"
+
 [[audits.bytes]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -149,6 +154,11 @@
 criteria = "safe-to-deploy"
 delta = "1.2.55 -> 1.2.56"
 
+[[audits.cc]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "1.2.61 -> 1.2.63"
+
 [[audits.cesu8]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -429,6 +439,11 @@
 criteria = "safe-to-deploy"
 delta = "0.2.1 -> 0.2.2"
 
+[[audits.pastey]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "0.2.2 -> 0.2.3"
+
 [[audits.pem]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -454,6 +469,11 @@
 criteria = "safe-to-deploy"
 version = "0.10.0"
 
+[[audits.rpassword]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "7.5.2 -> 7.5.4"
+
 [[audits.rustls]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -569,6 +589,11 @@
 criteria = "safe-to-deploy"
 delta = "3.16.1 -> 3.17.0"
 
+[[audits.serde_with]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "3.19.0 -> 3.20.0"
+
 [[audits.serde_with_macros]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -599,11 +624,21 @@
 criteria = "safe-to-deploy"
 delta = "3.16.1 -> 3.17.0"
 
+[[audits.serde_with_macros]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "3.19.0 -> 3.20.0"
+
 [[audits.servo_arc]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
 delta = "0.4.0 -> 0.4.3"
 
+[[audits.shlex]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "1.3.0 -> 2.0.1"
+
 [[audits.sshkeys]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -739,6 +774,11 @@
 criteria = "safe-to-deploy"
 delta = "1.20.0 -> 1.21.0"
 
+[[audits.uuid]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "1.23.1 -> 1.23.2"
+
 [[audits.uzers]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -769,6 +809,11 @@
 criteria = "safe-to-deploy"
 delta = "5.13.2 -> 5.14.0"
 
+[[audits.zbus]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "5.15.0 -> 5.16.0"
+
 [[audits.zbus_macros]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -784,6 +829,11 @@
 criteria = "safe-to-deploy"
 delta = "5.13.2 -> 5.14.0"
 
+[[audits.zbus_macros]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "5.15.0 -> 5.16.0"
+
 [[audits.zbus_names]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -799,6 +849,11 @@
 criteria = "safe-to-deploy"
 delta = "5.9.2 -> 5.10.0"
 
+[[audits.zvariant]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "5.11.0 -> 5.12.0"
+
 [[audits.zvariant_derive]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
@@ -809,11 +864,21 @@
 criteria = "safe-to-deploy"
 delta = "5.9.2 -> 5.10.0"
 
+[[audits.zvariant_derive]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "5.11.0 -> 5.12.0"
+
 [[audits.zvariant_utils]]
 who = "David Mulder <[email protected]>"
 criteria = "safe-to-deploy"
 delta = "3.2.0 -> 3.3.0"
 
+[[audits.zvariant_utils]]
+who = "David Mulder <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "3.3.1 -> 3.4.0"
+
 [[trusted.aho-corasick]]
 criteria = "safe-to-deploy"
 user-id = 189 # Andrew Gallant (BurntSushi)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/himmelblau-3.1.6+git0.102ee045/supply-chain/imports.lock 
new/himmelblau-3.1.7+git0.f4e43ca0/supply-chain/imports.lock
--- old/himmelblau-3.1.6+git0.102ee045/supply-chain/imports.lock        
2026-05-28 23:36:26.000000000 +0200
+++ new/himmelblau-3.1.7+git0.f4e43ca0/supply-chain/imports.lock        
2026-06-11 17:46:50.000000000 +0200
@@ -131,8 +131,8 @@
 user-name = "Ed Page"
 
 [[publisher.clap_complete]]
-version = "4.6.3"
-when = "2026-04-27"
+version = "4.6.5"
+when = "2026-05-11"
 user-id = 6743
 user-login = "epage"
 user-name = "Ed Page"
@@ -359,8 +359,8 @@
 user-login = "rust-lang-owner"
 
 [[publisher.hashbrown]]
-version = "0.17.0"
-when = "2026-04-09"
+version = "0.17.1"
+when = "2026-05-09"
 user-id = 55123
 user-login = "rust-lang-owner"
 
@@ -503,8 +503,8 @@
 user-name = "Nick Fitzgerald"
 
 [[publisher.libhimmelblau]]
-version = "0.8.20"
-when = "2026-05-28"
+version = "0.8.22"
+when = "2026-06-10"
 user-id = 247655
 user-login = "dmulder"
 user-name = "David Mulder"
@@ -796,8 +796,8 @@
 user-name = "David Tolnay"
 
 [[publisher.serde_json]]
-version = "1.0.149"
-when = "2026-01-06"
+version = "1.0.150"
+when = "2026-05-21"
 user-id = 3618
 user-login = "dtolnay"
 user-name = "David Tolnay"
@@ -5032,6 +5032,12 @@
 notes = "Adds panics to prevent a block size of zero from causing unsoundness."
 aggregated-from = 
"https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml";
 
+[[audits.zcash.audits.bs58]]
+who = "Daira-Emma Hopwood <[email protected]>"
+criteria = "safe-to-deploy"
+delta = "0.5.0 -> 0.5.1"
+aggregated-from = 
"https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml";
+
 [[audits.zcash.audits.constant_time_eq]]
 who = "Jack Grigg <[email protected]>"
 criteria = "safe-to-deploy"

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/himmelblau/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.himmelblau.new.1981/vendor.tar.zst differ: char 7, 
line 1

Reply via email to