Expand description
This is a library for getting information on Unix users and groups. It supports getting the system users, and creating your own mock tables.
In Unix, each user has an individual user ID, and each process has an
effective user ID that says which user’s permissions it is using.
Furthermore, users can be the members of groups, which also have names and
IDs. This functionality is exposed in libc, the C standard library, but as
an unsafe Rust interface. This wrapper library provides a safe interface,
using User
and Group
types
and functions such as get_user_by_uid
instead
of low-level pointers and strings. It also offers basic caching
functionality.
It does not (yet) offer editing functionality; the values returned are read-only.
§Users
The function get_current_uid
returns a
uid_t
value representing the user currently running the program, and the
get_user_by_uid
function scans the users
database and returns a User
with the user’s information. This function
returns None
when there is no user for that ID. The uid_t
type is
re-exported from the libc crate.
A User
value has the following accessors:
- uid: The user’s ID
- name: The user’s name
- primary_group: The ID of this user’s primary group
- OS-specific extensions such as home directories
Here is a complete example that prints out the current user’s name:
use uzers::{get_user_by_uid, get_current_uid};
let user = get_user_by_uid(get_current_uid()).unwrap();
println!("Hello, {}!", user.name().to_string_lossy());
This code assumes (with unwrap()
) that the user hasn’t been deleted after
the program has started running. For arbitrary user IDs, this is not a
safe assumption: it’s possible to delete a user while it’s running a
program, or is the owner of files, or for that user to have never existed.
So always check the return values!
There is also a get_current_username
function, as it’s such a common operation that it deserves special
treatment.
§Caching
Despite the above warning, the users and groups database rarely changes. While a short program may only need to get user information once, a long-running one may need to re-query the database many times, and a medium-length one may get away with caching the values to save on redundant system calls.
For this reason, this create offers two caching interfaces that expose the
same functionality while reducing system calls:
UsersCache
and
UsersSnapshot
. UsersCache
is a lazy
cache, storing answers as they arrive from the OS. UsersSnapshot
is an
eager cache, querying all data at once when constructed.
UsersCache
has a smaller memory and performance overhead, while
UsersSnapshot
offers better consistency and allows iterating over users
and groups.
For example, to introduce a lazy cache, create a new
UsersCache
. It has functions with the
same names as the ones from earlier:
use uzers::{Users, Groups, UsersCache};
let mut cache = UsersCache::new();
let uid = cache.get_current_uid();
let user = cache.get_user_by_uid(uid).unwrap();
println!("Hello again, {}!", user.name().to_string_lossy());
See documentation for UsersCache
and
UsersSnapshot
for more details.
§Groups
Finally, it’s possible to get groups in a similar manner.
A Group
has the following accessors:
- gid: The group’s ID
- name: The group’s name
- OS-specific extensions such as lists of members
And again, a complete example:
use uzers::{Users, Groups, UsersCache};
let mut cache = UsersCache::new();
let group = cache.get_group_by_name("admin").expect("No such group 'admin'!");
println!("The '{}' group has the ID {}", group.name().to_string_lossy(), group.gid());
§Logging
The logging
feature, which is on by default, uses the log
crate to
record all interactions with the operating system.
§Caveats
You should be prepared for the users and groups tables to be completely broken: IDs shouldn’t be assumed to map to actual users and groups, and usernames and group names aren’t guaranteed to map either!
Use the mock
module to create custom tables to test
your code for these edge cases.
Re-exports§
pub use cache::UsersCache;
pub use cache::UsersSnapshot;
Modules§
- Caches for users and groups provided by the OS.
- Mockable users and groups.
- OS-specific extensions to users and groups.
- Functions for switching the running process’s user or group.
Structs§
- Information about a particular group.
- Information about a particular user.
Traits§
- Trait for providers of group iterators.
- Trait for providers of user iterators.
- Trait for producers of groups.
- Trait for producers of users.
Functions§
- Creates a new iterator over every group present on the system.
- Creates a new iterator over every user present on the system.
- Returns the group ID for the user running the process.
- Returns the groupname of the user running the process.
- Returns the user ID for the user running the process.
- Returns the username of the user running the process.
- Returns the group ID for the effective user running the process.
- Returns the groupname of the effective user running the process.
- Returns the user ID for the effective user running the process.
- Returns the username of the effective user running the process.
- Searches for a
Group
with the given ID in the system’s group database. Returns it if one is found, otherwise returnsNone
. - Searches for a
Group
with the given group name in the system’s group database. Returns it if one is found, otherwise returnsNone
. - Searches for a
User
with the given username in the system’s user database. Returns it if one is found, otherwise returnsNone
. - Searches for a
User
with the given ID in the system’s user database. Returns it if one is found, otherwise returnsNone
. - Returns groups for a provided user name and primary group id.
- Returns the group access list for the current process.