Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable nologin #11

Merged
merged 2 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
generating a new salt. Please note that this changes nothing about the
security posture of Userborn. If you provide a plaintext password to
Userborn, there is nothing Userborn can do to protect it from leaking.
- You can now configure the path to the `nologin` binary via the compile-time
environment variable `USERBORN_NO_LOGIN_DEFAULT_PATH` and the runtime
variable `USERBORN_NO_LOGIN_PATH`. These values are used when no explicit
shell is provided in the user config.

## 0.2.0

Expand Down
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,33 @@ re-use is best illustrated by an example. Imagine the following scenario:
- Userborn will discard entries in the shadow database that are not present in
the passwd database. It will warn about these inconsistent entries.

## Configuration

You can configure Userborn during runtime via the provided config file and via
environment variables.

### Environment Variables

- `USERBORN_NO_LOGIN_PATH`: Set this to the path of the `nologin` binary on
your system. This path is used when the user config doesn't specify a
`shell`. If this enviroment variable is set, its value overrides
`USERBORN_NO_LOGIN_DEFAULT_PATH`.

## Building Userborn

Runtime dependencies:

- `libxcrypt`

### Build-Time Parameters

You can configure Userborn via compile-time environment variables:

- `USERBORN_NO_LOGIN_DEFAULT_PATH`: Set this to the default path of the
`nologin` binary in your distro or system. If this is not set, the value
`/run/current-system/sw/bin/nologin` is used which will only make sense on
NixOS.

## Comparison With Other Tools for Declarative User Management

### systemd-sysusers
Expand Down
19 changes: 16 additions & 3 deletions rust/userborn/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@ use passwd::Passwd;
use password::HashedPassword;
use shadow::Shadow;

/// Path to the nologin binary.
const NO_LOGIN: &str = "/run/current-system/sw/bin/nologin";
/// Fallback path to the nologin binary.
///
/// This is used when `USERBORN_NO_LOGIN_PATH` is not set during runtime and
/// `USERBORN_NO_LOGIN_DEFAULT_PATH` hasn't been set during compilation.
const NO_LOGIN_FALLBACK: &str = "/run/current-system/sw/bin/nologin";
/// Default path to the nolign binary.
///
/// This can be configured via a compile-time environment variable.
const NO_LOGIN_DEFAULT: Option<&'static str> = option_env!("USERBORN_NO_LOGIN_DEFAULT_PATH");
const DEFAULT_DIRECTORY: &str = "/etc";

fn main() -> ExitCode {
Expand Down Expand Up @@ -192,7 +199,10 @@ fn create_user(
gid,
user_config.description.clone().unwrap_or_default(),
user_config.home.clone().unwrap_or_default(),
user_config.shell.clone().unwrap_or(NO_LOGIN.into()),
user_config.shell.clone().unwrap_or(
std::env::var("USERBORN_NO_LOGIN_PATH")
.unwrap_or(NO_LOGIN_DEFAULT.unwrap_or(NO_LOGIN_FALLBACK).into()),
),
);

let description = new_entry.describe();
Expand Down Expand Up @@ -391,6 +401,9 @@ mod tests {

#[test]
fn update_users_and_groups_across_generations() -> Result<()> {
// Explitly set this because the expected values depend on this.
std::env::set_var("USERBORN_NO_LOGIN_PATH", NO_LOGIN_FALLBACK);

let mut group_db = Group::default();
let mut passwd_db = Passwd::default();
let mut shadow_db = Shadow::default();
Expand Down