]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
Remove previous himmelblau integration attempt
authorDavid Mulder <dmulder@samba.org>
Thu, 28 Aug 2025 19:09:36 +0000 (13:09 -0600)
committerDavid Mulder <dmulder@samba.org>
Tue, 4 Nov 2025 09:09:40 +0000 (09:09 +0000)
This was a project attempting to integrate
Himmelblau into Samba, but it has been
abandoned.

Signed-off-by: David Mulder <dmulder@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): David Mulder <dmulder@samba.org>
Autobuild-Date(master): Tue Nov  4 09:09:40 UTC 2025 on atb-devel-224

82 files changed:
docs-xml/generate-pathconf-entities.sh
docs-xml/smbdotconf/himmelblaud/himmelblaudhelloenabled.xml [deleted file]
docs-xml/smbdotconf/himmelblaud/himmelblaudhsmpinpath.xml [deleted file]
docs-xml/smbdotconf/himmelblaud/himmelblaudsfafallback.xml [deleted file]
dynconfig/dynconfig.c
dynconfig/dynconfig.h
dynconfig/wscript
lib/param/loadparm.c
rust/.cargo/config.toml [deleted file]
rust/.gitignore [deleted file]
rust/Cargo.lock [deleted file]
rust/Cargo.toml
rust/build.rs [deleted file]
rust/chelps/Cargo.toml [deleted file]
rust/chelps/src/lib.rs [deleted file]
rust/config/Cargo.toml [deleted file]
rust/config/additions.h [deleted file]
rust/config/build.rs [deleted file]
rust/config/src/lib.rs [deleted file]
rust/dbg/Cargo.toml [deleted file]
rust/dbg/build.rs [deleted file]
rust/dbg/src/lib.rs [deleted file]
rust/himmelblaud/Cargo.toml [deleted file]
rust/himmelblaud/build.rs [deleted file]
rust/himmelblaud/src/cache.rs [deleted file]
rust/himmelblaud/src/constants.rs [deleted file]
rust/himmelblaud/src/himmelblaud.rs [deleted file]
rust/himmelblaud/src/himmelblaud/himmelblaud_getgrent.rs [deleted file]
rust/himmelblaud/src/himmelblaud/himmelblaud_getgrgid.rs [deleted file]
rust/himmelblaud/src/himmelblaud/himmelblaud_getgrnam.rs [deleted file]
rust/himmelblaud/src/himmelblaud/himmelblaud_getpwent.rs [deleted file]
rust/himmelblaud/src/himmelblaud/himmelblaud_getpwnam.rs [deleted file]
rust/himmelblaud/src/himmelblaud/himmelblaud_getpwuid.rs [deleted file]
rust/himmelblaud/src/himmelblaud/himmelblaud_pam_acct_mgmt.rs [deleted file]
rust/himmelblaud/src/himmelblaud/himmelblaud_pam_auth.rs [deleted file]
rust/himmelblaud/src/main.rs [deleted file]
rust/himmelblaud/src/utils.rs [deleted file]
rust/idmap/Cargo.toml [deleted file]
rust/idmap/build.rs [deleted file]
rust/idmap/src/lib.rs [deleted file]
rust/idmap/src/murmurhash3.c [deleted file]
rust/idmap/src/murmurhash3.h [deleted file]
rust/idmap/src/sss_idmap.c [deleted file]
rust/idmap/src/sss_idmap.h [deleted file]
rust/idmap/src/sss_idmap_conv.c [deleted file]
rust/idmap/src/sss_idmap_private.h [deleted file]
rust/idmap/src/util.h [deleted file]
rust/nss/Cargo.toml [deleted file]
rust/nss/build.rs [deleted file]
rust/nss/src/lib.rs [deleted file]
rust/ntstatus_gen/Cargo.toml [deleted file]
rust/ntstatus_gen/src/lib.rs [deleted file]
rust/pam/Cargo.toml [deleted file]
rust/pam/build.rs [deleted file]
rust/pam/src/lib.rs [deleted file]
rust/pam/src/pam/constants.rs [deleted file]
rust/pam/src/pam/conv.rs [deleted file]
rust/pam/src/pam/items.rs [deleted file]
rust/pam/src/pam/macros.rs [deleted file]
rust/pam/src/pam/mod.rs [deleted file]
rust/pam/src/pam/module.rs [deleted file]
rust/param/Cargo.toml [deleted file]
rust/param/build.rs [deleted file]
rust/param/src/lib.rs [deleted file]
rust/rustfmt.toml [deleted file]
rust/sock/Cargo.toml [deleted file]
rust/sock/src/lib.rs [deleted file]
rust/sock/src/proto.rs [deleted file]
rust/talloc/Cargo.toml [deleted file]
rust/talloc/build.rs [deleted file]
rust/talloc/src/lib.rs [deleted file]
rust/tdb/Cargo.toml [deleted file]
rust/tdb/build.rs [deleted file]
rust/tdb/src/lib.rs [deleted file]
rust/version/Cargo.toml [deleted file]
rust/version/build.rs [deleted file]
rust/version/include/includes.h [deleted file]
rust/version/src/lib.rs [deleted file]
rust/wscript_build
script/autobuild.py
source3/param/loadparm.c
wscript

index 8d39c5034c066942826c6c5360aa6f39454d4052..1b689a8a23f26060f1b0e9c51ac7bcba17569129 100755 (executable)
@@ -19,5 +19,4 @@ echo "
 <!ENTITY pathconfig.SAMBA_DATADIR        '\${prefix}/var/samba'>
 <!ENTITY pathconfig.CTDB_DATADIR         '\${prefix}/share/ctdb'>
 <!ENTITY pathconfig.CONFIGFILE           '\${prefix}/etc/smb.conf'>
-<!ENTITY pathconfig.HIMMELBLAUD_HSM_PIN_PATH '\${prefix}/var/lib/himmelblaud/hsm-pin'>
 "
diff --git a/docs-xml/smbdotconf/himmelblaud/himmelblaudhelloenabled.xml b/docs-xml/smbdotconf/himmelblaud/himmelblaudhelloenabled.xml
deleted file mode 100644 (file)
index b148362..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<samba:parameter name="himmelblaud hello enabled"
-                 context="G"
-                 type="boolean"
-                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
-<description>
-
-       <para>This parameter controls Hello enrollment and authentication to
-       Azure Entra ID. By default, it is disabled to prevent security risks,
-       such as on hosts exposing the SSH port. Administrators should enable
-       this setting only when Hello enrollment is appropriate for their
-       environment.
-
-</para>
-</description>
-
-<value type="default">no</value>
-<value type="example">yes</value>
-</samba:parameter>
diff --git a/docs-xml/smbdotconf/himmelblaud/himmelblaudhsmpinpath.xml b/docs-xml/smbdotconf/himmelblaud/himmelblaudhsmpinpath.xml
deleted file mode 100644 (file)
index 8727127..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<samba:parameter name="himmelblaud hsm pin path"
-                 context="G"
-                 type="string"
-                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
-<description>
-       <para>Specifies the file path where the HSM PIN is stored. This PIN is used
-       for unlocking TPM objects required for Azure Entra ID authentication. The HSM
-       PIN is critical for ensuring secure communication and authentication within
-       the Himmelblaud daemon.</para>
-</description>
-
-<value type="default">&pathconfig.HIMMELBLAUD_HSM_PIN_PATH;</value>
-</samba:parameter>
diff --git a/docs-xml/smbdotconf/himmelblaud/himmelblaudsfafallback.xml b/docs-xml/smbdotconf/himmelblaud/himmelblaudsfafallback.xml
deleted file mode 100644 (file)
index 1b30d0a..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<samba:parameter name="himmelblaud sfa fallback"
-                 context="G"
-                 type="boolean"
-                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
-<description>
-
-       <para>This parameter is designed to control whether Himmelblaud should fallback to
-       Single Factor Authentication (SFA) if Multi-Factor Authentication (MFA) isn't
-       available. This normally is possible during a short window during which MFA
-       enrollment is available to a new user.
-
-</para>
-</description>
-
-<value type="default">no</value>
-<value type="example">yes</value>
-</samba:parameter>
index 69de711c4de718c32aa173e6523fc9b44964b89c..415ccc53c5257a92d796774b924388bfe0c2ea7e 100644 (file)
@@ -107,4 +107,3 @@ DEFINE_DYN_CONFIG_PARAM(NTP_SIGND_SOCKET_DIR)
 DEFINE_DYN_CONFIG_PARAM(PYTHONDIR)
 DEFINE_DYN_CONFIG_PARAM(PYTHONARCHDIR)
 DEFINE_DYN_CONFIG_PARAM(SCRIPTSBINDIR)
-DEFINE_DYN_CONFIG_PARAM(HIMMELBLAUD_HSM_PIN_PATH)
index d06636de82727ea975756d4d4fe655f45539dab7..72028a8c2e10eb975d94814dc718de5e94b2ff47 100644 (file)
@@ -58,4 +58,3 @@ DEFINE_DYN_CONFIG_PROTO(NTP_SIGND_SOCKET_DIR)
 DEFINE_DYN_CONFIG_PROTO(PYTHONDIR)
 DEFINE_DYN_CONFIG_PROTO(PYTHONARCHDIR)
 DEFINE_DYN_CONFIG_PROTO(SCRIPTSBINDIR)
-DEFINE_DYN_CONFIG_PROTO(HIMMELBLAUD_HSM_PIN_PATH)
index 2d7d79006fd74ee179203f7357b4def91788dd8c..5d7633b047bacc5036693f3ebe50d44f3628df84 100644 (file)
@@ -285,13 +285,6 @@ dynconfig = {
          'HELPTEXT':  'Where to put the smbpasswd file',
          'DELAY':     True,
     },
-    'HIMMELBLAUD_HSM_PIN_PATH': {
-         'STD-PATH':  '${LOCALSTATEDIR}/lib/himmelblaud/hsm-pin',
-         'FHS-PATH':  '${LOCALSTATEDIR}/lib/himmelblaud/hsm-pin',
-         'OPTION':    '--with-himmelblaud-hsm-pin-path',
-         'HELPTEXT':  'Where to store the hsm pin',
-         'DELAY':     True,
-    },
 }
 
 def options(opt):
index 8aea8f8499b20eb61012daf27a827187b24d1dc4..69baf4b70541722c52bc7ab5afac2b4af00047c1 100644 (file)
@@ -3284,17 +3284,6 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
                                  "acl claims evaluation",
                                  "AD DC only");
 
-       /* Set the default Himmelblaud globals */
-       lpcfg_do_global_parameter(lp_ctx,
-                                 "himmelblaud hsm pin path",
-                                 get_dyn_HIMMELBLAUD_HSM_PIN_PATH());
-       lpcfg_do_global_parameter(lp_ctx,
-                                 "himmelblaud hello enabled",
-                                 "false");
-       lpcfg_do_global_parameter(lp_ctx,
-                                 "himmelblaud sfa fallback",
-                                 "false");
-
        lpcfg_do_global_parameter(lp_ctx,
                                  "server smb encryption over quic",
                                  "yes");
diff --git a/rust/.cargo/config.toml b/rust/.cargo/config.toml
deleted file mode 100644 (file)
index 29bbcaf..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-[source.crates-io]
-replace-with = "vendored-sources"
-
-[source.vendored-sources]
-directory = "../bin/default/rust/vendor"
diff --git a/rust/.gitignore b/rust/.gitignore
deleted file mode 100644 (file)
index eadb94c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# ---> Rust
-# Generated by Cargo
-# will have compiled files and executables
-debug/
-target/
-
-# These are backup files generated by rustfmt
-**/*.rs.bk
-
-# MSVC Windows builds of rustc generate these, which store debugging information
-*.pdb
-
-vendor/
-tags
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
deleted file mode 100644 (file)
index 9a2af4b..0000000
+++ /dev/null
@@ -1,2899 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "addr2line"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
-dependencies = [
- "gimli",
-]
-
-[[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
-name = "ahash"
-version = "0.8.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
-dependencies = [
- "cfg-if",
- "getrandom",
- "once_cell",
- "version_check",
- "zerocopy",
-]
-
-[[package]]
-name = "aho-corasick"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "anstream"
-version = "0.6.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
-dependencies = [
- "anstyle",
- "anstyle-parse",
- "anstyle-query",
- "anstyle-wincon",
- "colorchoice",
- "is_terminal_polyfill",
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
-
-[[package]]
-name = "anstyle-parse"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
-dependencies = [
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle-query"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
-dependencies = [
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "anstyle-wincon"
-version = "3.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
-dependencies = [
- "anstyle",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "argon2"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
-dependencies = [
- "base64ct",
- "blake2",
- "cpufeatures",
- "password-hash",
-]
-
-[[package]]
-name = "atomic-waker"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
-
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi 0.1.19",
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
-
-[[package]]
-name = "backtrace"
-version = "0.3.73"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
-dependencies = [
- "addr2line",
- "cc",
- "cfg-if",
- "libc",
- "miniz_oxide",
- "object",
- "rustc-demangle",
-]
-
-[[package]]
-name = "base64"
-version = "0.21.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
-
-[[package]]
-name = "base64"
-version = "0.22.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
-
-[[package]]
-name = "base64ct"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
-
-[[package]]
-name = "base64urlsafedata"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a56894edf5cd1efa7068d7454adeb7ce0b3da4ffa5ab08cfc06165bbc62f0c7"
-dependencies = [
- "base64 0.21.7",
- "paste",
- "serde",
-]
-
-[[package]]
-name = "bindgen"
-version = "0.69.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
-dependencies = [
- "bitflags 2.6.0",
- "cexpr",
- "clang-sys",
- "itertools",
- "lazy_static",
- "lazycell",
- "log",
- "prettyplease",
- "proc-macro2",
- "quote",
- "regex",
- "rustc-hash",
- "shlex",
- "syn 2.0.72",
- "which",
-]
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "bitflags"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
-
-[[package]]
-name = "blake2"
-version = "0.10.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
-dependencies = [
- "digest",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
-
-[[package]]
-name = "byteorder"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
-
-[[package]]
-name = "bytes"
-version = "1.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
-
-[[package]]
-name = "cbindgen"
-version = "0.26.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49"
-dependencies = [
- "clap 3.2.25",
- "heck",
- "indexmap 1.9.3",
- "log",
- "proc-macro2",
- "quote",
- "serde",
- "serde_json",
- "syn 1.0.109",
- "tempfile",
- "toml",
-]
-
-[[package]]
-name = "cc"
-version = "1.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549"
-
-[[package]]
-name = "cexpr"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
-dependencies = [
- "nom",
-]
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "chelps"
-version = "4.21.0"
-
-[[package]]
-name = "clang-sys"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
-dependencies = [
- "glob",
- "libc",
- "libloading",
-]
-
-[[package]]
-name = "clap"
-version = "3.2.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
-dependencies = [
- "atty",
- "bitflags 1.3.2",
- "clap_lex 0.2.4",
- "indexmap 1.9.3",
- "strsim 0.10.0",
- "termcolor",
- "textwrap",
-]
-
-[[package]]
-name = "clap"
-version = "4.5.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36"
-dependencies = [
- "clap_builder",
-]
-
-[[package]]
-name = "clap_builder"
-version = "4.5.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed"
-dependencies = [
- "anstream",
- "anstyle",
- "clap_lex 0.7.2",
- "strsim 0.11.1",
-]
-
-[[package]]
-name = "clap_lex"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
-dependencies = [
- "os_str_bytes",
-]
-
-[[package]]
-name = "clap_lex"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
-
-[[package]]
-name = "colorchoice"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
-
-[[package]]
-name = "compact_jwt"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b6493b1c78b7c33fbbb00d8d60d633439fd0c0e44826fb4834efc28121ef266"
-dependencies = [
- "base64 0.21.7",
- "base64urlsafedata",
- "hex",
- "kanidm-hsm-crypto",
- "openssl",
- "openssl-kdf",
- "serde",
- "serde_json",
- "tracing",
- "url",
- "uuid",
-]
-
-[[package]]
-name = "config"
-version = "4.21.0"
-dependencies = [
- "bindgen",
- "libc",
-]
-
-[[package]]
-name = "cookie"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
-dependencies = [
- "percent-encoding",
- "time",
- "version_check",
-]
-
-[[package]]
-name = "cookie_store"
-version = "0.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4934e6b7e8419148b6ef56950d277af8561060b56afd59e2aadf98b59fce6baa"
-dependencies = [
- "cookie",
- "idna 0.5.0",
- "log",
- "publicsuffix",
- "serde",
- "serde_derive",
- "serde_json",
- "time",
- "url",
-]
-
-[[package]]
-name = "core-foundation"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
-
-[[package]]
-name = "cpufeatures"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "crypto-common"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
-dependencies = [
- "generic-array",
- "typenum",
-]
-
-[[package]]
-name = "cssparser"
-version = "0.31.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be"
-dependencies = [
- "cssparser-macros",
- "dtoa-short",
- "itoa",
- "phf 0.11.2",
- "smallvec",
-]
-
-[[package]]
-name = "cssparser-macros"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
-dependencies = [
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "dbg"
-version = "4.21.0"
-dependencies = [
- "bindgen",
- "chelps",
- "paste",
- "tempfile",
-]
-
-[[package]]
-name = "deranged"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
-dependencies = [
- "powerfmt",
-]
-
-[[package]]
-name = "derive_more"
-version = "0.99.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "digest"
-version = "0.10.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
-dependencies = [
- "block-buffer",
- "crypto-common",
- "subtle",
-]
-
-[[package]]
-name = "dtoa"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653"
-
-[[package]]
-name = "dtoa-short"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87"
-dependencies = [
- "dtoa",
-]
-
-[[package]]
-name = "ego-tree"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591"
-
-[[package]]
-name = "either"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
-
-[[package]]
-name = "encoding_rs"
-version = "0.8.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "equivalent"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
-
-[[package]]
-name = "errno"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
-dependencies = [
- "libc",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "fastrand"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
-[[package]]
-name = "form_urlencoded"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
-dependencies = [
- "percent-encoding",
-]
-
-[[package]]
-name = "futf"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843"
-dependencies = [
- "mac",
- "new_debug_unreachable",
-]
-
-[[package]]
-name = "futures"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
-dependencies = [
- "futures-core",
- "futures-sink",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
-
-[[package]]
-name = "futures-executor"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
-
-[[package]]
-name = "futures-macro"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
-
-[[package]]
-name = "futures-task"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
-
-[[package]]
-name = "futures-util"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
- "futures-task",
- "memchr",
- "pin-project-lite",
- "pin-utils",
- "slab",
-]
-
-[[package]]
-name = "fxhash"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
-dependencies = [
- "byteorder",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.14.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
-dependencies = [
- "typenum",
- "version_check",
-]
-
-[[package]]
-name = "getopts"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
-dependencies = [
- "unicode-width",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi",
-]
-
-[[package]]
-name = "gimli"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
-
-[[package]]
-name = "glob"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
-
-[[package]]
-name = "h2"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab"
-dependencies = [
- "atomic-waker",
- "bytes",
- "fnv",
- "futures-core",
- "futures-sink",
- "http",
- "indexmap 2.3.0",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
-version = "0.14.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
-
-[[package]]
-name = "heck"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
-
-[[package]]
-name = "hex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-
-[[package]]
-name = "himmelblaud"
-version = "4.21.0"
-dependencies = [
- "bytes",
- "chelps",
- "clap 4.5.14",
- "dbg",
- "futures",
- "idmap",
- "kanidm-hsm-crypto",
- "libc",
- "libhimmelblau",
- "ntstatus_gen",
- "param",
- "serde",
- "serde_json",
- "sock",
- "talloc",
- "tdb",
- "tempfile",
- "tokio",
- "tokio-util",
- "version",
-]
-
-[[package]]
-name = "home"
-version = "0.5.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
-dependencies = [
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "hostname"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba"
-dependencies = [
- "cfg-if",
- "libc",
- "windows",
-]
-
-[[package]]
-name = "html5ever"
-version = "0.27.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4"
-dependencies = [
- "log",
- "mac",
- "markup5ever",
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "http"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
-dependencies = [
- "bytes",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
-dependencies = [
- "bytes",
- "http",
-]
-
-[[package]]
-name = "http-body-util"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
-dependencies = [
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "pin-project-lite",
-]
-
-[[package]]
-name = "httparse"
-version = "1.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
-
-[[package]]
-name = "hyper"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05"
-dependencies = [
- "bytes",
- "futures-channel",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "httparse",
- "itoa",
- "pin-project-lite",
- "smallvec",
- "tokio",
- "want",
-]
-
-[[package]]
-name = "hyper-rustls"
-version = "0.27.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
-dependencies = [
- "futures-util",
- "http",
- "hyper",
- "hyper-util",
- "rustls",
- "rustls-pki-types",
- "tokio",
- "tokio-rustls",
- "tower-service",
-]
-
-[[package]]
-name = "hyper-tls"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
-dependencies = [
- "bytes",
- "http-body-util",
- "hyper",
- "hyper-util",
- "native-tls",
- "tokio",
- "tokio-native-tls",
- "tower-service",
-]
-
-[[package]]
-name = "hyper-util"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
-dependencies = [
- "bytes",
- "futures-channel",
- "futures-util",
- "http",
- "http-body",
- "hyper",
- "pin-project-lite",
- "socket2",
- "tokio",
- "tower",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "idmap"
-version = "4.21.0"
-dependencies = [
- "bindgen",
- "cc",
- "chelps",
- "dbg",
- "libc",
-]
-
-[[package]]
-name = "idna"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
-dependencies = [
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "idna"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
-dependencies = [
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
-dependencies = [
- "autocfg",
- "hashbrown 0.12.3",
-]
-
-[[package]]
-name = "indexmap"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
-dependencies = [
- "equivalent",
- "hashbrown 0.14.5",
-]
-
-[[package]]
-name = "ipnet"
-version = "2.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
-
-[[package]]
-name = "is_terminal_polyfill"
-version = "1.70.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
-
-[[package]]
-name = "itertools"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itoa"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
-
-[[package]]
-name = "js-sys"
-version = "0.3.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
-dependencies = [
- "wasm-bindgen",
-]
-
-[[package]]
-name = "kanidm-hsm-crypto"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10b3ed8e86cda3da4f274c677a3057d567bd7b715a0feb06a656e55cc75faf5e"
-dependencies = [
- "argon2",
- "hex",
- "openssl",
- "serde",
- "tracing",
- "zeroize",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-
-[[package]]
-name = "lazycell"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
-
-[[package]]
-name = "libc"
-version = "0.2.155"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
-
-[[package]]
-name = "libhimmelblau"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9bf69727a5d6f3e1e3685569791a7b591e23f811aa6dea5362b274516ee5696"
-dependencies = [
- "base64 0.22.1",
- "cbindgen",
- "compact_jwt",
- "hostname",
- "kanidm-hsm-crypto",
- "openssl",
- "os-release",
- "paste",
- "regex",
- "reqwest",
- "scraper",
- "serde",
- "serde_json",
- "tokio",
- "tracing",
- "tracing-subscriber",
- "urlencoding",
- "uuid",
- "zeroize",
-]
-
-[[package]]
-name = "libloading"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
-dependencies = [
- "cfg-if",
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "libnss"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c4bc0291fc787d67c56e9ed79b80780e53bfb9be173177f301ee666cec1021b"
-dependencies = [
- "lazy_static",
- "libc",
- "paste",
-]
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
-
-[[package]]
-name = "lock_api"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
-dependencies = [
- "autocfg",
- "scopeguard",
-]
-
-[[package]]
-name = "log"
-version = "0.4.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
-
-[[package]]
-name = "mac"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
-
-[[package]]
-name = "markup5ever"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45"
-dependencies = [
- "log",
- "phf 0.11.2",
- "phf_codegen 0.11.2",
- "string_cache",
- "string_cache_codegen",
- "tendril",
-]
-
-[[package]]
-name = "memchr"
-version = "2.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
-
-[[package]]
-name = "mime"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
-
-[[package]]
-name = "minimal-lexical"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
-[[package]]
-name = "miniz_oxide"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
-dependencies = [
- "adler",
-]
-
-[[package]]
-name = "mio"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
-dependencies = [
- "hermit-abi 0.3.9",
- "libc",
- "wasi",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "native-tls"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
-dependencies = [
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
-[[package]]
-name = "new_debug_unreachable"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
-
-[[package]]
-name = "nom"
-version = "7.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
-
-[[package]]
-name = "nss_himmelblau"
-version = "4.21.0"
-dependencies = [
- "libc",
- "libnss",
- "ntstatus_gen",
- "param",
- "sock",
- "version",
-]
-
-[[package]]
-name = "ntstatus_gen"
-version = "4.21.0"
-
-[[package]]
-name = "nu-ansi-term"
-version = "0.46.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
-dependencies = [
- "overload",
- "winapi",
-]
-
-[[package]]
-name = "num-conv"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
-
-[[package]]
-name = "object"
-version = "0.36.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
-
-[[package]]
-name = "openssl"
-version = "0.10.66"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
-dependencies = [
- "bitflags 2.6.0",
- "cfg-if",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-kdf"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feda4b74ded511c6d8543db00166f70f572ca7e5eb72f4817bf08628b5bbc1f4"
-dependencies = [
- "foreign-types",
- "libc",
- "openssl",
- "openssl-sys",
- "pkg-config",
- "thiserror",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "openssl-probe"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
-
-[[package]]
-name = "openssl-sys"
-version = "0.9.103"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "os-release"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82f29ae2f71b53ec19cc23385f8e4f3d90975195aa3d09171ba3bef7159bec27"
-dependencies = [
- "lazy_static",
-]
-
-[[package]]
-name = "os_str_bytes"
-version = "6.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
-
-[[package]]
-name = "overload"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
-
-[[package]]
-name = "pam_himmelblau"
-version = "4.21.0"
-dependencies = [
- "chelps",
- "dbg",
- "libc",
- "param",
- "pkg-config",
- "sock",
-]
-
-[[package]]
-name = "param"
-version = "4.21.0"
-dependencies = [
- "bindgen",
- "chelps",
- "dbg",
- "ntstatus_gen",
- "paste",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
-dependencies = [
- "lock_api",
- "parking_lot_core",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.9.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall",
- "smallvec",
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "password-hash"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
-dependencies = [
- "base64ct",
- "rand_core",
- "subtle",
-]
-
-[[package]]
-name = "paste"
-version = "1.0.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
-
-[[package]]
-name = "percent-encoding"
-version = "2.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
-
-[[package]]
-name = "phf"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
-dependencies = [
- "phf_shared 0.10.0",
-]
-
-[[package]]
-name = "phf"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
-dependencies = [
- "phf_macros",
- "phf_shared 0.11.2",
-]
-
-[[package]]
-name = "phf_codegen"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
-dependencies = [
- "phf_generator 0.10.0",
- "phf_shared 0.10.0",
-]
-
-[[package]]
-name = "phf_codegen"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
-dependencies = [
- "phf_generator 0.11.2",
- "phf_shared 0.11.2",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
-dependencies = [
- "phf_shared 0.10.0",
- "rand",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
-dependencies = [
- "phf_shared 0.11.2",
- "rand",
-]
-
-[[package]]
-name = "phf_macros"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
-dependencies = [
- "phf_generator 0.11.2",
- "phf_shared 0.11.2",
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
-dependencies = [
- "siphasher",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
-dependencies = [
- "siphasher",
-]
-
-[[package]]
-name = "pin-project"
-version = "1.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "pkg-config"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
-
-[[package]]
-name = "powerfmt"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
-dependencies = [
- "zerocopy",
-]
-
-[[package]]
-name = "precomputed-hash"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
-
-[[package]]
-name = "prettyplease"
-version = "0.2.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e"
-dependencies = [
- "proc-macro2",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.86"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "psl-types"
-version = "2.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
-
-[[package]]
-name = "publicsuffix"
-version = "2.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457"
-dependencies = [
- "idna 0.3.0",
- "psl-types",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.36"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "rand"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "libc",
- "rand_chacha",
- "rand_core",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
-dependencies = [
- "getrandom",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
-dependencies = [
- "bitflags 2.6.0",
-]
-
-[[package]]
-name = "regex"
-version = "1.10.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-automata",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
-
-[[package]]
-name = "reqwest"
-version = "0.12.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37"
-dependencies = [
- "base64 0.22.1",
- "bytes",
- "cookie",
- "cookie_store",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-rustls",
- "hyper-tls",
- "hyper-util",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "native-tls",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "rustls-pemfile",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper",
- "system-configuration",
- "tokio",
- "tokio-native-tls",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "winreg",
-]
-
-[[package]]
-name = "ring"
-version = "0.17.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
-dependencies = [
- "cc",
- "cfg-if",
- "getrandom",
- "libc",
- "spin",
- "untrusted",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "rustc-demangle"
-version = "0.1.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
-
-[[package]]
-name = "rustc-hash"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
-
-[[package]]
-name = "rustix"
-version = "0.38.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
-dependencies = [
- "bitflags 2.6.0",
- "errno",
- "libc",
- "linux-raw-sys",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "rustls"
-version = "0.23.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
-dependencies = [
- "once_cell",
- "rustls-pki-types",
- "rustls-webpki",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "rustls-pemfile"
-version = "2.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
-dependencies = [
- "base64 0.22.1",
- "rustls-pki-types",
-]
-
-[[package]]
-name = "rustls-pki-types"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
-
-[[package]]
-name = "rustls-webpki"
-version = "0.102.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e"
-dependencies = [
- "ring",
- "rustls-pki-types",
- "untrusted",
-]
-
-[[package]]
-name = "ryu"
-version = "1.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
-
-[[package]]
-name = "schannel"
-version = "0.1.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
-dependencies = [
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
-[[package]]
-name = "scraper"
-version = "0.19.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "761fb705fdf625482d2ed91d3f0559dcfeab2798fe2771c69560a774865d0802"
-dependencies = [
- "ahash",
- "cssparser",
- "ego-tree",
- "getopts",
- "html5ever",
- "once_cell",
- "selectors",
- "tendril",
-]
-
-[[package]]
-name = "security-framework"
-version = "2.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
-dependencies = [
- "bitflags 2.6.0",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "selectors"
-version = "0.25.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06"
-dependencies = [
- "bitflags 2.6.0",
- "cssparser",
- "derive_more",
- "fxhash",
- "log",
- "new_debug_unreachable",
- "phf 0.10.1",
- "phf_codegen 0.10.0",
- "precomputed-hash",
- "servo_arc",
- "smallvec",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.205"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.205"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.122"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
-dependencies = [
- "itoa",
- "memchr",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "serde_urlencoded"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
-dependencies = [
- "form_urlencoded",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "servo_arc"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44"
-dependencies = [
- "stable_deref_trait",
-]
-
-[[package]]
-name = "sharded-slab"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
-dependencies = [
- "lazy_static",
-]
-
-[[package]]
-name = "shlex"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
-
-[[package]]
-name = "signal-hook-registry"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "siphasher"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
-
-[[package]]
-name = "slab"
-version = "0.4.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "smallvec"
-version = "1.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
-
-[[package]]
-name = "sock"
-version = "4.21.0"
-dependencies = [
- "chelps",
- "dbg",
- "libc",
- "libnss",
- "ntstatus_gen",
- "param",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "socket2"
-version = "0.5.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
-dependencies = [
- "libc",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "spin"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
-
-[[package]]
-name = "string_cache"
-version = "0.8.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
-dependencies = [
- "new_debug_unreachable",
- "once_cell",
- "parking_lot",
- "phf_shared 0.10.0",
- "precomputed-hash",
- "serde",
-]
-
-[[package]]
-name = "string_cache_codegen"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
-dependencies = [
- "phf_generator 0.10.0",
- "phf_shared 0.10.0",
- "proc-macro2",
- "quote",
-]
-
-[[package]]
-name = "strsim"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-
-[[package]]
-name = "strsim"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
-
-[[package]]
-name = "subtle"
-version = "2.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
-
-[[package]]
-name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "syn"
-version = "2.0.72"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "sync_wrapper"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
-
-[[package]]
-name = "system-configuration"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "system-configuration-sys",
-]
-
-[[package]]
-name = "system-configuration-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "talloc"
-version = "4.21.0"
-dependencies = [
- "bindgen",
- "chelps",
- "config",
-]
-
-[[package]]
-name = "tdb"
-version = "4.21.0"
-dependencies = [
- "bindgen",
- "chelps",
- "config",
- "dbg",
- "libc",
- "ntstatus_gen",
-]
-
-[[package]]
-name = "tempfile"
-version = "3.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
-dependencies = [
- "cfg-if",
- "fastrand",
- "once_cell",
- "rustix",
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "tendril"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0"
-dependencies = [
- "futf",
- "mac",
- "utf-8",
-]
-
-[[package]]
-name = "termcolor"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "textwrap"
-version = "0.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
-
-[[package]]
-name = "thiserror"
-version = "1.0.63"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
-dependencies = [
- "thiserror-impl",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.63"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "thread_local"
-version = "1.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
-dependencies = [
- "cfg-if",
- "once_cell",
-]
-
-[[package]]
-name = "time"
-version = "0.3.36"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
-dependencies = [
- "deranged",
- "itoa",
- "num-conv",
- "powerfmt",
- "serde",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
-
-[[package]]
-name = "time-macros"
-version = "0.2.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
-dependencies = [
- "num-conv",
- "time-core",
-]
-
-[[package]]
-name = "tinyvec"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
-dependencies = [
- "tinyvec_macros",
-]
-
-[[package]]
-name = "tinyvec_macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
-
-[[package]]
-name = "tokio"
-version = "1.39.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
-dependencies = [
- "backtrace",
- "bytes",
- "libc",
- "mio",
- "parking_lot",
- "pin-project-lite",
- "signal-hook-registry",
- "socket2",
- "tokio-macros",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "2.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "tokio-native-tls"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
-dependencies = [
- "native-tls",
- "tokio",
-]
-
-[[package]]
-name = "tokio-rustls"
-version = "0.26.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
-dependencies = [
- "rustls",
- "rustls-pki-types",
- "tokio",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.7.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "tower"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
-dependencies = [
- "futures-core",
- "futures-util",
- "pin-project",
- "pin-project-lite",
- "tokio",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "tower-layer"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
-
-[[package]]
-name = "tower-service"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
-
-[[package]]
-name = "tracing"
-version = "0.1.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
-dependencies = [
- "pin-project-lite",
- "tracing-attributes",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-attributes"
-version = "0.1.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
-dependencies = [
- "once_cell",
- "valuable",
-]
-
-[[package]]
-name = "tracing-log"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
-dependencies = [
- "log",
- "once_cell",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-subscriber"
-version = "0.3.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
-dependencies = [
- "nu-ansi-term",
- "sharded-slab",
- "smallvec",
- "thread_local",
- "tracing-core",
- "tracing-log",
-]
-
-[[package]]
-name = "try-lock"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
-
-[[package]]
-name = "typenum"
-version = "1.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
-
-[[package]]
-name = "unicode-bidi"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
-
-[[package]]
-name = "unicode-normalization"
-version = "0.1.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
-dependencies = [
- "tinyvec",
-]
-
-[[package]]
-name = "unicode-width"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
-
-[[package]]
-name = "untrusted"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
-
-[[package]]
-name = "url"
-version = "2.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
-dependencies = [
- "form_urlencoded",
- "idna 0.5.0",
- "percent-encoding",
- "serde",
-]
-
-[[package]]
-name = "urlencoding"
-version = "2.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
-
-[[package]]
-name = "utf-8"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
-
-[[package]]
-name = "utf8parse"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
-
-[[package]]
-name = "uuid"
-version = "1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
-dependencies = [
- "getrandom",
- "serde",
-]
-
-[[package]]
-name = "valuable"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
-
-[[package]]
-name = "vcpkg"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
-
-[[package]]
-name = "version"
-version = "4.21.0"
-dependencies = [
- "bindgen",
- "cc",
- "chelps",
- "libc",
-]
-
-[[package]]
-name = "version_check"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
-
-[[package]]
-name = "want"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
-dependencies = [
- "try-lock",
-]
-
-[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.92"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
-dependencies = [
- "cfg-if",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.92"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
-dependencies = [
- "bumpalo",
- "log",
- "once_cell",
- "proc-macro2",
- "quote",
- "syn 2.0.72",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.42"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
-dependencies = [
- "cfg-if",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.92"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.92"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.92"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
-
-[[package]]
-name = "web-sys"
-version = "0.3.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "which"
-version = "4.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
-dependencies = [
- "either",
- "home",
- "once_cell",
- "rustix",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
-dependencies = [
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "windows"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
-dependencies = [
- "windows-core",
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-core"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.59.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
-dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
-
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-
-[[package]]
-name = "winreg"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
-dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "zerocopy"
-version = "0.7.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
-dependencies = [
- "byteorder",
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.7.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
-
-[[package]]
-name = "zeroize"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
-dependencies = [
- "zeroize_derive",
-]
-
-[[package]]
-name = "zeroize_derive"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.72",
-]
index c32050b9dd00527d40cb63bea09ab7b39bcb0f68..4ed73e6a384fb538a24786fcb0fd6601afa96738 100644 (file)
@@ -7,18 +7,6 @@ version = "4.21.0"
 [workspace]
 resolver = "2"
 members = [
-  "chelps", "config", "dbg", "himmelblaud", "idmap",
-  "nss", "ntstatus_gen", "pam",
-  "param", "sock", "talloc", "tdb", "version",
 ]
 
 [workspace.dependencies]
-param = { path = "param" }
-dbg = { path = "dbg" }
-chelps = { path = "chelps" }
-sock = { path = "sock" }
-ntstatus_gen = { path = "ntstatus_gen" }
-tdb = { path = "tdb" }
-idmap = { path = "idmap" }
-libc = "0.2.155"
-config = { path = "config" }
diff --git a/rust/build.rs b/rust/build.rs
deleted file mode 100644 (file)
index fc0dfaf..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-use std::env;
-
-fn main() {
-    if let Some(vers) = version::samba_version_string() {
-        println!("cargo:rustc-env=CARGO_PKG_VERSION={}", vers);
-    }
-    println!(
-        "cargo:rustc-env=CARGO_PKG_VERSION_MAJOR={}",
-        version::SAMBA_VERSION_MAJOR
-    );
-    println!(
-        "cargo:rustc-env=CARGO_PKG_VERSION_MINOR={}",
-        version::SAMBA_VERSION_MINOR
-    );
-    println!(
-        "cargo:rustc-env=CARGO_PKG_VERSION_PATCH={}",
-        version::SAMBA_VERSION_RELEASE
-    );
-}
diff --git a/rust/chelps/Cargo.toml b/rust/chelps/Cargo.toml
deleted file mode 100644 (file)
index 80dfe1c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "chelps"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[dependencies]
diff --git a/rust/chelps/src/lib.rs b/rust/chelps/src/lib.rs
deleted file mode 100644 (file)
index 79be4f0..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   C conversion helper functions and macros
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-use std::ffi::{CStr, CString};
-use std::os::raw::c_char;
-use std::ptr;
-
-pub unsafe fn wrap_c_char(input: *const c_char) -> Option<String> {
-    if input.is_null() {
-        return None;
-    }
-
-    let c_str = unsafe { CStr::from_ptr(input) };
-    match c_str.to_str() {
-        Ok(output) => Some(output.to_string()),
-        Err(_) => None,
-    }
-}
-
-pub fn wrap_string(input: &str) -> *mut c_char {
-    match CString::new(input.to_string()) {
-        Ok(msg) => msg.into_raw(),
-        Err(_) => ptr::null_mut(),
-    }
-}
-
-pub unsafe fn string_free(input: *mut c_char) {
-    if !input.is_null() {
-        unsafe {
-            let _ = CString::from_raw(input);
-        }
-    }
-}
-
-#[macro_export]
-macro_rules! function {
-    () => {{
-        fn f() {}
-        fn type_name_of<T>(_: T) -> &'static str {
-            std::any::type_name::<T>()
-        }
-        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::*;
-    use std::ffi::CString;
-    use std::ptr;
-
-    #[test]
-    fn test_wrap_c_char_non_null() {
-        let original = "Hello, world!";
-        let c_string = CString::new(original).expect("CString::new failed");
-        let c_ptr = c_string.as_ptr();
-
-        let result = unsafe { wrap_c_char(c_ptr) };
-        assert_eq!(result, Some(original.to_string()));
-    }
-
-    #[test]
-    fn test_wrap_c_char_null() {
-        let result = unsafe { wrap_c_char(ptr::null()) };
-        assert!(result.is_none());
-    }
-
-    #[test]
-    fn test_wrap_c_char_invalid_utf8() {
-        let invalid_utf8 = vec![0xff, 0xff, 0xff, 0xff];
-        let c_string = CString::new(invalid_utf8).expect("CString::new failed");
-        let c_ptr = c_string.as_ptr();
-
-        let result = unsafe { wrap_c_char(c_ptr) };
-        assert!(result.is_none());
-    }
-
-    #[test]
-    fn test_wrap_string() {
-        let original = "Hello, world!";
-        let c_ptr = wrap_string(original);
-
-        let c_str = unsafe { CStr::from_ptr(c_ptr) };
-        let result = c_str.to_str().expect("CStr::to_str failed");
-
-        assert_eq!(result, original);
-
-        // Clean up the allocated memory
-        unsafe { string_free(c_ptr) };
-    }
-
-    #[test]
-    fn test_wrap_string_empty() {
-        let original = "";
-        let c_ptr = wrap_string(original);
-
-        let c_str = unsafe { CStr::from_ptr(c_ptr) };
-        let result = c_str.to_str().expect("CStr::to_str failed");
-
-        assert_eq!(result, original);
-
-        // Clean up the allocated memory
-        unsafe { string_free(c_ptr) };
-    }
-
-    #[test]
-    fn test_wrap_string_null_pointer() {
-        let c_ptr = wrap_string("\0");
-        assert!(c_ptr.is_null());
-    }
-
-    #[test]
-    fn test_string_free_null() {
-        unsafe { string_free(ptr::null_mut()) };
-        // No assertion needed, just ensuring no crash occurs
-    }
-
-    #[test]
-    fn test_string_free_non_null() {
-        let original = "Hello, world!";
-        let c_ptr = wrap_string(original);
-
-        unsafe { string_free(c_ptr) };
-        // No assertion needed, just ensuring the memory was freed without a crash
-    }
-}
diff --git a/rust/config/Cargo.toml b/rust/config/Cargo.toml
deleted file mode 100644 (file)
index e61ab95..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-[package]
-name = "config"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[dependencies]
-libc.workspace = true
-
-[build-dependencies]
-bindgen = "0.69.4"
diff --git a/rust/config/additions.h b/rust/config/additions.h
deleted file mode 100644 (file)
index 96a4950..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "../../bin/default/include/config.h"
-#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/build.rs b/rust/config/build.rs
deleted file mode 100644 (file)
index b1c1549..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-use std::env;
-use std::path::PathBuf;
-
-fn main() {
-    let header = "../../bin/default/include/config.h";
-    println!("cargo:rerun-if-changed={}", header);
-    let additions_header = "./additions.h";
-    println!("cargo:rerun-if-changed={}", additions_header);
-
-    let bindings = bindgen::Builder::default()
-        .header(additions_header)
-        .header(header)
-        .generate()
-        .expect("Failed generating config bindings!");
-
-    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
-    bindings
-        .write_to_file(out_path.join("bindings.rs"))
-        .expect("Couldn't write bindings!");
-}
diff --git a/rust/config/src/lib.rs b/rust/config/src/lib.rs
deleted file mode 100644 (file)
index a8546ee..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Samba config imported into Rust
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-#![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"));
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_using_system_tdb() {
-        // This test just ensures that USING_SYSTEM_TDB is available from the
-        // config. None of the other options are really used at the moment.
-        assert!(
-            USING_SYSTEM_TDB == 0 || USING_SYSTEM_TDB == 1,
-            "Unexpected value for USING_SYSTEM_TDB: {}",
-            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/Cargo.toml b/rust/dbg/Cargo.toml
deleted file mode 100644 (file)
index e1c6284..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-name = "dbg"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[build-dependencies]
-bindgen = "0.69.4"
-
-[dependencies]
-chelps.workspace = true
-
-[dev-dependencies]
-tempfile = "3.12.0"
-paste = "1.0.15"
diff --git a/rust/dbg/build.rs b/rust/dbg/build.rs
deleted file mode 100644 (file)
index 149df6b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-use std::env;
-use std::path::PathBuf;
-
-fn main() {
-    let bindings = bindgen::Builder::default()
-        .header("../../lib/util/debug.h")
-        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
-        .generate()
-        .expect("Unable to generate bindings");
-
-    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/util");
-    println!(
-        "cargo:rustc-link-search=native={}",
-        src_dir.to_str().unwrap()
-    );
-    println!("cargo:rustc-link-lib=samba-debug-private-samba");
-    println!("cargo:rustc-link-lib=samba-util");
-    println!("cargo:rustc-env=LD_LIBRARY_PATH=../../bin/shared:../../bin/shared/private/");
-}
diff --git a/rust/dbg/src/lib.rs b/rust/dbg/src/lib.rs
deleted file mode 100644 (file)
index 26c513e..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Parameter loading 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 <http://www.gnu.org/licenses/>.
-*/
-
-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"));
-}
-
-pub const MAX_DEBUG_LEVEL: u32 = ffi::MAX_DEBUG_LEVEL;
-pub const DBGLVL_ERR: u32 = ffi::DBGLVL_ERR;
-pub const DBGLVL_WARNING: u32 = ffi::DBGLVL_WARNING;
-pub const DBGLVL_NOTICE: u32 = ffi::DBGLVL_NOTICE;
-pub const DBGLVL_INFO: u32 = ffi::DBGLVL_INFO;
-pub const DBGLVL_DEBUG: u32 = ffi::DBGLVL_DEBUG;
-
-pub const DEBUG_DEFAULT_STDERR: ffi::debug_logtype =
-    ffi::debug_logtype_DEBUG_DEFAULT_STDERR;
-pub const DEBUG_DEFAULT_STDOUT: ffi::debug_logtype =
-    ffi::debug_logtype_DEBUG_DEFAULT_STDOUT;
-pub const DEBUG_FILE: ffi::debug_logtype = ffi::debug_logtype_DEBUG_FILE;
-pub const DEBUG_STDOUT: ffi::debug_logtype = ffi::debug_logtype_DEBUG_STDOUT;
-pub const DEBUG_STDERR: ffi::debug_logtype = ffi::debug_logtype_DEBUG_STDERR;
-pub const DEBUG_CALLBACK: ffi::debug_logtype =
-    ffi::debug_logtype_DEBUG_CALLBACK;
-
-pub fn debug_set_logfile(name: &str) {
-    let name_cstr = chelps::wrap_string(name);
-    unsafe {
-        ffi::debug_set_logfile(name_cstr);
-        chelps::string_free(name_cstr);
-    }
-}
-
-pub fn setup_logging(prog_name: &str, new_logtype: ffi::debug_logtype) {
-    let prog_name_cstr = chelps::wrap_string(prog_name);
-    unsafe {
-        ffi::setup_logging(prog_name_cstr, new_logtype);
-        chelps::string_free(prog_name_cstr);
-    }
-}
-
-pub fn dbgflush() {
-    unsafe {
-        ffi::dbgflush();
-    }
-}
-
-#[macro_export]
-macro_rules! debuglevel_set {
-    ($level:expr) => {{
-        unsafe {
-            $crate::ffi::debuglevel_set_class(
-                $crate::ffi::DBGC_ALL as usize,
-                $level as i32,
-            )
-        }
-    }};
-}
-
-#[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 = chelps::function!();
-            let function_msg = format!("{}: ", function);
-            let function_cstr = chelps::wrap_string(&function);
-            let function_msg_cstr = chelps::wrap_string(&function_msg);
-            // Always append a newline to the debug, otherwise it won't flush
-            // to the log.
-            let msg = format!("{}\n", format!($($arg),*));
-            let msg_cstr = chelps::wrap_string(&msg);
-            unsafe {
-                let _ = $crate::ffi::debuglevel_get_class($crate::ffi::DBGC_CLASS as usize) >= ($level as i32)
-                    && $crate::ffi::dbghdrclass($level as i32,
-                           $crate::ffi::DBGC_CLASS as i32,
-                           location_cstr,
-                           function_cstr)
-                    && $crate::ffi::dbgtext(function_msg_cstr)
-                    && $crate::ffi::dbgtext(msg_cstr);
-                chelps::string_free(location_cstr);
-                chelps::string_free(function_cstr);
-                chelps::string_free(function_msg_cstr);
-                chelps::string_free(msg_cstr);
-            }
-        }
-    }}
-}
-
-#[macro_export]
-macro_rules! DBG_ERR {
-    ($msg:expr $(, $arg:expr)* $(,)?) => {{
-        $crate::DBG_PREFIX!($crate::ffi::DBGLVL_ERR, $msg, $($arg),*)
-    }}
-}
-
-#[macro_export]
-macro_rules! DBG_WARNING {
-    ($msg:expr $(, $arg:expr)* $(,)?) => {{
-        $crate::DBG_PREFIX!($crate::ffi::DBGLVL_WARNING, $msg, $($arg),*)
-    }}
-}
-
-#[macro_export]
-macro_rules! DBG_NOTICE {
-    ($msg:expr $(, $arg:expr)* $(,)?) => {{
-        $crate::DBG_PREFIX!($crate::ffi::DBGLVL_NOTICE, $msg, $($arg),*)
-    }}
-}
-
-#[macro_export]
-macro_rules! DBG_INFO {
-    ($msg:expr $(, $arg:expr)* $(,)?) => {{
-        $crate::DBG_PREFIX!($crate::ffi::DBGLVL_INFO, $msg, $($arg),*)
-    }}
-}
-
-#[macro_export]
-macro_rules! DBG_DEBUG {
-    ($msg:expr $(, $arg:expr)* $(,)?) => {{
-        $crate::DBG_PREFIX!($crate::ffi::DBGLVL_DEBUG, $msg, $($arg),*)
-    }}
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use paste::paste;
-    use std::fs::File;
-    use std::io::Read;
-    use tempfile::NamedTempFile;
-
-    #[test]
-    fn test_debug_constants() {
-        assert_eq!(MAX_DEBUG_LEVEL, ffi::MAX_DEBUG_LEVEL);
-        assert_eq!(DBGLVL_ERR, ffi::DBGLVL_ERR);
-        assert_eq!(DBGLVL_WARNING, ffi::DBGLVL_WARNING);
-        assert_eq!(DBGLVL_NOTICE, ffi::DBGLVL_NOTICE);
-        assert_eq!(DBGLVL_INFO, ffi::DBGLVL_INFO);
-        assert_eq!(DBGLVL_DEBUG, ffi::DBGLVL_DEBUG);
-
-        assert_eq!(
-            DEBUG_DEFAULT_STDERR,
-            ffi::debug_logtype_DEBUG_DEFAULT_STDERR
-        );
-        assert_eq!(
-            DEBUG_DEFAULT_STDOUT,
-            ffi::debug_logtype_DEBUG_DEFAULT_STDOUT
-        );
-        assert_eq!(DEBUG_FILE, ffi::debug_logtype_DEBUG_FILE);
-        assert_eq!(DEBUG_STDOUT, ffi::debug_logtype_DEBUG_STDOUT);
-        assert_eq!(DEBUG_STDERR, ffi::debug_logtype_DEBUG_STDERR);
-        assert_eq!(DEBUG_CALLBACK, ffi::debug_logtype_DEBUG_CALLBACK);
-    }
-
-    macro_rules! test_dbg_macro {
-        ($level:ident) => {
-            paste! {
-                #[test]
-                fn [<test_dbg_ $level:lower _macro>]() {
-                    let logfile = NamedTempFile::new().expect("Failed to create temporary file");
-                    let logfile = logfile.path().to_str().unwrap();
-                    setup_logging("test_program", DEBUG_FILE);
-                    debug_set_logfile(logfile);
-
-                    let logfile_output = concat!("This is a ", stringify!($level), " message");
-
-                    debuglevel_set!([<DBGLVL_ $level:upper>]);
-
-                    [<DBG_ $level:upper>]!("{}\n", logfile_output);
-                    dbgflush();
-
-                    let mut file = File::open(logfile).expect("Failed to open logfile");
-                    let mut logfile_contents = String::new();
-                    file.read_to_string(&mut logfile_contents)
-                        .expect("Failed to read logfile");
-                    assert!(
-                        logfile_contents.contains(logfile_output),
-                        "Test data missing from logfile: {}",
-                        logfile_contents
-                    );
-                }
-            }
-        };
-    }
-
-    test_dbg_macro!(DEBUG);
-    // Multiple re-inits of the debug env cause it to fail, so we can't
-    // reliably test all of these in one go.
-    //test_dbg_macro!(INFO);
-    //test_dbg_macro!(NOTICE);
-    //test_dbg_macro!(WARNING);
-    //test_dbg_macro!(ERR);
-}
diff --git a/rust/himmelblaud/Cargo.toml b/rust/himmelblaud/Cargo.toml
deleted file mode 100644 (file)
index dedde9e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-[package]
-name = "himmelblaud"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[dependencies]
-libhimmelblau = "0.2.9"
-ntstatus_gen.workspace = true
-param = { workspace = true }
-sock = { workspace = true }
-tdb = { workspace = true }
-dbg = { workspace = true }
-chelps.workspace = true
-clap = "4.5.9"
-kanidm-hsm-crypto = "0.2.0"
-serde_json = "1.0.120"
-tokio = { version = "1.38.1", features = [ "rt", "macros" ] }
-tokio-util = { version = "0.7.11", features = ["codec"] }
-bytes = "1.6.1"
-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" }
-
-[dev-dependencies]
-tempfile = "3.12.0"
diff --git a/rust/himmelblaud/build.rs b/rust/himmelblaud/build.rs
deleted file mode 100644 (file)
index da232e3..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
-    println!("cargo:rustc-env=LD_LIBRARY_PATH=../../bin/shared:../../bin/shared/private/");
-}
diff --git a/rust/himmelblaud/src/cache.rs b/rust/himmelblaud/src/cache.rs
deleted file mode 100644 (file)
index 764753d..0000000
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon cache
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use dbg::DBG_ERR;
-use himmelblau::error::MsalError;
-use himmelblau::graph::DirectoryObject;
-use himmelblau::UserToken;
-use kanidm_hsm_crypto::{
-    AuthValue, BoxedDynTpm, LoadableIdentityKey, LoadableMachineKey,
-    LoadableMsOapxbcRsaKey, Tpm,
-};
-use libc::uid_t;
-use ntstatus_gen::*;
-use serde::{Deserialize, Serialize};
-use serde_json::{from_slice as json_from_slice, to_vec as json_to_vec};
-use std::collections::HashSet;
-use tdb::Tdb;
-
-struct BasicCache {
-    tdb: Tdb,
-}
-
-impl BasicCache {
-    fn new(cache_path: &str) -> Result<Self, Box<NTSTATUS>> {
-        let tdb =
-            Tdb::open(cache_path, None, None, None, None).map_err(|e| {
-                DBG_ERR!("{:?}", e);
-                Box::new(NT_STATUS_FILE_INVALID)
-            })?;
-        Ok(BasicCache { tdb })
-    }
-
-    fn fetch_str(&self, key: &str) -> Option<String> {
-        let key = key.to_string().to_lowercase();
-        let exists = match self.tdb.exists(&key) {
-            Ok(exists) => exists,
-            Err(e) => {
-                DBG_ERR!("Failed to fetch {}: {:?}", key, e);
-                false
-            }
-        };
-        if exists {
-            match self.tdb.fetch(&key) {
-                Ok(val) => Some(val),
-                Err(e) => {
-                    DBG_ERR!("Failed to fetch {}: {:?}", key, e);
-                    None
-                }
-            }
-        } else {
-            None
-        }
-    }
-
-    fn fetch<'a, T>(&self, key: &str) -> Option<T>
-    where
-        T: for<'de> Deserialize<'de>,
-    {
-        let key = key.to_string().to_lowercase();
-        match self.fetch_str(&key) {
-            Some(val) => match json_from_slice::<T>(val.as_bytes()) {
-                Ok(res) => Some(res),
-                Err(e) => {
-                    DBG_ERR!("Failed to decode {}: {:?}", key, e);
-                    None
-                }
-            },
-            None => {
-                return None;
-            }
-        }
-    }
-
-    fn store_bytes(
-        &mut self,
-        key: &str,
-        val: &[u8],
-    ) -> Result<(), Box<NTSTATUS>> {
-        let key = key.to_string().to_lowercase();
-        match self.tdb.transaction_start() {
-            Ok(start) => {
-                if !start {
-                    DBG_ERR!("Failed to start the database transaction.");
-                    return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                }
-            }
-            Err(e) => {
-                DBG_ERR!("Failed to start the database transaction: {:?}", e);
-                return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-            }
-        };
-
-        let res = match self.tdb.store(&key, val, None) {
-            Ok(res) => Some(res),
-            Err(e) => {
-                DBG_ERR!("Unable to persist {}: {:?}", key, e);
-                None
-            }
-        };
-
-        let res = match res {
-            Some(res) => res,
-            None => {
-                let _ = self.tdb.transaction_cancel();
-                return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-            }
-        };
-        if !res {
-            DBG_ERR!("Unable to persist {}", key);
-            let _ = self.tdb.transaction_cancel();
-            return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-        }
-
-        let success = match self.tdb.transaction_commit() {
-            Ok(success) => success,
-            Err(e) => {
-                DBG_ERR!("Failed to commit the database transaction: {:?}", e);
-                return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-            }
-        };
-        if !success {
-            DBG_ERR!("Failed to commit the database transaction.");
-            let _ = self.tdb.transaction_cancel();
-            return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-        }
-
-        Ok(())
-    }
-
-    fn store<T>(&mut self, key: &str, val: T) -> Result<(), Box<NTSTATUS>>
-    where
-        T: Serialize,
-    {
-        let key = key.to_string().to_lowercase();
-        let val_bytes = match json_to_vec(&val) {
-            Ok(val_bytes) => val_bytes,
-            Err(e) => {
-                DBG_ERR!("Unable to serialize {}: {:?}", key, e);
-                return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-            }
-        };
-        self.store_bytes(&key, &val_bytes)
-    }
-
-    fn keys(&self) -> Result<Vec<String>, Box<NTSTATUS>> {
-        self.tdb.keys().map_err(|e| {
-            DBG_ERR!("{:?}", e);
-            Box::new(NT_STATUS_UNSUCCESSFUL)
-        })
-    }
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize)]
-pub(crate) struct UserEntry {
-    pub(crate) upn: String,
-    pub(crate) uuid: String,
-    pub(crate) name: String,
-}
-
-impl TryFrom<&UserToken> for UserEntry {
-    type Error = MsalError;
-
-    fn try_from(token: &UserToken) -> Result<Self, Self::Error> {
-        Ok(UserEntry {
-            upn: token.spn()?,
-            uuid: token.uuid()?.to_string(),
-            name: token.id_token.name.clone(),
-        })
-    }
-}
-
-pub(crate) struct UserCache {
-    cache: BasicCache,
-}
-
-impl UserCache {
-    pub(crate) fn new(cache_path: &str) -> Result<Self, Box<NTSTATUS>> {
-        Ok(UserCache {
-            cache: BasicCache::new(cache_path)?,
-        })
-    }
-
-    pub(crate) fn fetch(&mut self, upn: &str) -> Option<UserEntry> {
-        self.cache.fetch::<UserEntry>(upn)
-    }
-
-    pub(crate) fn fetch_all(
-        &mut self,
-    ) -> Result<Vec<UserEntry>, Box<NTSTATUS>> {
-        let keys = self.cache.keys()?;
-        let mut res = Vec::new();
-        for upn in keys {
-            let entry = match self.cache.fetch::<UserEntry>(&upn) {
-                Some(entry) => entry,
-                None => {
-                    DBG_ERR!("Unable to fetch user {}", upn);
-                    return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                }
-            };
-            res.push(entry);
-        }
-        Ok(res)
-    }
-
-    pub(crate) fn store(
-        &mut self,
-        entry: UserEntry,
-    ) -> Result<(), Box<NTSTATUS>> {
-        let key = entry.upn.clone();
-        self.cache.store::<UserEntry>(&key, entry)
-    }
-}
-
-pub(crate) struct UidCache {
-    cache: BasicCache,
-}
-
-impl UidCache {
-    pub(crate) fn new(cache_path: &str) -> Result<Self, Box<NTSTATUS>> {
-        Ok(UidCache {
-            cache: BasicCache::new(cache_path)?,
-        })
-    }
-
-    pub(crate) fn store(
-        &mut self,
-        uid: uid_t,
-        upn: &str,
-    ) -> Result<(), Box<NTSTATUS>> {
-        let key = format!("{}", uid);
-        let upn = upn.to_string().to_lowercase();
-        self.cache.store_bytes(&key, upn.as_bytes())
-    }
-
-    pub(crate) fn fetch(&mut self, uid: uid_t) -> Option<String> {
-        let key = format!("{}", uid);
-        self.cache.fetch_str(&key)
-    }
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize)]
-pub(crate) struct GroupEntry {
-    pub(crate) uuid: String,
-    members: HashSet<String>,
-}
-
-impl From<DirectoryObject> for GroupEntry {
-    fn from(obj: DirectoryObject) -> Self {
-        GroupEntry {
-            uuid: obj.id.clone(),
-            members: HashSet::new(),
-        }
-    }
-}
-
-impl GroupEntry {
-    pub(crate) fn add_member(&mut self, member: &str) {
-        // Only ever use lowercase names, otherwise the group
-        // memberships will have duplicates.
-        self.members.insert(member.to_lowercase());
-    }
-
-    pub(crate) fn remove_member(&mut self, member: &str) {
-        // Only ever use lowercase names, otherwise the group
-        // memberships will have duplicates.
-        self.members.remove(&member.to_lowercase());
-    }
-
-    pub(crate) fn into_with_member(obj: DirectoryObject, member: &str) -> Self {
-        let mut g: GroupEntry = obj.into();
-        g.add_member(member);
-        g
-    }
-
-    pub(crate) fn members(&self) -> Vec<String> {
-        self.members.clone().into_iter().collect::<Vec<String>>()
-    }
-}
-
-impl GroupEntry {
-    pub fn new(uuid: &str) -> Self {
-        GroupEntry {
-            uuid: uuid.to_string(),
-            members: HashSet::new(),
-        }
-    }
-}
-
-pub(crate) struct GroupCache {
-    cache: BasicCache,
-}
-
-impl GroupCache {
-    pub(crate) fn new(cache_path: &str) -> Result<Self, Box<NTSTATUS>> {
-        Ok(GroupCache {
-            cache: BasicCache::new(cache_path)?,
-        })
-    }
-
-    pub(crate) fn fetch(&mut self, uuid: &str) -> Option<GroupEntry> {
-        self.cache.fetch::<GroupEntry>(uuid)
-    }
-
-    pub(crate) fn fetch_all(
-        &mut self,
-    ) -> Result<Vec<GroupEntry>, Box<NTSTATUS>> {
-        let keys = self.cache.keys()?;
-        let mut res = Vec::new();
-        for uuid in keys {
-            let entry = match self.cache.fetch::<GroupEntry>(&uuid) {
-                Some(entry) => entry,
-                None => {
-                    DBG_ERR!("Unable to fetch group {}", uuid);
-                    return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                }
-            };
-            res.push(entry);
-        }
-        Ok(res)
-    }
-
-    pub(crate) fn merge_groups(
-        &mut self,
-        member: &str,
-        mut entries: Vec<GroupEntry>,
-    ) -> Result<(), Box<NTSTATUS>> {
-        // We need to ensure the member is removed from non-intersecting
-        // groups, otherwise we don't honor group membership removals.
-        let group_uuids: HashSet<String> = entries
-            .clone()
-            .into_iter()
-            .map(|g| g.uuid.clone())
-            .collect();
-        let existing_group_uuids = {
-            let cache = &self.cache;
-            match cache.keys() {
-                Ok(keys) => keys,
-                Err(e) => {
-                    DBG_ERR!("Unable to fetch groups: {:?}", e);
-                    return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                }
-            }
-        };
-        let existing_group_uuids: HashSet<String> =
-            existing_group_uuids.into_iter().collect();
-        let difference: HashSet<String> = existing_group_uuids
-            .difference(&group_uuids)
-            .cloned()
-            .collect();
-        for group_uuid in &difference {
-            if let Some(mut group) =
-                self.cache.fetch::<GroupEntry>(&group_uuid).clone()
-            {
-                group.remove_member(member);
-                if let Err(e) =
-                    self.cache.store::<GroupEntry>(&group.uuid.clone(), group)
-                {
-                    DBG_ERR!("Unable to store membership change: {:?}", e);
-                    return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                }
-            }
-        }
-
-        // Ensure the member is added to the listed groups
-        for group in &mut entries {
-            group.add_member(member);
-        }
-
-        // Now add the new entries, merging with existing memberships
-        for group in entries {
-            match self.cache.fetch::<GroupEntry>(&group.uuid) {
-                Some(mut existing_group) => {
-                    // Merge with an existing entry
-                    existing_group.add_member(member);
-                    if let Err(e) = self.cache.store::<GroupEntry>(
-                        &existing_group.uuid.clone(),
-                        existing_group,
-                    ) {
-                        DBG_ERR!("Unable to store membership change: {:?}", e);
-                        return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                    }
-                }
-                None => {
-                    if let Err(e) = self
-                        .cache
-                        .store::<GroupEntry>(&group.uuid.clone(), group)
-                    {
-                        DBG_ERR!("Unable to store membership change: {:?}", e);
-                        return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                    }
-                }
-            }
-        }
-        Ok(())
-    }
-}
-
-pub(crate) struct PrivateCache {
-    cache: BasicCache,
-}
-
-impl PrivateCache {
-    pub(crate) fn new(cache_path: &str) -> Result<Self, Box<NTSTATUS>> {
-        Ok(PrivateCache {
-            cache: BasicCache::new(cache_path)?,
-        })
-    }
-
-    pub(crate) fn loadable_machine_key_fetch_or_create(
-        &mut self,
-        hsm: &mut BoxedDynTpm,
-        auth_value: &AuthValue,
-    ) -> Result<LoadableMachineKey, Box<NTSTATUS>> {
-        match self
-            .cache
-            .fetch::<LoadableMachineKey>("loadable_machine_key")
-        {
-            Some(loadable_machine_key) => Ok(loadable_machine_key),
-            None => {
-                // No machine key found - create one, and store it.
-                let loadable_machine_key =
-                    match hsm.machine_key_create(&auth_value) {
-                        Ok(loadable_machine_key) => loadable_machine_key,
-                        Err(e) => {
-                            DBG_ERR!(
-                                "Unable to create hsm loadable \
-                                machine key: {:?}",
-                                e
-                            );
-                            return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                        }
-                    };
-
-                self.cache.store::<LoadableMachineKey>(
-                    "loadable_machine_key",
-                    loadable_machine_key.clone(),
-                )?;
-
-                Ok(loadable_machine_key)
-            }
-        }
-    }
-
-    pub(crate) fn loadable_transport_key_fetch(
-        &mut self,
-        realm: &str,
-    ) -> Option<LoadableMsOapxbcRsaKey> {
-        let transport_key_tag = format!("{}/transport", realm);
-        self.cache
-            .fetch::<LoadableMsOapxbcRsaKey>(&transport_key_tag)
-    }
-
-    pub(crate) fn loadable_cert_key_fetch(
-        &mut self,
-        realm: &str,
-    ) -> Option<LoadableIdentityKey> {
-        let cert_key_tag = format!("{}/certificate", realm);
-        self.cache.fetch::<LoadableIdentityKey>(&cert_key_tag)
-    }
-
-    pub(crate) fn loadable_hello_key_fetch(
-        &mut self,
-        account_id: &str,
-    ) -> Option<LoadableIdentityKey> {
-        let hello_key_tag = format!("{}/hello", account_id);
-        self.cache.fetch::<LoadableIdentityKey>(&hello_key_tag)
-    }
-
-    pub(crate) fn loadable_cert_key_store(
-        &mut self,
-        realm: &str,
-        cert_key: LoadableIdentityKey,
-    ) -> Result<(), Box<NTSTATUS>> {
-        let cert_key_tag = format!("{}/certificate", realm);
-        self.cache
-            .store::<LoadableIdentityKey>(&cert_key_tag, cert_key)
-    }
-
-    pub(crate) fn loadable_hello_key_store(
-        &mut self,
-        account_id: &str,
-        hello_key: LoadableIdentityKey,
-    ) -> Result<(), Box<NTSTATUS>> {
-        let hello_key_tag = format!("{}/hello", account_id);
-        self.cache
-            .store::<LoadableIdentityKey>(&hello_key_tag, hello_key)
-    }
-
-    pub(crate) fn loadable_transport_key_store(
-        &mut self,
-        realm: &str,
-        transport_key: LoadableMsOapxbcRsaKey,
-    ) -> Result<(), Box<NTSTATUS>> {
-        let transport_key_tag = format!("{}/transport", realm);
-        self.cache
-            .store::<LoadableMsOapxbcRsaKey>(&transport_key_tag, transport_key)
-    }
-
-    pub(crate) fn device_id(&mut self, realm: &str) -> Option<String> {
-        let device_id_tag = format!("{}/device_id", realm);
-        self.cache.fetch_str(&device_id_tag)
-    }
-
-    pub(crate) fn device_id_store(
-        &mut self,
-        realm: &str,
-        device_id: &str,
-    ) -> Result<(), Box<NTSTATUS>> {
-        let device_id_tag = format!("{}/device_id", realm);
-        self.cache.store_bytes(&device_id_tag, device_id.as_bytes())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use kanidm_hsm_crypto::soft::SoftTpm;
-    use std::str::FromStr;
-    use tempfile::tempdir;
-
-    #[test]
-    fn test_basic_cache_new() {
-        let dir = tempdir().unwrap();
-        let cache_path = dir.path().join("test.tdb");
-        let cache = BasicCache::new(cache_path.to_str().unwrap());
-        assert!(cache.is_ok());
-    }
-
-    #[test]
-    fn test_basic_cache_store_fetch_str() {
-        let dir = tempdir().unwrap();
-        let cache_path = dir.path().join("test.tdb");
-        let mut cache = BasicCache::new(cache_path.to_str().unwrap()).unwrap();
-
-        let key = "test_key";
-        let value = "test_value";
-        cache.store_bytes(key, value.as_bytes()).unwrap();
-        let fetched_value = cache.fetch_str(key).unwrap();
-        assert_eq!(fetched_value, value);
-    }
-
-    #[test]
-    fn test_basic_cache_store_fetch() {
-        let dir = tempdir().unwrap();
-        let cache_path = dir.path().join("test.tdb");
-        let mut cache = BasicCache::new(cache_path.to_str().unwrap()).unwrap();
-
-        let key = "test_key";
-        let value = UserEntry {
-            upn: "user@test.com".to_string(),
-            uuid: "f63a43c7-b783-4da9-acb4-89f8ebfc49e9".to_string(),
-            name: "Test User".to_string(),
-        };
-
-        cache.store(key, &value).unwrap();
-        let fetched_value: Option<UserEntry> = cache.fetch(key);
-        assert!(fetched_value.is_some());
-        let fetched_value = fetched_value.unwrap();
-        assert_eq!(fetched_value.upn, value.upn);
-        assert_eq!(fetched_value.uuid, value.uuid);
-        assert_eq!(fetched_value.name, value.name);
-    }
-
-    #[test]
-    fn test_user_cache_store_fetch() {
-        let dir = tempdir().unwrap();
-        let cache_path = dir.path().join("test.tdb");
-        let mut cache = UserCache::new(cache_path.to_str().unwrap()).unwrap();
-
-        let entry = UserEntry {
-            upn: "user@test.com".to_string(),
-            uuid: "f63a43c7-b783-4da9-acb4-89f8ebfc49e9".to_string(),
-            name: "Test User".to_string(),
-        };
-
-        cache.store(entry.clone()).unwrap();
-        let fetched_entry = cache.fetch(&entry.upn);
-        assert!(fetched_entry.is_some());
-        let fetched_entry = fetched_entry.unwrap();
-        assert_eq!(fetched_entry.upn, entry.upn);
-        assert_eq!(fetched_entry.uuid, entry.uuid);
-        assert_eq!(fetched_entry.name, entry.name);
-    }
-
-    #[test]
-    fn test_uid_cache_store_fetch() {
-        let dir = tempdir().unwrap();
-        let cache_path = dir.path().join("test.tdb");
-        let mut cache = UidCache::new(cache_path.to_str().unwrap()).unwrap();
-
-        let uid: uid_t = 1000;
-        let upn = "user@test.com";
-
-        cache.store(uid, upn).unwrap();
-        let fetched_upn = cache.fetch(uid);
-        assert!(fetched_upn.is_some());
-        assert_eq!(fetched_upn.unwrap(), upn);
-    }
-
-    #[test]
-    fn test_group_cache_store_fetch() {
-        let dir = tempdir().unwrap();
-        let cache_path = dir.path().join("test.tdb");
-        let mut cache = GroupCache::new(cache_path.to_str().unwrap()).unwrap();
-
-        let mut group = GroupEntry {
-            uuid: "5f8be63a-a379-4324-9f42-9ea40bed9d7f".to_string(),
-            members: HashSet::new(),
-        };
-        group.add_member("user@test.com");
-
-        cache.cache.store(&group.uuid, &group).unwrap();
-        let fetched_group = cache.fetch(&group.uuid);
-        assert!(fetched_group.is_some());
-        let fetched_group = fetched_group.unwrap();
-        assert_eq!(fetched_group.uuid, group.uuid);
-        assert!(fetched_group.members.contains("user@test.com"));
-    }
-
-    #[test]
-    fn test_private_cache_loadable_machine_key_fetch_or_create() {
-        let dir = tempdir().unwrap();
-        let cache_path = dir.path().join("test.tdb");
-        let mut cache =
-            PrivateCache::new(cache_path.to_str().unwrap()).unwrap();
-
-        let mut hsm = BoxedDynTpm::new(SoftTpm::new());
-        let auth_str = AuthValue::generate().expect("Failed to create hex pin");
-        let auth_value = AuthValue::from_str(&auth_str)
-            .expect("Unable to create auth value");
-
-        let result =
-            cache.loadable_machine_key_fetch_or_create(&mut hsm, &auth_value);
-        assert!(result.is_ok());
-
-        let fetched_key = cache
-            .cache
-            .fetch::<LoadableMachineKey>("loadable_machine_key");
-        assert!(fetched_key.is_some());
-    }
-}
diff --git a/rust/himmelblaud/src/constants.rs b/rust/himmelblaud/src/constants.rs
deleted file mode 100644 (file)
index e2a3647..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pub const DEFAULT_ODC_PROVIDER: &str = "odc.officeapps.live.com";
diff --git a/rust/himmelblaud/src/himmelblaud.rs b/rust/himmelblaud/src/himmelblaud.rs
deleted file mode 100644 (file)
index 36541d8..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::cache::{GroupCache, PrivateCache, UidCache, UserCache};
-#[cfg(not(test))]
-use crate::himmelblaud::himmelblaud_pam_auth::AuthSession;
-use bytes::{BufMut, BytesMut};
-use dbg::{DBG_DEBUG, DBG_ERR, DBG_WARNING};
-use futures::{SinkExt, StreamExt};
-use himmelblau::graph::Graph;
-use himmelblau::BrokerClientApplication;
-use idmap::Idmap;
-use kanidm_hsm_crypto::{BoxedDynTpm, MachineKey};
-use param::LoadParm;
-use sock::{PamAuthResponse, Request, Response};
-use std::error::Error;
-use std::io;
-use std::io::{Error as IoError, ErrorKind};
-use std::sync::Arc;
-use tokio::net::UnixStream;
-use tokio::sync::Mutex;
-use tokio_util::codec::{Decoder, Encoder, Framed};
-
-#[cfg(not(test))]
-pub(crate) struct Resolver {
-    realm: String,
-    tenant_id: String,
-    lp: LoadParm,
-    idmap: Idmap,
-    graph: Graph,
-    pcache: PrivateCache,
-    user_cache: UserCache,
-    uid_cache: UidCache,
-    group_cache: GroupCache,
-    hsm: Mutex<BoxedDynTpm>,
-    machine_key: MachineKey,
-    client: Arc<Mutex<BrokerClientApplication>>,
-}
-
-#[cfg(not(test))]
-impl Resolver {
-    pub(crate) fn new(
-        realm: &str,
-        tenant_id: &str,
-        lp: LoadParm,
-        idmap: Idmap,
-        graph: Graph,
-        pcache: PrivateCache,
-        user_cache: UserCache,
-        uid_cache: UidCache,
-        group_cache: GroupCache,
-        hsm: BoxedDynTpm,
-        machine_key: MachineKey,
-        client: BrokerClientApplication,
-    ) -> Self {
-        Resolver {
-            realm: realm.to_string(),
-            tenant_id: tenant_id.to_string(),
-            lp,
-            idmap,
-            graph,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-            hsm: Mutex::new(hsm),
-            machine_key,
-            client: Arc::new(Mutex::new(client)),
-        }
-    }
-}
-
-// The test environment is unable to communicate with Entra ID, therefore
-// we alter the resolver to only test the cache interactions.
-
-#[cfg(test)]
-pub(crate) struct Resolver {
-    realm: String,
-    tenant_id: String,
-    lp: LoadParm,
-    idmap: Idmap,
-    pcache: PrivateCache,
-    user_cache: UserCache,
-    uid_cache: UidCache,
-    group_cache: GroupCache,
-}
-
-#[cfg(test)]
-impl Resolver {
-    pub(crate) fn new(
-        realm: &str,
-        tenant_id: &str,
-        lp: LoadParm,
-        idmap: Idmap,
-        pcache: PrivateCache,
-        user_cache: UserCache,
-        uid_cache: UidCache,
-        group_cache: GroupCache,
-    ) -> Self {
-        Resolver {
-            realm: realm.to_string(),
-            tenant_id: tenant_id.to_string(),
-            lp,
-            idmap,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-        }
-    }
-}
-
-struct ClientCodec;
-
-impl Decoder for ClientCodec {
-    type Error = io::Error;
-    type Item = Request;
-
-    fn decode(
-        &mut self,
-        src: &mut BytesMut,
-    ) -> Result<Option<Self::Item>, Self::Error> {
-        match serde_json::from_slice::<Request>(src) {
-            Ok(msg) => {
-                src.clear();
-                Ok(Some(msg))
-            }
-            _ => Ok(None),
-        }
-    }
-}
-
-impl Encoder<Response> for ClientCodec {
-    type Error = io::Error;
-
-    fn encode(
-        &mut self,
-        msg: Response,
-        dst: &mut BytesMut,
-    ) -> Result<(), Self::Error> {
-        DBG_DEBUG!("Attempting to send response -> {:?} ...", msg);
-        let data = serde_json::to_vec(&msg).map_err(|e| {
-            DBG_ERR!("socket encoding error -> {:?}", e);
-            io::Error::new(ErrorKind::Other, "JSON encode error")
-        })?;
-        dst.put(data.as_slice());
-        Ok(())
-    }
-}
-
-impl ClientCodec {
-    fn new() -> Self {
-        ClientCodec
-    }
-}
-
-pub(crate) async fn handle_client(
-    stream: UnixStream,
-    resolver: Arc<Mutex<Resolver>>,
-) -> Result<(), Box<dyn Error>> {
-    DBG_DEBUG!("Accepted connection");
-
-    let Ok(_ucred) = stream.peer_cred() else {
-        return Err(Box::new(IoError::new(
-            ErrorKind::Other,
-            "Unable to verify peer credentials.",
-        )));
-    };
-
-    let mut reqs = Framed::new(stream, ClientCodec::new());
-    #[cfg(not(test))]
-    let mut pam_auth_session_state = None;
-
-    while let Some(Ok(req)) = reqs.next().await {
-        let mut resolver = resolver.lock().await;
-        let resp = match req {
-            #[cfg(not(test))]
-            Request::PamAuthenticateInit(account_id) => {
-                DBG_DEBUG!("pam authenticate init");
-
-                match &pam_auth_session_state {
-                    Some(_) => {
-                        DBG_WARNING!(
-                            "Attempt to init \
-                                                    auth session while current \
-                                                    session is active"
-                        );
-                        pam_auth_session_state = None;
-                        Response::Error
-                    }
-                    None => {
-                        let (auth_session, resp) =
-                            resolver.pam_auth_init(&account_id)?;
-                        pam_auth_session_state = Some(auth_session);
-                        resp
-                    }
-                }
-            }
-            #[cfg(not(test))]
-            Request::PamAuthenticateStep(pam_next_req) => {
-                DBG_DEBUG!("pam authenticate step");
-                match &mut pam_auth_session_state {
-                    Some(AuthSession::InProgress {
-                        account_id,
-                        cred_handler,
-                    }) => {
-                        let resp = resolver
-                            .pam_auth_step(
-                                account_id,
-                                cred_handler,
-                                pam_next_req,
-                            )
-                            .await?;
-                        match resp {
-                            Response::PamAuthStepResponse(
-                                PamAuthResponse::Success,
-                            ) => {
-                                pam_auth_session_state =
-                                    Some(AuthSession::Success);
-                            }
-                            Response::PamAuthStepResponse(
-                                PamAuthResponse::Denied,
-                            ) => {
-                                pam_auth_session_state =
-                                    Some(AuthSession::Denied);
-                            }
-                            _ => {}
-                        }
-                        resp
-                    }
-                    _ => {
-                        DBG_WARNING!(
-                            "Attempt to \
-                                                    continue auth session \
-                                                    while current session is \
-                                                    inactive"
-                        );
-                        Response::Error
-                    }
-                }
-            }
-            Request::NssAccounts => resolver.getpwent().await?,
-            Request::NssAccountByName(account_id) => {
-                resolver.getpwnam(&account_id).await?
-            }
-            Request::NssAccountByUid(uid) => resolver.getpwuid(uid).await?,
-            Request::NssGroups => resolver.getgrent().await?,
-            Request::NssGroupByName(grp_id) => {
-                resolver.getgrnam(&grp_id).await?
-            }
-            Request::NssGroupByGid(gid) => resolver.getgrgid(gid).await?,
-            #[cfg(not(test))]
-            Request::PamAccountAllowed(account_id) => {
-                resolver.pam_acct_mgmt(&account_id).await?
-            }
-            Request::PamAccountBeginSession(_account_id) => Response::Success,
-            #[cfg(test)]
-            _ => Response::Error,
-        };
-        reqs.send(resp).await?;
-        reqs.flush().await?;
-        DBG_DEBUG!("flushed response!");
-    }
-
-    DBG_DEBUG!("Disconnecting client ...");
-    Ok(())
-}
-
-mod himmelblaud_getgrent;
-mod himmelblaud_getgrgid;
-mod himmelblaud_getgrnam;
-mod himmelblaud_getpwent;
-mod himmelblaud_getpwnam;
-mod himmelblaud_getpwuid;
-#[cfg(not(test))]
-mod himmelblaud_pam_acct_mgmt;
-#[cfg(not(test))]
-mod himmelblaud_pam_auth;
diff --git a/rust/himmelblaud/src/himmelblaud/himmelblaud_getgrent.rs b/rust/himmelblaud/src/himmelblaud/himmelblaud_getgrent.rs
deleted file mode 100644 (file)
index 67e02ee..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon implementation for nss getgrent
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::himmelblaud::Resolver;
-use dbg::DBG_ERR;
-use ntstatus_gen::*;
-use sock::{Group, Response};
-
-impl Resolver {
-    pub(crate) async fn getgrent(&mut self) -> Result<Response, Box<NTSTATUS>> {
-        let group_entries = self.group_cache.fetch_all()?;
-        let mut res = Vec::new();
-        for entry in group_entries {
-            let name = entry.uuid.clone();
-            let gid = self
-                .idmap
-                .gen_to_unix(&self.tenant_id, &entry.uuid)
-                .map_err(|e| {
-                    DBG_ERR!("{:?}", e);
-                    Box::new(NT_STATUS_NO_SUCH_GROUP)
-                })?;
-            let group = Group {
-                name,
-                passwd: "x".to_string(),
-                gid,
-                members: entry.members(),
-            };
-            res.push(group);
-        }
-        Ok(Response::NssGroups(res))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::cache::GroupEntry;
-    use crate::{GroupCache, PrivateCache, UidCache, UserCache};
-    use idmap::Idmap;
-    use param::LoadParm;
-    use std::collections::HashSet;
-    use tempfile::tempdir;
-
-    #[tokio::test]
-    async fn test_getgrent() {
-        // Create a temporary directory for the cache
-        let dir = tempdir().unwrap();
-
-        // Initialize the caches
-        let private_cache_path = dir
-            .path()
-            .join("himmelblau.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let pcache = PrivateCache::new(&private_cache_path).unwrap();
-        let user_cache_path = dir
-            .path()
-            .join("himmelblau_users.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let user_cache = UserCache::new(&user_cache_path).unwrap();
-        let uid_cache_path = dir
-            .path()
-            .join("uid_cache.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let uid_cache = UidCache::new(&uid_cache_path).unwrap();
-        let group_cache_path = dir
-            .path()
-            .join("himmelblau_groups.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let mut group_cache = GroupCache::new(&group_cache_path).unwrap();
-
-        // Insert dummy GroupEntries into the cache
-        let group_uuid1 = "c490c3ea-fd98-4d45-b6aa-2a3520f804fa";
-        let group_uuid2 = "f7a51b58-84de-42a3-b5b1-967b17c04f89";
-        let dummy_group1 = GroupEntry::new(group_uuid1);
-        let dummy_group2 = GroupEntry::new(group_uuid2);
-        group_cache
-            .merge_groups("user1@test.com", vec![dummy_group1.clone()])
-            .unwrap();
-        group_cache
-            .merge_groups("user2@test.com", vec![dummy_group2.clone()])
-            .unwrap();
-
-        // Initialize the Idmap with dummy configuration
-        let realm = "test.com";
-        let tenant_id = "89a61bb7-d1b9-4356-a1e0-75d88e06f14e";
-        let mut idmap = Idmap::new().unwrap();
-        idmap
-            .add_gen_domain(realm, tenant_id, (1000, 2000))
-            .unwrap();
-
-        // Initialize dummy configuration
-        let lp = LoadParm::new(None).expect("Failed loading default config");
-
-        // Initialize the Resolver
-        let mut resolver = Resolver {
-            realm: realm.to_string(),
-            tenant_id: tenant_id.to_string(),
-            lp,
-            idmap,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-        };
-
-        // Test the getgrent function
-        let result = resolver.getgrent().await.unwrap();
-
-        match result {
-            Response::NssGroups(mut groups) => {
-                groups.sort_by(|a, b| a.name.cmp(&b.name));
-                assert_eq!(groups.len(), 2);
-
-                let group1 = &groups[0];
-                assert_eq!(group1.name, dummy_group1.uuid);
-                assert_eq!(group1.gid, 1388);
-                assert_eq!(group1.members, vec!["user1@test.com".to_string()]);
-
-                let group2 = &groups[1];
-                assert_eq!(group2.name, dummy_group2.uuid);
-                assert_eq!(group2.gid, 1593);
-                assert_eq!(group2.members, vec!["user2@test.com".to_string()]);
-            }
-            other => {
-                panic!("Expected NssGroups with a list of groups: {:?}", other)
-            }
-        }
-    }
-}
diff --git a/rust/himmelblaud/src/himmelblaud/himmelblaud_getgrgid.rs b/rust/himmelblaud/src/himmelblaud/himmelblaud_getgrgid.rs
deleted file mode 100644 (file)
index f921446..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon implementation for nss getgrgid
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::himmelblaud::Resolver;
-use libc::gid_t;
-use ntstatus_gen::NTSTATUS;
-use sock::{Group, Response};
-
-impl Resolver {
-    pub(crate) async fn getgrgid(
-        &mut self,
-        gid: gid_t,
-    ) -> Result<Response, Box<NTSTATUS>> {
-        if let Some(uuid) = self.uid_cache.fetch(gid) {
-            if let Some(entry) = self.group_cache.fetch(&uuid) {
-                return Ok(Response::NssGroup(Some(Group {
-                    name: entry.uuid.clone(),
-                    passwd: "x".to_string(),
-                    gid,
-                    members: entry.members(),
-                })));
-            }
-        }
-        Ok(Response::NssGroup(None))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::cache::GroupEntry;
-    use crate::{GroupCache, PrivateCache, UidCache, UserCache};
-    use idmap::Idmap;
-    use param::LoadParm;
-    use std::collections::HashSet;
-    use tempfile::tempdir;
-
-    #[tokio::test]
-    async fn test_getgrgid() {
-        // Create a temporary directory for the cache
-        let dir = tempdir().unwrap();
-
-        // Initialize the caches
-        let private_cache_path = dir
-            .path()
-            .join("himmelblau.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let pcache = PrivateCache::new(&private_cache_path).unwrap();
-        let user_cache_path = dir
-            .path()
-            .join("himmelblau_users.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let user_cache = UserCache::new(&user_cache_path).unwrap();
-        let uid_cache_path = dir
-            .path()
-            .join("uid_cache.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let mut uid_cache = UidCache::new(&uid_cache_path).unwrap();
-        let group_cache_path = dir
-            .path()
-            .join("himmelblau_groups.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let mut group_cache = GroupCache::new(&group_cache_path).unwrap();
-
-        // Initialize the Idmap with dummy configuration
-        let realm = "test.com";
-        let tenant_id = "89a61bb7-d1b9-4356-a1e0-75d88e06f14e";
-        let mut idmap = Idmap::new().unwrap();
-        idmap
-            .add_gen_domain(realm, tenant_id, (1000, 2000))
-            .unwrap();
-
-        // Insert a dummy GroupEntry into the cache
-        let group_uuid = "c490c3ea-fd98-4d45-b6aa-2a3520f804fa".to_string();
-        let dummy_gid = idmap
-            .gen_to_unix(tenant_id, &group_uuid)
-            .expect("Failed to map group gid");
-        // Store the calculated gid -> uuid map in the cache
-        uid_cache
-            .store(dummy_gid, &group_uuid)
-            .expect("Failed to store group gid");
-        let dummy_group = GroupEntry::new(&group_uuid);
-        group_cache
-            .merge_groups("user1@test.com", vec![dummy_group.clone()])
-            .unwrap();
-
-        // Initialize dummy configuration
-        let lp = LoadParm::new(None).expect("Failed loading default config");
-
-        // Initialize the Resolver
-        let mut resolver = Resolver {
-            realm: realm.to_string(),
-            tenant_id: tenant_id.to_string(),
-            lp,
-            idmap,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-        };
-
-        // Test the getgrgid function with a gid that exists
-        let result = resolver.getgrgid(dummy_gid).await.unwrap();
-
-        match result {
-            Response::NssGroup(Some(group)) => {
-                assert_eq!(group.name, dummy_group.uuid);
-                assert_eq!(group.gid, dummy_gid);
-                assert_eq!(group.members, vec!["user1@test.com".to_string()]);
-            }
-            other => panic!("Expected NssGroup with Some(group): {:?}", other),
-        }
-
-        // Test the getgrgid function with a gid that does not exist
-        let nonexistent_gid: gid_t = 1600;
-        let result = resolver.getgrgid(nonexistent_gid).await.unwrap();
-        match result {
-            Response::NssGroup(None) => {} // This is the expected result
-            _ => panic!("Expected NssGroup with None"),
-        }
-    }
-}
diff --git a/rust/himmelblaud/src/himmelblaud/himmelblaud_getgrnam.rs b/rust/himmelblaud/src/himmelblaud/himmelblaud_getgrnam.rs
deleted file mode 100644 (file)
index 16b1de5..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon implementation for nss getgrnam
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::himmelblaud::Resolver;
-use dbg::DBG_ERR;
-use ntstatus_gen::*;
-use sock::{Group, Response};
-
-impl Resolver {
-    pub(crate) async fn getgrnam(
-        &mut self,
-        grp_id: &str,
-    ) -> Result<Response, Box<NTSTATUS>> {
-        let entry = match self.group_cache.fetch(grp_id) {
-            Some(entry) => entry,
-            None => return Ok(Response::NssGroup(None)),
-        };
-        let gid = self
-            .idmap
-            .gen_to_unix(&self.tenant_id, &entry.uuid)
-            .map_err(|e| {
-                DBG_ERR!("{:?}", e);
-                Box::new(NT_STATUS_INVALID_TOKEN)
-            })?;
-        // Store the calculated gid -> uuid map in the cache
-        self.uid_cache.store(gid, &entry.uuid)?;
-        let group = Group {
-            name: entry.uuid.clone(),
-            passwd: "x".to_string(),
-            gid,
-            members: entry.members(),
-        };
-        return Ok(Response::NssGroup(Some(group)));
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::cache::GroupEntry;
-    use crate::{GroupCache, PrivateCache, UidCache, UserCache};
-    use idmap::Idmap;
-    use param::LoadParm;
-    use std::collections::HashSet;
-    use tempfile::tempdir;
-
-    #[tokio::test]
-    async fn test_getgrnam() {
-        // Create a temporary directory for the cache
-        let dir = tempdir().unwrap();
-
-        // Initialize the caches
-        let private_cache_path = dir
-            .path()
-            .join("himmelblau.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let pcache = PrivateCache::new(&private_cache_path).unwrap();
-        let user_cache_path = dir
-            .path()
-            .join("himmelblau_users.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let user_cache = UserCache::new(&user_cache_path).unwrap();
-        let uid_cache_path = dir
-            .path()
-            .join("uid_cache.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let uid_cache = UidCache::new(&uid_cache_path).unwrap();
-        let group_cache_path = dir
-            .path()
-            .join("himmelblau_groups.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let mut group_cache = GroupCache::new(&group_cache_path).unwrap();
-
-        // Insert a dummy GroupEntry into the cache
-        let group_uuid = "c490c3ea-fd98-4d45-b6aa-2a3520f804fa";
-        let dummy_group = GroupEntry::new(group_uuid);
-        group_cache
-            .merge_groups("user1@test.com", vec![dummy_group.clone()])
-            .unwrap();
-        group_cache
-            .merge_groups("user2@test.com", vec![dummy_group.clone()])
-            .unwrap();
-
-        // Initialize the Idmap with dummy configuration
-        let realm = "test.com";
-        let tenant_id = "89a61bb7-d1b9-4356-a1e0-75d88e06f14e";
-        let mut idmap = Idmap::new().unwrap();
-        idmap
-            .add_gen_domain(realm, tenant_id, (1000, 2000))
-            .unwrap();
-
-        // Initialize dummy configuration
-        let lp = LoadParm::new(None).expect("Failed loading default config");
-
-        // Initialize the Resolver
-        let mut resolver = Resolver {
-            realm: realm.to_string(),
-            tenant_id: tenant_id.to_string(),
-            lp,
-            idmap,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-        };
-
-        // Test the getgrnam function with a group that exists
-        let result = resolver.getgrnam(group_uuid).await.unwrap();
-
-        match result {
-            Response::NssGroup(Some(mut group)) => {
-                group.members.sort();
-                assert_eq!(group.name, dummy_group.uuid);
-                assert_eq!(group.gid, 1388);
-                assert_eq!(
-                    group.members,
-                    vec![
-                        "user1@test.com".to_string(),
-                        "user2@test.com".to_string()
-                    ]
-                );
-            }
-            other => panic!("Expected NssGroup with Some(group): {:?}", other),
-        }
-
-        // Test the getgrnam function with a group that does not exist
-        let nonexistent_group_uuid = "2ea8f1d4-1b94-4003-865b-cb247a8a1f5d";
-        let result = resolver.getgrnam(nonexistent_group_uuid).await.unwrap();
-        match result {
-            Response::NssGroup(None) => {} // This is the expected result
-            _ => panic!("Expected NssGroup with None"),
-        }
-    }
-}
diff --git a/rust/himmelblaud/src/himmelblaud/himmelblaud_getpwent.rs b/rust/himmelblaud/src/himmelblaud/himmelblaud_getpwent.rs
deleted file mode 100644 (file)
index e8f7d94..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon implementation for nss getpwent
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::himmelblaud::Resolver;
-use crate::utils::split_username;
-use dbg::DBG_ERR;
-use ntstatus_gen::*;
-use sock::{Passwd, Response};
-
-impl Resolver {
-    pub(crate) async fn getpwent(&mut self) -> Result<Response, Box<NTSTATUS>> {
-        let user_entries = self.user_cache.fetch_all()?;
-        let template_homedir = self
-            .lp
-            .template_homedir()
-            .map_err(|e| {
-                DBG_ERR!("{:?}", e);
-                Box::new(NT_STATUS_NOT_A_DIRECTORY)
-            })?
-            .ok_or_else(|| {
-                DBG_ERR!("Failed to discover template homedir. Is it set?");
-                Box::new(NT_STATUS_NOT_A_DIRECTORY)
-            })?;
-        let shell = self
-            .lp
-            .template_shell()
-            .map_err(|e| {
-                DBG_ERR!("{:?}", e);
-                Box::new(NT_STATUS_NOT_A_DIRECTORY)
-            })?
-            .ok_or_else(|| {
-                DBG_ERR!("Failed to discover template shell. Is it set?");
-                Box::new(NT_STATUS_NOT_A_DIRECTORY)
-            })?;
-        let mut res = Vec::new();
-        for entry in user_entries {
-            let uid = self
-                .idmap
-                .gen_to_unix(&self.tenant_id, &entry.upn)
-                .map_err(|e| {
-                    DBG_ERR!("{:?}", e);
-                    Box::new(NT_STATUS_INVALID_TOKEN)
-                })?;
-            let upn = entry.upn.clone();
-            let (cn, domain) = match split_username(&upn) {
-                Ok(res) => res,
-                Err(e) => {
-                    DBG_ERR!(
-                        "Failed to parse user upn '{}': {:?}",
-                        &entry.upn,
-                        e
-                    );
-                    return Err(Box::new(
-                        NT_STATUS_INVALID_USER_PRINCIPAL_NAME,
-                    ));
-                }
-            };
-            let homedir = template_homedir
-                .clone()
-                .replace("%D", &domain)
-                .replace("%U", &cn);
-            let passwd = Passwd {
-                name: entry.upn.clone(),
-                passwd: "x".to_string(),
-                uid,
-                gid: uid,
-                gecos: entry.name,
-                dir: homedir,
-                shell: shell.clone(),
-            };
-            res.push(passwd);
-        }
-        Ok(Response::NssAccounts(res))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::cache::UserEntry;
-    use crate::{GroupCache, PrivateCache, UidCache, UserCache};
-    use idmap::Idmap;
-    use param::LoadParm;
-    use std::collections::HashSet;
-    use tempfile::tempdir;
-
-    #[tokio::test]
-    async fn test_getpwent() {
-        // Create a temporary directory for the cache
-        let dir = tempdir().unwrap();
-
-        // Initialize the caches
-        let private_cache_path = dir
-            .path()
-            .join("himmelblau.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let pcache = PrivateCache::new(&private_cache_path).unwrap();
-        let user_cache_path = dir
-            .path()
-            .join("himmelblau_users.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let mut user_cache = UserCache::new(&user_cache_path).unwrap();
-        let uid_cache_path = dir
-            .path()
-            .join("uid_cache.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let uid_cache = UidCache::new(&uid_cache_path).unwrap();
-        let group_cache_path = dir
-            .path()
-            .join("himmelblau_groups.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let group_cache = GroupCache::new(&group_cache_path).unwrap();
-
-        // Insert dummy UserEntrys into the cache
-        let dummy_user = UserEntry {
-            upn: "user1@test.com".to_string(),
-            uuid: "731e9af3-668d-4033-afd1-9f09b9120cc7".to_string(),
-            name: "User One".to_string(),
-        };
-        user_cache
-            .store(dummy_user.clone())
-            .expect("Failed storing user in cache");
-
-        let dummy_user2 = UserEntry {
-            upn: "user2@test.com".to_string(),
-            uuid: "7be6c0c5-5763-4633-aecf-f8c460b338fd".to_string(),
-            name: "User Two".to_string(),
-        };
-        user_cache
-            .store(dummy_user2.clone())
-            .expect("Failed storing user in cache");
-
-        // Initialize the Idmap with dummy configuration
-        let realm = "test.com";
-        let tenant_id = "89a61bb7-d1b9-4356-a1e0-75d88e06f14e";
-        let mut idmap = Idmap::new().unwrap();
-        idmap
-            .add_gen_domain(realm, tenant_id, (1000, 2000))
-            .unwrap();
-
-        // Initialize dummy configuration for LoadParm
-        let lp = LoadParm::new(None).expect("Failed loading default config");
-
-        // Initialize the Resolver
-        let mut resolver = Resolver {
-            realm: realm.to_string(),
-            tenant_id: tenant_id.to_string(),
-            lp,
-            idmap,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-        };
-
-        // Test the getpwent function
-        let result = resolver.getpwent().await.unwrap();
-
-        match result {
-            Response::NssAccounts(accounts) => {
-                assert_eq!(accounts.len(), 2);
-
-                let account1 = &accounts[0];
-                assert_eq!(account1.name, dummy_user.upn);
-                assert_eq!(account1.uid, 1316);
-                assert_eq!(account1.gid, 1316);
-                assert_eq!(account1.gecos, dummy_user.name);
-                assert_eq!(account1.dir, "/home/test.com/user1");
-                assert_eq!(account1.shell, "/bin/false");
-
-                let account2 = &accounts[1];
-                assert_eq!(account2.name, dummy_user2.upn);
-                assert_eq!(account2.uid, 1671);
-                assert_eq!(account2.gid, 1671);
-                assert_eq!(account2.gecos, dummy_user2.name);
-                assert_eq!(account2.dir, "/home/test.com/user2");
-                assert_eq!(account2.shell, "/bin/false");
-            }
-            other => panic!(
-                "Expected NssAccounts with a list of accounts: {:?}",
-                other
-            ),
-        }
-    }
-}
diff --git a/rust/himmelblaud/src/himmelblaud/himmelblaud_getpwnam.rs b/rust/himmelblaud/src/himmelblaud/himmelblaud_getpwnam.rs
deleted file mode 100644 (file)
index 40a7bff..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon implementation for nss getpwnam
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::cache::GroupEntry;
-use crate::himmelblaud::Resolver;
-use crate::utils::split_username;
-use dbg::{DBG_ERR, DBG_WARNING};
-use ntstatus_gen::*;
-use sock::{Passwd, Response};
-
-impl Resolver {
-    pub(crate) fn create_passwd_from_upn(
-        &mut self,
-        upn: &str,
-        gecos: &str,
-    ) -> Result<Passwd, Box<NTSTATUS>> {
-        let template_homedir = self
-            .lp
-            .template_homedir()
-            .map_err(|e| {
-                DBG_ERR!("{:?}", e);
-                Box::new(NT_STATUS_NOT_A_DIRECTORY)
-            })?
-            .ok_or_else(|| {
-                DBG_ERR!("Failed to discover template homedir. Is it set?");
-                Box::new(NT_STATUS_NOT_A_DIRECTORY)
-            })?;
-        let shell = self
-            .lp
-            .template_shell()
-            .map_err(|e| {
-                DBG_ERR!("{:?}", e);
-                Box::new(NT_STATUS_NOT_A_DIRECTORY)
-            })?
-            .ok_or_else(|| {
-                DBG_ERR!("Failed to discover template shell. Is it set?");
-                Box::new(NT_STATUS_NOT_A_DIRECTORY)
-            })?;
-        let uid =
-            self.idmap.gen_to_unix(&self.tenant_id, &upn).map_err(|e| {
-                DBG_ERR!("{:?}", e);
-                Box::new(NT_STATUS_INVALID_TOKEN)
-            })?;
-        // Store the calculated uid -> upn map in the cache
-        self.uid_cache.store(uid, &upn)?;
-        // Store the primary group (which is a fake group matching the user upn)
-        let mut group = GroupEntry::new(upn);
-        group.add_member(upn);
-        self.group_cache.merge_groups(upn, vec![group])?;
-        let (cn, domain) = match split_username(&upn) {
-            Ok(res) => res,
-            Err(e) => {
-                DBG_ERR!("Failed to parse user upn '{}': {:?}", upn, e);
-                return Err(Box::new(NT_STATUS_INVALID_USER_PRINCIPAL_NAME));
-            }
-        };
-        let homedir = template_homedir
-            .clone()
-            .replace("%D", &domain)
-            .replace("%U", &cn);
-        let passwd = Passwd {
-            name: upn.to_string(),
-            passwd: "x".to_string(),
-            uid,
-            gid: uid,
-            gecos: gecos.to_string(),
-            dir: homedir,
-            shell: shell.clone(),
-        };
-        return Ok(passwd);
-    }
-
-    pub(crate) async fn getpwnam(
-        &mut self,
-        account_id: &str,
-    ) -> Result<Response, Box<NTSTATUS>> {
-        // We first try to fetch the user from the cache, so that we
-        // get the gecos. Otherwise we can just create a passwd entry
-        // based on whether the upn exists in Entra ID.
-        let entry = match self.user_cache.fetch(account_id) {
-            Some(entry) => entry,
-            #[cfg(not(test))]
-            None => {
-                // Check if the user exists in Entra ID
-                let exists = match self
-                    .client
-                    .lock()
-                    .await
-                    .check_user_exists(&account_id)
-                    .await
-                {
-                    Ok(exists) => exists,
-                    Err(e) => {
-                        DBG_WARNING!("{:?}", e);
-                        return Ok(Response::NssAccount(None));
-                    }
-                };
-                if exists {
-                    return Ok(Response::NssAccount(Some(
-                        self.create_passwd_from_upn(account_id, "")?,
-                    )));
-                }
-                return Ok(Response::NssAccount(None));
-            }
-            #[cfg(test)]
-            None => return Ok(Response::NssAccount(None)),
-        };
-        return Ok(Response::NssAccount(Some(
-            self.create_passwd_from_upn(&entry.upn, &entry.name)?,
-        )));
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::cache::UserEntry;
-    use crate::{GroupCache, PrivateCache, UidCache, UserCache};
-    use idmap::Idmap;
-    use param::LoadParm;
-    use tempfile::tempdir;
-
-    #[tokio::test]
-    async fn test_getpwnam() {
-        // Create a temporary directory for the cache
-        let dir = tempdir().unwrap();
-
-        // Initialize the caches
-        let private_cache_path = dir
-            .path()
-            .join("himmelblau.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let pcache = PrivateCache::new(&private_cache_path).unwrap();
-        let user_cache_path = dir
-            .path()
-            .join("himmelblau_users.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let mut user_cache = UserCache::new(&user_cache_path).unwrap();
-        let uid_cache_path = dir
-            .path()
-            .join("uid_cache.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let uid_cache = UidCache::new(&uid_cache_path).unwrap();
-        let group_cache_path = dir
-            .path()
-            .join("himmelblau_groups.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let group_cache = GroupCache::new(&group_cache_path).unwrap();
-
-        // Insert a dummy UserEntry into the cache
-        let dummy_user = UserEntry {
-            upn: "user1@test.com".to_string(),
-            uuid: "731e9af3-668d-4033-afd1-9f09b9120cc7".to_string(),
-            name: "User One".to_string(),
-        };
-        let _ = user_cache.store(dummy_user.clone());
-
-        // Initialize the Idmap with dummy configuration
-        let realm = "test.com";
-        let tenant_id = "89a61bb7-d1b9-4356-a1e0-75d88e06f14e";
-        let mut idmap = Idmap::new().unwrap();
-        idmap
-            .add_gen_domain(realm, tenant_id, (1000, 2000))
-            .unwrap();
-
-        // Initialize dummy configuration for LoadParm
-        let lp = LoadParm::new(None).expect("Failed loading default config");
-
-        // Initialize the Resolver
-        let mut resolver = Resolver {
-            realm: realm.to_string(),
-            tenant_id: tenant_id.to_string(),
-            lp,
-            idmap,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-        };
-
-        // Test the getpwnam function with a user that exists in the cache
-        let result = resolver.getpwnam(&dummy_user.upn).await.unwrap();
-
-        match result {
-            Response::NssAccount(Some(account)) => {
-                assert_eq!(account.name, dummy_user.upn);
-                assert_eq!(account.uid, 1316);
-                assert_eq!(account.gid, 1316);
-                assert_eq!(account.gecos, dummy_user.name);
-                assert_eq!(account.dir, "/home/test.com/user1");
-                assert_eq!(account.shell, "/bin/false");
-            }
-            other => {
-                panic!("Expected NssAccount with Some(account): {:?}", other)
-            }
-        }
-
-        // Test the getpwnam function with a user that does not exist in the cache
-        let nonexistent_user_upn = "nonexistent@test.com";
-        let result = resolver.getpwnam(nonexistent_user_upn).await.unwrap();
-
-        match result {
-            Response::NssAccount(None) => {} // This is the expected result
-            other => panic!("Expected NssAccount with None: {:?}", other),
-        }
-    }
-}
diff --git a/rust/himmelblaud/src/himmelblaud/himmelblaud_getpwuid.rs b/rust/himmelblaud/src/himmelblaud/himmelblaud_getpwuid.rs
deleted file mode 100644 (file)
index f93f55c..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon implementation for nss getpwuid
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::himmelblaud::Resolver;
-use libc::uid_t;
-use ntstatus_gen::NTSTATUS;
-use sock::Response;
-
-impl Resolver {
-    pub(crate) async fn getpwuid(
-        &mut self,
-        uid: uid_t,
-    ) -> Result<Response, Box<NTSTATUS>> {
-        if let Some(upn) = self.uid_cache.fetch(uid) {
-            if let Some(entry) = self.user_cache.fetch(&upn) {
-                Ok(Response::NssAccount(Some(
-                    self.create_passwd_from_upn(&entry.upn, &entry.name)?,
-                )))
-            } else {
-                Ok(Response::NssAccount(Some(
-                    self.create_passwd_from_upn(&upn, "")?,
-                )))
-            }
-        } else {
-            Ok(Response::NssAccount(None))
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::cache::UserEntry;
-    use crate::{GroupCache, PrivateCache, UidCache, UserCache};
-    use idmap::Idmap;
-    use param::LoadParm;
-    use tempfile::tempdir;
-
-    #[tokio::test]
-    async fn test_getpwuid() {
-        // Create a temporary directory for the cache
-        let dir = tempdir().unwrap();
-
-        // Initialize the caches
-        let private_cache_path = dir
-            .path()
-            .join("himmelblau.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let pcache = PrivateCache::new(&private_cache_path).unwrap();
-        let user_cache_path = dir
-            .path()
-            .join("himmelblau_users.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let mut user_cache = UserCache::new(&user_cache_path).unwrap();
-        let uid_cache_path = dir
-            .path()
-            .join("uid_cache.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let mut uid_cache = UidCache::new(&uid_cache_path).unwrap();
-        let group_cache_path = dir
-            .path()
-            .join("himmelblau_groups.tdb")
-            .to_str()
-            .unwrap()
-            .to_string();
-        let group_cache = GroupCache::new(&group_cache_path).unwrap();
-
-        // Insert a dummy UserEntry into the cache
-        let dummy_user = UserEntry {
-            upn: "user1@test.com".to_string(),
-            uuid: "731e9af3-668d-4033-afd1-9f09b9120cc7".to_string(),
-            name: "User One".to_string(),
-        };
-        let _ = user_cache.store(dummy_user.clone());
-
-        // Initialize the Idmap with dummy configuration
-        let realm = "test.com";
-        let tenant_id = "89a61bb7-d1b9-4356-a1e0-75d88e06f14e";
-        let mut idmap = Idmap::new().unwrap();
-        idmap
-            .add_gen_domain(realm, tenant_id, (1000, 2000))
-            .unwrap();
-
-        let uid = idmap
-            .gen_to_unix(tenant_id, &dummy_user.upn)
-            .expect("Failed to generate uid for user");
-        // Store the calculated uid -> upn map in the cache
-        uid_cache
-            .store(uid, &dummy_user.upn)
-            .expect("Failed storing generated uid in the cache");
-
-        // Initialize dummy configuration for LoadParm
-        let lp = LoadParm::new(None).expect("Failed loading default config");
-
-        // Initialize the Resolver
-        let mut resolver = Resolver {
-            realm: realm.to_string(),
-            tenant_id: tenant_id.to_string(),
-            lp,
-            idmap,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-        };
-
-        // Test the getpwuid function with a uid that exists in the cache
-        let result = resolver.getpwuid(uid).await.unwrap();
-
-        match result {
-            Response::NssAccount(Some(account)) => {
-                assert_eq!(account.name, dummy_user.upn);
-                assert_eq!(account.uid, uid);
-                assert_eq!(account.gid, uid);
-                assert_eq!(account.gecos, dummy_user.name);
-                assert_eq!(account.dir, "/home/test.com/user1");
-                assert_eq!(account.shell, "/bin/false");
-            }
-            other => {
-                panic!("Expected NssAccount with Some(account): {:?}", other)
-            }
-        }
-
-        // Test the getpwuid function with a uid that does not exist in the cache
-        let nonexistent_uid = 9999;
-        let result = resolver.getpwuid(nonexistent_uid).await.unwrap();
-
-        match result {
-            Response::NssAccount(None) => {} // This is the expected result
-            other => panic!("Expected NssAccount with None: {:?}", other),
-        }
-    }
-}
diff --git a/rust/himmelblaud/src/himmelblaud/himmelblaud_pam_acct_mgmt.rs b/rust/himmelblaud/src/himmelblaud/himmelblaud_pam_acct_mgmt.rs
deleted file mode 100644 (file)
index 98209ee..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon implementation for pam_acct_mgmt
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::himmelblaud::Resolver;
-use dbg::DBG_WARNING;
-use ntstatus_gen::*;
-use sock::Response;
-
-impl Resolver {
-    pub(crate) async fn pam_acct_mgmt(
-        &self,
-        account_id: &str,
-    ) -> Result<Response, Box<NTSTATUS>> {
-        // Check if the user exists in Entra ID
-        // TODO: If we're offline, check the cache instead
-        match self
-            .client
-            .lock()
-            .await
-            .check_user_exists(&account_id)
-            .await
-        {
-            Ok(exists) => Ok(Response::PamStatus(Some(exists))),
-            Err(e) => {
-                DBG_WARNING!("{:?}", e);
-                Ok(Response::PamStatus(None))
-            }
-        }
-    }
-}
diff --git a/rust/himmelblaud/src/himmelblaud/himmelblaud_pam_auth.rs b/rust/himmelblaud/src/himmelblaud/himmelblaud_pam_auth.rs
deleted file mode 100644 (file)
index c1cd64f..0000000
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon implementation for PAM_AUTH
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use crate::cache::{GroupEntry, UserEntry};
-use crate::himmelblaud::Resolver;
-use dbg::{DBG_DEBUG, DBG_ERR, DBG_INFO, DBG_WARNING};
-use himmelblau::error::{
-    MsalError, AUTH_PENDING, DEVICE_AUTH_FAIL, REQUIRES_MFA,
-};
-use himmelblau::{
-    DeviceAuthorizationResponse, EnrollAttrs, MFAAuthContinue,
-    UserToken as UnixUserToken,
-};
-use ntstatus_gen::*;
-use serde::{Deserialize, Serialize};
-use sock::{PamAuthRequest, PamAuthResponse, Response};
-use std::env;
-use std::thread::sleep;
-use std::time::Duration;
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct GroupToken {
-    pub name: String,
-    pub spn: String,
-    pub object_id: String,
-    pub gidnumber: u32,
-}
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct UserToken {
-    pub name: String,
-    pub spn: String,
-    pub object_id: String,
-    pub gidnumber: u32,
-    pub displayname: String,
-    pub shell: Option<String>,
-    pub groups: Vec<GroupToken>,
-}
-
-pub(crate) enum AuthCredHandler {
-    MFA { flow: MFAAuthContinue },
-    DeviceAuthorizationGrant { flow: DeviceAuthorizationResponse },
-    SetupPin { token: UnixUserToken },
-    None,
-}
-
-pub(crate) enum AuthSession {
-    InProgress {
-        account_id: String,
-        cred_handler: AuthCredHandler,
-    },
-    Success,
-    Denied,
-}
-
-impl Resolver {
-    pub(crate) fn pam_auth_init(
-        &mut self,
-        account_id: &str,
-    ) -> Result<(AuthSession, Response), Box<NTSTATUS>> {
-        let auth_session = AuthSession::InProgress {
-            account_id: account_id.to_string(),
-            cred_handler: AuthCredHandler::None,
-        };
-        let hello_key = self.pcache.loadable_hello_key_fetch(account_id);
-        // Skip Hello authentication if it is disabled by config
-        let hello_enabled =
-            self.lp.himmelblaud_hello_enabled().map_err(|e| {
-                DBG_ERR!("{:?}", e);
-                Box::new(NT_STATUS_LOGON_FAILURE)
-            })?;
-        if !self.is_domain_joined() || hello_key.is_none() || !hello_enabled {
-            // Send a password request to the client
-            Ok((
-                auth_session,
-                Response::PamAuthStepResponse(PamAuthResponse::Password),
-            ))
-        } else {
-            // Send a pin request to the client
-            Ok((
-                auth_session,
-                Response::PamAuthStepResponse(PamAuthResponse::Pin),
-            ))
-        }
-    }
-
-    pub(crate) async fn pam_auth_step(
-        &mut self,
-        account_id: &str,
-        cred_handler: &mut AuthCredHandler,
-        pam_next_req: PamAuthRequest,
-    ) -> Result<Response, Box<NTSTATUS>> {
-        macro_rules! enroll_and_obtain_enrolled_token {
-            ($token:ident) => {{
-                if !self.is_domain_joined() {
-                    DBG_DEBUG!("Device is not enrolled. Enrolling now.");
-                    self.join_domain(&$token)
-                        .await
-                        .map_err(|e| {
-                            DBG_ERR!("Failed to join domain: {:?}", e);
-                            Box::new(NT_STATUS_LOGON_FAILURE)
-                        })?;
-                }
-                let mut tpm = self.hsm.lock().await;
-                let mtoken2 = self
-                    .client
-                    .lock()
-                    .await
-                    .acquire_token_by_refresh_token(
-                        &$token.refresh_token,
-                        vec!["User.Read"],
-                        Some("https://graph.microsoft.com".to_string()),
-                        &mut tpm,
-                        &self.machine_key,
-                    )
-                    .await;
-                match mtoken2 {
-                    Ok(token) => token,
-                    Err(e) => {
-                        DBG_ERR!("{:?}", e);
-                        match e {
-                            MsalError::AcquireTokenFailed(err_resp) => {
-                                if err_resp.error_codes.contains(&DEVICE_AUTH_FAIL) {
-                                    /* A device authentication failure may happen
-                                     * if Azure hasn't finished replicating the new
-                                     * device object. Wait 5 seconds and try again. */
-                                    DBG_INFO!("Azure hasn't finished replicating the device...");
-                                    DBG_INFO!("Retrying in 5 seconds");
-                                    sleep(Duration::from_secs(5));
-                                    self.client
-                                        .lock()
-                                        .await
-                                        .acquire_token_by_refresh_token(
-                                            &$token.refresh_token,
-                                            vec!["User.Read"],
-                                            Some("https://graph.microsoft.com".to_string()),
-                                            &mut tpm,
-                                            &self.machine_key,
-                                        )
-                                        .await
-                                        .map_err(|e| {
-                                            DBG_ERR!("{:?}", e);
-                                            Box::new(NT_STATUS_NOT_FOUND)
-                                        })?
-                                } else {
-                                    return Err(Box::new(NT_STATUS_NOT_FOUND));
-                                }
-                            }
-                            _ => return Err(Box::new(NT_STATUS_NOT_FOUND)),
-                        }
-                    }
-                }
-            }};
-        }
-        macro_rules! auth_and_validate_hello_key {
-            ($hello_key:ident, $cred:ident) => {{
-                let token = {
-                    let mut tpm = self.hsm.lock().await;
-                    self
-                        .client
-                        .lock()
-                        .await
-                        .acquire_token_by_hello_for_business_key(
-                            account_id,
-                            &$hello_key,
-                            vec!["User.Read"],
-                            Some("https://graph.microsoft.com".to_string()),
-                            &mut tpm,
-                            &self.machine_key,
-                            &$cred,
-                        )
-                        .await
-                        .map_err(|e| {
-                            DBG_ERR!(
-                                "Failed to authenticate with hello key: {:?}",
-                                e
-                            );
-                            Box::new(NT_STATUS_LOGON_FAILURE)
-                        })?
-                    };
-
-                self.token_validate(account_id, &token).await
-            }};
-        }
-        match (&mut *cred_handler, pam_next_req) {
-            (
-                AuthCredHandler::SetupPin { token },
-                PamAuthRequest::SetupPin { pin },
-            ) => {
-                let hello_key = {
-                    let mut tpm = self.hsm.lock().await;
-                    match self
-                        .client
-                        .lock()
-                        .await
-                        .provision_hello_for_business_key(
-                            &token,
-                            &mut tpm,
-                            &self.machine_key,
-                            &pin,
-                        )
-                        .await
-                    {
-                        Ok(hello_key) => hello_key,
-                        Err(e) => {
-                            return Ok(Response::PamAuthStepResponse(
-                                PamAuthResponse::SetupPin {
-                                    msg: format!(
-                                        "Failed to provision hello key: {:?}\n{}",
-                                        e,
-                                        "Create a PIN to use in place of passwords."
-                                    ),
-                                }
-                            ));
-                        }
-                    }
-                };
-                self.pcache
-                    .loadable_hello_key_store(account_id, hello_key.clone())
-                    .map_err(|e| {
-                        DBG_ERR!("Failed to provision hello key: {:?}", e);
-                        Box::new(NT_STATUS_LOGON_FAILURE)
-                    })?;
-
-                auth_and_validate_hello_key!(hello_key, pin)
-            }
-            (_, PamAuthRequest::Pin { pin }) => {
-                let hello_key = self
-                    .pcache
-                    .loadable_hello_key_fetch(account_id)
-                    .ok_or_else(|| {
-                        DBG_ERR!("Authentication failed. Hello key missing.");
-                        Box::new(NT_STATUS_LOGON_FAILURE)
-                    })?;
-
-                auth_and_validate_hello_key!(hello_key, pin)
-            }
-            (_, PamAuthRequest::Password { cred }) => {
-                // Always attempt to force MFA when enrolling the device, otherwise
-                // the device object will not have the MFA claim. If we are already
-                // enrolled but creating a new Hello Pin, we follow the same process,
-                // since only an enrollment token can be exchanged for a PRT (which
-                // will be needed to enroll the Hello Pin).
-                let mresp = self
-                    .client
-                    .lock()
-                    .await
-                    .initiate_acquire_token_by_mfa_flow_for_device_enrollment(
-                        account_id, &cred,
-                    )
-                    .await;
-                // We need to wait to handle the response until after we've released
-                // the lock on the client, otherwise we will deadlock.
-                let resp = match mresp {
-                    Ok(resp) => resp,
-                    Err(e) => {
-                        // If SFA is disabled, we need to skip the SFA fallback.
-                        let sfa_enabled = self
-                            .lp
-                            .himmelblaud_sfa_fallback()
-                            .map_err(|e| {
-                                DBG_ERR!("{:?}", e);
-                                Box::new(NT_STATUS_LOGON_FAILURE)
-                            })?;
-                        macro_rules! init_dag {
-                            ($msg:expr) => {{
-                                DBG_WARNING!(
-                                    "SFA auth failed, falling back to DAG: {}",
-                                    $msg
-                                );
-                                // We've exhausted alternatives, and must perform a DAG
-                                let resp = self
-                                    .client
-                                    .lock()
-                                    .await
-                                    .initiate_device_flow_for_device_enrollment()
-                                    .await
-                                    .map_err(|e| {
-                                        DBG_ERR!("{:?}", e);
-                                        Box::new(NT_STATUS_LOGON_FAILURE)
-                                    })?;
-                                let msg = match &resp.message {
-                                    Some(msg) => msg.to_string(),
-                                    None => format!("Using a browser on another \
-                                        device, visit:\n{}\nAnd enter the code:\n{}",
-                                        resp.verification_uri, resp.user_code),
-                                };
-                                let polling_interval = match resp.interval {
-                                    Some(polling_interval) => polling_interval,
-                                    None => 5,
-                                };
-                                *cred_handler = AuthCredHandler::DeviceAuthorizationGrant {
-                                    flow: resp,
-                                };
-                                return Ok(Response::PamAuthStepResponse(
-                                    PamAuthResponse::MFAPoll {
-                                        msg,
-                                        polling_interval,
-                                    }
-                                ));
-                            }}
-                        }
-                        let token = if sfa_enabled {
-                            DBG_WARNING!(
-                                "MFA auth failed, falling back to SFA: {:?}",
-                                e
-                            );
-                            // Again, we need to wait to handle the response until after
-                            // we've released the write lock on the client, otherwise we
-                            // will deadlock.
-                            match self
-                                .client
-                                .lock()
-                                .await
-                                .acquire_token_by_username_password_for_device_enrollment(
-                                    account_id, &cred,
-                                )
-                                .await
-                            {
-                                Ok(token) => token,
-                                Err(e) => {
-                                    DBG_ERR!("{:?}", e);
-                                    match e {
-                                        MsalError::AcquireTokenFailed(
-                                            err_resp,
-                                        ) => {
-                                            if err_resp
-                                                .error_codes
-                                                .contains(&REQUIRES_MFA)
-                                            {
-                                                init_dag!(
-                                                    err_resp.error_description
-                                                );
-                                            }
-                                            return Err(Box::new(
-                                                NT_STATUS_LOGON_FAILURE,
-                                            ));
-                                        }
-                                        _ => {
-                                            return Err(Box::new(
-                                                NT_STATUS_LOGON_FAILURE,
-                                            ))
-                                        }
-                                    }
-                                }
-                            }
-                        } else {
-                            init_dag!(
-                                "SFA fallback is disabled by configuration"
-                            )
-                        };
-                        let token2 = enroll_and_obtain_enrolled_token!(token);
-                        return self.token_validate(account_id, &token2).await;
-                    }
-                };
-                match resp.mfa_method.as_str() {
-                    "PhoneAppOTP" | "OneWaySMS" | "ConsolidatedTelephony" => {
-                        let msg = resp.msg.clone();
-                        *cred_handler = AuthCredHandler::MFA { flow: resp };
-                        return Ok(Response::PamAuthStepResponse(
-                            PamAuthResponse::MFACode { msg },
-                        ));
-                    }
-                    _ => {
-                        let msg = resp.msg.clone();
-                        let polling_interval =
-                            resp.polling_interval.ok_or_else(|| {
-                                DBG_ERR!("Invalid response from the server");
-                                Box::new(NT_STATUS_LOGON_FAILURE)
-                            })?;
-                        *cred_handler = AuthCredHandler::MFA { flow: resp };
-                        return Ok(Response::PamAuthStepResponse(
-                            PamAuthResponse::MFAPoll {
-                                msg,
-                                // pam expects a polling_interval in
-                                // seconds, not milliseconds.
-                                polling_interval: polling_interval / 1000,
-                            },
-                        ));
-                    }
-                }
-            }
-            (
-                AuthCredHandler::DeviceAuthorizationGrant { flow },
-                PamAuthRequest::MFAPoll { .. },
-            ) => {
-                let token = match self
-                    .client
-                    .lock()
-                    .await
-                    .acquire_token_by_device_flow(flow.clone())
-                    .await
-                {
-                    Err(MsalError::AcquireTokenFailed(ref resp)) => {
-                        if resp.error_codes.contains(&AUTH_PENDING) {
-                            DBG_DEBUG!(
-                                "Polling for acquire_token_by_device_flow"
-                            );
-                            return Ok(Response::PamAuthStepResponse(
-                                PamAuthResponse::MFAPollWait,
-                            ));
-                        } else {
-                            DBG_ERR!("{}", resp.error_description);
-                            return Err(Box::new(NT_STATUS_LOGON_FAILURE));
-                        }
-                    }
-                    Err(e) => {
-                        DBG_ERR!("{:?}", e);
-                        return Err(Box::new(NT_STATUS_LOGON_FAILURE));
-                    }
-                    Ok(token) => token,
-                };
-                let token2 = enroll_and_obtain_enrolled_token!(token);
-                match self.token_validate(account_id, &token2).await {
-                    Ok(Response::PamAuthStepResponse(
-                        PamAuthResponse::Success,
-                    )) => {
-                        let mfa = token2.amr_mfa().map_err(|e| {
-                            DBG_ERR!("{:?}", e);
-                            Box::new(NT_STATUS_NOT_FOUND)
-                        })?;
-                        // If the DAG didn't obtain an MFA amr, and SFA fallback
-                        // is disabled, we need to reject the authentication
-                        // attempt here.
-                        let sfa_enabled = self
-                            .lp
-                            .himmelblaud_sfa_fallback()
-                            .map_err(|e| {
-                                DBG_ERR!("{:?}", e);
-                                Box::new(NT_STATUS_LOGON_FAILURE)
-                            })?;
-                        if !mfa && !sfa_enabled {
-                            DBG_INFO!(
-                                "A DAG produced an SFA token, yet SFA \
-                                fallback is disabled by configuration"
-                            );
-                            return Ok(Response::PamAuthStepResponse(
-                                PamAuthResponse::Denied,
-                            ));
-                        }
-                        // STOP! If the DAG doesn't hold an MFA amr, then we
-                        // need to bail out here and refuse Hello enrollment
-                        // (we can't enroll in Hello with an SFA token).
-                        // Also skip Hello enrollment if it is disabled by config
-                        let hello_enabled = self
-                            .lp
-                            .himmelblaud_hello_enabled()
-                            .map_err(|e| {
-                                DBG_ERR!("{:?}", e);
-                                Box::new(NT_STATUS_LOGON_FAILURE)
-                            })?;
-                        if !mfa || !hello_enabled {
-                            if !mfa {
-                                DBG_INFO!(
-                                    "Skipping Hello enrollment because \
-                                    the token doesn't contain an MFA amr"
-                                );
-                            } else if !hello_enabled {
-                                DBG_INFO!(
-                                    "Skipping Hello enrollment \
-                                    because it is disabled"
-                                );
-                            }
-                            return Ok(Response::PamAuthStepResponse(
-                                PamAuthResponse::Success,
-                            ));
-                        }
-
-                        // Setup Windows Hello
-                        *cred_handler = AuthCredHandler::SetupPin { token };
-                        return Ok(Response::PamAuthStepResponse(
-                            PamAuthResponse::SetupPin {
-                                msg: format!(
-                                    "Set up a PIN\n {}{}",
-                                    "A Hello PIN is a fast, secure way to sign",
-                                    "in to your device, apps, and services."
-                                ),
-                            },
-                        ));
-                    }
-                    Ok(auth_result) => Ok(auth_result),
-                    Err(e) => Err(e),
-                }
-            }
-            (
-                AuthCredHandler::MFA { ref mut flow },
-                PamAuthRequest::MFACode { cred },
-            ) => {
-                let token = self
-                    .client
-                    .lock()
-                    .await
-                    .acquire_token_by_mfa_flow(
-                        account_id,
-                        Some(&cred),
-                        None,
-                        flow,
-                    )
-                    .await
-                    .map_err(|e| {
-                        DBG_ERR!("{:?}", e);
-                        Box::new(NT_STATUS_NOT_FOUND)
-                    })?;
-                let token2 = enroll_and_obtain_enrolled_token!(token);
-                match self.token_validate(account_id, &token2).await {
-                    Ok(Response::PamAuthStepResponse(
-                        PamAuthResponse::Success,
-                    )) => {
-                        // Skip Hello enrollment if it is disabled by config
-                        let hello_enabled = self
-                            .lp
-                            .himmelblaud_hello_enabled()
-                            .map_err(|e| {
-                                DBG_ERR!("{:?}", e);
-                                Box::new(NT_STATUS_LOGON_FAILURE)
-                            })?;
-                        if !hello_enabled {
-                            DBG_INFO!("Skipping Hello enrollment because it is disabled");
-                            return Ok(Response::PamAuthStepResponse(
-                                PamAuthResponse::Success,
-                            ));
-                        }
-
-                        // Setup Windows Hello
-                        *cred_handler = AuthCredHandler::SetupPin { token };
-                        return Ok(Response::PamAuthStepResponse(
-                            PamAuthResponse::SetupPin {
-                                msg: format!(
-                                    "Set up a PIN\n {}{}",
-                                    "A Hello PIN is a fast, secure way to sign",
-                                    "in to your device, apps, and services."
-                                ),
-                            },
-                        ));
-                    }
-                    Ok(auth_result) => Ok(auth_result),
-                    Err(e) => Err(e),
-                }
-            }
-            (
-                AuthCredHandler::MFA { flow },
-                PamAuthRequest::MFAPoll { poll_attempt },
-            ) => {
-                let max_poll_attempts =
-                    flow.max_poll_attempts.ok_or_else(|| {
-                        DBG_ERR!("Invalid response from the server");
-                        Box::new(NT_STATUS_LOGON_FAILURE)
-                    })?;
-                if poll_attempt > max_poll_attempts {
-                    DBG_ERR!("MFA polling timed out");
-                    return Err(Box::new(NT_STATUS_LOGON_FAILURE));
-                }
-                let token = match self
-                    .client
-                    .lock()
-                    .await
-                    .acquire_token_by_mfa_flow(
-                        account_id,
-                        None,
-                        Some(poll_attempt),
-                        flow,
-                    )
-                    .await
-                {
-                    Ok(token) => token,
-                    Err(e) => match e {
-                        MsalError::MFAPollContinue => {
-                            return Ok(Response::PamAuthStepResponse(
-                                PamAuthResponse::MFAPollWait,
-                            ));
-                        }
-                        e => {
-                            DBG_ERR!("{:?}", e);
-                            return Err(Box::new(NT_STATUS_NOT_FOUND));
-                        }
-                    },
-                };
-                let token2 = enroll_and_obtain_enrolled_token!(token);
-                match self.token_validate(account_id, &token2).await {
-                    Ok(Response::PamAuthStepResponse(
-                        PamAuthResponse::Success,
-                    )) => {
-                        // Skip Hello enrollment if it is disabled by config
-                        let hello_enabled = self
-                            .lp
-                            .himmelblaud_hello_enabled()
-                            .map_err(|e| {
-                                DBG_ERR!("{:?}", e);
-                                Box::new(NT_STATUS_LOGON_FAILURE)
-                            })?;
-                        if !hello_enabled {
-                            DBG_INFO!("Skipping Hello enrollment because it is disabled");
-                            return Ok(Response::PamAuthStepResponse(
-                                PamAuthResponse::Success,
-                            ));
-                        }
-
-                        // Setup Windows Hello
-                        *cred_handler = AuthCredHandler::SetupPin { token };
-                        return Ok(Response::PamAuthStepResponse(
-                            PamAuthResponse::SetupPin {
-                                msg: format!(
-                                    "Set up a PIN\n {}{}",
-                                    "A Hello PIN is a fast, secure way to sign",
-                                    "in to your device, apps, and services."
-                                ),
-                            },
-                        ));
-                    }
-                    Ok(auth_result) => Ok(auth_result),
-                    Err(e) => Err(e),
-                }
-            }
-            _ => {
-                DBG_ERR!(
-                    "Unexpected AuthCredHandler and PamAuthRequest pairing"
-                );
-                Err(Box::new(NT_STATUS_NOT_IMPLEMENTED))
-            }
-        }
-    }
-
-    async fn token_validate(
-        &mut self,
-        account_id: &str,
-        token: &UnixUserToken,
-    ) -> Result<Response, Box<NTSTATUS>> {
-        match &token.access_token {
-            Some(access_token) => {
-                /* MFA can respond with different user than requested.
-                 * Azure resource names are case insensitive.
-                 */
-                let spn = token.spn().map_err(|e| {
-                    DBG_ERR!("Failed fetching user spn: {:?}", e);
-                    Box::new(NT_STATUS_LOGON_FAILURE)
-                })?;
-                if account_id.to_string().to_lowercase()
-                    != spn.to_string().to_lowercase()
-                {
-                    DBG_ERR!(
-                        "Authenticated user {} does not match requested user {}",
-                        spn, account_id
-                    );
-                    return Ok(Response::PamAuthStepResponse(
-                        PamAuthResponse::Denied,
-                    ));
-                }
-                DBG_INFO!(
-                    "Authentication successful for user '{}'",
-                    account_id
-                );
-
-                // Store the user in the cache
-                let user_entry: UserEntry = token.try_into().map_err(|e| {
-                    DBG_ERR!("{:?}", e);
-                    Box::new(NT_STATUS_LOGON_FAILURE)
-                })?;
-                self.user_cache.store(user_entry).map_err(|e| {
-                    DBG_ERR!("{:?}", e);
-                    Box::new(NT_STATUS_LOGON_FAILURE)
-                })?;
-
-                // Get the users groups, and store those groups in the cache
-                let groups: Vec<GroupEntry> = self
-                    .graph
-                    .request_user_groups(access_token)
-                    .await
-                    .map_err(|e| {
-                        DBG_ERR!("{:?}", e);
-                        Box::new(NT_STATUS_LOGON_FAILURE)
-                    })?
-                    .into_iter()
-                    .map(|g| GroupEntry::into_with_member(g, account_id))
-                    .collect();
-                self.group_cache.merge_groups(account_id, groups).map_err(
-                    |e| {
-                        DBG_ERR!("{:?}", e);
-                        Box::new(NT_STATUS_LOGON_FAILURE)
-                    },
-                )?;
-
-                Ok(Response::PamAuthStepResponse(PamAuthResponse::Success))
-            }
-            None => {
-                DBG_INFO!("Authentication failed for user '{}'", account_id);
-                Err(Box::new(NT_STATUS_NOT_FOUND))
-            }
-        }
-    }
-
-    async fn join_domain(
-        &mut self,
-        token: &UnixUserToken,
-    ) -> Result<(), Box<NTSTATUS>> {
-        /* If not already joined, join the domain now. */
-        let attrs = EnrollAttrs::new(
-            self.realm.clone(),
-            None,
-            Some(env::consts::OS.to_string()),
-            None,
-            None,
-        )
-        .map_err(|e| {
-            DBG_ERR!("{:?}", e);
-            Box::new(NT_STATUS_LOGON_FAILURE)
-        })?;
-        let mut tpm = self.hsm.lock().await;
-        match self
-            .client
-            .lock()
-            .await
-            .enroll_device(
-                &token.refresh_token,
-                attrs,
-                &mut tpm,
-                &self.machine_key,
-            )
-            .await
-        {
-            Ok((
-                new_loadable_transport_key,
-                new_loadable_cert_key,
-                device_id,
-            )) => {
-                DBG_INFO!("Joined domain {} ({})", self.realm, device_id);
-                // Store the new_loadable_cert_key in the keystore
-                self.pcache
-                    .loadable_cert_key_store(&self.realm, new_loadable_cert_key)
-                    .map_err(|e| {
-                        DBG_ERR!("{:?}", e);
-                        Box::new(NT_STATUS_LOGON_FAILURE)
-                    })?;
-                // Store the new_loadable_transport_key
-                self.pcache
-                    .loadable_transport_key_store(
-                        &self.realm,
-                        new_loadable_transport_key,
-                    )
-                    .map_err(|e| {
-                        DBG_ERR!("{:?}", e);
-                        Box::new(NT_STATUS_LOGON_FAILURE)
-                    })?;
-                // Store the device_id
-                self.pcache
-                    .device_id_store(&self.realm, &device_id)
-                    .map_err(|e| {
-                        DBG_ERR!("{:?}", e);
-                        Box::new(NT_STATUS_LOGON_FAILURE)
-                    })?;
-                Ok(())
-            }
-            Err(e) => {
-                DBG_ERR!("{:?}", e);
-                Err(Box::new(NT_STATUS_LOGON_FAILURE))
-            }
-        }
-    }
-
-    fn is_domain_joined(&mut self) -> bool {
-        /* If we have access to tpm keys, and the domain device_id is
-         * configured, we'll assume we are domain joined. */
-        let device_id = self.pcache.device_id(&self.realm);
-        if device_id.is_none() {
-            return false;
-        }
-        let transport_key =
-            self.pcache.loadable_transport_key_fetch(&self.realm);
-        if transport_key.is_none() {
-            return false;
-        }
-        let cert_key = self.pcache.loadable_cert_key_fetch(&self.realm);
-        if cert_key.is_none() {
-            return false;
-        }
-        true
-    }
-}
diff --git a/rust/himmelblaud/src/main.rs b/rust/himmelblaud/src/main.rs
deleted file mode 100644 (file)
index 835ba8c..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-// Ignore unused/dead code when running cargo test
-#![cfg_attr(test, allow(unused_imports))]
-#![cfg_attr(test, allow(dead_code))]
-
-use clap::{Arg, ArgAction, Command};
-use dbg::*;
-use himmelblau::graph::Graph;
-use himmelblau::BrokerClientApplication;
-use idmap::Idmap;
-use kanidm_hsm_crypto::soft::SoftTpm;
-use kanidm_hsm_crypto::{BoxedDynTpm, Tpm};
-use libc::umask;
-use param::LoadParm;
-use std::path::{Path, PathBuf};
-use std::process::ExitCode;
-use std::sync::atomic::{AtomicBool, Ordering};
-use std::sync::Arc;
-use tokio::net::UnixListener;
-use tokio::signal::unix::{signal, SignalKind};
-use tokio::sync::Mutex;
-
-mod constants;
-use constants::DEFAULT_ODC_PROVIDER;
-mod cache;
-mod himmelblaud;
-use cache::{GroupCache, PrivateCache, UidCache, UserCache};
-mod utils;
-
-#[cfg(not(test))]
-#[tokio::main(flavor = "current_thread")]
-async fn main() -> ExitCode {
-    let clap_args = Command::new("himmelblaud")
-        .version(env!("CARGO_PKG_VERSION"))
-        .about("Samba Himmelblau Authentication Daemon")
-        .arg(
-            Arg::new("debuglevel")
-                .help("Set debug level")
-                .short('d')
-                .long("debuglevel")
-                .value_parser(
-                    clap::value_parser!(u16).range(0..(MAX_DEBUG_LEVEL as i64)),
-                )
-                .action(ArgAction::Set),
-        )
-        .arg(
-            Arg::new("debug-stdout")
-                .help("Send debug output to standard output")
-                .long("debug-stdout")
-                .action(ArgAction::SetTrue),
-        )
-        .arg(
-            Arg::new("configfile")
-                .help("Use alternative configuration file")
-                .short('s')
-                .long("configfile")
-                .action(ArgAction::Set),
-        )
-        .get_matches();
-
-    let stop_now = Arc::new(AtomicBool::new(false));
-    let terminate_now = Arc::clone(&stop_now);
-    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::<u16>("debuglevel") {
-            debuglevel_set!(*debuglevel);
-        }
-
-        // Initialize the LoadParm from the command line specified config file
-        let lp = match LoadParm::new(
-            clap_args
-                .get_one::<String>("configfile")
-                .map(|x| x.as_str()),
-        ) {
-            Ok(lp) => lp,
-            Err(e) => {
-                eprintln!("Failed loading smb.conf: {:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        // Check that the realm is configured. This the bare minimum for
-        // himmelblaud, since a device join can happen at authentication time,
-        // but we need to know the permitted enrollment domain.
-        let realm = match lp.realm() {
-            Ok(Some(realm)) => realm,
-            _ => {
-                eprintln!(
-                    "The realm MUST be set in the \
-                    smb.conf to start himmelblaud"
-                );
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        // Setup logging, either to the configured logfile, or to stdout, depending
-        // on what is specified on the command line.
-        match clap_args.get_flag("debug-stdout") {
-            true => setup_logging(env!("CARGO_PKG_NAME"), DEBUG_STDOUT),
-            false => {
-                setup_logging(env!("CARGO_PKG_NAME"), DEBUG_FILE);
-                match lp.logfile() {
-                    Ok(Some(logfile)) => debug_set_logfile(&logfile),
-                    _ => {
-                        eprintln!("Failed to determine logfile name");
-                        talloc::TALLOC_FREE!(frame);
-                        return ExitCode::FAILURE;
-                    }
-                }
-            }
-        }
-
-        // Determine the unix socket path
-        let sock_dir_str = match lp.winbindd_socket_directory() {
-            Ok(Some(sock_dir)) => sock_dir,
-            _ => {
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-        let sock_dir = Path::new(&sock_dir_str);
-        let mut sock_path_buf = PathBuf::from(sock_dir);
-        sock_path_buf.push("hb_pipe");
-        let sock_path = match sock_path_buf.to_str() {
-            Some(sock_path) => sock_path,
-            None => {
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-        if sock_path_buf.exists() {
-            DBG_DEBUG!("Cleaning up socket from previous invocations");
-            if let Err(_) = std::fs::remove_file(sock_path) {
-                DBG_ERR!("Failed removing socket");
-            }
-        }
-
-        // Initialize the Himmelblau cache
-        let private_cache_path = match lp.private_path("himmelblau.tdb") {
-            Ok(Some(private_cache_path)) => private_cache_path,
-            _ => {
-                DBG_ERR!("Failed to determine private cache path");
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-        let mut private_dir = Path::new(&private_cache_path).to_path_buf();
-        private_dir.pop();
-        if !private_dir.exists() {
-            DBG_ERR!(
-                "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) {
-            Ok(cache) => cache,
-            Err(e) => {
-                DBG_ERR!(
-                    "Failed to open the himmelblau private cache: {:?}",
-                    e
-                );
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        let cache_dir = match lp.cache_directory() {
-            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;
-        }
-
-        let user_cache_path = Path::new(&cache_dir)
-            .join("himmelblau_users.tdb")
-            .display()
-            .to_string();
-        let user_cache = match UserCache::new(&user_cache_path) {
-            Ok(cache) => cache,
-            Err(e) => {
-                DBG_ERR!("Failed to open the himmelblau user cache: {:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        let uid_cache_path = Path::new(&cache_dir)
-            .join("himmelblau_uid_map.tdb")
-            .display()
-            .to_string();
-        let uid_cache = match UidCache::new(&uid_cache_path) {
-            Ok(cache) => cache,
-            Err(e) => {
-                DBG_ERR!("Failed to open the himmelblau uid cache: {:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        let group_cache_path = Path::new(&cache_dir)
-            .join("himmelblau_groups.tdb")
-            .display()
-            .to_string();
-        let group_cache = match GroupCache::new(&group_cache_path) {
-            Ok(cache) => cache,
-            Err(e) => {
-                DBG_ERR!("Failed to open the himmelblau group cache: {:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        // Check for and create the hsm pin if required.
-        let hsm_pin_path = match lp.himmelblaud_hsm_pin_path() {
-            Ok(Some(hsm_pin_path)) => hsm_pin_path,
-            _ => {
-                DBG_ERR!("Failed loading hsm pin path.");
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-        let mut hsm_pin_dir = Path::new(&hsm_pin_path).to_path_buf();
-        hsm_pin_dir.pop();
-        if !hsm_pin_dir.exists() {
-            DBG_ERR!(
-                "The hsm pin directory '{}' does not exist",
-                hsm_pin_dir.display()
-            );
-            talloc::TALLOC_FREE!(frame);
-            return ExitCode::FAILURE;
-        }
-        let auth_value =
-            match utils::hsm_pin_fetch_or_create(&hsm_pin_path).await {
-                Ok(auth_value) => auth_value,
-                Err(e) => {
-                    DBG_ERR!("{:?}", e);
-                    talloc::TALLOC_FREE!(frame);
-                    return ExitCode::FAILURE;
-                }
-            };
-
-        // Setup the HSM and its machine key
-        let mut hsm: BoxedDynTpm = BoxedDynTpm::new(SoftTpm::new());
-
-        let loadable_machine_key = match pcache
-            .loadable_machine_key_fetch_or_create(&mut hsm, &auth_value)
-        {
-            Ok(lmk) => lmk,
-            Err(e) => {
-                DBG_ERR!("{:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        let res = hsm.machine_key_load(&auth_value, &loadable_machine_key);
-        let machine_key = match res {
-            Ok(machine_key) => machine_key,
-            Err(e) => {
-                DBG_ERR!("Unable to load machine root key: {:?}", e);
-                DBG_INFO!("This can occur if you have changed your HSM pin.");
-                DBG_INFO!(
-                    "To proceed, run `tdbtool erase {}`",
-                    private_cache_path
-                );
-                DBG_INFO!("The host will forget domain enrollments.");
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        // Get the transport key for a joined domain
-        let loadable_transport_key =
-            pcache.loadable_transport_key_fetch(&realm);
-
-        // Get the certificate key for a joined domain
-        let loadable_cert_key = pcache.loadable_cert_key_fetch(&realm);
-
-        // Contact the odc provider to get the authority host and tenant id
-        let graph = match Graph::new(DEFAULT_ODC_PROVIDER, &realm).await {
-            Ok(graph) => graph,
-            Err(e) => {
-                DBG_ERR!("Failed initializing the graph: {:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-        let authority_host = graph.authority_host();
-        let tenant_id = graph.tenant_id();
-        let authority = format!("https://{}/{}", authority_host, tenant_id);
-
-        let client = match BrokerClientApplication::new(
-            Some(&authority),
-            loadable_transport_key,
-            loadable_cert_key,
-        ) {
-            Ok(client) => client,
-            Err(e) => {
-                DBG_ERR!("Failed initializing the broker: {:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-
-        let mut idmap = match Idmap::new() {
-            Ok(idmap) => idmap,
-            Err(e) => {
-                DBG_ERR!("Failed initializing the idmapper: {:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-        // Configure the idmap range
-        let (low, high) = match lp.idmap_range(&realm) {
-            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;
-        }
-
-        let resolver = Arc::new(Mutex::new(himmelblaud::Resolver::new(
-            &realm,
-            &tenant_id,
-            lp,
-            idmap,
-            graph,
-            pcache,
-            user_cache,
-            uid_cache,
-            group_cache,
-            hsm,
-            machine_key,
-            client,
-        )));
-
-        // Set the umask while we open the path for most clients.
-        let before = unsafe { umask(0) };
-        // Listen for incoming requests from PAM and NSS
-        let listener = match UnixListener::bind(sock_path) {
-            Ok(listener) => listener,
-            Err(e) => {
-                DBG_ERR!("Failed setting up the socket listener: {:?}", e);
-                talloc::TALLOC_FREE!(frame);
-                return ExitCode::FAILURE;
-            }
-        };
-        // Undo umask changes.
-        let _ = unsafe { umask(before) };
-
-        let server = tokio::spawn(async move {
-            while !stop_now.load(Ordering::Relaxed) {
-                let resolver_ref = resolver.clone();
-                match listener.accept().await {
-                    Ok((socket, _addr)) => {
-                        tokio::spawn(async move {
-                            if let Err(e) = himmelblaud::handle_client(
-                                socket,
-                                resolver_ref.clone(),
-                            )
-                            .await
-                            {
-                                DBG_ERR!(
-                                    "handle_client error occurred: {:?}",
-                                    e
-                                );
-                            }
-                        });
-                    }
-                    Err(e) => {
-                        DBG_ERR!("Error while handling connection: {:?}", e);
-                    }
-                }
-            }
-        });
-
-        let terminate_task = tokio::spawn(async move {
-            match signal(SignalKind::terminate()) {
-                Ok(mut stream) => {
-                    stream.recv().await;
-                    terminate_now.store(true, Ordering::Relaxed);
-                }
-                Err(e) => {
-                    DBG_ERR!("Failed registering terminate signal: {}", e);
-                }
-            };
-        });
-
-        let quit_task = tokio::spawn(async move {
-            match signal(SignalKind::quit()) {
-                Ok(mut stream) => {
-                    stream.recv().await;
-                    quit_now.store(true, Ordering::Relaxed);
-                }
-                Err(e) => {
-                    DBG_ERR!("Failed registering quit signal: {}", e);
-                }
-            };
-        });
-
-        let interrupt_task = tokio::spawn(async move {
-            match signal(SignalKind::interrupt()) {
-                Ok(mut stream) => {
-                    stream.recv().await;
-                    interrupt_now.store(true, Ordering::Relaxed);
-                }
-                Err(e) => {
-                    DBG_ERR!("Failed registering interrupt signal: {}", e);
-                }
-            };
-        });
-
-        DBG_INFO!("Server started ...");
-
-        tokio::select! {
-            _ = server => {
-                DBG_DEBUG!("Main listener task is terminating");
-            },
-            _ = terminate_task => {
-                DBG_DEBUG!("Received signal to terminate");
-            },
-            _ = quit_task => {
-                DBG_DEBUG!("Received signal to quit");
-            },
-            _ = interrupt_task => {
-                DBG_DEBUG!("Received signal to interrupt");
-            }
-        }
-
-        talloc::TALLOC_FREE!(frame);
-        ExitCode::SUCCESS
-    }
-    .await
-}
diff --git a/rust/himmelblaud/src/utils.rs b/rust/himmelblaud/src/utils.rs
deleted file mode 100644 (file)
index b452b48..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Himmelblau daemon common utilities
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use dbg::{DBG_ERR, DBG_INFO};
-use kanidm_hsm_crypto::AuthValue;
-use ntstatus_gen::*;
-use std::path::PathBuf;
-use std::str::FromStr;
-use tokio::fs::File;
-use tokio::io::AsyncReadExt;
-
-pub fn split_username(
-    username: &str,
-) -> Result<(String, String), Box<NTSTATUS>> {
-    let tup: Vec<&str> = username.split('@').collect();
-    if tup.len() == 2 {
-        return Ok((tup[0].to_string(), tup[1].to_string()));
-    }
-    Err(Box::new(NT_STATUS_INVALID_USER_PRINCIPAL_NAME))
-}
-
-pub(crate) async fn hsm_pin_fetch_or_create(
-    hsm_pin_path: &str,
-) -> Result<AuthValue, Box<NTSTATUS>> {
-    let auth_value = if !PathBuf::from_str(hsm_pin_path)
-        .map_err(|e| {
-            DBG_ERR!("Failed to create hsm pin: {:?}", e);
-            Box::new(NT_STATUS_UNSUCCESSFUL)
-        })?
-        .exists()
-    {
-        let auth_value = AuthValue::generate().map_err(|e| {
-            DBG_ERR!("Failed to create hsm pin: {:?}", e);
-            Box::new(NT_STATUS_UNSUCCESSFUL)
-        })?;
-        std::fs::write(hsm_pin_path, auth_value.clone()).map_err(|e| {
-            DBG_ERR!("Failed to write hsm pin: {:?}", e);
-            Box::new(NT_STATUS_UNSUCCESSFUL)
-        })?;
-
-        DBG_INFO!("Generated new HSM pin");
-        auth_value
-    } else {
-        let mut file = File::open(hsm_pin_path).await.map_err(|e| {
-            DBG_ERR!("Failed to read hsm pin: {:?}", e);
-            Box::new(NT_STATUS_UNSUCCESSFUL)
-        })?;
-        let mut auth_value = vec![];
-        file.read_to_end(&mut auth_value).await.map_err(|e| {
-            DBG_ERR!("Failed to read hsm pin: {:?}", e);
-            Box::new(NT_STATUS_UNSUCCESSFUL)
-        })?;
-        std::str::from_utf8(&auth_value)
-            .map_err(|e| {
-                DBG_ERR!("Failed to read hsm pin: {:?}", e);
-                Box::new(NT_STATUS_UNSUCCESSFUL)
-            })?
-            .to_string()
-    };
-    AuthValue::try_from(auth_value.as_bytes()).map_err(|e| {
-        DBG_ERR!("Invalid hsm pin: {:?}", e);
-        Box::new(NT_STATUS_UNSUCCESSFUL)
-    })
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use std::io::Write;
-    use tempfile::tempdir;
-    use tokio::fs;
-
-    #[test]
-    fn test_split_username_success() {
-        let username = "user@domain.com";
-        let result = split_username(username);
-        assert!(result.is_ok());
-        let (user, domain) = result.unwrap();
-        assert_eq!(user, "user");
-        assert_eq!(domain, "domain.com");
-    }
-
-    #[test]
-    fn test_split_username_failure() {
-        let username = "invalid_username";
-        let result = split_username(username);
-        assert!(result.is_err());
-        assert_eq!(*result.unwrap_err(), NT_STATUS_INVALID_USER_PRINCIPAL_NAME);
-    }
-
-    #[tokio::test]
-    async fn test_hsm_pin_fetch_or_create_generate() {
-        let dir = tempdir().unwrap();
-        let path = dir.path().join("hsm_pin");
-
-        let result = hsm_pin_fetch_or_create(path.to_str().unwrap()).await;
-        assert!(result.is_ok());
-
-        // Verify that the file is created and contains a valid auth value
-        let saved_pin = fs::read(path).await.expect("Auth value missing");
-        AuthValue::try_from(saved_pin.as_slice())
-            .expect("Failed parsing auth value");
-    }
-
-    #[tokio::test]
-    async fn test_hsm_pin_fetch_or_create_invalid_path() {
-        let result = hsm_pin_fetch_or_create("invalid_path\0").await;
-        assert!(result.is_err());
-        match result {
-            Err(e) => assert_eq!(*e, NT_STATUS_UNSUCCESSFUL),
-            Ok(_) => panic!("Expected error but got success"),
-        }
-    }
-
-    #[tokio::test]
-    async fn test_hsm_pin_fetch_or_create_invalid_auth_value() {
-        let dir = tempdir().unwrap();
-        let path = dir.path().join("hsm_pin");
-
-        // Write invalid content to the file
-        let mut file = std::fs::File::create(&path).unwrap();
-        file.write_all(b"invalid_auth_value").unwrap();
-
-        // Test reading the invalid file
-        let result = hsm_pin_fetch_or_create(path.to_str().unwrap()).await;
-        assert!(result.is_err());
-        match result {
-            Err(e) => assert_eq!(*e, NT_STATUS_UNSUCCESSFUL),
-            Ok(_) => panic!("Expected error but got success"),
-        }
-    }
-}
diff --git a/rust/idmap/Cargo.toml b/rust/idmap/Cargo.toml
deleted file mode 100644 (file)
index 8df127f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "idmap"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[dependencies]
-chelps.workspace = true
-dbg.workspace = true
-libc.workspace = true
-
-[build-dependencies]
-cc = "1.0.97"
-bindgen = "0.69.4"
diff --git a/rust/idmap/build.rs b/rust/idmap/build.rs
deleted file mode 100644 (file)
index c1a9f35..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-use std::env;
-use std::path::Path;
-use std::path::PathBuf;
-
-fn main() {
-    cc::Build::new()
-        .file("src/sss_idmap.c")
-        .file("src/sss_idmap_conv.c")
-        .file("src/murmurhash3.c")
-        .include(Path::new("../../bin/default/include"))
-        .warnings(false)
-        .compile("sss_idmap");
-
-    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")
-        .header("src/sss_idmap.h")
-        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
-        .generate()
-        .expect("Unable to generate bindings");
-
-    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
-    bindings
-        .write_to_file(out_path.join("bindings.rs"))
-        .expect("Couldn't write bindings!");
-    println!("cargo:rustc-link-lib=utf8proc");
-    println!("cargo:rustc-env=LD_LIBRARY_PATH=../../bin/shared/private/");
-}
diff --git a/rust/idmap/src/lib.rs b/rust/idmap/src/lib.rs
deleted file mode 100644 (file)
index 7e9e236..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
-   Himmelblaud
-
-   ID-mapping library
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use dbg::DBG_ERR;
-use std::ffi::CString;
-use std::fmt;
-use std::ptr;
-use std::sync::{Arc, Mutex};
-
-mod ffi {
-    #![allow(non_upper_case_globals)]
-    #![allow(non_camel_case_types)]
-    #![allow(non_snake_case)]
-    #![allow(dead_code)]
-    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
-}
-
-#[derive(PartialEq, Eq)]
-pub struct IdmapError(u32);
-
-pub const IDMAP_SUCCESS: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_SUCCESS);
-pub const IDMAP_NOT_IMPLEMENTED: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_NOT_IMPLEMENTED);
-pub const IDMAP_ERROR: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_ERROR);
-pub const IDMAP_OUT_OF_MEMORY: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_OUT_OF_MEMORY);
-pub const IDMAP_NO_DOMAIN: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_NO_DOMAIN);
-pub const IDMAP_CONTEXT_INVALID: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_CONTEXT_INVALID);
-pub const IDMAP_SID_INVALID: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_SID_INVALID);
-pub const IDMAP_SID_UNKNOWN: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_SID_UNKNOWN);
-pub const IDMAP_NO_RANGE: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_NO_RANGE);
-pub const IDMAP_BUILTIN_SID: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_BUILTIN_SID);
-pub const IDMAP_OUT_OF_SLICES: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_OUT_OF_SLICES);
-pub const IDMAP_COLLISION: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_COLLISION);
-pub const IDMAP_EXTERNAL: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_EXTERNAL);
-pub const IDMAP_NAME_UNKNOWN: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_NAME_UNKNOWN);
-pub const IDMAP_NO_REVERSE: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_NO_REVERSE);
-pub const IDMAP_ERR_LAST: IdmapError =
-    IdmapError(ffi::idmap_error_code_IDMAP_ERR_LAST);
-
-impl fmt::Display for IdmapError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "IdmapError({:#x})", self.0)
-    }
-}
-
-impl fmt::Debug for IdmapError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "IdmapError({:#x})", self.0)
-    }
-}
-
-impl std::error::Error for IdmapError {}
-
-pub struct Idmap {
-    ctx: Arc<Mutex<*mut ffi::sss_idmap_ctx>>,
-}
-
-impl Idmap {
-    pub fn new() -> Result<Idmap, IdmapError> {
-        let mut ctx = ptr::null_mut();
-        unsafe {
-            match IdmapError(ffi::sss_idmap_init(
-                None,
-                ptr::null_mut(),
-                None,
-                &mut ctx,
-            )) {
-                IDMAP_SUCCESS => Ok(Idmap {
-                    ctx: Arc::new(Mutex::new(ctx)),
-                }),
-                e => Err(e),
-            }
-        }
-    }
-
-    pub fn add_gen_domain(
-        &mut self,
-        domain_name: &str,
-        tenant_id: &str,
-        range: (u32, u32),
-    ) -> Result<(), IdmapError> {
-        let ctx = self.ctx.lock().map_err(|e| {
-            DBG_ERR!("Failed obtaining write lock on sss_idmap_ctx: {}", e);
-            IDMAP_ERROR
-        })?;
-        let domain_name_cstr =
-            CString::new(domain_name).map_err(|_| IDMAP_OUT_OF_MEMORY)?;
-        let tenant_id_cstr =
-            CString::new(tenant_id).map_err(|_| IDMAP_OUT_OF_MEMORY)?;
-        let mut idmap_range = ffi::sss_idmap_range {
-            min: range.0,
-            max: range.1,
-        };
-        unsafe {
-            match IdmapError(ffi::sss_idmap_add_gen_domain_ex(
-                *ctx,
-                domain_name_cstr.as_ptr(),
-                tenant_id_cstr.as_ptr(),
-                &mut idmap_range,
-                ptr::null_mut(),
-                None,
-                None,
-                ptr::null_mut(),
-                0,
-                false,
-            )) {
-                IDMAP_SUCCESS => Ok(()),
-                e => Err(e),
-            }
-        }
-    }
-
-    pub fn gen_to_unix(
-        &self,
-        tenant_id: &str,
-        input: &str,
-    ) -> Result<u32, IdmapError> {
-        let ctx = self.ctx.lock().map_err(|e| {
-            DBG_ERR!("Failed obtaining write lock on sss_idmap_ctx: {}", e);
-            IDMAP_ERROR
-        })?;
-        let tenant_id_cstr =
-            CString::new(tenant_id).map_err(|_| IDMAP_OUT_OF_MEMORY)?;
-        let input_cstr = CString::new(input.to_lowercase())
-            .map_err(|_| IDMAP_OUT_OF_MEMORY)?;
-        unsafe {
-            let mut id: u32 = 0;
-            match IdmapError(ffi::sss_idmap_gen_to_unix(
-                *ctx,
-                tenant_id_cstr.as_ptr(),
-                input_cstr.as_ptr(),
-                &mut id,
-            )) {
-                IDMAP_SUCCESS => Ok(id),
-                e => Err(e),
-            }
-        }
-    }
-}
-
-impl Drop for Idmap {
-    fn drop(&mut self) {
-        match self.ctx.lock() {
-            Ok(ctx) => unsafe {
-                let _ = ffi::sss_idmap_free(*ctx);
-            },
-            Err(e) => {
-                DBG_ERR!(
-                    "Failed obtaining write lock on sss_idmap_ctx during drop: {}",
-                    e
-                );
-            }
-        }
-    }
-}
-
-unsafe impl Send for Idmap {}
-unsafe impl Sync for Idmap {}
-
-#[cfg(test)]
-mod tests {
-    use crate::Idmap;
-    use std::collections::HashMap;
-    pub const DEFAULT_IDMAP_RANGE: (u32, u32) = (200000, 2000200000);
-
-    #[test]
-    fn sssd_idmapping() {
-        let domain = "contoso.onmicrosoft.com";
-        let tenant_id = "d7af6c1b-0497-40fe-9d17-07e6b0f8332e";
-        let mut idmap = Idmap::new().expect("Idmap initialization failed");
-
-        idmap
-            .add_gen_domain(domain, tenant_id, DEFAULT_IDMAP_RANGE)
-            .expect("Failed initializing test domain idmapping");
-
-        // Verify we always get the same mapping for various users
-        let mut usermap: HashMap<String, u32> = HashMap::new();
-        usermap.insert("tux@contoso.onmicrosoft.com".to_string(), 1912749799);
-        usermap.insert("admin@contoso.onmicrosoft.com".to_string(), 297515919);
-        usermap.insert("dave@contoso.onmicrosoft.com".to_string(), 132631922);
-        usermap.insert("joe@contoso.onmicrosoft.com".to_string(), 361591965);
-        usermap.insert("georg@contoso.onmicrosoft.com".to_string(), 866887005);
-
-        for (username, expected_uid) in &usermap {
-            let uid = idmap.gen_to_unix(tenant_id, username).expect(&format!(
-                "Failed converting username {} to uid",
-                username
-            ));
-            assert_eq!(
-                uid, *expected_uid,
-                "Uid for {} did not match",
-                username
-            );
-        }
-    }
-}
diff --git a/rust/idmap/src/murmurhash3.c b/rust/idmap/src/murmurhash3.c
deleted file mode 100644 (file)
index f0ccd92..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* This file is based on the public domain MurmurHash3 from Austin Appleby:
- * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
- *
- * We use only the 32 bit variant because the 2 produce different result while
- * we need to produce the same result regardless of the architecture as
- * clients can be both 64 or 32 bit at the same time.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "config.h"
-#include "murmurhash3.h"
-#include "util.h"
-
-static uint32_t rotl(uint32_t x, int8_t r)
-{
-    return (x << r) | (x >> (32 - r));
-}
-
-/* slower than original but is endian neutral and handles platforms that
- * do only aligned reads */
-__attribute__((always_inline))
-static inline uint32_t getblock(const uint8_t *p, int i)
-{
-    uint32_t r;
-    size_t size = sizeof(uint32_t);
-
-    memcpy(&r, &p[i * size], size);
-
-    return le32toh(r);
-}
-
-/*
- * Finalization mix - force all bits of a hash block to avalanche
- */
-
-__attribute__((always_inline))
-static inline uint32_t fmix(uint32_t h)
-{
-    h ^= h >> 16;
-    h *= 0x85ebca6b;
-    h ^= h >> 13;
-    h *= 0xc2b2ae35;
-    h ^= h >> 16;
-
-    return h;
-}
-
-
-uint32_t murmurhash3(const char *key, int len, uint32_t seed)
-{
-    const uint8_t *blocks;
-    const uint8_t *tail;
-    int nblocks;
-    uint32_t h1;
-    uint32_t k1;
-    uint32_t c1;
-    uint32_t c2;
-    int i;
-
-    blocks = (const uint8_t *)key;
-    nblocks = len / 4;
-    h1 = seed;
-    c1 = 0xcc9e2d51;
-    c2 = 0x1b873593;
-
-    /* body */
-
-    for (i = 0; i < nblocks; i++) {
-
-        k1 = getblock(blocks, i);
-
-        k1 *= c1;
-        k1 = rotl(k1, 15);
-        k1 *= c2;
-
-        h1 ^= k1;
-        h1 = rotl(h1, 13);
-        h1 = h1 * 5 + 0xe6546b64;
-    }
-
-    /* tail */
-
-    tail = (const uint8_t *)key + nblocks * 4;
-
-    k1 = 0;
-
-    switch (len & 3) {
-    case 3:
-        k1 ^= tail[2] << 16;
-        SSS_ATTRIBUTE_FALLTHROUGH;
-    case 2:
-        k1 ^= tail[1] << 8;
-        SSS_ATTRIBUTE_FALLTHROUGH;
-    case 1:
-        k1 ^= tail[0];
-        k1 *= c1;
-        k1 = rotl(k1, 15);
-        k1 *= c2;
-        h1 ^= k1;
-        break;
-    default:
-        break;
-    }
-
-    /* finalization */
-
-    h1 ^= len;
-    h1 = fmix(h1);
-
-    return h1;
-}
diff --git a/rust/idmap/src/murmurhash3.h b/rust/idmap/src/murmurhash3.h
deleted file mode 100644 (file)
index 2767183..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This file is based on the public domain MurmurHash3 from Austin Appleby:
- * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
- *
- * We use only the 32 bit variant because the 2 produce different result while
- * we need to produce the same result regardless of the architecture as
- * clients can be both 64 or 32 bit at the same time.
- */
-
-#ifndef _SHARED_MURMURHASH3_H_
-#define _SHARED_MURMURHASH3_H_
-
-/* CAUTION:
- * This file is also used in sss_client (pam, nss). Therefore it have to be
- * minimalist and cannot include DEBUG macros or header file util.h.
- */
-
-#include <stdint.h>
-
-uint32_t murmurhash3(const char *key, int len, uint32_t seed);
-
-#endif /* _SHARED_MURMURHASH3_H_ */
diff --git a/rust/idmap/src/sss_idmap.c b/rust/idmap/src/sss_idmap.c
deleted file mode 100644 (file)
index 4da1d0d..0000000
+++ /dev/null
@@ -1,1909 +0,0 @@
-/*
-    SSSD
-
-    ID-mapping library
-
-    Authors:
-        Sumit Bose <sbose@redhat.com>
-
-    Copyright (C) 2012 Red Hat
-
-    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 <http://www.gnu.org/licenses/>.
-*/
-
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <utf8proc.h>
-
-#include "sss_idmap.h"
-#include "sss_idmap_private.h"
-#include "murmurhash3.h"
-
-#define SID_FMT "%s-%"PRIu32
-#define SID_STR_MAX_LEN 1024
-
-/* Hold all parameters for unix<->sid mapping relevant for
- * given slice. */
-struct idmap_range_params {
-    uint32_t min_id;
-    uint32_t max_id;
-    char *range_id;
-
-    uint32_t first_rid;
-    struct idmap_range_params *next;
-};
-
-struct idmap_domain_info {
-    char *name;
-    char *sid;
-    struct idmap_range_params range_params;
-    struct idmap_domain_info *next;
-    bool external_mapping;
-
-    struct idmap_range_params *helpers;
-    bool auto_add_ranges;
-    bool helpers_owner;
-
-    idmap_offset_func *offset_func;
-    idmap_rev_offset_func *rev_offset_func;
-    void *offset_func_pvt;
-
-    idmap_store_cb cb;
-    void *pvt;
-};
-
-static void *default_alloc(size_t size, void *pvt)
-{
-    return malloc(size);
-}
-
-static void default_free(void *ptr, void *pvt)
-{
-    free(ptr);
-}
-
-static char *idmap_strdup(struct sss_idmap_ctx *ctx, const char *str)
-{
-    char *new = NULL;
-    size_t len;
-
-    CHECK_IDMAP_CTX(ctx, NULL);
-
-    len = strlen(str) + 1;
-
-    new = ctx->alloc_func(len, ctx->alloc_pvt);
-    if (new == NULL) {
-        return NULL;
-    }
-
-    memcpy(new, str, len);
-
-    return new;
-}
-
-static bool ranges_eq(const struct idmap_range_params *a,
-                      const struct idmap_range_params *b)
-{
-    if (a == NULL || b == NULL) {
-        return false;
-    }
-
-    if (a->first_rid == b->first_rid
-            && a->min_id == b->min_id
-            && a->max_id == b->max_id) {
-        return true;
-    }
-
-    return false;
-}
-
-static enum idmap_error_code
-construct_range(struct sss_idmap_ctx *ctx,
-                const struct idmap_range_params *src,
-                char *id,
-                struct idmap_range_params **_dst)
-{
-    struct idmap_range_params *dst;
-
-    if (src == NULL || id == NULL || _dst == NULL) {
-        return IDMAP_ERROR;
-    }
-
-    dst = ctx->alloc_func(sizeof(struct idmap_range_params), ctx->alloc_pvt);
-    if (dst == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-
-    dst->min_id = src->min_id;
-    dst->max_id = src->max_id;
-    dst->first_rid = src->first_rid;
-    dst->next = NULL;
-    dst->range_id = id;
-
-    *_dst = dst;
-    return IDMAP_SUCCESS;
-}
-
-static bool id_is_in_range(uint32_t id,
-                           struct idmap_range_params *rp,
-                           uint32_t *rid)
-{
-    if (id == 0 || rp == NULL) {
-        return false;
-    }
-
-    if (id >= rp->min_id && id <= rp->max_id) {
-        if (rid != NULL) {
-            *rid = rp->first_rid + (id - rp->min_id);
-        }
-
-        return true;
-    }
-
-    return false;
-}
-
-const char *idmap_error_string(enum idmap_error_code err)
-{
-    switch (err) {
-        case IDMAP_SUCCESS:
-            return "IDMAP operation successful";
-            break;
-        case IDMAP_NOT_IMPLEMENTED:
-            return "IDMAP Function is not yet implemented";
-            break;
-        case IDMAP_ERROR:
-            return "IDMAP general error";
-            break;
-        case IDMAP_OUT_OF_MEMORY:
-            return "IDMAP operation ran out of memory";
-            break;
-        case IDMAP_NO_DOMAIN:
-            return "IDMAP domain not found";
-            break;
-        case IDMAP_CONTEXT_INVALID:
-            return "IDMAP context is invalid";
-            break;
-        case IDMAP_SID_INVALID:
-            return "IDMAP SID is invalid";
-            break;
-        case IDMAP_SID_UNKNOWN:
-            return "IDMAP SID not found";
-            break;
-        case IDMAP_NO_RANGE:
-            return "IDMAP range not found";
-            break;
-        case IDMAP_BUILTIN_SID:
-            return "IDMAP SID from BUILTIN domain";
-            break;
-        case IDMAP_OUT_OF_SLICES:
-            return "IDMAP not more free slices";
-            break;
-        case IDMAP_COLLISION:
-            return "IDMAP new range collides with existing one";
-            break;
-        case IDMAP_EXTERNAL:
-            return "IDMAP ID managed externally";
-            break;
-        case IDMAP_NAME_UNKNOWN:
-            return "IDMAP domain with the given name not found";
-            break;
-        case IDMAP_NO_REVERSE:
-            return "IDMAP cannot revert id to original source";
-            break;
-        case IDMAP_UTF8_ERROR:
-            return "IDMAP failed to modify UTF8 string";
-            break;
-        default:
-            return "IDMAP unknown error code";
-    }
-}
-
-bool is_domain_sid(const char *sid)
-{
-    const char *p;
-    long long a;
-    char *endptr;
-    size_t c;
-
-    if (sid == NULL || strncmp(sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) != 0) {
-        return false;
-    }
-
-    p = sid + DOM_SID_PREFIX_LEN;
-    c = 0;
-
-    do {
-        errno = 0;
-        a = strtoull(p, &endptr, 10);
-        if (errno != 0 || a > UINT32_MAX) {
-            return false;
-        }
-
-        if (*endptr == '-') {
-            p = endptr + 1;
-        } else if (*endptr != '\0') {
-            return false;
-        }
-        c++;
-    } while(c < 3 && *endptr != '\0');
-
-    if (c != 3 || *endptr != '\0') {
-        return false;
-    }
-
-    return true;
-}
-
-enum idmap_error_code sss_idmap_init(idmap_alloc_func *alloc_func,
-                                     void *alloc_pvt,
-                                     idmap_free_func *free_func,
-                                     struct sss_idmap_ctx **_ctx)
-{
-    struct sss_idmap_ctx *ctx;
-
-    if (alloc_func == NULL) {
-        alloc_func = default_alloc;
-    }
-
-    ctx = alloc_func(sizeof(struct sss_idmap_ctx), alloc_pvt);
-    if (ctx == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-    memset(ctx, 0, sizeof(struct sss_idmap_ctx));
-
-    ctx->alloc_func = alloc_func;
-    ctx->alloc_pvt = alloc_pvt;
-    ctx->free_func = (free_func == NULL) ? default_free : free_func;
-
-    /* Set default values. */
-    ctx->idmap_opts.autorid_mode = SSS_IDMAP_DEFAULT_AUTORID;
-    ctx->idmap_opts.idmap_lower = SSS_IDMAP_DEFAULT_LOWER;
-    ctx->idmap_opts.idmap_upper = SSS_IDMAP_DEFAULT_UPPER;
-    ctx->idmap_opts.rangesize = SSS_IDMAP_DEFAULT_RANGESIZE;
-    ctx->idmap_opts.extra_slice_init = SSS_IDMAP_DEFAULT_EXTRA_SLICE_INIT;
-
-    *_ctx = ctx;
-
-    return IDMAP_SUCCESS;
-}
-
-static void free_helpers(struct sss_idmap_ctx *ctx,
-                         struct idmap_range_params *helpers,
-                         bool helpers_owner)
-{
-    struct idmap_range_params *it = helpers;
-    struct idmap_range_params *tmp;
-
-    if (helpers_owner == false) {
-        return;
-    }
-
-    while (it != NULL) {
-        tmp = it->next;
-
-        ctx->free_func(it->range_id, ctx->alloc_pvt);
-        ctx->free_func(it, ctx->alloc_pvt);
-
-        it = tmp;
-    }
-}
-
-static struct idmap_range_params*
-get_helper_by_id(struct idmap_range_params *helpers, const char *id)
-{
-    struct idmap_range_params *it;
-
-    for (it = helpers; it != NULL; it = it->next) {
-        if (strcmp(it->range_id, id) == 0) {
-            return it;
-        }
-    }
-
-    return NULL;
-}
-
-static void sss_idmap_free_domain(struct sss_idmap_ctx *ctx,
-                                  struct idmap_domain_info *dom)
-{
-    if (ctx == NULL || dom == NULL) {
-        return;
-    }
-
-    ctx->free_func(dom->range_params.range_id, ctx->alloc_pvt);
-
-    free_helpers(ctx, dom->helpers, dom->helpers_owner);
-
-    ctx->free_func(dom->name, ctx->alloc_pvt);
-    ctx->free_func(dom->sid, ctx->alloc_pvt);
-    ctx->free_func(dom, ctx->alloc_pvt);
-}
-
-enum idmap_error_code sss_idmap_free(struct sss_idmap_ctx *ctx)
-{
-    struct idmap_domain_info *dom;
-    struct idmap_domain_info *next;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    next = ctx->idmap_domain_info;
-    while (next) {
-        dom = next;
-        next = dom->next;
-        sss_idmap_free_domain(ctx, dom);
-    }
-
-    ctx->free_func(ctx, ctx->alloc_pvt);
-
-    return IDMAP_SUCCESS;
-}
-
-static enum idmap_error_code sss_idmap_free_ptr(struct sss_idmap_ctx *ctx,
-                                                void *ptr)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (ptr != NULL) {
-        ctx->free_func(ptr, ctx->alloc_pvt);
-    }
-
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code sss_idmap_free_sid(struct sss_idmap_ctx *ctx,
-                                         char *sid)
-{
-    return sss_idmap_free_ptr(ctx, sid);
-}
-
-enum idmap_error_code sss_idmap_free_dom_sid(struct sss_idmap_ctx *ctx,
-                                             struct sss_dom_sid *dom_sid)
-{
-    return sss_idmap_free_ptr(ctx, dom_sid);
-}
-
-enum idmap_error_code sss_idmap_free_smb_sid(struct sss_idmap_ctx *ctx,
-                                             struct dom_sid *smb_sid)
-{
-    return sss_idmap_free_ptr(ctx, smb_sid);
-}
-
-enum idmap_error_code sss_idmap_free_bin_sid(struct sss_idmap_ctx *ctx,
-                                             uint8_t *bin_sid)
-{
-    return sss_idmap_free_ptr(ctx, bin_sid);
-}
-
-static bool check_overlap(struct idmap_range_params *range,
-                          id_t min, id_t max)
-{
-    return ((range->min_id <= min && range->max_id >= max)
-                || (range->min_id >= min && range->min_id <= max)
-                || (range->max_id >= min && range->max_id <= max));
-}
-
-static bool check_dom_overlap(struct idmap_range_params *prim_range,
-                              /* struct idmap_range_params *sec_ranges, */
-                              id_t min,
-                              id_t max)
-{
-    return check_overlap(prim_range, min, max);
-}
-
-enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
-                                                const char *range_id,
-                                                id_t *slice_num,
-                                                struct sss_idmap_range *_range)
-{
-    id_t max_slices;
-    id_t orig_slice;
-    id_t new_slice = 0;
-    id_t min;
-    id_t max;
-    id_t idmap_lower;
-    id_t idmap_upper;
-    id_t rangesize;
-    bool autorid_mode;
-    uint32_t hash_val;
-    struct idmap_domain_info *dom;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    idmap_lower = ctx->idmap_opts.idmap_lower;
-    idmap_upper = ctx->idmap_opts.idmap_upper;
-    rangesize = ctx->idmap_opts.rangesize;
-    autorid_mode = ctx->idmap_opts.autorid_mode;
-
-    max_slices = (idmap_upper - idmap_lower) / rangesize;
-
-    if (slice_num && *slice_num != -1) {
-        /* The slice is being set explicitly.
-         * This may happen at system startup when we're loading
-         * previously-determined slices. In the future, we may also
-         * permit configuration to select the slice for a domain
-         * explicitly.
-         */
-        new_slice = *slice_num;
-        min = (rangesize * new_slice) + idmap_lower;
-        max = min + rangesize - 1;
-        for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
-                if (check_dom_overlap(&dom->range_params,min, max)) {
-                    /* This range overlaps one already registered
-                     * Fail, because the slice was manually configured
-                     */
-                    return IDMAP_COLLISION;
-                }
-        }
-    } else {
-        /* If slice is -1, we're being asked to pick a new slice */
-
-        if (autorid_mode) {
-            /* In autorid compatibility mode, always start at 0 and find the
-             * first free value.
-             */
-            orig_slice = 0;
-        } else {
-            /* Hash the range identifier string */
-            hash_val = murmurhash3(range_id, strlen(range_id), 0xdeadbeef);
-
-            /* Now get take the modulus of the hash val and the max_slices
-             * to determine its optimal position in the range.
-             */
-            new_slice = hash_val % max_slices;
-            orig_slice = new_slice;
-        }
-
-        min = (rangesize * new_slice) + idmap_lower;
-        max = min + rangesize - 1;
-        /* Verify that this slice is not already in use */
-        do {
-            for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
-
-                if (check_dom_overlap(&dom->range_params,
-                                      min, max)) {
-                    /* This range overlaps one already registered
-                     * We'll try the next available slot
-                     */
-                    new_slice++;
-                    if (new_slice >= max_slices) {
-                        /* loop around to the beginning if necessary */
-                        new_slice = 0;
-                    }
-
-                    min = (rangesize * new_slice) + idmap_lower;
-                    max = min + rangesize - 1;
-                    break;
-                }
-            }
-
-            /* Keep trying until dom is NULL (meaning we got to the end
-             * without matching) or we have run out of slices and gotten
-             * back to the first one we tried.
-             */
-        } while (dom && new_slice != orig_slice);
-
-        if (dom) {
-            /* We looped all the way through and found no empty slots */
-            return IDMAP_OUT_OF_SLICES;
-        }
-    }
-
-    _range->min = (rangesize * new_slice) + idmap_lower;
-    _range->max = _range->min + rangesize - 1;
-
-    if (slice_num) {
-        *slice_num = new_slice;
-    }
-
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code sss_idmap_check_collision_ex(const char *o_name,
-                                                const char *o_sid,
-                                                struct sss_idmap_range *o_range,
-                                                uint32_t o_first_rid,
-                                                const char *o_range_id,
-                                                bool o_external_mapping,
-                                                const char *n_name,
-                                                const char *n_sid,
-                                                struct sss_idmap_range *n_range,
-                                                uint32_t n_first_rid,
-                                                const char *n_range_id,
-                                                bool n_external_mapping)
-{
-    bool names_equal;
-    bool sids_equal;
-
-    /* TODO: if both ranges have the same ID check if an update is
-     * needed. */
-
-    /* Check if ID ranges overlap.
-     * ID ranges with external mapping may overlap. */
-    if ((!n_external_mapping && !o_external_mapping)
-        && ((n_range->min >= o_range->min
-                && n_range->min <= o_range->max)
-            || (n_range->max >= o_range->min
-                && n_range->max <= o_range->max))) {
-        return IDMAP_COLLISION;
-    }
-
-    names_equal = (strcasecmp(n_name, o_name) == 0);
-    sids_equal = ((n_sid == NULL && o_sid == NULL)
-                    || (n_sid != NULL && o_sid != NULL
-                        && strcasecmp(n_sid, o_sid) == 0));
-
-    /* check if domain name and SID are consistent */
-    if ((names_equal && !sids_equal) || (!names_equal && sids_equal)) {
-        return IDMAP_COLLISION;
-    }
-
-    /* check if external_mapping is consistent */
-    if (names_equal && sids_equal
-            && n_external_mapping != o_external_mapping) {
-        return IDMAP_COLLISION;
-    }
-
-    /* check if RID ranges overlap */
-    if (names_equal && sids_equal
-            && n_external_mapping == false
-            && n_first_rid >= o_first_rid
-            && n_first_rid <= o_first_rid + (o_range->max - o_range->min)) {
-        return IDMAP_COLLISION;
-    }
-
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code sss_idmap_check_collision(struct sss_idmap_ctx *ctx,
-                                                char *n_name, char *n_sid,
-                                                struct sss_idmap_range *n_range,
-                                                uint32_t n_first_rid,
-                                                char *n_range_id,
-                                                bool n_external_mapping)
-{
-    struct idmap_domain_info *dom;
-    enum idmap_error_code err;
-    struct sss_idmap_range range;
-
-    for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
-
-        range.min = dom->range_params.min_id;
-        range.max = dom->range_params.max_id;
-
-        err = sss_idmap_check_collision_ex(dom->name, dom->sid,
-                                           &range,
-                                           dom->range_params.first_rid,
-                                           dom->range_params.range_id,
-                                           dom->external_mapping,
-                                           n_name, n_sid, n_range, n_first_rid,
-                                           n_range_id, n_external_mapping);
-        if (err != IDMAP_SUCCESS) {
-            return err;
-        }
-    }
-    return IDMAP_SUCCESS;
-}
-
-static enum
-idmap_error_code dom_check_collision(struct idmap_domain_info *dom_list,
-                                     struct idmap_domain_info *new_dom)
-{
-    struct idmap_domain_info *dom;
-    enum idmap_error_code err;
-    struct sss_idmap_range range;
-    struct sss_idmap_range new_dom_range = { new_dom->range_params.min_id,
-                                             new_dom->range_params.max_id };
-
-    for (dom = dom_list; dom != NULL; dom = dom->next) {
-        range.min = dom->range_params.min_id;
-        range.max = dom->range_params.max_id;
-
-        err = sss_idmap_check_collision_ex(dom->name, dom->sid,
-                                           &range,
-                                           dom->range_params.first_rid,
-                                           dom->range_params.range_id,
-                                           dom->external_mapping,
-                                           new_dom->name, new_dom->sid,
-                                           &new_dom_range,
-                                           new_dom->range_params.first_rid,
-                                           new_dom->range_params.range_id,
-                                           new_dom->external_mapping);
-        if (err != IDMAP_SUCCESS) {
-            return err;
-        }
-    }
-    return IDMAP_SUCCESS;
-}
-
-static char*
-generate_sec_slice_name(struct sss_idmap_ctx *ctx,
-                        const char *domain_sid, uint32_t rid)
-{
-    const char *SEC_SLICE_NAME_FMT = "%s-%"PRIu32;
-    char *slice_name;
-    int len, len2;
-
-    len = snprintf(NULL, 0, SEC_SLICE_NAME_FMT, domain_sid, rid);
-    if (len <= 0) {
-        return NULL;
-    }
-
-    slice_name = ctx->alloc_func(len + 1, ctx->alloc_pvt);
-    if (slice_name == NULL) {
-        return NULL;
-    }
-
-    len2 = snprintf(slice_name, len + 1, SEC_SLICE_NAME_FMT, domain_sid,
-                    rid);
-    if (len != len2) {
-        ctx->free_func(slice_name, ctx->alloc_pvt);
-        return NULL;
-    }
-
-    return slice_name;
-}
-
-static enum idmap_error_code
-generate_slice(struct sss_idmap_ctx *ctx, char *slice_name, uint32_t first_rid,
-               struct idmap_range_params **_slice)
-{
-    struct idmap_range_params *slice;
-    struct sss_idmap_range tmp_range;
-    enum idmap_error_code err;
-
-    slice = ctx->alloc_func(sizeof(struct idmap_range_params), ctx->alloc_pvt);
-    if (slice == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-
-    slice->next = NULL;
-
-    err = sss_idmap_calculate_range(ctx, slice_name, NULL, &tmp_range);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(slice, ctx->alloc_pvt);
-        return err;
-    }
-
-    slice->min_id = tmp_range.min;
-    slice->max_id = tmp_range.max;
-    slice->range_id = slice_name;
-    slice->first_rid = first_rid;
-
-    *_slice = slice;
-    return IDMAP_SUCCESS;
-}
-
-static enum idmap_error_code
-get_helpers(struct sss_idmap_ctx *ctx,
-            const char *domain_sid,
-            uint32_t first_rid,
-            struct idmap_range_params **_sec_slices)
-{
-    struct idmap_range_params *prev = NULL;
-    struct idmap_range_params *sec_slices = NULL;
-    static enum idmap_error_code err;
-    struct idmap_range_params *slice;
-    char *secondary_name;
-
-    for (int i = 0; i < ctx->idmap_opts.extra_slice_init; i++) {
-        secondary_name = generate_sec_slice_name(ctx, domain_sid, first_rid);
-        if (secondary_name == NULL) {
-            err = IDMAP_OUT_OF_MEMORY;
-            goto fail;
-        }
-
-        err = generate_slice(ctx, secondary_name, first_rid, &slice);
-        if (err != IDMAP_SUCCESS) {
-            goto fail;
-        }
-
-        first_rid += ctx->idmap_opts.rangesize;
-
-        if (prev != NULL) {
-            prev->next = slice;
-        }
-
-        if (sec_slices == NULL) {
-            sec_slices = slice;
-        }
-
-        prev = slice;
-    }
-
-    *_sec_slices = sec_slices;
-    return IDMAP_SUCCESS;
-
-fail:
-    ctx->free_func(secondary_name, ctx->alloc_pvt);
-
-    /* Free already generated helpers. */
-    free_helpers(ctx, sec_slices, true);
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_add_gen_domain_ex(struct sss_idmap_ctx *ctx,
-                                                  const char *domain_name,
-                                                  const char *domain_id,
-                                                  struct sss_idmap_range *range,
-                                                  const char *range_id,
-                                                  idmap_offset_func *offset_func,
-                                                  idmap_rev_offset_func *rev_offset_func,
-                                                  void *offset_func_pvt,
-                                                  uint32_t shift,
-                                                  bool external_mapping)
-{
-    struct idmap_domain_info *dom = NULL;
-    enum idmap_error_code err;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (domain_name == NULL || domain_id == NULL) {
-        return IDMAP_NO_DOMAIN;
-    }
-
-    if (range == NULL) {
-        return IDMAP_NO_RANGE;
-    }
-
-    dom = ctx->alloc_func(sizeof(struct idmap_domain_info), ctx->alloc_pvt);
-    if (dom == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-    memset(dom, 0, sizeof(struct idmap_domain_info));
-
-    dom->name = idmap_strdup(ctx, domain_name);
-    if (dom->name == NULL) {
-        err = IDMAP_OUT_OF_MEMORY;
-        goto fail;
-    }
-
-    dom->sid = idmap_strdup(ctx, domain_id);
-    if (dom->sid == NULL) {
-        err = IDMAP_OUT_OF_MEMORY;
-        goto fail;
-    }
-
-    dom->range_params.min_id = range->min;
-    dom->range_params.max_id = range->max;
-
-    if (range_id != NULL) {
-        dom->range_params.range_id = idmap_strdup(ctx, range_id);
-        if (dom->range_params.range_id == NULL) {
-            err = IDMAP_OUT_OF_MEMORY;
-            goto fail;
-        }
-    }
-
-    dom->range_params.first_rid = shift;
-    dom->external_mapping = external_mapping;
-
-    dom->offset_func = offset_func;
-    dom->rev_offset_func = rev_offset_func;
-    dom->offset_func_pvt = offset_func_pvt;
-
-    err = dom_check_collision(ctx->idmap_domain_info, dom);
-    if (err != IDMAP_SUCCESS) {
-        goto fail;
-    }
-
-    dom->next = ctx->idmap_domain_info;
-    ctx->idmap_domain_info = dom;
-
-    return IDMAP_SUCCESS;
-
-fail:
-    sss_idmap_free_domain(ctx, dom);
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx,
-                                              const char *domain_name,
-                                              const char *domain_sid,
-                                              struct sss_idmap_range *range,
-                                              const char *range_id,
-                                              uint32_t rid,
-                                              bool external_mapping)
-{
-    struct idmap_domain_info *dom = NULL;
-    enum idmap_error_code err;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (domain_name == NULL) {
-        return IDMAP_NO_DOMAIN;
-    }
-
-    if (range == NULL) {
-        return IDMAP_NO_RANGE;
-    }
-
-    /* For algorithmic mapping a valid domain SID is required, for external
-     * mapping it may be NULL, but if set it should be valid. */
-    if ((!external_mapping && !is_domain_sid(domain_sid))
-            || (external_mapping
-                && domain_sid != NULL
-                && !is_domain_sid(domain_sid))) {
-        return IDMAP_SID_INVALID;
-    }
-
-    dom = ctx->alloc_func(sizeof(struct idmap_domain_info), ctx->alloc_pvt);
-    if (dom == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-    memset(dom, 0, sizeof(struct idmap_domain_info));
-
-    dom->name = idmap_strdup(ctx, domain_name);
-    if (dom->name == NULL) {
-        err = IDMAP_OUT_OF_MEMORY;
-        goto fail;
-    }
-
-    if (domain_sid != NULL) {
-        dom->sid = idmap_strdup(ctx, domain_sid);
-        if (dom->sid == NULL) {
-            err = IDMAP_OUT_OF_MEMORY;
-            goto fail;
-        }
-    }
-
-    dom->range_params.min_id = range->min;
-    dom->range_params.max_id = range->max;
-
-    if (range_id != NULL) {
-        dom->range_params.range_id = idmap_strdup(ctx, range_id);
-        if (dom->range_params.range_id == NULL) {
-            err = IDMAP_OUT_OF_MEMORY;
-            goto fail;
-        }
-    }
-
-    dom->range_params.first_rid = rid;
-    dom->external_mapping = external_mapping;
-
-    err = dom_check_collision(ctx->idmap_domain_info, dom);
-    if (err != IDMAP_SUCCESS) {
-        goto fail;
-    }
-
-    dom->next = ctx->idmap_domain_info;
-    ctx->idmap_domain_info = dom;
-
-    return IDMAP_SUCCESS;
-
-fail:
-    sss_idmap_free_domain(ctx, dom);
-
-    return err;
-}
-
-enum idmap_error_code
-sss_idmap_add_auto_domain_ex(struct sss_idmap_ctx *ctx,
-                             const char *domain_name,
-                             const char *domain_sid,
-                             struct sss_idmap_range *range,
-                             const char *range_id,
-                             uint32_t rid,
-                             bool external_mapping,
-                             idmap_store_cb cb,
-                             void *pvt)
-{
-    enum idmap_error_code err;
-
-    err = sss_idmap_add_domain_ex(ctx, domain_name, domain_sid, range,
-                                  range_id, rid, external_mapping);
-    if (err != IDMAP_SUCCESS) {
-        return err;
-    }
-
-    if (external_mapping) {
-        /* There's no point in generating secondary ranges if external_mapping
-           is enabled. */
-        ctx->idmap_domain_info->auto_add_ranges = false;
-        return IDMAP_SUCCESS;
-    }
-
-    if ((range->max - range->min + 1) != ctx->idmap_opts.rangesize) {
-        /* Range of primary slice is not equal to the value of
-           ldap_idmap_range_size option. */
-        return IDMAP_ERROR;
-    }
-
-    /* No additional secondary ranges should be added if no sec ranges are
-       predeclared. */
-    if (ctx->idmap_opts.extra_slice_init == 0) {
-        ctx->idmap_domain_info->auto_add_ranges = false;
-        return IDMAP_SUCCESS;
-    }
-
-    /* Add size of primary slice for first_rid of secondary slices. */
-    rid += ctx->idmap_opts.rangesize;
-    err = get_helpers(ctx, domain_sid, rid,
-                      &ctx->idmap_domain_info->helpers);
-    if (err == IDMAP_SUCCESS) {
-        ctx->idmap_domain_info->auto_add_ranges = true;
-        ctx->idmap_domain_info->helpers_owner = true;
-    } else {
-        /* Running out of slices for secondary mapping is a non-fatal
-         * problem. */
-        if (err == IDMAP_OUT_OF_SLICES) {
-            err = IDMAP_SUCCESS;
-        }
-        ctx->idmap_domain_info->auto_add_ranges = false;
-    }
-
-    ctx->idmap_domain_info->cb = cb;
-    ctx->idmap_domain_info->pvt = pvt;
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx,
-                                           const char *domain_name,
-                                           const char *domain_sid,
-                                           struct sss_idmap_range *range)
-{
-    return sss_idmap_add_domain_ex(ctx, domain_name, domain_sid, range, NULL,
-                                   0, false);
-}
-
-static bool sss_idmap_sid_is_builtin(const char *sid)
-{
-    if (strncmp(sid, "S-1-5-32-", 9) == 0) {
-        return true;
-    }
-
-    return false;
-}
-
-static bool parse_rid(const char *sid, size_t dom_prefix_len, long long *_rid)
-{
-    long long rid;
-    char *endptr;
-
-    errno = 0;
-    /* Use suffix of sid - part after domain and following '-' */
-    rid = strtoull(sid + dom_prefix_len + 1, &endptr, 10);
-    if (errno != 0 || rid > UINT32_MAX || *endptr != '\0') {
-        return false;
-    }
-
-    *_rid = rid;
-    return true;
-}
-
-static bool is_from_dom(const char *domain_id, const char *id)
-{
-    if (domain_id == NULL) {
-        return false;
-    }
-
-    return strcmp(domain_id, id) == 0;
-}
-
-static bool is_sid_from_dom(const char *dom_sid, const char *sid,
-                            size_t *_dom_sid_len)
-{
-    size_t dom_sid_len;
-
-    if (dom_sid == NULL) {
-        return false;
-    }
-
-    dom_sid_len = strlen(dom_sid);
-    *_dom_sid_len = dom_sid_len;
-
-    if (strlen(sid) < dom_sid_len || sid[dom_sid_len] != '-') {
-        return false;
-    }
-
-    return strncmp(sid, dom_sid, dom_sid_len) == 0;
-}
-
-static bool comp_id(struct idmap_range_params *range_params, long long rid,
-                    uint32_t *_id)
-{
-    uint32_t id;
-
-    if (rid >= range_params->first_rid
-            && ((UINT32_MAX - range_params->min_id) >
-               (rid - range_params->first_rid))) {
-        id = range_params->min_id + (rid - range_params->first_rid);
-        if (id <= range_params->max_id) {
-            *_id = id;
-            return true;
-        }
-    }
-    return false;
-}
-
-static enum idmap_error_code
-get_range(struct sss_idmap_ctx *ctx,
-          struct idmap_range_params *helpers,
-          const char *dom_sid,
-          long long rid,
-          struct idmap_range_params **_range)
-{
-    char *secondary_name = NULL;
-    enum idmap_error_code err;
-    int first_rid;
-    struct idmap_range_params *range;
-    struct idmap_range_params *helper;
-
-    first_rid = (rid / ctx->idmap_opts.rangesize) * ctx->idmap_opts.rangesize;
-
-    secondary_name = generate_sec_slice_name(ctx, dom_sid, first_rid);
-    if (secondary_name == NULL) {
-        err = IDMAP_OUT_OF_MEMORY;
-        goto error;
-    }
-
-    helper = get_helper_by_id(helpers, secondary_name);
-    if (helper != NULL) {
-        /* Utilize helper's range. */
-        err = construct_range(ctx, helper, secondary_name, &range);
-    } else {
-        /* Have to generate a whole new range. */
-        err = generate_slice(ctx, secondary_name, first_rid, &range);
-    }
-
-    if (err != IDMAP_SUCCESS) {
-        goto error;
-    }
-
-    *_range = range;
-    return IDMAP_SUCCESS;
-
-error:
-    ctx->free_func(secondary_name, ctx->alloc_pvt);
-    return err;
-}
-
-static enum idmap_error_code
-spawn_dom(struct sss_idmap_ctx *ctx,
-          struct idmap_domain_info *parent,
-          struct idmap_range_params *range)
-{
-    struct sss_idmap_range tmp;
-    static enum idmap_error_code err;
-    struct idmap_domain_info *it;
-
-    tmp.min = range->min_id;
-    tmp.max = range->max_id;
-
-    err = sss_idmap_add_domain_ex(ctx,
-                                  parent->name,
-                                  parent->sid,
-                                  &tmp, range->range_id,
-                                  range->first_rid, false);
-    if (err != IDMAP_SUCCESS) {
-        return err;
-    }
-
-    it = ctx->idmap_domain_info;
-    while (it != NULL) {
-        /* Find the newly added domain. */
-        if (ranges_eq(&it->range_params, range)) {
-
-            /* Share helpers. */
-            it->helpers = parent->helpers;
-            it->auto_add_ranges = parent->auto_add_ranges;
-
-            /* Share call back for storing domains */
-            it->cb = parent->cb;
-            it->pvt = parent->pvt;
-            break;
-        }
-
-        it = it->next;
-    }
-
-    if (it == NULL) {
-        /* Failed to find just added domain. */
-        return IDMAP_ERROR;
-    }
-
-    /* Store mapping for newly created domain. */
-    if (it->cb != NULL) {
-        err = it->cb(it->name,
-                     it->sid,
-                     it->range_params.range_id,
-                     it->range_params.min_id,
-                     it->range_params.max_id,
-                     it->range_params.first_rid,
-                     it->pvt);
-        if (err != IDMAP_SUCCESS) {
-            return err;
-        }
-    }
-
-    return IDMAP_SUCCESS;
-}
-
-static enum idmap_error_code
-add_dom_for_sid(struct sss_idmap_ctx *ctx,
-                struct idmap_domain_info *matched_dom,
-                const char *sid,
-                uint32_t *_id)
-{
-    enum idmap_error_code err;
-    long long rid;
-    struct idmap_range_params *range = NULL;
-
-    if (parse_rid(sid, strlen(matched_dom->sid), &rid) == false) {
-        err = IDMAP_SID_INVALID;
-        goto done;
-    }
-
-    err = get_range(ctx, matched_dom->helpers, matched_dom->sid, rid, &range);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = spawn_dom(ctx, matched_dom, range);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    if (!comp_id(range, rid, _id)) {
-        err = IDMAP_ERROR;
-        goto done;
-    }
-
-    err =  IDMAP_SUCCESS;
-
-done:
-    if (range != NULL) {
-        ctx->free_func(range->range_id, ctx->alloc_pvt);
-    }
-    ctx->free_func(range, ctx->alloc_pvt);
-    return err;
-}
-
-enum idmap_error_code offset_identity(void *pvt, uint32_t range_size,
-                                      const char *input, long long *offset)
-{
-    long long out;
-    char *endptr;
-
-    if (input == NULL || offset == NULL) {
-        return IDMAP_ERROR;
-    }
-
-    errno = 0;
-    out = strtoull(input, &endptr, 10);
-    if (errno != 0 || out >= range_size || *endptr != '\0'
-                   || endptr == input) {
-        return IDMAP_ERROR;
-    }
-
-    *offset = out;
-
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code rev_offset_identity(struct sss_idmap_ctx *ctx, void *pvt,
-                                          uint32_t id, char **_out)
-{
-    char *out;
-    int len;
-    int ret;
-
-    len = snprintf(NULL, 0, "%"PRIu32, id);
-    if (len <= 0 || len > SID_STR_MAX_LEN) {
-        return IDMAP_ERROR;
-    }
-
-    out = ctx->alloc_func(len + 1, ctx->alloc_pvt);
-    if (out == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-
-    ret = snprintf(out, len + 1, "%"PRIu32, id);
-    if (ret != len) {
-        ctx->free_func(out, ctx->alloc_pvt);
-        return IDMAP_ERROR;
-    }
-
-    *_out = out;
-    return IDMAP_SUCCESS;
-}
-
-static char *normalize_casefold(const char *input, bool normalize,
-                                bool casefold)
-{
-    if (casefold) {
-        return (char *) utf8proc_NFKC_Casefold((const utf8proc_uint8_t *) input);
-    }
-
-    if (normalize) {
-        return (char *) utf8proc_NFKC((const utf8proc_uint8_t *) input);
-    }
-
-    return NULL;
-}
-
-struct offset_murmurhash3_data offset_murmurhash3_data_default =
-                                                          { .seed = 0xdeadbeef,
-                                                            .normalize = true,
-                                                            .casefold = false };
-
-enum idmap_error_code offset_murmurhash3(void *pvt, uint32_t range_size,
-                                         const char *input, long long *offset)
-{
-    struct offset_murmurhash3_data *offset_murmurhash3_data;
-    long long out;
-    char *tmp = NULL;
-    const char *val;
-
-    if (input == NULL || offset == NULL) {
-        return IDMAP_ERROR;
-    }
-
-    if (pvt != NULL) {
-        offset_murmurhash3_data = (struct offset_murmurhash3_data *) pvt;
-    } else {
-        offset_murmurhash3_data = &offset_murmurhash3_data_default;
-    }
-
-    if (offset_murmurhash3_data->normalize || offset_murmurhash3_data->casefold) {
-        tmp = normalize_casefold(input, offset_murmurhash3_data->normalize,
-                                 offset_murmurhash3_data->casefold);
-        if (tmp == NULL) {
-            return IDMAP_UTF8_ERROR;
-        }
-    }
-
-    val = (tmp == NULL) ? input : tmp;
-
-    out = murmurhash3(val, strlen(val), offset_murmurhash3_data->seed);
-    free(tmp);
-
-    out %= range_size;
-
-    *offset = out;
-
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code sss_idmap_gen_to_unix(struct sss_idmap_ctx *ctx,
-                                            const char *domain_id,
-                                            const char *input,
-                                            uint32_t *_id)
-{
-    struct idmap_domain_info *idmap_domain_info;
-    struct idmap_domain_info *matched_dom = NULL;
-    long long offset;
-    uint32_t range_size;
-    enum idmap_error_code err;
-    idmap_offset_func *offset_func = offset_murmurhash3;
-    void *offset_func_pvt = NULL;
-
-    if (domain_id == NULL || input == NULL || _id == NULL) {
-        return IDMAP_ERROR;
-    }
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    idmap_domain_info = ctx->idmap_domain_info;
-
-    if (idmap_domain_info->offset_func != NULL) {
-        offset_func = idmap_domain_info->offset_func;
-        if (idmap_domain_info->offset_func_pvt != NULL) {
-            offset_func_pvt = idmap_domain_info->offset_func_pvt;
-        }
-    }
-
-    /* Try primary slices */
-    while (idmap_domain_info != NULL) {
-
-        if (is_from_dom(idmap_domain_info->sid, domain_id)) {
-
-            if (idmap_domain_info->external_mapping == true) {
-                return IDMAP_EXTERNAL;
-            }
-
-            range_size = 1 + (idmap_domain_info->range_params.max_id - idmap_domain_info->range_params.min_id);
-            err = offset_func(offset_func_pvt, range_size, input, &offset);
-            if (err != IDMAP_SUCCESS) {
-                return err;
-            }
-
-            if (offset >= range_size) {
-                return IDMAP_ERROR;
-            }
-
-            if (comp_id(&idmap_domain_info->range_params, offset, _id)) {
-                return IDMAP_SUCCESS;
-            }
-
-            matched_dom = idmap_domain_info;
-        }
-
-        idmap_domain_info = idmap_domain_info->next;
-    }
-
-    return matched_dom ? IDMAP_NO_RANGE : IDMAP_NO_DOMAIN;
-}
-
-enum idmap_error_code sss_idmap_unix_to_gen(struct sss_idmap_ctx *ctx,
-                                            uint32_t id,
-                                            char **_out)
-{
-    struct idmap_domain_info *idmap_domain_info;
-    uint32_t offset;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    idmap_domain_info = ctx->idmap_domain_info;
-
-    while (idmap_domain_info != NULL) {
-        if (id_is_in_range(id, &idmap_domain_info->range_params, &offset)) {
-
-            if (idmap_domain_info->external_mapping == true
-                    || idmap_domain_info->sid == NULL) {
-                return IDMAP_EXTERNAL;
-            }
-
-            if (idmap_domain_info->rev_offset_func == NULL) {
-                return IDMAP_NO_REVERSE;
-            }
-
-            return idmap_domain_info->rev_offset_func(ctx,
-                                             idmap_domain_info->offset_func_pvt,
-                                             offset, _out);
-        }
-
-        idmap_domain_info = idmap_domain_info->next;
-    }
-
-    return IDMAP_NO_DOMAIN;
-}
-
-enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                            const char *sid,
-                                            uint32_t *_id)
-{
-    struct idmap_domain_info *idmap_domain_info;
-    struct idmap_domain_info *matched_dom = NULL;
-    size_t dom_len;
-    long long rid;
-
-    if (sid == NULL || _id == NULL) {
-        return IDMAP_ERROR;
-    }
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    idmap_domain_info = ctx->idmap_domain_info;
-
-    if (sss_idmap_sid_is_builtin(sid)) {
-        return IDMAP_BUILTIN_SID;
-    }
-
-    /* Try primary slices */
-    while (idmap_domain_info != NULL) {
-
-        if (is_sid_from_dom(idmap_domain_info->sid, sid, &dom_len)) {
-
-            if (idmap_domain_info->external_mapping == true) {
-                return IDMAP_EXTERNAL;
-            }
-
-            if (parse_rid(sid, dom_len, &rid) == false) {
-                return IDMAP_SID_INVALID;
-            }
-
-            if (comp_id(&idmap_domain_info->range_params, rid, _id)) {
-                return IDMAP_SUCCESS;
-            }
-
-            matched_dom = idmap_domain_info;
-        }
-
-        idmap_domain_info = idmap_domain_info->next;
-    }
-
-    if (matched_dom != NULL && matched_dom->auto_add_ranges) {
-        return add_dom_for_sid(ctx, matched_dom, sid, _id);
-    }
-
-    return matched_dom ? IDMAP_NO_RANGE : IDMAP_NO_DOMAIN;
-}
-
-enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx,
-                                               const char *sid,
-                                               uint32_t id)
-{
-    struct idmap_domain_info *idmap_domain_info;
-    size_t dom_len;
-    bool no_range = false;
-
-    if (sid == NULL) {
-        return IDMAP_ERROR;
-    }
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (ctx->idmap_domain_info == NULL) {
-        return IDMAP_NO_DOMAIN;
-    }
-
-    idmap_domain_info = ctx->idmap_domain_info;
-
-    if (sss_idmap_sid_is_builtin(sid)) {
-        return IDMAP_BUILTIN_SID;
-    }
-
-    while (idmap_domain_info != NULL) {
-        if (idmap_domain_info->sid != NULL) {
-            dom_len = strlen(idmap_domain_info->sid);
-            if (strlen(sid) > dom_len && sid[dom_len] == '-'
-                    && strncmp(sid, idmap_domain_info->sid, dom_len) == 0) {
-
-                if (id >= idmap_domain_info->range_params.min_id
-                    && id <= idmap_domain_info->range_params.max_id) {
-                    return IDMAP_SUCCESS;
-                }
-
-                no_range = true;
-            }
-        }
-
-        idmap_domain_info = idmap_domain_info->next;
-    }
-
-    return no_range ? IDMAP_NO_RANGE : IDMAP_SID_UNKNOWN;
-}
-
-static enum idmap_error_code generate_sid(struct sss_idmap_ctx *ctx,
-                                          const char *dom_sid,
-                                          uint32_t rid,
-                                          char **_sid)
-{
-    char *sid;
-    int len;
-    int ret;
-
-    len = snprintf(NULL, 0, SID_FMT, dom_sid, rid);
-    if (len <= 0 || len > SID_STR_MAX_LEN) {
-        return IDMAP_ERROR;
-    }
-
-    sid = ctx->alloc_func(len + 1, ctx->alloc_pvt);
-    if (sid == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-
-    ret = snprintf(sid, len + 1, SID_FMT, dom_sid, rid);
-    if (ret != len) {
-        ctx->free_func(sid, ctx->alloc_pvt);
-        return IDMAP_ERROR;
-    }
-
-    *_sid = sid;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
-                                            uint32_t id,
-                                            char **_sid)
-{
-    struct idmap_domain_info *idmap_domain_info;
-    uint32_t rid;
-    enum idmap_error_code err;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    idmap_domain_info = ctx->idmap_domain_info;
-
-    while (idmap_domain_info != NULL) {
-        if (id_is_in_range(id, &idmap_domain_info->range_params, &rid)) {
-
-            if (idmap_domain_info->external_mapping == true
-                    || idmap_domain_info->sid == NULL) {
-                return IDMAP_EXTERNAL;
-            }
-
-            return generate_sid(ctx, idmap_domain_info->sid, rid, _sid);
-        }
-
-        idmap_domain_info = idmap_domain_info->next;
-    }
-
-    /* Check secondary ranges. */
-    idmap_domain_info = ctx->idmap_domain_info;
-    while (idmap_domain_info != NULL) {
-
-        for (struct idmap_range_params *it = idmap_domain_info->helpers;
-             it != NULL;
-             it = it->next) {
-
-            if (idmap_domain_info->helpers_owner == false) {
-                /* Checking helpers on owner is sufficient. */
-                continue;
-            }
-
-            if (id_is_in_range(id, it, &rid)) {
-
-                if (idmap_domain_info->external_mapping == true
-                    || idmap_domain_info->sid == NULL) {
-                    return IDMAP_EXTERNAL;
-                }
-
-                err = spawn_dom(ctx, idmap_domain_info, it);
-                if (err != IDMAP_SUCCESS) {
-                    return err;
-                }
-
-                return generate_sid(ctx, idmap_domain_info->sid, rid, _sid);
-            }
-        }
-
-        idmap_domain_info = idmap_domain_info->next;
-    }
-
-    return IDMAP_NO_DOMAIN;
-}
-
-enum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                                struct sss_dom_sid *dom_sid,
-                                                uint32_t *id)
-{
-    enum idmap_error_code err;
-    char *sid;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_sid_to_unix(ctx, sid, id);
-
-done:
-    ctx->free_func(sid, ctx->alloc_pvt);
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_bin_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                                uint8_t *bin_sid,
-                                                size_t length,
-                                                uint32_t *id)
-{
-    enum idmap_error_code err;
-    char *sid;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    err = sss_idmap_bin_sid_to_sid(ctx, bin_sid, length, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_sid_to_unix(ctx, sid, id);
-
-done:
-    ctx->free_func(sid, ctx->alloc_pvt);
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_smb_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                                struct dom_sid *smb_sid,
-                                                uint32_t *id)
-{
-    enum idmap_error_code err;
-    char *sid;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    err = sss_idmap_smb_sid_to_sid(ctx, smb_sid, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_sid_to_unix(ctx, sid, id);
-
-done:
-    ctx->free_func(sid, ctx->alloc_pvt);
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_check_dom_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                                    struct sss_dom_sid *dom_sid,
-                                                    uint32_t id)
-{
-    enum idmap_error_code err;
-    char *sid;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_check_sid_unix(ctx, sid, id);
-
-done:
-    ctx->free_func(sid, ctx->alloc_pvt);
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_check_bin_sid_unix(struct sss_idmap_ctx *ctx,
-                                                   uint8_t *bin_sid,
-                                                   size_t length,
-                                                   uint32_t id)
-{
-    enum idmap_error_code err;
-    char *sid;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    err = sss_idmap_bin_sid_to_sid(ctx, bin_sid, length, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_check_sid_unix(ctx, sid, id);
-
-done:
-    ctx->free_func(sid, ctx->alloc_pvt);
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_check_smb_sid_unix(struct sss_idmap_ctx *ctx,
-                                                   struct dom_sid *smb_sid,
-                                                   uint32_t id)
-{
-    enum idmap_error_code err;
-    char *sid;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    err = sss_idmap_smb_sid_to_sid(ctx, smb_sid, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_check_sid_unix(ctx, sid, id);
-
-done:
-    ctx->free_func(sid, ctx->alloc_pvt);
-
-    return err;
-}
-enum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx,
-                                                uint32_t id,
-                                                struct sss_dom_sid **_dom_sid)
-{
-    enum idmap_error_code err;
-    char *sid = NULL;
-    struct sss_dom_sid *dom_sid = NULL;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    err = sss_idmap_unix_to_sid(ctx, id, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    *_dom_sid = dom_sid;
-    err = IDMAP_SUCCESS;
-
-done:
-    ctx->free_func(sid, ctx->alloc_pvt);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(dom_sid, ctx->alloc_pvt);
-    }
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_unix_to_bin_sid(struct sss_idmap_ctx *ctx,
-                                                uint32_t id,
-                                                uint8_t **_bin_sid,
-                                                size_t *_length)
-{
-    enum idmap_error_code err;
-    char *sid = NULL;
-    uint8_t *bin_sid = NULL;
-    size_t length;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    err = sss_idmap_unix_to_sid(ctx, id, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_sid_to_bin_sid(ctx, sid, &bin_sid, &length);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    *_bin_sid = bin_sid;
-    *_length = length;
-    err = IDMAP_SUCCESS;
-
-done:
-    ctx->free_func(sid, ctx->alloc_pvt);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(bin_sid, ctx->alloc_pvt);
-    }
-
-    return err;
-
-}
-
-enum idmap_error_code
-sss_idmap_ctx_set_autorid(struct sss_idmap_ctx *ctx, bool use_autorid)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-    ctx->idmap_opts.autorid_mode = use_autorid;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_ctx_set_lower(struct sss_idmap_ctx *ctx, id_t lower)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-    ctx->idmap_opts.idmap_lower = lower;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_ctx_set_upper(struct sss_idmap_ctx *ctx, id_t upper)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-    ctx->idmap_opts.idmap_upper = upper;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t rangesize)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-    ctx->idmap_opts.rangesize = rangesize;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_ctx_set_extra_slice_init(struct sss_idmap_ctx *ctx,
-                                  int extra_slice_init)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-    ctx->idmap_opts.extra_slice_init = extra_slice_init;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_ctx_get_autorid(struct sss_idmap_ctx *ctx, bool *_autorid)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-     *_autorid = ctx->idmap_opts.autorid_mode;
-     return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_ctx_get_lower(struct sss_idmap_ctx *ctx, id_t *_lower)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-    *_lower = ctx->idmap_opts.idmap_lower;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_ctx_get_upper(struct sss_idmap_ctx *ctx, id_t *_upper)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-    *_upper = ctx->idmap_opts.idmap_upper;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_ctx_get_rangesize(struct sss_idmap_ctx *ctx, id_t *_rangesize)
-{
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-    *_rangesize =  ctx->idmap_opts.rangesize;
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code
-sss_idmap_domain_has_algorithmic_mapping(struct sss_idmap_ctx *ctx,
-                                         const char *dom_sid,
-                                         bool *has_algorithmic_mapping)
-{
-    struct idmap_domain_info *idmap_domain_info;
-    size_t len;
-    size_t dom_sid_len;
-
-    if (dom_sid == NULL) {
-        return IDMAP_SID_INVALID;
-    }
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (ctx->idmap_domain_info == NULL) {
-        return IDMAP_NO_DOMAIN;
-    }
-
-    idmap_domain_info = ctx->idmap_domain_info;
-
-    while (idmap_domain_info != NULL) {
-        if (idmap_domain_info->sid != NULL) {
-            len = strlen(idmap_domain_info->sid);
-            dom_sid_len = strlen(dom_sid);
-            if (((dom_sid_len > len && dom_sid[len] == '-')
-                        || dom_sid_len == len)
-                    && strncmp(dom_sid, idmap_domain_info->sid, len) == 0) {
-
-                *has_algorithmic_mapping = !idmap_domain_info->external_mapping;
-                return IDMAP_SUCCESS;
-
-            }
-        }
-
-        idmap_domain_info = idmap_domain_info->next;
-    }
-
-    return IDMAP_SID_UNKNOWN;
-}
-
-enum idmap_error_code
-sss_idmap_domain_by_name_has_algorithmic_mapping(struct sss_idmap_ctx *ctx,
-                                                 const char *dom_name,
-                                                 bool *has_algorithmic_mapping)
-{
-    struct idmap_domain_info *idmap_domain_info;
-
-    if (dom_name == NULL) {
-        return IDMAP_ERROR;
-    }
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (ctx->idmap_domain_info == NULL) {
-        return IDMAP_NO_DOMAIN;
-    }
-
-    idmap_domain_info = ctx->idmap_domain_info;
-
-    while (idmap_domain_info != NULL) {
-        if (idmap_domain_info->name != NULL
-                && strcmp(dom_name, idmap_domain_info->name) == 0) {
-
-            *has_algorithmic_mapping = !idmap_domain_info->external_mapping;
-            return IDMAP_SUCCESS;
-        }
-
-        idmap_domain_info = idmap_domain_info->next;
-    }
-
-    return IDMAP_NAME_UNKNOWN;
-}
diff --git a/rust/idmap/src/sss_idmap.h b/rust/idmap/src/sss_idmap.h
deleted file mode 100644 (file)
index a94c07f..0000000
+++ /dev/null
@@ -1,1100 +0,0 @@
-/*
-    SSSD
-
-    ID-mapping library
-
-    Authors:
-        Sumit Bose <sbose@redhat.com>
-
-    Copyright (C) 2012 Red Hat
-
-    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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef SSS_IDMAP_H_
-#define SSS_IDMAP_H_
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h>
-
-#define DOM_SID_PREFIX "S-1-5-21-"
-#define DOM_SID_PREFIX_LEN (sizeof(DOM_SID_PREFIX) - 1)
-
-/**
- * @defgroup sss_idmap Map Unix UIDs and GIDs to SIDs and back
- * Libsss_idmap provides a mechanism to translate a SID to a UNIX UID or GID
- * or the other way round.
- * @{
- */
-
-/**
- * Error codes used by libsss_idmap
- */
-enum idmap_error_code {
-    /** Success */
-    IDMAP_SUCCESS = 0,
-
-    /** Function is not yet implemented */
-    IDMAP_NOT_IMPLEMENTED,
-
-    /** General error */
-    IDMAP_ERROR,
-
-    /** Ran out of memory during processing */
-    IDMAP_OUT_OF_MEMORY,
-
-    /** No domain added */
-    IDMAP_NO_DOMAIN,
-
-    /** The provided idmap context is invalid */
-    IDMAP_CONTEXT_INVALID,
-
-    /** The provided SID is invalid */
-    IDMAP_SID_INVALID,
-
-    /** The provided  SID was not found */
-    IDMAP_SID_UNKNOWN,
-
-    /** The provided UID or GID could not be mapped */
-    IDMAP_NO_RANGE,
-
-    /** The provided SID is a built-in one */
-    IDMAP_BUILTIN_SID,
-
-    /** No more free slices */
-    IDMAP_OUT_OF_SLICES,
-
-    /** New domain collides with existing one */
-    IDMAP_COLLISION,
-
-    /** External source should be consulted for idmapping */
-    IDMAP_EXTERNAL,
-
-    /** The provided  name was not found */
-    IDMAP_NAME_UNKNOWN,
-
-    /** It is not possible to convert an id into the original value the id was
-     *  derived from */
-    IDMAP_NO_REVERSE,
-
-    /** Error during UTF8 operation like normalization or casefolding */
-    IDMAP_UTF8_ERROR,
-
-    /** Sentinel to indicate the end of the error code list, not returned by
-     * any call */
-    IDMAP_ERR_LAST
-};
-
-/**
- * Typedef for memory allocation functions
- */
-typedef void *(idmap_alloc_func)(size_t size, void *pvt);
-typedef void (idmap_free_func)(void *ptr, void *pvt);
-
-/**
- * Typedef for storing mappings of dynamically created domains
- */
-typedef enum idmap_error_code (*idmap_store_cb)(const char *dom_name,
-                                                const char *dom_sid,
-                                                const char *range_id,
-                                                uint32_t min_id,
-                                                uint32_t max_id,
-                                                uint32_t first_rid,
-                                                void *pvt);
-
-/**
- * Structure for id ranges
- * FIXME: this struct might change when it is clear how ranges are handled on
- * the server side
- */
-struct sss_idmap_range {
-    uint32_t min;
-    uint32_t max;
-};
-
-/**
- * Opaque type for SIDs
- */
-struct sss_dom_sid;
-
-/**
- * Opaque type for the idmap context
- */
-struct sss_idmap_ctx;
-
-/**
- * Placeholder for Samba's struct dom_sid. Consumers of libsss_idmap should
- * include an appropriate Samba header file to define struct dom_sid. We use
- * it here to avoid a hard dependency on Samba devel packages.
- */
-struct dom_sid;
-
-/**
- * @brief Initialize idmap context
- *
- * @param[in] alloc_func Function to allocate memory for the context, if
- *                       NULL malloc() id used
- * @param[in] alloc_pvt  Private data for allocation routine
- * @param[in] free_func  Function to free the memory the context, if
- *                       NULL free() id used
- * @param[out] ctx       idmap context
- *
- * @return
- *  - #IDMAP_OUT_OF_MEMORY: Insufficient memory to create the context
- */
-enum idmap_error_code sss_idmap_init(idmap_alloc_func *alloc_func,
-                                     void *alloc_pvt,
-                                     idmap_free_func *free_func,
-                                     struct sss_idmap_ctx **ctx);
-
-/**
- * @brief Set/unset autorid compatibility mode
- *
- * @param[in] ctx           idmap context
- * @param[in] use_autorid   If true, autorid compatibility mode will be used
- */
-enum idmap_error_code
-sss_idmap_ctx_set_autorid(struct sss_idmap_ctx *ctx, bool use_autorid);
-
-/**
- * @brief Set the lower bound of the range of POSIX IDs
- *
- * @param[in] ctx           idmap context
- * @param[in] lower         lower bound of the range
- */
-enum idmap_error_code
-sss_idmap_ctx_set_lower(struct sss_idmap_ctx *ctx, id_t lower);
-
-/**
- * @brief Set the upper bound of the range of POSIX IDs
- *
- * @param[in] ctx           idmap context
- * @param[in] upper         upper bound of the range
- */
-enum idmap_error_code
-sss_idmap_ctx_set_upper(struct sss_idmap_ctx *ctx, id_t upper);
-
-/**
- * @brief Set the range size of POSIX IDs available for single domain
- *
- * @param[in] ctx           idmap context
- * @param[in] rangesize     range size of IDs
- */
-enum idmap_error_code
-sss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t rangesize);
-
-/**
- * @brief Set the number of secondary slices available for domain
- *
- * @param[in] ctx                  idmap context
- * @param[in] extra_slice_init     number of secondary slices to be generated
- *                                 at startup
- */
-enum idmap_error_code
-sss_idmap_ctx_set_extra_slice_init(struct sss_idmap_ctx *ctx,
-                                  int extra_slice_init);
-
-/**
- * @brief Check if autorid compatibility mode is set
- *
- * @param[in] ctx           idmap context
- * @param[out] _autorid     true if autorid is used
- */
-enum idmap_error_code
-sss_idmap_ctx_get_autorid(struct sss_idmap_ctx *ctx, bool *_autorid);
-
-/**
- * @brief Get the lower bound of the range of POSIX IDs
- *
- * @param[in] ctx           idmap context
- * @param[out] _lower       returned lower bound
- */
-enum idmap_error_code
-sss_idmap_ctx_get_lower(struct sss_idmap_ctx *ctx, id_t *_lower);
-
-/**
- * @brief Get the upper bound of the range of POSIX IDs
- *
- * @param[in] ctx           idmap context
- * @param[out] _upper       returned upper bound
- */
-enum idmap_error_code
-sss_idmap_ctx_get_upper(struct sss_idmap_ctx *ctx, id_t *_upper);
-
-/**
- * @brief Get the range size of POSIX IDs available for single domain
- *
- * @param[in] ctx           idmap context
- * @param[out] rangesize    returned range size
- */
-enum idmap_error_code
-sss_idmap_ctx_get_rangesize(struct sss_idmap_ctx *ctx, id_t *rangesize);
-
-/**
- * @brief Calculate new range of available POSIX IDs
- *
- * @param[in] ctx           Idmap context
- * @param[in] dom_sid       Zero-terminated string representation of the domain
- *                          SID (S-1-15-.....)
- * @param[in,out] slice_num Slice number to be used. Set this pointer to NULL or
- *                          the addressed value to -1 to calculate slice number
- *                          automatically. The calculated value will be
- *                          returned in this parameter.
- * @param[out] range        Structure containing upper and lower bound of the
- *                          range of POSIX IDs
- *
- * @return
- *  - #IDMAP_OUT_OF_SLICES: Cannot calculate new range because all slices are
- *                          used.
- */
-enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
-                                                const char *dom_sid,
-                                                id_t *slice_num,
-                                                struct sss_idmap_range *range);
-
-/**
- * @brief Add a domain to the idmap context
- *
- * @param[in] ctx         Idmap context
- * @param[in] domain_name Zero-terminated string with the domain name
- * @param[in] domain_sid  Zero-terminated string representation of the domain
- *                        SID (S-1-15-.....)
- * @param[in] range       TBD Some information about the id ranges of this
- *                        domain
- *
- * @return
- *  - #IDMAP_OUT_OF_MEMORY: Insufficient memory to store the data in the idmap
- *                          context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_NO_DOMAIN:     No domain domain name given
- *  - #IDMAP_COLLISION:     New domain collides with existing one
- */
-enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx,
-                                           const char *domain_name,
-                                           const char *domain_sid,
-                                           struct sss_idmap_range *range);
-
-/**
- * @brief Add a domain with the first mappable RID to the idmap context
- *
- * @param[in] ctx         Idmap context
- * @param[in] domain_name Zero-terminated string with the domain name
- * @param[in] domain_sid  Zero-terminated string representation of the domain
- *                        SID (S-1-15-.....)
- * @param[in] range       TBD Some information about the id ranges of this
- *                        domain
- * @param[in] range_id    optional unique identifier of a range, it is needed
- *                        to allow updates at runtime
- * @param[in] rid         The RID that should be mapped to the first ID of the
- *                        given range.
- * @param[in] external_mapping  If set to true the ID will not be mapped
- *                        algorithmically, but the *_to_unix and *_unix_to_*
- *                        calls will return IDMAP_EXTERNAL to instruct the
- *                        caller to check external sources. For a single
- *                        domain all ranges must be of the same type. It is
- *                        not possible to mix algorithmic and external
- *                        mapping.
- *
- * @return
- *  - #IDMAP_OUT_OF_MEMORY: Insufficient memory to store the data in the idmap
- *                          context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_NO_DOMAIN:     No domain domain name given
- *  - #IDMAP_COLLISION:     New domain collides with existing one
- */
-enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx,
-                                              const char *domain_name,
-                                              const char *domain_sid,
-                                              struct sss_idmap_range *range,
-                                              const char *range_id,
-                                              uint32_t rid,
-                                              bool external_mapping);
-
-/**
- * @brief Add a domain with the first mappable RID to the idmap context and
- * generate automatically secondary slices
- *
- * @param[in] ctx         Idmap context
- * @param[in] domain_name Zero-terminated string with the domain name
- * @param[in] domain_sid  Zero-terminated string representation of the domain
- *                        SID (S-1-15-.....)
- * @param[in] range       TBD Some information about the id ranges of this
- *                        domain
- * @param[in] range_id    optional unique identifier of a range, it is needed
- *                        to allow updates at runtime
- * @param[in] rid         The RID that should be mapped to the first ID of the
- *                        given range.
- * @param[in] external_mapping  If set to true the ID will not be mapped
- *                        algorithmically, but the *_to_unix and *_unix_to_*
- *                        calls will return IDMAP_EXTERNAL to instruct the
- *                        caller to check external sources. For a single
- *                        domain all ranges must be of the same type. It is
- *                        not possible to mix algorithmic and external
- *                        mapping.
- * @param[in] cb          The callback for storing mapping of dynamically
- *                        created domains.
- * @param[in] pvt         Private data for callback cb.
- *
- * @return
- *  - #IDMAP_OUT_OF_MEMORY: Insufficient memory to store the data in the idmap
- *                          context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_NO_DOMAIN:     No domain domain name given
- *  - #IDMAP_COLLISION:     New domain collides with existing one
- */
-enum idmap_error_code
-sss_idmap_add_auto_domain_ex(struct sss_idmap_ctx *ctx,
-                             const char *domain_name,
-                             const char *domain_sid,
-                             struct sss_idmap_range *range,
-                             const char *range_id,
-                             uint32_t rid,
-                             bool external_mapping,
-                             idmap_store_cb cb,
-                             void *pvt);
-
-/**
- * @brief Check if a new range would collide with any existing one
- *
- * @param[in] ctx         Idmap context
- * @param[in] n_name      Zero-terminated string with the domain name the new
- *                        range should belong to
- * @param[in] n_sid       Zero-terminated string representation of the domain
- *                        SID (S-1-15-.....) the new range should belong to
- * @param[in] n_range     The new id range
- * @param[in] n_range_id  unique identifier of the new range, it is needed
- *                        to allow updates at runtime, may be NULL
- * @param[in] n_first_rid The RID that should be mapped to the first ID of the
- *                        new range.
- * @param[in] n_external_mapping Mapping type of the new range
- *
- * @return
- *  - #IDMAP_COLLISION:     New range collides with existing one
- */
-enum idmap_error_code sss_idmap_check_collision(struct sss_idmap_ctx *ctx,
-                                                char *n_name, char *n_sid,
-                                                struct sss_idmap_range *n_range,
-                                                uint32_t n_first_rid,
-                                                char *n_range_id,
-                                                bool n_external_mapping);
-
-/**
- * @brief Check if two ranges would collide
- *
- * @param[in] o_name      Zero-terminated string with the domain name the
- *                        first range should belong to
- * @param[in] o_sid       Zero-terminated string representation of the domain
- *                        SID (S-1-15-.....) the first range should belong to
- * @param[in] o_range     The first id range
- * @param[in] o_range_id  unique identifier of the first range, it is needed
- *                        to allow updates at runtime, may be NULL
- * @param[in] o_first_rid The RID that should be mapped to the first ID of the
- *                        first range.
- * @param[in] o_external_mapping Mapping type of the first range
- * @param[in] n_name      Zero-terminated string with the domain name the
- *                        second range should belong to
- * @param[in] n_sid       Zero-terminated string representation of the domain
- *                        SID (S-1-15-.....) the second range should belong to
- * @param[in] n_range     The second id range
- * @param[in] n_range_id  unique identifier of the second range, it is needed
- *                        to allow updates at runtime, may be NULL
- * @param[in] n_first_rid The RID that should be mapped to the first ID of the
- *                        second range.
- * @param[in] n_external_mapping Mapping type of the second range
- *
- * @return
- *  - #IDMAP_COLLISION:     New range collides with existing one
- */
-enum idmap_error_code sss_idmap_check_collision_ex(const char *o_name,
-                                                const char *o_sid,
-                                                struct sss_idmap_range *o_range,
-                                                uint32_t o_first_rid,
-                                                const char *o_range_id,
-                                                bool o_external_mapping,
-                                                const char *n_name,
-                                                const char *n_sid,
-                                                struct sss_idmap_range *n_range,
-                                                uint32_t n_first_rid,
-                                                const char *n_range_id,
-                                                bool n_external_mapping);
-
-/**
- * @brief Translate SID to a unix UID or GID
- *
- * @param[in] ctx Idmap context
- * @param[in] sid Zero-terminated string representation of the SID
- * @param[out] id Returned unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domains are added to the idmap context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_SID_UNKNOWN:   SID cannot be found in the domains added to the
- *                          idmap context
- *  - #IDMAP_EXTERNAL:      external source is authoritative for mapping
- */
-enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                            const char *sid,
-                                            uint32_t *id);
-
-/**
- * @brief Translate a SID structure to a unix UID or GID
- *
- * @param[in] ctx     Idmap context
- * @param[in] dom_sid SID structure
- * @param[out] id     Returned unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domains are added to the idmap context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_SID_UNKNOWN:   SID cannot be found in the domains added to the
- *                          idmap context
- *  - #IDMAP_EXTERNAL:      external source is authoritative for mapping
- */
-enum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                                struct sss_dom_sid *dom_sid,
-                                                uint32_t *id);
-
-/**
- * @brief Translate a binary SID to a unix UID or GID
- *
- * @param[in] ctx     Idmap context
- * @param[in] bin_sid Array with the binary SID
- * @param[in] length  Size of the array containing the binary SID
- * @param[out] id     Returned unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domains are added to the idmap context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_SID_UNKNOWN:   SID cannot be found in the domains added to the
- *                          idmap context
- *  - #IDMAP_EXTERNAL:      external source is authoritative for mapping
- */
-enum idmap_error_code sss_idmap_bin_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                                uint8_t *bin_sid,
-                                                size_t length,
-                                                uint32_t *id);
-
-/**
- * @brief Translate a Samba dom_sid structure to a unix UID or GID
- *
- * @param[in] ctx     Idmap context
- * @param[in] smb_sid Samba dom_sid structure
- * @param[out] id     Returned unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domains are added to the idmap context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_SID_UNKNOWN:   SID cannot be found in the domains added to the
- *                          idmap context
- *  - #IDMAP_EXTERNAL:      external source is authoritative for mapping
- */
-enum idmap_error_code sss_idmap_smb_sid_to_unix(struct sss_idmap_ctx *ctx,
-                                                struct dom_sid *smb_sid,
-                                                uint32_t *id);
-
-/**
- * @brief Check if a SID and a unix UID or GID belong to the same range
- *
- * @param[in] ctx Idmap context
- * @param[in] sid Zero-terminated string representation of the SID
- * @param[in] id  Unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domains are added to the idmap context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_SID_UNKNOWN:   SID cannot be found in the domains added to the
- *                          idmap context
- *  - #IDMAP_NO_RANGE       No matching ID range found
- */
-enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx,
-                                               const char *sid,
-                                               uint32_t id);
-
-/**
- * @brief Check if a SID structure and a unix UID or GID belong to the same range
- *
- * @param[in] ctx     Idmap context
- * @param[in] dom_sid SID structure
- * @param[in] id      Unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domains are added to the idmap context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_SID_UNKNOWN:   SID cannot be found in the domains added to the
- *                          idmap context
- *  - #IDMAP_NO_RANGE       No matching ID range found
- */
-enum idmap_error_code sss_idmap_check_dom_sid_unix(struct sss_idmap_ctx *ctx,
-                                                   struct sss_dom_sid *dom_sid,
-                                                   uint32_t id);
-
-/**
- * @brief Check if a binary SID and a unix UID or GID belong to the same range
- *
- * @param[in] ctx     Idmap context
- * @param[in] bin_sid Array with the binary SID
- * @param[in] length  Size of the array containing the binary SID
- * @param[in] id      Unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domains are added to the idmap context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_SID_UNKNOWN:   SID cannot be found in the domains added to the
- *                          idmap context
- *  - #IDMAP_NO_RANGE       No matching ID range found
- */
-enum idmap_error_code sss_idmap_check_bin_sid_unix(struct sss_idmap_ctx *ctx,
-                                                   uint8_t *bin_sid,
-                                                   size_t length,
-                                                   uint32_t id);
-
-/**
- * @brief Check if a Samba dom_sid structure and a unix UID or GID belong to
- * the same range
- *
- * @param[in] ctx     Idmap context
- * @param[in] smb_sid Samba dom_sid structure
- * @param[in] id      Unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domains are added to the idmap context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_SID_UNKNOWN:   SID cannot be found in the domains added to the
- *                          idmap context
- *  - #IDMAP_NO_RANGE       No matching ID range found
- */
-enum idmap_error_code sss_idmap_check_smb_sid_unix(struct sss_idmap_ctx *ctx,
-                                                   struct dom_sid *smb_sid,
-                                                   uint32_t id);
-
-/**
- * @brief Translate unix UID or GID to a SID
- *
- * @param[in] ctx  Idmap context
- * @param[in] id   unix UID or GID
- * @param[out] sid Zero-terminated string representation of the SID, must be
- *                 freed if not needed anymore
- *
- * @return
- *  - #IDMAP_NO_DOMAIN: No domains are added to the idmap context
- *  - #IDMAP_NO_RANGE:  The provided ID cannot be found in the domains added
- *                      to the idmap context
- *  - #IDMAP_EXTERNAL:  external source is authoritative for mapping
- */
-enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
-                                            uint32_t id,
-                                            char **sid);
-
-/**
- * @brief Translate unix UID or GID to a SID structure
- *
- * @param[in] ctx      Idmap context
- * @param[in] id       unix UID or GID
- * @param[out] dom_sid SID structure, must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_NO_DOMAIN: No domains are added to the idmap context
- *  - #IDMAP_NO_RANGE:  The provided ID cannot be found in the domains added
- *                      to the idmap context
- *  - #IDMAP_EXTERNAL:  external source is authoritative for mapping
- */
-enum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx,
-                                                uint32_t id,
-                                                struct sss_dom_sid **dom_sid);
-
-/**
- * @brief Translate unix UID or GID to a binary SID
- *
- * @param[in] ctx      Idmap context
- * @param[in] id       unix UID or GID
- * @param[out] bin_sid Array with the binary SID,
- *                     must be freed if not needed anymore
- * @param[out] length  size of the array containing the binary SID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN: No domains are added to the idmap context
- *  - #IDMAP_NO_RANGE:  The provided ID cannot be found in the domains added
- *                      to the idmap context
- *  - #IDMAP_EXTERNAL:  external source is authoritative for mapping
- */
-enum idmap_error_code sss_idmap_unix_to_bin_sid(struct sss_idmap_ctx *ctx,
-                                                uint32_t id,
-                                                uint8_t **bin_sid,
-                                                size_t *length);
-
-/**
- * @brief Free all the allocated memory of the idmap context
- *
- * @param[in] ctx         Idmap context
- *
- * @return
- *  - #IDMAP_CONTEXT_INVALID: Provided context is invalid
- */
-enum idmap_error_code sss_idmap_free(struct sss_idmap_ctx *ctx);
-
-/**
- * @brief Free mapped SID.
- *
- * @param[in] ctx         Idmap context
- * @param[in] sid         SID to be freed.
- *
- * @return
- *  - #IDMAP_CONTEXT_INVALID: Provided context is invalid
- */
-enum idmap_error_code sss_idmap_free_sid(struct sss_idmap_ctx *ctx,
-                                         char *sid);
-
-/**
- * @brief Free mapped domain SID.
- *
- * @param[in] ctx         Idmap context
- * @param[in] dom_sid     Domain SID to be freed.
- *
- * @return
- *  - #IDMAP_CONTEXT_INVALID: Provided context is invalid
- */
-enum idmap_error_code sss_idmap_free_dom_sid(struct sss_idmap_ctx *ctx,
-                                             struct sss_dom_sid *dom_sid);
-
-/**
- * @brief Free mapped Samba SID.
- *
- * @param[in] ctx         Idmap context
- * @param[in] smb_sid     Samba SID to be freed.
- *
- * @return
- *  - #IDMAP_CONTEXT_INVALID: Provided context is invalid
- */
-enum idmap_error_code sss_idmap_free_smb_sid(struct sss_idmap_ctx *ctx,
-                                             struct dom_sid *smb_sid);
-
-/**
- * @brief Free mapped binary SID.
- *
- * @param[in] ctx         Idmap context
- * @param[in] bin_sid     Binary SID to be freed.
- *
- * @return
- *  - #IDMAP_CONTEXT_INVALID: Provided context is invalid
- */
-enum idmap_error_code sss_idmap_free_bin_sid(struct sss_idmap_ctx *ctx,
-                                             uint8_t *bin_sid);
-
-/**
- * @brief Translate error code to a string
- *
- * @param[in] err  Idmap error code
- *
- * @return
- *  - Error description as a zero-terminated string
- */
-const char *idmap_error_string(enum idmap_error_code err);
-
-/**
- * @brief Check if given string can be used as domain SID
- *
- * @param[in] str   String to check
- *
- * @return
- *  - true: String can be used as domain SID
- *  - false: String can not be used as domain SID
- */
-bool is_domain_sid(const char *str);
-
-/**
- * @brief Check if a domain is configured with algorithmic mapping
- *
- * @param[in] ctx                      Idmap context
- * @param[in] dom_sid                  SID string, can be either a domain SID
- *                                     or an object SID
- * @param[out] has_algorithmic_mapping Boolean value indicating if the given
- *                                     domain is configured for algorithmic
- *                                     mapping or not.
- *
- * @return
- *  - #IDMAP_SUCCESS:         Domain for the given SID was found and
- *                            has_algorithmic_mapping is set accordingly
- *  - #IDMAP_SID_INVALID:     Provided SID is invalid
- *  - #IDMAP_CONTEXT_INVALID: Provided idmap context is invalid
- *  - #IDMAP_NO_DOMAIN:       No domains are available in the idmap context
- *  - #IDMAP_SID_UNKNOWN:     No domain with the given SID was found in the
- *                            idmap context
- */
-enum idmap_error_code
-sss_idmap_domain_has_algorithmic_mapping(struct sss_idmap_ctx *ctx,
-                                         const char *dom_sid,
-                                         bool *has_algorithmic_mapping);
-
-/**
- * @brief Check if a domain is configured with algorithmic mapping
- *
- * @param[in]  ctx                     Idmap context
- * @param[in]  dom_name                Name of the domain
- * @param[out] has_algorithmic_mapping Boolean value indicating if the given
- *                                     domain is configured for algorithmic
- *                                     mapping or not.
- *
- * @return
- *  - #IDMAP_SUCCESS:         Domain for the given name was found and
- *                            has_algorithmic_mapping is set accordingly
- *  - #IDMAP_ERROR:           Provided name is invalid
- *  - #IDMAP_CONTEXT_INVALID: Provided idmap context is invalid
- *  - #IDMAP_NO_DOMAIN:       No domains are available in the idmap context
- *  - #IDMAP_NAME_UNKNOWN:    No domain with the given name was found in the
- *                            idmap context
- */
-enum idmap_error_code
-sss_idmap_domain_by_name_has_algorithmic_mapping(struct sss_idmap_ctx *ctx,
-                                                 const char *dom_name,
-                                                 bool *has_algorithmic_mapping);
-
-/**
- * @brief Convert binary SID to SID structure
- *
- * @param[in] ctx      Idmap context
- * @param[in] bin_sid  Array with the binary SID
- * @param[in] length   Size of the array containing the binary SID
- * @param[out] dom_sid SID structure,
- *                     must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_bin_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
-                                                   const uint8_t *bin_sid,
-                                                   size_t length,
-                                                   struct sss_dom_sid **dom_sid);
-
-/**
- * @brief Convert binary SID to SID string
- *
- * @param[in] ctx      Idmap context
- * @param[in] bin_sid  Array with the binary SID
- * @param[in] length   Size of the array containing the binary SID
- * @param[out] sid     Zero-terminated string representation of the SID,
- *                     must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_bin_sid_to_sid(struct sss_idmap_ctx *ctx,
-                                               const uint8_t *bin_sid,
-                                               size_t length,
-                                               char **sid);
-
-/**
- * @brief Convert SID structure to binary SID
- *
- * @param[in] ctx       Idmap context
- * @param[in] dom_sid   SID structure
- * @param[out] bin_sid  Array with the binary SID,
- *                      must be freed if not needed anymore
- * @param[out] length   Size of the array containing the binary SID
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_dom_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
-                                                   struct sss_dom_sid *dom_sid,
-                                                   uint8_t **bin_sid,
-                                                   size_t *length);
-
-/**
- * @brief Convert SID string to binary SID
- *
- * @param[in] ctx       Idmap context
- * @param[in] sid       Zero-terminated string representation of the SID
- * @param[out] bin_sid  Array with the binary SID,
- *                      must be freed if not needed anymore
- * @param[out] length   Size of the array containing the binary SID
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
-                                               const char *sid,
-                                               uint8_t **bin_sid,
-                                               size_t *length);
-
-/**
- * @brief Convert SID structure to SID string
- *
- * @param[in] ctx      Idmap context
- * @param[in] dom_sid  SID structure
- * @param[out] sid     Zero-terminated string representation of the SID,
- *                     must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_dom_sid_to_sid(struct sss_idmap_ctx *ctx,
-                                               struct sss_dom_sid *dom_sid,
-                                               char **sid);
-
-/**
- * @brief Convert SID string to SID structure
- *
- * @param[in] ctx       Idmap context
- * @param[in] sid       Zero-terminated string representation of the SID
- * @param[out] dom_sid  SID structure,
- *                      must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
-                                               const char *sid,
-                                               struct sss_dom_sid **dom_sid);
-
-/**
- * @brief Convert SID string to Samba dom_sid structure
- *
- * @param[in] ctx       Idmap context
- * @param[in] sid       Zero-terminated string representation of the SID
- * @param[out] smb_sid  Samba dom_sid structure,
- *                      must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_sid_to_smb_sid(struct sss_idmap_ctx *ctx,
-                                               const char *sid,
-                                               struct dom_sid **smb_sid);
-
-/**
- * @brief Convert Samba dom_sid structure to SID string
- *
- * @param[in] ctx       Idmap context
- * @param[in] smb_sid   Samba dom_sid structure
- * @param[out] sid      Zero-terminated string representation of the SID,
- *                      must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_smb_sid_to_sid(struct sss_idmap_ctx *ctx,
-                                               struct dom_sid *smb_sid,
-                                               char **sid);
-
-/**
- * @brief Convert SID structure to Samba dom_sid structure
- *
- * @param[in] ctx       Idmap context
- * @param[in] dom_sid   SID structure
- * @param[out] smb_sid  Samba dom_sid structure,
- *                      must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_dom_sid_to_smb_sid(struct sss_idmap_ctx *ctx,
-                                                   struct sss_dom_sid *dom_sid,
-                                                   struct dom_sid **smb_sid);
-
-/**
- * @brief Convert Samba dom_sid structure to SID structure
- *
- * @param[in] ctx       Idmap context
- * @param[in] smb_sid   Samba dom_sid structure
- * @param[out] dom_sid  SID structure,
- *                      must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_smb_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
-                                                   struct dom_sid *smb_sid,
-                                                   struct sss_dom_sid **dom_sid);
-
-/**
- * @brief Convert binary SID to Samba dom_sid structure
- *
- * @param[in] ctx       Idmap context
- * @param[in] bin_sid   Array with the binary SID
- * @param[in] length    Size of the array containing the binary SID
- * @param[out] smb_sid  Samba dom_sid structure,
- *                      must be freed if not needed anymore
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_bin_sid_to_smb_sid(struct sss_idmap_ctx *ctx,
-                                                   const uint8_t *bin_sid,
-                                                   size_t length,
-                                                   struct dom_sid **smb_sid);
-
-/**
- * @brief Convert Samba dom_sid structure to binary SID
- *
- * @param[in] ctx       Idmap context
- * @param[in] smb_sid   Samba dom_sid structure
- * @param[out] bin_sid  Array with the binary SID,
- *                      must be freed if not needed anymore
- * @param[out] length   Size of the array containing the binary SID
- *
- * @return
- *  - #IDMAP_SID_INVALID: Given SID is invalid
- *  - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result
- */
-enum idmap_error_code sss_idmap_smb_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
-                                                   struct dom_sid *smb_sid,
-                                                   uint8_t **bin_sid,
-                                                   size_t *length);
-
-/**
- * Typedef for functions to calculate an offset for id-mapping and, if
- * possible, for the reverse operation.
- */
-typedef enum idmap_error_code (idmap_offset_func)(void *pvt,
-                                                  uint32_t range_size,
-                                                  const char *input,
-                                                  long long *offset);
-
-typedef enum idmap_error_code (idmap_rev_offset_func)(struct sss_idmap_ctx *ctx,
-                                                      void *pvt,
-                                                      uint32_t offset,
-                                                      char **out);
-
-/**
- * @brief Add a generic domain to the idmap context
- *
- * @param[in] ctx         Idmap context
- * @param[in] domain_name Zero-terminated string with the domain name
- * @param[in] domain_id   Zero-terminated string representation of a unique
- *                        identifier of the domain, e.g. if available a domain
- *                        UUID or the URI of domain specific service
- * @param[in] range       Id ranges struct with smallest and largest id of the
- *                        range
- * @param[in] range_id    A name for the id range, currently not used, might
- *                        become important when we allow multiple ranges for a
- *                        single domain
- * @param[in] offset_func Function to calculate an offset in a given range
- *                        from some input given as string, if NULL
- *                        offset_murmurhash3 will be used.
- * @param[in] rev_offset_func Function to calculate the original input from a
- *                        given offset, i.e. the reverse of offset_func, may
- *                        be NULL
- * @param[in] offset_func_pvt Private data for offset_func and
- *                        rev_offset_func, may be NULL
- * @param[in] shift       Currently not used, might become important when we
- *                        allow multiple ranges for a single domain
- * @param[in] external_mapping Indicates that for this domain the mapping
- *                        should not be done by libsss_idmap, the related
- *                        calls will return IDMAP_EXTERNAL in this case.
- *                        Nevertheless it might be important to add the domain
- *                        to the idmap context so that libsss_idmap will not
- *                        use the related ranges for mapping.
- *
- * @return
- *  - #IDMAP_OUT_OF_MEMORY: Insufficient memory to store the data in the idmap
- *                          context
- *  - #IDMAP_SID_INVALID:   Invalid SID provided
- *  - #IDMAP_NO_DOMAIN:     No domain domain name given
- *  - #IDMAP_COLLISION:     New domain collides with existing one
- */
-enum idmap_error_code sss_idmap_add_gen_domain_ex(struct sss_idmap_ctx *ctx,
-                                                  const char *domain_name,
-                                                  const char *domain_id,
-                                                  struct sss_idmap_range *range,
-                                                  const char *range_id,
-                                                  idmap_offset_func *offset_func,
-                                                  idmap_rev_offset_func *rev_offset_func,
-                                                  void *offset_func_pvt,
-                                                  uint32_t shift,
-                                                  bool external_mapping);
-
-/**
- * @brief Calculate offset from string containing only numbers
- */
-enum idmap_error_code offset_identity(void *pvt, uint32_t range_size,
-                                      const char *input, long long *offset);
-
-/**
- * @brief Reverse of offset_identity, return a string containing only numbers
- * representing the given offset
- */
-enum idmap_error_code rev_offset_identity(struct sss_idmap_ctx *ctx, void *pvt,
-                                          uint32_t id, char **_out);
-
-/**
- * @brief Calculate offset from string with the help of murmurhash3
- */
-enum idmap_error_code offset_murmurhash3(void *pvt, uint32_t range_size,
-                                         const char *input, long long *offset);
-
-/**
- * Structure for private data for offset_murmurhash3. If not given 0xdeadbeef
- * will be used as seed. UTF8 strings will be normalized by default but not
- * casefolded.
- */
-struct offset_murmurhash3_data {
-    uint32_t seed;
-    bool normalize;
-    bool casefold;
-};
-
-/**
- * @brief Translate some input to a unix UID or GID
- *
- * @param[in] ctx       Idmap context
- * @param[in] domain_id Zero-terminated string with the domain ID of a known
- *                      domain
- * @param[in] input     Zero-terminated string which should be translated into
- *                      an offset to calculate the unix UID or GID
- * @param[out] id       Returned unix UID or GID
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domain with domain_id found in ctx
- *  - #IDMAP_EXTERNAL:      external source is authoritative for mapping
- */
-enum idmap_error_code sss_idmap_gen_to_unix(struct sss_idmap_ctx *ctx,
-                                            const char *domain_id,
-                                            const char *input,
-                                            uint32_t *_id);
-
-/**
- * @brief Translate some input to a unix UID or GID
- *
- * @param[in] ctx       Idmap context
- * @param[in] id        UNIX UID or GID
- *                      an offset to calculate the unix UID or GID
- * @param[out] out      Original value the UID or GID was derived from
- *
- * @return
- *  - #IDMAP_NO_DOMAIN:     No domain with domain_id found in ctx
- *  - #IDMAP_EXTERNAL:      external source is authoritative for mapping
- *  - #IDMAP_NO_REVERSE:    the id cannot be reverted back to the original
- *                          source
- */
-enum idmap_error_code sss_idmap_unix_to_gen(struct sss_idmap_ctx *ctx,
-                                            uint32_t id,
-                                            char **out);
-
-/**
- * @}
- */
-#endif /* SSS_IDMAP_H_ */
diff --git a/rust/idmap/src/sss_idmap_conv.c b/rust/idmap/src/sss_idmap_conv.c
deleted file mode 100644 (file)
index bd3148d..0000000
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
-    SSSD
-
-    ID-mapping library - conversion utilities
-
-    Authors:
-        Sumit Bose <sbose@redhat.com>
-
-    Copyright (C) 2012 Red Hat
-
-    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 <http://www.gnu.org/licenses/>.
-*/
-
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "sss_idmap.h"
-#include "sss_idmap_private.h"
-//#include "util/util.h"
-//#include "util/sss_endian.h"
-#include "util.h"
-
-#define SID_ID_AUTHS 6
-#define SID_SUB_AUTHS 15
-struct sss_dom_sid {
-        uint8_t sid_rev_num;
-        int8_t num_auths;                  /* [range(0,15)] */
-        uint8_t id_auth[SID_ID_AUTHS];     /* highest order byte has index 0 */
-        uint32_t sub_auths[SID_SUB_AUTHS]; /* host byte-order */
-};
-
-enum idmap_error_code sss_idmap_bin_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
-                                                   const uint8_t *bin_sid,
-                                                   size_t length,
-                                                   struct sss_dom_sid **_dom_sid)
-{
-    enum idmap_error_code err;
-    struct sss_dom_sid *dom_sid;
-    size_t i = 0;
-    size_t p = 0;
-    uint32_t val;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (length > sizeof(struct sss_dom_sid)) return IDMAP_SID_INVALID;
-
-    dom_sid = ctx->alloc_func(sizeof(struct sss_dom_sid), ctx->alloc_pvt);
-    if (dom_sid == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-    memset(dom_sid, 0, sizeof(struct sss_dom_sid));
-
-    /* Safely copy in the SID revision number */
-    dom_sid->sid_rev_num = (uint8_t) *(bin_sid + p);
-    p++;
-
-    /* Safely copy in the number of sub auth values */
-    dom_sid->num_auths = (uint8_t) *(bin_sid + p);
-    p++;
-
-    /* Make sure we aren't being told to read more bin_sid
-     * than can fit in the structure
-     */
-    if (dom_sid->num_auths > SID_SUB_AUTHS) {
-        err = IDMAP_SID_INVALID;
-        goto done;
-    }
-
-    /* Safely copy in the id_auth values */
-    for (i = 0; i < SID_ID_AUTHS; i++) {
-        dom_sid->id_auth[i] = (uint8_t) *(bin_sid + p);
-        p++;
-    }
-
-    /* Safely copy in the sub_auths values */
-    for (i = 0; i < dom_sid->num_auths; i++) {
-        /* SID sub auth values in Active Directory are stored little-endian,
-         * we store them in host order */
-        SAFEALIGN_COPY_UINT32(&val, bin_sid + p, &p);
-        dom_sid->sub_auths[i] = le32toh(val);
-    }
-
-    *_dom_sid = dom_sid;
-    err = IDMAP_SUCCESS;
-
-done:
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(dom_sid, ctx->alloc_pvt);
-    }
-    return err;
-}
-
-enum idmap_error_code sss_idmap_dom_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
-                                                   struct sss_dom_sid *dom_sid,
-                                                   uint8_t **_bin_sid,
-                                                   size_t *_length)
-{
-    enum idmap_error_code err;
-    uint8_t *bin_sid;
-    size_t length;
-    size_t i = 0;
-    size_t p = 0;
-    uint32_t val;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (dom_sid->num_auths > SID_SUB_AUTHS) {
-        return IDMAP_SID_INVALID;
-    }
-
-    length = 2 + SID_ID_AUTHS + dom_sid->num_auths * 4;
-
-    bin_sid = ctx->alloc_func(length, ctx->alloc_pvt);
-    if (bin_sid == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-
-    bin_sid[p] = dom_sid->sid_rev_num;
-    p++;
-
-    bin_sid[p] = dom_sid->num_auths;
-    p++;
-
-    for (i = 0; i < SID_ID_AUTHS; i++) {
-        bin_sid[p] = dom_sid->id_auth[i];
-        p++;
-    }
-
-    for (i = 0; i < dom_sid->num_auths; i++) {
-        if (p + sizeof(uint32_t) > length) {
-            err = IDMAP_SID_INVALID;
-            goto done;
-        }
-        val = htole32(dom_sid->sub_auths[i]);
-        SAFEALIGN_COPY_UINT32(bin_sid + p, &val, &p);
-    }
-
-    *_bin_sid = bin_sid;
-    *_length = length;
-
-    err = IDMAP_SUCCESS;
-done:
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(bin_sid, ctx->alloc_pvt);
-    }
-    return err;
-}
-
-enum idmap_error_code sss_idmap_dom_sid_to_sid(struct sss_idmap_ctx *ctx,
-                                               struct sss_dom_sid *dom_sid,
-                                               char **_sid)
-{
-    enum idmap_error_code err;
-    char *sid_buf;
-    size_t sid_buf_len;
-    char *p;
-    int nc;
-    int8_t i;
-    uint32_t id_auth_val = 0;
-
-    if (dom_sid->num_auths > SID_SUB_AUTHS) {
-        return IDMAP_SID_INVALID;
-    }
-
-    sid_buf_len = 25 + dom_sid->num_auths * 11;
-    sid_buf = ctx->alloc_func(sid_buf_len, ctx->alloc_pvt);
-    if (sid_buf == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-    memset(sid_buf, 0, sid_buf_len);
-
-    /* Only 32bits are used for the string representation */
-    id_auth_val = (dom_sid->id_auth[2] << 24) +
-                  (dom_sid->id_auth[3] << 16) +
-                  (dom_sid->id_auth[4] << 8) +
-                  (dom_sid->id_auth[5]);
-
-    nc = snprintf(sid_buf, sid_buf_len, "S-%u-%lu", dom_sid->sid_rev_num,
-                                                    (unsigned long) id_auth_val);
-    if (nc < 0 || nc >= sid_buf_len) {
-        err = IDMAP_SID_INVALID;
-        goto done;
-    }
-
-
-    /* Loop through the sub-auths, if any, prepending a hyphen
-     * for each one.
-     */
-    p = sid_buf;
-    for (i = 0; i < dom_sid->num_auths ; i++) {
-        p += nc;
-        sid_buf_len -= nc;
-
-        nc = snprintf(p, sid_buf_len, "-%lu",
-                                      (unsigned long) dom_sid->sub_auths[i]);
-        if (nc < 0 || nc >= sid_buf_len) {
-            err = IDMAP_SID_INVALID;
-            goto done;
-        }
-    }
-
-    *_sid = sid_buf;
-    err = IDMAP_SUCCESS;
-
-done:
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(sid_buf, ctx->alloc_pvt);
-    }
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
-                                               const char *sid,
-                                               struct sss_dom_sid **_dom_sid)
-{
-    enum idmap_error_code err;
-    unsigned long ul;
-    char *r;
-    char *end;
-    struct sss_dom_sid *dom_sid;
-
-    CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
-
-    if (sid == NULL || (sid[0] != 'S' && sid[0] != 's') || sid[1] != '-') {
-            return IDMAP_SID_INVALID;
-    }
-
-    dom_sid = ctx->alloc_func(sizeof(struct sss_dom_sid), ctx->alloc_pvt);
-    if (dom_sid == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-    memset(dom_sid, 0, sizeof(struct sss_dom_sid));
-
-
-    if (!isdigit(sid[2])) {
-        err = IDMAP_SID_INVALID;
-        goto done;
-    }
-    errno = 0;
-    ul = strtoul(sid + 2, &r, 10);
-    if (errno != 0 || r == NULL || *r != '-' || ul > UINT8_MAX) {
-        err = IDMAP_SID_INVALID;
-        goto done;
-    }
-    dom_sid->sid_rev_num = (uint8_t) ul;
-    r++;
-
-    if (!isdigit(*r)) {
-        err = IDMAP_SID_INVALID;
-        goto done;
-    }
-    errno = 0;
-    ul = strtoul(r, &r, 10);
-    if (errno != 0 || r == NULL || ul > UINT32_MAX) {
-        err = IDMAP_SID_INVALID;
-        goto done;
-    }
-
-    /* id_auth in the string should always be <2^32 in decimal */
-    /* store values in the same order as the binary representation */
-    dom_sid->id_auth[0] = 0;
-    dom_sid->id_auth[1] = 0;
-    dom_sid->id_auth[2] = (ul & 0xff000000) >> 24;
-    dom_sid->id_auth[3] = (ul & 0x00ff0000) >> 16;
-    dom_sid->id_auth[4] = (ul & 0x0000ff00) >> 8;
-    dom_sid->id_auth[5] = (ul & 0x000000ff);
-
-    if (*r == '\0') {
-        /* no sub auths given */
-        err = IDMAP_SUCCESS;
-        goto done;
-    }
-
-    if (*r != '-') {
-        err = IDMAP_SID_INVALID;
-        goto done;
-    }
-
-    do {
-        if (dom_sid->num_auths >= SID_SUB_AUTHS) {
-            err = IDMAP_SID_INVALID;
-            goto done;
-        }
-
-        r++;
-        if (!isdigit(*r)) {
-            err = IDMAP_SID_INVALID;
-            goto done;
-        }
-
-        errno = 0;
-        ul = strtoul(r, &end, 10);
-        if (errno != 0 || ul > UINT32_MAX || end == NULL ||
-            (*end != '\0' && *end != '-')) {
-            err = IDMAP_SID_INVALID;
-            goto done;
-        }
-
-        dom_sid->sub_auths[dom_sid->num_auths++] = ul;
-
-        r = end;
-    } while (*r != '\0');
-
-    err = IDMAP_SUCCESS;
-
-done:
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(dom_sid, ctx->alloc_pvt);
-    } else {
-        *_dom_sid = dom_sid;
-    }
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
-                                               const char *sid,
-                                               uint8_t **_bin_sid,
-                                               size_t *_length)
-{
-    enum idmap_error_code err;
-    struct sss_dom_sid *dom_sid = NULL;
-    size_t length;
-    uint8_t *bin_sid = NULL;
-
-    err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_dom_sid_to_bin_sid(ctx, dom_sid, &bin_sid, &length);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    *_length = length;
-    *_bin_sid = bin_sid;
-    err = IDMAP_SUCCESS;
-
-done:
-    ctx->free_func(dom_sid, ctx->alloc_pvt);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(bin_sid, ctx->alloc_pvt);
-    }
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_bin_sid_to_sid(struct sss_idmap_ctx *ctx,
-                                               const uint8_t *bin_sid,
-                                               size_t length,
-                                               char **_sid)
-{
-    enum idmap_error_code err;
-    struct sss_dom_sid *dom_sid = NULL;
-    char *sid = NULL;
-
-    err = sss_idmap_bin_sid_to_dom_sid(ctx, bin_sid, length, &dom_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    *_sid = sid;
-    err = IDMAP_SUCCESS;
-
-done:
-    ctx->free_func(dom_sid, ctx->alloc_pvt);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(sid, ctx->alloc_pvt);
-    }
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_sid_to_smb_sid(struct sss_idmap_ctx *ctx,
-                                               const char *sid,
-                                               struct dom_sid **_smb_sid)
-{
-    enum idmap_error_code err;
-    struct sss_dom_sid *dom_sid = NULL;
-    struct dom_sid *smb_sid = NULL;
-
-    err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_dom_sid_to_smb_sid(ctx, dom_sid, &smb_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    *_smb_sid = smb_sid;
-    err = IDMAP_SUCCESS;
-
-done:
-    ctx->free_func(dom_sid, ctx->alloc_pvt);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(smb_sid, ctx->alloc_pvt);
-    }
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_smb_sid_to_sid(struct sss_idmap_ctx *ctx,
-                                               struct dom_sid *smb_sid,
-                                               char **_sid)
-{
-    enum idmap_error_code err;
-    struct sss_dom_sid *dom_sid = NULL;
-    char *sid = NULL;
-
-    err = sss_idmap_smb_sid_to_dom_sid(ctx, smb_sid, &dom_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    *_sid = sid;
-    err = IDMAP_SUCCESS;
-
-done:
-    ctx->free_func(dom_sid, ctx->alloc_pvt);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(sid, ctx->alloc_pvt);
-    }
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_dom_sid_to_smb_sid(struct sss_idmap_ctx *ctx,
-                                                   struct sss_dom_sid *dom_sid,
-                                                   struct dom_sid **_smb_sid)
-{
-    struct dom_sid *smb_sid;
-    size_t c;
-
-    smb_sid = ctx->alloc_func(sizeof(struct dom_sid), ctx->alloc_pvt);
-    if (smb_sid == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-    memset(smb_sid, 0, sizeof(struct dom_sid));
-
-    smb_sid->sid_rev_num = dom_sid->sid_rev_num;
-    smb_sid->num_auths = dom_sid->num_auths;
-    for (c = 0; c < SID_ID_AUTHS; c++) {
-        smb_sid->id_auth[c] = dom_sid->id_auth[c];
-    }
-    for (c = 0; c < SID_SUB_AUTHS; c++) {
-        smb_sid->sub_auths[c] = dom_sid->sub_auths[c];
-    }
-
-    *_smb_sid = smb_sid;
-
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code sss_idmap_smb_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
-                                                   struct dom_sid *smb_sid,
-                                                   struct sss_dom_sid **_dom_sid)
-{
-    struct sss_dom_sid *dom_sid;
-    size_t c;
-
-    dom_sid = ctx->alloc_func(sizeof(struct sss_dom_sid), ctx->alloc_pvt);
-    if (dom_sid == NULL) {
-        return IDMAP_OUT_OF_MEMORY;
-    }
-    memset(dom_sid, 0, sizeof(struct sss_dom_sid));
-
-    dom_sid->sid_rev_num = smb_sid->sid_rev_num;
-    dom_sid->num_auths = smb_sid->num_auths;
-    for (c = 0; c < SID_ID_AUTHS; c++) {
-        dom_sid->id_auth[c] = smb_sid->id_auth[c];
-    }
-    for (c = 0; c < SID_SUB_AUTHS; c++) {
-        dom_sid->sub_auths[c] = smb_sid->sub_auths[c];
-    }
-
-    *_dom_sid = dom_sid;
-
-    return IDMAP_SUCCESS;
-}
-
-enum idmap_error_code sss_idmap_bin_sid_to_smb_sid(struct sss_idmap_ctx *ctx,
-                                                   const uint8_t *bin_sid,
-                                                   size_t length,
-                                                   struct dom_sid **_smb_sid)
-{
-    enum idmap_error_code err;
-    struct sss_dom_sid *dom_sid = NULL;
-    struct dom_sid *smb_sid = NULL;
-
-    err = sss_idmap_bin_sid_to_dom_sid(ctx, bin_sid, length, &dom_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_dom_sid_to_smb_sid(ctx, dom_sid, &smb_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    *_smb_sid = smb_sid;
-    err = IDMAP_SUCCESS;
-
-done:
-    ctx->free_func(dom_sid, ctx->alloc_pvt);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(smb_sid, ctx->alloc_pvt);
-    }
-
-    return err;
-}
-
-enum idmap_error_code sss_idmap_smb_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
-                                                   struct dom_sid *smb_sid,
-                                                   uint8_t **_bin_sid,
-                                                   size_t *_length)
-{
-    enum idmap_error_code err;
-    struct sss_dom_sid *dom_sid = NULL;
-    uint8_t *bin_sid = NULL;
-    size_t length;
-
-    err = sss_idmap_smb_sid_to_dom_sid(ctx, smb_sid, &dom_sid);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    err = sss_idmap_dom_sid_to_bin_sid(ctx, dom_sid, &bin_sid, &length);
-    if (err != IDMAP_SUCCESS) {
-        goto done;
-    }
-
-    *_bin_sid = bin_sid;
-    *_length = length;
-    err = IDMAP_SUCCESS;
-
-done:
-    ctx->free_func(dom_sid, ctx->alloc_pvt);
-    if (err != IDMAP_SUCCESS) {
-        ctx->free_func(bin_sid, ctx->alloc_pvt);
-    }
-
-    return err;
-}
diff --git a/rust/idmap/src/sss_idmap_private.h b/rust/idmap/src/sss_idmap_private.h
deleted file mode 100644 (file)
index 15300d1..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-    SSSD
-
-    ID-mapping library - private headers
-
-    Authors:
-        Sumit Bose <sbose@redhat.com>
-
-    Copyright (C) 2012 Red Hat
-
-    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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef SSS_IDMAP_PRIVATE_H_
-#define SSS_IDMAP_PRIVATE_H_
-
-#define SSS_IDMAP_DEFAULT_LOWER 200000
-#define SSS_IDMAP_DEFAULT_UPPER 2000200000
-#define SSS_IDMAP_DEFAULT_RANGESIZE 200000
-#define SSS_IDMAP_DEFAULT_AUTORID false
-#define SSS_IDMAP_DEFAULT_EXTRA_SLICE_INIT 10
-
-#define CHECK_IDMAP_CTX(ctx, ret) do { \
-    if (ctx == NULL || ctx->alloc_func == NULL || ctx->free_func == NULL) { \
-        return ret; \
-    } \
-} while(0)
-
-struct sss_idmap_opts {
-    /* true if autorid compatibility mode is used */
-    bool autorid_mode;
-
-    /* smallest available id (for all domains) */
-    id_t idmap_lower;
-
-    /* highest available id (for all domains) */
-    id_t idmap_upper;
-
-    /* number of available UIDs (for single domain) */
-    id_t rangesize;
-
-    /* maximal number of secondary slices */
-    int extra_slice_init;
-};
-
-struct sss_idmap_ctx {
-    idmap_alloc_func *alloc_func;
-    void *alloc_pvt;
-    idmap_free_func *free_func;
-    struct sss_idmap_opts idmap_opts;
-    struct idmap_domain_info *idmap_domain_info;
-};
-
-/* This is a copy of the definition in the samba gen_ndr/security.h header
- * file. We use it here to be able to offer conversions form struct dom_sid to
- * string or binary representation since those are not made available by
- * public samba libraries.
- *
- * If the definition ever changes on the samba side we have to adopt the
- * change. But chances are very low that this will ever happen since e.g. this
- * struct is also defined in public documentation from Microsoft. See e.g.
- * section 2.4.2.3 of "[MS-DTYP]: Windows Data Types"
- * http://msdn.microsoft.com/en-us/library/cc230364(v=prot.10)
- */
-
-struct dom_sid {
-        uint8_t sid_rev_num;
-        int8_t num_auths;
-        uint8_t id_auth[6];
-        uint32_t sub_auths[15];
-};
-
-#endif /* SSS_IDMAP_PRIVATE_H_ */
diff --git a/rust/idmap/src/util.h b/rust/idmap/src/util.h
deleted file mode 100644 (file)
index 12d4cf9..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-   Himmelblaud
-
-   ID-mapping library utils
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _UTILS_H
-#define _UTILS_H
-
-#include <string.h>
-#include <stdint.h>
-
-static inline void
-safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
-{
-    memcpy(dest, src, n);
-    if (counter) {
-        *counter += n;
-    }
-}
-
-#define SAFEALIGN_COPY_UINT32(dest, src, pctr) \
-    safealign_memcpy(dest, src, sizeof(uint32_t), pctr)
-
-#if defined(__GNUC__) && __GNUC__ >= 7
- #define SSS_ATTRIBUTE_FALLTHROUGH __attribute__ ((fallthrough))
-#else
- #define SSS_ATTRIBUTE_FALLTHROUGH
-#endif
-
-#endif /* _UTILS_H */
diff --git a/rust/nss/Cargo.toml b/rust/nss/Cargo.toml
deleted file mode 100644 (file)
index 6970154..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-name = "nss_himmelblau"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[lib]
-name = "nss_himmelblau"
-crate-type = [ "cdylib" ]
-path =  "src/lib.rs"
-
-[dependencies]
-libc.workspace = true
-libnss = "0.8.0"
-ntstatus_gen.workspace = true
-param = { workspace = true }
-sock = { workspace = true }
-
-[build-dependencies]
-version = { path = "../version" }
diff --git a/rust/nss/build.rs b/rust/nss/build.rs
deleted file mode 100644 (file)
index 6fcc6b9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-fn main() {
-    if let Some(vers) = version::samba_version_string() {
-        println!("cargo:rustc-env=CARGO_PKG_VERSION={}", vers);
-    }
-    println!(
-        "cargo:rustc-env=CARGO_PKG_VERSION_MAJOR={}",
-        version::SAMBA_VERSION_MAJOR
-    );
-    println!(
-        "cargo:rustc-env=CARGO_PKG_VERSION_MINOR={}",
-        version::SAMBA_VERSION_MINOR
-    );
-    println!(
-        "cargo:rustc-env=CARGO_PKG_VERSION_PATCH={}",
-        version::SAMBA_VERSION_RELEASE
-    );
-    println!("cargo:rustc-env=LD_LIBRARY_PATH=../../bin/shared:../../bin/shared/private/");
-}
diff --git a/rust/nss/src/lib.rs b/rust/nss/src/lib.rs
deleted file mode 100644 (file)
index acd423f..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   NSS module for the Himmelblau daemon
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-#[macro_use]
-extern crate libnss;
-
-use libnss::group::{Group as NssGroup, GroupHooks};
-use libnss::interop::Response as NssResponse;
-use libnss::passwd::{Passwd as NssPasswd, PasswdHooks};
-use param::LoadParm;
-use sock::{stream_and_timeout, Group, Passwd, Request, Response};
-
-struct HimmelblauPasswd;
-libnss_passwd_hooks!(himmelblau, HimmelblauPasswd);
-
-impl PasswdHooks for HimmelblauPasswd {
-    fn get_all_entries() -> NssResponse<Vec<NssPasswd>> {
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return NssResponse::Unavail,
-        };
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok((stream, timeout)) => (stream, timeout),
-            Err(_) => return NssResponse::Unavail,
-        };
-
-        let req = Request::NssAccounts;
-        stream
-            .send(&req, timeout)
-            .map(|r| match r {
-                Response::NssAccounts(l) => {
-                    l.into_iter().map(|passwd| passwd.into()).collect()
-                }
-                _ => vec![],
-            })
-            .map(NssResponse::Success)
-            .unwrap_or_else(|_| NssResponse::Success(vec![]))
-    }
-
-    fn get_entry_by_uid(uid: libc::uid_t) -> NssResponse<NssPasswd> {
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return NssResponse::Unavail,
-        };
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok((stream, timeout)) => (stream, timeout),
-            Err(_) => return NssResponse::Unavail,
-        };
-
-        let req = Request::NssAccountByUid(uid);
-        stream
-            .send(&req, timeout)
-            .map(|r| match r {
-                Response::NssAccount(passwd) => passwd
-                    .map(nsspasswd_from_passwd)
-                    .map(NssResponse::Success)
-                    .unwrap_or_else(|| NssResponse::NotFound),
-                _ => NssResponse::NotFound,
-            })
-            .unwrap_or_else(|_| NssResponse::NotFound)
-    }
-
-    fn get_entry_by_name(name: String) -> NssResponse<NssPasswd> {
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return NssResponse::Unavail,
-        };
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok((stream, timeout)) => (stream, timeout),
-            Err(_) => return NssResponse::Unavail,
-        };
-
-        let req = Request::NssAccountByName(name);
-        stream
-            .send(&req, timeout)
-            .map(|r| match r {
-                Response::NssAccount(passwd) => passwd
-                    .map(nsspasswd_from_passwd)
-                    .map(NssResponse::Success)
-                    .unwrap_or_else(|| NssResponse::NotFound),
-                _ => NssResponse::NotFound,
-            })
-            .unwrap_or_else(|_| NssResponse::NotFound)
-    }
-}
-
-struct HimmelblauGroup;
-libnss_group_hooks!(himmelblau, HimmelblauGroup);
-
-impl GroupHooks for HimmelblauGroup {
-    fn get_all_entries() -> NssResponse<Vec<NssGroup>> {
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return NssResponse::Unavail,
-        };
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok((stream, timeout)) => (stream, timeout),
-            Err(_) => return NssResponse::Unavail,
-        };
-
-        let req = Request::NssGroups;
-        stream
-            .send(&req, timeout)
-            .map(|r| match r {
-                Response::NssGroups(l) => {
-                    l.into_iter().map(|group| group.into()).collect()
-                }
-                _ => vec![],
-            })
-            .map(NssResponse::Success)
-            .unwrap_or_else(|_| NssResponse::Success(vec![]))
-    }
-
-    fn get_entry_by_gid(gid: libc::gid_t) -> NssResponse<NssGroup> {
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return NssResponse::Unavail,
-        };
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok((stream, timeout)) => (stream, timeout),
-            Err(_) => return NssResponse::Unavail,
-        };
-
-        let req = Request::NssGroupByGid(gid);
-        stream
-            .send(&req, timeout)
-            .map(|r| match r {
-                Response::NssGroup(group) => group
-                    .map(nssgroup_from_group)
-                    .map(NssResponse::Success)
-                    .unwrap_or_else(|| NssResponse::NotFound),
-                _ => NssResponse::NotFound,
-            })
-            .unwrap_or_else(|_| NssResponse::NotFound)
-    }
-
-    fn get_entry_by_name(name: String) -> NssResponse<NssGroup> {
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return NssResponse::Unavail,
-        };
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok((stream, timeout)) => (stream, timeout),
-            Err(_) => return NssResponse::Unavail,
-        };
-
-        let req = Request::NssGroupByName(name);
-        stream
-            .send(&req, timeout)
-            .map(|r| match r {
-                Response::NssGroup(group) => group
-                    .map(nssgroup_from_group)
-                    .map(NssResponse::Success)
-                    .unwrap_or_else(|| NssResponse::NotFound),
-                _ => NssResponse::NotFound,
-            })
-            .unwrap_or_else(|_| NssResponse::NotFound)
-    }
-}
-
-fn nsspasswd_from_passwd(passwd: Passwd) -> NssPasswd {
-    passwd.into()
-}
-
-fn nssgroup_from_group(group: Group) -> NssGroup {
-    group.into()
-}
diff --git a/rust/ntstatus_gen/Cargo.toml b/rust/ntstatus_gen/Cargo.toml
deleted file mode 100644 (file)
index c36ee96..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[package]
-name = "ntstatus_gen"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
diff --git a/rust/ntstatus_gen/src/lib.rs b/rust/ntstatus_gen/src/lib.rs
deleted file mode 100644 (file)
index b112776..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Generated NTSTATUS Errors
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-#[path = "../../../bin/default/libcli/util/ntstatus_gen.rs"]
-mod ntstatus_gen;
-pub use ntstatus_gen::*;
diff --git a/rust/pam/Cargo.toml b/rust/pam/Cargo.toml
deleted file mode 100644 (file)
index 509468f..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-name = "pam_himmelblau"
-links = "pam"
-
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[lib]
-name = "pam_himmelblau"
-crate-type = [ "cdylib" ]
-path =  "src/lib.rs"
-
-[dependencies]
-libc = { workspace = true }
-dbg = { workspace = true }
-sock.workspace = true
-chelps.workspace = true
-param.workspace = true
-
-[build-dependencies]
-pkg-config = "0.3.30"
diff --git a/rust/pam/build.rs b/rust/pam/build.rs
deleted file mode 100644 (file)
index 11313da..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    // ignore errors here since older versions of pam do not ship the pkg-config `pam.pc` file.
-    // Not setting anything here will fall back on just blindly linking with `-lpam`,
-    // which will work on environments with libpam.so, but no pkg-config file.
-    let _ = pkg_config::Config::new()
-        .atleast_version("1.3.0")
-        .probe("pam");
-    println!("cargo:rustc-env=LD_LIBRARY_PATH=../../bin/shared:../../bin/shared/private/");
-}
diff --git a/rust/pam/src/lib.rs b/rust/pam/src/lib.rs
deleted file mode 100644 (file)
index 7a40284..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-   MIT License
-
-   Copyright (c) 2015 TOZNY
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy
-   of this software and associated documentation files (the "Software"), to deal
-   in the Software without restriction, including without limitation the rights
-   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   copies of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be included in all
-   copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-*/
-
-#![deny(warnings)]
-#![warn(unused_extern_crates)]
-#![deny(clippy::todo)]
-#![deny(clippy::unimplemented)]
-// In this file, we do want to panic on these faults.
-// #![deny(clippy::unwrap_used)]
-// #![deny(clippy::expect_used)]
-#![deny(clippy::panic)]
-#![deny(clippy::unreachable)]
-#![deny(clippy::await_holding_lock)]
-#![deny(clippy::needless_pass_by_value)]
-#![deny(clippy::trivially_copy_pass_by_ref)]
-
-#[cfg(target_family = "unix")]
-mod pam;
-
-// pub use needs to be here so it'll compile and export all the things
-#[cfg(target_family = "unix")]
-pub use crate::pam::*;
diff --git a/rust/pam/src/pam/constants.rs b/rust/pam/src/pam/constants.rs
deleted file mode 100644 (file)
index a626651..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-   MIT License
-
-   Copyright (c) 2015 TOZNY
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy
-   of this software and associated documentation files (the "Software"), to deal
-   in the Software without restriction, including without limitation the rights
-   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   copies of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be included in all
-   copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-*/
-use libc::{c_int, c_uint};
-
-pub type PamFlag = c_uint;
-pub type PamItemType = c_int;
-pub type PamMessageStyle = c_int;
-pub type AlwaysZero = c_int;
-
-// The Linux-PAM flags
-// see /usr/include/security/_pam_types.h
-pub const _PAM_SILENT: PamFlag = 0x8000;
-pub const _PAM_DISALLOW_NULL_AUTHTOK: PamFlag = 0x0001;
-pub const _PAM_ESTABLISH_CRED: PamFlag = 0x0002;
-pub const _PAM_DELETE_CRED: PamFlag = 0x0004;
-pub const _PAM_REINITIALIZE_CRED: PamFlag = 0x0008;
-pub const _PAM_REFRESH_CRED: PamFlag = 0x0010;
-pub const _PAM_CHANGE_EXPIRED_AUTHTOK: PamFlag = 0x0020;
-
-// The Linux-PAM item types
-// see /usr/include/security/_pam_types.h
-/// The service name
-pub const PAM_SERVICE: PamItemType = 1;
-/// The user name
-pub const PAM_USER: PamItemType = 2;
-/// The tty name
-pub const PAM_TTY: PamItemType = 3;
-/// The remote host name
-pub const PAM_RHOST: PamItemType = 4;
-/// The pam_conv structure
-pub const PAM_CONV: PamItemType = 5;
-/// The authentication token (password)
-pub const PAM_AUTHTOK: PamItemType = 6;
-/// The old authentication token
-pub const PAM_OLDAUTHTOK: PamItemType = 7;
-/// The remote user name
-pub const PAM_RUSER: PamItemType = 8;
-/// the prompt for getting a username
-pub const PAM_USER_PROMPT: PamItemType = 9;
-/* Linux-PAM :extensionsPamItemType = */
-/// app supplied function to override failure delays
-pub const _PAM_FAIL_DELAY: PamItemType = 10;
-/// X :display name
-pub const _PAM_XDISPLAY: PamItemType = 11;
-/// X :server authentication data
-pub const _PAM_XAUTHDATA: PamItemType = 12;
-/// The type for pam_get_authtok
-pub const _PAM_AUTHTOK_TYPE: PamItemType = 13;
-
-// Message styles
-pub const PAM_PROMPT_ECHO_OFF: PamMessageStyle = 1;
-pub const PAM_PROMPT_ECHO_ON: PamMessageStyle = 2;
-pub const PAM_ERROR_MSG: PamMessageStyle = 3;
-pub const PAM_TEXT_INFO: PamMessageStyle = 4;
-/// yes/no/maybe conditionals
-pub const _PAM_RADIO_TYPE: PamMessageStyle = 5;
-pub const _PAM_BINARY_PROMPT: PamMessageStyle = 7;
-
-// The Linux-PAM return values
-// see /usr/include/security/_pam_types.h
-#[allow(non_camel_case_types, dead_code)]
-#[derive(Debug, PartialEq)]
-#[repr(C)]
-pub enum PamResultCode {
-    PAM_SUCCESS = 0,
-    PAM_OPEN_ERR = 1,
-    PAM_SYMBOL_ERR = 2,
-    PAM_SERVICE_ERR = 3,
-    PAM_SYSTEM_ERR = 4,
-    PAM_BUF_ERR = 5,
-    PAM_PERM_DENIED = 6,
-    PAM_AUTH_ERR = 7,
-    PAM_CRED_INSUFFICIENT = 8,
-    PAM_AUTHINFO_UNAVAIL = 9,
-    PAM_USER_UNKNOWN = 10,
-    PAM_MAXTRIES = 11,
-    PAM_NEW_AUTHTOK_REQD = 12,
-    PAM_ACCT_EXPIRED = 13,
-    PAM_SESSION_ERR = 14,
-    PAM_CRED_UNAVAIL = 15,
-    PAM_CRED_EXPIRED = 16,
-    PAM_CRED_ERR = 17,
-    PAM_NO_MODULE_DATA = 18,
-    PAM_CONV_ERR = 19,
-    PAM_AUTHTOK_ERR = 20,
-    PAM_AUTHTOK_RECOVERY_ERR = 21,
-    PAM_AUTHTOK_LOCK_BUSY = 22,
-    PAM_AUTHTOK_DISABLE_AGING = 23,
-    PAM_TRY_AGAIN = 24,
-    PAM_IGNORE = 25,
-    PAM_ABORT = 26,
-    PAM_AUTHTOK_EXPIRED = 27,
-    PAM_MODULE_UNKNOWN = 28,
-    PAM_BAD_ITEM = 29,
-    PAM_CONV_AGAIN = 30,
-    PAM_INCOMPLETE = 31,
-}
diff --git a/rust/pam/src/pam/conv.rs b/rust/pam/src/pam/conv.rs
deleted file mode 100644 (file)
index 8fa8b46..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-   MIT License
-
-   Copyright (c) 2015 TOZNY
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy
-   of this software and associated documentation files (the "Software"), to deal
-   in the Software without restriction, including without limitation the rights
-   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   copies of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be included in all
-   copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-*/
-use std::ffi::{CStr, CString};
-use std::ptr;
-
-use libc::{c_char, c_int};
-
-use crate::pam::constants::{PamResultCode, *};
-use crate::pam::module::{PamItem, PamResult};
-
-#[allow(missing_copy_implementations)]
-pub enum AppDataPtr {}
-
-#[repr(C)]
-struct PamMessage {
-    msg_style: PamMessageStyle,
-    msg: *const c_char,
-}
-
-#[repr(C)]
-struct PamResponse {
-    resp: *const c_char,
-    resp_retcode: AlwaysZero,
-}
-
-/// `PamConv` acts as a channel for communicating with user.
-///
-/// Communication is mediated by the pam client (the application that invoked
-/// pam).  Messages sent will be relayed to the user by the client, and response
-/// will be relayed back.
-#[repr(C)]
-pub struct PamConv {
-    conv: extern "C" fn(
-        num_msg: c_int,
-        pam_message: &&PamMessage,
-        pam_response: &mut *const PamResponse,
-        appdata_ptr: *const AppDataPtr,
-    ) -> PamResultCode,
-    appdata_ptr: *const AppDataPtr,
-}
-
-impl PamConv {
-    /// Sends a message to the pam client.
-    ///
-    /// This will typically result in the user seeing a message or a prompt.
-    /// There are several message styles available:
-    ///
-    /// - PAM_PROMPT_ECHO_OFF
-    /// - PAM_PROMPT_ECHO_ON
-    /// - PAM_ERROR_MSG
-    /// - PAM_TEXT_INFO
-    /// - PAM_RADIO_TYPE
-    /// - PAM_BINARY_PROMPT
-    ///
-    /// Note that the user experience will depend on how the client implements
-    /// these message styles - and not all applications implement all message
-    /// styles.
-    pub fn send(
-        &self,
-        style: PamMessageStyle,
-        msg: &str,
-    ) -> PamResult<Option<String>> {
-        let mut resp_ptr: *const PamResponse = ptr::null();
-        let msg_cstr = CString::new(msg).unwrap();
-        let msg = PamMessage {
-            msg_style: style,
-            msg: msg_cstr.as_ptr(),
-        };
-
-        let ret = (self.conv)(1, &&msg, &mut resp_ptr, self.appdata_ptr);
-
-        if PamResultCode::PAM_SUCCESS == ret {
-            // PamResponse.resp is null for styles that don't return user input like PAM_TEXT_INFO
-            let response = unsafe { (*resp_ptr).resp };
-            if response.is_null() {
-                Ok(None)
-            } else {
-                let bytes = unsafe { CStr::from_ptr(response).to_bytes() };
-                Ok(String::from_utf8(bytes.to_vec()).ok())
-            }
-        } else {
-            Err(ret)
-        }
-    }
-}
-
-impl PamItem for PamConv {
-    fn item_type() -> PamItemType {
-        PAM_CONV
-    }
-}
diff --git a/rust/pam/src/pam/items.rs b/rust/pam/src/pam/items.rs
deleted file mode 100644 (file)
index 14bcade..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-   MIT License
-
-   Copyright (c) 2015 TOZNY
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy
-   of this software and associated documentation files (the "Software"), to deal
-   in the Software without restriction, including without limitation the rights
-   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   copies of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be included in all
-   copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-*/
-use crate::pam::constants::{
-    PamItemType, PAM_AUTHTOK, PAM_OLDAUTHTOK, PAM_RHOST, PAM_RUSER,
-    PAM_SERVICE, PAM_TTY, PAM_USER, PAM_USER_PROMPT,
-};
-pub use crate::pam::conv::PamConv;
-use crate::pam::module::PamItem;
-
-#[allow(dead_code)]
-pub struct PamService {}
-
-impl PamItem for PamService {
-    fn item_type() -> PamItemType {
-        PAM_SERVICE
-    }
-}
-
-#[allow(dead_code)]
-pub struct PamUser {}
-
-impl PamItem for PamUser {
-    fn item_type() -> PamItemType {
-        PAM_USER
-    }
-}
-
-#[allow(dead_code)]
-pub struct PamUserPrompt {}
-
-impl PamItem for PamUserPrompt {
-    fn item_type() -> PamItemType {
-        PAM_USER_PROMPT
-    }
-}
-
-#[allow(dead_code)]
-pub struct PamTty {}
-
-impl PamItem for PamTty {
-    fn item_type() -> PamItemType {
-        PAM_TTY
-    }
-}
-
-#[allow(dead_code)]
-pub struct PamRUser {}
-
-impl PamItem for PamRUser {
-    fn item_type() -> PamItemType {
-        PAM_RUSER
-    }
-}
-
-#[allow(dead_code)]
-pub struct PamRHost {}
-
-impl PamItem for PamRHost {
-    fn item_type() -> PamItemType {
-        PAM_RHOST
-    }
-}
-
-#[allow(dead_code)]
-pub struct PamAuthTok {}
-
-impl PamItem for PamAuthTok {
-    fn item_type() -> PamItemType {
-        PAM_AUTHTOK
-    }
-}
-
-#[allow(dead_code)]
-pub struct PamOldAuthTok {}
-
-impl PamItem for PamOldAuthTok {
-    fn item_type() -> PamItemType {
-        PAM_OLDAUTHTOK
-    }
-}
diff --git a/rust/pam/src/pam/macros.rs b/rust/pam/src/pam/macros.rs
deleted file mode 100644 (file)
index 6e3f6d9..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-   MIT License
-
-   Copyright (c) 2015 TOZNY
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy
-   of this software and associated documentation files (the "Software"), to deal
-   in the Software without restriction, including without limitation the rights
-   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   copies of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be included in all
-   copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-*/
-/// Macro to generate the `extern "C"` entrypoint bindings needed by PAM
-///
-/// You can call `pam_hooks!(SomeType);` for any type that implements `PamHooks`
-///
-/// ## Examples:
-///
-/// Here is full example of a PAM module that would authenticate and authorize everybody:
-///
-/// ```
-/// #[macro_use]
-/// extern crate pam;
-///
-/// use pam::constants::{PamFlag, PamResultCode};
-/// use pam::module::{PamHandle, PamHooks};
-/// use std::ffi::CStr;
-///
-/// # fn main() {}
-/// struct MyPamModule;
-/// pam_hooks!(MyPamModule);
-///
-/// impl PamHooks for MyPamModule {
-///     fn sm_authenticate(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode {
-///         println!("Everybody is authenticated!");
-///         PamResultCode::PAM_SUCCESS
-///     }
-///
-///     fn acct_mgmt(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode {
-///         println!("Everybody is authorized!");
-///         PamResultCode::PAM_SUCCESS
-///     }
-/// }
-/// ```
-#[macro_export]
-macro_rules! pam_hooks {
-    ($ident:ident) => {
-        pub use self::pam_hooks_scope::*;
-        mod pam_hooks_scope {
-            use std::ffi::CStr;
-            use std::os::raw::{c_char, c_int};
-
-            use $crate::pam::constants::{PamFlag, PamResultCode};
-            use $crate::pam::module::{PamHandle, PamHooks};
-
-            fn extract_argv<'a>(argc: c_int, argv: *const *const c_char) -> Vec<&'a CStr> {
-                (0..argc)
-                    .map(|o| unsafe { CStr::from_ptr(*argv.offset(o as isize) as *const c_char) })
-                    .collect()
-            }
-
-            #[no_mangle]
-            pub extern "C" fn pam_sm_acct_mgmt(
-                pamh: &PamHandle,
-                flags: PamFlag,
-                argc: c_int,
-                argv: *const *const c_char,
-            ) -> PamResultCode {
-                let args = extract_argv(argc, argv);
-                super::$ident::acct_mgmt(pamh, args, flags)
-            }
-
-            #[no_mangle]
-            pub extern "C" fn pam_sm_authenticate(
-                pamh: &PamHandle,
-                flags: PamFlag,
-                argc: c_int,
-                argv: *const *const c_char,
-            ) -> PamResultCode {
-                let args = extract_argv(argc, argv);
-                super::$ident::sm_authenticate(pamh, args, flags)
-            }
-
-            #[no_mangle]
-            pub extern "C" fn pam_sm_chauthtok(
-                pamh: &PamHandle,
-                flags: PamFlag,
-                argc: c_int,
-                argv: *const *const c_char,
-            ) -> PamResultCode {
-                let args = extract_argv(argc, argv);
-                super::$ident::sm_chauthtok(pamh, args, flags)
-            }
-
-            #[no_mangle]
-            pub extern "C" fn pam_sm_close_session(
-                pamh: &PamHandle,
-                flags: PamFlag,
-                argc: c_int,
-                argv: *const *const c_char,
-            ) -> PamResultCode {
-                let args = extract_argv(argc, argv);
-                super::$ident::sm_close_session(pamh, args, flags)
-            }
-
-            #[no_mangle]
-            pub extern "C" fn pam_sm_open_session(
-                pamh: &PamHandle,
-                flags: PamFlag,
-                argc: c_int,
-                argv: *const *const c_char,
-            ) -> PamResultCode {
-                let args = extract_argv(argc, argv);
-                super::$ident::sm_open_session(pamh, args, flags)
-            }
-
-            #[no_mangle]
-            pub extern "C" fn pam_sm_setcred(
-                pamh: &PamHandle,
-                flags: PamFlag,
-                argc: c_int,
-                argv: *const *const c_char,
-            ) -> PamResultCode {
-                let args = extract_argv(argc, argv);
-                super::$ident::sm_setcred(pamh, args, flags)
-            }
-        }
-    };
-}
diff --git a/rust/pam/src/pam/mod.rs b/rust/pam/src/pam/mod.rs
deleted file mode 100755 (executable)
index 7447ee0..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
-   MIT License
-
-   Copyright (c) 2015 TOZNY
-   Copyright (c) 2020 William Brown <william@blackhats.net.au>
-   Copyright (c) 2024 David Mulder <dmulder@samba.org>
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy
-   of this software and associated documentation files (the "Software"), to deal
-   in the Software without restriction, including without limitation the rights
-   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   copies of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be included in all
-   copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-*/
-//! Interface to the pluggable authentication module framework (PAM).
-//!
-//! The goal of this library is to provide a type-safe API that can be used to
-//! interact with PAM.  The library is incomplete - currently it supports
-//! a subset of functions for use in a pam authentication module.  A pam module
-//! is a shared library that is invoked to authenticate a user, or to perform
-//! other functions.
-//!
-//! For general information on writing pam modules, see
-//! [The Linux-PAM Module Writers' Guide][module-guide]
-//!
-//! [module-guide]: http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_MWG.html
-//!
-//! A typical authentication module will define an external function called
-//! `pam_sm_authenticate()`, which will use functions in this library to
-//! interrogate the program that requested authentication for more information,
-//! and to render a result.  For a working example that uses this library, see
-//! [toznyauth-pam][].
-//!
-//! [toznyauth-pam]: https://github.com/tozny/toznyauth-pam
-//!
-//! Note that constants that are normally read from pam header files are
-//! hard-coded in the `constants` module.  The values there are taken from
-//! a Linux system.  That means that it might take some work to get this library
-//! to work on other platforms.
-
-pub mod constants;
-pub mod conv;
-pub mod items;
-#[doc(hidden)]
-pub mod macros;
-pub mod module;
-
-use std::collections::BTreeSet;
-use std::convert::TryFrom;
-use std::ffi::CStr;
-
-use dbg::*;
-use param::LoadParm;
-use sock::{
-    stream_and_timeout, PamAuthRequest, PamAuthResponse, Request, Response,
-};
-
-use crate::pam::constants::*;
-use crate::pam::conv::PamConv;
-use crate::pam::module::{PamHandle, PamHooks};
-use crate::pam_hooks;
-use constants::PamResultCode;
-
-use std::thread;
-use std::time::Duration;
-
-fn install_subscriber(lp: &LoadParm, debug: bool) {
-    debuglevel_set!(if debug { DBGLVL_DEBUG } else { DBGLVL_ERR });
-    match lp.logfile() {
-        Ok(Some(logfile)) => {
-            debug_set_logfile(&logfile);
-            setup_logging(env!("CARGO_PKG_NAME"), DEBUG_FILE)
-        }
-        _ => setup_logging(env!("CARGO_PKG_NAME"), DEBUG_STDOUT),
-    }
-}
-
-#[derive(Debug)]
-struct Options {
-    debug: bool,
-    use_first_pass: bool,
-    ignore_unknown_user: bool,
-}
-
-impl TryFrom<&Vec<&CStr>> for Options {
-    type Error = ();
-
-    fn try_from(args: &Vec<&CStr>) -> Result<Self, Self::Error> {
-        let opts: Result<BTreeSet<&str>, _> =
-            args.iter().map(|cs| cs.to_str()).collect();
-        let gopts = match opts {
-            Ok(o) => o,
-            Err(e) => {
-                println!("Error in module args -> {:?}", e);
-                return Err(());
-            }
-        };
-
-        Ok(Options {
-            debug: gopts.contains("debug"),
-            use_first_pass: gopts.contains("use_first_pass"),
-            ignore_unknown_user: gopts.contains("ignore_unknown_user"),
-        })
-    }
-}
-
-pub struct PamHimmelblau;
-
-pam_hooks!(PamHimmelblau);
-
-macro_rules! match_sm_auth_client_response {
-    ($expr:expr, $opts:ident, $conv:ident, $req:ident, $authtok:ident, $($pat:pat => $result:expr),*) => {
-        match $expr {
-            Ok(r) => match r {
-                $($pat => $result),*
-                Response::PamAuthStepResponse(PamAuthResponse::Success) => {
-                    return PamResultCode::PAM_SUCCESS;
-                }
-                Response::PamAuthStepResponse(PamAuthResponse::Denied) => {
-                    return PamResultCode::PAM_AUTH_ERR;
-                }
-                Response::PamAuthStepResponse(PamAuthResponse::Unknown) => {
-                    if $opts.ignore_unknown_user {
-                        return PamResultCode::PAM_IGNORE;
-                    } else {
-                        return PamResultCode::PAM_USER_UNKNOWN;
-                    }
-                }
-                Response::PamAuthStepResponse(PamAuthResponse::SetupPin {
-                    msg,
-                }) => {
-                    match $conv.send(PAM_TEXT_INFO, &msg) {
-                        Ok(_) => {}
-                        Err(err) => {
-                            if $opts.debug {
-                                println!("Message prompt failed");
-                            }
-                            return err;
-                        }
-                    }
-
-                    let mut pin;
-                    let mut confirm;
-                    loop {
-                        pin = match $conv.send(PAM_PROMPT_ECHO_OFF, "New PIN: ") {
-                            Ok(password) => match password {
-                                Some(cred) => cred,
-                                None => {
-                                    DBG_DEBUG!("no pin");
-                                    return PamResultCode::PAM_CRED_INSUFFICIENT;
-                                }
-                            },
-                            Err(err) => {
-                                DBG_DEBUG!("unable to get pin");
-                                return err;
-                            }
-                        };
-
-                        confirm = match $conv.send(PAM_PROMPT_ECHO_OFF, "Confirm PIN: ") {
-                            Ok(password) => match password {
-                                Some(cred) => cred,
-                                None => {
-                                    DBG_DEBUG!("no confirmation pin");
-                                    return PamResultCode::PAM_CRED_INSUFFICIENT;
-                                }
-                            },
-                            Err(err) => {
-                                DBG_DEBUG!("unable to get confirmation pin");
-                                return err;
-                            }
-                        };
-
-                        if pin == confirm {
-                            break;
-                        } else {
-                            match $conv.send(PAM_TEXT_INFO, "Inputs did not match. Try again.") {
-                                Ok(_) => {}
-                                Err(err) => {
-                                    if $opts.debug {
-                                        println!("Message prompt failed");
-                                    }
-                                    return err;
-                                }
-                            }
-                        }
-                    }
-
-                    // Now setup the request for the next loop.
-                    $req = Request::PamAuthenticateStep(PamAuthRequest::SetupPin {
-                        pin,
-                    });
-                    continue;
-                },
-                Response::PamAuthStepResponse(PamAuthResponse::Pin) => {
-                    let mut consume_authtok = None;
-                    // Swap the authtok out with a None, so it can only be consumed once.
-                    // If it's already been swapped, we are just swapping two null pointers
-                    // here effectively.
-                    std::mem::swap(&mut $authtok, &mut consume_authtok);
-                    let cred = if let Some(cred) = consume_authtok {
-                        cred
-                    } else {
-                        match $conv.send(PAM_PROMPT_ECHO_OFF, "PIN: ") {
-                            Ok(password) => match password {
-                                Some(cred) => cred,
-                                None => {
-                                    DBG_DEBUG!("no pin");
-                                    return PamResultCode::PAM_CRED_INSUFFICIENT;
-                                }
-                            },
-                            Err(err) => {
-                                DBG_DEBUG!("unable to get pin");
-                                return err;
-                            }
-                        }
-                    };
-
-                    // Now setup the request for the next loop.
-                    $req = Request::PamAuthenticateStep(PamAuthRequest::Pin { pin: cred });
-                    continue;
-                }
-                _ => {
-                    // unexpected response.
-                    DBG_ERR!("PAM_IGNORE, unexpected resolver response: {:?}", r);
-                    return PamResultCode::PAM_IGNORE;
-                }
-            },
-            Err(e) => {
-                DBG_ERR!("PAM_IGNORE: {:?}", e);
-                return PamResultCode::PAM_IGNORE;
-            }
-        }
-    }
-}
-
-impl PamHooks for PamHimmelblau {
-    fn acct_mgmt(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        _flags: PamFlag,
-    ) -> PamResultCode {
-        let opts = match Options::try_from(&args) {
-            Ok(o) => o,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        install_subscriber(&lp, opts.debug);
-
-        let tty = pamh.get_tty();
-        let rhost = pamh.get_rhost();
-
-        DBG_DEBUG!("{:?} {:?} {:?} {:?} acct_mgmt", args, opts, tty, rhost);
-
-        let account_id = match pamh.get_user(None) {
-            Ok(aid) => aid,
-            Err(e) => {
-                DBG_ERR!("get_user: {:?}", e);
-                return e;
-            }
-        };
-
-        let req = Request::PamAccountAllowed(account_id);
-
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok(res) => res,
-            Err(e) => {
-                DBG_ERR!("Error stream_and_timeout: {:?}", e);
-                return PamResultCode::PAM_SERVICE_ERR;
-            }
-        };
-
-        match stream.send(&req, timeout) {
-            Ok(r) => match r {
-                Response::PamStatus(Some(true)) => {
-                    DBG_DEBUG!("PamResultCode::PAM_SUCCESS");
-                    PamResultCode::PAM_SUCCESS
-                }
-                Response::PamStatus(Some(false)) => {
-                    DBG_DEBUG!("PamResultCode::PAM_AUTH_ERR");
-                    PamResultCode::PAM_AUTH_ERR
-                }
-                Response::PamStatus(None) => {
-                    if opts.ignore_unknown_user {
-                        DBG_DEBUG!("PamResultCode::PAM_IGNORE");
-                        PamResultCode::PAM_IGNORE
-                    } else {
-                        DBG_DEBUG!("PamResultCode::PAM_USER_UNKNOWN");
-                        PamResultCode::PAM_USER_UNKNOWN
-                    }
-                }
-                _ => {
-                    // unexpected response.
-                    DBG_ERR!(
-                        "PAM_IGNORE, unexpected resolver response: {:?}",
-                        r
-                    );
-                    PamResultCode::PAM_IGNORE
-                }
-            },
-            Err(e) => {
-                DBG_ERR!("PamResultCode::PAM_IGNORE: {:?}", e);
-                PamResultCode::PAM_IGNORE
-            }
-        }
-    }
-
-    fn sm_authenticate(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        _flags: PamFlag,
-    ) -> PamResultCode {
-        let opts = match Options::try_from(&args) {
-            Ok(o) => o,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        install_subscriber(&lp, opts.debug);
-
-        let tty = pamh.get_tty();
-        let rhost = pamh.get_rhost();
-
-        DBG_DEBUG!(
-            "{:?} {:?} {:?} {:?} sm_authenticate",
-            args,
-            opts,
-            tty,
-            rhost
-        );
-
-        let account_id = match pamh.get_user(None) {
-            Ok(aid) => aid,
-            Err(e) => {
-                DBG_ERR!("get_user: {:?}", e);
-                return e;
-            }
-        };
-
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok(res) => res,
-            Err(e) => {
-                DBG_ERR!("Error stream_and_timeout: {:?}", e);
-                return PamResultCode::PAM_SERVICE_ERR;
-            }
-        };
-
-        // Later we may need to move this to a function and call it as a oneshot for auth methods
-        // that don't require any authtoks at all. For example, imagine a user authed and they
-        // needed to follow a URL to continue. In that case, they would fail here because they
-        // didn't enter an authtok that they didn't need!
-        let mut authtok = match pamh.get_authtok() {
-            Ok(Some(v)) => Some(v),
-            Ok(None) => {
-                if opts.use_first_pass {
-                    DBG_DEBUG!("Don't have an authtok, returning PAM_AUTH_ERR");
-                    return PamResultCode::PAM_AUTH_ERR;
-                }
-                None
-            }
-            Err(e) => {
-                DBG_ERR!("get_authtok: {:?}", e);
-                return e;
-            }
-        };
-
-        let conv = match pamh.get_item::<PamConv>() {
-            Ok(conv) => conv,
-            Err(e) => {
-                DBG_ERR!("pam_conv: {:?}", e);
-                return e;
-            }
-        };
-
-        let mut req = Request::PamAuthenticateInit(account_id);
-
-        loop {
-            match_sm_auth_client_response!(stream.send(&req, timeout), opts, conv, req, authtok,
-                Response::PamAuthStepResponse(PamAuthResponse::Password) => {
-                    let mut consume_authtok = None;
-                    // Swap the authtok out with a None, so it can only be consumed once.
-                    // If it's already been swapped, we are just swapping two null pointers
-                    // here effectively.
-                    std::mem::swap(&mut authtok, &mut consume_authtok);
-                    let cred = if let Some(cred) = consume_authtok {
-                        cred
-                    } else {
-                        match conv.send(PAM_PROMPT_ECHO_OFF, "Password: ") {
-                            Ok(password) => match password {
-                                Some(cred) => cred,
-                                None => {
-                                    DBG_DEBUG!("no password");
-                                    return PamResultCode::PAM_CRED_INSUFFICIENT;
-                                }
-                            },
-                            Err(err) => {
-                                DBG_DEBUG!("unable to get password");
-                                return err;
-                            }
-                        }
-                    };
-
-                    // Now setup the request for the next loop.
-                    req = Request::PamAuthenticateStep(PamAuthRequest::Password { cred });
-                    continue;
-                },
-                Response::PamAuthStepResponse(PamAuthResponse::MFACode {
-                    msg,
-                }) => {
-                    match conv.send(PAM_TEXT_INFO, &msg) {
-                        Ok(_) => {}
-                        Err(err) => {
-                            if opts.debug {
-                                println!("Message prompt failed");
-                            }
-                            return err;
-                        }
-                    }
-                    let cred = match conv.send(PAM_PROMPT_ECHO_OFF, "Code: ") {
-                        Ok(password) => match password {
-                            Some(cred) => cred,
-                            None => {
-                                DBG_DEBUG!("no mfa code");
-                                return PamResultCode::PAM_CRED_INSUFFICIENT;
-                            }
-                        },
-                        Err(err) => {
-                            DBG_DEBUG!("unable to get mfa code");
-                            return err;
-                        }
-                    };
-
-                    // Now setup the request for the next loop.
-                    req = Request::PamAuthenticateStep(PamAuthRequest::MFACode {
-                        cred,
-                    });
-                    continue;
-                },
-                Response::PamAuthStepResponse(PamAuthResponse::MFAPoll {
-                    msg,
-                    polling_interval,
-                }) => {
-                    match conv.send(PAM_TEXT_INFO, &msg) {
-                        Ok(_) => {}
-                        Err(err) => {
-                            if opts.debug {
-                                println!("Message prompt failed");
-                            }
-                            return err;
-                        }
-                    }
-
-                    // Necessary because of OpenSSH bug
-                    // https://bugzilla.mindrot.org/show_bug.cgi?id=2876 -
-                    // PAM_TEXT_INFO and PAM_ERROR_MSG conversation not
-                    // honoured during PAM authentication
-                    let _ = conv.send(PAM_PROMPT_ECHO_OFF, "Press enter to continue");
-
-                    let mut poll_attempt = 0;
-                    req = Request::PamAuthenticateStep(
-                        PamAuthRequest::MFAPoll { poll_attempt }
-                    );
-                    loop {
-                        thread::sleep(Duration::from_secs(polling_interval.into()));
-
-                        match_sm_auth_client_response!(
-                            stream.send(&req, timeout), opts, conv, req, authtok,
-                            Response::PamAuthStepResponse(
-                                    PamAuthResponse::MFAPollWait,
-                            ) => {
-                                // Continue polling if the daemon says to wait
-                                poll_attempt += 1;
-                                req = Request::PamAuthenticateStep(
-                                    PamAuthRequest::MFAPoll { poll_attempt }
-                                );
-                                continue;
-                            }
-                        );
-                    }
-                }
-            );
-        } // while true, continue calling PamAuthenticateStep until we get a decision.
-    }
-
-    fn sm_chauthtok(
-        _pamh: &PamHandle,
-        args: Vec<&CStr>,
-        _flags: PamFlag,
-    ) -> PamResultCode {
-        let opts = match Options::try_from(&args) {
-            Ok(o) => o,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        install_subscriber(&lp, opts.debug);
-
-        DBG_DEBUG!("{:?} {:?} sm_chauthtok", args, opts);
-
-        PamResultCode::PAM_IGNORE
-    }
-
-    fn sm_close_session(
-        _pamh: &PamHandle,
-        args: Vec<&CStr>,
-        _flags: PamFlag,
-    ) -> PamResultCode {
-        let opts = match Options::try_from(&args) {
-            Ok(o) => o,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        install_subscriber(&lp, opts.debug);
-
-        DBG_DEBUG!("{:?} {:?} sm_close_session", args, opts);
-
-        PamResultCode::PAM_SUCCESS
-    }
-
-    fn sm_open_session(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        _flags: PamFlag,
-    ) -> PamResultCode {
-        let opts = match Options::try_from(&args) {
-            Ok(o) => o,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        install_subscriber(&lp, opts.debug);
-
-        DBG_DEBUG!("{:?} {:?} sm_open_session", args, opts);
-
-        let account_id = match pamh.get_user(None) {
-            Ok(aid) => aid,
-            Err(e) => {
-                DBG_ERR!("get_user: {:?}", e);
-                return e;
-            }
-        };
-
-        let req = Request::PamAccountBeginSession(account_id);
-
-        let (mut stream, timeout) = match stream_and_timeout(&lp) {
-            Ok(res) => res,
-            Err(e) => {
-                DBG_ERR!("Error stream_and_timeout: {:?}", e);
-                return PamResultCode::PAM_SERVICE_ERR;
-            }
-        };
-
-        match stream.send(&req, timeout) {
-            Ok(Response::Success) => PamResultCode::PAM_SUCCESS,
-            other => {
-                DBG_DEBUG!("PAM_IGNORE: {:?}", other);
-                PamResultCode::PAM_IGNORE
-            }
-        }
-    }
-
-    fn sm_setcred(
-        _pamh: &PamHandle,
-        args: Vec<&CStr>,
-        _flags: PamFlag,
-    ) -> PamResultCode {
-        let opts = match Options::try_from(&args) {
-            Ok(o) => o,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        let lp = match LoadParm::new(None) {
-            Ok(lp) => lp,
-            Err(_) => return PamResultCode::PAM_SERVICE_ERR,
-        };
-
-        install_subscriber(&lp, opts.debug);
-
-        DBG_DEBUG!("{:?} {:?} sm_setcred", args, opts);
-
-        PamResultCode::PAM_SUCCESS
-    }
-}
diff --git a/rust/pam/src/pam/module.rs b/rust/pam/src/pam/module.rs
deleted file mode 100755 (executable)
index df2eade..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
-   MIT License
-
-   Copyright (c) 2015 TOZNY
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy
-   of this software and associated documentation files (the "Software"), to deal
-   in the Software without restriction, including without limitation the rights
-   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   copies of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be included in all
-   copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-*/
-//! Functions for use in pam modules.
-
-use std::ffi::{CStr, CString};
-use std::{mem, ptr};
-
-use libc::c_char;
-
-use crate::pam::constants::{
-    PamFlag, PamItemType, PamResultCode, PAM_AUTHTOK, PAM_RHOST, PAM_TTY,
-};
-
-/// Opaque type, used as a pointer when making pam API calls.
-///
-/// A module is invoked via an external function such as `pam_sm_authenticate`.
-/// Such a call provides a pam handle pointer.  The same pointer should be given
-/// as an argument when making API calls.
-#[allow(missing_copy_implementations)]
-pub enum PamHandle {}
-
-#[allow(missing_copy_implementations)]
-enum PamItemT {}
-
-#[allow(missing_copy_implementations)]
-pub enum PamDataT {}
-
-#[link(name = "pam")]
-extern "C" {
-    fn pam_get_data(
-        pamh: *const PamHandle,
-        module_data_name: *const c_char,
-        data: &mut *const PamDataT,
-    ) -> PamResultCode;
-
-    fn pam_set_data(
-        pamh: *const PamHandle,
-        module_data_name: *const c_char,
-        data: *mut PamDataT,
-        cleanup: unsafe extern "C" fn(
-            pamh: *const PamHandle,
-            data: *mut PamDataT,
-            error_status: PamResultCode,
-        ),
-    ) -> PamResultCode;
-
-    fn pam_get_item(
-        pamh: *const PamHandle,
-        item_type: PamItemType,
-        item: &mut *const PamItemT,
-    ) -> PamResultCode;
-
-    fn pam_set_item(
-        pamh: *mut PamHandle,
-        item_type: PamItemType,
-        item: &PamItemT,
-    ) -> PamResultCode;
-
-    fn pam_get_user(
-        pamh: *const PamHandle,
-        user: &*mut c_char,
-        prompt: *const c_char,
-    ) -> PamResultCode;
-}
-
-/// # Safety
-///
-/// We're doing what we can for this one, but it's FFI.
-pub unsafe extern "C" fn cleanup<T>(
-    _: *const PamHandle,
-    c_data: *mut PamDataT,
-    _: PamResultCode,
-) {
-    let c_data = Box::from_raw(c_data);
-    let data: Box<T> = mem::transmute(c_data);
-    mem::drop(data);
-}
-
-pub type PamResult<T> = Result<T, PamResultCode>;
-
-/// # Safety
-///
-/// Type-level mapping for safely retrieving values with `get_item`.
-///
-/// See `pam_get_item` in
-/// <http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html>
-pub trait PamItem {
-    /// Maps a Rust type to a pam constant.
-    ///
-    /// For example, the type PamConv maps to the constant PAM_CONV.  The pam
-    /// API contract specifies that when the API function `pam_get_item` is
-    /// called with the constant PAM_CONV, it will return a value of type
-    /// `PamConv`.
-    fn item_type() -> PamItemType;
-}
-
-impl PamHandle {
-    /// # Safety
-    ///
-    /// Gets some value, identified by `key`, that has been set by the module
-    /// previously.
-    ///
-    /// See `pam_get_data` in
-    /// <http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html>
-    pub unsafe fn get_data<'a, T>(&'a self, key: &str) -> PamResult<&'a T> {
-        let c_key = CString::new(key).unwrap();
-        let mut ptr: *const PamDataT = ptr::null();
-        let res = pam_get_data(self, c_key.as_ptr(), &mut ptr);
-        if PamResultCode::PAM_SUCCESS == res && !ptr.is_null() {
-            let typed_ptr: *const T = ptr as *const T;
-            let data: &T = &*typed_ptr;
-            Ok(data)
-        } else {
-            Err(res)
-        }
-    }
-
-    /// Stores a value that can be retrieved later with `get_data`.  The value lives
-    /// as long as the current pam cycle.
-    ///
-    /// See `pam_set_data` in
-    /// <http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html>
-    pub fn set_data<T>(&self, key: &str, data: Box<T>) -> PamResult<()> {
-        let c_key = CString::new(key).unwrap();
-        let res = unsafe {
-            let c_data: Box<PamDataT> = mem::transmute(data);
-            let c_data = Box::into_raw(c_data);
-            pam_set_data(self, c_key.as_ptr(), c_data, cleanup::<T>)
-        };
-        if PamResultCode::PAM_SUCCESS == res {
-            Ok(())
-        } else {
-            Err(res)
-        }
-    }
-
-    /// Retrieves a value that has been set, possibly by the pam client.  This is
-    /// particularly useful for getting a `PamConv` reference.
-    ///
-    /// See `pam_get_item` in
-    /// <http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html>
-    pub fn get_item<'a, T: PamItem>(&self) -> PamResult<&'a T> {
-        let mut ptr: *const PamItemT = ptr::null();
-        let (res, item) = unsafe {
-            let r = pam_get_item(self, T::item_type(), &mut ptr);
-            let typed_ptr: *const T = ptr as *const T;
-            let t: &T = &*typed_ptr;
-            (r, t)
-        };
-        if PamResultCode::PAM_SUCCESS == res {
-            Ok(item)
-        } else {
-            Err(res)
-        }
-    }
-
-    /// Sets a value in the pam context. The value can be retrieved using
-    /// `get_item`.
-    ///
-    /// Note that all items are strings, except `PAM_CONV` and `PAM_FAIL_DELAY`.
-    ///
-    /// See `pam_set_item` in
-    /// <http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html>
-    pub fn set_item_str<T: PamItem>(&mut self, item: &str) -> PamResult<()> {
-        let c_item = CString::new(item).unwrap();
-
-        let res = unsafe {
-            pam_set_item(
-                self,
-                T::item_type(),
-                // unwrapping is okay here, as c_item will not be a NULL
-                // pointer
-                (c_item.as_ptr() as *const PamItemT).as_ref().unwrap(),
-            )
-        };
-        if PamResultCode::PAM_SUCCESS == res {
-            Ok(())
-        } else {
-            Err(res)
-        }
-    }
-
-    /// Retrieves the name of the user who is authenticating or logging in.
-    ///
-    /// This is really a specialization of `get_item`.
-    ///
-    /// See `pam_get_user` in
-    /// <http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html>
-    pub fn get_user(&self, prompt: Option<&str>) -> PamResult<String> {
-        let ptr: *mut c_char = ptr::null_mut();
-        let res = match prompt {
-            Some(p) => {
-                let c_prompt = CString::new(p).unwrap();
-                unsafe { pam_get_user(self, &ptr, c_prompt.as_ptr()) }
-            }
-            None => unsafe { pam_get_user(self, &ptr, ptr::null()) },
-        };
-
-        if PamResultCode::PAM_SUCCESS == res && !ptr.is_null() {
-            let const_ptr = ptr as *const c_char;
-            let bytes = unsafe { CStr::from_ptr(const_ptr).to_bytes() };
-            String::from_utf8(bytes.to_vec())
-                .map_err(|_| PamResultCode::PAM_CONV_ERR)
-        } else {
-            Err(res)
-        }
-    }
-
-    pub fn get_authtok(&self) -> PamResult<Option<String>> {
-        let mut ptr: *const PamItemT = ptr::null();
-        let (res, item) = unsafe {
-            let r = pam_get_item(self, PAM_AUTHTOK, &mut ptr);
-            let t = if PamResultCode::PAM_SUCCESS == r && !ptr.is_null() {
-                let typed_ptr: *const c_char = ptr as *const c_char;
-                Some(CStr::from_ptr(typed_ptr).to_string_lossy().into_owned())
-            } else {
-                None
-            };
-            (r, t)
-        };
-        if PamResultCode::PAM_SUCCESS == res {
-            Ok(item)
-        } else {
-            Err(res)
-        }
-    }
-
-    pub fn get_tty(&self) -> PamResult<Option<String>> {
-        let mut ptr: *const PamItemT = ptr::null();
-        let (res, item) = unsafe {
-            let r = pam_get_item(self, PAM_TTY, &mut ptr);
-            let t = if PamResultCode::PAM_SUCCESS == r && !ptr.is_null() {
-                let typed_ptr: *const c_char = ptr as *const c_char;
-                Some(CStr::from_ptr(typed_ptr).to_string_lossy().into_owned())
-            } else {
-                None
-            };
-            (r, t)
-        };
-        if PamResultCode::PAM_SUCCESS == res {
-            Ok(item)
-        } else {
-            Err(res)
-        }
-    }
-
-    pub fn get_rhost(&self) -> PamResult<Option<String>> {
-        let mut ptr: *const PamItemT = ptr::null();
-        let (res, item) = unsafe {
-            let r = pam_get_item(self, PAM_RHOST, &mut ptr);
-            let t = if PamResultCode::PAM_SUCCESS == r && !ptr.is_null() {
-                let typed_ptr: *const c_char = ptr as *const c_char;
-                Some(CStr::from_ptr(typed_ptr).to_string_lossy().into_owned())
-            } else {
-                None
-            };
-            (r, t)
-        };
-        if PamResultCode::PAM_SUCCESS == res {
-            Ok(item)
-        } else {
-            Err(res)
-        }
-    }
-}
-
-/// Provides functions that are invoked by the entrypoints generated by the
-/// [`pam_hooks!` macro](../macro.pam_hooks.html).
-///
-/// All of hooks are ignored by PAM dispatch by default given the default return value of `PAM_IGNORE`.
-/// Override any functions that you want to handle with your module. See `man pam(3)`.
-#[allow(unused_variables)]
-pub trait PamHooks {
-    /// This function performs the task of establishing whether the user is permitted to gain access at
-    /// this time. It should be understood that the user has previously been validated by an
-    /// authentication module. This function checks for other things. Such things might be: the time of
-    /// day or the date, the terminal line, remote hostname, etc. This function may also determine
-    /// things like the expiration on passwords, and respond that the user change it before continuing.
-    fn acct_mgmt(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        flags: PamFlag,
-    ) -> PamResultCode {
-        PamResultCode::PAM_IGNORE
-    }
-
-    /// This function performs the task of authenticating the user.
-    fn sm_authenticate(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        flags: PamFlag,
-    ) -> PamResultCode {
-        PamResultCode::PAM_IGNORE
-    }
-
-    /// This function is used to (re-)set the authentication token of the user.
-    ///
-    /// The PAM library calls this function twice in succession. The first time with
-    /// PAM_PRELIM_CHECK and then, if the module does not return PAM_TRY_AGAIN, subsequently with
-    /// PAM_UPDATE_AUTHTOK. It is only on the second call that the authorization token is
-    /// (possibly) changed.
-    fn sm_chauthtok(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        flags: PamFlag,
-    ) -> PamResultCode {
-        PamResultCode::PAM_IGNORE
-    }
-
-    /// This function is called to terminate a session.
-    fn sm_close_session(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        flags: PamFlag,
-    ) -> PamResultCode {
-        PamResultCode::PAM_IGNORE
-    }
-
-    /// This function is called to commence a session.
-    fn sm_open_session(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        flags: PamFlag,
-    ) -> PamResultCode {
-        PamResultCode::PAM_IGNORE
-    }
-
-    /// This function performs the task of altering the credentials of the user with respect to the
-    /// corresponding authorization scheme. Generally, an authentication module may have access to more
-    /// information about a user than their authentication token. This function is used to make such
-    /// information available to the application. It should only be called after the user has been
-    /// authenticated but before a session has been established.
-    fn sm_setcred(
-        pamh: &PamHandle,
-        args: Vec<&CStr>,
-        flags: PamFlag,
-    ) -> PamResultCode {
-        PamResultCode::PAM_IGNORE
-    }
-}
diff --git a/rust/param/Cargo.toml b/rust/param/Cargo.toml
deleted file mode 100644 (file)
index e90e500..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "param"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[dependencies]
-chelps = { workspace = true }
-dbg.workspace = true
-ntstatus_gen.workspace = true
-paste = "1.0.15"
-
-[build-dependencies]
-bindgen = "0.69.4"
diff --git a/rust/param/build.rs b/rust/param/build.rs
deleted file mode 100644 (file)
index 6d533e3..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-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")
-        .clang_arg("-Doffset_t=loff_t")
-        .clang_arg("-I../../bin/default")
-        .clang_arg("-I../../lib/talloc")
-        .generate_comments(false)
-        .clang_arg("-includestdint.h")
-        .header("../../lib/param/param.h")
-        .header("../../lib/param/loadparm.h")
-        .header("../../source3/param/loadparm.h")
-        .header("../../bin/default/lib/param/param_functions.h")
-        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
-        .generate()
-        .expect("Unable to generate bindings");
-    println!("cargo:rerun-if-changed=../../lib/param/param.h");
-    println!("cargo:rerun-if-changed=../../lib/param/loadparm.h");
-    println!("cargo:rerun-if-changed=../../source3/param/loadparm.h");
-    println!(
-        "cargo:rerun-if-changed=../../bin/default/lib/param/param_functions.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/source3");
-    println!(
-        "cargo:rustc-link-search=native={}",
-        src_dir.to_str().unwrap()
-    );
-    println!("cargo:rustc-link-lib=smbconf");
-
-    let mut src_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
-    src_dir.push("../../bin/default/lib/param");
-    println!("cargo:rustc-link-lib=samba-hostconfig-private-samba");
-    println!(
-        "cargo:rustc-link-search=native={}",
-        src_dir.to_str().unwrap()
-    );
-}
diff --git a/rust/param/src/lib.rs b/rust/param/src/lib.rs
deleted file mode 100644 (file)
index 38e2728..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Parameter loading 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 <http://www.gnu.org/licenses/>.
-*/
-
-use chelps::{string_free, wrap_c_char, wrap_string};
-use dbg::{DBG_ERR, DBG_INFO, DBG_WARNING};
-use ntstatus_gen::NT_STATUS_UNSUCCESSFUL;
-use std::error::Error;
-use std::ffi::c_void;
-use std::ptr;
-use std::sync::{Arc, Mutex};
-
-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"));
-}
-
-pub struct LoadParm {
-    lp: Arc<Mutex<*mut ffi::loadparm_context>>,
-}
-
-macro_rules! lpcfg_str {
-    ($var:ident) => {
-        paste::item! {
-            pub fn $var (&self) -> Result<Option<String>, Box<dyn Error + '_>> {
-                let lp = self.lp.lock()?;
-                let val = unsafe { ffi::[< lpcfg_ $var >] (*lp) } ;
-                unsafe { Ok(wrap_c_char(val)) }
-            }
-        }
-    };
-}
-
-macro_rules! lpcfg_i32 {
-    ($var:ident) => {
-        paste::item! {
-            pub fn $var (&self) -> Result<i32, Box<dyn Error + '_>> {
-                let lp = self.lp.lock()?;
-                unsafe { Ok(ffi::[< lpcfg_ $var >] (*lp)) }
-            }
-        }
-    };
-}
-
-macro_rules! lpcfg_bool {
-    ($var:ident) => {
-        paste::item! {
-            pub fn $var (&self) -> Result<bool, Box<dyn Error + '_>> {
-                let lp = self.lp.lock()?;
-                unsafe { Ok(ffi::[< lpcfg_ $var >] (*lp) != 0) }
-            }
-        }
-    };
-}
-
-impl LoadParm {
-    pub fn new(configfile: Option<&str>) -> Result<Self, Box<dyn Error + '_>> {
-        let lp = unsafe {
-            match configfile {
-                Some(configfile) => {
-                    let configfile_cstr = wrap_string(configfile);
-                    let lp = ffi::loadparm_init_global(0);
-                    if ffi::lpcfg_load(lp, configfile_cstr) != 1 {
-                        return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-                    }
-                    string_free(configfile_cstr);
-                    lp
-                }
-                None => ffi::loadparm_init_global(1),
-            }
-        };
-        Ok(LoadParm {
-            lp: Arc::new(Mutex::new(lp)),
-        })
-    }
-
-    pub fn private_path(
-        &self,
-        name: &str,
-    ) -> Result<Option<String>, Box<dyn Error + '_>> {
-        let lp = self.lp.lock()?;
-        let path = unsafe {
-            let name_cstr = wrap_string(name);
-            let path =
-                ffi::lpcfg_private_path(*lp as *mut c_void, *lp, name_cstr);
-            string_free(name_cstr);
-            path
-        };
-        unsafe { Ok(wrap_c_char(path)) }
-    }
-
-    pub fn logfile(&self) -> Result<Option<String>, Box<dyn Error + '_>> {
-        let lp = self.lp.lock()?;
-        let logfile = unsafe {
-            let lp_sub = ffi::lpcfg_noop_substitution();
-            ffi::lpcfg_logfile(*lp, lp_sub, *lp as *mut c_void)
-        };
-        unsafe { Ok(wrap_c_char(logfile)) }
-    }
-
-    pub fn idmap_range(
-        &self,
-        domain_name: &str,
-    ) -> Result<(u32, u32), Box<dyn Error + '_>> {
-        if let Ok(Some(backend)) = self.idmap_backend(domain_name) {
-            if backend != "upn" {
-                DBG_ERR!("Backend '{}' is not supported for Entra ID", backend);
-                return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-            }
-        } else if domain_name != "*" {
-            DBG_WARNING!(
-                "No idmap backend configured for domain '{}'",
-                domain_name
-            );
-            DBG_INFO!("Falling back to default idmap configuration");
-            return self.idmap_range("*");
-        } else {
-            DBG_WARNING!("No idmap backend configured");
-            return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-        }
-        let lp = self.lp.lock()?;
-        let parm_name = format!("idmap config {}", domain_name);
-        let parm_opt = "range";
-        let range = unsafe {
-            let parm_name_cstr = wrap_string(&parm_name);
-            let parm_opt_cstr = wrap_string(parm_opt);
-            let parm_opt_value = ffi::lpcfg_parm_string(
-                *lp,
-                ptr::null_mut(),
-                parm_name_cstr,
-                parm_opt_cstr,
-            );
-            string_free(parm_name_cstr);
-            string_free(parm_opt_cstr);
-            wrap_c_char(parm_opt_value)
-        }
-        .ok_or(Box::new(NT_STATUS_UNSUCCESSFUL))?;
-        let parts: Vec<&str> = range.split('-').collect();
-        if parts.len() != 2 {
-            DBG_ERR!("Failed to parse the idmap range: {}", range);
-            return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-        }
-        Ok((parts[0].parse::<u32>()?, parts[1].parse::<u32>()?))
-    }
-
-    pub fn idmap_backend(
-        &self,
-        domain_name: &str,
-    ) -> Result<Option<String>, Box<dyn Error + '_>> {
-        let lp = self.lp.lock()?;
-        let parm_name = format!("idmap config {}", domain_name);
-        let parm_opt = "backend";
-        unsafe {
-            let parm_name_cstr = wrap_string(&parm_name);
-            let parm_opt_cstr = wrap_string(parm_opt);
-            let parm_opt_value = ffi::lpcfg_parm_string(
-                *lp,
-                ptr::null_mut(),
-                parm_name_cstr,
-                parm_opt_cstr,
-            );
-            string_free(parm_name_cstr);
-            string_free(parm_opt_cstr);
-            Ok(wrap_c_char(parm_opt_value))
-        }
-    }
-
-    lpcfg_str!(realm);
-    lpcfg_str!(winbindd_socket_directory);
-    lpcfg_i32!(winbind_request_timeout);
-    lpcfg_bool!(himmelblaud_sfa_fallback);
-    lpcfg_bool!(himmelblaud_hello_enabled);
-    lpcfg_str!(cache_directory);
-    lpcfg_str!(template_homedir);
-    lpcfg_str!(template_shell);
-    lpcfg_str!(himmelblaud_hsm_pin_path);
-}
-
-unsafe impl Send for LoadParm {}
-unsafe impl Sync for LoadParm {}
diff --git a/rust/rustfmt.toml b/rust/rustfmt.toml
deleted file mode 100644 (file)
index fee2c90..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# Lightly enforce maximum 80 characters
-max_width = 80
diff --git a/rust/sock/Cargo.toml b/rust/sock/Cargo.toml
deleted file mode 100644 (file)
index be649be..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-name = "sock"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[dependencies]
-chelps.workspace = true
-dbg.workspace = true
-libc.workspace = true
-libnss = "0.8.0"
-ntstatus_gen.workspace = true
-param.workspace = true
-serde = { version = "1.0.204", features = ["derive"] }
-serde_json = "1.0.120"
diff --git a/rust/sock/src/lib.rs b/rust/sock/src/lib.rs
deleted file mode 100644 (file)
index 9ccddde..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Unix socket communication for the Himmelblau daemon
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-mod proto;
-pub use proto::*;
-
-use dbg::DBG_ERR;
-use ntstatus_gen::*;
-use param::LoadParm;
-use serde_json::{from_slice as json_from_slice, to_vec as json_to_vec};
-use std::error::Error;
-use std::io::{Read, Write};
-use std::os::unix::net::UnixStream;
-use std::path::{Path, PathBuf};
-use std::time::{Duration, SystemTime};
-
-pub struct ClientStream {
-    stream: UnixStream,
-}
-
-impl ClientStream {
-    pub fn new(path: &str) -> Result<Self, Box<dyn Error>> {
-        Ok(ClientStream {
-            stream: UnixStream::connect(path)
-                .map_err(|e| {
-                    DBG_ERR!("Unix socket stream setup error while connecting to {}: {:?}",
-                        path, e
-                    );
-                    e
-                })?,
-        })
-    }
-
-    pub fn send(
-        &mut self,
-        req: &Request,
-        timeout: u64,
-    ) -> Result<Response, Box<dyn Error>> {
-        // Set the timeout
-        let timeout = Duration::from_secs(timeout);
-        self.stream.set_read_timeout(Some(timeout))?;
-        self.stream.set_write_timeout(Some(timeout))?;
-
-        // Encode the request as bytes
-        let req_bytes = json_to_vec(req)?;
-
-        // Send the request
-        self.stream.write_all(&req_bytes)?;
-
-        // Now wait on the response
-        let start = SystemTime::now();
-        let mut read_started = false;
-        let mut data = Vec::with_capacity(1024);
-        let mut counter = 0;
-
-        loop {
-            let mut buffer = [0; 1024];
-            let durr =
-                SystemTime::now().duration_since(start).map_err(Box::new)?;
-            if durr > timeout {
-                DBG_ERR!("Socket timeout");
-                break;
-            }
-            match self.stream.read(&mut buffer) {
-                Ok(0) => {
-                    if read_started {
-                        break;
-                    } else {
-                        continue;
-                    }
-                }
-                Ok(count) => {
-                    data.extend_from_slice(&buffer);
-                    counter += count;
-                    if count == 1024 {
-                        read_started = true;
-                        continue;
-                    } else {
-                        break;
-                    }
-                }
-                Err(e) => {
-                    DBG_ERR!(
-                        "Stream read failure from {:?}: {:?}",
-                        &self.stream,
-                        e
-                    );
-                    return Err(Box::new(e));
-                }
-            }
-        }
-
-        data.truncate(counter);
-
-        // Now decode the response
-        let resp: Response = json_from_slice(data.as_slice())?;
-        Ok(resp)
-    }
-}
-
-pub fn stream_and_timeout(
-    lp: &LoadParm,
-) -> Result<(ClientStream, u64), Box<NTSTATUS>> {
-    // Get the socket path
-    let sock_dir_str = lp
-        .winbindd_socket_directory()
-        .map_err(|_| Box::new(NT_STATUS_NOT_FOUND))?
-        .ok_or(Box::new(NT_STATUS_NOT_FOUND))?;
-    let sock_dir = Path::new(&sock_dir_str);
-    let mut sock_path = PathBuf::from(sock_dir);
-    sock_path.push("hb_pipe");
-    let sock_path = sock_path.to_str().ok_or(Box::new(NT_STATUS_NOT_FOUND))?;
-
-    // Open the socket
-    let timeout: u64 = lp
-        .winbind_request_timeout()
-        .map_err(|_| Box::new(NT_STATUS_NOT_FOUND))?
-        .try_into()
-        .map_err(|_| Box::new(NT_STATUS_NOT_FOUND))?;
-    let stream = ClientStream::new(sock_path)
-        .map_err(|_| Box::new(NT_STATUS_PIPE_NOT_AVAILABLE))?;
-    Ok((stream, timeout))
-}
diff --git a/rust/sock/src/proto.rs b/rust/sock/src/proto.rs
deleted file mode 100644 (file)
index 728637a..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Unix socket communication for the Himmelblau daemon
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-use libc::uid_t;
-use libnss::group::Group as NssGroup;
-use libnss::passwd::Passwd as NssPasswd;
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize)]
-pub struct Passwd {
-    pub name: String,
-    pub passwd: String,
-    pub uid: u32,
-    pub gid: u32,
-    pub gecos: String,
-    pub dir: String,
-    pub shell: String,
-}
-
-impl From<Passwd> for NssPasswd {
-    fn from(val: Passwd) -> Self {
-        NssPasswd {
-            name: val.name,
-            passwd: val.passwd,
-            uid: val.uid,
-            gid: val.gid,
-            gecos: val.gecos,
-            dir: val.dir,
-            shell: val.shell,
-        }
-    }
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub struct Group {
-    pub name: String,
-    pub passwd: String,
-    pub gid: u32,
-    pub members: Vec<String>,
-}
-
-impl From<Group> for NssGroup {
-    fn from(val: Group) -> Self {
-        NssGroup {
-            name: val.name,
-            passwd: val.passwd,
-            gid: val.gid,
-            members: val.members,
-        }
-    }
-}
-
-#[derive(Serialize, Deserialize)]
-pub enum PamAuthRequest {
-    Password { cred: String },
-    MFACode { cred: String },
-    MFAPoll { poll_attempt: u32 },
-    SetupPin { pin: String },
-    Pin { pin: String },
-}
-
-#[derive(Serialize, Deserialize)]
-pub enum Request {
-    NssAccounts,
-    NssAccountByUid(uid_t),
-    NssAccountByName(String),
-    NssGroups,
-    NssGroupByGid(uid_t),
-    NssGroupByName(String),
-    PamAuthenticateInit(String),
-    PamAuthenticateStep(PamAuthRequest),
-    PamAccountAllowed(String),
-    PamAccountBeginSession(String),
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub enum PamAuthResponse {
-    Unknown,
-    Success,
-    Denied,
-    Password,
-    MFACode { msg: String },
-    MFAPoll { msg: String, polling_interval: u32 },
-    MFAPollWait,
-    SetupPin { msg: String },
-    Pin,
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub enum Response {
-    NssAccounts(Vec<Passwd>),
-    NssAccount(Option<Passwd>),
-    NssGroups(Vec<Group>),
-    NssGroup(Option<Group>),
-    PamStatus(Option<bool>),
-    PamAuthStepResponse(PamAuthResponse),
-    Success,
-    Error,
-}
diff --git a/rust/talloc/Cargo.toml b/rust/talloc/Cargo.toml
deleted file mode 100644 (file)
index a21b3da..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-[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
deleted file mode 100644 (file)
index d14b0b0..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-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
deleted file mode 100644 (file)
index c2eef6f..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-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);
-            }
-        }
-    }};
-}
diff --git a/rust/tdb/Cargo.toml b/rust/tdb/Cargo.toml
deleted file mode 100644 (file)
index aad1c72..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-name = "tdb"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[dependencies]
-chelps = { workspace = true }
-dbg.workspace = true
-libc.workspace = true
-ntstatus_gen.workspace = true
-
-[build-dependencies]
-bindgen = "0.69.4"
-config.workspace = true
diff --git a/rust/tdb/build.rs b/rust/tdb/build.rs
deleted file mode 100644 (file)
index 57ee90a..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-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("-includesys/stat.h")
-        .header("../../lib/tdb/include/tdb.h")
-        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
-        .generate()
-        .expect("Unable to generate bindings");
-
-    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/tdb");
-    if config::USING_SYSTEM_TDB == 1 {
-        println!("cargo:rustc-link-lib=tdb");
-    } else {
-        println!("cargo:rustc-link-lib=tdb-private-samba");
-    }
-    println!(
-        "cargo:rustc-link-search=native={}",
-        src_dir.to_str().unwrap()
-    );
-}
diff --git a/rust/tdb/src/lib.rs b/rust/tdb/src/lib.rs
deleted file mode 100644 (file)
index cb9af44..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   trivial database library FFI
-
-   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 <http://www.gnu.org/licenses/>.
-*/
-
-use chelps::wrap_string;
-use dbg::DBG_ERR;
-use libc::free;
-use ntstatus_gen::NT_STATUS_UNSUCCESSFUL;
-use std::error::Error;
-use std::ffi::c_void;
-use std::fmt;
-use std::path::PathBuf;
-use std::sync::{Arc, Mutex};
-
-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"));
-}
-
-pub const TDB_SUCCESS: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_SUCCESS;
-pub const TDB_ERR_CORRUPT: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_CORRUPT;
-pub const TDB_ERR_IO: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_IO;
-pub const TDB_ERR_LOCK: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_LOCK;
-pub const TDB_ERR_OOM: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_OOM;
-pub const TDB_ERR_EXISTS: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_EXISTS;
-pub const TDB_ERR_NOLOCK: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_NOLOCK;
-pub const TDB_ERR_LOCK_TIMEOUT: ffi::TDB_ERROR =
-    ffi::TDB_ERROR_TDB_ERR_LOCK_TIMEOUT;
-pub const TDB_ERR_NOEXIST: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_NOEXIST;
-pub const TDB_ERR_EINVAL: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_EINVAL;
-pub const TDB_ERR_RDONLY: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_RDONLY;
-pub const TDB_ERR_NESTING: ffi::TDB_ERROR = ffi::TDB_ERROR_TDB_ERR_NESTING;
-
-#[allow(non_camel_case_types)]
-#[derive(PartialEq, Eq)]
-pub struct TDB_ERROR(pub u32);
-
-impl TDB_ERROR {
-    fn description(&self) -> &str {
-        match self.0 {
-            ffi::TDB_ERROR_TDB_SUCCESS => "TDB_SUCCESS",
-            ffi::TDB_ERROR_TDB_ERR_CORRUPT => "TDB_ERR_CORRUPT",
-            ffi::TDB_ERROR_TDB_ERR_IO => "TDB_ERR_IO",
-            ffi::TDB_ERROR_TDB_ERR_LOCK => "TDB_ERR_LOCK",
-            ffi::TDB_ERROR_TDB_ERR_OOM => "TDB_ERR_OOM",
-            ffi::TDB_ERROR_TDB_ERR_EXISTS => "TDB_ERR_EXISTS",
-            ffi::TDB_ERROR_TDB_ERR_NOLOCK => "TDB_ERR_NOLOCK",
-            ffi::TDB_ERROR_TDB_ERR_LOCK_TIMEOUT => "TDB_ERR_LOCK_TIMEOUT",
-            ffi::TDB_ERROR_TDB_ERR_NOEXIST => "TDB_ERR_NOEXIST",
-            ffi::TDB_ERROR_TDB_ERR_EINVAL => "TDB_ERR_EINVAL",
-            ffi::TDB_ERROR_TDB_ERR_RDONLY => "TDB_ERR_RDONLY",
-            ffi::TDB_ERROR_TDB_ERR_NESTING => "TDB_ERR_NESTING",
-            _ => "Unknown TDB_ERROR error code",
-        }
-    }
-}
-
-macro_rules! lock_check {
-    ($res:expr) => {{
-        $res.map_err(|e| {
-            DBG_ERR!("Failed to obtain tdb lock: {:?}", e);
-            Box::new(TDB_ERROR(TDB_ERR_NOLOCK))
-        })?
-    }};
-}
-
-impl fmt::Display for TDB_ERROR {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "TDB_ERROR({:#x}): {}", self.0, self.description())
-    }
-}
-
-impl fmt::Debug for TDB_ERROR {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "TDB_ERROR({:#x})", self.0)
-    }
-}
-
-impl std::error::Error for TDB_ERROR {}
-
-#[derive(Clone)]
-pub struct Tdb {
-    tdb: Arc<Mutex<*mut ffi::tdb_context>>,
-}
-
-impl Tdb {
-    pub fn open(
-        name: &str,
-        hash_size: Option<i32>,
-        tdb_flags: Option<i32>,
-        open_flags: Option<i32>,
-        mode: Option<u32>,
-    ) -> Result<Self, Box<dyn Error + '_>> {
-        let path = PathBuf::from(name);
-        let tdb = unsafe {
-            ffi::tdb_open(
-                wrap_string(name),
-                hash_size.unwrap_or(0),
-                tdb_flags.unwrap_or(ffi::TDB_DEFAULT as i32),
-                match open_flags {
-                    Some(open_flags) => open_flags,
-                    None => {
-                        if path.exists() {
-                            libc::O_RDWR
-                        } else {
-                            libc::O_RDWR | libc::O_CREAT
-                        }
-                    }
-                },
-                mode.unwrap_or(0o600),
-            )
-        };
-        if tdb.is_null() {
-            return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
-        }
-        Ok(Tdb {
-            tdb: Arc::new(Mutex::new(tdb)),
-        })
-    }
-
-    pub fn transaction_start(&mut self) -> Result<bool, Box<dyn Error + '_>> {
-        let tdb = self.tdb.lock()?;
-        unsafe { Ok(ffi::tdb_transaction_start(*tdb) == 0) }
-    }
-
-    pub fn transaction_commit(&mut self) -> Result<bool, Box<dyn Error + '_>> {
-        let tdb = self.tdb.lock()?;
-        unsafe { Ok(ffi::tdb_transaction_commit(*tdb) == 0) }
-    }
-
-    pub fn transaction_cancel(&mut self) -> Result<bool, Box<dyn Error + '_>> {
-        let tdb = self.tdb.lock()?;
-        unsafe { Ok(ffi::tdb_transaction_cancel(*tdb) == 0) }
-    }
-
-    pub fn exists(&self, key: &str) -> Result<bool, Box<dyn Error + '_>> {
-        let tdb = lock_check!(self.tdb.lock());
-        let key = ffi::TDB_DATA {
-            dptr: wrap_string(key) as *mut u8,
-            dsize: key.len(),
-        };
-        unsafe { Ok(ffi::tdb_exists(*tdb, key) == 1) }
-    }
-
-    pub fn fetch(&self, key: &str) -> Result<String, Box<dyn Error + '_>> {
-        let tdb = self.tdb.lock()?;
-        let key = ffi::TDB_DATA {
-            dptr: wrap_string(key) as *mut u8,
-            dsize: key.len(),
-        };
-        let res = unsafe { ffi::tdb_fetch(*tdb, key) };
-        if res.dptr.is_null() {
-            let err = unsafe { ffi::tdb_error(*tdb) };
-            return Err(Box::new(TDB_ERROR(err)));
-        }
-        Ok(unsafe {
-            std::str::from_utf8_unchecked(std::slice::from_raw_parts(
-                res.dptr, res.dsize,
-            ))
-        }
-        .to_string())
-    }
-
-    pub fn delete(&mut self, key: &str) -> Result<bool, Box<dyn Error + '_>> {
-        let tdb = self.tdb.lock()?;
-        let key = ffi::TDB_DATA {
-            dptr: wrap_string(key) as *mut u8,
-            dsize: key.len(),
-        };
-        unsafe { Ok(ffi::tdb_delete(*tdb, key) == 0) }
-    }
-
-    pub fn store(
-        &mut self,
-        key: &str,
-        dbuf: &[u8],
-        flag: Option<u32>,
-    ) -> Result<bool, Box<dyn Error + '_>> {
-        let tdb = self.tdb.lock()?;
-        let flag = match flag {
-            Some(flag) => flag,
-            None => ffi::TDB_REPLACE,
-        };
-        let key = ffi::TDB_DATA {
-            dptr: wrap_string(key) as *mut u8,
-            dsize: key.len(),
-        };
-        let dbuf = ffi::TDB_DATA {
-            dptr: dbuf.as_ptr() as *mut u8,
-            dsize: dbuf.len(),
-        };
-        unsafe { Ok(ffi::tdb_store(*tdb, key, dbuf, flag as i32) == 0) }
-    }
-
-    pub fn keys(&self) -> Result<Vec<String>, Box<dyn Error + '_>> {
-        let mut res = Vec::new();
-        let tdb = self.tdb.lock()?;
-        let mut key = unsafe { ffi::tdb_firstkey(*tdb) };
-        if key.dptr.is_null() {
-            return Ok(res);
-        }
-        let rkey = unsafe {
-            std::str::from_utf8_unchecked(std::slice::from_raw_parts(
-                key.dptr, key.dsize,
-            ))
-        }
-        .to_string();
-        res.push(rkey);
-
-        loop {
-            let next = unsafe { ffi::tdb_nextkey(*tdb, key) };
-            unsafe { free(key.dptr as *mut c_void) };
-            if next.dptr.is_null() {
-                break;
-            } else {
-                let rkey = unsafe {
-                    std::str::from_utf8_unchecked(std::slice::from_raw_parts(
-                        next.dptr, next.dsize,
-                    ))
-                }
-                .to_string();
-                res.push(rkey);
-            }
-            key = next;
-        }
-
-        Ok(res)
-    }
-}
-
-impl Drop for Tdb {
-    fn drop(&mut self) {
-        let tdb = self.tdb.lock().unwrap();
-        unsafe { ffi::tdb_close(*tdb) };
-    }
-}
-
-unsafe impl Send for Tdb {}
-unsafe impl Sync for Tdb {}
diff --git a/rust/version/Cargo.toml b/rust/version/Cargo.toml
deleted file mode 100644 (file)
index 046dbd0..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-[package]
-name = "version"
-edition.workspace = true
-license.workspace = true
-homepage.workspace = true
-version.workspace = true
-
-[lib]
-name = "version"
-path = "src/lib.rs"
-
-[dependencies]
-chelps.workspace = true
-libc.workspace = true
-
-[build-dependencies]
-cc = "1.0.97"
-bindgen = "0.69.4"
diff --git a/rust/version/build.rs b/rust/version/build.rs
deleted file mode 100644 (file)
index b426fd6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-use std::env;
-use std::path::{Path, PathBuf};
-
-fn main() {
-    cc::Build::new()
-        .file("../../source3/lib/version.c")
-        .include(Path::new("../../bin/default"))
-        .include(Path::new("./include")) // for the empty includes.h
-        .warnings(false)
-        .compile("version");
-
-    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")
-        .header("../../bin/default/version.h")
-        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
-        .generate()
-        .expect("Unable to generate bindings");
-
-    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
-    bindings
-        .write_to_file(out_path.join("bindings.rs"))
-        .expect("Couldn't write bindings!");
-}
diff --git a/rust/version/include/includes.h b/rust/version/include/includes.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/rust/version/src/lib.rs b/rust/version/src/lib.rs
deleted file mode 100644 (file)
index d71a4aa..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   Samba Version 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 <http://www.gnu.org/licenses/>.
-*/
-use std::str;
-
-include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
-
-pub fn samba_version_string() -> Option<String> {
-    let null_trimmed_vers =
-        &SAMBA_VERSION_STRING[..SAMBA_VERSION_STRING.len() - 1];
-    match str::from_utf8(null_trimmed_vers) {
-        Ok(vers) => Some(vers.to_string()),
-        Err(_) => None,
-    }
-}
-
-pub fn samba_copyright_string() -> Option<String> {
-    let null_trimmed_copy =
-        &SAMBA_COPYRIGHT_STRING[..SAMBA_COPYRIGHT_STRING.len() - 1];
-    match str::from_utf8(null_trimmed_copy) {
-        Ok(copy) => Some(copy.to_string()),
-        Err(_) => None,
-    }
-}
index 5e08c299f18a398ad999e05cbf267eed22b8b6a0..1ecfee24830f9139507f1b195bb434a0599422f5 100644 (file)
@@ -2,21 +2,4 @@
 
 bld.vendor_sources()
 
-if conf.env.enable_himmelblau:
-    bld.SAMBA_RUST_BINARY('himmelblaud', 'himmelblaud',
-                          ['param',
-                           'chelps',
-                           'dbg',
-                           'ntstatus_gen',
-                           'sock',
-                           'tdb',
-                           'version',
-                           'idmap'])
-    bld.SAMBA_RUST_LIBRARY('nss', 'libnss_himmelblau.so', ['sock',
-                                                           'ntstatus_gen',
-                                                           'param',
-                                                           'version'])
-    bld.SAMBA_RUST_LIBRARY('pam', 'libpam_himmelblau.so', ['sock',
-                                                           'chelps',
-                                                           'param',
-                                                           'version'])
+# There are no Rust integrations at the moment. If there were, they would be built here.
index 8acf6cdc854bfbe13a8008b4de3e0d2642d7cae8..feaafebe9e236c35095a55e2c38f447819873333 100755 (executable)
@@ -178,16 +178,11 @@ builddirs = {
 ctdb_configure_params = " --enable-developer ${PREFIX}"
 samba_configure_params = " ${ENABLE_COVERAGE} ${PREFIX} --with-profiling-data --with-prometheus-exporter"
 
-# We cannot configure himmelblau on old systems missing openssl 3, with glibc
-# older than version 2.32, or when cargo isn't available.
-himmelblau_configure_params = ''
 rust_configure_param = ''
 glibc_vers = float('.'.join(get_libc_version().split('.')[:2]))
 cargo = shutil.which('cargo')
 if glibc_vers >= 2.32 and cargo != None:
     rust_configure_param = ' --enable-rust'
-if ssl.OPENSSL_VERSION_INFO[0] >= 3 and rust_configure_param:
-    himmelblau_configure_params = rust_configure_param + ' --with-himmelblau'
 
 samba_libs_envvars = "PYTHONPATH=${PYTHON_PREFIX}:$PYTHONPATH"
 samba_libs_envvars += " PKG_CONFIG_PATH=$PKG_CONFIG_PATH:${PREFIX_DIR}/lib/pkgconfig"
@@ -854,7 +849,7 @@ tasks = {
     "samba-o3": {
         "sequence": [
             ("random-sleep", random_sleep(300, 900)),
-            ("configure", "ADDITIONAL_CFLAGS='" + samba_o3_cflags + "' ./configure.developer --abi-check-disable" + himmelblau_configure_params + samba_configure_params),
+            ("configure", "ADDITIONAL_CFLAGS='" + samba_o3_cflags + "' ./configure.developer --abi-check-disable" + samba_configure_params),
             ("make", "make -j"),
             ("test", make_test(cmd='make test', TESTS="--exclude=selftest/slow-none", include_envs=["none"])),
             ("quicktest", make_test(cmd='make quicktest', include_envs=["ad_dc", "ad_dc_smb1", "ad_dc_smb1_done"])),
index d8ee4002fab7edb9cc6775e02a19341dcd27d372..5a0cb261824dcd780b84b70bc5282b5735916762 100644 (file)
@@ -1014,13 +1014,6 @@ void loadparm_s3_init_globals(struct loadparm_context *lp_ctx,
 
        Globals.acl_claims_evaluation = ACL_CLAIMS_EVALUATION_AD_DC_ONLY;
 
-       /* Set the default Himmelblaud globals */
-       lpcfg_string_set(Globals.ctx,
-                       &Globals.himmelblaud_hsm_pin_path,
-                       get_dyn_HIMMELBLAUD_HSM_PIN_PATH());
-       Globals.himmelblaud_hello_enabled = false;
-       Globals.himmelblaud_sfa_fallback = false;
-
        Globals.server_smb_encryption_over_quic = true;
        Globals.client_smb_encryption_over_quic = true;
 
diff --git a/wscript b/wscript
index 7ce8cb875a0ddbf09912b29390bd8382ce55a4a6..f27863737fa289b69d10679503a66c538b7a80c5 100644 (file)
--- a/wscript
+++ b/wscript
@@ -156,10 +156,6 @@ def options(opt):
                    dest='SAMBA_VERSION_VENDOR_SUFFIX',
                    default=None)
 
-    opt.add_option('--with-himmelblau', default=False,
-                  help=('Build with Azure Entra ID support.'),
-                  action='store_true', dest='enable_himmelblau')
-
     opt.samba_add_onoff_option('systemd-userdb',
                                help=("Build winbind with support for systemd "
                                      "User/Group Record Lookup API via "
@@ -503,14 +499,6 @@ def configure(conf):
 
     conf.env.debug = Options.options.debug
     conf.env.developer = Options.options.developer
-    conf.env.enable_himmelblau = Options.options.enable_himmelblau
-    if Options.options.enable_himmelblau:
-        if not conf.env.enable_rust:
-            conf.fatal('--with-himmelblau cannot be specified without '
-                       '--enable-rust')
-        if ssl.OPENSSL_VERSION_INFO[0] < 3:
-            conf.fatal('--with-himmelblau cannot be specified with '
-                       '%s' % ssl.OPENSSL_VERSION)
 
     #
     # FreeBSD is broken. It doesn't include 'extern char **environ'