A simple sudo replacement
Go to file
Nathan Fisher dba3decfaf Give up to three attempts at password validation 2023-11-13 02:37:46 -05:00
error Replace all libc funcionality with `pw` crate, drastically reducing use 2023-06-18 22:54:49 -04:00
sg Give up to three attempts at password validation 2023-11-13 02:37:46 -05:00
src Give up to three attempts at password validation 2023-11-13 02:37:46 -05:00
su Fix setting permissions if bootstrap is run as root 2023-06-19 18:37:36 -04:00
.gitignore Simplify Linux code after adding BSD capability. Adjust the README to 2023-06-14 23:50:10 -04:00
Cargo.lock Give up to three attempts at password validation 2023-11-13 02:37:46 -05:00
Cargo.toml Give up to three attempts at password validation 2023-11-13 02:37:46 -05:00
LICENSE Added GPL3 license 2023-02-25 00:32:01 -05:00
README.md Fix up README formatting and update some of it's content 2023-06-19 19:00:12 -04:00
sizes.txt Replace all libc funcionality with `pw` crate, drastically reducing use 2023-06-18 22:54:49 -04:00

README.md

Contents

Description

Jah is the Rastafarian word for God. As the purpose of this program is to run commands on a Linux system with enhanced privileges, and being a Bob Marley fan, I thought it might be nice to think of Bob every time I needed to run a command with root access. So in this context, jah is best thought of as a sudo replacement with a much smaller scope and a simple and easy to audit codebase.

The rationale of this program is that 99.9% of those administering a Unix system will only ever use 5% of the feature set of sudo. The rest of the code making up the program is at best sitting unused and dormant on the system, and at worst is concealing any number of potential exploits. Any suid root owned binaries on my system are expected to be well vetted and hopefully simple to understand. Sudo is an example, at least in this author's opinion, of unjustifiable and potentially dangerous complexity for it's intended purpose. As of this writing the sudo code is made up of 108,255 lines of C and some 18,747 lines of C headers, according to Tokei. By contrast, Jah is a total of 315 lines of Rust excluding external crates. There are only four external crates used (clap, libc, libcrypt-rs and rpassword) and a minimum of transitive dependencies.

Jah allows any member of the wheel group to run any command requested as any user and group, provided they have authenticated using their own password. As historically only those who were members of wheel could use the su command to become root this has clear historical precedent. Authentication for each user is effective for five minutes, after which the user must re-authenticate, just as sudo does. If desired, a group named jah can be created on the system, and any members of this group will be able to run any command as any user without authentication. If this capability is not desired, simply do not have this group on your system.

There is no configuration file, so there is no complicated code required to parse configuration. That also means that there is drastically less possibility of misconfiguring the program and leaving security holes via user error. For Linux builds, it is assumed that a shadowed password database is in use. Password authentication is via comparing the stored password hash against the hash of the entered password using libcrypt, and it is assumed that the library will be available to link against at runtime.

Installation

You will need the Rust toolchain version 1.65 or greater to compile jah.

cargo build --release --features bootstrap

The --features bootstrap option will build a second binary named bootstrap which can be used to install the program into the correct location while also generating shell completions and Unix manual pages. This binary can also be used to install all of the above into a staging directory for packaging. If run with root privileges, then the jah binary will be installed setuid root.

The distribution also contains a replacement su binary which is behind the su feature flag. This has been developed specifically for HitchHiker Linux, but if desired it can be built by adding su to the list of features.

cargo build --release --features bootstrap,su

Usage

# jah -h
Run COMMAND as another user

Usage: jah [OPTIONS] <COMMAND>...

Arguments:
  <COMMAND>...

Options:
  -u, --user <user>    The user that the command will run as [default: root]
  -g, --group <group>  The group that the command will run as [default: wheel]
  -h, --help           Print help (see more with '--help')
  -V, --version        Print version

As there is no configuration, giving your user permission to use jah is as simple as adding your user to the wheel group. This group may not exist on some newer Linux distributions, in which case it can be created with the groupadd command.

# as root
# Create `wheel` if it does not exist
# The `-r` option ensures that it is created as a system group
groupadd -r wheel
# Add your user to `wheel` by adding it to your list of supplementary groups
# assuming your username is `bob`
usermod -aG wheel bob

Unsafe

It is rather common when writing such low level code in Rust to wind up with a great deal of unsafe. Indeed, the early drafts of this program had a number of unsafe blocks due to numerous calls into libc. Much of the libc functionality that was in use has been replaced with safe Rust in the pw crate, which parses the Unix passwd and group database files. The pw crate only uses unsafe to get user and group id numbers, which can only be done by either calling libc functions or making system calls directly, both of which involve use of unsafe. This is the unavoidable minimum for such a program.