erni - Info
Erni gives root a clean way to run commands as any user, even if they have no shell. Replace the age-old "su - {user} -c {command}" with Erni, and remove the login shells for your daemon accounts.
| Latest version: 0.41.0beta, released 2003/10/10 |
| Latest alpha version: 0.50.0, released 2004/06/09 |
Overview
The Premise
-
On Unix-based systems, many user accounts exist only as "daemon" accounts, or placeholders to run services and own files.
The root user sometimes needs to run commands as one of these daemon/placeholder accounts, perhaps to start a service. Typically, root calls "su" become that user and run the command:
su - {account} -c {some command} The Problem
-
This 'su' syntax only works if the user has a valid login shell. It is preferable that these accounts' login shells be disabled for reasons of system security.
Furthermore, 'su' lacks some much-needed precision: what if the command should run with a different umask than that of the current shell?
The Solution
-
Erni gives you the best of both worlds: using system calls instead of su, root assumes the user's identity to run the command. The account's shell is never loaded.
Additional Features
-
Erni also supports the following features:
-
set the command's umask
-
(optional) perform a chroot before running the command
-
set the target user's group memberships on-the-fly. This means you could grant membership to a given group only for the duration of the command you run.
Erni is not limited to kicking off daemons, though; it can be used in any situation in which root needs to run a command as some other user. For example, when tracing down write-access problems, a quick
erni -u user -E touch /www/admin/test
is much cleaner than "enable user shell; su to user; test access; remember to disable shell again." -
History
Erni is based on the runas.c code from the Titan distribution, with the following enhancements:
(as of version 0.41.0beta) support for supplementary group memberships, either the defaults loaded from the system (such as /etc/group) or specified on the commandline.
different return codes for each error type to facilitate debugging and error handling when run from a script.
use of getopt() for all commandline values, not just the chroot() dir.
optional use of a config file for runtime parameters, to keep the commandline clean.
Though a lot of my work is in C++, Erni is written in C. This means it should build (and run, too!) under any mainstream Unix-based OS with a C compiler. This is the case in my test environment, which includes Linux and Solaris.
Erni is not Sudo
Erni is not a sudo knockoff. These tools may complement one another, but they serve different sides of the same coin: Sudo grants nonroot users restricted root priveleges; Erni helps root run services as nonroot users in a controlled fashion.