Fix SSO/LDAP user origin overwritten by set_password
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()`.
This commit is contained in:
@@ -236,13 +236,17 @@ impl Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let is_sentinel = password.is_some_and(|p| p == "*");
|
||||||
|
|
||||||
match password.map(utils::hash::password) {
|
match password.map(utils::hash::password) {
|
||||||
| None => {
|
| None => {
|
||||||
self.db.userid_password.insert(user_id, b"");
|
self.db.userid_password.insert(user_id, b"");
|
||||||
},
|
},
|
||||||
| Some(Ok(hash)) => {
|
| Some(Ok(hash)) => {
|
||||||
self.db.userid_password.insert(user_id, 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)) => {
|
| Some(Err(e)) => {
|
||||||
return Err!(Request(InvalidParam(
|
return Err!(Request(InvalidParam(
|
||||||
|
|||||||
Reference in New Issue
Block a user