1use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntrySealed};
7use crate::event::{CreateEvent, DeleteEvent, ModifyEvent, ReviveRecycledEvent};
8use crate::prelude::*;
9use std::collections::{BTreeMap, BTreeSet};
10use std::sync::Arc;
11
12mod attrunique;
13mod base;
14mod cred_import;
15mod default_values;
16mod domain;
17pub(crate) mod dyngroup;
18mod eckeygen;
19pub(crate) mod gidnumber;
20pub(crate) mod hmac_name_unique;
21mod keyobject;
22mod memberof;
23mod namehistory;
24mod oauth2;
25mod refint;
26mod session;
27mod spn;
28mod valuedeny;
29
30trait Plugin {
31 fn id() -> &'static str;
32
33 fn pre_create_transform(
34 _qs: &mut QueryServerWriteTransaction,
35 _cand: &mut Vec<EntryInvalidNew>,
36 _ce: &CreateEvent,
37 ) -> Result<(), OperationError> {
38 error!(
39 "plugin {} has an unimplemented pre_create_transform!",
40 Self::id()
41 );
42 debug_assert!(false);
43 Err(OperationError::InvalidState)
44 }
45
46 #[allow(dead_code)]
47 fn pre_create(
48 _qs: &mut QueryServerWriteTransaction,
49 _cand: &[EntrySealedNew],
51 _ce: &CreateEvent,
52 ) -> Result<(), OperationError> {
53 error!("plugin {} has an unimplemented pre_create!", Self::id());
54 debug_assert!(false);
55 Err(OperationError::InvalidState)
56 }
57
58 fn post_create(
59 _qs: &mut QueryServerWriteTransaction,
60 _cand: &[EntrySealedCommitted],
62 _ce: &CreateEvent,
63 ) -> Result<(), OperationError> {
64 error!("plugin {} has an unimplemented post_create!", Self::id());
65 debug_assert!(false);
66 Err(OperationError::InvalidState)
67 }
68
69 fn teardown_memorials(
70 _qs: &mut QueryServerWriteTransaction,
71 _memorial_pairs: &mut [(&EntrySealedCommitted, &mut EntryInvalidCommitted)],
72 _re: &ReviveRecycledEvent,
73 ) -> Result<(), OperationError> {
74 error!("plugin {} has an unimplemented pre_modify!", Self::id());
75 debug_assert!(false);
76 Err(OperationError::InvalidState)
77 }
78
79 fn pre_modify(
80 _qs: &mut QueryServerWriteTransaction,
81 _pre_cand: &[Arc<EntrySealedCommitted>],
82 _cand: &mut Vec<EntryInvalidCommitted>,
83 _me: &ModifyEvent,
84 ) -> Result<(), OperationError> {
85 error!("plugin {} has an unimplemented pre_modify!", Self::id());
86 debug_assert!(false);
87 Err(OperationError::InvalidState)
88 }
89
90 fn post_modify(
91 _qs: &mut QueryServerWriteTransaction,
92 _pre_cand: &[Arc<EntrySealedCommitted>],
94 _cand: &[EntrySealedCommitted],
95 _ce: &ModifyEvent,
96 ) -> Result<(), OperationError> {
97 error!("plugin {} has an unimplemented post_modify!", Self::id());
98 debug_assert!(false);
99 Err(OperationError::InvalidState)
100 }
101
102 fn pre_batch_modify(
103 _qs: &mut QueryServerWriteTransaction,
104 _pre_cand: &[Arc<EntrySealedCommitted>],
105 _cand: &mut Vec<EntryInvalidCommitted>,
106 _me: &BatchModifyEvent,
107 ) -> Result<(), OperationError> {
108 error!(
109 "plugin {} has an unimplemented pre_batch_modify!",
110 Self::id()
111 );
112 debug_assert!(false);
113 Err(OperationError::InvalidState)
114 }
115
116 fn post_batch_modify(
117 _qs: &mut QueryServerWriteTransaction,
118 _pre_cand: &[Arc<EntrySealedCommitted>],
120 _cand: &[EntrySealedCommitted],
121 _me: &BatchModifyEvent,
122 ) -> Result<(), OperationError> {
123 error!(
124 "plugin {} has an unimplemented post_batch_modify!",
125 Self::id()
126 );
127 debug_assert!(false);
128 Err(OperationError::InvalidState)
129 }
130
131 fn build_memorials(
132 _qs: &mut QueryServerWriteTransaction,
133 _cand: &[Arc<EntrySealedCommitted>],
134 _memorials: &mut BTreeMap<Uuid, EntryInitNew>,
135 _de: &DeleteEvent,
136 ) -> Result<(), OperationError> {
137 error!(
138 "plugin {} has an unimplemented run_build_memorials!",
139 Self::id()
140 );
141 debug_assert!(false);
142 Err(OperationError::InvalidState)
143 }
144
145 fn pre_delete(
146 _qs: &mut QueryServerWriteTransaction,
147 _cand: &mut Vec<EntryInvalidCommitted>,
148 _de: &DeleteEvent,
149 ) -> Result<(), OperationError> {
150 error!("plugin {} has an unimplemented pre_delete!", Self::id());
151 debug_assert!(false);
152 Err(OperationError::InvalidState)
153 }
154
155 fn post_delete(
156 _qs: &mut QueryServerWriteTransaction,
157 _cand: &[EntrySealedCommitted],
159 _ce: &DeleteEvent,
160 ) -> Result<(), OperationError> {
161 error!("plugin {} has an unimplemented post_delete!", Self::id());
162 debug_assert!(false);
163 Err(OperationError::InvalidState)
164 }
165
166 fn pre_repl_refresh(
167 _qs: &mut QueryServerWriteTransaction,
168 _cand: &[EntryRefreshNew],
169 ) -> Result<(), OperationError> {
170 error!(
171 "plugin {} has an unimplemented pre_repl_refresh!",
172 Self::id()
173 );
174 debug_assert!(false);
175 Err(OperationError::InvalidState)
176 }
177
178 fn post_repl_refresh(
179 _qs: &mut QueryServerWriteTransaction,
180 _cand: &[EntrySealedCommitted],
181 ) -> Result<(), OperationError> {
182 error!(
183 "plugin {} has an unimplemented post_repl_refresh!",
184 Self::id()
185 );
186 debug_assert!(false);
187 Err(OperationError::InvalidState)
188 }
189
190 fn post_repl_incremental_conflict(
203 _qs: &mut QueryServerWriteTransaction,
204 _cand: &[(EntrySealedCommitted, Arc<EntrySealedCommitted>)],
205 _conflict_uuids: &mut BTreeSet<Uuid>,
206 ) -> Result<(), OperationError> {
207 error!(
208 "plugin {} has an unimplemented post_repl_incremental_conflict!",
209 Self::id()
210 );
211 debug_assert!(false);
212 Err(OperationError::InvalidState)
213 }
214
215 fn post_repl_incremental(
216 _qs: &mut QueryServerWriteTransaction,
217 _pre_cand: &[Arc<EntrySealedCommitted>],
218 _cand: &[EntrySealedCommitted],
219 _conflict_uuids: &BTreeSet<Uuid>,
220 ) -> Result<(), OperationError> {
221 error!(
222 "plugin {} has an unimplemented post_repl_incremental!",
223 Self::id()
224 );
225 debug_assert!(false);
226 Err(OperationError::InvalidState)
227 }
228
229 fn verify(_qs: &mut QueryServerReadTransaction) -> Vec<Result<(), ConsistencyError>> {
230 error!("plugin {} has an unimplemented verify!", Self::id());
231 vec![Err(ConsistencyError::Unknown)]
232 }
233}
234
235pub struct Plugins {}
236
237macro_rules! run_verify_plugin {
238 (
239 $qs:ident,
240 $results:expr,
241 $target_plugin:ty
242 ) => {{
243 let mut r = <$target_plugin>::verify($qs);
244 $results.append(&mut r);
245 }};
246}
247
248impl Plugins {
249 #[instrument(level = "debug", name = "plugins::run_pre_create_transform", skip_all)]
250 pub fn run_pre_create_transform(
251 qs: &mut QueryServerWriteTransaction,
252 cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
253 ce: &CreateEvent,
254 ) -> Result<(), OperationError> {
255 base::Base::pre_create_transform(qs, cand, ce)?;
256 valuedeny::ValueDeny::pre_create_transform(qs, cand, ce)?;
257
258 oauth2::OAuth2::pre_create_transform(qs, cand, ce)?;
259 eckeygen::EcdhKeyGen::pre_create_transform(qs, cand, ce)?;
260 keyobject::KeyObjectManagement::pre_create_transform(qs, cand, ce)?;
261 cred_import::CredImport::pre_create_transform(qs, cand, ce)?;
262
263 gidnumber::GidNumber::pre_create_transform(qs, cand, ce)?;
264 domain::Domain::pre_create_transform(qs, cand, ce)?;
265 spn::Spn::pre_create_transform(qs, cand, ce)?;
266 default_values::DefaultValues::pre_create_transform(qs, cand, ce)?;
267 namehistory::NameHistory::pre_create_transform(qs, cand, ce)?;
268 hmac_name_unique::HmacNameUnique::pre_create_transform(qs, cand, ce)?;
269 attrunique::AttrUnique::pre_create_transform(qs, cand, ce)
271 }
272
273 #[instrument(level = "trace", name = "plugins::run_pre_create", skip_all)]
274 pub fn run_pre_create(
275 _qs: &mut QueryServerWriteTransaction,
276 _cand: &[Entry<EntrySealed, EntryNew>],
277 _ce: &CreateEvent,
278 ) -> Result<(), OperationError> {
279 Ok(())
280 }
281
282 #[instrument(level = "debug", name = "plugins::run_post_create", skip_all)]
283 pub fn run_post_create(
284 qs: &mut QueryServerWriteTransaction,
285 cand: &[Entry<EntrySealed, EntryCommitted>],
286 ce: &CreateEvent,
287 ) -> Result<(), OperationError> {
288 refint::ReferentialIntegrity::post_create(qs, cand, ce)?;
289 memberof::MemberOf::post_create(qs, cand, ce)
290 }
291
292 #[instrument(level = "debug", name = "plugins::run_teardown_memorials", skip_all)]
293 pub fn run_teardown_memorials(
294 qs: &mut QueryServerWriteTransaction,
295 memorial_pairs: &mut [(&EntrySealedCommitted, &mut EntryInvalidCommitted)],
296 re: &ReviveRecycledEvent,
297 ) -> Result<(), OperationError> {
298 hmac_name_unique::HmacNameUnique::teardown_memorials(qs, memorial_pairs, re)
299 }
300
301 #[instrument(level = "debug", name = "plugins::run_pre_modify", skip_all)]
302 pub fn run_pre_modify(
303 qs: &mut QueryServerWriteTransaction,
304 pre_cand: &[Arc<EntrySealedCommitted>],
305 cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
306 me: &ModifyEvent,
307 ) -> Result<(), OperationError> {
308 base::Base::pre_modify(qs, pre_cand, cand, me)?;
309 valuedeny::ValueDeny::pre_modify(qs, pre_cand, cand, me)?;
310
311 oauth2::OAuth2::pre_modify(qs, pre_cand, cand, me)?;
312 eckeygen::EcdhKeyGen::pre_modify(qs, pre_cand, cand, me)?;
313 keyobject::KeyObjectManagement::pre_modify(qs, pre_cand, cand, me)?;
314 cred_import::CredImport::pre_modify(qs, pre_cand, cand, me)?;
315
316 gidnumber::GidNumber::pre_modify(qs, pre_cand, cand, me)?;
317 domain::Domain::pre_modify(qs, pre_cand, cand, me)?;
318 spn::Spn::pre_modify(qs, pre_cand, cand, me)?;
319 session::SessionConsistency::pre_modify(qs, pre_cand, cand, me)?;
320 default_values::DefaultValues::pre_modify(qs, pre_cand, cand, me)?;
321 namehistory::NameHistory::pre_modify(qs, pre_cand, cand, me)?;
322 hmac_name_unique::HmacNameUnique::pre_modify(qs, pre_cand, cand, me)?;
323 attrunique::AttrUnique::pre_modify(qs, pre_cand, cand, me)
325 }
326
327 #[instrument(level = "debug", name = "plugins::run_post_modify", skip_all)]
328 pub fn run_post_modify(
329 qs: &mut QueryServerWriteTransaction,
330 pre_cand: &[Arc<Entry<EntrySealed, EntryCommitted>>],
331 cand: &[Entry<EntrySealed, EntryCommitted>],
332 me: &ModifyEvent,
333 ) -> Result<(), OperationError> {
334 refint::ReferentialIntegrity::post_modify(qs, pre_cand, cand, me)?;
335 spn::Spn::post_modify(qs, pre_cand, cand, me)?;
336 memberof::MemberOf::post_modify(qs, pre_cand, cand, me)
337 }
338
339 #[instrument(level = "debug", name = "plugins::run_pre_batch_modify", skip_all)]
340 pub fn run_pre_batch_modify(
341 qs: &mut QueryServerWriteTransaction,
342 pre_cand: &[Arc<EntrySealedCommitted>],
343 cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
344 me: &BatchModifyEvent,
345 ) -> Result<(), OperationError> {
346 base::Base::pre_batch_modify(qs, pre_cand, cand, me)?;
347 valuedeny::ValueDeny::pre_batch_modify(qs, pre_cand, cand, me)?;
348
349 oauth2::OAuth2::pre_batch_modify(qs, pre_cand, cand, me)?;
350 eckeygen::EcdhKeyGen::pre_batch_modify(qs, pre_cand, cand, me)?;
351 keyobject::KeyObjectManagement::pre_batch_modify(qs, pre_cand, cand, me)?;
352 cred_import::CredImport::pre_batch_modify(qs, pre_cand, cand, me)?;
353
354 gidnumber::GidNumber::pre_batch_modify(qs, pre_cand, cand, me)?;
355 domain::Domain::pre_batch_modify(qs, pre_cand, cand, me)?;
356 spn::Spn::pre_batch_modify(qs, pre_cand, cand, me)?;
357 session::SessionConsistency::pre_batch_modify(qs, pre_cand, cand, me)?;
358 default_values::DefaultValues::pre_batch_modify(qs, pre_cand, cand, me)?;
359 namehistory::NameHistory::pre_batch_modify(qs, pre_cand, cand, me)?;
360 hmac_name_unique::HmacNameUnique::pre_batch_modify(qs, pre_cand, cand, me)?;
361 attrunique::AttrUnique::pre_batch_modify(qs, pre_cand, cand, me)
363 }
364
365 #[instrument(level = "debug", name = "plugins::run_post_batch_modify", skip_all)]
366 pub fn run_post_batch_modify(
367 qs: &mut QueryServerWriteTransaction,
368 pre_cand: &[Arc<Entry<EntrySealed, EntryCommitted>>],
369 cand: &[Entry<EntrySealed, EntryCommitted>],
370 me: &BatchModifyEvent,
371 ) -> Result<(), OperationError> {
372 refint::ReferentialIntegrity::post_batch_modify(qs, pre_cand, cand, me)?;
373 spn::Spn::post_batch_modify(qs, pre_cand, cand, me)?;
374 memberof::MemberOf::post_batch_modify(qs, pre_cand, cand, me)
375 }
376
377 #[instrument(level = "debug", name = "plugins::run_build_memorials", skip_all)]
378 pub fn run_build_memorials(
379 qs: &mut QueryServerWriteTransaction,
380 cand: &[Arc<EntrySealedCommitted>],
381 memorials: &mut BTreeMap<Uuid, EntryInitNew>,
382 de: &DeleteEvent,
383 ) -> Result<(), OperationError> {
384 hmac_name_unique::HmacNameUnique::build_memorials(qs, cand, memorials, de)
385 }
386
387 #[instrument(level = "debug", name = "plugins::run_pre_delete", skip_all)]
388 pub fn run_pre_delete(
389 qs: &mut QueryServerWriteTransaction,
390 cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
391 de: &DeleteEvent,
392 ) -> Result<(), OperationError> {
393 memberof::MemberOf::pre_delete(qs, cand, de)
394 }
395
396 #[instrument(level = "debug", name = "plugins::run_post_delete", skip_all)]
397 pub fn run_post_delete(
398 qs: &mut QueryServerWriteTransaction,
399 cand: &[Entry<EntrySealed, EntryCommitted>],
400 de: &DeleteEvent,
401 ) -> Result<(), OperationError> {
402 refint::ReferentialIntegrity::post_delete(qs, cand, de)?;
403 memberof::MemberOf::post_delete(qs, cand, de)
404 }
405
406 #[instrument(level = "debug", name = "plugins::run_pre_repl_refresh", skip_all)]
407 pub fn run_pre_repl_refresh(
408 qs: &mut QueryServerWriteTransaction,
409 cand: &[EntryRefreshNew],
410 ) -> Result<(), OperationError> {
411 attrunique::AttrUnique::pre_repl_refresh(qs, cand)
412 }
413
414 #[instrument(level = "debug", name = "plugins::run_post_repl_refresh", skip_all)]
415 pub fn run_post_repl_refresh(
416 qs: &mut QueryServerWriteTransaction,
417 cand: &[EntrySealedCommitted],
418 ) -> Result<(), OperationError> {
419 refint::ReferentialIntegrity::post_repl_refresh(qs, cand)?;
420 memberof::MemberOf::post_repl_refresh(qs, cand)
421 }
422
423 #[instrument(level = "debug", name = "plugins::run_pre_repl_incremental", skip_all)]
424 pub fn run_pre_repl_incremental(
425 _qs: &mut QueryServerWriteTransaction,
426 _cand: &mut [(EntryIncrementalCommitted, Arc<EntrySealedCommitted>)],
427 ) -> Result<(), OperationError> {
428 Ok(())
433 }
434
435 #[instrument(
436 level = "debug",
437 name = "plugins::run_post_repl_incremental_conflict",
438 skip_all
439 )]
440 pub fn run_post_repl_incremental_conflict(
441 qs: &mut QueryServerWriteTransaction,
442 cand: &[(EntrySealedCommitted, Arc<EntrySealedCommitted>)],
443 conflict_uuids: &mut BTreeSet<Uuid>,
444 ) -> Result<(), OperationError> {
445 attrunique::AttrUnique::post_repl_incremental_conflict(qs, cand, conflict_uuids)?;
447 refint::ReferentialIntegrity::post_repl_incremental_conflict(qs, cand, conflict_uuids)
449 }
450
451 #[instrument(level = "debug", name = "plugins::run_post_repl_incremental", skip_all)]
452 pub fn run_post_repl_incremental(
453 qs: &mut QueryServerWriteTransaction,
454 pre_cand: &[Arc<EntrySealedCommitted>],
455 cand: &[EntrySealedCommitted],
456 conflict_uuids: &BTreeSet<Uuid>,
457 ) -> Result<(), OperationError> {
458 spn::Spn::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)?;
461 refint::ReferentialIntegrity::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)?;
463 memberof::MemberOf::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)
465 }
466
467 #[instrument(level = "debug", name = "plugins::run_verify", skip_all)]
468 pub fn run_verify(
469 qs: &mut QueryServerReadTransaction,
470 results: &mut Vec<Result<(), ConsistencyError>>,
471 ) {
472 run_verify_plugin!(qs, results, base::Base);
473 run_verify_plugin!(qs, results, valuedeny::ValueDeny);
474 run_verify_plugin!(qs, results, attrunique::AttrUnique);
475 run_verify_plugin!(qs, results, refint::ReferentialIntegrity);
476 run_verify_plugin!(qs, results, keyobject::KeyObjectManagement);
477 run_verify_plugin!(qs, results, dyngroup::DynGroup);
478 run_verify_plugin!(qs, results, memberof::MemberOf);
479 run_verify_plugin!(qs, results, spn::Spn);
480 }
481}