From bb55fa100e00065b326c0ddd0e01ad7b48dabf0b Mon Sep 17 00:00:00 2001 From: David Mulder Date: Fri, 23 Aug 2024 08:02:01 -0600 Subject: [PATCH] Add talloc stackframe handling This appeases errors from libsmbconf that no talloc stackframe was created. Signed-off-by: David Mulder Reviewed-by: Alexander Bokovoy --- rust/Cargo.lock | 10 +++++++ rust/Cargo.toml | 2 +- rust/chelps/src/lib.rs | 21 ++++++++++++++ rust/config/additions.h | 4 +++ rust/config/src/lib.rs | 9 ++++++ rust/dbg/src/lib.rs | 23 +-------------- rust/himmelblaud/Cargo.toml | 1 + rust/himmelblaud/src/main.rs | 35 ++++++++++++++++++++-- rust/talloc/Cargo.toml | 13 +++++++++ rust/talloc/build.rs | 38 ++++++++++++++++++++++++ rust/talloc/src/lib.rs | 56 ++++++++++++++++++++++++++++++++++++ 11 files changed, 187 insertions(+), 25 deletions(-) create mode 100644 rust/talloc/Cargo.toml create mode 100644 rust/talloc/build.rs create mode 100644 rust/talloc/src/lib.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 6f6b3ea31ce..393707f07e7 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -818,6 +818,7 @@ dependencies = [ "serde", "serde_json", "sock", + "talloc", "tdb", "tempfile", "tokio", @@ -2138,6 +2139,15 @@ dependencies = [ "libc", ] +[[package]] +name = "talloc" +version = "4.21.0" +dependencies = [ + "bindgen", + "chelps", + "config", +] + [[package]] name = "tdb" version = "4.21.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 91d0ccbd9c8..c32050b9dd0 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -9,7 +9,7 @@ resolver = "2" members = [ "chelps", "config", "dbg", "himmelblaud", "idmap", "nss", "ntstatus_gen", "pam", - "param", "sock", "tdb", "version", + "param", "sock", "talloc", "tdb", "version", ] [workspace.dependencies] diff --git a/rust/chelps/src/lib.rs b/rust/chelps/src/lib.rs index a702dc35067..79be4f03e5e 100644 --- a/rust/chelps/src/lib.rs +++ b/rust/chelps/src/lib.rs @@ -50,6 +50,27 @@ pub unsafe fn string_free(input: *mut c_char) { } } +#[macro_export] +macro_rules! function { + () => {{ + fn f() {} + fn type_name_of(_: T) -> &'static str { + std::any::type_name::() + } + let name = type_name_of(f); + + let base_name = match name.rfind("::") { + Some(pos) => &name[..pos], + None => name, + }; + let parts: Vec<&str> = base_name + .split("::") + .filter(|&p| p != "{{closure}}") + .collect(); + parts.join("::") + }}; +} + #[cfg(test)] mod tests { use super::*; diff --git a/rust/config/additions.h b/rust/config/additions.h index c9561349028..96a49509ac4 100644 --- a/rust/config/additions.h +++ b/rust/config/additions.h @@ -2,3 +2,7 @@ #ifndef USING_SYSTEM_TDB #define USING_SYSTEM_TDB 0 #endif + +#ifndef USING_SYSTEM_TALLOC +#define USING_SYSTEM_TALLOC 0 +#endif diff --git a/rust/config/src/lib.rs b/rust/config/src/lib.rs index 2f1d2f84a43..a8546eecf65 100644 --- a/rust/config/src/lib.rs +++ b/rust/config/src/lib.rs @@ -40,4 +40,13 @@ mod tests { USING_SYSTEM_TDB ); } + + #[test] + fn test_using_system_talloc() { + assert!( + USING_SYSTEM_TALLOC == 0 || USING_SYSTEM_TALLOC == 1, + "Unexpected value for USING_SYSTEM_TALLOC: {}", + USING_SYSTEM_TALLOC + ); + } } diff --git a/rust/dbg/src/lib.rs b/rust/dbg/src/lib.rs index 2104cdb0d1c..30b66135811 100644 --- a/rust/dbg/src/lib.rs +++ b/rust/dbg/src/lib.rs @@ -79,34 +79,13 @@ macro_rules! debuglevel_set { }}; } -#[macro_export] -macro_rules! function { - () => {{ - fn f() {} - fn type_name_of(_: T) -> &'static str { - std::any::type_name::() - } - let name = type_name_of(f); - - let base_name = match name.rfind("::") { - Some(pos) => &name[..pos], - None => name, - }; - let parts: Vec<&str> = base_name - .split("::") - .filter(|&p| p != "{{closure}}") - .collect(); - parts.join("::") - }}; -} - #[macro_export] macro_rules! DBG_PREFIX { ($level:expr $(, $arg:expr)* $(,)?) => {{ if $level <= $crate::ffi::MAX_DEBUG_LEVEL { let location = format!("{}:{}", file!(), line!()); let location_cstr = chelps::wrap_string(&location); - let function = $crate::function!(); + let function = chelps::function!(); let function_msg = format!("{}: ", function); let function_cstr = chelps::wrap_string(&function); let function_msg_cstr = chelps::wrap_string(&function_msg); diff --git a/rust/himmelblaud/Cargo.toml b/rust/himmelblaud/Cargo.toml index 5806e51af55..dedde9e1f76 100644 --- a/rust/himmelblaud/Cargo.toml +++ b/rust/himmelblaud/Cargo.toml @@ -23,6 +23,7 @@ futures = "0.3.30" serde = "1.0.204" idmap = { workspace = true } libc = { workspace = true } +talloc = { version = "4.21.0", path = "../talloc" } [build-dependencies] version = { path = "../version" } diff --git a/rust/himmelblaud/src/main.rs b/rust/himmelblaud/src/main.rs index 42140a9709c..bc9f2f4f6a4 100644 --- a/rust/himmelblaud/src/main.rs +++ b/rust/himmelblaud/src/main.rs @@ -82,6 +82,8 @@ async fn main() -> ExitCode { let quit_now = Arc::clone(&stop_now); let interrupt_now = Arc::clone(&stop_now); + let frame = talloc::talloc_stackframe!(); + async { // Set the command line debug level if let Some(debuglevel) = clap_args.get_one::("debuglevel") { @@ -97,6 +99,7 @@ async fn main() -> ExitCode { Ok(lp) => lp, Err(e) => { eprintln!("Failed loading smb.conf: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -111,6 +114,7 @@ async fn main() -> ExitCode { "The realm MUST be set in the \ smb.conf to start himmelblaud" ); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -125,6 +129,7 @@ async fn main() -> ExitCode { Ok(Some(logfile)) => debug_set_logfile(&logfile), _ => { eprintln!("Failed to determine logfile name"); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } } @@ -134,14 +139,20 @@ async fn main() -> ExitCode { // Determine the unix socket path let sock_dir_str = match lp.winbindd_socket_directory() { Ok(Some(sock_dir)) => sock_dir, - _ => return ExitCode::FAILURE, + _ => { + talloc::TALLOC_FREE!(frame); + return ExitCode::FAILURE; + } }; let sock_dir = Path::new(&sock_dir_str); let mut sock_path = PathBuf::from(sock_dir); sock_path.push("hb_pipe"); let sock_path = match sock_path.to_str() { Some(sock_path) => sock_path, - None => return ExitCode::FAILURE, + None => { + talloc::TALLOC_FREE!(frame); + return ExitCode::FAILURE; + } }; // Initialize the Himmelblau cache @@ -149,6 +160,7 @@ async fn main() -> ExitCode { Ok(Some(private_cache_path)) => private_cache_path, _ => { DBG_ERR!("Failed to determine private cache path"); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -159,6 +171,7 @@ async fn main() -> ExitCode { "The private directory '{}' does not exist", private_dir.display() ); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } let mut pcache = match PrivateCache::new(&private_cache_path) { @@ -168,6 +181,7 @@ async fn main() -> ExitCode { "Failed to open the himmelblau private cache: {:?}", e ); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -176,11 +190,13 @@ async fn main() -> ExitCode { Ok(Some(cache_dir)) => cache_dir, _ => { DBG_ERR!("Failed to determine cache directory"); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; if !Path::new(&cache_dir).exists() { DBG_ERR!("The cache directory '{}' does not exist", cache_dir); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } @@ -192,6 +208,7 @@ async fn main() -> ExitCode { Ok(cache) => cache, Err(e) => { DBG_ERR!("Failed to open the himmelblau user cache: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -204,6 +221,7 @@ async fn main() -> ExitCode { Ok(cache) => cache, Err(e) => { DBG_ERR!("Failed to open the himmelblau uid cache: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -216,6 +234,7 @@ async fn main() -> ExitCode { Ok(cache) => cache, Err(e) => { DBG_ERR!("Failed to open the himmelblau group cache: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -225,6 +244,7 @@ async fn main() -> ExitCode { Ok(Some(hsm_pin_path)) => hsm_pin_path, _ => { DBG_ERR!("Failed loading hsm pin path."); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -235,6 +255,7 @@ async fn main() -> ExitCode { "The hsm pin directory '{}' does not exist", hsm_pin_dir.display() ); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } let auth_value = @@ -242,6 +263,7 @@ async fn main() -> ExitCode { Ok(auth_value) => auth_value, Err(e) => { DBG_ERR!("{:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -255,6 +277,7 @@ async fn main() -> ExitCode { Ok(lmk) => lmk, Err(e) => { DBG_ERR!("{:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -270,6 +293,7 @@ async fn main() -> ExitCode { private_cache_path ); DBG_INFO!("The host will forget domain enrollments."); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -286,6 +310,7 @@ async fn main() -> ExitCode { Ok(graph) => graph, Err(e) => { DBG_ERR!("Failed initializing the graph: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -301,6 +326,7 @@ async fn main() -> ExitCode { Ok(client) => client, Err(e) => { DBG_ERR!("Failed initializing the broker: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -309,6 +335,7 @@ async fn main() -> ExitCode { Ok(idmap) => idmap, Err(e) => { DBG_ERR!("Failed initializing the idmapper: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -317,11 +344,13 @@ async fn main() -> ExitCode { Ok(res) => res, Err(e) => { DBG_ERR!("Failed fetching idmap range: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; if let Err(e) = idmap.add_gen_domain(&realm, &tenant_id, (low, high)) { DBG_ERR!("Failed adding the domain idmap range: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } @@ -345,6 +374,7 @@ async fn main() -> ExitCode { Ok(listener) => listener, Err(e) => { DBG_ERR!("Failed setting up the socket listener: {:?}", e); + talloc::TALLOC_FREE!(frame); return ExitCode::FAILURE; } }; @@ -428,6 +458,7 @@ async fn main() -> ExitCode { } } + talloc::TALLOC_FREE!(frame); ExitCode::SUCCESS } .await diff --git a/rust/talloc/Cargo.toml b/rust/talloc/Cargo.toml new file mode 100644 index 00000000000..a21b3da9ad3 --- /dev/null +++ b/rust/talloc/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "talloc" +edition.workspace = true +license.workspace = true +homepage.workspace = true +version.workspace = true + +[build-dependencies] +bindgen = "0.69.4" +config.workspace = true + +[dependencies] +chelps.workspace = true diff --git a/rust/talloc/build.rs b/rust/talloc/build.rs new file mode 100644 index 00000000000..d14b0b045e9 --- /dev/null +++ b/rust/talloc/build.rs @@ -0,0 +1,38 @@ +use std::env; +use std::path::PathBuf; + +fn main() { + let bindings = bindgen::Builder::default() + .blocklist_function("qgcvt") + .blocklist_function("qgcvt_r") + .blocklist_function("qfcvt") + .blocklist_function("qfcvt_r") + .blocklist_function("qecvt") + .blocklist_function("qecvt_r") + .blocklist_function("strtold") + .clang_arg("-Dbool=int") + .generate_comments(false) + .clang_arg("-I../../lib/talloc") + .header("../../lib/util/talloc_stack.h") + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .generate() + .expect("Unable to generate bindings"); + println!("cargo:rerun-if-changed=../../lib/util/talloc_stack.h"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); + + let mut src_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + src_dir.push("../../bin/default/lib/talloc"); + if config::USING_SYSTEM_TALLOC == 1 { + println!("cargo:rustc-link-lib=talloc"); + } else { + println!("cargo:rustc-link-lib=talloc-private-samba"); + } + println!( + "cargo:rustc-link-search=native={}", + src_dir.to_str().unwrap() + ); +} diff --git a/rust/talloc/src/lib.rs b/rust/talloc/src/lib.rs new file mode 100644 index 00000000000..c2eef6f93dd --- /dev/null +++ b/rust/talloc/src/lib.rs @@ -0,0 +1,56 @@ +/* + Unix SMB/CIFS implementation. + + Talloc stackframe functions + + Copyright (C) David Mulder 2024 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +pub mod ffi { + #![allow(non_upper_case_globals)] + #![allow(non_camel_case_types)] + #![allow(non_snake_case)] + #![allow(dead_code)] + #![allow(clippy::upper_case_acronyms)] + include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +} + +#[macro_export] +macro_rules! talloc_stackframe { + () => {{ + let function = chelps::function!(); + let function_cstr = chelps::wrap_string(&function); + unsafe { + let ret = $crate::ffi::_talloc_stackframe(function_cstr); + chelps::string_free(function_cstr); + ret + } + }}; +} + +#[macro_export] +macro_rules! TALLOC_FREE { + ($ctx:ident) => {{ + if !$ctx.is_null() { + let function = chelps::function!(); + let function_cstr = chelps::wrap_string(&function); + unsafe { + $crate::ffi::_talloc_free($ctx, function_cstr); + chelps::string_free(function_cstr); + } + } + }}; +} -- 2.47.3