From: Tycho Andersen Date: Fri, 30 Jul 2021 16:52:52 +0000 (-0600) Subject: initial rust X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e5fb55be72a20b11ce1befdea9be6c076db4ca6d;p=thirdparty%2Fshadow.git initial rust Signed-off-by: Tycho Andersen --- diff --git a/.gitignore b/.gitignore index 80cc16c49..d1032460a 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,8 @@ Makefile.in /shadow.spec /shadow-*.tar.* /libmisc/getdate.c + + +# Added by cargo + +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..0fb92441b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,297 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "nix" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "os_str_bytes" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "shadow" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "nix", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..998196f24 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "shadow" +version = "0.1.0" +edition = "2018" + +[dependencies] +anyhow = "*" +clap = "3.0.0-beta.2" +nix = "*" diff --git a/Makefile.rust b/Makefile.rust new file mode 100644 index 000000000..1574de5d4 --- /dev/null +++ b/Makefile.rust @@ -0,0 +1,21 @@ +SRC=$(shell find . -name \*.rs | grep -v "^./target") + +target/debug/passwd: Cargo.toml $(SRC) + cargo build + +.PHONY: check +check: + RUST_BACKTRACE=1 cargo test -- --nocapture + +.PHONY: lint +lint: $(SRC) + rustfmt --check $(SRC) + cargo clippy --all-targets --all-features -- -D warnings -A clippy::upper-case-acronyms + +.PHONY: fmt +fmt: + rustfmt --emit files $(SRC) + +.PHONY: clean +clean: + -cargo clean diff --git a/src/bin/passwd.rs b/src/bin/passwd.rs new file mode 100644 index 000000000..c5276bba6 --- /dev/null +++ b/src/bin/passwd.rs @@ -0,0 +1,121 @@ +#[macro_use] +extern crate anyhow; +extern crate clap; +extern crate nix; + +use std::env; +use std::fs; +use std::path::Path; +use std::process::exit; + +use clap::{Clap, ErrorKind, IntoApp}; +use nix::unistd::{chroot, Uid}; + +const E_SUCCESS: i32 = 0; /* success */ +const E_NOPERM: i32 = 1; /* permission denied */ +const E_USAGE: i32 = 2; /* invalid combination of options */ +const E_FAILURE: i32 = 3; /* unexpected failure, nothing done */ +const E_MISSING: i32 = 4; /* unexpected failure, passwd file missing */ +const E_PWDBUSY: i32 = 5; /* passwd file busy, try again later */ +const E_BAD_ARG: i32 = 6; /* invalid argument to option */ + +#[derive(Clap, Debug)] +#[clap(version = "0.0.0-rust")] +struct Opts { + // TODO: find a better way to aggregate all other args? + #[clap(short, long, requires = "status", conflicts_with_all = &["delete", "expire"])] + all: bool, + + #[clap(short, long)] + delete: bool, + + #[clap(short, long)] + expire: bool, + + #[clap(short, long)] + help: bool, + + #[clap(short, long)] + keep_tokens: bool, + + #[clap(short, long)] + inactive: Option, + + #[clap(short, long)] + lock: bool, + + #[clap(short = 'n', long)] + mindays: Option, + + #[clap(short, long)] + quiet: bool, + + #[clap(short, long)] + repository: Option, + + #[clap(short = 'R', long)] + root: Option, + + #[clap(short = 'S', long)] + status: bool, + + login: Option, +} + +fn do_chroot(newroot: &Path) -> anyhow::Result<()> { + if !newroot.is_absolute() { + bail!("{:?} is not an absolute path", newroot) + } + + if let Err(e) = fs::symlink_metadata(newroot) { + bail!("cannot access {:?}: {}", newroot, e) + } + + env::set_current_dir(newroot)?; + Ok(chroot(newroot)?) +} + +fn main() { + let opts = Opts::try_parse().unwrap_or_else(|e| { + match e.kind { + ErrorKind::DisplayHelp => { + Opts::into_app().print_long_help().unwrap_or_else(|e| { + eprintln!("failed to render help: {}", e); + exit(E_FAILURE) + }); + exit(E_SUCCESS) + }, + ErrorKind::UnknownArgument => exit(E_BAD_ARG), + ErrorKind::InvalidValue => exit(E_BAD_ARG), + _ => exit(E_USAGE), + } + }); + + if let Some(newroot) = opts.root { + do_chroot(Path::new(&newroot)).unwrap_or_else(|e| { + eprintln!("failed to chroot: {}", e); + exit(E_FAILURE) + }) + } + + // TODO: openlog() + // sanitize environment + + let amroot = Uid::effective().is_root(); + + if opts.all { + if !amroot { + exit(E_NOPERM) + } + + todo!() + } + + let _name = opts.login.unwrap_or_else(|| { + // need to implement get_my_pwent(); or really just libc::getlogin(), but it sucks that + // it's unsafe... + todo!() + }); + + exit(E_SUCCESS) +}