]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
initial rust
authorTycho Andersen <tycho@tycho.pizza>
Fri, 30 Jul 2021 16:52:52 +0000 (10:52 -0600)
committerTycho Andersen <tycho@tycho.pizza>
Fri, 30 Jul 2021 19:47:02 +0000 (13:47 -0600)
Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
.gitignore
Cargo.lock [new file with mode: 0644]
Cargo.toml [new file with mode: 0644]
Makefile.rust [new file with mode: 0644]
src/bin/passwd.rs [new file with mode: 0644]

index 80cc16c49ea56fcbc0238f8e54bf28aaba6744a6..d1032460ac479a6086c7abd2d90a1bf61a277c01 100644 (file)
@@ -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 (file)
index 0000000..0fb9244
--- /dev/null
@@ -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 (file)
index 0000000..998196f
--- /dev/null
@@ -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 (file)
index 0000000..1574de5
--- /dev/null
@@ -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 (file)
index 0000000..c5276bb
--- /dev/null
@@ -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<u64>,
+
+    #[clap(short, long)]
+    lock: bool,
+
+    #[clap(short = 'n', long)]
+    mindays: Option<u64>,
+
+    #[clap(short, long)]
+    quiet: bool,
+
+    #[clap(short, long)]
+    repository: Option<String>,
+
+    #[clap(short = 'R', long)]
+    root: Option<String>,
+
+    #[clap(short = 'S', long)]
+    status: bool,
+
+    login: Option<String>,
+}
+
+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)
+}