From 6bed0d38f45b966c2e7a63a759a5bab5a3475e10 Mon Sep 17 00:00:00 2001 From: Denys Bezmenov Date: Sun, 15 Feb 2026 12:07:17 -0800 Subject: [PATCH] Fix SSO/LDAP user origin overwritten by set_password MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `create()` registers a user with `origin: Some("sso")`, it correctly sets `userid_origin = "sso"` then calls `set_password()`. However, `set_password()` unconditionally overwrites `userid_origin` to "password" whenever the password hash succeeds — including for the sentinel password "*" used by SSO and LDAP accounts. This causes all SSO/LDAP users to have `origin = "password"` in the database, which breaks the UIA SSO bypass check in `uiaa.rs` that gates on `users.origin(sender_user) == "sso"`. As a result, SSO users cannot delete devices or perform other UIA-protected operations because they are prompted for a password they don't have, and the SSO bypass never triggers. Fix: skip the `userid_origin` overwrite when the password is the sentinel value `"*"`, preserving the origin set by `create()`. --- src/service/users/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/service/users/mod.rs b/src/service/users/mod.rs index ef9da781..a4ea1189 100644 --- a/src/service/users/mod.rs +++ b/src/service/users/mod.rs @@ -236,13 +236,17 @@ impl Service { } } + let is_sentinel = password.is_some_and(|p| p == "*"); + match password.map(utils::hash::password) { | None => { self.db.userid_password.insert(user_id, b""); }, | Some(Ok(hash)) => { self.db.userid_password.insert(user_id, hash); - self.db.userid_origin.insert(user_id, "password"); + if !is_sentinel { + self.db.userid_origin.insert(user_id, "password"); + } }, | Some(Err(e)) => { return Err!(Request(InvalidParam(