From a55f277ac3eb8d5d027c2a9407385b20ee4609ef Mon Sep 17 00:00:00 2001 From: Firstyear Date: Mon, 27 Jan 2020 13:37:55 +1000 Subject: [PATCH] Add pragma integrity check to verify (#175) --- kanidm_proto/src/v1.rs | 1 + kanidmd/src/lib/be/idl_sqlite.rs | 47 ++++++++++++++++++++++++++++++-- kanidmd/src/lib/be/mod.rs | 4 +-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/kanidm_proto/src/v1.rs b/kanidm_proto/src/v1.rs index 1ea4f5a7c..82bc3b41f 100644 --- a/kanidm_proto/src/v1.rs +++ b/kanidm_proto/src/v1.rs @@ -39,6 +39,7 @@ pub enum ConsistencyError { InvalidAttributeType(String), DuplicateUniqueAttribute(String), InvalidSPN(u64), + SqliteIntegrityFailure, } #[derive(Serialize, Deserialize, Debug)] diff --git a/kanidmd/src/lib/be/idl_sqlite.rs b/kanidmd/src/lib/be/idl_sqlite.rs index 99c2e1e84..bde351d64 100644 --- a/kanidmd/src/lib/be/idl_sqlite.rs +++ b/kanidmd/src/lib/be/idl_sqlite.rs @@ -3,7 +3,7 @@ use crate::be::{IdEntry, IDL}; use crate::utils::SID; use crate::value::IndexType; use idlset::IDLBitRange; -use kanidm_proto::v1::OperationError; +use kanidm_proto::v1::{ConsistencyError, OperationError}; use r2d2::Pool; use r2d2_sqlite::SqliteConnectionManager; use rusqlite::types::ToSql; @@ -215,6 +215,37 @@ pub trait IdlSqliteTransaction { }) .map_err(|_| OperationError::SQLiteError) } + + fn verify(&self) -> Vec> { + let mut stmt = match self.get_conn().prepare("PRAGMA integrity_check;") { + Ok(r) => r, + Err(_) => return vec![Err(ConsistencyError::SqliteIntegrityFailure)], + }; + + let r = match stmt.query(NO_PARAMS) { + Ok(mut rows) => { + match rows.next() { + Ok(Some(v)) => { + // println!("{:?}", v.column_names()); + let r: Result = v.get(0); + match r { + Ok(t) => { + if t == "ok" { + Vec::new() + } else { + vec![Err(ConsistencyError::SqliteIntegrityFailure)] + } + } + Err(_) => vec![Err(ConsistencyError::SqliteIntegrityFailure)], + } + } + _ => vec![Err(ConsistencyError::SqliteIntegrityFailure)], + } + } + Err(_) => vec![Err(ConsistencyError::SqliteIntegrityFailure)], + }; + r + } } impl IdlSqliteTransaction for IdlSqliteReadTransaction { @@ -709,4 +740,16 @@ impl IdlSqlite { } #[cfg(test)] -mod tests {} +mod tests { + use crate::audit::AuditScope; + use crate::be::idl_sqlite::{IdlSqlite, IdlSqliteTransaction}; + + #[test] + fn test_idl_sqlite_verify() { + let mut audit = AuditScope::new("run_test"); + let be = IdlSqlite::new(&mut audit, "", 1).unwrap(); + let be_w = be.write(); + let r = be_w.verify(); + assert!(r.len() == 0); + } +} diff --git a/kanidmd/src/lib/be/mod.rs b/kanidmd/src/lib/be/mod.rs index a8b76d4d2..d636b24da 100644 --- a/kanidmd/src/lib/be/mod.rs +++ b/kanidmd/src/lib/be/mod.rs @@ -394,8 +394,8 @@ pub trait BackendTransaction { } fn verify(&self) -> Vec> { - // TODO: Implement this!!! - Vec::new() + // Vec::new() + self.get_idlayer().verify() } fn backup(&self, audit: &mut AuditScope, dst_path: &str) -> Result<(), OperationError> {