1use std::collections::BTreeSet;
7use std::sync::Arc;
8
9use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntrySealed};
10use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
11use crate::prelude::*;
12
13mod attrunique;
14mod base;
15mod cred_import;
16mod default_values;
17mod domain;
18pub(crate) mod dyngroup;
19mod eckeygen;
20pub(crate) mod gidnumber;
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 admin_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 admin_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 admin_error!("plugin {} has an unimplemented post_create!", Self::id());
65 debug_assert!(false);
66 Err(OperationError::InvalidState)
67 }
68
69 fn pre_modify(
70 _qs: &mut QueryServerWriteTransaction,
71 _pre_cand: &[Arc<EntrySealedCommitted>],
72 _cand: &mut Vec<EntryInvalidCommitted>,
73 _me: &ModifyEvent,
74 ) -> Result<(), OperationError> {
75 admin_error!("plugin {} has an unimplemented pre_modify!", Self::id());
76 debug_assert!(false);
77 Err(OperationError::InvalidState)
78 }
79
80 fn post_modify(
81 _qs: &mut QueryServerWriteTransaction,
82 _pre_cand: &[Arc<EntrySealedCommitted>],
84 _cand: &[EntrySealedCommitted],
85 _ce: &ModifyEvent,
86 ) -> Result<(), OperationError> {
87 admin_error!("plugin {} has an unimplemented post_modify!", Self::id());
88 debug_assert!(false);
89 Err(OperationError::InvalidState)
90 }
91
92 fn pre_batch_modify(
93 _qs: &mut QueryServerWriteTransaction,
94 _pre_cand: &[Arc<EntrySealedCommitted>],
95 _cand: &mut Vec<EntryInvalidCommitted>,
96 _me: &BatchModifyEvent,
97 ) -> Result<(), OperationError> {
98 admin_error!(
99 "plugin {} has an unimplemented pre_batch_modify!",
100 Self::id()
101 );
102 debug_assert!(false);
103 Err(OperationError::InvalidState)
104 }
105
106 fn post_batch_modify(
107 _qs: &mut QueryServerWriteTransaction,
108 _pre_cand: &[Arc<EntrySealedCommitted>],
110 _cand: &[EntrySealedCommitted],
111 _me: &BatchModifyEvent,
112 ) -> Result<(), OperationError> {
113 admin_error!(
114 "plugin {} has an unimplemented post_batch_modify!",
115 Self::id()
116 );
117 debug_assert!(false);
118 Err(OperationError::InvalidState)
119 }
120
121 fn pre_delete(
122 _qs: &mut QueryServerWriteTransaction,
123 _cand: &mut Vec<EntryInvalidCommitted>,
124 _de: &DeleteEvent,
125 ) -> Result<(), OperationError> {
126 admin_error!("plugin {} has an unimplemented pre_delete!", Self::id());
127 debug_assert!(false);
128 Err(OperationError::InvalidState)
129 }
130
131 fn post_delete(
132 _qs: &mut QueryServerWriteTransaction,
133 _cand: &[EntrySealedCommitted],
135 _ce: &DeleteEvent,
136 ) -> Result<(), OperationError> {
137 admin_error!("plugin {} has an unimplemented post_delete!", Self::id());
138 debug_assert!(false);
139 Err(OperationError::InvalidState)
140 }
141
142 fn pre_repl_refresh(
143 _qs: &mut QueryServerWriteTransaction,
144 _cand: &[EntryRefreshNew],
145 ) -> Result<(), OperationError> {
146 admin_error!(
147 "plugin {} has an unimplemented pre_repl_refresh!",
148 Self::id()
149 );
150 debug_assert!(false);
151 Err(OperationError::InvalidState)
152 }
153
154 fn post_repl_refresh(
155 _qs: &mut QueryServerWriteTransaction,
156 _cand: &[EntrySealedCommitted],
157 ) -> Result<(), OperationError> {
158 admin_error!(
159 "plugin {} has an unimplemented post_repl_refresh!",
160 Self::id()
161 );
162 debug_assert!(false);
163 Err(OperationError::InvalidState)
164 }
165
166 fn post_repl_incremental_conflict(
179 _qs: &mut QueryServerWriteTransaction,
180 _cand: &[(EntrySealedCommitted, Arc<EntrySealedCommitted>)],
181 _conflict_uuids: &mut BTreeSet<Uuid>,
182 ) -> Result<(), OperationError> {
183 admin_error!(
184 "plugin {} has an unimplemented post_repl_incremental_conflict!",
185 Self::id()
186 );
187 debug_assert!(false);
188 Err(OperationError::InvalidState)
189 }
190
191 fn post_repl_incremental(
192 _qs: &mut QueryServerWriteTransaction,
193 _pre_cand: &[Arc<EntrySealedCommitted>],
194 _cand: &[EntrySealedCommitted],
195 _conflict_uuids: &BTreeSet<Uuid>,
196 ) -> Result<(), OperationError> {
197 admin_error!(
198 "plugin {} has an unimplemented post_repl_incremental!",
199 Self::id()
200 );
201 debug_assert!(false);
202 Err(OperationError::InvalidState)
203 }
204
205 fn verify(_qs: &mut QueryServerReadTransaction) -> Vec<Result<(), ConsistencyError>> {
206 admin_error!("plugin {} has an unimplemented verify!", Self::id());
207 vec![Err(ConsistencyError::Unknown)]
208 }
209}
210
211pub struct Plugins {}
212
213macro_rules! run_verify_plugin {
214 (
215 $qs:ident,
216 $results:expr,
217 $target_plugin:ty
218 ) => {{
219 let mut r = <$target_plugin>::verify($qs);
220 $results.append(&mut r);
221 }};
222}
223
224impl Plugins {
225 #[instrument(level = "debug", name = "plugins::run_pre_create_transform", skip_all)]
226 pub fn run_pre_create_transform(
227 qs: &mut QueryServerWriteTransaction,
228 cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
229 ce: &CreateEvent,
230 ) -> Result<(), OperationError> {
231 base::Base::pre_create_transform(qs, cand, ce)?;
232 valuedeny::ValueDeny::pre_create_transform(qs, cand, ce)?;
233
234 oauth2::OAuth2::pre_create_transform(qs, cand, ce)?;
235 eckeygen::EcdhKeyGen::pre_create_transform(qs, cand, ce)?;
236 keyobject::KeyObjectManagement::pre_create_transform(qs, cand, ce)?;
237 cred_import::CredImport::pre_create_transform(qs, cand, ce)?;
238
239 gidnumber::GidNumber::pre_create_transform(qs, cand, ce)?;
240 domain::Domain::pre_create_transform(qs, cand, ce)?;
241 spn::Spn::pre_create_transform(qs, cand, ce)?;
242 default_values::DefaultValues::pre_create_transform(qs, cand, ce)?;
243 namehistory::NameHistory::pre_create_transform(qs, cand, ce)?;
244 attrunique::AttrUnique::pre_create_transform(qs, cand, ce)
246 }
247
248 #[instrument(level = "trace", name = "plugins::run_pre_create", skip_all)]
249 pub fn run_pre_create(
250 _qs: &mut QueryServerWriteTransaction,
251 _cand: &[Entry<EntrySealed, EntryNew>],
252 _ce: &CreateEvent,
253 ) -> Result<(), OperationError> {
254 Ok(())
255 }
256
257 #[instrument(level = "debug", name = "plugins::run_post_create", skip_all)]
258 pub fn run_post_create(
259 qs: &mut QueryServerWriteTransaction,
260 cand: &[Entry<EntrySealed, EntryCommitted>],
261 ce: &CreateEvent,
262 ) -> Result<(), OperationError> {
263 refint::ReferentialIntegrity::post_create(qs, cand, ce)?;
264 memberof::MemberOf::post_create(qs, cand, ce)
265 }
266
267 #[instrument(level = "debug", name = "plugins::run_pre_modify", skip_all)]
268 pub fn run_pre_modify(
269 qs: &mut QueryServerWriteTransaction,
270 pre_cand: &[Arc<EntrySealedCommitted>],
271 cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
272 me: &ModifyEvent,
273 ) -> Result<(), OperationError> {
274 base::Base::pre_modify(qs, pre_cand, cand, me)?;
275 valuedeny::ValueDeny::pre_modify(qs, pre_cand, cand, me)?;
276
277 oauth2::OAuth2::pre_modify(qs, pre_cand, cand, me)?;
278 eckeygen::EcdhKeyGen::pre_modify(qs, pre_cand, cand, me)?;
279 keyobject::KeyObjectManagement::pre_modify(qs, pre_cand, cand, me)?;
280 cred_import::CredImport::pre_modify(qs, pre_cand, cand, me)?;
281
282 gidnumber::GidNumber::pre_modify(qs, pre_cand, cand, me)?;
283 domain::Domain::pre_modify(qs, pre_cand, cand, me)?;
284 spn::Spn::pre_modify(qs, pre_cand, cand, me)?;
285 session::SessionConsistency::pre_modify(qs, pre_cand, cand, me)?;
286 default_values::DefaultValues::pre_modify(qs, pre_cand, cand, me)?;
287 namehistory::NameHistory::pre_modify(qs, pre_cand, cand, me)?;
288 attrunique::AttrUnique::pre_modify(qs, pre_cand, cand, me)
290 }
291
292 #[instrument(level = "debug", name = "plugins::run_post_modify", skip_all)]
293 pub fn run_post_modify(
294 qs: &mut QueryServerWriteTransaction,
295 pre_cand: &[Arc<Entry<EntrySealed, EntryCommitted>>],
296 cand: &[Entry<EntrySealed, EntryCommitted>],
297 me: &ModifyEvent,
298 ) -> Result<(), OperationError> {
299 refint::ReferentialIntegrity::post_modify(qs, pre_cand, cand, me)?;
300 spn::Spn::post_modify(qs, pre_cand, cand, me)?;
301 memberof::MemberOf::post_modify(qs, pre_cand, cand, me)
302 }
303
304 #[instrument(level = "debug", name = "plugins::run_pre_batch_modify", skip_all)]
305 pub fn run_pre_batch_modify(
306 qs: &mut QueryServerWriteTransaction,
307 pre_cand: &[Arc<EntrySealedCommitted>],
308 cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
309 me: &BatchModifyEvent,
310 ) -> Result<(), OperationError> {
311 base::Base::pre_batch_modify(qs, pre_cand, cand, me)?;
312 valuedeny::ValueDeny::pre_batch_modify(qs, pre_cand, cand, me)?;
313
314 oauth2::OAuth2::pre_batch_modify(qs, pre_cand, cand, me)?;
315 eckeygen::EcdhKeyGen::pre_batch_modify(qs, pre_cand, cand, me)?;
316 keyobject::KeyObjectManagement::pre_batch_modify(qs, pre_cand, cand, me)?;
317 cred_import::CredImport::pre_batch_modify(qs, pre_cand, cand, me)?;
318
319 gidnumber::GidNumber::pre_batch_modify(qs, pre_cand, cand, me)?;
320 domain::Domain::pre_batch_modify(qs, pre_cand, cand, me)?;
321 spn::Spn::pre_batch_modify(qs, pre_cand, cand, me)?;
322 session::SessionConsistency::pre_batch_modify(qs, pre_cand, cand, me)?;
323 default_values::DefaultValues::pre_batch_modify(qs, pre_cand, cand, me)?;
324 namehistory::NameHistory::pre_batch_modify(qs, pre_cand, cand, me)?;
325 attrunique::AttrUnique::pre_batch_modify(qs, pre_cand, cand, me)
327 }
328
329 #[instrument(level = "debug", name = "plugins::run_post_batch_modify", skip_all)]
330 pub fn run_post_batch_modify(
331 qs: &mut QueryServerWriteTransaction,
332 pre_cand: &[Arc<Entry<EntrySealed, EntryCommitted>>],
333 cand: &[Entry<EntrySealed, EntryCommitted>],
334 me: &BatchModifyEvent,
335 ) -> Result<(), OperationError> {
336 refint::ReferentialIntegrity::post_batch_modify(qs, pre_cand, cand, me)?;
337 spn::Spn::post_batch_modify(qs, pre_cand, cand, me)?;
338 memberof::MemberOf::post_batch_modify(qs, pre_cand, cand, me)
339 }
340
341 #[instrument(level = "debug", name = "plugins::run_pre_delete", skip_all)]
342 pub fn run_pre_delete(
343 qs: &mut QueryServerWriteTransaction,
344 cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
345 de: &DeleteEvent,
346 ) -> Result<(), OperationError> {
347 memberof::MemberOf::pre_delete(qs, cand, de)
348 }
349
350 #[instrument(level = "debug", name = "plugins::run_post_delete", skip_all)]
351 pub fn run_post_delete(
352 qs: &mut QueryServerWriteTransaction,
353 cand: &[Entry<EntrySealed, EntryCommitted>],
354 de: &DeleteEvent,
355 ) -> Result<(), OperationError> {
356 refint::ReferentialIntegrity::post_delete(qs, cand, de)?;
357 memberof::MemberOf::post_delete(qs, cand, de)
358 }
359
360 #[instrument(level = "debug", name = "plugins::run_pre_repl_refresh", skip_all)]
361 pub fn run_pre_repl_refresh(
362 qs: &mut QueryServerWriteTransaction,
363 cand: &[EntryRefreshNew],
364 ) -> Result<(), OperationError> {
365 attrunique::AttrUnique::pre_repl_refresh(qs, cand)
366 }
367
368 #[instrument(level = "debug", name = "plugins::run_post_repl_refresh", skip_all)]
369 pub fn run_post_repl_refresh(
370 qs: &mut QueryServerWriteTransaction,
371 cand: &[EntrySealedCommitted],
372 ) -> Result<(), OperationError> {
373 refint::ReferentialIntegrity::post_repl_refresh(qs, cand)?;
374 memberof::MemberOf::post_repl_refresh(qs, cand)
375 }
376
377 #[instrument(level = "debug", name = "plugins::run_pre_repl_incremental", skip_all)]
378 pub fn run_pre_repl_incremental(
379 _qs: &mut QueryServerWriteTransaction,
380 _cand: &mut [(EntryIncrementalCommitted, Arc<EntrySealedCommitted>)],
381 ) -> Result<(), OperationError> {
382 Ok(())
387 }
388
389 #[instrument(
390 level = "debug",
391 name = "plugins::run_post_repl_incremental_conflict",
392 skip_all
393 )]
394 pub fn run_post_repl_incremental_conflict(
395 qs: &mut QueryServerWriteTransaction,
396 cand: &[(EntrySealedCommitted, Arc<EntrySealedCommitted>)],
397 conflict_uuids: &mut BTreeSet<Uuid>,
398 ) -> Result<(), OperationError> {
399 attrunique::AttrUnique::post_repl_incremental_conflict(qs, cand, conflict_uuids)
401 }
402
403 #[instrument(level = "debug", name = "plugins::run_post_repl_incremental", skip_all)]
404 pub fn run_post_repl_incremental(
405 qs: &mut QueryServerWriteTransaction,
406 pre_cand: &[Arc<EntrySealedCommitted>],
407 cand: &[EntrySealedCommitted],
408 conflict_uuids: &BTreeSet<Uuid>,
409 ) -> Result<(), OperationError> {
410 spn::Spn::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)?;
413 refint::ReferentialIntegrity::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)?;
415 memberof::MemberOf::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)
417 }
418
419 #[instrument(level = "debug", name = "plugins::run_verify", skip_all)]
420 pub fn run_verify(
421 qs: &mut QueryServerReadTransaction,
422 results: &mut Vec<Result<(), ConsistencyError>>,
423 ) {
424 run_verify_plugin!(qs, results, base::Base);
425 run_verify_plugin!(qs, results, valuedeny::ValueDeny);
426 run_verify_plugin!(qs, results, attrunique::AttrUnique);
427 run_verify_plugin!(qs, results, refint::ReferentialIntegrity);
428 run_verify_plugin!(qs, results, keyobject::KeyObjectManagement);
429 run_verify_plugin!(qs, results, dyngroup::DynGroup);
430 run_verify_plugin!(qs, results, memberof::MemberOf);
431 run_verify_plugin!(qs, results, spn::Spn);
432 }
433}