Correctly return that uuid2spn changed on domain rename (#3402)

Due to a missing equality check in value, when a domain
rename occured, the uuid2spn index differential function
did not correctly detect that the domain name had updated
which meant that the uuid2spn index was not updated. Only
this index was affected, and a manual reindex would
resolve.
This commit is contained in:
Firstyear 2025-02-06 08:50:45 +10:00 committed by GitHub
parent 41b2eac1f4
commit 43b7f80535
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 10 deletions

View file

@ -208,10 +208,7 @@ impl Spn {
// All we do is purge spn, and allow the plugin to recreate. Neat! It's also all still // All we do is purge spn, and allow the plugin to recreate. Neat! It's also all still
// within the transaction, just in case! // within the transaction, just in case!
qs.internal_modify( qs.internal_modify(
&filter!(f_or!([ &filter!(f_pres(Attribute::Spn)),
f_eq(Attribute::Class, EntryClass::Group.into()),
f_eq(Attribute::Class, EntryClass::Account.into()),
])),
&modlist!([m_purge(Attribute::Spn)]), &modlist!([m_purge(Attribute::Spn)]),
) )
} }
@ -332,12 +329,40 @@ mod tests {
async fn test_spn_regen_domain_rename(server: &QueryServer) { async fn test_spn_regen_domain_rename(server: &QueryServer) {
let mut server_txn = server.write(duration_from_epoch_now()).await.unwrap(); let mut server_txn = server.write(duration_from_epoch_now()).await.unwrap();
let ex1 = Value::new_spn_str("admin", "example.com"); let ex1 = Value::new_spn_str("a_testperson1", "example.com");
let ex2 = Value::new_spn_str("admin", "new.example.com"); let ex2 = Value::new_spn_str("a_testperson1", "new.example.com");
let t_uuid = Uuid::new_v4();
let g_uuid = Uuid::new_v4();
assert!(server_txn
.internal_create(vec![
entry_init!(
(Attribute::Class, EntryClass::Object.to_value()),
(Attribute::Class, EntryClass::Account.to_value()),
(Attribute::Class, EntryClass::Person.to_value()),
(Attribute::Name, Value::new_iname("a_testperson1")),
(Attribute::Uuid, Value::Uuid(t_uuid)),
(Attribute::Description, Value::new_utf8s("testperson1")),
(Attribute::DisplayName, Value::new_utf8s("testperson1"))
),
entry_init!(
(Attribute::Class, EntryClass::Object.to_value()),
(Attribute::Class, EntryClass::Group.to_value()),
(Attribute::Name, Value::new_iname("testgroup")),
(Attribute::Uuid, Value::Uuid(g_uuid)),
(Attribute::Member, Value::Refer(t_uuid))
),
])
.is_ok());
assert!(server_txn.commit().is_ok());
let mut server_txn = server.write(duration_from_epoch_now()).await.unwrap();
// get the current domain name // get the current domain name
// check the spn on admin is admin@<initial domain> // check the spn on admin is admin@<initial domain>
let e_pre = server_txn let e_pre = server_txn
.internal_search_uuid(UUID_ADMIN) .internal_search_uuid(t_uuid)
.expect("must not fail"); .expect("must not fail");
let e_pre_spn = e_pre.get_ava_single(Attribute::Spn).expect("must not fail"); let e_pre_spn = e_pre.get_ava_single(Attribute::Spn).expect("must not fail");
@ -350,9 +375,12 @@ mod tests {
.danger_domain_rename("new.example.com") .danger_domain_rename("new.example.com")
.expect("should not fail!"); .expect("should not fail!");
assert!(server_txn.commit().is_ok());
let mut server_txn = server.write(duration_from_epoch_now()).await.unwrap();
// check the spn on admin is admin@<new domain> // check the spn on admin is admin@<new domain>
let e_post = server_txn let e_post = server_txn
.internal_search_uuid(UUID_ADMIN) .internal_search_uuid(t_uuid)
.expect("must not fail"); .expect("must not fail");
let e_post_spn = e_post let e_post_spn = e_post
@ -362,6 +390,13 @@ mod tests {
debug!("{:?}", ex2); debug!("{:?}", ex2);
assert_eq!(e_post_spn, ex2); assert_eq!(e_post_spn, ex2);
server_txn.commit().expect("Must not fail"); // Assert that the uuid2spn index updated.
let testuser_spn = server_txn
.uuid_to_spn(t_uuid)
.expect("Must be able to retrieve the spn")
.expect("Value must not be none");
assert_eq!(testuser_spn, ex2);
assert!(server_txn.commit().is_ok());
} }
} }

View file

@ -1311,13 +1311,14 @@ impl PartialEq for Value {
| (Value::Iname(a), Value::Iname(b)) | (Value::Iname(a), Value::Iname(b))
| (Value::Cred(a, _), Value::Cred(b, _)) | (Value::Cred(a, _), Value::Cred(b, _))
| (Value::SshKey(a, _), Value::SshKey(b, _)) | (Value::SshKey(a, _), Value::SshKey(b, _))
| (Value::Spn(a, _), Value::Spn(b, _))
| (Value::Nsuniqueid(a), Value::Nsuniqueid(b)) | (Value::Nsuniqueid(a), Value::Nsuniqueid(b))
| (Value::EmailAddress(a, _), Value::EmailAddress(b, _)) | (Value::EmailAddress(a, _), Value::EmailAddress(b, _))
| (Value::PhoneNumber(a, _), Value::PhoneNumber(b, _)) | (Value::PhoneNumber(a, _), Value::PhoneNumber(b, _))
| (Value::OauthScope(a), Value::OauthScope(b)) | (Value::OauthScope(a), Value::OauthScope(b))
| (Value::PublicBinary(a, _), Value::PublicBinary(b, _)) | (Value::PublicBinary(a, _), Value::PublicBinary(b, _))
| (Value::RestrictedString(a), Value::RestrictedString(b)) => a.eq(b), | (Value::RestrictedString(a), Value::RestrictedString(b)) => a.eq(b),
// Spn - need to check both name and domain.
(Value::Spn(a, c), Value::Spn(b, d)) => a.eq(b) && c.eq(d),
// Uuid, Refer // Uuid, Refer
(Value::Uuid(a), Value::Uuid(b)) | (Value::Refer(a), Value::Refer(b)) => a.eq(b), (Value::Uuid(a), Value::Uuid(b)) | (Value::Refer(a), Value::Refer(b)) => a.eq(b),
// Bool // Bool