kurbu5_kdb_rs/lib.rs
1//! Safe, idiomatic Rust API for writing MIT Kerberos KDB driver plugins.
2//!
3//! # Overview
4//!
5//! A KDB plugin is a shared library loaded by `libkdb5` at runtime. It must
6//! export the C symbol `kdb_function_table` containing a filled-in
7//! `kdb_vftabl` struct. This crate hides all of that plumbing
8//! behind a single trait and a macro.
9//!
10//! # Quick start
11//!
12//! ```rust,ignore
13//! use kurbu5_kdb_rs::{kdb_plugin, KdbModule, KdbContext, KdbError, LookupFlags, OpenMode};
14//! use kurbu5_kdb_rs::{PrincipalRef, PrincipalEntry};
15//!
16//! pub struct MyKdb { path: String }
17//!
18//! impl KdbModule for MyKdb {
19//! fn open(
20//! _ctx: &KdbContext<'_>,
21//! conf_section: &str,
22//! _args: &[&str],
23//! _mode: OpenMode,
24//! ) -> Result<Self, KdbError> {
25//! Ok(MyKdb { path: format!("/var/kerberos/{}.db", conf_section) })
26//! }
27//!
28//! fn get_principal(
29//! &self,
30//! _ctx: &KdbContext<'_>,
31//! _search_for: PrincipalRef<'_>,
32//! _flags: LookupFlags,
33//! ) -> Result<Option<PrincipalEntry>, KdbError>
34//! {
35//! Ok(None) // not found
36//! }
37//! }
38//!
39//! kdb_plugin!(mykdb, MyKdb);
40//! // Exports C symbol: kdb_function_table (libkdb5 selects the .so by the
41//! // name given in krb5.conf db_library, then dlsym's this fixed symbol)
42//! ```
43//!
44//! # Safety model
45//!
46//! Unsafe code in this crate is confined to [`glue`], [`context`], and
47//! [`backing_db`]; every unsafe block carries a `// SAFETY:` comment.
48//! Plugin authors never need to write `unsafe` themselves.
49
50pub mod backing_db;
51pub mod context;
52pub mod error;
53pub mod key_data;
54pub mod module;
55pub mod policy;
56pub mod principal;
57pub mod tl_data;
58pub mod types;
59
60// The glue module is #[doc(hidden)] so it does not appear in rustdoc, but it
61// must be `pub` so the `kdb_plugin!` macro can reference it from other crates.
62#[doc(hidden)]
63pub mod glue;
64
65// Re-export the raw sys types namespaced under `sys`.
66#[doc(hidden)]
67pub mod sys {
68 pub use kdb_sys::*;
69}
70
71// ---------------------------------------------------------------------------
72// Public API surface
73// ---------------------------------------------------------------------------
74
75pub use backing_db::BackingDb;
76pub use context::{KdbContext, Krb5Context};
77pub use error::{KdbError, PolicyDenied};
78pub use key_data::{
79 DecryptKeyRequest, EncryptKeyRequest, KeyBlock, KeyDataBuilder,
80 KeyDataOwned, KeyDataRef, KeyDataSlice, KeySalt,
81};
82pub use module::{
83 AddressRef, AsAuditEvent, AsPolicyRequest, AuthIndicators,
84 DelegationRequest, KdbModule, KdcRequestRef, PaDataIter, PacBuilder,
85 PacIssuanceOutput, PacIssuanceRequest, PacRef, ResourceDelegationRequest,
86 S4uX509Request, TgsPolicyRequest, TicketRef,
87};
88pub use policy::{PolicyEntry, PolicyEntryRef};
89pub use principal::{
90 OwnedPrincipal, PrincipalEntry, PrincipalEntryRef, PrincipalRef,
91};
92pub use tl_data::{
93 GenericFree, KdbFree, KdbTlDataList, OwnedTlDataList, TlDataBuilder,
94 TlDataFreePolicy, TlDataIter, TlDataList, TlDataRef,
95};
96pub use types::{
97 AccessMode, IterFlags, KdcOptions, LockMode, LookupFlags, OpenMode,
98 PrincipalAttributes, ServerType, TicketFlags, Timestamp, TlDataType,
99};
100
101// ---------------------------------------------------------------------------
102// Proc-macro re-exports (derive feature)
103// ---------------------------------------------------------------------------
104
105/// Rename a method for `#[derive(KdbModule)]` dispatch.
106/// See `kurbu5_kdb_derive::kdb_method` for details.
107#[cfg(feature = "derive")]
108pub use kurbu5_kdb_derive::kdb_method;
109
110/// Mark an inherent `impl` block containing KDB override methods.
111/// See `kurbu5_kdb_derive::kdb_impl` for details.
112#[cfg(feature = "derive")]
113pub use kurbu5_kdb_derive::kdb_impl;
114
115/// Derive `KdbModule` for overlay plugins via delegation to a backing field.
116///
117/// The derive macro and the [`KdbModule`] trait share the same name, exactly
118/// as `serde::Serialize` covers both the derive and the trait.
119/// See `kurbu5_kdb_derive::KdbModule` for full attribute documentation.
120#[cfg(feature = "derive")]
121pub use kurbu5_kdb_derive::KdbModule;
122
123// ---------------------------------------------------------------------------
124// Plugin export macro
125// ---------------------------------------------------------------------------
126
127/// Register a KDB plugin module and export the C vtable symbol.
128///
129/// Generates and exports the C symbol `kdb_function_table` that `libkdb5`
130/// looks for when loading the plugin. The plugin is selected by filename:
131/// `db_library = mykdb` in `krb5.conf` causes `libkdb5` to load
132/// `libmykdb.so` and then `dlsym` for `kdb_function_table`.
133///
134/// # Example
135///
136/// ```rust,ignore
137/// kdb_plugin!(mykdb, MyKdb);
138/// // Equivalent to:
139/// // #[no_mangle]
140/// // pub static kdb_function_table: kurbu5_kdb_rs::sys::kdb_vftabl =
141/// // kurbu5_kdb_rs::glue::make_vftabl::<MyKdb>();
142/// ```
143///
144/// The crate must be compiled as a `cdylib`:
145/// ```toml
146/// [lib]
147/// crate-type = ["cdylib"]
148/// ```
149#[macro_export]
150macro_rules! kdb_plugin {
151 ($name:ident, $module:ty) => {
152 // SAFETY: kdb_vftabl is a C struct of function pointers. All pointer
153 // values are produced by make_vftabl<M>() which generates correct
154 // extern "C" functions. The static is placed in the .data section
155 // and has the C ABI symbol name that libkdb5 dlsym's for.
156 #[no_mangle]
157 pub static kdb_function_table: $crate::sys::kdb_vftabl =
158 $crate::glue::make_vftabl::<$module>();
159 };
160}