From fd69cc22300b74f22648e4b2b7f118bba6559524 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Sun, 14 Sep 2025 18:58:46 +0300 Subject: [PATCH] nologin: Add tool --- Cargo.lock | 9 ++++ Cargo.toml | 2 + src/uu/nologin/Cargo.toml | 15 ++++++ src/uu/nologin/nologin.md | 7 +++ src/uu/nologin/src/main.rs | 1 + src/uu/nologin/src/nologin.rs | 91 +++++++++++++++++++++++++++++++++++ tests/by-util/test_nologin.rs | 37 ++++++++++++++ tests/tests.rs | 4 ++ 8 files changed, 166 insertions(+) create mode 100644 src/uu/nologin/Cargo.toml create mode 100644 src/uu/nologin/nologin.md create mode 100644 src/uu/nologin/src/main.rs create mode 100644 src/uu/nologin/src/nologin.rs create mode 100644 tests/by-util/test_nologin.rs diff --git a/Cargo.lock b/Cargo.lock index 2c18eca..c40371a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1269,6 +1269,7 @@ dependencies = [ "uu_mcookie", "uu_mesg", "uu_mountpoint", + "uu_nologin", "uu_renice", "uu_rev", "uu_setsid", @@ -1415,6 +1416,14 @@ dependencies = [ "uucore", ] +[[package]] +name = "uu_nologin" +version = "0.0.1" +dependencies = [ + "clap", + "uucore", +] + [[package]] name = "uu_renice" version = "0.0.1" diff --git a/Cargo.toml b/Cargo.toml index 5020ce2..7ab473b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ feat_common_core = [ "mcookie", "mesg", "mountpoint", + "nologin", "renice", "rev", "setsid", @@ -102,6 +103,7 @@ lsmem = { optional = true, version = "0.0.1", package = "uu_lsmem", path = "src/ mcookie = { optional = true, version = "0.0.1", package = "uu_mcookie", path = "src/uu/mcookie" } mesg = { optional = true, version = "0.0.1", package = "uu_mesg", path = "src/uu/mesg" } mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" } +nologin = { optional = true, version = "0.0.1", package = "uu_nologin", path = "src/uu/nologin" } renice = { optional = true, version = "0.0.1", package = "uu_renice", path = "src/uu/renice" } rev = { optional = true, version = "0.0.1", package = "uu_rev", path = "src/uu/rev" } setsid = { optional = true, version = "0.0.1", package = "uu_setsid", path ="src/uu/setsid" } diff --git a/src/uu/nologin/Cargo.toml b/src/uu/nologin/Cargo.toml new file mode 100644 index 0000000..065d428 --- /dev/null +++ b/src/uu/nologin/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "uu_nologin" +version = "0.0.1" +edition = "2021" + +[lib] +path = "src/nologin.rs" + +[[bin]] +name = "nologin" +path = "src/main.rs" + +[dependencies] +uucore = { workspace = true } +clap = { workspace = true } diff --git a/src/uu/nologin/nologin.md b/src/uu/nologin/nologin.md new file mode 100644 index 0000000..95265bc --- /dev/null +++ b/src/uu/nologin/nologin.md @@ -0,0 +1,7 @@ +# nologin + +``` +nologin [options] +``` + +Politely refuse a login. diff --git a/src/uu/nologin/src/main.rs b/src/uu/nologin/src/main.rs new file mode 100644 index 0000000..d7aaf91 --- /dev/null +++ b/src/uu/nologin/src/main.rs @@ -0,0 +1 @@ +uucore::bin!(uu_nologin); diff --git a/src/uu/nologin/src/nologin.rs b/src/uu/nologin/src/nologin.rs new file mode 100644 index 0000000..8c62af4 --- /dev/null +++ b/src/uu/nologin/src/nologin.rs @@ -0,0 +1,91 @@ +// This file is part of the uutils util-linux package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use clap::{crate_version, Arg, ArgAction, Command}; +use std::fs; +use uucore::{error::UResult, format_usage, help_about, help_usage}; + +const ABOUT: &str = help_about!("nologin.md"); +const USAGE: &str = help_usage!("nologin.md"); + +#[uucore::main] +pub fn uumain(args: impl uucore::Args) -> UResult<()> { + let _matches = uu_app().try_get_matches_from(args)?; + + // Try to read custom message from /etc/nologin.txt + let message = match fs::read_to_string("/etc/nologin.txt") { + Ok(content) => content.trim().to_string(), + Err(_) => "This account is currently not available.".to_string(), + }; + + println!("{}", message); + std::process::exit(1); +} + +pub fn uu_app() -> Command { + Command::new(uucore::util_name()) + .version(crate_version!()) + .about(ABOUT) + .override_usage(format_usage(USAGE)) + .infer_long_args(true) + .arg( + Arg::new("command") + .short('c') + .long("command") + .value_name("command") + .help("does nothing (for compatibility)"), + ) + .arg( + Arg::new("init-file") + .long("init-file") + .value_name("file") + .help("does nothing (for compatibility)"), + ) + .arg( + Arg::new("interactive") + .short('i') + .long("interactive") + .help("does nothing (for compatibility)") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("login") + .short('l') + .long("login") + .help("does nothing (for compatibility)") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("noprofile") + .long("noprofile") + .help("does nothing (for compatibility)") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("norc") + .long("norc") + .help("does nothing (for compatibility)") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("posix") + .long("posix") + .help("does nothing (for compatibility)") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("rcfile") + .long("rcfile") + .value_name("file") + .help("does nothing (for compatibility)"), + ) + .arg( + Arg::new("restricted") + .short('r') + .long("restricted") + .help("does nothing (for compatibility)") + .action(ArgAction::SetTrue), + ) +} diff --git a/tests/by-util/test_nologin.rs b/tests/by-util/test_nologin.rs new file mode 100644 index 0000000..f808c69 --- /dev/null +++ b/tests/by-util/test_nologin.rs @@ -0,0 +1,37 @@ +// This file is part of the uutils util-linux package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use uutests::{new_ucmd, util::TestScenario, util_name}; + +#[test] +fn test_invalid_arg() { + new_ucmd!().arg("--definitely-invalid").fails().code_is(1); +} + +#[test] +fn test_nologin_args() { + let args_to_try: &[&[&str]] = &[ + &[], + &["-c", "command"], + &["--init-file", "file"], + &["-i"], + &["--interactive"], + &["-l"], + &["--login"], + &["--noprofile"], + &["--norc"], + &["--posix"], + &["--rcfile", "file"], + &["--restricted"], + &["-r"], + ]; + for args in args_to_try { + new_ucmd!() + .args(args) + .fails() + .code_is(1) + .stdout_contains("This account is currently not available."); + } +} diff --git a/tests/tests.rs b/tests/tests.rs index d298378..4871156 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -35,6 +35,10 @@ mod test_mesg; #[path = "by-util/test_mountpoint.rs"] mod test_mountpoint; +#[cfg(feature = "nologin")] +#[path = "by-util/test_nologin.rs"] +mod test_nologin; + #[cfg(feature = "blockdev")] #[path = "by-util/test_blockdev.rs"] mod test_blockdev;