Library for Unix users and groups in Rust.

Overview

uzers-rs

Adoption and continuation of the unmaintained ogham/rust-users crate. Big shout-out to its creator Benjamin Sago.

This is a library for accessing Unix users and groups. It supports getting the system users and groups, storing them in a cache, and creating your own mock tables.

Installation

This crate works with Cargo. Add the following to your Cargo.toml dependencies section:

[dependencies]
uzers = "0.11.1"

Usage

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_id 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.

A User has the following accessors:

  • uid: The user’s ID
  • name: The user’s name
  • primary_group: The ID of this user’s primary group

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());

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 crate offers a caching interface to the database, which offers the same functionality while holding on to every result, caching the information so it can be re-used.

To introduce a cache, create a new UsersCache and call the same methods on it. For example:

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());

This cache is only additive: it’s not possible to drop it, or erase selected entries, as when the database may have been modified, it’s best to start entirely afresh. So to accomplish this, just start using a new UsersCache.

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

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(), group.gid());

Logging

The logging feature, which is on by default, uses the log crate to record all interactions with the operating system at Trace log level.

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!

Mockable users and groups

When you’re testing your code, you don’t want to actually rely on the system actually having various users and groups present - it’s much better to have a custom set of users that are guaranteed to be there, so you can test against them.

The mock module allows you to create these custom users and groups definitions, then access them using the same Users trait as in the main library, with few changes to your code.

Creating mock users

The only thing a mock users table needs to know in advance is the UID of the current user. Aside from that, you can add users and groups with add_user and add_group to the table:

use std::sync::Arc;
use uzers::mock::{MockUsers, User, Group};
use uzers::os::unix::{UserExt, GroupExt};

let mut users = MockUsers::with_current_uid(1000);
let bobbins = User::new(1000, "Bobbins", 1000).with_home_dir("/home/bobbins");
users.add_user(bobbins);
users.add_group(Group::new(100, "funkyppl"));

The exports get re-exported into the mock module, for simpler use lines.

Using mock users

To set your program up to use either type of Users table, make your functions and structs accept a generic parameter that implements the Users trait. Then, you can pass in a value of either OS or Mock type.

Here’s a complete example:

use std::sync::Arc;
use uzers::{Users, UsersCache, User};
use uzers::os::unix::UserExt;
use uzers::mock::MockUsers;

fn print_current_username<U: Users>(users: &mut U) {
    println!("Current user: {:?}", users.get_current_username());
}

let mut users = MockUsers::with_current_uid(1001);
users.add_user(User::new(1001, "fred", 101));
print_current_username(&mut users);

let mut actual_users = UsersCache::new();
print_current_username(&mut actual_users);
You might also like...
Just a UNIX's cat copy, but less bloated and in Rust.
Just a UNIX's cat copy, but less bloated and in Rust.

RAT The opposite of UNIX's cat, less bloated, and in Rust. About the project The idea of this CLI is "A CLI program that is basically UNIX's cat comma

A small unix and windows lib to search for executables in PATH folders.

A small unix and windows lib to search for executables in path folders.

Safe Unix shell-like parameter expansion/variable substitution via cross-platform CLI or Rust API
Safe Unix shell-like parameter expansion/variable substitution via cross-platform CLI or Rust API

Safe Unix shell-like parameter expansion/variable substitution for those who need a more powerful alternative to envsubst but don't want to resort to

A unix shell written in rust
A unix shell written in rust

rust-shell a unix shell written in rust Features Main features has .rc file (in ~/.rstshrc) has syntax highlighting fish-like autosuggestion emacs edi

Reviving the Research Edition Unix speak command

This repository contains the source code of Unix speak program that appeared in the Third (1973) to Sixth (1975) Research Unix editions, slightly adjusted to run on a modern computer. Details on the code's provenance and the methods employed for reviving it can be found in this blog post.

Spawn multiple concurrent unix terminals in Discord

Using this bot can be exceedingly dangerous since you're basically granting people direct access to your shell.

fcp is a significantly faster alternative to the classic Unix cp(1) command
fcp is a significantly faster alternative to the classic Unix cp(1) command

A significantly faster alternative to the classic Unix cp(1) command, copying large files and directories in a fraction of the time.

A tool for automating terminal applications in Unix.

expectrl A tool for automating terminal applications in Unix. Using the library you can: Spawn process Control process Expect/Verify responces It was

Modern file system navigation tool on Unix
Modern file system navigation tool on Unix

monat -- Modern file system Navigator 简体中文 Introduction monat is a Unix shell auxiliary command focusing on the navigation of the file system, especia

Comments
Releases(v0.11.2)
  • v0.11.2(Aug 25, 2023)

  • v0.11.1(Aug 21, 2023)

    This is the first version of uzers which continues the unmaintained users v0.11.0.

    Bug Fixes

    • Fix group listing: don't add root every time

    Features

    • Allow iterating all groups in the system
    • Add redox and illumos support

    Refactor

    • Reformat entire code base

    Documentation

    • Rename to uzers
    • Add this changelog

    CI

    • Add Github workflows

    What's Changed

    • (users PR 45) Fix group listing: don't add root every time by @gierens in https://github.com/gierens/uzers-rs/pull/1
    • (users PR 49) Add cfg illlumos in addition to solaris by @gierens in https://github.com/gierens/uzers-rs/pull/2
    • (users PR 51) Allow iterating all groups in the system by @gierens in https://github.com/gierens/uzers-rs/pull/3
    • (users PR 53) Add Redox support by @gierens in https://github.com/gierens/uzers-rs/pull/4

    New Contributors

    • @gierens made their first contribution in https://github.com/gierens/uzers-rs/pull/1

    Full Changelog: https://github.com/gierens/uzers-rs/commits/v0.11.1

    Source code(tar.gz)
    Source code(zip)
A Rust curses library, supports Unix platforms and Windows

pancurses pancurses is a curses library for Rust that supports both Linux and Windows by abstracting away the backend that it uses (ncurses-rs and pdc

Ilkka Halila 360 Jan 7, 2023
Terminal UI that allows Alacritty users to quickly and easily shuffle through provided themes 🦄

Alac-pretty alac-pretty.mp4 If you're like me in that you constantly need to change the colors of your dev environment because visual stagnation reall

Benji Nguyen 17 Aug 29, 2022
simple but convenient CLI-based Nostr client app for following users and sending DMs

nostr-commander-rs TLDR: simple but convenient CLI-based Nostr client app for publishing, sending DMs, as well as following users and channels nostr-c

null 18 Dec 30, 2022
Safer Nostr is a service that helps protect users by loading sensitive information (IP leak) and using AI to prevent inappropriate images from being uploaded.

Safer Nostr is a service that helps protect users by loading sensitive information (IP leak) and using AI to prevent inappropriate images from being uploaded. It also offers image optimization and storage options. It has configurable privacy and storage settings, as well as custom cache expiration.

Thomas 4 Dec 29, 2022
skyWM is an extensible tiling window manager written in Rust. skyWM has a clear and distinct focus adhering to the KISS and Unix philosophy.

Please note: skyWM is currently in heavy development and is not usable as of yet. Documentation and versions will change quickly. skyWM skyWM is an ex

MrBeeBenson 74 Dec 28, 2022
kwctl is the go-to CLI tool for Kubewarden users.

kwctl kwctl is the go-to CLI tool for Kubewarden users. Think of it as the docker CLI tool if you were working with containers. How does kwctl help me

Kubewarden 45 Dec 21, 2022
An interactive Bayesian Probability Calculator CLI that guides users through updating beliefs based on new evidence.

Bayesian Probability Calculator CLI Welcome to the Bayesian Probability Calculator CLI! This command-line tool is designed to help you update your bel

Ben Greenberg 4 Apr 25, 2023
TTAutoRecord is a tool to automatically download TikTok Livestreams of users you follow.

TTAutoRecord: Automated TikTok Live Stream Recorder TTAutoRecord is a specialized utility designed to automate the recording of live streams on TikTok

Ollie 4 Oct 30, 2023
A chat to help users understand lessons from St. Josemaria Escriva's works

A chat to help users understand lessons from St. Josemaria Escriva's works. I'll be using Rust, OpenAI API, and qdrant vector database. Non-profit code, only looking forward to enlightening minds.

Eduardo Lemos 3 Nov 9, 2023
A Unix shell written and implemented in rust 🦀

vsh A Blazingly fast shell made in Rust ?? Installation Copy and paste the following command and choose the appropriate installtion method for you. Yo

XMantle 89 Dec 18, 2022